aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml10
-rw-r--r--OTP_VERSION2
-rw-r--r--bootstrap/bin/no_dot_erlang.bootbin6544 -> 6563 bytes
-rw-r--r--bootstrap/bin/start.bootbin6544 -> 6563 bytes
-rw-r--r--bootstrap/bin/start_clean.bootbin6544 -> 6563 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_asm.beambin11052 -> 11052 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa.beambin12168 -> 12252 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_bsm.beambin17888 -> 17892 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_codegen.beambin37688 -> 37932 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_dead.beambin12004 -> 12424 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_opt.beambin39960 -> 40080 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_pre_codegen.beambin45604 -> 46536 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_share.beambin5348 -> 5372 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_ssa_type.beambin28636 -> 28480 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_validator.beambin50216 -> 50352 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin41388 -> 41392 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app2
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin11472 -> 11452 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_alias.beambin5548 -> 5556 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin50668 -> 50688 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin12688 -> 12920 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin22352 -> 22348 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/gen_udp.beambin1324 -> 1636 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin14200 -> 14196 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/hipe_unified_loader.beambin12336 -> 12340 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin23232 -> 23300 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_udp.beambin1720 -> 2104 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin25360 -> 25360 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_gethost_native.beambin9708 -> 9704 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin13396 -> 13424 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_udp.beambin1908 -> 2188 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app3
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.beambin3628 -> 3644 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/local_udp.beambin1372 -> 1388 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/logger_std_h.beambin9544 -> 9616 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net.beambin0 -> 1624 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user.beambin10980 -> 10980 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_drv.beambin11020 -> 10948 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin16968 -> 16988 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin45360 -> 45356 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6732 -> 6736 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin35048 -> 35024 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin86340 -> 86348 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin25696 -> 25692 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_tar.beambin30972 -> 30976 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin21604 -> 21608 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_pretty.beambin21116 -> 21136 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ordsets.beambin1940 -> 1848 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/rand.beambin29048 -> 29048 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/re.beambin12308 -> 12388 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin35276 -> 35284 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app4
-rw-r--r--bootstrap/lib/stdlib/ebin/string.beambin35872 -> 35740 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin9104 -> 9116 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/uri_string.beambin25084 -> 25072 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/zip.beambin24188 -> 24208 bytes
-rw-r--r--erts/doc/src/Makefile40
-rw-r--r--erts/doc/src/erlang.xml1
-rw-r--r--erts/doc/src/notes.xml88
-rw-r--r--erts/doc/src/part.xml.src (renamed from erts/doc/src/part.xml)4
-rw-r--r--erts/doc/src/ref_man.xml.src (renamed from erts/doc/src/ref_man.xml)5
-rw-r--r--erts/doc/src/socket.xml65
-rw-r--r--erts/doc/src/socket_usage.xml23
-rw-r--r--erts/doc/src/specs.xml.src (renamed from erts/doc/src/specs.xml)3
-rw-r--r--erts/emulator/Makefile.in7
-rw-r--r--erts/emulator/beam/beam_bif_load.c72
-rw-r--r--erts/emulator/beam/binary.c80
-rw-r--r--erts/emulator/beam/bs_instrs.tab23
-rw-r--r--erts/emulator/beam/copy.c49
-rw-r--r--erts/emulator/beam/dist.c28
-rw-r--r--erts/emulator/beam/dist.h16
-rw-r--r--erts/emulator/beam/erl_alloc.types1
-rw-r--r--erts/emulator/beam/erl_alloc_util.c69
-rw-r--r--erts/emulator/beam/erl_bif_binary.c184
-rw-r--r--erts/emulator/beam/erl_bif_info.c26
-rw-r--r--erts/emulator/beam/erl_bif_persistent.c99
-rw-r--r--erts/emulator/beam/erl_binary.h118
-rw-r--r--erts/emulator/beam/erl_bits.c95
-rw-r--r--erts/emulator/beam/erl_bits.h18
-rw-r--r--erts/emulator/beam/erl_db.c15
-rw-r--r--erts/emulator/beam/erl_db.h4
-rw-r--r--erts/emulator/beam/erl_db_catree.c28
-rw-r--r--erts/emulator/beam/erl_db_catree.h3
-rw-r--r--erts/emulator/beam/erl_db_hash.c6
-rw-r--r--erts/emulator/beam/erl_db_hash.h3
-rw-r--r--erts/emulator/beam/erl_db_tree.c6
-rw-r--r--erts/emulator/beam/erl_db_tree.h4
-rw-r--r--erts/emulator/beam/erl_gc.c55
-rw-r--r--erts/emulator/beam/erl_monitor_link.c49
-rw-r--r--erts/emulator/beam/erl_monitor_link.h17
-rw-r--r--erts/emulator/beam/erl_node_tables.c247
-rw-r--r--erts/emulator/beam/erl_node_tables.h39
-rw-r--r--erts/emulator/beam/erl_printf_term.c29
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.c8
-rw-r--r--erts/emulator/beam/erl_process.c76
-rw-r--r--erts/emulator/beam/erl_process.h7
-rw-r--r--erts/emulator/beam/erl_trace.c62
-rw-r--r--erts/emulator/beam/erl_trace.h8
-rw-r--r--erts/emulator/beam/global.h42
-rw-r--r--erts/emulator/drivers/common/inet_drv.c7
-rw-r--r--erts/emulator/nifs/common/prim_net_nif.c (renamed from erts/emulator/nifs/common/net_nif.c)2
-rw-r--r--erts/emulator/nifs/common/socket_dbg.c18
-rw-r--r--erts/emulator/nifs/common/socket_dbg.h4
-rw-r--r--erts/emulator/nifs/common/socket_int.h4
-rw-r--r--erts/emulator/nifs/common/socket_nif.c6542
-rw-r--r--erts/emulator/nifs/common/socket_util.c18
-rw-r--r--erts/emulator/pcre/LICENCE10
-rw-r--r--erts/emulator/pcre/pcre-8.42.tar.bz2bin1570171 -> 0 bytes
-rw-r--r--erts/emulator/pcre/pcre-8.43.tar.bz2bin0 -> 1576584 bytes
-rw-r--r--erts/emulator/pcre/pcre.h4
-rw-r--r--erts/emulator/pcre/pcre_compile.c18
-rw-r--r--erts/emulator/pcre/pcre_jit_compile.c2
-rw-r--r--erts/emulator/sys/unix/sys_drivers.c26
-rw-r--r--erts/emulator/test/binary_SUITE.erl17
-rw-r--r--erts/emulator/test/dump_SUITE.erl14
-rwxr-xr-xerts/emulator/test/esock_ttest/esock-ttest4
-rwxr-xr-xerts/emulator/test/esock_ttest/esock-ttest-client29
-rwxr-xr-xerts/emulator/test/esock_ttest/esock-ttest-server-sock14
-rw-r--r--erts/emulator/test/fun_SUITE.erl10
-rw-r--r--erts/emulator/test/net_SUITE.erl3
-rw-r--r--erts/emulator/test/node_container_SUITE.erl73
-rw-r--r--erts/emulator/test/process_SUITE.erl27
-rw-r--r--erts/emulator/test/socket_SUITE.erl4950
-rw-r--r--erts/emulator/test/socket_test_lib.erl201
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_client.erl5
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_client_socket.erl22
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_gen.erl26
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_server.erl104
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_socket.erl14
-rw-r--r--erts/etc/unix/etp-commands.in75
-rw-r--r--erts/lib_src/pthread/ethread.c4
-rw-r--r--erts/preloaded/ebin/erl_init.beambin2260 -> 2336 bytes
-rw-r--r--erts/preloaded/ebin/net.beambin6096 -> 0 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin81424 -> 81508 bytes
-rw-r--r--erts/preloaded/ebin/prim_net.beambin0 -> 4700 bytes
-rw-r--r--erts/preloaded/ebin/socket.beambin75044 -> 75892 bytes
-rw-r--r--erts/preloaded/src/Makefile19
-rw-r--r--erts/preloaded/src/erl_init.erl7
-rw-r--r--erts/preloaded/src/prim_inet.erl2
-rw-r--r--erts/preloaded/src/prim_net.erl (renamed from erts/preloaded/src/net.erl)74
-rw-r--r--erts/preloaded/src/socket.erl156
-rw-r--r--erts/vsn.mk2
-rw-r--r--lib/common_test/src/ct_release_test.erl22
-rw-r--r--lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl4
-rw-r--r--lib/compiler/doc/src/notes.xml44
-rw-r--r--lib/compiler/src/beam_except.erl32
-rw-r--r--lib/compiler/src/beam_ssa_bsm.erl6
-rw-r--r--lib/compiler/src/beam_ssa_codegen.erl18
-rw-r--r--lib/compiler/src/beam_ssa_dead.erl87
-rw-r--r--lib/compiler/src/beam_ssa_opt.erl84
-rw-r--r--lib/compiler/src/beam_ssa_pre_codegen.erl120
-rw-r--r--lib/compiler/src/beam_ssa_share.erl8
-rw-r--r--lib/compiler/src/beam_ssa_type.erl4
-rw-r--r--lib/compiler/src/beam_validator.erl73
-rw-r--r--lib/compiler/src/compile.erl7
-rw-r--r--lib/compiler/test/Makefile15
-rw-r--r--lib/compiler/test/beam_except_SUITE.erl14
-rw-r--r--lib/compiler/test/beam_ssa_SUITE.erl96
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl25
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl22
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl19
-rw-r--r--lib/compiler/test/match_SUITE.erl21
-rw-r--r--lib/compiler/test/receive_SUITE.erl35
-rw-r--r--lib/compiler/test/test_lib.erl3
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/dialyzer/doc/src/notes.xml36
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl116
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/hipe/doc/src/hipe_app.xml4
-rw-r--r--lib/hipe/doc/src/notes.xml20
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl41
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/inets/doc/src/notes.xml18
-rw-r--r--lib/inets/test/httpc_SUITE.erl2
-rw-r--r--lib/inets/vsn.mk2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java8
-rw-r--r--lib/kernel/doc/src/Makefile51
-rw-r--r--lib/kernel/doc/src/logger_disk_log_h.xml2
-rw-r--r--lib/kernel/doc/src/net.xml (renamed from erts/doc/src/net.xml)0
-rw-r--r--lib/kernel/doc/src/ref_man.xml.src (renamed from lib/kernel/doc/src/ref_man.xml)3
-rw-r--r--lib/kernel/doc/src/specs.xml.src (renamed from lib/kernel/doc/src/specs.xml)1
-rw-r--r--lib/kernel/src/Makefile4
-rw-r--r--lib/kernel/src/kernel.app.src1
-rw-r--r--lib/kernel/src/net.erl324
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl17
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl11
-rw-r--r--lib/kernel/test/interactive_shell_SUITE.erl60
-rw-r--r--lib/kernel/test/interactive_shell_SUITE_data/.gitignore1
-rw-r--r--lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl6
-rw-r--r--lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl6
-rw-r--r--lib/megaco/test/Makefile5
-rw-r--r--lib/megaco/test/megaco_SUITE.erl32
-rw-r--r--lib/megaco/test/megaco_actions_test.erl46
-rw-r--r--lib/megaco/test/megaco_app_test.erl17
-rw-r--r--lib/megaco/test/megaco_appup_test.erl25
-rw-r--r--lib/megaco/test/megaco_call_flow_test.erl94
-rw-r--r--lib/megaco/test/megaco_codec_test.erl15
-rw-r--r--lib/megaco/test/megaco_codec_test_lib.erl10
-rw-r--r--lib/megaco/test/megaco_config_test.erl99
-rw-r--r--lib/megaco/test/megaco_digit_map_test.erl74
-rw-r--r--lib/megaco/test/megaco_examples_test.erl15
-rw-r--r--lib/megaco/test/megaco_flex_test.erl17
-rw-r--r--lib/megaco/test/megaco_load_test.erl119
-rw-r--r--lib/megaco/test/megaco_mess_test.erl179
-rw-r--r--lib/megaco/test/megaco_mess_user_test.erl16
-rw-r--r--lib/megaco/test/megaco_mib_test.erl35
-rw-r--r--lib/megaco/test/megaco_mreq_test.erl68
-rw-r--r--lib/megaco/test/megaco_pending_limit_test.erl46
-rw-r--r--lib/megaco/test/megaco_segment_test.erl51
-rw-r--r--lib/megaco/test/megaco_tcp_test.erl141
-rw-r--r--lib/megaco/test/megaco_test_deliver.erl4
-rw-r--r--lib/megaco/test/megaco_test_generator.erl54
-rw-r--r--lib/megaco/test/megaco_test_generic_transport.erl20
-rw-r--r--lib/megaco/test/megaco_test_lib.erl44
-rw-r--r--lib/megaco/test/megaco_test_lib.hrl11
-rw-r--r--lib/megaco/test/megaco_test_megaco_generator.erl15
-rw-r--r--lib/megaco/test/megaco_test_mg.erl96
-rw-r--r--lib/megaco/test/megaco_test_mgc.erl103
-rw-r--r--lib/megaco/test/megaco_timer_test.erl4
-rw-r--r--lib/megaco/test/megaco_trans_test.erl35
-rw-r--r--lib/megaco/test/megaco_udp_test.erl17
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap7.xmlsrc2
-rw-r--r--lib/mnesia/src/mnesia_controller.erl81
-rw-r--r--lib/mnesia/src/mnesia_locker.erl2
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl6
-rw-r--r--lib/mnesia/src/mnesia_schema.erl70
-rw-r--r--lib/mnesia/src/mnesia_tm.erl99
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl91
-rwxr-xr-xlib/mnesia/test/mt38
-rw-r--r--lib/observer/src/cdv_bin_cb.erl37
-rw-r--r--lib/observer/src/cdv_html_wx.erl15
-rw-r--r--lib/observer/src/cdv_mod_cb.erl3
-rw-r--r--lib/observer/src/cdv_persistent_cb.erl5
-rw-r--r--lib/observer/src/cdv_proc_cb.erl2
-rw-r--r--lib/observer/src/cdv_term_cb.erl23
-rw-r--r--lib/observer/src/cdv_virtual_list_wx.erl9
-rw-r--r--lib/observer/src/cdv_wx.erl3
-rw-r--r--lib/observer/src/observer_app_wx.erl30
-rw-r--r--lib/observer/src/observer_defs.hrl1
-rw-r--r--lib/observer/src/observer_html_lib.erl76
-rw-r--r--lib/observer/src/observer_lib.erl60
-rw-r--r--lib/observer/src/observer_perf_wx.erl30
-rw-r--r--lib/observer/src/observer_port_wx.erl14
-rw-r--r--lib/observer/src/observer_pro_wx.erl2
-rw-r--r--lib/observer/src/observer_procinfo.erl19
-rw-r--r--lib/observer/src/observer_tv_table.erl5
-rw-r--r--lib/observer/src/observer_tv_wx.erl2
-rw-r--r--lib/observer/test/crashdump_helper.erl6
-rw-r--r--lib/os_mon/c_src/cpu_sup.c2
-rw-r--r--lib/sasl/src/Makefile3
-rw-r--r--lib/sasl/src/systools_make.erl10
-rw-r--r--lib/snmp/Makefile12
-rw-r--r--lib/snmp/doc/src/snmpa_mib_storage.xml6
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl22
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl3
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl10
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl20
-rw-r--r--lib/snmp/src/agent/snmpa_authentication_service.erl45
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl30
-rw-r--r--lib/snmp/src/agent/snmpa_discovery_handler.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_error_report.erl16
-rw-r--r--lib/snmp/src/agent/snmpa_get.erl27
-rw-r--r--lib/snmp/src/agent/snmpa_local_db.erl12
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage.erl6
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage_dets.erl14
-rw-r--r--lib/snmp/src/agent/snmpa_mib_storage_ets.erl9
-rw-r--r--lib/snmp/src/agent/snmpa_network_interface.erl78
-rw-r--r--lib/snmp/src/agent/snmpa_set_mechanism.erl37
-rw-r--r--lib/snmp/src/agent/snmpa_supervisor.erl35
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl2
-rw-r--r--lib/snmp/src/app/snmp.erl26
-rw-r--r--lib/snmp/src/manager/snmpm.erl11
-rw-r--r--lib/snmp/src/manager/snmpm_conf.erl3
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl12
-rw-r--r--lib/snmp/src/manager/snmpm_network_interface.erl74
-rw-r--r--lib/snmp/src/manager/snmpm_supervisor.erl40
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl8
-rw-r--r--lib/snmp/src/misc/snmp_config.erl11
-rw-r--r--lib/snmp/src/misc/snmp_log.erl17
-rw-r--r--lib/snmp/test/Makefile2
-rw-r--r--lib/snmp/test/modules.mk2
-rw-r--r--lib/snmp/test/snmp_agent_test.erl12
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl134
-rw-r--r--lib/snmp/test/snmp_manager_test.erl474
-rw-r--r--lib/snmp/test/snmp_test_global_sys_monitor.erl214
-rw-r--r--lib/snmp/test/snmp_test_lib.erl116
-rw-r--r--lib/snmp/test/snmp_test_lib.hrl11
-rw-r--r--lib/snmp/test/snmp_test_server.erl4
-rw-r--r--lib/snmp/test/snmp_test_sys_monitor.erl86
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl113
-rw-r--r--lib/ssl/doc/src/notes.xml79
-rw-r--r--lib/ssl/doc/src/ssl.xml23
-rw-r--r--lib/ssl/src/dtls_handshake.erl3
-rw-r--r--lib/ssl/src/ssl.erl10
-rw-r--r--lib/ssl/src/ssl_cipher.erl30
-rw-r--r--lib/ssl/src/ssl_connection.erl68
-rw-r--r--lib/ssl/src/ssl_handshake.erl154
-rw-r--r--lib/ssl/src/tls_connection.erl5
-rw-r--r--lib/ssl/src/tls_handshake.erl4
-rw-r--r--lib/ssl/src/tls_handshake_1_3.erl71
-rw-r--r--lib/ssl/src/tls_handshake_1_3.hrl47
-rw-r--r--lib/ssl/src/tls_record.erl23
-rw-r--r--lib/ssl/src/tls_record_1_3.erl9
-rw-r--r--lib/ssl/test/Makefile27
-rw-r--r--lib/ssl/test/openssl_alpn_SUITE.erl421
-rw-r--r--lib/ssl/test/openssl_cipher_suite_SUITE.erl (renamed from lib/ssl/test/openssl_server_cipher_suite_SUITE.erl)43
-rw-r--r--lib/ssl/test/openssl_client_cert_SUITE.erl350
-rw-r--r--lib/ssl/test/openssl_npn_SUITE.erl311
-rw-r--r--lib/ssl/test/openssl_reject_SUITE.erl209
-rw-r--r--lib/ssl/test/openssl_renegotiate_SUITE.erl341
-rw-r--r--lib/ssl/test/openssl_server_cert_SUITE.erl373
-rw-r--r--lib/ssl/test/openssl_session_SUITE.erl262
-rw-r--r--lib/ssl/test/openssl_sni_SUITE.erl251
-rw-r--r--lib/ssl/test/openssl_tls_1_3_version_SUITE.erl172
-rw-r--r--lib/ssl/test/property_test/ssl_eqc_handshake.erl105
-rw-r--r--lib/ssl/test/ssl_ECC_openssl_SUITE.erl3
-rw-r--r--lib/ssl/test/ssl_alert_SUITE.erl100
-rw-r--r--lib/ssl/test/ssl_alpn_SUITE.erl (renamed from lib/ssl/test/ssl_alpn_handshake_SUITE.erl)28
-rw-r--r--lib/ssl/test/ssl_api_SUITE.erl1976
-rw-r--r--lib/ssl/test/ssl_api_SUITE_data/dHParam.pem (renamed from lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem)0
-rw-r--r--lib/ssl/test/ssl_app_env_SUITE.erl171
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl6841
-rw-r--r--lib/ssl/test/ssl_bench_SUITE.erl7
-rw-r--r--lib/ssl/test/ssl_cert_SUITE.erl563
-rw-r--r--lib/ssl/test/ssl_cert_tests.erl386
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl612
-rw-r--r--lib/ssl/test/ssl_cipher_suite_SUITE.erl20
-rw-r--r--lib/ssl/test/ssl_dist_SUITE.erl4
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_npn_SUITE.erl (renamed from lib/ssl/test/ssl_npn_handshake_SUITE.erl)2
-rw-r--r--lib/ssl/test/ssl_npn_hello_SUITE.erl9
-rw-r--r--lib/ssl/test/ssl_pem_cache_SUITE.erl55
-rw-r--r--lib/ssl/test/ssl_renegotiate_SUITE.erl499
-rw-r--r--lib/ssl/test/ssl_session_SUITE.erl377
-rw-r--r--lib/ssl/test/ssl_sni_SUITE.erl68
-rw-r--r--lib/ssl/test/ssl_socket_SUITE.erl437
-rw-r--r--lib/ssl/test/ssl_test_lib.erl396
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl2021
-rw-r--r--lib/ssl/test/tls_1_3_record_SUITE.erl973
-rw-r--r--lib/ssl/test/tls_1_3_version_SUITE.erl153
-rw-r--r--lib/ssl/test/tls_api_SUITE.erl880
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/src/stdlib.app.src2
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl32
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput124
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput24
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput44
-rw-r--r--lib/stdlib/test/re_testoutput1_replacement_test.erl29
-rw-r--r--lib/stdlib/test/re_testoutput1_split_test.erl13779
-rw-r--r--make/otp.mk.in4
-rw-r--r--make/otp_version_tickets_in_merge6
-rw-r--r--otp_versions.table5
-rwxr-xr-xscripts/build-otp2
-rw-r--r--system/COPYRIGHT10
354 files changed, 31540 insertions, 22212 deletions
diff --git a/.travis.yml b/.travis.yml
index 00fe85fc04..51453639b0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,8 @@ sudo: false
os:
- linux
+dist: xenial
+
addons:
apt:
packages:
@@ -12,10 +14,8 @@ addons:
- libncurses-dev
- build-essential
- libssl-dev
- - libwxgtk2.8-dev
- - libgl1-mesa-dev
+ - libwxgtk3.0-dev
- libglu1-mesa-dev
- - libpng3
- default-jdk
- g++
- xsltproc
@@ -64,9 +64,7 @@ matrix:
- build-essential
- libssl-dev
- libwxgtk3.0-dev
- - libgl1-mesa-dev
- libglu1-mesa-dev
- - libpng3
- default-jdk
- g++
- xsltproc
@@ -80,7 +78,7 @@ matrix:
repo: erlang/cd
target-branch: master
skip-cleanup: true
- keep-history: true
+ keep-history: false
verbose: true
github-token: $ERLANG_CD_GITHUB_TOKEN
on:
diff --git a/OTP_VERSION b/OTP_VERSION
index 758704512b..84a941394a 100644
--- a/OTP_VERSION
+++ b/OTP_VERSION
@@ -1 +1 @@
-22.0.4
+22.0.7
diff --git a/bootstrap/bin/no_dot_erlang.boot b/bootstrap/bin/no_dot_erlang.boot
index 1f7f088a77..26cd9e4d5e 100644
--- a/bootstrap/bin/no_dot_erlang.boot
+++ b/bootstrap/bin/no_dot_erlang.boot
Binary files differ
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index 1f7f088a77..26cd9e4d5e 100644
--- a/bootstrap/bin/start.boot
+++ b/bootstrap/bin/start.boot
Binary files differ
diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot
index 1f7f088a77..26cd9e4d5e 100644
--- a/bootstrap/bin/start_clean.boot
+++ b/bootstrap/bin/start_clean.boot
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam
index 07acbb1da7..78b75359a6 100644
--- a/bootstrap/lib/compiler/ebin/beam_asm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_asm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa.beam b/bootstrap/lib/compiler/ebin/beam_ssa.beam
index 9ba124a92d..0327230a58 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_bsm.beam b/bootstrap/lib/compiler/ebin/beam_ssa_bsm.beam
index 50412bc8de..b9bb997cc7 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_bsm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_bsm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_codegen.beam b/bootstrap/lib/compiler/ebin/beam_ssa_codegen.beam
index e59340de4f..cb06630012 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_codegen.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_codegen.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_dead.beam b/bootstrap/lib/compiler/ebin/beam_ssa_dead.beam
index f6bd1b7a69..782073698e 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_dead.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_dead.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_opt.beam b/bootstrap/lib/compiler/ebin/beam_ssa_opt.beam
index c9838883ef..b8588725b4 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_opt.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_opt.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_pre_codegen.beam b/bootstrap/lib/compiler/ebin/beam_ssa_pre_codegen.beam
index 3de363dbb6..e22cb5c846 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_pre_codegen.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_pre_codegen.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_share.beam b/bootstrap/lib/compiler/ebin/beam_ssa_share.beam
index ea8e83d919..d975cebf48 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_share.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_share.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_ssa_type.beam b/bootstrap/lib/compiler/ebin/beam_ssa_type.beam
index c13b25bac3..0403230604 100644
--- a/bootstrap/lib/compiler/ebin/beam_ssa_type.beam
+++ b/bootstrap/lib/compiler/ebin/beam_ssa_type.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam
index 9d0c34a94a..050789f481 100644
--- a/bootstrap/lib/compiler/ebin/beam_validator.beam
+++ b/bootstrap/lib/compiler/ebin/beam_validator.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam
index 57cfc6b932..ebe42547ee 100644
--- a/bootstrap/lib/compiler/ebin/compile.beam
+++ b/bootstrap/lib/compiler/ebin/compile.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app
index c0483e7801..e086da1b68 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -19,7 +19,7 @@
{application, compiler,
[{description, "ERTS CXC 138 10"},
- {vsn, "7.3.2"},
+ {vsn, "7.4.4"},
{modules, [
beam_a,
beam_asm,
diff --git a/bootstrap/lib/compiler/ebin/core_pp.beam b/bootstrap/lib/compiler/ebin/core_pp.beam
index 2423c9b2ea..a2b3167e10 100644
--- a/bootstrap/lib/compiler/ebin/core_pp.beam
+++ b/bootstrap/lib/compiler/ebin/core_pp.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_alias.beam b/bootstrap/lib/compiler/ebin/sys_core_alias.beam
index 622221a8b0..b769b6be41 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_alias.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_alias.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam
index 243b911ac6..3cbbdfd88b 100644
--- a/bootstrap/lib/compiler/ebin/v3_core.beam
+++ b/bootstrap/lib/compiler/ebin/v3_core.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam
index 41e4bd4ab2..204b15fcf2 100644
--- a/bootstrap/lib/kernel/ebin/code.beam
+++ b/bootstrap/lib/kernel/ebin/code.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log_1.beam b/bootstrap/lib/kernel/ebin/disk_log_1.beam
index 17f65d6ceb..0a781001dc 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_1.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_1.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/gen_udp.beam b/bootstrap/lib/kernel/ebin/gen_udp.beam
index f6022dca19..0d6541ee53 100644
--- a/bootstrap/lib/kernel/ebin/gen_udp.beam
+++ b/bootstrap/lib/kernel/ebin/gen_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam
index 396f1166f1..dcec55421c 100644
--- a/bootstrap/lib/kernel/ebin/group.beam
+++ b/bootstrap/lib/kernel/ebin/group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
index 7ff507242b..de7d9c2e57 100644
--- a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
+++ b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam
index b0c67afe90..f64311e166 100644
--- a/bootstrap/lib/kernel/ebin/inet.beam
+++ b/bootstrap/lib/kernel/ebin/inet.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_udp.beam b/bootstrap/lib/kernel/ebin/inet6_udp.beam
index c12c6f4afc..ac4be100e8 100644
--- a/bootstrap/lib/kernel/ebin/inet6_udp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_db.beam b/bootstrap/lib/kernel/ebin/inet_db.beam
index 20d795e75f..a835fa1a74 100644
--- a/bootstrap/lib/kernel/ebin/inet_db.beam
+++ b/bootstrap/lib/kernel/ebin/inet_db.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
index afc4999c42..8166eca5de 100644
--- a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
+++ b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index 84c0169d4b..e8935134b5 100644
--- a/bootstrap/lib/kernel/ebin/inet_parse.beam
+++ b/bootstrap/lib/kernel/ebin/inet_parse.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_udp.beam b/bootstrap/lib/kernel/ebin/inet_udp.beam
index 62156a3284..5853bde54f 100644
--- a/bootstrap/lib/kernel/ebin/inet_udp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index 5ec7c41dbe..cb13db1a89 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -22,7 +22,7 @@
{application, kernel,
[
{description, "ERTS CXC 138 10"},
- {vsn, "6.3.1"},
+ {vsn, "6.4.1"},
{modules, [application,
application_controller,
application_master,
@@ -74,6 +74,7 @@
logger_simple_h,
logger_std_h,
logger_sup,
+ net,
net_adm,
net_kernel,
os,
diff --git a/bootstrap/lib/kernel/ebin/kernel.beam b/bootstrap/lib/kernel/ebin/kernel.beam
index 11be83a49e..2832938d95 100644
--- a/bootstrap/lib/kernel/ebin/kernel.beam
+++ b/bootstrap/lib/kernel/ebin/kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/local_udp.beam b/bootstrap/lib/kernel/ebin/local_udp.beam
index cc5f46f746..33ed76e5cd 100644
--- a/bootstrap/lib/kernel/ebin/local_udp.beam
+++ b/bootstrap/lib/kernel/ebin/local_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/logger_std_h.beam b/bootstrap/lib/kernel/ebin/logger_std_h.beam
index b0f56d9a62..c8eb73a076 100644
--- a/bootstrap/lib/kernel/ebin/logger_std_h.beam
+++ b/bootstrap/lib/kernel/ebin/logger_std_h.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/net.beam b/bootstrap/lib/kernel/ebin/net.beam
new file mode 100644
index 0000000000..44b1f10603
--- /dev/null
+++ b/bootstrap/lib/kernel/ebin/net.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user.beam b/bootstrap/lib/kernel/ebin/user.beam
index f3573d95af..8214d9d6aa 100644
--- a/bootstrap/lib/kernel/ebin/user.beam
+++ b/bootstrap/lib/kernel/ebin/user.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user_drv.beam b/bootstrap/lib/kernel/ebin/user_drv.beam
index 1b59423b71..43df5afa36 100644
--- a/bootstrap/lib/kernel/ebin/user_drv.beam
+++ b/bootstrap/lib/kernel/ebin/user_drv.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index c61132b2de..17e061b1d0 100644
--- a/bootstrap/lib/stdlib/ebin/c.beam
+++ b/bootstrap/lib/stdlib/ebin/c.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam
index 046de3bd5a..f73509ae3f 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v9.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph_utils.beam b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
index 772332cd08..fabe782d90 100644
--- a/bootstrap/lib/stdlib/ebin/digraph_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam
index 90b3858207..5ef1521371 100644
--- a/bootstrap/lib/stdlib/ebin/erl_eval.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index 62838ed771..c73ecdf942 100644
--- a/bootstrap/lib/stdlib/ebin/erl_lint.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam
index 3b30d3e8c7..18538620b7 100644
--- a/bootstrap/lib/stdlib/ebin/erl_scan.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_tar.beam b/bootstrap/lib/stdlib/ebin/erl_tar.beam
index 3c5004871d..871ccd82d4 100644
--- a/bootstrap/lib/stdlib/ebin/erl_tar.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_tar.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam
index b1cf286cea..350316dfcc 100644
--- a/bootstrap/lib/stdlib/ebin/ets.beam
+++ b/bootstrap/lib/stdlib/ebin/ets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
index 57c700cb31..b0f4177d71 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ordsets.beam b/bootstrap/lib/stdlib/ebin/ordsets.beam
index 9e49566404..44f9e5d8b5 100644
--- a/bootstrap/lib/stdlib/ebin/ordsets.beam
+++ b/bootstrap/lib/stdlib/ebin/ordsets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/rand.beam b/bootstrap/lib/stdlib/ebin/rand.beam
index f4d803b1ee..7f1e6140bf 100644
--- a/bootstrap/lib/stdlib/ebin/rand.beam
+++ b/bootstrap/lib/stdlib/ebin/rand.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/re.beam b/bootstrap/lib/stdlib/ebin/re.beam
index 5662594d4c..e16327b906 100644
--- a/bootstrap/lib/stdlib/ebin/re.beam
+++ b/bootstrap/lib/stdlib/ebin/re.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index f64faafa52..3a90a07add 100644
--- a/bootstrap/lib/stdlib/ebin/sofs.beam
+++ b/bootstrap/lib/stdlib/ebin/sofs.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.app b/bootstrap/lib/stdlib/ebin/stdlib.app
index ffb56f8306..41c1f14bbc 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -20,7 +20,7 @@
%%
{application, stdlib,
[{description, "ERTS CXC 138 10"},
- {vsn, "3.8.1"},
+ {vsn, "3.9.2"},
{modules, [array,
base64,
beam_lib,
@@ -108,7 +108,7 @@
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-3.0","kernel-6.0","erts-@OTP-15128@","crypto-3.3",
+ {runtime_dependencies, ["sasl-3.0","kernel-6.0","erts-@OTP-15831:OTP-15836:OTP-15889@","crypto-3.3",
"compiler-5.0"]}
]}.
diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam
index 5d1d66892b..ee19fb41a4 100644
--- a/bootstrap/lib/stdlib/ebin/string.beam
+++ b/bootstrap/lib/stdlib/ebin/string.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index a46ade8602..a3f46b5983 100644
--- a/bootstrap/lib/stdlib/ebin/sys.beam
+++ b/bootstrap/lib/stdlib/ebin/sys.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/uri_string.beam b/bootstrap/lib/stdlib/ebin/uri_string.beam
index b57c84a302..7255fdca63 100644
--- a/bootstrap/lib/stdlib/ebin/uri_string.beam
+++ b/bootstrap/lib/stdlib/ebin/uri_string.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam
index cd6274efe5..75c2289f47 100644
--- a/bootstrap/lib/stdlib/ebin/zip.beam
+++ b/bootstrap/lib/stdlib/ebin/zip.beam
Binary files differ
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile
index bc01919da1..bb96293947 100644
--- a/erts/doc/src/Makefile
+++ b/erts/doc/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2018. All Rights Reserved.
+# Copyright Ericsson AB 1997-2019. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -47,6 +47,20 @@ XML_REF1_FILES = epmd.xml \
run_erl.xml \
start.xml
+ifeq ($(USE_ESOCK), yes)
+XML_REF3_ESOCK_EFILES = socket.xml
+XML_CHAPTER_ESOCK_EFILES = socket_usage.xml
+ESOCK_USE_SOCKET_XML=<xi:include href="socket.xml"\/>
+ESOCK_USE_SOCKET_SPECS_XML=<xi:include href="../specs/specs_socket.xml"/>
+ESOCK_USE_SOCKET_USAGE_XML=<xi:include href="socket_usage.xml"/>
+else
+XML_REF3_ESOCK_EFILES =
+XML_CHAPTER_ESOCK_EFILES =
+ESOCK_USE_SOCKET_XML =
+ESOCK_USE_SOCKET_SPECS_XML =
+ESOCK_USE_SOCKET_USAGE_XML =
+endif
+
XML_REF3_EFILES = \
erl_prim_loader.xml \
erlang.xml \
@@ -56,8 +70,7 @@ XML_REF3_EFILES = \
atomics.xml \
counters.xml \
zlib.xml \
- socket.xml \
- net.xml
+ $(XML_REF3_ESOCK_EFILES)
XML_REF3_FILES = \
$(XML_REF3_EFILES) \
@@ -94,7 +107,7 @@ XML_CHAPTER_FILES = \
driver.xml \
absform.xml \
inet_cfg.xml \
- socket_usage.xml \
+ $(XML_CHAPTER_ESOCK_EFILES) \
erl_ext_dist.xml \
erl_dist_protocol.xml \
communication.xml \
@@ -159,7 +172,7 @@ $(HTMLDIR)/%.gif: %.gif
$(XML_FIGURE_DIR)/%.png: ../../emulator/internal_doc/figures/%.png
$(INSTALL_DATA) $< $@
-docs: figures man pdf html $(INFO_FILE)
+docs: part ref_man specs figures man pdf html $(INFO_FILE)
$(TOP_PDF_FILE): $(XML_FILES)
@@ -169,6 +182,10 @@ html: gifs $(HTML_REF_MAN_FILE)
man: $(MAN1_FILES) $(MAN3_FILES)
+ref_man: ref_man.xml
+part: part.xml
+specs: specs.xml
+
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
$(INFO_FILE): $(INFO_FILE_SRC) $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -196,6 +213,19 @@ $(SPECDIR)/specs_%.xml:
$(XMLDIR)/%.xml: ../../emulator/internal_doc/%.md $(ERL_TOP)/make/emd2exml
$(ERL_TOP)/make/emd2exml $< $@
+ref_man.xml: ref_man.xml.src
+ ($(PERL) -p -e 's?%ESOCK_USE_SOCKET_XML%?$(ESOCK_USE_SOCKET_XML)?' \
+ $<) > $@
+
+part.xml: part.xml.src
+ ($(PERL) -p -e 's?%ESOCK_USE_SOCKET_USAGE_XML%?$(ESOCK_USE_SOCKET_USAGE_XML)?' \
+ $<) > $@
+
+specs.xml: specs.xml.src
+ ($(PERL) -p -e 's?%ESOCK_USE_SOCKET_SPECS_XML%?$(ESOCK_USE_SOCKET_SPECS_XML)?' \
+ $<) > $@
+
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 0e82ceba7d..2183f75487 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2553,6 +2553,7 @@ os_prompt%</pre>
true
> is_map_key(value,Map).
false</code>
+ <p>Allowed in guard tests.</p>
</desc>
</func>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index cfa952f01c..5ca387ffd8 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,54 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 10.4.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An invalid value test caused the socket:setopt(Socket,
+ ip, add_membership, ip_mreq()) to fail with badarg. The
+ same for drop_membership.</p>
+ <p>
+ Own Id: OTP-15908 Aux Id: ERL-980 </p>
+ </item>
+ <item>
+ <p>
+ Fixed bug causing VM crash when doing textual dump of a
+ process containing an unhandled monitor down signal.
+ Textual process dumps can be done with
+ <c>erlang:system_info(procs)</c>, trace feature
+ <c>process_dump</c>, Erlang shell break menu and a
+ crashdump. Bug exist since OTP 21.0.</p>
+ <p>
+ Own Id: OTP-15909 Aux Id: ERL-979 </p>
+ </item>
+ <item>
+ <p><c>lists:subtract/2</c> would produce incorrect
+ results for some inputs on 64-bit platforms.</p>
+ <p>
+ Own Id: OTP-15938 Aux Id: ERL-986 </p>
+ </item>
+ <item>
+ <p>Fixed a bug in the loader that was similar to
+ <c>OTP-15938</c>, yielding incorrect code for some inputs
+ on 64-bit platforms.</p>
+ <p>
+ Own Id: OTP-15939</p>
+ </item>
+ <item>
+ <p>
+ Fixed bug causing scheduler threads in rare cases to
+ block spinnning indefinitely. Bug exists since OTP 21.0.</p>
+ <p>
+ Own Id: OTP-15941 Aux Id: PR-2313 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 10.4.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -592,6 +640,46 @@
</section>
+<section><title>Erts 10.3.5.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed bug causing VM crash when doing textual dump of a
+ process containing an unhandled monitor down signal.
+ Textual process dumps can be done with
+ <c>erlang:system_info(procs)</c>, trace feature
+ <c>process_dump</c>, Erlang shell break menu and a
+ crashdump. Bug exist since OTP 21.0.</p>
+ <p>
+ Own Id: OTP-15909 Aux Id: ERL-979 </p>
+ </item>
+ <item>
+ <p><c>lists:subtract/2</c> would produce incorrect
+ results for some inputs on 64-bit platforms.</p>
+ <p>
+ Own Id: OTP-15938 Aux Id: ERL-986 </p>
+ </item>
+ <item>
+ <p>Fixed a bug in the loader that was similar to
+ <c>OTP-15938</c>, yielding incorrect code for some inputs
+ on 64-bit platforms.</p>
+ <p>
+ Own Id: OTP-15939</p>
+ </item>
+ <item>
+ <p>
+ Fixed bug causing scheduler threads in rare cases to
+ block spinnning indefinitely. Bug exists since OTP 21.0.</p>
+ <p>
+ Own Id: OTP-15941 Aux Id: PR-2313 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 10.3.5.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml.src
index f0b8a00b90..9b20beffad 100644
--- a/erts/doc/src/part.xml
+++ b/erts/doc/src/part.xml.src
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2018</year>
+ <year>1996</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -42,7 +42,7 @@
<xi:include href="tty.xml"/>
<xi:include href="driver.xml"/>
<xi:include href="inet_cfg.xml"/>
- <xi:include href="socket_usage.xml"/>
+ %ESOCK_USE_SOCKET_USAGE_XML%
<xi:include href="erl_ext_dist.xml"/>
<xi:include href="erl_dist_protocol.xml"/>
</part>
diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml.src
index 80cdcf9145..7dd003763c 100644
--- a/erts/doc/src/ref_man.xml
+++ b/erts/doc/src/ref_man.xml.src
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2018</year>
+ <year>1996</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -46,10 +46,9 @@
<xi:include href="erts_alloc.xml"/>
<xi:include href="escript.xml"/>
<xi:include href="init.xml"/>
- <xi:include href="net.xml"/>
<xi:include href="persistent_term.xml"/>
<xi:include href="run_erl.xml"/>
- <xi:include href="socket.xml"/>
+ %ESOCK_USE_SOCKET_XML%
<xi:include href="start.xml"/>
<xi:include href="start_erl.xml"/>
<xi:include href="werl.xml"/>
diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml
index b4e22e86a8..2f7ff2fc07 100644
--- a/erts/doc/src/socket.xml
+++ b/erts/doc/src/socket.xml
@@ -47,14 +47,16 @@
<seealso marker="#recv_async"><c>recv/3</c></seealso>
function with Timeout set to <c>nowait</c> (<c>recv(Sock, 0, nowait)</c>)
when there is actually nothing to read, it will return with
- <c>{ok, </c>
- <seealso marker="#type-select_info"><c>SelectInfo</c></seealso><c>}</c>.
+ <c>{select, </c>
+ <seealso marker="#type-select_info"><c>SelectInfo</c></seealso><c>}</c>
+ (<c>SelectInfo</c> contains the
+ <seealso marker="socket#type-select_ref">SelectRef</seealso>).
When data eventually arrives a 'select' message
will be sent to the caller: </p>
<taglist>
<!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL -->
<tag></tag>
- <item><c>{'$socket', socket(), select, select_ref()}</c></item>
+ <item><c>{'$socket', socket(), select, SelectRef}</c></item>
</taglist>
<p>The caller can now make another
call to the recv function and now expect data.</p>
@@ -70,7 +72,7 @@
<p>This message indicates
that the (asynchronous) operation has been aborted.
If, for instance, the socket has been closed (by another process),
- <c>Info</c> will be <c>{select_ref(), closed}</c>. </p>
+ <c>Info</c> will be <c>{SelectRef, closed}</c>. </p>
</note>
<note>
<p>There is currently <em>no</em> support for Windows. </p>
@@ -112,6 +114,15 @@
<name name="select_info"/>
</datatype>
<datatype>
+ <name name="socket_counters"/>
+ </datatype>
+ <datatype>
+ <name name="socket_counter"/>
+ </datatype>
+ <datatype>
+ <name name="socket_info"/>
+ </datatype>
+ <datatype>
<name name="ip4_address"/>
</datatype>
<datatype>
@@ -329,7 +340,9 @@
<p>In the case when there is no connections waiting, the function
will return with the <c>SelectInfo</c>. The caller can then await a
select message, <c>{'$socket', Socket, select, Info}</c> (where
- <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>),
+ <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the <c>SelectInfo</c>),
when a client connects (a subsequent call to accept will then return
the socket). </p>
</desc>
@@ -401,7 +414,9 @@
<seealso marker="#type-select_info"><c>SelectInfo</c></seealso>.
The caller can then await a
select message, <c>{'$socket', Socket, select, Info}</c> (where
- <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>,
+ <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the <c>SelectInfo</c>,
a subsequent call to connect will then
establish the connection). </p>
</desc>
@@ -456,6 +471,20 @@
</func>
<func>
+ <name name="info" arity="1" since="OTP @OTP-15818@"/>
+ <fsummary>Get miscellaneous socket info.</fsummary>
+ <desc>
+ <p>Get miscellaneous info about the socket.</p>
+ <p>The function returns a map with each info item as a key-value
+ binding. It reflects the "current" state of the socket. </p>
+ <note>
+ <p>In order to ensure data integrity, mutex'es are taken when
+ needed. So, do not call this function often. </p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
<name name="listen" arity="1" since="OTP 22.0"/>
<name name="listen" arity="2" since="OTP 22.0"/>
<fsummary>Listen for connections on a socket.</fsummary>
@@ -528,7 +557,9 @@
<p>In the case when there is no data waiting, the function
will return with the <c>SelectInfo</c>. The caller can then await a
select message, <c>{'$socket', Socket, select, Info}</c> (where
- <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>),
+ <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the <c>SelectInfo</c>),
when data has arrived (a subsequent call to recv will then return
the data). </p>
<p>Note that if a length (<c>> 0</c>) is specified, and only part
@@ -587,7 +618,9 @@
<p>In the case when there is no data waiting, the function
will return with the <c>SelectInfo</c>. The caller can then await a
select message, <c>{'$socket', Socket, select, Info}</c> (where
- <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>),
+ <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the <c>SelectInfo</c>),
when data has arrived (a subsequent call to recvfrom will then return
the data). </p>
</desc>
@@ -663,7 +696,9 @@
<p>In the case when there is no data waiting, the function
will return with the <c>SelectInfo</c>. The caller can then await a
select message, <c>{'$socket', Socket, select, Info}</c> (where
- <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>),
+ <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the <c>SelectInfo</c>),
when data has arrived (a subsequent call to recvmsg will then return
the data). </p>
</desc>
@@ -691,7 +726,9 @@
the function will return with the <c>SelectInfo</c>. The caller
can then await a select message,
<c>{'$socket', Socket, select, Info}</c>
- (where <c>Info</c> is the <c>select_ref()</c> from the
+ (where <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the
<c>SelectInfo</c>), when there is room for more data (a subsequent
call to send will then send the data). </p>
<p>Note that if not all the data was sent, the function will return
@@ -749,7 +786,9 @@
the function will return with the <c>SelectInfo</c>. The caller
can then await a select message,
<c>{'$socket', Socket, select, Info}</c>
- (where <c>Info</c> is the <c>select_ref()</c> from the
+ (where <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the
<c>SelectInfo</c>), when there is room for more data (a subsequent
call to sendmsg will then send the data). </p>
</desc>
@@ -777,7 +816,9 @@
the function will return with the <c>SelectInfo</c>. The caller
can then await a select message,
<c>{'$socket', Socket, select, Info}</c>
- (where <c>Info</c> is the <c>select_ref()</c> from the
+ (where <c>Info</c> is the
+ <seealso marker="socket#type-select_ref"><c>ref</c></seealso>
+ field from the
<c>SelectInfo</c>), when there is room for more data (a subsequent
call to sendto will then send the data). </p>
</desc>
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index 7e65bcbf70..c3cda9a615 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -56,23 +56,20 @@
function with Timeout set to <c>nowait</c> (i.e.
<c>recv(Sock, 0, nowait)</c>)
when there is actually nothing to read, it will return with
- <c>{ok, </c>
- <seealso marker="socket#type-select_info"><c>SelectInfo</c></seealso><c>}</c>.
+ <c>{select, </c>
+ <seealso marker="socket#type-select_info"><c>SelectInfo</c></seealso><c>}</c>
+ (<c>SelectInfo</c> contains the
+ <seealso marker="socket#type-select_ref">SelectRef</seealso>).
When data eventually arrives a 'select message'
will be sent to the caller:</p>
<taglist>
<!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL -->
<tag></tag>
- <item><c>{'$socket', socket(), select, select_ref()}</c></item>
+ <item><c>{'$socket', socket(), select, SelectRef}</c></item>
</taglist>
<p>The caller can then make another
call to the recv function and now expect data.</p>
<p>The user must also be prepared to receive an abort message: </p>
- <!--
- <list type="ordered">
- <item><c>{'$socket', Sock, abort, Info}</c></item>
- </list>
- -->
<taglist>
<!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL -->
<tag></tag>
@@ -81,7 +78,7 @@
<p>If the operation is aborted
for whatever reason (e.g. if the socket is closed "by someone else").
The <c>Info</c> part contains the abort reason (in this case that
- the socket has been closed <c>Info = {select_ref(), closed}</c>). </p>
+ the socket has been closed <c>Info = {SelectRef, closed}</c>). </p>
<p>Note that all other users are <em>locked out</em> until the
'current user' has called the function (recv in this case). So either
immediately call the function or
@@ -197,7 +194,7 @@
<cell><em>Other Requirements and comments</em></cell>
</row>
<row>
- <cell>acceptcon</cell>
+ <cell>acceptconn</cell>
<cell>boolean()</cell>
<cell>no</cell>
<cell>yes</cell>
@@ -208,7 +205,9 @@
<cell>string()</cell>
<cell>yes</cell>
<cell>yes</cell>
- <cell>none</cell>
+ <cell>Before Linux 3.8, this socket option could be set, but not get.
+ Only works for some socket types (e.g. <c>inet</c>).
+ If empty value is set, the binding is removed.</cell>
</row>
<row>
<cell>broadcast</cell>
@@ -222,7 +221,7 @@
<cell>integer()</cell>
<cell>yes</cell>
<cell>yes</cell>
- <cell>requires admin capability</cell>
+ <cell>may require admin capability</cell>
</row>
<row>
<cell>domain</cell>
diff --git a/erts/doc/src/specs.xml b/erts/doc/src/specs.xml.src
index 68fab5edf1..54224c15f5 100644
--- a/erts/doc/src/specs.xml
+++ b/erts/doc/src/specs.xml.src
@@ -5,8 +5,7 @@
<xi:include href="../specs/specs_erl_tracer.xml"/>
<xi:include href="../specs/specs_init.xml"/>
<xi:include href="../specs/specs_persistent_term.xml"/>
- <xi:include href="../specs/specs_socket.xml"/>
- <xi:include href="../specs/specs_net.xml"/>
+ %ESOCK_USE_SOCKET_SPECS_XML%
<xi:include href="../specs/specs_zlib.xml"/>
<xi:include href="../specs/specs_atomics.xml"/>
<xi:include href="../specs/specs_counters.xml"/>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index a9f3bb8e89..ba5ba8abef 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -636,10 +636,9 @@ GENERATE += $(TTF_DIR)/driver_tab.c
ifeq ($(USE_ESOCK), yes)
ESOCK_PRELOAD_BEAM = \
$(ERL_TOP)/erts/preloaded/ebin/socket.beam \
- $(ERL_TOP)/erts/preloaded/ebin/net.beam
+ $(ERL_TOP)/erts/preloaded/ebin/prim_net.beam
else
-ESOCK_PRELOAD_BEAM = \
- $(ERL_TOP)/erts/preloaded/ebin/net.beam
+ESOCK_PRELOAD_BEAM =
endif
PRELOAD_BEAM = $(ERL_TOP)/erts/preloaded/ebin/erts_code_purger.beam \
@@ -850,7 +849,7 @@ ifeq ($(USE_ESOCK), yes)
ESOCK_NIF_OBJS = \
$(OBJDIR)/socket_nif.o \
- $(OBJDIR)/net_nif.o
+ $(OBJDIR)/prim_net_nif.o
ifneq ($(TARGET), win32)
# These are *currently* only needed for non-win32,
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index bb1b2e5b27..4c8ee5178a 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -1799,6 +1799,78 @@ erts_queue_release_literals(Process* c_p, ErtsLiteralArea* literals)
}
}
+struct debug_la_oh {
+ void (*func)(ErlOffHeap *, void *);
+ void *arg;
+};
+
+static void debug_later_cleanup_literal_area_off_heap(void *vfap,
+ ErtsThrPrgrVal val,
+ void *vlrlap)
+{
+ struct debug_la_oh *fap = vfap;
+ ErtsLaterReleasLiteralArea *lrlap = vlrlap;
+ ErtsLiteralArea *lap = lrlap->la;
+ if (!erts_debug_have_accessed_literal_area(lap)) {
+ ErlOffHeap oh;
+ ERTS_INIT_OFF_HEAP(&oh);
+ oh.first = lap->off_heap;
+ (*fap->func)(&oh, fap->arg);
+ erts_debug_save_accessed_literal_area(lap);
+ }
+}
+
+static void debug_later_complete_literal_area_switch_off_heap(void *vfap,
+ ErtsThrPrgrVal val,
+ void *vlap)
+{
+ struct debug_la_oh *fap = vfap;
+ ErtsLiteralArea *lap = vlap;
+ if (lap && !erts_debug_have_accessed_literal_area(lap)) {
+ ErlOffHeap oh;
+ ERTS_INIT_OFF_HEAP(&oh);
+ oh.first = lap->off_heap;
+ (*fap->func)(&oh, fap->arg);
+ erts_debug_save_accessed_literal_area(lap);
+ }
+}
+
+
+void
+erts_debug_foreach_release_literal_area_off_heap(void (*func)(ErlOffHeap *, void *), void *arg)
+{
+ ErtsLiteralArea *lap;
+ ErlOffHeap oh;
+ ErtsLiteralAreaRef *ref;
+ struct debug_la_oh fa;
+ erts_mtx_lock(&release_literal_areas.mtx);
+ for (ref = release_literal_areas.first; ref; ref = ref->next) {
+ lap = ref->literal_area;
+ if (!erts_debug_have_accessed_literal_area(lap)) {
+ ERTS_INIT_OFF_HEAP(&oh);
+ oh.first = lap->off_heap;
+ (*func)(&oh, arg);
+ erts_debug_save_accessed_literal_area(lap);
+ }
+ }
+ erts_mtx_unlock(&release_literal_areas.mtx);
+ lap = ERTS_COPY_LITERAL_AREA();
+ if (lap && !erts_debug_have_accessed_literal_area(lap)) {
+ ERTS_INIT_OFF_HEAP(&oh);
+ oh.first = lap->off_heap;
+ (*func)(&oh, arg);
+ erts_debug_save_accessed_literal_area(lap);
+ }
+ fa.func = func;
+ fa.arg = arg;
+ erts_debug_later_op_foreach(later_release_literal_area,
+ debug_later_cleanup_literal_area_off_heap,
+ (void *) &fa);
+ erts_debug_later_op_foreach(complete_literal_area_switch,
+ debug_later_complete_literal_area_switch_off_heap,
+ (void *) &fa);
+}
+
/*
* Move code from current to old and null all export entries for the module
*/
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index a18228b84a..4ddf59092a 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -1153,51 +1153,47 @@ BIF_RETTYPE list_to_bitstring_1(BIF_ALIST_1)
BIF_RETTYPE split_binary_2(BIF_ALIST_2)
{
- Uint pos;
- ErlSubBin* sb1;
- ErlSubBin* sb2;
- size_t orig_size;
- Eterm orig;
- Uint offset;
- Uint bit_offset;
- Uint bit_size;
- Eterm* hp;
+ size_t orig_size, left_size, right_size;
+ Uint byte_offset, bit_offset, bit_size;
+ Uint split_at;
+
+ Eterm *hp, *hp_end;
+ Eterm left, right;
+ Eterm real_bin;
+ Eterm result;
+ byte *bptr;
if (is_not_binary(BIF_ARG_1)) {
- goto error;
- }
- if (!term_to_Uint(BIF_ARG_2, &pos)) {
- goto error;
- }
- if ((orig_size = binary_size(BIF_ARG_1)) < pos) {
- goto error;
+ BIF_ERROR(BIF_P, BADARG);
+ } else if (!term_to_Uint(BIF_ARG_2, &split_at)) {
+ BIF_ERROR(BIF_P, BADARG);
+ } else if ((orig_size = binary_size(BIF_ARG_1)) < split_at) {
+ BIF_ERROR(BIF_P, BADARG);
}
- hp = HAlloc(BIF_P, 2*ERL_SUB_BIN_SIZE+3);
- ERTS_GET_REAL_BIN(BIF_ARG_1, orig, offset, bit_offset, bit_size);
- sb1 = (ErlSubBin *) hp;
- sb1->thing_word = HEADER_SUB_BIN;
- sb1->size = pos;
- sb1->offs = offset;
- sb1->orig = orig;
- sb1->bitoffs = bit_offset;
- sb1->bitsize = 0;
- sb1->is_writable = 0;
- hp += ERL_SUB_BIN_SIZE;
-
- sb2 = (ErlSubBin *) hp;
- sb2->thing_word = HEADER_SUB_BIN;
- sb2->size = orig_size - pos;
- sb2->offs = offset + pos;
- sb2->orig = orig;
- sb2->bitoffs = bit_offset;
- sb2->bitsize = bit_size; /* The extra bits go into the second binary. */
- sb2->is_writable = 0;
- hp += ERL_SUB_BIN_SIZE;
-
- return TUPLE2(hp, make_binary(sb1), make_binary(sb2));
-
- error:
- BIF_ERROR(BIF_P, BADARG);
+
+ left_size = split_at;
+ right_size = orig_size - split_at;
+
+ ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, byte_offset, bit_offset, bit_size);
+ bptr = binary_bytes(real_bin);
+
+ hp = HAlloc(BIF_P, EXTRACT_SUB_BIN_HEAP_NEED * 2 + 3);
+ hp_end = hp + (EXTRACT_SUB_BIN_HEAP_NEED * 2 + 3);
+
+ left = erts_extract_sub_binary(&hp, real_bin, bptr,
+ byte_offset * 8 + bit_offset,
+ left_size * 8);
+
+ right = erts_extract_sub_binary(&hp, real_bin, bptr,
+ (byte_offset + split_at) * 8 + bit_offset,
+ right_size * 8 + bit_size);
+
+ result = TUPLE2(hp, left, right);
+ hp += 3;
+
+ HRelease(BIF_P, hp_end, hp);
+
+ return result;
}
diff --git a/erts/emulator/beam/bs_instrs.tab b/erts/emulator/beam/bs_instrs.tab
index bd1ad91e45..5f25bc2ad3 100644
--- a/erts/emulator/beam/bs_instrs.tab
+++ b/erts/emulator/beam/bs_instrs.tab
@@ -149,7 +149,7 @@ i_bs_get_binary_all2.execute(Fail, Live, Unit, Dst) {
ErlBinMatchBuffer *_mb;
Eterm _result;
- $GC_TEST_PRESERVE(ERL_SUB_BIN_SIZE, $Live, context);
+ $GC_TEST_PRESERVE(EXTRACT_SUB_BIN_HEAP_NEED, $Live, context);
_mb = ms_matchbuffer(context);
if (((_mb->size - _mb->offset) % $Unit) == 0) {
LIGHT_SWAPOUT;
@@ -179,7 +179,7 @@ i_bs_get_binary2.execute(Fail, Live, Sz, Flags, Dst) {
Eterm _result;
Uint _size;
$BS_GET_FIELD_SIZE($Sz, (($Flags) >> 3), $FAIL($Fail), _size);
- $GC_TEST_PRESERVE(ERL_SUB_BIN_SIZE, $Live, context);
+ $GC_TEST_PRESERVE(EXTRACT_SUB_BIN_HEAP_NEED, $Live, context);
_mb = ms_matchbuffer(context);
LIGHT_SWAPOUT;
_result = erts_bs_get_binary_2(c_p, _size, $Flags, _mb);
@@ -206,8 +206,7 @@ i_bs_get_binary_imm2.fetch(Ctx) {
i_bs_get_binary_imm2.execute(Fail, Live, Sz, Flags, Dst) {
ErlBinMatchBuffer *_mb;
Eterm _result;
- $GC_TEST_PRESERVE(heap_bin_size(ERL_ONHEAP_BIN_LIMIT),
- $Live, context);
+ $GC_TEST_PRESERVE(EXTRACT_SUB_BIN_HEAP_NEED, $Live, context);
_mb = ms_matchbuffer(context);
LIGHT_SWAPOUT;
_result = erts_bs_get_binary_2(c_p, $Sz, $Flags, _mb);
@@ -876,9 +875,7 @@ bs_start_match.execute(Fail, Live, Slots, Dst) {
result = erts_bs_start_match_2(c_p, context, slots);
HTOP = HEAP_TOP(c_p);
HEAP_SPACE_VERIFIED(0);
- if (is_non_value(result)) {
- $FAIL($Fail);
- }
+
$REFRESH_GEN_DEST();
$Dst = result;
} else {
@@ -1296,10 +1293,6 @@ i_bs_start_match3_gp.execute(Live, Fail, Dst, Pos) {
HTOP = HEAP_TOP(c_p);
HEAP_SPACE_VERIFIED(0);
- if (ms == NULL) {
- $FAIL($Fail);
- }
-
$REFRESH_GEN_DEST();
$Dst = make_matchstate(ms);
position = ms->mb.offset;
@@ -1348,10 +1341,6 @@ i_bs_start_match3.execute(Live, Fail, Dst) {
HTOP = HEAP_TOP(c_p);
HEAP_SPACE_VERIFIED(0);
- if (ms == NULL) {
- $FAIL($Fail);
- }
-
$REFRESH_GEN_DEST();
$Dst = make_matchstate(ms);
} else {
@@ -1523,10 +1512,6 @@ i_bs_start_match3.execute(Live, Fail, Dst) {
HTOP = HEAP_TOP(c_p);
HEAP_SPACE_VERIFIED(0);
- if (is_non_value(result)) {
- $FAIL($Fail);
- }
-
$REFRESH_GEN_DEST();
$Dst = result;
} else {
diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c
index db74b06cc5..9bbcba6f3b 100644
--- a/erts/emulator/beam/copy.c
+++ b/erts/emulator/beam/copy.c
@@ -604,7 +604,12 @@ cleanup:
/*
* Copy a structure to a heap.
*/
-Eterm copy_struct_x(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap, Uint *bsz, erts_literal_area_t *litopt)
+Eterm copy_struct_x(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap,
+ Uint *bsz, erts_literal_area_t *litopt
+#ifdef ERTS_COPY_REGISTER_LOCATION
+ , char *file, int line
+#endif
+ )
{
char* hstart;
Uint hsize;
@@ -854,7 +859,11 @@ Eterm copy_struct_x(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap, Uint
case EXTERNAL_REF_SUBTAG:
{
ExternalThing *etp = (ExternalThing *) objp;
+#if defined(ERTS_COPY_REGISTER_LOCATION) && defined(ERL_NODE_BOOKKEEP)
+ erts_ref_node_entry__(etp->node, 2, make_boxed(htop), file, line);
+#else
erts_ref_node_entry(etp->node, 2, make_boxed(htop));
+#endif
}
L_off_heap_node_container_common:
{
@@ -1326,8 +1335,13 @@ Uint copy_shared_calculate(Eterm obj, erts_shcopy_t *info)
* Copy object "obj" preserving sharing.
* Second half: copy and restore the object.
*/
-Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info,
- Eterm** hpp, ErlOffHeap* off_heap) {
+Uint copy_shared_perform_x(Eterm obj, Uint size, erts_shcopy_t *info,
+ Eterm** hpp, ErlOffHeap* off_heap
+#ifdef ERTS_COPY_REGISTER_LOCATION
+ , char *file, int line
+#endif
+ )
+{
Uint e;
unsigned sz;
Eterm* ptr;
@@ -1393,7 +1407,11 @@ Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info,
*resp = obj;
} else {
Uint bsz = 0;
- *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL); /* copy literal */
+ *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL
+#ifdef ERTS_COPY_REGISTER_LOCATION
+ , file, line
+#endif
+ ); /* copy literal */
hbot -= bsz;
}
goto cleanup_next;
@@ -1461,7 +1479,11 @@ Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info,
*resp = obj;
} else {
Uint bsz = 0;
- *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL); /* copy literal */
+ *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL
+#ifdef ERTS_COPY_REGISTER_LOCATION
+ , file, line
+#endif
+ ); /* copy literal */
hbot -= bsz;
}
goto cleanup_next;
@@ -1660,7 +1682,12 @@ Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info,
case EXTERNAL_REF_SUBTAG:
{
ExternalThing *etp = (ExternalThing *) ptr;
+
+#if defined(ERTS_COPY_REGISTER_LOCATION) && defined(ERL_NODE_BOOKKEEP)
+ erts_ref_node_entry__(etp->node, 2, make_boxed(hp), file, line);
+#else
erts_ref_node_entry(etp->node, 2, make_boxed(hp));
+#endif
}
off_heap_node_container_common:
{
@@ -1823,8 +1850,12 @@ all_clean:
*
* NOTE: Assumes that term is a tuple (ptr is an untagged tuple ptr).
*/
-Eterm copy_shallow(Eterm* ERTS_RESTRICT ptr, Uint sz, Eterm** hpp,
- ErlOffHeap* off_heap)
+Eterm
+copy_shallow_x(Eterm* ERTS_RESTRICT ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap
+#ifdef ERTS_COPY_REGISTER_LOCATION
+ , char *file, int line
+#endif
+ )
{
Eterm* tp = ptr;
Eterm* hp = *hpp;
@@ -1866,7 +1897,11 @@ Eterm copy_shallow(Eterm* ERTS_RESTRICT ptr, Uint sz, Eterm** hpp,
case EXTERNAL_REF_SUBTAG:
{
ExternalThing* etp = (ExternalThing *) (tp-1);
+#if defined(ERTS_COPY_REGISTER_LOCATION) && defined(ERL_NODE_BOOKKEEP)
+ erts_ref_node_entry__(etp->node, 2, make_boxed(hp-1), file, line);
+#else
erts_ref_node_entry(etp->node, 2, make_boxed(hp-1));
+#endif
}
off_heap_common:
{
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 4537e3e569..eb9e749a08 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1266,18 +1266,6 @@ erts_dsig_send_group_leader(ErtsDSigSendContext *ctx, Eterm leader, Eterm remote
return dsig_send_ctl(ctx, ctl);
}
-struct dist_sequences {
- ErlHeapFragment hfrag;
- struct dist_sequences *parent;
- struct dist_sequences *left;
- struct dist_sequences *right;
- char is_red;
-
- Uint64 seq_id;
- int cnt;
- Sint ctl_len;
-};
-
#define ERTS_RBT_PREFIX dist_seq
#define ERTS_RBT_T DistSeqNode
#define ERTS_RBT_KEY_T Uint
@@ -1312,25 +1300,25 @@ struct dist_sequences {
#include "erl_rbtree.h"
-struct erts_dist_seq_tree_foreach_iter_arg {
- int (*func)(ErtsDistExternal *, void *, Sint);
+struct erts_debug_dist_seq_tree_foreach_iter_arg {
+ int (*func)(DistSeqNode *, void *, Sint);
void *arg;
};
static int
-erts_dist_seq_tree_foreach_iter(DistSeqNode *seq, void *arg, Sint reds)
+erts_debug_dist_seq_tree_foreach_iter(DistSeqNode *seq, void *arg, Sint reds)
{
- struct erts_dist_seq_tree_foreach_iter_arg *state = arg;
- return state->func(erts_get_dist_ext(&seq->hfrag), state->arg, reds);
+ struct erts_debug_dist_seq_tree_foreach_iter_arg *state = arg;
+ return state->func(seq, state->arg, reds);
}
void
-erts_dist_seq_tree_foreach(DistEntry *dep, int (*func)(ErtsDistExternal *, void *, Sint), void *arg)
+erts_debug_dist_seq_tree_foreach(DistEntry *dep, int (*func)(DistSeqNode *, void *, Sint), void *arg)
{
- struct erts_dist_seq_tree_foreach_iter_arg state;
+ struct erts_debug_dist_seq_tree_foreach_iter_arg state;
state.func = func;
state.arg = arg;
- dist_seq_rbt_foreach(dep->sequences, erts_dist_seq_tree_foreach_iter, &state);
+ dist_seq_rbt_foreach(dep->sequences, erts_debug_dist_seq_tree_foreach_iter, &state);
}
static int dist_seq_cleanup(DistSeqNode *seq, void *unused, Sint reds)
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index 067028634b..a33fb7efcf 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -274,6 +274,18 @@ typedef struct erts_dsig_send_context {
typedef struct dist_sequences DistSeqNode;
+struct dist_sequences {
+ ErlHeapFragment hfrag;
+ struct dist_sequences *parent;
+ struct dist_sequences *left;
+ struct dist_sequences *right;
+ char is_red;
+
+ Uint64 seq_id;
+ int cnt;
+ Sint ctl_len;
+};
+
/*
* erts_dsig_send_* return values.
*/
@@ -306,9 +318,9 @@ extern Uint erts_dist_cache_size(void);
extern Sint erts_abort_connection_rwunlock(DistEntry *dep);
-extern void erts_dist_seq_tree_foreach(
+extern void erts_debug_dist_seq_tree_foreach(
DistEntry *dep,
- int (*func)(ErtsDistExternal *, void*, Sint), void *args);
+ int (*func)(DistSeqNode *, void*, Sint), void *args);
extern int erts_dsig_prepare(ErtsDSigSendContext *,
DistEntry*,
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index 92e5069c71..21941ba96e 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -149,6 +149,7 @@ type MODULE_TABLE LONG_LIVED CODE module_tab
type TAINT LONG_LIVED CODE taint_list
type MODULE_REFS STANDARD CODE module_refs
type NC_TMP TEMPORARY SYSTEM nc_tmp
+type NC_STD STANDARD SYSTEM nc_std
type TMP TEMPORARY SYSTEM tmp
type UNDEF SYSTEM SYSTEM undefined
type DCACHE STANDARD SYSTEM dcache
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 25ac3bc5af..bfc2f5992c 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -7112,12 +7112,21 @@ static int blockscan_cpool_yielding(blockscan_t *state)
return 0;
}
-static int blockscan_yield_helper(blockscan_t *state,
- int (*yielding_op)(blockscan_t*))
+/* */
+
+static int blockscan_finish(blockscan_t *state)
{
- /* Note that we don't check whether to abort here; only yielding_op knows
- * whether the carrier is still in the list/pool. */
+ if (ERTS_PROC_IS_EXITING(state->process)) {
+ state->abort(state->user_data);
+ return 0;
+ }
+ state->current_op = blockscan_finish;
+
+ return state->finish(state->user_data);
+}
+
+static void blockscan_lock_helper(blockscan_t *state) {
if ((state->allocator)->thread_safe) {
/* Locked scans have to be as short as possible. */
state->reductions = 1;
@@ -7126,34 +7135,18 @@ static int blockscan_yield_helper(blockscan_t *state,
} else {
state->reductions = BLOCKSCAN_REDUCTIONS;
}
+}
- if (yielding_op(state)) {
- state->next_op = state->current_op;
- }
-
+static void blockscan_unlock_helper(blockscan_t *state) {
if ((state->allocator)->thread_safe) {
erts_mtx_unlock(&(state->allocator)->mutex);
}
-
- return 1;
-}
-
-/* */
-
-static int blockscan_finish(blockscan_t *state)
-{
- if (ERTS_PROC_IS_EXITING(state->process)) {
- state->abort(state->user_data);
- return 0;
- }
-
- state->current_op = blockscan_finish;
-
- return state->finish(state->user_data);
}
static int blockscan_sweep_sbcs(blockscan_t *state)
{
+ blockscan_lock_helper(state);
+
if (state->current_op != blockscan_sweep_sbcs) {
SET_CARRIER_HDR(&state->dummy_carrier, 0, SCH_SBC, state->allocator);
state->current_clist = &(state->allocator)->sbc_list;
@@ -7163,11 +7156,19 @@ static int blockscan_sweep_sbcs(blockscan_t *state)
state->current_op = blockscan_sweep_sbcs;
state->next_op = blockscan_finish;
- return blockscan_yield_helper(state, blockscan_clist_yielding);
+ if (blockscan_clist_yielding(state)) {
+ state->next_op = state->current_op;
+ }
+
+ blockscan_unlock_helper(state);
+
+ return 1;
}
static int blockscan_sweep_mbcs(blockscan_t *state)
{
+ blockscan_lock_helper(state);
+
if (state->current_op != blockscan_sweep_mbcs) {
SET_CARRIER_HDR(&state->dummy_carrier, 0, SCH_MBC, state->allocator);
state->current_clist = &(state->allocator)->mbc_list;
@@ -7177,11 +7178,19 @@ static int blockscan_sweep_mbcs(blockscan_t *state)
state->current_op = blockscan_sweep_mbcs;
state->next_op = blockscan_sweep_sbcs;
- return blockscan_yield_helper(state, blockscan_clist_yielding);
+ if (blockscan_clist_yielding(state)) {
+ state->next_op = state->current_op;
+ }
+
+ blockscan_unlock_helper(state);
+
+ return 1;
}
static int blockscan_sweep_cpool(blockscan_t *state)
{
+ blockscan_lock_helper(state);
+
if (state->current_op != blockscan_sweep_cpool) {
SET_CARRIER_HDR(&state->dummy_carrier, 0, SCH_MBC, state->allocator);
state->cpool_cursor = (state->allocator)->cpool.sentinel;
@@ -7190,7 +7199,13 @@ static int blockscan_sweep_cpool(blockscan_t *state)
state->current_op = blockscan_sweep_cpool;
state->next_op = blockscan_sweep_mbcs;
- return blockscan_yield_helper(state, blockscan_cpool_yielding);
+ if (blockscan_cpool_yielding(state)) {
+ state->next_op = state->current_op;
+ }
+
+ blockscan_unlock_helper(state);
+
+ return 1;
}
static int blockscan_get_specific_allocator(int allocator_num,
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index 4d6d31cd76..b8e56390c1 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -1750,9 +1750,8 @@ static Eterm do_split_single_result(Process *p, Eterm subject, BinaryFindContext
Uint offset;
Uint bit_offset;
Uint bit_size;
- ErlSubBin *sb1;
- ErlSubBin *sb2;
- Eterm *hp;
+ Uint hp_need;
+ Eterm *hp, *hp_end;
Eterm ret;
pos = ff->pos;
@@ -1765,57 +1764,58 @@ static Eterm do_split_single_result(Process *p, Eterm subject, BinaryFindContext
if (pos == 0) {
ret = NIL;
} else {
- hp = HAlloc(p, (ERL_SUB_BIN_SIZE + 2));
+ Eterm extracted;
+
+ hp_need = EXTRACT_SUB_BIN_HEAP_NEED + 2;
+
+ hp = HAlloc(p, hp_need);
+ hp_end = hp + hp_need;
+
ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size);
- sb1 = (ErlSubBin *) hp;
- sb1->thing_word = HEADER_SUB_BIN;
- sb1->size = pos;
- sb1->offs = offset;
- sb1->orig = orig;
- sb1->bitoffs = bit_offset;
- sb1->bitsize = bit_size;
- sb1->is_writable = 0;
- hp += ERL_SUB_BIN_SIZE;
-
- ret = CONS(hp, make_binary(sb1), NIL);
+ extracted = erts_extract_sub_binary(&hp, orig, binary_bytes(orig),
+ offset * 8 + bit_offset,
+ pos * 8 + bit_size);
+
+ ret = CONS(hp, extracted, NIL);
hp += 2;
+
+ HRelease(p, hp_end, hp);
+
+ return ret;
}
} else {
- if ((ctx->flags & BF_FLAG_SPLIT_TRIM_ALL) && (pos == 0)) {
- hp = HAlloc(p, 1 * (ERL_SUB_BIN_SIZE + 2));
- ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size);
- sb1 = NULL;
- } else {
- hp = HAlloc(p, 2 * (ERL_SUB_BIN_SIZE + 2));
- ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size);
- sb1 = (ErlSubBin *) hp;
- sb1->thing_word = HEADER_SUB_BIN;
- sb1->size = pos;
- sb1->offs = offset;
- sb1->orig = orig;
- sb1->bitoffs = bit_offset;
- sb1->bitsize = 0;
- sb1->is_writable = 0;
- hp += ERL_SUB_BIN_SIZE;
- }
-
- sb2 = (ErlSubBin *) hp;
- sb2->thing_word = HEADER_SUB_BIN;
- sb2->size = orig_size - pos - len;
- sb2->offs = offset + pos + len;
- sb2->orig = orig;
- sb2->bitoffs = bit_offset;
- sb2->bitsize = bit_size;
- sb2->is_writable = 0;
- hp += ERL_SUB_BIN_SIZE;
-
- ret = CONS(hp, make_binary(sb2), NIL);
- hp += 2;
- if (sb1 != NULL) {
- ret = CONS(hp, make_binary(sb1), ret);
- hp += 2;
- }
+ Eterm first, rest;
+
+ hp_need = (EXTRACT_SUB_BIN_HEAP_NEED + 2) * 2;
+
+ hp = HAlloc(p, hp_need);
+ hp_end = hp + hp_need;
+
+ ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size);
+
+ if ((ctx->flags & BF_FLAG_SPLIT_TRIM_ALL) && (pos == 0)) {
+ first = NIL;
+ } else {
+ first = erts_extract_sub_binary(&hp, orig, binary_bytes(orig),
+ offset * 8 + bit_offset,
+ pos * 8);
+ }
+
+ rest = erts_extract_sub_binary(&hp, orig, binary_bytes(orig),
+ (offset + pos + len) * 8 + bit_offset,
+ (orig_size - pos - len) * 8 + bit_size);
+
+ ret = CONS(hp, rest, NIL);
+ hp += 2;
+
+ if (first != NIL) {
+ ret = CONS(hp, first, ret);
+ hp += 2;
+ }
+
+ HRelease(p, hp_end, hp);
}
+
return ret;
}
@@ -1829,7 +1829,9 @@ static Eterm do_split_global_result(Process *p, Eterm subject, BinaryFindContext
Uint offset;
Uint bit_offset;
Uint bit_size;
- ErlSubBin *sb;
+ Uint extracted_offset;
+ Uint extracted_size;
+ Eterm extracted;
Uint do_trim;
Sint i;
register Uint reds = ctx->reds;
@@ -1852,7 +1854,8 @@ static Eterm do_split_global_result(Process *p, Eterm subject, BinaryFindContext
*ctxp = ctx;
fa = &(ctx->u.fa);
}
- erts_factory_proc_prealloc_init(&(fa->factory), p, (fa->size + 1) * (ERL_SUB_BIN_SIZE + 2));
+ erts_factory_proc_prealloc_init(&(fa->factory), p, (fa->size + 1) *
+ (EXTRACT_SUB_BIN_HEAP_NEED + 2));
ctx->state = BFResult;
}
@@ -1871,39 +1874,39 @@ static Eterm do_split_global_result(Process *p, Eterm subject, BinaryFindContext
}
return THE_NON_VALUE;
}
- sb = (ErlSubBin *)(fa->factory.hp);
- sb->size = fa->end_pos - (fad[i].pos + fad[i].len);
- if (!(sb->size == 0 && do_trim)) {
- sb->thing_word = HEADER_SUB_BIN;
- sb->offs = offset + fad[i].pos + fad[i].len;
- sb->orig = orig;
- sb->bitoffs = bit_offset;
- sb->bitsize = 0;
- sb->is_writable = 0;
- fa->factory.hp += ERL_SUB_BIN_SIZE;
- fa->term = CONS(fa->factory.hp, make_binary(sb), fa->term);
- fa->factory.hp += 2;
- do_trim &= ~BF_FLAG_SPLIT_TRIM;
- }
- fa->end_pos = fad[i].pos;
+
+ extracted_offset = (offset + fad[i].pos + fad[i].len) * 8 + bit_offset;
+ extracted_size = (fa->end_pos - (fad[i].pos + fad[i].len)) * 8;
+
+ if (!(extracted_size == 0 && do_trim)) {
+ extracted = erts_extract_sub_binary(&fa->factory.hp, orig,
+ binary_bytes(orig),
+ extracted_offset,
+ extracted_size);
+ fa->term = CONS(fa->factory.hp, extracted, fa->term);
+ fa->factory.hp += 2;
+
+ do_trim &= ~BF_FLAG_SPLIT_TRIM;
+ }
+
+ fa->end_pos = fad[i].pos;
}
fa->head = i;
ctx->reds = reds;
- sb = (ErlSubBin *)(fa->factory.hp);
- sb->size = fad[0].pos;
- if (!(sb->size == 0 && do_trim)) {
- sb->thing_word = HEADER_SUB_BIN;
- sb->offs = offset;
- sb->orig = orig;
- sb->bitoffs = bit_offset;
- sb->bitsize = 0;
- sb->is_writable = 0;
- fa->factory.hp += ERL_SUB_BIN_SIZE;
- fa->term = CONS(fa->factory.hp, make_binary(sb), fa->term);
- fa->factory.hp += 2;
+ extracted_offset = offset * 8 + bit_offset;
+ extracted_size = fad[0].pos * 8;
+
+ if (!(extracted_size == 0 && do_trim)) {
+ extracted = erts_extract_sub_binary(&fa->factory.hp, orig,
+ binary_bytes(orig),
+ extracted_offset,
+ extracted_size);
+ fa->term = CONS(fa->factory.hp, extracted, fa->term);
+ fa->factory.hp += 2;
}
+
erts_factory_close(&(fa->factory));
return fa->term;
@@ -1937,8 +1940,8 @@ BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen)
Uint offset;
Uint bit_offset;
Uint bit_size;
- Eterm* hp;
- ErlSubBin* sb;
+ Eterm *hp, *hp_end;
+ Eterm result;
if (is_not_binary(binary)) {
goto badarg;
@@ -1970,19 +1973,18 @@ BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen)
goto badarg;
}
- hp = HeapFragOnlyAlloc(p, ERL_SUB_BIN_SIZE);
+ hp = HeapFragOnlyAlloc(p, EXTRACT_SUB_BIN_HEAP_NEED);
+ hp_end = hp + EXTRACT_SUB_BIN_HEAP_NEED;
ERTS_GET_REAL_BIN(binary, orig, offset, bit_offset, bit_size);
- sb = (ErlSubBin *) hp;
- sb->thing_word = HEADER_SUB_BIN;
- sb->size = len;
- sb->offs = offset + pos;
- sb->orig = orig;
- sb->bitoffs = bit_offset;
- sb->bitsize = 0;
- sb->is_writable = 0;
-
- BIF_RET(make_binary(sb));
+
+ result = erts_extract_sub_binary(&hp, orig, binary_bytes(orig),
+ (offset + pos) * 8 + bit_offset,
+ len * 8);
+
+ HRelease(p, hp_end, hp);
+
+ BIF_RET(result);
badarg:
BIF_ERROR(p, BADARG);
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 0339589b79..4d8c3eb9dd 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -162,10 +162,10 @@ static Eterm current_stacktrace(ErtsHeapFactory *hfact, Process* rp,
Uint reserve_size);
static Eterm
-bld_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh)
+bld_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh, Eterm tail)
{
struct erl_off_heap_header* ohh;
- Eterm res = NIL;
+ Eterm res = tail;
Eterm tuple;
for (ohh = oh->first; ohh; ohh = ohh->next) {
@@ -1864,11 +1864,25 @@ process_info_aux(Process *c_p,
break;
case ERTS_PI_IX_BINARY: {
- Uint sz = 0;
- (void) bld_bin_list(NULL, &sz, &MSO(rp));
+ ErlHeapFragment *hfrag;
+ Uint sz;
+
+ res = NIL;
+ sz = 0;
+
+ (void)bld_bin_list(NULL, &sz, &MSO(rp), NIL);
+ for (hfrag = rp->mbuf; hfrag != NULL; hfrag = hfrag->next) {
+ (void)bld_bin_list(NULL, &sz, &hfrag->off_heap, NIL);
+ }
+
hp = erts_produce_heap(hfact, sz, reserve_size);
- res = bld_bin_list(&hp, NULL, &MSO(rp));
- break;
+
+ res = bld_bin_list(&hp, NULL, &MSO(rp), NIL);
+ for (hfrag = rp->mbuf; hfrag != NULL; hfrag = hfrag->next) {
+ res = bld_bin_list(&hp, NULL, &hfrag->off_heap, res);
+ }
+
+ break;
}
case ERTS_PI_IX_SEQUENTIAL_TRACE_TOKEN: {
diff --git a/erts/emulator/beam/erl_bif_persistent.c b/erts/emulator/beam/erl_bif_persistent.c
index f38e0cc5cb..8662a9e33a 100644
--- a/erts/emulator/beam/erl_bif_persistent.c
+++ b/erts/emulator/beam/erl_bif_persistent.c
@@ -1234,3 +1234,102 @@ next_to_delete(void)
erts_mtx_unlock(&delete_queue_mtx);
return table;
}
+
+/*
+ * test/debug functionality follow...
+ */
+
+static Uint accessed_literal_areas_size;
+static Uint accessed_no_literal_areas;
+static ErtsLiteralArea **accessed_literal_areas;
+
+int
+erts_debug_have_accessed_literal_area(ErtsLiteralArea *lap)
+{
+ Uint i;
+ for (i = 0; i < accessed_no_literal_areas; i++) {
+ if (accessed_literal_areas[i] == lap)
+ return !0;
+ }
+ return 0;
+}
+
+void
+erts_debug_save_accessed_literal_area(ErtsLiteralArea *lap)
+{
+ if (accessed_no_literal_areas == accessed_literal_areas_size) {
+ accessed_literal_areas_size += 10;
+ accessed_literal_areas = erts_realloc(ERTS_ALC_T_TMP,
+ accessed_literal_areas,
+ (sizeof(ErtsLiteralArea *)
+ *accessed_literal_areas_size));
+ }
+ accessed_literal_areas[accessed_no_literal_areas++] = lap;
+}
+
+static void debug_foreach_off_heap(HashTable *tbl, void (*func)(ErlOffHeap *, void *), void *arg)
+{
+ int i;
+
+ for (i = 0; i < tbl->allocated; i++) {
+ Eterm term = tbl->term[i];
+ if (is_tuple_arity(term, 2)) {
+ ErtsLiteralArea *lap = term_to_area(term);
+ ErlOffHeap oh;
+ if (!erts_debug_have_accessed_literal_area(lap)) {
+ ERTS_INIT_OFF_HEAP(&oh);
+ oh.first = lap->off_heap;
+ (*func)(&oh, arg);
+ erts_debug_save_accessed_literal_area(lap);
+ }
+ }
+ }
+}
+
+struct debug_la_oh {
+ void (*func)(ErlOffHeap *, void *);
+ void *arg;
+};
+
+static void debug_handle_table(void *vfap,
+ ErtsThrPrgrVal val,
+ void *vtbl)
+{
+ struct debug_la_oh *fap = vfap;
+ HashTable *tbl = vtbl;
+ debug_foreach_off_heap(tbl, fap->func, fap->arg);
+}
+
+void
+erts_debug_foreach_persistent_term_off_heap(void (*func)(ErlOffHeap *, void *), void *arg)
+{
+ HashTable *tbl;
+ struct debug_la_oh fa;
+ accessed_no_literal_areas = 0;
+ accessed_literal_areas_size = 10;
+ accessed_literal_areas = erts_alloc(ERTS_ALC_T_TMP,
+ (sizeof(ErtsLiteralArea *)
+ * accessed_literal_areas_size));
+
+ tbl = (HashTable *) erts_atomic_read_nob(&the_hash_table);
+ debug_foreach_off_heap(tbl, func, arg);
+ erts_mtx_lock(&delete_queue_mtx);
+ for (tbl = delete_queue_head; tbl; tbl = tbl->delete_next)
+ debug_foreach_off_heap(tbl, func, arg);
+ erts_mtx_unlock(&delete_queue_mtx);
+ fa.func = func;
+ fa.arg = arg;
+ erts_debug_later_op_foreach(table_updater,
+ debug_handle_table,
+ (void *) &fa);
+ erts_debug_later_op_foreach(table_deleter,
+ debug_handle_table,
+ (void *) &fa);
+ erts_debug_foreach_release_literal_area_off_heap(func, arg);
+
+ erts_free(ERTS_ALC_T_TMP, accessed_literal_areas);
+ accessed_no_literal_areas = 0;
+ accessed_literal_areas_size = 0;
+ accessed_literal_areas = NULL;
+}
+
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index c9c047255a..66b59ef1a3 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -351,6 +351,19 @@ erts_free_aligned_binary_bytes(byte* buf)
erts_free_aligned_binary_bytes_extra(buf,ERTS_ALC_T_TMP);
}
+/* A binary's size in bits must fit into a word for matching to work. We used
+ * to allow creating larger binaries than this, but they acted really strangely
+ * in Erlang code and were pretty much only usable in drivers and NIFs.
+ *
+ * This check also ensures, indirectly, that there won't be an overflow when
+ * the size is bumped by CHICKEN_PAD and the binary struct itself. */
+#define BINARY_OVERFLOW_CHECK(BYTE_SIZE) \
+ do { \
+ if (ERTS_UNLIKELY(BYTE_SIZE > ERTS_UWORD_MAX / CHAR_BIT)) { \
+ return NULL; \
+ } \
+ } while(0)
+
/* Explicit extra bytes allocated to counter buggy drivers.
** These extra bytes where earlier (< R13B04) added by an alignment-bug
** in this code. Do we dare remove this in some major release (R14?) maybe?
@@ -364,86 +377,107 @@ erts_free_aligned_binary_bytes(byte* buf)
ERTS_GLB_INLINE Binary *
erts_bin_drv_alloc_fnf(Uint size)
{
- Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
Binary *res;
+ Uint bsize;
+
+ BINARY_OVERFLOW_CHECK(size);
+ bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- if (bsize < size) /* overflow */
- return NULL;
res = erts_alloc_fnf(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
+
if (res) {
- res->orig_size = size;
- res->intern.flags = BIN_FLAG_DRV;
+ res->orig_size = size;
+ res->intern.flags = BIN_FLAG_DRV;
erts_refc_init(&res->intern.refc, 1);
}
+
return res;
}
ERTS_GLB_INLINE Binary *
erts_bin_drv_alloc(Uint size)
{
- Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
+ Binary *res = erts_bin_drv_alloc_fnf(size);
+
+ if (res) {
+ return res;
+ }
+
+ erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, size);
+}
+
+ERTS_GLB_INLINE Binary *
+erts_bin_nrml_alloc_fnf(Uint size)
+{
Binary *res;
+ Uint bsize;
- if (bsize < size) /* overflow */
- erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, size);
- res = erts_alloc(ERTS_ALC_T_DRV_BINARY, bsize);
+ BINARY_OVERFLOW_CHECK(size);
+ bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
+
+ res = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
- res->orig_size = size;
- res->intern.flags = BIN_FLAG_DRV;
- erts_refc_init(&res->intern.refc, 1);
+
+ if (res) {
+ res->orig_size = size;
+ res->intern.flags = 0;
+ erts_refc_init(&res->intern.refc, 1);
+ }
+
return res;
}
ERTS_GLB_INLINE Binary *
erts_bin_nrml_alloc(Uint size)
{
- Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- Binary *res;
+ Binary *res = erts_bin_drv_alloc_fnf(size);
- if (bsize < size) /* overflow */
- erts_alloc_enomem(ERTS_ALC_T_BINARY, size);
- res = erts_alloc(ERTS_ALC_T_BINARY, bsize);
- ERTS_CHK_BIN_ALIGNMENT(res);
- res->orig_size = size;
- res->intern.flags = 0;
- erts_refc_init(&res->intern.refc, 1);
- return res;
+ if (res) {
+ return res;
+ }
+
+ erts_alloc_enomem(ERTS_ALC_T_BINARY, size);
}
ERTS_GLB_INLINE Binary *
erts_bin_realloc_fnf(Binary *bp, Uint size)
{
+ ErtsAlcType_t type;
Binary *nbp;
- Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- ErtsAlcType_t type = (bp->intern.flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY
- : ERTS_ALC_T_BINARY;
+ Uint bsize;
+
+ type = (bp->intern.flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY
+ : ERTS_ALC_T_BINARY;
ASSERT((bp->intern.flags & BIN_FLAG_MAGIC) == 0);
- if (bsize < size) /* overflow */
- return NULL;
+
+ BINARY_OVERFLOW_CHECK(size);
+ bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
+
nbp = erts_realloc_fnf(type, (void *) bp, bsize);
ERTS_CHK_BIN_ALIGNMENT(nbp);
- if (nbp)
- nbp->orig_size = size;
+
+ if (nbp) {
+ nbp->orig_size = size;
+ }
+
return nbp;
}
ERTS_GLB_INLINE Binary *
erts_bin_realloc(Binary *bp, Uint size)
{
- Binary *nbp;
- Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
- ErtsAlcType_t type = (bp->intern.flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY
- : ERTS_ALC_T_BINARY;
- ASSERT((bp->intern.flags & BIN_FLAG_MAGIC) == 0);
- if (bsize < size) /* overflow */
- erts_realloc_enomem(type, bp, size);
- nbp = erts_realloc_fnf(type, (void *) bp, bsize);
- if (!nbp)
- erts_realloc_enomem(type, bp, bsize);
- ERTS_CHK_BIN_ALIGNMENT(nbp);
- nbp->orig_size = size;
- return nbp;
+ Binary *nbp = erts_bin_realloc_fnf(bp, size);
+
+ if (nbp) {
+ return nbp;
+ }
+
+ if (bp->intern.flags & BIN_FLAG_DRV) {
+ erts_realloc_enomem(ERTS_ALC_T_DRV_BINARY, bp, size);
+ } else {
+ erts_realloc_enomem(ERTS_ALC_T_BINARY, bp, size);
+ }
}
ERTS_GLB_INLINE void
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index f5807d25d7..a0edbc81a4 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -124,10 +124,10 @@ erts_bs_start_match_2(Process *p, Eterm Binary, Uint Max)
ProcBin* pb;
ASSERT(is_binary(Binary));
+
total_bin_size = binary_size(Binary);
- if ((total_bin_size >> (8*sizeof(Uint)-3)) != 0) {
- return THE_NON_VALUE;
- }
+ ASSERT(total_bin_size <= ERTS_UWORD_MAX / CHAR_BIT);
+
NeededSize = ERL_BIN_MATCHSTATE_SIZE(Max);
hp = HeapOnlyAlloc(p, NeededSize);
ms = (ErlBinMatchState *) hp;
@@ -157,10 +157,9 @@ ErlBinMatchState *erts_bs_start_match_3(Process *p, Eterm Binary)
ProcBin* pb;
ASSERT(is_binary(Binary));
+
total_bin_size = binary_size(Binary);
- if ((total_bin_size >> (8*sizeof(Uint)-3)) != 0) {
- return NULL;
- }
+ ASSERT(total_bin_size <= ERTS_UWORD_MAX / CHAR_BIT);
NeededSize = ERL_BIN_MATCHSTATE_SIZE(0);
hp = HeapOnlyAlloc(p, NeededSize);
@@ -459,29 +458,25 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
Eterm
erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb)
{
- ErlSubBin* sb;
+ Eterm result;
CHECK_MATCH_BUFFER(mb);
- if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */
- return THE_NON_VALUE;
+ if (mb->size - mb->offset < num_bits) {
+ /* Asked for too many bits. */
+ return THE_NON_VALUE;
}
/*
* From now on, we can't fail.
*/
- sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);
-
- sb->thing_word = HEADER_SUB_BIN;
- sb->orig = mb->orig;
- sb->size = BYTE_OFFSET(num_bits);
- sb->bitsize = BIT_OFFSET(num_bits);
- sb->offs = BYTE_OFFSET(mb->offset);
- sb->bitoffs = BIT_OFFSET(mb->offset);
- sb->is_writable = 0;
+ result = erts_extract_sub_binary(&HEAP_TOP(p),
+ mb->orig, mb->base,
+ mb->offset, num_bits);
+
mb->offset += num_bits;
-
- return make_binary(sb);
+
+ return result;
}
Eterm
@@ -545,21 +540,19 @@ erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer
Eterm
erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb)
{
- ErlSubBin* sb;
- Uint size;
+ Uint bit_size;
+ Eterm result;
CHECK_MATCH_BUFFER(mb);
- size = mb->size-mb->offset;
- sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);
- sb->thing_word = HEADER_SUB_BIN;
- sb->size = BYTE_OFFSET(size);
- sb->bitsize = BIT_OFFSET(size);
- sb->offs = BYTE_OFFSET(mb->offset);
- sb->bitoffs = BIT_OFFSET(mb->offset);
- sb->is_writable = 0;
- sb->orig = mb->orig;
- mb->offset = mb->size;
- return make_binary(sb);
+ bit_size = mb->size - mb->offset;
+
+ result = erts_extract_sub_binary(&HEAP_TOP(p),
+ mb->orig, mb->base,
+ mb->offset, bit_size);
+
+ mb->offset = mb->size;
+
+ return result;
}
/****************************************************************
@@ -2097,3 +2090,39 @@ erts_copy_bits(byte* src, /* Base pointer to source. */
}
}
+Eterm erts_extract_sub_binary(Eterm **hp, Eterm base_bin, byte *base_data,
+ Uint bit_offset, Uint bit_size)
+{
+ Uint byte_offset, byte_size;
+
+ ERTS_CT_ASSERT(ERL_SUB_BIN_SIZE <= ERL_ONHEAP_BIN_LIMIT);
+
+ byte_offset = BYTE_OFFSET(bit_offset);
+ byte_size = BYTE_OFFSET(bit_size);
+
+ if (BIT_OFFSET(bit_size) == 0 && byte_size <= ERL_ONHEAP_BIN_LIMIT) {
+ ErlHeapBin *hb = (ErlHeapBin*)*hp;
+ *hp += heap_bin_size(byte_size);
+
+ hb->thing_word = header_heap_bin(byte_size);
+ hb->size = byte_size;
+
+ copy_binary_to_buffer(hb->data, 0, base_data, bit_offset, bit_size);
+
+ return make_binary(hb);
+ } else {
+ ErlSubBin *sb = (ErlSubBin*)*hp;
+ *hp += ERL_SUB_BIN_SIZE;
+
+ sb->thing_word = HEADER_SUB_BIN;
+ sb->size = byte_size;
+ sb->offs = byte_offset;
+ sb->orig = base_bin;
+ sb->bitoffs = BIT_OFFSET(bit_offset);
+ sb->bitsize = BIT_OFFSET(bit_size);
+ sb->is_writable = 0;
+
+ return make_binary(sb);
+ }
+}
+
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index 50d353e1fa..0b2a6f3760 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -116,7 +116,7 @@ typedef struct erl_bin_match_struct{
do { \
if (BIT_OFFSET(DstBufOffset) == 0 && (SrcBufferOffset == 0) && \
(BIT_OFFSET(NumBits)==0) && (NumBits != 0)) { \
- sys_memcpy(DstBuffer+BYTE_OFFSET(DstBufOffset), \
+ sys_memcpy(((byte*)DstBuffer)+BYTE_OFFSET(DstBufOffset), \
SrcBuffer, NBYTES(NumBits)); \
} else { \
erts_copy_bits(SrcBuffer, SrcBufferOffset, 1, \
@@ -150,8 +150,11 @@ void erts_bits_destroy_state(ERL_BITS_PROTO_0);
Eterm erts_bs_start_match_2(Process *p, Eterm Bin, Uint Max);
ErlBinMatchState *erts_bs_start_match_3(Process *p, Eterm Bin);
Eterm erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
-Eterm erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
Eterm erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
+
+/* These will create heap binaries when appropriate, so they require free space
+ * up to EXTRACT_SUB_BIN_HEAP_NEED. */
+Eterm erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
Eterm erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb);
/*
@@ -182,6 +185,17 @@ void erts_copy_bits(byte* src, size_t soffs, int sdir,
byte* dst, size_t doffs,int ddir, size_t n);
int erts_cmp_bits(byte* a_ptr, size_t a_offs, byte* b_ptr, size_t b_offs, size_t size);
+
+/* Extracts a region from base_bin as a sub-binary or heap binary, whichever
+ * is the most appropriate.
+ *
+ * The caller must ensure that there's enough free space at *hp */
+Eterm erts_extract_sub_binary(Eterm **hp, Eterm base_bin, byte *base_data,
+ Uint bit_offset, Uint num_bits);
+
+/* Pessimistic estimate of the words required for erts_extract_sub_binary */
+#define EXTRACT_SUB_BIN_HEAP_NEED (heap_bin_size(ERL_ONHEAP_BIN_LIMIT))
+
/*
* Flags for bs_get_* / bs_put_* / bs_init* instructions.
*/
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index d24f30f126..3c74ef493b 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -4415,7 +4415,7 @@ void db_info(fmtfn_t to, void *to_arg, int show) /* Called by break handler *
pdbi.to_arg = to_arg;
pdbi.show = show;
- erts_db_foreach_table(db_info_print, &pdbi);
+ erts_db_foreach_table(db_info_print, &pdbi, !0);
}
Uint
@@ -4428,7 +4428,7 @@ erts_get_ets_misc_mem_size(void)
/* SMP Note: May only be used when system is locked */
void
-erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg)
+erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg, int alive_only)
{
int ix;
@@ -4440,7 +4440,7 @@ erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg)
if (first) {
DbTable *tb = first;
do {
- if (is_table_alive(tb))
+ if (!alive_only || is_table_alive(tb))
(*func)(tb, arg);
tb = tb->common.all.next;
} while (tb != first);
@@ -4457,6 +4457,15 @@ erts_db_foreach_offheap(DbTable *tb,
tb->common.meth->db_foreach_offheap(tb, func, arg);
}
+void
+erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *),
+ void *arg)
+{
+ erts_db_foreach_thr_prgr_offheap_hash(func, arg);
+ erts_db_foreach_thr_prgr_offheap_tree(func, arg);
+ erts_db_foreach_thr_prgr_offheap_catree(func, arg);
+}
+
/* retrieve max number of ets tables */
Uint
erts_db_get_max_tabs()
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index b3dc1b9ba3..c604744687 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -114,10 +114,12 @@ void init_db(ErtsDbSpinCount);
int erts_db_process_exiting(Process *, ErtsProcLocks, void **);
int erts_db_execute_free_fixation(Process*, DbFixation*);
void db_info(fmtfn_t, void *, int);
-void erts_db_foreach_table(void (*)(DbTable *, void *), void *);
+void erts_db_foreach_table(void (*)(DbTable *, void *), void *, int);
void erts_db_foreach_offheap(DbTable *,
void (*func)(ErlOffHeap *, void *),
void *);
+void erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *),
+ void *);
extern int erts_ets_rwmtx_spin_count;
extern int user_requested_db_max_tabs; /* set in erl_init */
diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c
index fed4b44a9b..8a89eb72df 100644
--- a/erts/emulator/beam/erl_db_catree.c
+++ b/erts/emulator/beam/erl_db_catree.c
@@ -2395,6 +2395,34 @@ void db_calc_stats_catree(DbTableCATree* tb, DbCATreeStats* stats)
} while (depth > 0);
}
+struct debug_catree_fa {
+ void (*func)(ErlOffHeap *, void *);
+ void *arg;
+};
+
+static void debug_free_route_node(void *vfap, ErtsThrPrgrVal val, void *vnp)
+{
+ DbTableCATreeNode *np = vnp;
+ if (np->u.route.key.oh) {
+ struct debug_catree_fa *fap = vfap;
+ ErlOffHeap oh;
+ ERTS_INIT_OFF_HEAP(&oh);
+ oh.first = np->u.route.key.oh;
+ (*fap->func)(&oh, fap->arg);
+ }
+}
+
+void
+erts_db_foreach_thr_prgr_offheap_catree(void (*func)(ErlOffHeap *, void *),
+ void *arg)
+{
+ struct debug_catree_fa fa;
+ fa.func = func;
+ fa.arg = arg;
+ erts_debug_later_op_foreach(do_free_route_node, debug_free_route_node, &fa);
+}
+
+
#ifdef HARDDEBUG
/*
diff --git a/erts/emulator/beam/erl_db_catree.h b/erts/emulator/beam/erl_db_catree.h
index c2c884eee3..2ede85e04e 100644
--- a/erts/emulator/beam/erl_db_catree.h
+++ b/erts/emulator/beam/erl_db_catree.h
@@ -132,6 +132,9 @@ typedef struct {
Uint max_depth;
} DbCATreeStats;
void db_calc_stats_catree(DbTableCATree*, DbCATreeStats*);
+void
+erts_db_foreach_thr_prgr_offheap_catree(void (*func)(ErlOffHeap *, void *),
+ void *arg);
#endif /* _DB_CATREE_H */
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index ceaccf7e44..4904d3fa42 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -3262,6 +3262,12 @@ Eterm erts_ets_hash_sizeof_ext_segtab(void)
return make_small(((SIZEOF_EXT_SEGTAB(0)-1) / sizeof(UWord)) + 1);
}
+void
+erts_db_foreach_thr_prgr_offheap_hash(void (*func)(ErlOffHeap *, void *),
+ void *arg)
+{
+}
+
#ifdef ERTS_ENABLE_LOCK_COUNT
void erts_lcnt_enable_db_hash_lock_count(DbTableHash *tb, int enable) {
int i;
diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h
index eae5537ba4..9759d8b466 100644
--- a/erts/emulator/beam/erl_db_hash.h
+++ b/erts/emulator/beam/erl_db_hash.h
@@ -110,6 +110,9 @@ typedef struct {
void db_calc_stats_hash(DbTableHash* tb, DbHashStats*);
Eterm erts_ets_hash_sizeof_ext_segtab(void);
+void
+erts_db_foreach_thr_prgr_offheap_hash(void (*func)(ErlOffHeap *, void *),
+ void *arg);
#ifdef ERTS_ENABLE_LOCK_COUNT
void erts_lcnt_enable_db_hash_lock_count(DbTableHash *tb, int enable);
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index 492ea81b63..19b94b0634 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -3936,6 +3936,12 @@ static int doit_select_replace(DbTableCommon *tb, TreeDbTerm **this,
return 1;
}
+void
+erts_db_foreach_thr_prgr_offheap_tree(void (*func)(ErlOffHeap *, void *),
+ void *arg)
+{
+}
+
#ifdef TREE_DEBUG
static void do_dump_tree2(DbTableCommon* tb, int to, void *to_arg, int show,
TreeDbTerm *t, int offset)
diff --git a/erts/emulator/beam/erl_db_tree.h b/erts/emulator/beam/erl_db_tree.h
index 54da2a6bc1..06e0005801 100644
--- a/erts/emulator/beam/erl_db_tree.h
+++ b/erts/emulator/beam/erl_db_tree.h
@@ -53,4 +53,8 @@ void db_initialize_tree(void);
int db_create_tree(Process *p, DbTable *tbl);
+void
+erts_db_foreach_thr_prgr_offheap_tree(void (*func)(ErlOffHeap *, void *),
+ void *arg);
+
#endif /* _DB_TREE_H */
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 67a73e4d57..13b1f8ab4d 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -151,6 +151,7 @@ static void grow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj);
static void sweep_off_heap(Process *p, int fullsweep);
static void offset_heap(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size);
static void offset_heap_ptr(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size);
+static void offset_heap_ptr_nstack(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size);
static void offset_rootset(Process *p, Sint offs, char* area, Uint area_size,
Eterm* objv, int nobj);
static void offset_off_heap(Process* p, Sint offs, char* area, Uint area_size);
@@ -1054,9 +1055,10 @@ erts_garbage_collect_hibernate(Process* p)
n_htop = tmp_n_htop; \
} while(0)
+
/*
* offset_nstack() can ignore the descriptor-based traversal the other
- * nstack procedures use and simply call offset_heap_ptr() instead.
+ * nstack procedures use and do a simpler word by word traversal instead.
* This relies on two facts:
* 1. The only live non-Erlang terms on an nstack are return addresses,
* and they will be skipped thanks to the low/high range check.
@@ -1071,14 +1073,51 @@ static ERTS_INLINE void offset_nstack(Process* p, Sint offs,
{
if (p->hipe.nstack) {
ASSERT(p->hipe.nsp && p->hipe.nstend);
- offset_heap_ptr(hipe_nstack_start(p), hipe_nstack_used(p),
- offs, area, area_size);
+ offset_heap_ptr_nstack(hipe_nstack_start(p), hipe_nstack_used(p),
+ offs, area, area_size);
}
else {
ASSERT(!p->hipe.nsp && !p->hipe.nstend);
}
}
+/*
+ * This is the same as offset_heap_ptr()
+ *
+ * Except for VALGRIND. It allows benign offsetting of undefined (dead) words
+ * on the nstack while also retaining them as undefined. This suppresses
+ * valgrinds "Conditional jump or move depends on uninitialised value(s)".
+ */
+static void
+offset_heap_ptr_nstack(Eterm* hp, Uint sz, Sint offs,
+ char* area, Uint area_size)
+{
+ while (sz--) {
+ Eterm val = *hp;
+#ifdef VALGRIND
+ Eterm val_vbits;
+ VALGRIND_GET_VBITS(&val, &val_vbits, sizeof(val));
+ VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val));
+#endif
+ switch (primary_tag(val)) {
+ case TAG_PRIMARY_LIST:
+ case TAG_PRIMARY_BOXED:
+ if (ErtsInArea(ptr_val(val), area, area_size)) {
+#ifdef VALGRIND
+ VALGRIND_SET_VBITS(&val, val_vbits, sizeof(val));
+#endif
+ *hp = offset_ptr(val, offs);
+ }
+ hp++;
+ break;
+ default:
+ hp++;
+ break;
+ }
+ }
+}
+
+
#else /* !HIPE */
#define fullsweep_nstack(p,n_htop) (n_htop)
@@ -2848,7 +2887,7 @@ sweep_off_heap(Process *p, int fullsweep)
if (is_external_header(((struct erl_off_heap_header*) boxed_val(ptr->thing_word))->thing_word))
erts_node_bookkeep(((ExternalThing*)ptr)->node,
make_boxed(&ptr->thing_word),
- ERL_NODE_DEC);
+ ERL_NODE_DEC, __FILE__, __LINE__);
*prev = ptr = (struct erl_off_heap_header*) boxed_val(ptr->thing_word);
ASSERT(!IS_MOVED_BOXED(ptr->thing_word));
switch (ptr->thing_word) {
@@ -2879,7 +2918,7 @@ sweep_off_heap(Process *p, int fullsweep)
if (is_external_header(ptr->thing_word)) {
erts_node_bookkeep(((ExternalThing*)ptr)->node,
make_boxed(&ptr->thing_word),
- ERL_NODE_INC);
+ ERL_NODE_INC, __FILE__, __LINE__);
}
prev = &ptr->next;
ptr = ptr->next;
@@ -3050,9 +3089,11 @@ offset_heap(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size)
if (is_external_header(oh->thing_word)) {
erts_node_bookkeep(((ExternalThing*)oh)->node,
- make_boxed(((Eterm*)oh)-offs), ERL_NODE_DEC);
+ make_boxed(((Eterm*)oh)-offs),
+ ERL_NODE_DEC, __FILE__, __LINE__);
erts_node_bookkeep(((ExternalThing*)oh)->node,
- make_boxed((Eterm*)oh), ERL_NODE_INC);
+ make_boxed((Eterm*)oh), ERL_NODE_INC,
+ __FILE__, __LINE__);
}
if (ErtsInArea(oh->next, area, area_size)) {
diff --git a/erts/emulator/beam/erl_monitor_link.c b/erts/emulator/beam/erl_monitor_link.c
index 1c6b4afaa3..43028be39d 100644
--- a/erts/emulator/beam/erl_monitor_link.c
+++ b/erts/emulator/beam/erl_monitor_link.c
@@ -671,6 +671,24 @@ erts_monitor_tree_foreach(ErtsMonitor *root,
arg);
}
+void
+erts_debug_monitor_tree_destroying_foreach(ErtsMonitor *root,
+ ErtsMonitorFunc func,
+ void *arg,
+ void *vysp)
+{
+ void *tmp_vysp = erts_alloc(ERTS_ALC_T_ML_YIELD_STATE,
+ sizeof(ErtsMonLnkYieldState));
+ Sint reds;
+ sys_memcpy(tmp_vysp, tmp_vysp, sizeof(ErtsMonLnkYieldState));
+ do {
+ reds = ml_rbt_foreach_yielding((ErtsMonLnkNode *) root,
+ (ErtsMonLnkNodeFunc) func,
+ arg, &tmp_vysp, (Sint) INT_MAX);
+ } while (reds <= 0);
+ ERTS_ML_ASSERT(!tmp_vysp);
+}
+
int
erts_monitor_tree_foreach_yielding(ErtsMonitor *root,
ErtsMonitorFunc func,
@@ -716,6 +734,19 @@ erts_monitor_list_foreach(ErtsMonitor *list,
arg, &ystate, (Sint) INT_MAX));
}
+void
+erts_debug_monitor_list_destroying_foreach(ErtsMonitor *list,
+ ErtsMonitorFunc func,
+ void *arg,
+ void *vysp)
+{
+ void *tmp_vysp = vysp;
+ while (!ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list,
+ (int (*)(ErtsMonLnkNode *, void *, Sint)) func,
+ arg, &tmp_vysp, (Sint) INT_MAX));
+ ERTS_ML_ASSERT(!tmp_vysp);
+}
+
int
erts_monitor_list_foreach_yielding(ErtsMonitor *list,
ErtsMonitorFunc func,
@@ -1080,6 +1111,24 @@ erts_link_tree_foreach(ErtsLink *root,
}
+void
+erts_debug_link_tree_destroying_foreach(ErtsLink *root,
+ ErtsLinkFunc func,
+ void *arg,
+ void *vysp)
+{
+ void *tmp_vysp = erts_alloc(ERTS_ALC_T_ML_YIELD_STATE,
+ sizeof(ErtsMonLnkYieldState));
+ Sint reds;
+ sys_memcpy(tmp_vysp, vysp, sizeof(ErtsMonLnkYieldState));
+ do {
+ reds = ml_rbt_foreach_yielding((ErtsMonLnkNode *) root,
+ (ErtsMonLnkNodeFunc) func,
+ arg, &tmp_vysp, (Sint) INT_MAX);
+ } while (reds <= 0);
+ ERTS_ML_ASSERT(!tmp_vysp);
+}
+
int
erts_link_tree_foreach_yielding(ErtsLink *root,
ErtsLinkFunc func,
diff --git a/erts/emulator/beam/erl_monitor_link.h b/erts/emulator/beam/erl_monitor_link.h
index eff861fce8..86be400c09 100644
--- a/erts/emulator/beam/erl_monitor_link.h
+++ b/erts/emulator/beam/erl_monitor_link.h
@@ -1509,6 +1509,17 @@ ERTS_GLB_INLINE ErtsMonitorSuspend *erts_monitor_suspend(ErtsMonitor *mon)
#endif
+void
+erts_debug_monitor_tree_destroying_foreach(ErtsMonitor *root,
+ ErtsMonitorFunc func,
+ void *arg,
+ void *vysp);
+void
+erts_debug_monitor_list_destroying_foreach(ErtsMonitor *list,
+ ErtsMonitorFunc func,
+ void *arg,
+ void *vysp);
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Link Operations *
\* */
@@ -2365,4 +2376,10 @@ erts_link_dist_delete(ErtsLink *lnk)
#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+void
+erts_debug_link_tree_destroying_foreach(ErtsLink *root,
+ ErtsLinkFunc func,
+ void *arg,
+ void *vysp);
+
#endif /* ERL_MONITOR_LINK_H__ */
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index 4eb6c3e214..50e9812534 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -932,7 +932,8 @@ static void try_delete_node(void *venp)
*
* If refc > 0, the entry is in use. Keep the entry.
*/
- erts_node_bookkeep(enp, THE_NON_VALUE, ERL_NODE_DEC);
+ erts_node_bookkeep(enp, THE_NON_VALUE, ERL_NODE_DEC,
+ __FILE__, __LINE__);
refc = erts_refc_dectest(&enp->refc, -1);
if (refc == -1)
(void) hash_erase(&erts_node_table, (void *) enp);
@@ -1164,6 +1165,12 @@ void erts_lcnt_update_distribution_locks(int enable) {
* can damage the real-time properties of the system. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifdef ERL_NODE_BOOKKEEP
+#define ERTS_DBG_NC_ALLOC_TYPE ERTS_ALC_T_NC_STD
+#else
+#define ERTS_DBG_NC_ALLOC_TYPE ERTS_ALC_T_NC_TMP
+#endif
+
#include "erl_db.h"
#undef INIT_AM
@@ -1188,10 +1195,12 @@ static Eterm AM_delayed_delete_timer;
static Eterm AM_thread_progress_delete_timer;
static Eterm AM_sequence;
static Eterm AM_signal;
+static Eterm AM_persistent_term;
static void setup_reference_table(void);
static Eterm reference_table_term(Uint **hpp, ErlOffHeap *ohp, Uint *szp);
static void delete_reference_table(void);
+static void clear_system(void);
#undef ERTS_MAX__
#define ERTS_MAX__(A, B) ((A) > (B) ? (A) : (B))
@@ -1244,11 +1253,11 @@ typedef struct inserted_bin_ {
Binary *bin_val;
} InsertedBin;
-static ReferredNode *referred_nodes;
+static ReferredNode *referred_nodes = NULL;
static int no_referred_nodes;
-static ReferredDist *referred_dists;
+static ReferredDist *referred_dists = NULL;
static int no_referred_dists;
-static InsertedBin *inserted_bins;
+static InsertedBin *inserted_bins = NULL;
Eterm
erts_get_node_and_dist_references(struct process *proc)
@@ -1284,9 +1293,15 @@ erts_get_node_and_dist_references(struct process *proc)
INIT_AM(thread_progress_delete_timer);
INIT_AM(signal);
INIT_AM(sequence);
+ INIT_AM(persistent_term);
references_atoms_need_init = 0;
}
+#ifdef ERL_NODE_BOOKKEEP
+ if (referred_nodes || referred_dists || inserted_bins)
+ delete_reference_table();
+#endif
+
setup_reference_table();
/* Get term size */
@@ -1304,7 +1319,11 @@ erts_get_node_and_dist_references(struct process *proc)
ASSERT(endp == hp);
+#ifndef ERL_NODE_BOOKKEEP
delete_reference_table();
+#endif
+
+ clear_system();
erts_thr_progress_unblock();
erts_proc_lock(proc, ERTS_PROC_LOCK_MAIN);
@@ -1339,7 +1358,7 @@ insert_dist_referrer(ReferredDist *referred_dist,
break;
if(!drp) {
- drp = (DistReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP,
+ drp = (DistReferrer *) erts_alloc(ERTS_DBG_NC_ALLOC_TYPE,
sizeof(DistReferrer));
drp->next = referred_dist->referrers;
referred_dist->referrers = drp;
@@ -1402,7 +1421,7 @@ insert_node_referrer(ReferredNode *referred_node, int type, Eterm id)
break;
if(!nrp) {
- nrp = (NodeReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP,
+ nrp = (NodeReferrer *) erts_alloc(ERTS_DBG_NC_ALLOC_TYPE,
sizeof(NodeReferrer));
nrp->next = referred_node->referrers;
ERTS_INIT_OFF_HEAP(&nrp->off_heap);
@@ -1516,7 +1535,8 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id)
erts_match_prog_foreach_offheap((Binary *) u.mref->mb,
insert_offheap2,
(void *) &a);
- nib = erts_alloc(ERTS_ALC_T_NC_TMP, sizeof(InsertedBin));
+ nib = erts_alloc(ERTS_DBG_NC_ALLOC_TYPE,
+ sizeof(InsertedBin));
nib->bin_val = (Binary *) u.mref->mb;
nib->next = inserted_bins;
inserted_bins = nib;
@@ -1574,18 +1594,6 @@ static int clear_visited_monitor(ErtsMonitor *mon, void *p, Sint reds)
}
static void
-insert_p_monitors(ErtsPTabElementCommon *p)
-{
- Eterm id = p->id;
- erts_monitor_tree_foreach(p->u.alive.monitors,
- insert_monitor,
- (void *) &id);
- erts_monitor_list_foreach(p->u.alive.lt_monitors,
- insert_monitor,
- (void *) &id);
-}
-
-static void
insert_dist_monitors(DistEntry *dep)
{
if (dep->mld) {
@@ -1600,8 +1608,10 @@ insert_dist_monitors(DistEntry *dep)
static int
-insert_sequence(ErtsDistExternal *edep, void *arg, Sint reds)
+insert_sequence(DistSeqNode *seq, void *arg, Sint reds)
{
+ ErtsDistExternal *edep = erts_get_dist_ext(&seq->hfrag);
+ insert_offheap(&seq->hfrag.off_heap, SEQUENCE_REF, *(Eterm*)arg);
insert_dist_entry(edep->dep, SEQUENCE_REF, *(Eterm*)arg, 0);
return 1;
}
@@ -1609,18 +1619,7 @@ insert_sequence(ErtsDistExternal *edep, void *arg, Sint reds)
static void
insert_dist_sequences(DistEntry *dep)
{
- erts_dist_seq_tree_foreach(dep, insert_sequence, (void *) &dep->sysname);
-}
-
-static void
-clear_visited_p_monitors(ErtsPTabElementCommon *p)
-{
- erts_monitor_tree_foreach(p->u.alive.monitors,
- clear_visited_monitor,
- NULL);
- erts_monitor_list_foreach(p->u.alive.lt_monitors,
- clear_visited_monitor,
- NULL);
+ erts_debug_dist_seq_tree_foreach(dep, insert_sequence, (void *) &dep->sysname);
}
static void
@@ -1667,13 +1666,6 @@ static int clear_visited_link(ErtsLink *lnk, void *p, Sint reds)
}
static void
-insert_p_links(ErtsPTabElementCommon *p)
-{
- Eterm id = p->id;
- erts_link_tree_foreach(p->u.alive.links, insert_link, (void *) &id);
-}
-
-static void
insert_dist_links(DistEntry *dep)
{
if (dep->mld)
@@ -1683,14 +1675,6 @@ insert_dist_links(DistEntry *dep)
}
static void
-clear_visited_p_links(ErtsPTabElementCommon *p)
-{
- erts_link_tree_foreach(p->u.alive.links,
- clear_visited_link,
- NULL);
-}
-
-static void
clear_visited_dist_links(DistEntry *dep)
{
if (dep->mld)
@@ -1885,15 +1869,11 @@ insert_process(Process *proc)
insert_sig_ext,
(void *) proc);
- /* If the process is FREE, the proc->common field has been
- re-used by the ptab delete, so we cannot trust it. */
- if (!(erts_atomic32_read_nob(&proc->state) & ERTS_PSFLG_FREE)) {
- /* Insert links */
- insert_p_links(&proc->common);
-
- /* Insert monitors */
- insert_p_monitors(&proc->common);
- }
+ /* Insert monitors and links... */
+ erts_debug_proc_monitor_link_foreach(proc,
+ insert_monitor,
+ insert_link,
+ (void *) &proc->common.id);
{
DistEntry *dep = ERTS_PROC_GET_DIST_ENTRY(proc);
@@ -1906,6 +1886,12 @@ insert_process(Process *proc)
}
static void
+insert_process2(Process *proc, void *arg)
+{
+ insert_process(proc);
+}
+
+static void
insert_dist_suspended_procs(DistEntry *dep)
{
ErtsProcList *plist = erts_proclist_peek_first(dep->suspended);
@@ -1916,16 +1902,47 @@ insert_dist_suspended_procs(DistEntry *dep)
}
}
+static void clear_process(Process *proc);
+
+static void
+clear_dist_suspended_procs(DistEntry *dep)
+{
+ ErtsProcList *plist = erts_proclist_peek_first(dep->suspended);
+ while (plist) {
+ if (is_not_immed(plist->u.pid))
+ clear_process(plist->u.p);
+ plist = erts_proclist_peek_next(dep->suspended, plist);
+ }
+}
+
+static void
+insert_persistent_term(ErlOffHeap *ohp, void *arg)
+{
+ Eterm heap[3];
+ insert_offheap(ohp, SYSTEM_REF,
+ TUPLE2(&heap[0], AM_system, AM_persistent_term));
+}
+
+static void
+insert_ets_offheap_thr_prgr(ErlOffHeap *ohp, void *arg)
+{
+ Eterm heap[3];
+ insert_offheap(ohp, ETS_REF,
+ TUPLE2(&heap[0], AM_system, AM_ets));
+}
+
#ifdef ERL_NODE_BOOKKEEP
void
-erts_node_bookkeep(ErlNode *np, Eterm term, int what)
+erts_node_bookkeep(ErlNode *np, Eterm term, int what, char *f, int l)
{
- erts_aint_t slot = (erts_atomic_inc_read_nob(&np->slot) - 1) % 1024;
+ erts_aint_t slot = (erts_atomic_inc_read_nob(&np->slot) - 1) % ERTS_BOOKKEEP_SIZE;
ErtsSchedulerData *esdp = erts_get_scheduler_data();
Eterm who = THE_NON_VALUE;
ASSERT(np);
np->books[slot].what = what;
np->books[slot].term = term;
+ np->books[slot].file = f;
+ np->books[slot].line = l;
if (esdp->current_process) {
who = esdp->current_process->common.id;
} else if (esdp->current_port) {
@@ -1946,14 +1963,14 @@ setup_reference_table(void)
inserted_bins = NULL;
hash_get_info(&hi, &erts_node_table);
- referred_nodes = erts_alloc(ERTS_ALC_T_NC_TMP,
+ referred_nodes = erts_alloc(ERTS_DBG_NC_ALLOC_TYPE,
hi.objs*sizeof(ReferredNode));
no_referred_nodes = 0;
hash_foreach(&erts_node_table, init_referred_node, NULL);
ASSERT(no_referred_nodes == hi.objs);
hash_get_info(&hi, &erts_dist_table);
- referred_dists = erts_alloc(ERTS_ALC_T_NC_TMP,
+ referred_dists = erts_alloc(ERTS_DBG_NC_ALLOC_TYPE,
hi.objs*sizeof(ReferredDist));
no_referred_dists = 0;
hash_foreach(&erts_dist_table, init_referred_dist, NULL);
@@ -1990,8 +2007,9 @@ setup_reference_table(void)
if (proc)
insert_process(proc);
}
+ erts_debug_free_process_foreach(insert_process2, NULL);
- erts_foreach_sys_msg_in_q(insert_sys_msg);
+ erts_debug_foreach_sys_msg_in_q(insert_sys_msg);
/* Insert all ports */
max = erts_ptab_max(&erts_port);
@@ -2008,10 +2026,18 @@ setup_reference_table(void)
if (state & ERTS_PORT_SFLGS_DEAD)
continue;
- /* Insert links */
- insert_p_links(&prt->common);
- /* Insert monitors */
- insert_p_monitors(&prt->common);
+ /* Insert links */
+ erts_link_tree_foreach(ERTS_P_LINKS(prt),
+ insert_link,
+ (void *) &prt->common.id);
+ /* Insert monitors */
+ erts_monitor_tree_foreach(ERTS_P_MONITORS(prt),
+ insert_monitor,
+ (void *) &prt->common.id);
+ /* Insert local target monitors */
+ erts_monitor_list_foreach(ERTS_P_LT_MONITORS(prt),
+ insert_monitor,
+ (void *) &prt->common.id);
/* Insert port data */
ohp = erts_port_data_offheap(prt);
if (ohp)
@@ -2091,11 +2117,16 @@ setup_reference_table(void)
}
/* Insert all ets tables */
- erts_db_foreach_table(insert_ets_table, NULL);
+ erts_db_foreach_table(insert_ets_table, NULL, 0);
+ erts_db_foreach_thr_prgr_offheap(insert_ets_offheap_thr_prgr, NULL);
/* Insert all bif timers */
erts_debug_bif_timer_foreach(insert_bif_timer, NULL);
+ /* Insert persistent term storage */
+ erts_debug_foreach_persistent_term_off_heap(insert_persistent_term,
+ NULL);
+
/* Insert node table (references to dist) */
hash_foreach(&erts_node_table, insert_erl_node, NULL);
}
@@ -2348,8 +2379,7 @@ static void noop_sig_ext(ErtsDistExternal *ext, void *arg)
static void
delete_reference_table(void)
{
- DistEntry *dep;
- int i, max;
+ int i;
for(i = 0; i < no_referred_nodes; i++) {
NodeReferrer *nrp;
NodeReferrer *tnrp;
@@ -2358,11 +2388,13 @@ delete_reference_table(void)
erts_cleanup_offheap(&nrp->off_heap);
tnrp = nrp;
nrp = nrp->next;
- erts_free(ERTS_ALC_T_NC_TMP, (void *) tnrp);
+ erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) tnrp);
}
}
- if (referred_nodes)
- erts_free(ERTS_ALC_T_NC_TMP, (void *) referred_nodes);
+ if (referred_nodes) {
+ erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) referred_nodes);
+ referred_nodes = NULL;
+ }
for(i = 0; i < no_referred_dists; i++) {
DistReferrer *drp;
@@ -2371,34 +2403,57 @@ delete_reference_table(void)
while(drp) {
tdrp = drp;
drp = drp->next;
- erts_free(ERTS_ALC_T_NC_TMP, (void *) tdrp);
+ erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) tdrp);
}
}
- if (referred_dists)
- erts_free(ERTS_ALC_T_NC_TMP, (void *) referred_dists);
+ if (referred_dists) {
+ erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) referred_dists);
+ referred_dists = NULL;
+ }
while(inserted_bins) {
InsertedBin *ib = inserted_bins;
inserted_bins = inserted_bins->next;
- erts_free(ERTS_ALC_T_NC_TMP, (void *)ib);
+ erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *)ib);
}
+}
+
+static void clear_process(Process *proc)
+{
+ erts_proc_sig_debug_foreach_sig(proc,
+ noop_sig_msg,
+ noop_sig_offheap,
+ clear_visited_monitor,
+ clear_visited_link,
+ noop_sig_ext,
+ (void *) proc);
+
+
+ /* Clear monitors and links... */
+ erts_debug_proc_monitor_link_foreach(proc,
+ clear_visited_monitor,
+ clear_visited_link,
+ (void *) &proc->common.id);
+}
+
+static void clear_process2(Process *proc, void *arg)
+{
+ clear_process(proc);
+}
- /* Cleanup... */
+static void
+clear_system(void)
+{
+ DistEntry *dep;
+ int i, max;
+ /* Clear... */
max = erts_ptab_max(&erts_proc);
for (i = 0; i < max; i++) {
Process *proc = erts_pix2proc(i);
- if (proc) {
- clear_visited_p_links(&proc->common);
- clear_visited_p_monitors(&proc->common);
- erts_proc_sig_debug_foreach_sig(proc,
- noop_sig_msg,
- noop_sig_offheap,
- clear_visited_monitor,
- clear_visited_link,
- noop_sig_ext,
- (void *) proc);
- }
+ if (proc)
+ clear_process(proc);
}
+ erts_debug_free_process_foreach(clear_process2, NULL);
max = erts_ptab_max(&erts_port);
for (i = 0; i < max; i++) {
@@ -2413,28 +2468,42 @@ delete_reference_table(void)
if (state & ERTS_PORT_SFLGS_DEAD)
continue;
- clear_visited_p_links(&prt->common);
- clear_visited_p_monitors(&prt->common);
+ /* Clear links */
+ erts_link_tree_foreach(ERTS_P_LINKS(prt),
+ clear_visited_link,
+ (void *) &prt->common.id);
+ /* Clear monitors */
+ erts_monitor_tree_foreach(ERTS_P_MONITORS(prt),
+ clear_visited_monitor,
+ (void *) &prt->common.id);
+ /* Clear local target monitors */
+ erts_monitor_list_foreach(ERTS_P_LT_MONITORS(prt),
+ clear_visited_monitor,
+ (void *) &prt->common.id);
}
for(dep = erts_visible_dist_entries; dep; dep = dep->next) {
clear_visited_dist_links(dep);
clear_visited_dist_monitors(dep);
+ clear_dist_suspended_procs(dep);
}
for(dep = erts_hidden_dist_entries; dep; dep = dep->next) {
clear_visited_dist_links(dep);
clear_visited_dist_monitors(dep);
+ clear_dist_suspended_procs(dep);
}
for(dep = erts_pending_dist_entries; dep; dep = dep->next) {
clear_visited_dist_links(dep);
clear_visited_dist_monitors(dep);
+ clear_dist_suspended_procs(dep);
}
for(dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
clear_visited_dist_links(dep);
clear_visited_dist_monitors(dep);
+ clear_dist_suspended_procs(dep);
}
}
diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h
index aa8af12555..ffaafbbbea 100644
--- a/erts/emulator/beam/erl_node_tables.h
+++ b/erts/emulator/beam/erl_node_tables.h
@@ -187,6 +187,7 @@ set pagination off
set $i = 0
set $node = referred_nodes[$node_ix].node
while $i < $node->slot.counter
+ printf "%s:%d ", $node->books[$i].file, $node->books[$i].line
printf "%p: ", $node->books[$i].term
etp-1 $node->books[$i].who
printf " "
@@ -211,8 +212,12 @@ lists:usort(lists:filter(fun({V,N}) -> N /= 0 end, maps:to_list(Accs))).
struct erl_node_bookkeeping {
Eterm who;
Eterm term;
+ char *file;
+ int line;
enum { ERL_NODE_INC, ERL_NODE_DEC } what;
};
+
+#define ERTS_BOOKKEEP_SIZE (1024)
#endif
typedef struct erl_node_ {
@@ -222,7 +227,7 @@ typedef struct erl_node_ {
Uint32 creation; /* Creation */
DistEntry *dist_entry; /* Corresponding dist entry */
#ifdef ERL_NODE_BOOKKEEP
- struct erl_node_bookkeeping books[1024];
+ struct erl_node_bookkeeping books[ERTS_BOOKKEEP_SIZE];
erts_atomic_t slot;
#endif
} ErlNode;
@@ -276,14 +281,21 @@ Eterm erts_build_dhandle(Eterm **hpp, ErlOffHeap*, DistEntry*, Uint32 conn_id);
Eterm erts_make_dhandle(Process *c_p, DistEntry*, Uint32 conn_id);
ERTS_GLB_INLINE void erts_init_node_entry(ErlNode *np, erts_aint_t val);
+#ifdef ERL_NODE_BOOKKEEP
+#define erts_ref_node_entry(NP, MIN, T) erts_ref_node_entry__((NP), (MIN), (T), __FILE__, __LINE__)
+#define erts_deref_node_entry(NP, T) erts_deref_node_entry__((NP), (T), __FILE__, __LINE__)
+ERTS_GLB_INLINE erts_aint_t erts_ref_node_entry__(ErlNode *np, int min_val, Eterm term, char *file, int line);
+ERTS_GLB_INLINE void erts_deref_node_entry__(ErlNode *np, Eterm term, char *file, int line);
+#else
ERTS_GLB_INLINE erts_aint_t erts_ref_node_entry(ErlNode *np, int min_val, Eterm term);
ERTS_GLB_INLINE void erts_deref_node_entry(ErlNode *np, Eterm term);
+#endif
ERTS_GLB_INLINE void erts_de_rlock(DistEntry *dep);
ERTS_GLB_INLINE void erts_de_runlock(DistEntry *dep);
ERTS_GLB_INLINE void erts_de_rwlock(DistEntry *dep);
ERTS_GLB_INLINE void erts_de_rwunlock(DistEntry *dep);
#ifdef ERL_NODE_BOOKKEEP
-void erts_node_bookkeep(ErlNode *, Eterm , int);
+void erts_node_bookkeep(ErlNode *, Eterm , int, char *file, int line);
#else
#define erts_node_bookkeep(...)
#endif
@@ -296,21 +308,40 @@ erts_init_node_entry(ErlNode *np, erts_aint_t val)
erts_refc_init(&np->refc, val);
}
+#ifdef ERL_NODE_BOOKKEEP
+
+ERTS_GLB_INLINE erts_aint_t
+erts_ref_node_entry__(ErlNode *np, int min_val, Eterm term, char *file, int line)
+{
+ erts_node_bookkeep(np, term, ERL_NODE_INC, file, line);
+ return erts_refc_inctest(&np->refc, min_val);
+}
+
+ERTS_GLB_INLINE void
+erts_deref_node_entry__(ErlNode *np, Eterm term, char *file, int line)
+{
+ erts_node_bookkeep(np, term, ERL_NODE_DEC, file, line);
+ if (erts_refc_dectest(&np->refc, 0) == 0)
+ erts_schedule_delete_node(np);
+}
+
+#else
+
ERTS_GLB_INLINE erts_aint_t
erts_ref_node_entry(ErlNode *np, int min_val, Eterm term)
{
- erts_node_bookkeep(np, term, ERL_NODE_INC);
return erts_refc_inctest(&np->refc, min_val);
}
ERTS_GLB_INLINE void
erts_deref_node_entry(ErlNode *np, Eterm term)
{
- erts_node_bookkeep(np, term, ERL_NODE_DEC);
if (erts_refc_dectest(&np->refc, 0) == 0)
erts_schedule_delete_node(np);
}
+#endif
+
ERTS_GLB_INLINE void
erts_de_rlock(DistEntry *dep)
{
diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c
index 2e33a8a782..67c486a0db 100644
--- a/erts/emulator/beam/erl_printf_term.c
+++ b/erts/emulator/beam/erl_printf_term.c
@@ -533,13 +533,34 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount) {
case EXPORT_DEF:
{
Export* ep = *((Export **) (export_val(wobj) + 1));
- Atom* module = atom_tab(atom_val(ep->info.mfa.module));
- Atom* name = atom_tab(atom_val(ep->info.mfa.function));
+ long tdcount;
+ int tres;
PRINT_STRING(res, fn, arg, "fun ");
- PRINT_BUF(res, fn, arg, module->name, module->len);
+
+ /* We pass a temporary 'dcount' and adjust the real one later to ensure
+ * that the fun doesn't get split up between the module and function
+ * name. */
+ tdcount = MAX_ATOM_SZ_LIMIT;
+ tres = print_atom_name(fn, arg, ep->info.mfa.module, &tdcount);
+ if (tres < 0) {
+ res = tres;
+ goto L_done;
+ }
+ *dcount -= (MAX_ATOM_SZ_LIMIT - tdcount);
+ res += tres;
+
PRINT_CHAR(res, fn, arg, ':');
- PRINT_BUF(res, fn, arg, name->name, name->len);
+
+ tdcount = MAX_ATOM_SZ_LIMIT;
+ tres = print_atom_name(fn, arg, ep->info.mfa.function, &tdcount);
+ if (tres < 0) {
+ res = tres;
+ goto L_done;
+ }
+ *dcount -= (MAX_ATOM_SZ_LIMIT - tdcount);
+ res += tres;
+
PRINT_CHAR(res, fn, arg, '/');
PRINT_SWORD(res, fn, arg, 'd', 0, 1,
(ErlPfSWord) ep->info.mfa.arity);
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c
index fb900ca7ba..d5e0e3b218 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.c
+++ b/erts/emulator/beam/erl_proc_sig_queue.c
@@ -4689,10 +4689,12 @@ erts_proc_sig_debug_foreach_sig(Process *c_p,
case ERTS_SIG_Q_OP_MONITOR_DOWN:
switch (type) {
case ERTS_SIG_Q_TYPE_GEN_EXIT:
- if (ERTS_SIG_IS_GEN_EXIT_EXTERNAL(sig))
- debug_foreach_sig_external(sig, ext_func, arg);
- else
+ if (!ERTS_SIG_IS_GEN_EXIT_EXTERNAL(sig))
debug_foreach_sig_heap_frags(&sig->hfrag, oh_func, arg);
+ else {
+ oh_func(&sig->hfrag.off_heap, arg);
+ debug_foreach_sig_external(sig, ext_func, arg);
+ }
break;
case ERTS_LNK_TYPE_PORT:
case ERTS_LNK_TYPE_PROC:
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index de0564292d..1c1ef1db84 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -13468,3 +13468,79 @@ erts_debug_later_op_foreach(void (*callback)(void*),
}
}
}
+
+void
+erts_debug_free_process_foreach(void (*func)(Process *, void *), void *arg)
+{
+ ErtsRunQueue *rq;
+ int ix, prio;
+ for (ix = 0; ix < erts_no_run_queues; ix++) {
+ rq = ERTS_RUNQ_IX(ix);
+ for (prio = PRIORITY_MAX; prio < PRIORITY_LOW; prio++) {
+ Process *p = rq->procs.prio[prio].first;
+ for (; p; p = p->next) {
+ if (ERTS_PSFLG_FREE & erts_atomic32_read_nob(&p->state))
+ (*func)(p, arg);
+ }
+ }
+ }
+}
+
+void
+erts_debug_proc_monitor_link_foreach(Process *proc,
+ int (*monitor_func)(ErtsMonitor *, void *, Sint ),
+ int (*link_func)(ErtsLink *, void *, Sint ),
+ void *arg)
+{
+ if (!(erts_atomic32_read_nob(&proc->state) & ERTS_PSFLG_FREE)) {
+ /* For all links */
+ erts_link_tree_foreach(ERTS_P_LINKS(proc),
+ link_func,
+ arg);
+ /* For all monitors */
+ erts_monitor_tree_foreach(ERTS_P_MONITORS(proc),
+ monitor_func,
+ arg);
+ /* For all local target monitors */
+ erts_monitor_list_foreach(ERTS_P_LT_MONITORS(proc),
+ monitor_func,
+ arg);
+ }
+ else {
+ struct continue_exit_state *ce_state = proc->u.terminate;
+
+ /* For all links */
+ if (ce_state->phase == ERTS_CONTINUE_EXIT_LINKS)
+ erts_debug_link_tree_destroying_foreach(ce_state->links,
+ link_func,
+ arg,
+ ce_state->yield_state);
+ else
+ erts_link_tree_foreach(ce_state->links,
+ link_func,
+ arg);
+
+ /* For all monitors */
+ if (ce_state->phase == ERTS_CONTINUE_EXIT_MONITORS)
+ erts_debug_monitor_tree_destroying_foreach(ce_state->monitors,
+ monitor_func,
+ arg,
+ ce_state->yield_state);
+ else
+ erts_monitor_tree_foreach(ce_state->monitors,
+ monitor_func,
+ arg);
+
+ /* For all local target monitors */
+ if (ce_state->phase == ERTS_CONTINUE_EXIT_LT_MONITORS)
+ erts_debug_monitor_list_destroying_foreach(ce_state->lt_monitors,
+ monitor_func,
+ arg,
+ ce_state->yield_state);
+ else
+ erts_monitor_list_foreach(ce_state->lt_monitors,
+ monitor_func,
+ arg);
+
+ }
+}
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 745a2a482c..c0d7cfd13d 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -701,6 +701,13 @@ void
erts_debug_later_op_foreach(void (*callback)(void*),
void (*func)(void *, ErtsThrPrgrVal, void *),
void *arg);
+void
+erts_debug_free_process_foreach(void (*func)(Process *, void *), void *arg);
+void
+erts_debug_proc_monitor_link_foreach(Process *proc,
+ int (*monitor_func)(ErtsMonitor *, void *, Sint ),
+ int (*link_func)(ErtsLink *, void *, Sint ),
+ void *arg);
#ifdef ERTS_INCLUDE_SCHEDULER_INTERNALS
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 9c835ac357..f6f177887c 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -2194,11 +2194,12 @@ sys_msg_dispatcher_wait(void *vwait_p)
erts_mtx_unlock(&smq_mtx);
}
+static ErtsSysMsgQ *local_sys_message_queue = NULL;
+
static void *
sys_msg_dispatcher_func(void *unused)
{
ErtsThrPrgrCallbacks callbacks;
- ErtsSysMsgQ *local_sys_message_queue = NULL;
ErtsThrPrgrData *tpd;
int wait = 0;
@@ -2206,6 +2207,8 @@ sys_msg_dispatcher_func(void *unused)
erts_lc_set_thread_name("system message dispatcher");
#endif
+ local_sys_message_queue = NULL;
+
callbacks.arg = (void *) &wait;
callbacks.wakeup = sys_msg_dispatcher_wakeup;
callbacks.prepare_wait = sys_msg_dispatcher_prep_wait;
@@ -2262,6 +2265,8 @@ sys_msg_dispatcher_func(void *unused)
Process *proc = NULL;
Port *port = NULL;
+ ASSERT(is_value(smqp->msg));
+
if (erts_thr_progress_update(tpd))
erts_thr_progress_leader_update(tpd);
@@ -2374,6 +2379,7 @@ sys_msg_dispatcher_func(void *unused)
erts_fprintf(stderr, "dropped\n");
#endif
}
+ smqp->msg = THE_NON_VALUE;
}
}
@@ -2381,32 +2387,38 @@ sys_msg_dispatcher_func(void *unused)
}
void
-erts_foreach_sys_msg_in_q(void (*func)(Eterm,
- Eterm,
- Eterm,
- ErlHeapFragment *))
+erts_debug_foreach_sys_msg_in_q(void (*func)(Eterm,
+ Eterm,
+ Eterm,
+ ErlHeapFragment *))
{
- ErtsSysMsgQ *sm;
- erts_mtx_lock(&smq_mtx);
- for (sm = sys_message_queue; sm; sm = sm->next) {
- Eterm to;
- switch (sm->type) {
- case SYS_MSG_TYPE_SYSMON:
- to = erts_get_system_monitor();
- break;
- case SYS_MSG_TYPE_SYSPROF:
- to = erts_get_system_profile();
- break;
- case SYS_MSG_TYPE_ERRLGR:
- to = erts_get_system_logger();
- break;
- default:
- to = NIL;
- break;
- }
- (*func)(sm->from, to, sm->msg, sm->bp);
+ ErtsSysMsgQ *smq[] = {sys_message_queue, local_sys_message_queue};
+ int i;
+
+ ERTS_LC_ASSERT(erts_thr_progress_is_blocking());
+
+ for (i = 0; i < sizeof(smq)/sizeof(smq[0]); i++) {
+ ErtsSysMsgQ *sm;
+ for (sm = smq[i]; sm; sm = sm->next) {
+ Eterm to;
+ switch (sm->type) {
+ case SYS_MSG_TYPE_SYSMON:
+ to = erts_get_system_monitor();
+ break;
+ case SYS_MSG_TYPE_SYSPROF:
+ to = erts_get_system_profile();
+ break;
+ case SYS_MSG_TYPE_ERRLGR:
+ to = erts_get_system_logger();
+ break;
+ default:
+ to = NIL;
+ break;
+ }
+ if (is_value(sm->msg))
+ (*func)(sm->from, to, sm->msg, sm->bp);
+ }
}
- erts_mtx_unlock(&smq_mtx);
}
diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h
index b7844d1cb0..af38ef52db 100644
--- a/erts/emulator/beam/erl_trace.h
+++ b/erts/emulator/beam/erl_trace.h
@@ -90,10 +90,10 @@ int erts_is_tracer_valid(Process* p);
void erts_check_my_tracer_proc(Process *);
void erts_block_sys_msg_dispatcher(void);
void erts_release_sys_msg_dispatcher(void);
-void erts_foreach_sys_msg_in_q(void (*func)(Eterm,
- Eterm,
- Eterm,
- ErlHeapFragment *));
+void erts_debug_foreach_sys_msg_in_q(void (*func)(Eterm,
+ Eterm,
+ Eterm,
+ ErlHeapFragment *));
Eterm erts_set_system_logger(Eterm);
Eterm erts_get_system_logger(void);
void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 4c8d3d3dbe..0c2cf98033 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -907,7 +907,8 @@ Eterm erl_is_function(Process* p, Eterm arg1, Eterm arg2);
/* beam_bif_load.c */
Eterm erts_check_process_code(Process *c_p, Eterm module, int *redsp, int fcalls);
Eterm erts_proc_copy_literal_area(Process *c_p, int *redsp, int fcalls, int gc_allowed);
-
+void erts_debug_foreach_release_literal_area_off_heap(void (*func)(ErlOffHeap *, void *),
+ void *arg);
typedef struct ErtsLiteralArea_ {
struct erl_off_heap_header *off_heap;
Eterm *end;
@@ -1072,17 +1073,46 @@ Uint size_object_x(Eterm, erts_literal_area_t*);
#define size_object_litopt(Term,LitArea) size_object_x(Term,LitArea)
Uint copy_shared_calculate(Eterm, erts_shcopy_t*);
-Eterm copy_shared_perform(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*);
-
Uint size_shared(Eterm);
+/* #define ERTS_COPY_REGISTER_LOCATION */
+
+#ifdef ERTS_COPY_REGISTER_LOCATION
+
+#define copy_shared_perform(U, V, X, Y, Z) \
+ copy_shared_perform_x((U), (V), (X), (Y), (Z), __FILE__, __LINE__)
+Eterm copy_shared_perform_x(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*,
+ char *file, int line);
+
+Eterm copy_struct_x(Eterm, Uint, Eterm**, ErlOffHeap*, Uint*, erts_literal_area_t*,
+ char *file, int line);
+#define copy_struct(Obj,Sz,HPP,OH) \
+ copy_struct_x(Obj,Sz,HPP,OH,NULL,NULL,__FILE__,__LINE__)
+#define copy_struct_litopt(Obj,Sz,HPP,OH,LitArea) \
+ copy_struct_x(Obj,Sz,HPP,OH,NULL,LitArea,__FILE__,__LINE__)
+
+#define copy_shallow(R, SZ, HPP, OH) \
+ copy_shallow_x((R), (SZ), (HPP), (OH), __FILE__, __LINE__)
+Eterm copy_shallow_x(Eterm* ERTS_RESTRICT, Uint, Eterm**, ErlOffHeap*,
+ char *file, int line);
+
+#else
+
+#define copy_shared_perform(U, V, X, Y, Z) \
+ copy_shared_perform_x((U), (V), (X), (Y), (Z))
+Eterm copy_shared_perform_x(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*);
+
Eterm copy_struct_x(Eterm, Uint, Eterm**, ErlOffHeap*, Uint*, erts_literal_area_t*);
#define copy_struct(Obj,Sz,HPP,OH) \
copy_struct_x(Obj,Sz,HPP,OH,NULL,NULL)
#define copy_struct_litopt(Obj,Sz,HPP,OH,LitArea) \
copy_struct_x(Obj,Sz,HPP,OH,NULL,LitArea)
-Eterm copy_shallow(Eterm* ERTS_RESTRICT, Uint, Eterm**, ErlOffHeap*);
+#define copy_shallow(R, SZ, HPP, OH) \
+ copy_shallow_x((R), (SZ), (HPP), (OH))
+Eterm copy_shallow_x(Eterm* ERTS_RESTRICT, Uint, Eterm**, ErlOffHeap*);
+
+#endif
void erts_move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first,
Eterm* refs, unsigned nrefs, int literals);
@@ -1257,6 +1287,10 @@ Uint erts_persistent_term_count(void);
void erts_init_persistent_dumping(void);
extern ErtsLiteralArea** erts_persistent_areas;
extern Uint erts_num_persistent_areas;
+void erts_debug_foreach_persistent_term_off_heap(void (*func)(ErlOffHeap *, void *),
+ void *arg);
+int erts_debug_have_accessed_literal_area(ErtsLiteralArea *lap);
+void erts_debug_save_accessed_literal_area(ErtsLiteralArea *lap);
/* external.c */
void erts_init_external(void);
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 311c5fdd6a..66ff8d8450 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -12733,7 +12733,7 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
len -= 4; ptr += 4;
if (len < anc_len) goto return_einval;
- if (anc_len == 0 && !!0/*XXX-short-circuit-for-testing*/) {
+ if (anc_len == 0) {
/* Empty ancillary data */
/* Now "ptr" is the user data ptr, "len" is data length: */
inet_output_count(desc, len);
@@ -12772,10 +12772,7 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
if (compile_ancillary_data(&mhdr, ptr, anc_len) != 0) {
goto return_einval;
}
- if (mhdr.msg_controllen == 0) {
- /* XXX Testing - only possible for anc_len == 0 */
- mhdr.msg_control = NULL;
- }
+ ASSERT(mhdr.msg_controllen != 0);
len -= anc_len;
ptr += anc_len;
/* Now "ptr" is the user data ptr, "len" is data length: */
diff --git a/erts/emulator/nifs/common/net_nif.c b/erts/emulator/nifs/common/prim_net_nif.c
index 8a69052935..11a8ff724e 100644
--- a/erts/emulator/nifs/common/net_nif.c
+++ b/erts/emulator/nifs/common/prim_net_nif.c
@@ -1653,4 +1653,4 @@ LOCAL_ERROR_REASON_ATOMS
return !net;
}
-ERL_NIF_INIT(net, net_funcs, on_load, NULL, NULL, NULL)
+ERL_NIF_INIT(prim_net, net_funcs, on_load, NULL, NULL, NULL)
diff --git a/erts/emulator/nifs/common/socket_dbg.c b/erts/emulator/nifs/common/socket_dbg.c
index 7dfc4b77bc..0005575017 100644
--- a/erts/emulator/nifs/common/socket_dbg.c
+++ b/erts/emulator/nifs/common/socket_dbg.c
@@ -37,23 +37,23 @@
#define TNAME(__T__) enif_thread_name( __T__ )
#define TSNAME() TNAME(TSELF())
-static FILE* dbgout = NULL;
+FILE* esock_dbgout = NULL;
extern
void esock_dbg_init(char* filename)
{
if (filename != NULL) {
if (strcmp(filename, ESOCK_DBGOUT_DEFAULT) == 0) {
- dbgout = stdout;
+ esock_dbgout = stdout;
} else if (strcmp(filename, ESOCK_DBGOUT_UNIQUE) == 0) {
- char template[] = "/tmp/esock-dbg-XXXXXX";
- dbgout = fdopen(mkstemp(template), "w+");
+ char template[] = "/tmp/esock-dbg-XXXXXX";
+ esock_dbgout = fdopen(mkstemp(template), "w+");
} else {
- dbgout = fopen(filename, "w+");
+ esock_dbgout = fopen(filename, "w+");
}
} else {
char template[] = "/tmp/esock-dbg-XXXXXX";
- dbgout = fdopen(mkstemp(template), "w+");
+ esock_dbgout = fdopen(mkstemp(template), "w+");
}
}
@@ -67,7 +67,7 @@ extern
void esock_dbg_printf( const char* prefix, const char* format, ... )
{
va_list args;
- char f[512 + sizeof(format)]; // This has to suffice...
+ char f[512 + strlen(format)]; // This has to suffice...
char stamp[30];
int res;
@@ -87,9 +87,9 @@ void esock_dbg_printf( const char* prefix, const char* format, ... )
if (res > 0) {
va_start (args, format);
- enif_vfprintf (dbgout, f, args);
+ enif_vfprintf (esock_dbgout, f, args);
va_end (args);
- fflush(dbgout);
+ fflush(esock_dbgout);
}
return;
diff --git a/erts/emulator/nifs/common/socket_dbg.h b/erts/emulator/nifs/common/socket_dbg.h
index 47739b46da..8fce211a8a 100644
--- a/erts/emulator/nifs/common/socket_dbg.h
+++ b/erts/emulator/nifs/common/socket_dbg.h
@@ -40,12 +40,12 @@
#endif
typedef unsigned long long llu_t;
-
+extern FILE* esock_dbgout; // Initiated by the 'init' function
#define ESOCK_DBG_PRINTF( ___COND___ , proto ) \
if ( ___COND___ ) { \
esock_dbg_printf proto; \
- fflush(stdout); \
+ fflush(esock_dbgout); \
}
diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h
index d6977be5aa..4161775a04 100644
--- a/erts/emulator/nifs/common/socket_int.h
+++ b/erts/emulator/nifs/common/socket_int.h
@@ -102,6 +102,9 @@ typedef unsigned int BOOLEAN_T;
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* "Global" atoms
+ *
+ * Note that when an (global) atom is added here, it must also be added
+ * in the socket_nif.c file!
*/
#define GLOBAL_ATOM_DEFS \
@@ -130,6 +133,7 @@ typedef unsigned int BOOLEAN_T;
GLOBAL_ATOM_DEF(busy_poll); \
GLOBAL_ATOM_DEF(checksum); \
GLOBAL_ATOM_DEF(close); \
+ GLOBAL_ATOM_DEF(command); \
GLOBAL_ATOM_DEF(connect); \
GLOBAL_ATOM_DEF(congestion); \
GLOBAL_ATOM_DEF(context); \
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 56a16a87a1..bbeb8b6cdd 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -24,7 +24,7 @@
* The first function is called 'nif_<something>', e.g. nif_open.
* This does the initial validation and argument processing and then
* calls the function that does the actual work. This is called
- * 'n<something>'.
+ * 'esock_<something>'.
* ----------------------------------------------------------------------
*
*
@@ -354,11 +354,11 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL;
/* Debug stuff... */
-#define SOCKET_GLOBAL_DEBUG_DEFAULT FALSE
-#define SOCKET_DEBUG_DEFAULT FALSE
+#define ESOCK_GLOBAL_DEBUG_DEFAULT FALSE
+#define ESOCK_DEBUG_DEFAULT FALSE
/* Counters and stuff (Don't know where to sent this stuff anyway) */
-#define SOCKET_NIF_IOW_DEFAULT FALSE
+#define ESOCK_NIF_IOW_DEFAULT FALSE
@@ -398,10 +398,10 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL;
#if defined(TCP_CA_NAME_MAX)
-#define SOCKET_OPT_TCP_CONGESTION_NAME_MAX TCP_CA_NAME_MAX
+#define ESOCK_OPT_TCP_CONGESTION_NAME_MAX TCP_CA_NAME_MAX
#else
/* This is really excessive, but just in case... */
-#define SOCKET_OPT_TCP_CONGESTION_NAME_MAX 256
+#define ESOCK_OPT_TCP_CONGESTION_NAME_MAX 256
#endif
@@ -414,25 +414,25 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL;
/* *** Socket state defs *** */
-#define SOCKET_FLAG_OPEN 0x0001
-#define SOCKET_FLAG_ACTIVE 0x0004
-#define SOCKET_FLAG_LISTEN 0x0008
-#define SOCKET_FLAG_CON 0x0010
-#define SOCKET_FLAG_ACC 0x0020
-#define SOCKET_FLAG_BUSY 0x0040
-#define SOCKET_FLAG_CLOSE 0x0080
-
-#define SOCKET_STATE_CLOSED (0)
-#define SOCKET_STATE_OPEN (SOCKET_FLAG_OPEN)
-#define SOCKET_STATE_CONNECTED (SOCKET_STATE_OPEN | SOCKET_FLAG_ACTIVE)
-#define SOCKET_STATE_LISTENING (SOCKET_STATE_OPEN | SOCKET_FLAG_LISTEN)
-#define SOCKET_STATE_CONNECTING (SOCKET_STATE_OPEN | SOCKET_FLAG_CON)
-#define SOCKET_STATE_ACCEPTING (SOCKET_STATE_LISTENING | SOCKET_FLAG_ACC)
-#define SOCKET_STATE_CLOSING (SOCKET_FLAG_CLOSE)
-#define SOCKET_STATE_DTOR (0xFFFF)
+#define ESOCK_FLAG_OPEN 0x0001
+#define ESOCK_FLAG_ACTIVE 0x0004
+#define ESOCK_FLAG_LISTEN 0x0008
+#define ESOCK_FLAG_CON 0x0010
+#define ESOCK_FLAG_ACC 0x0020
+#define ESOCK_FLAG_BUSY 0x0040
+#define ESOCK_FLAG_CLOSE 0x0080
+
+#define ESOCK_STATE_CLOSED (0)
+#define ESOCK_STATE_OPEN (ESOCK_FLAG_OPEN)
+#define ESOCK_STATE_CONNECTED (ESOCK_STATE_OPEN | ESOCK_FLAG_ACTIVE)
+#define ESOCK_STATE_LISTENING (ESOCK_STATE_OPEN | ESOCK_FLAG_LISTEN)
+#define ESOCK_STATE_CONNECTING (ESOCK_STATE_OPEN | ESOCK_FLAG_CON)
+#define ESOCK_STATE_ACCEPTING (ESOCK_STATE_LISTENING | ESOCK_FLAG_ACC)
+#define ESOCK_STATE_CLOSING (ESOCK_FLAG_CLOSE)
+#define ESOCK_STATE_DTOR (0xFFFF)
#define IS_CLOSED(d) \
- ((d)->state == SOCKET_STATE_CLOSED)
+ ((d)->state == ESOCK_STATE_CLOSED)
/*
#define IS_STATE(d, f) \
@@ -440,55 +440,59 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL;
*/
#define IS_CLOSING(d) \
- (((d)->state & SOCKET_STATE_CLOSING) == SOCKET_STATE_CLOSING)
+ (((d)->state & ESOCK_STATE_CLOSING) == ESOCK_STATE_CLOSING)
#define IS_OPEN(d) \
- (((d)->state & SOCKET_FLAG_OPEN) == SOCKET_FLAG_OPEN)
+ (((d)->state & ESOCK_FLAG_OPEN) == ESOCK_FLAG_OPEN)
#define IS_CONNECTED(d) \
- (((d)->state & SOCKET_STATE_CONNECTED) == SOCKET_STATE_CONNECTED)
+ (((d)->state & ESOCK_STATE_CONNECTED) == ESOCK_STATE_CONNECTED)
#define IS_CONNECTING(d) \
- (((d)->state & SOCKET_FLAG_CON) == SOCKET_FLAG_CON)
+ (((d)->state & ESOCK_FLAG_CON) == ESOCK_FLAG_CON)
/*
#define IS_BUSY(d) \
- (((d)->state & SOCKET_FLAG_BUSY) == SOCKET_FLAG_BUSY)
+ (((d)->state & ESOCK_FLAG_BUSY) == ESOCK_FLAG_BUSY)
*/
-#define SOCKET_SEND_FLAG_CONFIRM 0
-#define SOCKET_SEND_FLAG_DONTROUTE 1
-#define SOCKET_SEND_FLAG_EOR 2
-#define SOCKET_SEND_FLAG_MORE 3
-#define SOCKET_SEND_FLAG_NOSIGNAL 4
-#define SOCKET_SEND_FLAG_OOB 5
-#define SOCKET_SEND_FLAG_LOW SOCKET_SEND_FLAG_CONFIRM
-#define SOCKET_SEND_FLAG_HIGH SOCKET_SEND_FLAG_OOB
-
-#define SOCKET_RECV_FLAG_CMSG_CLOEXEC 0
-#define SOCKET_RECV_FLAG_ERRQUEUE 1
-#define SOCKET_RECV_FLAG_OOB 2
-#define SOCKET_RECV_FLAG_PEEK 3
-#define SOCKET_RECV_FLAG_TRUNC 4
-#define SOCKET_RECV_FLAG_LOW SOCKET_RECV_FLAG_CMSG_CLOEXEC
-#define SOCKET_RECV_FLAG_HIGH SOCKET_RECV_FLAG_TRUNC
-
-#define SOCKET_RECV_BUFFER_SIZE_DEFAULT 8192
-#define SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT 1024
-#define SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT 1024
-
-#define VT2S(__VT__) (((__VT__) == SOCKET_OPT_VALUE_TYPE_UNSPEC) ? "unspec" : \
- (((__VT__) == SOCKET_OPT_VALUE_TYPE_INT) ? "int" : \
- ((__VT__) == SOCKET_OPT_VALUE_TYPE_BOOL) ? "bool" : \
+#define ESOCK_GET_RESOURCE(ENV, REF, RES) \
+ enif_get_resource((ENV), (REF), esocks, (RES))
+
+#define ESOCK_SEND_FLAG_CONFIRM 0
+#define ESOCK_SEND_FLAG_DONTROUTE 1
+#define ESOCK_SEND_FLAG_EOR 2
+#define ESOCK_SEND_FLAG_MORE 3
+#define ESOCK_SEND_FLAG_NOSIGNAL 4
+#define ESOCK_SEND_FLAG_OOB 5
+#define ESOCK_SEND_FLAG_LOW ESOCK_SEND_FLAG_CONFIRM
+#define ESOCK_SEND_FLAG_HIGH ESOCK_SEND_FLAG_OOB
+
+#define ESOCK_RECV_FLAG_CMSG_CLOEXEC 0
+#define ESOCK_RECV_FLAG_ERRQUEUE 1
+#define ESOCK_RECV_FLAG_OOB 2
+#define ESOCK_RECV_FLAG_PEEK 3
+#define ESOCK_RECV_FLAG_TRUNC 4
+#define ESOCK_RECV_FLAG_LOW ESOCK_RECV_FLAG_CMSG_CLOEXEC
+#define ESOCK_RECV_FLAG_HIGH ESOCK_RECV_FLAG_TRUNC
+
+#define ESOCK_RECV_BUFFER_SIZE_DEFAULT 8192
+#define ESOCK_RECV_CTRL_BUFFER_SIZE_DEFAULT 1024
+#define ESOCK_SEND_CTRL_BUFFER_SIZE_DEFAULT 1024
+
+#define VT2S(__VT__) (((__VT__) == ESOCK_OPT_VALUE_TYPE_UNSPEC) ? "unspec" : \
+ (((__VT__) == ESOCK_OPT_VALUE_TYPE_INT) ? "int" : \
+ ((__VT__) == ESOCK_OPT_VALUE_TYPE_BOOL) ? "bool" : \
"undef"))
-#define SOCKET_OPT_VALUE_TYPE_UNSPEC 0
-#define SOCKET_OPT_VALUE_TYPE_INT 1
-#define SOCKET_OPT_VALUE_TYPE_BOOL 2
+#define ESOCK_OPT_VALUE_TYPE_UNSPEC 0
+#define ESOCK_OPT_VALUE_TYPE_INT 1
+#define ESOCK_OPT_VALUE_TYPE_BOOL 2
#define ESOCK_DESC_PATTERN_CREATED 0x03030303
#define ESOCK_DESC_PATTERN_DTOR 0xC0C0C0C0
+/*
typedef union {
struct {
// 0 = not open, 1 = open
@@ -501,15 +505,16 @@ typedef union {
unsigned int listen:2;
// unsigned int listening:1;
// unsigned int accepting:1;
- /* Room for more... */
+ / * Room for more... * /
} flags;
unsigned int field; // Make it easy to reset all flags...
} SocketState;
+*/
/*
#define IS_OPEN(d) ((d)->state.flags.open)
-#define IS_CONNECTED(d) ((d)->state.flags.connect == SOCKET_STATE_CONNECTED)
-#define IS_CONNECTING(d) ((d)->state.flags.connect == SOCKET_STATE_CONNECTING)
+#define IS_CONNECTED(d) ((d)->state.flags.connect == ESOCK_STATE_CONNECTED)
+#define IS_CONNECTING(d) ((d)->state.flags.connect == ESOCK_STATE_CONNECTING)
*/
@@ -520,150 +525,151 @@ typedef union {
*/
/* domain */
-#define SOCKET_DOMAIN_LOCAL 1
-#define SOCKET_DOMAIN_INET 2
-#define SOCKET_DOMAIN_INET6 3
+#define ESOCK_DOMAIN_LOCAL 1
+#define ESOCK_DOMAIN_INET 2
+#define ESOCK_DOMAIN_INET6 3
/* type */
-#define SOCKET_TYPE_STREAM 1
-#define SOCKET_TYPE_DGRAM 2
-#define SOCKET_TYPE_RAW 3
-// #define SOCKET_TYPE_RDM 4
-#define SOCKET_TYPE_SEQPACKET 5
+#define ESOCK_TYPE_STREAM 1
+#define ESOCK_TYPE_DGRAM 2
+#define ESOCK_TYPE_RAW 3
+// #define ESOCK_TYPE_RDM 4
+#define ESOCK_TYPE_SEQPACKET 5
/* protocol */
-#define SOCKET_PROTOCOL_DEFAULT 0
-#define SOCKET_PROTOCOL_IP 1
-#define SOCKET_PROTOCOL_TCP 2
-#define SOCKET_PROTOCOL_UDP 3
-#define SOCKET_PROTOCOL_SCTP 4
-#define SOCKET_PROTOCOL_ICMP 5
-#define SOCKET_PROTOCOL_IGMP 6
+#define ESOCK_PROTOCOL_DEFAULT 0
+#define ESOCK_PROTOCOL_IP 1
+#define ESOCK_PROTOCOL_TCP 2
+#define ESOCK_PROTOCOL_UDP 3
+#define ESOCK_PROTOCOL_SCTP 4
+#define ESOCK_PROTOCOL_ICMP 5
+#define ESOCK_PROTOCOL_IGMP 6
/* shutdown how */
-#define SOCKET_SHUTDOWN_HOW_RD 0
-#define SOCKET_SHUTDOWN_HOW_WR 1
-#define SOCKET_SHUTDOWN_HOW_RDWR 2
-
-
-#define SOCKET_OPT_LEVEL_OTP 0
-#define SOCKET_OPT_LEVEL_SOCKET 1
-#define SOCKET_OPT_LEVEL_IP 2
-#define SOCKET_OPT_LEVEL_IPV6 3
-#define SOCKET_OPT_LEVEL_TCP 4
-#define SOCKET_OPT_LEVEL_UDP 5
-#define SOCKET_OPT_LEVEL_SCTP 6
-
-#define SOCKET_OPT_OTP_DEBUG 1
-#define SOCKET_OPT_OTP_IOW 2
-#define SOCKET_OPT_OTP_CTRL_PROC 3
-#define SOCKET_OPT_OTP_RCVBUF 4
-#define SOCKET_OPT_OTP_RCVCTRLBUF 6
-#define SOCKET_OPT_OTP_SNDCTRLBUF 7
-#define SOCKET_OPT_OTP_FD 8
-#define SOCKET_OPT_OTP_DOMAIN 0xFF01 // INTERNAL AND ONLY GET
-#define SOCKET_OPT_OTP_TYPE 0xFF02 // INTERNAL AND ONLY GET
-#define SOCKET_OPT_OTP_PROTOCOL 0xFF03 // INTERNAL AND ONLY GET
-
-#define SOCKET_OPT_SOCK_ACCEPTCONN 1
-#define SOCKET_OPT_SOCK_BINDTODEVICE 3
-#define SOCKET_OPT_SOCK_BROADCAST 4
-#define SOCKET_OPT_SOCK_DEBUG 6
-#define SOCKET_OPT_SOCK_DOMAIN 7
-#define SOCKET_OPT_SOCK_DONTROUTE 8
-#define SOCKET_OPT_SOCK_KEEPALIVE 10
-#define SOCKET_OPT_SOCK_LINGER 11
-#define SOCKET_OPT_SOCK_OOBINLINE 13
-#define SOCKET_OPT_SOCK_PEEK_OFF 15
-#define SOCKET_OPT_SOCK_PRIORITY 17
-#define SOCKET_OPT_SOCK_PROTOCOL 18
-#define SOCKET_OPT_SOCK_RCVBUF 19
-#define SOCKET_OPT_SOCK_RCVLOWAT 21
-#define SOCKET_OPT_SOCK_RCVTIMEO 22
-#define SOCKET_OPT_SOCK_REUSEADDR 23
-#define SOCKET_OPT_SOCK_REUSEPORT 24
-#define SOCKET_OPT_SOCK_SNDBUF 27
-#define SOCKET_OPT_SOCK_SNDLOWAT 29
-#define SOCKET_OPT_SOCK_SNDTIMEO 30
-#define SOCKET_OPT_SOCK_TIMESTAMP 31
-#define SOCKET_OPT_SOCK_TYPE 32
-
-#define SOCKET_OPT_IP_ADD_MEMBERSHIP 1
-#define SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP 2
-#define SOCKET_OPT_IP_BLOCK_SOURCE 3
-#define SOCKET_OPT_IP_DROP_MEMBERSHIP 5
-#define SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP 6
-#define SOCKET_OPT_IP_FREEBIND 7
-#define SOCKET_OPT_IP_HDRINCL 8
-#define SOCKET_OPT_IP_MINTTL 9
-#define SOCKET_OPT_IP_MSFILTER 10
-#define SOCKET_OPT_IP_MTU 11
-#define SOCKET_OPT_IP_MTU_DISCOVER 12
-#define SOCKET_OPT_IP_MULTICAST_ALL 13
-#define SOCKET_OPT_IP_MULTICAST_IF 14
-#define SOCKET_OPT_IP_MULTICAST_LOOP 15
-#define SOCKET_OPT_IP_MULTICAST_TTL 16
-#define SOCKET_OPT_IP_NODEFRAG 17
-#define SOCKET_OPT_IP_PKTINFO 19
-#define SOCKET_OPT_IP_RECVDSTADDR 20
-#define SOCKET_OPT_IP_RECVERR 21
-#define SOCKET_OPT_IP_RECVIF 22
-#define SOCKET_OPT_IP_RECVOPTS 23
-#define SOCKET_OPT_IP_RECVORIGDSTADDR 24
-#define SOCKET_OPT_IP_RECVTOS 25
-#define SOCKET_OPT_IP_RECVTTL 26
-#define SOCKET_OPT_IP_RETOPTS 27
-#define SOCKET_OPT_IP_ROUTER_ALERT 28
-#define SOCKET_OPT_IP_SENDSRCADDR 29 // Same as IP_RECVDSTADDR?
-#define SOCKET_OPT_IP_TOS 30
-#define SOCKET_OPT_IP_TRANSPARENT 31
-#define SOCKET_OPT_IP_TTL 32
-#define SOCKET_OPT_IP_UNBLOCK_SOURCE 33
-
-#define SOCKET_OPT_IPV6_ADDRFORM 1
-#define SOCKET_OPT_IPV6_ADD_MEMBERSHIP 2
-#define SOCKET_OPT_IPV6_AUTHHDR 3
-#define SOCKET_OPT_IPV6_DROP_MEMBERSHIP 6
-#define SOCKET_OPT_IPV6_DSTOPTS 7
-#define SOCKET_OPT_IPV6_FLOWINFO 11
-#define SOCKET_OPT_IPV6_HOPLIMIT 12
-#define SOCKET_OPT_IPV6_HOPOPTS 13
-#define SOCKET_OPT_IPV6_MTU 17
-#define SOCKET_OPT_IPV6_MTU_DISCOVER 18
-#define SOCKET_OPT_IPV6_MULTICAST_HOPS 19
-#define SOCKET_OPT_IPV6_MULTICAST_IF 20
-#define SOCKET_OPT_IPV6_MULTICAST_LOOP 21
-#define SOCKET_OPT_IPV6_RECVERR 24
-#define SOCKET_OPT_IPV6_RECVPKTINFO 25 // PKTINFO on FreeBSD
-#define SOCKET_OPT_IPV6_ROUTER_ALERT 27
-#define SOCKET_OPT_IPV6_RTHDR 28
-#define SOCKET_OPT_IPV6_UNICAST_HOPS 30
-#define SOCKET_OPT_IPV6_V6ONLY 32
-
-#define SOCKET_OPT_TCP_CONGESTION 1
-#define SOCKET_OPT_TCP_CORK 2
-#define SOCKET_OPT_TCP_MAXSEG 7
-#define SOCKET_OPT_TCP_NODELAY 9
-
-#define SOCKET_OPT_UDP_CORK 1
-
-#define SOCKET_OPT_SCTP_ASSOCINFO 2
-#define SOCKET_OPT_SCTP_AUTOCLOSE 8
-#define SOCKET_OPT_SCTP_DISABLE_FRAGMENTS 12
-#define SOCKET_OPT_SCTP_EVENTS 14
-#define SOCKET_OPT_SCTP_INITMSG 18
-#define SOCKET_OPT_SCTP_MAXSEG 21
-#define SOCKET_OPT_SCTP_NODELAY 23
-#define SOCKET_OPT_SCTP_RTOINFO 29
+#define ESOCK_SHUTDOWN_HOW_RD 0
+#define ESOCK_SHUTDOWN_HOW_WR 1
+#define ESOCK_SHUTDOWN_HOW_RDWR 2
+
+
+#define ESOCK_OPT_LEVEL_OTP 0
+#define ESOCK_OPT_LEVEL_SOCKET 1
+#define ESOCK_OPT_LEVEL_IP 2
+#define ESOCK_OPT_LEVEL_IPV6 3
+#define ESOCK_OPT_LEVEL_TCP 4
+#define ESOCK_OPT_LEVEL_UDP 5
+#define ESOCK_OPT_LEVEL_SCTP 6
+
+#define ESOCK_OPT_OTP_DEBUG 1
+#define ESOCK_OPT_OTP_IOW 2
+#define ESOCK_OPT_OTP_CTRL_PROC 3
+#define ESOCK_OPT_OTP_RCVBUF 4
+#define ESOCK_OPT_OTP_RCVCTRLBUF 6
+#define ESOCK_OPT_OTP_SNDCTRLBUF 7
+#define ESOCK_OPT_OTP_FD 8
+#define ESOCK_OPT_OTP_DOMAIN 0xFF01 // INTERNAL AND ONLY GET
+#define ESOCK_OPT_OTP_TYPE 0xFF02 // INTERNAL AND ONLY GET
+#define ESOCK_OPT_OTP_PROTOCOL 0xFF03 // INTERNAL AND ONLY GET
+
+#define ESOCK_OPT_SOCK_ACCEPTCONN 1
+#define ESOCK_OPT_SOCK_BINDTODEVICE 3
+#define ESOCK_OPT_SOCK_BROADCAST 4
+#define ESOCK_OPT_SOCK_DEBUG 6
+#define ESOCK_OPT_SOCK_DOMAIN 7
+#define ESOCK_OPT_SOCK_DONTROUTE 8
+#define ESOCK_OPT_SOCK_KEEPALIVE 10
+#define ESOCK_OPT_SOCK_LINGER 11
+#define ESOCK_OPT_SOCK_OOBINLINE 13
+#define ESOCK_OPT_SOCK_PEEK_OFF 15
+#define ESOCK_OPT_SOCK_PRIORITY 17
+#define ESOCK_OPT_SOCK_PROTOCOL 18
+#define ESOCK_OPT_SOCK_RCVBUF 19
+#define ESOCK_OPT_SOCK_RCVLOWAT 21
+#define ESOCK_OPT_SOCK_RCVTIMEO 22
+#define ESOCK_OPT_SOCK_REUSEADDR 23
+#define ESOCK_OPT_SOCK_REUSEPORT 24
+#define ESOCK_OPT_SOCK_SNDBUF 27
+#define ESOCK_OPT_SOCK_SNDLOWAT 29
+#define ESOCK_OPT_SOCK_SNDTIMEO 30
+#define ESOCK_OPT_SOCK_TIMESTAMP 31
+#define ESOCK_OPT_SOCK_TYPE 32
+
+#define ESOCK_OPT_IP_ADD_MEMBERSHIP 1
+#define ESOCK_OPT_IP_ADD_SOURCE_MEMBERSHIP 2
+#define ESOCK_OPT_IP_BLOCK_SOURCE 3
+#define ESOCK_OPT_IP_DROP_MEMBERSHIP 5
+#define ESOCK_OPT_IP_DROP_SOURCE_MEMBERSHIP 6
+#define ESOCK_OPT_IP_FREEBIND 7
+#define ESOCK_OPT_IP_HDRINCL 8
+#define ESOCK_OPT_IP_MINTTL 9
+#define ESOCK_OPT_IP_MSFILTER 10
+#define ESOCK_OPT_IP_MTU 11
+#define ESOCK_OPT_IP_MTU_DISCOVER 12
+#define ESOCK_OPT_IP_MULTICAST_ALL 13
+#define ESOCK_OPT_IP_MULTICAST_IF 14
+#define ESOCK_OPT_IP_MULTICAST_LOOP 15
+#define ESOCK_OPT_IP_MULTICAST_TTL 16
+#define ESOCK_OPT_IP_NODEFRAG 17
+#define ESOCK_OPT_IP_PKTINFO 19
+#define ESOCK_OPT_IP_RECVDSTADDR 20
+#define ESOCK_OPT_IP_RECVERR 21
+#define ESOCK_OPT_IP_RECVIF 22
+#define ESOCK_OPT_IP_RECVOPTS 23
+#define ESOCK_OPT_IP_RECVORIGDSTADDR 24
+#define ESOCK_OPT_IP_RECVTOS 25
+#define ESOCK_OPT_IP_RECVTTL 26
+#define ESOCK_OPT_IP_RETOPTS 27
+#define ESOCK_OPT_IP_ROUTER_ALERT 28
+#define ESOCK_OPT_IP_SENDSRCADDR 29 // Same as IP_RECVDSTADDR?
+#define ESOCK_OPT_IP_TOS 30
+#define ESOCK_OPT_IP_TRANSPARENT 31
+#define ESOCK_OPT_IP_TTL 32
+#define ESOCK_OPT_IP_UNBLOCK_SOURCE 33
+
+#define ESOCK_OPT_IPV6_ADDRFORM 1
+#define ESOCK_OPT_IPV6_ADD_MEMBERSHIP 2
+#define ESOCK_OPT_IPV6_AUTHHDR 3
+#define ESOCK_OPT_IPV6_DROP_MEMBERSHIP 6
+#define ESOCK_OPT_IPV6_DSTOPTS 7
+#define ESOCK_OPT_IPV6_FLOWINFO 11
+#define ESOCK_OPT_IPV6_HOPLIMIT 12
+#define ESOCK_OPT_IPV6_HOPOPTS 13
+#define ESOCK_OPT_IPV6_MTU 17
+#define ESOCK_OPT_IPV6_MTU_DISCOVER 18
+#define ESOCK_OPT_IPV6_MULTICAST_HOPS 19
+#define ESOCK_OPT_IPV6_MULTICAST_IF 20
+#define ESOCK_OPT_IPV6_MULTICAST_LOOP 21
+#define ESOCK_OPT_IPV6_RECVERR 24
+#define ESOCK_OPT_IPV6_RECVPKTINFO 25 // PKTINFO on FreeBSD
+#define ESOCK_OPT_IPV6_ROUTER_ALERT 27
+#define ESOCK_OPT_IPV6_RTHDR 28
+#define ESOCK_OPT_IPV6_UNICAST_HOPS 30
+#define ESOCK_OPT_IPV6_V6ONLY 32
+
+#define ESOCK_OPT_TCP_CONGESTION 1
+#define ESOCK_OPT_TCP_CORK 2
+#define ESOCK_OPT_TCP_MAXSEG 7
+#define ESOCK_OPT_TCP_NODELAY 9
+
+#define ESOCK_OPT_UDP_CORK 1
+
+#define ESOCK_OPT_SCTP_ASSOCINFO 2
+#define ESOCK_OPT_SCTP_AUTOCLOSE 8
+#define ESOCK_OPT_SCTP_DISABLE_FRAGMENTS 12
+#define ESOCK_OPT_SCTP_EVENTS 14
+#define ESOCK_OPT_SCTP_INITMSG 18
+#define ESOCK_OPT_SCTP_MAXSEG 21
+#define ESOCK_OPT_SCTP_NODELAY 23
+#define ESOCK_OPT_SCTP_RTOINFO 29
/* We should *eventually* use this instead of hard-coding the size (to 1) */
#define ESOCK_RECVMSG_IOVEC_SZ 1
+#define ESOCK_CMD_DEBUG 0x0001
-#define SOCKET_SUPPORTS_OPTIONS 0x0001
-#define SOCKET_SUPPORTS_SCTP 0x0002
-#define SOCKET_SUPPORTS_IPV6 0x0003
-#define SOCKET_SUPPORTS_LOCAL 0x0004
+#define ESOCK_SUPPORTS_OPTIONS 0x0001
+#define ESOCK_SUPPORTS_SCTP 0x0002
+#define ESOCK_SUPPORTS_IPV6 0x0003
+#define ESOCK_SUPPORTS_LOCAL 0x0004
#define ESOCK_WHICH_PROTO_ERROR -1
#define ESOCK_WHICH_PROTO_UNSUP -2
@@ -672,7 +678,7 @@ typedef union {
/* =================================================================== *
* *
- * Various enif macros *
+ * Various esockmacros *
* *
* =================================================================== */
@@ -681,6 +687,12 @@ typedef union {
/* Socket specific debug */
#define SSDBG( __D__ , proto ) ESOCK_DBG_PRINTF( (__D__)->dbg , proto )
+#define SOCK_CNT_INC( __E__, __D__, SF, ACNT, CNT, INC) \
+ { \
+ if (cnt_inc(CNT, INC) && (__D__)->iow) { \
+ esock_send_wrap_msg(__E__, __D__, SF, ACNT); \
+ } \
+ }
/* =================================================================== *
@@ -865,6 +877,7 @@ typedef struct {
Uint32 readByteCnt;
Uint32 readTries;
Uint32 readWaits;
+ Uint32 readFails;
/* +++ Accept stuff +++ */
ErlNifMutex* accMtx;
@@ -948,6 +961,7 @@ extern char* erl_errno_id(int error); /* THIS IS JUST TEMPORARY??? */
* does the actual work. Except for the info function.
*
* nif_info
+ * nif_command
* nif_supports
* nif_open
* nif_bind
@@ -973,6 +987,7 @@ extern char* erl_errno_id(int error); /* THIS IS JUST TEMPORARY??? */
#define ESOCK_NIF_FUNCS \
ESOCK_NIF_FUNC_DEF(info); \
+ ESOCK_NIF_FUNC_DEF(command); \
ESOCK_NIF_FUNC_DEF(supports); \
ESOCK_NIF_FUNC_DEF(open); \
ESOCK_NIF_FUNC_DEF(bind); \
@@ -1004,1110 +1019,1143 @@ ESOCK_NIF_FUNCS
#if !defined(__WIN32__)
+
/* And here comes the functions that does the actual work (for the most part) */
-static ERL_NIF_TERM nsupports(ErlNifEnv* env, int key);
-static ERL_NIF_TERM nsupports_options(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env);
-static ERL_NIF_TERM nsupports_local(ErlNifEnv* env);
-
-static ERL_NIF_TERM nopen(ErlNifEnv* env,
+
+static BOOLEAN_T ecommand2command(ErlNifEnv* env,
+ ERL_NIF_TERM ecommand,
+ Uint16* command,
+ ERL_NIF_TERM* edata);
+static ERL_NIF_TERM esock_command(ErlNifEnv* env,
+ Uint16 cmd,
+ ERL_NIF_TERM ecdata);
+static ERL_NIF_TERM esock_command_debug(ErlNifEnv* env, ERL_NIF_TERM ecdata);
+
+static ERL_NIF_TERM esock_global_info(ErlNifEnv* env);
+static ERL_NIF_TERM esock_socket_info(ErlNifEnv* env,
+ ESockDescriptor* descP);
+static ERL_NIF_TERM esock_socket_info_counters(ErlNifEnv* env,
+ ESockDescriptor* descP);
+#define ESOCK_SOCKET_INFO_REQ_FUNCS \
+ ESOCK_SOCKET_INFO_REQ_FUNC_DEF(readers); \
+ ESOCK_SOCKET_INFO_REQ_FUNC_DEF(writers); \
+ ESOCK_SOCKET_INFO_REQ_FUNC_DEF(acceptors);
+
+#define ESOCK_SOCKET_INFO_REQ_FUNC_DEF(F) \
+ static ERL_NIF_TERM esock_socket_info_##F(ErlNifEnv* env, \
+ ESockDescriptor* descP);
+ESOCK_SOCKET_INFO_REQ_FUNCS
+#undef ESOCK_SOCKET_INFO_REQ_FUNC_DEF
+
+static ERL_NIF_TERM socket_info_reqs(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ErlNifMutex* mtx,
+ ESockRequestor* crp,
+ ESockRequestQueue* q);
+
+static ERL_NIF_TERM esock_supports(ErlNifEnv* env, int key);
+static ERL_NIF_TERM esock_supports_options(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_options_socket(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_options_ip(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_options_ipv6(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_options_tcp(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_options_udp(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_options_sctp(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_sctp(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_ipv6(ErlNifEnv* env);
+static ERL_NIF_TERM esock_supports_local(ErlNifEnv* env);
+
+static ERL_NIF_TERM esock_open(ErlNifEnv* env,
int domain,
int type,
int protocol,
char* netns);
-static BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto);
+static BOOLEAN_T esock_open_which_protocol(SOCKET sock, int* proto);
-static ERL_NIF_TERM nbind(ErlNifEnv* env,
- ESockDescriptor* descP,
- ESockAddress* sockAddrP,
- unsigned int addrLen);
-static ERL_NIF_TERM nconnect(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef);
-static ERL_NIF_TERM nlisten(ErlNifEnv* env,
- ESockDescriptor* descP,
- int backlog);
-static ERL_NIF_TERM naccept(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM ref);
-static ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM ref);
-static ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env,
+static ERL_NIF_TERM esock_bind(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ESockAddress* sockAddrP,
+ unsigned int addrLen);
+static ERL_NIF_TERM esock_connect(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef);
+static ERL_NIF_TERM esock_listen(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int backlog);
+static ERL_NIF_TERM esock_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM ref);
+static ERL_NIF_TERM esock_accept_listening(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM ref);
+static ERL_NIF_TERM esock_accept_listening_error(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM accRef,
+ ErlNifPid caller,
+ int save_errno);
+static ERL_NIF_TERM esock_accept_listening_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ SOCKET accSock,
+ ErlNifPid caller,
+ ESockAddress* remote);
+static ERL_NIF_TERM esock_accept_accepting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM ref);
+static ERL_NIF_TERM esock_accept_accepting_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM ref);
+static ERL_NIF_TERM esock_accept_accepting_current_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ SOCKET accSock,
+ ESockAddress* remote);
+static ERL_NIF_TERM esock_accept_accepting_current_error(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef,
+ int save_errno);
+static ERL_NIF_TERM esock_accept_accepting_other(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM ref,
+ ErlNifPid caller);
+static ERL_NIF_TERM esock_accept_busy_retry(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM sockRef,
ERL_NIF_TERM accRef,
- ErlNifPid caller,
- int save_errno);
-static ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env,
- ESockDescriptor* descP,
- SOCKET accSock,
- ErlNifPid caller,
- ESockAddress* remote);
-static ERL_NIF_TERM naccept_accepting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM ref);
-static ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM ref);
-static ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- SOCKET accSock,
- ESockAddress* remote);
-static ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef,
- int save_errno);
-static ERL_NIF_TERM naccept_accepting_other(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM ref,
- ErlNifPid caller);
-static ERL_NIF_TERM naccept_busy_retry(ErlNifEnv* env,
+ ErlNifPid* pid,
+ unsigned int nextState);
+static BOOLEAN_T esock_accept_accepted(ErlNifEnv* env,
ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM accRef,
- ErlNifPid* pid,
- unsigned int nextState);
-static BOOLEAN_T naccept_accepted(ErlNifEnv* env,
+ SOCKET accSock,
+ ErlNifPid pid,
+ ESockAddress* remote,
+ ERL_NIF_TERM* result);
+static ERL_NIF_TERM esock_send(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM sendRef,
+ ErlNifBinary* dataP,
+ int flags);
+static ERL_NIF_TERM esock_sendto(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM sendRef,
+ ErlNifBinary* dataP,
+ int flags,
+ ESockAddress* toAddrP,
+ unsigned int toAddrLen);
+static ERL_NIF_TERM esock_sendmsg(ErlNifEnv* env,
ESockDescriptor* descP,
- SOCKET accSock,
- ErlNifPid pid,
- ESockAddress* remote,
- ERL_NIF_TERM* result);
-static ERL_NIF_TERM nsend(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM sendRef,
- ErlNifBinary* dataP,
- int flags);
-static ERL_NIF_TERM nsendto(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM sendRef,
- ErlNifBinary* dataP,
- int flags,
- ESockAddress* toAddrP,
- unsigned int toAddrLen);
-static ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM sendRef,
- ERL_NIF_TERM eMsgHdr,
- int flags);
-static ERL_NIF_TERM nrecv(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sendRef,
- ERL_NIF_TERM recvRef,
- int len,
- int flags);
-static ERL_NIF_TERM nrecvfrom(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM recvRef,
- Uint16 bufSz,
- int flags);
-static ERL_NIF_TERM nrecvmsg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM recvRef,
- Uint16 bufLen,
- Uint16 ctrlLen,
- int flags);
-static ERL_NIF_TERM nclose(ErlNifEnv* env,
- ESockDescriptor* descP);
-static BOOLEAN_T nclose_check(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM* reason);
-static ERL_NIF_TERM nclose_do(ErlNifEnv* env,
- ESockDescriptor* descP);
-static ERL_NIF_TERM nshutdown(ErlNifEnv* env,
- ESockDescriptor* descP,
- int how);
-static ERL_NIF_TERM nsetopt(ErlNifEnv* env,
- ESockDescriptor* descP,
- BOOLEAN_T isEncoded,
- BOOLEAN_T isOTP,
- int level,
- int eOpt,
- ERL_NIF_TERM eVal);
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM sendRef,
+ ERL_NIF_TERM eMsgHdr,
+ int flags);
+static ERL_NIF_TERM esock_recv(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sendRef,
+ ERL_NIF_TERM recvRef,
+ int len,
+ int flags);
+static ERL_NIF_TERM esock_recvfrom(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM recvRef,
+ Uint16 bufSz,
+ int flags);
+static ERL_NIF_TERM esock_recvmsg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM recvRef,
+ Uint16 bufLen,
+ Uint16 ctrlLen,
+ int flags);
+static ERL_NIF_TERM esock_close(ErlNifEnv* env,
+ ESockDescriptor* descP);
+static BOOLEAN_T esock_close_check(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM* reason);
+static ERL_NIF_TERM esock_close_do(ErlNifEnv* env,
+ ESockDescriptor* descP);
+static ERL_NIF_TERM esock_shutdown(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int how);
+static ERL_NIF_TERM esock_setopt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ BOOLEAN_T isEncoded,
+ BOOLEAN_T isOTP,
+ int level,
+ int eOpt,
+ ERL_NIF_TERM eVal);
/* Set OTP level options */
-static ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal);
-/* *** nsetopt_otp_debug ***
- * *** nsetopt_otp_iow ***
- * *** nsetopt_otp_ctrl_proc ***
- * *** nsetopt_otp_rcvbuf ***
- * *** nsetopt_otp_rcvctrlbuf ***
- * *** nsetopt_otp_sndctrlbuf ***
- */
-#define NSETOPT_OTP_FUNCS \
- NSETOPT_OTP_FUNC_DEF(debug); \
- NSETOPT_OTP_FUNC_DEF(iow); \
- NSETOPT_OTP_FUNC_DEF(ctrl_proc); \
- NSETOPT_OTP_FUNC_DEF(rcvbuf); \
- NSETOPT_OTP_FUNC_DEF(rcvctrlbuf); \
- NSETOPT_OTP_FUNC_DEF(sndctrlbuf);
-#define NSETOPT_OTP_FUNC_DEF(F) \
- static ERL_NIF_TERM nsetopt_otp_##F(ErlNifEnv* env, \
- ESockDescriptor* descP, \
- ERL_NIF_TERM eVal)
-NSETOPT_OTP_FUNCS
-#undef NSETOPT_OTP_FUNC_DEF
+static ERL_NIF_TERM esock_setopt_otp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal);
+/* *** esock_setopt_otp_debug ***
+ * *** esock_setopt_otp_iow ***
+ * *** esock_setopt_otp_ctrl_proc ***
+ * *** esock_setopt_otp_rcvbuf ***
+ * *** esock_setopt_otp_rcvctrlbuf ***
+ * *** esock_setopt_otp_sndctrlbuf ***
+ */
+#define ESOCK_SETOPT_OTP_FUNCS \
+ ESOCK_SETOPT_OTP_FUNC_DEF(debug); \
+ ESOCK_SETOPT_OTP_FUNC_DEF(iow); \
+ ESOCK_SETOPT_OTP_FUNC_DEF(ctrl_proc); \
+ ESOCK_SETOPT_OTP_FUNC_DEF(rcvbuf); \
+ ESOCK_SETOPT_OTP_FUNC_DEF(rcvctrlbuf); \
+ ESOCK_SETOPT_OTP_FUNC_DEF(sndctrlbuf);
+#define ESOCK_SETOPT_OTP_FUNC_DEF(F) \
+ static ERL_NIF_TERM esock_setopt_otp_##F(ErlNifEnv* env, \
+ ESockDescriptor* descP, \
+ ERL_NIF_TERM eVal)
+ESOCK_SETOPT_OTP_FUNCS
+#undef ESOCK_SETOPT_OTP_FUNC_DEF
/* Set native options */
-static ERL_NIF_TERM nsetopt_native(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int eOpt,
- ERL_NIF_TERM eVal);
-static ERL_NIF_TERM nsetopt_level(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int eOpt,
- ERL_NIF_TERM eVal);
-static ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env,
+static ERL_NIF_TERM esock_setopt_native(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int eOpt,
+ ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_level(ErlNifEnv* env,
ESockDescriptor* descP,
+ int level,
int eOpt,
ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_socket(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal);
/* *** Handling set of socket options for level = socket *** */
#if defined(SO_BINDTODEVICE)
-static ERL_NIF_TERM nsetopt_lvl_sock_bindtodevice(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_bindtodevice(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_BROADCAST)
-static ERL_NIF_TERM nsetopt_lvl_sock_broadcast(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_broadcast(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_DEBUG)
-static ERL_NIF_TERM nsetopt_lvl_sock_debug(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_debug(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_DONTROUTE)
-static ERL_NIF_TERM nsetopt_lvl_sock_dontroute(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_dontroute(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_KEEPALIVE)
-static ERL_NIF_TERM nsetopt_lvl_sock_keepalive(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_keepalive(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_LINGER)
-static ERL_NIF_TERM nsetopt_lvl_sock_linger(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_linger(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_OOBINLINE)
-static ERL_NIF_TERM nsetopt_lvl_sock_oobinline(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_oobinline(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_PEEK_OFF)
-static ERL_NIF_TERM nsetopt_lvl_sock_peek_off(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_peek_off(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_PRIORITY)
-static ERL_NIF_TERM nsetopt_lvl_sock_priority(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_priority(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_RCVBUF)
-static ERL_NIF_TERM nsetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_rcvbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_RCVLOWAT)
-static ERL_NIF_TERM nsetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_RCVTIMEO)
-static ERL_NIF_TERM nsetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_REUSEADDR)
-static ERL_NIF_TERM nsetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_reuseaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_REUSEPORT)
-static ERL_NIF_TERM nsetopt_lvl_sock_reuseport(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_reuseport(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_SNDBUF)
-static ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_sndbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_SNDLOWAT)
-static ERL_NIF_TERM nsetopt_lvl_sock_sndlowat(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_SNDTIMEO)
-static ERL_NIF_TERM nsetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_sndtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SO_TIMESTAMP)
-static ERL_NIF_TERM nsetopt_lvl_sock_timestamp(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sock_timestamp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
-static ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal);
/* *** Handling set of socket options for level = ip *** */
#if defined(IP_ADD_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ip_add_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_add_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_ADD_SOURCE_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ip_add_source_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_add_source_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_BLOCK_SOURCE)
-static ERL_NIF_TERM nsetopt_lvl_ip_block_source(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_block_source(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_DROP_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ip_drop_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_drop_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_DROP_SOURCE_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ip_drop_source_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_drop_source_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_FREEBIND)
-static ERL_NIF_TERM nsetopt_lvl_ip_freebind(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_freebind(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_HDRINCL)
-static ERL_NIF_TERM nsetopt_lvl_ip_hdrincl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_hdrincl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_MINTTL)
-static ERL_NIF_TERM nsetopt_lvl_ip_minttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_minttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE)
-static ERL_NIF_TERM nsetopt_lvl_ip_msfilter(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_msfilter(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
static BOOLEAN_T decode_ip_msfilter_mode(ErlNifEnv* env,
ERL_NIF_TERM eVal,
Uint32* mode);
-static ERL_NIF_TERM nsetopt_lvl_ip_msfilter_set(ErlNifEnv* env,
- SOCKET sock,
- struct ip_msfilter* msfP,
- SOCKLEN_T optLen);
+static ERL_NIF_TERM esock_setopt_lvl_ip_msfilter_set(ErlNifEnv* env,
+ SOCKET sock,
+ struct ip_msfilter* msfP,
+ SOCKLEN_T optLen);
#endif
#if defined(IP_MTU_DISCOVER)
-static ERL_NIF_TERM nsetopt_lvl_ip_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_MULTICAST_ALL)
-static ERL_NIF_TERM nsetopt_lvl_ip_multicast_all(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_all(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_MULTICAST_IF)
-static ERL_NIF_TERM nsetopt_lvl_ip_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_MULTICAST_LOOP)
-static ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_MULTICAST_TTL)
-static ERL_NIF_TERM nsetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_NODEFRAG)
-static ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_nodefrag(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_PKTINFO)
-static ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_pktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVDSTADDR)
-static ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVERR)
-static ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVIF)
-static ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recvif(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVOPTS)
-static ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recvopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVORIGDSTADDR)
-static ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVTOS)
-static ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recvtos(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RECVTTL)
-static ERL_NIF_TERM nsetopt_lvl_ip_recvttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_recvttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_RETOPTS)
-static ERL_NIF_TERM nsetopt_lvl_ip_retopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
-#endif
-#if defined(IP_ROUTER_ALERT)
-static ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env,
+static ERL_NIF_TERM esock_setopt_lvl_ip_retopts(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IP_ROUTER_ALERT)
+static ERL_NIF_TERM esock_setopt_lvl_ip_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IP_SENDSRCADDR)
-static ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_TOS)
-static ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_tos(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_TRANSPARENT)
-static ERL_NIF_TERM nsetopt_lvl_ip_transparent(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_transparent(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_TTL)
-static ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_UNBLOCK_SOURCE)
-static ERL_NIF_TERM nsetopt_lvl_ip_unblock_source(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ip_unblock_source(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IP_DROP_MEMBERSHIP) || defined(IP_ADD_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal,
- int opt);
+ERL_NIF_TERM esock_setopt_lvl_ip_update_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal,
+ int opt);
#endif
#if defined(IP_ADD_SOURCE_MEMBERSHIP) || defined(IP_DROP_SOURCE_MEMBERSHIP) || defined(IP_BLOCK_SOURCE) || defined(IP_UNBLOCK_SOURCE)
static
-ERL_NIF_TERM nsetopt_lvl_ip_update_source(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal,
- int opt);
+ERL_NIF_TERM esock_setopt_lvl_ip_update_source(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal,
+ int opt);
#endif
/* *** Handling set of socket options for level = ipv6 *** */
#if defined(HAVE_IPV6)
-static ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal);
#if defined(IPV6_ADDRFORM)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_addrform(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_ADD_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_add_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_AUTHHDR)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_DROP_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_DSTOPTS)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_FLOWINFO)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_HOPLIMIT)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_HOPOPTS)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_MTU)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_MTU_DISCOVER)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_MULTICAST_HOPS)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_MULTICAST_IF)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_MULTICAST_LOOP)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_RECVERR)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_ROUTER_ALERT)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_RTHDR)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_rthdr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_UNICAST_HOPS)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_V6ONLY)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_v6only(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(IPV6_ADD_MEMBERSHIP) || defined(IPV6_DROP_MEMBERSHIP)
-static ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal,
- int opt);
+static ERL_NIF_TERM esock_setopt_lvl_ipv6_update_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal,
+ int opt);
#endif
#endif // defined(HAVE_IPV6)
-static ERL_NIF_TERM nsetopt_lvl_tcp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_tcp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal);
#if defined(TCP_CONGESTION)
-static ERL_NIF_TERM nsetopt_lvl_tcp_congestion(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_tcp_congestion(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(TCP_MAXSEG)
-static ERL_NIF_TERM nsetopt_lvl_tcp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_tcp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(TCP_NODELAY)
-static ERL_NIF_TERM nsetopt_lvl_tcp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_tcp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
-static ERL_NIF_TERM nsetopt_lvl_udp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal);
-#if defined(UDP_CORK)
-static ERL_NIF_TERM nsetopt_lvl_udp_cork(ErlNifEnv* env,
+static ERL_NIF_TERM esock_setopt_lvl_udp(ErlNifEnv* env,
ESockDescriptor* descP,
+ int eOpt,
ERL_NIF_TERM eVal);
+#if defined(UDP_CORK)
+static ERL_NIF_TERM esock_setopt_lvl_udp_cork(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(HAVE_SCTP)
-static ERL_NIF_TERM nsetopt_lvl_sctp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal);
#if defined(SCTP_ASSOCINFO)
-static ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_associnfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_AUTOCLOSE)
-static ERL_NIF_TERM nsetopt_lvl_sctp_autoclose(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_autoclose(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_DISABLE_FRAGMENTS)
-static ERL_NIF_TERM nsetopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_EVENTS)
-static ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_events(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_INITMSG)
-static ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_initmsg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_MAXSEG)
-static ERL_NIF_TERM nsetopt_lvl_sctp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_NODELAY)
-static ERL_NIF_TERM nsetopt_lvl_sctp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#if defined(SCTP_RTOINFO)
-static ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal);
#endif
#endif // defined(HAVE_SCTP)
-static ERL_NIF_TERM ngetopt(ErlNifEnv* env,
- ESockDescriptor* descP,
- BOOLEAN_T isEncoded,
- BOOLEAN_T isOTP,
- int level,
- ERL_NIF_TERM eOpt);
+static ERL_NIF_TERM esock_getopt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ BOOLEAN_T isEncoded,
+ BOOLEAN_T isOTP,
+ int level,
+ ERL_NIF_TERM eOpt);
-static ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt);
-/* *** ngetopt_otp_debug ***
- * *** ngetopt_otp_iow ***
- * *** ngetopt_otp_ctrl_proc ***
- * *** ngetopt_otp_rcvbuf ***
- * *** ngetopt_otp_rcvctrlbuf ***
- * *** ngetopt_otp_sndctrlbuf ***
- * *** ngetopt_otp_fd ***
- * *** ngetopt_otp_domain ***
- * *** ngetopt_otp_type ***
- * *** ngetopt_otp_protocol ***
- */
-#define NGETOPT_OTP_FUNCS \
- NGETOPT_OTP_FUNC_DEF(debug); \
- NGETOPT_OTP_FUNC_DEF(iow); \
- NGETOPT_OTP_FUNC_DEF(ctrl_proc); \
- NGETOPT_OTP_FUNC_DEF(rcvbuf); \
- NGETOPT_OTP_FUNC_DEF(rcvctrlbuf); \
- NGETOPT_OTP_FUNC_DEF(sndctrlbuf); \
- NGETOPT_OTP_FUNC_DEF(fd); \
- NGETOPT_OTP_FUNC_DEF(domain); \
- NGETOPT_OTP_FUNC_DEF(type); \
- NGETOPT_OTP_FUNC_DEF(protocol);
-#define NGETOPT_OTP_FUNC_DEF(F) \
- static ERL_NIF_TERM ngetopt_otp_##F(ErlNifEnv* env, \
- ESockDescriptor* descP)
-NGETOPT_OTP_FUNCS
-#undef NGETOPT_OTP_FUNC_DEF
+static ERL_NIF_TERM esock_getopt_otp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
+/* *** esock_getopt_otp_debug ***
+ * *** esock_getopt_otp_iow ***
+ * *** esock_getopt_otp_ctrl_proc ***
+ * *** esock_getopt_otp_rcvbuf ***
+ * *** esock_getopt_otp_rcvctrlbuf ***
+ * *** esock_getopt_otp_sndctrlbuf ***
+ * *** esock_getopt_otp_fd ***
+ * *** esock_getopt_otp_domain ***
+ * *** esock_getopt_otp_type ***
+ * *** esock_getopt_otp_protocol ***
+ */
+#define ESOCK_GETOPT_OTP_FUNCS \
+ ESOCK_GETOPT_OTP_FUNC_DEF(debug); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(iow); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(ctrl_proc); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(rcvbuf); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(rcvctrlbuf); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(sndctrlbuf); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(fd); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(domain); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(type); \
+ ESOCK_GETOPT_OTP_FUNC_DEF(protocol);
+#define ESOCK_GETOPT_OTP_FUNC_DEF(F) \
+ static ERL_NIF_TERM esock_getopt_otp_##F(ErlNifEnv* env, \
+ ESockDescriptor* descP)
+ESOCK_GETOPT_OTP_FUNCS
+#undef ESOCK_GETOPT_OTP_FUNC_DEF
-static ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- ERL_NIF_TERM eOpt);
-static ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- SOCKOPTLEN_T valueSz);
-static ERL_NIF_TERM ngetopt_level(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int eOpt);
-static ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
+static ERL_NIF_TERM esock_getopt_native(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ ERL_NIF_TERM eOpt);
+static ERL_NIF_TERM esock_getopt_native_unspec(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ SOCKOPTLEN_T valueSz);
+static ERL_NIF_TERM esock_getopt_level(ErlNifEnv* env,
ESockDescriptor* descP,
+ int level,
int eOpt);
+static ERL_NIF_TERM esock_getopt_lvl_socket(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
#if defined(SO_ACCEPTCONN)
-static ERL_NIF_TERM ngetopt_lvl_sock_acceptconn(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_acceptconn(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_BINDTODEVICE)
-static ERL_NIF_TERM ngetopt_lvl_sock_bindtodevice(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_bindtodevice(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_BROADCAST)
-static ERL_NIF_TERM ngetopt_lvl_sock_broadcast(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_broadcast(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_DEBUG)
-static ERL_NIF_TERM ngetopt_lvl_sock_debug(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_debug(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_DOMAIN)
-static ERL_NIF_TERM ngetopt_lvl_sock_domain(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_domain(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_DONTROUTE)
-static ERL_NIF_TERM ngetopt_lvl_sock_dontroute(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_dontroute(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_KEEPALIVE)
-static ERL_NIF_TERM ngetopt_lvl_sock_keepalive(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_keepalive(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_LINGER)
-static ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_linger(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_OOBINLINE)
-static ERL_NIF_TERM ngetopt_lvl_sock_oobinline(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_oobinline(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_PEEK_OFF)
-static ERL_NIF_TERM ngetopt_lvl_sock_peek_off(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_peek_off(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_PRIORITY)
-static ERL_NIF_TERM ngetopt_lvl_sock_priority(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_priority(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_PROTOCOL)
-static ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_protocol(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_RCVBUF)
-static ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_rcvbuf(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_RCVLOWAT)
-static ERL_NIF_TERM ngetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_RCVTIMEO)
-static ERL_NIF_TERM ngetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_REUSEADDR)
-static ERL_NIF_TERM ngetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_reuseaddr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_REUSEPORT)
-static ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_reuseport(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_SNDBUF)
-static ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_sndbuf(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_SNDLOWAT)
-static ERL_NIF_TERM ngetopt_lvl_sock_sndlowat(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_SNDTIMEO)
-static ERL_NIF_TERM ngetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_sndtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_TIMESTAMP)
-static ERL_NIF_TERM ngetopt_lvl_sock_timestamp(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_timestamp(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SO_TYPE)
-static ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sock_type(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
-static ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt);
+static ERL_NIF_TERM esock_getopt_lvl_ip(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
#if defined(IP_FREEBIND)
-static ERL_NIF_TERM ngetopt_lvl_ip_freebind(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_freebind(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_HDRINCL)
-static ERL_NIF_TERM ngetopt_lvl_ip_hdrincl(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_hdrincl(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MINTTL)
-static ERL_NIF_TERM ngetopt_lvl_ip_minttl(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_minttl(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MTU)
-static ERL_NIF_TERM ngetopt_lvl_ip_mtu(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_mtu(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MTU_DISCOVER)
-static ERL_NIF_TERM ngetopt_lvl_ip_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MULTICAST_ALL)
-static ERL_NIF_TERM ngetopt_lvl_ip_multicast_all(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_all(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MULTICAST_IF)
-static ERL_NIF_TERM ngetopt_lvl_ip_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MULTICAST_LOOP)
-static ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_MULTICAST_TTL)
-static ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_NODEFRAG)
-static ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_nodefrag(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_PKTINFO)
-static ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_pktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVDSTADDR)
-static ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVERR)
-static ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVIF)
-static ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recvif(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVOPTS)
-static ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recvopts(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVORIGDSTADDR)
-static ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVTOS)
-static ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recvtos(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RECVTTL)
-static ERL_NIF_TERM ngetopt_lvl_ip_recvttl(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_recvttl(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_RETOPTS)
-static ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_retopts(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_ROUTER_ALERT)
-static ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_SENDSRCADDR)
-static ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_TOS)
-static ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_tos(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_TRANSPARENT)
-static ERL_NIF_TERM ngetopt_lvl_ip_transparent(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_transparent(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IP_TTL)
-static ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ip_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(HAVE_IPV6)
-static ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
#if defined(IPV6_AUTHHDR)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_DSTOPTS)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_FLOWINFO)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_HOPLIMIT)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_HOPOPTS)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_MTU)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_MTU_DISCOVER)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_MULTICAST_HOPS)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_MULTICAST_IF)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_MULTICAST_LOOP)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_RECVERR)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_ROUTER_ALERT)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_RTHDR)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_rthdr(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_UNICAST_HOPS)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(IPV6_V6ONLY)
-static ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_ipv6_v6only(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#endif // defined(HAVE_IPV6)
-static ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt);
+static ERL_NIF_TERM esock_getopt_lvl_tcp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
#if defined(TCP_CONGESTION)
-static ERL_NIF_TERM ngetopt_lvl_tcp_congestion(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_tcp_congestion(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(TCP_MAXSEG)
-static ERL_NIF_TERM ngetopt_lvl_tcp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_tcp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(TCP_NODELAY)
-static ERL_NIF_TERM ngetopt_lvl_tcp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_tcp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
-static ERL_NIF_TERM ngetopt_lvl_udp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt);
+static ERL_NIF_TERM esock_getopt_lvl_udp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
#if defined(UDP_CORK)
-static ERL_NIF_TERM ngetopt_lvl_udp_cork(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_udp_cork(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(HAVE_SCTP)
-static ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt);
+static ERL_NIF_TERM esock_getopt_lvl_sctp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt);
#if defined(SCTP_ASSOCINFO)
-static ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_associnfo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SCTP_AUTOCLOSE)
-static ERL_NIF_TERM ngetopt_lvl_sctp_autoclose(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_autoclose(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SCTP_DISABLE_FRAGMENTS)
-static ERL_NIF_TERM ngetopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SCTP_MAXSEG)
-static ERL_NIF_TERM ngetopt_lvl_sctp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SCTP_INITMSG)
-static ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_initmsg(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SCTP_NODELAY)
-static ERL_NIF_TERM ngetopt_lvl_sctp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#if defined(SCTP_RTOINFO)
-static ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
- ESockDescriptor* descP);
+static ERL_NIF_TERM esock_getopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
+ ESockDescriptor* descP);
#endif
#endif // defined(HAVE_SCTP)
-static ERL_NIF_TERM nsockname(ErlNifEnv* env,
- ESockDescriptor* descP);
-static ERL_NIF_TERM npeername(ErlNifEnv* env,
- ESockDescriptor* descP);
-static ERL_NIF_TERM ncancel(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM op,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_connect(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_accept(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef);
-static ERL_NIF_TERM ncancel_accept_waiting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_send(ErlNifEnv* env,
+static ERL_NIF_TERM esock_sockname(ErlNifEnv* env,
+ ESockDescriptor* descP);
+static ERL_NIF_TERM esock_peername(ErlNifEnv* env,
+ ESockDescriptor* descP);
+static ERL_NIF_TERM esock_cancel(ErlNifEnv* env,
ESockDescriptor* descP,
+ ERL_NIF_TERM op,
ERL_NIF_TERM sockRef,
ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_send_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef);
-static ERL_NIF_TERM ncancel_send_waiting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_recv(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_recv_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef);
-static ERL_NIF_TERM ncancel_recv_waiting(ErlNifEnv* env,
+static ERL_NIF_TERM esock_cancel_connect(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_read_select(ErlNifEnv* env,
+static ERL_NIF_TERM esock_cancel_accept(ErlNifEnv* env,
ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_write_select(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef);
-static ERL_NIF_TERM ncancel_mode_select(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef,
- int smode,
- int rmode);
+static ERL_NIF_TERM esock_cancel_accept_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef);
+static ERL_NIF_TERM esock_cancel_accept_waiting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_send(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_send_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef);
+static ERL_NIF_TERM esock_cancel_send_waiting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_recv(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_recv_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef);
+static ERL_NIF_TERM esock_cancel_recv_waiting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_read_select(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_write_select(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef);
+static ERL_NIF_TERM esock_cancel_mode_select(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef,
+ int smode,
+ int rmode);
#if defined(USE_SETOPT_STR_OPT)
-static ERL_NIF_TERM nsetopt_str_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- int max,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_str_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ int max,
+ ERL_NIF_TERM eVal);
#endif
-static ERL_NIF_TERM nsetopt_bool_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal);
-static ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal);
-static ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_bool_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_int_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal);
+static ERL_NIF_TERM esock_setopt_timeval_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal);
#if defined(USE_GETOPT_STR_OPT)
-static ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- int max);
+static ERL_NIF_TERM esock_getopt_str_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ int max);
#endif
-static ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt);
-static ERL_NIF_TERM ngetopt_int_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt);
-static ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt);
+static ERL_NIF_TERM esock_getopt_bool_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt);
+static ERL_NIF_TERM esock_getopt_int_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt);
+static ERL_NIF_TERM esock_getopt_timeval_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt);
static BOOLEAN_T send_check_writer(ErlNifEnv* env,
ESockDescriptor* descP,
@@ -2238,10 +2286,10 @@ static ERL_NIF_TERM recvmsg_check_msg(ErlNifEnv* env,
ErlNifBinary* ctrlBufP,
ERL_NIF_TERM sockRef);
-static ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env,
+static ERL_NIF_TERM esock_finalize_connection(ErlNifEnv* env,
+ ESockDescriptor* descP);
+static ERL_NIF_TERM esock_finalize_close(ErlNifEnv* env,
ESockDescriptor* descP);
-static ERL_NIF_TERM nfinalize_close(ErlNifEnv* env,
- ESockDescriptor* descP);
extern char* encode_msghdr(ErlNifEnv* env,
ESockDescriptor* descP,
@@ -2374,11 +2422,11 @@ static BOOLEAN_T decode_native_get_opt(ErlNifEnv* env,
// static void encode_bool(BOOLEAN_T val, ERL_NIF_TERM* eVal);
static ERL_NIF_TERM encode_ip_tos(ErlNifEnv* env, int val);
-static void socket_stop_handle_current(ErlNifEnv* env,
- const char* role,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ESockRequestor* reqP);
+static void esock_stop_handle_current(ErlNifEnv* env,
+ const char* role,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ESockRequestor* reqP);
static void inform_waiting_procs(ErlNifEnv* env,
const char* role,
ESockDescriptor* descP,
@@ -2517,31 +2565,35 @@ static size_t my_strnlen(const char *s, size_t maxlen);
#endif
*/
-static void socket_dtor(ErlNifEnv* env, void* obj);
-static void socket_stop(ErlNifEnv* env,
- void* obj,
- int fd,
- int is_direct_call);
-static void socket_down(ErlNifEnv* env,
- void* obj,
- const ErlNifPid* pid,
- const ErlNifMonitor* mon);
+static void esock_dtor(ErlNifEnv* env, void* obj);
+static void esock_stop(ErlNifEnv* env,
+ void* obj,
+ int fd,
+ int is_direct_call);
+static void esock_down(ErlNifEnv* env,
+ void* obj,
+ const ErlNifPid* pid,
+ const ErlNifMonitor* mon);
#if !defined(__WIN32__)
-static void socket_down_acceptor(ErlNifEnv* env,
+static void esock_down_acceptor(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ const ErlNifPid* pid);
+static void esock_down_writer(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ const ErlNifPid* pid);
+static void esock_down_reader(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ const ErlNifPid* pid);
+
+static char* esock_send_wrap_msg(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM sockRef,
- const ErlNifPid* pid);
-static void socket_down_writer(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- const ErlNifPid* pid);
-static void socket_down_reader(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- const ErlNifPid* pid);
-
+ ERL_NIF_TERM cnt);
static char* esock_send_close_msg(ErlNifEnv* env,
ESockDescriptor* descP,
ErlNifPid* pid);
@@ -2560,6 +2612,9 @@ static ERL_NIF_TERM mk_abort_msg(ErlNifEnv* env,
ERL_NIF_TERM sockRef,
ERL_NIF_TERM opRef,
ERL_NIF_TERM reason);
+static ERL_NIF_TERM mk_wrap_msg(ErlNifEnv* env,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM cnt);
static ERL_NIF_TERM mk_close_msg(ErlNifEnv* env,
ERL_NIF_TERM sockRef,
ERL_NIF_TERM closeRef);
@@ -2634,7 +2689,10 @@ static char str_exsend[] = "exsend"; // failed send
-/* *** Global atoms *** */
+/* *** Global atoms ***
+ * Note that when an (global) atom is added here, it must also be added
+ * in the socket_int.h file!
+ */
#define GLOBAL_ATOMS \
GLOBAL_ATOM_DECL(abort); \
GLOBAL_ATOM_DECL(accept); \
@@ -2661,6 +2719,7 @@ static char str_exsend[] = "exsend"; // failed send
GLOBAL_ATOM_DECL(busy_poll); \
GLOBAL_ATOM_DECL(checksum); \
GLOBAL_ATOM_DECL(close); \
+ GLOBAL_ATOM_DECL(command); \
GLOBAL_ATOM_DECL(connect); \
GLOBAL_ATOM_DECL(congestion); \
GLOBAL_ATOM_DECL(context); \
@@ -2857,6 +2916,8 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket')
LOCAL_ATOM_DECL(closed); \
LOCAL_ATOM_DECL(closing); \
LOCAL_ATOM_DECL(cookie_life); \
+ LOCAL_ATOM_DECL(counter_wrap); \
+ LOCAL_ATOM_DECL(counters); \
LOCAL_ATOM_DECL(data_in); \
LOCAL_ATOM_DECL(do); \
LOCAL_ATOM_DECL(dont); \
@@ -2880,6 +2941,7 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket')
LOCAL_ATOM_DECL(mode); \
LOCAL_ATOM_DECL(multiaddr); \
LOCAL_ATOM_DECL(null); \
+ LOCAL_ATOM_DECL(num_acceptors); \
LOCAL_ATOM_DECL(num_dinet); \
LOCAL_ATOM_DECL(num_dinet6); \
LOCAL_ATOM_DECL(num_dlocal); \
@@ -2889,14 +2951,21 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket')
LOCAL_ATOM_DECL(num_psctp); \
LOCAL_ATOM_DECL(num_ptcp); \
LOCAL_ATOM_DECL(num_pudp); \
+ LOCAL_ATOM_DECL(num_readers); \
LOCAL_ATOM_DECL(num_sockets); \
LOCAL_ATOM_DECL(num_tdgrams); \
LOCAL_ATOM_DECL(num_tseqpkgs); \
LOCAL_ATOM_DECL(num_tstreams); \
+ LOCAL_ATOM_DECL(num_writers); \
LOCAL_ATOM_DECL(partial_delivery); \
LOCAL_ATOM_DECL(peer_error); \
LOCAL_ATOM_DECL(peer_rwnd); \
LOCAL_ATOM_DECL(probe); \
+ LOCAL_ATOM_DECL(read_byte); \
+ LOCAL_ATOM_DECL(read_fails); \
+ LOCAL_ATOM_DECL(read_pkg); \
+ LOCAL_ATOM_DECL(read_tries); \
+ LOCAL_ATOM_DECL(read_waits); \
LOCAL_ATOM_DECL(select); \
LOCAL_ATOM_DECL(sender_dry); \
LOCAL_ATOM_DECL(send_failure); \
@@ -2905,7 +2974,12 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket')
LOCAL_ATOM_DECL(sourceaddr); \
LOCAL_ATOM_DECL(timeout); \
LOCAL_ATOM_DECL(true); \
- LOCAL_ATOM_DECL(want);
+ LOCAL_ATOM_DECL(want); \
+ LOCAL_ATOM_DECL(write_byte); \
+ LOCAL_ATOM_DECL(write_fails); \
+ LOCAL_ATOM_DECL(write_pkg); \
+ LOCAL_ATOM_DECL(write_tries); \
+ LOCAL_ATOM_DECL(write_waits);
/* Local error reason atoms */
#define LOCAL_ERROR_REASON_ATOMS \
@@ -2926,11 +3000,11 @@ LOCAL_ERROR_REASON_ATOMS
/* *** Sockets *** */
-static ErlNifResourceType* sockets;
-static ErlNifResourceTypeInit socketInit = {
- socket_dtor,
- socket_stop,
- (ErlNifResourceDown*) socket_down
+static ErlNifResourceType* esocks;
+static ErlNifResourceTypeInit esockInit = {
+ esock_dtor,
+ esock_stop,
+ (ErlNifResourceDown*) esock_down
};
// Initiated when the nif is loaded
@@ -2967,8 +3041,8 @@ static ESOCK_INLINE ErlNifEnv* esock_alloc_env(const char* slogan)
* Utility and admin functions:
* ----------------------------
* nif_info/0
+ * nif_command/1
* nif_supports/1
- * (nif_debug/1)
*
* The "proper" socket functions:
* ------------------------------
@@ -3008,7 +3082,7 @@ static ESOCK_INLINE ErlNifEnv* esock_alloc_env(const char* slogan)
* Description:
* This is currently just a placeholder...
*/
-#define MKCT(E, T, C) MKT2((E), (T), MKI((E), (C)))
+#define MKCT(E, T, C) MKT2((E), (T), MKUI((E), (C)))
static
ERL_NIF_TERM nif_info(ErlNifEnv* env,
@@ -3018,43 +3092,338 @@ ERL_NIF_TERM nif_info(ErlNifEnv* env,
#if defined(__WIN32__)
return enif_raise_exception(env, MKA(env, "notsup"));
#else
- if (argc != 0) {
+ ERL_NIF_TERM info;
+
+ SGDBG( ("SOCKET", "nif_info -> entry with %d args\r\n", argc) );
+
+ switch (argc) {
+ case 0:
+ info = esock_global_info(env);
+ break;
+
+ case 1:
+ {
+ ESockDescriptor* descP;
+
+ if (!ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
+ return enif_make_badarg(env);
+ }
+ SSDBG( descP, ("SOCKET", "nif_info -> get socket info\r\n") );
+ info = esock_socket_info(env, descP);
+ }
+ break;
+
+ default:
return enif_make_badarg(env);
- } else {
- ERL_NIF_TERM numSockets = MKCT(env, atom_num_sockets, data.numSockets);
- ERL_NIF_TERM numTypeDGrams = MKCT(env, atom_num_tdgrams, data.numTypeDGrams);
- ERL_NIF_TERM numTypeStreams = MKCT(env, atom_num_tstreams, data.numTypeStreams);
- ERL_NIF_TERM numTypeSeqPkgs = MKCT(env, atom_num_tseqpkgs, data.numTypeSeqPkgs);
- ERL_NIF_TERM numDomLocal = MKCT(env, atom_num_dlocal, data.numDomainLocal);
- ERL_NIF_TERM numDomInet = MKCT(env, atom_num_dinet, data.numDomainInet);
- ERL_NIF_TERM numDomInet6 = MKCT(env, atom_num_dinet6, data.numDomainInet6);
- ERL_NIF_TERM numProtoIP = MKCT(env, atom_num_pip, data.numProtoIP);
- ERL_NIF_TERM numProtoTCP = MKCT(env, atom_num_ptcp, data.numProtoTCP);
- ERL_NIF_TERM numProtoUDP = MKCT(env, atom_num_pudp, data.numProtoUDP);
- ERL_NIF_TERM numProtoSCTP = MKCT(env, atom_num_psctp, data.numProtoSCTP);
- ERL_NIF_TERM gcnt[] = {numSockets,
- numTypeDGrams, numTypeStreams, numTypeSeqPkgs,
- numDomLocal, numDomInet, numDomInet6,
- numProtoIP, numProtoTCP, numProtoUDP, numProtoSCTP};
- unsigned int lenGCnt = sizeof(gcnt) / sizeof(ERL_NIF_TERM);
- ERL_NIF_TERM lgcnt = MKLA(env, gcnt, lenGCnt);
- ERL_NIF_TERM keys[] = {esock_atom_debug, atom_iow, atom_global_counters};
- ERL_NIF_TERM vals[] = {BOOL2ATOM(data.dbg), BOOL2ATOM(data.iow), lgcnt};
- ERL_NIF_TERM info;
- unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM);
- unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM);
+ }
- ESOCK_ASSERT( (numKeys == numVals) );
+ return info;
+
+#endif
+}
+
+
+/*
+ * This function return a property list containing "global" info.
+ */
+#if !defined(__WIN32__)
+static
+ERL_NIF_TERM esock_global_info(ErlNifEnv* env)
+{
+ ERL_NIF_TERM numSockets = MKCT(env, atom_num_sockets, data.numSockets);
+ ERL_NIF_TERM numTypeDGrams = MKCT(env, atom_num_tdgrams, data.numTypeDGrams);
+ ERL_NIF_TERM numTypeStreams = MKCT(env, atom_num_tstreams, data.numTypeStreams);
+ ERL_NIF_TERM numTypeSeqPkgs = MKCT(env, atom_num_tseqpkgs, data.numTypeSeqPkgs);
+ ERL_NIF_TERM numDomLocal = MKCT(env, atom_num_dlocal, data.numDomainLocal);
+ ERL_NIF_TERM numDomInet = MKCT(env, atom_num_dinet, data.numDomainInet);
+ ERL_NIF_TERM numDomInet6 = MKCT(env, atom_num_dinet6, data.numDomainInet6);
+ ERL_NIF_TERM numProtoIP = MKCT(env, atom_num_pip, data.numProtoIP);
+ ERL_NIF_TERM numProtoTCP = MKCT(env, atom_num_ptcp, data.numProtoTCP);
+ ERL_NIF_TERM numProtoUDP = MKCT(env, atom_num_pudp, data.numProtoUDP);
+ ERL_NIF_TERM numProtoSCTP = MKCT(env, atom_num_psctp, data.numProtoSCTP);
+ ERL_NIF_TERM gcnt[] = {numSockets,
+ numTypeDGrams, numTypeStreams, numTypeSeqPkgs,
+ numDomLocal, numDomInet, numDomInet6,
+ numProtoIP, numProtoTCP, numProtoUDP, numProtoSCTP};
+ unsigned int lenGCnt = sizeof(gcnt) / sizeof(ERL_NIF_TERM);
+ ERL_NIF_TERM lgcnt = MKLA(env, gcnt, lenGCnt);
+ ERL_NIF_TERM keys[] = {esock_atom_debug, atom_iow, atom_global_counters};
+ ERL_NIF_TERM vals[] = {BOOL2ATOM(data.dbg), BOOL2ATOM(data.iow), lgcnt};
+ ERL_NIF_TERM info;
+ unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM);
+ unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM);
+
+ ESOCK_ASSERT( (numKeys == numVals) );
+
+ if (!MKMA(env, keys, vals, numKeys, &info))
+ return enif_make_badarg(env);
+
+ return info;
+}
+
+
+
+/*
+ * This function return a property *map*. The properties are:
+ * counters: A list of each socket counter and there current values
+ * readers: The number of current and waiting readers
+ * writers: The number of current and waiting writers
+ * acceptors: The number of current and waiting acceptors
+ */
+static
+ERL_NIF_TERM esock_socket_info(ErlNifEnv* env,
+ ESockDescriptor* descP)
+{
+ ERL_NIF_TERM counters = esock_socket_info_counters(env, descP);
+ ERL_NIF_TERM readers = esock_socket_info_readers(env, descP);
+ ERL_NIF_TERM writers = esock_socket_info_writers(env, descP);
+ ERL_NIF_TERM acceptors = esock_socket_info_acceptors(env, descP);
+ ERL_NIF_TERM keys[] = {atom_counters, atom_num_readers,
+ atom_num_writers, atom_num_acceptors};
+ ERL_NIF_TERM vals[] = {counters, readers, writers, acceptors};
+ ERL_NIF_TERM info;
+ unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM);
+ unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM);
+
+ SSDBG( descP, ("SOCKET", "esock_socket_info -> "
+ "\r\n numKeys: %d"
+ "\r\n numVals: %d"
+ "\r\n", numKeys, numVals) );
+
+ ESOCK_ASSERT( (numKeys == numVals) );
+
+ if (!MKMA(env, keys, vals, numKeys, &info))
+ return enif_make_badarg(env);
- if (!MKMA(env, keys, vals, numKeys, &info))
- return enif_make_badarg(env);
+ SSDBG( descP, ("SOCKET", "esock_socket_info -> done with"
+ "\r\n info: %T"
+ "\r\n", info) );
+
+ return info;
- return info;
+}
+
+
+/*
+ * Collect all counters for a socket.
+ */
+static
+ERL_NIF_TERM esock_socket_info_counters(ErlNifEnv* env,
+ ESockDescriptor* descP)
+{
+ ERL_NIF_TERM info;
+
+ MLOCK(descP->writeMtx);
+ MLOCK(descP->readMtx);
+
+ {
+ ERL_NIF_TERM readByteCnt = MKCT(env, atom_read_byte, descP->readByteCnt);
+ ERL_NIF_TERM readFails = MKCT(env, atom_read_fails, descP->readFails);
+ ERL_NIF_TERM readPkgCnt = MKCT(env, atom_read_pkg, descP->readPkgCnt);
+ ERL_NIF_TERM readTries = MKCT(env, atom_read_tries, descP->readTries);
+ ERL_NIF_TERM readWaits = MKCT(env, atom_read_waits, descP->readWaits);
+ ERL_NIF_TERM writeByteCnt = MKCT(env, atom_write_byte, descP->writeByteCnt);
+ ERL_NIF_TERM writeFails = MKCT(env, atom_write_fails, descP->writeFails);
+ ERL_NIF_TERM writePkgCnt = MKCT(env, atom_write_pkg, descP->writePkgCnt);
+ ERL_NIF_TERM writeTries = MKCT(env, atom_write_tries, descP->writeTries);
+ ERL_NIF_TERM writeWaits = MKCT(env, atom_write_waits, descP->writeWaits);
+ ERL_NIF_TERM acnt[] = {readByteCnt, readFails, readPkgCnt,
+ readTries, readWaits,
+ writeByteCnt, writeFails, writePkgCnt,
+ writeTries, writeWaits};
+ unsigned int lenACnt = sizeof(acnt) / sizeof(ERL_NIF_TERM);
+
+ info = MKLA(env, acnt, lenACnt);
+
+ SSDBG( descP, ("SOCKET", "esock_socket_info_counters -> "
+ "\r\n lenACnt: %d"
+ "\r\n info: %T"
+ "\r\n", lenACnt, info) );
+
+ }
+
+ MUNLOCK(descP->readMtx);
+ MUNLOCK(descP->writeMtx);
+
+ SSDBG( descP, ("SOCKET", "esock_socket_info_counters -> done with"
+ "\r\n info: %T"
+ "\r\n", info) );
+
+ return info;
+}
+#endif
+
+
+/* ----------------------------------------------------------------------
+ * nif_command
+ *
+ * Description:
+ * This function is intended to handle "various" commands. That is,
+ * commands and operations that are not part of the socket API proper.
+ * Currently it handles setting the global debug. Its a map with two
+ * attributes command and (command) data:
+ * #{command :: atom(), data :: term()}
+ *
+ * Command Data
+ * debug boolean()
+ *
+ */
+
+static
+ERL_NIF_TERM nif_command(ErlNifEnv* env,
+ int argc,
+ const ERL_NIF_TERM argv[])
+{
+#if defined(__WIN32__)
+ return enif_raise_exception(env, MKA(env, "notsup"));
+#else
+ ERL_NIF_TERM ecmd, ecdata, result;
+ Uint16 cmd;
+
+ SGDBG( ("SOCKET", "nif_command -> entry with %d args\r\n", argc) );
+
+ if ((argc != 1) ||
+ !IS_MAP(env, argv[0])) {
+ return enif_make_badarg(env);
}
+ ecmd = argv[0];
+
+ SGDBG( ("SOCKET", "nif_command -> "
+ "\r\n (e) command: %T"
+ "\r\n", ecmd) );
+
+ if (!ecommand2command(env, ecmd, &cmd, &ecdata)) {
+ SGDBG( ("SOCKET", "nif_command -> invalid command\r\n") );
+ return esock_make_error(env, esock_atom_einval);
+ }
+
+ SGDBG( ("SOCKET", "nif_command -> "
+ "\r\n command: %d"
+ "\r\n (e) command data: %T"
+ "\r\n", cmd, ecdata) );
+
+ result = esock_command(env, cmd, ecdata);
+
+ SGDBG( ("SOCKET", "nif_command -> done with result: "
+ "\r\n %T"
+ "\r\n", result) );
+
+ return result;
+
#endif
}
+#if !defined(__WIN32__)
+static
+ERL_NIF_TERM esock_command(ErlNifEnv* env, Uint16 cmd, ERL_NIF_TERM ecdata)
+{
+ ERL_NIF_TERM result;
+
+ SGDBG( ("SOCKET", "esock_command -> entry with 0x%lX\r\n", cmd) );
+
+ switch (cmd) {
+ case ESOCK_CMD_DEBUG:
+ result = esock_command_debug(env, ecdata);
+ break;
+
+ default:
+ result = esock_make_error(env, esock_atom_einval);
+ break;
+ }
+
+ return result;
+}
+
+
+
+static
+ERL_NIF_TERM esock_command_debug(ErlNifEnv* env, ERL_NIF_TERM ecdata)
+{
+ ERL_NIF_TERM result;
+
+ /* The data *should* be a boolean() */
+
+ if (COMPARE(ecdata, esock_atom_true) == 0) {
+ data.dbg = TRUE;
+ result = esock_atom_ok;
+ } else if (COMPARE(ecdata, esock_atom_false) == 0) {
+ data.dbg = FALSE;
+ result = esock_atom_ok;
+ } else {
+ SGDBG( ("SOCKET", "esock_command_debug -> invalid debug value: %T\r\n",
+ ecdata) );
+ result = esock_make_error(env, esock_atom_einval);
+ }
+
+ return result;
+}
+#endif
+
+
+/* *** esock_socket_info_readers ***
+ * *** esock_socket_info_writers ***
+ * *** esock_socket_info_acceptors ***
+ *
+ * Calculate how many readers | writers | acceptors we have for this socket.
+ * Current requestor + any waiting requestors (of the type).
+ *
+ */
+
+#if !defined(__WIN32__)
+#define ESOCK_INFO_REQ_FUNCS \
+ ESOCK_INFO_REQ_FUNC_DECL(readers, readMtx, currentReaderP, readersQ) \
+ ESOCK_INFO_REQ_FUNC_DECL(writers, writeMtx, currentWriterP, writersQ) \
+ ESOCK_INFO_REQ_FUNC_DECL(acceptors, accMtx, currentAcceptorP, acceptorsQ)
+
+#define ESOCK_INFO_REQ_FUNC_DECL(F, MTX, CRP, Q) \
+ static \
+ ERL_NIF_TERM esock_socket_info_##F(ErlNifEnv* env, \
+ ESockDescriptor* descP) \
+ { \
+ return socket_info_reqs(env, descP, descP->MTX, descP->CRP, &descP->Q); \
+ }
+ESOCK_INFO_REQ_FUNCS
+#undef ESOCK_INFO_REQ_FUNC_DECL
+
+
+static
+ERL_NIF_TERM socket_info_reqs(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ErlNifMutex* mtx,
+ ESockRequestor* crp,
+ ESockRequestQueue* q)
+{
+ ESockRequestQueueElement* tmp;
+ ERL_NIF_TERM info;
+ unsigned int cnt = 0;
+
+ MLOCK(mtx);
+
+ if (crp != NULL) {
+ // We have an active requestor!
+ cnt++;
+
+ // And add all the waiting requestors
+ tmp = q->first;
+ while (tmp != NULL) {
+ cnt++;
+ tmp = tmp->nextP;
+ }
+ }
+
+ MUNLOCK(mtx);
+
+ info = MKUI(env, cnt);
+
+ SSDBG( descP, ("SOCKET", "socket_info_reqs -> done with"
+ "\r\n info: %T"
+ "\r\n", info) );
+
+ return info;
+}
+#endif
+
/* ----------------------------------------------------------------------
* nif_supports
@@ -3097,40 +3466,40 @@ ERL_NIF_TERM nif_supports(ErlNifEnv* env,
return enif_make_badarg(env);
}
- return nsupports(env, key);
+ return esock_supports(env, key);
#endif
}
-/* nsupports - what features do we support
+/* esock_supports - what features do we support
*
* This is to prove information about what features actually
* work on the current platform.
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports(ErlNifEnv* env, int key)
+ERL_NIF_TERM esock_supports(ErlNifEnv* env, int key)
{
ERL_NIF_TERM result;
- SGDBG( ("SOCKET", "nsupports -> entry with 0x%lX\r\n", key) );
+ SGDBG( ("SOCKET", "esock_supports -> entry with 0x%lX\r\n", key) );
switch (key) {
- case SOCKET_SUPPORTS_OPTIONS:
- result = nsupports_options(env);
+ case ESOCK_SUPPORTS_OPTIONS:
+ result = esock_supports_options(env);
break;
- case SOCKET_SUPPORTS_SCTP:
- result = nsupports_sctp(env);
+ case ESOCK_SUPPORTS_SCTP:
+ result = esock_supports_sctp(env);
break;
- case SOCKET_SUPPORTS_IPV6:
- result = nsupports_ipv6(env);
+ case ESOCK_SUPPORTS_IPV6:
+ result = esock_supports_ipv6(env);
break;
- case SOCKET_SUPPORTS_LOCAL:
- result = nsupports_local(env);
+ case ESOCK_SUPPORTS_LOCAL:
+ result = esock_supports_local(env);
break;
default:
@@ -3145,19 +3514,19 @@ ERL_NIF_TERM nsupports(ErlNifEnv* env, int key)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options(ErlNifEnv* env)
{
- ERL_NIF_TERM sockOpts = nsupports_options_socket(env);
+ ERL_NIF_TERM sockOpts = esock_supports_options_socket(env);
ERL_NIF_TERM sockOptsT = MKT2(env, esock_atom_socket, sockOpts);
- ERL_NIF_TERM ipOpts = nsupports_options_ip(env);
+ ERL_NIF_TERM ipOpts = esock_supports_options_ip(env);
ERL_NIF_TERM ipOptsT = MKT2(env, esock_atom_ip, ipOpts);
- ERL_NIF_TERM ipv6Opts = nsupports_options_ipv6(env);
+ ERL_NIF_TERM ipv6Opts = esock_supports_options_ipv6(env);
ERL_NIF_TERM ipv6OptsT = MKT2(env, esock_atom_ipv6, ipv6Opts);
- ERL_NIF_TERM tcpOpts = nsupports_options_tcp(env);
+ ERL_NIF_TERM tcpOpts = esock_supports_options_tcp(env);
ERL_NIF_TERM tcpOptsT = MKT2(env, esock_atom_tcp, tcpOpts);
- ERL_NIF_TERM udpOpts = nsupports_options_udp(env);
+ ERL_NIF_TERM udpOpts = esock_supports_options_udp(env);
ERL_NIF_TERM udpOptsT = MKT2(env, esock_atom_udp, udpOpts);
- ERL_NIF_TERM sctpOpts = nsupports_options_sctp(env);
+ ERL_NIF_TERM sctpOpts = esock_supports_options_sctp(env);
ERL_NIF_TERM sctpOptsT = MKT2(env, esock_atom_sctp, sctpOpts);
ERL_NIF_TERM optsA[] = {sockOptsT,
ipOptsT, ipv6OptsT,
@@ -3173,13 +3542,13 @@ ERL_NIF_TERM nsupports_options(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options_socket(ErlNifEnv* env)
{
SocketTArray opts = TARRAY_CREATE(128);
ERL_NIF_TERM tmp, optsL;
- /* *** SOCKET_OPT_SOCK_ACCEPTCONN => SO_ACCEPTCONN *** */
+ /* *** ESOCK_OPT_SOCK_ACCEPTCONN => SO_ACCEPTCONN *** */
#if defined(SO_ACCEPTCONN)
tmp = MKT2(env, esock_atom_acceptconn, esock_atom_true);
#else
@@ -3188,12 +3557,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_ACCEPTFILTER => SO_ACCEPTFILTER *** */
+ /* *** ESOCK_OPT_SOCK_ACCEPTFILTER => SO_ACCEPTFILTER *** */
tmp = MKT2(env, esock_atom_acceptfilter, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_BINDTODEVICE => SO_BINDTODEVICE *** */
+ /* *** ESOCK_OPT_SOCK_BINDTODEVICE => SO_BINDTODEVICE *** */
#if defined(SO_BINDTODEVICE)
tmp = MKT2(env, esock_atom_bindtodevice, esock_atom_true);
#else
@@ -3202,7 +3571,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_BROADCAST => SO_BROADCAST *** */
+ /* *** ESOCK_OPT_SOCK_BROADCAST => SO_BROADCAST *** */
#if defined(SO_BROADCAST)
tmp = MKT2(env, esock_atom_broadcast, esock_atom_true);
#else
@@ -3211,12 +3580,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_BUSY_POLL => SO_BUSY_POLL *** */
+ /* *** ESOCK_OPT_SOCK_BUSY_POLL => SO_BUSY_POLL *** */
tmp = MKT2(env, esock_atom_busy_poll, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_DEBUG => SO_DEBUG *** */
+ /* *** ESOCK_OPT_SOCK_DEBUG => SO_DEBUG *** */
#if defined(SO_DEBUG)
tmp = MKT2(env, esock_atom_debug, esock_atom_true);
#else
@@ -3225,7 +3594,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_DOMAIN => SO_DOMAIN *** */
+ /* *** ESOCK_OPT_SOCK_DOMAIN => SO_DOMAIN *** */
#if defined(SO_DOMAIN)
tmp = MKT2(env, esock_atom_domain, esock_atom_true);
#else
@@ -3234,7 +3603,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_DONTROUTE => SO_DONTROUTE *** */
+ /* *** ESOCK_OPT_SOCK_DONTROUTE => SO_DONTROUTE *** */
#if defined(SO_DONTROUTE)
tmp = MKT2(env, esock_atom_dontroute, esock_atom_true);
#else
@@ -3243,12 +3612,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_ERROR => SO_ERROR *** */
+ /* *** ESOCK_OPT_SOCK_ERROR => SO_ERROR *** */
tmp = MKT2(env, esock_atom_error, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_KEEPALIVE => SO_KEEPALIVE *** */
+ /* *** ESOCK_OPT_SOCK_KEEPALIVE => SO_KEEPALIVE *** */
#if defined(SO_KEEPALIVE)
tmp = MKT2(env, esock_atom_keepalive, esock_atom_true);
#else
@@ -3257,7 +3626,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_LINGER => SO_LINGER *** */
+ /* *** ESOCK_OPT_SOCK_LINGER => SO_LINGER *** */
#if defined(SO_LINGER)
tmp = MKT2(env, esock_atom_linger, esock_atom_true);
#else
@@ -3266,12 +3635,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_MARK => SO_MARK *** */
+ /* *** ESOCK_OPT_SOCK_MARK => SO_MARK *** */
tmp = MKT2(env, esock_atom_mark, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_OOBINLINE => SO_OOBINLINE *** */
+ /* *** ESOCK_OPT_SOCK_OOBINLINE => SO_OOBINLINE *** */
#if defined(SO_OOBINLINE)
tmp = MKT2(env, esock_atom_oobinline, esock_atom_true);
#else
@@ -3280,12 +3649,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_PASSCRED => SO_PASSCRED *** */
+ /* *** ESOCK_OPT_PASSCRED => SO_PASSCRED *** */
tmp = MKT2(env, esock_atom_passcred, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_PEEK_OFF => SO_PEEK_OFF *** */
+ /* *** ESOCK_OPT_SOCK_PEEK_OFF => SO_PEEK_OFF *** */
#if defined(SO_PEEK_OFF)
tmp = MKT2(env, esock_atom_peek_off, esock_atom_true);
#else
@@ -3294,12 +3663,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_PEEKCRED => SO_PEEKCRED *** */
+ /* *** ESOCK_OPT_SOCK_PEEKCRED => SO_PEEKCRED *** */
tmp = MKT2(env, esock_atom_peekcred, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_PRIORITY => SO_PRIORITY *** */
+ /* *** ESOCK_OPT_SOCK_PRIORITY => SO_PRIORITY *** */
#if defined(SO_PRIORITY)
tmp = MKT2(env, esock_atom_priority, esock_atom_true);
#else
@@ -3308,7 +3677,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_PROTOCOL => SO_PROTOCOL *** */
+ /* *** ESOCK_OPT_SOCK_PROTOCOL => SO_PROTOCOL *** */
#if defined(SO_PROTOCOL)
tmp = MKT2(env, esock_atom_protocol, esock_atom_true);
#else
@@ -3317,7 +3686,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_RCVBUF => SO_RCVBUF *** */
+ /* *** ESOCK_OPT_SOCK_RCVBUF => SO_RCVBUF *** */
#if defined(SO_RCVBUF)
tmp = MKT2(env, esock_atom_rcvbuf, esock_atom_true);
#else
@@ -3326,12 +3695,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_RCVBUFFORCE => SO_RCVBUFFORCE *** */
+ /* *** ESOCK_OPT_SOCK_RCVBUFFORCE => SO_RCVBUFFORCE *** */
tmp = MKT2(env, esock_atom_rcvbufforce, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_RCVLOWAT => SO_RCVLOWAT *** */
+ /* *** ESOCK_OPT_SOCK_RCVLOWAT => SO_RCVLOWAT *** */
#if defined(SO_RCVLOWAT)
tmp = MKT2(env, esock_atom_rcvlowat, esock_atom_true);
#else
@@ -3340,7 +3709,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_RCVTIMEO => SO_RCVTIMEO *** */
+ /* *** ESOCK_OPT_SOCK_RCVTIMEO => SO_RCVTIMEO *** */
#if defined(SO_RCVTIMEO)
tmp = MKT2(env, esock_atom_rcvtimeo, esock_atom_true);
#else
@@ -3349,7 +3718,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_REUSEADDR => SO_REUSEADDR *** */
+ /* *** ESOCK_OPT_SOCK_REUSEADDR => SO_REUSEADDR *** */
#if defined(SO_REUSEADDR)
tmp = MKT2(env, esock_atom_reuseaddr, esock_atom_true);
#else
@@ -3358,7 +3727,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_REUSEPORT => SO_REUSEPORT *** */
+ /* *** ESOCK_OPT_SOCK_REUSEPORT => SO_REUSEPORT *** */
#if defined(SO_REUSEPORT)
tmp = MKT2(env, esock_atom_reuseport, esock_atom_true);
#else
@@ -3367,17 +3736,17 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_RXQ_OVFL => SO_RXQ_OVFL *** */
+ /* *** ESOCK_OPT_SOCK_RXQ_OVFL => SO_RXQ_OVFL *** */
tmp = MKT2(env, esock_atom_rxq_ovfl, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_SETFIB => SO_SETFIB *** */
+ /* *** ESOCK_OPT_SOCK_SETFIB => SO_SETFIB *** */
tmp = MKT2(env, esock_atom_setfib, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_SNDBUF => SO_SNDBUF *** */
+ /* *** ESOCK_OPT_SOCK_SNDBUF => SO_SNDBUF *** */
#if defined(SO_SNDBUF)
tmp = MKT2(env, esock_atom_sndbuf, esock_atom_true);
#else
@@ -3386,12 +3755,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_SNDBUFFORCE => SO_SNDBUFFORCE *** */
+ /* *** ESOCK_OPT_SOCK_SNDBUFFORCE => SO_SNDBUFFORCE *** */
tmp = MKT2(env, esock_atom_sndbufforce, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_SNDLOWAT => SO_SNDLOWAT *** */
+ /* *** ESOCK_OPT_SOCK_SNDLOWAT => SO_SNDLOWAT *** */
#if defined(SO_SNDLOWAT)
tmp = MKT2(env, esock_atom_sndlowat, esock_atom_true);
#else
@@ -3400,7 +3769,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_SNDTIMEO => SO_SNDTIMEO *** */
+ /* *** ESOCK_OPT_SOCK_SNDTIMEO => SO_SNDTIMEO *** */
#if defined(SO_SNDTIMEO)
tmp = MKT2(env, esock_atom_sndtimeo, esock_atom_true);
#else
@@ -3409,7 +3778,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_TIMESTAMP => SO_TIMESTAMP *** */
+ /* *** ESOCK_OPT_SOCK_TIMESTAMP => SO_TIMESTAMP *** */
#if defined(SO_TIMESTAMP)
tmp = MKT2(env, esock_atom_timestamp, esock_atom_true);
#else
@@ -3418,7 +3787,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SOCK_TYPE => SO_TYPE *** */
+ /* *** ESOCK_OPT_SOCK_TYPE => SO_TYPE *** */
#if defined(SO_TYPE)
tmp = MKT2(env, esock_atom_type, esock_atom_true);
#else
@@ -3437,13 +3806,13 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options_ip(ErlNifEnv* env)
{
SocketTArray opts = TARRAY_CREATE(128);
ERL_NIF_TERM tmp, optsL;
- /* *** SOCKET_OPT_IP_ADD_MEMBERSHIP => IP_ADD_MEMBERSHIP *** */
+ /* *** ESOCK_OPT_IP_ADD_MEMBERSHIP => IP_ADD_MEMBERSHIP *** */
#if defined(IP_ADD_MEMBERSHIP)
tmp = MKT2(env, esock_atom_add_membership, esock_atom_true);
#else
@@ -3452,7 +3821,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP => IP_ADD_SOURCE_MEMBERSHIP *** */
+ /* *** ESOCK_OPT_IP_ADD_SOURCE_MEMBERSHIP => IP_ADD_SOURCE_MEMBERSHIP *** */
#if defined(IP_ADD_SOURCE_MEMBERSHIP)
tmp = MKT2(env, esock_atom_add_source_membership, esock_atom_true);
#else
@@ -3461,7 +3830,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_BLOCK_SOURCE => IP_BLOCK_SOURCE *** */
+ /* *** ESOCK_OPT_IP_BLOCK_SOURCE => IP_BLOCK_SOURCE *** */
#if defined(IP_BLOCK_SOURCE)
tmp = MKT2(env, esock_atom_block_source, esock_atom_true);
#else
@@ -3470,12 +3839,12 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_DONTFRAG => IP_DONTFRAG *** */
+ /* *** ESOCK_OPT_IP_DONTFRAG => IP_DONTFRAG *** */
tmp = MKT2(env, esock_atom_dontfrag, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_DROP_MEMBERSHIP => IP_DROP_MEMBERSHIP *** */
+ /* *** ESOCK_OPT_IP_DROP_MEMBERSHIP => IP_DROP_MEMBERSHIP *** */
#if defined(IP_DROP_MEMBERSHIP)
tmp = MKT2(env, esock_atom_drop_membership, esock_atom_true);
#else
@@ -3484,7 +3853,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP => IP_DROP_SOURCE_MEMBERSHIP *** */
+ /* *** ESOCK_OPT_IP_DROP_SOURCE_MEMBERSHIP => IP_DROP_SOURCE_MEMBERSHIP *** */
#if defined(IP_DROP_SOURCE_MEMBERSHIP)
tmp = MKT2(env, esock_atom_drop_source_membership, esock_atom_true);
#else
@@ -3493,7 +3862,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_FREEBIND => IP_FREEBIND *** */
+ /* *** ESOCK_OPT_IP_FREEBIND => IP_FREEBIND *** */
#if defined(IP_FREEBIND)
tmp = MKT2(env, esock_atom_freebind, esock_atom_true);
#else
@@ -3502,7 +3871,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_HDRINCL => IP_HDRINCL *** */
+ /* *** ESOCK_OPT_IP_HDRINCL => IP_HDRINCL *** */
#if defined(IP_HDRINCL)
tmp = MKT2(env, esock_atom_hdrincl, esock_atom_true);
#else
@@ -3511,7 +3880,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MINTTL => IP_MINTTL *** */
+ /* *** ESOCK_OPT_IP_MINTTL => IP_MINTTL *** */
#if defined(IP_MINTTL)
tmp = MKT2(env, esock_atom_minttl, esock_atom_true);
#else
@@ -3520,7 +3889,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MSFILTER => IP_MSFILTER / IP_MSFILTER_SIZE *** */
+ /* *** ESOCK_OPT_IP_MSFILTER => IP_MSFILTER / IP_MSFILTER_SIZE *** */
#if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE)
tmp = MKT2(env, esock_atom_msfilter, esock_atom_true);
#else
@@ -3529,12 +3898,12 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MTU => IP_MTU *** */
+ /* *** ESOCK_OPT_IP_MTU => IP_MTU *** */
tmp = MKT2(env, esock_atom_mtu, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MTU_DISCOVER => IP_MTU_DISCOVER *** */
+ /* *** ESOCK_OPT_IP_MTU_DISCOVER => IP_MTU_DISCOVER *** */
#if defined(IP_MTU_DISCOVER)
tmp = MKT2(env, esock_atom_mtu_discover, esock_atom_true);
#else
@@ -3543,7 +3912,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MULTICAST_ALL => IP_MULTICAST_ALL *** */
+ /* *** ESOCK_OPT_IP_MULTICAST_ALL => IP_MULTICAST_ALL *** */
#if defined(IP_MULTICAST_ALL)
tmp = MKT2(env, esock_atom_multicast_all, esock_atom_true);
#else
@@ -3552,7 +3921,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MULTICAST_IF => IP_MULTICAST_IF *** */
+ /* *** ESOCK_OPT_IP_MULTICAST_IF => IP_MULTICAST_IF *** */
#if defined(IP_MULTICAST_IF)
tmp = MKT2(env, esock_atom_multicast_if, esock_atom_true);
#else
@@ -3561,7 +3930,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MULTICAST_LOOP => IP_MULTICAST_LOOP *** */
+ /* *** ESOCK_OPT_IP_MULTICAST_LOOP => IP_MULTICAST_LOOP *** */
#if defined(IP_MULTICAST_LOOP)
tmp = MKT2(env, esock_atom_multicast_loop, esock_atom_true);
#else
@@ -3570,7 +3939,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_MULTICAST_TTL => IP_MULTICAST_TTL *** */
+ /* *** ESOCK_OPT_IP_MULTICAST_TTL => IP_MULTICAST_TTL *** */
#if defined(IP_MULTICAST_TTL)
tmp = MKT2(env, esock_atom_multicast_ttl, esock_atom_true);
#else
@@ -3579,7 +3948,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_NODEFRAG => IP_NODEFRAG *** */
+ /* *** ESOCK_OPT_IP_NODEFRAG => IP_NODEFRAG *** */
#if defined(IP_NODEFRAG)
tmp = MKT2(env, esock_atom_nodefrag, esock_atom_true);
#else
@@ -3588,12 +3957,12 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_OPTIONS => IP_OPTIONS *** */
+ /* *** ESOCK_OPT_IP_OPTIONS => IP_OPTIONS *** */
tmp = MKT2(env, esock_atom_options, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_PKTINFO => IP_PKTINFO *** */
+ /* *** ESOCK_OPT_IP_PKTINFO => IP_PKTINFO *** */
#if defined(IP_PKTINFO)
tmp = MKT2(env, esock_atom_pktinfo, esock_atom_true);
#else
@@ -3602,7 +3971,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVDSTADDR => IP_RECVDSTADDR *** */
+ /* *** ESOCK_OPT_IP_RECVDSTADDR => IP_RECVDSTADDR *** */
#if defined(IP_RECVDSTADDR)
tmp = MKT2(env, esock_atom_recvdstaddr, esock_atom_true);
#else
@@ -3611,7 +3980,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVERR => IP_RECVERR *** */
+ /* *** ESOCK_OPT_IP_RECVERR => IP_RECVERR *** */
#if defined(IP_RECVERR)
tmp = MKT2(env, esock_atom_recverr, esock_atom_true);
#else
@@ -3620,7 +3989,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVIF => IP_RECVIF *** */
+ /* *** ESOCK_OPT_IP_RECVIF => IP_RECVIF *** */
#if defined(IP_RECVIF)
tmp = MKT2(env, esock_atom_recvif, esock_atom_true);
#else
@@ -3629,7 +3998,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVOPTS => IP_RECVOPTS *** */
+ /* *** ESOCK_OPT_IP_RECVOPTS => IP_RECVOPTS *** */
#if defined(IP_RECVOPTS)
tmp = MKT2(env, esock_atom_recvopts, esock_atom_true);
#else
@@ -3638,7 +4007,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVORIGDSTADDR => IP_RECVORIGDSTADDR *** */
+ /* *** ESOCK_OPT_IP_RECVORIGDSTADDR => IP_RECVORIGDSTADDR *** */
#if defined(IP_RECVORIGDSTADDR)
tmp = MKT2(env, esock_atom_recvorigdstaddr, esock_atom_true);
#else
@@ -3647,7 +4016,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVTOS => IP_RECVTOS *** */
+ /* *** ESOCK_OPT_IP_RECVTOS => IP_RECVTOS *** */
#if defined(IP_RECVTOS)
tmp = MKT2(env, esock_atom_recvtos, esock_atom_true);
#else
@@ -3656,7 +4025,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RECVTTL => IP_RECVTTL *** */
+ /* *** ESOCK_OPT_IP_RECVTTL => IP_RECVTTL *** */
#if defined(IP_RECVTTL)
tmp = MKT2(env, esock_atom_recvttl, esock_atom_true);
#else
@@ -3665,7 +4034,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_RETOPTS => IP_RETOPTS *** */
+ /* *** ESOCK_OPT_IP_RETOPTS => IP_RETOPTS *** */
#if defined(IP_RETOPTS)
tmp = MKT2(env, esock_atom_retopts, esock_atom_true);
#else
@@ -3674,7 +4043,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_ROUTER_ALERT => IP_ROUTER_ALERT *** */
+ /* *** ESOCK_OPT_IP_ROUTER_ALERT => IP_ROUTER_ALERT *** */
#if defined(IP_ROUTER_ALERT)
tmp = MKT2(env, esock_atom_router_alert, esock_atom_true);
#else
@@ -3683,7 +4052,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_SENDSRCADDR => IP_SENDSRCADDR *** */
+ /* *** ESOCK_OPT_IP_SENDSRCADDR => IP_SENDSRCADDR *** */
#if defined(IP_SENDSRCADDR)
tmp = MKT2(env, esock_atom_sendsrcaddr, esock_atom_true);
#else
@@ -3692,7 +4061,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_TOS => IP_TOS *** */
+ /* *** ESOCK_OPT_IP_TOS => IP_TOS *** */
#if defined(IP_TOS)
tmp = MKT2(env, esock_atom_tos, esock_atom_true);
#else
@@ -3701,7 +4070,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_TRANSPARENT => IP_TRANSPARENT *** */
+ /* *** ESOCK_OPT_IP_TRANSPARENT => IP_TRANSPARENT *** */
#if defined(IP_TRANSPARENT)
tmp = MKT2(env, esock_atom_transparent, esock_atom_true);
#else
@@ -3710,7 +4079,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_TTL => IP_TTL *** */
+ /* *** ESOCK_OPT_IP_TTL => IP_TTL *** */
#if defined(IP_TTL)
tmp = MKT2(env, esock_atom_ttl, esock_atom_true);
#else
@@ -3719,7 +4088,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IP_UNBLOCK_SOURCE => IP_UNBLOCK_SOURCE *** */
+ /* *** ESOCK_OPT_IP_UNBLOCK_SOURCE => IP_UNBLOCK_SOURCE *** */
#if defined(IP_UNBLOCK_SOURCE)
tmp = MKT2(env, esock_atom_unblock_source, esock_atom_true);
#else
@@ -3738,13 +4107,13 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options_ipv6(ErlNifEnv* env)
{
SocketTArray opts = TARRAY_CREATE(128);
ERL_NIF_TERM tmp, optsL;
- /* *** SOCKET_OPT_IPV6_ADDRFORM => IPV6_ADDRFORM *** */
+ /* *** ESOCK_OPT_IPV6_ADDRFORM => IPV6_ADDRFORM *** */
#if defined(IPV6_ADDRFORM)
tmp = MKT2(env, esock_atom_addrform, esock_atom_true);
#else
@@ -3753,7 +4122,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_ADD_MEMBERSHIP => IPV6_ADD_MEMBERSHIP *** */
+ /* *** ESOCK_OPT_IPV6_ADD_MEMBERSHIP => IPV6_ADD_MEMBERSHIP *** */
#if defined(IPV6_ADD_MEMBERSHIP)
tmp = MKT2(env, esock_atom_add_membership, esock_atom_true);
#else
@@ -3762,7 +4131,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_AUTHHDR => IPV6_AUTHHDR *** */
+ /* *** ESOCK_OPT_IPV6_AUTHHDR => IPV6_AUTHHDR *** */
#if defined(IPV6_AUTHHDR)
tmp = MKT2(env, esock_atom_authhdr, esock_atom_true);
#else
@@ -3771,17 +4140,17 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_AUTH_LEVEL => IPV6_AUTH_LEVEL *** */
+ /* *** ESOCK_OPT_IPV6_AUTH_LEVEL => IPV6_AUTH_LEVEL *** */
tmp = MKT2(env, esock_atom_auth_level, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_CHECKSUM => IPV6_CHECKSUM *** */
+ /* *** ESOCK_OPT_IPV6_CHECKSUM => IPV6_CHECKSUM *** */
tmp = MKT2(env, esock_atom_checksum, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_DROP_MEMBERSHIP => IPV6_DROP_MEMBERSHIP *** */
+ /* *** ESOCK_OPT_IPV6_DROP_MEMBERSHIP => IPV6_DROP_MEMBERSHIP *** */
#if defined(IPV6_DROP_MEMBERSHIP)
tmp = MKT2(env, esock_atom_drop_membership, esock_atom_true);
#else
@@ -3790,7 +4159,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_DSTOPTS => IPV6_DSTOPTS *** */
+ /* *** ESOCK_OPT_IPV6_DSTOPTS => IPV6_DSTOPTS *** */
#if defined(IPV6_DSTOPTS)
tmp = MKT2(env, esock_atom_dstopts, esock_atom_true);
#else
@@ -3799,22 +4168,22 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_ESP_NETWORK_LEVEL => IPV6_ESP_NETWORK_LEVEL *** */
+ /* *** ESOCK_OPT_IPV6_ESP_NETWORK_LEVEL => IPV6_ESP_NETWORK_LEVEL *** */
tmp = MKT2(env, esock_atom_esp_network_level, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_ESP_TRANS_LEVEL => IPV6_ESP_TRANS_LEVEL *** */
+ /* *** ESOCK_OPT_IPV6_ESP_TRANS_LEVEL => IPV6_ESP_TRANS_LEVEL *** */
tmp = MKT2(env, esock_atom_esp_trans_level, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_FAITH => IPV6_FAITH *** */
+ /* *** ESOCK_OPT_IPV6_FAITH => IPV6_FAITH *** */
tmp = MKT2(env, esock_atom_faith, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_FLOWINFO => IPV6_FLOWINFO *** */
+ /* *** ESOCK_OPT_IPV6_FLOWINFO => IPV6_FLOWINFO *** */
#if defined(IPV6_FLOWINFO)
tmp = MKT2(env, esock_atom_flowinfo, esock_atom_true);
#else
@@ -3823,7 +4192,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_HOPLIMIT => IPV6_HOPLIMIT *** */
+ /* *** ESOCK_OPT_IPV6_HOPLIMIT => IPV6_HOPLIMIT *** */
#if defined(IPV6_HOPLIMIT)
tmp = MKT2(env, esock_atom_hoplimit, esock_atom_true);
#else
@@ -3832,7 +4201,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_HOPOPTS => IPV6_HOPOPTS *** */
+ /* *** ESOCK_OPT_IPV6_HOPOPTS => IPV6_HOPOPTS *** */
#if defined(IPV6_HOPOPTS)
tmp = MKT2(env, esock_atom_hopopts, esock_atom_true);
#else
@@ -3841,22 +4210,22 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_IPCOMP_LEVEL => IPV6_IPCOMP_LEVEL *** */
+ /* *** ESOCK_OPT_IPV6_IPCOMP_LEVEL => IPV6_IPCOMP_LEVEL *** */
tmp = MKT2(env, esock_atom_ipcomp_level, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_JOIN_GROUP => IPV6_JOIN_GROUP *** */
+ /* *** ESOCK_OPT_IPV6_JOIN_GROUP => IPV6_JOIN_GROUP *** */
tmp = MKT2(env, esock_atom_join_group, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_LEAVE_GROUP => IPV6_LEAVE_GROUP *** */
+ /* *** ESOCK_OPT_IPV6_LEAVE_GROUP => IPV6_LEAVE_GROUP *** */
tmp = MKT2(env, esock_atom_leave_group, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_MTU => IPV6_MTU *** */
+ /* *** ESOCK_OPT_IPV6_MTU => IPV6_MTU *** */
#if defined(IPV6_MTU)
tmp = MKT2(env, esock_atom_mtu, esock_atom_true);
#else
@@ -3865,7 +4234,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_MTU_DISCOVER => IPV6_MTU_DISCOVER *** */
+ /* *** ESOCK_OPT_IPV6_MTU_DISCOVER => IPV6_MTU_DISCOVER *** */
#if defined(IPV6_MTU_DISCOVER)
tmp = MKT2(env, esock_atom_mtu_discover, esock_atom_true);
#else
@@ -3874,7 +4243,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_MULTICAST_HOPS => IPV6_MULTICAST_HOPS *** */
+ /* *** ESOCK_OPT_IPV6_MULTICAST_HOPS => IPV6_MULTICAST_HOPS *** */
#if defined(IPV6_MULTICAST_HOPS)
tmp = MKT2(env, esock_atom_multicast_hops, esock_atom_true);
#else
@@ -3883,7 +4252,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_MULTICAST_IF => IPV6_MULTICAST_IF *** */
+ /* *** ESOCK_OPT_IPV6_MULTICAST_IF => IPV6_MULTICAST_IF *** */
#if defined(IPV6_MULTICAST_IF)
tmp = MKT2(env, esock_atom_multicast_if, esock_atom_true);
#else
@@ -3892,7 +4261,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_MULTICAST_LOOP => IPV6_MULTICAST_LOOP *** */
+ /* *** ESOCK_OPT_IPV6_MULTICAST_LOOP => IPV6_MULTICAST_LOOP *** */
#if defined(IPV6_MULTICAST_LOOP)
tmp = MKT2(env, esock_atom_multicast_loop, esock_atom_true);
#else
@@ -3901,17 +4270,17 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_PORTRANGE => IPV6_PORTRANGE *** */
+ /* *** ESOCK_OPT_IPV6_PORTRANGE => IPV6_PORTRANGE *** */
tmp = MKT2(env, esock_atom_portrange, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_PKTOPTIONS => IPV6_PKTOPTIONS *** */
+ /* *** ESOCK_OPT_IPV6_PKTOPTIONS => IPV6_PKTOPTIONS *** */
tmp = MKT2(env, esock_atom_pktoptions, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_RECVERR => IPV6_RECVERR *** */
+ /* *** ESOCK_OPT_IPV6_RECVERR => IPV6_RECVERR *** */
#if defined(IPV6_RECVERR)
tmp = MKT2(env, esock_atom_recverr, esock_atom_true);
#else
@@ -3920,7 +4289,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_RECVPKTINFO => IPV6_RECVPKTINFO *** */
+ /* *** ESOCK_OPT_IPV6_RECVPKTINFO => IPV6_RECVPKTINFO *** */
#if defined(IPV6_RECVPKTINFO)
tmp = MKT2(env, esock_atom_recvpktinfo, esock_atom_true);
#else
@@ -3929,12 +4298,12 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_RECVTCLASS => IPV6_RECVTCLASS *** */
+ /* *** ESOCK_OPT_IPV6_RECVTCLASS => IPV6_RECVTCLASS *** */
tmp = MKT2(env, esock_atom_recvtclass, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_ROUTER_ALERT => IPV6_ROUTER_ALERT *** */
+ /* *** ESOCK_OPT_IPV6_ROUTER_ALERT => IPV6_ROUTER_ALERT *** */
#if defined(IPV6_ROUTER_ALERT)
tmp = MKT2(env, esock_atom_router_alert, esock_atom_true);
#else
@@ -3943,7 +4312,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_RTHDR => IPV6_RTHDR *** */
+ /* *** ESOCK_OPT_IPV6_RTHDR => IPV6_RTHDR *** */
#if defined(IPV6_RTHDR)
tmp = MKT2(env, esock_atom_rthdr, esock_atom_true);
#else
@@ -3952,12 +4321,12 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_TCLASS => IPV6_TCLASS *** */
+ /* *** ESOCK_OPT_IPV6_TCLASS => IPV6_TCLASS *** */
tmp = MKT2(env, esock_atom_tclass, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_UNICAST_HOPS => IPV6_UNICAST_HOPS *** */
+ /* *** ESOCK_OPT_IPV6_UNICAST_HOPS => IPV6_UNICAST_HOPS *** */
#if defined(IPV6_UNICAST_HOPS)
tmp = MKT2(env, esock_atom_unicast_hops, esock_atom_true);
#else
@@ -3966,12 +4335,12 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_USE_MIN_MTU => IPV6_USE_MIN_MTU *** */
+ /* *** ESOCK_OPT_IPV6_USE_MIN_MTU => IPV6_USE_MIN_MTU *** */
tmp = MKT2(env, esock_atom_use_min_mtu, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_IPV6_V6ONLY => IPV6_V6ONLY *** */
+ /* *** ESOCK_OPT_IPV6_V6ONLY => IPV6_V6ONLY *** */
#if defined(IPV6_V6ONLY)
tmp = MKT2(env, esock_atom_v6only, esock_atom_true);
#else
@@ -3990,13 +4359,13 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options_tcp(ErlNifEnv* env)
{
SocketTArray opts = TARRAY_CREATE(32);
ERL_NIF_TERM tmp, optsL;
- /* *** SOCKET_OPT_TCP_CONGESTION => TCP_CONGESTION *** */
+ /* *** ESOCK_OPT_TCP_CONGESTION => TCP_CONGESTION *** */
#if defined(TCP_CONGESTION)
tmp = MKT2(env, esock_atom_congestion, esock_atom_true);
#else
@@ -4005,7 +4374,7 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_CORK => TCP_CORK *** */
+ /* *** ESOCK_OPT_TCP_CORK => TCP_CORK *** */
#if defined(TCP_CORK)
tmp = MKT2(env, esock_atom_cork, esock_atom_true);
#else
@@ -4014,27 +4383,27 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_INFO => TCP_INFO *** */
+ /* *** ESOCK_OPT_TCP_INFO => TCP_INFO *** */
tmp = MKT2(env, esock_atom_info, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_KEEPCNT => TCP_KEEPCNT *** */
+ /* *** ESOCK_OPT_TCP_KEEPCNT => TCP_KEEPCNT *** */
tmp = MKT2(env, esock_atom_keepcnt, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_KEEPIDLE => TCP_KEEPIDLE *** */
+ /* *** ESOCK_OPT_TCP_KEEPIDLE => TCP_KEEPIDLE *** */
tmp = MKT2(env, esock_atom_keepidle, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_KEEPINTVL => TCP_KEEPINTVL *** */
+ /* *** ESOCK_OPT_TCP_KEEPINTVL => TCP_KEEPINTVL *** */
tmp = MKT2(env, esock_atom_keepintvl, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_MAXSEG => TCP_MAXSEG *** */
+ /* *** ESOCK_OPT_TCP_MAXSEG => TCP_MAXSEG *** */
#if defined(TCP_MAXSEG)
tmp = MKT2(env, esock_atom_maxseg, esock_atom_true);
#else
@@ -4043,12 +4412,12 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_MD5SIG => TCP_MD5SIG *** */
+ /* *** ESOCK_OPT_TCP_MD5SIG => TCP_MD5SIG *** */
tmp = MKT2(env, esock_atom_md5sig, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_NODELAY => TCP_NODELAY *** */
+ /* *** ESOCK_OPT_TCP_NODELAY => TCP_NODELAY *** */
#if defined(TCP_NODELAY)
tmp = MKT2(env, esock_atom_nodelay, esock_atom_true);
#else
@@ -4057,22 +4426,22 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_NOOPT => TCP_NOOPT *** */
+ /* *** ESOCK_OPT_TCP_NOOPT => TCP_NOOPT *** */
tmp = MKT2(env, esock_atom_noopt, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_NOPUSH => TCP_NOPUSH *** */
+ /* *** ESOCK_OPT_TCP_NOPUSH => TCP_NOPUSH *** */
tmp = MKT2(env, esock_atom_nopush, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_SYNCNT => TCP_SYNCNT *** */
+ /* *** ESOCK_OPT_TCP_SYNCNT => TCP_SYNCNT *** */
tmp = MKT2(env, esock_atom_syncnt, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_TCP_USER_TIMEOUT => TCP_USER_TIMEOUT *** */
+ /* *** ESOCK_OPT_TCP_USER_TIMEOUT => TCP_USER_TIMEOUT *** */
tmp = MKT2(env, esock_atom_user_timeout, esock_atom_false);
TARRAY_ADD(opts, tmp);
@@ -4087,13 +4456,13 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options_udp(ErlNifEnv* env)
{
SocketTArray opts = TARRAY_CREATE(8);
ERL_NIF_TERM tmp, optsL;
- /* *** SOCKET_OPT_UDP_CORK => UDP_CORK *** */
+ /* *** ESOCK_OPT_UDP_CORK => UDP_CORK *** */
#if defined(UDP_CORK)
tmp = MKT2(env, esock_atom_cork, esock_atom_true);
#else
@@ -4112,18 +4481,18 @@ ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_options_sctp(ErlNifEnv* env)
{
SocketTArray opts = TARRAY_CREATE(64);
ERL_NIF_TERM tmp, optsL;
- /* *** SOCKET_OPT_SCTP_ADAPTION_LAYER => SCTP_ADAPTION_LAYER *** */
+ /* *** ESOCK_OPT_SCTP_ADAPTION_LAYER => SCTP_ADAPTION_LAYER *** */
tmp = MKT2(env, esock_atom_adaption_layer, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_ASSOCINFO => SCTP_ASSOCINFO *** */
+ /* *** ESOCK_OPT_SCTP_ASSOCINFO => SCTP_ASSOCINFO *** */
#if defined(SCTP_ASSOCINFO)
tmp = MKT2(env, esock_atom_associnfo, esock_atom_true);
#else
@@ -4132,32 +4501,32 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_AUTH_ACTIVE_KEY => SCTP_AUTH_ACTIVE_KEY *** */
+ /* *** ESOCK_OPT_SCTP_AUTH_ACTIVE_KEY => SCTP_AUTH_ACTIVE_KEY *** */
tmp = MKT2(env, esock_atom_auth_active_key, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_AUTH_ASCONF => SCTP_AUTH_ASCONF *** */
+ /* *** ESOCK_OPT_SCTP_AUTH_ASCONF => SCTP_AUTH_ASCONF *** */
tmp = MKT2(env, esock_atom_auth_asconf, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_AUTH_CHUNK => SCTP_AUTH_CHUNK *** */
+ /* *** ESOCK_OPT_SCTP_AUTH_CHUNK => SCTP_AUTH_CHUNK *** */
tmp = MKT2(env, esock_atom_auth_chunk, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_AUTH_DELETE_KEY => SCTP_AUTH_DELETE_KEY *** */
+ /* *** ESOCK_OPT_SCTP_AUTH_DELETE_KEY => SCTP_AUTH_DELETE_KEY *** */
tmp = MKT2(env, esock_atom_auth_delete_key, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_AUTH_KEY => SCTP_AUTH_KEY *** */
+ /* *** ESOCK_OPT_SCTP_AUTH_KEY => SCTP_AUTH_KEY *** */
tmp = MKT2(env, esock_atom_auth_key, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_AUTOCLOSE => SCTP_AUTOCLOSE *** */
+ /* *** ESOCK_OPT_SCTP_AUTOCLOSE => SCTP_AUTOCLOSE *** */
#if defined(SCTP_AUTOCLOSE)
tmp = MKT2(env, esock_atom_autoclose, esock_atom_true);
#else
@@ -4166,22 +4535,22 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_CONTEXT => SCTP_CONTEXT *** */
+ /* *** ESOCK_OPT_SCTP_CONTEXT => SCTP_CONTEXT *** */
tmp = MKT2(env, esock_atom_context, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_DEFAULT_SEND_PARAMS => SCTP_DEFAULT_SEND_PARAMS *** */
+ /* *** ESOCK_OPT_SCTP_DEFAULT_SEND_PARAMS => SCTP_DEFAULT_SEND_PARAMS *** */
tmp = MKT2(env, esock_atom_default_send_params, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_DELAYED_ACK_TIME => SCTP_DELAYED_ACK_TIME *** */
+ /* *** ESOCK_OPT_SCTP_DELAYED_ACK_TIME => SCTP_DELAYED_ACK_TIME *** */
tmp = MKT2(env, esock_atom_delayed_ack_time, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_DISABLE_FRAGMENTS => SCTP_DISABLE_FRAGMENTS *** */
+ /* *** ESOCK_OPT_SCTP_DISABLE_FRAGMENTS => SCTP_DISABLE_FRAGMENTS *** */
#if defined(SCTP_DISABLE_FRAGMENTS)
tmp = MKT2(env, esock_atom_disable_fragments, esock_atom_true);
#else
@@ -4190,12 +4559,12 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_HMAC_IDENT => SCTP_HMAC_IDENT *** */
+ /* *** ESOCK_OPT_SCTP_HMAC_IDENT => SCTP_HMAC_IDENT *** */
tmp = MKT2(env, esock_atom_hmac_ident, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_EVENTS => SCTP_EVENTS *** */
+ /* *** ESOCK_OPT_SCTP_EVENTS => SCTP_EVENTS *** */
#if defined(SCTP_EVENTS)
tmp = MKT2(env, esock_atom_events, esock_atom_true);
#else
@@ -4204,22 +4573,22 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_EXPLICIT_EOR => SCTP_EXPLICIT_EOR *** */
+ /* *** ESOCK_OPT_SCTP_EXPLICIT_EOR => SCTP_EXPLICIT_EOR *** */
tmp = MKT2(env, esock_atom_explicit_eor, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_FRAGMENT_INTERLEAVE => SCTP_FRAGMENT_INTERLEAVE *** */
+ /* *** ESOCK_OPT_SCTP_FRAGMENT_INTERLEAVE => SCTP_FRAGMENT_INTERLEAVE *** */
tmp = MKT2(env, esock_atom_fragment_interleave, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_GET_PEER_ADDR_INFO => SCTP_GET_PEER_ADDR_INFO *** */
+ /* *** ESOCK_OPT_SCTP_GET_PEER_ADDR_INFO => SCTP_GET_PEER_ADDR_INFO *** */
tmp = MKT2(env, esock_atom_get_peer_addr_info, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_INITMSG => SCTP_INITMSG *** */
+ /* *** ESOCK_OPT_SCTP_INITMSG => SCTP_INITMSG *** */
#if defined(SCTP_INITMSG)
tmp = MKT2(env, esock_atom_initmsg, esock_atom_true);
#else
@@ -4228,17 +4597,17 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_I_WANT_MAPPED_V4_ADDR => SCTP_I_WANT_MAPPED_V4_ADDR *** */
+ /* *** ESOCK_OPT_SCTP_I_WANT_MAPPED_V4_ADDR => SCTP_I_WANT_MAPPED_V4_ADDR *** */
tmp = MKT2(env, esock_atom_i_want_mapped_v4_addr, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_LOCAL_AUTH_CHUNKS => SCTP_LOCAL_AUTH_CHUNKS *** */
+ /* *** ESOCK_OPT_SCTP_LOCAL_AUTH_CHUNKS => SCTP_LOCAL_AUTH_CHUNKS *** */
tmp = MKT2(env, esock_atom_local_auth_chunks, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_MAXSEG => SCTP_MAXSEG *** */
+ /* *** ESOCK_OPT_SCTP_MAXSEG => SCTP_MAXSEG *** */
#if defined(SCTP_MAXSEG)
tmp = MKT2(env, esock_atom_maxseg, esock_atom_true);
#else
@@ -4247,12 +4616,12 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_MAXBURST => SCTP_MAXBURST *** */
+ /* *** ESOCK_OPT_SCTP_MAXBURST => SCTP_MAXBURST *** */
tmp = MKT2(env, esock_atom_maxburst, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_NODELAY => SCTP_NODELAY *** */
+ /* *** ESOCK_OPT_SCTP_NODELAY => SCTP_NODELAY *** */
#if defined(SCTP_NODELAY)
tmp = MKT2(env, esock_atom_nodelay, esock_atom_true);
#else
@@ -4261,32 +4630,32 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_PARTIAL_DELIVERY_POINT => SCTP_PARTIAL_DELIVERY_POINT *** */
+ /* *** ESOCK_OPT_SCTP_PARTIAL_DELIVERY_POINT => SCTP_PARTIAL_DELIVERY_POINT *** */
tmp = MKT2(env, esock_atom_partial_delivery_point, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_PEER_ADDR_PARAMS => SCTP_PEER_ADDR_PARAMS *** */
+ /* *** ESOCK_OPT_SCTP_PEER_ADDR_PARAMS => SCTP_PEER_ADDR_PARAMS *** */
tmp = MKT2(env, esock_atom_peer_addr_params, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_PEER_AUTH_CHUNKS => SCTP_PEER_AUTH_CHUNKS *** */
+ /* *** ESOCK_OPT_SCTP_PEER_AUTH_CHUNKS => SCTP_PEER_AUTH_CHUNKS *** */
tmp = MKT2(env, esock_atom_peer_auth_chunks, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_PRIMARY_ADDR => SCTP_PRIMARY_ADDR *** */
+ /* *** ESOCK_OPT_SCTP_PRIMARY_ADDR => SCTP_PRIMARY_ADDR *** */
tmp = MKT2(env, esock_atom_primary_addr, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_RESET_STREAMS => SCTP_RESET_STREAMS *** */
+ /* *** ESOCK_OPT_SCTP_RESET_STREAMS => SCTP_RESET_STREAMS *** */
tmp = MKT2(env, esock_atom_reset_streams, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_RTOINFO => SCTP_RTOINFO *** */
+ /* *** ESOCK_OPT_SCTP_RTOINFO => SCTP_RTOINFO *** */
#if defined(SCTP_RTOINFO)
tmp = MKT2(env, esock_atom_rtoinfo, esock_atom_true);
#else
@@ -4295,17 +4664,17 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_SET_PEER_PRIMARY_ADDR => SCTP_SET_PEER_PRIMARY_ADDR *** */
+ /* *** ESOCK_OPT_SCTP_SET_PEER_PRIMARY_ADDR => SCTP_SET_PEER_PRIMARY_ADDR *** */
tmp = MKT2(env, esock_atom_set_peer_primary_addr, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_STATUS => SCTP_STATUS *** */
+ /* *** ESOCK_OPT_SCTP_STATUS => SCTP_STATUS *** */
tmp = MKT2(env, esock_atom_status, esock_atom_false);
TARRAY_ADD(opts, tmp);
- /* *** SOCKET_OPT_SCTP_USE_EXT_RECVINFO => SCTP_USE_EXT_RECVINFO *** */
+ /* *** ESOCK_OPT_SCTP_USE_EXT_RECVINFO => SCTP_USE_EXT_RECVINFO *** */
tmp = MKT2(env, esock_atom_use_ext_recvinfo, esock_atom_false);
TARRAY_ADD(opts, tmp);
@@ -4320,7 +4689,7 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_sctp(ErlNifEnv* env)
{
ERL_NIF_TERM supports;
@@ -4338,7 +4707,7 @@ ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_ipv6(ErlNifEnv* env)
{
ERL_NIF_TERM supports;
@@ -4357,7 +4726,7 @@ ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env)
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsupports_local(ErlNifEnv* env)
+ERL_NIF_TERM esock_supports_local(ErlNifEnv* env)
{
ERL_NIF_TERM supports;
@@ -4449,7 +4818,7 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env,
#endif
- result = nopen(env, domain, type, proto, netns);
+ result = esock_open(env, domain, type, proto, netns);
SGDBG( ("SOCKET", "nif_open -> done with result: "
"\r\n %T"
@@ -4461,7 +4830,7 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env,
}
-/* nopen - create an endpoint for communication
+/* esock_open - create an endpoint for communication
*
* Assumes the input has been validated.
*
@@ -4472,9 +4841,9 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nopen(ErlNifEnv* env,
- int domain, int type, int protocol,
- char* netns)
+ERL_NIF_TERM esock_open(ErlNifEnv* env,
+ int domain, int type, int protocol,
+ char* netns)
{
ESockDescriptor* descP;
ERL_NIF_TERM res;
@@ -4485,7 +4854,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
int current_ns = 0;
#endif
- SGDBG( ("SOCKET", "nopen -> entry with"
+ SGDBG( ("SOCKET", "esock_open -> entry with"
"\r\n domain: %d"
"\r\n type: %d"
"\r\n protocol: %d"
@@ -4501,7 +4870,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
if ((sock = sock_open(domain, type, proto)) == INVALID_SOCKET)
return esock_make_error_errno(env, sock_errno());
- SGDBG( ("SOCKET", "nopen -> open success: %d\r\n", sock) );
+ SGDBG( ("SOCKET", "esock_open -> open success: %d\r\n", sock) );
/* NOTE that if the protocol = 0 (default) and the domain is not
@@ -4513,7 +4882,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
&& (domain != AF_LOCAL)
#endif
)
- if (!nopen_which_protocol(sock, &proto)) {
+ if (!esock_open_which_protocol(sock, &proto)) {
if (proto == ESOCK_WHICH_PROTO_ERROR) {
save_errno = sock_errno();
while ((sock_close(sock) == INVALID_SOCKET) &&
@@ -4543,7 +4912,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
return esock_make_error_errno(env, save_errno);
}
- SGDBG( ("SOCKET", "nopen -> event success: %d\r\n", event) );
+ SGDBG( ("SOCKET", "esock_open -> event success: %d\r\n", event) );
SET_NONBLOCKING(sock);
@@ -4555,7 +4924,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
return enif_make_badarg(env);
}
- descP->state = SOCKET_STATE_OPEN;
+ descP->state = ESOCK_STATE_OPEN;
descP->domain = domain;
descP->type = type;
descP->protocol = proto;
@@ -4584,7 +4953,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
if (enif_self(env, &descP->ctrlPid) == NULL)
return esock_make_error(env, atom_exself);
- if (MONP("nopen -> ctrl",
+ if (MONP("esock_open -> ctrl",
env, descP,
&descP->ctrlPid,
&descP->ctrlMon) != 0)
@@ -4598,7 +4967,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
static
-BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto)
+BOOLEAN_T esock_open_which_protocol(SOCKET sock, int* proto)
{
#if defined(SO_PROTOCOL)
int val;
@@ -4757,7 +5126,7 @@ ERL_NIF_TERM nif_bind(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 2) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
return enif_make_badarg(env);
}
eSockAddr = argv[1];
@@ -4774,13 +5143,13 @@ ERL_NIF_TERM nif_bind(ErlNifEnv* env,
/* Make sure we are ready
* Not sure how this would even happen, but...
*/
- if (descP->state != SOCKET_STATE_OPEN)
+ if (descP->state != ESOCK_STATE_OPEN)
return esock_make_error(env, atom_exbadstate);
if ((xres = esock_decode_sockaddr(env, eSockAddr, &sockAddr, &addrLen)) != NULL)
return esock_make_error_str(env, xres);
- return nbind(env, descP, &sockAddr, addrLen);
+ return esock_bind(env, descP, &sockAddr, addrLen);
#endif // if defined(__WIN32__)
}
@@ -4788,24 +5157,24 @@ ERL_NIF_TERM nif_bind(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nbind(ErlNifEnv* env,
- ESockDescriptor* descP,
- ESockAddress* sockAddrP,
- unsigned int addrLen)
+ERL_NIF_TERM esock_bind(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ESockAddress* sockAddrP,
+ unsigned int addrLen)
{
int port, ntohs_port;
- SSDBG( descP, ("SOCKET", "nbind -> try bind\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_bind -> try bind\r\n") );
if (IS_SOCKET_ERROR(sock_bind(descP->sock,
(struct sockaddr*) sockAddrP, addrLen))) {
return esock_make_error_errno(env, sock_errno());
}
- SSDBG( descP, ("SOCKET", "nbind -> bound - get port\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_bind -> bound - get port\r\n") );
port = which_address_port(sockAddrP);
- SSDBG( descP, ("SOCKET", "nbind -> port: %d\r\n", port) );
+ SSDBG( descP, ("SOCKET", "esock_bind -> port: %d\r\n", port) );
if (port == 0) {
SOCKLEN_T len = sizeof(ESockAddress);
sys_memzero((char *) sockAddrP, len);
@@ -4817,7 +5186,8 @@ ERL_NIF_TERM nbind(ErlNifEnv* env,
ntohs_port = sock_ntohs(port);
- SSDBG( descP, ("SOCKET", "nbind -> done with port = %d\r\n", ntohs_port) );
+ SSDBG( descP, ("SOCKET",
+ "esock_bind -> done with port = %d\r\n", ntohs_port) );
return esock_make_ok2(env, MKI(env, ntohs_port));
@@ -4857,7 +5227,7 @@ ERL_NIF_TERM nif_connect(ErlNifEnv* env,
sockRef = argv[0];
if ((argc != 2) ||
- !enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
eSockAddr = argv[1];
@@ -4884,7 +5254,7 @@ ERL_NIF_TERM nif_connect(ErlNifEnv* env,
MLOCK(descP->writeMtx);
MLOCK(descP->cfgMtx);
- res = nconnect(env, descP, sockRef);
+ res = esock_connect(env, descP, sockRef);
MUNLOCK(descP->cfgMtx);
MUNLOCK(descP->writeMtx);
@@ -4898,9 +5268,9 @@ ERL_NIF_TERM nif_connect(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nconnect(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef)
+ERL_NIF_TERM esock_connect(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef)
{
ERL_NIF_TERM res, ref;
int code, sres, save_errno = 0;
@@ -4913,17 +5283,17 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
return esock_make_error(env, atom_closed);
if (!IS_OPEN(descP)) {
- SSDBG( descP, ("SOCKET", "nconnect -> not open\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_connect -> not open\r\n") );
return esock_make_error(env, atom_exbadstate);
}
if (IS_CONNECTED(descP)) {
- SSDBG( descP, ("SOCKET", "nconnect -> already connected\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_connect -> already connected\r\n") );
return esock_make_error(env, atom_eisconn);
}
if (IS_CONNECTING(descP) && !is_connector(env, descP)) {
- SSDBG( descP, ("SOCKET", "nconnect -> already connecting\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_connect -> already connecting\r\n") );
return esock_make_error(env, esock_atom_einval);
}
@@ -4937,14 +5307,15 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
descP->addrLen);
save_errno = sock_errno();
- SSDBG( descP, ("SOCKET", "nconnect -> connect result: %d, %d\r\n",
+ SSDBG( descP, ("SOCKET", "esock_connect -> connect result: %d, %d\r\n",
code, save_errno) );
if (IS_SOCKET_ERROR(code)) {
switch (save_errno) {
case ERRNO_BLOCK: /* Winsock2 */
case EINPROGRESS: /* Unix & OSE!! */
- SSDBG( descP, ("SOCKET", "nconnect -> would block => select\r\n") );
+ SSDBG( descP, ("SOCKET",
+ "esock_connect -> would block => select\r\n") );
ref = MKREF(env);
@@ -4958,13 +5329,13 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
if (enif_self(env, &descP->connPid) == NULL)
return esock_make_error(env, atom_exself);
- if (MONP("nconnect -> conn",
+ if (MONP("esock_connect -> conn",
env, descP,
&descP->connPid,
&descP->connMon) != 0)
return esock_make_error(env, atom_exmon);
- descP->state = SOCKET_STATE_CONNECTING;
+ descP->state = ESOCK_STATE_CONNECTING;
if ((sres = esock_select_write(env, descP->sock, descP, NULL,
sockRef, ref)) < 0) {
@@ -4979,18 +5350,19 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
break;
case EISCONN:
- SSDBG( descP, ("SOCKET", "nconnect -> *already* connected\r\n") );
+ SSDBG( descP, ("SOCKET",
+ "esock_connect -> *already* connected\r\n") );
{
/* This is ***strange*** so make sure */
int err = 0;
if (!verify_is_connected(descP, &err)) {
- descP->state = SOCKET_STATE_OPEN; /* restore state */
+ descP->state = ESOCK_STATE_OPEN; /* restore state */
res = esock_make_error_errno(env, err);
} else {
- descP->state = SOCKET_STATE_CONNECTED;
+ descP->state = ESOCK_STATE_CONNECTED;
/* And just to be on the safe side, reset these */
enif_set_pid_undefined(&descP->connPid);
- DEMONP("nconnect -> connected",
+ DEMONP("esock_connect -> connected",
env, descP, &descP->connMon);
descP->isReadable = TRUE;
descP->isWritable = TRUE;
@@ -5000,7 +5372,7 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
break;
default:
- SSDBG( descP, ("SOCKET", "nconnect -> other error(1): %d\r\n",
+ SSDBG( descP, ("SOCKET", "esock_connect -> other error(1): %d\r\n",
save_errno) );
res = esock_make_error_errno(env, save_errno);
break;
@@ -5008,11 +5380,11 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
} else if (code == 0) { /* ok we are connected */
- SSDBG( descP, ("SOCKET", "nconnect -> connected\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_connect -> connected\r\n") );
- descP->state = SOCKET_STATE_CONNECTED;
+ descP->state = ESOCK_STATE_CONNECTED;
enif_set_pid_undefined(&descP->connPid);
- DEMONP("nconnect -> connected", env, descP, &descP->connMon);
+ DEMONP("esock_connect -> connected", env, descP, &descP->connMon);
descP->isReadable = TRUE;
descP->isWritable = TRUE;
@@ -5021,7 +5393,7 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env,
} else {
/* Do we really need this case? */
- SSDBG( descP, ("SOCKET", "nconnect -> other error(2): %d\r\n",
+ SSDBG( descP, ("SOCKET", "esock_connect -> other error(2): %d\r\n",
save_errno) );
res = esock_make_error_errno(env, save_errno);
@@ -5058,23 +5430,23 @@ ERL_NIF_TERM nif_finalize_connection(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 1) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
return enif_make_badarg(env);
}
- return nfinalize_connection(env, descP);
+ return esock_finalize_connection(env, descP);
#endif
}
-/* *** nfinalize_connection ***
+/* *** esock_finalize_connection ***
* Perform the final check to verify a connection.
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_finalize_connection(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
int error;
@@ -5082,13 +5454,14 @@ ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env,
return esock_make_error(env, atom_enotconn);
if (!verify_is_connected(descP, &error)) {
- descP->state = SOCKET_STATE_OPEN; /* restore state */
+ descP->state = ESOCK_STATE_OPEN; /* restore state */
return esock_make_error_errno(env, error);
}
- descP->state = SOCKET_STATE_CONNECTED;
+ descP->state = ESOCK_STATE_CONNECTED;
enif_set_pid_undefined(&descP->connPid);
- DEMONP("nfinalize_connection -> connected", env, descP, &descP->connMon);
+ DEMONP("esock_finalize_connection -> connected",
+ env, descP, &descP->connMon);
descP->isReadable = TRUE;
descP->isWritable = TRUE;
@@ -5201,7 +5574,7 @@ ERL_NIF_TERM nif_listen(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 2) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP) ||
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) ||
!GET_INT(env, argv[1], &backlog)) {
return enif_make_badarg(env);
}
@@ -5212,7 +5585,7 @@ ERL_NIF_TERM nif_listen(ErlNifEnv* env,
"\r\n backlog: %d"
"\r\n", descP->sock, argv[0], backlog) );
- return nlisten(env, descP, backlog);
+ return esock_listen(env, descP, backlog);
#endif // if defined(__WIN32__)
}
@@ -5221,9 +5594,9 @@ ERL_NIF_TERM nif_listen(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nlisten(ErlNifEnv* env,
- ESockDescriptor* descP,
- int backlog)
+ERL_NIF_TERM esock_listen(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int backlog)
{
/*
@@ -5233,7 +5606,7 @@ ERL_NIF_TERM nlisten(ErlNifEnv* env,
if (IS_CLOSED(descP) || IS_CLOSING(descP))
return esock_make_error(env, atom_closed);
- if (descP->state == SOCKET_STATE_CLOSED)
+ if (descP->state == ESOCK_STATE_CLOSED)
return esock_make_error(env, atom_exbadstate);
if (!IS_OPEN(descP))
@@ -5247,7 +5620,7 @@ ERL_NIF_TERM nlisten(ErlNifEnv* env,
if (IS_SOCKET_ERROR(sock_listen(descP->sock, backlog)))
return esock_make_error_errno(env, sock_errno());
- descP->state = SOCKET_STATE_LISTENING;
+ descP->state = ESOCK_STATE_LISTENING;
return esock_atom_ok;
@@ -5284,7 +5657,7 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env,
sockRef = argv[0];
if ((argc != 2) ||
- !enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
ref = argv[1];
@@ -5305,15 +5678,15 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env,
"\r\n",
descP->sock,
sockRef, ref,
- ((descP->state == SOCKET_STATE_LISTENING) ? "listening" :
- ((descP->state == SOCKET_STATE_ACCEPTING) ? "accepting" : "other")),
+ ((descP->state == ESOCK_STATE_LISTENING) ? "listening" :
+ ((descP->state == ESOCK_STATE_ACCEPTING) ? "accepting" : "other")),
descP->currentAcceptorP,
descP->currentAcceptor.pid,
esock_make_monitor_term(env, &descP->currentAcceptor.mon),
descP->currentAcceptor.env,
descP->currentAcceptor.ref) );
- res = naccept(env, descP, sockRef, ref);
+ res = esock_accept(env, descP, sockRef, ref);
MUNLOCK(descP->accMtx);
@@ -5325,10 +5698,10 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM naccept(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM ref)
+ERL_NIF_TERM esock_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM ref)
{
ERL_NIF_TERM res;
@@ -5336,12 +5709,12 @@ ERL_NIF_TERM naccept(ErlNifEnv* env,
return esock_make_error(env, atom_closed);
switch (descP->state) {
- case SOCKET_STATE_LISTENING:
- res = naccept_listening(env, descP, sockRef, ref);
+ case ESOCK_STATE_LISTENING:
+ res = esock_accept_listening(env, descP, sockRef, ref);
break;
- case SOCKET_STATE_ACCEPTING:
- res = naccept_accepting(env, descP, sockRef, ref);
+ case ESOCK_STATE_ACCEPTING:
+ res = esock_accept_accepting(env, descP, sockRef, ref);
break;
default:
@@ -5354,16 +5727,16 @@ ERL_NIF_TERM naccept(ErlNifEnv* env,
#endif // if !defined(__WIN32__)
-/* *** naccept_listening ***
+/* *** esock_accept_listening ***
*
* We have no active acceptor (and therefor no acceptors in queue).
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM accRef)
+ERL_NIF_TERM esock_accept_listening(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM accRef)
{
ESockAddress remote;
unsigned int n;
@@ -5372,14 +5745,14 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
ErlNifPid caller;
ERL_NIF_TERM res;
- SSDBG( descP, ("SOCKET", "naccept_listening -> get caller\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_accept_listening -> get caller\r\n") );
if (enif_self(env, &caller) == NULL)
return esock_make_error(env, atom_exself);
n = sizeof(remote);
sys_memzero((char *) &remote, n);
- SSDBG( descP, ("SOCKET", "naccept_listening -> try accept\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_accept_listening -> try accept\r\n") );
accSock = sock_accept(descP->sock, (struct sockaddr*) &remote, &n);
if (accSock == INVALID_SOCKET) {
@@ -5387,10 +5760,11 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
SSDBG( descP,
("SOCKET",
- "naccept_listening -> accept failed (%d)\r\n", save_errno) );
+ "esock_accept_listening -> accept failed (%d)\r\n",
+ save_errno) );
- res = naccept_listening_error(env, descP, sockRef, accRef,
- caller, save_errno);
+ res = esock_accept_listening_error(env, descP, sockRef, accRef,
+ caller, save_errno);
} else {
@@ -5398,9 +5772,9 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
* We got one
*/
- SSDBG( descP, ("SOCKET", "naccept_listening -> success\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_accept_listening -> success\r\n") );
- res = naccept_listening_accept(env, descP, accSock, caller, &remote);
+ res = esock_accept_listening_accept(env, descP, accSock, caller, &remote);
}
@@ -5408,7 +5782,7 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
}
-/* *** naccept_listening_error ***
+/* *** esock_accept_listening_error ***
*
* The accept call resultet in an error - handle it.
* There are only two cases:
@@ -5416,12 +5790,12 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env,
* 2) Other => Return the value (converted to an atom)
*/
static
-ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM accRef,
- ErlNifPid caller,
- int save_errno)
+ERL_NIF_TERM esock_accept_listening_error(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM accRef,
+ ErlNifPid caller,
+ int save_errno)
{
ERL_NIF_TERM res;
@@ -5430,10 +5804,10 @@ ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env,
/* *** Try again later *** */
SSDBG( descP,
- ("SOCKET", "naccept_listening_error -> would block\r\n") );
+ ("SOCKET", "esock_accept_listening_error -> would block\r\n") );
descP->currentAcceptor.pid = caller;
- if (MONP("naccept_listening -> current acceptor",
+ if (MONP("esock_accept_listening -> current acceptor",
env, descP,
&descP->currentAcceptor.pid,
&descP->currentAcceptor.mon) != 0) {
@@ -5445,14 +5819,14 @@ ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env,
descP->currentAcceptor.ref = CP_TERM(descP->currentAcceptor.env,
accRef);
descP->currentAcceptorP = &descP->currentAcceptor;
- res = naccept_busy_retry(env, descP,
- sockRef, accRef,
- NULL, SOCKET_STATE_ACCEPTING);
+ res = esock_accept_busy_retry(env, descP,
+ sockRef, accRef,
+ NULL, ESOCK_STATE_ACCEPTING);
}
} else {
SSDBG( descP,
("SOCKET",
- "naccept_listening -> errno: %d\r\n", save_errno) );
+ "esock_accept_listening -> errno: %d\r\n", save_errno) );
res = esock_make_error_errno(env, save_errno);
}
@@ -5460,20 +5834,20 @@ ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env,
}
-/* *** naccept_listening_accept ***
+/* *** esock_accept_listening_accept ***
*
* The accept call was successful (accepted) - handle the new connection.
*/
static
-ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env,
- ESockDescriptor* descP,
- SOCKET accSock,
- ErlNifPid caller,
- ESockAddress* remote)
+ERL_NIF_TERM esock_accept_listening_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ SOCKET accSock,
+ ErlNifPid caller,
+ ESockAddress* remote)
{
ERL_NIF_TERM res;
- naccept_accepted(env, descP, accSock, caller, remote, &res);
+ esock_accept_accepted(env, descP, accSock, caller, remote, &res);
return res;
}
@@ -5481,7 +5855,7 @@ ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env,
-/* *** naccept_accepting ***
+/* *** esock_accept_accepting ***
*
* We have an active acceptor and possibly acceptors waiting in queue.
* If the pid of the calling process is not the pid of the "current process",
@@ -5489,20 +5863,20 @@ ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env,
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM naccept_accepting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM ref)
+ERL_NIF_TERM esock_accept_accepting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM ref)
{
ErlNifPid caller;
ERL_NIF_TERM res;
- SSDBG( descP, ("SOCKET", "naccept_accepting -> get caller\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_accept_accepting -> get caller\r\n") );
if (enif_self(env, &caller) == NULL)
return esock_make_error(env, atom_exself);
- SSDBG( descP, ("SOCKET", "naccept_accepting -> check: "
+ SSDBG( descP, ("SOCKET", "esock_accept_accepting -> check: "
"are caller current acceptor:"
"\r\n Caller: %T"
"\r\n Current: %T"
@@ -5511,18 +5885,19 @@ ERL_NIF_TERM naccept_accepting(ErlNifEnv* env,
if (COMPARE_PIDS(&descP->currentAcceptor.pid, &caller) == 0) {
SSDBG( descP,
- ("SOCKET", "naccept_accepting -> current acceptor\r\n") );
+ ("SOCKET", "esock_accept_accepting -> current acceptor\r\n") );
- res = naccept_accepting_current(env, descP, sockRef, ref);
+ res = esock_accept_accepting_current(env, descP, sockRef, ref);
} else {
/* Not the "current acceptor", so (maybe) push onto queue */
SSDBG( descP,
- ("SOCKET", "naccept_accepting -> *not* current acceptor\r\n") );
+ ("SOCKET",
+ "esock_accept_accepting -> *not* current acceptor\r\n") );
- res = naccept_accepting_other(env, descP, ref, caller);
+ res = esock_accept_accepting_other(env, descP, ref, caller);
}
@@ -5532,14 +5907,14 @@ ERL_NIF_TERM naccept_accepting(ErlNifEnv* env,
-/* *** naccept_accepting_current ***
+/* *** esock_accept_accepting_current ***
* Handles when the current acceptor makes another attempt.
*/
static
-ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM accRef)
+ERL_NIF_TERM esock_accept_accepting_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM accRef)
{
ESockAddress remote;
unsigned int n;
@@ -5547,7 +5922,8 @@ ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env,
int save_errno;
ERL_NIF_TERM res;
- SSDBG( descP, ("SOCKET", "naccept_accepting_current -> try accept\r\n") );
+ SSDBG( descP, ("SOCKET",
+ "esock_accept_accepting_current -> try accept\r\n") );
n = sizeof(descP->remote);
sys_memzero((char *) &remote, n);
accSock = sock_accept(descP->sock, (struct sockaddr*) &remote, &n);
@@ -5557,18 +5933,19 @@ ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env,
SSDBG( descP,
("SOCKET",
- "naccept_accepting_current -> accept failed: %d\r\n",
+ "esock_accept_accepting_current -> accept failed: %d\r\n",
save_errno) );
- res = naccept_accepting_current_error(env, descP, sockRef,
- accRef, save_errno);
+ res = esock_accept_accepting_current_error(env, descP, sockRef,
+ accRef, save_errno);
} else {
- SSDBG( descP, ("SOCKET", "naccept_accepting_current -> accepted\r\n") );
+ SSDBG( descP, ("SOCKET",
+ "esock_accept_accepting_current -> accepted\r\n") );
- res = naccept_accepting_current_accept(env, descP, sockRef,
- accSock, &remote);
+ res = esock_accept_accepting_current_accept(env, descP, sockRef,
+ accSock, &remote);
}
@@ -5576,27 +5953,27 @@ ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env,
}
-/* *** naccept_accepting_current_accept ***
+/* *** esock_accept_accepting_current_accept ***
* Handles when the current acceptor succeeded in its accept call -
* handle the new connection.
*/
static
-ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- SOCKET accSock,
- ESockAddress* remote)
+ERL_NIF_TERM esock_accept_accepting_current_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ SOCKET accSock,
+ ESockAddress* remote)
{
ERL_NIF_TERM res;
- if (naccept_accepted(env, descP, accSock,
- descP->currentAcceptor.pid, remote, &res)) {
+ if (esock_accept_accepted(env, descP, accSock,
+ descP->currentAcceptor.pid, remote, &res)) {
/* Clean out the old cobweb's before trying to invite a new spider */
descP->currentAcceptor.ref = esock_atom_undefined;
enif_set_pid_undefined(&descP->currentAcceptor.pid);
- esock_free_env("naccept_accepting_current_accept - "
+ esock_free_env("esock_accept_accepting_current_accept - "
"current-accept-env",
descP->currentAcceptor.env);
descP->currentAcceptor.env = NULL;
@@ -5605,10 +5982,10 @@ ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env,
SSDBG( descP,
("SOCKET",
- "naccept_accepting_current_accept -> "
+ "esock_accept_accepting_current_accept -> "
"no more writers\r\n") );
- descP->state = SOCKET_STATE_LISTENING;
+ descP->state = ESOCK_STATE_LISTENING;
descP->currentAcceptorP = NULL;
ESOCK_ASSERT(!descP->currentAcceptor.env);
@@ -5622,18 +5999,18 @@ ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env,
}
-/* *** naccept_accepting_current_error ***
+/* *** esock_accept_accepting_current_error ***
* The accept call of current acceptor resultet in an error - handle it.
* There are only two cases:
* 1) BLOCK => Attempt a "retry"
* 2) Other => Return the value (converted to an atom)
*/
static
-ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef,
- int save_errno)
+ERL_NIF_TERM esock_accept_accepting_current_error(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef,
+ int save_errno)
{
ESockRequestor req;
ERL_NIF_TERM res, reason;
@@ -5647,13 +6024,13 @@ ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env,
SSDBG( descP,
("SOCKET",
- "naccept_accepting_current_error -> "
+ "esock_accept_accepting_current_error -> "
"would block: try again\r\n") );
- res = naccept_busy_retry(env, descP, sockRef, opRef,
- &descP->currentAcceptor.pid,
- /* No state change */
- descP->state);
+ res = esock_accept_busy_retry(env, descP, sockRef, opRef,
+ &descP->currentAcceptor.pid,
+ /* No state change */
+ descP->state);
} else {
@@ -5662,12 +6039,13 @@ ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env,
while (acceptor_pop(env, descP, &req)) {
SSDBG( descP,
- ("SOCKET", "naccept_accepting_current_error -> abort %T\r\n",
+ ("SOCKET",
+ "esock_accept_accepting_current_error -> abort %T\r\n",
req.pid) );
esock_send_abort_msg(env, sockRef, req.ref, req.env,
reason, &req.pid);
req.env = NULL;
- DEMONP("naccept_accepting_current_error -> pop'ed writer",
+ DEMONP("esock_accept_accepting_current_error -> pop'ed writer",
env, descP, &req.mon);
}
@@ -5677,16 +6055,16 @@ ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env,
}
-/* *** naccept_accepting_other ***
+/* *** esock_accept_accepting_other ***
* Handles when the another acceptor makes an attempt, which
* results (maybe) in the request beeing pushed onto the
* acceptor queue.
*/
static
-ERL_NIF_TERM naccept_accepting_other(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM ref,
- ErlNifPid caller)
+ERL_NIF_TERM esock_accept_accepting_other(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM ref,
+ ErlNifPid caller)
{
ERL_NIF_TERM result;
@@ -5701,18 +6079,18 @@ ERL_NIF_TERM naccept_accepting_other(ErlNifEnv* env,
-/* *** naccept_busy_retry ***
+/* *** esock_accept_busy_retry ***
*
* Perform a retry select. If successful, set nextState.
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM naccept_busy_retry(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM accRef,
- ErlNifPid* pid,
- unsigned int nextState)
+ERL_NIF_TERM esock_accept_busy_retry(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM accRef,
+ ErlNifPid* pid,
+ unsigned int nextState)
{
int sres;
ERL_NIF_TERM res, reason;
@@ -5731,17 +6109,17 @@ ERL_NIF_TERM naccept_busy_retry(ErlNifEnv* env,
-/* *** naccept_accepted ***
+/* *** esock_accept_accepted ***
*
* Generic function handling a successful accept.
*/
static
-BOOLEAN_T naccept_accepted(ErlNifEnv* env,
- ESockDescriptor* descP,
- SOCKET accSock,
- ErlNifPid pid,
- ESockAddress* remote,
- ERL_NIF_TERM* result)
+BOOLEAN_T esock_accept_accepted(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ SOCKET accSock,
+ ErlNifPid pid,
+ ESockAddress* remote,
+ ERL_NIF_TERM* result)
{
ESockDescriptor* accDescP;
HANDLE accEvent;
@@ -5779,7 +6157,7 @@ BOOLEAN_T naccept_accepted(ErlNifEnv* env,
enif_release_resource(accDescP);
accDescP->ctrlPid = pid;
- if (MONP("naccept_accepted -> ctrl",
+ if (MONP("esock_accept_accepted -> ctrl",
env, accDescP,
&accDescP->ctrlPid,
&accDescP->ctrlMon) != 0) {
@@ -5792,7 +6170,7 @@ BOOLEAN_T naccept_accepted(ErlNifEnv* env,
accDescP->remote = *remote;
SET_NONBLOCKING(accDescP->sock);
- accDescP->state = SOCKET_STATE_CONNECTED;
+ accDescP->state = ESOCK_STATE_CONNECTED;
accDescP->isReadable = TRUE;
accDescP->isWritable = TRUE;
@@ -5845,7 +6223,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env,
sockRef = argv[0]; // We need this in case we send in case we send abort
sendRef = argv[1];
- if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -5870,7 +6248,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env,
* is done!
*/
- res = nsend(env, descP, sockRef, sendRef, &sndData, flags);
+ res = esock_send(env, descP, sockRef, sendRef, &sndData, flags);
MUNLOCK(descP->writeMtx);
@@ -5881,7 +6259,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env,
-/* *** nsend ***
+/* *** esock_send ***
*
* Do the actual send.
* Do some initial writer checks, do the actual send and then
@@ -5890,12 +6268,12 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env,
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsend(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM sendRef,
- ErlNifBinary* sndDataP,
- int flags)
+ERL_NIF_TERM esock_send(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM sendRef,
+ ErlNifBinary* sndDataP,
+ int flags)
{
int save_errno;
ssize_t written;
@@ -5911,7 +6289,8 @@ ERL_NIF_TERM nsend(ErlNifEnv* env,
/* We ignore the wrap for the moment.
* Maybe we should issue a wrap-message to controlling process...
*/
- cnt_inc(&descP->writeTries, 1);
+ // cnt_inc(&descP->writeTries, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_write_tries, &descP->writeTries, 1);
written = sock_send(descP->sock, sndDataP->data, sndDataP->size, flags);
if (IS_SOCKET_ERROR(written))
@@ -5966,16 +6345,15 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 5) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP) ||
!GET_BIN(env, argv[2], &sndData) ||
!GET_UINT(env, argv[4], &eflags)) {
return enif_make_badarg(env);
}
- sockRef = argv[0]; // We need this in case we send in case we send abort
+ sockRef = argv[0]; // We need this in case we send abort (to the caller)
sendRef = argv[1];
eSockAddr = argv[3];
- if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -6004,8 +6382,8 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env,
MLOCK(descP->writeMtx);
- res = nsendto(env, descP, sockRef, sendRef, &sndData, flags,
- &remoteAddr, remoteAddrLen);
+ res = esock_sendto(env, descP, sockRef, sendRef, &sndData, flags,
+ &remoteAddr, remoteAddrLen);
MUNLOCK(descP->writeMtx);
@@ -6021,14 +6399,14 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsendto(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM sendRef,
- ErlNifBinary* dataP,
- int flags,
- ESockAddress* toAddrP,
- unsigned int toAddrLen)
+ERL_NIF_TERM esock_sendto(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM sendRef,
+ ErlNifBinary* dataP,
+ int flags,
+ ESockAddress* toAddrP,
+ unsigned int toAddrLen)
{
int save_errno;
ssize_t written;
@@ -6044,7 +6422,8 @@ ERL_NIF_TERM nsendto(ErlNifEnv* env,
/* We ignore the wrap for the moment.
* Maybe we should issue a wrap-message to controlling process...
*/
- cnt_inc(&descP->writeTries, 1);
+ // cnt_inc(&descP->writeTries, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_write_tries, &descP->writeTries, 1);
if (toAddrP != NULL) {
written = sock_sendto(descP->sock,
@@ -6102,11 +6481,11 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env,
!GET_UINT(env, argv[3], &eflags)) {
return enif_make_badarg(env);
}
- sockRef = argv[0]; // We need this in case we send in case we send abort
+ sockRef = argv[0]; // We need this in case we send abort (to the caller)
sendRef = argv[1];
eMsgHdr = argv[2];
- if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -6123,7 +6502,7 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env,
MLOCK(descP->writeMtx);
- res = nsendmsg(env, descP, sockRef, sendRef, eMsgHdr, flags);
+ res = esock_sendmsg(env, descP, sockRef, sendRef, eMsgHdr, flags);
MUNLOCK(descP->writeMtx);
@@ -6140,12 +6519,12 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM sendRef,
- ERL_NIF_TERM eMsgHdr,
- int flags)
+ERL_NIF_TERM esock_sendmsg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM sendRef,
+ ERL_NIF_TERM eMsgHdr,
+ int flags)
{
ERL_NIF_TERM res, eAddr, eIOV, eCtrl;
ESockAddress addr;
@@ -6174,7 +6553,8 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
/* We don't need the address */
- SSDBG( descP, ("SOCKET", "nsendmsg -> connected: no address\r\n") );
+ SSDBG( descP, ("SOCKET",
+ "esock_sendmsg -> connected: no address\r\n") );
msgHdr.msg_name = NULL;
msgHdr.msg_namelen = 0;
@@ -6189,7 +6569,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
if (!GET_MAP_VAL(env, eMsgHdr, esock_atom_addr, &eAddr))
return esock_make_error(env, esock_atom_einval);
- SSDBG( descP, ("SOCKET", "nsendmsg -> not connected: "
+ SSDBG( descP, ("SOCKET", "esock_sendmsg -> not connected: "
"\r\n address: %T"
"\r\n", eAddr) );
@@ -6209,7 +6589,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
if (!GET_LIST_LEN(env, eIOV, &iovLen) && (iovLen > 0))
return esock_make_error(env, esock_atom_einval);
- SSDBG( descP, ("SOCKET", "nsendmsg -> iov length: %d\r\n", iovLen) );
+ SSDBG( descP, ("SOCKET", "esock_sendmsg -> iov length: %d\r\n", iovLen) );
iovBins = MALLOC(iovLen * sizeof(ErlNifBinary));
ESOCK_ASSERT( (iovBins != NULL) );
@@ -6227,7 +6607,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
ctrlBufLen = 0;
ctrlBuf = NULL;
}
- SSDBG( descP, ("SOCKET", "nsendmsg -> optional ctrl: "
+ SSDBG( descP, ("SOCKET", "esock_sendmsg -> optional ctrl: "
"\r\n ctrlBuf: 0x%lX"
"\r\n ctrlBufLen: %d"
"\r\n eCtrl: %T\r\n", ctrlBuf, ctrlBufLen, eCtrl) );
@@ -6245,7 +6625,8 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
SSDBG( descP, ("SOCKET",
- "nsendmsg -> total (iov) data size: %d\r\n", dataSize) );
+ "esock_sendmsg -> "
+ "total (iov) data size: %d\r\n", dataSize) );
/* Decode the ctrl and initiate that part of the msghdr.
@@ -6273,7 +6654,8 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env,
/* We ignore the wrap for the moment.
* Maybe we should issue a wrap-message to controlling process...
*/
- cnt_inc(&descP->writeTries, 1);
+ // cnt_inc(&descP->writeTries, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_write_tries, &descP->writeTries, 1);
/* And now, finally, try to send the message */
written = sock_sendmsg(descP->sock, &msgHdr, flags);
@@ -6402,10 +6784,10 @@ ERL_NIF_TERM nif_recv(ErlNifEnv* env,
!GET_UINT(env, argv[3], &eflags)) {
return enif_make_badarg(env);
}
- sockRef = argv[0]; // We need this in case we case we send abort
+ sockRef = argv[0]; // We need this in case we send abort (to the caller)
recvRef = argv[1];
- if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -6422,7 +6804,7 @@ ERL_NIF_TERM nif_recv(ErlNifEnv* env,
* is done!
*/
- res = nrecv(env, descP, sockRef, recvRef, len, flags);
+ res = esock_recv(env, descP, sockRef, recvRef, len, flags);
MUNLOCK(descP->readMtx);
@@ -6439,12 +6821,12 @@ ERL_NIF_TERM nif_recv(ErlNifEnv* env,
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nrecv(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM recvRef,
- int len,
- int flags)
+ERL_NIF_TERM esock_recv(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM recvRef,
+ int len,
+ int flags)
{
ssize_t read;
ErlNifBinary buf;
@@ -6452,7 +6834,7 @@ ERL_NIF_TERM nrecv(ErlNifEnv* env,
int save_errno;
int bufSz = (len ? len : descP->rBufSz);
- SSDBG( descP, ("SOCKET", "nrecv -> entry with"
+ SSDBG( descP, ("SOCKET", "esock_recv -> entry with"
"\r\n len: %d (%d:%d)"
"\r\n flags: %d"
"\r\n", len, descP->rNumCnt, bufSz, flags) );
@@ -6471,13 +6853,11 @@ ERL_NIF_TERM nrecv(ErlNifEnv* env,
if (!ALLOC_BIN(bufSz, &buf))
return esock_make_error(env, atom_exalloc);
- /* We ignore the wrap for the moment.
- * Maybe we should issue a wrap-message to controlling process...
- */
- cnt_inc(&descP->readTries, 1);
+ // cnt_inc(&descP->readTries, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_tries, &descP->readTries, 1);
// If it fails (read = -1), we need errno...
- SSDBG( descP, ("SOCKET", "nrecv -> try read (%d)\r\n", buf.size) );
+ SSDBG( descP, ("SOCKET", "esock_recv -> try read (%d)\r\n", buf.size) );
read = sock_recv(descP->sock, buf.data, buf.size, flags);
if (IS_SOCKET_ERROR(read)) {
save_errno = sock_errno();
@@ -6485,7 +6865,8 @@ ERL_NIF_TERM nrecv(ErlNifEnv* env,
save_errno = -1; // The value does not actually matter in this case
}
- SSDBG( descP, ("SOCKET", "nrecv -> read: %d (%d)\r\n", read, save_errno) );
+ SSDBG( descP, ("SOCKET",
+ "esock_recv -> read: %d (%d)\r\n", read, save_errno) );
return recv_check_result(env, descP,
read, len,
@@ -6546,10 +6927,10 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env,
!GET_UINT(env, argv[3], &eflags)) {
return enif_make_badarg(env);
}
- sockRef = argv[0]; // We need this in case we send in case we send abort
+ sockRef = argv[0]; // We need this in case we send abort (to the caller)
recvRef = argv[1];
- if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -6586,7 +6967,7 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env,
* </KOLLA>
*/
- res = nrecvfrom(env, descP, sockRef, recvRef, bufSz, flags);
+ res = esock_recvfrom(env, descP, sockRef, recvRef, bufSz, flags);
MUNLOCK(descP->readMtx);
@@ -6602,12 +6983,12 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env,
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nrecvfrom(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM recvRef,
- Uint16 len,
- int flags)
+ERL_NIF_TERM esock_recvfrom(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM recvRef,
+ Uint16 len,
+ int flags)
{
ESockAddress fromAddr;
unsigned int addrLen;
@@ -6617,7 +6998,7 @@ ERL_NIF_TERM nrecvfrom(ErlNifEnv* env,
ERL_NIF_TERM readerCheck;
int bufSz = (len ? len : descP->rBufSz);
- SSDBG( descP, ("SOCKET", "nrecvfrom -> entry with"
+ SSDBG( descP, ("SOCKET", "esock_recvfrom -> entry with"
"\r\n len: %d (%d)"
"\r\n flags: %d"
"\r\n", len, bufSz, flags) );
@@ -6636,10 +7017,8 @@ ERL_NIF_TERM nrecvfrom(ErlNifEnv* env,
if (!ALLOC_BIN(bufSz, &buf))
return esock_make_error(env, atom_exalloc);
- /* We ignore the wrap for the moment.
- * Maybe we should issue a wrap-message to controlling process...
- */
- cnt_inc(&descP->readTries, 1);
+ // cnt_inc(&descP->readTries, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_tries, &descP->readTries, 1);
addrLen = sizeof(fromAddr);
sys_memzero((char*) &fromAddr, addrLen);
@@ -6717,10 +7096,10 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env,
!GET_UINT(env, argv[4], &eflags)) {
return enif_make_badarg(env);
}
- sockRef = argv[0]; // We need this in case we send in case we send abort
+ sockRef = argv[0]; // We need this in case we send abort (to the caller)
recvRef = argv[1];
- if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -6758,7 +7137,7 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env,
* </KOLLA>
*/
- res = nrecvmsg(env, descP, sockRef, recvRef, bufSz, ctrlSz, flags);
+ res = esock_recvmsg(env, descP, sockRef, recvRef, bufSz, ctrlSz, flags);
MUNLOCK(descP->readMtx);
@@ -6774,13 +7153,13 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env,
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nrecvmsg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM recvRef,
- Uint16 bufLen,
- Uint16 ctrlLen,
- int flags)
+ERL_NIF_TERM esock_recvmsg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM recvRef,
+ Uint16 bufLen,
+ Uint16 ctrlLen,
+ int flags)
{
unsigned int addrLen;
ssize_t read;
@@ -6794,7 +7173,7 @@ ERL_NIF_TERM nrecvmsg(ErlNifEnv* env,
ERL_NIF_TERM readerCheck;
ESockAddress addr;
- SSDBG( descP, ("SOCKET", "nrecvmsg -> entry with"
+ SSDBG( descP, ("SOCKET", "esock_recvmsg -> entry with"
"\r\n bufSz: %d (%d)"
"\r\n ctrlSz: %d (%d)"
"\r\n flags: %d"
@@ -6826,10 +7205,8 @@ ERL_NIF_TERM nrecvmsg(ErlNifEnv* env,
if (!ALLOC_BIN(ctrlSz, &ctrl))
return esock_make_error(env, atom_exalloc);
- /* We ignore the wrap for the moment.
- * Maybe we should issue a wrap-message to controlling process...
- */
- cnt_inc(&descP->readTries, 1);
+ // cnt_inc(&descP->readTries, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_tries, &descP->readTries, 1);
addrLen = sizeof(addr);
sys_memzero((char*) &addr, addrLen);
@@ -6885,28 +7262,28 @@ ERL_NIF_TERM nif_close(ErlNifEnv* env,
ESockDescriptor* descP;
if ((argc != 1) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
return enif_make_badarg(env);
}
if (IS_CLOSED(descP) || IS_CLOSING(descP))
return esock_make_error(env, atom_closed);
- return nclose(env, descP);
+ return esock_close(env, descP);
#endif // if defined(__WIN32__)
}
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nclose(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_close(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM reply, reason;
BOOLEAN_T doClose;
SSDBG( descP, ("SOCKET",
- "nclose -> [%d] entry (0x%lX, 0x%lX, 0x%lX, 0x%lX)\r\n",
+ "esock_close -> [%d] entry (0x%lX, 0x%lX, 0x%lX, 0x%lX)\r\n",
descP->sock,
descP->state,
descP->currentWriterP,
@@ -6915,10 +7292,10 @@ ERL_NIF_TERM nclose(ErlNifEnv* env,
MLOCK(descP->closeMtx);
- doClose = nclose_check(env, descP, &reason);
+ doClose = esock_close_check(env, descP, &reason);
if (doClose) {
- reply = nclose_do(env, descP);
+ reply = esock_close_do(env, descP);
} else {
reply = esock_make_error(env, reason);
}
@@ -6926,7 +7303,7 @@ ERL_NIF_TERM nclose(ErlNifEnv* env,
MUNLOCK(descP->closeMtx);
SSDBG( descP,
- ("SOCKET", "nclose -> [%d] done when: "
+ ("SOCKET", "esock_close -> [%d] done when: "
"\r\n state: 0x%lX"
"\r\n reply: %T"
"\r\n", descP->sock, descP->state, reply) );
@@ -6936,23 +7313,23 @@ ERL_NIF_TERM nclose(ErlNifEnv* env,
-/* *** nclose_check ***
+/* *** esock_close_check ***
*
* Check if we should try to perform the first stage close.
*/
static
-BOOLEAN_T nclose_check(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM* reason)
+BOOLEAN_T esock_close_check(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM* reason)
{
BOOLEAN_T doClose;
- if (descP->state == SOCKET_STATE_CLOSED) {
+ if (descP->state == ESOCK_STATE_CLOSED) {
doClose = FALSE;
*reason = atom_closed;
- } else if (descP->state == SOCKET_STATE_CLOSING) {
+ } else if (descP->state == ESOCK_STATE_CLOSING) {
doClose = FALSE;
*reason = atom_closing;
@@ -6982,7 +7359,7 @@ BOOLEAN_T nclose_check(ErlNifEnv* env,
* </KOLLA>
*/
- if (MONP("nclose_check -> closer",
+ if (MONP("esock_close_check -> closer",
env, descP,
&descP->closerPid,
&descP->closerMon) != 0) {
@@ -6993,7 +7370,7 @@ BOOLEAN_T nclose_check(ErlNifEnv* env,
} else {
descP->closeLocal = TRUE;
- descP->state = SOCKET_STATE_CLOSING;
+ descP->state = ESOCK_STATE_CLOSING;
descP->isReadable = FALSE;
descP->isWritable = FALSE;
doClose = TRUE;
@@ -7009,13 +7386,13 @@ BOOLEAN_T nclose_check(ErlNifEnv* env,
-/* *** nclose_do ***
+/* *** esock_close_do ***
*
* Perform (do) the first stage close.
*/
static
-ERL_NIF_TERM nclose_do(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_close_do(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
int domain = descP->domain;
int type = descP->type;
@@ -7023,7 +7400,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env,
int sres;
ERL_NIF_TERM reply, reason;
- descP->closeEnv = esock_alloc_env("nclose-do - close-env");
+ descP->closeEnv = esock_alloc_env("esock_close_do - close-env");
descP->closeRef = MKREF(descP->closeEnv);
sres = esock_select_stop(env, descP->sock, descP);
@@ -7032,7 +7409,8 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env,
/* Prep done - inform the caller it can finalize (close) directly */
SSDBG( descP,
- ("SOCKET", "nclose -> [%d] stop was called\r\n", descP->sock) );
+ ("SOCKET",
+ "esock_close -> [%d] stop was called\r\n", descP->sock) );
dec_socket(domain, type, protocol);
reply = esock_atom_ok;
@@ -7042,7 +7420,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env,
/* The stop callback function has been *scheduled* which means that we
* have to wait for it to complete. */
SSDBG( descP,
- ("SOCKET", "nclose -> [%d] stop was scheduled\r\n",
+ ("SOCKET", "esock_close -> [%d] stop was scheduled\r\n",
descP->sock) );
dec_socket(domain, type, protocol); // SHALL WE DO THIS AT finalize?
@@ -7051,7 +7429,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env,
} else {
SSDBG( descP,
- ("SOCKET", "nclose -> [%d] stop failed: %d\r\n",
+ ("SOCKET", "esock_close -> [%d] stop failed: %d\r\n",
descP->sock, sres) );
/* <KOLLA>
@@ -7065,7 +7443,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env,
*/
// Do we need this?
- DEMONP("nclose_do -> closer", env, descP, &descP->closerMon);
+ DEMONP("esock_close_do -> closer", env, descP, &descP->closerMon);
reason = MKT2(env, esock_atom_select_failed, MKI(env, sres));
reply = esock_make_error(env, reason);
@@ -7103,22 +7481,22 @@ ERL_NIF_TERM nif_finalize_close(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 1) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
return enif_make_badarg(env);
}
- return nfinalize_close(env, descP);
+ return esock_finalize_close(env, descP);
#endif // if defined(__WIN32__)
}
-/* *** nfinalize_close ***
+/* *** esock_finalize_close ***
* Perform the final step in the socket close.
*/
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nfinalize_close(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_finalize_close(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM reply;
@@ -7155,7 +7533,7 @@ ERL_NIF_TERM nfinalize_close(ErlNifEnv* env,
descP->sock = INVALID_SOCKET;
descP->event = INVALID_EVENT;
- descP->state = SOCKET_STATE_CLOSED;
+ descP->state = ESOCK_STATE_CLOSED;
return reply;
}
@@ -7187,7 +7565,7 @@ ERL_NIF_TERM nif_shutdown(ErlNifEnv* env,
int how;
if ((argc != 2) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP) ||
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) ||
!GET_UINT(env, argv[1], &ehow)) {
return enif_make_badarg(env);
}
@@ -7198,7 +7576,7 @@ ERL_NIF_TERM nif_shutdown(ErlNifEnv* env,
if (!ehow2how(ehow, &how))
return enif_make_badarg(env);
- return nshutdown(env, descP, how);
+ return esock_shutdown(env, descP, how);
#endif // if defined(__WIN32__)
}
@@ -7206,9 +7584,9 @@ ERL_NIF_TERM nif_shutdown(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nshutdown(ErlNifEnv* env,
- ESockDescriptor* descP,
- int how)
+ERL_NIF_TERM esock_shutdown(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int how)
{
ERL_NIF_TERM reply;
@@ -7276,7 +7654,7 @@ ERL_NIF_TERM nif_setopt(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 5) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP) ||
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) ||
!GET_INT(env, argv[2], &eLevel) ||
!GET_INT(env, argv[3], &eOpt)) {
SGDBG( ("SOCKET", "nif_setopt -> failed initial arg check\r\n") );
@@ -7313,7 +7691,7 @@ ERL_NIF_TERM nif_setopt(ErlNifEnv* env,
MLOCK(descP->cfgMtx);
- result = nsetopt(env, descP, isEncoded, isOTP, level, eOpt, eVal);
+ result = esock_setopt(env, descP, isEncoded, isOTP, level, eOpt, eVal);
MUNLOCK(descP->cfgMtx);
@@ -7330,13 +7708,13 @@ ERL_NIF_TERM nif_setopt(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsetopt(ErlNifEnv* env,
- ESockDescriptor* descP,
- BOOLEAN_T isEncoded,
- BOOLEAN_T isOTP,
- int level,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ BOOLEAN_T isEncoded,
+ BOOLEAN_T isOTP,
+ int level,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
@@ -7344,11 +7722,11 @@ ERL_NIF_TERM nsetopt(ErlNifEnv* env,
/* These are not actual socket options,
* but options for our implementation.
*/
- result = nsetopt_otp(env, descP, eOpt, eVal);
+ result = esock_setopt_otp(env, descP, eOpt, eVal);
} else if (!isEncoded) {
- result = nsetopt_native(env, descP, level, eOpt, eVal);
+ result = esock_setopt_native(env, descP, level, eOpt, eVal);
} else {
- result = nsetopt_level(env, descP, level, eOpt, eVal);
+ result = esock_setopt_level(env, descP, level, eOpt, eVal);
}
return result;
@@ -7356,45 +7734,45 @@ ERL_NIF_TERM nsetopt(ErlNifEnv* env,
-/* nsetopt_otp - Handle OTP (level) options
+/* esock_setopt_otp - Handle OTP (level) options
*/
static
-ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_otp -> entry with"
+ ("SOCKET", "esock_setopt_otp -> entry with"
"\r\n eOpt: %d"
"\r\n eVal: %T"
"\r\n", eOpt, eVal) );
switch (eOpt) {
- case SOCKET_OPT_OTP_DEBUG:
- result = nsetopt_otp_debug(env, descP, eVal);
+ case ESOCK_OPT_OTP_DEBUG:
+ result = esock_setopt_otp_debug(env, descP, eVal);
break;
- case SOCKET_OPT_OTP_IOW:
- result = nsetopt_otp_iow(env, descP, eVal);
+ case ESOCK_OPT_OTP_IOW:
+ result = esock_setopt_otp_iow(env, descP, eVal);
break;
- case SOCKET_OPT_OTP_CTRL_PROC:
- result = nsetopt_otp_ctrl_proc(env, descP, eVal);
+ case ESOCK_OPT_OTP_CTRL_PROC:
+ result = esock_setopt_otp_ctrl_proc(env, descP, eVal);
break;
- case SOCKET_OPT_OTP_RCVBUF:
- result = nsetopt_otp_rcvbuf(env, descP, eVal);
+ case ESOCK_OPT_OTP_RCVBUF:
+ result = esock_setopt_otp_rcvbuf(env, descP, eVal);
break;
- case SOCKET_OPT_OTP_RCVCTRLBUF:
- result = nsetopt_otp_rcvctrlbuf(env, descP, eVal);
+ case ESOCK_OPT_OTP_RCVCTRLBUF:
+ result = esock_setopt_otp_rcvctrlbuf(env, descP, eVal);
break;
- case SOCKET_OPT_OTP_SNDCTRLBUF:
- result = nsetopt_otp_sndctrlbuf(env, descP, eVal);
+ case ESOCK_OPT_OTP_SNDCTRLBUF:
+ result = esock_setopt_otp_sndctrlbuf(env, descP, eVal);
break;
default:
@@ -7406,12 +7784,12 @@ ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env,
}
-/* nsetopt_otp_debug - Handle the OTP (level) debug options
+/* esock_setopt_otp_debug - Handle the OTP (level) debug options
*/
static
-ERL_NIF_TERM nsetopt_otp_debug(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp_debug(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
descP->dbg = esock_decode_bool(eVal);
@@ -7419,12 +7797,12 @@ ERL_NIF_TERM nsetopt_otp_debug(ErlNifEnv* env,
}
-/* nsetopt_otp_iow - Handle the OTP (level) iow options
+/* esock_setopt_otp_iow - Handle the OTP (level) iow options
*/
static
-ERL_NIF_TERM nsetopt_otp_iow(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp_iow(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
descP->iow = esock_decode_bool(eVal);
@@ -7433,19 +7811,20 @@ ERL_NIF_TERM nsetopt_otp_iow(ErlNifEnv* env,
-/* nsetopt_otp_ctrl_proc - Handle the OTP (level) controlling_process options
+/* esock_setopt_otp_ctrl_proc - Handle the OTP (level)
+ * controlling_process options
*/
static
-ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp_ctrl_proc(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ErlNifPid caller, newCtrlPid;
ESockMonitor newCtrlMon;
int xres;
SSDBG( descP,
- ("SOCKET", "nsetopt_otp_ctrl_proc -> entry with"
+ ("SOCKET", "esock_setopt_otp_ctrl_proc -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -7454,7 +7833,8 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
return esock_make_error(env, atom_exself);
if (COMPARE_PIDS(&descP->ctrlPid, &caller) != 0) {
- SSDBG( descP, ("SOCKET", "nsetopt_otp_ctrl_proc -> not owner (%T)\r\n",
+ SSDBG( descP, ("SOCKET",
+ "esock_setopt_otp_ctrl_proc -> not owner (%T)\r\n",
descP->ctrlPid) );
return esock_make_error(env, esock_atom_not_owner);
}
@@ -7464,13 +7844,14 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
}
- if ((xres = MONP("nsetopt_otp_ctrl_proc -> (new) ctrl",
+ if ((xres = MONP("esock_setopt_otp_ctrl_proc -> (new) ctrl",
env, descP, &newCtrlPid, &newCtrlMon)) != 0) {
- esock_warning_msg("Failed monitor %d) (new) controlling process\r\n", xres);
+ esock_warning_msg("Failed monitor (%d) (new) controlling process\r\n",
+ xres);
return esock_make_error(env, esock_atom_einval);
}
- if ((xres = DEMONP("nsetopt_otp_ctrl_proc -> (old) ctrl",
+ if ((xres = DEMONP("esock_setopt_otp_ctrl_proc -> (old) ctrl",
env, descP, &descP->ctrlMon)) != 0) {
esock_warning_msg("Failed demonitor (%d) "
"old controlling process %T (%T)\r\n",
@@ -7480,14 +7861,14 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
descP->ctrlPid = newCtrlPid;
descP->ctrlMon = newCtrlMon;
- SSDBG( descP, ("SOCKET", "nsetopt_otp_ctrl_proc -> done\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_setopt_otp_ctrl_proc -> done\r\n") );
return esock_atom_ok;
}
-/* nsetopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option
+/* esock_setopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option
* The (otp) rcvbuf option is provided as:
*
* BufSz :: integer() | {N :: pos_integer(), BufSz :: pod_integer()}
@@ -7495,9 +7876,9 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
* Where N is the max number of reads.
*/
static
-ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp_rcvbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
const ERL_NIF_TERM* t; // The array of the elements of the tuple
int tsz; // The size of the tuple - should be 2
@@ -7514,7 +7895,7 @@ ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env,
if ((xres = esock_decode_bufsz(env,
eVal,
- SOCKET_RECV_BUFFER_SIZE_DEFAULT,
+ ESOCK_RECV_BUFFER_SIZE_DEFAULT,
&bufSz)) != NULL)
return esock_make_error_str(env, xres);
@@ -7531,7 +7912,7 @@ ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env,
if ((xres = esock_decode_bufsz(env,
t[1],
- SOCKET_RECV_BUFFER_SIZE_DEFAULT,
+ ESOCK_RECV_BUFFER_SIZE_DEFAULT,
&bufSz)) != NULL)
return esock_make_error_str(env, xres);
@@ -7547,19 +7928,19 @@ ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env,
-/* nsetopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option
+/* esock_setopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option
*/
static
-ERL_NIF_TERM nsetopt_otp_rcvctrlbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp_rcvctrlbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
size_t val;
char* xres;
if ((xres = esock_decode_bufsz(env,
eVal,
- SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT,
+ ESOCK_RECV_CTRL_BUFFER_SIZE_DEFAULT,
&val)) != NULL)
return esock_make_error_str(env, xres);
@@ -7570,19 +7951,19 @@ ERL_NIF_TERM nsetopt_otp_rcvctrlbuf(ErlNifEnv* env,
-/* nsetopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option
+/* esock_setopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option
*/
static
-ERL_NIF_TERM nsetopt_otp_sndctrlbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_otp_sndctrlbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
size_t val;
char* xres;
if ((xres = esock_decode_bufsz(env,
eVal,
- SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT,
+ ESOCK_SEND_CTRL_BUFFER_SIZE_DEFAULT,
&val)) != NULL)
return esock_make_error_str(env, xres);
@@ -7597,17 +7978,17 @@ ERL_NIF_TERM nsetopt_otp_sndctrlbuf(ErlNifEnv* env,
* in "native mode" (option is provided as is and value as a binary).
*/
static
-ERL_NIF_TERM nsetopt_native(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_native(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal)
{
ErlNifBinary val;
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_native -> entry with"
+ ("SOCKET", "esock_setopt_native -> entry with"
"\r\n level: %d"
"\r\n opt: %d"
"\r\n eVal: %T"
@@ -7625,7 +8006,7 @@ ERL_NIF_TERM nsetopt_native(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "nsetopt_native -> done when"
+ ("SOCKET", "esock_setopt_native -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -7634,25 +8015,25 @@ ERL_NIF_TERM nsetopt_native(ErlNifEnv* env,
-/* nsetopt_level - A "proper" level (option) has been specified
+/* esock_setopt_level - A "proper" level (option) has been specified
*/
static
-ERL_NIF_TERM nsetopt_level(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_level(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_level -> entry with"
+ ("SOCKET", "esock_setopt_level -> entry with"
"\r\n level: %d"
"\r\n", level) );
switch (level) {
case SOL_SOCKET:
- result = nsetopt_lvl_socket(env, descP, eOpt, eVal);
+ result = esock_setopt_lvl_socket(env, descP, eOpt, eVal);
break;
#if defined(SOL_IP)
@@ -7660,7 +8041,7 @@ ERL_NIF_TERM nsetopt_level(ErlNifEnv* env,
#else
case IPPROTO_IP:
#endif
- result = nsetopt_lvl_ip(env, descP, eOpt, eVal);
+ result = esock_setopt_lvl_ip(env, descP, eOpt, eVal);
break;
#if defined(HAVE_IPV6)
@@ -7669,33 +8050,34 @@ ERL_NIF_TERM nsetopt_level(ErlNifEnv* env,
#else
case IPPROTO_IPV6:
#endif
- result = nsetopt_lvl_ipv6(env, descP, eOpt, eVal);
+ result = esock_setopt_lvl_ipv6(env, descP, eOpt, eVal);
break;
#endif
case IPPROTO_TCP:
- result = nsetopt_lvl_tcp(env, descP, eOpt, eVal);
+ result = esock_setopt_lvl_tcp(env, descP, eOpt, eVal);
break;
case IPPROTO_UDP:
- result = nsetopt_lvl_udp(env, descP, eOpt, eVal);
+ result = esock_setopt_lvl_udp(env, descP, eOpt, eVal);
break;
#if defined(HAVE_SCTP)
case IPPROTO_SCTP:
- result = nsetopt_lvl_sctp(env, descP, eOpt, eVal);
+ result = esock_setopt_lvl_sctp(env, descP, eOpt, eVal);
break;
#endif
default:
SSDBG( descP,
- ("SOCKET", "nsetopt_level -> unknown level (%d)\r\n", level) );
+ ("SOCKET",
+ "esock_setopt_level -> unknown level (%d)\r\n", level) );
result = esock_make_error(env, esock_atom_einval);
break;
}
SSDBG( descP,
- ("SOCKET", "nsetopt_level -> done when"
+ ("SOCKET", "esock_setopt_level -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -7704,139 +8086,140 @@ ERL_NIF_TERM nsetopt_level(ErlNifEnv* env,
-/* nsetopt_lvl_socket - Level *SOCKET* option
+/* esock_setopt_lvl_socket - Level *SOCKET* option
*/
static
-ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_socket(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_socket -> entry with"
+ ("SOCKET", "esock_setopt_lvl_socket -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(SO_BINDTODEVICE)
- case SOCKET_OPT_SOCK_BINDTODEVICE:
- result = nsetopt_lvl_sock_bindtodevice(env, descP, eVal);
+ case ESOCK_OPT_SOCK_BINDTODEVICE:
+ result = esock_setopt_lvl_sock_bindtodevice(env, descP, eVal);
break;
#endif
#if defined(SO_BROADCAST)
- case SOCKET_OPT_SOCK_BROADCAST:
- result = nsetopt_lvl_sock_broadcast(env, descP, eVal);
+ case ESOCK_OPT_SOCK_BROADCAST:
+ result = esock_setopt_lvl_sock_broadcast(env, descP, eVal);
break;
#endif
#if defined(SO_DEBUG)
- case SOCKET_OPT_SOCK_DEBUG:
- result = nsetopt_lvl_sock_debug(env, descP, eVal);
+ case ESOCK_OPT_SOCK_DEBUG:
+ result = esock_setopt_lvl_sock_debug(env, descP, eVal);
break;
#endif
#if defined(SO_DONTROUTE)
- case SOCKET_OPT_SOCK_DONTROUTE:
- result = nsetopt_lvl_sock_dontroute(env, descP, eVal);
+ case ESOCK_OPT_SOCK_DONTROUTE:
+ result = esock_setopt_lvl_sock_dontroute(env, descP, eVal);
break;
#endif
#if defined(SO_KEEPALIVE)
- case SOCKET_OPT_SOCK_KEEPALIVE:
- result = nsetopt_lvl_sock_keepalive(env, descP, eVal);
+ case ESOCK_OPT_SOCK_KEEPALIVE:
+ result = esock_setopt_lvl_sock_keepalive(env, descP, eVal);
break;
#endif
#if defined(SO_LINGER)
- case SOCKET_OPT_SOCK_LINGER:
- result = nsetopt_lvl_sock_linger(env, descP, eVal);
+ case ESOCK_OPT_SOCK_LINGER:
+ result = esock_setopt_lvl_sock_linger(env, descP, eVal);
break;
#endif
#if defined(SO_PEEK_OFF)
- case SOCKET_OPT_SOCK_PEEK_OFF:
- result = nsetopt_lvl_sock_peek_off(env, descP, eVal);
+ case ESOCK_OPT_SOCK_PEEK_OFF:
+ result = esock_setopt_lvl_sock_peek_off(env, descP, eVal);
break;
#endif
#if defined(SO_OOBINLINE)
- case SOCKET_OPT_SOCK_OOBINLINE:
- result = nsetopt_lvl_sock_oobinline(env, descP, eVal);
+ case ESOCK_OPT_SOCK_OOBINLINE:
+ result = esock_setopt_lvl_sock_oobinline(env, descP, eVal);
break;
#endif
#if defined(SO_PRIORITY)
- case SOCKET_OPT_SOCK_PRIORITY:
- result = nsetopt_lvl_sock_priority(env, descP, eVal);
+ case ESOCK_OPT_SOCK_PRIORITY:
+ result = esock_setopt_lvl_sock_priority(env, descP, eVal);
break;
#endif
#if defined(SO_RCVBUF)
- case SOCKET_OPT_SOCK_RCVBUF:
- result = nsetopt_lvl_sock_rcvbuf(env, descP, eVal);
+ case ESOCK_OPT_SOCK_RCVBUF:
+ result = esock_setopt_lvl_sock_rcvbuf(env, descP, eVal);
break;
#endif
#if defined(SO_RCVLOWAT)
- case SOCKET_OPT_SOCK_RCVLOWAT:
- result = nsetopt_lvl_sock_rcvlowat(env, descP, eVal);
+ case ESOCK_OPT_SOCK_RCVLOWAT:
+ result = esock_setopt_lvl_sock_rcvlowat(env, descP, eVal);
break;
#endif
#if defined(SO_RCVTIMEO)
- case SOCKET_OPT_SOCK_RCVTIMEO:
- result = nsetopt_lvl_sock_rcvtimeo(env, descP, eVal);
+ case ESOCK_OPT_SOCK_RCVTIMEO:
+ result = esock_setopt_lvl_sock_rcvtimeo(env, descP, eVal);
break;
#endif
#if defined(SO_REUSEADDR)
- case SOCKET_OPT_SOCK_REUSEADDR:
- result = nsetopt_lvl_sock_reuseaddr(env, descP, eVal);
+ case ESOCK_OPT_SOCK_REUSEADDR:
+ result = esock_setopt_lvl_sock_reuseaddr(env, descP, eVal);
break;
#endif
#if defined(SO_REUSEPORT)
- case SOCKET_OPT_SOCK_REUSEPORT:
- result = nsetopt_lvl_sock_reuseport(env, descP, eVal);
+ case ESOCK_OPT_SOCK_REUSEPORT:
+ result = esock_setopt_lvl_sock_reuseport(env, descP, eVal);
break;
#endif
#if defined(SO_SNDBUF)
- case SOCKET_OPT_SOCK_SNDBUF:
- result = nsetopt_lvl_sock_sndbuf(env, descP, eVal);
+ case ESOCK_OPT_SOCK_SNDBUF:
+ result = esock_setopt_lvl_sock_sndbuf(env, descP, eVal);
break;
#endif
#if defined(SO_SNDLOWAT)
- case SOCKET_OPT_SOCK_SNDLOWAT:
- result = nsetopt_lvl_sock_sndlowat(env, descP, eVal);
+ case ESOCK_OPT_SOCK_SNDLOWAT:
+ result = esock_setopt_lvl_sock_sndlowat(env, descP, eVal);
break;
#endif
#if defined(SO_SNDTIMEO)
- case SOCKET_OPT_SOCK_SNDTIMEO:
- result = nsetopt_lvl_sock_sndtimeo(env, descP, eVal);
+ case ESOCK_OPT_SOCK_SNDTIMEO:
+ result = esock_setopt_lvl_sock_sndtimeo(env, descP, eVal);
break;
#endif
#if defined(SO_TIMESTAMP)
- case SOCKET_OPT_SOCK_TIMESTAMP:
- result = nsetopt_lvl_sock_timestamp(env, descP, eVal);
+ case ESOCK_OPT_SOCK_TIMESTAMP:
+ result = esock_setopt_lvl_sock_timestamp(env, descP, eVal);
break;
#endif
default:
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_socket -> unknown opt (%d)\r\n", eOpt) );
+ ("SOCKET",
+ "esock_setopt_lvl_socket -> unknown opt (%d)\r\n", eOpt) );
result = esock_make_error(env, esock_atom_einval);
break;
}
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_socket -> done when"
+ ("SOCKET", "esock_setopt_lvl_socket -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -7846,66 +8229,66 @@ ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env,
#if defined(SO_BINDTODEVICE)
static
-ERL_NIF_TERM nsetopt_lvl_sock_bindtodevice(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_bindtodevice(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_str_opt(env, descP,
- SOL_SOCKET, SO_BROADCAST,
- IFNAMSIZ, eVal);
+ return esock_setopt_str_opt(env, descP,
+ SOL_SOCKET, SO_BINDTODEVICE,
+ IFNAMSIZ, eVal);
}
#endif
#if defined(SO_BROADCAST)
static
-ERL_NIF_TERM nsetopt_lvl_sock_broadcast(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_broadcast(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST, eVal);
}
#endif
#if defined(SO_DEBUG)
static
-ERL_NIF_TERM nsetopt_lvl_sock_debug(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_debug(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG, eVal);
}
#endif
#if defined(SO_DONTROUTE)
static
-ERL_NIF_TERM nsetopt_lvl_sock_dontroute(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_dontroute(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE, eVal);
}
#endif
#if defined(SO_KEEPALIVE)
static
-ERL_NIF_TERM nsetopt_lvl_sock_keepalive(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_keepalive(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE, eVal);
}
#endif
#if defined(SO_LINGER)
static
-ERL_NIF_TERM nsetopt_lvl_sock_linger(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_linger(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
struct linger val;
@@ -7929,346 +8312,347 @@ ERL_NIF_TERM nsetopt_lvl_sock_linger(ErlNifEnv* env,
#if defined(SO_OOBINLINE)
static
-ERL_NIF_TERM nsetopt_lvl_sock_oobinline(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_oobinline(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE, eVal);
}
#endif
#if defined(SO_PEEK_OFF)
static
-ERL_NIF_TERM nsetopt_lvl_sock_peek_off(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_peek_off(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF, eVal);
}
#endif
#if defined(SO_PRIORITY)
static
-ERL_NIF_TERM nsetopt_lvl_sock_priority(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_priority(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY, eVal);
}
#endif
#if defined(SO_RCVBUF)
static
-ERL_NIF_TERM nsetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_rcvbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF, eVal);
}
#endif
#if defined(SO_RCVLOWAT)
static
-ERL_NIF_TERM nsetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT, eVal);
}
#endif
#if defined(SO_RCVTIMEO)
static
-ERL_NIF_TERM nsetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO, eVal);
+ return esock_setopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO, eVal);
}
#endif
#if defined(SO_REUSEADDR)
static
-ERL_NIF_TERM nsetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_reuseaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR, eVal);
}
#endif
#if defined(SO_REUSEPORT)
static
-ERL_NIF_TERM nsetopt_lvl_sock_reuseport(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_reuseport(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT, eVal);
}
#endif
#if defined(SO_SNDBUF)
static
-ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_sndbuf(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF, eVal);
}
#endif
#if defined(SO_SNDLOWAT)
static
-ERL_NIF_TERM nsetopt_lvl_sock_sndlowat(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT, eVal);
+ return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT, eVal);
}
#endif
#if defined(SO_SNDTIMEO)
static
-ERL_NIF_TERM nsetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_sndtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sock_sndtimeo -> entry with"
+ ("SOCKET", "esock_setopt_lvl_sock_sndtimeo -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
- return nsetopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO, eVal);
+ return esock_setopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO, eVal);
}
#endif
#if defined(SO_TIMESTAMP)
static
-ERL_NIF_TERM nsetopt_lvl_sock_timestamp(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sock_timestamp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP, eVal);
}
#endif
-/* nsetopt_lvl_ip - Level *IP* option(s)
+/* esock_setopt_lvl_ip - Level *IP* option(s)
*/
static
-ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip -> entry with"
+ ("SOCKET", "esock_setopt_lvl_ip -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(IP_ADD_MEMBERSHIP)
- case SOCKET_OPT_IP_ADD_MEMBERSHIP:
- result = nsetopt_lvl_ip_add_membership(env, descP, eVal);
+ case ESOCK_OPT_IP_ADD_MEMBERSHIP:
+ result = esock_setopt_lvl_ip_add_membership(env, descP, eVal);
break;
#endif
#if defined(IP_ADD_SOURCE_MEMBERSHIP)
- case SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP:
- result = nsetopt_lvl_ip_add_source_membership(env, descP, eVal);
+ case ESOCK_OPT_IP_ADD_SOURCE_MEMBERSHIP:
+ result = esock_setopt_lvl_ip_add_source_membership(env, descP, eVal);
break;
#endif
#if defined(IP_BLOCK_SOURCE)
- case SOCKET_OPT_IP_BLOCK_SOURCE:
- result = nsetopt_lvl_ip_block_source(env, descP, eVal);
+ case ESOCK_OPT_IP_BLOCK_SOURCE:
+ result = esock_setopt_lvl_ip_block_source(env, descP, eVal);
break;
#endif
#if defined(IP_DROP_MEMBERSHIP)
- case SOCKET_OPT_IP_DROP_MEMBERSHIP:
- result = nsetopt_lvl_ip_drop_membership(env, descP, eVal);
+ case ESOCK_OPT_IP_DROP_MEMBERSHIP:
+ result = esock_setopt_lvl_ip_drop_membership(env, descP, eVal);
break;
#endif
#if defined(IP_DROP_SOURCE_MEMBERSHIP)
- case SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP:
- result = nsetopt_lvl_ip_drop_source_membership(env, descP, eVal);
+ case ESOCK_OPT_IP_DROP_SOURCE_MEMBERSHIP:
+ result = esock_setopt_lvl_ip_drop_source_membership(env, descP, eVal);
break;
#endif
#if defined(IP_FREEBIND)
- case SOCKET_OPT_IP_FREEBIND:
- result = nsetopt_lvl_ip_freebind(env, descP, eVal);
+ case ESOCK_OPT_IP_FREEBIND:
+ result = esock_setopt_lvl_ip_freebind(env, descP, eVal);
break;
#endif
#if defined(IP_HDRINCL)
- case SOCKET_OPT_IP_HDRINCL:
- result = nsetopt_lvl_ip_hdrincl(env, descP, eVal);
+ case ESOCK_OPT_IP_HDRINCL:
+ result = esock_setopt_lvl_ip_hdrincl(env, descP, eVal);
break;
#endif
#if defined(IP_MINTTL)
- case SOCKET_OPT_IP_MINTTL:
- result = nsetopt_lvl_ip_minttl(env, descP, eVal);
+ case ESOCK_OPT_IP_MINTTL:
+ result = esock_setopt_lvl_ip_minttl(env, descP, eVal);
break;
#endif
#if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE)
- case SOCKET_OPT_IP_MSFILTER:
- result = nsetopt_lvl_ip_msfilter(env, descP, eVal);
+ case ESOCK_OPT_IP_MSFILTER:
+ result = esock_setopt_lvl_ip_msfilter(env, descP, eVal);
break;
#endif
#if defined(IP_MTU_DISCOVER)
- case SOCKET_OPT_IP_MTU_DISCOVER:
- result = nsetopt_lvl_ip_mtu_discover(env, descP, eVal);
+ case ESOCK_OPT_IP_MTU_DISCOVER:
+ result = esock_setopt_lvl_ip_mtu_discover(env, descP, eVal);
break;
#endif
#if defined(IP_MULTICAST_ALL)
- case SOCKET_OPT_IP_MULTICAST_ALL:
- result = nsetopt_lvl_ip_multicast_all(env, descP, eVal);
+ case ESOCK_OPT_IP_MULTICAST_ALL:
+ result = esock_setopt_lvl_ip_multicast_all(env, descP, eVal);
break;
#endif
#if defined(IP_MULTICAST_IF)
- case SOCKET_OPT_IP_MULTICAST_IF:
- result = nsetopt_lvl_ip_multicast_if(env, descP, eVal);
+ case ESOCK_OPT_IP_MULTICAST_IF:
+ result = esock_setopt_lvl_ip_multicast_if(env, descP, eVal);
break;
#endif
#if defined(IP_MULTICAST_LOOP)
- case SOCKET_OPT_IP_MULTICAST_LOOP:
- result = nsetopt_lvl_ip_multicast_loop(env, descP, eVal);
+ case ESOCK_OPT_IP_MULTICAST_LOOP:
+ result = esock_setopt_lvl_ip_multicast_loop(env, descP, eVal);
break;
#endif
#if defined(IP_MULTICAST_TTL)
- case SOCKET_OPT_IP_MULTICAST_TTL:
- result = nsetopt_lvl_ip_multicast_ttl(env, descP, eVal);
+ case ESOCK_OPT_IP_MULTICAST_TTL:
+ result = esock_setopt_lvl_ip_multicast_ttl(env, descP, eVal);
break;
#endif
#if defined(IP_NODEFRAG)
- case SOCKET_OPT_IP_NODEFRAG:
- result = nsetopt_lvl_ip_nodefrag(env, descP, eVal);
+ case ESOCK_OPT_IP_NODEFRAG:
+ result = esock_setopt_lvl_ip_nodefrag(env, descP, eVal);
break;
#endif
#if defined(IP_PKTINFO)
- case SOCKET_OPT_IP_PKTINFO:
- result = nsetopt_lvl_ip_pktinfo(env, descP, eVal);
+ case ESOCK_OPT_IP_PKTINFO:
+ result = esock_setopt_lvl_ip_pktinfo(env, descP, eVal);
break;
#endif
#if defined(IP_RECVDSTADDR)
- case SOCKET_OPT_IP_RECVDSTADDR:
- result = nsetopt_lvl_ip_recvdstaddr(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVDSTADDR:
+ result = esock_setopt_lvl_ip_recvdstaddr(env, descP, eVal);
break;
#endif
#if defined(IP_RECVERR)
- case SOCKET_OPT_IP_RECVERR:
- result = nsetopt_lvl_ip_recverr(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVERR:
+ result = esock_setopt_lvl_ip_recverr(env, descP, eVal);
break;
#endif
#if defined(IP_RECVIF)
- case SOCKET_OPT_IP_RECVIF:
- result = nsetopt_lvl_ip_recvif(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVIF:
+ result = esock_setopt_lvl_ip_recvif(env, descP, eVal);
break;
#endif
#if defined(IP_RECVOPTS)
- case SOCKET_OPT_IP_RECVOPTS:
- result = nsetopt_lvl_ip_recvopts(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVOPTS:
+ result = esock_setopt_lvl_ip_recvopts(env, descP, eVal);
break;
#endif
#if defined(IP_RECVORIGDSTADDR)
- case SOCKET_OPT_IP_RECVORIGDSTADDR:
- result = nsetopt_lvl_ip_recvorigdstaddr(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVORIGDSTADDR:
+ result = esock_setopt_lvl_ip_recvorigdstaddr(env, descP, eVal);
break;
#endif
#if defined(IP_RECVTOS)
- case SOCKET_OPT_IP_RECVTOS:
- result = nsetopt_lvl_ip_recvtos(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVTOS:
+ result = esock_setopt_lvl_ip_recvtos(env, descP, eVal);
break;
#endif
#if defined(IP_RECVTTL)
- case SOCKET_OPT_IP_RECVTTL:
- result = nsetopt_lvl_ip_recvttl(env, descP, eVal);
+ case ESOCK_OPT_IP_RECVTTL:
+ result = esock_setopt_lvl_ip_recvttl(env, descP, eVal);
break;
#endif
#if defined(IP_RETOPTS)
- case SOCKET_OPT_IP_RETOPTS:
- result = nsetopt_lvl_ip_retopts(env, descP, eVal);
+ case ESOCK_OPT_IP_RETOPTS:
+ result = esock_setopt_lvl_ip_retopts(env, descP, eVal);
break;
#endif
#if defined(IP_ROUTER_ALERT)
- case SOCKET_OPT_IP_ROUTER_ALERT:
- result = nsetopt_lvl_ip_router_alert(env, descP, eVal);
+ case ESOCK_OPT_IP_ROUTER_ALERT:
+ result = esock_setopt_lvl_ip_router_alert(env, descP, eVal);
break;
#endif
#if defined(IP_SENDSRCADDR)
- case SOCKET_OPT_IP_SENDSRCADDR:
- result = nsetopt_lvl_ip_sendsrcaddr(env, descP, eVal);
+ case ESOCK_OPT_IP_SENDSRCADDR:
+ result = esock_setopt_lvl_ip_sendsrcaddr(env, descP, eVal);
break;
#endif
#if defined(IP_TOS)
- case SOCKET_OPT_IP_TOS:
- result = nsetopt_lvl_ip_tos(env, descP, eVal);
+ case ESOCK_OPT_IP_TOS:
+ result = esock_setopt_lvl_ip_tos(env, descP, eVal);
break;
#endif
#if defined(IP_TRANSPARENT)
- case SOCKET_OPT_IP_TRANSPARENT:
- result = nsetopt_lvl_ip_transparent(env, descP, eVal);
+ case ESOCK_OPT_IP_TRANSPARENT:
+ result = esock_setopt_lvl_ip_transparent(env, descP, eVal);
break;
#endif
#if defined(IP_TTL)
- case SOCKET_OPT_IP_TTL:
- result = nsetopt_lvl_ip_ttl(env, descP, eVal);
+ case ESOCK_OPT_IP_TTL:
+ result = esock_setopt_lvl_ip_ttl(env, descP, eVal);
break;
#endif
#if defined(IP_UNBLOCK_SOURCE)
- case SOCKET_OPT_IP_UNBLOCK_SOURCE:
- result = nsetopt_lvl_ip_unblock_source(env, descP, eVal);
+ case ESOCK_OPT_IP_UNBLOCK_SOURCE:
+ result = esock_setopt_lvl_ip_unblock_source(env, descP, eVal);
break;
#endif
default:
- SSDBG( descP, ("SOCKET", "nsetopt_lvl_ip -> unknown opt (%d)\r\n", eOpt) );
+ SSDBG( descP, ("SOCKET",
+ "esock_setopt_lvl_ip -> unknown opt (%d)\r\n", eOpt) );
result = esock_make_error(env, esock_atom_einval);
break;
}
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip -> done when"
+ ("SOCKET", "esock_setopt_lvl_ip -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -8276,7 +8660,7 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
}
-/* nsetopt_lvl_ip_add_membership - Level IP ADD_MEMBERSHIP option
+/* esock_setopt_lvl_ip_add_membership - Level IP ADD_MEMBERSHIP option
*
* The value is a map with two attributes: multiaddr and interface.
* The attribute 'multiaddr' is always a 4-tuple (IPv4 address).
@@ -8285,16 +8669,18 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
*/
#if defined(IP_ADD_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_add_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_add_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ip_update_membership(env, descP, eVal, IP_ADD_MEMBERSHIP);
+ return esock_setopt_lvl_ip_update_membership(env, descP, eVal,
+ IP_ADD_MEMBERSHIP);
}
#endif
-/* nsetopt_lvl_ip_add_source_membership - Level IP ADD_SOURCE_MEMBERSHIP option
+/* esock_setopt_lvl_ip_add_source_membership -
+ * Level IP ADD_SOURCE_MEMBERSHIP option
*
* The value is a map with three attributes: multiaddr, interface and
* sourceaddr.
@@ -8305,17 +8691,17 @@ ERL_NIF_TERM nsetopt_lvl_ip_add_membership(ErlNifEnv* env,
*/
#if defined(IP_ADD_SOURCE_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_add_source_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_add_source_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ip_update_source(env, descP, eVal,
- IP_ADD_SOURCE_MEMBERSHIP);
+ return esock_setopt_lvl_ip_update_source(env, descP, eVal,
+ IP_ADD_SOURCE_MEMBERSHIP);
}
#endif
-/* nsetopt_lvl_ip_block_source - Level IP BLOCK_SOURCE option
+/* esock_setopt_lvl_ip_block_source - Level IP BLOCK_SOURCE option
*
* The value is a map with three attributes: multiaddr, interface and
* sourceaddr.
@@ -8326,16 +8712,16 @@ ERL_NIF_TERM nsetopt_lvl_ip_add_source_membership(ErlNifEnv* env,
*/
#if defined(IP_BLOCK_SOURCE)
static
-ERL_NIF_TERM nsetopt_lvl_ip_block_source(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_block_source(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ip_update_source(env, descP, eVal, IP_BLOCK_SOURCE);
+ return esock_setopt_lvl_ip_update_source(env, descP, eVal, IP_BLOCK_SOURCE);
}
#endif
-/* nsetopt_lvl_ip_drop_membership - Level IP DROP_MEMBERSHIP option
+/* esock_setopt_lvl_ip_drop_membership - Level IP DROP_MEMBERSHIP option
*
* The value is a map with two attributes: multiaddr and interface.
* The attribute 'multiaddr' is always a 4-tuple (IPv4 address).
@@ -8348,18 +8734,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_block_source(ErlNifEnv* env,
*/
#if defined(IP_DROP_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_drop_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_drop_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ip_update_membership(env, descP, eVal,
- IP_DROP_MEMBERSHIP);
+ return esock_setopt_lvl_ip_update_membership(env, descP, eVal,
+ IP_DROP_MEMBERSHIP);
}
#endif
-/* nsetopt_lvl_ip_drop_source_membership - Level IP DROP_SOURCE_MEMBERSHIP option
+/* esock_setopt_lvl_ip_drop_source_membership -
+ * Level IP DROP_SOURCE_MEMBERSHIP option
*
* The value is a map with three attributes: multiaddr, interface and
* sourceaddr.
@@ -8370,24 +8757,24 @@ ERL_NIF_TERM nsetopt_lvl_ip_drop_membership(ErlNifEnv* env,
*/
#if defined(IP_DROP_SOURCE_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_drop_source_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_drop_source_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ip_update_source(env, descP, eVal,
- IP_DROP_SOURCE_MEMBERSHIP);
+ return esock_setopt_lvl_ip_update_source(env, descP, eVal,
+ IP_DROP_SOURCE_MEMBERSHIP);
}
#endif
-/* nsetopt_lvl_ip_freebind - Level IP FREEBIND option
+/* esock_setopt_lvl_ip_freebind - Level IP FREEBIND option
*/
#if defined(IP_FREEBIND)
static
-ERL_NIF_TERM nsetopt_lvl_ip_freebind(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_freebind(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8395,19 +8782,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_freebind(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_FREEBIND, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_FREEBIND, eVal);
}
#endif
-/* nsetopt_lvl_ip_hdrincl - Level IP HDRINCL option
+/* esock_setopt_lvl_ip_hdrincl - Level IP HDRINCL option
*/
#if defined(IP_HDRINCL)
static
-ERL_NIF_TERM nsetopt_lvl_ip_hdrincl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_hdrincl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8415,19 +8802,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_hdrincl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_HDRINCL, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_HDRINCL, eVal);
}
#endif
-/* nsetopt_lvl_ip_minttl - Level IP MINTTL option
+/* esock_setopt_lvl_ip_minttl - Level IP MINTTL option
*/
#if defined(IP_MINTTL)
static
-ERL_NIF_TERM nsetopt_lvl_ip_minttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_minttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8435,26 +8822,26 @@ ERL_NIF_TERM nsetopt_lvl_ip_minttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_int_opt(env, descP, level, IP_MINTTL, eVal);
+ return esock_setopt_int_opt(env, descP, level, IP_MINTTL, eVal);
}
#endif
-/* nsetopt_lvl_ip_msfilter - Level IP MSFILTER option
+/* esock_setopt_lvl_ip_msfilter - Level IP MSFILTER option
*
* The value can be *either* the atom 'null' or a map of type ip_msfilter().
*/
#if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE)
static
-ERL_NIF_TERM nsetopt_lvl_ip_msfilter(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_msfilter(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
if (COMPARE(eVal, atom_null) == 0) {
- return nsetopt_lvl_ip_msfilter_set(env, descP->sock, NULL, 0);
+ return esock_setopt_lvl_ip_msfilter_set(env, descP->sock, NULL, 0);
} else {
struct ip_msfilter* msfP;
Uint32 msfSz;
@@ -8519,7 +8906,8 @@ ERL_NIF_TERM nsetopt_lvl_ip_msfilter(ErlNifEnv* env,
}
/* And now, finally, set the option */
- result = nsetopt_lvl_ip_msfilter_set(env, descP->sock, msfP, msfSz);
+ result = esock_setopt_lvl_ip_msfilter_set(env, descP->sock,
+ msfP, msfSz);
FREE(msfP);
return result;
}
@@ -8549,10 +8937,10 @@ BOOLEAN_T decode_ip_msfilter_mode(ErlNifEnv* env,
static
-ERL_NIF_TERM nsetopt_lvl_ip_msfilter_set(ErlNifEnv* env,
- SOCKET sock,
- struct ip_msfilter* msfP,
- SOCKLEN_T optLen)
+ERL_NIF_TERM esock_setopt_lvl_ip_msfilter_set(ErlNifEnv* env,
+ SOCKET sock,
+ struct ip_msfilter* msfP,
+ SOCKLEN_T optLen)
{
ERL_NIF_TERM result;
int res;
@@ -8574,15 +8962,15 @@ ERL_NIF_TERM nsetopt_lvl_ip_msfilter_set(ErlNifEnv* env,
-/* nsetopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option
+/* esock_setopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option
*
* The value is an atom of the type ip_pmtudisc().
*/
#if defined(IP_MTU_DISCOVER)
static
-ERL_NIF_TERM nsetopt_lvl_ip_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
int val;
@@ -8615,13 +9003,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_mtu_discover(ErlNifEnv* env,
#endif
-/* nsetopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option
+/* esock_setopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option
*/
#if defined(IP_MULTICAST_ALL)
static
-ERL_NIF_TERM nsetopt_lvl_ip_multicast_all(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_multicast_all(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8629,20 +9017,20 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_all(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_MULTICAST_ALL, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_MULTICAST_ALL, eVal);
}
#endif
-/* nsetopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option
+/* esock_setopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option
*
* The value is either the atom 'any' or a 4-tuple.
*/
#if defined(IP_MULTICAST_IF)
static
-ERL_NIF_TERM nsetopt_lvl_ip_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
struct in_addr ifAddr;
@@ -8673,13 +9061,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_if(ErlNifEnv* env,
#endif
-/* nsetopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option
+/* esock_setopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option
*/
#if defined(IP_MULTICAST_LOOP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8687,18 +9075,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP, eVal);
}
#endif
-/* nsetopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option
+/* esock_setopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option
*/
#if defined(IP_MULTICAST_TTL)
static
-ERL_NIF_TERM nsetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8706,18 +9094,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_int_opt(env, descP, level, IP_MULTICAST_TTL, eVal);
+ return esock_setopt_int_opt(env, descP, level, IP_MULTICAST_TTL, eVal);
}
#endif
-/* nsetopt_lvl_ip_nodefrag - Level IP NODEFRAG option
+/* esock_setopt_lvl_ip_nodefrag - Level IP NODEFRAG option
*/
#if defined(IP_NODEFRAG)
static
-ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_nodefrag(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8725,18 +9113,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_NODEFRAG, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_NODEFRAG, eVal);
}
#endif
-/* nsetopt_lvl_ip_pktinfo - Level IP PKTINFO option
+/* esock_setopt_lvl_ip_pktinfo - Level IP PKTINFO option
*/
#if defined(IP_PKTINFO)
static
-ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_pktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8744,18 +9132,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_PKTINFO, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_PKTINFO, eVal);
}
#endif
-/* nsetopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option
+/* esock_setopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option
*/
#if defined(IP_RECVDSTADDR)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8763,18 +9151,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVDSTADDR, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVDSTADDR, eVal);
}
#endif
-/* nsetopt_lvl_ip_recverr - Level IP RECVERR option
+/* esock_setopt_lvl_ip_recverr - Level IP RECVERR option
*/
#if defined(IP_RECVERR)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8782,18 +9170,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVERR, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVERR, eVal);
}
#endif
-/* nsetopt_lvl_ip_recvif - Level IP RECVIF option
+/* esock_setopt_lvl_ip_recvif - Level IP RECVIF option
*/
#if defined(IP_RECVIF)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recvif(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8801,18 +9189,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVIF, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVIF, eVal);
}
#endif
-/* nsetopt_lvl_ip_recvopts - Level IP RECVOPTS option
+/* esock_setopt_lvl_ip_recvopts - Level IP RECVOPTS option
*/
#if defined(IP_RECVOPTS)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recvopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8820,18 +9208,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVOPTS, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVOPTS, eVal);
}
#endif
-/* nsetopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option
+/* esock_setopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option
*/
#if defined(IP_RECVORIGDSTADDR)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8839,18 +9227,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR, eVal);
}
#endif
-/* nsetopt_lvl_ip_recvtos - Level IP RECVTOS option
+/* esock_setopt_lvl_ip_recvtos - Level IP RECVTOS option
*/
#if defined(IP_RECVTOS)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recvtos(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8858,18 +9246,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVTOS, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVTOS, eVal);
}
#endif
-/* nsetopt_lvl_ip_recvttl - Level IP RECVTTL option
+/* esock_setopt_lvl_ip_recvttl - Level IP RECVTTL option
*/
#if defined(IP_RECVTTL)
static
-ERL_NIF_TERM nsetopt_lvl_ip_recvttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_recvttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8877,18 +9265,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RECVTTL, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RECVTTL, eVal);
}
#endif
-/* nsetopt_lvl_ip_retopts - Level IP RETOPTS option
+/* esock_setopt_lvl_ip_retopts - Level IP RETOPTS option
*/
#if defined(IP_RETOPTS)
static
-ERL_NIF_TERM nsetopt_lvl_ip_retopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_retopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8896,18 +9284,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_retopts(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_RETOPTS, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_RETOPTS, eVal);
}
#endif
-/* nsetopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option
+/* esock_setopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option
*/
#if defined(IP_ROUTER_ALERT)
static
-ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8915,18 +9303,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_int_opt(env, descP, level, IP_ROUTER_ALERT, eVal);
+ return esock_setopt_int_opt(env, descP, level, IP_ROUTER_ALERT, eVal);
}
#endif
-/* nsetopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option
+/* esock_setopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option
*/
#if defined(IP_SENDSRCADDR)
static
-ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8934,18 +9322,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_SENDSRCADDR, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_SENDSRCADDR, eVal);
}
#endif
-/* nsetopt_lvl_ip_tos - Level IP TOS option
+/* esock_setopt_lvl_ip_tos - Level IP TOS option
*/
#if defined(IP_TOS)
static
-ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_tos(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8972,13 +9360,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env,
#endif
-/* nsetopt_lvl_ip_transparent - Level IP TRANSPARENT option
+/* esock_setopt_lvl_ip_transparent - Level IP TRANSPARENT option
*/
#if defined(IP_TRANSPARENT)
static
-ERL_NIF_TERM nsetopt_lvl_ip_transparent(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_transparent(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8986,19 +9374,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_transparent(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_bool_opt(env, descP, level, IP_TRANSPARENT, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IP_TRANSPARENT, eVal);
}
#endif
-/* nsetopt_lvl_ip_ttl - Level IP TTL option
+/* esock_setopt_lvl_ip_ttl - Level IP TTL option
*/
#if defined(IP_TTL)
static
-ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -9006,13 +9394,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return nsetopt_int_opt(env, descP, level, IP_TTL, eVal);
+ return esock_setopt_int_opt(env, descP, level, IP_TTL, eVal);
}
#endif
-/* nsetopt_lvl_ip_unblock_source - Level IP UNBLOCK_SOURCE option
+/* esock_setopt_lvl_ip_unblock_source - Level IP UNBLOCK_SOURCE option
*
* The value is a map with three attributes: multiaddr, interface and
* sourceaddr.
@@ -9023,11 +9411,12 @@ ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env,
*/
#if defined(IP_UNBLOCK_SOURCE)
static
-ERL_NIF_TERM nsetopt_lvl_ip_unblock_source(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ip_unblock_source(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ip_update_source(env, descP, eVal, IP_UNBLOCK_SOURCE);
+ return esock_setopt_lvl_ip_update_source(env, descP, eVal,
+ IP_UNBLOCK_SOURCE);
}
#endif
@@ -9035,10 +9424,10 @@ ERL_NIF_TERM nsetopt_lvl_ip_unblock_source(ErlNifEnv* env,
#if defined(IP_ADD_MEMBERSHIP) || defined(IP_DROP_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal,
- int opt)
+ERL_NIF_TERM esock_setopt_lvl_ip_update_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal,
+ int opt)
{
ERL_NIF_TERM result, eMultiAddr, eInterface;
struct ip_mreq mreq;
@@ -9054,7 +9443,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
// It must be a map
if (!IS_MAP(env, eVal)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"value *not* a map\r\n") );
return enif_make_badarg(env);
}
@@ -9062,21 +9451,21 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
// It must have atleast two attributes
if (!enif_get_map_size(env, eVal, &sz) || (sz < 2)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"invalid map value: %T\r\n", eVal) );
return enif_make_badarg(env);
}
if (!GET_MAP_VAL(env, eVal, atom_multiaddr, &eMultiAddr)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"failed get multiaddr (map) attribute\r\n") );
return enif_make_badarg(env);
}
if (!GET_MAP_VAL(env, eVal, atom_interface, &eInterface)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"failed get interface (map) attribute\r\n") );
return enif_make_badarg(env);
}
@@ -9085,7 +9474,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
eMultiAddr,
&mreq.imr_multiaddr)) != NULL) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"failed decode multiaddr %T: %s\r\n", eMultiAddr, xres) );
return esock_make_error_str(env, xres);
}
@@ -9094,7 +9483,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
eInterface,
&mreq.imr_interface)) != NULL) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"failed decode interface %T: %s\r\n", eInterface, xres) );
return esock_make_error_str(env, xres);
}
@@ -9107,7 +9496,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
result = esock_make_error_errno(env, save_errno);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"failed setopt: %T (%d)\r\n", result, save_errno) );
} else {
@@ -9121,10 +9510,10 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env,
#if defined(IP_ADD_SOURCE_MEMBERSHIP) || defined(IP_DROP_SOURCE_MEMBERSHIP) || defined(IP_BLOCK_SOURCE) || defined(IP_UNBLOCK_SOURCE)
static
-ERL_NIF_TERM nsetopt_lvl_ip_update_source(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal,
- int opt)
+ERL_NIF_TERM esock_setopt_lvl_ip_update_source(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal,
+ int opt)
{
ERL_NIF_TERM result, eMultiAddr, eInterface, eSourceAddr;
struct ip_mreq_source mreq;
@@ -9184,146 +9573,147 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_source(ErlNifEnv* env,
/* *** Handling set of socket options for level = ipv6 *** */
-/* nsetopt_lvl_ipv6 - Level *IPv6* option(s)
+/* esock_setopt_lvl_ipv6 - Level *IPv6* option(s)
*/
#if defined(HAVE_IPV6)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6 -> entry with"
+ ("SOCKET", "esock_setopt_lvl_ipv6 -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(IPV6_ADDRFORM)
- case SOCKET_OPT_IPV6_ADDRFORM:
- result = nsetopt_lvl_ipv6_addrform(env, descP, eVal);
+ case ESOCK_OPT_IPV6_ADDRFORM:
+ result = esock_setopt_lvl_ipv6_addrform(env, descP, eVal);
break;
#endif
#if defined(IPV6_ADD_MEMBERSHIP)
- case SOCKET_OPT_IPV6_ADD_MEMBERSHIP:
- result = nsetopt_lvl_ipv6_add_membership(env, descP, eVal);
+ case ESOCK_OPT_IPV6_ADD_MEMBERSHIP:
+ result = esock_setopt_lvl_ipv6_add_membership(env, descP, eVal);
break;
#endif
#if defined(IPV6_AUTHHDR)
- case SOCKET_OPT_IPV6_AUTHHDR:
- result = nsetopt_lvl_ipv6_authhdr(env, descP, eVal);
+ case ESOCK_OPT_IPV6_AUTHHDR:
+ result = esock_setopt_lvl_ipv6_authhdr(env, descP, eVal);
break;
#endif
#if defined(IPV6_DROP_MEMBERSHIP)
- case SOCKET_OPT_IPV6_DROP_MEMBERSHIP:
- result = nsetopt_lvl_ipv6_drop_membership(env, descP, eVal);
+ case ESOCK_OPT_IPV6_DROP_MEMBERSHIP:
+ result = esock_setopt_lvl_ipv6_drop_membership(env, descP, eVal);
break;
#endif
#if defined(IPV6_DSTOPTS)
- case SOCKET_OPT_IPV6_DSTOPTS:
- result = nsetopt_lvl_ipv6_dstopts(env, descP, eVal);
+ case ESOCK_OPT_IPV6_DSTOPTS:
+ result = esock_setopt_lvl_ipv6_dstopts(env, descP, eVal);
break;
#endif
#if defined(IPV6_FLOWINFO)
- case SOCKET_OPT_IPV6_FLOWINFO:
- result = nsetopt_lvl_ipv6_flowinfo(env, descP, eVal);
+ case ESOCK_OPT_IPV6_FLOWINFO:
+ result = esock_setopt_lvl_ipv6_flowinfo(env, descP, eVal);
break;
#endif
#if defined(IPV6_HOPLIMIT)
- case SOCKET_OPT_IPV6_HOPLIMIT:
- result = nsetopt_lvl_ipv6_hoplimit(env, descP, eVal);
+ case ESOCK_OPT_IPV6_HOPLIMIT:
+ result = esock_setopt_lvl_ipv6_hoplimit(env, descP, eVal);
break;
#endif
#if defined(IPV6_HOPOPTS)
- case SOCKET_OPT_IPV6_HOPOPTS:
- result = nsetopt_lvl_ipv6_hopopts(env, descP, eVal);
+ case ESOCK_OPT_IPV6_HOPOPTS:
+ result = esock_setopt_lvl_ipv6_hopopts(env, descP, eVal);
break;
#endif
#if defined(IPV6_MTU)
- case SOCKET_OPT_IPV6_MTU:
- result = nsetopt_lvl_ipv6_mtu(env, descP, eVal);
+ case ESOCK_OPT_IPV6_MTU:
+ result = esock_setopt_lvl_ipv6_mtu(env, descP, eVal);
break;
#endif
#if defined(IPV6_MTU_DISCOVER)
- case SOCKET_OPT_IPV6_MTU_DISCOVER:
- result = nsetopt_lvl_ipv6_mtu_discover(env, descP, eVal);
+ case ESOCK_OPT_IPV6_MTU_DISCOVER:
+ result = esock_setopt_lvl_ipv6_mtu_discover(env, descP, eVal);
break;
#endif
#if defined(IPV6_MULTICAST_HOPS)
- case SOCKET_OPT_IPV6_MULTICAST_HOPS:
- result = nsetopt_lvl_ipv6_multicast_hops(env, descP, eVal);
+ case ESOCK_OPT_IPV6_MULTICAST_HOPS:
+ result = esock_setopt_lvl_ipv6_multicast_hops(env, descP, eVal);
break;
#endif
#if defined(IPV6_MULTICAST_IF)
- case SOCKET_OPT_IPV6_MULTICAST_IF:
- result = nsetopt_lvl_ipv6_multicast_if(env, descP, eVal);
+ case ESOCK_OPT_IPV6_MULTICAST_IF:
+ result = esock_setopt_lvl_ipv6_multicast_if(env, descP, eVal);
break;
#endif
#if defined(IPV6_MULTICAST_LOOP)
- case SOCKET_OPT_IPV6_MULTICAST_LOOP:
- result = nsetopt_lvl_ipv6_multicast_loop(env, descP, eVal);
+ case ESOCK_OPT_IPV6_MULTICAST_LOOP:
+ result = esock_setopt_lvl_ipv6_multicast_loop(env, descP, eVal);
break;
#endif
#if defined(IPV6_RECVERR)
- case SOCKET_OPT_IPV6_RECVERR:
- result = nsetopt_lvl_ipv6_recverr(env, descP, eVal);
+ case ESOCK_OPT_IPV6_RECVERR:
+ result = esock_setopt_lvl_ipv6_recverr(env, descP, eVal);
break;
#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
- case SOCKET_OPT_IPV6_RECVPKTINFO:
- result = nsetopt_lvl_ipv6_recvpktinfo(env, descP, eVal);
+ case ESOCK_OPT_IPV6_RECVPKTINFO:
+ result = esock_setopt_lvl_ipv6_recvpktinfo(env, descP, eVal);
break;
#endif
#if defined(IPV6_ROUTER_ALERT)
- case SOCKET_OPT_IPV6_ROUTER_ALERT:
- result = nsetopt_lvl_ipv6_router_alert(env, descP, eVal);
+ case ESOCK_OPT_IPV6_ROUTER_ALERT:
+ result = esock_setopt_lvl_ipv6_router_alert(env, descP, eVal);
break;
#endif
#if defined(IPV6_RTHDR)
- case SOCKET_OPT_IPV6_RTHDR:
- result = nsetopt_lvl_ipv6_rthdr(env, descP, eVal);
+ case ESOCK_OPT_IPV6_RTHDR:
+ result = esock_setopt_lvl_ipv6_rthdr(env, descP, eVal);
break;
#endif
#if defined(IPV6_UNICAST_HOPS)
- case SOCKET_OPT_IPV6_UNICAST_HOPS:
- result = nsetopt_lvl_ipv6_unicast_hops(env, descP, eVal);
+ case ESOCK_OPT_IPV6_UNICAST_HOPS:
+ result = esock_setopt_lvl_ipv6_unicast_hops(env, descP, eVal);
break;
#endif
#if defined(IPV6_V6ONLY)
- case SOCKET_OPT_IPV6_V6ONLY:
- result = nsetopt_lvl_ipv6_v6only(env, descP, eVal);
+ case ESOCK_OPT_IPV6_V6ONLY:
+ result = esock_setopt_lvl_ipv6_v6only(env, descP, eVal);
break;
#endif
default:
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6 -> unknown opt (%d)\r\n", eOpt) );
+ ("SOCKET",
+ "esock_setopt_lvl_ipv6 -> unknown opt (%d)\r\n", eOpt) );
result = esock_make_error(env, esock_atom_einval);
break;
}
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6 -> done when"
+ ("SOCKET", "esock_setopt_lvl_ipv6 -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -9333,15 +9723,15 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
#if defined(IPV6_ADDRFORM)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_addrform(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
int res, edomain, domain;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_addrform -> entry with"
+ ("SOCKET", "esock_setopt_lvl_ipv6_addrform -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -9349,14 +9739,15 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_addrform -> decode"
+ ("SOCKET", "esock_setopt_lvl_ipv6_addrform -> decode"
"\r\n edomain: %d"
"\r\n", edomain) );
if (!edomain2domain(edomain, &domain))
return esock_make_error(env, esock_atom_einval);
- SSDBG( descP, ("SOCKET", "nsetopt_lvl_ipv6_addrform -> try set opt to %d\r\n",
+ SSDBG( descP, ("SOCKET",
+ "esock_setopt_lvl_ipv6_addrform -> try set opt to %d\r\n",
domain) );
res = socket_setopt(descP->sock,
@@ -9375,11 +9766,11 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env,
#if defined(IPV6_ADD_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_add_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ipv6_update_membership(env, descP, eVal,
+ return esock_setopt_lvl_ipv6_update_membership(env, descP, eVal,
IPV6_ADD_MEMBERSHIP);
}
#endif
@@ -9387,22 +9778,22 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env,
#if defined(IPV6_AUTHHDR)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR, eVal);
+ return esock_setopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR, eVal);
}
#endif
#if defined(IPV6_DROP_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_lvl_ipv6_update_membership(env, descP, eVal,
+ return esock_setopt_lvl_ipv6_update_membership(env, descP, eVal,
IPV6_DROP_MEMBERSHIP);
}
#endif
@@ -9410,9 +9801,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
#if defined(IPV6_DSTOPTS)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9420,16 +9811,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_DSTOPTS, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_DSTOPTS, eVal);
}
#endif
#if defined(IPV6_FLOWINFO)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9437,16 +9828,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_FLOWINFO, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_FLOWINFO, eVal);
}
#endif
#if defined(IPV6_HOPLIMIT)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9454,16 +9845,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_HOPLIMIT, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_HOPLIMIT, eVal);
}
#endif
#if defined(IPV6_HOPOPTS)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9471,14 +9862,14 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_HOPOPTS, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_HOPOPTS, eVal);
}
#endif
#if defined(IPV6_MTU)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env,
+ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM eVal)
{
@@ -9488,20 +9879,20 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_int_opt(env, descP, level, IPV6_MTU, eVal);
+ return esock_setopt_int_opt(env, descP, level, IPV6_MTU, eVal);
}
#endif
-/* nsetopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option
+/* esock_setopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option
*
* The value is an atom of the type ipv6_pmtudisc().
*/
#if defined(IPV6_MTU_DISCOVER)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
int val;
@@ -9537,9 +9928,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
#if defined(IPV6_MULTICAST_HOPS)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9547,7 +9938,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS, eVal);
+ return esock_setopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS, eVal);
}
#endif
@@ -9555,9 +9946,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
#if defined(IPV6_MULTICAST_IF)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9565,7 +9956,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_int_opt(env, descP, level, IPV6_MULTICAST_IF, eVal);
+ return esock_setopt_int_opt(env, descP, level, IPV6_MULTICAST_IF, eVal);
}
#endif
@@ -9573,9 +9964,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
#if defined(IPV6_MULTICAST_LOOP)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9583,16 +9974,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP, eVal);
}
#endif
#if defined(IPV6_RECVERR)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9600,16 +9991,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_RECVERR, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_RECVERR, eVal);
}
#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9622,16 +10013,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
int opt = IPV6_PKTINFO;
#endif
- return nsetopt_bool_opt(env, descP, level, opt, eVal);
+ return esock_setopt_bool_opt(env, descP, level, opt, eVal);
}
#endif
#if defined(IPV6_ROUTER_ALERT)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9639,7 +10030,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT, eVal);
+ return esock_setopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT, eVal);
}
#endif
@@ -9647,9 +10038,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
#if defined(IPV6_RTHDR)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_rthdr(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9657,16 +10048,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_RTHDR, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_RTHDR, eVal);
}
#endif
#if defined(IPV6_UNICAST_HOPS)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9674,7 +10065,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS, eVal);
+ return esock_setopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS, eVal);
}
#endif
@@ -9682,9 +10073,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
#if defined(IPV6_V6ONLY)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_v6only(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -9692,17 +10083,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return nsetopt_bool_opt(env, descP, level, IPV6_V6ONLY, eVal);
+ return esock_setopt_bool_opt(env, descP, level, IPV6_V6ONLY, eVal);
}
#endif
#if defined(IPV6_ADD_MEMBERSHIP) || defined(IPV6_DROP_MEMBERSHIP)
static
-ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal,
- int opt)
+ERL_NIF_TERM esock_setopt_lvl_ipv6_update_membership(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal,
+ int opt)
{
ERL_NIF_TERM result, eMultiAddr, eInterface;
struct ipv6_mreq mreq;
@@ -9718,7 +10109,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
// It must be a map
if (!IS_MAP(env, eVal)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> "
"value *not* a map\r\n") );
return enif_make_badarg(env);
}
@@ -9726,21 +10117,21 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
// It must have atleast two attributes
if (!enif_get_map_size(env, eVal, &sz) || (sz < 2)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> "
"invalid map value: %T\r\n", eVal) );
return enif_make_badarg(env);
}
if (!GET_MAP_VAL(env, eVal, atom_multiaddr, &eMultiAddr)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> "
"failed get multiaddr (map) attribute\r\n") );
return enif_make_badarg(env);
}
if (!GET_MAP_VAL(env, eVal, atom_interface, &eInterface)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> "
"failed get interface (map) attribute\r\n") );
return enif_make_badarg(env);
}
@@ -9749,14 +10140,14 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
eMultiAddr,
&mreq.ipv6mr_multiaddr)) != NULL) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> "
"failed decode multiaddr %T: %s\r\n", eMultiAddr, xres) );
return esock_make_error_str(env, xres);
}
if (!GET_UINT(env, eInterface, &mreq.ipv6mr_interface)) {
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ip_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ip_update_membership -> "
"failed decode interface %T: %s\r\n", eInterface, xres) );
return esock_make_error(env, esock_atom_einval);
}
@@ -9769,7 +10160,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
result = esock_make_error_errno(env, save_errno);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> "
+ ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> "
"failed setopt: %T (%d)\r\n", result, save_errno) );
} else {
@@ -9786,37 +10177,37 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env,
-/* nsetopt_lvl_tcp - Level *TCP* option(s)
+/* esock_setopt_lvl_tcp - Level *TCP* option(s)
*/
static
-ERL_NIF_TERM nsetopt_lvl_tcp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_tcp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_tcp -> entry with"
+ ("SOCKET", "esock_setopt_lvl_tcp -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(TCP_CONGESTION)
- case SOCKET_OPT_TCP_CONGESTION:
- result = nsetopt_lvl_tcp_congestion(env, descP, eVal);
+ case ESOCK_OPT_TCP_CONGESTION:
+ result = esock_setopt_lvl_tcp_congestion(env, descP, eVal);
break;
#endif
#if defined(TCP_MAXSEG)
- case SOCKET_OPT_TCP_MAXSEG:
- result = nsetopt_lvl_tcp_maxseg(env, descP, eVal);
+ case ESOCK_OPT_TCP_MAXSEG:
+ result = esock_setopt_lvl_tcp_maxseg(env, descP, eVal);
break;
#endif
#if defined(TCP_NODELAY)
- case SOCKET_OPT_TCP_NODELAY:
- result = nsetopt_lvl_tcp_nodelay(env, descP, eVal);
+ case ESOCK_OPT_TCP_NODELAY:
+ result = esock_setopt_lvl_tcp_nodelay(env, descP, eVal);
break;
#endif
@@ -9829,67 +10220,68 @@ ERL_NIF_TERM nsetopt_lvl_tcp(ErlNifEnv* env,
}
-/* nsetopt_lvl_tcp_congestion - Level TCP CONGESTION option
+/* esock_setopt_lvl_tcp_congestion - Level TCP CONGESTION option
*/
#if defined(TCP_CONGESTION)
static
-ERL_NIF_TERM nsetopt_lvl_tcp_congestion(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_tcp_congestion(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- int max = SOCKET_OPT_TCP_CONGESTION_NAME_MAX+1;
+ int max = ESOCK_OPT_TCP_CONGESTION_NAME_MAX+1;
- return nsetopt_str_opt(env, descP, IPPROTO_TCP, TCP_CONGESTION, max, eVal);
+ return esock_setopt_str_opt(env, descP,
+ IPPROTO_TCP, TCP_CONGESTION, max, eVal);
}
#endif
-/* nsetopt_lvl_tcp_maxseg - Level TCP MAXSEG option
+/* esock_setopt_lvl_tcp_maxseg - Level TCP MAXSEG option
*/
#if defined(TCP_MAXSEG)
static
-ERL_NIF_TERM nsetopt_lvl_tcp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_tcp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG, eVal);
+ return esock_setopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG, eVal);
}
#endif
-/* nsetopt_lvl_tcp_nodelay - Level TCP NODELAY option
+/* esock_setopt_lvl_tcp_nodelay - Level TCP NODELAY option
*/
#if defined(TCP_NODELAY)
static
-ERL_NIF_TERM nsetopt_lvl_tcp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_tcp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY, eVal);
+ return esock_setopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY, eVal);
}
#endif
-/* nsetopt_lvl_udp - Level *UDP* option(s)
+/* esock_setopt_lvl_udp - Level *UDP* option(s)
*/
static
-ERL_NIF_TERM nsetopt_lvl_udp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_udp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_udp -> entry with"
+ ("SOCKET", "esock_setopt_lvl_udp -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(UDP_CORK)
- case SOCKET_OPT_UDP_CORK:
- result = nsetopt_lvl_udp_cork(env, descP, eVal);
+ case ESOCK_OPT_UDP_CORK:
+ result = esock_setopt_lvl_udp_cork(env, descP, eVal);
break;
#endif
@@ -9902,83 +10294,83 @@ ERL_NIF_TERM nsetopt_lvl_udp(ErlNifEnv* env,
}
-/* nsetopt_lvl_udp_cork - Level UDP CORK option
+/* esock_setopt_lvl_udp_cork - Level UDP CORK option
*/
#if defined(UDP_CORK)
static
-ERL_NIF_TERM nsetopt_lvl_udp_cork(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_udp_cork(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK, eVal);
+ return esock_setopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK, eVal);
}
#endif
-/* nsetopt_lvl_sctp - Level *SCTP* option(s)
+/* esock_setopt_lvl_sctp - Level *SCTP* option(s)
*/
#if defined(HAVE_SCTP)
static
-ERL_NIF_TERM nsetopt_lvl_sctp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp -> entry with"
+ ("SOCKET", "esock_setopt_lvl_sctp -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(SCTP_ASSOCINFO)
- case SOCKET_OPT_SCTP_ASSOCINFO:
- result = nsetopt_lvl_sctp_associnfo(env, descP, eVal);
+ case ESOCK_OPT_SCTP_ASSOCINFO:
+ result = esock_setopt_lvl_sctp_associnfo(env, descP, eVal);
break;
#endif
#if defined(SCTP_AUTOCLOSE)
- case SOCKET_OPT_SCTP_AUTOCLOSE:
- result = nsetopt_lvl_sctp_autoclose(env, descP, eVal);
+ case ESOCK_OPT_SCTP_AUTOCLOSE:
+ result = esock_setopt_lvl_sctp_autoclose(env, descP, eVal);
break;
#endif
#if defined(SCTP_DISABLE_FRAGMENTS)
- case SOCKET_OPT_SCTP_DISABLE_FRAGMENTS:
- result = nsetopt_lvl_sctp_disable_fragments(env, descP, eVal);
+ case ESOCK_OPT_SCTP_DISABLE_FRAGMENTS:
+ result = esock_setopt_lvl_sctp_disable_fragments(env, descP, eVal);
break;
#endif
#if defined(SCTP_EVENTS)
- case SOCKET_OPT_SCTP_EVENTS:
- result = nsetopt_lvl_sctp_events(env, descP, eVal);
+ case ESOCK_OPT_SCTP_EVENTS:
+ result = esock_setopt_lvl_sctp_events(env, descP, eVal);
break;
#endif
#if defined(SCTP_INITMSG)
- case SOCKET_OPT_SCTP_INITMSG:
- result = nsetopt_lvl_sctp_initmsg(env, descP, eVal);
+ case ESOCK_OPT_SCTP_INITMSG:
+ result = esock_setopt_lvl_sctp_initmsg(env, descP, eVal);
break;
#endif
#if defined(SCTP_MAXSEG)
- case SOCKET_OPT_SCTP_MAXSEG:
- result = nsetopt_lvl_sctp_maxseg(env, descP, eVal);
+ case ESOCK_OPT_SCTP_MAXSEG:
+ result = esock_setopt_lvl_sctp_maxseg(env, descP, eVal);
break;
#endif
#if defined(SCTP_NODELAY)
- case SOCKET_OPT_SCTP_NODELAY:
- result = nsetopt_lvl_sctp_nodelay(env, descP, eVal);
+ case ESOCK_OPT_SCTP_NODELAY:
+ result = esock_setopt_lvl_sctp_nodelay(env, descP, eVal);
break;
#endif
#if defined(SCTP_RTOINFO)
- case SOCKET_OPT_SCTP_RTOINFO:
- result = nsetopt_lvl_sctp_rtoinfo(env, descP, eVal);
+ case ESOCK_OPT_SCTP_RTOINFO:
+ result = esock_setopt_lvl_sctp_rtoinfo(env, descP, eVal);
break;
#endif
@@ -9991,13 +10383,13 @@ ERL_NIF_TERM nsetopt_lvl_sctp(ErlNifEnv* env,
}
-/* nsetopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option
+/* esock_setopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option
*/
#if defined(SCTP_ASSOCINFO)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_associnfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eAssocId, eMaxRxt, eNumPeerDests;
@@ -10008,7 +10400,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
unsigned int tmp;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_associnfo -> entry with"
+ ("SOCKET", "esock_setopt_lvl_sctp_associnfo -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -10021,7 +10413,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_associnfo -> extract attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_associnfo -> extract attributes\r\n") );
if (!GET_MAP_VAL(env, eVal, atom_assoc_id, &eAssocId))
return esock_make_error(env, esock_atom_einval);
@@ -10042,7 +10435,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_associnfo -> decode attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_associnfo -> decode attributes\r\n") );
/* On some platforms the assoc id is typed as an unsigned integer (uint32)
* So, to avoid warnings there, we always make an explicit cast...
@@ -10095,7 +10489,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_associnfo -> set associnfo option\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_associnfo -> set associnfo option\r\n") );
res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_ASSOCINFO,
&assocParams, sizeof(assocParams));
@@ -10106,7 +10501,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
result = esock_atom_ok;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_associnfo -> done with"
+ ("SOCKET", "esock_setopt_lvl_sctp_associnfo -> done with"
"\r\n result: %T"
"\r\n", result) );
@@ -10116,39 +10511,42 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env,
#endif
-/* nsetopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option
+/* esock_setopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option
*/
#if defined(SCTP_AUTOCLOSE)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_autoclose(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_autoclose(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_AUTOCLOSE, eVal);
+ return esock_setopt_int_opt(env, descP,
+ IPPROTO_SCTP, SCTP_AUTOCLOSE, eVal);
}
#endif
-/* nsetopt_lvl_sctp_disable_fragments - Level SCTP DISABLE_FRAGMENTS option
+/* esock_setopt_lvl_sctp_disable_fragments -
+ * Level SCTP DISABLE_FRAGMENTS option
*/
#if defined(SCTP_DISABLE_FRAGMENTS)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, eVal);
+ return esock_setopt_bool_opt(env, descP,
+ IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, eVal);
}
#endif
-/* nsetopt_lvl_sctp_events - Level SCTP EVENTS option
+/* esock_setopt_lvl_sctp_events - Level SCTP EVENTS option
*/
#if defined(SCTP_EVENTS)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_events(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eDataIn, eAssoc, eAddr, eSndFailure;
@@ -10165,7 +10563,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
size_t sz;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_events -> entry with"
+ ("SOCKET", "esock_setopt_lvl_sctp_events -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -10178,7 +10576,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_events -> extract attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_events -> extract attributes\r\n") );
if (!GET_MAP_VAL(env, eVal, atom_data_in, &eDataIn))
return esock_make_error(env, esock_atom_einval);
@@ -10215,7 +10614,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
#endif
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_events -> decode attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_events -> decode attributes\r\n") );
events.sctp_data_io_event = esock_decode_bool(eDataIn);
events.sctp_association_event = esock_decode_bool(eAssoc);
@@ -10233,7 +10633,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
#endif
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_events -> set events option\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_events -> set events option\r\n") );
res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_EVENTS,
&events, sizeof(events));
@@ -10244,7 +10645,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
result = esock_atom_ok;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_events -> done with"
+ ("SOCKET", "esock_setopt_lvl_sctp_events -> done with"
"\r\n result: %T"
"\r\n", result) );
@@ -10254,13 +10655,13 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env,
#endif
-/* nsetopt_lvl_sctp_initmsg - Level SCTP INITMSG option
+/* esock_setopt_lvl_sctp_initmsg - Level SCTP INITMSG option
*/
#if defined(SCTP_INITMSG)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_initmsg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eNumOut, eMaxIn, eMaxAttempts, eMaxInitTO;
@@ -10270,7 +10671,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
unsigned int tmp;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_initmsg -> entry with"
+ ("SOCKET", "esock_setopt_lvl_sctp_initmsg -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -10283,7 +10684,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_initmsg -> extract attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_initmsg -> extract attributes\r\n") );
if (!GET_MAP_VAL(env, eVal, atom_num_outstreams, &eNumOut))
return esock_make_error(env, esock_atom_einval);
@@ -10298,7 +10700,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_initmsg -> decode attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_initmsg -> decode attributes\r\n") );
if (!GET_UINT(env, eNumOut, &tmp))
return esock_make_error(env, esock_atom_einval);
@@ -10317,7 +10720,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
initMsg.sinit_max_init_timeo = (Uint16) tmp;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_initmsg -> set initmsg option\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_initmsg -> set initmsg option\r\n") );
res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_INITMSG,
&initMsg, sizeof(initMsg));
@@ -10328,7 +10732,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
result = esock_atom_ok;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_initmsg -> done with"
+ ("SOCKET", "esock_setopt_lvl_sctp_initmsg -> done with"
"\r\n result: %T"
"\r\n", result) );
@@ -10338,39 +10742,39 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env,
#endif
-/* nsetopt_lvl_sctp_maxseg - Level SCTP MAXSEG option
+/* esock_setopt_lvl_sctp_maxseg - Level SCTP MAXSEG option
*/
#if defined(SCTP_MAXSEG)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG, eVal);
+ return esock_setopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG, eVal);
}
#endif
-/* nsetopt_lvl_sctp_nodelay - Level SCTP NODELAY option
+/* esock_setopt_lvl_sctp_nodelay - Level SCTP NODELAY option
*/
#if defined(SCTP_NODELAY)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
- return nsetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY, eVal);
+ return esock_setopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY, eVal);
}
#endif
-/* nsetopt_lvl_sctp_rtoinfo - Level SCTP RTOINFO option
+/* esock_setopt_lvl_sctp_rtoinfo - Level SCTP RTOINFO option
*/
#if defined(SCTP_RTOINFO)
static
-ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eAssocId, eInitial, eMax, eMin;
@@ -10379,7 +10783,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
size_t sz;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> entry with"
+ ("SOCKET", "esock_setopt_lvl_sctp_rtoinfo -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -10392,7 +10796,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> extract attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_rtoinfo -> extract attributes\r\n") );
if (!GET_MAP_VAL(env, eVal, atom_assoc_id, &eAssocId))
return esock_make_error(env, esock_atom_einval);
@@ -10407,7 +10812,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> decode attributes\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_rtoinfo -> decode attributes\r\n") );
/* On some platforms the assoc id is typed as an unsigned integer (uint32)
* So, to avoid warnings there, we always make an explicit cast...
@@ -10442,7 +10848,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
return esock_make_error(env, esock_atom_einval);
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> set associnfo option\r\n") );
+ ("SOCKET",
+ "esock_setopt_lvl_sctp_rtoinfo -> set associnfo option\r\n") );
res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoInfo, sizeof(rtoInfo));
@@ -10453,7 +10860,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
result = esock_atom_ok;
SSDBG( descP,
- ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> done with"
+ ("SOCKET", "esock_setopt_lvl_sctp_rtoinfo -> done with"
"\r\n result: %T"
"\r\n", result) );
@@ -10469,14 +10876,14 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
-/* nsetopt_bool_opt - set an option that has an (integer) bool value
+/* esock_setopt_bool_opt - set an option that has an (integer) bool value
*/
static
-ERL_NIF_TERM nsetopt_bool_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_bool_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
BOOLEAN_T val;
@@ -10496,14 +10903,14 @@ ERL_NIF_TERM nsetopt_bool_opt(ErlNifEnv* env,
}
-/* nsetopt_int_opt - set an option that has an integer value
+/* esock_setopt_int_opt - set an option that has an integer value
*/
static
-ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_int_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
int val;
@@ -10513,7 +10920,7 @@ ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env,
/*
SSDBG( descP,
- ("SOCKET", "nsetopt_int_opt -> set option"
+ ("SOCKET", "esock_setopt_int_opt -> set option"
"\r\n opt: %d"
"\r\n val: %d"
"\r\n", opt, val) );
@@ -10534,16 +10941,16 @@ ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env,
}
-/* nsetopt_str_opt - set an option that has an string value
+/* esock_setopt_str_opt - set an option that has an string value
*/
#if defined(USE_SETOPT_STR_OPT)
static
-ERL_NIF_TERM nsetopt_str_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- int max,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_str_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ int max,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
char* val = MALLOC(max);
@@ -10568,14 +10975,14 @@ ERL_NIF_TERM nsetopt_str_opt(ErlNifEnv* env,
#endif
-/* nsetopt_timeval_opt - set an option that has an (timeval) bool value
+/* esock_setopt_timeval_opt - set an option that has an (timeval) bool value
*/
static
-ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- ERL_NIF_TERM eVal)
+ERL_NIF_TERM esock_setopt_timeval_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ ERL_NIF_TERM eVal)
{
ERL_NIF_TERM result;
struct timeval timeVal;
@@ -10583,7 +10990,7 @@ ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env,
char* xres;
SSDBG( descP,
- ("SOCKET", "nsetopt_timeval_opt -> entry with"
+ ("SOCKET", "esock_setopt_timeval_opt -> entry with"
"\r\n eVal: %T"
"\r\n", eVal) );
@@ -10591,7 +10998,7 @@ ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env,
return esock_make_error_str(env, xres);
SSDBG( descP,
- ("SOCKET", "nsetopt_timeval_opt -> set timeval option\r\n") );
+ ("SOCKET", "esock_setopt_timeval_opt -> set timeval option\r\n") );
res = socket_setopt(descP->sock, level, opt, &timeVal, sizeof(timeVal));
@@ -10601,7 +11008,7 @@ ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env,
result = esock_atom_ok;
SSDBG( descP,
- ("SOCKET", "nsetopt_timeval_opt -> done with"
+ ("SOCKET", "esock_setopt_timeval_opt -> done with"
"\r\n result: %T"
"\r\n", result) );
@@ -10621,19 +11028,19 @@ BOOLEAN_T elevel2level(BOOLEAN_T isEncoded,
if (isEncoded) {
switch (eLevel) {
- case SOCKET_OPT_LEVEL_OTP:
+ case ESOCK_OPT_LEVEL_OTP:
*isOTP = TRUE;
*level = -1;
result = TRUE;
break;
- case SOCKET_OPT_LEVEL_SOCKET:
+ case ESOCK_OPT_LEVEL_SOCKET:
*isOTP = FALSE;
*level = SOL_SOCKET;
result = TRUE;
break;
- case SOCKET_OPT_LEVEL_IP:
+ case ESOCK_OPT_LEVEL_IP:
*isOTP = FALSE;
#if defined(SOL_IP)
*level = SOL_IP;
@@ -10644,7 +11051,7 @@ BOOLEAN_T elevel2level(BOOLEAN_T isEncoded,
break;
#if defined(HAVE_IPV6)
- case SOCKET_OPT_LEVEL_IPV6:
+ case ESOCK_OPT_LEVEL_IPV6:
*isOTP = FALSE;
#if defined(SOL_IPV6)
*level = SOL_IPV6;
@@ -10655,20 +11062,20 @@ BOOLEAN_T elevel2level(BOOLEAN_T isEncoded,
break;
#endif
- case SOCKET_OPT_LEVEL_TCP:
+ case ESOCK_OPT_LEVEL_TCP:
*isOTP = FALSE;
*level = IPPROTO_TCP;
result = TRUE;
break;
- case SOCKET_OPT_LEVEL_UDP:
+ case ESOCK_OPT_LEVEL_UDP:
*isOTP = FALSE;
*level = IPPROTO_UDP;
result = TRUE;
break;
#ifdef HAVE_SCTP
- case SOCKET_OPT_LEVEL_SCTP:
+ case ESOCK_OPT_LEVEL_SCTP:
*isOTP = FALSE;
*level = IPPROTO_SCTP;
result = TRUE;
@@ -10813,7 +11220,7 @@ ERL_NIF_TERM nif_getopt(ErlNifEnv* env,
SGDBG( ("SOCKET", "nif_getopt -> entry with argc: %d\r\n", argc) );
if ((argc != 4) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP) ||
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) ||
!GET_INT(env, argv[2], &eLevel)) {
SGDBG( ("SOCKET", "nif_getopt -> failed processing args\r\n") );
return enif_make_badarg(env);
@@ -10839,7 +11246,7 @@ ERL_NIF_TERM nif_getopt(ErlNifEnv* env,
MLOCK(descP->cfgMtx);
- result = ngetopt(env, descP, isEncoded, isOTP, level, eOpt);
+ result = esock_getopt(env, descP, isEncoded, isOTP, level, eOpt);
MUNLOCK(descP->cfgMtx);
@@ -10852,18 +11259,18 @@ ERL_NIF_TERM nif_getopt(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM ngetopt(ErlNifEnv* env,
- ESockDescriptor* descP,
- BOOLEAN_T isEncoded,
- BOOLEAN_T isOTP,
- int level,
- ERL_NIF_TERM eOpt)
+ERL_NIF_TERM esock_getopt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ BOOLEAN_T isEncoded,
+ BOOLEAN_T isOTP,
+ int level,
+ ERL_NIF_TERM eOpt)
{
ERL_NIF_TERM result;
int opt;
SSDBG( descP,
- ("SOCKET", "ngetopt -> entry with"
+ ("SOCKET", "esock_getopt -> entry with"
"\r\n isEncoded: %s"
"\r\n isOTP: %s"
"\r\n level: %d"
@@ -10875,20 +11282,20 @@ ERL_NIF_TERM ngetopt(ErlNifEnv* env,
* but options for our implementation.
*/
if (GET_INT(env, eOpt, &opt))
- result = ngetopt_otp(env, descP, opt);
+ result = esock_getopt_otp(env, descP, opt);
else
result = esock_make_error(env, esock_atom_einval);
} else if (!isEncoded) {
- result = ngetopt_native(env, descP, level, eOpt);
+ result = esock_getopt_native(env, descP, level, eOpt);
} else {
if (GET_INT(env, eOpt, &opt))
- result = ngetopt_level(env, descP, level, opt);
+ result = esock_getopt_level(env, descP, level, opt);
else
result = esock_make_error(env, esock_atom_einval);
}
SSDBG( descP,
- ("SOCKET", "ngetopt -> done when"
+ ("SOCKET", "esock_getopt -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -10897,60 +11304,60 @@ ERL_NIF_TERM ngetopt(ErlNifEnv* env,
-/* ngetopt_otp - Handle OTP (level) options
+/* esock_getopt_otp - Handle OTP (level) options
*/
static
-ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_otp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "ngetopt_otp -> entry with"
+ ("SOCKET", "esock_getopt_otp -> entry with"
"\r\n eOpt: %d"
"\r\n", eOpt) );
switch (eOpt) {
- case SOCKET_OPT_OTP_DEBUG:
- result = ngetopt_otp_debug(env, descP);
+ case ESOCK_OPT_OTP_DEBUG:
+ result = esock_getopt_otp_debug(env, descP);
break;
- case SOCKET_OPT_OTP_IOW:
- result = ngetopt_otp_iow(env, descP);
+ case ESOCK_OPT_OTP_IOW:
+ result = esock_getopt_otp_iow(env, descP);
break;
- case SOCKET_OPT_OTP_CTRL_PROC:
- result = ngetopt_otp_ctrl_proc(env, descP);
+ case ESOCK_OPT_OTP_CTRL_PROC:
+ result = esock_getopt_otp_ctrl_proc(env, descP);
break;
- case SOCKET_OPT_OTP_RCVBUF:
- result = ngetopt_otp_rcvbuf(env, descP);
+ case ESOCK_OPT_OTP_RCVBUF:
+ result = esock_getopt_otp_rcvbuf(env, descP);
break;
- case SOCKET_OPT_OTP_RCVCTRLBUF:
- result = ngetopt_otp_rcvctrlbuf(env, descP);
+ case ESOCK_OPT_OTP_RCVCTRLBUF:
+ result = esock_getopt_otp_rcvctrlbuf(env, descP);
break;
- case SOCKET_OPT_OTP_SNDCTRLBUF:
- result = ngetopt_otp_sndctrlbuf(env, descP);
+ case ESOCK_OPT_OTP_SNDCTRLBUF:
+ result = esock_getopt_otp_sndctrlbuf(env, descP);
break;
- case SOCKET_OPT_OTP_FD:
- result = ngetopt_otp_fd(env, descP);
+ case ESOCK_OPT_OTP_FD:
+ result = esock_getopt_otp_fd(env, descP);
break;
/* *** INTERNAL *** */
- case SOCKET_OPT_OTP_DOMAIN:
- result = ngetopt_otp_domain(env, descP);
+ case ESOCK_OPT_OTP_DOMAIN:
+ result = esock_getopt_otp_domain(env, descP);
break;
- case SOCKET_OPT_OTP_TYPE:
- result = ngetopt_otp_type(env, descP);
+ case ESOCK_OPT_OTP_TYPE:
+ result = esock_getopt_otp_type(env, descP);
break;
- case SOCKET_OPT_OTP_PROTOCOL:
- result = ngetopt_otp_protocol(env, descP);
+ case ESOCK_OPT_OTP_PROTOCOL:
+ result = esock_getopt_otp_protocol(env, descP);
break;
default:
@@ -10959,7 +11366,7 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_otp -> done when"
+ ("SOCKET", "esock_getopt_otp -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -10967,11 +11374,11 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env,
}
-/* ngetopt_otp_debug - Handle the OTP (level) debug option
+/* esock_getopt_otp_debug - Handle the OTP (level) debug option
*/
static
-ERL_NIF_TERM ngetopt_otp_debug(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_debug(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal = esock_encode_bool(descP->dbg);
@@ -10979,11 +11386,11 @@ ERL_NIF_TERM ngetopt_otp_debug(ErlNifEnv* env,
}
-/* ngetopt_otp_iow - Handle the OTP (level) iow option
+/* esock_getopt_otp_iow - Handle the OTP (level) iow option
*/
static
-ERL_NIF_TERM ngetopt_otp_iow(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_iow(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal = esock_encode_bool(descP->iow);
@@ -10991,11 +11398,11 @@ ERL_NIF_TERM ngetopt_otp_iow(ErlNifEnv* env,
}
-/* ngetopt_otp_ctrl_proc - Handle the OTP (level) controlling_process option
+/* esock_getopt_otp_ctrl_proc - Handle the OTP (level) controlling_process option
*/
static
-ERL_NIF_TERM ngetopt_otp_ctrl_proc(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_ctrl_proc(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal = MKPID(env, &descP->ctrlPid);
@@ -11004,11 +11411,11 @@ ERL_NIF_TERM ngetopt_otp_ctrl_proc(ErlNifEnv* env,
-/* ngetopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option
+/* esock_getopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option
*/
static
-ERL_NIF_TERM ngetopt_otp_rcvbuf(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_rcvbuf(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal;
@@ -11022,11 +11429,11 @@ ERL_NIF_TERM ngetopt_otp_rcvbuf(ErlNifEnv* env,
}
-/* ngetopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option
+/* esock_getopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option
*/
static
-ERL_NIF_TERM ngetopt_otp_rcvctrlbuf(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_rcvctrlbuf(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal = MKI(env, descP->rCtrlSz);
@@ -11034,11 +11441,11 @@ ERL_NIF_TERM ngetopt_otp_rcvctrlbuf(ErlNifEnv* env,
}
-/* ngetopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option
+/* esock_getopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option
*/
static
-ERL_NIF_TERM ngetopt_otp_sndctrlbuf(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_sndctrlbuf(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal = MKI(env, descP->wCtrlSz);
@@ -11046,11 +11453,11 @@ ERL_NIF_TERM ngetopt_otp_sndctrlbuf(ErlNifEnv* env,
}
-/* ngetopt_otp_fd - Handle the OTP (level) fd option
+/* esock_getopt_otp_fd - Handle the OTP (level) fd option
*/
static
-ERL_NIF_TERM ngetopt_otp_fd(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_fd(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM eVal = MKI(env, descP->sock);
@@ -11058,11 +11465,11 @@ ERL_NIF_TERM ngetopt_otp_fd(ErlNifEnv* env,
}
-/* ngetopt_otp_domain - Handle the OTP (level) domain option
+/* esock_getopt_otp_domain - Handle the OTP (level) domain option
*/
static
-ERL_NIF_TERM ngetopt_otp_domain(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_domain(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result, reason;
int val = descP->domain;
@@ -11094,11 +11501,11 @@ ERL_NIF_TERM ngetopt_otp_domain(ErlNifEnv* env,
}
-/* ngetopt_otp_type - Handle the OTP (level) type options.
+/* esock_getopt_otp_type - Handle the OTP (level) type options.
*/
static
-ERL_NIF_TERM ngetopt_otp_type(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_type(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result, reason;
int val = descP->type;
@@ -11135,11 +11542,11 @@ ERL_NIF_TERM ngetopt_otp_type(ErlNifEnv* env,
}
-/* ngetopt_otp_protocol - Handle the OTP (level) protocol options.
+/* esock_getopt_otp_protocol - Handle the OTP (level) protocol options.
*/
static
-ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_otp_protocol(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result, reason;
int val = descP->protocol;
@@ -11187,10 +11594,10 @@ ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env,
* format: {NativeOpt :: integer(), ValueSize :: non_neg_integer()}
*/
static
-ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- ERL_NIF_TERM eOpt)
+ERL_NIF_TERM esock_getopt_native(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ ERL_NIF_TERM eOpt)
{
ERL_NIF_TERM result = enif_make_badarg(env);
int opt;
@@ -11198,7 +11605,7 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
SOCKOPTLEN_T valueSz;
SSDBG( descP,
- ("SOCKET", "ngetopt_native -> entry with"
+ ("SOCKET", "esock_getopt_native -> entry with"
"\r\n level: %d"
"\r\n eOpt: %T"
"\r\n", level, eOpt) );
@@ -11212,20 +11619,21 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
if (decode_native_get_opt(env, eOpt, &opt, &valueType, (int*) &valueSz)) {
SSDBG( descP,
- ("SOCKET", "ngetopt_native -> decoded opt"
+ ("SOCKET", "esock_getopt_native -> decoded opt"
"\r\n valueType: %d (%s)"
"\r\n ValueSize: %d"
"\r\n", valueType, VT2S(valueType), valueSz) );
switch (valueType) {
- case SOCKET_OPT_VALUE_TYPE_UNSPEC:
- result = ngetopt_native_unspec(env, descP, level, opt, valueSz);
+ case ESOCK_OPT_VALUE_TYPE_UNSPEC:
+ result = esock_getopt_native_unspec(env, descP,
+ level, opt, valueSz);
break;
- case SOCKET_OPT_VALUE_TYPE_INT:
- result = ngetopt_int_opt(env, descP, level, opt);
+ case ESOCK_OPT_VALUE_TYPE_INT:
+ result = esock_getopt_int_opt(env, descP, level, opt);
break;
- case SOCKET_OPT_VALUE_TYPE_BOOL:
- result = ngetopt_bool_opt(env, descP, level, opt);
+ case ESOCK_OPT_VALUE_TYPE_BOOL:
+ result = esock_getopt_bool_opt(env, descP, level, opt);
break;
default:
result = esock_make_error(env, esock_atom_einval);
@@ -11236,7 +11644,7 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_native -> done when"
+ ("SOCKET", "esock_getopt_native -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -11245,17 +11653,17 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
static
-ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- SOCKOPTLEN_T valueSz)
+ERL_NIF_TERM esock_getopt_native_unspec(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ SOCKOPTLEN_T valueSz)
{
ERL_NIF_TERM result = esock_make_error(env, esock_atom_einval);
int res;
SSDBG( descP,
- ("SOCKET", "ngetopt_native_unspec -> entry with"
+ ("SOCKET", "esock_getopt_native_unspec -> entry with"
"\r\n level: %d"
"\r\n opt: %d"
"\r\n valueSz: %d"
@@ -11271,7 +11679,8 @@ ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env,
SOCKOPTLEN_T vsz = valueSz;
ErlNifBinary val;
- SSDBG( descP, ("SOCKET", "ngetopt_native_unspec -> try alloc buffer\r\n") );
+ SSDBG( descP, ("SOCKET",
+ "esock_getopt_native_unspec -> try alloc buffer\r\n") );
if (ALLOC_BIN(vsz, &val)) {
int saveErrno;
@@ -11303,7 +11712,7 @@ ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_native_unspec -> done when"
+ ("SOCKET", "esock_getopt_native_unspec -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -11312,25 +11721,25 @@ ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env,
-/* ngetopt_level - A "proper" level (option) has been specified
+/* esock_getopt_level - A "proper" level (option) has been specified
*/
static
-ERL_NIF_TERM ngetopt_level(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int eOpt)
+ERL_NIF_TERM esock_getopt_level(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int eOpt)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "ngetopt_level -> entry with"
+ ("SOCKET", "esock_getopt_level -> entry with"
"\r\n level: %d"
"\r\n eOpt: %d"
"\r\n", level, eOpt) );
switch (level) {
case SOL_SOCKET:
- result = ngetopt_lvl_socket(env, descP, eOpt);
+ result = esock_getopt_lvl_socket(env, descP, eOpt);
break;
#if defined(SOL_IP)
@@ -11338,7 +11747,7 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env,
#else
case IPPROTO_IP:
#endif
- result = ngetopt_lvl_ip(env, descP, eOpt);
+ result = esock_getopt_lvl_ip(env, descP, eOpt);
break;
#if defined(HAVE_IPV6)
@@ -11347,21 +11756,21 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env,
#else
case IPPROTO_IPV6:
#endif
- result = ngetopt_lvl_ipv6(env, descP, eOpt);
+ result = esock_getopt_lvl_ipv6(env, descP, eOpt);
break;
#endif
case IPPROTO_TCP:
- result = ngetopt_lvl_tcp(env, descP, eOpt);
+ result = esock_getopt_lvl_tcp(env, descP, eOpt);
break;
case IPPROTO_UDP:
- result = ngetopt_lvl_udp(env, descP, eOpt);
+ result = esock_getopt_lvl_udp(env, descP, eOpt);
break;
#if defined(HAVE_SCTP)
case IPPROTO_SCTP:
- result = ngetopt_lvl_sctp(env, descP, eOpt);
+ result = esock_getopt_lvl_sctp(env, descP, eOpt);
break;
#endif
@@ -11371,7 +11780,7 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_level -> done when"
+ ("SOCKET", "esock_getopt_level -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -11379,150 +11788,150 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env,
}
-/* ngetopt_lvl_socket - Level *SOCKET* option
+/* esock_getopt_lvl_socket - Level *SOCKET* option
*/
static
-ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_lvl_socket(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_socket -> entry with"
+ ("SOCKET", "esock_getopt_lvl_socket -> entry with"
"\r\n eOpt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(SO_ACCEPTCONN)
- case SOCKET_OPT_SOCK_ACCEPTCONN:
- result = ngetopt_lvl_sock_acceptconn(env, descP);
+ case ESOCK_OPT_SOCK_ACCEPTCONN:
+ result = esock_getopt_lvl_sock_acceptconn(env, descP);
break;
#endif
#if defined(SO_BINDTODEVICE)
- case SOCKET_OPT_SOCK_BINDTODEVICE:
- result = ngetopt_lvl_sock_bindtodevice(env, descP);
+ case ESOCK_OPT_SOCK_BINDTODEVICE:
+ result = esock_getopt_lvl_sock_bindtodevice(env, descP);
break;
#endif
#if defined(SO_BROADCAST)
- case SOCKET_OPT_SOCK_BROADCAST:
- result = ngetopt_lvl_sock_broadcast(env, descP);
+ case ESOCK_OPT_SOCK_BROADCAST:
+ result = esock_getopt_lvl_sock_broadcast(env, descP);
break;
#endif
#if defined(SO_DEBUG)
- case SOCKET_OPT_SOCK_DEBUG:
- result = ngetopt_lvl_sock_debug(env, descP);
+ case ESOCK_OPT_SOCK_DEBUG:
+ result = esock_getopt_lvl_sock_debug(env, descP);
break;
#endif
#if defined(SO_DOMAIN)
- case SOCKET_OPT_SOCK_DOMAIN:
- result = ngetopt_lvl_sock_domain(env, descP);
+ case ESOCK_OPT_SOCK_DOMAIN:
+ result = esock_getopt_lvl_sock_domain(env, descP);
break;
#endif
#if defined(SO_DONTROUTE)
- case SOCKET_OPT_SOCK_DONTROUTE:
- result = ngetopt_lvl_sock_dontroute(env, descP);
+ case ESOCK_OPT_SOCK_DONTROUTE:
+ result = esock_getopt_lvl_sock_dontroute(env, descP);
break;
#endif
#if defined(SO_KEEPALIVE)
- case SOCKET_OPT_SOCK_KEEPALIVE:
- result = ngetopt_lvl_sock_keepalive(env, descP);
+ case ESOCK_OPT_SOCK_KEEPALIVE:
+ result = esock_getopt_lvl_sock_keepalive(env, descP);
break;
#endif
#if defined(SO_LINGER)
- case SOCKET_OPT_SOCK_LINGER:
- result = ngetopt_lvl_sock_linger(env, descP);
+ case ESOCK_OPT_SOCK_LINGER:
+ result = esock_getopt_lvl_sock_linger(env, descP);
break;
#endif
#if defined(SO_OOBINLINE)
- case SOCKET_OPT_SOCK_OOBINLINE:
- result = ngetopt_lvl_sock_oobinline(env, descP);
+ case ESOCK_OPT_SOCK_OOBINLINE:
+ result = esock_getopt_lvl_sock_oobinline(env, descP);
break;
#endif
#if defined(SO_PEEK_OFF)
- case SOCKET_OPT_SOCK_PEEK_OFF:
- result = ngetopt_lvl_sock_peek_off(env, descP);
+ case ESOCK_OPT_SOCK_PEEK_OFF:
+ result = esock_getopt_lvl_sock_peek_off(env, descP);
break;
#endif
#if defined(SO_PRIORITY)
- case SOCKET_OPT_SOCK_PRIORITY:
- result = ngetopt_lvl_sock_priority(env, descP);
+ case ESOCK_OPT_SOCK_PRIORITY:
+ result = esock_getopt_lvl_sock_priority(env, descP);
break;
#endif
#if defined(SO_PROTOCOL)
- case SOCKET_OPT_SOCK_PROTOCOL:
- result = ngetopt_lvl_sock_protocol(env, descP);
+ case ESOCK_OPT_SOCK_PROTOCOL:
+ result = esock_getopt_lvl_sock_protocol(env, descP);
break;
#endif
#if defined(SO_RCVBUF)
- case SOCKET_OPT_SOCK_RCVBUF:
- result = ngetopt_lvl_sock_rcvbuf(env, descP);
+ case ESOCK_OPT_SOCK_RCVBUF:
+ result = esock_getopt_lvl_sock_rcvbuf(env, descP);
break;
#endif
#if defined(SO_RCVLOWAT)
- case SOCKET_OPT_SOCK_RCVLOWAT:
- result = ngetopt_lvl_sock_rcvlowat(env, descP);
+ case ESOCK_OPT_SOCK_RCVLOWAT:
+ result = esock_getopt_lvl_sock_rcvlowat(env, descP);
break;
#endif
#if defined(SO_RCVTIMEO)
- case SOCKET_OPT_SOCK_RCVTIMEO:
- result = ngetopt_lvl_sock_rcvtimeo(env, descP);
+ case ESOCK_OPT_SOCK_RCVTIMEO:
+ result = esock_getopt_lvl_sock_rcvtimeo(env, descP);
break;
#endif
#if defined(SO_REUSEADDR)
- case SOCKET_OPT_SOCK_REUSEADDR:
- result = ngetopt_lvl_sock_reuseaddr(env, descP);
+ case ESOCK_OPT_SOCK_REUSEADDR:
+ result = esock_getopt_lvl_sock_reuseaddr(env, descP);
break;
#endif
#if defined(SO_REUSEPORT)
- case SOCKET_OPT_SOCK_REUSEPORT:
- result = ngetopt_lvl_sock_reuseport(env, descP);
+ case ESOCK_OPT_SOCK_REUSEPORT:
+ result = esock_getopt_lvl_sock_reuseport(env, descP);
break;
#endif
#if defined(SO_SNDBUF)
- case SOCKET_OPT_SOCK_SNDBUF:
- result = ngetopt_lvl_sock_sndbuf(env, descP);
+ case ESOCK_OPT_SOCK_SNDBUF:
+ result = esock_getopt_lvl_sock_sndbuf(env, descP);
break;
#endif
#if defined(SO_SNDLOWAT)
- case SOCKET_OPT_SOCK_SNDLOWAT:
- result = ngetopt_lvl_sock_sndlowat(env, descP);
+ case ESOCK_OPT_SOCK_SNDLOWAT:
+ result = esock_getopt_lvl_sock_sndlowat(env, descP);
break;
#endif
#if defined(SO_SNDTIMEO)
- case SOCKET_OPT_SOCK_SNDTIMEO:
- result = ngetopt_lvl_sock_sndtimeo(env, descP);
+ case ESOCK_OPT_SOCK_SNDTIMEO:
+ result = esock_getopt_lvl_sock_sndtimeo(env, descP);
break;
#endif
#if defined(SO_TIMESTAMP)
- case SOCKET_OPT_SOCK_TIMESTAMP:
- result = ngetopt_lvl_sock_timestamp(env, descP);
+ case ESOCK_OPT_SOCK_TIMESTAMP:
+ result = esock_getopt_lvl_sock_timestamp(env, descP);
break;
#endif
#if defined(SO_TYPE)
- case SOCKET_OPT_SOCK_TYPE:
- result = ngetopt_lvl_sock_type(env, descP);
+ case ESOCK_OPT_SOCK_TYPE:
+ result = esock_getopt_lvl_sock_type(env, descP);
break;
#endif
@@ -11532,7 +11941,7 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_socket -> done when"
+ ("SOCKET", "esock_getopt_lvl_socket -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -11542,51 +11951,52 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
#if defined(SO_ACCEPTCONN)
static
-ERL_NIF_TERM ngetopt_lvl_sock_acceptconn(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_acceptconn(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_ACCEPTCONN);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_ACCEPTCONN);
}
#endif
#if defined(SO_BINDTODEVICE)
static
-ERL_NIF_TERM ngetopt_lvl_sock_bindtodevice(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_bindtodevice(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_sock_bindtodevice -> entry with\r\n") );
+ ("SOCKET", "esock_getopt_lvl_sock_bindtodevice -> entry with\r\n") );
- return ngetopt_str_opt(env, descP, SOL_SOCKET, SO_BROADCAST, IFNAMSIZ+1);
+ return esock_getopt_str_opt(env, descP,
+ SOL_SOCKET, SO_BINDTODEVICE, IFNAMSIZ+1);
}
#endif
#if defined(SO_BROADCAST)
static
-ERL_NIF_TERM ngetopt_lvl_sock_broadcast(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_broadcast(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST);
}
#endif
#if defined(SO_DEBUG)
static
-ERL_NIF_TERM ngetopt_lvl_sock_debug(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_debug(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG);
}
#endif
#if defined(SO_DOMAIN)
static
-ERL_NIF_TERM ngetopt_lvl_sock_domain(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_domain(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result, reason;
int val;
@@ -11630,28 +12040,28 @@ ERL_NIF_TERM ngetopt_lvl_sock_domain(ErlNifEnv* env,
#if defined(SO_DONTROUTE)
static
-ERL_NIF_TERM ngetopt_lvl_sock_dontroute(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_dontroute(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE);
}
#endif
#if defined(SO_KEEPALIVE)
static
-ERL_NIF_TERM ngetopt_lvl_sock_keepalive(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_keepalive(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE);
}
#endif
#if defined(SO_LINGER)
static
-ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_linger(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
struct linger val;
@@ -11680,38 +12090,38 @@ ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env,
#if defined(SO_OOBINLINE)
static
-ERL_NIF_TERM ngetopt_lvl_sock_oobinline(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_oobinline(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE);
}
#endif
#if defined(SO_PEEK_OFF)
static
-ERL_NIF_TERM ngetopt_lvl_sock_peek_off(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_peek_off(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF);
}
#endif
#if defined(SO_PRIORITY)
static
-ERL_NIF_TERM ngetopt_lvl_sock_priority(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_priority(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY);
}
#endif
#if defined(SO_PROTOCOL)
static
-ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_protocol(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result, reason;
int val;
@@ -11764,98 +12174,98 @@ ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env,
#if defined(SO_RCVBUF)
static
-ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_rcvbuf(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF);
}
#endif
#if defined(SO_RCVLOWAT)
static
-ERL_NIF_TERM ngetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT);
}
#endif
#if defined(SO_RCVTIMEO)
static
-ERL_NIF_TERM ngetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO);
+ return esock_getopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO);
}
#endif
#if defined(SO_REUSEADDR)
static
-ERL_NIF_TERM ngetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_reuseaddr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR);
}
#endif
#if defined(SO_REUSEPORT)
static
-ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_reuseport(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT);
}
#endif
#if defined(SO_SNDBUF)
static
-ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_sndbuf(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF);
}
#endif
#if defined(SO_SNDLOWAT)
static
-ERL_NIF_TERM ngetopt_lvl_sock_sndlowat(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT);
+ return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT);
}
#endif
#if defined(SO_SNDTIMEO)
static
-ERL_NIF_TERM ngetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_sndtimeo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO);
+ return esock_getopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO);
}
#endif
#if defined(SO_TIMESTAMP)
static
-ERL_NIF_TERM ngetopt_lvl_sock_timestamp(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_timestamp(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP);
+ return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP);
}
#endif
#if defined(SO_TYPE)
static
-ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sock_type(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result, reason;
int val;
@@ -11897,174 +12307,174 @@ ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_ip - Level *IP* option(s)
+/* esock_getopt_lvl_ip - Level *IP* option(s)
*/
static
-ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_lvl_ip(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_ip -> entry with"
+ ("SOCKET", "esock_getopt_lvl_ip -> entry with"
"\r\n eOpt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(IP_FREEBIND)
- case SOCKET_OPT_IP_FREEBIND:
- result = ngetopt_lvl_ip_freebind(env, descP);
+ case ESOCK_OPT_IP_FREEBIND:
+ result = esock_getopt_lvl_ip_freebind(env, descP);
break;
#endif
#if defined(IP_HDRINCL)
- case SOCKET_OPT_IP_HDRINCL:
- result = ngetopt_lvl_ip_hdrincl(env, descP);
+ case ESOCK_OPT_IP_HDRINCL:
+ result = esock_getopt_lvl_ip_hdrincl(env, descP);
break;
#endif
#if defined(IP_MINTTL)
- case SOCKET_OPT_IP_MINTTL:
- result = ngetopt_lvl_ip_minttl(env, descP);
+ case ESOCK_OPT_IP_MINTTL:
+ result = esock_getopt_lvl_ip_minttl(env, descP);
break;
#endif
#if defined(IP_MTU)
- case SOCKET_OPT_IP_MTU:
- result = ngetopt_lvl_ip_mtu(env, descP);
+ case ESOCK_OPT_IP_MTU:
+ result = esock_getopt_lvl_ip_mtu(env, descP);
break;
#endif
#if defined(IP_MTU_DISCOVER)
- case SOCKET_OPT_IP_MTU_DISCOVER:
- result = ngetopt_lvl_ip_mtu_discover(env, descP);
+ case ESOCK_OPT_IP_MTU_DISCOVER:
+ result = esock_getopt_lvl_ip_mtu_discover(env, descP);
break;
#endif
#if defined(IP_MULTICAST_ALL)
- case SOCKET_OPT_IP_MULTICAST_ALL:
- result = ngetopt_lvl_ip_multicast_all(env, descP);
+ case ESOCK_OPT_IP_MULTICAST_ALL:
+ result = esock_getopt_lvl_ip_multicast_all(env, descP);
break;
#endif
#if defined(IP_MULTICAST_IF)
- case SOCKET_OPT_IP_MULTICAST_IF:
- result = ngetopt_lvl_ip_multicast_if(env, descP);
+ case ESOCK_OPT_IP_MULTICAST_IF:
+ result = esock_getopt_lvl_ip_multicast_if(env, descP);
break;
#endif
#if defined(IP_MULTICAST_LOOP)
- case SOCKET_OPT_IP_MULTICAST_LOOP:
- result = ngetopt_lvl_ip_multicast_loop(env, descP);
+ case ESOCK_OPT_IP_MULTICAST_LOOP:
+ result = esock_getopt_lvl_ip_multicast_loop(env, descP);
break;
#endif
#if defined(IP_MULTICAST_TTL)
- case SOCKET_OPT_IP_MULTICAST_TTL:
- result = ngetopt_lvl_ip_multicast_ttl(env, descP);
+ case ESOCK_OPT_IP_MULTICAST_TTL:
+ result = esock_getopt_lvl_ip_multicast_ttl(env, descP);
break;
#endif
#if defined(IP_NODEFRAG)
- case SOCKET_OPT_IP_NODEFRAG:
- result = ngetopt_lvl_ip_nodefrag(env, descP);
+ case ESOCK_OPT_IP_NODEFRAG:
+ result = esock_getopt_lvl_ip_nodefrag(env, descP);
break;
#endif
#if defined(IP_PKTINFO)
- case SOCKET_OPT_IP_PKTINFO:
- result = ngetopt_lvl_ip_pktinfo(env, descP);
+ case ESOCK_OPT_IP_PKTINFO:
+ result = esock_getopt_lvl_ip_pktinfo(env, descP);
break;
#endif
#if defined(IP_RECVDSTADDR)
- case SOCKET_OPT_IP_RECVDSTADDR:
- result = ngetopt_lvl_ip_recvdstaddr(env, descP);
+ case ESOCK_OPT_IP_RECVDSTADDR:
+ result = esock_getopt_lvl_ip_recvdstaddr(env, descP);
break;
#endif
#if defined(IP_RECVERR)
- case SOCKET_OPT_IP_RECVERR:
- result = ngetopt_lvl_ip_recverr(env, descP);
+ case ESOCK_OPT_IP_RECVERR:
+ result = esock_getopt_lvl_ip_recverr(env, descP);
break;
#endif
#if defined(IP_RECVIF)
- case SOCKET_OPT_IP_RECVIF:
- result = ngetopt_lvl_ip_recvif(env, descP);
+ case ESOCK_OPT_IP_RECVIF:
+ result = esock_getopt_lvl_ip_recvif(env, descP);
break;
#endif
#if defined(IP_RECVOPTS)
- case SOCKET_OPT_IP_RECVOPTS:
- result = ngetopt_lvl_ip_recvopts(env, descP);
+ case ESOCK_OPT_IP_RECVOPTS:
+ result = esock_getopt_lvl_ip_recvopts(env, descP);
break;
#endif
#if defined(IP_RECVORIGDSTADDR)
- case SOCKET_OPT_IP_RECVORIGDSTADDR:
- result = ngetopt_lvl_ip_recvorigdstaddr(env, descP);
+ case ESOCK_OPT_IP_RECVORIGDSTADDR:
+ result = esock_getopt_lvl_ip_recvorigdstaddr(env, descP);
break;
#endif
#if defined(IP_RECVTOS)
- case SOCKET_OPT_IP_RECVTOS:
- result = ngetopt_lvl_ip_recvtos(env, descP);
+ case ESOCK_OPT_IP_RECVTOS:
+ result = esock_getopt_lvl_ip_recvtos(env, descP);
break;
#endif
#if defined(IP_RECVTTL)
- case SOCKET_OPT_IP_RECVTTL:
- result = ngetopt_lvl_ip_recvttl(env, descP);
+ case ESOCK_OPT_IP_RECVTTL:
+ result = esock_getopt_lvl_ip_recvttl(env, descP);
break;
#endif
#if defined(IP_RETOPTS)
- case SOCKET_OPT_IP_RETOPTS:
- result = ngetopt_lvl_ip_retopts(env, descP);
+ case ESOCK_OPT_IP_RETOPTS:
+ result = esock_getopt_lvl_ip_retopts(env, descP);
break;
#endif
#if defined(IP_ROUTER_ALERT)
- case SOCKET_OPT_IP_ROUTER_ALERT:
- result = ngetopt_lvl_ip_router_alert(env, descP);
+ case ESOCK_OPT_IP_ROUTER_ALERT:
+ result = esock_getopt_lvl_ip_router_alert(env, descP);
break;
#endif
#if defined(IP_SENDSRCADDR)
- case SOCKET_OPT_IP_SENDSRCADDR:
- result = ngetopt_lvl_ip_sendsrcaddr(env, descP);
+ case ESOCK_OPT_IP_SENDSRCADDR:
+ result = esock_getopt_lvl_ip_sendsrcaddr(env, descP);
break;
#endif
#if defined(IP_TOS)
- case SOCKET_OPT_IP_TOS:
- result = ngetopt_lvl_ip_tos(env, descP);
+ case ESOCK_OPT_IP_TOS:
+ result = esock_getopt_lvl_ip_tos(env, descP);
break;
#endif
#if defined(IP_TRANSPARENT)
- case SOCKET_OPT_IP_TRANSPARENT:
- result = ngetopt_lvl_ip_transparent(env, descP);
+ case ESOCK_OPT_IP_TRANSPARENT:
+ result = esock_getopt_lvl_ip_transparent(env, descP);
break;
#endif
#if defined(IP_TTL)
- case SOCKET_OPT_IP_TTL:
- result = ngetopt_lvl_ip_ttl(env, descP);
+ case ESOCK_OPT_IP_TTL:
+ result = esock_getopt_lvl_ip_ttl(env, descP);
break;
#endif
default:
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_ip -> unknown opt %d\r\n", eOpt) );
+ ("SOCKET", "esock_getopt_lvl_ip -> unknown opt %d\r\n", eOpt) );
result = esock_make_error(env, esock_atom_einval);
break;
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_ip -> done when"
+ ("SOCKET", "esock_getopt_lvl_ip -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -12072,12 +12482,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
}
-/* ngetopt_lvl_ip_minttl - Level IP MINTTL option
+/* esock_getopt_lvl_ip_minttl - Level IP MINTTL option
*/
#if defined(IP_MINTTL)
static
-ERL_NIF_TERM ngetopt_lvl_ip_minttl(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_minttl(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12085,17 +12495,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_minttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_int_opt(env, descP, level, IP_MINTTL);
+ return esock_getopt_int_opt(env, descP, level, IP_MINTTL);
}
#endif
-/* ngetopt_lvl_ip_freebind - Level IP FREEBIND option
+/* esock_getopt_lvl_ip_freebind - Level IP FREEBIND option
*/
#if defined(IP_FREEBIND)
static
-ERL_NIF_TERM ngetopt_lvl_ip_freebind(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_freebind(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12103,17 +12513,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_freebind(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_FREEBIND);
+ return esock_getopt_bool_opt(env, descP, level, IP_FREEBIND);
}
#endif
-/* ngetopt_lvl_ip_hdrincl - Level IP HDRINCL option
+/* esock_getopt_lvl_ip_hdrincl - Level IP HDRINCL option
*/
#if defined(IP_HDRINCL)
static
-ERL_NIF_TERM ngetopt_lvl_ip_hdrincl(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_hdrincl(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12121,17 +12531,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_hdrincl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_HDRINCL);
+ return esock_getopt_bool_opt(env, descP, level, IP_HDRINCL);
}
#endif
-/* ngetopt_lvl_ip_mtu - Level IP MTU option
+/* esock_getopt_lvl_ip_mtu - Level IP MTU option
*/
#if defined(IP_MTU)
static
-ERL_NIF_TERM ngetopt_lvl_ip_mtu(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_mtu(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12139,17 +12549,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_mtu(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_int_opt(env, descP, level, IP_MTU);
+ return esock_getopt_int_opt(env, descP, level, IP_MTU);
}
#endif
-/* ngetopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option
+/* esock_getopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option
*/
#if defined(IP_MTU_DISCOVER)
static
-ERL_NIF_TERM ngetopt_lvl_ip_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eMtuDisc;
@@ -12178,12 +12588,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_mtu_discover(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option
+/* esock_getopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option
*/
#if defined(IP_MULTICAST_ALL)
static
-ERL_NIF_TERM ngetopt_lvl_ip_multicast_all(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_multicast_all(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12191,17 +12601,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_all(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_MULTICAST_ALL);
+ return esock_getopt_bool_opt(env, descP, level, IP_MULTICAST_ALL);
}
#endif
-/* ngetopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option
+/* esock_getopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option
*/
#if defined(IP_MULTICAST_IF)
static
-ERL_NIF_TERM ngetopt_lvl_ip_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eAddr;
@@ -12233,12 +12643,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_if(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option
+/* esock_getopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option
*/
#if defined(IP_MULTICAST_LOOP)
static
-ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12246,17 +12656,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP);
+ return esock_getopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP);
}
#endif
-/* ngetopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option
+/* esock_getopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option
*/
#if defined(IP_MULTICAST_TTL)
static
-ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12264,17 +12674,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_int_opt(env, descP, level, IP_MULTICAST_TTL);
+ return esock_getopt_int_opt(env, descP, level, IP_MULTICAST_TTL);
}
#endif
-/* ngetopt_lvl_ip_nodefrag - Level IP NODEFRAG option
+/* esock_getopt_lvl_ip_nodefrag - Level IP NODEFRAG option
*/
#if defined(IP_NODEFRAG)
static
-ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_nodefrag(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12282,17 +12692,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_NODEFRAG);
+ return esock_getopt_bool_opt(env, descP, level, IP_NODEFRAG);
}
#endif
-/* ngetopt_lvl_ip_pktinfo - Level IP PKTINFO option
+/* esock_getopt_lvl_ip_pktinfo - Level IP PKTINFO option
*/
#if defined(IP_PKTINFO)
static
-ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_pktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12300,17 +12710,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_PKTINFO);
+ return esock_getopt_bool_opt(env, descP, level, IP_PKTINFO);
}
#endif
-/* ngetopt_lvl_ip_recvtos - Level IP RECVTOS option
+/* esock_getopt_lvl_ip_recvtos - Level IP RECVTOS option
*/
#if defined(IP_RECVTOS)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recvtos(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12318,17 +12728,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVTOS);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVTOS);
}
#endif
-/* ngetopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option
+/* esock_getopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option
*/
#if defined(IP_RECVDSTADDR)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12336,17 +12746,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVDSTADDR);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVDSTADDR);
}
#endif
-/* ngetopt_lvl_ip_recverr - Level IP RECVERR option
+/* esock_getopt_lvl_ip_recverr - Level IP RECVERR option
*/
#if defined(IP_RECVERR)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12354,17 +12764,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVERR);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVERR);
}
#endif
-/* ngetopt_lvl_ip_recvif - Level IP RECVIF option
+/* esock_getopt_lvl_ip_recvif - Level IP RECVIF option
*/
#if defined(IP_RECVIF)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recvif(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12372,17 +12782,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVIF);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVIF);
}
#endif
-/* ngetopt_lvl_ip_recvopt - Level IP RECVOPTS option
+/* esock_getopt_lvl_ip_recvopt - Level IP RECVOPTS option
*/
#if defined(IP_RECVOPTS)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recvopts(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12390,17 +12800,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVOPTS);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVOPTS);
}
#endif
-/* ngetopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option
+/* esock_getopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option
*/
#if defined(IP_RECVORIGDSTADDR)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12408,17 +12818,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR);
}
#endif
-/* ngetopt_lvl_ip_recvttl - Level IP RECVTTL option
+/* esock_getopt_lvl_ip_recvttl - Level IP RECVTTL option
*/
#if defined(IP_RECVTTL)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvttl(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_recvttl(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12426,17 +12836,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVTTL);
+ return esock_getopt_bool_opt(env, descP, level, IP_RECVTTL);
}
#endif
-/* ngetopt_lvl_ip_retopts - Level IP RETOPTS option
+/* esock_getopt_lvl_ip_retopts - Level IP RETOPTS option
*/
#if defined(IP_RETOPTS)
static
-ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_retopts(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12444,17 +12854,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RETOPTS);
+ return esock_getopt_bool_opt(env, descP, level, IP_RETOPTS);
}
#endif
-/* ngetopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option
+/* esock_getopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option
*/
#if defined(IP_ROUTER_ALERT)
static
-ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12462,17 +12872,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_int_opt(env, descP, level, IP_ROUTER_ALERT);
+ return esock_getopt_int_opt(env, descP, level, IP_ROUTER_ALERT);
}
#endif
-/* ngetopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option
+/* esock_getopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option
*/
#if defined(IP_SENDSRCADDR)
static
-ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12480,17 +12890,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_SENDSRCADDR);
+ return esock_getopt_bool_opt(env, descP, level, IP_SENDSRCADDR);
}
#endif
-/* ngetopt_lvl_ip_tos - Level IP TOS option
+/* esock_getopt_lvl_ip_tos - Level IP TOS option
*/
#if defined(IP_TOS)
static
-ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_tos(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12515,12 +12925,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_ip_transparent - Level IP TRANSPARENT option
+/* esock_getopt_lvl_ip_transparent - Level IP TRANSPARENT option
*/
#if defined(IP_TRANSPARENT)
static
-ERL_NIF_TERM ngetopt_lvl_ip_transparent(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_transparent(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12528,18 +12938,18 @@ ERL_NIF_TERM ngetopt_lvl_ip_transparent(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_TRANSPARENT);
+ return esock_getopt_bool_opt(env, descP, level, IP_TRANSPARENT);
}
#endif
-/* ngetopt_lvl_ip_ttl - Level IP TTL option
+/* esock_getopt_lvl_ip_ttl - Level IP TTL option
*/
#if defined(IP_TTL)
static
-ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ip_ttl(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -12547,121 +12957,121 @@ ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_int_opt(env, descP, level, IP_TTL);
+ return esock_getopt_int_opt(env, descP, level, IP_TTL);
}
#endif
-/* ngetopt_lvl_ipv6 - Level *IPv6* option(s)
+/* esock_getopt_lvl_ipv6 - Level *IPv6* option(s)
*/
#if defined(HAVE_IPV6)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_lvl_ipv6(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_ipv6 -> entry with"
+ ("SOCKET", "esock_getopt_lvl_ipv6 -> entry with"
"\r\n eOpt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(IPV6_AUTHHDR)
- case SOCKET_OPT_IPV6_AUTHHDR:
- result = ngetopt_lvl_ipv6_authhdr(env, descP);
+ case ESOCK_OPT_IPV6_AUTHHDR:
+ result = esock_getopt_lvl_ipv6_authhdr(env, descP);
break;
#endif
#if defined(IPV6_DSTOPTS)
- case SOCKET_OPT_IPV6_DSTOPTS:
- result = ngetopt_lvl_ipv6_dstopts(env, descP);
+ case ESOCK_OPT_IPV6_DSTOPTS:
+ result = esock_getopt_lvl_ipv6_dstopts(env, descP);
break;
#endif
#if defined(IPV6_FLOWINFO)
- case SOCKET_OPT_IPV6_FLOWINFO:
- result = ngetopt_lvl_ipv6_flowinfo(env, descP);
+ case ESOCK_OPT_IPV6_FLOWINFO:
+ result = esock_getopt_lvl_ipv6_flowinfo(env, descP);
break;
#endif
#if defined(IPV6_HOPLIMIT)
- case SOCKET_OPT_IPV6_HOPLIMIT:
- result = ngetopt_lvl_ipv6_hoplimit(env, descP);
+ case ESOCK_OPT_IPV6_HOPLIMIT:
+ result = esock_getopt_lvl_ipv6_hoplimit(env, descP);
break;
#endif
#if defined(IPV6_HOPOPTS)
- case SOCKET_OPT_IPV6_HOPOPTS:
- result = ngetopt_lvl_ipv6_hopopts(env, descP);
+ case ESOCK_OPT_IPV6_HOPOPTS:
+ result = esock_getopt_lvl_ipv6_hopopts(env, descP);
break;
#endif
#if defined(IPV6_MTU)
- case SOCKET_OPT_IPV6_MTU:
- result = ngetopt_lvl_ipv6_mtu(env, descP);
+ case ESOCK_OPT_IPV6_MTU:
+ result = esock_getopt_lvl_ipv6_mtu(env, descP);
break;
#endif
#if defined(IPV6_MTU_DISCOVER)
- case SOCKET_OPT_IPV6_MTU_DISCOVER:
- result = ngetopt_lvl_ipv6_mtu_discover(env, descP);
+ case ESOCK_OPT_IPV6_MTU_DISCOVER:
+ result = esock_getopt_lvl_ipv6_mtu_discover(env, descP);
break;
#endif
#if defined(IPV6_MULTICAST_HOPS)
- case SOCKET_OPT_IPV6_MULTICAST_HOPS:
- result = ngetopt_lvl_ipv6_multicast_hops(env, descP);
+ case ESOCK_OPT_IPV6_MULTICAST_HOPS:
+ result = esock_getopt_lvl_ipv6_multicast_hops(env, descP);
break;
#endif
#if defined(IPV6_MULTICAST_IF)
- case SOCKET_OPT_IPV6_MULTICAST_IF:
- result = ngetopt_lvl_ipv6_multicast_if(env, descP);
+ case ESOCK_OPT_IPV6_MULTICAST_IF:
+ result = esock_getopt_lvl_ipv6_multicast_if(env, descP);
break;
#endif
#if defined(IPV6_MULTICAST_LOOP)
- case SOCKET_OPT_IPV6_MULTICAST_LOOP:
- result = ngetopt_lvl_ipv6_multicast_loop(env, descP);
+ case ESOCK_OPT_IPV6_MULTICAST_LOOP:
+ result = esock_getopt_lvl_ipv6_multicast_loop(env, descP);
break;
#endif
#if defined(IPV6_RECVERR)
- case SOCKET_OPT_IPV6_RECVERR:
- result = ngetopt_lvl_ipv6_recverr(env, descP);
+ case ESOCK_OPT_IPV6_RECVERR:
+ result = esock_getopt_lvl_ipv6_recverr(env, descP);
break;
#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
- case SOCKET_OPT_IPV6_RECVPKTINFO:
- result = ngetopt_lvl_ipv6_recvpktinfo(env, descP);
+ case ESOCK_OPT_IPV6_RECVPKTINFO:
+ result = esock_getopt_lvl_ipv6_recvpktinfo(env, descP);
break;
#endif
#if defined(IPV6_ROUTER_ALERT)
- case SOCKET_OPT_IPV6_ROUTER_ALERT:
- result = ngetopt_lvl_ipv6_router_alert(env, descP);
+ case ESOCK_OPT_IPV6_ROUTER_ALERT:
+ result = esock_getopt_lvl_ipv6_router_alert(env, descP);
break;
#endif
#if defined(IPV6_RTHDR)
- case SOCKET_OPT_IPV6_RTHDR:
- result = ngetopt_lvl_ipv6_rthdr(env, descP);
+ case ESOCK_OPT_IPV6_RTHDR:
+ result = esock_getopt_lvl_ipv6_rthdr(env, descP);
break;
#endif
#if defined(IPV6_UNICAST_HOPS)
- case SOCKET_OPT_IPV6_UNICAST_HOPS:
- result = ngetopt_lvl_ipv6_unicast_hops(env, descP);
+ case ESOCK_OPT_IPV6_UNICAST_HOPS:
+ result = esock_getopt_lvl_ipv6_unicast_hops(env, descP);
break;
#endif
#if defined(IPV6_V6ONLY)
- case SOCKET_OPT_IPV6_V6ONLY:
- result = ngetopt_lvl_ipv6_v6only(env, descP);
+ case ESOCK_OPT_IPV6_V6ONLY:
+ result = esock_getopt_lvl_ipv6_v6only(env, descP);
break;
#endif
@@ -12671,7 +13081,7 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_ipv6 -> done when"
+ ("SOCKET", "esock_getopt_lvl_ipv6 -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -12681,33 +13091,33 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
#if defined(IPV6_AUTHHDR)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR);
+ return esock_getopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR);
}
#endif
#if defined(IPV6_DSTOPTS)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
#else
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_DSTOPTS);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_DSTOPTS);
}
#endif
#if defined(IPV6_FLOWINFO)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12715,15 +13125,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_FLOWINFO);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_FLOWINFO);
}
#endif
#if defined(IPV6_HOPLIMIT)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12731,15 +13141,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_HOPLIMIT);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_HOPLIMIT);
}
#endif
#if defined(IPV6_HOPOPTS)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12747,15 +13157,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_HOPOPTS);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_HOPOPTS);
}
#endif
#if defined(IPV6_MTU)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12763,17 +13173,17 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_int_opt(env, descP, level, IPV6_MTU);
+ return esock_getopt_int_opt(env, descP, level, IPV6_MTU);
}
#endif
-/* ngetopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option
+/* esock_getopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option
*/
#if defined(IPV6_MTU_DISCOVER)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
ERL_NIF_TERM eMtuDisc;
@@ -12804,8 +13214,8 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env,
#if defined(IPV6_MULTICAST_HOPS)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12813,15 +13223,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS);
+ return esock_getopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS);
}
#endif
#if defined(IPV6_MULTICAST_IF)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12829,15 +13239,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_int_opt(env, descP, level, IPV6_MULTICAST_IF);
+ return esock_getopt_int_opt(env, descP, level, IPV6_MULTICAST_IF);
}
#endif
#if defined(IPV6_MULTICAST_LOOP)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12845,15 +13255,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP);
}
#endif
#if defined(IPV6_RECVERR)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12861,15 +13271,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_RECVERR);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_RECVERR);
}
#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12882,15 +13292,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
int opt = IPV6_PKTINFO;
#endif
- return ngetopt_bool_opt(env, descP, level, opt);
+ return esock_getopt_bool_opt(env, descP, level, opt);
}
#endif
#if defined(IPV6_ROUTER_ALERT)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_router_alert(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12898,15 +13308,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_router_alert(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT);
+ return esock_getopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT);
}
#endif
#if defined(IPV6_RTHDR)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_rthdr(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12914,15 +13324,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_RTHDR);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_RTHDR);
}
#endif
#if defined(IPV6_UNICAST_HOPS)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12930,15 +13340,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS);
+ return esock_getopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS);
}
#endif
#if defined(IPV6_V6ONLY)
static
-ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_ipv6_v6only(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
#if defined(SOL_IPV6)
int level = SOL_IPV6;
@@ -12946,7 +13356,7 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
int level = IPPROTO_IPV6;
#endif
- return ngetopt_bool_opt(env, descP, level, IPV6_V6ONLY);
+ return esock_getopt_bool_opt(env, descP, level, IPV6_V6ONLY);
}
#endif
@@ -12955,31 +13365,31 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
-/* ngetopt_lvl_tcp - Level *TCP* option(s)
+/* esock_getopt_lvl_tcp - Level *TCP* option(s)
*/
static
-ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_lvl_tcp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
switch (eOpt) {
#if defined(TCP_CONGESTION)
- case SOCKET_OPT_TCP_CONGESTION:
- result = ngetopt_lvl_tcp_congestion(env, descP);
+ case ESOCK_OPT_TCP_CONGESTION:
+ result = esock_getopt_lvl_tcp_congestion(env, descP);
break;
#endif
#if defined(TCP_MAXSEG)
- case SOCKET_OPT_TCP_MAXSEG:
- result = ngetopt_lvl_tcp_maxseg(env, descP);
+ case ESOCK_OPT_TCP_MAXSEG:
+ result = esock_getopt_lvl_tcp_maxseg(env, descP);
break;
#endif
#if defined(TCP_NODELAY)
- case SOCKET_OPT_TCP_NODELAY:
- result = ngetopt_lvl_tcp_nodelay(env, descP);
+ case ESOCK_OPT_TCP_NODELAY:
+ result = esock_getopt_lvl_tcp_nodelay(env, descP);
break;
#endif
@@ -12992,58 +13402,58 @@ ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env,
}
-/* ngetopt_lvl_tcp_congestion - Level TCP CONGESTION option
+/* esock_getopt_lvl_tcp_congestion - Level TCP CONGESTION option
*/
#if defined(TCP_CONGESTION)
static
-ERL_NIF_TERM ngetopt_lvl_tcp_congestion(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_tcp_congestion(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- int max = SOCKET_OPT_TCP_CONGESTION_NAME_MAX+1;
+ int max = ESOCK_OPT_TCP_CONGESTION_NAME_MAX+1;
- return ngetopt_str_opt(env, descP, IPPROTO_TCP, TCP_CONGESTION, max);
+ return esock_getopt_str_opt(env, descP, IPPROTO_TCP, TCP_CONGESTION, max);
}
#endif
-/* ngetopt_lvl_tcp_maxseg - Level TCP MAXSEG option
+/* esock_getopt_lvl_tcp_maxseg - Level TCP MAXSEG option
*/
#if defined(TCP_MAXSEG)
static
-ERL_NIF_TERM ngetopt_lvl_tcp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_tcp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG);
+ return esock_getopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG);
}
#endif
-/* ngetopt_lvl_tcp_nodelay - Level TCP NODELAY option
+/* esock_getopt_lvl_tcp_nodelay - Level TCP NODELAY option
*/
#if defined(TCP_NODELAY)
static
-ERL_NIF_TERM ngetopt_lvl_tcp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_tcp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY);
+ return esock_getopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY);
}
#endif
-/* ngetopt_lvl_udp - Level *UDP* option(s)
+/* esock_getopt_lvl_udp - Level *UDP* option(s)
*/
static
-ERL_NIF_TERM ngetopt_lvl_udp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_lvl_udp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
switch (eOpt) {
#if defined(UDP_CORK)
- case SOCKET_OPT_UDP_CORK:
- result = ngetopt_lvl_udp_cork(env, descP);
+ case ESOCK_OPT_UDP_CORK:
+ result = esock_getopt_lvl_udp_cork(env, descP);
break;
#endif
@@ -13056,74 +13466,74 @@ ERL_NIF_TERM ngetopt_lvl_udp(ErlNifEnv* env,
}
-/* ngetopt_lvl_udp_cork - Level UDP CORK option
+/* esock_getopt_lvl_udp_cork - Level UDP CORK option
*/
#if defined(UDP_CORK)
static
-ERL_NIF_TERM ngetopt_lvl_udp_cork(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_udp_cork(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK);
+ return esock_getopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK);
}
#endif
-/* ngetopt_lvl_sctp - Level *SCTP* option(s)
+/* esock_getopt_lvl_sctp - Level *SCTP* option(s)
*/
#if defined(HAVE_SCTP)
static
-ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env,
- ESockDescriptor* descP,
- int eOpt)
+ERL_NIF_TERM esock_getopt_lvl_sctp(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int eOpt)
{
ERL_NIF_TERM result;
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_sctp -> entry with"
+ ("SOCKET", "esock_getopt_lvl_sctp -> entry with"
"\r\n opt: %d"
"\r\n", eOpt) );
switch (eOpt) {
#if defined(SCTP_ASSOCINFO)
- case SOCKET_OPT_SCTP_ASSOCINFO:
- result = ngetopt_lvl_sctp_associnfo(env, descP);
+ case ESOCK_OPT_SCTP_ASSOCINFO:
+ result = esock_getopt_lvl_sctp_associnfo(env, descP);
break;
#endif
#if defined(SCTP_AUTOCLOSE)
- case SOCKET_OPT_SCTP_AUTOCLOSE:
- result = ngetopt_lvl_sctp_autoclose(env, descP);
+ case ESOCK_OPT_SCTP_AUTOCLOSE:
+ result = esock_getopt_lvl_sctp_autoclose(env, descP);
break;
#endif
#if defined(SCTP_DISABLE_FRAGMENTS)
- case SOCKET_OPT_SCTP_DISABLE_FRAGMENTS:
- result = ngetopt_lvl_sctp_disable_fragments(env, descP);
+ case ESOCK_OPT_SCTP_DISABLE_FRAGMENTS:
+ result = esock_getopt_lvl_sctp_disable_fragments(env, descP);
break;
#endif
#if defined(SCTP_INITMSG)
- case SOCKET_OPT_SCTP_INITMSG:
- result = ngetopt_lvl_sctp_initmsg(env, descP);
+ case ESOCK_OPT_SCTP_INITMSG:
+ result = esock_getopt_lvl_sctp_initmsg(env, descP);
break;
#endif
#if defined(SCTP_MAXSEG)
- case SOCKET_OPT_SCTP_MAXSEG:
- result = ngetopt_lvl_sctp_maxseg(env, descP);
+ case ESOCK_OPT_SCTP_MAXSEG:
+ result = esock_getopt_lvl_sctp_maxseg(env, descP);
break;
#endif
#if defined(SCTP_NODELAY)
- case SOCKET_OPT_SCTP_NODELAY:
- result = ngetopt_lvl_sctp_nodelay(env, descP);
+ case ESOCK_OPT_SCTP_NODELAY:
+ result = esock_getopt_lvl_sctp_nodelay(env, descP);
break;
#endif
#if defined(SCTP_RTOINFO)
- case SOCKET_OPT_SCTP_RTOINFO:
- result = ngetopt_lvl_sctp_rtoinfo(env, descP);
+ case ESOCK_OPT_SCTP_RTOINFO:
+ result = esock_getopt_lvl_sctp_rtoinfo(env, descP);
break;
#endif
@@ -13133,7 +13543,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_sctp -> done when"
+ ("SOCKET", "esock_getopt_lvl_sctp -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -13141,7 +13551,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env,
}
-/* ngetopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option
+/* esock_getopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option
*
* <KOLLA>
*
@@ -13156,15 +13566,15 @@ ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env,
*/
#if defined(SCTP_ASSOCINFO)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_associnfo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
struct sctp_assocparams val;
SOCKOPTLEN_T valSz = sizeof(val);
int res;
- SSDBG( descP, ("SOCKET", "ngetopt_lvl_sctp_associnfo -> entry\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_getopt_lvl_sctp_associnfo -> entry\r\n") );
sys_memzero((char*) &val, valSz);
res = sock_getopt(descP->sock, IPPROTO_SCTP, SCTP_ASSOCINFO, &val, &valSz);
@@ -13193,7 +13603,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_sctp_associnfo -> done with"
+ ("SOCKET", "esock_getopt_lvl_sctp_associnfo -> done with"
"\r\n res: %d"
"\r\n result: %T"
"\r\n", res, result) );
@@ -13203,44 +13613,45 @@ ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option
+/* esock_getopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option
*/
#if defined(SCTP_AUTOCLOSE)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_autoclose(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_autoclose(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_AUTOCLOSE);
+ return esock_getopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_AUTOCLOSE);
}
#endif
-/* ngetopt_lvl_sctp_disable_fragments - Level SCTP DISABLE:FRAGMENTS option
+/* esock_getopt_lvl_sctp_disable_fragments - Level SCTP DISABLE:FRAGMENTS option
*/
#if defined(SCTP_DISABLE_FRAGMENTS)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_disable_fragments(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS);
+ return esock_getopt_bool_opt(env, descP,
+ IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS);
}
#endif
-/* ngetopt_lvl_sctp_initmsg - Level SCTP INITMSG option
+/* esock_getopt_lvl_sctp_initmsg - Level SCTP INITMSG option
*
*/
#if defined(SCTP_INITMSG)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_initmsg(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
struct sctp_initmsg val;
SOCKOPTLEN_T valSz = sizeof(val);
int res;
- SSDBG( descP, ("SOCKET", "ngetopt_lvl_sctp_initmsg -> entry\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_getopt_lvl_sctp_initmsg -> entry\r\n") );
sys_memzero((char*) &val, valSz);
res = sock_getopt(descP->sock, IPPROTO_SCTP, SCTP_INITMSG, &val, &valSz);
@@ -13267,7 +13678,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_sctp_initmsg -> done with"
+ ("SOCKET", "esock_getopt_lvl_sctp_initmsg -> done with"
"\r\n res: %d"
"\r\n result: %T"
"\r\n", res, result) );
@@ -13277,31 +13688,31 @@ ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_sctp_maxseg - Level SCTP MAXSEG option
+/* esock_getopt_lvl_sctp_maxseg - Level SCTP MAXSEG option
*/
#if defined(SCTP_MAXSEG)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_maxseg(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_maxseg(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG);
+ return esock_getopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG);
}
#endif
-/* ngetopt_lvl_sctp_nodelay - Level SCTP NODELAY option
+/* esock_getopt_lvl_sctp_nodelay - Level SCTP NODELAY option
*/
#if defined(SCTP_NODELAY)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_nodelay(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_nodelay(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
- return ngetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY);
+ return esock_getopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY);
}
#endif
-/* ngetopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option
+/* esock_getopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option
*
* <KOLLA>
*
@@ -13316,15 +13727,15 @@ ERL_NIF_TERM ngetopt_lvl_sctp_nodelay(ErlNifEnv* env,
*/
#if defined(SCTP_RTOINFO)
static
-ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_getopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ERL_NIF_TERM result;
struct sctp_rtoinfo val;
SOCKOPTLEN_T valSz = sizeof(val);
int res;
- SSDBG( descP, ("SOCKET", "ngetopt_lvl_sctp_rtoinfo -> entry\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_getopt_lvl_sctp_rtoinfo -> entry\r\n") );
sys_memzero((char*) &val, valSz);
res = sock_getopt(descP->sock, IPPROTO_SCTP, SCTP_RTOINFO, &val, &valSz);
@@ -13350,7 +13761,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_lvl_sctp_rtoinfo -> done with"
+ ("SOCKET", "esock_getopt_lvl_sctp_rtoinfo -> done with"
"\r\n res: %d"
"\r\n result: %T"
"\r\n", res, result) );
@@ -13365,13 +13776,13 @@ ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env,
-/* ngetopt_bool_opt - get an (integer) bool option
+/* esock_getopt_bool_opt - get an (integer) bool option
*/
static
-ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt)
+ERL_NIF_TERM esock_getopt_bool_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt)
{
ERL_NIF_TERM result;
int val;
@@ -13379,7 +13790,7 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
int res;
/*
- SSDBG( descP, ("SOCKET", "ngetopt_bool_opt -> entry with"
+ SSDBG( descP, ("SOCKET", "esock_getopt_bool_opt -> entry with"
"\r\n: level: %d"
"\r\n: opt: %d"
"\r\n", level, opt) );
@@ -13396,7 +13807,7 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
}
/*
- SSDBG( descP, ("SOCKET", "ngetopt_bool_opt -> done when"
+ SSDBG( descP, ("SOCKET", "esock_getopt_bool_opt -> done when"
"\r\n: res: %d"
"\r\n: result: %T"
"\r\n", res, result) );
@@ -13406,13 +13817,13 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
}
-/* ngetopt_int_opt - get an integer option
+/* esock_getopt_int_opt - get an integer option
*/
static
-ERL_NIF_TERM ngetopt_int_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt)
+ERL_NIF_TERM esock_getopt_int_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt)
{
ERL_NIF_TERM result;
int val;
@@ -13432,13 +13843,13 @@ ERL_NIF_TERM ngetopt_int_opt(ErlNifEnv* env,
-/* ngetopt_timeval_opt - get an timeval option
+/* esock_getopt_timeval_opt - get an timeval option
*/
static
-ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt)
+ERL_NIF_TERM esock_getopt_timeval_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt)
{
ERL_NIF_TERM result;
struct timeval val;
@@ -13446,7 +13857,7 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env,
int res;
SSDBG( descP,
- ("SOCKET", "ngetopt_timeval_opt -> entry with"
+ ("SOCKET", "esock_getopt_timeval_opt -> entry with"
"\r\n level: %d"
"\r\n opt: %d"
"\r\n", level, opt) );
@@ -13467,7 +13878,7 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_timeval_opt -> done when"
+ ("SOCKET", "esock_getopt_timeval_opt -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -13476,7 +13887,7 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env,
-/* ngetopt_str_opt - get an string option
+/* esock_getopt_str_opt - get an string option
*
* We provide the max size of the string. This is the
* size of the buffer we allocate for the value.
@@ -13485,11 +13896,11 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env,
*/
#if defined(USE_GETOPT_STR_OPT)
static
-ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env,
- ESockDescriptor* descP,
- int level,
- int opt,
- int max)
+ERL_NIF_TERM esock_getopt_str_opt(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ int level,
+ int opt,
+ int max)
{
ERL_NIF_TERM result;
char* val = MALLOC(max);
@@ -13497,7 +13908,7 @@ ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env,
int res;
SSDBG( descP,
- ("SOCKET", "ngetopt_str_opt -> entry with"
+ ("SOCKET", "esock_getopt_str_opt -> entry with"
"\r\n level: %d"
"\r\n opt: %d"
"\r\n max: %d"
@@ -13514,7 +13925,7 @@ ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env,
}
SSDBG( descP,
- ("SOCKET", "ngetopt_str_opt -> done when"
+ ("SOCKET", "esock_getopt_str_opt -> done when"
"\r\n result: %T"
"\r\n", result) );
@@ -13553,7 +13964,7 @@ ERL_NIF_TERM nif_sockname(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 1) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -13565,7 +13976,7 @@ ERL_NIF_TERM nif_sockname(ErlNifEnv* env,
"\r\n Socket: %T"
"\r\n", descP->sock, argv[0]) );
- res = nsockname(env, descP);
+ res = esock_sockname(env, descP);
SSDBG( descP, ("SOCKET", "nif_sockname -> done with res = %T\r\n", res) );
@@ -13577,8 +13988,8 @@ ERL_NIF_TERM nif_sockname(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM nsockname(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_sockname(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ESockAddress sa;
ESockAddress* saP = &sa;
@@ -13627,7 +14038,7 @@ ERL_NIF_TERM nif_peername(ErlNifEnv* env,
/* Extract arguments and perform preliminary validation */
if ((argc != 1) ||
- !enif_get_resource(env, argv[0], sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) {
return enif_make_badarg(env);
}
@@ -13639,7 +14050,7 @@ ERL_NIF_TERM nif_peername(ErlNifEnv* env,
"\r\n Socket: %T"
"\r\n", descP->sock, argv[0]) );
- res = npeername(env, descP);
+ res = esock_peername(env, descP);
SSDBG( descP, ("SOCKET", "nif_peername -> done with res = %T\r\n", res) );
@@ -13651,8 +14062,8 @@ ERL_NIF_TERM nif_peername(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM npeername(ErlNifEnv* env,
- ESockDescriptor* descP)
+ERL_NIF_TERM esock_peername(ErlNifEnv* env,
+ ESockDescriptor* descP)
{
ESockAddress sa;
ESockAddress* saP = &sa;
@@ -13703,7 +14114,7 @@ ERL_NIF_TERM nif_cancel(ErlNifEnv* env,
sockRef = argv[0];
if ((argc != 3) ||
- !enif_get_resource(env, sockRef, sockets, (void**) &descP)) {
+ !ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) {
return enif_make_badarg(env);
}
op = argv[1];
@@ -13718,7 +14129,7 @@ ERL_NIF_TERM nif_cancel(ErlNifEnv* env,
"\r\n opRef: %T"
"\r\n", descP->sock, op, opRef) );
- result = ncancel(env, descP, op, sockRef, opRef);
+ result = esock_cancel(env, descP, op, sockRef, opRef);
SSDBG( descP,
("SOCKET", "nif_cancel -> done with result: "
@@ -13732,11 +14143,11 @@ ERL_NIF_TERM nif_cancel(ErlNifEnv* env,
#if !defined(__WIN32__)
static
-ERL_NIF_TERM ncancel(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM op,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM op,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef)
{
/* <KOLLA>
*
@@ -13747,21 +14158,21 @@ ERL_NIF_TERM ncancel(ErlNifEnv* env,
* </KOLLA>
*/
if (COMPARE(op, esock_atom_connect) == 0) {
- return ncancel_connect(env, descP, opRef);
+ return esock_cancel_connect(env, descP, opRef);
} else if (COMPARE(op, esock_atom_accept) == 0) {
- return ncancel_accept(env, descP, sockRef, opRef);
+ return esock_cancel_accept(env, descP, sockRef, opRef);
} else if (COMPARE(op, esock_atom_send) == 0) {
- return ncancel_send(env, descP, sockRef, opRef);
+ return esock_cancel_send(env, descP, sockRef, opRef);
} else if (COMPARE(op, esock_atom_sendto) == 0) {
- return ncancel_send(env, descP, sockRef, opRef);
+ return esock_cancel_send(env, descP, sockRef, opRef);
} else if (COMPARE(op, esock_atom_sendmsg) == 0) {
- return ncancel_send(env, descP, sockRef, opRef);
+ return esock_cancel_send(env, descP, sockRef, opRef);
} else if (COMPARE(op, esock_atom_recv) == 0) {
- return ncancel_recv(env, descP, sockRef, opRef);
+ return esock_cancel_recv(env, descP, sockRef, opRef);
} else if (COMPARE(op, esock_atom_recvfrom) == 0) {
- return ncancel_recv(env, descP, sockRef, opRef);
+ return esock_cancel_recv(env, descP, sockRef, opRef);
} else if (COMPARE(op, esock_atom_recvmsg) == 0) {
- return ncancel_recv(env, descP, sockRef, opRef);
+ return esock_cancel_recv(env, descP, sockRef, opRef);
} else {
return esock_make_error(env, esock_atom_einval);
}
@@ -13769,20 +14180,20 @@ ERL_NIF_TERM ncancel(ErlNifEnv* env,
-/* *** ncancel_connect ***
+/* *** esock_cancel_connect ***
*
*
*/
static
-ERL_NIF_TERM ncancel_connect(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_connect(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef)
{
- return ncancel_write_select(env, descP, opRef);
+ return esock_cancel_write_select(env, descP, opRef);
}
-/* *** ncancel_accept ***
+/* *** esock_cancel_accept ***
*
* We have two different cases:
* *) Its the current acceptor
@@ -13793,15 +14204,15 @@ ERL_NIF_TERM ncancel_connect(ErlNifEnv* env,
*
*/
static
-ERL_NIF_TERM ncancel_accept(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_accept(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef)
{
ERL_NIF_TERM res;
SSDBG( descP,
- ("SOCKET", "ncancel_accept -> entry with"
+ ("SOCKET", "esock_cancel_accept -> entry with"
"\r\n opRef: %T"
"\r\n %s"
"\r\n", opRef,
@@ -13811,9 +14222,9 @@ ERL_NIF_TERM ncancel_accept(ErlNifEnv* env,
if (descP->currentAcceptorP != NULL) {
if (COMPARE(opRef, descP->currentAcceptor.ref) == 0) {
- res = ncancel_accept_current(env, descP, sockRef);
+ res = esock_cancel_accept_current(env, descP, sockRef);
} else {
- res = ncancel_accept_waiting(env, descP, opRef);
+ res = esock_cancel_accept_waiting(env, descP, opRef);
}
} else {
/* Or badarg? */
@@ -13823,7 +14234,7 @@ ERL_NIF_TERM ncancel_accept(ErlNifEnv* env,
MUNLOCK(descP->accMtx);
SSDBG( descP,
- ("SOCKET", "ncancel_accept -> done with result:"
+ ("SOCKET", "esock_cancel_accept -> done with result:"
"\r\n %T"
"\r\n", res) );
@@ -13836,27 +14247,27 @@ ERL_NIF_TERM ncancel_accept(ErlNifEnv* env,
* in the acceptor queue).
*/
static
-ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef)
+ERL_NIF_TERM esock_cancel_accept_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef)
{
ERL_NIF_TERM res;
- SSDBG( descP, ("SOCKET", "ncancel_accept_current -> entry\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_cancel_accept_current -> entry\r\n") );
- DEMONP("ncancel_accept_current -> current acceptor",
+ DEMONP("esock_cancel_accept_current -> current acceptor",
env, descP, &descP->currentAcceptor.mon);
- res = ncancel_read_select(env, descP, descP->currentAcceptor.ref);
+ res = esock_cancel_read_select(env, descP, descP->currentAcceptor.ref);
SSDBG( descP, ("SOCKET",
- "ncancel_accept_current -> cancel res: %T\r\n", res) );
+ "esock_cancel_accept_current -> cancel res: %T\r\n", res) );
if (!activate_next_acceptor(env, descP, sockRef)) {
SSDBG( descP,
- ("SOCKET", "ncancel_accept_current -> no more writers\r\n") );
+ ("SOCKET", "esock_cancel_accept_current -> no more writers\r\n") );
- descP->state = SOCKET_STATE_LISTENING;
+ descP->state = ESOCK_STATE_LISTENING;
descP->currentAcceptorP = NULL;
descP->currentAcceptor.ref = esock_atom_undefined;
@@ -13864,7 +14275,7 @@ ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env,
esock_monitor_init(&descP->currentAcceptor.mon);
}
- SSDBG( descP, ("SOCKET", "ncancel_accept_current -> done with result:"
+ SSDBG( descP, ("SOCKET", "esock_cancel_accept_current -> done with result:"
"\r\n %T"
"\r\n", res) );
@@ -13876,9 +14287,9 @@ ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env,
* remove them from the acceptor queue.
*/
static
-ERL_NIF_TERM ncancel_accept_waiting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_accept_waiting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef)
{
ErlNifPid caller;
@@ -13897,23 +14308,23 @@ ERL_NIF_TERM ncancel_accept_waiting(ErlNifEnv* env,
-/* *** ncancel_send ***
+/* *** esock_cancel_send ***
*
* Cancel a send operation.
* Its either the current writer or one of the waiting writers.
*/
static
-ERL_NIF_TERM ncancel_send(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_send(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef)
{
ERL_NIF_TERM res;
MLOCK(descP->writeMtx);
SSDBG( descP,
- ("SOCKET", "ncancel_send -> entry with"
+ ("SOCKET", "esock_cancel_send -> entry with"
"\r\n opRef: %T"
"\r\n %s"
"\r\n", opRef,
@@ -13921,9 +14332,9 @@ ERL_NIF_TERM ncancel_send(ErlNifEnv* env,
if (descP->currentWriterP != NULL) {
if (COMPARE(opRef, descP->currentWriter.ref) == 0) {
- res = ncancel_send_current(env, descP, sockRef);
+ res = esock_cancel_send_current(env, descP, sockRef);
} else {
- res = ncancel_send_waiting(env, descP, opRef);
+ res = esock_cancel_send_waiting(env, descP, opRef);
}
} else {
/* Or badarg? */
@@ -13933,7 +14344,7 @@ ERL_NIF_TERM ncancel_send(ErlNifEnv* env,
MUNLOCK(descP->writeMtx);
SSDBG( descP,
- ("SOCKET", "ncancel_send -> done with result:"
+ ("SOCKET", "esock_cancel_send -> done with result:"
"\r\n %T"
"\r\n", res) );
@@ -13947,31 +14358,31 @@ ERL_NIF_TERM ncancel_send(ErlNifEnv* env,
* in the writer queue).
*/
static
-ERL_NIF_TERM ncancel_send_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef)
+ERL_NIF_TERM esock_cancel_send_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef)
{
ERL_NIF_TERM res;
- SSDBG( descP, ("SOCKET", "ncancel_send_current -> entry\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_cancel_send_current -> entry\r\n") );
- DEMONP("ncancel_send_current -> current writer",
+ DEMONP("esock_cancel_send_current -> current writer",
env, descP, &descP->currentWriter.mon);
- res = ncancel_write_select(env, descP, descP->currentWriter.ref);
+ res = esock_cancel_write_select(env, descP, descP->currentWriter.ref);
SSDBG( descP,
- ("SOCKET", "ncancel_send_current -> cancel res: %T\r\n", res) );
+ ("SOCKET", "esock_cancel_send_current -> cancel res: %T\r\n", res) );
if (!activate_next_writer(env, descP, sockRef)) {
SSDBG( descP,
- ("SOCKET", "ncancel_send_current -> no more writers\r\n") );
+ ("SOCKET", "esock_cancel_send_current -> no more writers\r\n") );
descP->currentWriterP = NULL;
descP->currentWriter.ref = esock_atom_undefined;
enif_set_pid_undefined(&descP->currentWriter.pid);
esock_monitor_init(&descP->currentWriter.mon);
}
- SSDBG( descP, ("SOCKET", "ncancel_send_current -> done with result:"
+ SSDBG( descP, ("SOCKET", "esock_cancel_send_current -> done with result:"
"\r\n %T"
"\r\n", res) );
@@ -13983,9 +14394,9 @@ ERL_NIF_TERM ncancel_send_current(ErlNifEnv* env,
* remove them from the writer queue.
*/
static
-ERL_NIF_TERM ncancel_send_waiting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_send_waiting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef)
{
ErlNifPid caller;
@@ -14004,23 +14415,23 @@ ERL_NIF_TERM ncancel_send_waiting(ErlNifEnv* env,
-/* *** ncancel_recv ***
+/* *** esock_cancel_recv ***
*
* Cancel a read operation.
* Its either the current reader or one of the waiting readers.
*/
static
-ERL_NIF_TERM ncancel_recv(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_recv(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM opRef)
{
ERL_NIF_TERM res;
MLOCK(descP->readMtx);
SSDBG( descP,
- ("SOCKET", "ncancel_recv -> entry with"
+ ("SOCKET", "esock_cancel_recv -> entry with"
"\r\n opRef: %T"
"\r\n %s"
"\r\n", opRef,
@@ -14028,9 +14439,9 @@ ERL_NIF_TERM ncancel_recv(ErlNifEnv* env,
if (descP->currentReaderP != NULL) {
if (COMPARE(opRef, descP->currentReader.ref) == 0) {
- res = ncancel_recv_current(env, descP, sockRef);
+ res = esock_cancel_recv_current(env, descP, sockRef);
} else {
- res = ncancel_recv_waiting(env, descP, opRef);
+ res = esock_cancel_recv_waiting(env, descP, opRef);
}
} else {
/* Or badarg? */
@@ -14040,7 +14451,7 @@ ERL_NIF_TERM ncancel_recv(ErlNifEnv* env,
MUNLOCK(descP->readMtx);
SSDBG( descP,
- ("SOCKET", "ncancel_recv -> done with result:"
+ ("SOCKET", "esock_cancel_recv -> done with result:"
"\r\n %T"
"\r\n", res) );
@@ -14053,31 +14464,31 @@ ERL_NIF_TERM ncancel_recv(ErlNifEnv* env,
* in the reader queue).
*/
static
-ERL_NIF_TERM ncancel_recv_current(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef)
+ERL_NIF_TERM esock_cancel_recv_current(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef)
{
ERL_NIF_TERM res;
- SSDBG( descP, ("SOCKET", "ncancel_recv_current -> entry\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_cancel_recv_current -> entry\r\n") );
- DEMONP("ncancel_recv_current -> current reader",
+ DEMONP("esock_cancel_recv_current -> current reader",
env, descP, &descP->currentReader.mon);
- res = ncancel_read_select(env, descP, descP->currentReader.ref);
+ res = esock_cancel_read_select(env, descP, descP->currentReader.ref);
SSDBG( descP,
- ("SOCKET", "ncancel_recv_current -> cancel res: %T\r\n", res) );
+ ("SOCKET", "esock_cancel_recv_current -> cancel res: %T\r\n", res) );
if (!activate_next_reader(env, descP, sockRef)) {
SSDBG( descP,
- ("SOCKET", "ncancel_recv_current -> no more readers\r\n") );
+ ("SOCKET", "esock_cancel_recv_current -> no more readers\r\n") );
descP->currentReaderP = NULL;
descP->currentReader.ref = esock_atom_undefined;
enif_set_pid_undefined(&descP->currentReader.pid);
esock_monitor_init(&descP->currentReader.mon);
}
- SSDBG( descP, ("SOCKET", "ncancel_recv_current -> done with result:"
+ SSDBG( descP, ("SOCKET", "esock_cancel_recv_current -> done with result:"
"\r\n %T"
"\r\n", res) );
@@ -14089,9 +14500,9 @@ ERL_NIF_TERM ncancel_recv_current(ErlNifEnv* env,
* remove them from the reader queue.
*/
static
-ERL_NIF_TERM ncancel_recv_waiting(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_recv_waiting(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef)
{
ErlNifPid caller;
@@ -14111,33 +14522,33 @@ ERL_NIF_TERM ncancel_recv_waiting(ErlNifEnv* env,
static
-ERL_NIF_TERM ncancel_read_select(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef)
+ERL_NIF_TERM esock_cancel_read_select(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef)
{
- return ncancel_mode_select(env, descP, opRef,
- ERL_NIF_SELECT_READ,
- ERL_NIF_SELECT_READ_CANCELLED);
+ return esock_cancel_mode_select(env, descP, opRef,
+ ERL_NIF_SELECT_READ,
+ ERL_NIF_SELECT_READ_CANCELLED);
}
static
-ERL_NIF_TERM ncancel_write_select(ErlNifEnv* env,
+ERL_NIF_TERM esock_cancel_write_select(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM opRef)
{
- return ncancel_mode_select(env, descP, opRef,
- ERL_NIF_SELECT_WRITE,
- ERL_NIF_SELECT_WRITE_CANCELLED);
+ return esock_cancel_mode_select(env, descP, opRef,
+ ERL_NIF_SELECT_WRITE,
+ ERL_NIF_SELECT_WRITE_CANCELLED);
}
static
-ERL_NIF_TERM ncancel_mode_select(ErlNifEnv* env,
- ESockDescriptor* descP,
- ERL_NIF_TERM opRef,
- int smode,
- int rmode)
+ERL_NIF_TERM esock_cancel_mode_select(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM opRef,
+ int smode,
+ int rmode)
{
int selectRes = esock_select_cancel(env, descP->sock, smode, descP);
@@ -14149,7 +14560,8 @@ ERL_NIF_TERM ncancel_mode_select(ErlNifEnv* env,
return esock_make_error(env, esock_atom_select_sent);
} else {
/* Stopped? */
- SSDBG( descP, ("SOCKET", "ncancel_mode_select -> failed: %d (0x%lX)"
+ SSDBG( descP, ("SOCKET",
+ "esock_cancel_mode_select -> failed: %d (0x%lX)"
"\r\n", selectRes, selectRes) );
return esock_make_error(env, esock_atom_einval);
}
@@ -14301,8 +14713,12 @@ ERL_NIF_TERM send_check_ok(ErlNifEnv* env,
ssize_t dataSize,
ERL_NIF_TERM sockRef)
{
- cnt_inc(&descP->writePkgCnt, 1);
- cnt_inc(&descP->writeByteCnt, written);
+ // cnt_inc(&descP->writePkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef,
+ atom_write_pkg, &descP->writePkgCnt, 1);
+ // cnt_inc(&descP->writeByteCnt, written);
+ SOCK_CNT_INC(env, descP, sockRef,
+ atom_write_byte, &descP->writeByteCnt, written);
if (descP->currentWriterP != NULL) {
DEMONP("send_check_ok -> current writer",
@@ -14348,7 +14764,8 @@ ERL_NIF_TERM send_check_fail(ErlNifEnv* env,
ERL_NIF_TERM reason;
req.env = NULL;
- cnt_inc(&descP->writeFails, 1);
+ // cnt_inc(&descP->writeFails, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_write_fails, &descP->writeFails, 1);
SSDBG( descP, ("SOCKET", "send_check_fail -> error: %d\r\n", saveErrno) );
@@ -14413,7 +14830,8 @@ ERL_NIF_TERM send_check_retry(ErlNifEnv* env,
}
}
- cnt_inc(&descP->writeWaits, 1);
+ // cnt_inc(&descP->writeWaits, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_write_waits, &descP->writeWaits, 1);
sres = esock_select_write(env, descP->sock, descP, NULL, sockRef, sendRef);
@@ -14675,6 +15093,8 @@ ERL_NIF_TERM recv_check_result(ErlNifEnv* env,
res = esock_make_error(env, atom_closed);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1);
+
/*
* When a stream socket peer has performed an orderly shutdown,
* the return value will be 0 (the traditional "end-of-file" return).
@@ -14821,7 +15241,8 @@ ERL_NIF_TERM recv_check_full_maybe_done(ErlNifEnv* env,
{
char* xres;
- cnt_inc(&descP->readByteCnt, read);
+ // cnt_inc(&descP->readByteCnt, read);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read);
if (descP->rNum > 0) {
@@ -14830,7 +15251,8 @@ ERL_NIF_TERM recv_check_full_maybe_done(ErlNifEnv* env,
descP->rNumCnt = 0;
- cnt_inc(&descP->readPkgCnt, 1);
+ // cnt_inc(&descP->readPkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1);
recv_update_current_reader(env, descP, sockRef);
@@ -14878,8 +15300,10 @@ ERL_NIF_TERM recv_check_full_done(ErlNifEnv* env,
{
ERL_NIF_TERM data;
- cnt_inc(&descP->readPkgCnt, 1);
- cnt_inc(&descP->readByteCnt, read);
+ // cnt_inc(&descP->readPkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1);
+ // cnt_inc(&descP->readByteCnt, read);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read);
recv_update_current_reader(env, descP, sockRef);
@@ -14916,6 +15340,10 @@ ERL_NIF_TERM recv_check_fail(ErlNifEnv* env,
SSDBG( descP, ("SOCKET", "recv_check_fail -> closed\r\n") );
+ // This is a bit overkill (to count here), but just in case...
+ // cnt_inc(&descP->readFails, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1);
+
res = recv_check_fail_closed(env, descP, sockRef, recvRef);
} else if ((saveErrno == ERRNO_BLOCK) ||
@@ -14930,6 +15358,9 @@ ERL_NIF_TERM recv_check_fail(ErlNifEnv* env,
SSDBG( descP, ("SOCKET", "recv_check_fail -> errno: %d\r\n",
saveErrno) );
+ // cnt_inc(&descP->readFails, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1);
+
res = recv_check_fail_gen(env, descP, saveErrno, sockRef);
}
@@ -14968,7 +15399,7 @@ ERL_NIF_TERM recv_check_fail_closed(ErlNifEnv* env,
*/
descP->closeLocal = FALSE;
- descP->state = SOCKET_STATE_CLOSING;
+ descP->state = ESOCK_STATE_CLOSING;
recv_error_current_reader(env, descP, sockRef, res);
@@ -15093,8 +15524,10 @@ ERL_NIF_TERM recv_check_partial_done(ErlNifEnv* env,
ERL_NIF_TERM data;
descP->rNumCnt = 0;
- cnt_inc(&descP->readPkgCnt, 1);
- cnt_inc(&descP->readByteCnt, read);
+ // cnt_inc(&descP->readPkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1);
+ // cnt_inc(&descP->readByteCnt, read);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read);
recv_update_current_reader(env, descP, sockRef);
@@ -15137,7 +15570,8 @@ ERL_NIF_TERM recv_check_partial_part(ErlNifEnv* env,
data = MKBIN(env, bufP);
data = MKSBIN(env, data, 0, read);
- cnt_inc(&descP->readByteCnt, read);
+ // cnt_inc(&descP->readByteCnt, read);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read);
/* SELECT for more data */
@@ -15224,6 +15658,12 @@ ERL_NIF_TERM recvfrom_check_result(ErlNifEnv* env,
data = MKSBIN(env, data, 0, read);
}
+ // cnt_inc(&descP->readPkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1);
+ // cnt_inc(&descP->readByteCnt, read);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte,
+ &descP->readByteCnt, read);
+
recv_update_current_reader(env, descP, sockRef);
res = esock_make_ok2(env, MKT2(env, eSockAddr, data));
@@ -15281,6 +15721,7 @@ ERL_NIF_TERM recvmsg_check_result(ErlNifEnv* env,
* *We* do never actually try to read 0 bytes from a stream socket!
*/
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1);
FREE_BIN(dataBufP); FREE_BIN(ctrlBufP);
@@ -15351,6 +15792,21 @@ ERL_NIF_TERM recvmsg_check_msg(ErlNifEnv* env,
"recvmsg_check_result -> "
"(msghdr) encode failed: %s\r\n", xres) );
+ /* So this is a bit strange. We did "successfully" read 'read' bytes,
+ * but then we fail to process the message header. So what counters
+ * shall we increment?
+ * Only failure?
+ * Or only success (pkg and byte), since the read was "ok" (or was it?)
+ * Or all of them?
+ *
+ * For now, we increment all three...
+ */
+
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte,
+ &descP->readByteCnt, read);
+
recv_update_current_reader(env, descP, sockRef);
FREE_BIN(dataBufP); FREE_BIN(ctrlBufP);
@@ -15362,6 +15818,10 @@ ERL_NIF_TERM recvmsg_check_msg(ErlNifEnv* env,
SSDBG( descP,
("SOCKET", "recvmsg_check_result -> (msghdr) encode ok\r\n") );
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1);
+ SOCK_CNT_INC(env, descP, sockRef, atom_read_byte,
+ &descP->readByteCnt, read);
+
recv_update_current_reader(env, descP, sockRef);
res = esock_make_ok2(env, eMsgHdr);
@@ -16959,11 +17419,11 @@ BOOLEAN_T decode_native_get_opt(ErlNifEnv* env, ERL_NIF_TERM eVal,
if (COMPARE(nativeOptT[1], atom_int) == 0) {
SGDBG( ("SOCKET", "decode_native_get_opt -> int\r\n") );
- *valueType = SOCKET_OPT_VALUE_TYPE_INT;
+ *valueType = ESOCK_OPT_VALUE_TYPE_INT;
*valueSz = sizeof(int); // Just to be sure
} else if (COMPARE(nativeOptT[1], atom_bool) == 0) {
SGDBG( ("SOCKET", "decode_native_get_opt -> bool\r\n") );
- *valueType = SOCKET_OPT_VALUE_TYPE_BOOL;
+ *valueType = ESOCK_OPT_VALUE_TYPE_BOOL;
*valueSz = sizeof(int); // Just to be sure
} else {
return FALSE;
@@ -16971,7 +17431,7 @@ BOOLEAN_T decode_native_get_opt(ErlNifEnv* env, ERL_NIF_TERM eVal,
} else if (IS_NUM(env, nativeOptT[1])) {
if (GET_INT(env, nativeOptT[1], valueSz)) {
SGDBG( ("SOCKET", "decode_native_get_opt -> unspec\r\n") );
- *valueType = SOCKET_OPT_VALUE_TYPE_UNSPEC;
+ *valueType = ESOCK_OPT_VALUE_TYPE_UNSPEC;
} else {
return FALSE;
}
@@ -17038,7 +17498,7 @@ ESockDescriptor* alloc_descriptor(SOCKET sock, HANDLE event)
{
ESockDescriptor* descP;
- if ((descP = enif_alloc_resource(sockets, sizeof(ESockDescriptor))) != NULL) {
+ if ((descP = enif_alloc_resource(esocks, sizeof(ESockDescriptor))) != NULL) {
char buf[64]; /* Buffer used for building the mutex name */
descP->pattern = ESOCK_DESC_PATTERN_CREATED;
@@ -17076,6 +17536,7 @@ ESockDescriptor* alloc_descriptor(SOCKET sock, HANDLE event)
descP->readByteCnt = 0;
descP->readTries = 0;
descP->readWaits = 0;
+ descP->readFails = 0;
sprintf(buf, "esock[acc,%d]", sock);
descP->accMtx = MCREATE(buf);
@@ -17096,13 +17557,13 @@ ESockDescriptor* alloc_descriptor(SOCKET sock, HANDLE event)
sprintf(buf, "esock[cfg,%d]", sock);
descP->cfgMtx = MCREATE(buf);
- descP->rBufSz = SOCKET_RECV_BUFFER_SIZE_DEFAULT;
+ descP->rBufSz = ESOCK_RECV_BUFFER_SIZE_DEFAULT;
descP->rNum = 0;
descP->rNumCnt = 0;
- descP->rCtrlSz = SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT;
- descP->wCtrlSz = SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT;
+ descP->rCtrlSz = ESOCK_RECV_CTRL_BUFFER_SIZE_DEFAULT;
+ descP->wCtrlSz = ESOCK_SEND_CTRL_BUFFER_SIZE_DEFAULT;
descP->iow = FALSE;
- descP->dbg = SOCKET_DEBUG_DEFAULT;
+ descP->dbg = ESOCK_DEBUG_DEFAULT;
descP->sock = sock;
descP->event = event;
@@ -17229,17 +17690,17 @@ static
BOOLEAN_T edomain2domain(int edomain, int* domain)
{
switch (edomain) {
- case SOCKET_DOMAIN_INET:
+ case ESOCK_DOMAIN_INET:
*domain = AF_INET;
break;
#if defined(HAVE_IN6) && defined(AF_INET6)
- case SOCKET_DOMAIN_INET6:
+ case ESOCK_DOMAIN_INET6:
*domain = AF_INET6;
break;
#endif
#ifdef HAVE_SYS_UN_H
- case SOCKET_DOMAIN_LOCAL:
+ case ESOCK_DOMAIN_LOCAL:
*domain = AF_UNIX;
break;
#endif
@@ -17261,20 +17722,20 @@ static
BOOLEAN_T etype2type(int etype, int* type)
{
switch (etype) {
- case SOCKET_TYPE_STREAM:
+ case ESOCK_TYPE_STREAM:
*type = SOCK_STREAM;
break;
- case SOCKET_TYPE_DGRAM:
+ case ESOCK_TYPE_DGRAM:
*type = SOCK_DGRAM;
break;
- case SOCKET_TYPE_RAW:
+ case ESOCK_TYPE_RAW:
*type = SOCK_RAW;
break;
#ifdef HAVE_SCTP
- case SOCKET_TYPE_SEQPACKET:
+ case ESOCK_TYPE_SEQPACKET:
*type = SOCK_SEQPACKET;
break;
#endif
@@ -17306,33 +17767,33 @@ BOOLEAN_T eproto2proto(ErlNifEnv* env,
}
switch (ep) {
- case SOCKET_PROTOCOL_DEFAULT:
+ case ESOCK_PROTOCOL_DEFAULT:
*proto = 0; // default - note that _IP also has the value 0...
break;
- case SOCKET_PROTOCOL_IP:
+ case ESOCK_PROTOCOL_IP:
*proto = IPPROTO_IP;
break;
- case SOCKET_PROTOCOL_TCP:
+ case ESOCK_PROTOCOL_TCP:
*proto = IPPROTO_TCP;
break;
- case SOCKET_PROTOCOL_UDP:
+ case ESOCK_PROTOCOL_UDP:
*proto = IPPROTO_UDP;
break;
#if defined(HAVE_SCTP)
- case SOCKET_PROTOCOL_SCTP:
+ case ESOCK_PROTOCOL_SCTP:
*proto = IPPROTO_SCTP;
break;
#endif
- case SOCKET_PROTOCOL_ICMP:
+ case ESOCK_PROTOCOL_ICMP:
*proto = IPPROTO_ICMP;
break;
- case SOCKET_PROTOCOL_IGMP:
+ case ESOCK_PROTOCOL_IGMP:
*proto = IPPROTO_IGMP;
break;
@@ -17441,47 +17902,47 @@ BOOLEAN_T esendflags2sendflags(unsigned int eflags, int* flags)
return TRUE;
}
- for (ef = SOCKET_SEND_FLAG_LOW; ef <= SOCKET_SEND_FLAG_HIGH; ef++) {
+ for (ef = ESOCK_SEND_FLAG_LOW; ef <= ESOCK_SEND_FLAG_HIGH; ef++) {
switch (ef) {
#if defined(MSG_CONFIRM)
- case SOCKET_SEND_FLAG_CONFIRM:
- if ((1 << SOCKET_SEND_FLAG_CONFIRM) & eflags)
+ case ESOCK_SEND_FLAG_CONFIRM:
+ if ((1 << ESOCK_SEND_FLAG_CONFIRM) & eflags)
tmp |= MSG_CONFIRM;
break;
#endif
#if defined(MSG_DONTROUTE)
- case SOCKET_SEND_FLAG_DONTROUTE:
- if ((1 << SOCKET_SEND_FLAG_DONTROUTE) & eflags)
+ case ESOCK_SEND_FLAG_DONTROUTE:
+ if ((1 << ESOCK_SEND_FLAG_DONTROUTE) & eflags)
tmp |= MSG_DONTROUTE;
break;
#endif
#if defined(MSG_EOR)
- case SOCKET_SEND_FLAG_EOR:
- if ((1 << SOCKET_SEND_FLAG_EOR) & eflags)
+ case ESOCK_SEND_FLAG_EOR:
+ if ((1 << ESOCK_SEND_FLAG_EOR) & eflags)
tmp |= MSG_EOR;
break;
#endif
#if defined(MSG_MORE)
- case SOCKET_SEND_FLAG_MORE:
- if ((1 << SOCKET_SEND_FLAG_MORE) & eflags)
+ case ESOCK_SEND_FLAG_MORE:
+ if ((1 << ESOCK_SEND_FLAG_MORE) & eflags)
tmp |= MSG_MORE;
break;
#endif
#if defined(MSG_NOSIGNAL)
- case SOCKET_SEND_FLAG_NOSIGNAL:
- if ((1 << SOCKET_SEND_FLAG_NOSIGNAL) & eflags)
+ case ESOCK_SEND_FLAG_NOSIGNAL:
+ if ((1 << ESOCK_SEND_FLAG_NOSIGNAL) & eflags)
tmp |= MSG_NOSIGNAL;
break;
#endif
#if defined(MSG_OOB)
- case SOCKET_SEND_FLAG_OOB:
- if ((1 << SOCKET_SEND_FLAG_OOB) & eflags)
+ case ESOCK_SEND_FLAG_OOB:
+ if ((1 << ESOCK_SEND_FLAG_OOB) & eflags)
tmp |= MSG_OOB;
break;
#endif
@@ -17517,7 +17978,7 @@ BOOLEAN_T erecvflags2recvflags(unsigned int eflags, int* flags)
return TRUE;
}
- for (ef = SOCKET_RECV_FLAG_LOW; ef <= SOCKET_RECV_FLAG_HIGH; ef++) {
+ for (ef = ESOCK_RECV_FLAG_LOW; ef <= ESOCK_RECV_FLAG_HIGH; ef++) {
SGDBG( ("SOCKET", "erecvflags2recvflags -> iteration"
"\r\n ef: %d"
@@ -17526,22 +17987,22 @@ BOOLEAN_T erecvflags2recvflags(unsigned int eflags, int* flags)
switch (ef) {
#if defined(MSG_CMSG_CLOEXEC)
- case SOCKET_RECV_FLAG_CMSG_CLOEXEC:
- if ((1 << SOCKET_RECV_FLAG_CMSG_CLOEXEC) & eflags)
+ case ESOCK_RECV_FLAG_CMSG_CLOEXEC:
+ if ((1 << ESOCK_RECV_FLAG_CMSG_CLOEXEC) & eflags)
tmp |= MSG_CMSG_CLOEXEC;
break;
#endif
#if defined(MSG_ERRQUEUE)
- case SOCKET_RECV_FLAG_ERRQUEUE:
- if ((1 << SOCKET_RECV_FLAG_ERRQUEUE) & eflags)
+ case ESOCK_RECV_FLAG_ERRQUEUE:
+ if ((1 << ESOCK_RECV_FLAG_ERRQUEUE) & eflags)
tmp |= MSG_ERRQUEUE;
break;
#endif
#if defined(MSG_OOB)
- case SOCKET_RECV_FLAG_OOB:
- if ((1 << SOCKET_RECV_FLAG_OOB) & eflags)
+ case ESOCK_RECV_FLAG_OOB:
+ if ((1 << ESOCK_RECV_FLAG_OOB) & eflags)
tmp |= MSG_OOB;
break;
#endif
@@ -17554,15 +18015,15 @@ BOOLEAN_T erecvflags2recvflags(unsigned int eflags, int* flags)
* </KOLLA>
*/
#if defined(MSG_PEEK)
- case SOCKET_RECV_FLAG_PEEK:
- if ((1 << SOCKET_RECV_FLAG_PEEK) & eflags)
+ case ESOCK_RECV_FLAG_PEEK:
+ if ((1 << ESOCK_RECV_FLAG_PEEK) & eflags)
tmp |= MSG_PEEK;
break;
#endif
#if defined(MSG_TRUNC)
- case SOCKET_RECV_FLAG_TRUNC:
- if ((1 << SOCKET_RECV_FLAG_TRUNC) & eflags)
+ case ESOCK_RECV_FLAG_TRUNC:
+ if ((1 << ESOCK_RECV_FLAG_TRUNC) & eflags)
tmp |= MSG_TRUNC;
break;
#endif
@@ -17588,15 +18049,15 @@ static
BOOLEAN_T ehow2how(unsigned int ehow, int* how)
{
switch (ehow) {
- case SOCKET_SHUTDOWN_HOW_RD:
+ case ESOCK_SHUTDOWN_HOW_RD:
*how = SHUT_RD;
break;
- case SOCKET_SHUTDOWN_HOW_WR:
+ case ESOCK_SHUTDOWN_HOW_WR:
*how = SHUT_WR;
break;
- case SOCKET_SHUTDOWN_HOW_RDWR:
+ case ESOCK_SHUTDOWN_HOW_RDWR:
*how = SHUT_RDWR;
break;
@@ -17609,6 +18070,59 @@ BOOLEAN_T ehow2how(unsigned int ehow, int* how)
+/* ecommand2command - convert erlang command to "native" command (and data)
+ */
+static
+BOOLEAN_T ecommand2command(ErlNifEnv* env,
+ ERL_NIF_TERM ecommand,
+ Uint16* command,
+ ERL_NIF_TERM* edata)
+{
+ size_t sz;
+ ERL_NIF_TERM ecmd;
+
+ if (!IS_MAP(env, ecommand)) {
+ SGDBG( ("SOCKET", "ecommand2command -> (e)command not a map\r\n") );
+ return FALSE;
+ }
+
+ /* The map shall have exactly two attrbutes:
+ * 'command' and 'data'
+ */
+ if (!enif_get_map_size(env, ecommand, &sz) || (sz != 2)) {
+ SGDBG( ("SOCKET", "ecommand2command -> comamnd map size invalid\r\n") );
+ return FALSE;
+ }
+
+ /* Get the command value, and transform into integer
+ * (might as well do that, since theer is no point in
+ * extracting the data if command is invalid).
+ */
+ if (!GET_MAP_VAL(env, ecommand, esock_atom_command, &ecmd)) {
+ SGDBG( ("SOCKET", "ecommand2command -> command attribute not found\r\n") );
+ return FALSE;
+ }
+ if (COMPARE(ecmd, esock_atom_debug) == 0) {
+ *command = ESOCK_CMD_DEBUG;
+ } else {
+ SGDBG( ("SOCKET", "ecommand2command -> unknown command %T\r\n", ecmd) );
+ return FALSE;
+ }
+
+ /* Get the command data value, we do *not* convert it to
+ * the native form (here) since it may "in theory" be complex.
+ */
+ if (!GET_MAP_VAL(env, ecommand, esock_atom_data, edata)) {
+ SGDBG( ("SOCKET", "ecommand2command -> (command) data not found\r\n") );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+
#if defined(HAVE_SYS_UN_H) || defined(SO_BINDTODEVICE)
/* strnlen doesn't exist everywhere */
/*
@@ -17624,6 +18138,25 @@ size_t my_strnlen(const char *s, size_t maxlen)
#endif
+/* Send an counter wrap message to the controlling process:
+ * A message in the form:
+ *
+ * {'$socket', Socket, counter_wrap, Counter :: atom()}
+ *
+ * This message will only be sent if the iow (Inform On Wrap) is TRUE.
+ */
+static
+char* esock_send_wrap_msg(ErlNifEnv* env,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM cnt)
+{
+ ERL_NIF_TERM msg = mk_wrap_msg(env, sockRef, cnt);
+
+ return esock_send_msg(env, &descP->ctrlPid, msg, NULL);
+}
+
+
/* Send an close message to the specified process:
* A message in the form:
*
@@ -17721,6 +18254,22 @@ ERL_NIF_TERM mk_abort_msg(ErlNifEnv* env,
}
+/* *** mk_wrap_msg ***
+ *
+ * Construct a counter wrap (socket) message. It has the form:
+ *
+ * {'$socket', Socket, counter_wrap, Counter}
+ *
+ */
+static
+ERL_NIF_TERM mk_wrap_msg(ErlNifEnv* env,
+ ERL_NIF_TERM sockRef,
+ ERL_NIF_TERM cnt)
+{
+ return mk_socket_msg(env, sockRef, atom_counter_wrap, cnt);
+}
+
+
/* *** mk_close_msg ***
*
* Construct a close (socket) message. It has the form:
@@ -18376,11 +18925,11 @@ static void free_request_queue(ESockRequestQueue* q)
}
/* =========================================================================
- * socket_dtor - Callback function for resource destructor
+ * esock_dtor - Callback function for resource destructor
*
*/
static
-void socket_dtor(ErlNifEnv* env, void* obj)
+void esock_dtor(ErlNifEnv* env, void* obj)
{
#if !defined(__WIN32__)
ESockDescriptor* descP = (ESockDescriptor*) obj;
@@ -18407,14 +18956,14 @@ void socket_dtor(ErlNifEnv* env, void* obj)
free_request_queue(&descP->writersQ);
free_request_queue(&descP->acceptorsQ);
- descP->state = SOCKET_STATE_DTOR;
+ descP->state = ESOCK_STATE_DTOR;
descP->pattern = ESOCK_DESC_PATTERN_DTOR;
#endif
}
/* =========================================================================
- * socket_stop - Callback function for resource stop
+ * esock_stop - Callback function for resource stop
*
* When the socket is stopped, we need to inform:
*
@@ -18429,14 +18978,14 @@ void socket_dtor(ErlNifEnv* env, void* obj)
*
*/
static
-void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
+void esock_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
{
#if !defined(__WIN32__)
ESockDescriptor* descP = (ESockDescriptor*) obj;
ERL_NIF_TERM sockRef;
SSDBG( descP,
- ("SOCKET", "socket_stop -> entry when %s"
+ ("SOCKET", "esock_stop -> entry when %s"
"\r\n sock: %d (%d)"
"\r\n",
((is_direct_call) ? "called" : "scheduled"), descP->sock, fd) );
@@ -18449,7 +18998,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
MLOCK(descP->cfgMtx);
if (!is_direct_call) MLOCK(descP->closeMtx);
- SSDBG( descP, ("SOCKET", "socket_stop -> "
+ SSDBG( descP, ("SOCKET", "esock_stop -> "
"[%d, %T] all mutex(s) locked when counters:"
"\r\n writePkgCnt: %u"
"\r\n writeByteCnt: %u"
@@ -18473,7 +19022,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
descP->readWaits) );
sockRef = enif_make_resource(env, descP);
- descP->state = SOCKET_STATE_CLOSING; // Just in case...???
+ descP->state = ESOCK_STATE_CLOSING; // Just in case...???
descP->isReadable = FALSE;
descP->isWritable = FALSE;
@@ -18484,7 +19033,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
* there is no point to demonitor. Also, we do not actually
* have a monitor in that case...
*/
- DEMONP("socket_stop -> ctrl", env, descP, &descP->ctrlMon);
+ DEMONP("esock_stop -> ctrl", env, descP, &descP->ctrlMon);
@@ -18501,12 +19050,12 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
* writers waiting.
*/
- socket_stop_handle_current(env,
- "writer",
- descP, sockRef, &descP->currentWriter);
+ esock_stop_handle_current(env,
+ "writer",
+ descP, sockRef, &descP->currentWriter);
/* And also deal with the waiting writers (in the same way) */
- SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting writer(s)\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_stop -> handle waiting writer(s)\r\n") );
inform_waiting_procs(env, "writer",
descP, sockRef, &descP->writersQ, TRUE, atom_closed);
}
@@ -18525,12 +19074,12 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
* readers waiting.
*/
- socket_stop_handle_current(env,
- "reader",
- descP, sockRef, &descP->currentReader);
+ esock_stop_handle_current(env,
+ "reader",
+ descP, sockRef, &descP->currentReader);
/* And also deal with the waiting readers (in the same way) */
- SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting reader(s)\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_stop -> handle waiting reader(s)\r\n") );
inform_waiting_procs(env, "reader",
descP, sockRef, &descP->readersQ, TRUE, atom_closed);
}
@@ -18550,12 +19099,12 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
* acceptors waiting.
*/
- socket_stop_handle_current(env,
- "acceptor",
- descP, sockRef, &descP->currentAcceptor);
-
+ esock_stop_handle_current(env,
+ "acceptor",
+ descP, sockRef, &descP->currentAcceptor);
+
/* And also deal with the waiting acceptors (in the same way) */
- SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting acceptor(s)\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_stop -> handle waiting acceptor(s)\r\n") );
inform_waiting_procs(env, "acceptor",
descP, sockRef, &descP->acceptorsQ, TRUE, atom_closed);
}
@@ -18579,7 +19128,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
esock_send_close_msg(env, descP, &descP->closerPid);
- DEMONP("socket_stop -> closer", env, descP, &descP->closerMon);
+ DEMONP("esock_stop -> closer", env, descP, &descP->closerMon);
} else {
@@ -18588,14 +19137,14 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
*/
if (descP->closeEnv != NULL)
- esock_free_env("socket_stop - close-env", descP->closeEnv);
+ esock_free_env("esock_stop - close-env", descP->closeEnv);
}
}
}
- SSDBG( descP, ("SOCKET", "socket_stop -> unlock all mutex(s)\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_stop -> unlock all mutex(s)\r\n") );
if (!is_direct_call) MUNLOCK(descP->closeMtx);
MUNLOCK(descP->cfgMtx);
@@ -18604,33 +19153,33 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
MUNLOCK(descP->writeMtx);
SSDBG( descP,
- ("SOCKET", "socket_stop -> done (%d, %d)\r\n", descP->sock, fd) );
+ ("SOCKET", "esock_stop -> done (%d, %d)\r\n", descP->sock, fd) );
#endif // if !defined(__WIN32__)
}
-/* *** socket_stop_handle_current ***
+/* *** esock_stop_handle_current ***
*
* Handle current requestor (reader, writer or acceptor) during
* socket stop.
*/
#if !defined(__WIN32__)
static
-void socket_stop_handle_current(ErlNifEnv* env,
- const char* role,
- ESockDescriptor* descP,
- ERL_NIF_TERM sockRef,
- ESockRequestor* reqP)
+void esock_stop_handle_current(ErlNifEnv* env,
+ const char* role,
+ ESockDescriptor* descP,
+ ERL_NIF_TERM sockRef,
+ ESockRequestor* reqP)
{
- SSDBG( descP, ("SOCKET", "socket_stop -> handle current %s\r\n", role) );
+ SSDBG( descP, ("SOCKET", "esock_stop -> handle current %s\r\n", role) );
- DEMONP("socket_stop_handle_current", env, descP, &reqP->mon);
+ DEMONP("esock_stop_handle_current", env, descP, &reqP->mon);
if (COMPARE_PIDS(&descP->closerPid, &reqP->pid) != 0) {
- SSDBG( descP, ("SOCKET", "socket_stop_handle_current -> "
+ SSDBG( descP, ("SOCKET", "esock_stop_handle_current -> "
"send abort message to current %s %T\r\n",
role, reqP->pid) );
@@ -18715,21 +19264,21 @@ void inform_waiting_procs(ErlNifEnv* env,
/* =========================================================================
- * socket_down - Callback function for resource down (monitored processes)
+ * esock_down - Callback function for resource down (monitored processes)
*
*/
static
-void socket_down(ErlNifEnv* env,
- void* obj,
- const ErlNifPid* pid,
- const ErlNifMonitor* mon)
+void esock_down(ErlNifEnv* env,
+ void* obj,
+ const ErlNifPid* pid,
+ const ErlNifMonitor* mon)
{
#if !defined(__WIN32__)
ESockDescriptor* descP = (ESockDescriptor*) obj;
int sres;
ERL_NIF_TERM sockRef;
- SSDBG( descP, ("SOCKET", "socket_down -> entry with"
+ SSDBG( descP, ("SOCKET", "esock_down -> entry with"
"\r\n sock: %d"
"\r\n pid: %T"
"\r\n Close: %s (%s)"
@@ -18747,9 +19296,9 @@ void socket_down(ErlNifEnv* env,
*/
SSDBG( descP,
- ("SOCKET", "socket_down -> controlling process exit\r\n") );
+ ("SOCKET", "esock_down -> controlling process exit\r\n") );
- descP->state = SOCKET_STATE_CLOSING;
+ descP->state = ESOCK_STATE_CLOSING;
descP->closeLocal = TRUE;
descP->closerPid = *pid;
MON_INIT(&descP->closerMon);
@@ -18761,10 +19310,10 @@ void socket_down(ErlNifEnv* env,
/* We are done - we can finalize (socket close) directly */
SSDBG( descP,
("SOCKET",
- "socket_down -> [%d] stop called\r\n", descP->sock) );
+ "esock_down -> [%d] stop called\r\n", descP->sock) );
dec_socket(descP->domain, descP->type, descP->protocol);
- descP->state = SOCKET_STATE_CLOSED;
+ descP->state = ESOCK_STATE_CLOSED;
/* And finally close the socket.
* Since we close the socket because of an exiting owner,
@@ -18787,7 +19336,7 @@ void socket_down(ErlNifEnv* env,
descP->sock = INVALID_SOCKET;
descP->event = INVALID_EVENT;
- descP->state = SOCKET_STATE_CLOSED;
+ descP->state = ESOCK_STATE_CLOSED;
} else if (sres & ERL_NIF_SELECT_STOP_SCHEDULED) {
@@ -18798,7 +19347,7 @@ void socket_down(ErlNifEnv* env,
*/
SSDBG( descP,
("SOCKET",
- "socket_down -> [%d] stop scheduled\r\n",
+ "esock_down -> [%d] stop scheduled\r\n",
descP->sock) );
dec_socket(descP->domain, descP->type, descP->protocol);
@@ -18838,9 +19387,9 @@ void socket_down(ErlNifEnv* env,
* The same goes for the monitor (connMon).
*/
- descP->state = SOCKET_STATE_OPEN; /* restore state */
+ descP->state = ESOCK_STATE_OPEN; /* restore state */
enif_set_pid_undefined(&descP->connPid);
- DEMONP("socket_down -> connector",
+ DEMONP("esock_down -> connector",
env, descP, &descP->connMon);
} else {
@@ -18851,43 +19400,43 @@ void socket_down(ErlNifEnv* env,
*
*/
- SSDBG( descP, ("SOCKET", "socket_down -> other process term\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_down -> other process term\r\n") );
sockRef = enif_make_resource(env, descP);
MLOCK(descP->accMtx);
if (descP->currentAcceptorP != NULL)
- socket_down_acceptor(env, descP, sockRef, pid);
+ esock_down_acceptor(env, descP, sockRef, pid);
MUNLOCK(descP->accMtx);
MLOCK(descP->writeMtx);
if (descP->currentWriterP != NULL)
- socket_down_writer(env, descP, sockRef, pid);
+ esock_down_writer(env, descP, sockRef, pid);
MUNLOCK(descP->writeMtx);
MLOCK(descP->readMtx);
if (descP->currentReaderP != NULL)
- socket_down_reader(env, descP, sockRef, pid);
+ esock_down_reader(env, descP, sockRef, pid);
MUNLOCK(descP->readMtx);
}
}
- SSDBG( descP, ("SOCKET", "socket_down -> done\r\n") );
+ SSDBG( descP, ("SOCKET", "esock_down -> done\r\n") );
#endif // if !defined(__WIN32__)
}
-/* *** socket_down_acceptor ***
+/* *** esock_down_acceptor ***
*
* Check and then handle a downed acceptor process.
*
*/
#if !defined(__WIN32__)
static
-void socket_down_acceptor(ErlNifEnv* env,
+void esock_down_acceptor(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM sockRef,
const ErlNifPid* pid)
@@ -18895,15 +19444,15 @@ void socket_down_acceptor(ErlNifEnv* env,
if (COMPARE_PIDS(&descP->currentAcceptor.pid, pid) == 0) {
SSDBG( descP, ("SOCKET",
- "socket_down_acceptor -> "
+ "esock_down_acceptor -> "
"current acceptor - try activate next\r\n") );
if (!activate_next_acceptor(env, descP, sockRef)) {
SSDBG( descP,
- ("SOCKET", "socket_down_acceptor -> no more writers\r\n") );
+ ("SOCKET", "esock_down_acceptor -> no more writers\r\n") );
- descP->state = SOCKET_STATE_LISTENING;
+ descP->state = ESOCK_STATE_LISTENING;
descP->currentAcceptorP = NULL;
descP->currentAcceptor.ref = esock_atom_undefined;
@@ -18916,7 +19465,7 @@ void socket_down_acceptor(ErlNifEnv* env,
/* Maybe unqueue one of the waiting acceptors */
SSDBG( descP, ("SOCKET",
- "socket_down_acceptor -> "
+ "esock_down_acceptor -> "
"not current acceptor - maybe a waiting acceptor\r\n") );
acceptor_unqueue(env, descP, pid);
@@ -18926,13 +19475,13 @@ void socket_down_acceptor(ErlNifEnv* env,
-/* *** socket_down_writer ***
+/* *** esock_down_writer ***
*
* Check and then handle a downed writer process.
*
*/
static
-void socket_down_writer(ErlNifEnv* env,
+void esock_down_writer(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM sockRef,
const ErlNifPid* pid)
@@ -18940,12 +19489,12 @@ void socket_down_writer(ErlNifEnv* env,
if (COMPARE_PIDS(&descP->currentWriter.pid, pid) == 0) {
SSDBG( descP, ("SOCKET",
- "socket_down_writer -> "
+ "esock_down_writer -> "
"current writer - try activate next\r\n") );
if (!activate_next_writer(env, descP, sockRef)) {
SSDBG( descP, ("SOCKET",
- "socket_down_writer -> no active writer\r\n") );
+ "esock_down_writer -> no active writer\r\n") );
descP->currentWriterP = NULL;
descP->currentWriter.ref = esock_atom_undefined;
enif_set_pid_undefined(&descP->currentWriter.pid);
@@ -18957,7 +19506,7 @@ void socket_down_writer(ErlNifEnv* env,
/* Maybe unqueue one of the waiting writer(s) */
SSDBG( descP, ("SOCKET",
- "socket_down_writer -> "
+ "esock_down_writer -> "
"not current writer - maybe a waiting writer\r\n") );
writer_unqueue(env, descP, pid);
@@ -18967,13 +19516,13 @@ void socket_down_writer(ErlNifEnv* env,
-/* *** socket_down_reader ***
+/* *** esock_down_reader ***
*
* Check and then handle a downed reader process.
*
*/
static
-void socket_down_reader(ErlNifEnv* env,
+void esock_down_reader(ErlNifEnv* env,
ESockDescriptor* descP,
ERL_NIF_TERM sockRef,
const ErlNifPid* pid)
@@ -18981,12 +19530,13 @@ void socket_down_reader(ErlNifEnv* env,
if (COMPARE_PIDS(&descP->currentReader.pid, pid) == 0) {
SSDBG( descP, ("SOCKET",
- "socket_down_reader -> "
+ "esock_down_reader -> "
"current reader - try activate next\r\n") );
if (!activate_next_reader(env, descP, sockRef)) {
SSDBG( descP,
- ("SOCKET", "ncancel_recv_current -> no more readers\r\n") );
+ ("SOCKET",
+ "esock_down_reader -> no more readers\r\n") );
descP->currentReaderP = NULL;
descP->currentReader.ref = esock_atom_undefined;
enif_set_pid_undefined(&descP->currentReader.pid);
@@ -18998,7 +19548,7 @@ void socket_down_reader(ErlNifEnv* env,
/* Maybe unqueue one of the waiting reader(s) */
SSDBG( descP, ("SOCKET",
- "socket_down_reader -> "
+ "esock_down_reader -> "
"not current reader - maybe a waiting reader\r\n") );
reader_unqueue(env, descP, pid);
@@ -19014,16 +19564,16 @@ void socket_down_reader(ErlNifEnv* env,
*/
static
-ErlNifFunc socket_funcs[] =
+ErlNifFunc esock_funcs[] =
{
// Some utility and support functions
{"nif_info", 0, nif_info, 0},
+ {"nif_info", 1, nif_info, 0},
{"nif_supports", 1, nif_supports, 0},
- // {"nif_debug", 1, nif_debug, 0},
- // {"nif_command", 1, nif_command, 0},
+ {"nif_command", 1, nif_command, 0},
// The proper "socket" interface
- // nif_open/1 is used when we already have a file descriptor
+ // nif_open/1 is (supposed to be) used when we already have a file descriptor
// {"nif_open", 1, nif_open, 0},
{"nif_open", 4, nif_open, 0},
{"nif_bind", 2, nif_bind, 0},
@@ -19066,7 +19616,7 @@ BOOLEAN_T extract_debug(ErlNifEnv* env,
*/
ERL_NIF_TERM debug = MKA(env, "debug");
- return esock_extract_bool_from_map(env, map, debug, SOCKET_GLOBAL_DEBUG_DEFAULT);
+ return esock_extract_bool_from_map(env, map, debug, ESOCK_GLOBAL_DEBUG_DEFAULT);
}
static
@@ -19079,7 +19629,7 @@ BOOLEAN_T extract_iow(ErlNifEnv* env,
*/
ERL_NIF_TERM iow = MKA(env, "iow");
- return esock_extract_bool_from_map(env, map, iow, SOCKET_NIF_IOW_DEFAULT);
+ return esock_extract_bool_from_map(env, map, iow, ESOCK_NIF_IOW_DEFAULT);
}
#endif // if !defined(__WIN32__)
@@ -19100,7 +19650,7 @@ int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
data.iow = extract_iow(env, load_info);
/* +++ Global Counters +++ */
- data.cntMtx = MCREATE("socket[gcnt]");
+ data.cntMtx = MCREATE("esock[gcnt]");
data.numSockets = 0;
data.numTypeDGrams = 0;
data.numTypeStreams = 0;
@@ -19127,13 +19677,21 @@ GLOBAL_ERROR_REASON_ATOMS
#undef GLOBAL_ATOM_DECL
esock_atom_socket_tag = MKA(env, "$socket");
- sockets = enif_open_resource_type_x(env,
- "sockets",
- &socketInit,
- ERL_NIF_RT_CREATE,
- NULL);
+ esocks = enif_open_resource_type_x(env,
+ "sockets",
+ &esockInit,
+ ERL_NIF_RT_CREATE,
+ NULL);
- return !sockets;
+ return !esocks;
}
-ERL_NIF_INIT(socket, socket_funcs, on_load, NULL, NULL, NULL)
+/*
+ * MODULE: socket (the erlang API/interface module)
+ * funcs: esock_funcs (defines the API of this nif)
+ * load: on_load (load this nif)
+ * upgrade: NULL (not used)
+ * NULL: THIS IS NOT USED
+ * unload: NULL (not used)
+ */
+ERL_NIF_INIT(socket, esock_funcs, on_load, NULL, NULL, NULL)
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index 2740cb51ef..54c310ecc7 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -741,16 +741,24 @@ char* esock_decode_ip4_address(ErlNifEnv* env,
"\r\n", eAddr) );
if (IS_ATOM(env, eAddr)) {
- /* This is either 'any' or 'loopback' */
+
+ /* This is either 'any' | 'broadcast' | 'loopback' */
if (COMPARE(esock_atom_loopback, eAddr) == 0) {
- UDBG( ("SUTIL", "esock_decode_ip4_address -> address: lookback\r\n") );
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: lookback\r\n") );
addr.s_addr = htonl(INADDR_LOOPBACK);
} else if (COMPARE(esock_atom_any, eAddr) == 0) {
- UDBG( ("SUTIL", "esock_decode_ip4_address -> address: any\r\n") );
- addr.s_addr = htonl(INADDR_ANY);
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: any\r\n") );
+ addr.s_addr = htonl(INADDR_ANY);
+ } else if (COMPARE(esock_atom_broadcast, eAddr) == 0) {
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: broadcast\r\n") );
+ addr.s_addr = htonl(INADDR_BROADCAST);
} else {
- UDBG( ("SUTIL", "esock_decode_ip4_address -> address: unknown\r\n") );
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: unknown\r\n") );
return ESOCK_STR_EINVAL;
}
diff --git a/erts/emulator/pcre/LICENCE b/erts/emulator/pcre/LICENCE
index f6ef7fd766..760a6666b6 100644
--- a/erts/emulator/pcre/LICENCE
+++ b/erts/emulator/pcre/LICENCE
@@ -25,7 +25,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2018 University of Cambridge
+Copyright (c) 1997-2019 University of Cambridge
All rights reserved.
@@ -34,9 +34,9 @@ PCRE JUST-IN-TIME COMPILATION SUPPORT
Written by: Zoltan Herczeg
Email local part: hzmester
-Emain domain: freemail.hu
+Email domain: freemail.hu
-Copyright(c) 2010-2018 Zoltan Herczeg
+Copyright(c) 2010-2019 Zoltan Herczeg
All rights reserved.
@@ -45,9 +45,9 @@ STACK-LESS JUST-IN-TIME COMPILER
Written by: Zoltan Herczeg
Email local part: hzmester
-Emain domain: freemail.hu
+Email domain: freemail.hu
-Copyright(c) 2009-2018 Zoltan Herczeg
+Copyright(c) 2009-2019 Zoltan Herczeg
All rights reserved.
diff --git a/erts/emulator/pcre/pcre-8.42.tar.bz2 b/erts/emulator/pcre/pcre-8.42.tar.bz2
deleted file mode 100644
index 61bfa38970..0000000000
--- a/erts/emulator/pcre/pcre-8.42.tar.bz2
+++ /dev/null
Binary files differ
diff --git a/erts/emulator/pcre/pcre-8.43.tar.bz2 b/erts/emulator/pcre/pcre-8.43.tar.bz2
new file mode 100644
index 0000000000..e20c601f71
--- /dev/null
+++ b/erts/emulator/pcre/pcre-8.43.tar.bz2
Binary files differ
diff --git a/erts/emulator/pcre/pcre.h b/erts/emulator/pcre/pcre.h
index 505e2ccce0..49c9fc6dc8 100644
--- a/erts/emulator/pcre/pcre.h
+++ b/erts/emulator/pcre/pcre.h
@@ -43,9 +43,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE_MAJOR 8
-#define PCRE_MINOR 42
+#define PCRE_MINOR 43
#define PCRE_PRERELEASE
-#define PCRE_DATE 2018-03-20
+#define PCRE_DATE 2019-02-23
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE, the appropriate
diff --git a/erts/emulator/pcre/pcre_compile.c b/erts/emulator/pcre/pcre_compile.c
index ae7f6e2a2a..6ac222b27e 100644
--- a/erts/emulator/pcre/pcre_compile.c
+++ b/erts/emulator/pcre/pcre_compile.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2016 University of Cambridge
+ Copyright (c) 1997-2018 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -3300,7 +3300,7 @@ for(;;)
if ((*xclass_flags & XCL_MAP) == 0)
{
/* No bits are set for characters < 256. */
- if (list[1] == 0) return TRUE;
+ if (list[1] == 0) return (*xclass_flags & XCL_NOT) == 0;
/* Might be an empty repeat. */
continue;
}
@@ -7643,6 +7643,8 @@ for (;; ptr++)
/* Can't determine a first byte now */
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
+ zerofirstchar = firstchar;
+ zerofirstcharflags = firstcharflags;
continue;
@@ -8683,10 +8685,18 @@ do {
if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE;
}
- /* Positive forward assertions and conditions */
+ /* Positive forward assertion */
- else if (op == OP_ASSERT || op == OP_COND)
+ else if (op == OP_ASSERT)
+ {
+ if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE;
+ }
+
+ /* Condition; not anchored if no second branch */
+
+ else if (op == OP_COND)
{
+ if (scode[GET(scode,1)] != OP_ALT) return FALSE;
if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE;
}
diff --git a/erts/emulator/pcre/pcre_jit_compile.c b/erts/emulator/pcre/pcre_jit_compile.c
index 926e40f6d3..2d2288f81e 100644
--- a/erts/emulator/pcre/pcre_jit_compile.c
+++ b/erts/emulator/pcre/pcre_jit_compile.c
@@ -9002,7 +9002,7 @@ if (exact > 1)
#ifdef SUPPORT_UTF
&& !common->utf
#endif
- )
+ && type != OP_ANYNL && type != OP_EXTUNI)
{
OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0));
diff --git a/erts/emulator/sys/unix/sys_drivers.c b/erts/emulator/sys/unix/sys_drivers.c
index 664d677ebd..92020c6f35 100644
--- a/erts/emulator/sys/unix/sys_drivers.c
+++ b/erts/emulator/sys/unix/sys_drivers.c
@@ -785,15 +785,15 @@ static ErlDrvSSizeT spawn_control(ErlDrvData e, unsigned int cmd, char *buf,
static int fd_get_window_size(int fd, Uint32 *width, Uint32 *height)
{
-#ifdef TIOCGWINSZ
+#ifdef TIOCGWINSZ
struct winsize ws;
if (ioctl(fd,TIOCGWINSZ,&ws) == 0) {
*width = (Uint32) ws.ws_col;
*height = (Uint32) ws.ws_row;
- return 0;
+ return 1;
}
#endif
- return -1;
+ return 0;
}
static ErlDrvSSizeT fd_control(ErlDrvData drv_data,
@@ -801,16 +801,28 @@ static ErlDrvSSizeT fd_control(ErlDrvData drv_data,
char *buf, ErlDrvSizeT len,
char **rbuf, ErlDrvSizeT rlen)
{
- int fd = (int)(long)drv_data;
char resbuff[2*sizeof(Uint32)];
-
+ ErtsSysDriverData* dd = (ErtsSysDriverData*)drv_data;
command -= ERTS_TTYSL_DRV_CONTROL_MAGIC_NUMBER;
switch (command) {
case FD_CTRL_OP_GET_WINSIZE:
{
Uint32 w,h;
- if (fd_get_window_size(fd,&w,&h))
- return 0;
+ int success = 0;
+ if (dd->ofd != NULL) {
+ /* Try with output file descriptor */
+ int out_fd = dd->ofd->fd;
+ success = fd_get_window_size(out_fd,&w,&h);
+ }
+ if (!success && dd->ifd != NULL) {
+ /* Try with input file descriptor */
+ int in_fd = dd->ifd->fd;
+ success = fd_get_window_size(in_fd,&w,&h);
+ }
+ if (!success) {
+ return -1;
+ }
+ /* Succeeded */
memcpy(resbuff,&w,sizeof(Uint32));
memcpy(resbuff+sizeof(Uint32),&h,sizeof(Uint32));
}
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 4fb339926e..fbd1325c3a 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -1438,7 +1438,8 @@ sleeper() ->
gc_test(Config) when is_list(Config) ->
%% Note: This test is only relevant for REFC binaries.
%% Therefore, we take care that all binaries are REFC binaries.
- B = list_to_binary(lists:seq(0, ?heap_binary_size)),
+ true = 192 > ?heap_binary_size,
+ B = list_to_binary(lists:seq(1, 192)),
Self = self(),
F1 = fun() ->
gc(),
@@ -1447,22 +1448,22 @@ gc_test(Config) when is_list(Config) ->
end,
F = fun() ->
receive go -> ok end,
- {binary,[{_,65,1}]} = process_info(self(), binary),
+ {binary,[{_,192,1}]} = process_info(self(), binary),
gc(),
- {B1,B2} = my_split_binary(B, 4),
+ {B1,B2} = my_split_binary(B, 68),
gc(),
gc(),
{binary,L1} = process_info(self(), binary),
[Binfo1,Binfo2,Binfo3] = L1,
- {_,65,3} = Binfo1 = Binfo2 = Binfo3,
- 65 = size(B),
- 4 = size(B1),
- 61 = size(B2),
+ {_,192,3} = Binfo1 = Binfo2 = Binfo3,
+ 192 = size(B),
+ 68 = size(B1),
+ 124 = size(B2),
F1()
end,
gc(),
gc(),
- 65 = size(B),
+ 192 = size(B),
gc_test1(spawn_opt(erlang, apply, [F,[]], [link,{fullsweep_after,0}])).
gc_test1(Pid) ->
diff --git a/erts/emulator/test/dump_SUITE.erl b/erts/emulator/test/dump_SUITE.erl
index b7da69e556..6133b82756 100644
--- a/erts/emulator/test/dump_SUITE.erl
+++ b/erts/emulator/test/dump_SUITE.erl
@@ -68,12 +68,14 @@ signal_abort(Config) ->
{ok, Node} = start_node(Config),
- _P1 = spawn(Node, ?MODULE, load, []),
- _P2 = spawn(Node, ?MODULE, load, []),
- _P3 = spawn(Node, ?MODULE, load, []),
- _P4 = spawn(Node, ?MODULE, load, []),
- _P5 = spawn(Node, ?MODULE, load, []),
- _P6 = spawn(Node, ?MODULE, load, []),
+ SO = rpc:call(Node, erlang, system_info, [schedulers_online]),
+
+ _P1 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (0 rem SO) + 1}]),
+ _P2 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (1 rem SO) + 1}]),
+ _P3 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (2 rem SO) + 1}]),
+ _P4 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (3 rem SO) + 1}]),
+ _P5 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (4 rem SO) + 1}]),
+ _P6 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (5 rem SO) + 1}]),
timer:sleep(500),
diff --git a/erts/emulator/test/esock_ttest/esock-ttest b/erts/emulator/test/esock_ttest/esock-ttest
index 9adc51fc8b..2ded557484 100755
--- a/erts/emulator/test/esock_ttest/esock-ttest
+++ b/erts/emulator/test/esock_ttest/esock-ttest
@@ -203,7 +203,7 @@ process_client_args(["--max-outstanding", Max|Args], State) ->
end;
process_client_args(["--scon", Server|Args], State) ->
- case string:tokens(Server, [$:]) of
+ case string:split(Server, ":", trailing) of
[AddrStr,PortStr] ->
Addr = case inet:parse_address(AddrStr) of
{ok, A} ->
@@ -343,9 +343,9 @@ exec(#{role := client,
runtime := RunTime}) ->
case socket_test_ttest_tcp_client_socket:start(true,
Async,
+ Active,
Method,
ServerInfo,
- Active,
MsgID, MaxOutstanding,
RunTime) of
{ok, Pid} ->
diff --git a/erts/emulator/test/esock_ttest/esock-ttest-client b/erts/emulator/test/esock_ttest/esock-ttest-client
index 7c90ae6391..5ae05d03b8 100755
--- a/erts/emulator/test/esock_ttest/esock-ttest-client
+++ b/erts/emulator/test/esock_ttest/esock-ttest-client
@@ -20,23 +20,30 @@
# %CopyrightEnd%
#
+#
+# This is just a simple convenience wrapper to the esock-ttest.
+# That means that there are some options not available here.
+#
+
EMU=$ERL_TOP/erts/emulator
EMU_TEST=$EMU/test
ESOCK_TTEST=$EMU_TEST/esock_ttest
RUNTIME=30
+# RUNTIME=60
+# RUNTIME=600
if [ $# = 3 ]; then
MSGID=$1
SERVER_INFO=$2:$3
ITERATIONS="\
- gen false $MSGID
- gen true $MSGID
- gen once $MSGID
- sock false $MSGID
- sock true $MSGID
- sock once $MSGID"
+ gen false $MSGID
+ gen true $MSGID
+ gen once $MSGID
+ sock false $MSGID --async
+ sock true $MSGID --async
+ sock once $MSGID --async"
else
if [ $# = 2 ]; then
@@ -44,9 +51,9 @@ else
SERVER_INFO=$2
ITERATIONS="\
- sock false $MSGID
- sock true $MSGID
- sock once $MSGID"
+ sock false $MSGID --async
+ sock true $MSGID --async
+ sock once $MSGID --async"
else
echo "Invalid number of args"
@@ -70,14 +77,14 @@ fi
# ---------------------------------------------------------------------------
echo "$ITERATIONS" |
- while read TRANSPORT ACTIVE MSG_ID; do
+ while read TRANSPORT ACTIVE MSG_ID ASYNC; do
echo ""
echo "=========== transport = $TRANSPORT, active = $ACTIVE, msg-id = $MSG_ID ==========="
# The /dev/null at the end is necessary because erlang "does things" with stdin
# and this case would cause the 'while read' to "fail" so that we only would
# loop one time
- $ESOCK_TTEST/esock-ttest --client --transport $TRANSPORT --active $ACTIVE --msg-id $MSG_ID --scon $SERVER_INFO --runtime $RUNTIME </dev/null
+ $ESOCK_TTEST/esock-ttest --client --transport $TRANSPORT $ASYNC --active $ACTIVE --msg-id $MSG_ID --scon $SERVER_INFO --runtime $RUNTIME </dev/null
echo ""
done
diff --git a/erts/emulator/test/esock_ttest/esock-ttest-server-sock b/erts/emulator/test/esock_ttest/esock-ttest-server-sock
index fc87499f09..c443d42e64 100755
--- a/erts/emulator/test/esock_ttest/esock-ttest-server-sock
+++ b/erts/emulator/test/esock_ttest/esock-ttest-server-sock
@@ -24,9 +24,10 @@ EMU=$ERL_TOP/erts/emulator
EMU_TEST=$EMU/test
ESOCK_TTEST=$EMU_TEST/esock_ttest
-# $1 - async - boolean()
-# $2 - active - once | boolean()
-if [ $# = 2 ]; then
+# $1 - async - boolean()
+# $2 - active - once | boolean()
+# [$3 - domain - inet (default) | inet6 | local]
+if [ $# -ge 2 ]; then
async=$1
active=$2
@@ -39,6 +40,11 @@ if [ $# = 2 ]; then
ACTIVE="--active $active"
+ if [ $# = 3 ]; then
+ DOMAIN="--domain $3"
+ fi
+
+
else
echo "<ERROR> Missing args: async and active"
echo ""
@@ -46,5 +52,5 @@ else
fi
-$ESOCK_TTEST/esock-ttest --server $ASYNC --transport sock $ACTIVE
+$ESOCK_TTEST/esock-ttest --server $DOMAIN $ASYNC --transport sock $ACTIVE
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index 2cbde621ce..ad8ef0feff 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -27,7 +27,7 @@
fun_to_port/1,t_phash/1,t_phash2/1,md5/1,
refc/1,refc_ets/1,refc_dist/1,
const_propagation/1,t_arity/1,t_is_function2/1,
- t_fun_info/1,t_fun_info_mfa/1]).
+ t_fun_info/1,t_fun_info_mfa/1,t_fun_to_list/1]).
-export([nothing/0]).
@@ -44,7 +44,7 @@ all() ->
equality, ordering, fun_to_port, t_phash,
t_phash2, md5, refc, refc_ets, refc_dist,
const_propagation, t_arity, t_is_function2, t_fun_info,
- t_fun_info_mfa].
+ t_fun_info_mfa,t_fun_to_list].
%% Test that the correct EXIT code is returned for all types of bad funs.
bad_apply(Config) when is_list(Config) ->
@@ -802,6 +802,12 @@ t_fun_info_mfa(Config) when is_list(Config) ->
{'EXIT',_} = (catch erlang:fun_info_mfa(id(d))),
ok.
+t_fun_to_list(Config) when is_list(Config) ->
+ "fun a:b/1" = erlang:fun_to_list(fun a:b/1),
+ "fun 'a-esc':'b-esc'/1" = erlang:fun_to_list(fun 'a-esc':'b-esc'/1),
+ "fun 'a-esc':b/1" = erlang:fun_to_list(fun 'a-esc':b/1),
+ "fun a:'b-esc'/1" = erlang:fun_to_list(fun a:'b-esc'/1),
+ ok.
bad_info(Term) ->
try erlang:fun_info(Term, module) of
diff --git a/erts/emulator/test/net_SUITE.erl b/erts/emulator/test/net_SUITE.erl
index 6111fc76a5..c6e77a5373 100644
--- a/erts/emulator/test/net_SUITE.erl
+++ b/erts/emulator/test/net_SUITE.erl
@@ -20,6 +20,8 @@
%%
%% This test suite is basically a "placeholder" for a proper test suite...
+%% Also we should really call prim_net directly, and not net (since that does
+%% not even reside here).
%%
%% Run the entire test suite:
@@ -127,6 +129,7 @@ api_basic_cases() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init_per_suite(Config) ->
+ %% We test on the socket module for simplicity
case lists:member(socket, erlang:loaded()) of
true ->
case os:type() of
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index ef4635a6f5..c44693f8d9 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -51,7 +51,8 @@
unique_pid/1,
iter_max_procs/1,
magic_ref/1,
- dist_entry_gc/1]).
+ dist_entry_gc/1,
+ persistent_term/1]).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -63,7 +64,8 @@ all() ->
node_table_gc, dist_link_refc, dist_monitor_refc,
node_controller_refc, ets_refc, match_spec_refc,
timer_refc, pid_wrap, port_wrap, bad_nc,
- unique_pid, iter_max_procs, magic_ref].
+ unique_pid, iter_max_procs,
+ magic_ref, persistent_term].
init_per_suite(Config) ->
Config.
@@ -570,7 +572,17 @@ node_controller_refc(Config) when is_list(Config) ->
wait_until(fun () -> not is_process_alive(P) end),
lists:foreach(fun (Proc) -> garbage_collect(Proc) end, processes()),
false = get_node_references({Node,Creation}),
- false = get_dist_references(Node),
+ wait_until(fun () ->
+ case get_dist_references(Node) of
+ false ->
+ true;
+ [{{system,thread_progress_delete_timer},
+ [{system,1}]}] ->
+ false;
+ Other ->
+ ct:fail(Other)
+ end
+ end),
false = lists:member(Node, nodes(known)),
nc_refc_check(node()),
erts_debug:set_internal_state(node_tab_delayed_delete, -1), %% restore original value
@@ -871,7 +883,22 @@ magic_ref(Config) when is_list(Config) ->
{'DOWN', Mon, process, Pid, _} ->
ok
end,
- {Addr0, 2, true} = erts_debug:get_internal_state({magic_ref,MRef0}),
+ MaxTime = erlang:monotonic_time(millisecond) + 1000,
+ %% The DOWN signal is sent before heap is cleaned up,
+ %% so we might need to wait some time after the DOWN
+ %% signal has been received before the heap actually
+ %% has been cleaned up...
+ wait_until(fun () ->
+ case erts_debug:get_internal_state({magic_ref,MRef0}) of
+ {Addr0, 2, true} ->
+ true;
+ {Addr0, 3, true} ->
+ true = MaxTime >= erlang:monotonic_time(millisecond),
+ false;
+ Error ->
+ ct:fail(Error)
+ end
+ end),
id(MRef0),
id(MRef1),
MRefExt = term_to_binary(erts_debug:set_internal_state(make, magic_ref)),
@@ -881,6 +908,44 @@ magic_ref(Config) when is_list(Config) ->
true = erts_debug:get_internal_state({magic_ref,MRef2}),
ok.
+persistent_term(Config) when is_list(Config) ->
+ {ok, Node} = start_node(get_nodefirstname()),
+ Self = self(),
+ NcData = make_ref(),
+ RPid = spawn_link(Node,
+ fun () ->
+ Self ! {NcData, self(), hd(erlang:ports()), erlang:make_ref()}
+ end),
+ Data = receive
+ {NcData, RPid, RPort, RRef} ->
+ {RPid, RPort, RRef}
+ end,
+ unlink(RPid),
+ stop_node(Node),
+ Stuff = lists:foldl(fun (N, Acc) ->
+ persistent_term:put({?MODULE, N}, Data),
+ persistent_term:erase({?MODULE, N-1}),
+ node_container_refc_check(node()),
+ Data = persistent_term:get({?MODULE, N}),
+ try
+ persistent_term:get({?MODULE, N-1})
+ catch
+ error:badarg ->
+ ok
+ end,
+ case N rem 4 of
+ 0 -> [persistent_term:get({?MODULE, N})|Acc];
+ _ -> Acc
+ end
+ end,
+ [],
+ lists:seq(1, 100)),
+ persistent_term:erase({?MODULE, 100}),
+ receive after 2000 -> ok end, %% give literal gc some time to run...
+ node_container_refc_check(node()),
+ id(Stuff),
+ ok.
+
lost_pending_connection(Node) ->
_ = (catch erts_internal:new_connection(Node)),
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 3684cde8d4..13dde12e69 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -2600,14 +2600,20 @@ garb_other_running(Config) when is_list(Config) ->
no_priority_inversion(Config) when is_list(Config) ->
Prio = process_flag(priority, max),
- HTLs = lists:map(fun (_) ->
+ Master = self(),
+ Executing = make_ref(),
+ HTLs = lists:map(fun (Sched) ->
spawn_opt(fun () ->
+ Master ! {self(), Executing},
tok_loop()
end,
- [{priority, high}, monitor, link])
+ [{priority, high},
+ {scheduler, Sched},
+ monitor,
+ link])
end,
- lists:seq(1, 2*erlang:system_info(schedulers))),
- receive after 500 -> ok end,
+ lists:seq(1, erlang:system_info(schedulers_online))),
+ lists:foreach(fun ({P, _}) -> receive {P,Executing} -> ok end end, HTLs),
LTL = spawn_opt(fun () ->
tok_loop()
end,
@@ -2629,14 +2635,19 @@ no_priority_inversion(Config) when is_list(Config) ->
no_priority_inversion2(Config) when is_list(Config) ->
Prio = process_flag(priority, max),
- MTLs = lists:map(fun (_) ->
+ Master = self(),
+ Executing = make_ref(),
+ MTLs = lists:map(fun (Sched) ->
spawn_opt(fun () ->
+ Master ! {self(), Executing},
tok_loop()
end,
- [{priority, max}, monitor, link])
+ [{priority, max},
+ {scheduler, Sched},
+ monitor, link])
end,
- lists:seq(1, 2*erlang:system_info(schedulers))),
- receive after 2000 -> ok end,
+ lists:seq(1, erlang:system_info(schedulers_online))),
+ lists:foreach(fun ({P, _}) -> receive {P,Executing} -> ok end end, MTLs),
{PL, ML} = spawn_opt(fun () ->
tok_loop()
end,
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index c82e2efad9..4980ea2a82 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -58,6 +58,7 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
+-include("socket_test_evaluator.hrl").
%% Suite exports
-export([suite/0, all/0, groups/0]).
@@ -67,6 +68,9 @@
%% Test cases
-export([
+ %% *** API Misc ***
+ api_m_debug/1,
+
%% *** API Basic ***
api_b_open_and_close_udp4/1,
api_b_open_and_close_tcp4/1,
@@ -83,26 +87,52 @@
%% *** API async ***
api_a_connect_tcp4/1,
+ api_a_connect_tcp6/1,
api_a_sendto_and_recvfrom_udp4/1,
+ api_a_sendto_and_recvfrom_udp6/1,
api_a_sendmsg_and_recvmsg_udp4/1,
+ api_a_sendmsg_and_recvmsg_udp6/1,
api_a_send_and_recv_tcp4/1,
+ api_a_send_and_recv_tcp6/1,
api_a_sendmsg_and_recvmsg_tcp4/1,
+ api_a_sendmsg_and_recvmsg_tcp6/1,
api_a_recvfrom_cancel_udp4/1,
+ api_a_recvfrom_cancel_udp6/1,
api_a_recvmsg_cancel_udp4/1,
+ api_a_recvmsg_cancel_udp6/1,
api_a_accept_cancel_tcp4/1,
+ api_a_accept_cancel_tcp6/1,
api_a_recv_cancel_tcp4/1,
+ api_a_recv_cancel_tcp6/1,
api_a_recvmsg_cancel_tcp4/1,
+ api_a_recvmsg_cancel_tcp6/1,
api_a_mrecvfrom_cancel_udp4/1,
+ api_a_mrecvfrom_cancel_udp6/1,
api_a_mrecvmsg_cancel_udp4/1,
+ api_a_mrecvmsg_cancel_udp6/1,
api_a_maccept_cancel_tcp4/1,
+ api_a_maccept_cancel_tcp6/1,
api_a_mrecv_cancel_tcp4/1,
+ api_a_mrecv_cancel_tcp6/1,
api_a_mrecvmsg_cancel_tcp4/1,
+ api_a_mrecvmsg_cancel_tcp6/1,
%% *** API Options ***
api_opt_simple_otp_options/1,
api_opt_simple_otp_rcvbuf_option/1,
api_opt_simple_otp_controlling_process/1,
+ api_opt_sock_acceptconn_udp/1,
+ api_opt_sock_acceptconn_tcp/1,
+ api_opt_sock_acceptfilter/1,
+ api_opt_sock_bindtodevice/1,
+ api_opt_sock_broadcast/1,
+ api_opt_sock_debug/1,
+ api_opt_sock_domain/1,
+ api_opt_sock_dontroute/1,
+ api_opt_sock_error/1,
+ api_opt_sock_keepalive/1,
+ api_opt_sock_linger/1,
api_opt_ip_add_drop_membership/1,
%% *** API Operation Timeout ***
@@ -168,6 +198,19 @@
sc_rs_recvmsg_send_shutdown_receive_tcpL/1,
%% *** Traffic ***
+ traffic_send_and_recv_counters_tcp4/1,
+ traffic_send_and_recv_counters_tcp6/1,
+ traffic_send_and_recv_counters_tcpL/1,
+ traffic_sendmsg_and_recvmsg_counters_tcp4/1,
+ traffic_sendmsg_and_recvmsg_counters_tcp6/1,
+ traffic_sendmsg_and_recvmsg_counters_tcpL/1,
+ traffic_sendto_and_recvfrom_counters_udp4/1,
+ traffic_sendto_and_recvfrom_counters_udp6/1,
+ traffic_sendto_and_recvfrom_counters_udpL/1,
+ traffic_sendmsg_and_recvmsg_counters_udp4/1,
+ traffic_sendmsg_and_recvmsg_counters_udp6/1,
+ traffic_sendmsg_and_recvmsg_counters_udpL/1,
+
traffic_send_and_recv_chunks_tcp4/1,
traffic_send_and_recv_chunks_tcp6/1,
traffic_send_and_recv_chunks_tcpL/1,
@@ -514,30 +557,31 @@
]).
--include("socket_test_evaluator.hrl").
-
%% Internal exports
%% -export([]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--define(BASIC_REQ, <<"hejsan">>).
--define(BASIC_REP, <<"hoppsan">>).
+-define(LIB, socket_test_lib).
+-define(TTEST_LIB, socket_test_ttest_lib).
+-define(LOGGER, socket_test_logger).
--define(DATA, <<"HOPPSAN">>). % Temporary
--define(FAIL(R), exit(R)).
+-define(BASIC_REQ, <<"hejsan">>).
+-define(BASIC_REP, <<"hoppsan">>).
--define(SLEEP(T), receive after T -> ok end).
+-define(DATA, <<"HOPPSAN">>). % Temporary
+-define(FAIL(R), exit(R)).
--define(MINS(M), timer:minutes(M)).
--define(SECS(S), timer:seconds(S)).
+-define(SLEEP(T), receive after T -> ok end).
--define(TT(T), ct:timetrap(T)).
+-define(MINS(M), timer:minutes(M)).
+-define(SECS(S), timer:seconds(S)).
+
+-define(TT(T), ct:timetrap(T)).
+
+-define(F(F, A), ?LIB:f(F, A)).
--define(LIB, socket_test_lib).
--define(TTEST_LIB, socket_test_ttest_lib).
--define(LOGGER, socket_test_logger).
-define(TPP_SMALL, lists:seq(1, 8)).
-define(TPP_MEDIUM, lists:flatten(lists:duplicate(1024, ?TPP_SMALL))).
@@ -557,10 +601,10 @@ suite() ->
{timetrap,{minutes,1}}].
all() ->
- Groups = [{api, "ESOCK_TEST_API", include},
- {socket_closure, "ESOCK_TEST_SOCK_CLOSE", include},
- {traffic, "ESOCK_TEST_TRAFFIC", include},
- {ttest, "ESOCK_TEST_TTEST", exclude}],
+ Groups = [{api, "ESOCK_TEST_API", include},
+ {socket_close, "ESOCK_TEST_SOCK_CLOSE", include},
+ {traffic, "ESOCK_TEST_TRAFFIC", include},
+ {ttest, "ESOCK_TEST_TTEST", exclude}],
[use_group(Group, Env, Default) || {Group, Env, Default} <- Groups].
use_group(Group, Env, Default) ->
@@ -582,90 +626,104 @@ use_group(Group, Env, Default) ->
groups() ->
- [{api, [], api_cases()},
- {api_basic, [], api_basic_cases()},
- {api_async, [], api_async_cases()},
- {api_options, [], api_options_cases()},
- {api_options_otp, [], api_options_otp_cases()},
- {api_options_ip, [], api_options_ip_cases()},
- {api_op_with_timeout, [], api_op_with_timeout_cases()},
- {socket_closure, [], socket_closure_cases()},
- {sc_ctrl_proc_exit, [], sc_cp_exit_cases()},
- {sc_local_close, [], sc_lc_cases()},
- {sc_remote_close, [], sc_rc_cases()},
- {sc_remote_shutdown, [], sc_rs_cases()},
- {traffic, [], traffic_cases()},
- {traffic_chunks, [], traffic_chunks_cases()},
- {traffic_pp_send_recv, [], traffic_pp_send_recv_cases()},
- {traffic_pp_sendto_recvfrom, [], traffic_pp_sendto_recvfrom_cases()},
- {traffic_pp_sendmsg_recvmsg, [], traffic_pp_sendmsg_recvmsg_cases()},
- {ttest, [], ttest_cases()},
- {ttest_sgenf, [], ttest_sgenf_cases()},
- {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()},
- {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()},
- {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()},
- {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()},
- {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()},
- {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()},
- {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()},
- {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()},
- {ttest_sgeno, [], ttest_sgeno_cases()},
- {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()},
- {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()},
- {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()},
- {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()},
- {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()},
- {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()},
- {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()},
- {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()},
- {ttest_sgent, [], ttest_sgent_cases()},
- {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()},
- {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()},
- {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()},
- {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()},
- {ttest_sgent_csock, [], ttest_sgent_csock_cases()},
- {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()},
- {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()},
- {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()},
- {ttest_ssockf, [], ttest_ssockf_cases()},
- {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()},
- {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()},
- {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()},
- {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()},
- {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()},
- {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()},
- {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()},
- {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()},
- {ttest_ssocko, [], ttest_ssocko_cases()},
- {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()},
- {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()},
- {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()},
- {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()},
- {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()},
- {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()},
- {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()},
- {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()},
- {ttest_ssockt, [], ttest_ssockt_cases()},
- {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()},
- {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()},
- {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()},
- {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()},
- {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()},
- {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()},
- {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()},
- {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()}
+ [{api, [], api_cases()},
+ {api_misc, [], api_misc_cases()},
+ {api_basic, [], api_basic_cases()},
+ {api_async, [], api_async_cases()},
+ {api_options, [], api_options_cases()},
+ {api_options_otp, [], api_options_otp_cases()},
+ {api_options_socket, [], api_options_socket_cases()},
+ {api_option_sock_acceptconn, [], api_option_sock_acceptconn_cases()},
+ {api_options_ip, [], api_options_ip_cases()},
+ %% {api_options_ipv6, [], api_options_ipv6_cases()},
+ %% {api_options_tcp, [], api_options_tcp_cases()},
+ %% {api_options_udp, [], api_options_udp_cases()},
+ %% {api_options_sctp, [], api_options_sctp_cases()},
+ {api_op_with_timeout, [], api_op_with_timeout_cases()},
+ {socket_close, [], socket_close_cases()},
+ {sc_ctrl_proc_exit, [], sc_cp_exit_cases()},
+ {sc_local_close, [], sc_lc_cases()},
+ {sc_remote_close, [], sc_rc_cases()},
+ {sc_remote_shutdown, [], sc_rs_cases()},
+ {traffic, [], traffic_cases()},
+ {traffic_counters, [], traffic_counters_cases()},
+ {traffic_chunks, [], traffic_chunks_cases()},
+ {traffic_pp_send_recv, [], traffic_pp_send_recv_cases()},
+ {traffic_pp_sendto_recvfrom, [], traffic_pp_sendto_recvfrom_cases()},
+ {traffic_pp_sendmsg_recvmsg, [], traffic_pp_sendmsg_recvmsg_cases()},
+ {ttest, [], ttest_cases()},
+ {ttest_sgenf, [], ttest_sgenf_cases()},
+ {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()},
+ {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()},
+ {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()},
+ {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()},
+ {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()},
+ {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()},
+ {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()},
+ {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()},
+ {ttest_sgeno, [], ttest_sgeno_cases()},
+ {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()},
+ {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()},
+ {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()},
+ {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()},
+ {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()},
+ {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()},
+ {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()},
+ {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()},
+ {ttest_sgent, [], ttest_sgent_cases()},
+ {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()},
+ {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()},
+ {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()},
+ {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()},
+ {ttest_sgent_csock, [], ttest_sgent_csock_cases()},
+ {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()},
+ {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()},
+ {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()},
+ {ttest_ssockf, [], ttest_ssockf_cases()},
+ {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()},
+ {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()},
+ {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()},
+ {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()},
+ {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()},
+ {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()},
+ {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()},
+ {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()},
+ {ttest_ssocko, [], ttest_ssocko_cases()},
+ {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()},
+ {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()},
+ {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()},
+ {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()},
+ {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()},
+ {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()},
+ {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()},
+ {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()},
+ {ttest_ssockt, [], ttest_ssockt_cases()},
+ {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()},
+ {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()},
+ {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()},
+ {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()},
+ {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()},
+ {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()},
+ {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()},
+ {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()}
%% {tickets, [], ticket_cases()}
].
api_cases() ->
[
+ {group, api_misc},
{group, api_basic},
{group, api_async},
{group, api_options},
{group, api_op_with_timeout}
].
+api_misc_cases() ->
+ [
+ api_m_debug
+ ].
+
api_basic_cases() ->
[
api_b_open_and_close_udp4,
@@ -685,26 +743,46 @@ api_basic_cases() ->
api_async_cases() ->
[
api_a_connect_tcp4,
+ api_a_connect_tcp6,
api_a_sendto_and_recvfrom_udp4,
+ api_a_sendto_and_recvfrom_udp6,
api_a_sendmsg_and_recvmsg_udp4,
+ api_a_sendmsg_and_recvmsg_udp6,
api_a_send_and_recv_tcp4,
+ api_a_send_and_recv_tcp6,
api_a_sendmsg_and_recvmsg_tcp4,
+ api_a_sendmsg_and_recvmsg_tcp6,
api_a_recvfrom_cancel_udp4,
+ api_a_recvfrom_cancel_udp6,
api_a_recvmsg_cancel_udp4,
+ api_a_recvmsg_cancel_udp6,
api_a_accept_cancel_tcp4,
+ api_a_accept_cancel_tcp6,
api_a_recv_cancel_tcp4,
+ api_a_recv_cancel_tcp6,
api_a_recvmsg_cancel_tcp4,
+ api_a_recvmsg_cancel_tcp6,
api_a_mrecvfrom_cancel_udp4,
+ api_a_mrecvfrom_cancel_udp6,
api_a_mrecvmsg_cancel_udp4,
+ api_a_mrecvmsg_cancel_udp6,
api_a_maccept_cancel_tcp4,
+ api_a_maccept_cancel_tcp6,
api_a_mrecv_cancel_tcp4,
- api_a_mrecvmsg_cancel_tcp4
+ api_a_mrecv_cancel_tcp6,
+ api_a_mrecvmsg_cancel_tcp4,
+ api_a_mrecvmsg_cancel_tcp6
].
api_options_cases() ->
[
{group, api_options_otp},
- {group, api_options_ip}
+ {group, api_options_socket},
+ {group, api_options_ip}% ,
+ %% {group, api_options_ipv6},
+ %% {group, api_options_tcp},
+ %% {group, api_options_udp},
+ %% {group, api_options_sctp}
].
api_options_otp_cases() ->
@@ -714,11 +792,35 @@ api_options_otp_cases() ->
api_opt_simple_otp_controlling_process
].
+api_options_socket_cases() ->
+ [
+ {group, api_option_sock_acceptconn},
+ api_opt_sock_acceptfilter,
+ api_opt_sock_bindtodevice,
+ api_opt_sock_broadcast,
+ api_opt_sock_debug,
+ api_opt_sock_domain,
+ api_opt_sock_dontroute,
+ api_opt_sock_error,
+ api_opt_sock_keepalive,
+ api_opt_sock_linger
+ ].
+
+api_option_sock_acceptconn_cases() ->
+ [
+ api_opt_sock_acceptconn_udp,
+ api_opt_sock_acceptconn_tcp
+ ].
+
api_options_ip_cases() ->
[
api_opt_ip_add_drop_membership
].
+%% api_options_ipv6_cases() ->
+%% [
+%% ].
+
api_op_with_timeout_cases() ->
[
api_to_connect_tcp4,
@@ -747,7 +849,7 @@ api_op_with_timeout_cases() ->
%% These cases tests what happens when the socket is closed/shutdown,
%% locally or remotely.
-socket_closure_cases() ->
+socket_close_cases() ->
[
{group, sc_ctrl_proc_exit},
{group, sc_local_close},
@@ -818,12 +920,29 @@ sc_rs_cases() ->
traffic_cases() ->
[
+ {group, traffic_counters},
{group, traffic_chunks},
{group, traffic_pp_send_recv},
{group, traffic_pp_sendto_recvfrom},
{group, traffic_pp_sendmsg_recvmsg}
].
+traffic_counters_cases() ->
+ [
+ traffic_send_and_recv_counters_tcp4,
+ traffic_send_and_recv_counters_tcp6,
+ traffic_send_and_recv_counters_tcpL,
+ traffic_sendmsg_and_recvmsg_counters_tcp4,
+ traffic_sendmsg_and_recvmsg_counters_tcp6,
+ traffic_sendmsg_and_recvmsg_counters_tcpL,
+ traffic_sendto_and_recvfrom_counters_udp4,
+ traffic_sendto_and_recvfrom_counters_udp6,
+ traffic_sendto_and_recvfrom_counters_udpL,
+ traffic_sendmsg_and_recvmsg_counters_udp4,
+ traffic_sendmsg_and_recvmsg_counters_udp6,
+ traffic_sendmsg_and_recvmsg_counters_udpL
+ ].
+
traffic_chunks_cases() ->
[
traffic_send_and_recv_chunks_tcp4,
@@ -1650,6 +1769,80 @@ quiet_mode(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
+%% API MISC %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% A simple test case that tests that the global debug can be channged.
+%% At the same time, it will test the info function (since it uses it
+%% for verification).
+
+api_m_debug(suite) ->
+ [];
+api_m_debug(doc) ->
+ [];
+api_m_debug(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_m_debug,
+ fun() -> has_bugfree_gcc() end,
+ fun() ->
+ ok = api_m_debug()
+ end).
+
+%% For some reason this test case triggers a gcc bug, which causes
+%% a segfault, on an ancient Fedora 16 VM. So, check the version of gcc...
+%% Not pretty, but the simplest way to skip (without actually testing for the host).
+has_bugfree_gcc() ->
+ has_bugfree_gcc(os:type()).
+
+%% Make sure we are on linux
+has_bugfree_gcc({unix, linux}) ->
+ has_bugfree_gcc2(string:trim(os:cmd("cat /etc/issue")));
+has_bugfree_gcc(_) ->
+ ok.
+
+%% Make sure we are on Fedora 16
+has_bugfree_gcc2("Fedora release 16 " ++ _) ->
+ has_bugfree_gcc3(os:cmd("gcc --version"));
+has_bugfree_gcc2("Welcome to SUSE Linux " ++ _) ->
+ has_bugfree_gcc4(os:cmd("gcc --version"));
+has_bugfree_gcc2(_) ->
+ ok.
+
+has_bugfree_gcc3("gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2" ++ _) ->
+ skip("Buggy GCC");
+has_bugfree_gcc3(_) ->
+ ok.
+
+has_bugfree_gcc4("gcc (SUSE Linux) 4.3.2" ++ _) ->
+ skip("Buggy GCC");
+has_bugfree_gcc4(_) ->
+ ok.
+
+api_m_debug() ->
+ i("get initial info"),
+ #{debug := D0} = socket:info(),
+ D1 = not D0,
+ i("set new debug (~w => ~w)", [D0, D1]),
+ ok = socket:debug(D1),
+ i("get updated info (~w)", [D1]),
+ #{debug := D1} = socket:info(),
+ D2 = not D1,
+ i("set new debug (~w => ~w)", [D1, D2]),
+ ok = socket:debug(D2),
+ i("get updated info (~w)", [D2]),
+ #{debug := D2} = socket:info(),
+ i("ok"),
+ ok.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
%% API BASIC %%
%% %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2669,7 +2862,7 @@ api_b_send_and_recv_tcp(InitState) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Basically establish a TCP connection via an async connect.
+%% Basically establish a TCP connection via an async connect. IPv4.
api_a_connect_tcp4(suite) ->
[];
@@ -2679,25 +2872,48 @@ api_a_connect_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(10)),
tc_try(api_a_connect_tcp4,
fun() ->
- Connect = fun(Sock, SockAddr) ->
- socket:connect(Sock, SockAddr, nowait)
- end,
- Send = fun(Sock, Data) ->
- socket:send(Sock, Data)
- end,
- Recv = fun(Sock) ->
- socket:recv(Sock)
- end,
- InitState = #{domain => inet,
- connect => Connect,
- send => Send,
- recv => Recv},
- ok = api_a_connect_tcp(InitState)
+ ok = api_a_connect_tcpD(inet)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically establish a TCP connection via an async connect. IPv6.
+
+api_a_connect_tcp6(suite) ->
+ [];
+api_a_connect_tcp6(doc) ->
+ [];
+api_a_connect_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_connect_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ ok = api_a_connect_tcpD(inet6)
end).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+api_a_connect_tcpD(Domain) ->
+ Connect = fun(Sock, SockAddr) ->
+ socket:connect(Sock, SockAddr, nowait)
+ end,
+ Send = fun(Sock, Data) ->
+ socket:send(Sock, Data)
+ end,
+ Recv = fun(Sock) ->
+ socket:recv(Sock)
+ end,
+ InitState = #{domain => Domain,
+ connect => Connect,
+ send => Send,
+ recv => Recv},
+ api_a_connect_tcp(InitState).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_connect_tcp(InitState) ->
process_flag(trap_exit, true),
ServerSeq =
@@ -3197,6 +3413,37 @@ api_a_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically send and receive on an IPv6 UDP (dgram) socket using
+%% sendto and recvfrom. But we try to be async. That is, we use
+%% the 'nowait' value for the Timeout argument (and await the eventual
+%% select message). Note that we only do this for the recvfrom,
+%% since its much more difficult to "arrange" for sendto.
+%%
+api_a_sendto_and_recvfrom_udp6(suite) ->
+ [];
+api_a_sendto_and_recvfrom_udp6(doc) ->
+ [];
+api_a_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_a_sendto_and_recvfrom_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Send = fun(Sock, Data, Dest) ->
+ socket:sendto(Sock, Data, Dest)
+ end,
+ Recv = fun(Sock) ->
+ socket:recvfrom(Sock, 0, nowait)
+ end,
+ InitState = #{domain => inet6,
+ send => Send,
+ recv => Recv},
+ ok = api_a_send_and_recv_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically send and receive on an IPv4 UDP (dgram) socket using
%% sendto and recvfrom. But we try to be async. That is, we use
%% the 'nowait' value for the Timeout argument (and await the eventual
@@ -3240,6 +3487,50 @@ api_a_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically send and receive on an IPv6 UDP (dgram) socket using
+%% sendto and recvfrom. But we try to be async. That is, we use
+%% the 'nowait' value for the Timeout argument (and await the eventual
+%% select message). Note that we only do this for the recvmsg,
+%% since its much more difficult to "arrange" for sendmsg.
+%%
+api_a_sendmsg_and_recvmsg_udp6(suite) ->
+ [];
+api_a_sendmsg_and_recvmsg_udp6(doc) ->
+ [];
+api_a_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_a_sendmsg_and_recvmsg_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Send = fun(Sock, Data, Dest) ->
+ MsgHdr = #{addr => Dest,
+ %% ctrl => CMsgHdrs,
+ iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr)
+ end,
+ Recv = fun(Sock) ->
+ case socket:recvmsg(Sock, nowait) of
+ {ok, #{addr := Source,
+ iov := [Data]}} ->
+ {ok, {Source, Data}};
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ send => Send,
+ recv => Recv},
+ ok = api_a_send_and_recv_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_send_and_recv_udp(InitState) ->
ServerSeq =
[
@@ -3689,6 +3980,37 @@ api_a_send_and_recv_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically send and receive using the "common" functions (send and recv)
+%% on an IPv6 TCP (stream) socket. But we try to be async. That is, we use
+%% the 'nowait' value for the Timeout argument (and await the eventual
+%% select message). Note that we only do this for the recv,
+%% since its much more difficult to "arrange" for send.
+%% We *also* test async for accept.
+api_a_send_and_recv_tcp6(suite) ->
+ [];
+api_a_send_and_recv_tcp6(doc) ->
+ [];
+api_a_send_and_recv_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_send_and_recv_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Send = fun(Sock, Data) ->
+ socket:send(Sock, Data)
+ end,
+ Recv = fun(Sock) ->
+ socket:recv(Sock, 0, nowait)
+ end,
+ InitState = #{domain => inet6,
+ send => Send,
+ recv => Recv},
+ ok = api_a_send_and_recv_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically send and receive using the msg functions (sendmsg and recvmsg)
%% on an IPv4 TCP (stream) socket. But we try to be async. That is, we use
%% the 'nowait' value for the Timeout argument (and await the eventual
@@ -3716,7 +4038,7 @@ api_a_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) ->
OK;
{select, _} = SELECT ->
SELECT;
- {error, _} = ERROR ->
+ {error, _} = ERROR ->
ERROR
end
end,
@@ -3727,6 +4049,49 @@ api_a_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) ->
end).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically send and receive using the msg functions (sendmsg and recvmsg)
+%% on an IPv6 TCP (stream) socket. But we try to be async. That is, we use
+%% the 'nowait' value for the Timeout argument (and await the eventual
+%% select message). Note that we only do this for the recvmsg,
+%% since its much more difficult to "arrange" for sendmsg.
+%% We *also* test async for accept.
+api_a_sendmsg_and_recvmsg_tcp6(suite) ->
+ [];
+api_a_sendmsg_and_recvmsg_tcp6(doc) ->
+ [];
+api_a_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_sendmsg_and_recvmsg_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Send = fun(Sock, Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr)
+ end,
+ Recv = fun(Sock) ->
+ case socket:recvmsg(Sock, nowait) of
+ {ok, #{addr := undefined,
+ iov := [Data]}} ->
+ {ok, Data};
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ send => Send,
+ recv => Recv},
+ ok = api_a_send_and_recv_tcp(InitState)
+ end).
+
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
api_a_send_and_recv_tcp(InitState) ->
@@ -4227,7 +4592,7 @@ api_a_send_and_recv_tcp(InitState) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Basically we make an async (Timeout = nowait) call to recvfrom,
-%% wait some time and then cancel.
+%% wait some time and then cancel. IPv4
%%
api_a_recvfrom_cancel_udp4(suite) ->
[];
@@ -4256,8 +4621,39 @@ api_a_recvfrom_cancel_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make an async (Timeout = nowait) call to recvfrom,
+%% wait some time and then cancel. IPv6
+%%
+api_a_recvfrom_cancel_udp6(suite) ->
+ [];
+api_a_recvfrom_cancel_udp6(doc) ->
+ [];
+api_a_recvfrom_cancel_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_recvfrom_cancel_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ case socket:recvfrom(Sock, 0, nowait) of
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_recv_cancel_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically we make an async (Timeout = nowait) call to recvmsg,
-%% wait some time and then cancel.
+%% wait some time and then cancel. IPv4
%%
api_a_recvmsg_cancel_udp4(suite) ->
[];
@@ -4286,6 +4682,37 @@ api_a_recvmsg_cancel_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make an async (Timeout = nowait) call to recvmsg,
+%% wait some time and then cancel. IPv6
+%%
+api_a_recvmsg_cancel_udp6(suite) ->
+ [];
+api_a_recvmsg_cancel_udp6(doc) ->
+ [];
+api_a_recvmsg_cancel_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_recvmsg_cancel_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ case socket:recvmsg(Sock, nowait) of
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_recv_cancel_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_recv_cancel_udp(InitState) ->
ServerSeq =
[
@@ -4491,7 +4918,7 @@ api_a_recv_cancel_udp(InitState) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Basically we make an async (Timeout = nowait) call to accept,
-%% wait some time and then cancel.
+%% wait some time and then cancel. IPv4
%%
api_a_accept_cancel_tcp4(suite) ->
[];
@@ -4521,6 +4948,38 @@ api_a_accept_cancel_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make an async (Timeout = nowait) call to accept,
+%% wait some time and then cancel. IPv6
+%%
+api_a_accept_cancel_tcp6(suite) ->
+ [];
+api_a_accept_cancel_tcp6(doc) ->
+ [];
+api_a_accept_cancel_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_accept_cancel_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Accept = fun(Sock) ->
+ case socket:accept(Sock, nowait) of
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ accept => Accept},
+ ok = api_a_accept_cancel_tcp(InitState)
+ end).
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_accept_cancel_tcp(InitState) ->
process_flag(trap_exit, true),
ServerSeq =
@@ -4721,7 +5180,7 @@ api_a_accept_cancel_tcp(InitState) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Basically we make an async (Timeout = nowait) call to recv,
-%% wait some time and then cancel.
+%% wait some time and then cancel. IPv4
%%
api_a_recv_cancel_tcp4(suite) ->
[];
@@ -4743,8 +5202,32 @@ api_a_recv_cancel_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make an async (Timeout = nowait) call to recv,
+%% wait some time and then cancel. IPv6
+%%
+api_a_recv_cancel_tcp6(suite) ->
+ [];
+api_a_recv_cancel_tcp6(doc) ->
+ [];
+api_a_recv_cancel_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_recv_cancel_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ socket:recv(Sock, 0, nowait)
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_recv_cancel_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically we make an async (Timeout = nowait) call to recvmsg,
-%% wait some time and then cancel.
+%% wait some time and then cancel. IPv4
%%
api_a_recvmsg_cancel_tcp4(suite) ->
[];
@@ -4766,6 +5249,30 @@ api_a_recvmsg_cancel_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make an async (Timeout = nowait) call to recvmsg,
+%% wait some time and then cancel. IPv6
+%%
+api_a_recvmsg_cancel_tcp6(suite) ->
+ [];
+api_a_recvmsg_cancel_tcp6(doc) ->
+ [];
+api_a_recvmsg_cancel_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_a_recvmsg_cancel_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ socket:recvmsg(Sock, nowait)
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_recv_cancel_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_recv_cancel_tcp(InitState) ->
process_flag(trap_exit, true),
ServerSeq =
@@ -5119,7 +5626,7 @@ api_a_recv_cancel_tcp(InitState) ->
%% Basically we make multiple async (Timeout = nowait) call(s) to recvfrom
%% (from *several* processes), wait some time and then cancel.
-%% This should result in abort messages to the 'other' processes.
+%% This should result in abort messages to the 'other' processes. IPv4
%%
api_a_mrecvfrom_cancel_udp4(suite) ->
[];
@@ -5148,9 +5655,41 @@ api_a_mrecvfrom_cancel_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make multiple async (Timeout = nowait) call(s) to recvfrom
+%% (from *several* processes), wait some time and then cancel.
+%% This should result in abort messages to the 'other' processes. IPv6
+%%
+api_a_mrecvfrom_cancel_udp6(suite) ->
+ [];
+api_a_mrecvfrom_cancel_udp6(doc) ->
+ [];
+api_a_mrecvfrom_cancel_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(20)),
+ tc_try(api_a_mrecvfrom_cancel_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ case socket:recvfrom(Sock, 0, nowait) of
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_mrecv_cancel_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg
%% (from *several* processes), wait some time and then cancel.
-%% This should result in abort messages to the 'other' processes.
+%% This should result in abort messages to the 'other' processes. IPv4
%%
api_a_mrecvmsg_cancel_udp4(suite) ->
[];
@@ -5179,6 +5718,38 @@ api_a_mrecvmsg_cancel_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg
+%% (from *several* processes), wait some time and then cancel.
+%% This should result in abort messages to the 'other' processes. IPv6
+%%
+api_a_mrecvmsg_cancel_udp6(suite) ->
+ [];
+api_a_mrecvmsg_cancel_udp6(doc) ->
+ [];
+api_a_mrecvmsg_cancel_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(20)),
+ tc_try(api_a_mrecvmsg_cancel_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ case socket:recvmsg(Sock, nowait) of
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_mrecv_cancel_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_mrecv_cancel_udp(InitState) ->
ServerSeq =
[
@@ -5550,7 +6121,7 @@ api_a_mrecv_cancel_udp(InitState) ->
%% Basically we make multiple async (Timeout = nowait) call(s) to accept
%% (from *several* processes), wait some time and then cancel,
-%% This should result in abort messages to the 'other' processes.
+%% This should result in abort messages to the 'other' processes. IPv4
%%
api_a_maccept_cancel_tcp4(suite) ->
[];
@@ -5580,6 +6151,39 @@ api_a_maccept_cancel_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make multiple async (Timeout = nowait) call(s) to accept
+%% (from *several* processes), wait some time and then cancel,
+%% This should result in abort messages to the 'other' processes. IPv6
+%%
+api_a_maccept_cancel_tcp6(suite) ->
+ [];
+api_a_maccept_cancel_tcp6(doc) ->
+ [];
+api_a_maccept_cancel_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(20)),
+ tc_try(api_a_maccept_cancel_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Accept = fun(Sock) ->
+ case socket:accept(Sock, nowait) of
+ {ok, _} = OK ->
+ OK;
+ {select, _} = SELECT ->
+ SELECT;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => inet6,
+ accept => Accept},
+ ok = api_a_maccept_cancel_tcp(InitState)
+ end).
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_maccept_cancel_tcp(InitState) ->
process_flag(trap_exit, true),
ServerSeq =
@@ -5948,7 +6552,7 @@ api_a_maccept_cancel_tcp(InitState) ->
%% Basically we make multiple async (Timeout = nowait) call(s) to recv
%% (from *several* processes), wait some time and then cancel,
-%% This should result in abort messages to the 'other' processes.
+%% This should result in abort messages to the 'other' processes. IPv4
%%
api_a_mrecv_cancel_tcp4(suite) ->
[];
@@ -5970,9 +6574,34 @@ api_a_mrecv_cancel_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make multiple async (Timeout = nowait) call(s) to recv
+%% (from *several* processes), wait some time and then cancel,
+%% This should result in abort messages to the 'other' processes. IPv6
+%%
+api_a_mrecv_cancel_tcp6(suite) ->
+ [];
+api_a_mrecv_cancel_tcp6(doc) ->
+ [];
+api_a_mrecv_cancel_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(20)),
+ tc_try(api_a_mrecv_cancel_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ socket:recv(Sock, 0, nowait)
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_mrecv_cancel_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg
%% (from *several* processes), wait some time and then cancel,
-%% This should result in abort messages to the 'other' processes.
+%% This should result in abort messages to the 'other' processes. IPv4
%%
api_a_mrecvmsg_cancel_tcp4(suite) ->
[];
@@ -5994,6 +6623,31 @@ api_a_mrecvmsg_cancel_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg
+%% (from *several* processes), wait some time and then cancel,
+%% This should result in abort messages to the 'other' processes. IPv6
+%%
+api_a_mrecvmsg_cancel_tcp6(suite) ->
+ [];
+api_a_mrecvmsg_cancel_tcp6(doc) ->
+ [];
+api_a_mrecvmsg_cancel_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(20)),
+ tc_try(api_a_mrecvmsg_cancel_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ Recv = fun(Sock) ->
+ socket:recvmsg(Sock, nowait)
+ end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = api_a_mrecv_cancel_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_a_mrecv_cancel_tcp(InitState) ->
process_flag(trap_exit, true),
ServerSeq =
@@ -7735,6 +8389,1695 @@ api_opt_simple_otp_controlling_process() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Tests the socket option acceptconn for UDP.
+%% This should be possible to get but not set.
+
+api_opt_sock_acceptconn_udp(suite) ->
+ [];
+api_opt_sock_acceptconn_udp(doc) ->
+ [];
+api_opt_sock_acceptconn_udp(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(api_opt_sock_acceptconn_udp,
+ fun() ->
+ has_support_sock_acceptconn()
+ end,
+ fun() -> api_opt_sock_acceptconn_udp() end).
+
+
+
+api_opt_sock_acceptconn_udp() ->
+ Opt = acceptconn,
+ Set = fun(S, Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ {ok, State#{local_sa => LSA}}
+ end},
+ #{desc => "create socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[get] verify socket (before bind)",
+ cmd => fun(#{sock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, enoprotoopt = Reason} ->
+ %% On some platforms this is not accepted
+ %% for UDP, so skip this part (UDP).
+ ?SEV_EPRINT("Expected Failure: "
+ "~p => SKIP", [Reason]),
+ (catch socket:close(Sock)),
+ {skip, Reason};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify socket (before bind)",
+ cmd => fun(#{sock := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p",
+ [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ #{desc => "bind socket to local address",
+ cmd => fun(#{sock := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _} ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[get] verify socket (after bind)",
+ cmd => fun(#{sock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify socket (after bind)",
+ cmd => fun(#{sock := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p",
+ [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close socket",
+ cmd => fun(#{sock := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(sock, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option acceptconn for TCP.
+%% This should be possible to get but not set.
+
+api_opt_sock_acceptconn_tcp(suite) ->
+ [];
+api_opt_sock_acceptconn_tcp(doc) ->
+ [];
+api_opt_sock_acceptconn_tcp(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(api_opt_sock_acceptconn_tcp,
+ fun() ->
+ has_support_sock_acceptconn()
+ end,
+ fun() -> api_opt_sock_acceptconn_tcp() end).
+
+
+
+api_opt_sock_acceptconn_tcp() ->
+ Opt = acceptconn,
+ Set = fun(S, Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ {ok, State#{local_sa => LSA}}
+ end},
+
+ #{desc => "create listen socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{lsock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[get] verify listen socket (before bind)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, enoprotoopt = Reason} ->
+ ?SEV_EPRINT("Expected Failure: "
+ "~p => SKIP", [Reason]),
+ (catch socket:close(Sock)),
+ {skip, Reason};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify listen socket (before bind)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "bind listen socket to local address",
+ cmd => fun(#{lsock := Sock, local_sa := LSA} = State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, Port} ->
+ {ok, State#{server_sa => LSA#{port => Port}}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[get] verify listen socket (after bind)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify listen socket (after bind)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "make listen socket accept connections",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case socket:listen(Sock) of
+ ok ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[get] verify listen socket (after listen)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, true} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Accepting connections"),
+ ok;
+ {ok, false} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Not accepting connections"),
+ {error, {unexpected_success, {Opt, false}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify listen socket (after listen)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Set(Sock, false) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=false)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "create (connecting) socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{csockc => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "bind connecting socket to local address",
+ cmd => fun(#{csockc := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[get] verify connecting socket (before connect)",
+ cmd => fun(#{csockc := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify connecting socket (before connect)",
+ cmd => fun(#{csockc := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "connect to server",
+ cmd => fun(#{csockc := Sock, server_sa := SSA} = _State) ->
+ case socket:connect(Sock, SSA) of
+ ok ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "accept connection",
+ cmd => fun(#{lsock := Sock} = State) ->
+ case socket:accept(Sock) of
+ {ok, CSock} ->
+ {ok, State#{csocks => CSock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[get] verify connecting socket (after connect)",
+ cmd => fun(#{csockc := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify connecting socket (after connect)",
+ cmd => fun(#{csockc := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ #{desc => "[get] verify connected socket",
+ cmd => fun(#{csocks := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Not accepting connections"),
+ ok;
+ {ok, true} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Accepting connections"),
+ {error, {unexpected_success, {Opt, true}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify connected socket",
+ cmd => fun(#{csocks := Sock} = _State) ->
+ case Set(Sock, true) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=true)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ #{desc => "[get] verify listen socket (after connect)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, true} ->
+ ?SEV_IPRINT("Expected Success: "
+ "Accepting connections"),
+ ok;
+ {ok, false} ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Not accepting connections"),
+ {error, {unexpected_success, {Opt, false}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[set] verify listen socket (after connect)",
+ cmd => fun(#{lsock := Sock} = _State) ->
+ case Set(Sock, false) of
+ {error, Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ ok;
+ ok ->
+ ?SEV_EPRINT("Unexpected Success: "
+ "Set acceptconn (=false)"),
+ {error, unexpected_success}
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close connecting socket(s)",
+ cmd => fun(#{csockc := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(csockc, State0),
+ State2 = maps:remove(csocks, State1), %% Auto-close
+ {ok, maps:remove(csockc, State2)}
+ end},
+ #{desc => "close listen socket",
+ cmd => fun(#{lsock := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(lsock, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option acceptfilter. PLACEHOLDER!
+
+api_opt_sock_acceptfilter(suite) ->
+ [];
+api_opt_sock_acceptfilter(doc) ->
+ [];
+api_opt_sock_acceptfilter(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(api_opt_sock_acceptfilter,
+ fun() -> not_yet_implemented() end,
+ fun() -> ok end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option bindtodevice.
+%% It has not always been possible to 'get' this option
+%% (atleast on linux).
+
+api_opt_sock_bindtodevice(suite) ->
+ [];
+api_opt_sock_bindtodevice(doc) ->
+ [];
+api_opt_sock_bindtodevice(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(api_opt_sock_bindtodevice,
+ fun() -> has_support_sock_bindtodevice() end,
+ fun() -> api_opt_sock_bindtodevice() end).
+
+
+api_opt_sock_bindtodevice() ->
+ Opt = bindtodevice,
+ Set = fun(S, Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name, addr := Addr}} ->
+ ?SEV_IPRINT("local host info (~p): "
+ "~n Name: ~p"
+ "~n Addr: ~p",
+ [Domain, Name, Addr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ {ok, State#{dev => Name,
+ local_sa => LSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "create UDP socket 1",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{usock1 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "create UDP socket 2",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{usock2 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "create TCP socket 1",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{tsock1 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "create TCP socket 2",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{tsock2 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[get] verify UDP socket 1 (before bindtodevice)",
+ cmd => fun(#{usock1 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, enoprotoopt = Reason} ->
+ ?SEV_EPRINT("Unexpected Failure: ~p => SKIP",
+ [Reason]),
+ {skip, Reason};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[get] verify UDP socket 2 (before bind)",
+ cmd => fun(#{usock2 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[get] verify TCP socket 1 (before bindtodevice)",
+ cmd => fun(#{tsock1 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[get] verify TCP socket 2 (before bind)",
+ cmd => fun(#{tsock2 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "Bind UDP socket 1 to device",
+ cmd => fun(#{usock1 := Sock, dev := Dev} = State) ->
+ case Set(Sock, Dev) of
+ ok ->
+ ?SEV_IPRINT("Expected Success"),
+ ok;
+ {error, eperm = Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ (catch socket:close(Sock)),
+ {ok, State#{usock1 => skip}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Bind UDP socket 2 to local address",
+ cmd => fun(#{usock2 := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ?SEV_IPRINT("Expected Success"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Bind TCP socket 1 to device",
+ cmd => fun(#{usock1 := USock1,
+ tsock1 := Sock, dev := Dev} = State) ->
+ case Set(Sock, Dev) of
+ ok ->
+ ?SEV_IPRINT("Expected Success"),
+ ok;
+ {error, eperm = Reason} when (USock1 =:= skip) ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ {skip, Reason};
+ {error, eperm = Reason} ->
+ ?SEV_IPRINT("Expected Failure: ~p", [Reason]),
+ (catch socket:close(Sock)),
+ {ok, State#{tsock1 => skip}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Bind TCP socket 2 to local address",
+ cmd => fun(#{tsock2 := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ?SEV_IPRINT("Expected Success"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[get] verify UDP socket 1 (after bindtodevice)",
+ cmd => fun(#{usock1 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP'ed (previous eperm)"),
+ ok;
+ (#{usock1 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[get] verify UDP socket 2 (after bind)",
+ cmd => fun(#{usock2 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[get] verify TCP socket 1 (after bindtodevice)",
+ cmd => fun(#{tsock1 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP'ed (previous eperm)"),
+ ok;
+ (#{tsock1 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[get] verify TCP socket 2 (after bind)",
+ cmd => fun(#{tsock2 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Dev} ->
+ ?SEV_IPRINT("Expected Success: ~p", [Dev]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]),
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ %% *** Termination ***
+ #{desc => "close UDP socket 1",
+ cmd => fun(#{usock1 := skip} = State) ->
+ ?SEV_IPRINT("SKIP'ed (already closed)"),
+ {ok, maps:remove(usock1, State)};
+ (#{usock1 := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(usock1, State)}
+ end},
+ #{desc => "close UDP socket 2",
+ cmd => fun(#{usock2 := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(usock2, State)}
+ end},
+ #{desc => "close TCP socket 1",
+ cmd => fun(#{tsock1 := skip} = State) ->
+ ?SEV_IPRINT("SKIP'ed (already closed)"),
+ {ok, maps:remove(tsock1, State)};
+ (#{tsock1 := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(tsock1, State)}
+ end},
+ #{desc => "close TCP socket 2",
+ cmd => fun(#{tsock2 := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(tsock2, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option broadcast.
+%% Make it possible for datagram sockets to send packets to a broadcast
+%% address (IPv4 only).
+
+api_opt_sock_broadcast(suite) ->
+ [];
+api_opt_sock_broadcast(doc) ->
+ [];
+api_opt_sock_broadcast(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(api_opt_sock_broadcast,
+ fun() -> has_support_sock_broadcast() end,
+ fun() -> api_opt_sock_broadcast() end).
+
+
+api_opt_sock_broadcast() ->
+ Opt = broadcast,
+ Set = fun(S, Val) when is_boolean(Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name,
+ addr := Addr,
+ broadaddr := BAddr}} ->
+ ?SEV_IPRINT("local host info: "
+ "~n Name: ~p"
+ "~n Addr: ~p"
+ "~n Broadcast Addr: ~p",
+ [Name, Addr, BAddr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ BSA = #{family => Domain,
+ addr => BAddr},
+ {ok, State#{lsa => LSA,
+ bsa => BSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "[socket 1] create UDP socket (listening 1)",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{sock1 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "[socket 1] Bind UDP socket (to limited broadcast address)",
+ cmd => fun(#{sock1 := Sock} = State) ->
+ BSA = #{family => inet,
+ addr => broadcast},
+ ?SEV_IPRINT("Try bind (socket 1) to: "
+ "~n ~p", [BSA]),
+ case socket:bind(Sock, BSA) of
+ {ok, Port} ->
+ ?SEV_IPRINT("Expected Success (bound): ~p",
+ [Port]),
+ {ok, State#{sa1 => BSA#{port => Port}}};
+ {error, eaddrnotavail = Reason} ->
+ ?SEV_IPRINT("~p => "
+ "SKIP limited broadcast test",
+ [Reason]),
+ {ok, State#{sa1 => skip}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 1] UDP socket sockname",
+ cmd => fun(#{sa1 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP limited broadcast test"),
+ ok;
+ (#{sock1 := Sock} = _State) ->
+ case socket:sockname(Sock) of
+ {ok, SA} ->
+ ?SEV_IPRINT("SA: ~p", [SA]),
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[socket 2] create UDP socket (listening 2)",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{sock2 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "[socket 2] Bind UDP socket (to subnet-directed broadcast address)",
+ cmd => fun(#{sock2 := Sock,
+ bsa := BSA} = State) ->
+ ?SEV_IPRINT("Try bind (socket 1) to: "
+ "~n ~p", [BSA]),
+ case socket:bind(Sock, BSA) of
+ {ok, Port} ->
+ ?SEV_IPRINT("Expected Success (bound): ~p",
+ [Port]),
+ {ok, State#{sa2 => BSA#{port => Port}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 2] UDP socket sockname",
+ cmd => fun(#{sock2 := Sock} = _State) ->
+ case socket:sockname(Sock) of
+ {ok, SA} ->
+ ?SEV_IPRINT("SA: ~p", [SA]),
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[socket 3] create UDP socket (sender)",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{sock3 => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "[socket 3][get] verify UDP socket (before bind and set)",
+ cmd => fun(#{sock3 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, false} ->
+ ?SEV_IPRINT("Expected Success: "
+ "broadcast not allowed"),
+ ok;
+ {ok, true} ->
+ ?SEV_IPRINT("Unexpected Success result: "
+ "broadcast already allowed"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 3] Try make broadcast allowed",
+ cmd => fun(#{sock3 := Sock} = _State) ->
+ case Set(Sock, true) of
+ ok ->
+ ?SEV_IPRINT("Expected Success: "
+ "broadcast now allowed"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 3] verify UDP socket broadcast allowed",
+ cmd => fun(#{sock3 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, true} ->
+ ?SEV_IPRINT("Expected Success: "
+ "broadcast allowed"),
+ ok;
+ {ok, false} ->
+ ?SEV_IPRINT("Unexpected Success result: "
+ "broadcast *not* allowed"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 3] Bind UDP socket (to local address)",
+ cmd => fun(#{sock3 := Sock, lsa := LSA} = State) ->
+ ?SEV_IPRINT("Try bind (socket 2) to: "
+ "~n ~p", [LSA]),
+ case socket:bind(Sock, LSA) of
+ {ok, Port} ->
+ ?SEV_IPRINT("Expected Success (bound): ~p",
+ [Port]),
+ {ok, State#{sa3 => LSA#{port => Port}}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 3] verify UDP socket (after set)",
+ cmd => fun(#{sock3 := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, true} ->
+ ?SEV_IPRINT("Expected Success: "
+ "broadcast allowed"),
+ ok;
+ {ok, false} ->
+ ?SEV_IPRINT("Unexpected Success result: "
+ "broadcast not allowed"),
+ {error, not_allowed};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[socket 3] try send to limited broadcast address",
+ cmd => fun(#{sa1 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP limited broadcast test"),
+ ok;
+ (#{sock3 := Sock,
+ sa1 := Dest} = _State) ->
+ Data = list_to_binary("hejsan"),
+ ?SEV_IPRINT("try send to bradcast address: "
+ "~n ~p", [Dest]),
+ case socket:sendto(Sock, Data, Dest) of
+ ok ->
+ ?SEV_IPRINT("Expected Success: "
+ "broadcast message sent"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 1] try recv",
+ cmd => fun(#{sa1 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP limited broadcast test"),
+ ok;
+ (#{sock1 := Sock} = State) ->
+ case socket:recvfrom(Sock, 0, 5000) of
+ {ok, _} ->
+ ?SEV_IPRINT("Expected Success: "
+ "received message"),
+ ok;
+ {error, timeout = Reason} ->
+ %% Some platforms seem to balk at this.
+ %% It spossible to bind to this, and
+ %% send to it, but no data is received.
+ %% At some point we should investigate...
+ %% For now, we just skip this part of
+ %% the test...
+ ?SEV_IPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ {ok, State#{sa1 => skip}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "[socket 3] try send to subnet-directed broadcast address",
+ cmd => fun(#{sock3 := Sock,
+ sa2 := Dest} = _State) ->
+ Data = list_to_binary("hejsan"),
+ ?SEV_IPRINT("try send to bradcast address: "
+ "~n ~p", [Dest]),
+ case socket:sendto(Sock, Data, Dest) of
+ ok ->
+ ?SEV_IPRINT("Expected Success: "
+ "broadcast message sent"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "[socket 2] try recv",
+ cmd => fun(#{sock2 := Sock, sa1 := SA1} = _State) ->
+ case socket:recvfrom(Sock, 0, 5000) of
+ {ok, _} ->
+ ?SEV_IPRINT("Expected Success: "
+ "received message"),
+ ok;
+ {error, timeout = Reason} when (SA1 =:= skip) ->
+ ?SEV_IPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ {skip, "receive timeout"};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "[socket 3] close UDP socket (sender)",
+ cmd => fun(#{sock3 := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock3, State0),
+ State2 = maps:remove(sa3, State1),
+ {ok, State2}
+ end},
+ #{desc => "[socket 2] close UDP socket (listener 2)",
+ cmd => fun(#{sock2 := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock2, State0),
+ State2 = maps:remove(sa2, State1),
+ {ok, State2}
+ end},
+ #{desc => "[socket 1] close UDP socket (listener 1)",
+ cmd => fun(#{sock1 := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock1, State0),
+ State2 = maps:remove(sa1, State1),
+ {ok, State2}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option debug.
+%% On linux, this test requires that the user running the test to have
+%% CAP_NET_ADMIN capabilities or be root (effective user ID of 0),
+%% therefor we explicitly test for the result eacces when attempting to
+%% set, and skip if we get it.
+
+api_opt_sock_debug(suite) ->
+ [];
+api_opt_sock_debug(doc) ->
+ [];
+api_opt_sock_debug(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_debug,
+ fun() -> has_support_sock_debug() end,
+ fun() -> api_opt_sock_debug() end).
+
+
+api_opt_sock_debug() ->
+ Opt = debug,
+ Set = fun(S, Val) when is_integer(Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name,
+ addr := Addr,
+ broadaddr := BAddr}} ->
+ ?SEV_IPRINT("local host info: "
+ "~n Name: ~p"
+ "~n Addr: ~p"
+ "~n Broadcast Addr: ~p",
+ [Name, Addr, BAddr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ BSA = #{family => Domain,
+ addr => BAddr},
+ {ok, State#{lsa => LSA,
+ bsa => BSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "create UDP socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "Get current debug value",
+ cmd => fun(#{sock := Sock} = State) ->
+ case Get(Sock) of
+ {ok, Debug} when is_integer(Debug) ->
+ ?SEV_IPRINT("Success: ~p", [Debug]),
+ {ok, State#{debug => Debug}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Try enable socket debug",
+ cmd => fun(#{sock := Sock, debug := Debug} = State) ->
+ NewDebug = Debug + 1,
+ case Set(Sock, NewDebug) of
+ ok ->
+ ?SEV_IPRINT("Expected Success"),
+ {ok, State#{debug => NewDebug}};
+ {error, eacces = Reason} ->
+ ?SEV_EPRINT("NO ACCESS => SKIP"),
+ {skip, Reason};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Get current (new) debug value",
+ cmd => fun(#{sock := Sock, debug := Debug} = _State) ->
+ case Get(Sock) of
+ {ok, Debug} when is_integer(Debug) ->
+ ?SEV_IPRINT("Success: ~p", [Debug]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close UDP socket",
+ cmd => fun(#{sock := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock, State0),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option domain.
+%% This is a read only option. Also not available on all platforms.
+
+api_opt_sock_domain(suite) ->
+ [];
+api_opt_sock_domain(doc) ->
+ [];
+api_opt_sock_domain(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_domain,
+ fun() -> has_support_sock_domain() end,
+ fun() -> api_opt_sock_domain() end).
+
+
+api_opt_sock_domain() ->
+ Opt = domain,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name,
+ addr := Addr,
+ broadaddr := BAddr}} ->
+ ?SEV_IPRINT("local host info: "
+ "~n Name: ~p"
+ "~n Addr: ~p"
+ "~n Broadcast Addr: ~p",
+ [Name, Addr, BAddr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ BSA = #{family => Domain,
+ addr => BAddr},
+ {ok, State#{lsa => LSA,
+ bsa => BSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "create IPv4 UDP socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{usock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "Get domain for the UDP socket",
+ cmd => fun(#{domain := Domain, usock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Domain} ->
+ ?SEV_IPRINT("Success: ~p", [Domain]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "create TCP socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{tsock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "Get domain for the TCP socket",
+ cmd => fun(#{domain := Domain, tsock := Sock} = _State) ->
+ case Get(Sock) of
+ {ok, Domain} ->
+ ?SEV_IPRINT("Success: ~p", [Domain]),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close UDP socket",
+ cmd => fun(#{usock := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(usock, State0),
+ {ok, State1}
+ end},
+ #{desc => "close TCP socket",
+ cmd => fun(#{tsock := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(tsock, State0),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option dontroute.
+%% The man page has the following to say:
+%% "Don't send via a gateway, send only to directly connected hosts.
+%% The same effect can be achieved by setting the MSG_DONTROUTE
+%% flag on a socket send(2) operation."
+%% Since its "kind of" difficult to check if it actually takes an
+%% effect (you would need a gateway for that and a machine "on the
+%% other side"), we only test if we can set and get the value.
+%% Better then nothing.
+
+api_opt_sock_dontroute(suite) ->
+ [];
+api_opt_sock_dontroute(doc) ->
+ [];
+api_opt_sock_dontroute(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_dontroute,
+ fun() -> has_support_sock_dontroute() end,
+ fun() -> api_opt_sock_dontroute() end).
+
+
+api_opt_sock_dontroute() ->
+ Opt = dontroute,
+ Set = fun(S, Val) when is_boolean(Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name,
+ addr := Addr,
+ broadaddr := BAddr}} ->
+ ?SEV_IPRINT("local host info: "
+ "~n Name: ~p"
+ "~n Addr: ~p"
+ "~n Broadcast Addr: ~p",
+ [Name, Addr, BAddr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ BSA = #{family => Domain,
+ addr => BAddr},
+ {ok, State#{lsa => LSA,
+ bsa => BSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "create UDP socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, dgram, udp) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "Get current value",
+ cmd => fun(#{sock := Sock} = State) ->
+ case Get(Sock) of
+ {ok, Val} when is_boolean(Val) ->
+ ?SEV_IPRINT("Success: ~p", [Val]),
+ {ok, State#{dontroute => Val}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Try change value",
+ cmd => fun(#{sock := Sock, dontroute := Current} = State) ->
+ New = not Current,
+ ?SEV_IPRINT("Change from ~p to ~p", [Current, New]),
+ case Set(Sock, New) of
+ ok ->
+ ?SEV_IPRINT("Expected Success"),
+ {ok, State#{dontroute => New}};
+ {error, eopnotsupp = Reason} ->
+ ?SEV_EPRINT("Expected Failure: ~p",
+ [Reason]),
+ {skip, Reason};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Verify changed value",
+ cmd => fun(#{sock := Sock, dontroute := Val} = _State) ->
+ case Get(Sock) of
+ {ok, Val} ->
+ ?SEV_IPRINT("Expected Success"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close UDP socket",
+ cmd => fun(#{sock := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock, State0),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option error. PLACEHOLDER!
+
+api_opt_sock_error(suite) ->
+ [];
+api_opt_sock_error(doc) ->
+ [];
+api_opt_sock_error(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_error,
+ fun() -> not_yet_implemented() end,
+ fun() -> ok end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option keepalive.
+%% This is bit tricky to test, partly because we have no control over
+%% the underlying TCP timeouts. So, for now, we just test that we can
+%% change the value.
+
+api_opt_sock_keepalive(suite) ->
+ [];
+api_opt_sock_keepalive(doc) ->
+ [];
+api_opt_sock_keepalive(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_keepalive,
+ fun() -> has_support_sock_keepalive() end,
+ fun() -> api_opt_sock_keepalive() end).
+
+
+api_opt_sock_keepalive() ->
+ Opt = keepalive,
+ Set = fun(S, Val) when is_boolean(Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name,
+ addr := Addr,
+ broadaddr := BAddr}} ->
+ ?SEV_IPRINT("local host info: "
+ "~n Name: ~p"
+ "~n Addr: ~p"
+ "~n Broadcast Addr: ~p",
+ [Name, Addr, BAddr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ BSA = #{family => Domain,
+ addr => BAddr},
+ {ok, State#{lsa => LSA,
+ bsa => BSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "create TCP socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "Get current value",
+ cmd => fun(#{sock := Sock} = State) ->
+ case Get(Sock) of
+ {ok, Val} when is_boolean(Val) ->
+ ?SEV_IPRINT("Success: ~p", [Val]),
+ {ok, State#{keepalive => Val}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Try change the value",
+ cmd => fun(#{sock := Sock, keepalive := Current} = State) ->
+ New = not Current,
+ ?SEV_IPRINT("Try change value from ~p to ~p",
+ [Current, New]),
+ case Set(Sock, New) of
+ ok ->
+ ?SEV_IPRINT("Expected Success"),
+ {ok, State#{keepalive => New}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Verify (new) current value",
+ cmd => fun(#{sock := Sock, keepalive := Val} = _State) ->
+ case Get(Sock) of
+ {ok, Val} ->
+ ?SEV_IPRINT("Expected Success (~p)", [Val]),
+ ok;
+ {ok, OtherVal} ->
+ ?SEV_IPRINT("Unexpected Success: ~p",
+ [OtherVal]),
+ {error, {unexpected_success_value,
+ Val, OtherVal}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close UDP socket",
+ cmd => fun(#{sock := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock, State0),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the socket option linger. PLACEHOLDER!
+
+api_opt_sock_linger(suite) ->
+ [];
+api_opt_sock_linger(doc) ->
+ [];
+api_opt_sock_linger(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_linger,
+ fun() -> not_yet_implemented() end,
+ fun() -> ok end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Tests that the add_mambership and drop_membership ip options work.
%% We create one server and two clients. The server only send messages,
%% the clients only receives messages.
@@ -7754,9 +10097,9 @@ api_opt_ip_add_drop_membership(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
tc_try(api_opt_ip_add_drop_membership,
fun() ->
- has_ip_add_membership_support(),
- has_ip_drop_membership_support(),
- has_ip_multicast_support()
+ has_support_ip_add_membership(),
+ has_support_ip_drop_membership(),
+ has_support_ip_multicast()
end,
fun() -> api_opt_ip_add_drop_membership() end).
@@ -7973,8 +10316,8 @@ api_opt_ip_add_drop_membership() ->
],
- i("get multicast address"),
Domain = inet,
+ i("get multicast address"),
MAddr = which_ip_multicast_address(),
MSA = #{family => Domain, addr => MAddr},
@@ -8007,6 +10350,7 @@ which_multicast_address(Domain) ->
which_multicast_address2(Domain, WhichMAddr);
Type ->
+ %% Actually, what is "not supported". is netstat!
not_supported({multicast, Type})
end.
@@ -8015,13 +10359,30 @@ which_multicast_address(Domain) ->
%% SunOS: IfName - Group - RefCnt
which_multicast_address2(Domain, WhichMAddr) ->
- IfName = which_local_host_ifname(Domain),
- NetstatGroupsStr = os:cmd("netstat -g | grep " ++ IfName),
- NetstatGroups0 = string:tokens(NetstatGroupsStr, [$\n]),
- NetstatGroups = [string:tokens(G, [$ ]) || G <- NetstatGroups0],
- MAddrs = [WhichMAddr(NetstatGroup) || NetstatGroup <-
- NetstatGroups],
- which_multicast_address3(Domain, MAddrs).
+ IfName = which_local_host_ifname(Domain),
+ %% On some platforms the netstat barfs out some crap on stderr
+ %% before the actual info...
+ case os:cmd("netstat -g 2>/dev/null | grep " ++ IfName) of
+ [] ->
+ %% Can't figure out if we support multicast or not...
+ not_supported(no_netstat);
+ NetstatGroupsStr ->
+ try
+ begin
+ NetstatGroups0 = string:tokens(NetstatGroupsStr, [$\n]),
+ NetstatGroups = [string:tokens(G, [$ ]) ||
+ G <- NetstatGroups0],
+ MAddrs = [WhichMAddr(NetstatGroup) ||
+ NetstatGroup <- NetstatGroups],
+ which_multicast_address3(Domain, MAddrs)
+ end
+ catch
+ throw:E:_ ->
+ throw(E);
+ C:E:S ->
+ not_supported({multicast, {C,E,S}})
+ end
+ end.
which_multicast_address3(_Domain, []) ->
not_supported({multicast, no_valid_addrs});
@@ -8038,8 +10399,8 @@ which_multicast_address3(Domain, [MAddrStr|MAddrs]) ->
end.
which_local_host_ifname(Domain) ->
- case which_local_host_info(Domain) of
- {ok, {Name, _Addr, _Flags}} ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name}} ->
Name;
{error, Reason} ->
not_supported({multicast, Reason})
@@ -9114,6 +11475,7 @@ api_to_send_tcp6(doc) ->
[];
api_to_send_tcp6(_Config) when is_list(_Config) ->
tc_try(api_to_send_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
not_yet_implemented()%% ,
%% ok = api_to_send_tcp(inet6)
@@ -9146,6 +11508,7 @@ api_to_sendto_udp6(doc) ->
[];
api_to_sendto_udp6(_Config) when is_list(_Config) ->
tc_try(api_to_sendto_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
not_yet_implemented()%% ,
%% ok = api_to_sendto_to_udp(inet6)
@@ -9178,6 +11541,7 @@ api_to_sendmsg_tcp6(doc) ->
[];
api_to_sendmsg_tcp6(_Config) when is_list(_Config) ->
tc_try(api_to_sendmsg_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
not_yet_implemented()%% ,
%% ok = api_to_sendmsg_tcp(inet6)
@@ -9212,6 +11576,7 @@ api_to_recv_udp6(doc) ->
[];
api_to_recv_udp6(_Config) when is_list(_Config) ->
tc_try(api_to_recv_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
not_yet_implemented()%% ,
%% ok = api_to_recv_udp(inet6)
@@ -9791,7 +12156,7 @@ sc_cpe_socket_cleanup_tcp4(suite) ->
sc_cpe_socket_cleanup_tcp4(doc) ->
[];
sc_cpe_socket_cleanup_tcp4(_Config) when is_list(_Config) ->
- ?TT(?SECS(5)),
+ ?TT(?SECS(30)),
tc_try(sc_cpe_socket_cleanup_tcp4,
fun() ->
InitState = #{domain => inet,
@@ -9811,7 +12176,7 @@ sc_cpe_socket_cleanup_tcp6(suite) ->
sc_cpe_socket_cleanup_tcp6(doc) ->
[];
sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) ->
- ?TT(?SECS(5)),
+ ?TT(?SECS(30)),
tc_try(sc_cpe_socket_cleanup_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
@@ -9832,7 +12197,7 @@ sc_cpe_socket_cleanup_tcpL(suite) ->
sc_cpe_socket_cleanup_tcpL(doc) ->
[];
sc_cpe_socket_cleanup_tcpL(_Config) when is_list(_Config) ->
- ?TT(?SECS(5)),
+ ?TT(?SECS(30)),
tc_try(sc_cpe_socket_cleanup_tcpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
@@ -9853,7 +12218,7 @@ sc_cpe_socket_cleanup_udp4(suite) ->
sc_cpe_socket_cleanup_udp4(doc) ->
[];
sc_cpe_socket_cleanup_udp4(_Config) when is_list(_Config) ->
- ?TT(?SECS(5)),
+ ?TT(?SECS(30)),
tc_try(sc_cpe_socket_cleanup_udp4,
fun() ->
InitState = #{domain => inet,
@@ -9874,7 +12239,7 @@ sc_cpe_socket_cleanup_udp6(suite) ->
sc_cpe_socket_cleanup_udp6(doc) ->
[];
sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) ->
- ?TT(?SECS(5)),
+ ?TT(?SECS(30)),
tc_try(sc_cpe_socket_cleanup_udp6,
fun() -> has_support_ipv6() end,
fun() ->
@@ -9895,7 +12260,7 @@ sc_cpe_socket_cleanup_udpL(suite) ->
sc_cpe_socket_cleanup_udpL(doc) ->
[];
sc_cpe_socket_cleanup_udpL(_Config) when is_list(_Config) ->
- ?TT(?SECS(5)),
+ ?TT(?SECS(30)),
tc_try(sc_cpe_socket_cleanup_udpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
@@ -10001,8 +12366,15 @@ sc_cpe_socket_cleanup(InitState) ->
ERROR
end
end},
+
+ ?SEV_SLEEP(?SECS(5)),
+
%% The reason we get closed, is that as long as there is a ref to
%% the resource (socket), then it will not be garbage collected.
+ %% Note that its still a race that the nif has processed that the
+ %% "controlling process" has terminated. There really is no
+ %% proper timeout for this, but the 5 seconds "should" be enough...
+ %% We should really have some way to subscribe to socket events...
#{desc => "verify no socket (closed)",
cmd => fun(#{owner := Pid, sock := Sock} = _State) ->
case socket:getopt(Sock, otp, controlling_process) of
@@ -13819,6 +16191,2044 @@ sc_rs_recvmsg_send_shutdown_receive_tcpL(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use TCP on IPv4.
+
+traffic_send_and_recv_counters_tcp4(suite) ->
+ [];
+traffic_send_and_recv_counters_tcp4(doc) ->
+ [];
+traffic_send_and_recv_counters_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_send_and_recv_counters_tcp4,
+ fun() ->
+ InitState = #{domain => inet,
+ proto => tcp,
+ recv => fun(S) -> socket:recv(S) end,
+ send => fun(S, D) -> socket:send(S, D) end},
+ ok = traffic_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use TCP on IPv6.
+
+traffic_send_and_recv_counters_tcp6(suite) ->
+ [];
+traffic_send_and_recv_counters_tcp6(doc) ->
+ [];
+traffic_send_and_recv_counters_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_send_and_recv_counters_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ InitState = #{domain => inet6,
+ proto => tcp,
+ recv => fun(S) -> socket:recv(S) end,
+ send => fun(S, D) -> socket:send(S, D) end},
+ ok = traffic_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use default (TCP) on local.
+
+traffic_send_and_recv_counters_tcpL(suite) ->
+ [];
+traffic_send_and_recv_counters_tcpL(doc) ->
+ [];
+traffic_send_and_recv_counters_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_send_and_recv_counters_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
+ recv => fun(S) -> socket:recv(S) end,
+ send => fun(S, D) -> socket:send(S, D) end},
+ ok = traffic_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use TCP on IPv4.
+
+traffic_sendmsg_and_recvmsg_counters_tcp4(suite) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_tcp4(doc) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendmsg_and_recvmsg_counters_tcp4,
+ fun() ->
+ InitState = #{domain => inet,
+ proto => tcp,
+ recv => fun(S) ->
+ case socket:recvmsg(S) of
+ {ok, #{addr := _Source,
+ iov := [Data]}} ->
+ {ok, Data};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ send => fun(S, Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(S, MsgHdr)
+ end},
+ ok = traffic_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use TCP on IPv6.
+
+traffic_sendmsg_and_recvmsg_counters_tcp6(suite) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_tcp6(doc) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendmsg_and_recvmsg_counters_tcp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ InitState = #{domain => inet6,
+ proto => tcp,
+ recv => fun(S) ->
+ case socket:recvmsg(S) of
+ {ok, #{addr := _Source,
+ iov := [Data]}} ->
+ {ok, Data};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ send => fun(S, Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(S, MsgHdr)
+ end},
+ ok = traffic_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use default (TCP) on local.
+
+traffic_sendmsg_and_recvmsg_counters_tcpL(suite) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_tcpL(doc) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendmsg_and_recvmsg_counters_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
+ recv => fun(S) ->
+ case socket:recvmsg(S) of
+ {ok, #{addr := _Source,
+ iov := [Data]}} ->
+ {ok, Data};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ send => fun(S, Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(S, MsgHdr)
+ end},
+ ok = traffic_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+traffic_send_and_recv_tcp(InitState) ->
+ ServerSeq =
+ [
+ %% *** Wait for start order part ***
+ #{desc => "await start",
+ cmd => fun(State) ->
+ Tester = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester}}
+ end},
+ #{desc => "monitor tester",
+ cmd => fun(#{tester := Tester} = _State) ->
+ _MRef = erlang:monitor(process, Tester),
+ ok
+ end},
+
+ %% *** Init part ***
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ {ok, State#{local_sa => LSA}}
+ end},
+ #{desc => "create listen socket",
+ cmd => fun(#{domain := Domain, proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
+ {ok, Sock} ->
+ {ok, State#{lsock => Sock}};
+ {error, eafnosupport = Reason} ->
+ {skip, Reason};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "bind to local address",
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ local_sa := LSA} = _State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock,
+ local_sa := LSA} = State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, Port} ->
+ {ok, State#{lport => Port}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "make listen socket",
+ cmd => fun(#{lsock := LSock}) ->
+ socket:listen(LSock)
+ end},
+ #{desc => "announce ready (init)",
+ cmd => fun(#{domain := local,
+ tester := Tester,
+ local_sa := #{path := Path}}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Path),
+ ok;
+ (#{tester := Tester,
+ lport := Port}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Port),
+ ok
+ end},
+
+ %% The actual test
+ #{desc => "await continue (accept)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, accept)
+ end},
+ #{desc => "accept",
+ cmd => fun(#{lsock := LSock} = State) ->
+ case socket:accept(LSock) of
+ {ok, Sock} ->
+ {ok, State#{csock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "initial counter validation (=zero)",
+ cmd => fun(#{csock := Sock} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("Validate initial counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(Counters)
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (accept)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, accept),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (1)",
+ cmd => fun(#{csock := Sock,
+ recv := Recv} = State) ->
+ case Recv(Sock) of
+ {ok, Data} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => 1,
+ read_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 1)",
+ cmd => fun(#{csock := Sock,
+ read_pkg := Pkg,
+ read_byte := Byte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, Pkg},
+ {read_byte, Byte},
+ {read_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (1)",
+ cmd => fun(#{csock := Sock,
+ send := Send} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => 1,
+ write_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 1)",
+ cmd => fun(#{csock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (2)",
+ cmd => fun(#{csock := Sock,
+ recv := Recv,
+ read_pkg := Pkg,
+ read_byte := Byte} = State) ->
+ case Recv(Sock) of
+ {ok, Data} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => Pkg + 1,
+ read_byte => Byte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 2)",
+ cmd => fun(#{csock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (2)",
+ cmd => fun(#{csock := Sock,
+ send := Send,
+ write_pkg := Pkg,
+ write_byte := Byte} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => Pkg + 1,
+ write_byte => Byte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 2)",
+ cmd => fun(#{csock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+
+ %% Termination
+ #{desc => "await terminate (from tester)",
+ cmd => fun(#{tester := Tester} = State) ->
+ case ?SEV_AWAIT_TERMINATE(Tester, tester) of
+ ok ->
+ {ok, maps:remove(tester, State)};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "close connection socket (just in case)",
+ cmd => fun(#{csock := Sock} = State) ->
+ (catch socket:close(Sock)),
+ {ok, maps:remove(csock, State)}
+ end},
+ #{desc => "close listen socket",
+ cmd => fun(#{domain := local,
+ lsock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(lsock, State1)};
+ (#{lsock := Sock} = State) ->
+ (catch socket:close(Sock)),
+ {ok, maps:remove(lsock, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ ClientSeq =
+ [
+ %% *** Wait for start order part ***
+ #{desc => "await start (from tester)",
+ cmd => fun(#{domain := local} = State) ->
+ {Tester, Path} = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester, server_path => Path}};
+ (State) ->
+ {Tester, Port} = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester, server_port => Port}}
+ end},
+ #{desc => "monitor tester",
+ cmd => fun(#{tester := Tester} = _State) ->
+ _MRef = erlang:monitor(process, Tester),
+ ok
+ end},
+
+ %% *** Init part ***
+ #{desc => "which server (local) address",
+ cmd => fun(#{domain := local = Domain,
+ server_path := Path} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ SSA = #{family => Domain, path => Path},
+ {ok, State#{local_sa => LSA, server_sa => SSA}};
+ (#{domain := Domain, server_port := Port} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ SSA = LSA#{port => Port},
+ {ok, State#{local_sa => LSA, server_sa => SSA}}
+ end},
+ #{desc => "create socket",
+ cmd => fun(#{domain := Domain,
+ proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, eafnosupport = Reason} ->
+ {skip, Reason};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "bind to local address",
+ cmd => fun(#{sock := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "announce ready (init)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init),
+ ok
+ end},
+
+ %% The actual test
+ #{desc => "await continue (connect)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, connect),
+ ok
+ end},
+ #{desc => "connect to server",
+ cmd => fun(#{sock := Sock, server_sa := SSA}) ->
+ socket:connect(Sock, SSA)
+ end},
+ #{desc => "announce ready (connect)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, connect),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (1)",
+ cmd => fun(#{sock := Sock,
+ send := Send} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => 1,
+ write_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 1)",
+ cmd => fun(#{sock := Sock,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{write_pkg, SPkg},
+ {write_byte, SByte},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (1)",
+ cmd => fun(#{sock := Sock,
+ recv := Recv} = State) ->
+ case Recv(Sock) of
+ {ok, Data} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => 1,
+ read_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 1)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (2)",
+ cmd => fun(#{sock := Sock,
+ send := Send,
+ write_pkg := SPkg,
+ write_byte := SByte} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => SPkg + 1,
+ write_byte => SByte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 2)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (2)",
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ read_pkg := RPkg,
+ read_byte := RByte} = State) ->
+ case Recv(Sock) of
+ {ok, Data} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => RPkg + 1,
+ read_byte => RByte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 2)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ %% Termination
+ #{desc => "await terminate (from tester)",
+ cmd => fun(#{tester := Tester} = State) ->
+ case ?SEV_AWAIT_TERMINATE(Tester, tester) of
+ ok ->
+ {ok, maps:remove(tester, State)};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "close connection socket",
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(sock, State1)};
+ (#{sock := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(sock, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+
+ TesterSeq =
+ [
+ %% *** Init part ***
+ #{desc => "monitor server",
+ cmd => fun(#{server := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+ #{desc => "monitor client",
+ cmd => fun(#{client := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+
+ %% Start the server
+ #{desc => "order server start",
+ cmd => fun(#{server := Pid} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid),
+ ok
+ end},
+ #{desc => "await server ready (init)",
+ cmd => fun(#{domain := local,
+ server := Pid} = State) ->
+ {ok, Path} = ?SEV_AWAIT_READY(Pid, server, init),
+ {ok, State#{path => Path}};
+ (#{server := Pid} = State) ->
+ {ok, Port} = ?SEV_AWAIT_READY(Pid, server, init),
+ {ok, State#{port => Port}}
+ end},
+
+ %% Start the client
+ #{desc => "order client start",
+ cmd => fun(#{domain := local,
+ client := Pid,
+ path := Path} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid, Path),
+ ok;
+ (#{client := Pid,
+ port := Port} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid, Port),
+ ok
+ end},
+ #{desc => "await client ready (init)",
+ cmd => fun(#{client := Pid} = _State) ->
+ ok = ?SEV_AWAIT_READY(Pid, client, init)
+ end},
+
+ %% *** The actual test ***
+
+ #{desc => "order server to continue (with accept)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, accept),
+ ok
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order client to continue (with connect)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, connect),
+ ok
+ end},
+ #{desc => "await client ready (connect)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, connect)
+ end},
+ #{desc => "await server ready (accept)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, accept)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order server to continue (recv_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate),
+ ok
+ end},
+ #{desc => "order client to continue (send_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate),
+ ok
+ end},
+ #{desc => "await client ready (send_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, send_and_validate)
+ end},
+ #{desc => "await server ready (recv_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, recv_and_validate)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order client to continue (recv_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate),
+ ok
+ end},
+ #{desc => "order server to continue (send_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate),
+ ok
+ end},
+ #{desc => "await server ready (send_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, send_and_validate)
+ end},
+ #{desc => "await client ready (recv_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, recv_and_validate)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order server to continue (recv_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate),
+ ok
+ end},
+ #{desc => "order client to continue (send_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate),
+ ok
+ end},
+ #{desc => "await client ready (send_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, send_and_validate)
+ end},
+ #{desc => "await server ready (recv_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, recv_and_validate)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order client to continue (recv_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate),
+ ok
+ end},
+ #{desc => "order server to continue (send_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate),
+ ok
+ end},
+ #{desc => "await server ready (send_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, send_and_validate)
+ end},
+ #{desc => "await client ready (recv_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, recv_and_validate)
+ end},
+
+ %% *** Termination ***
+ #{desc => "order client to terminate",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_TERMINATE(Client),
+ ok
+ end},
+ #{desc => "await client termination",
+ cmd => fun(#{client := Client} = State) ->
+ ?SEV_AWAIT_TERMINATION(Client),
+ State1 = maps:remove(client, State),
+ {ok, State1}
+ end},
+ #{desc => "order server to terminate",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_TERMINATE(Server),
+ ok
+ end},
+ #{desc => "await server termination",
+ cmd => fun(#{server := Server} = State) ->
+ ?SEV_AWAIT_TERMINATION(Server),
+ State1 = maps:remove(server, State),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ i("start server evaluator"),
+ ServerInitState = InitState#{host => local_host()},
+ Server = ?SEV_START("server", ServerSeq, ServerInitState),
+
+ i("start client evaluator(s)"),
+ ClientInitState = InitState#{host => local_host()},
+ Client = ?SEV_START("client", ClientSeq, ClientInitState),
+
+ i("start 'tester' evaluator"),
+ TesterInitState = #{server => Server#ev.pid,
+ client => Client#ev.pid},
+ Tester = ?SEV_START("tester", TesterSeq, TesterInitState),
+
+ i("await evaluator"),
+ ok = ?SEV_AWAIT_FINISH([Server, Client, Tester]).
+
+
+
+traffic_sar_counters_validation(Counters) ->
+ traffic_sar_counters_validation(Counters, []).
+
+traffic_sar_counters_validation(Counters, []) ->
+ (catch lists:foreach(
+ fun({_Cnt, 0}) -> ok;
+ ({Cnt, Val}) -> throw({error, {invalid_counter, Cnt, Val}})
+ end,
+ Counters));
+traffic_sar_counters_validation(Counters, [{Cnt, Val}|ValidateCounters]) ->
+ case lists:keysearch(Cnt, 1, Counters) of
+ {value, {Cnt, Val}} ->
+ Counters2 = lists:keydelete(Cnt, 1, Counters),
+ traffic_sar_counters_validation(Counters2, ValidateCounters);
+ {value, {Cnt, _Val}} when (Val =:= any) ->
+ Counters2 = lists:keydelete(Cnt, 1, Counters),
+ traffic_sar_counters_validation(Counters2, ValidateCounters);
+ {value, {Cnt, InvVal}} ->
+ {error, {invalid_counter, Cnt, InvVal, Val}};
+ false ->
+ {error, {unknown_counter, Cnt, Counters}}
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use UDP on IPv4.
+
+traffic_sendto_and_recvfrom_counters_udp4(suite) ->
+ [];
+traffic_sendto_and_recvfrom_counters_udp4(doc) ->
+ [];
+traffic_sendto_and_recvfrom_counters_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendto_and_recvfrom_counters_udp4,
+ fun() ->
+ InitState = #{domain => inet,
+ proto => udp,
+ recv => fun(S) ->
+ socket:recvfrom(S)
+ end,
+ send => fun(S, Data, Dest) ->
+ socket:sendto(S, Data, Dest)
+ end},
+ ok = traffic_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use UDP on IPv6.
+
+traffic_sendto_and_recvfrom_counters_udp6(suite) ->
+ [];
+traffic_sendto_and_recvfrom_counters_udp6(doc) ->
+ [];
+traffic_sendto_and_recvfrom_counters_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendto_and_recvfrom_counters_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ InitState = #{domain => inet6,
+ proto => udp,
+ recv => fun(S) ->
+ socket:recvfrom(S)
+ end,
+ send => fun(S, Data, Dest) ->
+ socket:sendto(S, Data, Dest)
+ end},
+ ok = traffic_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use default (UDP) on local.
+
+traffic_sendto_and_recvfrom_counters_udpL(suite) ->
+ [];
+traffic_sendto_and_recvfrom_counters_udpL(doc) ->
+ [];
+traffic_sendto_and_recvfrom_counters_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendto_and_recvfrom_counters_udp4,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
+ recv => fun(S) ->
+ socket:recvfrom(S)
+ end,
+ send => fun(S, Data, Dest) ->
+ socket:sendto(S, Data, Dest)
+ end},
+ ok = traffic_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use UDP on IPv4.
+
+traffic_sendmsg_and_recvmsg_counters_udp4(suite) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_udp4(doc) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendmsg_and_recvmsg_counters_udp4,
+ fun() ->
+ InitState = #{domain => inet,
+ proto => udp,
+ recv => fun(S) ->
+ case socket:recvmsg(S) of
+ {ok, #{addr := Source,
+ iov := [Data]}} ->
+ {ok, {Source, Data}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ send => fun(S, Data, Dest) ->
+ MsgHdr = #{addr => Dest,
+ iov => [Data]},
+ socket:sendmsg(S, MsgHdr)
+ end},
+ ok = traffic_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use UDP on IPv6.
+
+traffic_sendmsg_and_recvmsg_counters_udp6(suite) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_udp6(doc) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendmsg_and_recvmsg_counters_udp6,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ InitState = #{domain => inet6,
+ proto => udp,
+ recv => fun(S) ->
+ case socket:recvmsg(S) of
+ {ok, #{addr := Source,
+ iov := [Data]}} ->
+ {ok, {Source, Data}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ send => fun(S, Data, Dest) ->
+ MsgHdr = #{addr => Dest,
+ iov => [Data]},
+ socket:sendmsg(S, MsgHdr)
+ end},
+ ok = traffic_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to (simply) test that the counters
+%% for both read and write.
+%% So that its easy to extend, we use fun's for read and write.
+%% We use default (UDP) on local.
+
+traffic_sendmsg_and_recvmsg_counters_udpL(suite) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_udpL(doc) ->
+ [];
+traffic_sendmsg_and_recvmsg_counters_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ tc_try(traffic_sendmsg_and_recvmsg_counters_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
+ recv => fun(S) ->
+ case socket:recvmsg(S) of
+ {ok, #{addr := Source,
+ iov := [Data]}} ->
+ {ok, {Source, Data}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ send => fun(S, Data, Dest) ->
+ MsgHdr = #{addr => Dest,
+ iov => [Data]},
+ socket:sendmsg(S, MsgHdr)
+ end},
+ ok = traffic_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+traffic_send_and_recv_udp(InitState) ->
+ ServerSeq =
+ [
+ %% *** Wait for start order part ***
+ #{desc => "await start",
+ cmd => fun(State) ->
+ Tester = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester}}
+ end},
+ #{desc => "monitor tester",
+ cmd => fun(#{tester := Tester} = _State) ->
+ _MRef = erlang:monitor(process, Tester),
+ ok
+ end},
+
+ %% *** Init part ***
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ {ok, State#{local_sa => LSA}}
+ end},
+ #{desc => "create socket",
+ cmd => fun(#{domain := Domain, proto := Proto} = State) ->
+ case socket:open(Domain, dgram, Proto) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "bind to local address",
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{sock := LSock,
+ local_sa := LSA} = State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, Port} ->
+ {ok, State#{lport => Port}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "initial counter validation (=zero)",
+ cmd => fun(#{sock := Sock} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("Validate initial counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(Counters)
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (init)",
+ cmd => fun(#{domain := local,
+ tester := Tester,
+ local_sa := #{path := Path}}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Path),
+ ok;
+ (#{tester := Tester,
+ lport := Port}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Port),
+ ok
+ end},
+
+ %% The actual test
+ #{desc => "await continue (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (1)",
+ cmd => fun(#{sock := Sock,
+ recv := Recv} = State) ->
+ case Recv(Sock) of
+ {ok, {ClientSA, Data}} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{client_sa => ClientSA,
+ read_pkg => 1,
+ read_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 1)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := Pkg,
+ read_byte := Byte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, Pkg},
+ {read_byte, Byte},
+ {read_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (1)",
+ cmd => fun(#{sock := Sock,
+ send := Send,
+ client_sa := ClientSA} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data, ClientSA) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => 1,
+ write_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 1)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (2)",
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ read_pkg := Pkg,
+ read_byte := Byte} = State) ->
+ case Recv(Sock) of
+ {ok, {Source, Data}} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{client_sa => Source,
+ read_pkg => Pkg + 1,
+ read_byte => Byte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 2)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (2)",
+ cmd => fun(#{sock := Sock,
+ client_sa := ClientSA,
+ send := Send,
+ write_pkg := Pkg,
+ write_byte := Byte} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data, ClientSA) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => Pkg + 1,
+ write_byte => Byte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 2)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+
+ %% Termination
+ #{desc => "await terminate (from tester)",
+ cmd => fun(#{tester := Tester} = State) ->
+ case ?SEV_AWAIT_TERMINATE(Tester, tester) of
+ ok ->
+ {ok, maps:remove(tester, State)};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "close socket (just in case)",
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(lsock, State1)};
+ (#{sock := Sock} = State) ->
+ (catch socket:close(Sock)),
+ {ok, maps:remove(sock, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ ClientSeq =
+ [
+ %% *** Wait for start order part ***
+ #{desc => "await start (from tester)",
+ cmd => fun(#{domain := local} = State) ->
+ {Tester, Path} = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester, server_path => Path}};
+ (State) ->
+ {Tester, Port} = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester, server_port => Port}}
+ end},
+ #{desc => "monitor tester",
+ cmd => fun(#{tester := Tester} = _State) ->
+ _MRef = erlang:monitor(process, Tester),
+ ok
+ end},
+
+ %% *** Init part ***
+ #{desc => "which server (local) address",
+ cmd => fun(#{domain := local = Domain,
+ server_path := Path} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ SSA = #{family => Domain, path => Path},
+ {ok, State#{local_sa => LSA, server_sa => SSA}};
+ (#{domain := Domain, server_port := Port} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ SSA = LSA#{port => Port},
+ {ok, State#{local_sa => LSA, server_sa => SSA}}
+ end},
+ #{desc => "create socket",
+ cmd => fun(#{domain := Domain,
+ proto := Proto} = State) ->
+ case socket:open(Domain, dgram, Proto) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "bind to local address",
+ cmd => fun(#{sock := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "initial counter validation (=zero)",
+ cmd => fun(#{sock := Sock} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("Validate initial counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(Counters)
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (init)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init),
+ ok
+ end},
+
+ %% The actual test
+ #{desc => "await continue (send_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (1)",
+ cmd => fun(#{sock := Sock,
+ send := Send,
+ server_sa := ServerSA} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data, ServerSA) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => 1,
+ write_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 1)",
+ cmd => fun(#{sock := Sock,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{write_pkg, SPkg},
+ {write_byte, SByte},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (1)",
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ server_sa := #{family := local} = ServerSA} = State) ->
+ case Recv(Sock) of
+ {ok, {ServerSA, Data}} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => 1,
+ read_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{sock := Sock,
+ recv := Recv,
+ server_sa := #{addr := Addr, port := Port}} = State) ->
+ case Recv(Sock) of
+ {ok, {#{addr := Addr, port := Port}, Data}} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => 1,
+ read_byte => size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 1)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 1)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (send_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate)
+ end},
+ #{desc => "send (2)",
+ cmd => fun(#{sock := Sock,
+ send := Send,
+ server_sa := ServerSA,
+ write_pkg := SPkg,
+ write_byte := SByte} = State) ->
+ Data = ?DATA,
+ case Send(Sock, Data, ServerSA) of
+ ok ->
+ ?SEV_IPRINT("sent ~p bytes", [size(Data)]),
+ {ok, State#{write_pkg => SPkg + 1,
+ write_byte => SByte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (send 2)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (send_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, send_and_validate),
+ ok
+ end},
+
+ #{desc => "await continue (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate)
+ end},
+ #{desc => "recv (2)",
+ cmd => fun(#{sock := Sock,
+ server_sa := #{family := local} = ServerSA,
+ recv := Recv,
+ read_pkg := RPkg,
+ read_byte := RByte} = State) ->
+ case Recv(Sock) of
+ {ok, {ServerSA, Data}} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => RPkg + 1,
+ read_byte => RByte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{sock := Sock,
+ server_sa := #{addr := Addr, port := Port},
+ recv := Recv,
+ read_pkg := RPkg,
+ read_byte := RByte} = State) ->
+ case Recv(Sock) of
+ {ok, {#{addr := Addr, port := Port}, Data}} ->
+ ?SEV_IPRINT("recv ~p bytes", [size(Data)]),
+ {ok, State#{read_pkg => RPkg + 1,
+ read_byte => RByte + size(Data)}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "validate (recv 2)",
+ cmd => fun(#{sock := Sock,
+ read_pkg := RPkg,
+ read_byte := RByte,
+ write_pkg := SPkg,
+ write_byte := SByte} = _State) ->
+ try socket:info(Sock) of
+ #{counters := Counters} ->
+ ?SEV_IPRINT("validate counters: "
+ "~n ~p", [Counters]),
+ traffic_sar_counters_validation(
+ Counters,
+ [{read_pkg, RPkg},
+ {read_byte, RByte},
+ {write_pkg, SPkg},
+ {write_byte, SByte},
+ {read_tries, any},
+ {write_tries, any}])
+ catch
+ C:E:S ->
+ ?SEV_EPRINT("Failed get socket info: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ {error, {socket_info_failed, {C, E, S}}}
+ end
+ end},
+ #{desc => "announce ready (recv_and_validate 2)",
+ cmd => fun(#{tester := Tester}) ->
+ ?SEV_ANNOUNCE_READY(Tester, recv_and_validate),
+ ok
+ end},
+
+ %% Termination
+ #{desc => "await terminate (from tester)",
+ cmd => fun(#{tester := Tester} = State) ->
+ case ?SEV_AWAIT_TERMINATE(Tester, tester) of
+ ok ->
+ {ok, maps:remove(tester, State)};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "close connection socket",
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(sock, State1)};
+ (#{sock := Sock} = State) ->
+ socket:close(Sock),
+ {ok, maps:remove(sock, State)}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+
+ TesterSeq =
+ [
+ %% *** Init part ***
+ #{desc => "monitor server",
+ cmd => fun(#{server := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+ #{desc => "monitor client",
+ cmd => fun(#{client := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+
+ %% Start the server
+ #{desc => "order server start",
+ cmd => fun(#{server := Pid} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid),
+ ok
+ end},
+ #{desc => "await server ready (init)",
+ cmd => fun(#{domain := local,
+ server := Pid} = State) ->
+ {ok, Path} = ?SEV_AWAIT_READY(Pid, server, init),
+ {ok, State#{path => Path}};
+ (#{server := Pid} = State) ->
+ {ok, Port} = ?SEV_AWAIT_READY(Pid, server, init),
+ {ok, State#{port => Port}}
+ end},
+
+ %% Start the client
+ #{desc => "order client start",
+ cmd => fun(#{domain := local,
+ client := Pid,
+ path := Path} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid, Path),
+ ok;
+ (#{client := Pid,
+ port := Port} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid, Port),
+ ok
+ end},
+ #{desc => "await client ready (init)",
+ cmd => fun(#{client := Pid} = _State) ->
+ ok = ?SEV_AWAIT_READY(Pid, client, init)
+ end},
+
+ %% *** The actual test ***
+
+ #{desc => "order server to continue (recv_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate),
+ ok
+ end},
+ #{desc => "order client to continue (send_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate),
+ ok
+ end},
+ #{desc => "await client ready (send_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, send_and_validate)
+ end},
+ #{desc => "await server ready (recv_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, recv_and_validate)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order client to continue (recv_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate),
+ ok
+ end},
+ #{desc => "order server to continue (send_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate),
+ ok
+ end},
+ #{desc => "await server ready (send_and_validate 1)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, send_and_validate)
+ end},
+ #{desc => "await client ready (recv_and_validate 1)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, recv_and_validate)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order server to continue (recv_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate),
+ ok
+ end},
+ #{desc => "order client to continue (send_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate),
+ ok
+ end},
+ #{desc => "await client ready (send_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, send_and_validate)
+ end},
+ #{desc => "await server ready (recv_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, recv_and_validate)
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "order client to continue (recv_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate),
+ ok
+ end},
+ #{desc => "order server to continue (send_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate),
+ ok
+ end},
+ #{desc => "await server ready (send_and_validate 2)",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_AWAIT_READY(Server, server, send_and_validate)
+ end},
+ #{desc => "await client ready (recv_and_validate 2)",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_AWAIT_READY(Client, client, recv_and_validate)
+ end},
+
+ %% *** Termination ***
+ #{desc => "order client to terminate",
+ cmd => fun(#{client := Client} = _State) ->
+ ?SEV_ANNOUNCE_TERMINATE(Client),
+ ok
+ end},
+ #{desc => "await client termination",
+ cmd => fun(#{client := Client} = State) ->
+ ?SEV_AWAIT_TERMINATION(Client),
+ State1 = maps:remove(client, State),
+ {ok, State1}
+ end},
+ #{desc => "order server to terminate",
+ cmd => fun(#{server := Server} = _State) ->
+ ?SEV_ANNOUNCE_TERMINATE(Server),
+ ok
+ end},
+ #{desc => "await server termination",
+ cmd => fun(#{server := Server} = State) ->
+ ?SEV_AWAIT_TERMINATION(Server),
+ State1 = maps:remove(server, State),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ i("start server evaluator"),
+ ServerInitState = InitState#{host => local_host()},
+ Server = ?SEV_START("server", ServerSeq, ServerInitState),
+
+ i("start client evaluator(s)"),
+ ClientInitState = InitState#{host => local_host()},
+ Client = ?SEV_START("client", ClientSeq, ClientInitState),
+
+ i("start 'tester' evaluator"),
+ TesterInitState = #{server => Server#ev.pid,
+ client => Client#ev.pid},
+ Tester = ?SEV_START("tester", TesterSeq, TesterInitState),
+
+ i("await evaluator"),
+ ok = ?SEV_AWAIT_FINISH([Server, Client, Tester]).
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test that the send and recv functions
%% behave as expected when sending and/or reading chunks.
%% First send data in one "big" chunk, and read it in "small" chunks.
@@ -15180,12 +19590,12 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp6(suite) ->
traffic_ping_pong_small_sendto_and_recvfrom_udp6(doc) ->
[];
traffic_ping_pong_small_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) ->
- ?TT(?SECS(45)),
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udp6,
fun() -> has_support_ipv6() end,
fun() ->
+ ?TT(?SECS(45)),
InitState = #{domain => inet6,
proto => udp,
msg => Msg,
@@ -15209,12 +19619,12 @@ traffic_ping_pong_small_sendto_and_recvfrom_udpL(suite) ->
traffic_ping_pong_small_sendto_and_recvfrom_udpL(doc) ->
[];
traffic_ping_pong_small_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) ->
- ?TT(?SECS(45)),
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
+ ?TT(?SECS(45)),
InitState = #{domain => local,
proto => default,
msg => Msg,
@@ -15438,7 +19848,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(20)),
+ ?TT(?SECS(30)),
InitState = #{domain => inet6,
proto => tcp,
msg => Msg,
@@ -15466,7 +19876,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
- ?TT(?SECS(20)),
+ ?TT(?SECS(30)),
InitState = #{domain => local,
proto => default,
msg => Msg,
@@ -15494,7 +19904,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4,
fun() -> traffic_ping_pong_large_sendmsg_and_recvmsg_cond() end,
fun() ->
- ?TT(?SECS(30)),
+ ?TT(?SECS(60)),
InitState = #{domain => inet,
proto => tcp,
msg => Msg,
@@ -15535,7 +19945,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
traffic_ping_pong_large_sendmsg_and_recvmsg_cond()
end,
fun() ->
- ?TT(?SECS(30)),
+ ?TT(?SECS(60)),
InitState = #{domain => inet6,
proto => tcp,
msg => Msg,
@@ -15564,7 +19974,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
- ?TT(?SECS(30)),
+ ?TT(?SECS(60)),
InitState = #{domain => local,
proto => default,
msg => Msg,
@@ -15620,7 +20030,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(30)),
+ ?TT(?SECS(60)),
InitState = #{domain => inet6,
proto => udp,
msg => Msg,
@@ -15648,7 +20058,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
- ?TT(?SECS(30)),
+ ?TT(?SECS(60)),
InitState = #{domain => local,
proto => default,
msg => Msg,
@@ -15675,7 +20085,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config)
Num = ?TPP_MEDIUM_NUM,
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4,
fun() ->
- ?TT(?SECS(30)),
+ ?TT(?SECS(60)),
InitState = #{domain => inet,
proto => udp,
msg => Msg,
@@ -15703,7 +20113,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(20)),
+ ?TT(?SECS(60)),
InitState = #{domain => inet6,
proto => udp,
msg => Msg,
@@ -15732,7 +20142,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config)
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
- ?TT(?SECS(20)),
+ ?TT(?SECS(60)),
InitState = #{domain => local,
proto => default,
msg => Msg,
@@ -15804,12 +20214,14 @@ traffic_ping_pong_send_and_receive_tcp(#{msg := Msg} = InitState) ->
?SEV_IPRINT("RcvBuf is ~p (needs atleast ~p)",
[RcvSz, 16+size(Msg)]),
if (RcvSz < size(Msg)) ->
- case socket:setopt(Sock,
- socket, rcvbuf, 1024+size(Msg)) of
+ NewRcvSz = 1024+size(Msg),
+ case socket:setopt(Sock, socket, rcvbuf, NewRcvSz) of
ok ->
ok;
{error, enobufs} ->
- skip({failed_change, rcvbuf});
+ skip(?F("Change ~w buffer size (to ~w) "
+ "not allowed",
+ [rcvbuf, NewRcvSz]));
{error, Reason1} ->
?FAIL({rcvbuf, Reason1})
end;
@@ -15820,12 +20232,14 @@ traffic_ping_pong_send_and_receive_tcp(#{msg := Msg} = InitState) ->
?SEV_IPRINT("SndBuf is ~p (needs atleast ~p)",
[SndSz, 16+size(Msg)]),
if (SndSz < size(Msg)) ->
- case socket:setopt(Sock,
- socket, sndbuf, 1024+size(Msg)) of
+ NewSndSz = 1024+size(Msg),
+ case socket:setopt(Sock, socket, sndbuf, NewSndSz) of
ok ->
ok;
{error, enobufs} ->
- skip({failed_change, sndbuf});
+ skip(?F("Change ~w buffer size (to ~w) "
+ "not allowed",
+ [sndbuf, NewSndSz]));
{error, Reason2} ->
?FAIL({sndbuf, Reason2})
end;
@@ -17413,7 +21827,9 @@ tpp_udp_client_handler_msg_exchange_loop(_Sock, _Dest, _Send, _Recv, _Msg,
Start) ->
Stop = ?LIB:timestamp(),
{Sent, Received, Start, Stop};
-tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv, Data,
+tpp_udp_client_handler_msg_exchange_loop(Sock,
+ #{family := local} = Dest,
+ Send, Recv, Data,
Num, N, Sent, Received, Start) ->
case tpp_udp_send_req(Sock, Send, Data, Dest) of
{ok, SendSz} ->
@@ -17432,6 +21848,28 @@ tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv, Data,
{error, SReason} ->
?SEV_EPRINT("send (~w of ~w): ~p", [N, Num, SReason]),
exit({send, SReason, N})
+ end;
+tpp_udp_client_handler_msg_exchange_loop(Sock,
+ #{addr := Addr, port := Port} = Dest0,
+ Send, Recv, Data,
+ Num, N, Sent, Received, Start) ->
+ case tpp_udp_send_req(Sock, Send, Data, Dest0) of
+ {ok, SendSz} ->
+ case tpp_udp_recv_rep(Sock, Recv) of
+ {ok, NewData, RecvSz, #{addr := Addr, port := Port} = Dest1} ->
+ tpp_udp_client_handler_msg_exchange_loop(Sock, Dest1,
+ Send, Recv,
+ NewData, Num, N+1,
+ Sent+SendSz,
+ Received+RecvSz,
+ Start);
+ {error, RReason} ->
+ ?SEV_EPRINT("recv (~w of ~w): ~p", [N, Num, RReason]),
+ exit({recv, RReason, N})
+ end;
+ {error, SReason} ->
+ ?SEV_EPRINT("send (~w of ~w): ~p", [N, Num, SReason]),
+ exit({send, SReason, N})
end.
@@ -23455,7 +27893,7 @@ ttest_tcp(TC,
fun() ->
if
(Domain =:= local) -> has_support_unix_domain_socket();
- (Domain =:= inet6) -> has_support_ipv6();
+ (Domain =:= inet6) -> has_support_ipv6();
true -> ok
end
end,
@@ -23918,16 +28356,22 @@ ttest_tcp(InitState) ->
?SEV_FINISH_NORMAL
],
+ Domain = maps:get(domain, InitState),
+ LHost = local_host(),
+ LAddr = which_local_addr(Domain),
+
i("start server evaluator"),
- ServerInitState = #{host => local_host(),
- domain => maps:get(domain, InitState),
+ ServerInitState = #{host => LHost,
+ addr => LAddr,
+ domain => Domain,
mod => maps:get(server_mod, InitState),
active => maps:get(server_active, InitState)},
Server = ?SEV_START("server", ServerSeq, ServerInitState),
i("start client evaluator"),
- ClientInitState = #{host => local_host(),
- domain => maps:get(domain, InitState),
+ ClientInitState = #{host => LHost,
+ addr => LAddr,
+ domain => Domain,
mod => maps:get(client_mod, InitState),
active => maps:get(client_active, InitState),
msg_id => maps:get(msg_id, InitState),
@@ -23936,9 +28380,14 @@ ttest_tcp(InitState) ->
Client = ?SEV_START("client", ClientSeq, ClientInitState),
i("start 'tester' evaluator"),
- TesterInitState = #{domain => maps:get(domain, InitState),
- server => Server#ev.pid,
- client => Client#ev.pid},
+ TesterInitState = #{domain => Domain,
+ msg_id => maps:get(msg_id, InitState),
+ client => Client#ev.pid,
+ client_mod => maps:get(client_mod, InitState),
+ client_active => maps:get(client_active, InitState),
+ server => Server#ev.pid,
+ server_mod => maps:get(server_mod, InitState),
+ server_active => maps:get(server_active, InitState)},
Tester = ?SEV_START("tester", TesterSeq, TesterInitState),
i("await evaluator(s)"),
@@ -23946,8 +28395,9 @@ ttest_tcp(InitState) ->
-ttest_tcp_server_start(Node, _Domain, gen, Active) ->
- Transport = socket_test_ttest_tcp_gen,
+ttest_tcp_server_start(Node, Domain, gen, Active) ->
+ TransportMod = socket_test_ttest_tcp_gen,
+ Transport = {TransportMod, #{domain => Domain}},
socket_test_ttest_tcp_server:start_monitor(Node, Transport, Active);
ttest_tcp_server_start(Node, Domain, sock, Active) ->
TransportMod = socket_test_ttest_tcp_socket,
@@ -23961,9 +28411,10 @@ ttest_tcp_server_stop(Pid) ->
ttest_tcp_client_start(Node,
Notify,
- _Domain, gen,
+ Domain, gen,
ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
- Transport = socket_test_ttest_tcp_gen,
+ TransportMod = socket_test_ttest_tcp_gen,
+ Transport = {TransportMod, #{domain => Domain}},
socket_test_ttest_tcp_client:start_monitor(Node,
Notify,
Transport,
@@ -24258,39 +28709,6 @@ sock_sockname(Sock) ->
?FAIL({sockname, C, E, S})
end.
-
-%% sock_listen(Sock) ->
-%% sock_listen2(fun() -> socket:listen(Sock) end).
-
-%% sock_listen(Sock, BackLog) ->
-%% sock_listen2(fun() -> socket:listen(Sock, BackLog) end).
-
-%% sock_listen2(Listen) ->
-%% try Listen() of
-%% ok ->
-%% ok;
-%% {error, Reason} ->
-%% ?FAIL({listen, Reason})
-%% catch
-%% C:E:S ->
-%% ?FAIL({listen, C, E, S})
-%% end.
-
-
-%% sock_accept(LSock) ->
-%% try socket:accept(LSock) of
-%% {ok, Sock} ->
-%% Sock;
-%% {error, Reason} ->
-%% i("sock_accept -> error: ~p", [Reason]),
-%% ?FAIL({accept, Reason})
-%% catch
-%% C:E:S ->
-%% i("sock_accept -> failed: ~p, ~p, ~p", [C, E, S]),
-%% ?FAIL({accept, C, E, S})
-%% end.
-
-
sock_close(Sock) ->
try socket:close(Sock) of
ok ->
@@ -24356,12 +28774,12 @@ which_local_socket_addr(local = Domain) ->
#{family => Domain,
path => mk_unique_path()};
-%% This gets the local address (not 127.0...)
+%% This gets the local socket address (not 127.0...)
%% We should really implement this using the (new) net module,
%% but until that gets the necessary functionality...
which_local_socket_addr(Domain) ->
- case which_local_host_info(Domain) of
- {ok, {_Name, _Flags, Addr}} ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{addr := Addr}} ->
#{family => Domain,
addr => Addr};
{error, Reason} ->
@@ -24369,55 +28787,15 @@ which_local_socket_addr(Domain) ->
end.
-%% Returns the interface (name), flags and address (not 127...)
-%% of the local host.
-which_local_host_info(Domain) ->
- case inet:getifaddrs() of
- {ok, IFL} ->
- which_local_host_info(Domain, IFL);
- {error, _} = ERROR ->
- ERROR
- end.
-which_local_host_info(_Domain, []) ->
- ?FAIL(no_address);
-which_local_host_info(Domain, [{"lo" ++ _, _}|IFL]) ->
- which_local_host_info(Domain, IFL);
-which_local_host_info(Domain, [{"docker" ++ _, _}|IFL]) ->
- which_local_host_info(Domain, IFL);
-which_local_host_info(Domain, [{"br-" ++ _, _}|IFL]) ->
- which_local_host_info(Domain, IFL);
-which_local_host_info(Domain, [{Name, IFO}|IFL]) ->
- case which_local_host_info2(Domain, IFO) of
- {ok, {Flags, Addr}} ->
- {ok, {Name, Flags, Addr}};
- {error, _} ->
- which_local_host_info(Domain, IFL)
- end;
-which_local_host_info(Domain, [_|IFL]) ->
- which_local_host_info(Domain, IFL).
-
-which_local_host_info2(Domain, IFO) ->
- case lists:keysearch(flags, 1, IFO) of
- {value, {flags, Flags}} ->
- which_local_host_info2(Domain, IFO, Flags);
- false ->
- {error, no_flags}
- end.
-
-which_local_host_info2(_Domain, [], _Flags) ->
- {error, no_address};
-which_local_host_info2(inet = _Domain, [{addr, Addr}|_IFO], Flags)
- when (size(Addr) =:= 4) andalso (element(1, Addr) =/= 127) ->
- {ok, {Flags, Addr}};
-which_local_host_info2(inet6 = _Domain, [{addr, Addr}|_IFO], Flags)
- when (size(Addr) =:= 8) andalso
- (element(1, Addr) =/= 0) andalso
- (element(1, Addr) =/= 16#fe80) ->
- {ok, {Flags, Addr}};
-which_local_host_info2(Domain, [_|IFO], Flags) ->
- which_local_host_info2(Domain, IFO, Flags).
+which_local_addr(local = _Domain) ->
+ mk_unique_path();
+%% This gets the local address (not 127.0...)
+%% We should really implement this using the (new) net module,
+%% but until that gets the necessary functionality...
+which_local_addr(Domain) ->
+ ?LIB:which_local_addr(Domain).
@@ -24430,12 +28808,12 @@ which_local_host_info2(Domain, [_|IFO], Flags) ->
%% We don't do that here, but since we can only do that (find a
%% multicast address) for specific platforms, we check that we are
%% on of those platforms here.
-has_ip_multicast_support() ->
+has_support_ip_multicast() ->
case os:type() of
{unix, OsName} when (OsName =:= linux) orelse
(OsName =:= sunos) ->
- case which_local_host_info(inet) of
- {ok, {_Name, Flags, _Addr}} ->
+ case ?LIB:which_local_host_info(inet) of
+ {ok, #{flags := Flags}} ->
case lists:member(multicast, Flags) of
true ->
ok;
@@ -24445,26 +28823,64 @@ has_ip_multicast_support() ->
{error, Reason} ->
not_supported({multicast, Reason})
end;
+ {unix, OsName} ->
+ skip(?F("Not Supported: platform ~w", [OsName]));
Type ->
- not_supported({multicast, Type})
+ skip(?F("Not Supported: platform ~p", [Type]))
+ end.
+
+has_support_sock_acceptconn() ->
+ has_support_socket_option_sock(acceptconn).
+
+has_support_sock_bindtodevice() ->
+ has_support_socket_option_sock(bindtodevice).
+
+has_support_sock_broadcast() ->
+ has_support_socket_option_sock(broadcast),
+ case ?LIB:which_local_host_info(inet) of
+ {ok, #{flags := Flags}} ->
+ case lists:member(broadcast, Flags) of
+ true ->
+ ok;
+ false ->
+ not_supported({broadcast, Flags})
+ end;
+ {error, Reason} ->
+ not_supported({broadcast, Reason})
end.
-has_ip_add_membership_support() ->
- has_socket_option_ip_support(add_membership).
+has_support_sock_debug() ->
+ has_support_socket_option_sock(debug).
+
+has_support_sock_domain() ->
+ has_support_socket_option_sock(domain).
+
+has_support_sock_dontroute() ->
+ has_support_socket_option_sock(dontroute).
+
+has_support_sock_keepalive() ->
+ has_support_socket_option_sock(keepalive).
+
+
+has_support_ip_add_membership() ->
+ has_support_socket_option_ip(add_membership).
+
+has_support_ip_drop_membership() ->
+ has_support_socket_option_ip(drop_membership).
-has_ip_drop_membership_support() ->
- has_socket_option_ip_support(drop_membership).
+has_support_socket_option_ip(Opt) ->
+ has_support_socket_option(ip, Opt).
-has_socket_option_ip_support(Opt) ->
- has_socket_option_support(ip, Opt).
+has_support_socket_option_sock(Opt) ->
+ has_support_socket_option(socket, Opt).
-has_socket_option_support(Level, Option) ->
+has_support_socket_option(Level, Option) ->
case socket:supports(options, Level, Option) of
true ->
ok;
false ->
- not_supported({options, Level, Option})
+ skip(?F("Not Supported: ~w option ~w", [Level, Option]))
end.
@@ -24496,13 +28912,7 @@ has_support_unix_domain_socket() ->
%% support for IPv6. If not, there is no point in running IPv6 tests.
%% Currently we just skip.
has_support_ipv6() ->
- %% case socket:supports(ipv6) of
- %% true ->
- %% ok;
- %% false ->
- %% {error, not_supported}
- %% end.
- not_yet_implemented().
+ ?LIB:has_support_ipv6().
diff --git a/erts/emulator/test/socket_test_lib.erl b/erts/emulator/test/socket_test_lib.erl
index 4e65c4f3c0..39cbf0c79f 100644
--- a/erts/emulator/test/socket_test_lib.erl
+++ b/erts/emulator/test/socket_test_lib.erl
@@ -32,6 +32,12 @@
%% String and format
f/2,
+ %% Generic 'has support' test function(s)
+ has_support_ipv6/0,
+
+ which_local_host_info/1,
+ which_local_addr/1,
+
%% Skipping
not_yet_implemented/0,
skip/1
@@ -40,6 +46,11 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-define(FAIL(R), exit(R)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
pi(Item) when is_atom(Item) ->
pi(self(), Item).
@@ -88,6 +99,196 @@ f(F, A) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+has_support_ipv6() ->
+ case socket:supports(ipv6) of
+ true ->
+ ok;
+ false ->
+ skip("IPv6 Not Supported")
+ end,
+ Domain = inet6,
+ LocalAddr =
+ case which_local_addr(Domain) of
+ {ok, Addr} ->
+ Addr;
+ {error, R1} ->
+ skip(f("Local Address eval failed: ~p", [R1]))
+ end,
+ ServerSock =
+ case socket:open(Domain, dgram, udp) of
+ {ok, SS} ->
+ SS;
+ {error, R2} ->
+ skip(f("(server) socket open failed: ~p", [R2]))
+ end,
+ LocalSA = #{family => Domain, addr => LocalAddr},
+ ServerPort =
+ case socket:bind(ServerSock, LocalSA) of
+ {ok, P1} ->
+ P1;
+ {error, R3} ->
+ socket:close(ServerSock),
+ skip(f("(server) socket bind failed: ~p", [R3]))
+ end,
+ ServerSA = LocalSA#{port => ServerPort},
+ ClientSock =
+ case socket:open(Domain, dgram, udp) of
+ {ok, CS} ->
+ CS;
+ {error, R4} ->
+ skip(f("(client) socket open failed: ~p", [R4]))
+ end,
+ case socket:bind(ClientSock, LocalSA) of
+ {ok, _} ->
+ ok;
+ {error, R5} ->
+ socket:close(ServerSock),
+ socket:close(ClientSock),
+ skip(f("(client) socket bind failed: ~p", [R5]))
+ end,
+ case socket:sendto(ClientSock, <<"hejsan">>, ServerSA) of
+ ok ->
+ ok;
+ {error, R6} ->
+ socket:close(ServerSock),
+ socket:close(ClientSock),
+ skip(f("failed socket sendto test: ~p", [R6]))
+ end,
+ case socket:recvfrom(ServerSock) of
+ {ok, {_, <<"hejsan">>}} ->
+ socket:close(ServerSock),
+ socket:close(ClientSock),
+ ok;
+ {error, R7} ->
+ socket:close(ServerSock),
+ socket:close(ClientSock),
+ skip(f("failed socket recvfrom test: ~p", [R7]))
+ end.
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% This gets the local address (not {127, _} or {0, ...} or {16#fe80, ...})
+%% We should really implement this using the (new) net module,
+%% but until that gets the necessary functionality...
+which_local_addr(Domain) ->
+ case which_local_host_info(Domain) of
+ {ok, #{addr := Addr}} ->
+ {ok, Addr};
+ {error, _Reason} = ERROR ->
+ ERROR
+ end.
+
+
+%% Returns the interface (name), flags and address (not 127...)
+%% of the local host.
+which_local_host_info(Domain) ->
+ case inet:getifaddrs() of
+ {ok, IFL} ->
+ which_local_host_info(Domain, IFL);
+ {error, _} = ERROR ->
+ ERROR
+ end.
+
+which_local_host_info(_Domain, []) ->
+ {error, no_address};
+which_local_host_info(Domain, [{"lo" ++ _, _}|IFL]) ->
+ which_local_host_info(Domain, IFL);
+which_local_host_info(Domain, [{"docker" ++ _, _}|IFL]) ->
+ which_local_host_info(Domain, IFL);
+which_local_host_info(Domain, [{"br-" ++ _, _}|IFL]) ->
+ which_local_host_info(Domain, IFL);
+which_local_host_info(Domain, [{Name, IFO}|IFL]) ->
+ try which_local_host_info2(Domain, IFO) of
+ Info ->
+ {ok, Info#{name => Name}}
+ catch
+ throw:_:_ ->
+ which_local_host_info(Domain, IFL)
+ end;
+which_local_host_info(Domain, [_|IFL]) ->
+ which_local_host_info(Domain, IFL).
+
+%% which_local_host_info2(Domain, IFO) ->
+%% case lists:keysearch(flags, 1, IFO) of
+%% {value, {flags, Flags}} ->
+%% which_local_host_info2(Domain, IFO, Flags);
+%% false ->
+%% {error, no_flags}
+%% end.
+
+
+%% which_local_host_info2(_Domain, [], _Flags) ->
+%% {error, no_address};
+%% which_local_host_info2(inet = _Domain, [{addr, Addr}|_IFO], Flags)
+%% when (size(Addr) =:= 4) andalso (element(1, Addr) =/= 127) ->
+%% {ok, {Flags, Addr}};
+%% which_local_host_info2(inet6 = _Domain, [{addr, Addr}|_IFO], Flags)
+%% when (size(Addr) =:= 8) andalso
+%% (element(1, Addr) =/= 0) andalso
+%% (element(1, Addr) =/= 16#fe80) ->
+%% {ok, {Flags, Addr}};
+%% which_local_host_info2(Domain, [_|IFO], Flags) ->
+%% which_local_host_info2(Domain, IFO, Flags).
+
+%% foo(Info, inet = Domain, IFO) ->
+%% foo(Info, Domain, IFO, [flags, addr, netmask, broadaddr, hwaddr]);
+%% foo(Info, inet6 = Domain, IFO) ->
+%% foo(Info, Domain, IFO, [flags, addr, netmask, hwaddr]).
+
+which_local_host_info2(inet = _Domain, IFO) ->
+ Addr = which_local_host_info3(addr, IFO,
+ fun({A, _, _, _}) when (A =/= 127) -> true;
+ (_) -> false
+ end),
+ NetMask = which_local_host_info3(netmask, IFO,
+ fun({_, _, _, _}) -> true;
+ (_) -> false
+ end),
+ BroadAddr = which_local_host_info3(broadaddr, IFO,
+ fun({_, _, _, _}) -> true;
+ (_) -> false
+ end),
+ Flags = which_local_host_info3(flags, IFO, fun(_) -> true end),
+ #{flags => Flags,
+ addr => Addr,
+ broadaddr => BroadAddr,
+ netmask => NetMask};
+which_local_host_info2(inet6 = _Domain, IFO) ->
+ Addr = which_local_host_info3(addr, IFO,
+ fun({A, _, _, _, _, _, _, _})
+ when (A =/= 0) andalso
+ (A =/= 16#fe80) -> true;
+ (_) -> false
+ end),
+ NetMask = which_local_host_info3(netmask, IFO,
+ fun({_, _, _, _, _, _, _, _}) -> true;
+ (_) -> false
+ end),
+ Flags = which_local_host_info3(flags, IFO, fun(_) -> true end),
+ #{flags => Flags,
+ addr => Addr,
+ netmask => NetMask}.
+
+which_local_host_info3(_Key, [], _) ->
+ throw({error, no_address});
+which_local_host_info3(Key, [{Key, Val}|IFO], Check) ->
+ case Check(Val) of
+ true ->
+ Val;
+ false ->
+ which_local_host_info3(Key, IFO, Check)
+ end;
+which_local_host_info3(Key, [_|IFO], Check) ->
+ which_local_host_info3(Key, IFO, Check).
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
not_yet_implemented() ->
skip("not yet implemented").
diff --git a/erts/emulator/test/socket_test_ttest_tcp_client.erl b/erts/emulator/test/socket_test_ttest_tcp_client.erl
index b5c5300fd0..f28819ca69 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_client.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_client.erl
@@ -266,8 +266,9 @@ init(Quiet,
(catch Mod:close(Sock)),
exit(normal);
{error, Reason} ->
- ?E("connect failed: ~p", [Reason]),
- exit({connect, Reason})
+ ?E("connect failed: ~p"
+ "~n ~p", [Reason, ServerInfo]),
+ exit({connect, Reason, ServerInfo})
end.
process_transport(Mod) when is_atom(Mod) ->
diff --git a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl
index ca7eff4437..2fb1242028 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl
@@ -34,24 +34,24 @@ start(Method, Async, Active, ServerInfo)
when is_list(ServerInfo) ->
Domain = local,
socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Async, Method),
- Active, ServerInfo);
+ ServerInfo, Active);
start(Method, Async, Active, ServerInfo = {Addr, _})
when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
Domain = inet,
socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Async, Method),
- Active, ServerInfo);
+ ServerInfo, Active);
start(Method, Async, Active, ServerInfo = {Addr, _})
when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
Domain = inet6,
socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Async, Method),
- Active, ServerInfo).
+ ServerInfo, Active).
start(Method, Async, Active, ServerInfo, MsgID)
when is_list(ServerInfo) ->
%% This is just a simplification
Domain = local,
socket_test_ttest_tcp_client:start(?MOD(Domain, Async, Method),
- Active, ServerInfo, MsgID);
+ ServerInfo, Active, MsgID);
start(Method, Async, Active, ServerInfo = {Addr, _}, MsgID)
when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
%% This is just a simplification
@@ -62,14 +62,14 @@ start(Method, Async, Active, ServerInfo = {Addr, _}, MsgID)
when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
Domain = inet6,
socket_test_ttest_tcp_client:start(?MOD(Domain, Async, Method),
- Active, ServerInfo, MsgID).
+ ServerInfo, Active, MsgID).
start(Method, Async, Active, ServerInfo, MsgID, MaxOutstanding, RunTime)
when is_list(ServerInfo) ->
Domain = local,
socket_test_ttest_tcp_client:start(false,
?MOD(Domain, Async, Method),
- Active, ServerInfo,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime);
start(Method, Async, Active, ServerInfo = {Addr, _},
MsgID, MaxOutstanding, RunTime)
@@ -77,7 +77,7 @@ start(Method, Async, Active, ServerInfo = {Addr, _},
Domain = inet,
socket_test_ttest_tcp_client:start(false,
?MOD(Domain, Async, Method),
- Active, ServerInfo,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime);
start(Method, Async, Active, ServerInfo = {Addr, _},
MsgID, MaxOutstanding, RunTime)
@@ -85,7 +85,7 @@ start(Method, Async, Active, ServerInfo = {Addr, _},
Domain = inet6,
socket_test_ttest_tcp_client:start(false,
?MOD(Domain, Async, Method),
- Active, ServerInfo,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime).
start(Quiet, Async, Active, Method, ServerInfo, MsgID, MaxOutstanding, RunTime)
@@ -93,7 +93,7 @@ start(Quiet, Async, Active, Method, ServerInfo, MsgID, MaxOutstanding, RunTime)
Domain = local,
socket_test_ttest_tcp_client:start(Quiet,
?MOD(Domain, Async, Method),
- Active, ServerInfo,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime);
start(Quiet, Async, Active, Method, ServerInfo = {Addr, _},
MsgID, MaxOutstanding, RunTime)
@@ -101,7 +101,7 @@ start(Quiet, Async, Active, Method, ServerInfo = {Addr, _},
Domain = inet,
socket_test_ttest_tcp_client:start(Quiet,
?MOD(Domain, Async, Method),
- Active, ServerInfo,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime);
start(Quiet, Async, Active, Method, ServerInfo = {Addr, _},
MsgID, MaxOutstanding, RunTime)
@@ -109,7 +109,7 @@ start(Quiet, Async, Active, Method, ServerInfo = {Addr, _},
Domain = inet6,
socket_test_ttest_tcp_client:start(Quiet,
?MOD(Domain, Async, Method),
- Active, ServerInfo,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime).
stop(Pid) ->
diff --git a/erts/emulator/test/socket_test_ttest_tcp_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_gen.erl
index 05b250e3d9..e59bd881e7 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_gen.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_gen.erl
@@ -36,19 +36,7 @@
]).
-%% ==========================================================================
-
-%% getopt(Sock, Opt) when is_atom(Opt) ->
-%% case inet:getopts(Sock, [Opt]) of
-%% {ok, [{Opt, Value}]} ->
-%% {ok, Value};
-%% {error, _} = ERROR ->
-%% ERROR
-%% end.
-
-%% setopt(Sock, Opt, Value) when is_atom(Opt) ->
-%% inet:setopts(Sock, [{Opt, Value}]).
-
+-define(LIB, socket_test_lib).
%% ==========================================================================
@@ -106,12 +94,12 @@ listen(Port) ->
listen(Port, #{domain => inet}).
listen(Port, #{domain := Domain}) when is_integer(Port) andalso (Port >= 0) ->
- Opts = [Domain,
- binary, {ip, {0,0,0,0}}, {packet, raw}, {active, false},
- {buffer, 32*1024}],
- case gen_tcp:listen(Port, Opts) of
- {ok, Sock} ->
- {ok, Sock};
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, {_, _, Addr}} ->
+ Opts = [Domain,
+ binary, {ip, Addr}, {packet, raw}, {active, false},
+ {buffer, 32*1024}],
+ gen_tcp:listen(Port, Opts);
{error, _} = ERROR ->
ERROR
end.
diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl
index 27b561d4b7..2394dc7924 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_server.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl
@@ -134,12 +134,18 @@ server_init(Starter, Parent, Transport, Active) ->
if
is_integer(PortOrPath) ->
%% This is just for convenience
- Addr = which_addr(),
- ?I("listening on:"
- "~n Addr: ~p (~s)"
- "~n Port: ~w"
- "~n", [Addr, inet:ntoa(Addr), PortOrPath]),
- {Addr, PortOrPath};
+ case Mod:sockname(LSock) of
+ {ok, {Addr, _}} ->
+ ?I("listening on:"
+ "~n Addr: ~p (~s)"
+ "~n Port: ~w"
+ "~n", [Addr,
+ inet:ntoa(Addr),
+ PortOrPath]),
+ {Addr, PortOrPath};
+ {error, SNReason} ->
+ exit({sockname, SNReason})
+ end;
is_list(PortOrPath) ->
?I("listening on:"
"~n Path: ~s"
@@ -569,51 +575,51 @@ handler_maybe_activate(_, _, _) ->
%% ==========================================================================
-which_addr() ->
- case inet:getifaddrs() of
- {ok, IfAddrs} ->
- which_addrs(inet, IfAddrs);
- {error, Reason} ->
- exit({getifaddrs, Reason})
- end.
+%% which_addr() ->
+%% case inet:getifaddrs() of
+%% {ok, IfAddrs} ->
+%% which_addrs(inet, IfAddrs);
+%% {error, Reason} ->
+%% exit({getifaddrs, Reason})
+%% end.
-which_addrs(_Family, []) ->
- exit({getifaddrs, not_found});
-which_addrs(Family, [{"lo", _} | IfAddrs]) ->
- %% Skip
- which_addrs(Family, IfAddrs);
-which_addrs(Family, [{"docker" ++ _, _} | IfAddrs]) ->
- %% Skip docker
- which_addrs(Family, IfAddrs);
-which_addrs(Family, [{"br-" ++ _, _} | IfAddrs]) ->
- %% Skip docker
- which_addrs(Family, IfAddrs);
-which_addrs(Family, [{"en" ++ _, IfOpts} | IfAddrs]) ->
- %% Maybe take this one
- case which_addr(Family, IfOpts) of
- {ok, Addr} ->
- Addr;
- error ->
- which_addrs(Family, IfAddrs)
- end;
-which_addrs(Family, [{_IfName, IfOpts} | IfAddrs]) ->
- case which_addr(Family, IfOpts) of
- {ok, Addr} ->
- Addr;
- error ->
- which_addrs(Family, IfAddrs)
- end.
+%% which_addrs(_Family, []) ->
+%% exit({getifaddrs, not_found});
+%% which_addrs(Family, [{"lo", _} | IfAddrs]) ->
+%% %% Skip
+%% which_addrs(Family, IfAddrs);
+%% which_addrs(Family, [{"docker" ++ _, _} | IfAddrs]) ->
+%% %% Skip docker
+%% which_addrs(Family, IfAddrs);
+%% which_addrs(Family, [{"br-" ++ _, _} | IfAddrs]) ->
+%% %% Skip docker
+%% which_addrs(Family, IfAddrs);
+%% which_addrs(Family, [{"en" ++ _, IfOpts} | IfAddrs]) ->
+%% %% Maybe take this one
+%% case which_addr(Family, IfOpts) of
+%% {ok, Addr} ->
+%% Addr;
+%% error ->
+%% which_addrs(Family, IfAddrs)
+%% end;
+%% which_addrs(Family, [{_IfName, IfOpts} | IfAddrs]) ->
+%% case which_addr(Family, IfOpts) of
+%% {ok, Addr} ->
+%% Addr;
+%% error ->
+%% which_addrs(Family, IfAddrs)
+%% end.
-which_addr(_, []) ->
- error;
-which_addr(inet, [{addr, Addr}|_])
- when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
- {ok, Addr};
-which_addr(inet6, [{addr, Addr}|_])
- when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
- {ok, Addr};
-which_addr(Family, [_|IfOpts]) ->
- which_addr(Family, IfOpts).
+%% which_addr(_, []) ->
+%% error;
+%% which_addr(inet, [{addr, Addr}|_])
+%% when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+%% {ok, Addr};
+%% which_addr(inet6, [{addr, Addr}|_])
+%% when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+%% {ok, Addr};
+%% which_addr(Family, [_|IfOpts]) ->
+%% which_addr(Family, IfOpts).
%% ==========================================================================
diff --git a/erts/emulator/test/socket_test_ttest_tcp_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_socket.erl
index 3aa3b2c504..9112748b4c 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_socket.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_socket.erl
@@ -247,10 +247,16 @@ listen(Path, #{domain := local = Domain} = Opts)
listen(Port, #{domain := Domain} = Opts)
when is_integer(Port) andalso (Port >= 0) ->
%% Bind fills in the rest
- SA = #{family => Domain,
- port => Port},
- Cleanup = fun() -> ok end,
- do_listen(SA, Cleanup, Opts#{proto => tcp}).
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, {_, _, Addr}} ->
+ SA = #{family => Domain,
+ addr => Addr,
+ port => Port},
+ Cleanup = fun() -> ok end,
+ do_listen(SA, Cleanup, Opts#{proto => tcp});
+ {error, _} = ERROR ->
+ ERROR
+ end.
do_listen(SA,
Cleanup,
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 8b6abb5336..20809d61e8 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -3993,22 +3993,79 @@ end
# ETS table debug
#
+define etp-ets-tab-status-int
+# Args:
+#
+# Non-reentrant
+ if ($arg0 & 0x1)
+ printf "priv"
+ end
+ if ($arg0 & 0x2)
+ printf "prot"
+ end
+ if ($arg0 & 0x4)
+ printf "pub"
+ end
+ if ($arg0 & 0x8)
+ printf "|del"
+ end
+ if ($arg0 & 0x10)
+ printf "|set"
+ end
+ if ($arg0 & 0x20)
+ printf "|bag"
+ end
+ if ($arg0 & 0x40)
+ printf "|dbag"
+ end
+ if ($arg0 & 0x80)
+ printf "|oset"
+ end
+ if ($arg0 & 0x100)
+ printf "|caoset"
+ end
+ if ($arg0 & 0x200)
+ printf "|flocked"
+ end
+ if ($arg0 & 0x400)
+ printf "|fread"
+ end
+ if ($arg0 & 0x800)
+ printf "|named"
+ end
+ if ($arg0 & 0x1000)
+ printf "|busy"
+ end
+end
+
define etp-ets-tables
# Args:
#
# Non-reentrant
- printf "%% Dumping < %lu ETS tables\n", (unsigned long)db_max_tabs
- while $etp_ets_tables_i < db_max_tabs
- if (meta_main_tab[$etp_ets_tables_i].u.next_free & 3) == 0
- printf "%% %d:", $etp_ets_tables_i
- etp-1 ((Eterm)(meta_main_tab[$etp_ets_tables_i].u.tb->common.id)) 0
+ set $sched_ix = 0
+ while $sched_ix < erts_no_schedulers
+ set $ets_tabs = &erts_aligned_scheduler_data[$sched_ix].esd.ets_tables
+ set $no_ets_tabs = *(unsigned long *)&($ets_tabs->count)
+ printf "\n%% %lu ETS tables created on scheduler %lu...\n\n", $no_ets_tabs, (unsigned long)$sched_ix+1
+ set $ets_tab = $ets_tabs->clist
+ set $first_ets_tab = $ets_tab
+ while $ets_tab
+ set $refn = &((ErtsMagicBinary *)$ets_tab->common->btid)->refn
+ printf "%% "
+ etp-1 $ets_tab->common.the_name 0
+ printf " #Ref<0.%u.%u.%u> ", (unsigned)$refn[2], (unsigned)$refn[1], (unsigned)$refn[0]
+ etp-1 $ets_tab->common.owner 0
printf " "
- etp-1 ((Eterm)(meta_main_tab[$etp_ets_tables_i].u.tb->common.owner)) 0
- printf "\n"
+ etp-ets-tab-status-int $ets_tab->common.status
+ printf " (DbTable*)%p\n", $ets_tab
+ if $ets_tab->common.all.next == $first_ets_tab
+ set $ets_tab = (DbTable *) 0
+ else
+ set $ets_tab = $ets_tab->common.all.next
+ end
end
- set $etp_ets_tables_i++
+ set $sched_ix++
end
- set $etp_ets_tables_i = 0
end
document etp-ets-tables
diff --git a/erts/lib_src/pthread/ethread.c b/erts/lib_src/pthread/ethread.c
index b4b12fcd86..b567ed81b0 100644
--- a/erts/lib_src/pthread/ethread.c
+++ b/erts/lib_src/pthread/ethread.c
@@ -208,9 +208,9 @@ ethr_x86_cpuid__(int *eax, int *ebx, int *ecx, int *edx)
"popl %%eax\n\t"
"movl $0x0, %0\n\t"
"xorl %%ecx, %%eax\n\t"
- "jz no_cpuid\n\t"
+ "jz 1f\n\t"
"movl $0x1, %0\n\t"
- "no_cpuid:\n\t"
+ "1:\n\t"
: "=r"(have_cpuid)
:
: "%eax", "%ecx", "cc");
diff --git a/erts/preloaded/ebin/erl_init.beam b/erts/preloaded/ebin/erl_init.beam
index 0c032e8e91..bc7639781c 100644
--- a/erts/preloaded/ebin/erl_init.beam
+++ b/erts/preloaded/ebin/erl_init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/net.beam b/erts/preloaded/ebin/net.beam
deleted file mode 100644
index 88d546a3af..0000000000
--- a/erts/preloaded/ebin/net.beam
+++ /dev/null
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index f67b660a08..f77e9e863d 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_net.beam b/erts/preloaded/ebin/prim_net.beam
new file mode 100644
index 0000000000..9d50b3210f
--- /dev/null
+++ b/erts/preloaded/ebin/prim_net.beam
Binary files differ
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 134b4eac13..73a0bd4f72 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/src/Makefile b/erts/preloaded/src/Makefile
index 27d450c873..38b85915cc 100644
--- a/erts/preloaded/src/Makefile
+++ b/erts/preloaded/src/Makefile
@@ -36,10 +36,9 @@ include $(ERL_TOP)/lib/kernel/vsn.mk
ifeq ($(USE_ESOCK), yes)
PRE_LOADED_ERL_ESOCK_MODULES = \
socket \
- net
+ prim_net
else
-PRE_LOADED_ERL_ESOCK_MODULES = \
- net
+PRE_LOADED_ERL_ESOCK_MODULES =
endif
PRE_LOADED_ERL_MODULES = \
@@ -82,9 +81,9 @@ APP_FILE= erts.app
APP_SRC= $(APP_FILE).src
APP_TARGET= $(STATIC_EBIN)/$(APP_FILE)
ifeq ($(USE_ESOCK), yes)
-APP_ESOCK_MODS= net, socket
+APP_ESOCK_MODS= prim_net, socket
else
-APP_ESOCK_MODS= net
+APP_ESOCK_MODS=
endif
@@ -96,6 +95,15 @@ ERL_COMPILE_FLAGS += +debug_info -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE)
DIA_PLT = erts-preloaded.plt
DIA_ANALYSIS = $(basename $(DIA_PLT)).dialyzer_analysis
+ifeq ($(DIAW_EH),true)
+DIA_WARNINGS += -Werror_handling
+endif
+ifeq ($(DIAW_US),true)
+DIA_WARNINGS += -Wunderspecs
+endif
+ifeq ($(DIAW_UR),true)
+DIA_WARNINGS += -Wunmatched_returns
+endif
debug opt: $(TARGET_FILES)
@@ -145,6 +153,7 @@ dialyzer: $(DIA_PLT)
@echo "Running dialyzer on $(basename $(DIA_PLT))"
@dialyzer --plt $< \
../ebin \
+ $(DIA_WARNINGS) \
--verbose
#
diff --git a/erts/preloaded/src/erl_init.erl b/erts/preloaded/src/erl_init.erl
index d209c4033b..dadf7dda6f 100644
--- a/erts/preloaded/src/erl_init.erl
+++ b/erts/preloaded/src/erl_init.erl
@@ -35,7 +35,8 @@ start(Mod, BootArgs) ->
erl_tracer:on_load(),
prim_buffer:on_load(),
prim_file:on_load(),
- conditional_load(socket, [socket, net]), % socket:on_load(), net:on_load(),
+ %% socket:on_load(), prim_net:on_load(),
+ conditional_load(socket, [socket, prim_net]),
%% Proceed to the specified boot module
run(Mod, boot, BootArgs).
@@ -49,7 +50,9 @@ run(M, F, A) ->
end.
conditional_load(CondMod, Mods2Load) ->
- conditional_load(CondMod, erlang:loaded(), Mods2Load).
+ Loaded = erlang:loaded(),
+ %% erlang:display({?MODULE, conditional_load, Loaded}),
+ conditional_load(CondMod, Loaded, Mods2Load).
conditional_load(_CondMod, [], _Mods2LOad) ->
ok;
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index 374facb2a3..4dab3de006 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -427,7 +427,7 @@ accept_opts(L, S, FamilyOpts) ->
case
getopts(
L,
- [active, nodelay, keepalive, delay_send, priority]
+ [active, nodelay, keepalive, delay_send, priority, linger]
++ FamilyOpts)
of
{ok, Opts} ->
diff --git a/erts/preloaded/src/net.erl b/erts/preloaded/src/prim_net.erl
index 13d2e3a117..107043d1aa 100644
--- a/erts/preloaded/src/net.erl
+++ b/erts/preloaded/src/prim_net.erl
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
%%
--module(net).
+-module(prim_net).
-compile(no_native).
@@ -31,22 +31,14 @@
-export([
gethostname/0,
- getnameinfo/1, getnameinfo/2,
- getaddrinfo/1, getaddrinfo/2,
+ getnameinfo/2,
+ getaddrinfo/2,
if_name2index/1,
if_index2name/1,
if_names/0
]).
-%% Deprecated functions from the "old" net module
--export([call/4,
- cast/4,
- broadcast/3,
- ping/1,
- relay/1,
- sleep/1]).
-
-export_type([
address_info/0,
name_info/0,
@@ -59,13 +51,6 @@
network_interface_index/0
]).
--deprecated({call, 4, eventually}).
--deprecated({cast, 4, eventually}).
--deprecated({broadcast, 3, eventually}).
--deprecated({ping, 1, eventually}).
--deprecated({relay, 1, eventually}).
--deprecated({sleep, 1, eventually}).
-
-type name_info_flags() :: [name_info_flag()|name_info_flag_ext()].
-type name_info_flag() :: namereqd |
@@ -88,21 +73,6 @@
%% ===========================================================================
%%
-%% D E P R E C A T E D F U N C T I O N S
-%%
-%% ===========================================================================
-
-call(N,M,F,A) -> rpc:call(N,M,F,A).
-cast(N,M,F,A) -> rpc:cast(N,M,F,A).
-broadcast(M,F,A) -> rpc:eval_everywhere(M,F,A).
-ping(Node) -> net_adm:ping(Node).
-sleep(T) -> receive after T -> ok end.
-relay(X) -> slave:relay(X).
-
-
-
-%% ===========================================================================
-%%
%% Administrative and utility API
%%
%% ===========================================================================
@@ -117,7 +87,7 @@ on_load() ->
Extra :: map().
on_load(Extra) ->
- ok = erlang:load_nif(atom_to_list(?MODULE), Extra).
+ ok = erlang:load_nif(atom_to_list(net), Extra).
-spec info() -> list().
@@ -159,14 +129,6 @@ gethostname() ->
%%
%%
--spec getnameinfo(SockAddr) -> {ok, Info} | {error, Reason} when
- SockAddr :: socket:sockaddr(),
- Info :: name_info(),
- Reason :: term().
-
-getnameinfo(SockAddr) ->
- getnameinfo(SockAddr, undefined).
-
-spec getnameinfo(SockAddr, Flags) -> {ok, Info} | {error, Reason} when
SockAddr :: socket:sockaddr(),
Flags :: name_info_flags() | undefined,
@@ -178,44 +140,18 @@ getnameinfo(SockAddr, [] = _Flags) ->
getnameinfo(#{family := Fam, addr := _Addr} = SockAddr, Flags)
when ((Fam =:= inet) orelse (Fam =:= inet6)) andalso
(is_list(Flags) orelse (Flags =:= undefined)) ->
- nif_getnameinfo((catch ensure_sockaddr(SockAddr)), Flags);
+ nif_getnameinfo(socket:ensure_sockaddr(SockAddr), Flags);
getnameinfo(#{family := Fam, path := _Path} = SockAddr, Flags)
when (Fam =:= local) andalso (is_list(Flags) orelse (Flags =:= undefined)) ->
nif_getnameinfo(SockAddr, Flags).
-%% This function is intended to "handle" the case when the user
-%% has built their (OTP) system with "--disable-esock".
-%% That means the socket module does not exist. This is not really
-%% a problem since the nif_getnameinfo won't work either (since
-%% the nif file is not part of the system). The result of calling
-%% getnameinfo will be a undef exception (erlang:nif_error(undef)).
-%%
-%% The only functions in this module that actually work in this case
-%% (--disable-esock) is the depricated stuff (call, cast, ...).
-%%
-ensure_sockaddr(SockAddr) ->
- try socket:ensure_sockaddr(SockAddr)
- catch
- error:undef:_ ->
- undefined
- end.
-
%% ===========================================================================
%%
%% getaddrinfo - Network address and service translation
%%
%% There is also a "hint" argument that we "at some point" should implement.
--spec getaddrinfo(Host) -> {ok, Info} | {error, Reason} when
- Host :: string(),
- Info :: [address_info()],
- Reason :: term().
-
-getaddrinfo(Host) when is_list(Host) ->
- getaddrinfo(Host, undefined).
-
-
-spec getaddrinfo(Host, undefined) -> {ok, Info} | {error, Reason} when
Host :: string(),
Info :: [address_info()],
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index ae1ffdb4ac..07e720c44d 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -26,9 +26,13 @@
%% Administrative and "global" utility functions
-export([
on_load/0, on_load/1,
- info/0,
- supports/0, supports/1, supports/2, supports/3,
- ensure_sockaddr/1
+
+ ensure_sockaddr/1,
+
+ debug/1,
+ %% command/1,
+ info/0, info/1,
+ supports/0, supports/1, supports/2, supports/3
]).
-export([
@@ -63,6 +67,12 @@
select_ref/0,
select_info/0,
+ socket_counters/0,
+ socket_counter/0,
+ socket_info/0,
+
+ %% command/0,
+
domain/0,
type/0,
protocol/0,
@@ -135,6 +145,27 @@
]).
+%% The command type has the general form:
+%% #{
+%% command := atom(),
+%% data := term()
+%% }
+%% But only certain values are actually valid, so the type gets the form:
+-type debug_command() :: #{
+ command := debug,
+ data := boolean()
+ }.
+%% -type command() :: debug_command().
+
+-type socket_counters() :: [{socket_counter(), non_neg_integer()}].
+-type socket_counter() :: read_byte | read_fails | read_pkg | read_tries |
+ read_waits | write_byte | write_fails | write_pkg |
+ write_tries | write_waits.
+-type socket_info() :: #{counters := socket_counters(),
+ num_readers := non_neg_integer(),
+ num_writers := non_neg_integer(),
+ num_acceptors := non_neg_integer()}.
+
-type uint8() :: 0..16#FF.
-type uint16() :: 0..16#FFFF.
-type uint20() :: 0..16#FFFFF.
@@ -282,7 +313,8 @@
path := binary() | string()}.
-type sockaddr_in4() :: #{family := inet,
port := port_number(),
- addr := any | loopback | ip4_address()}.
+ %% The 'broadcast' here is the "limited broadcast"
+ addr := any | broadcast | loopback | ip4_address()}.
-type sockaddr_in6() :: #{family := inet6,
port := port_number(),
addr := any | loopback | ip6_address(),
@@ -303,7 +335,7 @@
-define(SOCKADDR_IN6_DEFAULTS, ?SOCKADDR_IN6_DEFAULTS(any)).
-define(SOCKADDR_IN6_DEFAULT(A), (?SOCKADDR_IN6_DEFAULTS(A))#{family => inet6}).
-%% otp - The option is internal to our (OTP) imeplementation.
+%% otp - This option is internal to our (OTP) implementation.
%% socket - The socket layer (SOL_SOCKET).
%% ip - The IP layer (SOL_IP or is it IPPROTO_IP?).
%% ipv6 - The IPv6 layer (SOL_IPV6).
@@ -311,6 +343,7 @@
%% udp - The UDP (User Datagram Protocol) layer (IPPROTO_UDP).
%% sctp - The SCTP (Stream Control Transmission Protocol) layer (IPPROTO_SCTP).
%% Int - Raw level, sent down and used "as is".
+%% Its up to the caller to make sure this is correct!
-type sockopt_level() :: otp |
socket |
ip | ipv6 | tcp | udp | sctp |
@@ -594,11 +627,11 @@
-opaque select_tag() :: atom().
-opaque select_ref() :: reference().
--record(select_info, {tag :: select_tag(), ref :: select_ref()}).
+%% -record(select_info, {tag :: select_tag(), ref :: select_ref()}).
--type select_info() :: #select_info{}.
+-type select_info() :: {select_info, select_tag(), select_ref()}.
--define(SELECT_INFO(T, R), #select_info{tag = T, ref = R}).
+-define(SELECT_INFO(T, R), {select_info, T, R}).
-define(SELECT(T, R), {select, ?SELECT_INFO(T, R)}).
@@ -861,12 +894,46 @@ on_load(Extra) ->
--spec info() -> list().
+-spec info() -> map().
info() ->
nif_info().
+-spec debug(D) -> ok when
+ D :: boolean().
+
+debug(D) when is_boolean(D) ->
+ command(#{command => debug,
+ data => D}).
+
+
+-spec command(Command) -> ok when
+ Command :: debug_command().
+
+command(#{command := debug,
+ data := Dbg} = Command) when is_boolean(Dbg) ->
+ nif_command(Command).
+
+
+
+%% ===========================================================================
+%%
+%% info - Get miscellaneous information about a socket.
+%%
+%% Generates a list of various info about the socket, such as counter values.
+%%
+%% Do *not* call this function often.
+%%
+%% ===========================================================================
+
+-spec info(Socket) -> socket_info() when
+ Socket :: socket().
+
+info(#socket{ref = SockRef}) ->
+ nif_info(SockRef).
+
+
%% ===========================================================================
%%
@@ -1081,19 +1148,25 @@ open(Domain, Type, Protocol, Extra) when is_map(Extra) ->
%%
%% bind - bind a name to a socket
%%
+%% Note that Addr can only have the value of broadcast *if* Domain =:= inet!
+%%
-spec bind(Socket, Addr) -> ok | {error, Reason} when
Socket :: socket(),
- Addr :: any | loopback | sockaddr(),
+ Addr :: any | broadcast | loopback | sockaddr(),
Reason :: term().
bind(#socket{ref = SockRef}, Addr)
- when ((Addr =:= any) orelse (Addr =:= loopback)) ->
+ when ((Addr =:= any) orelse
+ (Addr =:= broadcast) orelse
+ (Addr =:= loopback)) ->
try which_domain(SockRef) of
inet ->
nif_bind(SockRef, ?SOCKADDR_IN4_DEFAULT(Addr));
- inet6 ->
- nif_bind(SockRef, ?SOCKADDR_IN6_DEFAULT(Addr))
+ inet6 when (Addr =:= any) orelse (Addr =:= loopback) ->
+ nif_bind(SockRef, ?SOCKADDR_IN6_DEFAULT(Addr));
+ _ ->
+ einval()
catch
%% <WIN32-TEMPORARY>
error:notsup:S ->
@@ -1236,7 +1309,7 @@ connect(#socket{ref = SockRef}, #{family := Fam} = SockAddr, Timeout)
((Timeout =:= nowait) orelse
(Timeout =:= infinity) orelse is_integer(Timeout)) ->
TS = timestamp(Timeout),
- case nif_connect(SockRef, SockAddr) of
+ case nif_connect(SockRef, ensure_sockaddr(SockAddr)) of
ok ->
%% Connected!
ok;
@@ -1494,7 +1567,7 @@ do_send(SockRef, Data, EFlags, Timeout) ->
ok | {error, Reason} when
Socket :: socket(),
Data :: binary(),
- Dest :: null | sockaddr(),
+ Dest :: sockaddr(),
Reason :: term().
sendto(Socket, Data, Dest) ->
@@ -1503,7 +1576,7 @@ sendto(Socket, Data, Dest) ->
-spec sendto(Socket, Data, Dest, Flags) -> ok | {error, Reason} when
Socket :: socket(),
Data :: binary(),
- Dest :: null | sockaddr(),
+ Dest :: sockaddr(),
Flags :: send_flags(),
Reason :: term()
; (Socket, Data, Dest, Timeout :: nowait) -> ok |
@@ -1511,13 +1584,13 @@ sendto(Socket, Data, Dest) ->
{error, Reason} when
Socket :: socket(),
Data :: iodata(),
- Dest :: null | sockaddr(),
+ Dest :: sockaddr(),
SelectInfo :: select_info(),
Reason :: term()
; (Socket, Data, Dest, Timeout) -> ok | {error, Reason} when
Socket :: socket(),
Data :: iodata(),
- Dest :: null | sockaddr(),
+ Dest :: sockaddr(),
Timeout :: timeout(),
Reason :: term().
@@ -1532,14 +1605,14 @@ sendto(Socket, Data, Dest, Timeout) ->
{error, Reason} when
Socket :: socket(),
Data :: binary(),
- Dest :: null | sockaddr(),
+ Dest :: sockaddr(),
Flags :: send_flags(),
SelectInfo :: select_info(),
Reason :: term()
; (Socket, Data, Dest, Flags, Timeout) -> ok | {error, Reason} when
Socket :: socket(),
Data :: binary(),
- Dest :: null | sockaddr(),
+ Dest :: sockaddr(),
Flags :: send_flags(),
Timeout :: timeout(),
Reason :: term().
@@ -1547,15 +1620,6 @@ sendto(Socket, Data, Dest, Timeout) ->
sendto(Socket, Data, Dest, Flags, Timeout) when is_list(Data) ->
Bin = erlang:list_to_binary(Data),
sendto(Socket, Bin, Dest, Flags, Timeout);
-sendto(#socket{ref = SockRef}, Data, Dest, Flags, Timeout)
- when is_binary(Data) andalso
- (Dest =:= null) andalso
- is_list(Flags) andalso
- ((Timeout =:= nowait) orelse
- (Timeout =:= infinity) orelse
- (is_integer(Timeout) andalso (Timeout > 0))) ->
- EFlags = enc_send_flags(Flags),
- do_sendto(SockRef, Data, Dest, EFlags, Timeout);
sendto(#socket{ref = SockRef}, Data, #{family := Fam} = Dest, Flags, Timeout)
when is_binary(Data) andalso
((Fam =:= inet) orelse (Fam =:= inet6) orelse (Fam =:= local)) andalso
@@ -1564,7 +1628,7 @@ sendto(#socket{ref = SockRef}, Data, #{family := Fam} = Dest, Flags, Timeout)
(Timeout =:= infinity) orelse
(is_integer(Timeout) andalso (Timeout > 0))) ->
EFlags = enc_send_flags(Flags),
- do_sendto(SockRef, Data, Dest, EFlags, Timeout).
+ do_sendto(SockRef, Data, ensure_sockaddr(Dest), EFlags, Timeout).
do_sendto(SockRef, Data, Dest, EFlags, Timeout) ->
TS = timestamp(Timeout),
@@ -1755,8 +1819,12 @@ do_sendmsg_rest([B|IOVec], Written) ->
ensure_msghdr(#{ctrl := []} = M) ->
ensure_msghdr(maps:remove(ctrl, M));
-ensure_msghdr(#{iov := IOV} = M) when is_list(IOV) andalso (IOV =/= []) ->
- M#{iov := erlang:iolist_to_iovec(IOV)};
+ensure_msghdr(#{iov := IOV, addr := Addr} = M)
+ when is_list(IOV) andalso (IOV =/= []) ->
+ M#{iov => erlang:iolist_to_iovec(IOV), addr => ensure_sockaddr(Addr)};
+ensure_msghdr(#{iov := IOV} = M)
+ when is_list(IOV) andalso (IOV =/= []) ->
+ M#{iov => erlang:iolist_to_iovec(IOV)};
ensure_msghdr(_) ->
einval().
@@ -2617,7 +2685,7 @@ peername(#socket{ref = SockRef}) ->
SelectInfo :: select_info(),
Reason :: term().
-cancel(#socket{ref = SockRef}, #select_info{tag = Tag, ref = Ref}) ->
+cancel(#socket{ref = SockRef}, ?SELECT_INFO(Tag, Ref)) ->
cancel(SockRef, Tag, Ref).
@@ -2628,17 +2696,17 @@ cancel(#socket{ref = SockRef}, #select_info{tag = Tag, ref = Ref}) ->
%%
%% ===========================================================================
--spec enc_domain(Domain) -> non_neg_integer() when
- Domain :: domain().
+%% -spec enc_domain(Domain) -> non_neg_integer() when
+%% Domain :: domain().
enc_domain(local) -> ?SOCKET_DOMAIN_LOCAL;
enc_domain(inet) -> ?SOCKET_DOMAIN_INET;
enc_domain(inet6) -> ?SOCKET_DOMAIN_INET6;
enc_domain(Domain) -> invalid_domain(Domain).
--spec enc_type(Domain, Type) -> non_neg_integer() when
- Domain :: domain(),
- Type :: type().
+%% -spec enc_type(Domain, Type) -> non_neg_integer() when
+%% Domain :: domain(),
+%% Type :: type().
%% What combos are valid?
enc_type(_, stream) -> ?SOCKET_TYPE_STREAM;
@@ -3308,10 +3376,12 @@ enc_sockopt_key(otp = L, Opt, _, _, _, _) ->
%% +++ SOCKET socket options +++
enc_sockopt_key(socket = _L, acceptconn = _Opt, get = _Dir, _D, _T, _P) ->
?SOCKET_OPT_SOCK_ACCEPTCONN;
+enc_sockopt_key(socket = L, acceptconn = Opt, Dir, _D, _T, _P) ->
+ not_supported({L, Opt, Dir});
enc_sockopt_key(socket = L, acceptfilter = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-%% Before linux 3.8, this socket option could be set.
-%% Maximum size of buffer for name: IFNAMSZIZ
+%% Before linux 3.8, this socket option could be set but not get.
+%% Maximum size of buffer for name: IFNAMSIZ
%% So, we let the implementation decide.
enc_sockopt_key(socket = _L, bindtodevice = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_SOCK_BINDTODEVICE;
@@ -3845,6 +3915,12 @@ error(Reason) ->
nif_info() ->
erlang:nif_error(undef).
+nif_info(_SRef) ->
+ erlang:nif_error(undef).
+
+nif_command(_Command) ->
+ erlang:nif_error(undef).
+
nif_supports(_Key) ->
erlang:nif_error(undef).
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 40a9685e9d..f06fd08540 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 10.4.3
+VSN = 10.4.4
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/common_test/src/ct_release_test.erl b/lib/common_test/src/ct_release_test.erl
index ac3dcab7c9..839fb300c7 100644
--- a/lib/common_test/src/ct_release_test.erl
+++ b/lib/common_test/src/ct_release_test.erl
@@ -475,7 +475,7 @@ fetch_all_apps(Node) ->
A = list_to_atom(filename:basename(filename:rootname(F))),
_ = rpc:call(Node,application,load,[A]),
case rpc:call(Node,application,get_key,[A,vsn]) of
- {ok,V} -> [{A,V}];
+ {ok,V} -> [{A,V,rpc:call(Node,code,lib_dir,[A])}];
_ -> []
end
end,
@@ -517,7 +517,7 @@ upgrade(Apps,Level,Callback,CreateDir,InstallDir,Config) ->
target_system(Apps,CreateDir,InstallDir,{FromVsn,_,AllAppsVsns,Path}) ->
RelName0 = "otp-"++FromVsn,
- AppsVsns = [{A,V} || {A,V} <- AllAppsVsns, lists:member(A,Apps)],
+ AppsVsns = [{A,V,D} || {A,V,D} <- AllAppsVsns, lists:member(A,Apps)],
{RelName,ErtsVsn} = create_relfile(AppsVsns,CreateDir,RelName0,FromVsn),
%% Create .script and .boot
@@ -636,8 +636,7 @@ do_upgrade({Cb,InitState},FromVsn,FromAppsVsns,ToRel,ToAppsVsns,InstallDir) ->
{ok,Node} = start_node(Start,FromVsn,FromAppsVsns),
ct:log("Node started: ~p",[Node]),
- CtData = #ct_data{from = [{A,V,code:lib_dir(A)} || {A,V} <- FromAppsVsns],
- to=[{A,V,code:lib_dir(A)} || {A,V} <- ToAppsVsns]},
+ CtData = #ct_data{from = FromAppsVsns,to=ToAppsVsns},
State1 = do_callback(Node,Cb,upgrade_init,[CtData,InitState]),
[{"OTP upgrade test",FromVsn,_,permanent}] =
@@ -724,14 +723,14 @@ previous_major(Rel) ->
integer_to_list(list_to_integer(Rel)-1).
create_relfile(AppsVsns,CreateDir,RelName0,RelVsn) ->
- UpgradeAppsVsns = [{A,V,restart_type(A)} || {A,V} <- AppsVsns],
+ UpgradeAppsVsns = [{A,V,restart_type(A)} || {A,V,_D} <- AppsVsns],
CoreAppVsns0 = get_vsns([kernel,stdlib,sasl]),
CoreAppVsns =
- [{A,V,restart_type(A)} || {A,V} <- CoreAppVsns0,
+ [{A,V,restart_type(A)} || {A,V,_D} <- CoreAppVsns0,
false == lists:keymember(A,1,AppsVsns)],
- Apps = [App || {App,_} <- AppsVsns],
+ Apps = [App || {App,_,_} <- AppsVsns],
StartDepsVsns = get_start_deps(Apps,CoreAppVsns),
StartApps = [StartApp || {StartApp,_,_} <- StartDepsVsns] ++ Apps,
@@ -744,7 +743,7 @@ create_relfile(AppsVsns,CreateDir,RelName0,RelVsn) ->
%% processes of these applications will not be running.
TestToolAppsVsns0 = get_vsns([common_test]),
TestToolAppsVsns =
- [{A,V,none} || {A,V} <- TestToolAppsVsns0,
+ [{A,V,none} || {A,V,_D} <- TestToolAppsVsns0,
false == lists:keymember(A,1,AllAppsVsns0)],
AllAppsVsns1 = AllAppsVsns0 ++ TestToolAppsVsns,
@@ -766,7 +765,7 @@ get_vsns(Apps) ->
[begin
_ = application:load(A),
{ok,V} = application:get_key(A,vsn),
- {A,V}
+ {A,V,code:lib_dir(A)}
end || A <- Apps].
get_start_deps([App|Apps],Acc) ->
@@ -880,8 +879,9 @@ start_node(Start,ExpVsn,ExpAppsVsns) ->
erlang:port_close(Port),
wait_node_up(permanent,ExpVsn,ExpAppsVsns).
-wait_node_up(ExpStatus,ExpVsn,ExpAppsVsns) ->
+wait_node_up(ExpStatus,ExpVsn,ExpAppsVsns0) ->
Node = node_name(?testnode),
+ ExpAppsVsns = [{A,V} || {A,V,_D} <- ExpAppsVsns0],
wait_node_up(Node,ExpStatus,ExpVsn,lists:keysort(1,ExpAppsVsns),60).
wait_node_up(Node,ExpStatus,ExpVsn,ExpAppsVsns,0) ->
@@ -893,7 +893,7 @@ wait_node_up(Node,ExpStatus,ExpVsn,ExpAppsVsns,N) ->
rpc:call(Node, application, which_applications, [])} of
{[{_,ExpVsn,_,_}],Apps} when is_list(Apps) ->
case [{A,V} || {A,_,V} <- lists:keysort(1,Apps),
- lists:keymember(A,1,ExpAppsVsns)] of
+ lists:keymember(A,1,ExpAppsVsns)] of
ExpAppsVsns ->
{ok,Node};
_ ->
diff --git a/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl b/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl
index 7f0ba65791..fe69ad0748 100644
--- a/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl
+++ b/lib/common_test/test/ct_release_test_SUITE_data/release_test_SUITE.erl
@@ -47,7 +47,9 @@ end_per_suite(_Config) ->
init_per_testcase(major_fail_no_init, Config) ->
Config;
init_per_testcase(_Case, Config) ->
- ct_release_test:init(Config).
+ Config1 = ct_release_test:init(Config),
+ ct:log("ct_release_test:init/1 returned:~n~p",[Config1]),
+ Config1.
end_per_testcase(_Case, Config) ->
ct_release_test:cleanup(Config).
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index f0d869381b..f11444137d 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -32,6 +32,50 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 7.4.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fixed a compiler crash introduced in <c>22.0.6</c>
+ (OTP-15952).</p>
+ <p>
+ Own Id: OTP-15953 Aux Id: ERL-999 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 7.4.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fixed an unsafe optimization when matching
+ <c>tuple_size/1</c> outside of guards, which could crash
+ the emulator if the argument was not a tuple.</p>
+ <p>
+ Own Id: OTP-15945</p>
+ </item>
+ <item>
+ <p>Fixed a rare bug that could cause the wrong kind of
+ exception to be thrown when a BIF failed in a function
+ that matched bitstrings.</p>
+ <p>
+ Own Id: OTP-15946</p>
+ </item>
+ <item>
+ <p>Fixed a bug where receive statements inside try/catch
+ blocks could return incorrect results.</p>
+ <p>
+ Own Id: OTP-15952</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 7.4.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/src/beam_except.erl b/lib/compiler/src/beam_except.erl
index 2305502800..2b9c1b0cf5 100644
--- a/lib/compiler/src/beam_except.erl
+++ b/lib/compiler/src/beam_except.erl
@@ -152,7 +152,7 @@ dig_out_fc(Arity, Is0) ->
({test,_,_,_}) -> false;
(_) -> true
end, Is0),
- {Regs,Acc} = dig_out_fc_1(reverse(Is), Regs0, Acc0),
+ {Regs,Acc} = dig_out_fc_1(reverse(Is), Arity, Regs0, Acc0),
case Regs of
#{{x,0}:={atom,function_clause},{x,1}:=Args} ->
case moves_from_stack(Args, 0, []) of
@@ -165,19 +165,27 @@ dig_out_fc(Arity, Is0) ->
no
end.
-dig_out_fc_1([{block,Bl}|Is], Regs0, Acc) ->
+dig_out_fc_1([{block,Bl}|Is], Arity, Regs0, Acc) ->
Regs = dig_out_fc_block(Bl, Regs0),
- dig_out_fc_1(Is, Regs, Acc);
-dig_out_fc_1([{bs_set_position,_,_}=I|Is], Regs, Acc) ->
- dig_out_fc_1(Is, Regs, [I|Acc]);
-dig_out_fc_1([{bs_get_tail,Src,Dst,Live0}|Is], Regs0, Acc) ->
- Regs = prune_xregs(Live0, Regs0),
- Live = dig_out_stack_live(Regs, Live0),
- I = {bs_get_tail,Src,Dst,Live},
- dig_out_fc_1(Is, Regs, [I|Acc]);
-dig_out_fc_1([_|_], _Regs, _Acc) ->
+ dig_out_fc_1(Is, Arity, Regs, Acc);
+dig_out_fc_1([{bs_set_position,_,_}=I|Is], Arity, Regs, Acc) ->
+ dig_out_fc_1(Is, Arity, Regs, [I|Acc]);
+dig_out_fc_1([{bs_get_tail,Src,Dst,Live0}|Is], Arity, Regs0, Acc) ->
+ case Src of
+ {x,X} when X < Arity ->
+ %% The heuristic for determining the number of live
+ %% registers is likely to give an incorrect result.
+ %% Give up.
+ {#{},[]};
+ _ ->
+ Regs = prune_xregs(Live0, Regs0),
+ Live = dig_out_stack_live(Regs, Live0),
+ I = {bs_get_tail,Src,Dst,Live},
+ dig_out_fc_1(Is, Arity, Regs, [I|Acc])
+ end;
+dig_out_fc_1([_|_], _Arity, _Regs, _Acc) ->
{#{},[]};
-dig_out_fc_1([], Regs, Acc) ->
+dig_out_fc_1([], _Arity, Regs, Acc) ->
{Regs,Acc}.
dig_out_fc_block([{set,[],[],{alloc,Live,_}}|Is], Regs0) ->
diff --git a/lib/compiler/src/beam_ssa_bsm.erl b/lib/compiler/src/beam_ssa_bsm.erl
index 382e6f635e..1ac9e6a3bb 100644
--- a/lib/compiler/src/beam_ssa_bsm.erl
+++ b/lib/compiler/src/beam_ssa_bsm.erl
@@ -683,8 +683,12 @@ aca_copy_successors(Lbl0, Blocks0, Counter0) ->
Lbl = maps:get(Lbl0, BRs),
{Lbl, Blocks, Counter}.
+aca_cs_build_brs([?BADARG_BLOCK=Lbl | Path], Counter, Acc) ->
+ %% ?BADARG_BLOCK is a marker and not an actual block, so renaming it will
+ %% break exception handling.
+ aca_cs_build_brs(Path, Counter, Acc#{ Lbl => Lbl });
aca_cs_build_brs([Lbl | Path], Counter0, Acc) ->
- aca_cs_build_brs(Path, Counter0 + 1, maps:put(Lbl, Counter0, Acc));
+ aca_cs_build_brs(Path, Counter0 + 1, Acc#{ Lbl => Counter0 });
aca_cs_build_brs([], Counter, Acc) ->
{Acc, Counter}.
diff --git a/lib/compiler/src/beam_ssa_codegen.erl b/lib/compiler/src/beam_ssa_codegen.erl
index 07f4c8b461..08641e2abc 100644
--- a/lib/compiler/src/beam_ssa_codegen.erl
+++ b/lib/compiler/src/beam_ssa_codegen.erl
@@ -764,9 +764,8 @@ defined(Linear, #cg{regs=Regs}) ->
def([{L,#cg_blk{is=Is0,last=Last}=Blk0}|Bs], DefMap0, Regs) ->
Def0 = def_get(L, DefMap0),
- {Is,Def} = def_is(Is0, Regs, Def0, []),
- Successors = successors(Last),
- DefMap = def_successors(Successors, Def, DefMap0),
+ {Is,Def,MaybeDef} = def_is(Is0, Regs, Def0, []),
+ DefMap = def_successors(Last, Def, MaybeDef, DefMap0),
Blk = Blk0#cg_blk{is=Is},
[{L,Blk}|def(Bs, DefMap, Regs)];
def([], _, _) -> [].
@@ -780,6 +779,11 @@ def_get(L, DefMap) ->
def_is([#cg_alloc{anno=Anno0}=I0|Is], Regs, Def, Acc) ->
I = I0#cg_alloc{anno=Anno0#{def_yregs=>Def}},
def_is(Is, Regs, Def, [I|Acc]);
+def_is([#cg_set{op=succeeded,args=[Var]}=I], Regs, Def, Acc) ->
+ %% Var will only be defined on the success branch of the `br`
+ %% for this block.
+ MaybeDef = def_add_yreg(Var, [], Regs),
+ {reverse(Acc, [I]),Def,MaybeDef};
def_is([#cg_set{op=kill_try_tag,args=[#b_var{}=Tag]}=I|Is], Regs, Def0, Acc) ->
Def = ordsets:del_element(Tag, Def0),
def_is(Is, Regs, Def, [I|Acc]);
@@ -822,7 +826,7 @@ def_is([#cg_set{anno=Anno0,dst=Dst}=I0|Is], Regs, Def0, Acc) ->
Def = def_add_yreg(Dst, Def0, Regs),
def_is(Is, Regs, Def, [I|Acc]);
def_is([], _, Def, Acc) ->
- {reverse(Acc),Def}.
+ {reverse(Acc),Def,[]}.
def_add_yreg(Dst, Def, Regs) ->
case is_yreg(Dst, Regs) of
@@ -830,6 +834,12 @@ def_add_yreg(Dst, Def, Regs) ->
false -> Def
end.
+def_successors(#cg_br{bool=#b_var{},succ=Succ,fail=Fail}, Def, MaybeDef, DefMap0) ->
+ DefMap = def_successors([Fail], ordsets:subtract(Def, MaybeDef), DefMap0),
+ def_successors([Succ], Def, DefMap);
+def_successors(Last, Def, [], DefMap) ->
+ def_successors(successors(Last), Def, DefMap).
+
def_successors([S|Ss], Def0, DefMap) ->
case DefMap of
#{S:=Def1} ->
diff --git a/lib/compiler/src/beam_ssa_dead.erl b/lib/compiler/src/beam_ssa_dead.erl
index 64b9b3e222..e78e4647a8 100644
--- a/lib/compiler/src/beam_ssa_dead.erl
+++ b/lib/compiler/src/beam_ssa_dead.erl
@@ -30,7 +30,7 @@
-import(lists, [append/1,keymember/3,last/1,member/2,
takewhile/2,reverse/1]).
--type used_vars() :: #{beam_ssa:label():=ordsets:ordset(beam_ssa:var_name())}.
+-type used_vars() :: #{beam_ssa:label():=cerl_sets:set(beam_ssa:var_name())}.
-type basic_type_test() :: atom() | {'is_tagged_tuple',pos_integer(),atom()}.
-type type_test() :: basic_type_test() | {'not',basic_type_test()}.
@@ -90,13 +90,11 @@ shortcut_opt(#st{bs=Blocks}=St) ->
%% the diff.)
%%
%% Unfortunately, processing the blocks in reverse post order
- %% potentially makes the time complexity quadratic or even cubic if
- %% the ordset of unset variables grows large, instead of
- %% linear for post order processing. We try to still get reasonable
- %% compilation times by optimizations that will keep the constant
- %% factor as low as possible, and we try to avoid the cubic time
- %% complexity by trying to keep the set of unset variables as small
- %% as possible.
+ %% potentially makes the time complexity quadratic, instead of
+ %% linear for post order processing. We avoid drastic slowdowns by
+ %% limiting how far we search forward to a common block that
+ %% both the success and failure label will reach (see the comment
+ %% in the first clause of shortcut_2/5).
Ls = beam_ssa:rpo(Blocks),
shortcut_opt(Ls, #{}, St).
@@ -124,10 +122,15 @@ shortcut_terminator(#b_br{bool=#b_var{}=Bool,succ=Succ0,fail=Fail0}=Br,
Is, From, Bs, St0) ->
St = St0#st{target=one_way},
RelOp = get_rel_op(Bool, Is),
- SuccBs = bind_var(Bool, #b_literal{val=true}, Bs),
+
+ %% The boolean in a `br` is seldom used by the successors. By
+ %% not binding its value unless it is actually used we might be able
+ %% to skip some work in shortcut/4 and sub/2.
+ SuccBs = bind_var_if_used(Succ0, Bool, #b_literal{val=true}, Bs, St),
BrSucc = shortcut(Succ0, From, SuccBs, St#st{rel_op=RelOp}),
- FailBs = bind_var(Bool, #b_literal{val=false}, Bs),
+ FailBs = bind_var_if_used(Fail0, Bool, #b_literal{val=false}, Bs, St),
BrFail = shortcut(Fail0, From, FailBs, St#st{rel_op=invert_op(RelOp)}),
+
case {BrSucc,BrFail} of
{#b_br{bool=#b_literal{val=true},succ=Succ},
#b_br{bool=#b_literal{val=true},succ=Fail}}
@@ -152,8 +155,14 @@ shortcut_switch([{Lit,L0}|T], Bool, From, Bs, St0) ->
[{Lit,L}|shortcut_switch(T, Bool, From, Bs, St0)];
shortcut_switch([], _, _, _, _) -> [].
+shortcut(L, _From, Bs, #st{rel_op=none,target=one_way}) when map_size(Bs) =:= 0 ->
+ %% There is no way that we can find a suitable branch, because there is no
+ %% relational operator stored, there are no bindings, and the block L can't
+ %% have any phi nodes from which we could pick bindings because when the target
+ %% is `one_way`, it implies the From block has a two-way `br` terminator.
+ #b_br{bool=#b_literal{val=true},succ=L,fail=L};
shortcut(L, From, Bs, St) ->
- shortcut_1(L, From, Bs, ordsets:new(), St).
+ shortcut_1(L, From, Bs, cerl_sets:new(), St).
shortcut_1(L, From, Bs0, UnsetVars0, St) ->
case shortcut_2(L, From, Bs0, UnsetVars0, St) of
@@ -170,7 +179,19 @@ shortcut_1(L, From, Bs0, UnsetVars0, St) ->
end.
%% Try to shortcut this block, branching to a successor.
-shortcut_2(L, From, Bs0, UnsetVars0, St) ->
+shortcut_2(L, From, Bs, UnsetVars, St) ->
+ case cerl_sets:size(UnsetVars) of
+ SetSize when SetSize > 128 ->
+ %% This is an heuristic to limit the search for a forced label
+ %% before it drastically slows down the compiler. Experiments
+ %% with scripts/diffable showed that limits larger than 31 did not
+ %% find any more opportunities for optimization.
+ none;
+ _SetSize ->
+ shortcut_3(L, From, Bs, UnsetVars, St)
+ end.
+
+shortcut_3(L, From, Bs0, UnsetVars0, St) ->
#b_blk{is=Is,last=Last} = get_block(L, St),
case eval_is(Is, From, Bs0, St) of
none ->
@@ -347,7 +368,7 @@ update_unset_vars(L, Is, Br, UnsetVars, #st{skippable=Skippable}) ->
%% Some variables defined in this block are used by
%% successors. We must update the set of unset variables.
SetInThisBlock = [V || #b_set{dst=V} <- Is],
- ordsets:union(UnsetVars, ordsets:from_list(SetInThisBlock))
+ cerl_sets:union(UnsetVars, cerl_sets:from_list(SetInThisBlock))
end.
shortcut_two_way(#b_br{succ=Succ,fail=Fail}, From, Bs0, UnsetVars0, St0) ->
@@ -376,14 +397,14 @@ is_br_safe(UnsetVars, Br, #st{us=Us}=St) ->
%% A two-way branch never branches to a phi node, so there
%% is no need to check for phi nodes here.
- not member(V, UnsetVars) andalso
- ordsets:is_disjoint(Used0, UnsetVars) andalso
- ordsets:is_disjoint(Used1, UnsetVars);
+ not cerl_sets:is_element(V, UnsetVars) andalso
+ cerl_sets:is_disjoint(Used0, UnsetVars) andalso
+ cerl_sets:is_disjoint(Used1, UnsetVars);
#b_br{succ=Same,fail=Same} ->
%% An unconditional branch must not jump to
%% a phi node.
not is_forbidden(Same, St) andalso
- ordsets:is_disjoint(map_get(Same, Us), UnsetVars)
+ cerl_sets:is_disjoint(map_get(Same, Us), UnsetVars)
end.
is_forbidden(L, St) ->
@@ -500,6 +521,15 @@ eval_switch_1([], _Arg, _PrevOp, Fail) ->
%% Fail is now either the failure label or 'none'.
Fail.
+bind_var_if_used(L, Var, Val0, Bs, #st{us=Us}) ->
+ case cerl_sets:is_element(Var, map_get(L, Us)) of
+ true ->
+ Val = get_value(Val0, Bs),
+ Bs#{Var=>Val};
+ false ->
+ Bs
+ end.
+
bind_var(Var, Val0, Bs) ->
Val = get_value(Val0, Bs),
Bs#{Var=>Val}.
@@ -989,7 +1019,7 @@ used_vars([{L,#b_blk{is=Is}=Blk}|Bs], UsedVars0, Skip0) ->
%% shortcut_opt/1.
Successors = beam_ssa:successors(Blk),
- Used0 = used_vars_succ(Successors, L, UsedVars0, []),
+ Used0 = used_vars_succ(Successors, L, UsedVars0, cerl_sets:new()),
Used = used_vars_blk(Blk, Used0),
UsedVars = used_vars_phis(Is, L, Used, UsedVars0),
@@ -1000,8 +1030,8 @@ used_vars([{L,#b_blk{is=Is}=Blk}|Bs], UsedVars0, Skip0) ->
%% shortcut_opt/1.
Defined0 = [Def || #b_set{dst=Def} <- Is],
- Defined = ordsets:from_list(Defined0),
- MaySkip = ordsets:is_disjoint(Defined, Used0),
+ Defined = cerl_sets:from_list(Defined0),
+ MaySkip = cerl_sets:is_disjoint(Defined, Used0),
case MaySkip of
true ->
Skip = Skip0#{L=>true},
@@ -1018,11 +1048,11 @@ used_vars_succ([S|Ss], L, LiveMap, Live0) ->
#{Key:=Live} ->
%% The successor has a phi node, and the value for
%% this block in the phi node is a variable.
- used_vars_succ(Ss, L, LiveMap, ordsets:union(Live, Live0));
+ used_vars_succ(Ss, L, LiveMap, cerl_sets:union(Live, Live0));
#{S:=Live} ->
%% No phi node in the successor, or the value for
%% this block in the phi node is a literal.
- used_vars_succ(Ss, L, LiveMap, ordsets:union(Live, Live0));
+ used_vars_succ(Ss, L, LiveMap, cerl_sets:union(Live, Live0));
#{} ->
%% A peek_message block which has not been processed yet.
used_vars_succ(Ss, L, LiveMap, Live0)
@@ -1040,7 +1070,7 @@ used_vars_phis(Is, L, Live0, UsedVars0) ->
case [{P,V} || {#b_var{}=V,P} <- PhiArgs] of
[_|_]=PhiVars ->
PhiLive0 = rel2fam(PhiVars),
- PhiLive = [{{L,P},ordsets:union(ordsets:from_list(Vs), Live0)} ||
+ PhiLive = [{{L,P},cerl_sets:union(cerl_sets:from_list(Vs), Live0)} ||
{P,Vs} <- PhiLive0],
maps:merge(UsedVars, maps:from_list(PhiLive));
[] ->
@@ -1050,14 +1080,14 @@ used_vars_phis(Is, L, Live0, UsedVars0) ->
end.
used_vars_blk(#b_blk{is=Is,last=Last}, Used0) ->
- Used = ordsets:union(Used0, beam_ssa:used(Last)),
+ Used = cerl_sets:union(Used0, cerl_sets:from_list(beam_ssa:used(Last))),
used_vars_is(reverse(Is), Used).
used_vars_is([#b_set{op=phi}|Is], Used) ->
used_vars_is(Is, Used);
used_vars_is([#b_set{dst=Dst}=I|Is], Used0) ->
- Used1 = ordsets:union(Used0, beam_ssa:used(I)),
- Used = ordsets:del_element(Dst, Used1),
+ Used1 = cerl_sets:union(Used0, cerl_sets:from_list(beam_ssa:used(I))),
+ Used = cerl_sets:del_element(Dst, Used1),
used_vars_is(Is, Used);
used_vars_is([], Used) ->
Used.
@@ -1066,8 +1096,9 @@ used_vars_is([], Used) ->
%%% Common utilities.
%%%
-sub(#b_set{args=Args}=I, Sub) ->
- I#b_set{args=[sub_arg(A, Sub) || A <- Args]}.
+sub(#b_set{args=Args}=I, Sub) when map_size(Sub) =/= 0 ->
+ I#b_set{args=[sub_arg(A, Sub) || A <- Args]};
+sub(I, _Sub) -> I.
sub_arg(#b_var{}=Old, Sub) ->
case Sub of
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl
index 90c0d3cf16..d87c66c272 100644
--- a/lib/compiler/src/beam_ssa_opt.erl
+++ b/lib/compiler/src/beam_ssa_opt.erl
@@ -904,8 +904,7 @@ cse_suitable(#b_set{}) -> false.
}).
ssa_opt_float({#st{ssa=Linear0,cnt=Count0}=St, FuncDb}) ->
- NonGuards0 = float_non_guards(Linear0),
- NonGuards = gb_sets:from_list(NonGuards0),
+ NonGuards = non_guards(Linear0),
Blocks = maps:from_list(Linear0),
Fs = #fs{non_guards=NonGuards,bs=Blocks},
{Linear,Count} = float_opt(Linear0, Count0, Fs),
@@ -916,15 +915,6 @@ float_blk_is_in_guard(#b_blk{last=#b_br{fail=F}}, #fs{non_guards=NonGuards}) ->
float_blk_is_in_guard(#b_blk{}, #fs{}) ->
false.
-float_non_guards([{L,#b_blk{is=Is}}|Bs]) ->
- case Is of
- [#b_set{op=landingpad}|_] ->
- [L|float_non_guards(Bs)];
- _ ->
- float_non_guards(Bs)
- end;
-float_non_guards([]) -> [?BADARG_BLOCK].
-
float_opt([{L,Blk}|Bs0], Count0, Fs) ->
case float_blk_is_in_guard(Blk, Fs) of
true ->
@@ -1774,35 +1764,44 @@ opt_bs_put_split_int_1(Int, L, R) ->
%%%
ssa_opt_tuple_size({#st{ssa=Linear0,cnt=Count0}=St, FuncDb}) ->
- {Linear,Count} = opt_tup_size(Linear0, Count0, []),
+ %% This optimization is only safe in guards, as prefixing tuple_size with
+ %% an is_tuple check prevents it from throwing an exception.
+ NonGuards = non_guards(Linear0),
+ {Linear,Count} = opt_tup_size(Linear0, NonGuards, Count0, []),
{St#st{ssa=Linear,cnt=Count}, FuncDb}.
-opt_tup_size([{L,#b_blk{is=Is,last=Last}=Blk}|Bs], Count0, Acc0) ->
+opt_tup_size([{L,#b_blk{is=Is,last=Last}=Blk}|Bs], NonGuards, Count0, Acc0) ->
case {Is,Last} of
{[#b_set{op={bif,'=:='},dst=Bool,args=[#b_var{}=Tup,#b_literal{val=Arity}]}],
#b_br{bool=Bool}} when is_integer(Arity), Arity >= 0 ->
- {Acc,Count} = opt_tup_size_1(Tup, L, Count0, Acc0),
- opt_tup_size(Bs, Count, [{L,Blk}|Acc]);
+ {Acc,Count} = opt_tup_size_1(Tup, L, NonGuards, Count0, Acc0),
+ opt_tup_size(Bs, NonGuards, Count, [{L,Blk}|Acc]);
{_,_} ->
- opt_tup_size(Bs, Count0, [{L,Blk}|Acc0])
+ opt_tup_size(Bs, NonGuards, Count0, [{L,Blk}|Acc0])
end;
-opt_tup_size([], Count, Acc) ->
+opt_tup_size([], _NonGuards, Count, Acc) ->
{reverse(Acc),Count}.
-opt_tup_size_1(Size, EqL, Count0, [{L,Blk0}|Acc]) ->
- case Blk0 of
- #b_blk{is=Is0,last=#b_br{bool=Bool,succ=EqL,fail=Fail}} ->
- case opt_tup_size_is(Is0, Bool, Size, []) of
- none ->
+opt_tup_size_1(Size, EqL, NonGuards, Count0, [{L,Blk0}|Acc]) ->
+ #b_blk{is=Is0,last=Last} = Blk0,
+ case Last of
+ #b_br{bool=Bool,succ=EqL,fail=Fail} ->
+ case gb_sets:is_member(Fail, NonGuards) of
+ true ->
{[{L,Blk0}|Acc],Count0};
- {PreIs,TupleSizeIs,Tuple} ->
- opt_tup_size_2(PreIs, TupleSizeIs, L, EqL,
- Tuple, Fail, Count0, Acc)
+ false ->
+ case opt_tup_size_is(Is0, Bool, Size, []) of
+ none ->
+ {[{L,Blk0}|Acc],Count0};
+ {PreIs,TupleSizeIs,Tuple} ->
+ opt_tup_size_2(PreIs, TupleSizeIs, L, EqL,
+ Tuple, Fail, Count0, Acc)
+ end
end;
- #b_blk{} ->
+ _ ->
{[{L,Blk0}|Acc],Count0}
end;
-opt_tup_size_1(_, _, Count, Acc) ->
+opt_tup_size_1(_, _, _, Count, Acc) ->
{Acc,Count}.
opt_tup_size_2(PreIs, TupleSizeIs, PreL, EqL, Tuple, Fail, Count0, Acc) ->
@@ -1940,12 +1939,24 @@ verify_merge_is(_) ->
is_merge_allowed(_, #b_blk{}, #b_blk{is=[#b_set{op=peek_message}|_]}) ->
false;
-is_merge_allowed(L, #b_blk{last=#b_br{}}=Blk, #b_blk{}) ->
+is_merge_allowed(L, #b_blk{last=#b_br{}}=Blk, #b_blk{is=Is}) ->
%% The predecessor block must have exactly one successor (L) for
%% the merge to be safe.
case beam_ssa:successors(Blk) of
- [L] -> true;
- [_|_] -> false
+ [L] ->
+ case Is of
+ [#b_set{op=phi,args=[_]}|_] ->
+ %% The type optimizer pass must have been
+ %% turned off, since it would have removed this
+ %% redundant phi node. Refuse to merge the blocks
+ %% to ensure that this phi node remains at the
+ %% beginning of a block.
+ false;
+ _ ->
+ true
+ end;
+ [_|_] ->
+ false
end;
is_merge_allowed(_, #b_blk{last=#b_switch{}}, #b_blk{}) ->
false.
@@ -2241,6 +2252,19 @@ gcd(A, B) ->
X -> gcd(B, X)
end.
+non_guards(Linear) ->
+ gb_sets:from_list(non_guards_1(Linear)).
+
+non_guards_1([{L,#b_blk{is=Is}}|Bs]) ->
+ case Is of
+ [#b_set{op=landingpad}|_] ->
+ [L | non_guards_1(Bs)];
+ _ ->
+ non_guards_1(Bs)
+ end;
+non_guards_1([]) ->
+ [?BADARG_BLOCK].
+
rel2fam(S0) ->
S1 = sofs:relation(S0),
S = sofs:rel2fam(S1),
diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl
index 9af72afca7..7f816b9802 100644
--- a/lib/compiler/src/beam_ssa_pre_codegen.erl
+++ b/lib/compiler/src/beam_ssa_pre_codegen.erl
@@ -156,7 +156,9 @@ passes(Opts) ->
%% Allocate registers.
?PASS(linear_scan),
?PASS(frame_size),
- ?PASS(turn_yregs)],
+ ?PASS(turn_yregs),
+
+ ?PASS(assert_no_critical_edges)],
[P || P <- Ps, P =/= ignore].
function(#b_function{anno=Anno,args=Args,bs=Blocks0,cnt=Count0}=F0,
@@ -1321,10 +1323,11 @@ fix_receives_1([{L,Blk}|Ls], Blocks0, Count0) ->
LoopExit = find_loop_exit(Rm, Blocks0),
Defs0 = beam_ssa:def([L], Blocks0),
CommonUsed = recv_common(Defs0, LoopExit, Blocks0),
- {Blocks1,Count1} = recv_fix_common(CommonUsed, LoopExit, Rm,
- Blocks0, Count0),
+ {Blocks1,Count1} = recv_crit_edges(Rm, LoopExit, Blocks0, Count0),
+ {Blocks2,Count2} = recv_fix_common(CommonUsed, LoopExit, Rm,
+ Blocks1, Count1),
Defs = ordsets:subtract(Defs0, CommonUsed),
- {Blocks,Count} = fix_receive(Rm, Defs, Blocks1, Count1),
+ {Blocks,Count} = fix_receive(Rm, Defs, Blocks2, Count2),
fix_receives_1(Ls, Blocks, Count);
#b_blk{} ->
fix_receives_1(Ls, Blocks0, Count0)
@@ -1341,6 +1344,57 @@ recv_common(Defs, Exit, Blocks) ->
Def = ordsets:subtract(Defs, ExitDefs),
ordsets:intersection(Def, ExitUsed).
+%% recv_crit_edges([RemoveMessageLabel], LoopExit,
+%% Blocks0, Count0) -> {Blocks,Count}.
+%%
+%% Adds dummy blocks on all conditional jumps to the exit block so that
+%% recv_fix_common/5 can insert phi nodes without having to worry about
+%% critical edges.
+
+recv_crit_edges(_Rms, none, Blocks0, Count0) ->
+ {Blocks0, Count0};
+recv_crit_edges(Rms, Exit, Blocks0, Count0) ->
+ Ls = beam_ssa:rpo(Rms, Blocks0),
+ rce_insert_edges(Ls, Exit, Count0, Blocks0).
+
+rce_insert_edges([L | Ls], Exit, Count0, Blocks0) ->
+ Successors = beam_ssa:successors(map_get(L, Blocks0)),
+ case member(Exit, Successors) of
+ true when Successors =/= [Exit] ->
+ {Blocks, Count} = rce_insert_edge(L, Exit, Count0, Blocks0),
+ rce_insert_edges(Ls, Exit, Count, Blocks);
+ _ ->
+ rce_insert_edges(Ls, Exit, Count0, Blocks0)
+ end;
+rce_insert_edges([], _Exit, Count, Blocks) ->
+ {Blocks, Count}.
+
+rce_insert_edge(L, Exit, Count, Blocks0) ->
+ #b_blk{last=Last0} = FromBlk0 = map_get(L, Blocks0),
+
+ ToExit = #b_br{bool=#b_literal{val=true},succ=Exit,fail=Exit},
+
+ FromBlk = FromBlk0#b_blk{last=rce_reroute_terminator(Last0, Exit, Count)},
+ EdgeBlk = #b_blk{anno=#{},is=[],last=ToExit},
+
+ Blocks = Blocks0#{ Count => EdgeBlk, L => FromBlk },
+ {Blocks, Count + 1}.
+
+rce_reroute_terminator(#b_br{succ=Exit}=Last, Exit, New) ->
+ rce_reroute_terminator(Last#b_br{succ=New}, Exit, New);
+rce_reroute_terminator(#b_br{fail=Exit}=Last, Exit, New) ->
+ rce_reroute_terminator(Last#b_br{fail=New}, Exit, New);
+rce_reroute_terminator(#b_br{}=Last, _Exit, _New) ->
+ Last;
+rce_reroute_terminator(#b_switch{fail=Exit}=Last, Exit, New) ->
+ rce_reroute_terminator(Last#b_switch{fail=New}, Exit, New);
+rce_reroute_terminator(#b_switch{list=List0}=Last, Exit, New) ->
+ List = [if
+ Lbl =:= Exit -> {Arg, New};
+ Lbl =/= Exit -> {Arg, Lbl}
+ end || {Arg, Lbl} <- List0],
+ Last#b_switch{list=List}.
+
%% recv_fix_common([CommonVar], LoopExit, [RemoveMessageLabel],
%% Blocks0, Count0) -> {Blocks,Count}.
%% Handle variables alwys defined in a receive and used
@@ -1409,21 +1463,51 @@ fix_receive([], _Defs, Blocks, Count) ->
{Blocks,Count}.
%% find_loop_exit([Label], Blocks) -> Label | none.
-%% Find the block to which control is transferred when the
-%% the receive loop is exited.
-
-find_loop_exit([L1,L2|_Ls], Blocks) ->
- Path1 = beam_ssa:rpo([L1], Blocks),
- Path2 = beam_ssa:rpo([L2], Blocks),
- find_loop_exit_1(Path1, cerl_sets:from_list(Path2));
-find_loop_exit(_, _) -> none.
-
-find_loop_exit_1([H|T], OtherPath) ->
- case cerl_sets:is_element(H, OtherPath) of
- true -> H;
- false -> find_loop_exit_1(T, OtherPath)
+%% Given the list of all blocks with the remove_message instructions
+%% for this receive, find the block to which control is transferred
+%% when the receive loop is exited (if any).
+
+find_loop_exit([_,_|_]=RmBlocks, Blocks) ->
+ %% We used to only analyze the path from two of the remove_message
+ %% blocks. That would fail to find a common block if one or both
+ %% of the blocks happened to raise an exception. To be sure that
+ %% we always find a common block if there is one (shared by at
+ %% least two clauses), we must analyze the path from all
+ %% remove_message blocks.
+ {Dominators,_} = beam_ssa:dominators(Blocks),
+ RmSet = cerl_sets:from_list(RmBlocks),
+ Rpo = beam_ssa:rpo(RmBlocks, Blocks),
+ find_loop_exit_1(Rpo, RmSet, Dominators);
+find_loop_exit(_, _) ->
+ %% There is (at most) a single clause. There is no common
+ %% loop exit block.
+ none.
+
+find_loop_exit_1([?BADARG_BLOCK|Ls], RmSet, Dominators) ->
+ %% ?BADARG_BLOCK is a marker and not an actual block, so it is not
+ %% the block we are looking for.
+ find_loop_exit_1(Ls, RmSet, Dominators);
+find_loop_exit_1([L|Ls], RmSet, Dominators) ->
+ DomBy = map_get(L, Dominators),
+ case any(fun(E) -> cerl_sets:is_element(E, RmSet) end, DomBy) of
+ true ->
+ %% This block is dominated by one of the remove_message blocks,
+ %% which means that the block is part of only one clause.
+ %% It is not the block we are looking for.
+ find_loop_exit_1(Ls, RmSet, Dominators);
+ false ->
+ %% This block is the first block that is not dominated by
+ %% any of the blocks with remove_message instructions,
+ %% which means that at least two of the receive clauses
+ %% will ultimately transfer control to it. It is the block
+ %% we are looking for.
+ L
end;
-find_loop_exit_1([], _) -> none.
+find_loop_exit_1([], _, _) ->
+ %% None of clauses transfers control to a common block after the receive
+ %% statement. That means that the receive statement is a the end of a
+ %% function (or that all clauses raise exceptions).
+ none.
%% find_rm_blocks(StartLabel, Blocks) -> [Label].
%% Find all blocks that start with remove_message within the receive
diff --git a/lib/compiler/src/beam_ssa_share.erl b/lib/compiler/src/beam_ssa_share.erl
index 426efa2cc9..73983bd34a 100644
--- a/lib/compiler/src/beam_ssa_share.erl
+++ b/lib/compiler/src/beam_ssa_share.erl
@@ -303,8 +303,12 @@ canonical_is([#b_ret{arg=Arg}], VarMap, Acc0) ->
Acc0
end,
{{ret,canonical_arg(Arg, VarMap),Acc1},VarMap};
-canonical_is([#b_br{bool=#b_var{},fail=Fail}], VarMap, Acc) ->
- {{br,succ,Fail,Acc},VarMap};
+canonical_is([#b_br{bool=#b_var{}=Arg,fail=Fail}], VarMap, Acc) ->
+ %% A previous buggy version of this code omitted the canonicalized
+ %% argument in the return value. Unfortunately, that worked most
+ %% of the time, except when `br` terminator referenced a variable
+ %% defined in a previous block instead of in the same block.
+ {{br,canonical_arg(Arg, VarMap),succ,Fail,Acc},VarMap};
canonical_is([#b_br{succ=Succ}], VarMap, Acc) ->
{{br,Succ,Acc},VarMap};
canonical_is([], VarMap, Acc) ->
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 68920e7dd3..3c06c83e2e 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -160,6 +160,10 @@ opt_finish_1([Arg | Args], [TypeMap | TypeMaps], ParamInfo0) ->
case join(maps:values(TypeMap)) of
any ->
opt_finish_1(Args, TypeMaps, ParamInfo0);
+ none ->
+ %% This function will never be called. Pretend that we don't
+ %% know the type for this argument.
+ opt_finish_1(Args, TypeMaps, ParamInfo0);
JoinedType ->
JoinedType = verified_type(JoinedType),
ParamInfo = ParamInfo0#{ Arg => validator_anno(JoinedType) },
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index ebe9631e09..349d74eb58 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1068,8 +1068,11 @@ verify_get_map(Fail, Src, List, Vst0) ->
%% {get_map_elements,{f,7},{x,1},{list,[{atom,a},{x,1},{atom,b},{x,2}]}}.
%%
%% If 'a' exists but not 'b', {x,1} is overwritten when we jump to {f,7}.
+%%
+%% We must be careful to preserve the uninitialized status for Y registers
+%% that have been allocated but not yet defined.
clobber_map_vals([Key,Dst|T], Map, Vst0) ->
- case is_reg_defined(Dst, Vst0) of
+ case is_reg_initialized(Dst, Vst0) of
true ->
Vst = extract_term(term, {bif,map_get}, [Key, Map], Dst, Vst0),
clobber_map_vals(T, Map, Vst);
@@ -1079,6 +1082,17 @@ clobber_map_vals([Key,Dst|T], Map, Vst0) ->
clobber_map_vals([], _Map, Vst) ->
Vst.
+is_reg_initialized({x,_}=Reg, #vst{current=#st{xs=Xs}}) ->
+ is_map_key(Reg, Xs);
+is_reg_initialized({y,_}=Reg, #vst{current=#st{ys=Ys}}) ->
+ case Ys of
+ #{Reg:=Val} ->
+ Val =/= uninitialized;
+ #{} ->
+ false
+ end;
+is_reg_initialized(V, #vst{}) -> error({not_a_register, V}).
+
extract_map_keys([Key,_Val|T]) ->
[Key|extract_map_keys(T)];
extract_map_keys([]) -> [].
@@ -1604,13 +1618,8 @@ infer_types_1(#value{op={bif,'=:='},args=[LHS,RHS]}) ->
end;
infer_types_1(#value{op={bif,element},args=[{integer,Index}=Key,Tuple]}) ->
fun(Val, S) ->
- case is_value_alive(Tuple, S) of
- true ->
- Type = {tuple,[Index], #{ Key => get_term_type(Val, S) }},
- update_type(fun meet/2, Type, Tuple, S);
- false ->
- S
- end
+ Type = {tuple,[Index], #{ Key => get_term_type(Val, S) }},
+ update_type(fun meet/2, Type, Tuple, S)
end;
infer_types_1(#value{op={bif,is_atom},args=[Src]}) ->
infer_type_test_bif({atom,[]}, Src);
@@ -1634,10 +1643,7 @@ infer_types_1(#value{op={bif,is_tuple},args=[Src]}) ->
infer_type_test_bif({tuple,[0],#{}}, Src);
infer_types_1(#value{op={bif,tuple_size}, args=[Tuple]}) ->
fun({integer,Arity}, S) ->
- case is_value_alive(Tuple, S) of
- true -> update_type(fun meet/2, {tuple,Arity,#{}}, Tuple, S);
- false -> S
- end;
+ update_type(fun meet/2, {tuple,Arity,#{}}, Tuple, S);
(_, S) -> S
end;
infer_types_1(_) ->
@@ -1645,10 +1651,7 @@ infer_types_1(_) ->
infer_type_test_bif(Type, Src) ->
fun({atom,true}, S) ->
- case is_value_alive(Src, S) of
- true -> update_type(fun meet/2, Type, Src, S);
- false -> S
- end;
+ update_type(fun meet/2, Type, Src, S);
(_, S) ->
S
end.
@@ -1885,10 +1888,6 @@ check_try_catch_tags(Type, {y,N}=Reg, Vst) ->
ok
end.
-is_reg_defined({x,_}=Reg, #vst{current=#st{xs=Xs}}) -> is_map_key(Reg, Xs);
-is_reg_defined({y,_}=Reg, #vst{current=#st{ys=Ys}}) -> is_map_key(Reg, Ys);
-is_reg_defined(V, #vst{}) -> error({not_a_register, V}).
-
assert_term(Src, Vst) ->
_ = get_term_type(Src, Vst),
ok.
@@ -2285,9 +2284,6 @@ get_raw_type(#value_ref{}=Ref, #vst{current=#st{vs=Vs}}) ->
get_raw_type(Src, #vst{}) ->
get_literal_type(Src).
-is_value_alive(#value_ref{}=Ref, #vst{current=#st{vs=Vs}}) ->
- is_map_key(Ref, Vs).
-
get_literal_type(nil=T) -> T;
get_literal_type({atom,A}=T) when is_atom(A) -> T;
get_literal_type({float,F}=T) when is_float(F) -> T;
@@ -2469,25 +2465,44 @@ merge_vrefs(RefA, RefB, Merge, Counter) ->
merge_values(Merge, VsA, VsB) ->
maps:fold(fun(Spec, New, Acc) ->
- merge_values_1(Spec, New, VsA, VsB, Acc)
+ mv_1(Spec, New, VsA, VsB, Acc)
end, #{}, Merge).
-merge_values_1(Same, Same, VsA, VsB, Acc) ->
+mv_1(Same, Same, VsA, VsB, Acc0) ->
%% We're merging different versions of the same value, so it's safe to
%% reuse old entries if the type's unchanged.
- #value{type=TypeA}=EntryA = map_get(Same, VsA),
- #value{type=TypeB}=EntryB = map_get(Same, VsB),
+ #value{type=TypeA,args=Args}=EntryA = map_get(Same, VsA),
+ #value{type=TypeB,args=Args}=EntryB = map_get(Same, VsB),
+
Entry = case join(TypeA, TypeB) of
TypeA -> EntryA;
TypeB -> EntryB;
JoinedType -> EntryA#value{type=JoinedType}
end,
- Acc#{ Same => Entry };
-merge_values_1({RefA, RefB}, New, VsA, VsB, Acc) ->
+
+ Acc = Acc0#{ Same => Entry },
+
+ %% Type inference may depend on values that are no longer reachable from a
+ %% register, so all arguments must be merged into the new state.
+ mv_args(Args, VsA, VsB, Acc);
+mv_1({RefA, RefB}, New, VsA, VsB, Acc) ->
#value{type=TypeA} = map_get(RefA, VsA),
#value{type=TypeB} = map_get(RefB, VsB),
Acc#{ New => #value{op=join,args=[],type=join(TypeA, TypeB)} }.
+mv_args([#value_ref{}=Arg | Args], VsA, VsB, Acc0) ->
+ case Acc0 of
+ #{ Arg := _ } ->
+ mv_args(Args, VsA, VsB, Acc0);
+ #{} ->
+ Acc = mv_1(Arg, Arg, VsA, VsB, Acc0),
+ mv_args(Args, VsA, VsB, Acc)
+ end;
+mv_args([_ | Args], VsA, VsB, Acc) ->
+ mv_args(Args, VsA, VsB, Acc);
+mv_args([], _VsA, _VsB, Acc) ->
+ Acc.
+
merge_fragility(FragileA, FragileB) ->
cerl_sets:union(FragileA, FragileB).
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 28db8986ff..0325c714d0 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -268,8 +268,11 @@ expand_opt(r21, Os) ->
[no_put_tuple2 | expand_opt(no_bsm3, Os)];
expand_opt({debug_info_key,_}=O, Os) ->
[encrypt_debug_info,O|Os];
-expand_opt(no_type_opt, Os) ->
- [no_ssa_opt_type_start,
+expand_opt(no_type_opt=O, Os) ->
+ %% Be sure to keep the no_type_opt option so that it will
+ %% be recorded in the BEAM file, allowing the test suites
+ %% to recompile the file with this option.
+ [O,no_ssa_opt_type_start,
no_ssa_opt_type_continue,
no_ssa_opt_type_finish | Os];
expand_opt(O, Os) -> [O|Os].
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index db8eb7e2e1..7be23fbb93 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -109,6 +109,8 @@ NO_MOD_OPT = $(NO_OPT)
NO_SSA_OPT = $(NO_OPT)
+NO_TYPE_OPT = $(NO_OPT)
+
NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE)
NO_OPT_ERL_FILES= $(NO_OPT_MODULES:%=%.erl)
POST_OPT_MODULES= $(NO_OPT:%=%_post_opt_SUITE)
@@ -121,6 +123,8 @@ NO_MOD_OPT_MODULES= $(NO_MOD_OPT:%=%_no_module_opt_SUITE)
NO_MOD_OPT_ERL_FILES= $(NO_MOD_OPT_MODULES:%=%.erl)
NO_SSA_OPT_MODULES= $(NO_SSA_OPT:%=%_no_ssa_opt_SUITE)
NO_SSA_OPT_ERL_FILES= $(NO_SSA_OPT_MODULES:%=%.erl)
+NO_TYPE_OPT_MODULES= $(NO_TYPE_OPT:%=%_no_type_opt_SUITE)
+NO_TYPE_OPT_ERL_FILES= $(NO_TYPE_OPT_MODULES:%=%.erl)
ERL_FILES= $(MODULES:%=%.erl)
CORE_FILES= $(CORE_MODULES:%=%.core)
@@ -150,7 +154,7 @@ EBIN = .
# ----------------------------------------------------
make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(NO_SSA_OPT_ERL_FILES) \
- $(INLINE_ERL_FILES) $(R21_ERL_FILES) $(NO_MOD_OPT_ERL_FILES)
+ $(INLINE_ERL_FILES) $(R21_ERL_FILES) $(NO_MOD_OPT_ERL_FILES) $(NO_TYPE_OPT_ERL_FILES)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile +no_copt +no_postopt \
@@ -169,6 +173,8 @@ make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(NO_SSA_OPT_ERL_FILES
-o$(EBIN) $(NO_MOD_OPT_MODULES) >> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile +from_core $(ERL_COMPILE_FLAGS) \
-o$(EBIN) $(CORE_MODULES) >> $(EMAKEFILE)
+ $(ERL_TOP)/make/make_emakefile +no_type_opt $(ERL_COMPILE_FLAGS) \
+ -o$(EBIN) $(NO_TYPE_OPT_MODULES) >> $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
@@ -202,6 +208,10 @@ docs:
%_no_module_opt_SUITE.erl: %_SUITE.erl
sed -e 's;-module($(basename $<));-module($(basename $@));' $< > $@
+%_no_type_opt_SUITE.erl: %_SUITE.erl
+ sed -e 's;-module($(basename $<));-module($(basename $@));' $< > $@
+
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -216,7 +226,8 @@ release_tests_spec: make_emakefile
$(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \
$(INLINE_ERL_FILES) $(R21_ERL_FILES) \
$(NO_MOD_OPT_ERL_FILES) \
- $(NO_SSA_OPT_ERL_FILES) "$(RELSYSDIR)"
+ $(NO_SSA_OPT_ERL_FILES) \
+ $(NO_TYPE_OPT_ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) $(CORE_FILES) "$(RELSYSDIR)"
for file in $(ERL_DUMMY_FILES); do \
module=`basename $$file .erl`; \
diff --git a/lib/compiler/test/beam_except_SUITE.erl b/lib/compiler/test/beam_except_SUITE.erl
index 67947dc292..f52239f2a8 100644
--- a/lib/compiler/test/beam_except_SUITE.erl
+++ b/lib/compiler/test/beam_except_SUITE.erl
@@ -72,11 +72,25 @@ bs_get_tail(Config) ->
{function_clause,
[{?MODULE,bs_get_tail_1,[<<>>,0,0,Config],_}|_]}} =
(catch bs_get_tail_1(id(<<>>), 0, 0, Config)),
+
+ ok = bs_get_tail_2(<<"W">>, <<"X">>, <<"Z">>),
+ ok = bs_get_tail_2(<<"M">>, <<"X">>, <<"Z">>),
+ {'EXIT',
+ {function_clause,
+ [{?MODULE,do_get_bs_tail_2,[<<"A">>,<<"B">>,[],<<"C">>],_}|_]}} =
+ (catch bs_get_tail_2(<<"A">>, <<"B">>, <<"C">>)),
+
ok.
bs_get_tail_1(<<_:32, Rest/binary>>, Z1, Z2, F1) ->
{Rest,Z1,Z2,F1}.
+bs_get_tail_2(A, B, C) ->
+ do_get_bs_tail_2(A, B, [], C).
+
+do_get_bs_tail_2(<<"W">>, <<"X">>, _, <<"Z">>) -> ok;
+do_get_bs_tail_2(<<"M">>, <<"X">>, _, <<"Z">>) -> ok.
+
coverage(_) ->
File = {file,"fake.erl"},
ok = fc(a),
diff --git a/lib/compiler/test/beam_ssa_SUITE.erl b/lib/compiler/test/beam_ssa_SUITE.erl
index a741ebbdf9..3b510f3528 100644
--- a/lib/compiler/test/beam_ssa_SUITE.erl
+++ b/lib/compiler/test/beam_ssa_SUITE.erl
@@ -23,7 +23,7 @@
init_per_group/2,end_per_group/2,
calls/1,tuple_matching/1,recv/1,maps/1,
cover_ssa_dead/1,combine_sw/1,share_opt/1,
- beam_ssa_dead_crash/1]).
+ beam_ssa_dead_crash/1,stack_init/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -39,7 +39,8 @@ groups() ->
cover_ssa_dead,
combine_sw,
share_opt,
- beam_ssa_dead_crash
+ beam_ssa_dead_crash,
+ stack_init
]}].
init_per_suite(Config) ->
@@ -190,6 +191,15 @@ recv(_Config) ->
self() ! {[self(),r1],{2,99,<<"data">>}},
{Parent,r1,<<1:32,2:8,99:8,"data">>} = tricky_recv_4(),
+ %% Test tricky_recv_5/0.
+ self() ! 1,
+ a = tricky_recv_5(),
+ self() ! 2,
+ b = tricky_recv_5(),
+
+ %% tricky_recv_6/0 is a compile-time error.
+ tricky_recv_6(),
+
ok.
sync_wait_mon({Pid, Ref}, Timeout) ->
@@ -295,6 +305,38 @@ tricky_recv_4() ->
end,
id({Pid,R,Request}).
+%% beam_ssa_pre_codegen would accidentally create phi nodes on critical edges
+%% when fixing up receives; the call to id/2 can either succeed or land in the
+%% catch block, and we added a phi node to its immediate successor.
+tricky_recv_5() ->
+ try
+ receive
+ X=1 ->
+ id(42),
+ a;
+ X=2 ->
+ b
+ end,
+ case X of
+ 1 -> a;
+ 2 -> b
+ end
+ catch
+ _:_ -> c
+ end.
+
+%% When fixing tricky_recv_5, we introduced a compiler crash when the common
+%% exit block was ?BADARG_BLOCK and floats were in the picture.
+tricky_recv_6() ->
+ RefA = make_ref(),
+ RefB = make_ref(),
+ receive
+ {RefA, Number} -> Number + 1.0;
+ {RefB, Number} -> Number + 2.0
+ after 0 ->
+ ok
+ end.
+
maps(_Config) ->
{'EXIT',{{badmatch,#{}},_}} = (catch maps_1(any)),
ok.
@@ -483,9 +525,11 @@ do_comb_sw_2(X) ->
erase(?MODULE).
share_opt(_Config) ->
- ok = do_share_opt(0).
+ ok = do_share_opt_1(0),
+ ok = do_share_opt_2(),
+ ok.
-do_share_opt(A) ->
+do_share_opt_1(A) ->
%% The compiler would be stuck in an infinite loop in beam_ssa_share.
case A of
0 -> a;
@@ -494,6 +538,26 @@ do_share_opt(A) ->
end,
receive after 1 -> ok end.
+do_share_opt_2() ->
+ ok = sopt_2({[pointtopoint], [{dstaddr,any}]}, ok),
+ ok = sopt_2({[broadcast], [{broadaddr,any}]}, ok),
+ ok = sopt_2({[], []}, ok),
+ ok.
+
+sopt_2({Flags, Opts}, ok) ->
+ Broadcast = lists:member(broadcast, Flags),
+ P2P = lists:member(pointtopoint, Flags),
+ case Opts of
+ %% The following two clauses would be combined to one, silently
+ %% discarding the guard test of the P2P variable.
+ [{broadaddr,_}|Os] when Broadcast ->
+ sopt_2({Flags, Os}, ok);
+ [{dstaddr,_}|Os] when P2P ->
+ sopt_2({Flags, Os}, ok);
+ [] ->
+ ok
+ end.
+
beam_ssa_dead_crash(_Config) ->
not_A_B = do_beam_ssa_dead_crash(id(false), id(true)),
not_A_not_B = do_beam_ssa_dead_crash(false, false),
@@ -548,6 +612,30 @@ do_beam_ssa_dead_crash(A, B) ->
end
end.
+stack_init(_Config) ->
+ 6 = stack_init(a, #{a => [1,2,3]}),
+ 0 = stack_init(missing, #{}),
+ ok.
+
+stack_init(Key, Map) ->
+ %% beam_ssa_codegen would wrongly assume that y(0) would always be
+ %% initialized by the `get_map_elements` instruction that follows, and
+ %% would set up the stack frame using an `allocate` instruction and
+ %% would not generate an `init` instruction to initialize y(0).
+ Res = case Map of
+ #{Key := Elements} ->
+ %% Elements will be assigned to y(0) if the key Key exists.
+ lists:foldl(fun(El, Acc) ->
+ Acc + El
+ end, 0, Elements);
+ #{} ->
+ %% y(0) will be left uninitialized when the key is not
+ %% present in the map.
+ 0
+ end,
+ %% y(0) would be uninitialized here if the key was not present in the map
+ %% (if the second clause was executed).
+ id(Res).
%% The identity function.
id(I) -> I.
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 076a604aa4..a99dee48aa 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -24,7 +24,8 @@
integers/1,numbers/1,coverage/1,booleans/1,setelement/1,
cons/1,tuple/1,record_float/1,binary_float/1,float_compare/1,
arity_checks/1,elixir_binaries/1,find_best/1,
- test_size/1,cover_lists_functions/1,list_append/1,bad_binary_unit/1]).
+ test_size/1,cover_lists_functions/1,list_append/1,bad_binary_unit/1,
+ none_argument/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -49,7 +50,8 @@ groups() ->
test_size,
cover_lists_functions,
list_append,
- bad_binary_unit
+ bad_binary_unit,
+ none_argument
]}].
init_per_suite(Config) ->
@@ -518,5 +520,24 @@ bad_binary_unit(_Config) ->
false = is_binary(Bitstring),
ok.
+%% ERL-1013: The compiler would crash during the type optimization pass.
+none_argument(_Config) ->
+ Binary = id(<<3:16, 42>>),
+ error = id(case Binary of
+ <<Len:16, Body/binary>> when length(Body) == Len - 2 ->
+ %% The type for Body will be none. It means
+ %% that this clause will never match and that
+ %% uncompress/1 will never be called.
+ uncompress(Body);
+ _ ->
+ error
+ end),
+ ok.
+
+uncompress(CompressedBinary) ->
+ %% The type for CompressedBinary is none, which beam_ssa_type
+ %% did not handle properly.
+ zlib:uncompress(CompressedBinary).
+
id(I) ->
I.
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 6b1438abdd..20f6cb2691 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -681,11 +681,16 @@ infer_on_eq_4(T) ->
%% ERIERL-348; types were inferred for dead values, causing validation to fail.
+-record(idv, {key}).
+
infer_dead_value(Config) when is_list(Config) ->
a = idv_1({a, b, c, d, e, f, g}, {0, 0, 0, 0, 0, 0, 0}),
b = idv_1({a, b, c, d, 0, 0, 0}, {a, b, c, d, 0, 0, 0}),
c = idv_1({0, 0, 0, 0, 0, f, g}, {0, 0, 0, 0, 0, f, g}),
error = idv_1(gurka, gaffel),
+
+ ok = idv_2(id(#idv{})),
+
ok.
idv_1({_A, _B, _C, _D, _E, _F, _G},
@@ -700,6 +705,23 @@ idv_1({_A, _B, _C, _D, _E, F, G},
idv_1(_A, _B) ->
error.
+%% ERL-995: The first solution to ERIERL-348 was incomplete and caused
+%% validation to fail when living values depended on delayed type inference on
+%% "dead" values.
+
+idv_2(State) ->
+ Flag = (State#idv.key == undefined),
+ case id(gurka) of
+ {_} -> id([Flag]);
+ _ -> ok
+ end,
+ if
+ Flag -> idv_called_once(State);
+ true -> ok
+ end.
+
+idv_called_once(_State) -> ok.
+
%%%-------------------------------------------------------------------------
transform_remove(Remove, Module) ->
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index d97f49c56e..145a50f4ad 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -44,7 +44,8 @@
beam_bsm/1,guard/1,is_ascii/1,non_opt_eq/1,
expression_before_match/1,erl_689/1,restore_on_call/1,
restore_after_catch/1,matches_on_parameter/1,big_positions/1,
- matching_meets_apply/1,bs_start_match2_defs/1]).
+ matching_meets_apply/1,bs_start_match2_defs/1,
+ exceptions_after_match_failure/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -80,7 +81,8 @@ groups() ->
beam_bsm,guard,is_ascii,non_opt_eq,
expression_before_match,erl_689,restore_on_call,
matches_on_parameter,big_positions,
- matching_meets_apply,bs_start_match2_defs]}].
+ matching_meets_apply,bs_start_match2_defs,
+ exceptions_after_match_failure]}].
init_per_suite(Config) ->
@@ -2005,4 +2007,17 @@ do_matching_meets_apply(_Bin, {Handler, State}) ->
%% Another case of the above.
Handler:abs(State).
+%% Exception handling was broken on the failure path of bs_start_match as
+%% beam_ssa_bsm accidentally cloned and renamed the ?BADARG_BLOCK.
+exceptions_after_match_failure(_Config) ->
+ {'EXIT', {badarith, _}} = (catch do_exceptions_after_match_failure(atom)),
+ ok = do_exceptions_after_match_failure(<<0, 1, "gurka">>),
+ ok = do_exceptions_after_match_failure(2.0).
+
+do_exceptions_after_match_failure(<<_A, _B, "gurka">>) ->
+ ok;
+do_exceptions_after_match_failure(Other) ->
+ Other / 2.0,
+ ok.
+
id(I) -> I.
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index aac9de278d..bc74ec4984 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -25,7 +25,8 @@
match_in_call/1,untuplify/1,shortcut_boolean/1,letify_guard/1,
selectify/1,deselectify/1,underscore/1,match_map/1,map_vars_used/1,
coverage/1,grab_bag/1,literal_binary/1,
- unary_op/1,eq_types/1,match_after_return/1,match_right_tuple/1]).
+ unary_op/1,eq_types/1,match_after_return/1,match_right_tuple/1,
+ tuple_size_in_try/1]).
-include_lib("common_test/include/ct.hrl").
@@ -41,7 +42,8 @@ groups() ->
shortcut_boolean,letify_guard,selectify,deselectify,
underscore,match_map,map_vars_used,coverage,
grab_bag,literal_binary,unary_op,eq_types,
- match_after_return,match_right_tuple]}].
+ match_after_return,match_right_tuple,
+ tuple_size_in_try]}].
init_per_suite(Config) ->
@@ -922,4 +924,19 @@ match_right_tuple_1(T) ->
force_succ_regs(_A, B) -> B.
+tuple_size_in_try(Config) when is_list(Config) ->
+ %% The tuple_size optimization was applied outside of guards, causing
+ %% either the emulator or compiler to crash.
+ ok = tsit(gurka),
+ ok = tsit(gaffel).
+
+tsit(A) ->
+ try
+ id(ignored),
+ 1 = tuple_size(A),
+ error
+ catch
+ _:_ -> ok
+ end.
+
id(I) -> I.
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 752491f0f8..8cd864c59e 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -431,6 +431,20 @@ elusive_common_exit(_Config) ->
self() ! {1, a},
self() ! {2, b},
{[z], [{2,b},{1,a}]} = elusive_loop([x,y,z], 2, []),
+
+ CodeServer = whereis(code_server),
+ Self = self(),
+ Self ! {Self, abc},
+ Self ! {CodeServer, []},
+ Self ! {Self, other},
+ try elusive2([]) of
+ Unexpected ->
+ ct:fail("Expected an exception; got ~p\n", [Unexpected])
+ catch
+ throw:[other, CodeServer, Self] ->
+ ok
+ end,
+
ok.
elusive_loop(List, 0, Results) ->
@@ -449,4 +463,25 @@ elusive_loop(List, ToReceive, Results) ->
%% that it would not insert all necessary copy instructions.
elusive_loop(RemList, ToReceive-1, [Result | Results]).
+
+elusive2(Acc) ->
+ receive
+ {Pid, abc} ->
+ ok;
+ {Pid, []} ->
+ ok;
+ {Pid, Res} ->
+ %% beam_ssa_pre_codegen:find_loop_exit/2 attempts to find
+ %% the first block of the common code after the receive
+ %% statement. It used to only look at the two last clauses
+ %% of the receive. In this function, the last two clauses
+ %% don't have any common block, so it would be assumed
+ %% that there was no common block for any of the
+ %% clauses. That would mean that copy instructions would
+ %% not be inserted as needed.
+ throw([Res | Acc])
+ end,
+ %% Common code.
+ elusive2([Pid | Acc]).
+
id(I) -> I.
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index 3348c6e9ea..34410e4b2a 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -97,7 +97,8 @@ get_data_dir(Config) ->
Data2 = re:replace(Data1, "_post_opt_SUITE", "_SUITE", Opts),
Data3 = re:replace(Data2, "_inline_SUITE", "_SUITE", Opts),
Data4 = re:replace(Data3, "_r21_SUITE", "_SUITE", Opts),
- Data = re:replace(Data4, "_no_module_opt_SUITE", "_SUITE", Opts),
+ Data5 = re:replace(Data4, "_no_module_opt_SUITE", "_SUITE", Opts),
+ Data = re:replace(Data5, "_no_type_opt_SUITE", "_SUITE", Opts),
re:replace(Data, "_no_ssa_opt_SUITE", "_SUITE", Opts).
is_cloned_mod(Mod) ->
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 508bbc902c..7192ddca15 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 7.4.2
+COMPILER_VSN = 7.4.4
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 0930f79840..dad9fd18c7 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -32,6 +32,42 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 4.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The HiPE compiler would badly miscompile certain
+ try/catch expressions, so it will now refuse to compile
+ modules containing try or catch.</p> <p>As a consequence
+ of this, <c>dialyzer</c> will no longer compile key
+ modules to native code.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-15949</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 4.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Make sure Dialyzer does not crash if the formatting
+ of results fails. Instead of crashing, an unformatted
+ version of the results is returned. </p>
+ <p>
+ Own Id: OTP-15922 Aux Id: PR-2240, ERL-949 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 4.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index 403fcb6279..5e680062fb 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -320,12 +320,6 @@ report_analysis_start(#options{analysis_type = Type,
end
end.
-report_native_comp(#options{report_mode = ReportMode}) ->
- case ReportMode of
- quiet -> ok;
- _ -> io:format(" Compiling some key modules to native code...")
- end.
-
report_elapsed_time(T1, T2, #options{report_mode = ReportMode}) ->
case ReportMode of
quiet -> ok;
@@ -375,7 +369,6 @@ do_analysis(Options) ->
do_analysis(Files, Options, Plt, PltInfo) ->
assert_writable(Options#options.output_plt),
- hipe_compile(Files, Options),
report_analysis_start(Options),
State0 = new_state(),
State1 = init_output(State0, Options),
@@ -484,115 +477,6 @@ expand_dependent_modules_1([Mod|Mods], Included, ModDeps) ->
expand_dependent_modules_1([], Included, _ModDeps) ->
Included.
--define(MIN_PARALLELISM, 7).
--define(MIN_FILES_FOR_NATIVE_COMPILE, 20).
-
--spec hipe_compile([file:filename()], #options{}) -> 'ok'.
-
-hipe_compile(Files, #options{erlang_mode = ErlangMode,
- native = Native,
- native_cache = NativeCache} = Options) ->
- NoNative =
- case ErlangMode of
- true ->
- %% In Erlang mode, native compilation must be explicitly enabled
- Native =/= true;
- false ->
- %% In CLI mode, perform native compilation unless disabled
- Native =:= false
- end,
- FewFiles = (length(Files) < ?MIN_FILES_FOR_NATIVE_COMPILE),
- case NoNative orelse FewFiles of
- true -> ok;
- false ->
- case erlang:system_info(hipe_architecture) of
- undefined -> ok;
- _ ->
- Mods = [lists, dict, digraph, digraph_utils, ets,
- gb_sets, gb_trees, ordsets, sets, sofs,
- cerl, erl_types, cerl_trees, erl_bif_types,
- dialyzer_analysis_callgraph, dialyzer, dialyzer_behaviours,
- dialyzer_codeserver, dialyzer_contracts,
- dialyzer_coordinator, dialyzer_dataflow, dialyzer_dep,
- dialyzer_plt, dialyzer_succ_typings, dialyzer_typesig,
- dialyzer_worker],
- report_native_comp(Options),
- {T1, _} = statistics(wall_clock),
- native_compile(Mods, NativeCache),
- {T2, _} = statistics(wall_clock),
- report_elapsed_time(T1, T2, Options)
- end
- end.
-
-native_compile(Mods, Cache) ->
- case dialyzer_utils:parallelism() > ?MIN_PARALLELISM of
- true ->
- Parent = self(),
- Pids = [spawn(fun () -> Parent ! {self(), hc(M, Cache)} end) || M <- Mods],
- lists:foreach(fun (Pid) -> receive {Pid, Res} -> Res end end, Pids);
- false ->
- lists:foreach(fun (Mod) -> hc(Mod, Cache) end, Mods)
- end.
-
-hc(Mod, Cache) ->
- {module, Mod} = code:ensure_loaded(Mod),
- case code:is_module_native(Mod) of
- true -> ok;
- false ->
- %% io:format(" ~w", [Mod]),
- case Cache of
- false ->
- {ok, Mod} = hipe:c(Mod),
- ok;
- true ->
- hc_cache(Mod)
- end
- end.
-
-hc_cache(Mod) ->
- CacheBase = cache_base_dir(),
- %% Use HiPE architecture, version and erts checksum in directory name,
- %% to avoid clashes between incompatible binaries.
- HipeArchVersion =
- lists:concat(
- [erlang:system_info(hipe_architecture), "-",
- hipe:version(), "-",
- hipe:erts_checksum()]),
- CacheDir = filename:join(CacheBase, HipeArchVersion),
- OrigBeamFile = code:which(Mod),
- {ok, {Mod, <<Checksum:128>>}} = beam_lib:md5(OrigBeamFile),
- CachedBeamFile = filename:join(CacheDir, lists:concat([Mod, "-", Checksum, ".beam"])),
- ok = filelib:ensure_dir(CachedBeamFile),
- ModBin =
- case filelib:is_file(CachedBeamFile) of
- true ->
- {ok, BinFromFile} = file:read_file(CachedBeamFile),
- BinFromFile;
- false ->
- {ok, Mod, CompiledBin} = compile:file(OrigBeamFile, [from_beam, native, binary]),
- ok = file:write_file(CachedBeamFile, CompiledBin),
- CompiledBin
- end,
- code:unstick_dir(filename:dirname(OrigBeamFile)),
- {module, Mod} = code:load_binary(Mod, CachedBeamFile, ModBin),
- true = code:is_module_native(Mod),
- ok.
-
-cache_base_dir() ->
- %% http://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
- %% If XDG_CACHE_HOME is set to an absolute path, use it as base.
- XdgCacheHome = os:getenv("XDG_CACHE_HOME"),
- CacheHome =
- case is_list(XdgCacheHome) andalso filename:pathtype(XdgCacheHome) =:= absolute of
- true ->
- XdgCacheHome;
- false ->
- %% Otherwise, the default is $HOME/.cache.
- {ok, [[Home]]} = init:get_argument(home),
- filename:join(Home, ".cache")
- end,
- filename:join([CacheHome, "dialyzer_hipe_cache"]).
-
new_state() ->
#cl_state{}.
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 466bbfd0f2..a77c74c717 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 4.0.1
+DIALYZER_VSN = 4.0.3
diff --git a/lib/hipe/doc/src/hipe_app.xml b/lib/hipe/doc/src/hipe_app.xml
index 61d92fdffe..5ac445ac58 100644
--- a/lib/hipe/doc/src/hipe_app.xml
+++ b/lib/hipe/doc/src/hipe_app.xml
@@ -66,6 +66,10 @@
<item><p>The HiPE compiler will crash on modules containing binary
matching.</p>
</item>
+ <tag>try/catch</tag>
+ <item><p>The HiPE compiler will crash on modules containing 'try' or
+ 'catch'.</p>
+ </item>
<tag>Stack traces</tag>
<item><p>Stack traces returned from <seealso marker="erts:erlang#get_stacktrace/0">
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index a2e0766bb7..3fad2ac53a 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -31,6 +31,26 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.19.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The HiPE compiler would badly miscompile certain
+ try/catch expressions, so it will now refuse to compile
+ modules containing try or catch.</p> <p>As a consequence
+ of this, <c>dialyzer</c> will no longer compile key
+ modules to native code.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-15949</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.19</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 8e7e56b6c4..995c961e09 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -557,32 +557,21 @@ trans_fun([{move,Src,Dst}|Instructions], Env) ->
Dst1 = mk_var(Dst),
Src1 = trans_arg(Src),
[hipe_icode:mk_move(Dst1,Src1) | trans_fun(Instructions,Env)];
-%%--- catch --- ITS PROCESSING IS POSTPONED
-trans_fun([{'catch',N,{_,EndLabel}}|Instructions], Env) ->
- NewContLbl = mk_label(new),
- [{'catch',N,EndLabel},NewContLbl | trans_fun(Instructions,Env)];
-%%--- catch_end --- ITS PROCESSING IS POSTPONED
-trans_fun([{catch_end,_N}=I|Instructions], Env) ->
- [I | trans_fun(Instructions,Env)];
-%%--- try --- ITS PROCESSING IS POSTPONED
-trans_fun([{'try',N,{_,EndLabel}}|Instructions], Env) ->
- NewContLbl = mk_label(new),
- [{'try',N,EndLabel},NewContLbl | trans_fun(Instructions,Env)];
-%%--- try_end ---
-trans_fun([{try_end,_N}|Instructions], Env) ->
- [hipe_icode:mk_end_try() | trans_fun(Instructions,Env)];
-%%--- try_case --- ITS PROCESSING IS POSTPONED
-trans_fun([{try_case,_N}=I|Instructions], Env) ->
- [I | trans_fun(Instructions,Env)];
-%%--- try_case_end ---
-trans_fun([{try_case_end,Arg}|Instructions], Env) ->
- BadArg = trans_arg(Arg),
- ErrVar = mk_var(new),
- Vs = [mk_var(new)],
- Atom = hipe_icode:mk_move(ErrVar,hipe_icode:mk_const(try_clause)),
- Tuple = hipe_icode:mk_primop(Vs,mktuple,[ErrVar,BadArg]),
- Fail = hipe_icode:mk_fail(Vs,error),
- [Atom,Tuple,Fail | trans_fun(Instructions,Env)];
+%%
+%% try/catch -- THESE ARE KNOWN TO MISCOMPILE, SEE OTP-15949
+%%
+trans_fun([{'catch'=Name,_,_}|_], _Env) ->
+ nyi(Name);
+trans_fun([{catch_end=Name,_}|_], _Env) ->
+ nyi(Name);
+trans_fun([{'try'=Name,_,_}|_], _Env) ->
+ nyi(Name);
+trans_fun([{try_end=Name,_}|_], _Env) ->
+ nyi(Name);
+trans_fun([{try_case=Name,_}|_], _Env) ->
+ nyi(Name);
+trans_fun([{try_case_end=Name,_}|_], _Env) ->
+ nyi(Name);
%%--- raise ---
trans_fun([{raise,{f,0},[Reg1,Reg2],{x,0}}|Instructions], Env) ->
V1 = trans_arg(Reg1),
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index a91d92ca14..3a22e07f57 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.19
+HIPE_VSN = 3.19.1
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 03bd1d8042..45533c4f4b 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -33,7 +33,23 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 7.0.8</title>
+ <section><title>Inets 7.0.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a regression in http client that causes a crash when
+ request URI has no scheme.</p>
+ <p>
+ Own Id: OTP-15930 Aux Id: ERL-969 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 7.0.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 1d37e71847..8ca4f21928 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -2191,7 +2191,7 @@ check_cookie([_Head | Tail]) ->
content_length([]) ->
0;
-content_length(["content-length:" ++ Value | _]) ->
+content_length([{"content-length", Value}|_]) ->
list_to_integer(string:strip(Value));
content_length([_Head | Tail]) ->
content_length(Tail).
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 5dbec9e7b3..d948204618 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 7.0.8
+INETS_VSN = 7.0.9
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
index 187705a0b5..5e777c1164 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -106,9 +106,9 @@ public class OtpOutputStream extends ByteArrayOutputStream {
}
/**
- * Trims the capacity of this <tt>OtpOutputStream</tt> instance to be the
+ * Trims the capacity of this <code>OtpOutputStream</code> instance to be the
* buffer's current size. An application can use this operation to minimize
- * the storage of an <tt>OtpOutputStream</tt> instance.
+ * the storage of an <code>OtpOutputStream</code> instance.
*/
public void trimToSize() {
resize(super.count);
@@ -125,7 +125,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
}
/**
- * Increases the capacity of this <tt>OtpOutputStream</tt> instance, if
+ * Increases the capacity of this <code>OtpOutputStream</code> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
@@ -939,7 +939,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* @param o
* the Erlang term to write.
* @param level
- * the compression level (<tt>0..9</tt>)
+ * the compression level (<code>0..9</code>)
*/
public void write_compressed(final OtpErlangObject o, final int level) {
@SuppressWarnings("resource")
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index f8867ccf25..70623ab9aa 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2018. All Rights Reserved.
+# Copyright Ericsson AB 1997-2019. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -36,6 +36,18 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# Target Specs
# ----------------------------------------------------
XML_APPLICATION_FILES = ref_man.xml
+
+# The doc build has problems with if-defing out modules...
+ifeq ($(USE_ESOCK),yes)
+XML_REF3_ESOCK_FILES = net.xml
+ESOCK_USE_NET_XML=<xi:include href="net.xml"\/>
+ESOCK_USE_NET_SPECS_XML=<xi:include href="../specs/specs_net.xml"/>
+else
+XML_REF3_ESOCK_FILES =
+ESOCK_USE_NET_SPECS_XML =
+ESOCK_USE_NET_XML =
+endif
+
XML_REF3_FILES = application.xml \
auth.xml \
code.xml \
@@ -62,6 +74,7 @@ XML_REF3_FILES = application.xml \
logger_disk_log_h.xml \
logger_filters.xml \
logger_formatter.xml \
+ $(XML_REF3_ESOCK_FILES) \
net_adm.xml \
net_kernel.xml \
os.xml \
@@ -112,6 +125,7 @@ SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml)
TOP_SPECS_FILE = specs.xml
+
# ----------------------------------------------------
# FIGURES
# ----------------------------------------------------
@@ -138,7 +152,7 @@ SPECS_FLAGS = -I../../include
$(HTMLDIR)/%: %
$(INSTALL_DATA) $< $@
-docs: man pdf html
+docs: ref_man specs man pdf html
$(TOP_PDF_FILE): $(XML_FILES)
@@ -148,19 +162,32 @@ html: images $(HTML_REF_MAN_FILE)
man: $(MAN3_FILES) $(MAN4_FILES) $(MAN6_FILES)
+ref_man: ref_man.xml
+specs: specs.xml
+
images: $(IMAGE_FILES:%=$(HTMLDIR)/%)
+info:
+ @echo "XML_APPLICATION_FILES: $(XML_APPLICATION_FILES)"
+ @echo "XML_REF3_ESOCK_FILES: $(XML_REF3_ESOCK_FILES)"
+ @echo "XML_REF3_FILES: $(XML_REF3_FILES)"
+ @echo "XML_REF4_FILES: $(XML_REF4_FILES)"
+ @echo "XML_REF6_FILES: $(XML_REF6_FILES)"
+ @echo "XML_PART_FILES: $(XML_PART_FILES)"
+ @echo "XML_CHAPTER_FILES: $(XML_CHAPTER_FILES)"
+ @echo "BOOK_FILES: $(BOOK_FILES)"
+
debug opt:
clean clean_docs:
rm -rf $(HTMLDIR)/*
rm -rf $(XMLDIR)
- rm -f $(MAN3DIR)/*
- rm -f $(MAN4DIR)/*
- rm -f $(MAN6DIR)/*
- rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
- rm -f $(SPECDIR)/*
- rm -f errs core *~ *.eps
+ rm -f $(MAN3DIR)/*
+ rm -f $(MAN4DIR)/*
+ rm -f $(MAN6DIR)/*
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
+ rm -f errs core *~ *.eps
$(SPECDIR)/specs_erl_prim_loader_stub.xml:
$(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
@@ -175,6 +202,14 @@ $(SPECDIR)/specs_zlib_stub.xml:
$(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
-o$(dir $@) -module zlib_stub
+ref_man.xml: ref_man.xml.src
+ ($(PERL) -p -e 's?%ESOCK_USE_NET_XML%?$(ESOCK_USE_NET_XML)?' \
+ $<) > $@
+specs.xml: specs.xml.src
+ ($(PERL) -p -e 's?%ESOCK_USE_NET_SPECS_XML%?$(ESOCK_USE_NET_SPECS_XML)?' \
+ $<) > $@
+
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/lib/kernel/doc/src/logger_disk_log_h.xml b/lib/kernel/doc/src/logger_disk_log_h.xml
index aa577f3c62..3d8e82ce7c 100644
--- a/lib/kernel/doc/src/logger_disk_log_h.xml
+++ b/lib/kernel/doc/src/logger_disk_log_h.xml
@@ -133,7 +133,7 @@ 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},
+ max_no_bytes => 10000,
filesync_repeat_interval => 1000}}).
</code>
<p>To use the disk_log handler instead of the default standard
diff --git a/erts/doc/src/net.xml b/lib/kernel/doc/src/net.xml
index 6fbc37076c..6fbc37076c 100644
--- a/erts/doc/src/net.xml
+++ b/lib/kernel/doc/src/net.xml
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml.src
index d3b947527f..72e3409123 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml.src
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2018</year>
+ <year>1996</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -60,6 +60,7 @@
<xi:include href="logger_formatter.xml"/>
<xi:include href="logger_std_h.xml"/>
<xi:include href="logger_disk_log_h.xml"/>
+ %ESOCK_USE_NET_XML%
<xi:include href="net_adm.xml"/>
<xi:include href="net_kernel.xml"/>
<xi:include href="os.xml"/>
diff --git a/lib/kernel/doc/src/specs.xml b/lib/kernel/doc/src/specs.xml.src
index b8c25ca53b..ccb26b9458 100644
--- a/lib/kernel/doc/src/specs.xml
+++ b/lib/kernel/doc/src/specs.xml.src
@@ -26,6 +26,7 @@
<xi:include href="../specs/specs_logger_formatter.xml"/>
<xi:include href="../specs/specs_logger_std_h.xml"/>
<xi:include href="../specs/specs_logger_disk_log_h.xml"/>
+ %ESOCK_USE_NET_SPECS_XML%
<xi:include href="../specs/specs_net_adm.xml"/>
<xi:include href="../specs/specs_net_kernel.xml"/>
<xi:include href="../specs/specs_os.xml"/>
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index fcb599859b..88752431eb 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2018. All Rights Reserved.
+# Copyright Ericsson AB 1996-2019. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -123,6 +123,7 @@ MODULES = \
logger_server \
logger_simple_h \
logger_sup \
+ net \
net_adm \
net_kernel \
os \
@@ -180,6 +181,7 @@ ERL_COMPILE_FLAGS += -Werror
endif
ERL_COMPILE_FLAGS += -I../include
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 8fe6bdd1ca..c2ff6b63e9 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -74,6 +74,7 @@
logger_simple_h,
logger_std_h,
logger_sup,
+ net,
net_adm,
net_kernel,
os,
diff --git a/lib/kernel/src/net.erl b/lib/kernel/src/net.erl
new file mode 100644
index 0000000000..b8ffa64043
--- /dev/null
+++ b/lib/kernel/src/net.erl
@@ -0,0 +1,324 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(net).
+
+%% We should really ifdef this module depending on if we actually built
+%% the system with esock support (socket and prim_net), but our doc-building
+%% can't handle the "variables" we need (USE_ESOCK). So instead, we just
+%% leave everything hanging...
+%% If one of the "hanging" functions is called when esock has been disabled,
+%% the function will through a 'notsup' error (erlang:error/1).
+
+%% Administrative and utility functions
+-export([
+ info/0,
+ command/1
+ ]).
+
+-export([
+ gethostname/0,
+ getnameinfo/1, getnameinfo/2,
+ getaddrinfo/1, getaddrinfo/2,
+
+ if_name2index/1,
+ if_index2name/1,
+ if_names/0
+ ]).
+
+%% Deprecated functions from the "old" net module
+-export([call/4,
+ cast/4,
+ broadcast/3,
+ ping/1,
+ relay/1,
+ sleep/1]).
+
+%% Should we define these here or refer to the prim_net module
+-export_type([
+ address_info/0,
+ name_info/0,
+
+ name_info_flags/0,
+ name_info_flag/0,
+ name_info_flag_ext/0,
+
+ network_interface_name/0,
+ network_interface_index/0
+ ]).
+
+
+-deprecated({call, 4, eventually}).
+-deprecated({cast, 4, eventually}).
+-deprecated({broadcast, 3, eventually}).
+-deprecated({ping, 1, eventually}).
+-deprecated({relay, 1, eventually}).
+-deprecated({sleep, 1, eventually}).
+
+
+-type name_info_flags() :: [name_info_flag()|name_info_flag_ext()].
+-type name_info_flag() :: namereqd |
+ dgram |
+ nofqdn |
+ numerichost |
+ nomericserv.
+-type name_info_flag_ext() :: idn |
+ idna_allow_unassigned |
+ idna_use_std3_ascii_rules.
+-type name_info() :: #{host := string(),
+ service := string()}.
+-type address_info() :: #{family := socket:domain(),
+ socktype := socket:type(),
+ protocol := socket:protocol(),
+ address := socket:sockaddr()}.
+-type network_interface_name() :: string().
+-type network_interface_index() :: non_neg_integer().
+
+
+%% ===========================================================================
+%%
+%% D E P R E C A T E D F U N C T I O N S
+%%
+%% ===========================================================================
+
+call(N,M,F,A) -> rpc:call(N,M,F,A).
+cast(N,M,F,A) -> rpc:cast(N,M,F,A).
+broadcast(M,F,A) -> rpc:eval_everywhere(M,F,A).
+ping(Node) -> net_adm:ping(Node).
+sleep(T) -> receive after T -> ok end.
+relay(X) -> slave:relay(X).
+
+
+%% ===========================================================================
+%%
+%% Administrative and utility API
+%%
+%% ===========================================================================
+
+-spec info() -> list().
+
+-ifdef(USE_ESOCK).
+info() ->
+ prim_net:info().
+-else.
+-dialyzer({nowarn_function, info/0}).
+info() ->
+ erlang:error(notsup).
+-endif.
+
+
+-spec command(Cmd :: term()) -> term().
+
+-ifdef(USE_ESOCK).
+command(Cmd) ->
+ prim_net:command(Cmd).
+-else.
+-dialyzer({nowarn_function, command/1}).
+command(_Cmd) ->
+ erlang:error(notsup).
+-endif.
+
+
+
+%% ===========================================================================
+%%
+%% The proper net API
+%%
+%% ===========================================================================
+
+%% ===========================================================================
+%%
+%% gethostname - Get the name of the current host.
+%%
+%%
+
+-spec gethostname() -> {ok, HostName} | {error, Reason} when
+ HostName :: string(),
+ Reason :: term().
+
+-ifdef(USE_ESOCK).
+gethostname() ->
+ prim_net:gethostname().
+-else.
+-dialyzer({nowarn_function, gethostname/0}).
+gethostname() ->
+ erlang:error(notsup).
+-endif.
+
+
+%% ===========================================================================
+%%
+%% getnameinfo - Address-to-name translation in protocol-independent manner.
+%%
+%%
+
+-spec getnameinfo(SockAddr) -> {ok, Info} | {error, Reason} when
+ SockAddr :: socket:sockaddr(),
+ Info :: name_info(),
+ Reason :: term().
+
+getnameinfo(SockAddr) ->
+ getnameinfo(SockAddr, undefined).
+
+-spec getnameinfo(SockAddr, Flags) -> {ok, Info} | {error, Reason} when
+ SockAddr :: socket:sockaddr(),
+ Flags :: name_info_flags() | undefined,
+ Info :: name_info(),
+ Reason :: term().
+
+-ifdef(USE_ESOCK).
+getnameinfo(SockAddr, [] = _Flags) ->
+ getnameinfo(SockAddr, undefined);
+getnameinfo(#{family := Fam, addr := _Addr} = SockAddr, Flags)
+ when ((Fam =:= inet) orelse (Fam =:= inet6)) andalso
+ (is_list(Flags) orelse (Flags =:= undefined)) ->
+ prim_net:getnameinfo(socket:ensure_sockaddr(SockAddr), Flags);
+getnameinfo(#{family := Fam, path := _Path} = SockAddr, Flags)
+ when (Fam =:= local) andalso (is_list(Flags) orelse (Flags =:= undefined)) ->
+ prim_net:getnameinfo(SockAddr, Flags).
+-else.
+-dialyzer({nowarn_function, getnameinfo/2}).
+getnameinfo(SockAddr, [] = _Flags) ->
+ getnameinfo(SockAddr, undefined);
+getnameinfo(#{family := Fam, addr := _Addr} = _SockAddr, Flags)
+ when ((Fam =:= inet) orelse (Fam =:= inet6)) andalso
+ (is_list(Flags) orelse (Flags =:= undefined)) ->
+ erlang:error(notsup);
+getnameinfo(#{family := Fam, path := _Path} = _SockAddr, Flags)
+ when (Fam =:= local) andalso (is_list(Flags) orelse (Flags =:= undefined)) ->
+ erlang:error(notsup).
+-endif.
+
+
+%% ===========================================================================
+%%
+%% getaddrinfo - Network address and service translation
+%%
+%% There is also a "hint" argument that we "at some point" should implement.
+
+-spec getaddrinfo(Host) -> {ok, Info} | {error, Reason} when
+ Host :: string(),
+ Info :: [address_info()],
+ Reason :: term().
+
+getaddrinfo(Host) when is_list(Host) ->
+ getaddrinfo(Host, undefined).
+
+
+-spec getaddrinfo(Host, undefined) -> {ok, Info} | {error, Reason} when
+ Host :: string(),
+ Info :: [address_info()],
+ Reason :: term()
+ ; (undefined, Service) -> {ok, Info} | {error, Reason} when
+ Service :: string(),
+ Info :: [address_info()],
+ Reason :: term()
+ ; (Host, Service) -> {ok, Info} | {error, Reason} when
+ Host :: string(),
+ Service :: string(),
+ Info :: [address_info()],
+ Reason :: term().
+
+-ifdef(USE_ESOCK).
+getaddrinfo(Host, Service)
+ when (is_list(Host) orelse (Host =:= undefined)) andalso
+ (is_list(Service) orelse (Service =:= undefined)) andalso
+ (not ((Service =:= undefined) andalso (Host =:= undefined))) ->
+ prim_net:getaddrinfo(Host, Service).
+-else.
+-dialyzer({nowarn_function, getaddrinfo/2}).
+getaddrinfo(Host, Service)
+ when (is_list(Host) orelse (Host =:= undefined)) andalso
+ (is_list(Service) orelse (Service =:= undefined)) andalso
+ (not ((Service =:= undefined) andalso (Host =:= undefined))) ->
+ erlang:error(notsup).
+-endif.
+
+
+
+
+%% ===========================================================================
+%%
+%% if_name2index - Mappings between network interface names and indexes:
+%% name -> idx
+%%
+%%
+
+-spec if_name2index(Name) -> {ok, Idx} | {error, Reason} when
+ Name :: network_interface_name(),
+ Idx :: network_interface_index(),
+ Reason :: term().
+
+-ifdef(USE_ESOCK).
+if_name2index(If) when is_list(If) ->
+ prim_net:if_name2index(If).
+-else.
+-dialyzer({nowarn_function, if_name2index/1}).
+if_name2index(If) when is_list(If) ->
+ erlang:error(notsup).
+-endif.
+
+
+
+%% ===========================================================================
+%%
+%% if_index2name - Mappings between network interface index and names:
+%% idx -> name
+%%
+%%
+
+-spec if_index2name(Idx) -> {ok, Name} | {error, Reason} when
+ Idx :: network_interface_index(),
+ Name :: network_interface_name(),
+ Reason :: term().
+
+-ifdef(USE_ESOCK).
+if_index2name(Idx) when is_integer(Idx) ->
+ prim_net:if_index2name(Idx).
+-else.
+-dialyzer({nowarn_function, if_index2name/1}).
+if_index2name(Idx) when is_integer(Idx) ->
+ erlang:error(notsup).
+-endif.
+
+
+
+%% ===========================================================================
+%%
+%% if_names - Get network interface names and indexes
+%%
+%%
+
+-spec if_names() -> Names | {error, Reason} when
+ Names :: [{Idx, If}],
+ Idx :: network_interface_index(),
+ If :: network_interface_name(),
+ Reason :: term().
+
+-ifdef(USE_ESOCK).
+if_names() ->
+ prim_net:if_names().
+-else.
+-dialyzer({nowarn_function, if_names/0}).
+if_names() ->
+ erlang:error(notsup).
+-endif.
+
+
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 421510f9d6..de87bd9472 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -2019,7 +2019,7 @@ recvtclass(_Config) ->
%% platforms - change {unix,_} to false?
%% pktoptions is not supported for IPv4
-recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0});
+recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0});
recvtos_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0});
%% Using the option returns einval, so it is not implemented.
recvtos_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0});
@@ -2031,7 +2031,7 @@ recvtos_ok({unix,_}, _) -> true;
recvtos_ok(_, _) -> false.
%% pktoptions is not supported for IPv4
-recvttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0});
+recvttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0});
recvttl_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0});
%% Using the option returns einval, so it is not implemented.
recvttl_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0});
@@ -2043,7 +2043,7 @@ recvttl_ok({unix,_}, _) -> true;
recvttl_ok(_, _) -> false.
%% pktoptions is not supported for IPv6
-recvtclass_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0});
+recvtclass_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0});
recvtclass_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0});
recvtclass_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0});
%% Using the option returns einval, so it is not implemented.
@@ -2224,18 +2224,19 @@ collect_accepts(N,Tmo) ->
A = millis(),
receive
{accepted,P,Msg} ->
- [{P,Msg}] ++ collect_accepts(N-1,Tmo-(millis() - A))
+ NextN = if N =:= infinity -> N; true -> N - 1 end,
+ [{P,Msg}] ++ collect_accepts(NextN, Tmo - (millis()-A))
after Tmo ->
[]
end.
-define(EXPECT_ACCEPTS(Pattern,N,Timeout),
(fun() ->
- case collect_accepts(if N =:= infinity -> -1; true -> N end,Timeout) of
+ case collect_accepts((N), (Timeout)) of
Pattern ->
ok;
- Other ->
- {error,{unexpected,{Other,process_info(self(),messages)}}}
+ Other__ ->
+ {error,{unexpected,{Other__,process_info(self(),messages)}}}
end
end)()).
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index 730886865c..70d8caf478 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -646,7 +646,7 @@ sendtclass(_Config) ->
%% Using the option returns einval, so it is not implemented.
recvtos_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {17,6,0});
%% Using the option returns einval, so it is not implemented.
-recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0});
+recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0});
%% Using the option returns einval, so it is not implemented.
recvtos_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0});
%%
@@ -675,7 +675,7 @@ recvtclass_ok(_, _) -> false.
%% Using the option returns einval, so it is not implemented.
sendtos_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0});
-sendtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,5,0});
+sendtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0});
sendtos_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0});
sendtos_ok({unix,linux}, OSVer) -> not semver_lt(OSVer, {4,0,0});
sendtos_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0});
@@ -689,7 +689,8 @@ sendttl_ok({unix,linux}, OSVer) -> not semver_lt(OSVer, {4,0,0});
%% Using the option returns enoprotoopt, so it is not implemented.
sendttl_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0});
%% Option has no effect
-sendttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,5,0});
+sendttl_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0});
+sendttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0});
%%
sendttl_ok({unix,_}, _) -> true;
sendttl_ok(_, _) -> false.
@@ -697,6 +698,8 @@ sendttl_ok(_, _) -> false.
%% Using the option returns einval, so it is not implemented.
sendtclass_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {9,9,0});
sendtclass_ok({unix,linux}, OSVer) -> not semver_lt(OSVer, {2,6,11});
+%% Option has no effect
+sendtclass_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0});
%%
sendtclass_ok({unix,_}, _) -> true;
sendtclass_ok(_, _) -> false.
diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl
index 298a364a91..173e25c520 100644
--- a/lib/kernel/test/interactive_shell_SUITE.erl
+++ b/lib/kernel/test/interactive_shell_SUITE.erl
@@ -23,7 +23,8 @@
init_per_group/2,end_per_group/2,
get_columns_and_rows/1, exit_initial/1, job_control_local/1,
job_control_remote/1,
- job_control_remote_noshell/1,ctrl_keys/1]).
+ job_control_remote_noshell/1,ctrl_keys/1,
+ get_columns_and_rows_escript/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% For spawn
@@ -40,7 +41,8 @@ suite() ->
{timetrap,{minutes,3}}].
all() ->
- [get_columns_and_rows, exit_initial, job_control_local,
+ [get_columns_and_rows_escript,get_columns_and_rows,
+ exit_initial, job_control_local,
job_control_remote, job_control_remote_noshell,
ctrl_keys].
@@ -72,6 +74,60 @@ end_per_group(_GroupName, Config) ->
-define(dbg(Data),noop).
-endif.
+string_to_term(Str) ->
+ {ok,Tokens,_EndLine} = erl_scan:string(Str ++ "."),
+ {ok,AbsForm} = erl_parse:parse_exprs(Tokens),
+ {value,Value,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()),
+ Value.
+
+run_unbuffer_escript(Rows, Columns, EScript, NoTermStdIn, NoTermStdOut) ->
+ DataDir = filename:join(filename:dirname(code:which(?MODULE)), "interactive_shell_SUITE_data"),
+ TmpFile = filename:join(DataDir, "tmp"),
+ ok = file:write_file(TmpFile, <<>>),
+ CommandModifier =
+ case {NoTermStdIn, NoTermStdOut} of
+ {false, false} -> "";
+ {true, false} -> io_lib:format(" < ~s", [TmpFile]);
+ {false, true} -> io_lib:format(" > ~s ; cat ~s", [TmpFile, TmpFile]);
+ {true, true} -> io_lib:format(" > ~s < ~s ; cat ~s", [TmpFile, TmpFile, TmpFile])
+ end,
+ Command = io_lib:format("unbuffer -p bash -c \"stty rows ~p; stty columns ~p; escript ~s ~s\"",
+ [Rows, Columns, EScript, CommandModifier]),
+ %% io:format("Command: ~s ~n", [Command]),
+ Out = os:cmd(Command),
+ %% io:format("Out: ~p ~n", [Out]),
+ string_to_term(Out).
+
+get_columns_and_rows_escript(Config) when is_list(Config) ->
+ ExpectUnbufferInstalled =
+ try
+ "79" = string:trim(os:cmd("unbuffer -p bash -c \"stty columns 79 ; tput cols\"")),
+ true
+ catch
+ _:_ -> false
+ end,
+ case ExpectUnbufferInstalled of
+ false ->
+ {skip,
+ "The unbuffer tool (https://core.tcl-lang.org/expect/index) does not seem to be installed.~n"
+ "On Ubuntu/Debian: \"sudo apt-get install expect\""};
+ true ->
+ DataDir = filename:join(filename:dirname(code:which(?MODULE)), "interactive_shell_SUITE_data"),
+ IoColumnsErl = filename:join(DataDir, "io_columns.erl"),
+ IoRowsErl = filename:join(DataDir, "io_rows.erl"),
+ [
+ begin
+ {ok, 42} = run_unbuffer_escript(99, 42, IoColumnsErl, NoTermStdIn, NoTermStdOut),
+ {ok, 99} = run_unbuffer_escript(99, 42, IoRowsErl, NoTermStdIn, NoTermStdOut)
+ end
+ ||
+ {NoTermStdIn, NoTermStdOut} <- [{false, false}, {true, false}, {false, true}]
+ ],
+ {error,enotsup} = run_unbuffer_escript(99, 42, IoRowsErl, true, true),
+ {error,enotsup} = run_unbuffer_escript(99, 42, IoColumnsErl, true, true),
+ ok
+ end.
+
%% Test that the shell can access columns and rows.
get_columns_and_rows(Config) when is_list(Config) ->
case proplists:get_value(default_shell,Config) of
diff --git a/lib/kernel/test/interactive_shell_SUITE_data/.gitignore b/lib/kernel/test/interactive_shell_SUITE_data/.gitignore
new file mode 100644
index 0000000000..1c2f433de1
--- /dev/null
+++ b/lib/kernel/test/interactive_shell_SUITE_data/.gitignore
@@ -0,0 +1 @@
+tmp \ No newline at end of file
diff --git a/lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl b/lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl
new file mode 100644
index 0000000000..32d0cf25df
--- /dev/null
+++ b/lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl
@@ -0,0 +1,6 @@
+-module(io_columns).
+
+-export([main/1]).
+
+main(_) ->
+ io:format("~p",[io:columns()]).
diff --git a/lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl b/lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl
new file mode 100644
index 0000000000..53ceb464b0
--- /dev/null
+++ b/lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl
@@ -0,0 +1,6 @@
+-module(io_rows).
+
+-export([main/1]).
+
+main(_) ->
+ io:format("~p",[io:rows()]).
diff --git a/lib/megaco/test/Makefile b/lib/megaco/test/Makefile
index 4ddd73eea1..b4e31765b8 100644
--- a/lib/megaco/test/Makefile
+++ b/lib/megaco/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2016. All Rights Reserved.
+# Copyright Ericsson AB 1999-2019. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -102,6 +102,9 @@ endif
ERL_COMPILE_FLAGS += $(MEGACO_ERL_COMPILE_FLAGS)
+# We have a behaviour in the test catalog (megaco_test_generator)
+ERL_COMPILE_FLAGS += -pa ../../megaco/test
+
ERL_PATH = -pa ../../megaco/examples/simple \
-pa ../../megaco/ebin \
-pa ../../et/ebin
diff --git a/lib/megaco/test/megaco_SUITE.erl b/lib/megaco/test/megaco_SUITE.erl
index 38590f9fee..f7b8ffe032 100644
--- a/lib/megaco/test/megaco_SUITE.erl
+++ b/lib/megaco/test/megaco_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,21 @@
-module(megaco_SUITE).
--compile(export_all).
+-export([
+ suite/0,
+ all/0,
+ groups/0,
+
+ init_per_suite/1,
+ end_per_suite/1,
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ t/0, t/1,
+ init/0
+ ]).
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
@@ -96,6 +110,20 @@ groups() ->
{flex, [], [{megaco_flex_test, all}]}].
init_per_suite(Config) ->
+ io:format("~w:init_per_suite -> entry with"
+ "~n Config: ~p"
+ "~n OS Type: ~p"
+ "~n OS Version: ~s"
+ "~n",
+ [?MODULE,
+ Config,
+ os:type(),
+ case os:version() of
+ {Major, Minor, Release} ->
+ ?F("~w.~w.~w", [Major, Minor, Release]);
+ Str when is_list(Str) ->
+ Str
+ end]),
Config.
end_per_suite(_Config) ->
diff --git a/lib/megaco/test/megaco_actions_test.erl b/lib/megaco/test/megaco_actions_test.erl
index fcbe4f12fa..498e5c91cb 100644
--- a/lib/megaco/test/megaco_actions_test.erl
+++ b/lib/megaco/test/megaco_actions_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,13 +20,30 @@
%%
%%----------------------------------------------------------------------
-%% Purpose: Verify that it is possible to separatelly encode
+%% Purpose: Verify that it is possible to separately encode
%% the action requests list. Do this with all codec's
%% that supports partial encode.
%%----------------------------------------------------------------------
-module(megaco_actions_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ t/0, t/1,
+
+ pretty_text/1,
+ flex_pretty_text/1,
+ compact_text/1,
+ flex_compact_text/1,
+ erl_dist/1,
+ erl_dist_mc/1
+ ]).
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
@@ -364,9 +381,6 @@ sleep(X) ->
receive after X -> ok end.
-error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i(F) ->
@@ -376,8 +390,8 @@ i(F, A) ->
print(info, get(verbosity), "", F, A).
-d(F) ->
- d(F, []).
+%% d(F) ->
+%% d(F, []).
d(F, A) ->
print(debug, get(verbosity), "DBG: ", F, A).
@@ -391,20 +405,10 @@ print(Severity, Verbosity, P, F, A) ->
print(printable(Severity,Verbosity), P, F, A).
print(true, P, F, A) ->
- io:format("~s~p:~s: " ++ F ++ "~n", [P, self(), get(sname) | A]);
+ io:format("*** [~s] ~s ~p ~s ***"
+ "~n " ++ F ++ "~n",
+ [?FTS(), P, self(), get(sname) | A]);
print(_, _, _, _) ->
ok.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-random_init() ->
- {A,B,C} = now(),
- random:seed(A,B,C).
-
-random() ->
- 10 * random:uniform(50).
-
-apply_load_timer() ->
- erlang:send_after(random(), self(), apply_load_timeout).
-
diff --git a/lib/megaco/test/megaco_app_test.erl b/lib/megaco/test/megaco_app_test.erl
index 981d93f5dd..fff2d8c7d4 100644
--- a/lib/megaco/test/megaco_app_test.erl
+++ b/lib/megaco/test/megaco_app_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,29 +20,42 @@
%%----------------------------------------------------------------------
%% Purpose: Verify the application specifics of the Megaco application
%%----------------------------------------------------------------------
+
-module(megaco_app_test).
--compile(export_all).
+-export([
+ all/0,
+
+ app/0, app/1,
+ appup/0, appup/1
+ ]).
-include_lib("common_test/include/ct.hrl").
+
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
+
all() ->
[
app,
appup
].
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
+
app() ->
[{doc, "Test that the megaco app file is ok"}].
app(Config) when is_list(Config) ->
ok = test_server:app_test(megaco).
+
+
%%--------------------------------------------------------------------
+
appup() ->
[{doc, "Test that the megaco appup file is ok"}].
appup(Config) when is_list(Config) ->
diff --git a/lib/megaco/test/megaco_appup_test.erl b/lib/megaco/test/megaco_appup_test.erl
index 8dc3ad51a0..a06d274844 100644
--- a/lib/megaco/test/megaco_appup_test.erl
+++ b/lib/megaco/test/megaco_appup_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,8 +22,23 @@
%%----------------------------------------------------------------------
-module(megaco_appup_test).
--compile(export_all).
--compile({no_auto_import,[error/1]}).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_suite/1,
+ end_per_suite/1,
+
+ init_per_group/2,
+ end_per_group/2,
+
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ appup_file/1
+ ]).
+
+-compile({no_auto_import, [error/1]}).
-include_lib("common_test/include/ct.hrl").
-include("megaco_test_lib.hrl").
@@ -76,6 +91,10 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Perform a simple check of the appup file
+appup_file(suite) ->
+ [];
+appup_file(doc) ->
+ ["Perform a simple check of the appup file"];
appup_file(Config) when is_list(Config) ->
ok = ?t:appup_test(megaco).
diff --git a/lib/megaco/test/megaco_call_flow_test.erl b/lib/megaco/test/megaco_call_flow_test.erl
index eb4574862d..03caf705ba 100644
--- a/lib/megaco/test/megaco_call_flow_test.erl
+++ b/lib/megaco/test/megaco_call_flow_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -38,7 +38,85 @@
-module(megaco_call_flow_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ pretty/1,
+ compact/1,
+ pretty_flex/1,
+ compact_flex/1,
+ bin/1,
+ ber/1,
+ per/1,
+ standard_erl/1,
+ compressed_erl/1,
+
+ t/0, t/1
+
+ ]).
+
+-export([
+ msg1/0, msg1/1,
+ msg2/0, msg2/1,
+ msg3/0, msg3/1,
+ msg4/0, msg4/1,
+ msg5a/0, msg5a/1,
+ msg5b/0, msg5b/1,
+ msg6/0, msg6/1,
+ msg7/0, msg7/1,
+ msg9/0, msg9/1,
+ msg10/0, msg10/1,
+ msg11/0, msg11/1,
+ msg12/0, msg12/1,
+ msg13/0, msg13/1,
+ msg14/0, msg14/1,
+ msg15/0, msg15/1,
+ msg16/0, msg16/1,
+ msg17a/0, msg17a/1,
+ msg17b/0, msg17b/1,
+ msg18a/0, msg18a/1,
+ msg18b/0, msg18b/1,
+ msg18c/0, msg18c/1,
+ msg18d/0, msg18d/1,
+ msg19a/0, msg19a/1,
+ msg19b/0, msg19b/1,
+ msg20/0, msg20/1,
+ msg21/0, msg21/1,
+ msg22a/0, msg22a/1,
+ msg22b/0, msg22b/1,
+ msg23a/0, msg23a/1,
+ msg23b/0, msg23b/1
+
+ ]).
+
+-export([
+ encoders/0,
+ msg_sizes/0,
+ coding_times/0,
+ encoding_times/0,
+ decoding_times/0,
+ coding_times_stat/0,
+ encoding_times_stat/0,
+ decoding_times_stat/0,
+ size_stat/0,
+ gnuplot_gif/0,
+ gnuplot_size_gif/0,
+
+ gen_byte_msg/2,
+ gen_header_file_binary/1,
+ gen_ber_header/0,
+ gen_ber_bin_header/0,
+ gen_per_header/0,
+ single_meter/4,
+ count/2
+ ]).
+
-include_lib("megaco/include/megaco.hrl").
-include_lib("megaco/include/megaco_message_v1.hrl").
-include("megaco_test_lib.hrl").
@@ -53,16 +131,20 @@ init_per_testcase(Case, Config) ->
end_per_testcase(Case, Config) ->
megaco_test_lib:end_per_testcase(Case, Config).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
all() ->
- [{group, text}, {group, binary}].
+ [{group, text}, {group, binary}, {group, erl}].
groups() ->
- [{text, [], [pretty, compact]},
- {flex, [], [pretty_flex, compact_flex]},
- {binary, [], [bin, ber, per]}].
+ [
+ {text, [], [pretty, compact]},
+ {flex, [], [pretty_flex, compact_flex]},
+ {binary, [], [bin, ber, per]},
+ {erl, [], [standard_erl, compressed_erl]}
+ ].
init_per_group(_GroupName, Config) ->
Config.
diff --git a/lib/megaco/test/megaco_codec_test.erl b/lib/megaco/test/megaco_codec_test.erl
index 007136f83e..0dfbabcc81 100644
--- a/lib/megaco/test/megaco_codec_test.erl
+++ b/lib/megaco/test/megaco_codec_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,18 @@
-module(megaco_codec_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ t/0, t/1,
+ init/0
+ ]).
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_codec_test_lib.erl b/lib/megaco/test/megaco_codec_test_lib.erl
index 6eee5caaaa..7a3d4e6cf8 100644
--- a/lib/megaco/test/megaco_codec_test_lib.erl
+++ b/lib/megaco/test/megaco_codec_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -993,15 +993,15 @@ expect_exec([#expect_instruction{description = Desc,
skip({What, Why}) when is_atom(What) andalso is_list(Why) ->
Reason = lists:flatten(io_lib:format("~p: ~s", [What, Why])),
- exit({skipped, Reason});
+ ?SKIP(Reason);
skip({What, Why}) ->
Reason = lists:flatten(io_lib:format("~p: ~p", [What, Why])),
- exit({skipped, Reason});
+ ?SKIP(Reason);
skip(Reason) when is_list(Reason) ->
- exit({skipped, Reason});
+ ?SKIP(Reason);
skip(Reason1) ->
Reason2 = lists:flatten(io_lib:format("~p", [Reason1])),
- exit({skipped, Reason2}).
+ ?SKIP(Reason2).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_config_test.erl b/lib/megaco/test/megaco_config_test.erl
index 02e06a722a..d46806927a 100644
--- a/lib/megaco/test/megaco_config_test.erl
+++ b/lib/megaco/test/megaco_config_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,24 @@
-module(megaco_config_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ config/1,
+ transaction_id_counter_mg/1,
+ transaction_id_counter_mgc/1,
+ otp_7216/1,
+ otp_8167/1,
+ otp_8183/1,
+
+ t/0, t/1
+ ]).
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
@@ -37,6 +54,19 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
min(M) -> timer:minutes(M).
%% Test server callbacks
+init_per_testcase(Case, Config) when (Case =:= otp_7216) orelse
+ (Case =:= otp_8167) orelse
+ (Case =:= otp_8183) ->
+ i("try starting megaco_config"),
+ case megaco_config:start_link() of
+ {ok, _} ->
+ C = lists:keydelete(tc_timeout, 1, Config),
+ do_init_per_testcase(Case, [{tc_timeout, min(3)}|C]);
+ {error, Reason} ->
+ i("Failed starting megaco_config: "
+ "~n ~p", [Reason]),
+ {skip, ?F("Failed starting config: ~p", [Reason])}
+ end;
init_per_testcase(Case, Config) ->
C = lists:keydelete(tc_timeout, 1, Config),
do_init_per_testcase(Case, [{tc_timeout, min(3)}|C]).
@@ -45,6 +75,12 @@ do_init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
+end_per_testcase(Case, Config) when (Case =:= otp_7216) orelse
+ (Case =:= otp_8167) orelse
+ (Case =:= otp_8183) ->
+ (catch megaco_config:stop()),
+ process_flag(trap_exit, false),
+ megaco_test_lib:end_per_testcase(Case, Config);
end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
megaco_test_lib:end_per_testcase(Case, Config).
@@ -60,14 +96,17 @@ end_per_testcase(Case, Config) ->
%% Top test case
all() ->
- [config, {group, transaction_id_counter},
- {group, tickets}].
+ [
+ config,
+ {group, transaction_id_counter},
+ {group, tickets}
+ ].
groups() ->
- [{transaction_id_counter, [],
- [transaction_id_counter_mg,
- transaction_id_counter_mgc]},
- {tickets, [], [otp_7216, otp_8167, otp_8183]}].
+ [
+ {transaction_id_counter, [], transaction_id_counter_cases()},
+ {tickets, [], tickets_cases()}
+ ].
init_per_group(_GroupName, Config) ->
Config.
@@ -75,6 +114,19 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+transaction_id_counter_cases() ->
+ [
+ transaction_id_counter_mg,
+ transaction_id_counter_mgc
+ ].
+
+tickets_cases() ->
+ [
+ otp_7216,
+ otp_8167,
+ otp_8183
+ ].
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Config test case
@@ -736,9 +788,6 @@ otp_7216(Config) when is_list(Config) ->
put(tc, otp_7216),
p("start"),
- p("start the megaco config process"),
- megaco_config:start_link(),
-
LocalMid1 = {deviceName, "local-mid-1"},
%% LocalMid2 = {deviceName, "local-mid-2"},
RemoteMid1 = {deviceName, "remote-mid-1"},
@@ -859,9 +908,6 @@ otp_8167(Config) when is_list(Config) ->
put(tc, otp8167),
p("start"),
- p("start the megaco config process"),
- megaco_config:start_link(),
-
LocalMid1 = {deviceName, "local-mid-1"},
LocalMid2 = {deviceName, "local-mid-2"},
RemoteMid1 = {deviceName, "remote-mid-1"},
@@ -981,9 +1027,6 @@ otp_8183(Config) when is_list(Config) ->
put(tc, otp8183),
p("start"),
- p("start the megaco config process"),
- megaco_config:start_link(),
-
LocalMid1 = {deviceName, "local-mid-1"},
LocalMid2 = {deviceName, "local-mid-2"},
RemoteMid1 = {deviceName, "remote-mid-1"},
@@ -1122,28 +1165,18 @@ i(F) ->
i(F, []).
i(F, A) ->
- print(info, get(verbosity), now(), get(tc), "INF", F, A).
+ print(info, get(verbosity), get(tc), "INF", F, A).
printable(_, debug) -> true;
printable(info, info) -> true;
printable(_,_) -> false.
-print(Severity, Verbosity, Ts, Tc, P, F, A) ->
- print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
+print(Severity, Verbosity, Tc, P, F, A) ->
+ print(printable(Severity,Verbosity), Tc, P, F, A).
-print(true, Ts, Tc, P, F, A) ->
+print(true, Tc, P, F, A) ->
io:format("*** [~s] ~s ~p ~s:~w ***"
"~n " ++ F ++ "~n",
- [format_timestamp(Ts), P, self(), get(sname), Tc | A]);
-print(_, _, _, _, _, _) ->
+ [?FTS(), P, self(), get(sname), Tc | A]);
+print(_, _, _, _, _) ->
ok.
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
diff --git a/lib/megaco/test/megaco_digit_map_test.erl b/lib/megaco/test/megaco_digit_map_test.erl
index 998e829b67..e03d38497c 100644
--- a/lib/megaco/test/megaco_digit_map_test.erl
+++ b/lib/megaco/test/megaco_digit_map_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,27 @@
%%----------------------------------------------------------------------
-module(megaco_digit_map_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ otp_5750_01/1,
+ otp_5750_02/1,
+ otp_5799_01/1,
+ otp_5826_01/1,
+ otp_5826_02/1,
+ otp_5826_03/1,
+ otp_7449_1/1,
+ otp_7449_2/1,
+
+ t/0, t/1
+ ]).
+
-include("megaco_test_lib.hrl").
@@ -44,16 +64,18 @@ end_per_testcase(Case, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all() ->
- [{group, tickets}].
+ [
+ {group, tickets}
+ ].
groups() ->
- [{tickets, [],
- [{group, otp_5750}, {group, otp_5799},
- {group, otp_5826}, {group, otp_7449}]},
- {otp_5750, [], [otp_5750_01, otp_5750_02]},
- {otp_5799, [], [otp_5799_01]},
- {otp_5826, [], [otp_5826_01, otp_5826_02, otp_5826_03]},
- {otp_7449, [], [otp_7449_1, otp_7449_2]}].
+ [
+ {tickets, [], tickets_cases()},
+ {otp_5750, [], otp_5750_cases()},
+ {otp_5799, [], otp_5799_cases()},
+ {otp_5826, [], otp_5826_cases()},
+ {otp_7449, [], otp_7449_cases()}
+ ].
init_per_group(_GroupName, Config) ->
Config.
@@ -62,6 +84,38 @@ end_per_group(_GroupName, Config) ->
Config.
+tickets_cases() ->
+ [
+ {group, otp_5750},
+ {group, otp_5799},
+ {group, otp_5826},
+ {group, otp_7449}
+ ].
+
+otp_5750_cases() ->
+ [
+ otp_5750_01,
+ otp_5750_02
+ ].
+
+otp_5799_cases() ->
+ [
+ otp_5799_01
+ ].
+
+otp_5826_cases() ->
+ [
+ otp_5826_01,
+ otp_5826_02,
+ otp_5826_03
+ ].
+
+otp_7449_cases() ->
+ [
+ otp_7449_1,
+ otp_7449_2
+ ].
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_examples_test.erl b/lib/megaco/test/megaco_examples_test.erl
index 10ca0375f6..fdf9fe29ff 100644
--- a/lib/megaco/test/megaco_examples_test.erl
+++ b/lib/megaco/test/megaco_examples_test.erl
@@ -25,7 +25,20 @@
-module(megaco_examples_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ simple/1,
+
+ t/0, t/1
+ ]).
+
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_flex_test.erl b/lib/megaco/test/megaco_flex_test.erl
index 999d1abc6c..27c46a3b47 100644
--- a/lib/megaco/test/megaco_flex_test.erl
+++ b/lib/megaco/test/megaco_flex_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -219,18 +219,5 @@ p(F, A) ->
TC = get(tc),
io:format("*** [~s] ~p ~w ***"
"~n " ++ F ++ "~n",
- [formated_timestamp(), self(), TC | A]).
-
-formated_timestamp() ->
- format_timestamp(erlang:now()).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY, MM, DD} = Date,
- {Hour, Min, Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
+ [?FTS(), self(), TC | A]).
diff --git a/lib/megaco/test/megaco_load_test.erl b/lib/megaco/test/megaco_load_test.erl
index 511e5a2e8e..9cce9e70ce 100644
--- a/lib/megaco/test/megaco_load_test.erl
+++ b/lib/megaco/test/megaco_load_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,33 @@
%%----------------------------------------------------------------------
-module(megaco_load_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ single_user_light_load/1,
+ single_user_medium_load/1,
+ single_user_heavy_load/1,
+ single_user_extreme_load/1,
+
+ multi_user_light_load/1,
+ multi_user_medium_load/1,
+ multi_user_heavy_load/1,
+ multi_user_extreme_load/1,
+
+ t/0, t/1
+ ]).
+
+-export([
+ do_multi_load/3,
+ multi_load_collector/7
+ ]).
+
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
@@ -66,8 +92,6 @@
t() -> megaco_test_lib:t(?MODULE).
t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-min(M) -> timer:minutes(M).
-
%% Test server callbacks
init_per_testcase(single_user_light_load = Case, Config) ->
C = lists:keydelete(tc_timeout, 1, Config),
@@ -108,15 +132,33 @@ end_per_testcase(Case, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all() ->
- [single_user_light_load,
- single_user_medium_load, single_user_heavy_load,
- single_user_extreme_load, multi_user_light_load,
- multi_user_medium_load, multi_user_heavy_load,
- multi_user_extreme_load].
+ [
+ {group, single},
+ {group, multi}
+ ].
groups() ->
- [].
-
+ [
+ {single, [], single_cases()},
+ {multi, [], multi_cases()}
+ ].
+
+single_cases() ->
+ [
+ single_user_light_load,
+ single_user_medium_load,
+ single_user_heavy_load,
+ single_user_extreme_load
+ ].
+
+multi_cases() ->
+ [
+ multi_user_light_load,
+ multi_user_medium_load,
+ multi_user_heavy_load,
+ multi_user_extreme_load
+ ].
+
init_per_group(_GroupName, Config) ->
Config.
@@ -326,6 +368,17 @@ load_controller(Config, Fun) when is_list(Config) and is_function(Fun) ->
d("load_controller -> "
"loader [~p] terminated with ok~n", [Loader]),
ok;
+ {'EXIT', Loader, {skipped, {fatal, Reason, File, Line}}} ->
+ i("load_controller -> "
+ "loader [~p] terminated with fatal skip"
+ "~n Reason: ~p"
+ "~n At: ~p:~p", [Loader, Reason, File, Line]),
+ ?SKIP(Reason);
+ {'EXIT', Loader, {skipped, Reason}} ->
+ i("load_controller -> "
+ "loader [~p] terminated with skip"
+ "~n Reason: ~p", [Loader, Reason]),
+ ?SKIP(Reason);
{'EXIT', Loader, Reason} ->
i("load_controller -> "
"loader [~p] terminated with"
@@ -629,14 +682,6 @@ make_mids([MgNode|MgNodes], Mids) ->
exit("Test node must be started with '-sname'")
end.
-tim() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-sleep(X) -> receive after X -> ok end.
-
-error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
-
maybe_display_system_info(NumLoaders) when NumLoaders > 50 ->
[{display_system_info, timer:seconds(2)}];
maybe_display_system_info(NumLoaders) when NumLoaders > 10 ->
@@ -647,50 +692,32 @@ maybe_display_system_info(_) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+min(M) -> timer:minutes(M).
+
i(F) ->
i(F, []).
i(F, A) ->
- print(info, get(verbosity), now(), get(tc), "INF", F, A).
+ print(info, get(verbosity), get(tc), "INF", F, A).
d(F) ->
d(F, []).
d(F, A) ->
- print(debug, get(verbosity), now(), get(tc), "DBG", F, A).
+ print(debug, get(verbosity), get(tc), "DBG", F, A).
printable(_, debug) -> true;
printable(info, info) -> true;
printable(_,_) -> false.
-print(Severity, Verbosity, Ts, Tc, P, F, A) ->
- print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
+print(Severity, Verbosity, Tc, P, F, A) ->
+ print(printable(Severity,Verbosity), Tc, P, F, A).
-print(true, Ts, Tc, P, F, A) ->
+print(true, Tc, P, F, A) ->
io:format("*** [~s] ~s ~p ~s:~w ***"
"~n " ++ F ++ "~n",
- [format_timestamp(Ts), P, self(), get(sname), Tc | A]);
-print(_, _, _, _, _, _) ->
+ [?FTS(), P, self(), get(sname), Tc | A]);
+print(_, _, _, _, _) ->
ok.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-random_init() ->
- {A,B,C} = now(),
- random:seed(A,B,C).
-
-random() ->
- 10 * random:uniform(50).
-
-apply_load_timer() ->
- erlang:send_after(random(), self(), apply_load_timeout).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
diff --git a/lib/megaco/test/megaco_mess_test.erl b/lib/megaco/test/megaco_mess_test.erl
index d3216c2a6d..3fd39a9e58 100644
--- a/lib/megaco/test/megaco_mess_test.erl
+++ b/lib/megaco/test/megaco_mess_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -281,6 +281,8 @@
-define(VERSION, 1).
+-define(USER_MOD, megaco_mess_user_test).
+
-define(TEST_VERBOSITY, debug).
-define(MGC_VERBOSITY, debug).
-define(MG_VERBOSITY, debug).
@@ -303,26 +305,48 @@
-define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)).
-define(SEND(Expr),
- ?VERIFY(ok, megaco_mess_user_test:apply_proxy(fun() -> Expr end))).
+ ?VERIFY(ok, ?USER_MOD:apply_proxy(fun() -> Expr end))).
-define(USER(Expected, Reply),
- megaco_mess_user_test:reply(?MODULE,
- ?LINE,
- fun(Actual) ->
- case ?VERIFY(Expected, Actual) of
- Expected -> {ok, Reply};
- UnExpected -> {error, {reply_verify,
- ?MODULE,
- ?LINE,
- UnExpected}}
- end
- end)).
-
-%% t() -> megaco_test_lib:t(?MODULE).
-%% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-
-
-min(M) -> timer:minutes(M).
+ ?USER_MOD:reply(?MODULE,
+ ?LINE,
+ fun(Actual) ->
+ case ?VERIFY(Expected, Actual) of
+ Expected -> {ok, Reply};
+ UnExpected -> {error, {reply_verify,
+ ?MODULE,
+ ?LINE,
+ UnExpected}}
+ end
+ end)).
+
+%% Some generator (utility) macros
+-define(GM_START(), megaco_start).
+-define(GM_STOP(), megaco_stop).
+-define(GM_START_USER(M, RI, C), {megaco_start_user, M, RI, C}).
+-define(GM_START_USER(M, RI), ?GM_START_USER(M, RI, [])).
+-define(GM_STOP_USER(), megaco_stop_user).
+-define(GMSI(I), {megaco_system_info, I}).
+-define(GMSI_USERS(), ?GMSI(users)).
+-define(GMSI_CONNS(), ?GMSI(connections)).
+-define(GMCAST(Reqs, Opts), {megaco_cast, Reqs, Opts}).
+-define(GMCAST(Reqs), ?GMCAST(Reqs, [])).
+-define(GMCB(CB, VF), {megaco_callback, CB, VF}).
+-define(GMCB_CONNECT(VF), ?GMCB(handle_connect, VF)).
+-define(GMCB_TRANS_REP(VF), ?GMCB(handle_trans_reply, VF)).
+-define(GMT(T), {megaco_trace, T}).
+-define(GMT_ENABLE(), ?GMT(enable)).
+-define(GMT_DISABLE(), ?GMT(disable)).
+-define(GD(D), {debug, D}).
+-define(GD_ENABLE(), ?GD(true)).
+-define(GD_DISABLE(), ?GD(false)).
+-define(GS(T), {sleep, T}).
+
+-define(GSND(T, D), {send, T, D}).
+-define(GERCV(T, VF, TO), {expect_receive, T, {VF, TO}}).
+
+
+min(M) -> ?MINS(M).
%% Test server callbacks
init_per_testcase(otp_7189 = Case, Config) ->
@@ -396,8 +420,19 @@ groups() ->
init_per_suite(Config) ->
io:format("~w:init_per_suite -> entry with"
- "~n Config: ~p"
- "~n", [?MODULE, Config]),
+ "~n Config: ~p"
+ "~n OS Type: ~p"
+ "~n OS Version: ~s"
+ "~n",
+ [?MODULE,
+ Config,
+ os:type(),
+ case os:version() of
+ {Major, Minor, Release} ->
+ ?F("~w.~w.~w", [Major, Minor, Release]);
+ Str when is_list(Str) ->
+ Str
+ end]),
Config.
end_per_suite(_Config) ->
@@ -491,12 +526,12 @@ request_and_reply_plain(suite) ->
request_and_reply_plain(Config) when is_list(Config) ->
?ACQUIRE_NODES(1, Config),
d("request_and_reply_plain -> start proxy",[]),
- megaco_mess_user_test:start_proxy(),
+ ?USER_MOD:start_proxy(),
PrelMid = preliminary_mid,
MgMid = ipv4_mid(4711),
MgcMid = ipv4_mid(),
- UserMod = megaco_mess_user_test,
+ UserMod = ?USER_MOD,
d("request_and_reply_plain -> start megaco app",[]),
?VERIFY(ok, application:start(megaco)),
UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
@@ -564,6 +599,7 @@ request_and_reply_plain(Config) when is_list(Config) ->
ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% OTP-4760
@@ -1715,9 +1751,6 @@ rarpaop_mg_event_sequence(Port, EncMod, EncConf) ->
ScrVerifyFun = ?rarpaop_mg_verify_service_change_rep_msg_fun(),
PendVerifyFun = ?rarpaop_mg_verify_pending_msg_fun(TransId),
NrVerifyFun = ?rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
-%% ScrVerifyFun = rarpaop_mg_verify_service_change_rep_msg_fun(),
-%% PendVerifyFun = rarpaop_mg_verify_pending_msg_fun(TransId),
-%% NrVerifyFun = rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
EvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -2359,9 +2392,6 @@ strar_mg_event_sequence(text, tcp) ->
ConnectVerify = ?strar_mg_verify_handle_connect_fun(),
ServiceChangeReplyVerify = ?strar_mg_verify_service_change_reply_fun(),
NotifyReplyVerify = ?strar_mg_verify_notify_reply_fun(),
-%% ConnectVerify = strar_mg_verify_handle_connect_fun(),
-%% ServiceChangeReplyVerify = strar_mg_verify_service_change_reply_fun(),
-%% NotifyReplyVerify = fun strar_mg_verify_notify_reply/1,
EvSeq = [
{debug, true},
megaco_start,
@@ -3437,9 +3467,6 @@ raraa_mg_event_sequence(text, tcp) ->
ScrVerifyFun = ?raraa_mg_verify_service_change_rep_msg_fun(),
NrVerifyFun = ?raraa_mg_verify_notify_rep_msg_fun(TermId,
TransId, ReqId, CtxId),
-%% ScrVerifyFun = raraa_mg_verify_service_change_rep_msg_fun(),
-%% NrVerifyFun = raraa_mg_verify_notify_rep_msg_fun(TermId,
-%% TransId, ReqId, CtxId),
EvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -4048,9 +4075,6 @@ rarana_mg_event_sequence(text, tcp) ->
ScrVerifyFun = ?rarana_mg_verify_service_change_rep_msg_fun(),
NrVerifyFun = ?rarana_mg_verify_notify_rep_msg_fun(TermId,
TransId, ReqId, CtxId),
-%% ScrVerifyFun = rarana_mg_verify_service_change_rep_msg_fun(),
-%% NrVerifyFun = rarana_mg_verify_notify_rep_msg_fun(TermId,
-%% TransId, ReqId, CtxId),
EvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -4663,9 +4687,6 @@ rarala_mg_event_sequence(text, tcp) ->
ScrVerifyFun = ?rarala_mg_verify_service_change_rep_msg_fun(),
NrVerifyFun = ?rarala_mg_verify_notify_rep_msg_fun(TermId,
TransId, ReqId, CtxId),
-%% ScrVerifyFun = rarala_mg_verify_service_change_rep_msg_fun(),
-%% NrVerifyFun = rarala_mg_verify_notify_rep_msg_fun(TermId,
-%% TransId, ReqId, CtxId),
EvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -5298,15 +5319,6 @@ trarar_mg_event_sequence(text, tcp) ->
?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 3, 3),
NrVerifyFun4 =
?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 4, 4),
-%% ScrVerifyFun = trarar_mg_verify_service_change_rep_msg_fun(),
-%% NrVerifyFun1 =
-%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 1, 1),
-%% NrVerifyFun2 =
-%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 2, 2),
-%% NrVerifyFun3 =
-%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 3, 3),
-%% NrVerifyFun4 =
-%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 4, 4),
EvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -5983,11 +5995,6 @@ pap_mg_event_sequence(text, tcp) ->
?pap_mg_verify_pending_msg_fun(TransId),
NrVerifyFun =
?pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
-%% ScrVerifyFun = pap_mg_verify_service_change_rep_msg_fun(),
-%% PendingVerifyFun =
-%% pap_mg_verify_pending_msg_fun(TransId),
-%% NrVerifyFun =
-%% pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
EvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -6380,10 +6387,6 @@ rapalr_mgc_event_sequence(text, tcp) ->
NrVerifyFun =
?rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
AckVerifyFun = ?rapalr_mgc_verify_trans_ack_msg_fun(TransId),
-%% ScrVerifyFun = rapalr_mgc_verify_service_change_req_msg_fun(),
-%% NrVerifyFun =
-%% rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
-%% AckVerifyFun = rapalr_mgc_verify_trans_ack_msg_fun(TransId),
EvSeq = [{debug, false},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -6866,12 +6869,12 @@ dist(Config) when is_list(Config) ->
?SKIP("Needs a re-write..."),
[_Local, Dist] = ?ACQUIRE_NODES(2, Config),
d("dist -> start proxy",[]),
- megaco_mess_user_test:start_proxy(),
+ ?USER_MOD:start_proxy(),
PrelMid = preliminary_mid,
MgMid = ipv4_mid(4711),
MgcMid = ipv4_mid(),
- UserMod = megaco_mess_user_test,
+ UserMod = ?USER_MOD,
d("dist -> start megaco app",[]),
?VERIFY(ok, application:start(megaco)),
UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
@@ -6977,7 +6980,7 @@ dist(Config) when is_list(Config) ->
?RECEIVE([]),
d("dist -> stop proxy",[]),
- megaco_mess_user_test:stop_proxy(),
+ ?USER_MOD:stop_proxy(),
d("dist -> done", []),
ok.
@@ -7444,9 +7447,6 @@ otp_5805_mg_event_sequence(text, tcp) ->
?otp_5805_mg_verify_service_change_rep_msg_fun(),
EDVerify =
?otp_5805_mg_verify_error_descriptor_msg_fun(),
-%% ServiceChangeReplyVerifyFun =
-%% otp_5805_mg_verify_service_change_rep_msg_fun(),
-%% EDVerify = otp_5805_mg_verify_error_descriptor_msg_fun(),
MgEvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -7939,8 +7939,6 @@ otp_5881_mgc_event_sequence(text, tcp) ->
%% Pending = otp_5881_pending_msg(Mid,2),
ServiceChangeVerifyFun = ?otp_5881_mgc_verify_service_change_req_msg_fun(),
NotifyReqVerifyFun = ?otp_5881_mgc_verify_notify_req_msg_fun(),
-%% ServiceChangeVerifyFun = otp_5881_verify_service_change_req_msg_fun(),
-%% NotifyReqVerifyFun = otp_5881_verify_notify_request_fun(),
MgcEvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -8211,8 +8209,6 @@ otp_5887_mgc_event_sequence(text, tcp) ->
NotifyReply = otp_5887_notify_reply_msg(Mid, 2, 0, TermId),
ServiceChangeVerifyFun = ?otp_5887_mgc_verify_service_change_req_msg_fun(),
NotifyReqVerifyFun = ?otp_5887_mgc_verify_notify_req_msg_fun(),
-%% ServiceChangeVerifyFun = otp_5887_verify_service_change_req_msg_fun(),
-%% NotifyReqVerifyFun = otp_5887_verify_notify_request_fun(),
MgcEvSeq = [{debug, true},
{decode, DecodeFun},
{encode, EncodeFun},
@@ -8362,7 +8358,7 @@ otp_6253(Config) when is_list(Config) ->
MgMid = ipv4_mid(4711),
?VERIFY(ok, application:start(megaco)),
- ?VERIFY(ok, megaco:start_user(MgMid, [{send_mod, megaco_mess_user_test},
+ ?VERIFY(ok, megaco:start_user(MgMid, [{send_mod, ?USER_MOD},
{request_timer, infinity},
{reply_timer, infinity}])),
@@ -8668,8 +8664,6 @@ otp_6275_mgc_event_sequence(text, tcp) ->
NotifyReq = otp_6275_mgc_notify_request_msg(Mid, 2, 1, TermId, 1),
SCRVerifyFun = ?otp_6275_mgc_verify_service_change_req_msg_fun(),
NotifyReplyVerifyFun = ?otp_6275_mgc_verify_notify_rep_msg_fun(),
-%% SCRVerifyFun = otp_6275_mgc_verify_service_change_req_fun(),
-%% NotifyReplyVerifyFun = otp_6275_mgc_verify_notify_reply_fun(),
MgcEvSeq =
[{debug, true},
{decode, DecodeFun},
@@ -11015,12 +11009,12 @@ otp_6865_request_and_reply_plain_extra1(Config) when is_list(Config) ->
ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
d("start proxy",[]),
- megaco_mess_user_test:start_proxy(),
+ ?USER_MOD:start_proxy(),
PrelMid = preliminary_mid,
MgMid = ipv4_mid(4711),
MgcMid = ipv4_mid(),
- UserMod = megaco_mess_user_test,
+ UserMod = ?USER_MOD,
d("start megaco app",[]),
?VERIFY(ok, application:start(megaco)),
UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
@@ -12286,15 +12280,15 @@ otp_7189_mg_event_sequence(text, tcp) ->
?otp_7189_mg_verify_service_change_rep_msg_fun(),
NotifyReqVerify = ?otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
EvSeq = [
- {debug, true},
+ ?GD_ENABLE(),
{decode, DecodeFun},
{encode, EncodeFun},
{connect, 2944},
- {send, "service-change-request", ServiceChangeReq},
- {expect_receive, "service-change-reply", {ServiceChangeReplyVerifyFun, 2000}},
- {expect_receive, "notify request", {NotifyReqVerify, 2000}},
- {sleep, 100},
- {send, "pending", Pending},
+ ?GSND("service-change-request", ServiceChangeReq),
+ ?GERCV("service-change-reply", ServiceChangeReplyVerifyFun, ?SECS(5)),
+ ?GERCV("notify request", NotifyReqVerify, ?SECS(5)),
+ ?GS(100),
+ ?GSND("pending", Pending),
{expect_closed, timer:seconds(120)},
disconnect
],
@@ -12532,7 +12526,7 @@ otp_7259(Config) when is_list(Config) ->
megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
d("[MG] await the generator reply"),
- await_completion([MgId], 5000),
+ await_completion([MgId], 7000),
%% Tell Mg to stop
i("[MG] stop generator"),
@@ -12832,13 +12826,13 @@ otp_7713(Config) when is_list(Config) ->
i("starting"),
d("start proxy",[]),
- megaco_mess_user_test:start_proxy(),
+ ?USER_MOD:start_proxy(),
Extra = otp7713_extra,
PrelMid = preliminary_mid,
MgMid = ipv4_mid(4711),
MgcMid = ipv4_mid(),
- UserMod = megaco_mess_user_test,
+ UserMod = ?USER_MOD,
d("start megaco app",[]),
?VERIFY(ok, application:start(megaco)),
UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
@@ -12954,10 +12948,11 @@ otp_8183_request1(Config) when is_list(Config) ->
i("wait some before issuing the notify reply (twice)"),
sleep(500),
- i("send the notify reply, twice times"),
+ i("send the notify reply - twice"),
NotifyReply =
otp_8183_r1_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
+ sleep(100), %% This is to "make sure" the events come in the "right" order
megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
d("await the generator reply"),
@@ -13228,13 +13223,33 @@ otp_8183_r1_mg_verify_notify_rep_fun(Nr) ->
end.
-endif.
-otp_8183_r1_mg_verify_notify_rep(Nr,
+otp_8183_r1_mg_verify_notify_rep(
+ Nr,
{handle_trans_reply, _CH, ?VERSION, {ok, Nr, [AR]}, _}) ->
io:format("otp_8183_r1_mg_verify_notify_rep -> ok"
"~n Nr: ~p"
"~n AR: ~p"
"~n", [Nr, AR]),
{ok, AR, ok};
+otp_8183_r1_mg_verify_notify_rep(
+ ExpNr,
+ {handle_trans_reply, _CH, ?VERSION, {ok, ActNr, [AR]}, _}) ->
+ io:format("otp_8183_r1_mg_verify_notify_rep -> error"
+ "~n Expected Nr: ~p"
+ "~n Actual Nr: ~p"
+ "~n AR: ~p"
+ "~n", [ExpNr, ActNr, AR]),
+ Error = {unexpected_nr, ExpNr, ActNr},
+ {error, Error, ok};
+otp_8183_r1_mg_verify_notify_rep(
+ Nr,
+ {handle_trans_reply, _CH, ?VERSION, Res, _}) ->
+ io:format("otp_8183_r1_mg_verify_notify_rep -> error"
+ "~n Nr: ~p"
+ "~n Res: ~p"
+ "~n", [Nr, Res]),
+ Error = {unexpected_result, Nr, Res},
+ {error, Error, ok};
otp_8183_r1_mg_verify_notify_rep(Nr, Else) ->
io:format("otp_8183_r1_mg_verify_notify_rep -> unknown"
"~n Nr: ~p"
diff --git a/lib/megaco/test/megaco_mess_user_test.erl b/lib/megaco/test/megaco_mess_user_test.erl
index b5a554112e..d2a9c0f290 100644
--- a/lib/megaco/test/megaco_mess_user_test.erl
+++ b/lib/megaco/test/megaco_mess_user_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -86,13 +86,13 @@ reply(Mod, Line, Fun) when is_function(Fun) ->
{?MODULE, Pid, UserCallback} ->
UserReply = Fun(UserCallback),
Pid ! {?MODULE, self(), UserReply},
- UserReply;
- Other ->
- megaco_test_lib:error(Other, Mod, Line),
- {error, Other}
-%% after 1000 ->
-%% megaco_test_lib:error(timeout, Mod, Line),
-%% {error, timeout}
+ UserReply%% ;
+ %% Other ->
+ %% megaco_test_lib:error(Other, Mod, Line),
+ %% {error, Other}
+ after 10000 ->
+ megaco_test_lib:error(timeout, Mod, Line),
+ {error, timeout}
end.
call(UserCallback) ->
diff --git a/lib/megaco/test/megaco_mib_test.erl b/lib/megaco/test/megaco_mib_test.erl
index 06ac7c08ed..9d1d408f18 100644
--- a/lib/megaco/test/megaco_mib_test.erl
+++ b/lib/megaco/test/megaco_mib_test.erl
@@ -264,7 +264,7 @@ connect(Config) when is_list(Config) ->
d("connect -> (Mg1) service change result: ~p", [Res1]),
%% Collect the statistics
- progress("collect MG1 statustics (after service change)"),
+ progress("collect MG1 statistics (after service change)"),
{ok, Mg1Stats1} = get_stats(Mg1, 1),
d("connect -> stats for Mg1: ~n~p", [Mg1Stats1]),
progress("collect MGC statistics (after MG1 service change)"),
@@ -279,7 +279,7 @@ connect(Config) when is_list(Config) ->
d("connect -> (Mg2) service change result: ~p", [Res2]),
%% Collect the statistics
- progress("collect MG2 statustics (after service change)"),
+ progress("collect MG2 statistics (after service change)"),
{ok, Mg2Stats1} = get_stats(Mg2, 1),
d("connect -> stats for Mg1: ~n~p", [Mg2Stats1]),
progress("collect MGC statistics (after MG2 service change)"),
@@ -751,7 +751,7 @@ mgc_init(Config) ->
d("mgc_init -> entry"),
Mid = get_conf(local_mid, Config),
RI = get_conf(receive_info, Config),
- d("mgc_init -> start megaco"),
+ i("mgc_init -> start megaco"),
application:start(megaco),
d("mgc_init -> start megaco user"),
megaco:start_user(Mid, []),
@@ -763,7 +763,7 @@ mgc_init(Config) ->
RH = megaco:user_info(Mid,receive_handle),
d("mgc_init -> parse receive info"),
ListenTo = mgc_parse_receive_info(RI, RH),
- d("mgc_init -> start transports"),
+ i("mgc_init -> start transport(s)"),
{Tcp, Udp} = mgc_start_transports(ListenTo),
{Mid, Tcp, Udp}.
@@ -948,7 +948,7 @@ mgc_start_transports([{_Port, RH}|_ListenTo], _TcpSup, _UdpSup) ->
mgc_start_tcp(RH, Port, undefined) ->
- d("start tcp transport"),
+ i("start tcp transport"),
case megaco_tcp:start_transport() of
{ok, Sup} ->
mgc_start_tcp(RH, Port, Sup);
@@ -956,7 +956,7 @@ mgc_start_tcp(RH, Port, undefined) ->
throw({error, {failed_starting_tcp_transport, Else}})
end;
mgc_start_tcp(RH, Port, Sup) when is_pid(Sup) ->
- d("tcp listen on ~p", [Port]),
+ i("tcp listen on ~p", [Port]),
Opts = [{port, Port},
{receive_handle, RH},
{tcp_options, [{nodelay, true}]}],
@@ -986,7 +986,7 @@ mgc_tcp_create_listen(Sup, Opts, MaxN, N, _InitialReason)
mgc_start_udp(RH, Port, undefined) ->
- d("start udp transport"),
+ i("start udp transport"),
case megaco_udp:start_transport() of
{ok, Sup} ->
mgc_start_udp(RH, Port, Sup);
@@ -994,7 +994,7 @@ mgc_start_udp(RH, Port, undefined) ->
throw({error, {failed_starting_udp_transport, Else}})
end;
mgc_start_udp(RH, Port, Sup) ->
- d("open udp ~p", [Port]),
+ i("open udp ~p", [Port]),
Opts = [{port, Port}, {receive_handle, RH}],
case megaco_udp:open(Sup, Opts) of
{ok, _SendHandle, _ControlPid} ->
@@ -1119,7 +1119,7 @@ mg_init(Config) ->
d("mg_init -> entry"),
Mid = get_conf(local_mid, Config),
RI = get_conf(receive_info, Config),
- d("mg_init -> start megaco"),
+ i("mg_init -> start megaco"),
application:start(megaco),
d("mg_init -> start megaco user"),
megaco:start_user(Mid, []),
@@ -1131,7 +1131,7 @@ mg_init(Config) ->
RH = megaco:user_info(Mid,receive_handle),
d("mg_init -> parse receive info"),
{MgcPort,RH1} = mg_parse_receive_info(RI, RH),
- d("mg_init -> start transport with"),
+ i("mg_init -> start transport(s)"),
ConnHandle = mg_start_transport(MgcPort, RH1),
{Mid, ConnHandle}.
@@ -1255,16 +1255,6 @@ mg_close_conn(CH) ->
SendMod -> exit(Pid, Reason)
end.
-% display_tuple(T) when tuple(T), size(T) > 0 ->
-% i("size(T): ~p", [size(T)]),
-% display_tuple(T,1).
-
-% display_tuple(T,P) when P > size(T) ->
-% ok;
-% display_tuple(T,P) ->
-% i("T[~p]: ~p", [P,element(P,T)]),
-% display_tuple(T,P+1).
-
mg_parse_receive_info(RI, RH) ->
d("mg_parse_receive_info -> get encoding module"),
@@ -1292,7 +1282,7 @@ mg_start_transport(_, #megaco_receive_handle{send_mod = Mod}) ->
mg_start_tcp(MgcPort, RH) ->
- d("start tcp transport"),
+ i("start tcp transport"),
case megaco_tcp:start_transport() of
{ok, Sup} ->
{ok, LocalHost} = inet:gethostname(),
@@ -1316,7 +1306,7 @@ mg_start_tcp(MgcPort, RH) ->
mg_start_udp(MgcPort, RH) ->
- d("start udp transport"),
+ i("start udp transport"),
case megaco_udp:start_transport() of
{ok, Sup} ->
%% Some linux (Ubuntu) has "crap" in their /etc/hosts, that
@@ -1723,6 +1713,7 @@ progress(F) ->
progress(F, []).
progress(F, A) ->
+ io:format("~s " ++ F ++ "~n", [?FTS()|A]),
io:format(user, "~s " ++ F ++ "~n", [?FTS()|A]).
diff --git a/lib/megaco/test/megaco_mreq_test.erl b/lib/megaco/test/megaco_mreq_test.erl
index e6a5ed3181..ba20329ab3 100644
--- a/lib/megaco/test/megaco_mreq_test.erl
+++ b/lib/megaco/test/megaco_mreq_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,21 @@
%%----------------------------------------------------------------------
-module(megaco_mreq_test).
--compile(export_all).
+-export([
+ all/0,
+ groups/0,
+
+ init_per_group/2,
+ end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ req_and_rep/1,
+ req_and_pending/1,
+ req_and_cancel/1,
+
+ t/0, t/1
+ ]).
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
@@ -51,16 +65,19 @@
-define(MG_START(Pid, Mid, Enc, Transp, Verb),
megaco_test_mg:start(Pid, Mid, Enc, Transp, Verb)).
--define(MG_STOP(Pid), megaco_test_mg:stop(Pid)).
--define(MG_GET_STATS(Pid, No), megaco_test_mg:get_stats(Pid, No)).
--define(MG_RESET_STATS(Pid), megaco_test_mg:reset_stats(Pid)).
--define(MG_SERV_CHANGE(Pid), megaco_test_mg:service_change(Pid)).
--define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)).
--define(MG_NOTIF_REQ(Pid), megaco_test_mg:notify_request(Pid)).
--define(MG_NOTIF_AR(Pid), megaco_test_mg:await_notify_reply(Pid)).
--define(MG_CANCEL(Pid,R), megaco_test_mg:cancel_request(Pid,R)).
+-define(MG_STOP(Pid), megaco_test_mg:stop(Pid)).
+-define(MG_GET_STATS(Pid), megaco_test_mg:get_stats(Pid)).
+-define(MG_RESET_STATS(Pid), megaco_test_mg:reset_stats(Pid)).
+-define(MG_SERV_CHANGE(Pid), megaco_test_mg:service_change(Pid)).
+-define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)).
+-define(MG_NOTIF_REQ(Pid), megaco_test_mg:notify_request(Pid)).
+-define(MG_NOTIF_AR(Pid), megaco_test_mg:await_notify_reply(Pid)).
+-define(MG_CANCEL(Pid,R), megaco_test_mg:cancel_request(Pid,R)).
-define(MG_APPLY_LOAD(Pid,CntStart), megaco_test_mg:apply_load(Pid,CntStart)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
t() -> megaco_test_lib:t(?MODULE).
t(Case) -> megaco_test_lib:t({?MODULE, Case}).
@@ -74,6 +91,7 @@ end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
megaco_test_lib:end_per_testcase(Case, Config).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all() ->
@@ -228,7 +246,7 @@ req_and_rep_stop_mg(MGs) ->
req_and_rep_get_mg_stats([], Acc) ->
lists:reverse(Acc);
req_and_rep_get_mg_stats([{Name, Pid}|Mgs], Acc) ->
- {ok, Stats} = ?MG_GET_STATS(Pid, 1),
+ {ok, Stats} = ?MG_GET_STATS(Pid),
d("req_and_rep_get_mg_stats -> stats for ~s: ~n~p~n", [Name, Stats]),
req_and_rep_get_mg_stats(Mgs, [{Name, Stats}|Acc]).
@@ -399,11 +417,13 @@ req_and_cancel(Config) when is_list(Config) ->
req_and_cancel_analyze_result({ok,{_PV,Res}}) ->
- d("req_and_cancel -> notify request result: ~n ~p", [Res]),
+ i("req_and_cancel -> notify request result: ~n ~p", [Res]),
req_and_cancel_analyze_result2(Res);
req_and_cancel_analyze_result(Unexpected) ->
exit({unexpected_result,Unexpected}).
+req_and_cancel_analyze_result2({error,{user_cancel,req_and_cancel}}) ->
+ ok;
req_and_cancel_analyze_result2([]) ->
ok;
req_and_cancel_analyze_result2([{error,{user_cancel,req_and_cancel}}|Res]) ->
@@ -429,9 +449,6 @@ sleep(X) ->
receive after X -> ok end.
-error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i(F) ->
@@ -441,8 +458,8 @@ i(F, A) ->
print(info, get(verbosity), "", F, A).
-d(F) ->
- d(F, []).
+%% d(F) ->
+%% d(F, []).
d(F, A) ->
print(debug, get(verbosity), "DBG: ", F, A).
@@ -456,20 +473,9 @@ print(Severity, Verbosity, P, F, A) ->
print(printable(Severity,Verbosity), P, F, A).
print(true, P, F, A) ->
- io:format("~s~p:~s: " ++ F ++ "~n", [P, self(), get(sname) | A]);
+ io:format("*** [~s] ~s ~p ~s ***"
+ "~n " ++ F ++ "~n",
+ [?FTS(), P, self(), get(sname) | A]);
print(_, _, _, _) ->
ok.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-random_init() ->
- {A,B,C} = now(),
- random:seed(A,B,C).
-
-random() ->
- 10 * random:uniform(50).
-
-apply_load_timer() ->
- erlang:send_after(random(), self(), apply_load_timeout).
-
diff --git a/lib/megaco/test/megaco_pending_limit_test.erl b/lib/megaco/test/megaco_pending_limit_test.erl
index ef3b7e51cf..e0c0468d99 100644
--- a/lib/megaco/test/megaco_pending_limit_test.erl
+++ b/lib/megaco/test/megaco_pending_limit_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -2065,23 +2065,12 @@ await_completion(Ids) ->
?ERROR({failed, Reply})
end.
-%% await_completion(Ids, Timeout) ->
-%% case megaco_test_generator_lib:await_completion(Ids, Timeout) of
-%% {ok, Reply} ->
-%% d("OK => Reply: ~n~p", [Reply]),
-%% ok;
-%% {error, Reply} ->
-%% d("ERROR => Reply: ~n~p", [Reply]),
-%% ?ERROR({failed, Reply})
-%% end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sleep(X) -> receive after X -> ok end.
-%% error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2089,49 +2078,30 @@ i(F) ->
i(F, []).
i(F, A) ->
- print(info, get(verbosity), now(), get(tc), "INF", F, A).
+ print(info, get(verbosity), get(tc), "INF", F, A).
d(F) ->
d(F, []).
d(F, A) ->
- print(debug, get(verbosity), now(), get(tc), "DBG", F, A).
+ print(debug, get(verbosity), get(tc), "DBG", F, A).
printable(_, debug) -> true;
printable(info, info) -> true;
printable(_,_) -> false.
-print(Severity, Verbosity, Ts, Tc, P, F, A) ->
- print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
+print(Severity, Verbosity, Tc, P, F, A) ->
+ print(printable(Severity,Verbosity), Tc, P, F, A).
-print(true, Ts, Tc, P, F, A) ->
+print(true, Tc, P, F, A) ->
io:format("*** [~s] ~s ~p ~s:~w ***"
"~n " ++ F ++ "~n",
- [format_timestamp(Ts), P, self(), get(sname), Tc | A]);
-print(_, _, _, _, _, _) ->
+ [?FTS(), P, self(), get(sname), Tc | A]);
+print(_, _, _, _, _) ->
ok.
-%% print(F, A) ->
-%% io:format("*** [~s] ***"
-%% "~n " ++ F ++ "~n",
-%% [format_timestamp(now()) | A]).
-
-format_timestamp(Now) -> megaco:format_timestamp(Now).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% random_init() ->
-%% {A,B,C} = now(),
-%% random:seed(A,B,C).
-
-%% random() ->
-%% 10 * random:uniform(50).
-
-%% apply_load_timer() ->
-%% erlang:send_after(random(), self(), apply_load_timeout).
-
-
-
diff --git a/lib/megaco/test/megaco_segment_test.erl b/lib/megaco/test/megaco_segment_test.erl
index ddb8b9f06b..47f708a14b 100644
--- a/lib/megaco/test/megaco_segment_test.erl
+++ b/lib/megaco/test/megaco_segment_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -7718,29 +7718,9 @@ await_completion(Ids) ->
?ERROR({failed, Reply})
end.
-%% await_completion(Ids, Timeout) ->
-%% case megaco_test_generator_lib:await_completion(Ids, Timeout) of
-%% {ok, Reply} ->
-%% d("OK => Reply: ~n~p", [Reply]),
-%% ok;
-%% {error, {OK, ERROR}} ->
-%% d("ERROR => "
-%% "~n OK: ~p"
-%% "~n ERROR: ~p", [OK, ERROR]),
-%% ?ERROR({failed, ERROR});
-%% {error, Reply} ->
-%% d("ERROR => Reply: ~n~p", [Reply]),
-%% ?ERROR({failed, Reply})
-%% end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% tim() ->
-%% {A,B,C} = erlang:now(),
-%% A*1000000000+B*1000+(C div 1000).
-
-
make_node_name(Name) ->
case string:tokens(atom_to_list(node()), [$@]) of
[_,Host] ->
@@ -7754,8 +7734,6 @@ make_node_name(Name) ->
sleep(X) -> receive after X -> ok end.
-%% error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -7763,44 +7741,31 @@ i(F) ->
i(F, []).
i(F, A) ->
- print(info, get(verbosity), now(), get(tc), "INF", F, A).
+ print(info, get(verbosity), get(tc), "INF", F, A).
d(F) ->
d(F, []).
d(F, A) ->
- print(debug, get(verbosity), now(), get(tc), "DBG", F, A).
+ print(debug, get(verbosity), get(tc), "DBG", F, A).
printable(_, debug) -> true;
printable(info, info) -> true;
printable(_,_) -> false.
-print(Severity, Verbosity, Ts, Tc, P, F, A) ->
- print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
+print(Severity, Verbosity, Tc, P, F, A) ->
+ print(printable(Severity, Verbosity), Tc, P, F, A).
-print(true, Ts, Tc, P, F, A) ->
+print(true, Tc, P, F, A) ->
io:format("*** [~s] ~s ~p ~s:~w ***"
"~n " ++ F ++ "~n",
- [format_timestamp(Ts), P, self(), get(sname), Tc | A]);
-print(_, _, _, _, _, _) ->
+ [?FTS(), P, self(), get(sname), Tc | A]);
+print(_, _, _, _, _) ->
ok.
-format_timestamp(Now) -> megaco:format_timestamp(Now).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% random_init() ->
-%% {A,B,C} = now(),
-%% random:seed(A,B,C).
-
-%% random() ->
-%% 10 * random:uniform(50).
-
-%% apply_load_timer() ->
-%% erlang:send_after(random(), self(), apply_load_timeout).
-
-
diff --git a/lib/megaco/test/megaco_tcp_test.erl b/lib/megaco/test/megaco_tcp_test.erl
index a1865ad690..cc66a40f43 100644
--- a/lib/megaco/test/megaco_tcp_test.erl
+++ b/lib/megaco/test/megaco_tcp_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -117,15 +117,39 @@ end_per_testcase(Case, Config) ->
%% Test case definitions
%%======================================================================
all() ->
- [{group, start}, {group, sending}, {group, errors}].
+ [
+ {group, start},
+ {group, sending},
+ {group, errors}
+ ].
groups() ->
- [{start, [],
- [start_normal, start_invalid_opt, start_and_stop]},
- {sending, [], [sendreceive, block_unblock]},
- {errors, [],
- [socket_failure, accept_process, accept_supervisor,
- connection_supervisor, tcp_server]}].
+ [{start, [], start_cases()},
+ {sending, [], sending_cases()},
+ {errors, [], errors_cases()}].
+
+start_cases() ->
+ [
+ start_normal,
+ start_invalid_opt,
+ start_and_stop
+ ].
+
+sending_cases() ->
+ [
+ sendreceive,
+ block_unblock
+ ].
+
+errors_cases() ->
+ [
+ socket_failure,
+ accept_process,
+ accept_supervisor,
+ connection_supervisor,
+ tcp_server
+ ].
+
init_per_group(_GroupName, Config) ->
Config.
@@ -196,17 +220,8 @@ start_and_stop(Config) when is_list(Config) ->
Client = client_start_command_handler(ClientNode, ClientCmds),
p("client command handler started: ~p", [Client]),
- ok =
- receive
- {listening, Server} ->
- p("received listening message from server [~p] => "
- "send continue to client [~p]~n", [Server, Client]),
- Client ! {continue, self()},
- ok
- after 5000 ->
- {error, server_timeout}
- end,
-
+ await_server_listening(Server, Client),
+
await_command_handler_completion([Server, Client], timer:seconds(20)),
p("done"),
ok.
@@ -335,16 +350,7 @@ sendreceive(Config) when is_list(Config) ->
Client = client_start_command_handler(ClientNode, ClientCmds),
p("client command handler started: ~p", [Client]),
- ok =
- receive
- {listening, Server} ->
- p("received listening message from server [~p] => "
- "send continue to client [~p]~n", [Server, Client]),
- Client ! {continue, self()},
- ok
- after 5000 ->
- {error, server_timeout}
- end,
+ await_server_listening(Server, Client),
await_command_handler_completion([Server, Client], timer:seconds(20)),
p("done"),
@@ -544,27 +550,9 @@ block_unblock(Config) when is_list(Config) ->
Client = client_start_command_handler(ClientNode, ClientCmds),
p("client command handler started: ~p", [Client]),
- ok =
- receive
- {listening, Server} ->
- p("received listening message from server [~p] => "
- "send continue to client [~p]~n", [Server, Client]),
- Client ! {continue, self()},
- ok
- after 5000 ->
- {error, server_timeout}
- end,
-
- ok =
- receive
- {blocked, Client} ->
- p("received blocked message from client [~p] => "
- "send continue to server [~p]~n", [Client, Server]),
- Server ! {continue, self()},
- ok
- after 5000 ->
- {error, timeout}
- end,
+ await_server_listening(Server, Client),
+
+ await_client_blocked(Server, Client),
await_command_handler_completion([Server, Client], timer:seconds(30)),
p("done"),
@@ -908,6 +896,42 @@ process_received_message(ReceiveHandle, ControlPid, SendHandle, BinMsg)
%% Internal functions
%%======================================================================
+await_server_listening(Server, Client) ->
+ receive
+ {listening, Server} ->
+ p("received listening message from server [~p] => "
+ "send continue to client [~p]"
+ "~n", [Server, Client]),
+ Client ! {continue, self()},
+ ok
+ after 5000 ->
+ %% There is no normal reason why this should take any time.
+ %% Normally, this takes a few milli seconds. So, if we are not
+ %% up and running after 5 seconds, we give up and skip!!
+ exit(Server, kill),
+ exit(Client, kill),
+ ?SKIP("Server timeout (listen)")
+ end.
+
+
+await_client_blocked(Server, Client) ->
+ receive
+ {blocked, Client} ->
+ p("received blocked message from client [~p] => "
+ "send continue to server [~p]~n", [Client, Server]),
+ Server ! {continue, self()},
+ ok
+ after 5000 ->
+ %% There is no normal reason why this should take any time.
+ %% Normally, this takes a few milli seconds. So, if we are not
+ %% up and running after 5 seconds, we give up and skip!!
+ exit(Client, kill),
+ exit(Server, kill),
+ ?SKIP("Client timeout (blocked)")
+ end.
+
+
+
%% ------- Server command handler and utility functions ----------
server_start_command_handler(Node, Commands) ->
@@ -1214,23 +1238,14 @@ p(F, A) ->
p(S, F, A) when is_list(S) ->
io:format("*** [~s] ~p ~s ***"
"~n " ++ F ++ "~n",
- [format_timestamp(now()), self(), S | A]);
+ [?FTS(), self(), S | A]);
p(_S, F, A) ->
io:format("*** [~s] ~p ~s *** "
"~n " ++ F ++ "~n",
- [format_timestamp(now()), self(), "undefined" | A]).
+ [?FTS(), self(), "undefined" | A]).
ms() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
+ erlang:monotonic_time(milli_seconds).
+
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
diff --git a/lib/megaco/test/megaco_test_deliver.erl b/lib/megaco/test/megaco_test_deliver.erl
index 78033f0e36..c042d9c9a7 100644
--- a/lib/megaco/test/megaco_test_deliver.erl
+++ b/lib/megaco/test/megaco_test_deliver.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -186,4 +186,4 @@ i(F) ->
i(F, []).
i(F, A) ->
- io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]).
+ io:format("*** [~s] ~p ~w:" ++ F ++ "~n", [?FTS(), self(), ?MODULE | A]).
diff --git a/lib/megaco/test/megaco_test_generator.erl b/lib/megaco/test/megaco_test_generator.erl
index 63f66bda07..8ea7f5ddf7 100644
--- a/lib/megaco/test/megaco_test_generator.erl
+++ b/lib/megaco/test/megaco_test_generator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,7 +47,6 @@
print/3, print/4
]).
--export([behaviour_info/1]).
%% Internal exports
-export([start/4]).
@@ -65,6 +64,7 @@
-include_lib("megaco/include/megaco.hrl").
+-include("megaco_test_lib.hrl").
%%----------------------------------------------------------------------
@@ -90,15 +90,32 @@
%%% API
%%%=========================================================================
-behaviour_info(callbacks) ->
- [
- {init, 1},
- {handle_parse, 2},
- {handle_exec, 2},
- {terminate, 2}
- ];
-behaviour_info(_Other) ->
- undefined.
+-callback init(Args) -> {ok, State} | {error, Reason} when
+ Args :: term(),
+ State :: term(),
+ Reason :: term().
+
+-callback handle_parse(Instruction, State) ->
+ {ok, NewInstruction, NewState} |
+ {error, Reason} when
+ Instruction :: term(),
+ State :: term(),
+ NewInstruction :: term(),
+ NewState :: term(),
+ Reason :: term().
+
+-callback handle_exec(Instruction, State) ->
+ {ok, NewState} |
+ {error, Reason} when
+ Instruction :: term(),
+ State :: term(),
+ NewState :: term(),
+ Reason :: term().
+
+-callback terminate(Reason, State) ->
+ megaco:void() when
+ Reason :: term(),
+ State :: term().
%%----------------------------------------------------------------------
@@ -533,22 +550,13 @@ print(P, F, A) ->
print([], undefined, F, A) ->
io:format("*** [~s] ~p *** " ++
"~n " ++ F ++ "~n",
- [format_timestamp(now()),self()|A]);
+ [?FTS(), self() | A]);
print(P, undefined, F, A) ->
io:format("*** [~s] ~p ~s *** " ++
"~n " ++ F ++ "~n",
- [format_timestamp(now()),self(),P|A]);
+ [?FTS(), self(), P | A]);
print(P, N, F, A) ->
io:format("*** [~s] ~p ~s~s *** " ++
"~n " ++ F ++ "~n",
- [format_timestamp(now()),self(),N,P|A]).
-
+ [?FTS(), self(), N, P | A]).
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY, MM, DD} = Date,
- {Hour, Min, Sec} = Time,
- FormatDate =
- io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY, MM, DD, Hour, Min, Sec, round(N3/1000)]),
- lists:flatten(FormatDate).
diff --git a/lib/megaco/test/megaco_test_generic_transport.erl b/lib/megaco/test/megaco_test_generic_transport.erl
index 3185e4c6b6..cd387f748a 100644
--- a/lib/megaco/test/megaco_test_generic_transport.erl
+++ b/lib/megaco/test/megaco_test_generic_transport.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -59,7 +59,7 @@
receive_handle}).
-include_lib("megaco/include/megaco.hrl").
-%% -include("megaco_test_lib.hrl").
+-include("megaco_test_lib.hrl").
-define(SERVER, ?MODULE).
@@ -335,21 +335,11 @@ d(F) ->
d(F, []).
d(F, A) ->
- print(now(), F, A).
+ print(F, A).
-print(Ts, F, A) ->
+print(F, A) ->
io:format("*** [~s] GENERIC TRANSPORT [~p] ***"
"~n " ++ F ++ "~n",
- [format_timestamp(Ts), self() | A]).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
+ [?FTS(), self() | A]).
diff --git a/lib/megaco/test/megaco_test_lib.erl b/lib/megaco/test/megaco_test_lib.erl
index 0617b96456..7c8c287e7c 100644
--- a/lib/megaco/test/megaco_test_lib.erl
+++ b/lib/megaco/test/megaco_test_lib.erl
@@ -318,9 +318,9 @@ t({Mod, {group, Name} = Group, Groups}, Config)
[Name, Error]),
[{failed, {Mod, Group}, Error}]
catch
- exit:{skipped, SkipReason} ->
+ exit:{skip, SkipReason} ->
io:format(" => skipping group: ~p~n", [SkipReason]),
- [{skipped, {Mod, Group}, SkipReason, 0}];
+ [{skip, {Mod, Group}, SkipReason, 0}];
error:undef ->
[t({Mod, Case, Groups}, Config) ||
Case <- GroupsAndCases];
@@ -383,9 +383,9 @@ t(Mod, Config) when is_atom(Mod) ->
io:format(" => suite init failed: ~p~n", [Error]),
[{failed, {Mod, init_per_suite}, Error}]
catch
- exit:{skipped, SkipReason} ->
+ exit:{skip, SkipReason} ->
io:format(" => skipping suite: ~p~n", [SkipReason]),
- [{skipped, {Mod, init_per_suite}, SkipReason, 0}];
+ [{skip, {Mod, init_per_suite}, SkipReason, 0}];
error:undef ->
[t({Mod, Case, Groups}, Config) || Case <- Cases];
T:E ->
@@ -458,10 +458,10 @@ wait_for_evaluator(Pid, Mod, Fun, Config, Errors, AccTime) ->
megaco:report_event(20, Mod, ?MODULE, Label ++ " failed",
[TestCase, Config, {return, Fail}, Errors]),
{failed, {Mod,Fun}, Fail, Time};
- {'EXIT', Pid, {skipped, Reason}, Time} ->
+ {'EXIT', Pid, {skip, Reason}, Time} ->
megaco:report_event(20, Mod, ?MODULE, Label ++ " skipped",
- [TestCase, Config, {skipped, Reason}]),
- {skipped, {Mod, Fun}, Errors, Time};
+ [TestCase, Config, {skip, Reason}]),
+ {skip, {Mod, Fun}, Errors, Time};
{'EXIT', Pid, Reason, Time} ->
megaco:report_event(20, Mod, ?MODULE, Label ++ " crashed",
[TestCase, Config, {'EXIT', Reason}]),
@@ -492,14 +492,14 @@ do_eval(ReplyTo, Mod, Fun, Config) ->
error:undef ->
%% p("do_eval -> error - undef", []),
ReplyTo ! {'EXIT', self(), undef, 0};
- exit:{skipped, Reason} ->
+ exit:{skip, Reason} ->
%% p("do_eval -> exit - skipped"
%% "~n Reason: ~p", [Reason]),
T2 = os:timestamp(),
Time = timer:now_diff(T2, T1),
display_tc_time(Time),
display_system_info("after (skipped)", Mod, Fun),
- ReplyTo ! {'EXIT', self(), {skipped, Reason}, Time};
+ ReplyTo ! {'EXIT', self(), {skip, Reason}, Time};
exit:{suite_failed, Reason} ->
%% p("do_eval -> exit - suite-failed"
%% "~n Reason: ~p", [Reason]),
@@ -616,9 +616,9 @@ display_result(Res) when is_list(Res) ->
Ok = [{MF, Time} || {ok, MF, _, Time} <- Res],
Nyi = [MF || {nyi, MF, _, _Time} <- Res],
SkippedGrps = [{{M,G}, Reason} ||
- {skipped, {M, {group, G}}, Reason, _Time} <- Res],
+ {skip, {M, {group, G}}, Reason, _Time} <- Res],
SkippedCases = [{MF, Reason} ||
- {skipped, {_M, F} = MF, Reason, _Time} <- Res,
+ {skip, {_M, F} = MF, Reason, _Time} <- Res,
is_atom(F)],
FailedGrps = [{{M,G}, Reason} ||
{failed, {M, {group, G}}, Reason, _Time} <- Res],
@@ -730,15 +730,18 @@ log(Format, Args, Mod, Line) ->
[self(), Mod, Line] ++ Args)
end.
+skip(Reason) ->
+ exit({skip, Reason}).
+
skip(Actual, File, Line) ->
- log("Skipping test case~n", [], File, Line),
- String = lists:flatten(io_lib:format("Skipping test case ~p(~p): ~p~n",
- [File, Line, Actual])),
- exit({skipped, String}).
+ log("Skipping test case: ~p~n", [Actual], File, Line),
+ String = f("~p(~p): ~p~n", [File, Line, Actual]),
+ skip(String).
fatal_skip(Actual, File, Line) ->
error(Actual, File, Line),
- exit({skipped, {fatal, Actual, File, Line}}).
+ skip({fatal, Actual, File, Line}).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -750,7 +753,8 @@ flush() ->
after 1000 ->
[]
end.
-
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Check if process is alive and kicking
still_alive(Pid) ->
@@ -988,11 +992,14 @@ node_to_name_and_host(Node) ->
start_nodes([Node | Nodes], File, Line) ->
case net_adm:ping(Node) of
pong ->
+ p("node ~p already running", [Node]),
start_nodes(Nodes, File, Line);
pang ->
[Name, Host] = node_to_name_and_host(Node),
+ p("try start node ~p", [Node]),
case slave:start_link(Host, Name) of
{ok, NewNode} when NewNode =:= Node ->
+ p("node ~p started - now set path, cwd and sync", [Node]),
Path = code:get_path(),
{ok, Cwd} = file:get_cwd(),
true = rpc:call(Node, code, set_path, [Path]),
@@ -1001,6 +1008,7 @@ start_nodes([Node | Nodes], File, Line) ->
{_, []} = rpc:multicall(global, sync, []),
start_nodes(Nodes, File, Line);
Other ->
+ p("failed starting node ~p: ~p", [Node, Other]),
fatal_skip({cannot_start_node, Node, Other}, File, Line)
end
end;
@@ -1014,4 +1022,4 @@ f(F, A) ->
lists:flatten(io_lib:format(F, A)).
p(F, A) ->
- io:format("~p~w:" ++ F ++ "~n", [self(), ?MODULE |A]).
+ io:format("~s ~p " ++ F ++ "~n", [?FTS(), self() | A]).
diff --git a/lib/megaco/test/megaco_test_lib.hrl b/lib/megaco/test/megaco_test_lib.hrl
index 409f8d52e5..546ecaab9a 100644
--- a/lib/megaco/test/megaco_test_lib.hrl
+++ b/lib/megaco/test/megaco_test_lib.hrl
@@ -32,8 +32,6 @@
-define(ERROR(Reason),
megaco_test_lib:error(Reason, ?MODULE, ?LINE)).
--define(F(FMT, ARGS), lists:flatten(io_lib:format(FMT, ARGS))).
-
-define(OS_BASED_SKIP(Skippable),
megaco_test_lib:os_based_skip(Skippable)).
@@ -83,7 +81,10 @@
-define(SLEEP(MSEC), megaco_test_lib:sleep(MSEC)).
-define(HOURS(T), megaco_test_lib:hours(T)).
--define(MINUTES(T), megaco_test_lib:minutes(T)).
--define(SECONDS(T), megaco_test_lib:seconds(T)).
+-define(MINS(T), megaco_test_lib:minutes(T)).
+-define(MINUTES(T), ?MINS(T)).
+-define(SECS(T), megaco_test_lib:seconds(T)).
+-define(SECONDS(T), ?SECS(T)).
-define(FTS(), megaco:format_timestamp(erlang:timestamp())).
-
+-define(FTS(TS), megaco:format_timestamp(TS)).
+-define(F(F,A), lists:flatten(io_lib:format(F, A))).
diff --git a/lib/megaco/test/megaco_test_megaco_generator.erl b/lib/megaco/test/megaco_test_megaco_generator.erl
index 8a37fa33fe..4e0f2e334c 100644
--- a/lib/megaco/test/megaco_test_megaco_generator.erl
+++ b/lib/megaco/test/megaco_test_megaco_generator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -118,7 +118,7 @@ init([]) ->
%% ----- instruction parser -----
handle_parse({debug, Debug} = Instruction, State)
- when (Debug == true) orelse (Debug == false) ->
+ when is_boolean(Debug) ->
{ok, Instruction, State};
handle_parse({expect_nothing, To} = Instruction, State)
@@ -126,9 +126,9 @@ handle_parse({expect_nothing, To} = Instruction, State)
{ok, Instruction, State};
handle_parse({megaco_trace, Level} = Instruction, State)
- when (Level == disable) orelse
- (Level == max) orelse
- (Level == min) orelse
+ when (Level =:= disable) orelse
+ (Level =:= max) orelse
+ (Level =:= min) orelse
is_integer(Level) ->
{ok, Instruction, State};
@@ -1096,11 +1096,10 @@ handle_megaco_callback_reply(_, _, _, _) ->
%%----------------------------------------------------------------------
random_init() ->
- {A,B,C} = now(),
- random:seed(A,B,C).
+ ok.
random(N) ->
- random:uniform(N).
+ rand:uniform(N).
get_config(Key, Opts) ->
diff --git a/lib/megaco/test/megaco_test_mg.erl b/lib/megaco/test/megaco_test_mg.erl
index d6a9a8c314..38883c94f0 100644
--- a/lib/megaco/test/megaco_test_mg.erl
+++ b/lib/megaco/test/megaco_test_mg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -79,7 +79,10 @@
reply_counter = 0,
mload_info = undefined,
parent = undefined,
- dsi_timer}).
+ dsi_timer,
+ evs = []}).
+
+-define(EVS_MAX, 10).
%%% --------------------------------------------------------------------
@@ -364,7 +367,7 @@ mg(Parent, Verbosity, Config) ->
MG = #mg{parent = Parent, mid = Mid, dsi_timer = DSITimer},
i("mg -> started"),
put(verbosity, Verbosity),
- case (catch loop(MG)) of
+ case (catch loop(evs(MG, started))) of
{'EXIT', normal} ->
exit(normal);
{'EXIT', Reason} ->
@@ -438,12 +441,12 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
{display_system_info, Time} ->
display_system_info(S#mg.mid),
NewTimer = create_timer(Time, display_system_info),
- loop(S#mg{dsi_timer = NewTimer});
+ loop(evs(S#mg{dsi_timer = NewTimer}, {dsi, Time}));
{verbosity, V, Parent} ->
i("loop -> received new verbosity: ~p", [V]),
put(verbosity,V),
- loop(S);
+ loop(evs(S, {verb, V}));
{stop, Parent} ->
@@ -453,7 +456,7 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
Res = do_stop(Mid),
d("loop -> stop result: ~p", [Res]),
server_reply(Parent, stopped, {ok, Res}),
- exit(normal);
+ done(evs(S, stop), normal);
{{enable_test_code, Tag, Fun}, Parent} ->
i("loop -> enable_test_code: ~p, ~p", [Tag, Fun]),
@@ -463,52 +466,52 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
"~n ets:tab2list(megaco_test_data): ~p",
[Reply,ets:tab2list(megaco_test_data)]),
server_reply(Parent, enable_test_code_reply, Reply),
- loop(S);
+ loop(evs(S, {enable_test_code, Tag}));
{{encode_ar_first, EAF}, Parent} ->
i("loop -> encode_ar_first: ~p", [EAF]),
{Reply, S1} = handle_encode_ar_first(S, EAF),
server_reply(Parent, encode_ar_first_reply, Reply),
- loop(S1#mg{encode_ar_first = EAF});
+ loop(evs(S1#mg{encode_ar_first = EAF}, {enc_arf, EAF}));
%% Give me statistics
{statistics, Parent} ->
i("loop -> got request for statistics", []),
Stats = do_get_statistics(Mid),
server_reply(Parent, statistics_reply, {ok, Stats}),
- loop(S);
+ loop(evs(S, stats));
{reset_stats, Parent} ->
i("loop -> got request to reset stats counters", []),
do_reset_stats(Mid),
server_reply(Parent, reset_stats_ack, ok),
- loop(S);
+ loop(evs(S, rst_stats));
{{user_info, Tag}, Parent} ->
i("loop -> got user_info request for ~w", [Tag]),
Res = do_get_user_info(Mid, Tag),
d("loop -> Res: ~p", [Res]),
server_reply(Parent, user_info_ack, Res),
- loop(S);
+ loop(evs(S, {ui, Tag}));
{{update_user_info, Tag, Val}, Parent} ->
i("loop -> got update_user_info: ~w -> ~p", [Tag, Val]),
Res = do_update_user_info(Mid, Tag, Val),
d("loop -> Res: ~p", [Res]),
server_reply(Parent, update_user_info_ack, Res),
- loop(S);
+ loop(evs(S, {uui, {Tag, Val}}));
{{conn_info, Tag}, Parent} ->
i("loop -> got conn_info request for ~w", [Tag]),
Res = do_get_conn_info(Mid, Tag),
server_reply(Parent, conn_info_ack, Res),
- loop(S);
+ loop(evs(S, {ci, Tag}));
{{update_conn_info, Tag, Val}, Parent} ->
i("loop -> got update_conn_info: ~w -> ~p", [Tag, Val]),
Res = do_update_conn_info(Mid, Tag, Val),
server_reply(Parent, update_conn_info_ack, Res),
- loop(S);
+ loop(evs(S, {uci, {Tag, Val}}));
%% Do a service change
@@ -526,28 +529,28 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
server_reply(Parent, service_change_reply, Error),
S
end,
- loop(S1);
+ loop(evs(S1, svc_ch));
{{group_requests, N}, Parent} when N > 0 ->
i("loop -> received group_requests ~p", [N]),
Reply = {ok, S#mg.group_size},
server_reply(Parent, group_requests_reply, Reply),
- loop(S#mg{group_size = N});
+ loop(evs(S#mg{group_size = N}, {grp_reqs, N}));
{{ack_info, To}, Parent} ->
i("loop -> received request to inform about received ack's ", []),
- loop(S#mg{ack_info = To});
+ loop(evs(S#mg{ack_info = To}, {acki, To}));
{{rep_info, To}, Parent} ->
i("loop -> received request to inform about received rep's ", []),
- loop(S#mg{rep_info = To});
+ loop(evs(S#mg{rep_info = To}, {repi, To}));
%% Make a sync-call
{notify_request, Parent} ->
i("loop -> received request to send notify request ", []),
{Res, S1} = do_handle_notify_request(S),
d("loop -> notify request result: ~p", [Res]),
- loop(S1);
+ loop(evs(S1, not_req));
%% sync-call complete
{notify_request_complete, NotifyReply, Pid} ->
@@ -556,7 +559,7 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
"~n NotifyReply: ~p",
[Pid, NotifyReply]),
server_reply(Parent, notify_request_reply, NotifyReply),
- loop(S#mg{req_handler = undefined});
+ loop(evs(S#mg{req_handler = undefined}, {not_reqc, NotifyReply}));
%% cancel requests
@@ -564,14 +567,14 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
i("loop -> received request to cancel (all) megaco requests ", []),
Res = do_cancel_requests(Mid, Reason),
server_reply(Parent, cancel_request_reply, Res),
- loop(S);
+ loop(evs(S, {creq, Reason}));
%% Apply multi-load
{apply_multi_load, {NL, NR}, Parent} ->
i("loop -> received apply_multi_load request: ~w, ~w", [NL, NR]),
S1 = start_loaders(S, NL, NR),
- loop(S1);
+ loop(evs(S1, {apply_mload, {NL, NR}}));
%% Apply some load
@@ -587,12 +590,12 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
server_reply(Parent, apply_load_ack, Error),
S
end,
- loop(S1);
+ loop(evs(S1, {apply_load, Times}));
{apply_load_timeout, _} ->
d("loop -> received apply_load timeout", []),
S1 = do_apply_load(S),
- loop(S1);
+ loop(evs(S1, apply_loadto));
%% Megaco callback messages
@@ -604,22 +607,35 @@ loop(#mg{parent = Parent, mid = Mid} = S) ->
{Reply, S1} = handle_megaco_request(S, Request),
d("loop -> send (megaco callback) request reply: ~n~p", [Reply]),
From ! {reply, Reply, self()},
- loop(S1);
+ loop(evs(S1, {req, {Request, Mid, From}}));
{'EXIT', Pid, Reason} ->
- i("loop -> received exit signal from ~p: ~n~p", [Pid, Reason]),
+ i("loop -> received exit signal from ~p: "
+ "~n ~p", [Pid, Reason]),
S1 = handle_exit(S, Pid, Reason),
- loop(S1);
+ loop(evs(S1, {exit, {Pid, Reason}}));
Invalid ->
error_msg("received invalid request: ~n~p", [Invalid]),
- loop(S)
+ loop(evs(S, {invalid, Invalid}))
end.
+evs(#mg{evs = EVS} = S, Ev) when (length(EVS) < ?EVS_MAX) ->
+ S#mg{evs = [{?FTS(), Ev}|EVS]};
+evs(#mg{evs = EVS} = S, Ev) ->
+ S#mg{evs = [{?FTS(), Ev}|lists:droplast(EVS)]}.
+
+done(#mg{evs = EVS}, Reason) ->
+ info_msg("Exiting with latest event(s): "
+ "~n ~p"
+ "~n", [EVS]),
+ exit(Reason).
+
+
handle_encode_ar_first(#mg{encode_ar_first = Old} = MG, New)
when (New =:= true) orelse (New =:= false) ->
{{ok, Old}, MG#mg{encode_ar_first = New}};
@@ -776,7 +792,7 @@ do_service_change(#mg{state = State} = MG) ->
{{error, {invalid_state, State}}, MG}.
do_service_change(ConnHandle, Method, EAF, Reason) ->
- d("sending service change using:"
+ d("send service change using:"
"~n ConnHandle: ~p"
"~n Method: ~p"
"~n EAF: ~p"
@@ -844,10 +860,10 @@ loader_main(EAF, N, CH) ->
-handle_exit(#mg{parent = Pid}, Pid, Reason) ->
+handle_exit(#mg{parent = Pid} = S, Pid, Reason) ->
error_msg("received exit from the parent:"
"~n ~p", [Reason]),
- exit({parent_terminated, Reason});
+ done(S, {parent_terminated, Reason});
handle_exit(#mg{parent = Parent, req_handler = Pid} = MG, Pid, Reason) ->
error_msg("received unexpected exit from the request handler:"
@@ -1423,6 +1439,7 @@ sleep(X) ->
receive after X -> ok end.
+info_msg(F,A) -> error_logger:info_msg("MG: " ++ F ++ "~n",A).
error_msg(F,A) -> error_logger:error_msg("MG: " ++ F ++ "~n",A).
@@ -1536,37 +1553,28 @@ print(Severity, Verbosity, P, F, A) ->
print(true, P, F, A) ->
io:format("*** [~s] ~s ~p ~s ***"
"~n " ++ F ++ "~n~n",
- [format_timestamp(now()), P, self(), get(sname) | A]);
+ [?FTS(), P, self(), get(sname) | A]);
print(_, _, _, _) ->
ok.
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
random_init() ->
- {A,B,C} = now(),
- random:seed(A,B,C).
+ ok.
random() ->
random(50).
random(N) ->
- random:uniform(N).
+ rand:uniform(N).
display_system_info(Mid) ->
display_system_info(Mid, "").
display_system_info(Mid, Pre) ->
- TimeStr = format_timestamp(now()),
+ TimeStr = ?FTS(),
MibStr = lists:flatten(io_lib:format("~p ", [Mid])),
megaco_test_lib:display_system_info(MibStr ++ Pre ++ TimeStr).
diff --git a/lib/megaco/test/megaco_test_mgc.erl b/lib/megaco/test/megaco_test_mgc.erl
index 045bc7c9fd..a9027ca68e 100644
--- a/lib/megaco/test/megaco_test_mgc.erl
+++ b/lib/megaco/test/megaco_test_mgc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -75,7 +75,10 @@
abort_info = undefined,
req_info = undefined,
mg = [],
- dsi_timer}).
+ dsi_timer,
+ evs = []}).
+
+-define(EVS_MAX, 10).
%%% ------------------------------------------------------------------
@@ -297,7 +300,7 @@ mgc(Parent, Verbosity, Config) ->
dsi_timer = DSITimer},
i("mgc -> started"),
display_system_info("at start "),
- loop(S)
+ loop(evs(S, started))
end.
init(Config) ->
@@ -359,7 +362,7 @@ loop(S) ->
{display_system_info, Time} ->
display_system_info(S#mgc.mid),
NewTimer = create_timer(Time, display_system_info),
- loop(S#mgc{dsi_timer = NewTimer});
+ loop(evs(S#mgc{dsi_timer = NewTimer}, {dsi, Time}));
{stop, Parent} when S#mgc.parent =:= Parent ->
i("loop -> stopping", []),
@@ -371,7 +374,7 @@ loop(S) ->
application:stop(megaco),
i("loop -> stopped", []),
server_reply(Parent, stopped, ok),
- exit(normal);
+ done(evs(S, stop), normal);
{{disconnect, Reason}, Parent} when S#mgc.parent == Parent ->
i("loop -> disconnecting", []),
@@ -379,22 +382,22 @@ loop(S) ->
[Conn|_] = megaco:user_info(Mid, connections),
Res = megaco:disconnect(Conn, {self(), Reason}),
server_reply(Parent, disconnected, Res),
- loop(S);
+ loop(evs(S, {disconnect, Reason}));
{{update_user_info, Tag, Val}, Parent} when S#mgc.parent == Parent ->
i("loop -> got update_user_info: ~w -> ~p", [Tag, Val]),
Res = (catch megaco:update_user_info(S#mgc.mid, Tag, Val)),
d("loop -> Res: ~p", [Res]),
server_reply(Parent, update_user_info_ack, Res),
- loop(S);
-
- {{user_info, Tag}, Parent} when S#mgc.parent == Parent ->
- i("loop -> got user_info request for ~w", [Tag]),
- Res = (catch megaco:user_info(S#mgc.mid, Tag)),
- d("loop -> Res: ~p", [Res]),
- server_reply(Parent, user_info_ack, Res),
- loop(S);
-
+ loop(evs(S, {uui, {Tag, Val}}));
+
+ {{user_info, Tag}, Parent} when S#mgc.parent == Parent ->
+ i("loop -> got user_info request for ~w", [Tag]),
+ Res = (catch megaco:user_info(S#mgc.mid, Tag)),
+ d("loop -> Res: ~p", [Res]),
+ server_reply(Parent, user_info_ack, Res),
+ loop(evs(S, {ui, Tag}));
+
{{update_conn_info, Tag, Val}, Parent} when S#mgc.parent == Parent ->
i("loop -> got update_conn_info: ~w -> ~p", [Tag, Val]),
Conns = megaco:user_info(S#mgc.mid, connections),
@@ -404,7 +407,7 @@ loop(S) ->
Res = lists:map(Fun, Conns),
d("loop -> Res: ~p", [Res]),
server_reply(Parent, update_conn_info_ack, Res),
- loop(S);
+ loop(evs(S, {uci, {Tag, Val}}));
{{conn_info, Tag}, Parent} when S#mgc.parent == Parent ->
i("loop -> got conn_info request for ~w", [Tag]),
@@ -415,11 +418,11 @@ loop(S) ->
Res = lists:map(Fun, Conns),
d("loop -> Res: ~p", [Res]),
server_reply(Parent, conn_info_ack, Res),
- loop(S);
+ loop(evs(S, {ci, Tag}));
%%
- {request_action, {Action, To}, Parent} when S#mgc.parent == Parent ->
+ {request_action, {Action, To}, Parent} when S#mgc.parent == Parent ->
i("loop -> got new request_action: ~p:~w", [Action,To]),
{Reply, S1} =
case lists:member(Action, ?valid_actions) of
@@ -432,7 +435,7 @@ loop(S) ->
{{error, {invalid_action, Action}}, S}
end,
server_reply(Parent, request_action_ack, Reply),
- loop(S1);
+ loop(evs(S1, {req_act, {Action, To}}));
%% Reset stats
@@ -440,7 +443,7 @@ loop(S) ->
i("loop -> got request to reset stats counters"),
do_reset_stats(S#mgc.mid),
server_reply(Parent, reset_stats_ack, ok),
- loop(S);
+ loop(evs(S, rst_stats));
%% Give me statistics
@@ -466,7 +469,7 @@ loop(S) ->
lists:map(GetTrans, megaco:user_info(Mid, connections)),
Reply = {ok, [{gen, Gen}, {trans, Trans}]},
server_reply(Parent, {statistics_reply, 1}, Reply),
- loop(S);
+ loop(evs(S, {stats, 1}));
{{statistics, 2}, Parent} when S#mgc.parent == Parent ->
@@ -477,7 +480,7 @@ loop(S) ->
UdpStats = get_trans_stats(UdpSup, megaco_udp),
Reply = {ok, [{gen, Gen}, {trans, [TcpStats, UdpStats]}]},
server_reply(Parent, {statistics_reply, 2}, Reply),
- loop(S);
+ loop(evs(S, {stats, 2}));
%% Megaco callback messages
@@ -487,28 +490,28 @@ loop(S) ->
{Reply, S1} = handle_megaco_request(Request, S),
d("loop -> send request reply: ~n~p", [Reply]),
reply(From, Reply),
- loop(S1);
+ loop(evs(S1, {req, Request}));
{ack_info, To, Parent} when S#mgc.parent == Parent ->
i("loop -> received request to inform about received ack's ", []),
- loop(S#mgc{ack_info = To});
+ loop(evs(S#mgc{ack_info = To}, {acki, To}));
{abort_info, To, Parent} when S#mgc.parent == Parent ->
i("loop -> received request to inform about received aborts ", []),
- loop(S#mgc{abort_info = To});
+ loop(evs(S#mgc{abort_info = To}, {abi, To}));
{req_info, To, Parent} when S#mgc.parent == Parent ->
i("loop -> received request to inform about received req's ", []),
- loop(S#mgc{req_info = To});
+ loop(evs(S#mgc{req_info = To}, {reqi, To}));
{verbosity, V, Parent} when S#mgc.parent == Parent ->
i("loop -> received new verbosity: ~p", [V]),
put(verbosity,V),
- loop(S);
+ loop(evs(S, {verb, V}));
{'EXIT', Pid, Reason} when S#mgc.tcp_sup =:= Pid ->
@@ -525,7 +528,7 @@ loop(S) ->
i("loop -> stopped", []),
StopReason = {error, {tcp_terminated, Pid, Reason}},
server_reply(S#mgc.parent, stopped, StopReason),
- exit(StopReason);
+ done(evs(S, {tcp_sup_exit, Reason}), StopReason);
{'EXIT', Pid, Reason} when S#mgc.udp_sup =:= Pid ->
@@ -542,15 +545,27 @@ loop(S) ->
i("loop -> stopped", []),
StopReason = {error, {udp_terminated, Pid, Reason}},
server_reply(S#mgc.parent, stopped, StopReason),
- exit(StopReason);
+ done(evs(S, {udp_sup_exit, Reason}), StopReason);
Invalid ->
i("loop -> received invalid request: ~p", [Invalid]),
- loop(S)
+ loop(evs(S, {invalid, Invalid}))
end.
+evs(#mgc{evs = EVS} = S, Ev) when (length(EVS) < ?EVS_MAX) ->
+ S#mgc{evs = [{?FTS(), Ev}|EVS]};
+evs(#mgc{evs = EVS} = S, Ev) ->
+ S#mgc{evs = [{?FTS(), Ev}|lists:droplast(EVS)]}.
+
+done(#mgc{evs = EVS}, Reason) ->
+ info_msg("Exiting with latest event(s): "
+ "~n ~p"
+ "~n", [EVS]),
+ exit(Reason).
+
+
do_reset_stats(Mid) ->
megaco:reset_stats(),
do_reset_trans_stats(megaco:user_info(Mid, connections), []).
@@ -825,10 +840,10 @@ handle_megaco_request({handle_trans_ack, CH, PV, AS, AD},
handle_megaco_request({handle_trans_ack, CH, PV, AS, AD}, S) ->
d("handle_megaco_request(handle_trans_ack) -> entry with"
- "~n CH: ~p"
- "~n PV: ~p"
- "~n AS: ~p"
- "~n AD: ~p", [CH, PV, AS, AD]),
+ "~n Conn Handle: ~p"
+ "~n Prot Version: ~p"
+ "~n Ack Status: ~p"
+ "~n Ack Data: ~p", [CH, PV, AS, AD]),
{ok, S};
handle_megaco_request({handle_unexpected_trans, CH, PV, TR}, S) ->
@@ -1090,6 +1105,7 @@ sleep(X) ->
receive after X -> ok end.
+info_msg(F,A) -> error_logger:info_msg("MGC: " ++ F ++ "~n",A).
error_msg(F,A) -> error_logger:error_msg("MGC: " ++ F ++ "~n",A).
@@ -1153,18 +1169,17 @@ get_conf(Key, Config, Default) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
random_init() ->
- {A,B,C} = now(),
- random:seed(A,B,C).
+ ok.
random(N) ->
- random:uniform(N).
+ rand:uniform(N).
display_system_info(Mid) ->
display_system_info(Mid, "").
display_system_info(Mid, Pre) ->
- TimeStr = format_timestamp(now()),
+ TimeStr = ?FTS(),
MibStr = lists:flatten(io_lib:format("~p ", [Mid])),
megaco_test_lib:display_system_info(MibStr ++ Pre ++ TimeStr).
@@ -1209,14 +1224,6 @@ print(_, _, _, _) ->
print(P, F, A) ->
io:format("*** [~s] ~s ~p ~s ***"
"~n " ++ F ++ "~n~n",
- [format_timestamp(now()), P, self(), get(sname) | A]).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
+ [?FTS(), P, self(), get(sname) | A]).
+
diff --git a/lib/megaco/test/megaco_timer_test.erl b/lib/megaco/test/megaco_timer_test.erl
index d3e8e27636..84c314d8ed 100644
--- a/lib/megaco/test/megaco_timer_test.erl
+++ b/lib/megaco/test/megaco_timer_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -362,6 +362,8 @@ integer_timer_start_and_stop(Config) when is_list(Config) ->
case tmr_stop(Ref) of
ok ->
ok;
+ {ok, _} ->
+ ok;
CancelRes ->
?SKIP({cancel_failed, CancelRes})
end
diff --git a/lib/megaco/test/megaco_trans_test.erl b/lib/megaco/test/megaco_trans_test.erl
index fb44a3c6e6..37bc134c8d 100644
--- a/lib/megaco/test/megaco_trans_test.erl
+++ b/lib/megaco/test/megaco_trans_test.erl
@@ -295,7 +295,7 @@ multi_ack_timeout(doc) ->
[];
multi_ack_timeout(Config) when is_list(Config) ->
%% <CONDITIONAL-SKIP>
- Skippable = [win32, {unix, [darwin, linux]}],
+ Skippable = [win32, {unix, [darwin, linux, sunos]}], % Is there any left?
Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
?NON_PC_TC_MAYBE_SKIP(Config, Condition),
%% </CONDITIONAL-SKIP>
@@ -9247,10 +9247,10 @@ await_ack(User, N, Timeout, Expected) when (N > 0) andalso is_integer(Timeout) -
T = tim(),
receive
{ack_received, User, Expected} ->
- d("await_ack -> received another ack"),
+ d("await_ack -> received another expected ack"),
await_ack(User, N-1, Timeout - (tim() - T), Expected);
{ack_received, User, UnExpected} ->
- e("await_ack -> unexpected ack result: ~p", [UnExpected]),
+ e("await_ack -> received unexpected ack result: ~p", [UnExpected]),
exit({unexpected_ack_result, UnExpected, Expected})
after Timeout ->
exit({await_ack_timeout, N})
@@ -9266,35 +9266,6 @@ await_ack(User, N, infinity, Expected) when N > 0 ->
exit({unexpected_ack_result, UnExpected, Expected})
end.
-%% await_req(_User, 0, Timeout) ->
-%% d("await_req -> done when Timeout = ~p", [Timeout]),
-%% ok;
-%% await_req(User, N, Timeout) when (N > 0) andalso is_integer(Timeout) ->
-%% d("await_req -> entry with N: ~p, Timeout: ~p", [N,Timeout]),
-%% T = tim(),
-%% receive
-%% {req_received, User, ARs} ->
-%% d("await_req -> received req(s) when N = ~w", [N]),
-%% N1 = await_req1(N, ARs),
-%% await_req(User, N1, Timeout - (tim() - T))
-%% after Timeout ->
-%% exit({await_req_timeout, N})
-%% end;
-%% await_req(User, N, infinity) when N > 0 ->
-%% d("await_req -> entry with N: ~p", [N]),
-%% receive
-%% {req_received, User, ARs} ->
-%% d("await_req -> received req(s) when N = ~2",[N]),
-%% N1 = await_req1(N, ARs),
-%% await_req(User, N1, infinity)
-%% end.
-
-%% await_req1(N, []) when N >= 0 ->
-%% N;
-%% await_req1(N, [AR|ARs]) when (N > 0) andalso is_record(AR, 'ActionRequest') ->
-%% await_req1(N-1, ARs);
-%% await_req1(N, ARs) ->
-%% exit({unexpected_req_result, N, ARs}).
tim() ->
{A,B,C} = erlang:timestamp(),
diff --git a/lib/megaco/test/megaco_udp_test.erl b/lib/megaco/test/megaco_udp_test.erl
index cc03ec733a..39ff44709e 100644
--- a/lib/megaco/test/megaco_udp_test.erl
+++ b/lib/megaco/test/megaco_udp_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1211,23 +1211,14 @@ p(F, A) ->
p(S, F, A) when is_list(S) ->
io:format("*** [~s] ~p ~s ***"
"~n " ++ F ++ "~n",
- [format_timestamp(now()), self(), S | A]);
+ [?FTS(), self(), S | A]);
p(_S, F, A) ->
io:format("*** [~s] ~p ~s *** "
"~n " ++ F ++ "~n",
- [format_timestamp(now()), self(), "undefined" | A]).
+ [?FTS(), self(), "undefined" | A]).
ms() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
+ erlang:monotonic_time(milli_seconds).
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
diff --git a/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
index ffbbdadec0..968e89a745 100644
--- a/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
@@ -295,7 +295,7 @@ ok</pre>
if the log is large. Notice that the <c>Mnesia</c> system
continues to operate during log dumps.</p>
<p>By default <c>Mnesia</c> either dumps the log whenever
- 100 records have
+ 1000 records have
been written in the log or when three minutes have passed.
This is controlled by the two application parameters
<c>-mnesia dump_log_write_threshold WriteOperations</c> and
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 882de0d613..0f221b0c1f 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -331,35 +331,39 @@ release_schema_commit_lock() ->
%% Special for preparation of add table copy
get_network_copy(Tid, Tab, Cs) ->
-% We can't let the controller queue this one
-% because that may cause a deadlock between schema_operations
-% and initial tableloadings which both takes schema locks.
-% But we have to get copier_done msgs when the other side
-% goes down.
- call({add_other, self()}),
- Reason = {dumper,{add_table_copy, Tid}},
- Work = #net_load{table = Tab,reason = Reason,cstruct = Cs},
- %% I'll need this cause it's linked trough the subscriber
- %% might be solved by using monitor in subscr instead.
- process_flag(trap_exit, true),
- Load = load_table_fun(Work),
- Res = ?CATCH(Load()),
- process_flag(trap_exit, false),
- call({del_other, self()}),
- case Res of
- #loader_done{is_loaded = true} ->
- Tab = Res#loader_done.table_name,
- case Res#loader_done.needs_announce of
- true ->
- i_have_tab(Tab);
- false ->
- ignore
- end,
- Res#loader_done.reply;
- #loader_done{} ->
- Res#loader_done.reply;
- Else ->
- {not_loaded, Else}
+ %% We can't let the controller queue this one
+ %% because that may cause a deadlock between schema_operations
+ %% and initial tableloadings which both takes schema locks.
+ %% But we have to get copier_done msgs when the other side
+ %% goes down.
+ case call({add_other, self()}) of
+ ok ->
+ Reason = {dumper,{add_table_copy, Tid}},
+ Work = #net_load{table = Tab,reason = Reason,cstruct = Cs},
+ %% I'll need this cause it's linked trough the subscriber
+ %% might be solved by using monitor in subscr instead.
+ process_flag(trap_exit, true),
+ Load = load_table_fun(Work),
+ Res = ?CATCH(Load()),
+ process_flag(trap_exit, false),
+ call({del_other, self()}),
+ case Res of
+ #loader_done{is_loaded = true} ->
+ Tab = Res#loader_done.table_name,
+ case Res#loader_done.needs_announce of
+ true ->
+ i_have_tab(Tab);
+ false ->
+ ignore
+ end,
+ Res#loader_done.reply;
+ #loader_done{} ->
+ Res#loader_done.reply;
+ Else ->
+ {not_loaded, Else}
+ end;
+ {error, Else} ->
+ {not_loaded, Else}
end.
%% This functions is invoked from the dumper
@@ -772,6 +776,18 @@ handle_call({unannounce_add_table_copy, [Tab, Node], From}, ReplyTo, State) ->
noreply(State#state{early_msgs = [{call, Msg, undefined} | Msgs]})
end;
+handle_call({add_other, Who}, _From, State = #state{others=Others0, schema_is_merged=SM}) ->
+ case SM of
+ true ->
+ Others = [Who|Others0],
+ {reply, ok, State#state{others=Others}};
+ false ->
+ {reply, {error, {not_active,schema,node()}}, State}
+ end;
+handle_call({del_other, Who}, _From, State = #state{others=Others0}) ->
+ Others = lists:delete(Who, Others0),
+ {reply, ok, State#state{others=Others}};
+
handle_call(Msg, From, State) when State#state.schema_is_merged /= true ->
%% Buffer early messages
Msgs = State#state.early_msgs,
@@ -803,13 +819,6 @@ handle_call({block_table, [Tab], From}, _Dummy, State) ->
handle_call({check_w2r, _Node, Tab}, _From, State) ->
{reply, val({Tab, where_to_read}), State};
-handle_call({add_other, Who}, _From, State = #state{others=Others0}) ->
- Others = [Who|Others0],
- {reply, ok, State#state{others=Others}};
-handle_call({del_other, Who}, _From, State = #state{others=Others0}) ->
- Others = lists:delete(Who, Others0),
- {reply, ok, State#state{others=Others}};
-
handle_call(Msg, _From, State) ->
error("~p got unexpected call: ~tp~n", [?SERVER_NAME, Msg]),
noreply(State).
diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl
index f68626413e..0222c5b1a0 100644
--- a/lib/mnesia/src/mnesia_locker.erl
+++ b/lib/mnesia/src/mnesia_locker.erl
@@ -774,10 +774,12 @@ do_sticky_lock(Tid, Store, {Tab, Key} = Oid, Lock) ->
N = node(),
receive
{?MODULE, N, granted} ->
+ ?ets_insert(Store, {sticky, true}),
?ets_insert(Store, {{locks, Tab, Key}, write}),
[?ets_insert(Store, {nodes, Node}) || Node <- WNodes],
granted;
{?MODULE, N, {granted, Val}} -> %% for rwlocks
+ ?ets_insert(Store, {sticky, true}),
case opt_lookup_in_client(Val, Oid, write) of
C = #cyclic{} ->
exit({aborted, C});
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index 4cfe16dec0..4e50b46da8 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -83,9 +83,9 @@
going_down = [], tm_started = false, early_connects = [],
connecting, mq = [], remote_node_status = []}).
--define(current_protocol_version, {8,3}).
+-define(current_protocol_version, {8,4}).
--define(previous_protocol_version, {8,2}).
+-define(previous_protocol_version, {8,3}).
start() ->
gen_server:start_link({local, ?MODULE}, ?MODULE,
@@ -196,7 +196,7 @@ protocol_version() ->
%% A sorted list of acceptable protocols the
%% preferred protocols are first in the list
acceptable_protocol_versions() ->
- [protocol_version(), ?previous_protocol_version, {8,1}].
+ [protocol_version(), ?previous_protocol_version].
needs_protocol_conversion(Node) ->
case {?catch_val({protocol, Node}), protocol_version()} of
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index ef38adca1e..d0f5d0e07b 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -697,7 +697,7 @@ schema_coordinator(Client, _Fun, undefined) ->
schema_coordinator(Client, Fun, Controller) when is_pid(Controller) ->
%% Do not trap exit in order to automatically die
%% when the controller dies
-
+ put(transaction_client, Client), %% debug
link(Controller),
unlink(Client),
@@ -730,7 +730,10 @@ api_list2cs(Other) ->
mnesia:abort({badarg, Other}).
vsn_cs2list(Cs) ->
- cs2list(need_old_cstructs(), Cs).
+ cs2list(Cs).
+
+cs2list(false, Cs) ->
+ cs2list(Cs).
cs2list(Cs) when is_record(Cs, cstruct) ->
Tags = record_info(fields, cstruct),
@@ -755,25 +758,6 @@ cs2list(Cs) when element(1, Cs) == cstruct, tuple_size(Cs) == 19 ->
cookie,version],
rec2list(Tags, Tags, 2, Cs).
-cs2list(false, Cs) ->
- cs2list(Cs);
-cs2list({8,3}, Cs) ->
- cs2list(Cs);
-cs2list({8,Minor}, Cs) when Minor =:= 2; Minor =:= 1 ->
- Orig = record_info(fields, cstruct),
- Tags = [name,type,ram_copies,disc_copies,disc_only_copies,
- load_order,access_mode,majority,index,snmp,local_content,
- record_name,attributes,
- user_properties,frag_properties,storage_properties,
- cookie,version],
- CsList = rec2list(Tags, Orig, 2, Cs),
- case proplists:get_value(index, CsList, []) of
- [] -> CsList;
- NewFormat ->
- OldFormat = [Pos || {Pos, _Pref} <- NewFormat],
- lists:keyreplace(index, 1, CsList, {index, OldFormat})
- end.
-
rec2list([index | Tags], [index|Orig], Pos, Rec) ->
Val = element(Pos, Rec),
[{index, lists:map(
@@ -796,19 +780,8 @@ rec2list([], _, _Pos, _Rec) ->
rec2list(Tags, [_|Orig], Pos, Rec) ->
rec2list(Tags, Orig, Pos+1, Rec).
-normalize_cs(Cstructs, Node) ->
- %% backward-compatibility hack; normalize before returning
- case need_old_cstructs([Node]) of
- false ->
- Cstructs;
- Version ->
- %% some other format
- [convert_cs(Version, Cs) || Cs <- Cstructs]
- end.
-
-convert_cs(Version, Cs) ->
- Fields = [Value || {_, Value} <- cs2list(Version, Cs)],
- list_to_tuple([cstruct|Fields]).
+normalize_cs(Cstructs, _Node) ->
+ Cstructs.
list2cs(List) ->
list2cs(List, get_ext_types()).
@@ -1864,11 +1837,7 @@ do_move_table(schema, _FromNode, _ToNode) ->
mnesia:abort({bad_type, schema});
do_move_table(Tab, FromNode, ToNode) when is_atom(FromNode), is_atom(ToNode) ->
TidTs = get_tid_ts_and_lock(schema, write),
- AnyOld = lists:any(fun(Node) -> mnesia_monitor:needs_protocol_conversion(Node) end,
- [ToNode|val({Tab, where_to_write})]),
- if AnyOld -> ignore; %% Leads to deadlock on old nodes
- true -> get_tid_ts_and_lock(Tab, write)
- end,
+ get_tid_ts_and_lock(Tab, write),
insert_schema_ops(TidTs, make_move_table(Tab, FromNode, ToNode));
do_move_table(Tab, FromNode, ToNode) ->
mnesia:abort({badarg, Tab, FromNode, ToNode}).
@@ -3438,15 +3407,14 @@ do_merge_schema(LockTabs0) ->
mnesia_lib:intersect(Ns,NeedsLock))
|| {T,Ns} <- LockTabs],
- NeedsConversion = need_old_cstructs(NeedsLock ++ LockedAlready),
{value, SchemaCs} = lists:keysearch(schema, #cstruct.name, Cstructs),
- SchemaDef = cs2list(NeedsConversion, SchemaCs),
+ SchemaDef = cs2list(false, SchemaCs),
%% Announce that Node is running
A = [{op, announce_im_running, node(), SchemaDef, Running, RemoteRunning}],
do_insert_schema_ops(Store, A),
%% Introduce remote tables to local node
- do_insert_schema_ops(Store, make_merge_schema(Node, NeedsConversion, Cstructs)),
+ do_insert_schema_ops(Store, make_merge_schema(Node, false, Cstructs)),
%% Introduce local tables to remote nodes
Tabs = val({schema, tables}),
@@ -3471,23 +3439,7 @@ do_merge_schema(LockTabs0) ->
end.
fetch_cstructs(Node) ->
- Convert = mnesia_monitor:needs_protocol_conversion(Node),
- case rpc:call(Node, mnesia_controller, get_remote_cstructs, []) of
- {cstructs, Cs0, RemoteRunning1} when Convert ->
- {cstructs, [list2cs(cs2list(Cs)) || Cs <- Cs0], RemoteRunning1};
- Result ->
- Result
- end.
-
-need_old_cstructs() ->
- need_old_cstructs(val({schema, where_to_write})).
-
-need_old_cstructs(Nodes) ->
- Filter = fun(Node) -> mnesia_monitor:needs_protocol_conversion(Node) end,
- case lists:filter(Filter, Nodes) of
- [] -> false;
- Ns -> lists:min([element(1, ?catch_val({protocol, Node})) || Node <- Ns])
- end.
+ rpc:call(Node, mnesia_controller, get_remote_cstructs, []).
tab_to_nodes(Tab) when is_atom(Tab) ->
Cs = val({Tab, cstruct}),
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index 8b79fca1d7..8a4113422a 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -26,7 +26,7 @@
init/1,
non_transaction/5,
transaction/6,
- commit_participant/5,
+ commit_participant/6,
dirty/2,
display_info/2,
do_update_op/3,
@@ -62,13 +62,14 @@
%% Format on coordinators is [{Tid, EtsTabList} .....
-record(prep, {protocol = sym_trans,
- %% async_dirty | sync_dirty | sym_trans | sync_sym_trans | asym_trans
+ %% async_dirty | sync_dirty | sym_trans | sync_sym_trans | asym_trans | sync_asym_trans
records = [],
prev_tab = [], % initiate to a non valid table name
prev_types,
prev_snmp,
types,
- majority = []
+ majority = [],
+ sync = false
}).
-record(participant, {tid, pid, commit, disc_nodes = [],
@@ -250,11 +251,13 @@ doit_loop(#state{coordinators=Coordinators,participants=Participants,supervisor=
mnesia_checkpoint:tm_enter_pending(Tid, DiscNs, RamNs),
Commit = new_cr_format(Commit0),
Pid =
- case Protocol of
- asym_trans when node(Tid#tid.pid) /= node() ->
- Args = [tmpid(From), Tid, Commit, DiscNs, RamNs],
+ if
+ node(Tid#tid.pid) =:= node() ->
+ error({internal_error, local_node});
+ Protocol =:= asym_trans orelse Protocol =:= sync_asym_trans ->
+ Args = [Protocol, tmpid(From), Tid, Commit, DiscNs, RamNs],
spawn_link(?MODULE, commit_participant, Args);
- _ when node(Tid#tid.pid) /= node() -> %% *_sym_trans
+ true -> %% *_sym_trans
reply(From, {vote_yes, Tid}),
nopid
end,
@@ -1190,7 +1193,15 @@ do_arrange(Tid, Store, RestoreKey, Prep, N) when RestoreKey == restore_op ->
P2 = Prep#prep{protocol = asym_trans, records = Recs2},
do_arrange(Tid, Store, ?ets_next(Store, RestoreKey), P2, N + 1);
do_arrange(_Tid, _Store, '$end_of_table', Prep, N) ->
- {N, Prep};
+ case Prep of
+ #prep{sync=true, protocol=asym_trans} ->
+ {N, Prep#prep{protocol=sync_asym_trans}};
+ _ ->
+ {N, Prep}
+ end;
+do_arrange(Tid, Store, sticky, Prep, N) ->
+ P2 = Prep#prep{sync=true},
+ do_arrange(Tid, Store, ?ets_next(Store, sticky), P2, N);
do_arrange(Tid, Store, IgnoredKey, Prep, N) -> %% locks, nodes ... local atoms...
do_arrange(Tid, Store, ?ets_next(Store, IgnoredKey), Prep, N).
@@ -1448,7 +1459,8 @@ multi_commit(sync_sym_trans, _Maj = [], Tid, CR, Store) ->
[{tid, Tid}, {outcome, Outcome}]),
Outcome;
-multi_commit(asym_trans, Majority, Tid, CR, Store) ->
+multi_commit(Protocol, Majority, Tid, CR, Store)
+ when Protocol =:= asym_trans; Protocol =:= sync_asym_trans ->
%% This more expensive commit protocol is used when
%% table definitions are changed (schema transactions).
%% It is also used when the involved tables are
@@ -1515,7 +1527,7 @@ multi_commit(asym_trans, Majority, Tid, CR, Store) ->
end,
Pending = mnesia_checkpoint:tm_enter_pending(Tid, DiscNs, RamNs),
?ets_insert(Store, Pending),
- {WaitFor, Local} = ask_commit(asym_trans, Tid, CR2, DiscNs, RamNs),
+ {WaitFor, Local} = ask_commit(Protocol, Tid, CR2, DiscNs, RamNs),
SchemaPrep = ?CATCH(mnesia_schema:prepare_commit(Tid, Local, {coord, WaitFor})),
{Votes, Pids} = rec_all(WaitFor, Tid, do_commit, []),
@@ -1563,38 +1575,38 @@ multi_commit(asym_trans, Majority, Tid, CR, Store) ->
%% Returns do_commit or {do_abort, Reason}
rec_acc_pre_commit([Pid | Tail], Tid, Store, Commit, Res, DumperMode,
- GoodPids, SchemaAckPids) ->
+ GoodPids, AckPids) ->
receive
{?MODULE, _, {acc_pre_commit, Tid, Pid, true}} ->
rec_acc_pre_commit(Tail, Tid, Store, Commit, Res, DumperMode,
- [Pid | GoodPids], [Pid | SchemaAckPids]);
+ [Pid | GoodPids], [Pid | AckPids]);
{?MODULE, _, {acc_pre_commit, Tid, Pid, false}} ->
rec_acc_pre_commit(Tail, Tid, Store, Commit, Res, DumperMode,
- [Pid | GoodPids], SchemaAckPids);
+ [Pid | GoodPids], AckPids);
{?MODULE, _, {acc_pre_commit, Tid, Pid}} ->
%% Kept for backwards compatibility. Remove after Mnesia 4.x
rec_acc_pre_commit(Tail, Tid, Store, Commit, Res, DumperMode,
- [Pid | GoodPids], [Pid | SchemaAckPids]);
+ [Pid | GoodPids], [Pid | AckPids]);
{?MODULE, _, {do_abort, Tid, Pid, _Reason}} ->
AbortRes = {do_abort, {bad_commit, node(Pid)}},
rec_acc_pre_commit(Tail, Tid, Store, Commit, AbortRes, DumperMode,
- GoodPids, SchemaAckPids);
+ GoodPids, AckPids);
{mnesia_down, Node} when Node == node(Pid) ->
AbortRes = {do_abort, {bad_commit, Node}},
?SAFE(Pid ! {Tid, AbortRes}), %% Tell him that he has died
rec_acc_pre_commit(Tail, Tid, Store, Commit, AbortRes, DumperMode,
- GoodPids, SchemaAckPids)
+ GoodPids, AckPids)
end;
-rec_acc_pre_commit([], Tid, Store, {Commit,OrigC}, Res, DumperMode, GoodPids, SchemaAckPids) ->
+rec_acc_pre_commit([], Tid, Store, {Commit,OrigC}, Res, DumperMode, GoodPids, AckPids) ->
D = Commit#commit.decision,
case Res of
do_commit ->
%% Now everybody knows that the others
%% has voted yes. We also know that
%% everybody are uncertain.
- prepare_sync_schema_commit(Store, SchemaAckPids),
+ prepare_sync_schema_commit(Store, AckPids),
tell_participants(GoodPids, {Tid, committed}),
D2 = D#decision{outcome = committed},
mnesia_recover:log_decision(D2),
@@ -1606,7 +1618,7 @@ rec_acc_pre_commit([], Tid, Store, {Commit,OrigC}, Res, DumperMode, GoodPids, Sc
do_commit(Tid, Commit, DumperMode),
?eval_debug_fun({?MODULE, rec_acc_pre_commit_done_commit},
[{tid, Tid}]),
- sync_schema_commit(Tid, Store, SchemaAckPids),
+ sync_schema_commit(Tid, Store, AckPids),
mnesia_locker:release_tid(Tid),
?MODULE ! {delete_transaction, Tid};
@@ -1623,6 +1635,7 @@ rec_acc_pre_commit([], Tid, Store, {Commit,OrigC}, Res, DumperMode, GoodPids, Sc
Res.
%% Note all nodes in case of mnesia_down mgt
+%% sync_schema_commit is (ab)used for sync_asym_trans as well.
prepare_sync_schema_commit(_Store, []) ->
ok;
prepare_sync_schema_commit(Store, [Pid | Pids]) ->
@@ -1648,17 +1661,17 @@ tell_participants([Pid | Pids], Msg) ->
tell_participants([], _Msg) ->
ok.
--spec commit_participant(_, _, _, _, _) -> no_return().
+-spec commit_participant(_, _, _, _, _, _) -> no_return().
%% Trap exit because we can get a shutdown from application manager
-commit_participant(Coord, Tid, Bin, DiscNs, RamNs) when is_binary(Bin) ->
+commit_participant(Protocol, Coord, Tid, Bin, DiscNs, RamNs) when is_binary(Bin) ->
process_flag(trap_exit, true),
Commit = binary_to_term(Bin),
- commit_participant(Coord, Tid, Bin, Commit, DiscNs, RamNs);
-commit_participant(Coord, Tid, C = #commit{}, DiscNs, RamNs) ->
+ commit_participant(Protocol, Coord, Tid, Bin, Commit, DiscNs, RamNs);
+commit_participant(Protocol, Coord, Tid, C = #commit{}, DiscNs, RamNs) ->
process_flag(trap_exit, true),
- commit_participant(Coord, Tid, C, C, DiscNs, RamNs).
+ commit_participant(Protocol, Coord, Tid, C, C, DiscNs, RamNs).
-commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
+commit_participant(Protocol, Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
?eval_debug_fun({?MODULE, commit_participant, pre}, [{tid, Tid}]),
try mnesia_schema:prepare_commit(Tid, C0, {part, Coord}) of
{Modified, C = #commit{}, DumperMode} ->
@@ -1683,8 +1696,9 @@ commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
mnesia_recover:log_decision(D#decision{outcome = unclear}),
?eval_debug_fun({?MODULE, commit_participant, pre_commit},
[{tid, Tid}]),
- Expect_schema_ack = C#commit.schema_ops /= [],
- reply(Coord, {acc_pre_commit, Tid, self(), Expect_schema_ack}),
+ ExpectAck = C#commit.schema_ops /= []
+ orelse Protocol =:= sync_asym_trans,
+ reply(Coord, {acc_pre_commit, Tid, self(), ExpectAck}),
%% Now we are vulnerable for failures, since
%% we cannot decide without asking others
@@ -1694,7 +1708,7 @@ commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
?eval_debug_fun({?MODULE, commit_participant, log_commit},
[{tid, Tid}]),
do_commit(Tid, C, DumperMode),
- case Expect_schema_ack of
+ case ExpectAck of
false -> ignore;
true -> reply(Coord, {schema_commit, Tid, self()})
end,
@@ -1978,7 +1992,7 @@ sync_send_dirty(Tid, [Head | Tail], Tab, WaitFor) ->
Res = do_dirty(Tid, Head),
{WF, Res};
true ->
- {?MODULE, Node} ! {self(), {sync_dirty, Tid, ext_format(Head), Tab}},
+ {?MODULE, Node} ! {self(), {sync_dirty, Tid, Head, Tab}},
sync_send_dirty(Tid, Tail, Tab, [Node | WaitFor])
end;
sync_send_dirty(_Tid, [], _Tab, WaitFor) ->
@@ -1997,11 +2011,11 @@ async_send_dirty(Tid, [Head | Tail], Tab, ReadNode, WaitFor, Res) ->
NewRes = do_dirty(Tid, Head),
async_send_dirty(Tid, Tail, Tab, ReadNode, WaitFor, NewRes);
ReadNode == Node ->
- {?MODULE, Node} ! {self(), {sync_dirty, Tid, ext_format(Head), Tab}},
+ {?MODULE, Node} ! {self(), {sync_dirty, Tid, Head, Tab}},
NewRes = {'EXIT', {aborted, {node_not_running, Node}}},
async_send_dirty(Tid, Tail, Tab, ReadNode, [Node | WaitFor], NewRes);
true ->
- {?MODULE, Node} ! {self(), {async_dirty, Tid, ext_format(Head), Tab}},
+ {?MODULE, Node} ! {self(), {async_dirty, Tid, Head, Tab}},
async_send_dirty(Tid, Tail, Tab, ReadNode, WaitFor, Res)
end;
async_send_dirty(_Tid, [], _Tab, _ReadNode, WaitFor, Res) ->
@@ -2058,24 +2072,20 @@ ask_commit(Protocol, Tid, [Head | Tail], DiscNs, RamNs, WaitFor, Local) ->
Node == node() ->
ask_commit(Protocol, Tid, Tail, DiscNs, RamNs, WaitFor, Head);
true ->
- CR = ext_format(Head),
- Msg = {ask_commit, Protocol, Tid, CR, DiscNs, RamNs},
+ Msg = {ask_commit, convert_old(Protocol, Node), Tid, Head, DiscNs, RamNs},
{?MODULE, Node} ! {self(), Msg},
ask_commit(Protocol, Tid, Tail, DiscNs, RamNs, [Node | WaitFor], Local)
end;
ask_commit(_Protocol, _Tid, [], _DiscNs, _RamNs, WaitFor, Local) ->
{WaitFor, Local}.
-ext_format(#commit{ext=[]}=CR) -> CR;
-ext_format(#commit{node=Node, ext=Ext}=CR) ->
+convert_old(sync_asym_trans, Node) ->
case mnesia_monitor:needs_protocol_conversion(Node) of
- true ->
- case lists:keyfind(snmp, 1, Ext) of
- false -> CR#commit{ext=[]};
- {snmp, List} -> CR#commit{ext=List}
- end;
- false -> CR
- end.
+ true -> asym_trans;
+ false -> sync_asym_trans
+ end;
+convert_old(Protocol, _) ->
+ Protocol.
new_cr_format(#commit{ext=[]}=Cr) -> Cr;
new_cr_format(#commit{ext=[{_,_}|_]}=Cr) -> Cr;
@@ -2304,7 +2314,7 @@ reconfigure_participants(_, []) ->
%% tell mnesia_tm on all involved nodes (including the local node)
%% about the outcome.
tell_outcome(Tid, Protocol, Node, CheckNodes, TellNodes) ->
- Outcome = mnesia_recover:what_happened(Tid, Protocol, CheckNodes),
+ Outcome = mnesia_recover:what_happened(Tid, proto(Protocol), CheckNodes),
case Outcome of
aborted ->
rpc:abcast(TellNodes, ?MODULE, {Tid,{do_abort, {mnesia_down, Node}}});
@@ -2313,6 +2323,9 @@ tell_outcome(Tid, Protocol, Node, CheckNodes, TellNodes) ->
end,
Outcome.
+proto(sync_asym_trans) -> asym_trans;
+proto(Proto) -> Proto.
+
do_stop(#state{coordinators = Coordinators}) ->
Msg = {mnesia_down, node()},
lists:foreach(fun({Tid, _}) -> Tid#tid.pid ! Msg end, gb_trees:to_list(Coordinators)),
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index 49bcec14af..c99158945d 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -29,7 +29,7 @@
-export([no_conflict/1, simple_queue_conflict/1,
advanced_queue_conflict/1, simple_deadlock_conflict/1,
advanced_deadlock_conflict/1, schema_deadlock/1, lock_burst/1,
- nasty/1, basic_sticky_functionality/1,
+ nasty/1, basic_sticky_functionality/1, sticky_sync/1,
unbound1/1, unbound2/1,
create_table/1, delete_table/1, move_table_copy/1,
add_table_index/1, del_table_index/1, transform_table/1,
@@ -71,7 +71,8 @@ groups() ->
advanced_deadlock_conflict, schema_deadlock, lock_burst,
{group, sticky_locks}, {group, unbound_locking},
{group, admin_conflict}, nasty]},
- {sticky_locks, [], [basic_sticky_functionality]},
+ {sticky_locks, [],
+ [basic_sticky_functionality,sticky_sync]},
{unbound_locking, [], [unbound1, unbound2]},
{admin_conflict, [],
[create_table, delete_table, move_table_copy,
@@ -594,9 +595,49 @@ get_held() ->
mnesia_locker ! {get_table, self(), mnesia_sticky_locks},
receive {mnesia_sticky_locks, Locks} -> Locks end.
+sticky_sync(suite) -> [];
+sticky_sync(Config) when is_list(Config) ->
+ %% BUG ERIERL-768
+ Nodes = [N1, N2] = ?acquire_nodes(2, Config),
+
+ mnesia:create_table(dc, [{type, ordered_set}, {disc_copies, Nodes}]),
+ mnesia:create_table(ec, [{type, ordered_set}, {ram_copies, [N2]}]),
+
+ TestFun =
+ fun(I) ->
+ %% In first transaction we initialise {dc, I} record with value 0
+ First = fun() ->
+ %% Do a lot of writes into ram copies table
+ %% which on the Slave in do_commit will be
+ %% processed first
+ lists:foreach(fun(J) -> ok = mnesia:write(ec, {ec, J, 0}, write) end,
+ lists:seq(1, 750)),
+ %% Then set initial value of {dc, I} record to 0 with sticky_write
+ mnesia:write(dc, {dc, I, 0}, sticky_write)
+ end,
+ ok = mnesia:activity(transaction, First),
+ %% In second transaction we set value of {dc, I} record to 1
+ Upd = fun() ->
+ %% Modify a single ram copies record with ensured lock grant
+ %% (key not used in previous transactions)
+ %% we use this second table only to force asym_trans protocol
+ mnesia:write(ec, {ec, 1001 + I, 0}, write),
+ %% And set final version of {dc, I} record to 1 with sticky_write
+ mnesia:write(dc, {dc, I, 1}, sticky_write)
+ end,
+ ok = mnesia:activity(transaction, Upd)
+ end,
+
+ %% Fill 1000 dc records. At the end all dc records should have value 1.
+ lists:foreach(TestFun, lists:seq(1,1000)),
+ io:format("Written, check content~n",[]),
+ All = fun() -> mnesia:select(dc, [ {{dc, '_', 0}, [] ,['$_']} ]) end,
+ ?match({atomic, []}, rpc:call(N1, mnesia, sync_transaction, [All])),
+ ?match({atomic, []}, rpc:call(N2, mnesia, sync_transaction, [All])),
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ ?verify_mnesia(Nodes, []).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
unbound1(suite) -> [];
unbound1(Config) when is_list(Config) ->
@@ -1036,29 +1077,57 @@ add_table_copy(Config) when is_list(Config) ->
Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
?match({atomic, ok}, mnesia:create_table(Tab, Def)),
insert(Tab, 50),
- {success, [A]} = ?start_activities([ThisNode]),
+ {success, [A]} = ?start_activities([ThisNode]),
mnesia_test_lib:start_sync_transactions([A], 0),
A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
?match_receive({A, ok}), %% A is executed
- Pid = spawn_link(?MODULE, op, [self(), mnesia, add_table_copy,
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, add_table_copy,
[Tab, Node2, ram_copies]]),
-
+
?match_receive(timeout), %% op waits for locks occupied by A
A ! end_trans, %% Kill A, locks should be released
- ?match_receive({A,{atomic,end_trans}}),
-
- receive
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
Msg -> ?match({Pid, {atomic, ok}}, Msg)
after
timer:seconds(20) -> ?error("Operation timed out", [])
end,
+ ?match_receive({'EXIT', Pid, normal}),
sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
- ?match([], mnesia:system_info(held_locks)),
- ?match([], mnesia:system_info(lock_queue)),
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+
+ {atomic, ok} = mnesia:del_table_copy(Tab, Node2),
+ Self = self(),
+ New = spawn_link(Node2,
+ fun () ->
+ application:stop(mnesia),
+ Self ! {self(), ok},
+ io:format(user, "restart mnesia~n", []),
+ Self ! {self(), catch application:start(mnesia)}
+ end),
+ receive {New,ok} -> ok end,
+
+ Add = fun Add() ->
+ case mnesia:add_table_copy(Tab, Node2, disc_copies) of
+ {atomic, ok} -> ok;
+ _R -> io:format(user, "aborted with reason ~p~n", [_R]),
+ timer:sleep(10),
+ Add()
+ end
+ end,
+
+ ?match(ok, Add()),
+ ?match_receive({New,ok}),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
ok.
del_table_copy(suite) -> [];
diff --git a/lib/mnesia/test/mt b/lib/mnesia/test/mt
index a398ee0422..b169734f56 100755
--- a/lib/mnesia/test/mt
+++ b/lib/mnesia/test/mt
@@ -34,8 +34,35 @@ erlcmd="erl -sname a $p $args -mnesia_test_timeout"
erlcmd1="erl -sname a1 $p $args"
erlcmd2="erl -sname a2 $p $args"
-xterm -geometry 70x20+0+550 -T a1 -e $erlcmd1 &
-xterm -geometry 70x20+450+550 -T a2 -e $erlcmd2 &
+if test z"$MT_TERM" = z ; then
+ MT_TERM=xterm
+fi
+
+case $MT_TERM in
+ xterm)
+ geom0="-geometry 142x40+0+0"
+ geom1="-geometry 70x20+0+550"
+ geom2="-geometry 70x20+480+550"
+ title="-T"
+ exec="-e"
+ ;;
+ gnome-terminal)
+ geom0="--geometry 142x40+0+0"
+ geom1="--geometry 70x20+0+740"
+ geom2="--geometry 70x20+700+740"
+ title="--title"
+ exec="--hide-menubar --"
+ ;;
+ *rxvt)
+ geom0="-geometry 142x40+0+0"
+ geom1="-geometry 70x20+0+680"
+ geom2="-geometry 70x20+630+680"
+ title="-title"
+ exec="-e"
+esac
+
+$MT_TERM $geom1 $title a1 $exec $erlcmd1 &
+$MT_TERM $geom2 $title a2 $exec $erlcmd2 &
rm "$latest" 2>/dev/null
ln -s "$log" "$latest"
@@ -51,11 +78,6 @@ echo "Give the following command in order to see the outcome from node a@$h"":"
echo ""
echo " less test_log$$"
-ostype=`uname -s`
-if [ "$ostype" = "SunOS" ] ; then
- /usr/openwin/bin/xterm -geometry 145x40+0+0 -T a -l -lf "$log" -e $erlcmd &
-else
- xterm -geometry 145x40+0+0 -T a -e script -f -c "$erlcmd" "$log" &
-fi
+$MT_TERM $geom0 $title a $exec script -f -c "$erlcmd" "$log" &
tail -f "$log" | egrep 'Eval|<>ERROR|NYI'
diff --git a/lib/observer/src/cdv_bin_cb.erl b/lib/observer/src/cdv_bin_cb.erl
index 91d33474c8..819596b483 100644
--- a/lib/observer/src/cdv_bin_cb.erl
+++ b/lib/observer/src/cdv_bin_cb.erl
@@ -33,42 +33,43 @@ detail_pages() ->
[{"Binary", fun init_bin_page/2}].
init_bin_page(Parent,{Type,Bin}) ->
+ Cs = observer_lib:colors(Parent),
cdv_multi_wx:start_link(
Parent,
- [{"Format \~p",cdv_html_wx,{Type,format_bin_fun("~p",Bin)}},
- {"Format \~tp",cdv_html_wx,{Type,format_bin_fun("~tp",Bin)}},
- {"Format \~w",cdv_html_wx,{Type,format_bin_fun("~w",Bin)}},
- {"Format \~tw",cdv_html_wx,{Type,format_bin_fun("~tw",Bin)}},
- {"Format \~s",cdv_html_wx,{Type,format_bin_fun("~s",Bin)}},
- {"Format \~ts",cdv_html_wx,{Type,format_bin_fun("~ts",Bin)}},
- {"Hex",cdv_html_wx,{Type,hex_binary_fun(Bin)}},
- {"Term",cdv_html_wx,{Type,binary_to_term_fun(Bin)}}]).
+ [{"Format \~p",cdv_html_wx,{Type,format_bin_fun("~p",Bin,Cs)}},
+ {"Format \~tp",cdv_html_wx,{Type,format_bin_fun("~tp",Bin,Cs)}},
+ {"Format \~w",cdv_html_wx,{Type,format_bin_fun("~w",Bin,Cs)}},
+ {"Format \~tw",cdv_html_wx,{Type,format_bin_fun("~tw",Bin,Cs)}},
+ {"Format \~s",cdv_html_wx,{Type,format_bin_fun("~s",Bin,Cs)}},
+ {"Format \~ts",cdv_html_wx,{Type,format_bin_fun("~ts",Bin,Cs)}},
+ {"Hex",cdv_html_wx,{Type,hex_binary_fun(Bin,Cs)}},
+ {"Term",cdv_html_wx,{Type,binary_to_term_fun(Bin,Cs)}}]).
-format_bin_fun(Format,Bin) ->
+format_bin_fun(Format,Bin,Cs) ->
fun() ->
try io_lib:format(Format,[Bin]) of
- Str -> plain_html(lists:flatten(Str))
+ Str -> plain_html(lists:flatten(Str),Cs)
catch error:badarg ->
Warning = "This binary cannot be formatted with " ++ Format,
- observer_html_lib:warning(Warning)
+ observer_html_lib:warning(Warning,Cs)
end
end.
-binary_to_term_fun(Bin) ->
+binary_to_term_fun(Bin,Cs) ->
fun() ->
try binary_to_term(Bin) of
- Term -> plain_html(io_lib:format("~tp",[Term]))
+ Term -> plain_html(io_lib:format("~tp",[Term]),Cs)
catch error:badarg ->
Warning = "This binary cannot be converted to an Erlang term",
- observer_html_lib:warning(Warning)
+ observer_html_lib:warning(Warning,Cs)
end
end.
-define(line_break,25).
-hex_binary_fun(Bin) ->
+hex_binary_fun(Bin,Cs) ->
fun() ->
S = "<<" ++ format_hex(Bin,?line_break) ++ ">>",
- plain_html(io_lib:format("~s",[S]))
+ plain_html(io_lib:format("~s",[S]), Cs)
end.
format_hex(<<>>,_) ->
@@ -82,5 +83,5 @@ format_hex(<<B1:4,B2:4,Bin/binary>>,N) ->
[integer_to_list(B1,16),integer_to_list(B2,16),$,
| format_hex(Bin,N-1)].
-plain_html(Text) ->
- observer_html_lib:plain_page(Text).
+plain_html(Text,Cs) ->
+ observer_html_lib:plain_page(Text,Cs).
diff --git a/lib/observer/src/cdv_html_wx.erl b/lib/observer/src/cdv_html_wx.erl
index 8956173c93..83ee98de6e 100644
--- a/lib/observer/src/cdv_html_wx.erl
+++ b/lib/observer/src/cdv_html_wx.erl
@@ -30,7 +30,8 @@
%% Records
-record(state,
- {panel,
+ {parent,
+ panel,
app, %% which tool is the user
expand_table,
expand_wins=[],
@@ -62,7 +63,7 @@ init(ParentWin, HtmlText, Tab, App) ->
HtmlWin = observer_lib:html_window(ParentWin),
wxHtmlWindow:setPage(HtmlWin,HtmlText),
wx_misc:endBusyCursor(),
- {HtmlWin, #state{panel=HtmlWin,expand_table=Tab,app=App}}.
+ {HtmlWin, #state{parent=ParentWin, panel=HtmlWin,expand_table=Tab,app=App}}.
init(ParentWin, Callback) ->
{HtmlWin, State} = init(ParentWin, "", undefined, cdv),
@@ -70,12 +71,15 @@ init(ParentWin, Callback) ->
%%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-handle_info(active, #state{panel=HtmlWin,delayed_fetch=Callback}=State)
+handle_info(active, #state{parent=Parent, panel=HtmlWin,delayed_fetch=Callback}=State)
when Callback=/=undefined ->
observer_lib:display_progress_dialog(HtmlWin,
"Crashdump Viewer",
"Reading data"),
- {{expand,HtmlText,Tab},TW} = Callback:get_info(),
+ {{expand,Title,Info,Tab},TW} = Callback:get_info(),
+ Cs = observer_lib:colors(Parent),
+ HtmlText = observer_html_lib:expandable_term(Title,Info,Tab,Cs),
+
observer_lib:sync_destroy_progress_dialog(),
wx_misc:beginBusyCursor(),
wxHtmlWindow:setPage(HtmlWin,HtmlText),
@@ -138,7 +142,8 @@ handle_event(#wx{event=#wxHtmlLink{type=command_html_link_clicked,
list_to_integer(Key3)}}},
expand(Id,cdv_term_cb,State);
_ when App =:= obs ->
- observer ! {open_link, Target};
+ observer ! {open_link, Target},
+ State;
_ ->
cdv_virtual_list_wx:start_detail_win(Target),
State
diff --git a/lib/observer/src/cdv_mod_cb.erl b/lib/observer/src/cdv_mod_cb.erl
index 2183e1aa3d..7f2cd0cf87 100644
--- a/lib/observer/src/cdv_mod_cb.erl
+++ b/lib/observer/src/cdv_mod_cb.erl
@@ -85,7 +85,8 @@ init_old_comp_page(Parent, Info) ->
init_info_page(Parent, undefined) ->
init_info_page(Parent, "");
init_info_page(Parent, String) ->
- cdv_html_wx:start_link(Parent,observer_html_lib:plain_page(String)).
+ Cs = observer_lib:colors(Parent),
+ cdv_html_wx:start_link(Parent,observer_html_lib:plain_page(String,Cs)).
format({Bin,q}) when is_binary(Bin) ->
[$'|binary_to_list(Bin)];
diff --git a/lib/observer/src/cdv_persistent_cb.erl b/lib/observer/src/cdv_persistent_cb.erl
index d5da18f7fc..90abc6a4f5 100644
--- a/lib/observer/src/cdv_persistent_cb.erl
+++ b/lib/observer/src/cdv_persistent_cb.erl
@@ -26,7 +26,4 @@
get_info() ->
Tab = ets:new(pt_expand,[set,public]),
{ok,PT,TW} = crashdump_viewer:persistent_terms(),
- {{expand,
- observer_html_lib:expandable_term("Persistent Terms",PT,Tab),
- Tab},
- TW}.
+ {{expand, "Persistent Terms", PT, Tab}, TW}.
diff --git a/lib/observer/src/cdv_proc_cb.erl b/lib/observer/src/cdv_proc_cb.erl
index 2497b4889e..61bd86f188 100644
--- a/lib/observer/src/cdv_proc_cb.erl
+++ b/lib/observer/src/cdv_proc_cb.erl
@@ -108,7 +108,7 @@ init_stack_page(Parent, Info) ->
init_memory_page(Parent, Info0, Tag, Heading) ->
Info = proplists:get_value(Tag,Info0),
Tab = proplists:get_value(expand_table,Info0),
- Html = observer_html_lib:expandable_term(Heading,Info,Tab),
+ Html = observer_html_lib:expandable_term(Heading,Info,Tab, observer_lib:colors(Parent)),
cdv_html_wx:start_link(Parent,{expand,Html,Tab}).
init_ets_page(Parent, Info) ->
diff --git a/lib/observer/src/cdv_term_cb.erl b/lib/observer/src/cdv_term_cb.erl
index 85da1d227a..a2a7a8750d 100644
--- a/lib/observer/src/cdv_term_cb.erl
+++ b/lib/observer/src/cdv_term_cb.erl
@@ -35,31 +35,32 @@ init_term_page(ParentWin, {Type, [Term, Tab]}) ->
Expanded = expand(Term, true),
BinSaved = expand(Term, Tab),
observer_lib:report_progress({ok,stop_pulse}),
+ Cs = observer_lib:colors(ParentWin),
cdv_multi_wx:start_link(
ParentWin,
- [{"Format \~p",cdv_html_wx,{Type, format_term_fun("~p",BinSaved,Tab)}},
- {"Format \~tp",cdv_html_wx,{Type,format_term_fun("~tp",BinSaved,Tab)}},
- {"Format \~w",cdv_html_wx,{Type,format_term_fun("~w",BinSaved,Tab)}},
- {"Format \~tw",cdv_html_wx,{Type,format_term_fun("~tw",BinSaved,Tab)}},
- {"Format \~s",cdv_html_wx,{Type,format_term_fun("~s",Expanded,Tab)}},
- {"Format \~ts",cdv_html_wx,{Type,format_term_fun("~ts",Expanded,Tab)}}]).
+ [{"Format \~p",cdv_html_wx,{Type, format_term_fun("~p",BinSaved,Tab,Cs)}},
+ {"Format \~tp",cdv_html_wx,{Type,format_term_fun("~tp",BinSaved,Tab,Cs)}},
+ {"Format \~w",cdv_html_wx,{Type,format_term_fun("~w",BinSaved,Tab,Cs)}},
+ {"Format \~tw",cdv_html_wx,{Type,format_term_fun("~tw",BinSaved,Tab,Cs)}},
+ {"Format \~s",cdv_html_wx,{Type,format_term_fun("~s",Expanded,Tab,Cs)}},
+ {"Format \~ts",cdv_html_wx,{Type,format_term_fun("~ts",Expanded,Tab,Cs)}}]).
-format_term_fun(Format,Term,Tab) ->
+format_term_fun(Format,Term,Tab,Cs) ->
fun() ->
observer_lib:report_progress({ok,"Formatting term"}),
observer_lib:report_progress({ok,start_pulse}),
try io_lib:format(Format,[Term]) of
- Str -> {expand, plain_html(Str), Tab}
+ Str -> {expand, plain_html(Str,Cs), Tab}
catch error:badarg ->
Warning = "This term cannot be formatted with " ++ Format,
- observer_html_lib:warning(Warning)
+ observer_html_lib:warning(Warning,Cs)
after
observer_lib:report_progress({ok,stop_pulse})
end
end.
-plain_html(Text) ->
- observer_html_lib:plain_page(Text).
+plain_html(Text,Cs) ->
+ observer_html_lib:plain_page(Text,Cs).
expand(['#CDVBin',Offset,Size,Pos], true) ->
{ok,Bin} = crashdump_viewer:expand_binary({Offset,Size,Pos}),
diff --git a/lib/observer/src/cdv_virtual_list_wx.erl b/lib/observer/src/cdv_virtual_list_wx.erl
index 14877b7eab..51e85e17c1 100644
--- a/lib/observer/src/cdv_virtual_list_wx.erl
+++ b/lib/observer/src/cdv_virtual_list_wx.erl
@@ -96,8 +96,9 @@ start_detail_win_2(Callback,Id) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init([ParentWin, Callback, Owner]) ->
- {Holder,TW} = spawn_table_holder(Callback, Owner),
Panel = wxPanel:new(ParentWin),
+ Attrs = observer_lib:create_attrs(Panel),
+ {Holder,TW} = spawn_table_holder(Callback, Owner, Attrs),
{Grid,MenuCols} = create_list_box(Panel, Holder, Callback, Owner),
Sizer = wxBoxSizer:new(?wxVERTICAL),
wxSizer:add(Sizer, Grid, [{flag, ?wxEXPAND bor ?wxALL},
@@ -233,7 +234,8 @@ handle_call(new_dump, _From,
Ref = erlang:monitor(process,Holder),
Holder ! stop,
receive {'DOWN',Ref,_,_,_} -> ok end,
- {NewHolder,TW} = spawn_table_holder(Callback, all),
+ Attrs = observer_lib:create_attrs(Grid),
+ {NewHolder,TW} = spawn_table_holder(Callback, all, Attrs),
{reply, ok, State#state{detail_wins=[],holder=NewHolder,trunc_warn=TW}};
handle_call(Msg, _From, State) ->
@@ -329,9 +331,8 @@ handle_event(Event, State) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%TABLE HOLDER%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spawn_table_holder(Callback, Owner) ->
+spawn_table_holder(Callback, Owner, Attrs) ->
{Info,TW} = Callback:get_info(Owner),
- Attrs = observer_lib:create_attrs(),
Parent = self(),
Holder =
case Owner of
diff --git a/lib/observer/src/cdv_wx.erl b/lib/observer/src/cdv_wx.erl
index 7100cc8790..8ad5da857e 100644
--- a/lib/observer/src/cdv_wx.erl
+++ b/lib/observer/src/cdv_wx.erl
@@ -197,8 +197,7 @@ setup(#state{frame=Frame, notebook=Notebook}=State) ->
MemPanel = add_page(Notebook, ?MEM_STR, cdv_multi_wx, cdv_mem_cb),
%% Persistent Terms Panel
- PersistentPanel = add_page(Notebook, ?PERSISTENT_STR,
- cdv_html_wx, cdv_persistent_cb),
+ PersistentPanel = add_page(Notebook, ?PERSISTENT_STR, cdv_html_wx, cdv_persistent_cb),
%% Memory Panel
IntPanel = add_page(Notebook, ?INT_STR, cdv_multi_wx, cdv_int_tab_cb),
diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl
index 8c3eef5411..c4527ba063 100644
--- a/lib/observer/src/observer_app_wx.erl
+++ b/lib/observer/src/observer_app_wx.erl
@@ -48,7 +48,7 @@
usegc = false
}).
--record(paint, {font, pen, brush, sel, links}).
+-record(paint, {font, fg, pen, brush, sel, links}).
-record(app, {ptree, n2p, links, dim}).
-record(box, {x,y, w,h, s1}).
@@ -92,7 +92,8 @@ init([Notebook, Parent, _Config]) ->
Extra = wxBoxSizer:new(?wxVERTICAL),
DrawingArea = wxScrolledWindow:new(P2, [{winid, ?DRAWAREA},
{style,?wxFULL_REPAINT_ON_RESIZE}]),
- wxWindow:setBackgroundColour(DrawingArea, ?wxWHITE),
+ BG = wxWindow:getBackgroundColour(Apps),
+ wxWindow:setBackgroundStyle(DrawingArea, ?wxBG_STYLE_SYSTEM),
wxWindow:setVirtualSize(DrawingArea, 800, 800),
wxSplitterWindow:setMinimumPaneSize(Splitter,50),
wxSizer:add(Extra, DrawingArea, [{flag, ?wxEXPAND},{proportion, 1}]),
@@ -127,7 +128,17 @@ init([Notebook, Parent, _Config]) ->
Font0
end,
SelCol = wxSystemSettings:getColour(?wxSYS_COLOUR_HIGHLIGHT),
- GreyBrush = wxBrush:new({230,230,240}),
+ {Fg,BGBrush,Pen} =
+ case observer_lib:is_darkmode(BG) of
+ false ->
+ {wxSystemSettings:getColour(?wxSYS_COLOUR_BTNTEXT),
+ wxBrush:new(wxSystemSettings:getColour(?wxSYS_COLOUR_BTNSHADOW)),
+ wxPen:new({80,80,80}, [{width, Scale * 2}])};
+ true ->
+ {wxSystemSettings:getColour(?wxSYS_COLOUR_BTNTEXT),
+ wxBrush:new(wxSystemSettings:getColour(?wxSYS_COLOUR_BTNSHADOW)),
+ wxPen:new({0,0,0}, [{width, Scale * 2}])}
+ end,
SelBrush = wxBrush:new(SelCol),
LinkPen = wxPen:new(SelCol, [{width, Scale * 2}]),
process_flag(trap_exit, true),
@@ -137,8 +148,9 @@ init([Notebook, Parent, _Config]) ->
app_w =DrawingArea,
usegc = UseGC,
paint=#paint{font = Font,
- pen = wxPen:new({80,80,80}, [{width, Scale * 2}]),
- brush= GreyBrush,
+ fg = Fg,
+ pen = Pen,
+ brush= BGBrush,
sel = SelBrush,
links= LinkPen
}
@@ -306,11 +318,11 @@ handle_info({delivery, _Pid, app, _Curr, {[], [], [], []}},
handle_info({delivery, Pid, app, Curr, AppData},
State = #state{panel=Panel, appmon=Pid, current=Curr, usegc=UseGC,
- app_w=AppWin, paint=#paint{font=Font}}) ->
+ app_w=AppWin, paint=#paint{fg=Fg, font=Font}}) ->
GC = if UseGC -> {?wxGC:create(AppWin), false};
true -> {false, wxWindowDC:new(AppWin)}
end,
- setFont(GC, Font, {0,0,0}),
+ setFont(GC, Font, Fg),
App = build_tree(AppData, GC),
destroy_gc(GC),
setup_scrollbar(AppWin, App),
@@ -508,13 +520,13 @@ tree_map([], _ , Acc) -> Acc.
draw(_DC, undefined, _, _) ->
ok;
draw(DC, #app{dim={_W,_H}, ptree=Tree, links=Links}, Sel,
- #paint{font=Font, pen=Pen, brush=Brush, links=LPen, sel=SelBrush}) ->
+ #paint{font=Font, fg=Fg, pen=Pen, brush=Brush, links=LPen, sel=SelBrush}) ->
setPen(DC, LPen),
[draw_xlink(Link, DC) || Link <- Links],
setPen(DC, Pen),
%% ?wxGC:drawRectangle(DC, 2,2, _W-2,_H-2), %% DEBUG
setBrush(DC, Brush),
- setFont(DC, Font, {0,0,0}),
+ setFont(DC, Font, Fg),
draw_tree(Tree, root, DC),
case Sel of
undefined -> ok;
diff --git a/lib/observer/src/observer_defs.hrl b/lib/observer/src/observer_defs.hrl
index 504d0877d9..7902b32cba 100644
--- a/lib/observer/src/observer_defs.hrl
+++ b/lib/observer/src/observer_defs.hrl
@@ -36,6 +36,7 @@
check = false
}).
+-record(colors, {fg, even, odd}).
-record(attrs, {even, odd, searched, deleted, changed_odd, changed_even, new_odd, new_even}).
-define(EVEN(Row), ((Row rem 2) =:= 0)).
-define(BG_EVEN, {230,230,250}).
diff --git a/lib/observer/src/observer_html_lib.erl b/lib/observer/src/observer_html_lib.erl
index c67fa28c6d..4c92a8faab 100644
--- a/lib/observer/src/observer_html_lib.erl
+++ b/lib/observer/src/observer_html_lib.erl
@@ -24,9 +24,9 @@
%% viewer. No logic or states are kept by this module.
%%
--export([plain_page/1,
- expandable_term/3,
- warning/1]).
+-export([plain_page/2,
+ expandable_term/4,
+ warning/2]).
-include("crashdump_viewer.hrl").
-include("observer_defs.hrl").
@@ -34,8 +34,9 @@
%%%-----------------------------------------------------------------
%%% Display the given information as is, no heading
%%% Empty body if no info exists.
-warning(Info) ->
- header(body(warning_body(Info))).
+warning(Info, Colors0) ->
+ Colors = convert(Colors0),
+ header(body(warning_body(Info), Colors)).
warning_body(Info) ->
[warn(Info)].
@@ -43,18 +44,22 @@ warning_body(Info) ->
%%%-----------------------------------------------------------------
%%% Display the given information as is, no heading
%%% Empty body if no info exists.
-plain_page(Info) ->
- header(body(plain_body(Info))).
+plain_page(Info, Colors0) ->
+ Colors = convert(Colors0),
+ header(body(plain_body(Info), Colors)).
plain_body(Info) ->
[pre(href_proc_port(lists:flatten(Info)))].
%%%-----------------------------------------------------------------
%%% Expanded memory
-expandable_term(Heading,Expanded,Tab) ->
- header(Heading,body(expandable_term_body(Heading,Expanded,Tab))).
+expandable_term(Heading,Expanded,Tab, Colors0) ->
+ Colors = convert(Colors0),
+ header(Heading,
+ body(expandable_term_body(Heading,Expanded,Tab,Colors),
+ Colors)).
-expandable_term_body(Heading,[],_Tab) ->
+expandable_term_body(Heading,[],_Tab, _) ->
[case Heading of
"MsgQueue" -> "No messages were found";
"Message Queue" -> "No messages were found";
@@ -65,7 +70,7 @@ expandable_term_body(Heading,[],_Tab) ->
"SaslLog" -> "No log entry was found";
"Persistent Terms" -> "No persistent terms were found"
end];
-expandable_term_body(Heading,Expanded,Tab) ->
+expandable_term_body(Heading,Expanded,Tab, Colors) ->
Attr = "BORDER=0 CELLPADDING=0 CELLSPACING=1 WIDTH=100%",
[case Heading of
"MsgQueue" ->
@@ -74,7 +79,7 @@ expandable_term_body(Heading,Expanded,Tab) ->
[th("WIDTH=70%","Message"),
th("WIDTH=30%","SeqTraceToken")]) |
element(1, lists:mapfoldl(fun(Msg, Even) ->
- {msgq_table(Tab, Msg, Even),
+ {msgq_table(Tab, Msg, Even, Colors),
not Even}
end,
true, Expanded))]);
@@ -84,7 +89,7 @@ expandable_term_body(Heading,Expanded,Tab) ->
[th("WIDTH=10%","Id"),
th("WIDTH=90%","Message")]) |
element(1, lists:mapfoldl(fun(Msg, {Even,N}) ->
- {msgq_table(Tab, Msg, N, Even),
+ {msgq_table(Tab, Msg, N, Even, Colors),
{not Even, N+1}}
end,
{true,1}, Expanded))]);
@@ -94,7 +99,7 @@ expandable_term_body(Heading,Expanded,Tab) ->
[th("WIDTH=20%","Label"),
th("WIDTH=80%","Term")]) |
element(1, lists:mapfoldl(fun(Entry, Even) ->
- {stackdump_table(Tab, Entry, Even),
+ {stackdump_table(Tab, Entry, Even, Colors),
not Even}
end, true, Expanded))]);
"ProcState" ->
@@ -103,7 +108,7 @@ expandable_term_body(Heading,Expanded,Tab) ->
[th("WIDTH=20%","Label"),
th("WIDTH=80%","Information")]) |
element(1, lists:mapfoldl(fun(Entry, Even) ->
- {proc_state(Tab, Entry,Even),
+ {proc_state(Tab, Entry,Even, Colors),
not Even}
end, true, Expanded))]);
"SaslLog" ->
@@ -115,37 +120,37 @@ expandable_term_body(Heading,Expanded,Tab) ->
[th("WIDTH=30%","Key"),
th("WIDTH=70%","Value")]) |
element(1, lists:mapfoldl(fun(Entry, Even) ->
- {dict_table(Tab, Entry,Even),
+ {dict_table(Tab, Entry, Even, Colors),
not Even}
end, true, Expanded))])
end].
-msgq_table(Tab,{Msg0,Token0}, Even) ->
+msgq_table(Tab,{Msg0,Token0}, Even, Colors) ->
Token = case Token0 of
[] -> "";
_ -> io_lib:fwrite("~w",[Token0])
end,
Msg = all_or_expand(Tab,Msg0),
- tr(color(Even),[td(pre(Msg)), td(Token)]).
+ tr(color(Even, Colors),[td(pre(Msg)), td(Token)]).
-msgq_table(Tab,Msg0, Id, Even) ->
+msgq_table(Tab,Msg0, Id, Even, Colors) ->
Msg = all_or_expand(Tab,Msg0),
- tr(color(Even),[td(integer_to_list(Id)), td(pre(Msg))]).
+ tr(color(Even, Colors),[td(integer_to_list(Id)), td(pre(Msg))]).
-stackdump_table(Tab,{Label0,Term0},Even) ->
+stackdump_table(Tab,{Label0,Term0},Even, Colors) ->
Label = io_lib:format("~w",[Label0]),
Term = all_or_expand(Tab,Term0),
- tr(color(Even), [td("VALIGN=center",pre(Label)), td(pre(Term))]).
+ tr(color(Even, Colors), [td("VALIGN=center",pre(Label)), td(pre(Term))]).
-dict_table(Tab,{Key0,Value0}, Even) ->
+dict_table(Tab,{Key0,Value0}, Even, Colors) ->
Key = all_or_expand(Tab,Key0),
Value = all_or_expand(Tab,Value0),
- tr(color(Even), [td("VALIGN=center",pre(Key)), td(pre(Value))]).
+ tr(color(Even, Colors), [td("VALIGN=center",pre(Key)), td(pre(Value))]).
-proc_state(Tab,{Key0,Value0}, Even) ->
+proc_state(Tab,{Key0,Value0}, Even, Colors) ->
Key = lists:flatten(io_lib:format("~ts",[Key0])),
Value = all_or_expand(Tab,Value0),
- tr(color(Even), [td("VALIGN=center",Key), td(pre(Value))]).
+ tr(color(Even, Colors), [td("VALIGN=center",Key), td(pre(Value))]).
all_or_expand(Tab,Term) ->
Preview = io_lib:format("~tP",[Term,8]),
@@ -171,8 +176,8 @@ all_or_expand(Tab,Bin,_PreviewStr,_Expand)
Term = io_lib:format("~tp", [OBSBin]),
href_proc_port(lists:flatten(Term), true).
-color(true) -> io_lib:format("BGCOLOR=\"#~2.16.0B~2.16.0B~2.16.0B\"", tuple_to_list(?BG_EVEN));
-color(false) -> io_lib:format("BGCOLOR=\"#~2.16.0B~2.16.0B~2.16.0B\"", tuple_to_list(?BG_ODD)).
+color(true, #colors{even=Even}) -> "BGCOLOR="++Even;
+color(false,#colors{odd=Odd}) -> "BGCOLOR="++Odd.
%%%-----------------------------------------------------------------
%%% Internal library
@@ -180,10 +185,10 @@ start_html() ->
"<HTML>\n".
stop_html() ->
"</HTML>".
-start_html_body() ->
- "<BODY BGCOLOR=\"#FFFFFF\">\n".
+start_html_body(#colors{even=Even, fg=Fg}) ->
+ "<BODY BGCOLOR=" ++ Even ++ ">\n <FONT COLOR=" ++ Fg ++ ">\n".
stop_html_body() ->
- "</BODY>\n".
+ "</FONT> </BODY>\n".
header(Body) ->
header("","",Body).
@@ -205,8 +210,8 @@ only_html_header(Title,JavaScript) ->
JavaScript,
"</HEAD>\n"].
-body(Text) ->
- [start_html_body(),
+body(Text, Colors) ->
+ [start_html_body(Colors),
Text,
stop_html_body()].
@@ -417,3 +422,8 @@ warn([]) ->
[];
warn(Warning) ->
font("COLOR=\"#FF0000\"",p([Warning,br(),br()])).
+
+convert(#colors{fg={FR,FB,FG}, even={ER,EB,EG}, odd={OR,OG,OB}}) ->
+ #colors{fg = io_lib:format("\"#~2.16.0B~2.16.0B~2.16.0B\"", [FR,FB,FG]),
+ even = io_lib:format("\"#~2.16.0B~2.16.0B~2.16.0B\"", [ER,EB,EG]),
+ odd = io_lib:format("\"#~2.16.0B~2.16.0B~2.16.0B\"", [OR,OG,OB])}.
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index 7c68b0ebb6..7d115306bd 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -28,8 +28,8 @@
interval_dialog/4, start_timer/1, start_timer/2, stop_timer/1, timer_config/1,
display_info/2, display_info/3, fill_info/2, update_info/2, to_str/1,
create_menus/3, create_menu_item/3,
- create_attrs/0,
- set_listctrl_col_size/2,
+ is_darkmode/1, colors/1, create_attrs/1,
+ set_listctrl_col_size/2, mix/3,
create_status_bar/1,
html_window/1, html_window/2,
make_obsbin/2,
@@ -373,26 +373,44 @@ create_menu_item(separator, Menu, Index) ->
wxMenu:insertSeparator(Menu, Index),
Index+1.
-create_attrs() ->
- Font = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT),
+colors(Window) ->
+ DarkMode = is_darkmode(wxWindow:getBackgroundColour(Window)),
Text = case wxSystemSettings:getColour(?wxSYS_COLOUR_LISTBOXTEXT) of
- {255,255,255,_} -> {10,10,10}; %% Is white on Mac for some reason
- Color -> Color
- end,
- #attrs{even = wxListItemAttr:new(Text, ?BG_EVEN, Font),
- odd = wxListItemAttr:new(Text, ?BG_ODD, Font),
- deleted = wxListItemAttr:new(?FG_DELETED, ?BG_DELETED, Font),
- changed_even = wxListItemAttr:new(Text, mix(?BG_CHANGED,?BG_EVEN), Font),
- changed_odd = wxListItemAttr:new(Text, mix(?BG_CHANGED,?BG_ODD), Font),
- new_even = wxListItemAttr:new(Text, mix(?BG_NEW,?BG_EVEN), Font),
- new_odd = wxListItemAttr:new(Text, mix(?BG_NEW, ?BG_ODD), Font),
- searched = wxListItemAttr:new(Text, ?BG_SEARCHED, Font)
- }.
-
-mix(RGB,_) -> RGB.
-
-%% mix({R,G,B},{MR,MG,MB}) ->
-%% {trunc(R*MR/255), trunc(G*MG/255), trunc(B*MB/255)}.
+ {255,255,255,_} when not DarkMode -> {10,10,10}; %% Is white on Mac for some reason
+ Color -> Color
+ end,
+ Even = wxSystemSettings:getColour(?wxSYS_COLOUR_LISTBOX),
+ Odd = mix(Even, wxSystemSettings:getColour(?wxSYS_COLOUR_HIGHLIGHT), 0.8),
+ #colors{fg=rgb(Text), even=rgb(Even), odd=rgb(Odd)}.
+
+create_attrs(Window) ->
+ Font = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT),
+ #colors{fg=Text, even=Even, odd=Odd} = colors(Window),
+ #attrs{even = wxListItemAttr:new(Text, Even, Font),
+ odd = wxListItemAttr:new(Text, Odd, Font),
+ deleted = wxListItemAttr:new(?FG_DELETED, ?BG_DELETED, Font),
+ changed_even = wxListItemAttr:new(Text, mix(?BG_CHANGED, ?BG_EVEN, 0.9), Font),
+ changed_odd = wxListItemAttr:new(Text, mix(?BG_CHANGED, ?BG_ODD, 0.9), Font),
+ new_even = wxListItemAttr:new(Text, mix(?BG_NEW, ?BG_EVEN, 0.9), Font),
+ new_odd = wxListItemAttr:new(Text, mix(?BG_NEW, ?BG_ODD, 0.9), Font),
+ searched = wxListItemAttr:new(Text, ?BG_SEARCHED, Font)
+ }.
+
+rgb({R,G,B,_}) -> {R,G,B};
+rgb({_,_,_}=RGB) -> RGB.
+
+mix(RGB,{MR,MG,MB,_}, V) ->
+ mix(RGB, {MR,MG,MB}, V);
+mix({R,G,B,_}, RGB, V) ->
+ mix({R,G,B}, RGB, V);
+mix({R,G,B},{MR,MG,MB}, V) when V =< 1.0 ->
+ {min(255, round(R*V+MR*(1.0-V))),
+ min(255, round(G*V+MG*(1.0-V))),
+ min(255, round(B*V+MB*(1.0-V)))}.
+
+
+is_darkmode({R,G,B,_}) ->
+ ((R+G+B) div 3) < 100.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl
index 79271addf2..50a6d6a915 100644
--- a/lib/observer/src/observer_perf_wx.erl
+++ b/lib/observer/src/observer_perf_wx.erl
@@ -55,7 +55,7 @@
-define(wxGC, wxGraphicsContext).
--record(paint, {font, small, pen, pen2, pens, dot_pens, usegc = false}).
+-record(paint, {font, small, fg, pen, pen2, pens, dot_pens, usegc = false}).
start_link(Notebook, Parent, Config) ->
wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
@@ -126,7 +126,16 @@ setup_graph_drawing(Panels) ->
SF = wxFont:new(Scale * (DefSize-2), DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL),
{F, SF}
end,
- BlackPen = wxPen:new({0,0,0}, [{width, Scale}]),
+ BG = wxWindow:getBackgroundColour((hd(Panels))#win.panel),
+ Fg = case observer_lib:is_darkmode(BG) of
+ false -> {0,0,0};
+ true -> wxSystemSettings:getColour(?wxSYS_COLOUR_BTNTEXT)
+ end,
+
+ PenColor = case observer_lib:is_darkmode(BG) of
+ false -> {0,0,0};
+ true -> {0,0,0}
+ end,
Pens = [wxPen:new(Col, [{width, Scale}, {style, ?wxSOLID}])
|| Col <- tuple_to_list(colors())],
DotPens = [wxPen:new(Col, [{width, Scale}, {style, ?wxDOT}])
@@ -134,8 +143,9 @@ setup_graph_drawing(Panels) ->
#paint{usegc = UseGC,
font = Font,
small = SmallFont,
- pen = ?wxGREY_PEN,
- pen2 = BlackPen,
+ fg = Fg, %% Text color
+ pen = wxPen:new(PenColor),
+ pen2 = wxPen:new(PenColor, [{width, Scale}]),
pens = list_to_tuple(Pens),
dot_pens = list_to_tuple(DotPens)
}.
@@ -525,7 +535,7 @@ draw_win(DC, #win{name=Name, no_samples=Samples, geom=#{scale:={WS,HS}},
DrawBs(),
ok;
-draw_win(DC, #win{no_samples=Samples} = Win,Ti, #paint{small=Small}=Paint) ->
+draw_win(DC, #win{no_samples=Samples} = Win,Ti, #paint{fg=Fg, small=Small}=Paint) ->
%% Draw Error Msg
try draw_borders(DC, Ti, Win, Paint) of
{X0,_Y0,DrawBs} ->
@@ -533,7 +543,7 @@ draw_win(DC, #win{no_samples=Samples} = Win,Ti, #paint{small=Small}=Paint) ->
true -> "Waiting for data";
false -> "Information not available"
end,
- setFont(DC, Small, {0,0,0}),
+ setFont(DC, Small, Fg),
{_,WW} = getSize(DC),
drawText(DC, Text, X0 + 100, WW div 2),
DrawBs(),
@@ -628,7 +638,7 @@ spline_tan(Y0, Y1, Y2, Y3) ->
draw_borders(DC, #ti{secs=Secs, fetch=FetchFreq},
#win{name=Type, geom=Geom, info=Info, max={_,_,Unit,_}},
- #paint{pen=Pen, pen2=Pen2, font=Font, small=Small}) ->
+ #paint{pen=Pen, pen2=Pen2, fg=Fg, font=Font, small=Small}) ->
#{p0:={GraphX0, GraphY0}, p1:={GraphX1,GraphY1}, scale:={ScaleW0,_},
txsz:={TW,TH,SpaceW}, txt:={BottomTextY, MaxTextY}, strs:={Str1,Str2,Str3}} = Geom,
@@ -640,7 +650,7 @@ draw_borders(DC, #ti{secs=Secs, fetch=FetchFreq},
GraphY50 = GraphY0 + (GraphY1 - GraphY0) / 2,
GraphY75 = GraphY0 + 3*(GraphY1 - GraphY0) / 4,
- setFont(DC, Small, {0,0,0}),
+ setFont(DC, Small, Fg),
Align = fun(Str, Y) ->
{StrW, _} = getTextExtent(DC, Str),
drawText(DC, Str, GraphX0 - StrW - ?BW, Y)
@@ -670,11 +680,11 @@ draw_borders(DC, #ti{secs=Secs, fetch=FetchFreq},
strokeLine(DC, GraphX0-3, GraphY50, GraphX1, GraphY50),
strokeLine(DC, GraphX0-3, GraphY75, GraphX1, GraphY75),
- setFont(DC, Font, {0,0,0}),
+ setFont(DC, Font, Fg),
Text = fun(X,Y, Str, PenId) ->
if PenId == 0 ->
- setFont(DC, Font, {0,0,0});
+ setFont(DC, Font, Fg);
PenId > 0 ->
Id = 1 + ((PenId-1) rem tuple_size(colors())),
setFont(DC, Font, element(Id, colors()))
diff --git a/lib/observer/src/observer_port_wx.erl b/lib/observer/src/observer_port_wx.erl
index 00cf1b5fba..5cb6d9bc22 100644
--- a/lib/observer/src/observer_port_wx.erl
+++ b/lib/observer/src/observer_port_wx.erl
@@ -61,7 +61,8 @@
inet}).
-record(opt, {sort_key=2,
- sort_incr=true
+ sort_incr=true,
+ odd_bg
}).
-record(state,
@@ -111,7 +112,10 @@ init([Notebook, Parent, Config]) ->
wxListCtrl:connect(Grid, size, [{skip, true}]),
wxWindow:setFocus(Grid),
- {Panel, #state{grid=Grid, parent=Parent, panel=Panel, timer=Config}}.
+ Even = wxSystemSettings:getColour(?wxSYS_COLOUR_LISTBOX),
+ Odd = observer_lib:mix(Even, wxSystemSettings:getColour(?wxSYS_COLOUR_HIGHLIGHT), 0.8),
+ Opt = #opt{odd_bg=Odd},
+ {Panel, #state{grid=Grid, parent=Parent, panel=Panel, timer=Config, opt=Opt}}.
handle_event(#wx{id=?ID_REFRESH},
State = #state{node=Node, grid=Grid, opt=Opt}) ->
@@ -553,7 +557,7 @@ filter_monitor_info() ->
update_grid(Grid, Sel, Opt, Ports) ->
wx:batch(fun() -> update_grid2(Grid, Sel, Opt, Ports) end).
-update_grid2(Grid, Sel, #opt{sort_key=Sort,sort_incr=Dir}, Ports) ->
+update_grid2(Grid, Sel, #opt{sort_key=Sort,sort_incr=Dir, odd_bg=BG}, Ports) ->
wxListCtrl:deleteAllItems(Grid),
Update =
fun(#port{id = Id,
@@ -563,8 +567,8 @@ update_grid2(Grid, Sel, #opt{sort_key=Sort,sort_incr=Dir}, Ports) ->
controls = Ctrl},
Row) ->
_Item = wxListCtrl:insertItem(Grid, Row, ""),
- if (Row rem 2) =:= 0 ->
- wxListCtrl:setItemBackgroundColour(Grid, Row, ?BG_EVEN);
+ if (Row rem 2) =:= 1 ->
+ wxListCtrl:setItemBackgroundColour(Grid, Row, BG);
true -> ignore
end,
diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl
index 4ab4a78462..6b359f3c44 100644
--- a/lib/observer/src/observer_pro_wx.erl
+++ b/lib/observer/src/observer_pro_wx.erl
@@ -94,7 +94,7 @@ start_link(Notebook, Parent, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init([Notebook, Parent, Config]) ->
- Attrs = observer_lib:create_attrs(),
+ Attrs = observer_lib:create_attrs(Notebook),
Self = self(),
Acc = maps:get(acc, Config, false),
Holder = spawn_link(fun() -> init_table_holder(Self, Acc, Attrs) end),
diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl
index bd5fed0951..637a090a15 100644
--- a/lib/observer/src/observer_procinfo.erl
+++ b/lib/observer/src/observer_procinfo.erl
@@ -214,12 +214,14 @@ init_process_page(Panel, Pid) ->
init_message_page(Parent, Pid, Table) ->
Win = observer_lib:html_window(Parent),
+ Cs = observer_lib:colors(Parent),
Update = fun() ->
case observer_wx:try_rpc(node(Pid), erlang, process_info,
[Pid, messages])
of
{messages, Messages} ->
- Html = observer_html_lib:expandable_term("Message Queue", Messages, Table),
+ Html = observer_html_lib:expandable_term("Message Queue", Messages,
+ Table, Cs),
wxHtmlWindow:setPage(Win, Html);
_ ->
throw(process_undefined)
@@ -230,11 +232,12 @@ init_message_page(Parent, Pid, Table) ->
init_dict_page(Parent, Pid, Table) ->
Win = observer_lib:html_window(Parent),
+ Cs = observer_lib:colors(Parent),
Update = fun() ->
case observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, dictionary])
of
{dictionary,Dict} ->
- Html = observer_html_lib:expandable_term("Dictionary", Dict, Table),
+ Html = observer_html_lib:expandable_term("Dictionary", Dict, Table, Cs),
wxHtmlWindow:setPage(Win, Html);
_ ->
throw(process_undefined)
@@ -254,6 +257,8 @@ init_stack_page(Parent, Pid) ->
wxListCtrl:insertColumn(LCtrl, 1, Li),
wxListCtrl:setColumnWidth(LCtrl, 1, Scale * 300),
wxListItem:destroy(Li),
+ Even = wxSystemSettings:getColour(?wxSYS_COLOUR_LISTBOX),
+ Odd = observer_lib:mix(Even, wxSystemSettings:getColour(?wxSYS_COLOUR_HIGHLIGHT), 0.8),
Update = fun() ->
case observer_wx:try_rpc(node(Pid), erlang, process_info,
[Pid, current_stacktrace])
@@ -262,8 +267,8 @@ init_stack_page(Parent, Pid) ->
wxListCtrl:deleteAllItems(LCtrl),
wx:foldl(fun({M, F, A, Info}, Row) ->
_Item = wxListCtrl:insertItem(LCtrl, Row, ""),
- ?EVEN(Row) andalso
- wxListCtrl:setItemBackgroundColour(LCtrl, Row, ?BG_EVEN),
+ ?EVEN(Row) orelse
+ wxListCtrl:setItemBackgroundColour(LCtrl, Row, Odd),
wxListCtrl:setItem(LCtrl, Row, 0, observer_lib:to_str({M,F,A})),
FileLine = case Info of
[{file,File},{line,Line}] ->
@@ -288,9 +293,10 @@ init_stack_page(Parent, Pid) ->
init_state_page(Parent, Pid, Table) ->
Win = observer_lib:html_window(Parent),
+ Cs = observer_lib:colors(Parent),
Update = fun() ->
StateInfo = fetch_state_info(Pid),
- Html = observer_html_lib:expandable_term("ProcState", StateInfo, Table),
+ Html = observer_html_lib:expandable_term("ProcState", StateInfo, Table, Cs),
wxHtmlWindow:setPage(Win, Html)
end,
Update(),
@@ -341,6 +347,7 @@ fetch_state_info2(Pid, M) ->
init_log_page(Parent, Pid, Table) ->
Win = observer_lib:html_window(Parent),
+ Cs = observer_lib:colors(Parent),
Update = fun() ->
Fd = spawn_link(fun() -> io_server() end),
rpc:call(node(Pid), rb, rescan, [[{start_log, Fd}]]),
@@ -353,7 +360,7 @@ init_log_page(Parent, Pid, Table) ->
NbBlanks = length(Pref) - 1,
Re = "(<" ++ Pref ++ "\.[^>]{1,}>)[ ]{"++ integer_to_list(NbBlanks) ++ "}",
Look = re:replace(ExpPid, Re, "\\1", [global, {return, list}]),
- Html = observer_html_lib:expandable_term("SaslLog", Look, Table),
+ Html = observer_html_lib:expandable_term("SaslLog", Look, Table, Cs),
wxHtmlWindow:setPage(Win, Html)
end,
Update(),
diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl
index 7bd67a0f0b..32d75f77d4 100644
--- a/lib/observer/src/observer_tv_table.erl
+++ b/lib/observer/src/observer_tv_table.erl
@@ -116,8 +116,8 @@ init([Parent, Opts]) ->
TabId = table_id(Table),
ColumnNames = column_names(Node, Source, TabId),
KeyPos = key_pos(Node, Source, TabId),
-
- Attrs = observer_lib:create_attrs(),
+ Panel = wxPanel:new(Frame),
+ Attrs = observer_lib:create_attrs(Panel),
Self = self(),
Holder = spawn_link(fun() ->
@@ -125,7 +125,6 @@ init([Parent, Opts]) ->
length(ColumnNames), Node, Attrs)
end),
- Panel = wxPanel:new(Frame),
Sizer = wxBoxSizer:new(?wxVERTICAL),
Style = ?wxLC_REPORT bor ?wxLC_VIRTUAL bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES,
Grid = wxListCtrl:new(Panel, [{style, Style},
diff --git a/lib/observer/src/observer_tv_wx.erl b/lib/observer/src/observer_tv_wx.erl
index 9743a6ed42..d622b1423b 100644
--- a/lib/observer/src/observer_tv_wx.erl
+++ b/lib/observer/src/observer_tv_wx.erl
@@ -71,7 +71,7 @@ init([Notebook, Parent, Config]) ->
Style = ?wxLC_REPORT bor ?wxLC_VIRTUAL bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES,
Self = self(),
- Attrs = observer_lib:create_attrs(),
+ Attrs = observer_lib:create_attrs(Panel),
Holder = spawn_link(fun() -> init_table_holder(Self, Attrs) end),
CBs = [{onGetItemText, fun(_, Item,Col) -> get_row(Holder, Item, Col) end},
{onGetItemAttr, fun(_, Item) -> get_attr(Holder, Item) end}],
diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl
index 84ed99afa5..10d88c994a 100644
--- a/lib/observer/test/crashdump_helper.erl
+++ b/lib/observer/test/crashdump_helper.erl
@@ -48,7 +48,7 @@ n1_proc(Creator,_N2,Pid2,Port2,_L) ->
Ref = make_ref(),
Pid = self(),
Bin = list_to_binary(lists:seq(1, 255)),
- <<_:2,SubBin:17/binary,_/bits>> = Bin,
+ <<_:2,SubBin:65/binary,_/bits>> = Bin,
register(named_port,Port),
@@ -102,7 +102,7 @@ remote_proc(P1,Creator) ->
end).
create_binaries() ->
- Sizes = lists:seq(60, 70) ++ lists:seq(120, 140),
+ Sizes = lists:seq(100, 120) ++ lists:seq(200, 240),
[begin
<<H:16/unit:8>> = erlang:md5(<<Size:32>>),
Data = ((H bsl (8*150)) div (H+7919)),
@@ -113,7 +113,7 @@ create_sub_binaries(Bins) ->
[create_sub_binary(Bin, Start, LenSub) ||
Bin <- Bins,
Start <- [0,1,2,3,4,5,10,22],
- LenSub <- [0,1,2,3,4,6,9]].
+ LenSub <- [0,1,2,3,4,6,9,65]].
create_sub_binary(Bin, Start, LenSub) ->
Len = byte_size(Bin) - LenSub - Start,
diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c
index c96a5c9f7c..98a2526aab 100644
--- a/lib/os_mon/c_src/cpu_sup.c
+++ b/lib/os_mon/c_src/cpu_sup.c
@@ -359,7 +359,7 @@ static cpu_t *read_procstat(FILE *fp, cpu_t *cpu) {
memset(cpu, 0, sizeof(cpu_t));
return cpu;
}
- sscanf(buffer, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
+ sscanf(buffer, "cpu%u %llu %llu %llu %llu %llu %llu %llu %llu",
&(cpu->id),
&(cpu->user),
&(cpu->nice_user),
diff --git a/lib/sasl/src/Makefile b/lib/sasl/src/Makefile
index fd62588f5c..a5b9a5e731 100644
--- a/lib/sasl/src/Makefile
+++ b/lib/sasl/src/Makefile
@@ -63,9 +63,6 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
# ----------------------------------------------------
ERL_COMPILE_FLAGS += -I../../stdlib/include -Werror
-ifeq ($(USE_ESOCK), yes)
-ERL_COMPILE_FLAGS += -DUSE_ESOCK=true
-endif
# ----------------------------------------------------
diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl
index b5a6b44f93..c5d4b9bef3 100644
--- a/lib/sasl/src/systools_make.erl
+++ b/lib/sasl/src/systools_make.erl
@@ -47,9 +47,11 @@
-compile({inline,[{badarg,2}]}).
-ifdef(USE_ESOCK).
--define(ESOCK_MODS, [socket]).
+-define(ESOCK_SOCKET_MODS, [socket]).
+-define(ESOCK_NET_MODS, [prim_net]).
-else.
--define(ESOCK_MODS, []).
+-define(ESOCK_SOCKET_MODS, []).
+-define(ESOCK_NET_MODS, []).
-endif.
@@ -1573,8 +1575,8 @@ preloaded() ->
[atomics,counters,erl_init,erl_prim_loader,erl_tracer,erlang,
erts_code_purger,erts_dirty_process_signal_handler,
erts_internal,erts_literal_area_collector,
- init,net,persistent_term,prim_buffer,prim_eval,prim_file,
- prim_inet,prim_zip] ++ ?ESOCK_MODS ++ [zlib].
+ init,persistent_term,prim_buffer,prim_eval,prim_file,
+ prim_inet] ++ ?ESOCK_NET_MODS ++ [prim_zip] ++ ?ESOCK_SOCKET_MODS ++ [zlib].
%%______________________________________________________________________
%% Kernel processes; processes that are specially treated by the init
diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile
index 879f1b05c5..df321fc2d1 100644
--- a/lib/snmp/Makefile
+++ b/lib/snmp/Makefile
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
+# Copyright Ericsson AB 1996-2019. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -136,11 +136,17 @@ dclean:
dialyzer_plt: $(DIA_PLT)
-$(DIA_PLT):
+$(DIA_PLT): Makefile
@echo "Building $(APPLICATION) plt file"
@dialyzer --build_plt \
--output_plt $@ \
-r ../$(APPLICATION)/ebin \
+ ../../lib/kernel/ebin \
+ ../../lib/stdlib/ebin \
+ ../../lib/runtime_tools/ebin \
+ ../../lib/crypto/ebin \
+ ../../lib/mnesia/ebin \
+ ../../erts/preloaded/ebin \
--output $(DIA_ANALYSIS) \
--verbose
@@ -148,4 +154,4 @@ dialyzer: $(DIA_PLT)
@echo "Running dialyzer on $(APPLICATION)"
@dialyzer --plt $< \
../$(APPLICATION)/ebin \
- --verbose \ No newline at end of file
+ --verbose
diff --git a/lib/snmp/doc/src/snmpa_mib_storage.xml b/lib/snmp/doc/src/snmpa_mib_storage.xml
index ee2b009e77..6db2f178a9 100644
--- a/lib/snmp/doc/src/snmpa_mib_storage.xml
+++ b/lib/snmp/doc/src/snmpa_mib_storage.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2013</year><year>2016</year>
+ <year>2013</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -193,7 +193,7 @@
</func>
<func>
- <name since="OTP R16B01">Module:match_object(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name>
+ <name since="OTP R16B01">Module:match_object(TabId, Pattern) -> Recs | {error, Reason}</name>
<fsummary>Search the mib-storage table for record matching pattern</fsummary>
<type>
<v>TabId = term()</v>
@@ -210,7 +210,7 @@
</func>
<func>
- <name since="OTP R16B01">Module:match_delete(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name>
+ <name since="OTP R16B01">Module:match_delete(TabId, Pattern) -> Recs | {error, Reason}</name>
<fsummary>Delete records in the mib-storage table matching pattern</fsummary>
<type>
<v>TabId = term()</v>
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index 984b0bcee1..4bd30632f5 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -545,26 +545,18 @@ snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) ->
end.
-
get_snmpTargetAddrTDomain(RowIndex, Col) ->
- case
- get(
- snmpTargetAddrTable, RowIndex,
- [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain])
- of
- [{value,?snmpTargetAddrRowStatus_active},ValueTDomain] ->
- case ValueTDomain of
- {value,TDomain} ->
- TDomain;
- _ ->
- ?snmpUDPDomain
- end;
- _ ->
+ Cols = [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain],
+ case snmp_target_mib:snmpTargetAddrTable(get, RowIndex, Cols) of
+ [{value, ?snmpTargetAddrRowStatus_active}, {value, TDomain}] ->
+ TDomain;
+ [{value, ?snmpTargetAddrRowStatus_active}, _] ->
+ ?snmpUDPDomain;
+ _ ->
wrongValue(Col)
end.
-
verify_snmpTargetAddrExtTable_cols([], _TDomain, Cols) ->
{ok, lists:reverse(Cols)};
verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], TDomain, Acc) ->
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index 7ea4f0ed97..6db6f87a85 100644
--- a/lib/snmp/src/agent/snmp_framework_mib.erl
+++ b/lib/snmp/src/agent/snmp_framework_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -246,6 +246,7 @@ check_agent(X) ->
%% Ordering function to sort intAgentTransportDomain first
%% hence before intAgentIpAddress. Sort other entries on the key.
+-dialyzer({nowarn_function, order_agent/2}).
order_agent(EntryA, EntryB) ->
snmp_conf:keyorder(
1, EntryA, EntryB,
diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
index 56b5d96142..a5a65d9326 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -654,7 +654,7 @@ vacmAccessTable(is_set_ok, RowIndex, Cols0) ->
{{Col, ?'RowStatus_createAndWait'}, _} ->
%% Row already exists => inconsistentValue
{inconsistentValue, Col};
- {value, {_Col, ?'RowStatus_destroy'}} ->
+ {{_Col, ?'RowStatus_destroy'}, _} ->
%% always ok!
{noError, 0};
{_, false} ->
@@ -1115,9 +1115,7 @@ externalize_next(Name, Result) when is_list(Result) ->
F = fun({[Col | _] = Idx, Val}) -> {Idx, externalize(Name, Col, Val)};
(Other) -> Other
end,
- [F(R) || R <- Result];
-externalize_next(_, Result) ->
- Result.
+ [F(R) || R <- Result].
externalize_get(Name, Cols, Result) when is_list(Result) ->
@@ -1127,9 +1125,7 @@ externalize_get(Name, Cols, Result) when is_list(Result) ->
end,
%% Merge column numbers and return values. there must be as much
%% return values as there are columns requested. And then patch all values
- [F(R) || R <- lists:zip(Cols, Result)];
-externalize_get(_, _, Result) ->
- Result.
+ [F(R) || R <- lists:zip(Cols, Result)].
externalize(vacmViewTreeFamilyTable, ?vacmViewTreeFamilyMask, Val) ->
imask2emask(Val);
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index f280260f47..7489f74223 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -525,9 +525,25 @@ unregister_subagent(Agent, SubagentOidOrPid) ->
%% These subagent_ functions either return a value, or exits
%% with {nodedown, Node} | Reason.
%%-----------------------------------------------------------------
-subagent_get(SubAgent, Varbinds, IsNotification) ->
+
+%% A proper spec for this would be something like this:
+%% But, there is now way to spec that a process *can* exit.
+%% -spec subagent_get(Agent, VBs, IsNotification) ->
+%% {noError, 0, NewVBs} |
+%% {ErrStatus, ErrIndex, []} |
+%% erlang:exit(Reason) when
+%% Agent :: pid(),
+%% VBs :: [snmp:varbind()],
+%% IsNotification :: boolean(),
+%% NewVBs :: [snmp:varbind()],
+%% ErrStatus :: snmp:error_status(),
+%% ErrIndex :: snmp:error_index(),
+%% Reason :: {nodedown, Node} | term(),
+%% Node :: atom().
+
+subagent_get(SubAgent, VBs, IsNotification) ->
PduData = get_pdu_data(),
- call(SubAgent, {subagent_get, Varbinds, PduData, IsNotification}).
+ call(SubAgent, {subagent_get, VBs, PduData, IsNotification}).
subagent_get_next(SubAgent, MibView, Varbinds) ->
PduData = get_pdu_data(),
diff --git a/lib/snmp/src/agent/snmpa_authentication_service.erl b/lib/snmp/src/agent/snmpa_authentication_service.erl
index e4238a8384..b6b9f5bd96 100644
--- a/lib/snmp/src/agent/snmpa_authentication_service.erl
+++ b/lib/snmp/src/agent/snmpa_authentication_service.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,13 +19,27 @@
%%
-module(snmpa_authentication_service).
--export([behaviour_info/1]).
-
-behaviour_info(callbacks) ->
- [{init_check_access, 2}];
-behaviour_info(_) ->
- undefined.
-
+-export_type([
+ acm_data/0
+ ]).
+
+-type acm_data() :: {community,
+ SecModel :: 0 | 1 | 2 | 3, % any | v1 | v2c | v3
+ Community :: string(),
+ %% Oids for either:
+ %% transportDomainUdpIpv4 | transportDomainUdpIpv6
+ TDomain :: snmp:oid(),
+ TAddress :: [non_neg_integer()]} |
+ {v3,
+ MsgID :: integer(),
+ SecModel :: 0 | 1 | 2 | 3, % any | v1 | v2c | v3
+ SecName :: string(),
+ %% noAuthNoPriv | authNoPriv | authPriv
+ SecLevel :: 1 | 2 | 3,
+ ContextEngineID :: string(),
+ ContextName :: string(),
+ SecData :: term()}.
+
%%-----------------------------------------------------------------
%% init_check_access(Pdu, ACMData)
@@ -46,9 +60,7 @@ behaviour_info(_) ->
%% Variable = snmpInBadCommunityNames |
%% snmpInBadCommunityUses |
%% snmpInASNParseErrs
-%% Reason = snmp_message_decoding |
-%% {bad_community_name, Address, Community}} |
-%% {invalid_access, Access, Op}
+%% Reason = {bad_community_name, Address, Community}}
%%
%% Purpose: Called once for each Pdu. Returns a MibView
%% which is later used for each variable in the pdu.
@@ -57,3 +69,14 @@ behaviour_info(_) ->
%%
%% NOTE: This function is executed in the Master agents's context
%%-----------------------------------------------------------------
+
+-callback init_check_access(Pdu, ACMData) ->
+ {ok, MibView, ContextName} |
+ {error, Reason} |
+ {discarded, Variable, Reason} when
+ Pdu :: snmp:pdu(),
+ ACMData :: acm_data(),
+ MibView :: snmp_view_based_acm_mib:mibview(),
+ ContextName :: string(),
+ Reason :: term(),
+ Variable :: snmpInBadCommunityNames.
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index fc5116dac9..c2e9d4025a 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -83,6 +83,34 @@
+-export_type([
+ usm_entry/0
+ ]).
+
+-type usm_entry() :: {
+ EngineID :: string(),
+ UserName :: string(),
+ SecName :: string(),
+ Clone :: zeroDotZero | [non_neg_integer()],
+ AuthP :: usmNoAuthProtocol |
+ usmHMACMD5AuthProtocol |
+ usmHMACSHAAuthProtocol,
+ AuthKeyC :: string(),
+ OwnAuthKeyC :: string(),
+ PrivP :: usmNoPrivProtocol |
+ usmDESPrivProtocol |
+ usmAesCfb128Protocol,
+ PrivKeyC :: string(),
+ OwnPrivKeyC :: string(),
+ Public :: string(),
+ %% Size 16 for usmHMACMD5AuthProtocol
+ %% Size 20 for usmHMACSHAAuthProtocol
+ AuthKey :: [non_neg_integer()],
+ %% Size 16 for usmDESPrivProtocol | usmAesCfb128Protocol
+ PrivKey :: [non_neg_integer()]
+ }.
+
+
%%
%% ------ agent.conf ------
%%
diff --git a/lib/snmp/src/agent/snmpa_discovery_handler.erl b/lib/snmp/src/agent/snmpa_discovery_handler.erl
index ffdd6aca1e..6fb1d1eb72 100644
--- a/lib/snmp/src/agent/snmpa_discovery_handler.erl
+++ b/lib/snmp/src/agent/snmpa_discovery_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,12 +19,17 @@
%%
-module(snmpa_discovery_handler).
--export([behaviour_info/1, verify/1]).
-
-behaviour_info(callbacks) ->
- [{stage1_finish, 3}];
-behaviour_info(_) ->
- undefined.
+-export([verify/1]).
+-callback stage1_finish(TargetName, ManagerEngineID, ExtraInfo) ->
+ ignore |
+ {ok, snmpa_conf:usm_entry() | [snmpa_conf:usm_entry()]} |
+ {ok, snmpa_conf:usm_entry() | [snmpa_conf:usm_entry()], NewExtraInfo} when
+ TargetName :: string(),
+ ManagerEngineID :: string(),
+ ExtraInfo :: term(),
+ NewExtraInfo :: term().
+
verify(Mod) ->
snmp_misc:verify_behaviour(?MODULE, Mod).
+
diff --git a/lib/snmp/src/agent/snmpa_error_report.erl b/lib/snmp/src/agent/snmpa_error_report.erl
index 8f28eac653..6b281693e5 100644
--- a/lib/snmp/src/agent/snmpa_error_report.erl
+++ b/lib/snmp/src/agent/snmpa_error_report.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,10 +19,12 @@
%%
-module(snmpa_error_report).
--export([behaviour_info/1]).
+-callback config_err(Format, Args) ->
+ snmp:void() when
+ Format :: string(),
+ Args :: [term()].
-behaviour_info(callbacks) ->
- [{user_err, 2},
- {config_err, 2}];
-behaviour_info(_) ->
- undefined.
+-callback user_err(Format, Args) ->
+ snmp:void() when
+ Format :: string(),
+ Args :: [term()].
diff --git a/lib/snmp/src/agent/snmpa_get.erl b/lib/snmp/src/agent/snmpa_get.erl
index e67975a67d..8b16016d84 100644
--- a/lib/snmp/src/agent/snmpa_get.erl
+++ b/lib/snmp/src/agent/snmpa_get.erl
@@ -75,6 +75,9 @@
%% {ErrorStatus, ErrorIndex, []}
%%-----------------------------------------------------------------
+%% There is now to properly spec the behaviour of the ?AGENT:subagent_get/3
+%% function (it *can* exit).
+-dialyzer({nowarn_function, do_get/3}).
do_get(UnsortedVarbinds, IsNotification, _Extra) ->
{MyVarbinds, SubagentVarbinds} = ?LIB:agent_sort_vbs(UnsortedVarbinds),
case do_get_local(MyVarbinds, IsNotification) of
@@ -122,6 +125,7 @@ do_get(MibView, UnsortedVarbinds, IsNotification, Extra) ->
do_get_local(VBs, IsNotification) ->
do_get_local(VBs, [], IsNotification).
+-dialyzer({nowarn_function, do_get_local/3}).
do_get_local([Vb | Vbs], Res, IsNotification) ->
case try_get(Vb, IsNotification) of
NewVb when is_record(NewVb, varbind) ->
@@ -144,11 +148,16 @@ do_get_local([], Res, _IsNotification) ->
%% Returns: {noError, 0, ListOfNewVarbinds} |
%% {ErrorStatus, ErrorIndex, []}
%%-----------------------------------------------------------------
+
+%% There is now to properly spec the behaviour of the ?AGENT:subagent_get/3
+%% function (it *can* exit).
+-dialyzer({nowarn_function, do_get_subagents/3}).
do_get_subagents(SubagentVarbinds, IsNotification) ->
do_get_subagents(SubagentVarbinds, [], IsNotification).
+
do_get_subagents([{SubAgentPid, SAVbs} | Tail], Res, IsNotification) ->
{_SAOids, Vbs} = ?LIB:sa_split(SAVbs),
- case catch ?AGENT:subagent_get(SubAgentPid, Vbs, IsNotification) of
+ case (catch ?AGENT:subagent_get(SubAgentPid, Vbs, IsNotification)) of
{noError, 0, NewVbs} ->
do_get_subagents(Tail, lists:append(NewVbs, Res), IsNotification);
{ErrorStatus, ErrorIndex, _} ->
@@ -168,6 +177,8 @@ do_get_subagents([], Res, _IsNotification) ->
%% #varbind |
%% List of #varbind
%%-----------------------------------------------------------------
+
+-dialyzer({nowarn_function, try_get/2}).
try_get(IVb, IsNotification) when is_record(IVb, ivarbind) ->
?vtrace("try_get(ivarbind) -> entry with"
"~n IVb: ~p", [IVb]),
@@ -186,9 +197,12 @@ try_get({TableOid, TableVbs}, IsNotification) ->
NVbs ++ NoAccessVbs
end.
+
%%-----------------------------------------------------------------
%% Make sure all requested columns are accessible.
%%-----------------------------------------------------------------
+
+-dialyzer({nowarn_function, check_all_table_vbs/4}).
check_all_table_vbs([IVb| IVbs], IsNotification, NoA, A) ->
#ivarbind{mibentry = Me, varbind = Vb} = IVb,
case Me#me.access of
@@ -210,6 +224,7 @@ check_all_table_vbs([], _IsNotification, NoA, A) -> {NoA, A}.
%% Returns: {error, ErrorStatus, OrgIndex} |
%% #varbind
%%-----------------------------------------------------------------
+-dialyzer({nowarn_function, get_var_value_from_ivb/2}).
get_var_value_from_ivb(IVb, IsNotification)
when IVb#ivarbind.status =:= noError ->
?vtrace("get_var_value_from_ivb(noError) -> entry", []),
@@ -242,6 +257,7 @@ get_var_value_from_ivb(#ivarbind{status = Status, varbind = Vb}, _) ->
%%-----------------------------------------------------------------
%% Pre: Oid is a correct instance Oid (lookup checked that).
%% Returns: A correct return value (see ?AGENT:make_value_a_correct_value)
+-dialyzer({nowarn_function, get_var_value_from_mib/2}).
get_var_value_from_mib(#me{entrytype = variable,
asn1_type = ASN1Type,
mfa = {Mod, Func, Args}},
@@ -280,6 +296,7 @@ get_var_value_from_mib(#me{entrytype = table_column,
%% non-existing row).
%% Returns: {error, ErrorStatus, OrgIndex} |
%% {value, Type, Value}
+-dialyzer({nowarn_function, get_tab_value_from_mib/3}).
get_tab_value_from_mib(#me{mfa = {Mod, Func, Args}}, TableOid, TableVbs) ->
?vtrace("get_tab_value_from_mib -> entry when"
"~n Mod: ~p"
@@ -302,12 +319,14 @@ get_tab_value_from_mib(#me{mfa = {Mod, Func, Args}}, TableOid, TableVbs) ->
%% #varbind.
%% The Values list comes from validate_tab_res.
%%-----------------------------------------------------------------
+-dialyzer({nowarn_function, merge_varbinds_and_value/2}).
merge_varbinds_and_value(IVbs, [{{value, Type, Value}, Index} | Values]) ->
#ivarbind{varbind = Vb} = lists:nth(Index, IVbs),
[Vb#varbind{variabletype = Type, value = Value} |
merge_varbinds_and_value(IVbs, Values)];
merge_varbinds_and_value(_, []) -> [].
+-dialyzer({nowarn_function, get_value_all_rows/5}).
get_value_all_rows([{[], OrgCols} | Rows], Mod, Func, Args, Res) ->
?vtrace("get_value_all_rows -> entry when"
"~n OrgCols: ~p", [OrgCols]),
@@ -352,10 +371,13 @@ delete_index([]) -> [].
%% the retrieved values to reconstruct the original column list,
%% but with the retrieved value for each column.
%%-----------------------------------------------------------------
+
+-dialyzer({nowarn_function, remove_duplicates/1}).
remove_duplicates(Cols) ->
remove_duplicates(Cols, [], []).
+-dialyzer({nowarn_function, remove_duplicates/3}).
remove_duplicates([{Col, V1, OrgIdx1}, {Col, V2, OrgIdx2} | T], NCols, Dup) ->
remove_duplicates([{Col, V1, OrgIdx1} | T], NCols,
[{Col, V2, OrgIdx2} | Dup]);
@@ -364,6 +386,7 @@ remove_duplicates([Col | T], NCols, Dup) ->
remove_duplicates([], NCols, Dup) ->
{lists:reverse(NCols), lists:reverse(Dup)}.
+-dialyzer({nowarn_function, restore_duplicates/2}).
restore_duplicates([], Cols) ->
[{Val, OrgIndex} || {_Col, Val, OrgIndex} <- Cols];
restore_duplicates([{Col, _Val2, OrgIndex2} | Dup],
@@ -385,6 +408,7 @@ restore_duplicates(Dup, [{_Col, Val, OrgIndex} | T]) ->
%% each element in Values and OrgCols correspond to each
%% other.
%%-----------------------------------------------------------------
+-dialyzer({nowarn_function, validate_tab_res/3}).
validate_tab_res(Values, OrgCols, Mfa) when is_list(Values) ->
{_Col, _ASN1Type, OneIdx} = hd(OrgCols),
validate_tab_res(Values, OrgCols, Mfa, [], OneIdx);
@@ -407,6 +431,7 @@ validate_tab_res(Error, [{_Col, _ASN1Type, Index} | _OrgCols], Mfa) ->
?LIB:user_err("Invalid return value ~w from ~w (get)",[Error, Mfa]),
{error, genErr, Index}.
+-dialyzer({nowarn_function, validate_tab_res/5}).
validate_tab_res([Value | Values],
[{Col, ASN1Type, Index} | OrgCols],
Mfa, Res, I) ->
diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl
index f481641242..c9093fcdb9 100644
--- a/lib/snmp/src/agent/snmpa_local_db.erl
+++ b/lib/snmp/src/agent/snmpa_local_db.erl
@@ -733,16 +733,16 @@ dets_backup(close, _Cont, _D, B) ->
ok;
dets_backup(read, Cont1, D, B) ->
case dets:bchunk(D, Cont1) of
+ {error, _} = ERROR ->
+ ERROR;
+ '$end_of_table' ->
+ dets:close(B),
+ end_of_input;
{Cont2, Data} ->
F = fun(Arg) ->
dets_backup(Arg, Cont2, D, B)
end,
- {Data, F};
- '$end_of_table' ->
- dets:close(B),
- end_of_input;
- Error ->
- Error
+ {Data, F}
end.
diff --git a/lib/snmp/src/agent/snmpa_mib_storage.erl b/lib/snmp/src/agent/snmpa_mib_storage.erl
index ed0607fb84..d46dab0be0 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -120,7 +120,7 @@
-callback match_object(TabId :: mib_storage_table_id(),
Pattern :: ets:match_pattern()) ->
- {ok, Recs :: [tuple()]} | {error, Reason :: term()}.
+ Recs :: [tuple()] | {error, Reason :: term()}.
%% ---------------------------------------------------------------
@@ -133,7 +133,7 @@
-callback match_delete(TabId :: mib_storage_table_id(),
Pattern :: ets:match_pattern()) ->
- {ok, Recs :: [tuple()]} | {error, Reason :: term()}.
+ Recs :: [tuple()] | {error, Reason :: term()}.
%% ---------------------------------------------------------------
diff --git a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl
index 2459b6bc3e..0fcb8083f5 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -291,16 +291,16 @@ dets_backup(close, _Cont, _ID, B) ->
ok;
dets_backup(read, Cont1, ID, B) ->
case dets:bchunk(ID, Cont1) of
+ {error, _} = ERROR ->
+ ERROR;
+ '$end_of_table' ->
+ dets:close(B),
+ end_of_input;
{Cont2, Data} ->
F = fun(Arg) ->
dets_backup(Arg, Cont2, ID, B)
end,
- {Data, F};
- '$end_of_table' ->
- dets:close(B),
- end_of_input;
- Error ->
- Error
+ {Data, F}
end.
diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl
index 68dfa83247..173dac276e 100644
--- a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl
+++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -189,7 +189,8 @@ read(#tab{id = ID}, Key) ->
write(#tab{id = ID, rec_name = RecName}, Rec)
when (is_tuple(Rec) andalso (element(1, Rec) =:= RecName)) ->
?vtrace("write to table ~p", [ID]),
- ets:insert(ID, Rec).
+ ets:insert(ID, Rec),
+ ok.
%% ---------------------------------------------------------------
@@ -213,7 +214,9 @@ delete(#tab{id = ID, file = File}) ->
%% ---------------------------------------------------------------
delete(#tab{id = ID}, Key) ->
?vtrace("delete from table ~p: ~p", [ID, Key]),
- ets:delete(ID, Key).
+ ets:delete(ID, Key),
+ ok.
+
%% ---------------------------------------------------------------
diff --git a/lib/snmp/src/agent/snmpa_network_interface.erl b/lib/snmp/src/agent/snmpa_network_interface.erl
index 699fbde671..24985c113e 100644
--- a/lib/snmp/src/agent/snmpa_network_interface.erl
+++ b/lib/snmp/src/agent/snmpa_network_interface.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,28 +19,56 @@
%%
-module(snmpa_network_interface).
--export([behaviour_info/1]).
-
-behaviour_info(callbacks) ->
- [{start_link, 4},
- {get_log_type, 1},
- {set_log_type, 2},
- {get_request_limit, 1},
- {set_request_limit, 2},
- {info, 1},
- {verbosity, 2}];
-behaviour_info(_) ->
- undefined.
-
-
-%% behaviour_info(callbacks) ->
-%% [{start_link, 4},
-%% {send_pdu, 5},
-%% {send_response_pdu, 6},
-%% {discard_pdu, 6},
-%% {send_pdu_req, 6},
-%% {verbosity, 2},
-%% {change_log_type, 2}];
-%% behaviour_info(_) ->
-%% undefined.
+%% Note that this behaviour is not enough!
+%% There is also a set of mandatory messages which the
+%% network interface entity must be able to receive and
+%% be able to send. See the documentation for more info.
+
+-callback start_link(Prio, NoteStore, MasterAgent, Opts) ->
+ {ok, Pid} | {error, Reason} when
+ Prio :: low | normal | high, % priority_level(),
+ NoteStore :: pid(),
+ MasterAgent :: pid(),
+ Opts :: [Option],
+ Option :: {verbosity, snmp:verbosity()} |
+ {versions, [snmp:version()]} |
+ term(),
+ Pid :: pid(),
+ Reason :: term().
+
+-callback info(Pid) ->
+ Info when
+ Pid :: pid(),
+ Info :: [{Key, Value}],
+ Key :: term(),
+ Value :: term().
+
+-callback verbosity(Pid, Verbosity) ->
+ snmp:void() when
+ Pid :: pid(),
+ Verbosity :: snmp:verbosity().
+
+-callback get_log_type(Pid) ->
+ {ok, LogType} | {error, Reason} when
+ Pid :: pid(),
+ LogType :: snmp:atl_type(),
+ Reason :: term().
+
+-callback set_log_type(Pid, NewType) ->
+ {ok, OldType} | {error, Reason} when
+ Pid :: pid(),
+ NewType :: snmp:atl_type(),
+ OldType :: snmp:atl_type(),
+ Reason :: term().
+
+-callback get_request_limit(Pid) ->
+ {ok, Limit} when
+ Pid :: pid(),
+ Limit :: non_neg_integer() | infinity.
+
+-callback set_request_limit(Pid, NewLimit) ->
+ {ok, OldLimit} when
+ Pid :: pid(),
+ NewLimit :: non_neg_integer() | infinity,
+ OldLimit :: non_neg_integer() | infinity.
diff --git a/lib/snmp/src/agent/snmpa_set_mechanism.erl b/lib/snmp/src/agent/snmpa_set_mechanism.erl
index 2f24f38092..4eee7d7257 100644
--- a/lib/snmp/src/agent/snmpa_set_mechanism.erl
+++ b/lib/snmp/src/agent/snmpa_set_mechanism.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,18 +19,26 @@
%%
-module(snmpa_set_mechanism).
--export([behaviour_info/1]).
-
-behaviour_info(callbacks) ->
- [{do_set, 2}, {do_subagent_set, 1}];
-behaviour_info(_) ->
- undefined.
+%% -export([behaviour_info/1]).
+%% behaviour_info(callbacks) ->
+%% [{do_set, 2}, {do_subagent_set, 1}];
+%% behaviour_info(_) ->
+%% undefined.
+
%%-----------------------------------------------------------------
%% do_set(MibView, UnsortedVarbinds)
%%-----------------------------------------------------------------
+-callback do_set(MibView, UnsortedVBs) ->
+ {noError, 0} | {ErrStatus, ErrIndex} when
+ MibView :: snmp_view_based_acm_mib:mibview(),
+ UnsortedVBs :: [snmp:varbind()],
+ ErrStatus :: snmp:error_status(),
+ ErrIndex :: snmp:error_index().
+
+
%%-----------------------------------------------------------------
%% do_subagent_set(Args)
%%
@@ -41,3 +49,18 @@ behaviour_info(_) ->
%% [phase_two, set, UnsortedVarbinds]
%% [phase_two, undo, UnsortedVarbinds]
%%-----------------------------------------------------------------
+
+%% -callback do_subagent_set(Args) ->
+%% {noError, 0} | {ErrStatus, ErrIndex} when
+%% Args :: [phase_one, UnsortedVBs] |
+%% [phase_two, set, UnsortedVBs] |
+%% [phase_two, undo, UnsortedVBs],
+%% ErrStatus :: snmp:error_status(),
+%% ErrIndex :: snmp:error_index(),
+%% UnsortedVBs :: [snmp:varbind()].
+
+-callback do_subagent_set(Args) ->
+ {noError, 0} | {ErrStatus, ErrIndex} when
+ Args :: list(),
+ ErrStatus :: snmp:error_status(),
+ ErrIndex :: snmp:error_index().
diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl
index 2cb0556001..7d5c6da2c8 100644
--- a/lib/snmp/src/agent/snmpa_supervisor.erl
+++ b/lib/snmp/src/agent/snmpa_supervisor.erl
@@ -22,7 +22,7 @@
-behaviour(supervisor).
%% External exports
--export([start_link/2]).
+-export([start_link/2, stop/0, stop/1]).
-export([start_sub_sup/1, start_master_sup/1]).
-export([start_sub_agent/3, stop_sub_agent/1]).
@@ -91,6 +91,39 @@ start_link(master, Opts, {takeover, Node}) ->
Else
end.
+
+stop() ->
+ stop(0).
+
+stop(Timeout) ->
+ case whereis(?SERVER) of
+ Pid when is_pid(Pid) ->
+ stop(Pid, Timeout);
+ _ ->
+ not_running
+ end.
+
+%% For some unfathomable reason there is no "nice" way to stop
+%% a supervisor. The "normal" way to do it is:
+%% 1) exit(Pid, kill) (kaboom)
+%% 2) If the caller is the *parent*: exit(Pid, shutdown)
+%% So, here we do it the really ugly way...but since this function is
+%% intended for testing (mostly)...
+stop(Pid, Timeout) when (Timeout =:= 0) ->
+ sys:terminate(Pid, shutdown),
+ ok;
+stop(Pid, Timeout) ->
+ MRef = erlang:monitor(process, Pid),
+ sys:terminate(Pid, shutdown),
+ receive
+ {'DOWN', MRef, process, Pid, _} ->
+ ok
+ after Timeout ->
+ erlang:demonitor(MRef, [flush]),
+ {error, timeout}
+ end.
+
+
get_own_loaded_mibs() ->
AgentInfo = snmpa:info(snmp_master_agent),
[ Name || {Name, _, _} <- loaded_mibs(AgentInfo) ].
diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index f741c3aaa9..119207c76b 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -1115,7 +1115,7 @@ transform_taddrs(TAddrs) ->
%% v2
transform_taddr({?snmpUDPDomain, Addr}) ->
- transform_taddr(transportDomainIdpIpv4, Addr);
+ transform_taddr(transportDomainUdpIpv4, Addr);
transform_taddr({?transportDomainUdpIpv4, Addr}) ->
transform_taddr(transportDomainUdpIpv4, Addr);
transform_taddr({?transportDomainUdpIpv6, Addr}) ->
diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl
index 216452afdd..1e6a93deff 100644
--- a/lib/snmp/src/app/snmp.erl
+++ b/lib/snmp/src/app/snmp.erl
@@ -95,6 +95,9 @@
dir/0,
snmp_timer/0,
+ atl_type/0,
+ verbosity/0,
+
engine_id/0,
tdomain/0,
community/0,
@@ -188,6 +191,9 @@
-type dir() :: string().
-type snmp_timer() :: #snmp_incr_timer{}.
+-type atl_type() :: read | write | read_write.
+-type verbosity() :: info | log | debug | trace | silence.
+
-type engine_id() :: string().
-type tdomain() :: transportDomainUdpIpv4 | transportDomainUdpIpv6.
-type community() :: string().
@@ -590,15 +596,6 @@ print_mod_info(Prefix, {Module, Info}) ->
_ ->
"Not found"
end,
- CompDate =
- case key1search(compile_time, Info) of
- {value, {Year, Month, Day, Hour, Min, Sec}} ->
- io_lib:format(
- "~w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
- [Year, Month, Day, Hour, Min, Sec]);
- _ ->
- "Not found"
- end,
Digest =
case key1search(md5, Info) of
{value, MD5} when is_binary(MD5) ->
@@ -610,13 +607,11 @@ print_mod_info(Prefix, {Module, Info}) ->
"~s Vsn: ~s~n"
"~s App vsn: ~s~n"
"~s Compiler ver: ~s~n"
- "~s Compile time: ~s~n"
"~s MD5 digest: ~s~n",
[Prefix, Module,
Prefix, Vsn,
Prefix, AppVsn,
Prefix, CompVer,
- Prefix, CompDate,
Prefix, Digest]),
ok.
@@ -711,13 +706,8 @@ sys_info() ->
[{arch, SysArch}, {ver, SysVer}].
os_info() ->
- V = os:version(),
- case os:type() of
- {OsFam, OsName} ->
- [{fam, OsFam}, {name, OsName}, {ver, V}];
- OsFam ->
- [{fam, OsFam}, {ver, V}]
- end.
+ {OsFam, OsName} = os:type(),
+ [{fam, OsFam}, {name, OsName}, {ver, os:version()}].
ms1() ->
App = ?APPLICATION,
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index cf8c95d69f..8e60cecaf9 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@
%% Management API
start/0, start/1,
start_link/0, start_link/1,
- stop/0,
+ stop/0, stop/1,
monitor/0, demonitor/1,
notify_started/1, cancel_notify_started/1,
@@ -196,7 +196,12 @@ start(Opts) ->
ok.
stop() ->
- snmpm_supervisor:stop().
+ stop(0).
+
+stop(Timeout) when (Timeout =:= infinity) orelse
+ (is_integer(Timeout) andalso (Timeout >= 0)) ->
+ snmpm_supervisor:stop(Timeout).
+
monitor() ->
diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl
index 0421f49c88..d097b40438 100644
--- a/lib/snmp/src/manager/snmpm_conf.erl
+++ b/lib/snmp/src/manager/snmpm_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -356,6 +356,7 @@ read_config_file(Dir, File, Order, Check) ->
%% ---- config file utility functions ----
+-dialyzer({nowarn_function, check_ok/1}). % Future compat
check_ok(ok) ->
ok;
check_ok({ok, _}) ->
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index cd9fecd4d4..4653d9822d 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -2738,16 +2738,16 @@ dets_backup(close, _Cont, _D, B) ->
ok;
dets_backup(read, Cont1, D, B) ->
case dets:bchunk(D, Cont1) of
+ {error, _} = ERROR ->
+ ERROR;
+ '$end_of_table' ->
+ dets:close(B),
+ end_of_input;
{Cont2, Data} ->
F = fun(Arg) ->
dets_backup(Arg, Cont2, D, B)
end,
- {Data, F};
- '$end_of_table' ->
- dets:close(B),
- end_of_input;
- Error ->
- Error
+ {Data, F}
end.
diff --git a/lib/snmp/src/manager/snmpm_network_interface.erl b/lib/snmp/src/manager/snmpm_network_interface.erl
index d0f6f709d3..7123bb94f0 100644
--- a/lib/snmp/src/manager/snmpm_network_interface.erl
+++ b/lib/snmp/src/manager/snmpm_network_interface.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,19 +20,61 @@
-module(snmpm_network_interface).
--export([behaviour_info/1]).
-
-behaviour_info(callbacks) ->
- [{start_link, 2},
- {stop, 1},
- {send_pdu, 7},
- {inform_response, 4},
- {note_store, 2},
- {info, 1},
- {verbosity, 2},
- %% {system_info_updated, 2},
- {get_log_type, 1},
- {set_log_type, 2}];
-behaviour_info(_) ->
- undefined.
+-callback start_link(Server, NoteStore) ->
+ {ok, Pid} | {error, Reason} when
+ Server :: pid(),
+ NoteStore :: pid(),
+ Pid :: pid(),
+ Reason :: term().
+
+-callback stop(Pid) ->
+ snmp:void() when
+ Pid :: pid().
+
+-callback send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo) ->
+ snmp:void() when
+ Pid :: pid(),
+ Pdu :: snmp:pdu(),
+ Vsn :: 'version-1' | 'version-2' | 'version-3',
+ MsgData :: term(),
+ Domain :: snmp:tdomain(),
+ Addr :: {inet:ip_address(), inet:port_number()},
+ ExtraInfo :: term().
+
+-callback inform_response(Pid, Ref, Addr, Port) ->
+ snmp:void() when
+ Pid :: pid(),
+ Ref :: term(),
+ Addr :: inet:ip_address(),
+ Port :: inet:port_number().
+
+-callback note_store(Pid, NoteStore) ->
+ snmp:void() when
+ Pid :: pid(),
+ NoteStore :: pid().
+
+-callback info(Pid) ->
+ Info when
+ Pid :: pid(),
+ Info :: [{Key, Value}],
+ Key :: term(),
+ Value :: term().
+
+-callback verbosity(Pid, Verbosity) ->
+ snmp:void() when
+ Pid :: pid(),
+ Verbosity :: snmp:verbosity().
+
+-callback get_log_type(Pid) ->
+ {ok, LogType} | {error, Reason} when
+ Pid :: pid(),
+ LogType :: snmp:atl_type(),
+ Reason :: term().
+
+-callback set_log_type(Pid, NewType) ->
+ {ok, OldType} | {error, Reason} when
+ Pid :: pid(),
+ NewType :: snmp:atl_type(),
+ OldType :: snmp:atl_type(),
+ Reason :: term().
diff --git a/lib/snmp/src/manager/snmpm_supervisor.erl b/lib/snmp/src/manager/snmpm_supervisor.erl
index c36bbe1bdd..bc66025c6f 100644
--- a/lib/snmp/src/manager/snmpm_supervisor.erl
+++ b/lib/snmp/src/manager/snmpm_supervisor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
%% External exports
--export([start_link/2, stop/0]).
+-export([start_link/2, stop/0, stop/1]).
%% supervisor callbacks
-export([init/1]).
@@ -38,26 +38,54 @@
%%%-------------------------------------------------------------------
%%% API
%%%-------------------------------------------------------------------
+
start_link(Type, Opts) ->
?d("start_link -> entry with"
"~n Opts: ~p", [Opts]),
SupName = {local, ?MODULE},
supervisor:start_link(SupName, ?MODULE, [Type, Opts]).
+
stop() ->
+ stop(0).
+
+stop(Timeout) ->
?d("stop -> entry", []),
case whereis(?SERVER) of
Pid when is_pid(Pid) ->
- ?d("stop -> Pid: ~p", [Pid]),
- exit(Pid, shutdown),
- ?d("stop -> stopped", []),
- ok;
+ stop(Pid, Timeout);
_ ->
?d("stop -> not running", []),
not_running
end.
+%% For some unfathomable reason there is no "nice" way to stop
+%% a supervisor. The "normal" way to do it is:
+%% 1) exit(Pid, kill) (kaboom)
+%% 2) If the caller is the *parent*: exit(Pid, shutdown)
+%% So, here we do it the really ugly way...but since this function is
+%% intended for testing (mostly)...
+stop(Pid, Timeout) when (Timeout =:= 0) ->
+ ?d("stop -> Pid: ~p", [Pid]),
+ sys:terminate(Pid, shutdown),
+ ?d("stop -> stopped", []),
+ ok;
+stop(Pid, Timeout) ->
+ ?d("stop -> Pid: ~p", [Pid]),
+ MRef = erlang:monitor(process, Pid),
+ sys:terminate(Pid, shutdown),
+ receive
+ {'DOWN', MRef, process, Pid, _} ->
+ ?d("stop -> stopped", []),
+ ok
+ after Timeout ->
+ ?d("stop -> timeout", []),
+ erlang:demonitor(MRef, [flush]),
+ {error, timeout}
+ end.
+
+
%%%-------------------------------------------------------------------
%%% Callback functions from supervisor
%%%-------------------------------------------------------------------
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index d73291764d..20b7af0373 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -164,6 +164,14 @@ no_filter(X) -> X.
%% An ordering function (A, B) shall return true iff
%% A is less than or equal to B i.e shall return
%% false iff A is to be ordered after B.
+
+-spec keyorder(N, A, B, Keys) ->
+ boolean() when
+ N :: integer(),
+ A :: tuple(),
+ B :: tuple(),
+ Keys :: maybe_improper_list().
+
keyorder(N, A, B, _) when element(N, A) == element(N, B) ->
true;
keyorder(N, A, B, [Key | _])
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index 26e85897f4..3104f2a096 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -96,17 +96,15 @@
]).
--export_type([void/0,
- order_config_entry_function/0,
+-export_type([
+ order_config_entry_function/0,
check_config_entry_function/0,
- write_config_function/0]).
+ write_config_function/0
+ ]).
%%----------------------------------------------------------------------
--type void() :: term(). % Any value - ignored
-
-
%%----------------------------------------------------------------------
%% Handy SNMP configuration
%%----------------------------------------------------------------------
@@ -1106,6 +1104,7 @@ verify_sec_type(ST) -> {error, "invalid security type: " ++ ST}.
verify_address(A) ->
verify_address(A, snmpUDPDomain).
+-dialyzer({nowarn_function, verify_address/2}). % Future compat
verify_address(A, snmpUDPDomain = _Domain) ->
do_verify_address(A, inet);
verify_address(A, transportDomainUdpIpv4 = _Domain) ->
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index 5713c14912..8a4dfa621b 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -342,9 +342,9 @@ validate_loop({Cont, Terms, BadBytes}, Log, Validator, PrevTS, PrevSN) ->
?vtrace("validate_loop -> "
"~n NextTS: ~p"
"~n NextSN: ~p", [NextTS, NextSN]),
- validate_loop(disk_log:chunk(Log, Cont), Log, Validator, NextTS, NextSN);
-validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) ->
- Error.
+ validate_loop(disk_log:chunk(Log, Cont), Log, Validator, NextTS, NextSN).
+%% validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) ->
+%% Error.
%% -- log ---
@@ -924,14 +924,7 @@ f(TimeStamp, SeqNo,
end,
format_tab(
"~w ~s - ~s [~s]~s ~w\n~s",
- [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]);
-f(TimeStamp, SeqNo, Msg, AddrStr, _Mib) ->
- io:format("<ERROR> Unexpected data: "
- "~n TimeStamp: ~s~s"
- "~n Msg: ~p"
- "~n AddrStr: ~p"
- "~n", [TimeStamp, SeqNo, Msg, AddrStr]),
- throw({error, 'invalid-message'}).
+ [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
f(F, A) ->
lists:flatten(io_lib:format(F, A)).
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile
index a9142d911d..d9b01536ea 100644
--- a/lib/snmp/test/Makefile
+++ b/lib/snmp/test/Makefile
@@ -180,7 +180,7 @@ emakebuild: $(EMAKEFILE)
targets: mib $(EMAKEFILE)
erl -make
-old_targets: $(TARGET_FILES) $(TEST_SERVER_TARGETS)
+old_targets: mib $(TARGET_FILES) $(TEST_SERVER_TARGETS)
$(EMAKEFILE): Makefile
$(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' > $(EMAKEFILE)
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index 8b6547f9a9..ec3870dbd8 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -42,6 +42,8 @@ SUITE_MODULES = \
snmp_manager_test
TEST_UTIL_MODULES = \
+ snmp_test_global_sys_monitor \
+ snmp_test_sys_monitor \
snmp_test_lib \
snmp_test_manager \
snmp_test_mgr \
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index 860ca17cdb..a45cfa9e98 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -557,6 +557,8 @@ init_per_suite(Config0) when is_list(Config0) ->
Config3 = [{mib_dir, MibDir}, {std_mib_dir, StdMibDir} | Config2],
+ snmp_test_global_sys_monitor:start(),
+ snmp_test_sys_monitor:start(), % We need one on this node also
snmp_test_mgr_counter_server:start(),
p("init_per_suite -> end when"
@@ -580,6 +582,8 @@ end_per_suite(Config) when is_list(Config) ->
p("end_per_suite -> failed stopping counter server"
"~n Reason: ~p", [Reason])
end,
+ snmp_test_sys_monitor:stop(),
+ snmp_test_global_sys_monitor:stop(),
p("end_per_suite -> end when"
"~n Nodes: ~p", [erlang:nodes()]),
@@ -768,6 +772,8 @@ init_per_testcase(Case, Config) when is_list(Config) ->
Result = init_per_testcase1(Case, Config),
+ snmp_test_global_sys_monitor:reset_events(),
+
p("init_per_testcase -> done when"
"~n Result: ~p"
"~n Nodes: ~p", [Result, erlang:nodes()]),
@@ -817,6 +823,9 @@ end_per_testcase(Case, Config) when is_list(Config) ->
"~n Nodes: ~p", [Config, erlang:nodes()]),
display_log(Config),
+
+ p("system events during test: "
+ "~n ~p", [snmp_test_global_sys_monitor:events()]),
Result = end_per_testcase1(Case, Config),
@@ -1654,7 +1663,7 @@ create_local_db_dir(Config) when is_list(Config) ->
Name = list_to_atom(atom_to_list(create_local_db_dir)
++"-"++As++"-"++Bs++"-"++Cs),
Pa = filename:dirname(code:which(?MODULE)),
- {ok,Node} = ?t:start_node(Name, slave, [{args, "-pa "++Pa}]),
+ {ok,Node} = ?t:start_node(Name, slave, [{args, "-pa " ++ Pa}]),
%% first start with a nonexisting DbDir
Fun1 = fun() ->
@@ -6584,7 +6593,6 @@ otp_4394_test() ->
gn([[1,1]]),
Res =
case snmp_test_mgr:expect(1, [{[sysDescr,0], "Erlang SNMP agent"}]) of
- %% {error, 1, {"?",[]}, {"~w",[timeout]}}
{error, 1, _, {_, [timeout]}} ->
?DBG("otp_4394_test -> expected result: timeout", []),
ok;
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 1128fc8a8c..c0da47dc4c 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -319,7 +319,7 @@ tc_try(N, M, F, A) ->
await_tc_runner_done(Runner, OldFlag);
pang ->
?EPRINT2("tc_try -> ~p *not* running~n", [N]),
- exit({node_not_running, N})
+ skip({node_not_running, N})
end.
await_tc_runner_started(Runner, OldFlag) ->
@@ -332,7 +332,7 @@ await_tc_runner_started(Runner, OldFlag) ->
{tc_runner_started, Runner} ->
?PRINT2("TC runner start acknowledged~n"),
ok
- after 10000 ->
+ after 10000 -> %% We should *really* not have to wait this long, but...
trap_exit(OldFlag),
unlink_and_flush_exit(Runner),
RunnerInfo = process_info(Runner),
@@ -346,9 +346,31 @@ await_tc_runner_started(Runner, OldFlag) ->
await_tc_runner_done(Runner, OldFlag) ->
receive
{'EXIT', Runner, Reason} ->
- ?EPRINT2("TC runner failed: "
- "~n ~p~n", [Reason]),
- exit({tx_runner_failed, Reason});
+ %% This is not a normal (tc) failure (that is the clause below).
+ %% Instead the tc runner process crashed, for some reason. So
+ %% check if have got any system events, and if so, skip.
+ SysEvs = snmp_test_global_sys_monitor:events(),
+ if
+ (SysEvs =:= []) ->
+ ?EPRINT2("TC runner failed: "
+ "~n ~p~n", [Reason]),
+ exit({tx_runner_failed, Reason});
+ true ->
+ ?EPRINT2("TC runner failed when we got system events: "
+ "~n Reason: ~p"
+ "~n Sys Events: ~p"
+ "~n", [Reason, SysEvs]),
+ skip([{reason, Reason}, {system_events, SysEvs}])
+ end;
+ {tc_runner_done, Runner, {'EXIT', {skip, Reason}}, Loc} ->
+ ?PRINT2("call -> done with skip: "
+ "~n Reason: ~p"
+ "~n Loc: ~p"
+ "~n", [Reason, Loc]),
+ trap_exit(OldFlag),
+ unlink_and_flush_exit(Runner),
+ put(test_server_loc, Loc),
+ skip(Reason);
{tc_runner_done, Runner, {'EXIT', Rn}, Loc} ->
?PRINT2("call -> done with exit: "
"~n Rn: ~p"
@@ -367,6 +389,8 @@ await_tc_runner_done(Runner, OldFlag) ->
case Ret of
{error, Reason} ->
exit(Reason);
+ {skip, Reason} ->
+ skip(Reason);
OK ->
OK
end
@@ -399,7 +423,18 @@ tc_wait(From, Env, M, F, A) ->
"~n ~p"
"~n", [Res]),
From ! {tc_runner_done, self(), Res, get(test_server_loc)},
- exit(Res).
+ %% The point of this is that in some cases we have seen that the
+ %% exit signal having been "passed on" to the CT, which consider any
+ %% exit a fail (even if its {'EXIT', ok}).
+ %% So, just to be on the safe side, convert an 'ok' to a 'normal'.
+ case Res of
+ ok ->
+ exit(normal);
+ {ok, _} ->
+ exit(normal);
+ _ ->
+ exit(Res)
+ end.
tc_run(Mod, Func, Args, Opts) ->
?PRINT2("tc_run -> entry with"
@@ -451,9 +486,30 @@ tc_run(Mod, Func, Args, Opts) ->
{mibs, mibs(StdM, M)}]) of
{ok, _Pid} ->
case (catch apply(Mod, Func, Args)) of
+ {'EXIT', {skip, Reason}} ->
+ ?EPRINT2("apply skip detected: "
+ "~n ~p", [Reason]),
+ (catch snmp_test_mgr:stop()),
+ ?SKIP(Reason);
{'EXIT', Reason} ->
+ %% We have hosts (mostly *very* slooow VMs) that
+ %% can timeout anything. Since we are basically
+ %% testing communication, we therefor must check
+ %% for system events at every failure. Grrr!
+ SysEvs = snmp_test_global_sys_monitor:events(),
(catch snmp_test_mgr:stop()),
- ?FAIL({apply_failed, {Mod, Func, Args}, Reason});
+ if
+ (SysEvs =:= []) ->
+ ?EPRINT2("TC runner failed: "
+ "~n ~p~n", [Reason]),
+ ?FAIL({apply_failed, {Mod, Func, Args}, Reason});
+ true ->
+ ?EPRINT2("apply exit catched when we got system events: "
+ "~n Reason: ~p"
+ "~n Sys Events: ~p"
+ "~n", [Reason, SysEvs]),
+ ?SKIP([{reason, Reason}, {system_events, SysEvs}])
+ end;
Res ->
(catch snmp_test_mgr:stop()),
Res
@@ -982,10 +1038,22 @@ expect2(Mod, Line, F) ->
%% ----------------------------------------------------------------------
-get_timeout() ->
- get_timeout(os:type()).
+-define(BASE_REQ_TIMEOUT, 3500).
-get_timeout(_) -> 3500.
+get_timeout() ->
+ %% Try to figure out how "fast" a machine is.
+ %% We assume that the number of schedulers
+ %% (which depends on the number of core:s)
+ %% effect the performance of the host...
+ %% This is obviously not enough. The network
+ %% also matterns, clock freq or the CPU, ...
+ %% But its better than what we had before...
+ case erlang:system_info(schedulers) of
+ N when is_integer(N) ->
+ ?BASE_REQ_TIMEOUT + timer:seconds(10 div N);
+ _ ->
+ ?BASE_REQ_TIMEOUT
+ end.
receive_pdu(To) ->
receive
@@ -1158,6 +1226,18 @@ do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) ->
{PureE, Generic, Specific, ExpVBs},
{Ent2, G2, Spec2, VBs}}};
+ {error, timeout} = Error ->
+ SysEvs = snmp_test_global_sys_monitor:events(),
+ io_format_expect("[expecting trap] got timeout when system events:"
+ "~n ~p", [SysEvs]),
+ if
+ (SysEvs =:= []) ->
+ Error;
+ true ->
+ skip({system_events, SysEvs})
+ end;
+
+
Error ->
Error
end.
@@ -1259,7 +1339,7 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
io_format_expect("received unexpected pdu with (11) "
"~n Type: ~p"
"~n ReqId: ~p"
- "~n Errot status: ~p"
+ "~n Error status: ~p"
"~n Error index: ~p",
[Type2, ReqId, Err2, Idx2]),
{error,
@@ -1322,7 +1402,7 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
io_format_expect("received unexpected pdu with (15) "
"~n Type: ~p"
"~n ReqId: ~p"
- "~n Errot status: ~p"
+ "~n Error status: ~p"
"~n Error index: ~p"
"~n Varbinds: ~p",
[Type2, ReqId, Err2, Idx2, VBs2]),
@@ -1332,10 +1412,23 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
{Type2, Err2, Idx2, VBs2},
ReqId}};
- Error ->
- io_format_expect("received error (16): "
+
+ {error, timeout} = Error ->
+ SysEvs = snmp_test_global_sys_monitor:events(),
+ io_format_expect("got timeout (16) when system events:"
+ "~n ~p", [SysEvs]),
+ if
+ (SysEvs =:= []) ->
+ Error;
+ true ->
+ skip({system_events, SysEvs})
+ end;
+
+
+ Error ->
+ io_format_expect("received error (17): "
"~n Error: ~p", [Error]),
- Error
+ Error
end.
@@ -1453,12 +1546,15 @@ start_node(Name) ->
""
end,
%% Do not use start_link!!! (the proc that calls this one is tmp)
- ?DBG("start_node -> Args: ~p~n",[Args]),
- A = Args ++ " -pa " ++ Pa,
+ ?DBG("start_node -> Args: ~p~n", [Args]),
+ A = Args ++ " -pa " ++ Pa ++
+ " -s " ++ atom_to_list(snmp_test_sys_monitor) ++ " start" ++
+ " -s global sync",
case (catch ?START_NODE(Name, A)) of
{ok, Node} ->
%% Tell the test_server to not clean up things it never started.
?DBG("start_node -> Node: ~p",[Node]),
+ global:sync(),
{ok, Node};
Else ->
?ERR("start_node -> failed with(other): Else: ~p",[Else]),
@@ -1776,6 +1872,10 @@ rpc(Node, F, A) ->
join(Dir, File) ->
filename:join(Dir, File).
+
+skip(R) ->
+ exit({skip, R}).
+
%% await_pdu(To) ->
%% await_response(To, pdu).
%%
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index d959d9e09b..c31bb92e1f 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@
register_user1/1,
- register_agent1/1,
+ register_agent_old/1,
register_agent2/1,
register_agent3/1,
@@ -185,7 +185,6 @@ end_per_suite(Config) when is_list(Config) ->
init_per_testcase(Case, Config) when is_list(Config) ->
- io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
p(Case, "init_per_testcase begin when"
"~n Nodes: ~p~n~n", [erlang:nodes()]),
%% This version of the API, based on Addr and Port, has been deprecated
@@ -204,13 +203,15 @@ init_per_testcase(Case, Config) when is_list(Config) ->
Result =
case lists:member(Case, DeprecatedApiCases) of
true ->
- {skip, api_no_longer_supported};
+ {skip, "API no longer supported"};
false ->
try init_per_testcase2(Case, Config)
catch
- C:{skip, _} = E:_ when ((C =:= throw) orelse (C =:= exit)) ->
+ C:{skip, _} = E:_ when ((C =:= throw) orelse
+ (C =:= exit)) ->
E;
- C:E:_ when ((C =:= throw) orelse (C =:= exit)) ->
+ C:E:_ when ((C =:= throw) orelse
+ (C =:= exit)) ->
{skip, {catched, C, E}}
end
end,
@@ -479,7 +480,7 @@ groups() ->
},
{agent_tests, [],
[
- register_agent1,
+ register_agent_old,
register_agent2,
register_agent3
]
@@ -595,7 +596,7 @@ groups() ->
ipv6_tests() ->
[
- register_agent1,
+ register_agent_old,
simple_sync_get_next3,
simple_async_get2,
simple_sync_get3,
@@ -671,11 +672,11 @@ end_per_group(_GroupName, Config) ->
simple_start_and_stop1(suite) -> [];
simple_start_and_stop1(Config) when is_list(Config) ->
- %% ?SKIP(not_yet_implemented),
- process_flag(trap_exit, true),
- put(tname,ssas1),
- p("starting with Config: ~n~p", [Config]),
+ ?TC_TRY(simple_start_and_stop1,
+ fun() -> do_simple_start_and_stop1(Config) end).
+do_simple_start_and_stop1(Config) ->
+ p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -696,7 +697,6 @@ simple_start_and_stop1(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -704,9 +704,10 @@ simple_start_and_stop1(Config) when is_list(Config) ->
simple_start_and_stop2(suite) -> [];
simple_start_and_stop2(Config) when is_list(Config) ->
- %% ?SKIP(not_yet_implemented),
- process_flag(trap_exit, true),
- put(tname,ssas2),
+ ?TC_TRY(simple_start_and_stop2,
+ fun() -> do_simple_start_and_stop2(Config) end).
+
+do_simple_start_and_stop2(Config) ->
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -744,7 +745,6 @@ simple_start_and_stop2(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -752,8 +752,10 @@ simple_start_and_stop2(Config) when is_list(Config) ->
simple_start_and_monitor_crash1(suite) -> [];
simple_start_and_monitor_crash1(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,ssamc1),
+ ?TC_TRY(simple_start_and_monitor_crash1,
+ fun() -> do_simple_start_and_monitor_crash1(Config) end).
+
+do_simple_start_and_monitor_crash1(Config) ->
p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -797,7 +799,6 @@ simple_start_and_monitor_crash1(Config) when is_list(Config) ->
?FAIL(timeout)
end,
- p("end"),
ok.
@@ -805,8 +806,10 @@ simple_start_and_monitor_crash1(Config) when is_list(Config) ->
simple_start_and_monitor_crash2(suite) -> [];
simple_start_and_monitor_crash2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,ssamc2),
+ ?TC_TRY(simple_start_and_monitor_crash2,
+ fun() -> do_simple_start_and_monitor_crash2(Config) end).
+
+do_simple_start_and_monitor_crash2(Config) ->
p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -851,7 +854,6 @@ simple_start_and_monitor_crash2(Config) when is_list(Config) ->
?FAIL(timeout)
end,
- p("end"),
ok.
@@ -897,8 +899,10 @@ simulate_crash(NumKills, _) ->
notify_started01(suite) -> [];
notify_started01(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,ns01),
+ ?TC_TRY(notify_started01,
+ fun() -> do_notify_started01(Config) end).
+
+do_notify_started01(Config) ->
p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -985,37 +989,34 @@ snmpm_starter(Opts, To) ->
notify_started02(suite) -> [];
notify_started02(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,ns02),
+ ?TC_TRY(notify_started02,
+ fun() -> notify_started02_cond(Config) end,
+ fun() -> do_notify_started02(Config) end).
- %% <CONDITIONAL-SKIP>
- %% The point of this is to catch machines running
- %% SLES9 (2.6.5)
+notify_started02_cond(Config) ->
LinuxVersionVerify =
fun() ->
case os:cmd("uname -m") of
"i686" ++ _ ->
-%% io:format("found an i686 machine, "
-%% "now check version~n", []),
case os:version() of
{2, 6, Rev} when Rev >= 16 ->
- true;
+ false;
{2, Min, _} when Min > 6 ->
- true;
+ false;
{Maj, _, _} when Maj > 2 ->
- true;
+ false;
_ ->
- false
+ true
end;
_ ->
- true
+ false
end
end,
Skippable = [{unix, [{linux, LinuxVersionVerify}]}],
Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
- ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
- %% </CONDITIONAL-SKIP>
-
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition).
+
+do_notify_started02(Config) ->
p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -1023,10 +1024,10 @@ notify_started02(Config) when is_list(Config) ->
write_manager_conf(ConfDir),
- Opts = [{server, [{verbosity, log}]},
- {net_if, [{verbosity, silence}]},
+ Opts = [{server, [{verbosity, log}]},
+ {net_if, [{verbosity, silence}]},
{note_store, [{verbosity, silence}]},
- {config, [{verbosity, log}, {dir, ConfDir}, {db_dir, DbDir}]}],
+ {config, [{verbosity, debug}, {dir, ConfDir}, {db_dir, DbDir}]}],
p("start snmpm client process"),
NumIterations = 5,
@@ -1056,8 +1057,14 @@ notify_started02(Config) when is_list(Config) ->
p("await snmpm client process exit (max ~p+10000 msec)", [ApproxStartTime]),
receive
+ %% We take this opportunity to check if we got a skip from
+ %% the ctrl process.
+ {'EXIT', Pid2, {skip, SkipReason1}} ->
+ ?SKIP(SkipReason1);
{'EXIT', Pid1, normal} ->
ok;
+ {'EXIT', Pid1, {suite_failed, Reason1}} ->
+ ?FAIL({client, Reason1});
{'EXIT', Pid1, Reason1} ->
?FAIL({client, Reason1})
after ApproxStartTime + 10000 ->
@@ -1070,6 +1077,9 @@ notify_started02(Config) when is_list(Config) ->
receive
{'EXIT', Pid2, normal} ->
ok;
+ {'EXIT', Pid2, {skip, SkipReason2}} ->
+ %% In case of a race
+ ?SKIP(SkipReason2);
{'EXIT', Pid2, Reason2} ->
?FAIL({ctrl, Reason2})
after 5000 ->
@@ -1094,7 +1104,7 @@ ns02_client_await_approx_runtime(Pid) ->
"~n ~p", [Pid, Reason]),
{error, Reason}
- after 15000 ->
+ after 30000 ->
%% Either something is *really* wrong or this machine
%% is dog slow. Either way, this is a skip-reason...
{skip, approx_runtime_timeout}
@@ -1159,6 +1169,12 @@ ns02_ctrl(Opts, N) ->
p("starting"),
ns02_ctrl_loop(Opts, N).
+
+%% We have seen that some times it takes unreasonably long time to
+%% start the manager (it got "stuck" in snmpm_config). But since
+%% we did not have enough verbosity, we do not know how far it got.
+%% So, we try to monitor each start attempt. We allow 5 sec (just
+%% to give slow boxes a chance).
ns02_ctrl_loop(_Opts, 0) ->
p("done"),
exit(normal);
@@ -1166,19 +1182,45 @@ ns02_ctrl_loop(Opts, N) ->
p("entry when N: ~p", [N]),
?SLEEP(2000),
p("start manager"),
- snmpm:start(Opts),
+ TS1 = erlang:system_time(millisecond),
+ {StarterPid, StarterMRef} =
+ erlang:spawn_monitor(fun() -> exit(snmpm:start(Opts)) end),
+ receive
+ {'DOWN', StarterMRef, process, StarterPid, ok} ->
+ TS2 = erlang:system_time(millisecond),
+ p("manager started: ~w ms", [TS2-TS1]),
+ ok
+ after 5000 ->
+ p("manager (~p) start timeout - kill", [StarterPid]),
+ exit(StarterPid, kill),
+ exit({skip, start_timeout})
+ end,
?SLEEP(2000),
p("stop manager"),
- snmpm:stop(),
+ ?SLEEP(100), % Give the verbosity to take effect...
+ TS3 = erlang:system_time(millisecond),
+ case snmpm:stop(5000) of
+ ok ->
+ TS4 = erlang:system_time(millisecond),
+ p("manager stopped: ~p ms", [TS4-TS3]),
+ ok;
+ {error, timeout} ->
+ p("manager stop timeout - kill (cleanup) and skip"),
+ exit(whereis(snmpm_supervisor), kill),
+ exit({skip, stop_timeout})
+ end,
ns02_ctrl_loop(Opts, N-1).
+
%%======================================================================
info(suite) -> [];
info(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,info),
+ ?TC_TRY(info,
+ fun() -> do_info(Config) end).
+
+do_info(Config) ->
p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -1206,7 +1248,6 @@ info(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
verify_info(Info) when is_list(Info) ->
@@ -1246,9 +1287,10 @@ verify_info([{Key, SubKeys}|Keys], Info) ->
register_user1(suite) -> [];
register_user1(Config) when is_list(Config) ->
- %% ?SKIP(not_yet_implemented).
- process_flag(trap_exit, true),
- put(tname,ru1),
+ ?TC_TRY(register_user1,
+ fun() -> do_register_user1(Config) end).
+
+do_register_user1(Config) ->
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -1322,7 +1364,6 @@ register_user1(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
verify_users([], []) ->
@@ -1340,14 +1381,15 @@ verify_users(ActualUsers0, [User|RegUsers]) ->
%%======================================================================
-register_agent1(doc) ->
+register_agent_old(doc) ->
["Test registration of agents with the OLD interface functions"];
-register_agent1(suite) ->
+register_agent_old(suite) ->
[];
-register_agent1(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,ra1),
-
+register_agent_old(Config) when is_list(Config) ->
+ ?TC_TRY(register_agent_old,
+ fun() -> do_register_agent_old(Config) end).
+
+do_register_agent_old(Config) ->
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -1462,7 +1504,6 @@ register_agent1(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -1473,8 +1514,10 @@ register_agent2(doc) ->
register_agent2(suite) ->
[];
register_agent2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ra2),
+ ?TC_TRY(register_agent2,
+ fun() -> do_register_agent2(Config) end).
+
+do_register_agent2(Config) ->
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -1607,7 +1650,6 @@ register_agent2(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -1619,8 +1661,10 @@ register_agent3(doc) ->
register_agent3(suite) ->
[];
register_agent3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ra3),
+ ?TC_TRY(register_agent3,
+ fun() -> do_register_agent3(Config) end).
+
+do_register_agent3(Config) ->
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -1757,7 +1801,6 @@ register_agent3(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -1766,10 +1809,11 @@ register_agent3(Config) when is_list(Config) ->
simple_sync_get1(doc) -> ["Simple sync get-request - Old style (Addr & Port)"];
simple_sync_get1(suite) -> [];
simple_sync_get1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_sync_get1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_get1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssg1),
+do_simple_sync_get1(Config) ->
p("starting with Config: ~p~n", [Config]),
Node = ?config(manager_node, Config),
@@ -1828,18 +1872,18 @@ simple_sync_get2(doc) ->
["Simple sync get-request - Version 2 API (TargetName)"];
simple_sync_get2(suite) -> [];
simple_sync_get2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssg2),
- do_simple_sync_get2(Config),
- display_log(Config),
- ok.
+ ?TC_TRY(simple_sync_get2,
+ fun() -> do_simple_sync_get2(Config) end).
do_simple_sync_get2(Config) ->
+ p("starting with Config: ~n~p", [Config]),
Get = fun(Node, TargetName, Oids) ->
mgr_user_sync_get(Node, TargetName, Oids)
end,
PostVerify = fun() -> ok end,
- do_simple_sync_get2(Config, Get, PostVerify).
+ do_simple_sync_get2(Config, Get, PostVerify),
+ display_log(Config),
+ ok.
do_simple_sync_get2(Config, Get, PostVerify) ->
p("starting with Config: ~p~n", [Config]),
@@ -1895,13 +1939,11 @@ simple_sync_get3(doc) ->
["Simple sync get-request - Version 3 API (TargetName and send-opts)"];
simple_sync_get3(suite) -> [];
simple_sync_get3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssg3),
- do_simple_sync_get3(Config),
- display_log(Config),
- ok.
+ ?TC_TRY(simple_sync_get3,
+ fun() -> do_simple_sync_get3(Config) end).
do_simple_sync_get3(Config) ->
+ p("starting with Config: ~n~p", [Config]),
Self = self(),
Msg = simple_sync_get3,
Fun = fun() -> Self ! Msg end,
@@ -1920,7 +1962,9 @@ do_simple_sync_get3(Config) ->
ok
end
end,
- do_simple_sync_get2(Config, Get, PostVerify).
+ do_simple_sync_get2(Config, Get, PostVerify),
+ display_log(Config),
+ ok.
%%======================================================================
@@ -1929,10 +1973,11 @@ simple_async_get1(doc) ->
["Simple (async) get-request - Old style (Addr & Port)"];
simple_async_get1(suite) -> [];
simple_async_get1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_async_get1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_get1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sag1),
+do_simple_async_get1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2033,8 +2078,10 @@ simple_async_get2(doc) ->
["Simple (async) get-request - Version 2 API (TargetName)"];
simple_async_get2(suite) -> [];
simple_async_get2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sag2),
+ ?TC_TRY(simple_async_get2,
+ fun() -> do_simple_async_get2(Config) end).
+
+do_simple_async_get2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2114,8 +2161,10 @@ simple_async_get3(doc) ->
["Simple (async) get-request - Version 3 API (TargetName and send-opts)"];
simple_async_get3(suite) -> [];
simple_async_get3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sag3),
+ ?TC_TRY(simple_async_get3,
+ fun() -> do_simple_async_get3(Config) end).
+
+do_simple_async_get3(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2146,10 +2195,11 @@ simple_sync_get_next1(doc) -> ["Simple (sync) get_next-request - "
"Old style (Addr & Port)"];
simple_sync_get_next1(suite) -> [];
simple_sync_get_next1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_sync_get_next1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_get_next1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssgn1),
+do_simple_sync_get_next1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2287,8 +2337,10 @@ simple_sync_get_next2(doc) ->
["Simple (sync) get_next-request - Version 2 API (TargetName)"];
simple_sync_get_next2(suite) -> [];
simple_sync_get_next2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssgn2),
+ ?TC_TRY(simple_sync_get_next2,
+ fun() -> do_simple_sync_get_next2(Config) end).
+
+do_simple_sync_get_next2(Config) ->
p("starting with Config: ~p~n", [Config]),
GetNext = fun(Node, TargetName, Oids) ->
@@ -2440,10 +2492,11 @@ simple_async_get_next1(doc) -> ["Simple (async) get_next-request - "
"Old style (Addr & Port)"];
simple_async_get_next1(suite) -> [];
simple_async_get_next1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_async_get_next1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_get_next1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssgn1),
+do_simple_async_get_next1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2540,8 +2593,10 @@ simple_async_get_next2(doc) ->
["Simple (async) get_next-request - Version 2 API (TargetName)"];
simple_async_get_next2(suite) -> [];
simple_async_get_next2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssgn2),
+ ?TC_TRY(simple_async_get_next2,
+ fun() -> do_simple_async_get_next2(Config) end).
+
+do_simple_async_get_next2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2651,8 +2706,10 @@ simple_async_get_next3(doc) ->
"Version 3 API (TargetName with send-opts)"];
simple_async_get_next3(suite) -> [];
simple_async_get_next3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssgn2),
+ ?TC_TRY(simple_async_get_next3,
+ fun() -> do_simple_async_get_next3(Config) end).
+
+do_simple_async_get_next3(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2694,10 +2751,11 @@ simple_sync_set1(doc) -> ["Simple (sync) set-request - "
"Old style (Addr & Port)"];
simple_sync_set1(suite) -> [];
simple_sync_set1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_sync_set1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_set1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sss1),
+do_simple_sync_set1(Config) ->
p("starting with Config: ~p~n", [Config]),
Node = ?config(manager_node, Config),
@@ -2767,8 +2825,10 @@ simple_sync_set2(doc) ->
["Simple (sync) set-request - Version 2 API (TargetName)"];
simple_sync_set2(suite) -> [];
simple_sync_set2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sss2),
+ ?TC_TRY(simple_sync_set2,
+ fun() -> do_simple_sync_set2(Config) end).
+
+do_simple_sync_set2(Config) ->
p("starting with Config: ~p~n", [Config]),
Set = fun(Node, TargetName, VAVs) ->
@@ -2837,8 +2897,10 @@ simple_sync_set3(doc) ->
["Simple (sync) set-request - Version 3 API (TargetName with send-opts)"];
simple_sync_set3(suite) -> [];
simple_sync_set3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sss3),
+ ?TC_TRY(simple_sync_set3,
+ fun() -> do_simple_sync_set3(Config) end).
+
+do_simple_sync_set3(Config) ->
p("starting with Config: ~p~n", [Config]),
Self = self(),
@@ -2866,10 +2928,11 @@ simple_async_set1(doc) -> ["Simple (async) set-request - "
"Old style (Addr & Port)"];
simple_async_set1(suite) -> [];
simple_async_set1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_async_set1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_set1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sas1),
+do_simple_async_set1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2961,8 +3024,10 @@ simple_async_set2(doc) ->
["Simple (async) set-request - Version 2 API (TargetName)"];
simple_async_set2(suite) -> [];
simple_async_set2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sas2),
+ ?TC_TRY(simple_async_set2,
+ fun() -> do_simple_async_set2(Config) end).
+
+do_simple_async_set2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3034,8 +3099,10 @@ simple_async_set3(doc) ->
["Simple (async) set-request - Version 3 API (TargetName with send-opts)"];
simple_async_set3(suite) -> [];
simple_async_set3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sas3),
+ ?TC_TRY(simple_async_set3,
+ fun() -> do_simple_async_set3(Config) end).
+
+do_simple_async_set3(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3078,10 +3145,11 @@ simple_sync_get_bulk1(doc) -> ["Simple (sync) get_bulk-request - "
"Old style (Addr & Port)"];
simple_sync_get_bulk1(suite) -> [];
simple_sync_get_bulk1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_sync_get_bulk1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_get_bulk1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssgb1),
+do_simple_sync_get_bulk1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3252,8 +3320,10 @@ simple_sync_get_bulk2(doc) ->
["Simple (sync) get_bulk-request - Version 2 API (TargetName)"];
simple_sync_get_bulk2(suite) -> [];
simple_sync_get_bulk2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssgb2),
+ ?TC_TRY(simple_sync_get_bulk2,
+ fun() -> do_simple_sync_get_bulk2(Config) end).
+
+do_simple_sync_get_bulk2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3408,8 +3478,10 @@ simple_sync_get_bulk3(doc) ->
"Version 3 API (TargetName with send-opts)"];
simple_sync_get_bulk3(suite) -> [];
simple_sync_get_bulk3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ssgb3),
+ ?TC_TRY(simple_sync_get_bulk3,
+ fun() -> do_simple_sync_get_bulk3(Config) end).
+
+do_simple_sync_get_bulk3(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3445,10 +3517,11 @@ simple_async_get_bulk1(doc) -> ["Simple (async) get_bulk-request - "
"Old style (Addr & Port)"];
simple_async_get_bulk1(suite) -> [];
simple_async_get_bulk1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(simple_async_get_bulk1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_get_bulk1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sagb1),
+do_simple_async_get_bulk1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3591,8 +3664,10 @@ simple_async_get_bulk2(doc) ->
["Simple (async) get_bulk-request - Version 2 API (TargetName)"];
simple_async_get_bulk2(suite) -> [];
simple_async_get_bulk2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sagb2),
+ ?TC_TRY(simple_async_get_bulk2,
+ fun() -> do_simple_async_get_bulk2(Config) end).
+
+do_simple_async_get_bulk2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3747,8 +3822,10 @@ simple_async_get_bulk3(doc) ->
"Version 3 API (TargetName with send-opts)"];
simple_async_get_bulk3(suite) -> [];
simple_async_get_bulk3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, sagb3),
+ ?TC_TRY(simple_async_get_bulk3,
+ fun() -> do_simple_async_get_bulk3(Config) end).
+
+do_simple_async_get_bulk3(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3791,10 +3868,11 @@ misc_async1(doc) -> ["Misc (async) request(s) - "
"Old style (Addr & Port)"];
misc_async1(suite) -> [];
misc_async1(Config) when is_list(Config) ->
- ?SKIP(api_no_longer_supported),
+ ?TC_TRY(misc_async1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_misc_async1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ms1),
+do_misc_async1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3983,8 +4061,10 @@ misc_async2(doc) ->
["Misc (async) request(s) - Version 2 API (TargetName)"];
misc_async2(suite) -> [];
misc_async2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, ms2),
+ ?TC_TRY(misc_async2,
+ fun() -> do_misc_async2(Config) end).
+
+do_misc_async2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -4233,8 +4313,10 @@ verify_trap(Trap, [{Id, Verifier}|Verifiers]) ->
trap1(suite) -> [];
trap1(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,t1),
+ ?TC_TRY(trap1,
+ fun() -> do_trap1(Config) end).
+
+do_trap1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -4386,8 +4468,10 @@ trap1(Config) when is_list(Config) ->
trap2(suite) -> [];
trap2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,t2),
+ ?TC_TRY(trap2,
+ fun() -> do_trap2(Config) end).
+
+do_trap2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -4579,8 +4663,10 @@ trap2(Config) when is_list(Config) ->
inform1(suite) -> [];
inform1(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,i1),
+ ?TC_TRY(inform1,
+ fun() -> do_inform1(Config) end).
+
+do_inform1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -4706,8 +4792,10 @@ inform1(Config) when is_list(Config) ->
inform2(suite) -> [];
inform2(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, i2),
+ ?TC_TRY(inform2,
+ fun() -> do_inform2(Config) end).
+
+do_inform2(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -4841,7 +4929,7 @@ inform2(Config) when is_list(Config) ->
"~n ~p", [Addr]),
ok;
{snmp_notification, inform2_tag1, {no_response, Addr}} ->
- p("<ERROR> received expected \"no response\" "
+ e("Received unexpected \"no response\" "
"notification from: "
"~n ~p", [Addr]),
{error, no_response}
@@ -4878,8 +4966,10 @@ inform2(Config) when is_list(Config) ->
inform3(suite) -> [];
inform3(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,i3),
+ ?TC_TRY(inform3,
+ fun() -> do_inform3(Config) end).
+
+do_inform3(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -4975,7 +5065,7 @@ inform3(Config) when is_list(Config) ->
"~n ~p", [Addr]),
ok;
{snmp_notification, inform3_tag1, {got_response, Addr}} ->
- p("<ERROR> received unexpected \"got response\" "
+ e("Received unexpected \"got response\" "
"notification from: "
"~n ~p",
[Addr]),
@@ -5014,8 +5104,10 @@ inform3(Config) when is_list(Config) ->
inform4(suite) -> [];
inform4(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname,i4),
+ ?TC_TRY(inform4,
+ fun() -> do_inform4(Config) end).
+
+do_inform4(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -5134,8 +5226,10 @@ inform4(Config) when is_list(Config) ->
inform_swarm(suite) -> [];
inform_swarm(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, is),
+ ?TC_TRY(inform_swarm,
+ fun() -> do_inform_swarm(Config) end).
+
+do_inform_swarm(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -5262,7 +5356,7 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) ->
inform_swarm_collector(N, SentAckCnt, RecvCnt+1, RespCnt,
Timeout);
{Err, Idx, VBs} ->
- p("<ERROR> unexpected error status: "
+ e("Unexpected error status: "
"~n Err: ~p"
"~n Idx: ~p"
"~n VBs: ~p", [Err, Idx, VBs]),
@@ -5281,7 +5375,7 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) ->
%% The agent did not received ack from the manager in time
{snmp_notification, inform2_tag1, {no_response, Addr}} ->
- p("<ERROR> received expected \"no response\" notification "
+ e("Received expected \"no response\" notification "
"from: "
"~n ~p", [Addr]),
Reason = {no_response, Addr, {N, SentAckCnt, RecvCnt, RespCnt}},
@@ -5306,8 +5400,10 @@ report(Config) when is_list(Config) ->
otp8015_1(doc) -> ["OTP-8015:1 - testing the new api-function."];
otp8015_1(suite) -> [];
otp8015_1(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, otp8015_1),
+ ?TC_TRY(otp8015_1,
+ fun() -> do_otp8015_1(Config) end).
+
+do_otp8015_1(Config) ->
p("starting with Config: ~p~n", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -5354,8 +5450,10 @@ otp8015_1(Config) when is_list(Config) ->
otp8395_1(doc) -> ["OTP-8395:1 - simple get with ATL sequence numbering."];
otp8395_1(suite) -> [];
otp8395_1(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- put(tname, otp8395_1),
+ ?TC_TRY(otp8395_1,
+ fun() -> do_otp8395_1(Config) end).
+
+do_otp8395_1(Config) ->
do_simple_sync_get2(Config).
@@ -5458,10 +5556,10 @@ command_handler([{No, Desc, Cmd}|Cmds]) ->
p("command_handler -> ~w: ok",[No]),
command_handler(Cmds);
{error, Reason} ->
- p("<ERROR> command_handler -> ~w error: ~n~p",[No, Reason]),
+ e("Command_handler -> ~w error: ~n~p",[No, Reason]),
?line ?FAIL({command_failed, No, Reason});
Error ->
- p("<ERROR> command_handler -> ~w unexpected: ~n~p",[No, Error]),
+ e("Command_handler -> ~w unexpected: ~n~p",[No, Error]),
?line ?FAIL({unexpected_command_result, No, Error})
end.
@@ -6327,6 +6425,8 @@ start_manager_node() ->
start_node(snmp_manager).
start_node(Name) ->
+ start_node(Name, true).
+start_node(Name, Retry) ->
Pa = filename:dirname(code:which(?MODULE)),
Args = case init:get_argument('CC_TEST') of
{ok, [[]]} ->
@@ -6337,30 +6437,47 @@ start_node(Name) ->
""
end,
A = Args ++ " -pa " ++ Pa,
- case (catch ?START_NODE(Name, A)) of
+ try ?START_NODE(Name, A) of
{ok, Node} ->
Node;
- Else ->
- ?line ?FAIL(Else)
+ {error, timeout} ->
+ e("Failed starting node ~p: timeout", [Name]),
+ ?line ?FAIL({error_starting_node, Name, timeout});
+ {error, {already_running, Node}} when (Retry =:= true) ->
+ %% Ouch
+ %% Either we previously failed to (properly) stop the node
+ %% or it was a failed start, that reported failure (for instance
+ %% timeout) but actually succeeded. Regardless, we don't know
+ %% the state of this node, so (try) stop it and then (re-) try
+ %% start again.
+ e("Failed starting node ~p: Already Running - try stop", [Node]),
+ case ?STOP_NODE(Node) of
+ true ->
+ p("Successfully stopped old node ~p", [Node]),
+ start_node(Name, false);
+ false ->
+ e("Failed stop old node ~p", [Node]),
+ ?line ?FAIL({error_starting_node, Node, Retry, already_running})
+ end;
+ {error, {already_running, Node}} ->
+ e("Failed starting node ~p: Already Running", [Node]),
+ ?line ?FAIL({error_starting_node, Node, Retry, already_running});
+ {error, Reason} ->
+ e("Failed starting node ~p: ~p", [Name, Reason]),
+ ?line ?FAIL({error_starting_node, Name, Reason})
+ catch
+ exit:{suite_failed, Reason} ->
+ e("(suite) Failed starting node ~p: ~p", [Name, Reason]),
+ ?line ?FAIL({failed_starting_node, Name, Reason})
end.
-stop_node(Node) ->
- rpc:cast(Node, erlang, halt, []),
- await_stopped(Node, 5).
-await_stopped(Node, 0) ->
- p("await_stopped -> ~p still exist: giving up", [Node]),
- ok;
-await_stopped(Node, N) ->
- Nodes = erlang:nodes(),
- case lists:member(Node, Nodes) of
- true ->
- p("await_stopped -> ~p still exist: ~w", [Node, N]),
- ?SLEEP(1000),
- await_stopped(Node, N-1);
- false ->
- p("await_stopped -> ~p gone: ~w", [Node, N]),
- ok
+stop_node(Node) ->
+ case ?STOP_NODE(Node) of
+ true ->
+ ok;
+ false ->
+ ?line ?FAIL({failed_stop_node, Node})
end.
@@ -6605,12 +6722,15 @@ rcall(Node, Mod, Func, Args) ->
%% ------
+e(F, A) ->
+ p("<ERROR> " ++ F, A).
+
p(F) ->
p(F, []).
p(F, A) ->
p(get(tname), F, A).
-
+
p(TName, F, A) ->
io:format("*** [~w][~s] ***"
"~n " ++ F ++ "~n", [TName, formated_timestamp()|A]).
diff --git a/lib/snmp/test/snmp_test_global_sys_monitor.erl b/lib/snmp/test/snmp_test_global_sys_monitor.erl
new file mode 100644
index 0000000000..eafb96621a
--- /dev/null
+++ b/lib/snmp/test/snmp_test_global_sys_monitor.erl
@@ -0,0 +1,214 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(snmp_test_global_sys_monitor).
+
+-export([start/0, stop/0,
+ reset_events/0,
+ events/0,
+ log/1]).
+-export([init/1]).
+
+-define(NAME, ?MODULE).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+start() ->
+ Parent = self(),
+ proc_lib:start(?MODULE, init, [Parent]).
+
+stop() ->
+ cast(stop).
+
+%% This does not reset the global counter but the "collector"
+%% See events for more info.
+reset_events() ->
+ cast(reset_events).
+
+events() ->
+ call(events).
+
+log(Event) ->
+ cast({node(), Event}).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init(Parent) ->
+ process_flag(priority, high),
+ case global:register_name(?NAME, self()) of
+ yes ->
+ info_msg("Starting", []),
+ proc_lib:init_ack(Parent, {ok, self()}),
+ loop(#{parent => Parent, ev_cnt => 0, evs => []});
+ no ->
+ warning_msg("Already started", []),
+ proc_lib:init_ack(Parent, {error, already_started}),
+ exit(normal)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+loop(State) ->
+ receive
+ {?MODULE, stop} ->
+ warning_msg("Stopping with ~w events counted",
+ [maps:get(ev_cnt, State)]),
+ exit(normal);
+
+ {?MODULE, reset_events} ->
+ loop(State#{evs => []});
+
+ {?MODULE, Ref, From, events} ->
+ Evs = maps:get(evs, State),
+ From ! {?MODULE, Ref, lists:reverse(Evs)},
+ loop(State);
+
+ {?MODULE, {Node, Event}} ->
+ State2 = process_event(State, Node, Event),
+ loop(State2);
+
+ {nodedown = Event, Node} ->
+ State2 = process_event(State, Node, Event),
+ loop(State2);
+
+ _ ->
+ loop(State)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+process_event(State, Node, {Pid, TS, Tag, Info}) ->
+ process_system_event(State, Node, Pid, TS, Tag, Info);
+
+process_event(State, Node, {TS, starting}) ->
+ FTS = snmp_misc:format_timestamp(TS),
+ info_msg("System Monitor on node ~p starting at ~s", [Node, FTS]),
+ if
+ (Node =/= node()) ->
+ erlang:monitor_node(Node, true);
+ true ->
+ ok
+ end,
+ State;
+
+process_event(State, Node, {TS, already_started}) ->
+ FTS = snmp_misc:format_timestamp(TS),
+ info_msg("System Monitor on node ~p already started", [Node, FTS]),
+ State;
+
+process_event(State, Node, nodedown) ->
+ info_msg("Node ~p down", [Node]),
+ State;
+
+process_event(State, Node, Event) ->
+ warning_msg("Received unknown event from node ~p:"
+ "~n ~p", [Node, Event]),
+ State.
+
+
+%% System Monitor events
+%% We only *count* system events
+process_system_event(#{ev_cnt := Cnt, evs := Evs} = State,
+ Node, Pid, TS, long_gc = Ev, Info) ->
+ print_system_event("Long GC", Node, Pid, TS, Info),
+ State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]};
+process_system_event(#{ev_cnt := Cnt, evs := Evs} = State,
+ Node, Pid, TS, long_schedule = Ev, Info) ->
+ print_system_event("Long Schedule", Node, Pid, TS, Info),
+ State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]};
+process_system_event(#{ev_cnt := Cnt, evs := Evs} = State,
+ Node, Pid, TS, large_heap = Ev, Info) ->
+ print_system_event("Large Heap", Node, Pid, TS, Info),
+ State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]};
+process_system_event(#{ev_cnt := Cnt, evs := Evs} = State,
+ Node, Pid, TS, busy_port = Ev, Info) ->
+ print_system_event("Busy port", Node, Pid, TS, Info),
+ State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]};
+process_system_event(#{ev_cnt := Cnt, evs := Evs} = State,
+ Node, Pid, TS, busy_dist_port = Ev, Info) ->
+ print_system_event("Busy dist port", Node, Pid, TS, Info),
+ State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]};
+
+%% And everything else
+process_system_event(State, Node, Pid, TS, Tag, Info) ->
+ Pre = f("Unknown Event '~p'", [Tag]),
+ print_system_event(Pre, Node, Pid, TS, Info),
+ State.
+
+
+print_system_event(Pre, Node, Pid, TS, Info) ->
+ FTS = snmp_misc:format_timestamp(TS),
+ warning_msg("~s from ~p (~p) at ~s:"
+ "~n ~p", [Pre, Node, Pid, FTS, Info]).
+
+f(F, A) ->
+ lists:flatten(io_lib:format(F, A)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+cast(Msg) ->
+ try global:send(?NAME, {?MODULE, Msg}) of
+ Pid when is_pid(Pid) ->
+ ok
+ catch
+ C:E:_ ->
+ {error, {catched, C, E}}
+ end.
+
+call(Req) ->
+ call(Req, infinity).
+
+call(Req, Timeout) ->
+ Ref = make_ref(),
+ try global:send(?NAME, {?MODULE, Ref, self(), Req}) of
+ Pid when is_pid(Pid) ->
+ receive
+ {?MODULE, Ref, Rep} ->
+ Rep
+ after Timeout ->
+ {error, timeout}
+ end
+ catch
+ C:E:_ ->
+ {error, {catched, C, E}}
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+info_msg(F, A) ->
+ error_logger:info_msg(format_msg(F, A), []).
+
+warning_msg(F, A) ->
+ error_logger:warning_msg(format_msg(F, A), []).
+
+
+format_msg(F, A) ->
+ f("~n" ++
+ "****** SNMP TEST GLOBAL SYSTEM MONITOR ******~n~n" ++
+ F ++
+ "~n~n",
+ A).
+
diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl
index 42f710e4cd..26b68501e2 100644
--- a/lib/snmp/test/snmp_test_lib.erl
+++ b/lib/snmp/test/snmp_test_lib.erl
@@ -23,6 +23,7 @@
-include_lib("kernel/include/file.hrl").
+-export([tc_try/2, tc_try/3]).
-export([hostname/0, hostname/1, localhost/0, localhost/1, os_type/0, sz/1,
display_suite_info/1]).
-export([non_pc_tc_maybe_skip/4, os_based_skip/1,
@@ -36,17 +37,114 @@
-export([hours/1, minutes/1, seconds/1, sleep/1]).
-export([flush_mqueue/0, trap_exit/0, trap_exit/1]).
-export([ping/1, local_nodes/0, nodes_on/1]).
--export([start_node/2]).
+-export([start_node/2, stop_node/1]).
-export([is_app_running/1,
is_crypto_running/0, is_mnesia_running/0, is_snmp_running/0]).
-export([crypto_start/0, crypto_support/0]).
-export([watchdog/3, watchdog_start/1, watchdog_start/2, watchdog_stop/1]).
-export([del_dir/1]).
-export([cover/1]).
--export([p/2, print1/2, print2/2, print/5, formated_timestamp/0]).
+-export([f/2, p/2, print1/2, print2/2, print/5, formated_timestamp/0]).
%% ----------------------------------------------------------------------
+%% Run test-case
+%%
+
+%% *** tc_try/2,3 ***
+%% Case: Basically the test case name
+%% TCCondFun: A fun that is evaluated before the actual test case
+%% The point of this is that it can performs checks to
+%% see if we shall run the test case at all.
+%% For instance, the test case may only work in specific
+%% conditions.
+%% FCFun: The test case fun
+tc_try(Case, TCFun) ->
+ tc_try(Case, fun() -> ok end, TCFun).
+
+tc_try(Case, TCCondFun, TCFun)
+ when is_atom(Case) andalso
+ is_function(TCCondFun, 0) andalso
+ is_function(TCFun, 0) ->
+ tc_begin(Case),
+ try TCCondFun() of
+ ok ->
+ try
+ begin
+ TCFun(),
+ sleep(seconds(1)),
+ tc_end("ok")
+ end
+ catch
+ C:{skip, _} = SKIP when ((C =:= throw) orelse (C =:= exit)) ->
+ tc_end( f("skipping(catched,~w,tc)", [C]) ),
+ SKIP;
+ C:E:S ->
+ tc_end( f("failed(catched,~w,tc)", [C]) ),
+ erlang:raise(C, E, S)
+ end;
+ {skip, _} = SKIP ->
+ tc_end("skipping(tc)"),
+ SKIP;
+ {error, Reason} ->
+ tc_end("failed(tc)"),
+ exit({tc_cond_failed, Reason})
+ catch
+ C:{skip, _} = SKIP when ((C =:= throw) orelse (C =:= exit)) ->
+ tc_end( f("skipping(catched,~w,cond)", [C]) ),
+ SKIP;
+ C:E:S ->
+ tc_end( f("failed(catched,~w,cond)", [C]) ),
+ erlang:raise(C, E, S)
+ end.
+
+
+tc_set_name(N) when is_atom(N) ->
+ tc_set_name(atom_to_list(N));
+tc_set_name(N) when is_list(N) ->
+ put(tc_name, N).
+
+tc_get_name() ->
+ get(tc_name).
+
+tc_begin(TC) ->
+ OldVal = process_flag(trap_exit, true),
+ put(old_trap_exit, OldVal),
+ tc_set_name(TC),
+ tc_print("begin ***",
+ "~n----------------------------------------------------~n", "").
+
+tc_end(Result) when is_list(Result) ->
+ OldVal = erase(old_trap_exit),
+ process_flag(trap_exit, OldVal),
+ tc_print("done: ~s", [Result],
+ "", "----------------------------------------------------~n~n"),
+ ok.
+
+tc_print(F, Before, After) ->
+ tc_print(F, [], Before, After).
+
+tc_print(F, A, Before, After) ->
+ Name = tc_which_name(),
+ FStr = f("*** [~s][~s][~p] " ++ F ++ "~n",
+ [formated_timestamp(),Name,self()|A]),
+ io:format(user, Before ++ FStr ++ After, []).
+
+tc_which_name() ->
+ case tc_get_name() of
+ undefined ->
+ case get(sname) of
+ undefined ->
+ "";
+ SName when is_list(SName) ->
+ SName
+ end;
+ Name when is_list(Name) ->
+ Name
+ end.
+
+
+%% ----------------------------------------------------------------------
%% Misc functions
%%
@@ -202,11 +300,14 @@ non_pc_tc_maybe_skip(Config, Condition, File, Line)
%% test-server...
ok;
_ ->
- case Condition() of
+ try Condition() of
true ->
skip(non_pc_testcase, File, Line);
false ->
ok
+ catch
+ C:E:S ->
+ skip({condition, C, E, S}, File, Line)
end
end
end.
@@ -512,10 +613,14 @@ nodes_on(Host) when is_list(Host) ->
start_node(Name, Args) ->
- Opts = [{cleanup,false}, {args,Args}],
+ Opts = [{cleanup, false}, {args, Args}],
test_server:start_node(Name, slave, Opts).
+stop_node(Node) ->
+ test_server:stop_node(Node).
+
+
%% ----------------------------------------------------------------
%% Application and Crypto utility functions
%%
@@ -708,6 +813,9 @@ cover([Suite, Case] = Args) when is_atom(Suite) andalso is_atom(Case) ->
%% (debug) Print functions
%%
+f(F, A) ->
+ lists:flatten(io_lib:format(F, A)).
+
p(Mod, Case) when is_atom(Mod) andalso is_atom(Case) ->
case get(test_case) of
undefined ->
diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl
index c66602b779..f077f15d3e 100644
--- a/lib/snmp/test/snmp_test_lib.hrl
+++ b/lib/snmp/test/snmp_test_lib.hrl
@@ -18,15 +18,11 @@
%% The Initial Developer of the Original Code is Ericsson AB.
%% %CopyrightEnd%
%%
+
%%----------------------------------------------------------------------
-%% Purpose: Define common macros for testing
+%% Purpose: Define common macros for (the snmp) testing
%%----------------------------------------------------------------------
-%% - (some of the) Macros stolen from the test server -
-
-%% -define(line,put(test_server_loc,{?MODULE,?LINE}),).
-
-
%% - Misc macros -
-ifndef(APPLICATION).
@@ -45,6 +41,8 @@
%% - Test case macros -
+-define(TC_TRY(C, TC), snmp_test_lib:tc_try(C, TC)).
+-define(TC_TRY(C, TCCond, TC), snmp_test_lib:tc_try(C, TCCond, TC)).
-define(OS_BASED_SKIP(Skippable),
snmp_test_lib:os_based_skip(Skippable)).
-define(NON_PC_TC_MAYBE_SKIP(Config, Condition),
@@ -92,6 +90,7 @@
-define(LNODES(), snmp_test_lib:local_nodes()).
-define(NODES(H), snmp_test_lib:nodes_on(H)).
-define(START_NODE(N,A), snmp_test_lib:start_node(N,A)).
+-define(STOP_NODE(N), snmp_test_lib:stop_node(N)).
%% - Application and Crypto utility macros -
diff --git a/lib/snmp/test/snmp_test_server.erl b/lib/snmp/test/snmp_test_server.erl
index a77bdc142c..ab7dbbbaa0 100644
--- a/lib/snmp/test/snmp_test_server.erl
+++ b/lib/snmp/test/snmp_test_server.erl
@@ -207,7 +207,7 @@ do_subcases(Mod, Fun, [{conf, Init, Cases, Finish}|SubCases], Config, Acc)
[{failed, {Mod, Fun}, Error}]
end,
do_subcases(Mod, Fun, SubCases, Config, [R|Acc]);
-do_subcases(Mod, Fun, [SubCase|SubCases], Config, Acc) when atom(SubCase) ->
+do_subcases(Mod, Fun, [SubCase|SubCases], Config, Acc) when is_atom(SubCase) ->
R = do_case(Mod, SubCase, Config),
do_subcases(Mod, Fun, SubCases,Config, [R|Acc]).
@@ -407,7 +407,7 @@ d(_, _, _, _) ->
ok.
timestamp() ->
- {Date, Time} = calendar:now_to_datetime( now() ),
+ {Date, Time} = calendar:now_to_datetime( erlang:timestamp() ),
{YYYY, MM, DD} = Date,
{Hour, Min, Sec} = Time,
FormatDate =
diff --git a/lib/snmp/test/snmp_test_sys_monitor.erl b/lib/snmp/test/snmp_test_sys_monitor.erl
new file mode 100644
index 0000000000..2291c6ca97
--- /dev/null
+++ b/lib/snmp/test/snmp_test_sys_monitor.erl
@@ -0,0 +1,86 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(snmp_test_sys_monitor).
+
+-export([start/0, stop/0,
+ init/1]).
+
+-define(NAME, ?MODULE).
+-define(GSM, snmp_test_global_sys_monitor).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+start() ->
+ Parent = self(),
+ proc_lib:start(?MODULE, init, [Parent]).
+
+stop() ->
+ case whereis(?NAME) of
+ Pid when is_pid(Pid) ->
+ Pid ! {?MODULE, stop},
+ ok;
+ _ ->
+ ok
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init(Parent) ->
+ process_flag(priority, high),
+ try register(?NAME, self()) of
+ true ->
+ global:sync(),
+ MonSettings = [
+ busy_port,
+ busy_dist_port,
+ {long_gc, 1000},
+ {long_schedule, 1000},
+ {large_heap, 8*1024*1024} % 8 MB
+ ],
+ erlang:system_monitor(self(), MonSettings),
+ ?GSM:log({erlang:timestamp(), starting}),
+ proc_lib:init_ack(Parent, {ok, self()}),
+ loop(#{parent => Parent})
+ catch
+ _:_:_ ->
+ ?GSM:log({erlang:timestamp(), already_started}),
+ proc_lib:init_ack(Parent, {error, already_started}),
+ exit(normal)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+loop(State) ->
+ receive
+ {monitor, Pid, Tag, Info} ->
+ ?GSM:log({Pid, erlang:timestamp(), Tag, Info}),
+ loop(State);
+
+ _ ->
+ loop(State)
+ end.
+
+
+
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 8f32966a12..9df4f1e2d7 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -386,16 +386,24 @@ init_connection_handler(Role, Socket, Opts) ->
D);
{stop, Error} ->
- Sups = ?GET_INTERNAL_OPT(supervisors, Opts),
- C = #connection{system_supervisor = proplists:get_value(system_sup, Sups),
- sub_system_supervisor = proplists:get_value(subsystem_sup, Sups),
- connection_supervisor = proplists:get_value(connection_sup, Sups)
- },
+ D = try
+ %% Only servers have supervisorts defined in Opts
+ Sups = ?GET_INTERNAL_OPT(supervisors, Opts),
+ #connection{system_supervisor = proplists:get_value(system_sup, Sups),
+ sub_system_supervisor = proplists:get_value(subsystem_sup, Sups),
+ connection_supervisor = proplists:get_value(connection_sup, Sups)
+ }
+ of
+ C ->
+ #data{connection_state=C}
+ catch
+ _:_ ->
+ #data{connection_state=#connection{}}
+ end,
gen_statem:enter_loop(?MODULE,
[],
{init_error,Error},
- #data{connection_state=C,
- socket=Socket})
+ D#data{socket=Socket})
end.
@@ -1550,7 +1558,7 @@ terminate({shutdown,"Connection closed"}, _StateName, D) ->
terminate({shutdown,{init,Reason}}, StateName, D) ->
%% Error in initiation. "This error should not occur".
- log(error, D, io_lib:format("Shutdown in init (StateName=~p): ~p~n",[StateName,Reason])),
+ log(error, D, "Shutdown in init (StateName=~p): ~p~n", [StateName,Reason]),
stop_subsystem(D),
close_transport(D);
@@ -1952,12 +1960,12 @@ send_disconnect(Code, Reason, DetailedText, Module, Line, StateName, D0) ->
call_disconnectfun_and_log_cond(LogMsg, DetailedText, Module, Line, StateName, D) ->
case disconnect_fun(LogMsg, D) of
void ->
- log(info, D,
- io_lib:format("~s~n"
- "State = ~p~n"
- "Module = ~p, Line = ~p.~n"
- "Details:~n ~s~n",
- [LogMsg, StateName, Module, Line, DetailedText]));
+ log(info, D,
+ "~s~n"
+ "State = ~p~n"
+ "Module = ~p, Line = ~p.~n"
+ "Details:~n ~s~n",
+ [LogMsg, StateName, Module, Line, DetailedText]);
_ ->
ok
end.
@@ -2021,6 +2029,9 @@ fold_keys(Keys, Fun, Extra) ->
end, [], Keys).
%%%----------------------------------------------------------------
+log(Tag, D, Format, Args) ->
+ log(Tag, D, io_lib:format(Format,Args)).
+
log(Tag, D, Reason) ->
case atom_to_list(Tag) of % Dialyzer-technical reasons...
"error" -> do_log(error_msg, Reason, D);
@@ -2028,36 +2039,50 @@ log(Tag, D, Reason) ->
"info" -> do_log(info_msg, Reason, D)
end.
-do_log(F, Reason, #data{ssh_params = #ssh{role = Role} = S
- }) ->
- VSN =
- case application:get_key(ssh,vsn) of
- {ok,Vsn} -> Vsn;
- undefined -> ""
- end,
- PeerVersion =
- case Role of
- server -> S#ssh.c_version;
- client -> S#ssh.s_version
- end,
- CryptoInfo =
- try
- [{_,_,CI}] = crypto:info_lib(),
- <<"(",CI/binary,")">>
- catch
- _:_ -> ""
- end,
- Other =
- case Role of
- server -> "Client";
- client -> "Server"
- end,
- error_logger:F("Erlang SSH ~p ~s ~s.~n"
- "~s: ~p~n"
- "~s~n",
- [Role, VSN, CryptoInfo,
- Other, PeerVersion,
- Reason]).
+
+do_log(F, Reason, #data{ssh_params = S}) ->
+ case S of
+ #ssh{role = Role} when Role==server ;
+ Role==client ->
+ {PeerRole,PeerVersion} =
+ case Role of
+ server -> {"Client", S#ssh.c_version};
+ client -> {"Server", S#ssh.s_version}
+ end,
+ error_logger:F("Erlang SSH ~p ~s ~s.~n"
+ "~s: ~p~n"
+ "~s~n",
+ [Role,
+ ssh_log_version(), crypto_log_info(),
+ PeerRole, PeerVersion,
+ Reason]);
+ _ ->
+ error_logger:F("Erlang SSH ~s ~s.~n"
+ "~s~n",
+ [ssh_log_version(), crypto_log_info(),
+ Reason])
+ end.
+
+crypto_log_info() ->
+ try
+ [{_,_,CI}] = crypto:info_lib(),
+ case crypto:info_fips() of
+ enabled ->
+ <<"(",CI/binary,". FIPS enabled)">>;
+ not_enabled ->
+ <<"(",CI/binary,". FIPS available but not enabled)">>;
+ _ ->
+ <<"(",CI/binary,")">>
+ end
+ catch
+ _:_ -> ""
+ end.
+
+ssh_log_version() ->
+ case application:get_key(ssh,vsn) of
+ {ok,Vsn} -> Vsn;
+ undefined -> ""
+ end.
%%%----------------------------------------------------------------
not_connected_filter({connection_reply, _Data}) -> true;
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index f320b4c006..335896c60a 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -27,6 +27,53 @@
</header>
<p>This document describes the changes made to the SSL application.</p>
+<section><title>SSL 9.3.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Enhance error handling for erroneous alerts from the
+ peer.</p>
+ <p>
+ Own Id: OTP-15943</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 9.3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix handling of certificate decoding problems in TLS 1.3
+ similarly as in TLS 1.2.</p>
+ <p>
+ Own Id: OTP-15900</p>
+ </item>
+ <item>
+ <p>
+ Hibernation now works as expected in all cases, was
+ accidently broken by optimization efforts.</p>
+ <p>
+ Own Id: OTP-15910</p>
+ </item>
+ <item>
+ <p>
+ Fix interoperability problems with openssl when the TLS
+ 1.3 server is configured wirh the option
+ signature_algs_cert.</p>
+ <p>
+ Own Id: OTP-15913</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SSL 9.3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -179,6 +226,38 @@
</section>
+<section><title>SSL 9.2.3.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Handling of zero size fragments in TLS could cause an
+ infinite loop. This has now been corrected.</p>
+ <p>
+ Own Id: OTP-15328 Aux Id: ERIERL-379 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 9.2.3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Hibernation now works as expected in all cases, was
+ accidently broken by optimization efforts.</p>
+ <p>
+ Own Id: OTP-15910</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SSL 9.2.3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 3aa6e09c2c..05590666da 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -207,6 +207,10 @@
<datatype>
<name name="sign_scheme"/>
</datatype>
+
+ <datatype>
+ <name name="group"/>
+ </datatype>
<datatype>
<name name="kex_algo"/>
@@ -363,7 +367,20 @@
</p>
</desc>
</datatype>
-
+
+ <datatype>
+ <name name="supported_groups"/>
+ <desc>
+ <p>TLS 1.3 introduces the "supported_groups" extension that is used for negotiating
+ the Diffie-Hellman parameters in a TLS 1.3 handshake. Both client and server
+ can specify a list of parameters that they are willing to use.
+ </p>
+ <p> If it is not specified it will use a default list ([x25519, x448, secp256r1, secp384r1]) that
+ is filtered based on the installed crypto library version.
+ </p>
+ </desc>
+ </datatype>
+
<datatype>
<name name="secure_renegotiation"/>
<desc><p>Specifies if to reject renegotiation attempt that does
@@ -919,6 +936,8 @@ fun(srp, Username :: string(), UserState :: term()) ->
<name name="dh_der"/>
<desc><p>The DER-encoded Diffie-Hellman parameters. If
specified, it overrides option <c>dhfile</c>.</p>
+ <warning><p>The <c>dh_der</c> option is not supported by TLS 1.3. Use the
+ <c>supported_groups</c> option instead.</p></warning>
</desc>
</datatype>
@@ -928,6 +947,8 @@ fun(srp, Username :: string(), UserState :: term()) ->
parameters to be used by the server if a cipher suite using
Diffie Hellman key exchange is negotiated. If not specified,
default parameters are used.</p>
+ <warning><p>The <c>dh_file</c> option is not supported by TLS 1.3. Use the
+ <c>supported_groups</c> option instead.</p></warning>
</desc>
</datatype>
diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl
index d8c0e30973..4a381745d4 100644
--- a/lib/ssl/src/dtls_handshake.erl
+++ b/lib/ssl/src/dtls_handshake.erl
@@ -255,7 +255,8 @@ enc_handshake(#client_hello{client_version = {Major, Minor},
CmLength = byte_size(BinCompMethods),
BinCipherSuites = list_to_binary(CipherSuites),
CsLength = byte_size(BinCipherSuites),
- ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions),
+ ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions,
+ dtls_v1:corresponding_tls_version({Major, Minor})),
{?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SIDLength), SessionID/binary,
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 20b1e85ceb..7ff9aed8ea 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -128,7 +128,8 @@
tls_alert/0,
srp_param_type/0,
named_curve/0,
- sign_scheme/0]).
+ sign_scheme/0,
+ group/0]).
%% -------------------------------------------------------------------------------------------------------
@@ -243,7 +244,7 @@
secp160r2. % exported
-type group() :: secp256r1 | secp384r1 | secp521r1 | ffdhe2048 |
- ffdhe3072 | ffdhe4096 | ffdhe6144 | ffdhe8192.
+ ffdhe3072 | ffdhe4096 | ffdhe6144 | ffdhe8192. % exported
-type srp_param_type() :: srp_1024 |
srp_1536 |
@@ -296,6 +297,7 @@
{ciphers, cipher_suites()} |
{eccs, [named_curve()]} |
{signature_algs_cert, signature_schemes()} |
+ {supported_groups, supported_groups()} |
{secure_renegotiate, secure_renegotiation()} |
{depth, allowed_cert_chain_length()} |
{verify_fun, custom_verify()} |
@@ -342,6 +344,7 @@
-type protocol_versions() :: [protocol_version()].
-type signature_algs() :: [{hash(), sign_algo()}].
-type signature_schemes() :: [sign_scheme()].
+-type supported_groups() :: [group()].
-type custom_user_lookup() :: {Lookupfun :: fun(), UserState :: any()}.
-type padding_check() :: boolean().
-type beast_mitigation() :: one_n_minus_one | zero_n | disabled.
@@ -979,7 +982,8 @@ cipher_suites(all) ->
%% Description: Returns all default and all supported cipher suites for a
%% TLS/DTLS version
%%--------------------------------------------------------------------
-cipher_suites(Base, Version) when Version == 'tlsv1.2';
+cipher_suites(Base, Version) when Version == 'tlsv1.3';
+ Version == 'tlsv1.2';
Version == 'tlsv1.1';
Version == tlsv1;
Version == sslv3 ->
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index f4a91cac52..c16e2331ff 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -38,7 +38,7 @@
cipher_init/3, nonce_seed/2, decipher/6, cipher/5, aead_encrypt/6, aead_decrypt/6,
suites/1, all_suites/1, crypto_support_filters/0,
chacha_suites/1, anonymous_suites/1, psk_suites/1, psk_suites_anon/1,
- srp_suites/0, srp_suites_anon/0,
+ srp_suites/1, srp_suites_anon/1,
rc4_suites/1, des_suites/1, rsa_suites/1,
filter/3, filter_suites/1, filter_suites/2,
hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2, is_fallback/1,
@@ -284,7 +284,7 @@ all_suites({3, _} = Version) ->
suites(Version)
++ chacha_suites(Version)
++ psk_suites(Version)
- ++ srp_suites()
+ ++ srp_suites(Version)
++ rc4_suites(Version)
++ des_suites(Version)
++ rsa_suites(Version);
@@ -313,8 +313,8 @@ chacha_suites(_) ->
%% Description: Returns a list of the anonymous cipher suites, only supported
%% if explicitly set by user. Intended only for testing.
%%--------------------------------------------------------------------
-anonymous_suites({3, N}) ->
- srp_suites_anon() ++ anonymous_suites(N);
+anonymous_suites({3, N} = Version) ->
+ srp_suites_anon(Version) ++ anonymous_suites(N);
anonymous_suites({254, _} = Version) ->
dtls_v1:anonymous_suites(Version);
anonymous_suites(4) ->
@@ -375,7 +375,7 @@ psk_suites(_) ->
%%--------------------------------------------------------------------
psk_suites_anon({3, N}) ->
psk_suites_anon(N);
-psk_suites_anon(3) ->
+psk_suites_anon(3 = N) ->
[
?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
?TLS_PSK_WITH_AES_256_GCM_SHA384,
@@ -401,8 +401,8 @@ psk_suites_anon(3) ->
?TLS_PSK_WITH_AES_128_CCM,
?TLS_PSK_WITH_AES_128_CCM_8,
?TLS_ECDHE_PSK_WITH_RC4_128_SHA
- ] ++ psk_suites_anon(0);
-psk_suites_anon(_) ->
+ ] ++ psk_suites_anon(N-1);
+psk_suites_anon(N) when N > 0 ->
[?TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
?TLS_PSK_WITH_AES_256_CBC_SHA,
?TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
@@ -413,14 +413,18 @@ psk_suites_anon(_) ->
?TLS_PSK_WITH_3DES_EDE_CBC_SHA,
?TLS_ECDHE_PSK_WITH_RC4_128_SHA,
?TLS_DHE_PSK_WITH_RC4_128_SHA,
- ?TLS_PSK_WITH_RC4_128_SHA].
+ ?TLS_PSK_WITH_RC4_128_SHA];
+psk_suites_anon(0) ->
+ [].
%%--------------------------------------------------------------------
--spec srp_suites() -> [ssl_cipher_format:cipher_suite()].
+-spec srp_suites(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()].
%%
%% Description: Returns a list of the SRP cipher suites, only supported
%% if explicitly set by user.
%%--------------------------------------------------------------------
-srp_suites() ->
+srp_suites({3,0}) ->
+ [];
+srp_suites(_) ->
[?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
@@ -429,12 +433,14 @@ srp_suites() ->
?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA].
%%--------------------------------------------------------------------
--spec srp_suites_anon() -> [ssl_cipher_format:cipher_suite()].
+-spec srp_suites_anon(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()].
%%
%% Description: Returns a list of the SRP anonymous cipher suites, only supported
%% if explicitly set by user.
%%--------------------------------------------------------------------
-srp_suites_anon() ->
+srp_suites_anon({3,0}) ->
+ [];
+srp_suites_anon(_) ->
[?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
?TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
?TLS_SRP_SHA_WITH_AES_256_CBC_SHA].
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index cc4d60389e..2483509228 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -614,7 +614,8 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) ->
<<SizeA:32, DataA:SizeA/binary,
SizeB:32, DataB:SizeB/binary,
SizeC:32, DataC:SizeC/binary,
- SizeD:32, DataD:SizeD/binary, Rest/binary>> ->
+ SizeD:32, DataD:SizeD/binary, Rest/binary>>
+ when 0 < SizeA, 0 < SizeB, 0 < SizeC, 0 < SizeD ->
%% We have 4 complete packets in the first binary
erlang:dist_ctrl_put_data(DHandle, DataA),
erlang:dist_ctrl_put_data(DHandle, DataB),
@@ -624,7 +625,8 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) ->
DHandle, Front0, BufferSize - (4*4+SizeA+SizeB+SizeC+SizeD), Rear0, Rest);
<<SizeA:32, DataA:SizeA/binary,
SizeB:32, DataB:SizeB/binary,
- SizeC:32, DataC:SizeC/binary, Rest/binary>> ->
+ SizeC:32, DataC:SizeC/binary, Rest/binary>>
+ when 0 < SizeA, 0 < SizeB, 0 < SizeC ->
%% We have 3 complete packets in the first binary
erlang:dist_ctrl_put_data(DHandle, DataA),
erlang:dist_ctrl_put_data(DHandle, DataB),
@@ -632,7 +634,8 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) ->
read_application_dist_data(
DHandle, Front0, BufferSize - (3*4+SizeA+SizeB+SizeC), Rear0, Rest);
<<SizeA:32, DataA:SizeA/binary,
- SizeB:32, DataB:SizeB/binary, Rest/binary>> ->
+ SizeB:32, DataB:SizeB/binary, Rest/binary>>
+ when 0 < SizeA, 0 < SizeB ->
%% We have 2 complete packets in the first binary
erlang:dist_ctrl_put_data(DHandle, DataA),
erlang:dist_ctrl_put_data(DHandle, DataB),
@@ -643,13 +646,13 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) ->
%% Basic one packet code path
<<Size:32, Data:Size/binary, Rest/binary>> ->
%% We have a complete packet in the first binary
- erlang:dist_ctrl_put_data(DHandle, Data),
+ 0 < Size andalso erlang:dist_ctrl_put_data(DHandle, Data),
read_application_dist_data(DHandle, Front0, BufferSize - (4+Size), Rear0, Rest);
<<Size:32, FirstData/binary>> when 4+Size =< BufferSize ->
%% We have a complete packet in the buffer
%% - fetch the missing content from the buffer front
{Data,Front,Rear} = iovec_from_front(Size - byte_size(FirstData), Front0, Rear0, [FirstData]),
- erlang:dist_ctrl_put_data(DHandle, Data),
+ 0 < Size andalso erlang:dist_ctrl_put_data(DHandle, Data),
read_application_dist_data(DHandle, Front, BufferSize - (4+Size), Rear);
<<Bin/binary>> ->
%% In OTP-21 the match context reuse optimization fails if we use Bin0 in recursion, so here we
@@ -665,23 +668,61 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) ->
%% contains enough data to maybe form a packet
%% - fetch a tiny binary from the buffer front to complete the length field
{LengthField,Front,Rear} =
- iovec_from_front(4 - byte_size(IncompleteLengthField), Front0, Rear0, [IncompleteLengthField]),
+ case IncompleteLengthField of
+ <<>> ->
+ iovec_from_front(4, Front0, Rear0, []);
+ _ ->
+ iovec_from_front(
+ 4 - byte_size(IncompleteLengthField), Front0, Rear0, [IncompleteLengthField])
+ end,
LengthBin = iolist_to_binary(LengthField),
read_application_dist_data(DHandle, Front, BufferSize, Rear, LengthBin);
<<IncompleteLengthField/binary>> ->
%% We do not have enough data in the buffer to even form a length field - await more data
- {[IncompleteLengthField|Front0],BufferSize,Rear0}
+ case IncompleteLengthField of
+ <<>> ->
+ {Front0,BufferSize,Rear0};
+ _ ->
+ {[IncompleteLengthField|Front0],BufferSize,Rear0}
+ end
end
end.
+iovec_from_front(0, Front, Rear, Acc) ->
+ {lists:reverse(Acc),Front,Rear};
iovec_from_front(Size, [], Rear, Acc) ->
- iovec_from_front(Size, lists:reverse(Rear), [], Acc);
+ case Rear of
+ %% Avoid lists:reverse/1 for simple cases.
+ %% Case clause for [] to avoid infinite loop.
+ [_] ->
+ iovec_from_front(Size, Rear, [], Acc);
+ [Bin2,Bin1] ->
+ iovec_from_front(Size, [Bin1,Bin2], [], Acc);
+ [Bin3,Bin2,Bin1] ->
+ iovec_from_front(Size, [Bin1,Bin2,Bin3], [], Acc);
+ [_,_,_|_] = Rear ->
+ iovec_from_front(Size, lists:reverse(Rear), [], Acc)
+ end;
+iovec_from_front(Size, [Bin|Front], Rear, []) ->
+ case Bin of
+ <<Last:Size/binary>> -> % Just enough
+ {[Last],Front,Rear};
+ <<Last:Size/binary, Rest/binary>> -> % More than enough, split here
+ {[Last],[Rest|Front],Rear};
+ <<>> -> % Not enough, skip empty binaries
+ iovec_from_front(Size, Front, Rear, []);
+ <<_/binary>> -> % Not enough
+ BinSize = byte_size(Bin),
+ iovec_from_front(Size - BinSize, Front, Rear, [Bin])
+ end;
iovec_from_front(Size, [Bin|Front], Rear, Acc) ->
case Bin of
<<Last:Size/binary>> -> % Just enough
{lists:reverse(Acc, [Last]),Front,Rear};
<<Last:Size/binary, Rest/binary>> -> % More than enough, split here
{lists:reverse(Acc, [Last]),[Rest|Front],Rear};
+ <<>> -> % Not enough, skip empty binaries
+ iovec_from_front(Size, Front, Rear, Acc);
<<_/binary>> -> % Not enough
BinSize = byte_size(Bin),
iovec_from_front(Size - BinSize, Front, Rear, [Bin|Acc])
@@ -1234,10 +1275,17 @@ connection({call, From}, {connection_information, false}, State, _) ->
Info = connection_info(State),
hibernate_after(?FUNCTION_NAME, State, [{reply, From, {ok, Info}}]);
connection({call, From}, negotiated_protocol,
- #state{handshake_env = #handshake_env{negotiated_protocol = undefined}} = State, _) ->
+ #state{handshake_env = #handshake_env{alpn = undefined,
+ negotiated_protocol = undefined}} = State, _) ->
hibernate_after(?FUNCTION_NAME, State, [{reply, From, {error, protocol_not_negotiated}}]);
connection({call, From}, negotiated_protocol,
- #state{handshake_env = #handshake_env{negotiated_protocol = SelectedProtocol}} = State, _) ->
+ #state{handshake_env = #handshake_env{alpn = undefined,
+ negotiated_protocol = SelectedProtocol}} = State, _) ->
+ hibernate_after(?FUNCTION_NAME, State,
+ [{reply, From, {ok, SelectedProtocol}}]);
+connection({call, From}, negotiated_protocol,
+ #state{handshake_env = #handshake_env{alpn = SelectedProtocol,
+ negotiated_protocol = undefined}} = State, _) ->
hibernate_after(?FUNCTION_NAME, State,
[{reply, From, {ok, SelectedProtocol}}]);
connection({call, From}, Msg, State, Connection) ->
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index c6698bc74a..bd2efa9fbb 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -58,7 +58,7 @@
]).
%% Encode
--export([encode_handshake/2, encode_hello_extensions/1, encode_extensions/1, encode_extensions/2,
+-export([encode_handshake/2, encode_hello_extensions/2, encode_extensions/1, encode_extensions/2,
encode_client_protocol_negotiation/2, encode_protocols_advertised_on_server/1]).
%% Decode
-export([decode_handshake/3, decode_vector/1, decode_hello_extensions/4, decode_extensions/3,
@@ -534,14 +534,14 @@ encode_handshake(#next_protocol{selected_protocol = SelectedProtocol}, _Version)
PaddingLength = 32 - ((byte_size(SelectedProtocol) + 2) rem 32),
{?NEXT_PROTOCOL, <<?BYTE((byte_size(SelectedProtocol))), SelectedProtocol/binary,
?BYTE(PaddingLength), 0:(PaddingLength * 8)>>};
-encode_handshake(#server_hello{server_version = {Major, Minor},
+encode_handshake(#server_hello{server_version = {Major, Minor} = Version,
random = Random,
session_id = Session_ID,
cipher_suite = CipherSuite,
compression_method = Comp_method,
extensions = Extensions}, _Version) ->
SID_length = byte_size(Session_ID),
- ExtensionsBin = encode_hello_extensions(Extensions),
+ ExtensionsBin = encode_hello_extensions(Extensions, Version),
{?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID/binary,
CipherSuite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>};
@@ -589,7 +589,9 @@ encode_handshake(#certificate_verify{signature = BinSig, hashsign_algorithm = Ha
encode_handshake(#finished{verify_data = VerifyData}, _Version) ->
{?FINISHED, VerifyData}.
-encode_hello_extensions(Extensions) ->
+encode_hello_extensions(_, {3, 0}) ->
+ <<>>;
+encode_hello_extensions(Extensions, _) ->
encode_extensions(hello_extensions_list(Extensions), <<>>).
encode_extensions(Exts) ->
@@ -707,7 +709,25 @@ encode_extensions([#key_share_server_hello{server_share = ServerShare0} | Rest],
encode_extensions([#key_share_hello_retry_request{selected_group = Group0} | Rest], Acc) ->
Group = tls_v1:group_to_enum(Group0),
encode_extensions(Rest, <<?UINT16(?KEY_SHARE_EXT),
- ?UINT16(2), ?UINT16(Group), Acc/binary>>).
+ ?UINT16(2), ?UINT16(Group), Acc/binary>>);
+encode_extensions([#psk_key_exchange_modes{ke_modes = KEModes0} | Rest], Acc) ->
+ KEModes = encode_psk_key_exchange_modes(KEModes0),
+ KEModesLen = byte_size(KEModes),
+ ExtLen = KEModesLen + 1,
+ encode_extensions(Rest, <<?UINT16(?PSK_KEY_EXCHANGE_MODES_EXT),
+ ?UINT16(ExtLen), ?BYTE(KEModesLen), KEModes/binary, Acc/binary>>);
+encode_extensions([#pre_shared_key_client_hello{
+ offered_psks = #offered_psks{
+ identities = Identities0,
+ binders = Binders0} = PSKs} | Rest], Acc) ->
+ Identities = encode_psk_identities(Identities0),
+ Binders = encode_psk_binders(Binders0),
+ Len = byte_size(Identities) + byte_size(Binders),
+ encode_extensions(Rest, <<?UINT16(?PRE_SHARED_KEY_EXT),
+ ?UINT16(Len), Identities/binary, Binders/binary, Acc/binary>>);
+encode_extensions([#pre_shared_key_server_hello{selected_identity = Identity} | Rest], Acc) ->
+ encode_extensions(Rest, <<?UINT16(?PRE_SHARED_KEY_EXT),
+ ?UINT16(2), ?UINT16(Identity), Acc/binary>>).
encode_client_protocol_negotiation(undefined, _) ->
@@ -1256,6 +1276,8 @@ handle_server_hello_extensions(RecordCB, Random, CipherSuite, Compression,
%% We also ignore the ALPN extension during renegotiation (see encode_alpn/2).
[Protocol] when not Renegotiation ->
{ConnectionStates, alpn, Protocol};
+ [_] when Renegotiation ->
+ {ConnectionStates, alpn, undefined};
undefined ->
NextProtocolNegotiation = maps:get(next_protocol_negotiation, Exts, undefined),
Protocol = handle_next_protocol(NextProtocolNegotiation, NextProtoSelector, Renegotiation),
@@ -1486,8 +1508,12 @@ extension_value(#signature_algorithms_cert{signature_scheme_list = Schemes}) ->
Schemes;
extension_value(#key_share_client_hello{client_shares = ClientShares}) ->
ClientShares;
+extension_value(#key_share_server_hello{server_share = ServerShare}) ->
+ ServerShare;
extension_value(#client_hello_versions{versions = Versions}) ->
- Versions.
+ Versions;
+extension_value(#server_hello_selected_version{selected_version = SelectedVersion}) ->
+ SelectedVersion.
%%--------------------------------------------------------------------
@@ -2089,6 +2115,41 @@ encode_key_share_entry(#key_share_entry{
Len = byte_size(KeyExchange),
<<?UINT16((tls_v1:group_to_enum(Group))),?UINT16(Len),KeyExchange/binary>>.
+encode_psk_key_exchange_modes(KEModes) ->
+ encode_psk_key_exchange_modes(lists:reverse(KEModes), <<>>).
+%%
+encode_psk_key_exchange_modes([], Acc) ->
+ Acc;
+encode_psk_key_exchange_modes([psk_ke|T], Acc) ->
+ encode_psk_key_exchange_modes(T, <<?BYTE(?PSK_KE),Acc/binary>>);
+encode_psk_key_exchange_modes([psk_dhe_ke|T], Acc) ->
+ encode_psk_key_exchange_modes(T, <<?BYTE(?PSK_DHE_KE),Acc/binary>>).
+
+
+encode_psk_identities(Identities) ->
+ encode_psk_identities(Identities, <<>>).
+%%
+encode_psk_identities([], Acc) ->
+ Len = byte_size(Acc),
+ <<?UINT16(Len), Acc/binary>>;
+encode_psk_identities([#psk_identity{
+ identity = Identity,
+ obfuscated_ticket_age = Age}|T], Acc) ->
+ IdLen = byte_size(Identity),
+ encode_psk_identities(T, <<Acc/binary,?UINT16(IdLen),Identity/binary,Age/binary>>).
+
+
+encode_psk_binders(Binders) ->
+ encode_psk_binders(Binders, <<>>).
+%%
+encode_psk_binders([], Acc) ->
+ Len = byte_size(Acc),
+ <<?UINT16(Len), Acc/binary>>;
+encode_psk_binders([Binder|T], Acc) ->
+ Len = byte_size(Binder),
+ encode_psk_binders(T, <<Acc/binary,?BYTE(Len),Binder/binary>>).
+
+
hello_extensions_list(HelloExtensions) ->
[Ext || {_, Ext} <- maps:to_list(HelloExtensions), Ext =/= undefined].
@@ -2441,6 +2502,33 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
#key_share_hello_retry_request{
selected_group = tls_v1:enum_to_group(Group)}});
+decode_extensions(<<?UINT16(?PSK_KEY_EXCHANGE_MODES_EXT), ?UINT16(Len),
+ ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
+ <<?BYTE(PLen),KEModes:PLen/binary>> = ExtData,
+ decode_extensions(Rest, Version, MessageType,
+ Acc#{psk_key_exchange_modes =>
+ #psk_key_exchange_modes{
+ ke_modes = decode_psk_key_exchange_modes(KEModes)}});
+
+decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
+ ExtData:Len/binary, Rest/binary>>,
+ Version, MessageType = client_hello, Acc) ->
+ <<?UINT16(IdLen),Identities:IdLen/binary,?UINT16(BLen),Binders:BLen/binary>> = ExtData,
+ decode_extensions(Rest, Version, MessageType,
+ Acc#{pre_shared_key =>
+ #pre_shared_key_client_hello{
+ offered_psks = #offered_psks{
+ identities = decode_psk_identities(Identities),
+ binders = decode_psk_binders(Binders)}}});
+
+decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
+ ExtData:Len/binary, Rest/binary>>,
+ Version, MessageType = server_hello, Acc) ->
+ <<?UINT16(Identity)>> = ExtData,
+ decode_extensions(Rest, Version, MessageType,
+ Acc#{pre_shared_key =>
+ #pre_shared_key_server_hello{
+ selected_identity = Identity}});
%% Ignore data following the ClientHello (i.e.,
%% extensions) if not understood.
@@ -2500,6 +2588,38 @@ decode_protocols(<<?BYTE(Len), Protocol:Len/binary, Rest/binary>>, Acc) ->
decode_protocols(_Bytes, _Acc) ->
{error, invalid_protocols}.
+
+decode_psk_key_exchange_modes(KEModes) ->
+ decode_psk_key_exchange_modes(KEModes, []).
+%%
+decode_psk_key_exchange_modes(<<>>, Acc) ->
+ lists:reverse(Acc);
+decode_psk_key_exchange_modes(<<?BYTE(?PSK_KE), Rest/binary>>, Acc) ->
+ decode_psk_key_exchange_modes(Rest, [psk_ke|Acc]);
+decode_psk_key_exchange_modes(<<?BYTE(?PSK_DHE_KE), Rest/binary>>, Acc) ->
+ decode_psk_key_exchange_modes(Rest, [psk_dhe_ke|Acc]).
+
+
+decode_psk_identities(Identities) ->
+ decode_psk_identities(Identities, []).
+%%
+decode_psk_identities(<<>>, Acc) ->
+ lists:reverse(Acc);
+decode_psk_identities(<<?UINT16(Len), Identity:Len/binary, Age:4/binary, Rest/binary>>, Acc) ->
+ decode_psk_identities(Rest, [#psk_identity{
+ identity = Identity,
+ obfuscated_ticket_age = Age}|Acc]).
+
+
+decode_psk_binders(Binders) ->
+ decode_psk_binders(Binders, []).
+%%
+decode_psk_binders(<<>>, Acc) ->
+ lists:reverse(Acc);
+decode_psk_binders(<<?BYTE(Len), Binder:Len/binary, Rest/binary>>, Acc) ->
+ decode_psk_binders(Rest, [Binder|Acc]).
+
+
%% encode/decode stream of certificate data to/from list of certificate data
certs_to_list(ASN1Certs) ->
certs_to_list(ASN1Certs, []).
@@ -2666,7 +2786,7 @@ filter_unavailable_ecc_suites(_, Suites) ->
handle_renegotiation_extension(Role, RecordCB, Version, Info, Random, NegotiatedCipherSuite,
ClientCipherSuites, Compression,
ConnectionStates0, Renegotiation, SecureRenegotation) ->
- {ok, ConnectionStates} = handle_renegotiation_info(RecordCB, Role, Info, ConnectionStates0,
+ {ok, ConnectionStates} = handle_renegotiation_info(Version, RecordCB, Role, Info, ConnectionStates0,
Renegotiation, SecureRenegotation,
ClientCipherSuites),
hello_pending_connection_states(RecordCB, Role,
@@ -2936,11 +3056,11 @@ renegotiation_info(_RecordCB, server, ConnectionStates, true) ->
#renegotiation_info{renegotiated_connection = undefined}
end.
-handle_renegotiation_info(_RecordCB, _, #renegotiation_info{renegotiated_connection = ?byte(0)},
+handle_renegotiation_info(_, _RecordCB, _, #renegotiation_info{renegotiated_connection = ?byte(0)},
ConnectionStates, false, _, _) ->
{ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)};
-handle_renegotiation_info(_RecordCB, server, undefined, ConnectionStates, _, _, CipherSuites) ->
+handle_renegotiation_info(_, _RecordCB, server, undefined, ConnectionStates, _, _, CipherSuites) ->
case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
true ->
{ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)};
@@ -2948,10 +3068,10 @@ handle_renegotiation_info(_RecordCB, server, undefined, ConnectionStates, _, _,
{ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)}
end;
-handle_renegotiation_info(_RecordCB, _, undefined, ConnectionStates, false, _, _) ->
+handle_renegotiation_info(_, _RecordCB, _, undefined, ConnectionStates, false, _, _) ->
{ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)};
-handle_renegotiation_info(_RecordCB, client, #renegotiation_info{renegotiated_connection = ClientServerVerify},
+handle_renegotiation_info(_, _RecordCB, client, #renegotiation_info{renegotiated_connection = ClientServerVerify},
ConnectionStates, true, _, _) ->
ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
CData = maps:get(client_verify_data, ConnectionState),
@@ -2962,7 +3082,7 @@ handle_renegotiation_info(_RecordCB, client, #renegotiation_info{renegotiated_co
false ->
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, client_renegotiation))
end;
-handle_renegotiation_info(_RecordCB, server, #renegotiation_info{renegotiated_connection = ClientVerify},
+handle_renegotiation_info(_, _RecordCB, server, #renegotiation_info{renegotiated_connection = ClientVerify},
ConnectionStates, true, _, CipherSuites) ->
case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
@@ -2978,11 +3098,13 @@ handle_renegotiation_info(_RecordCB, server, #renegotiation_info{renegotiated_co
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, server_renegotiation))
end
end;
+handle_renegotiation_info({3,0}, _RecordCB, client, undefined, ConnectionStates, true, _SecureRenegotation, _) ->
+ {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)};
-handle_renegotiation_info(RecordCB, client, undefined, ConnectionStates, true, SecureRenegotation, _) ->
+handle_renegotiation_info(_, RecordCB, client, undefined, ConnectionStates, true, SecureRenegotation, _) ->
handle_renegotiation_info(RecordCB, ConnectionStates, SecureRenegotation);
-handle_renegotiation_info(RecordCB, server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) ->
+handle_renegotiation_info(_, RecordCB, server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) ->
case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
true ->
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, {server_renegotiation, empty_renegotiation_info_scsv}));
@@ -3036,7 +3158,7 @@ empty_extensions({3,4}, client_hello) ->
%% padding => undefined,
key_share => undefined,
pre_shared_key => undefined,
- %% psk_key_exhange_modes => undefined,
+ psk_key_exchange_modes => undefined,
%% early_data => undefined,
%% cookie => undefined,
client_hello_versions => undefined,
@@ -3065,6 +3187,8 @@ empty_extensions({3,4}, hello_retry_request) ->
key_share => undefined,
pre_shared_key => undefined
};
+empty_extensions({3,0}, _) ->
+ empty_extensions();
empty_extensions(_, server_hello) ->
#{renegotiation_info => undefined,
alpn => undefined,
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 323d9e3284..3998f03519 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -336,7 +336,9 @@ handle_protocol_record(#ssl_tls{type = ?ALERT, fragment = EncAlerts}, StateName,
handle_alerts(Alerts, {next_state, StateName, State});
[] ->
ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, empty_alert),
- Version, StateName, State)
+ Version, StateName, State);
+ #alert{} = Alert ->
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State)
catch
_:_ ->
ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, alert_decode_error),
@@ -1175,7 +1177,6 @@ encode_handshake(Handshake, Version, ConnectionStates0, Hist0) ->
encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) ->
tls_record:encode_change_cipher_spec(Version, ConnectionStates).
--spec decode_alerts(binary()) -> list().
decode_alerts(Bin) ->
ssl_alert:decode(Bin).
diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl
index c132f75eae..37265e0759 100644
--- a/lib/ssl/src/tls_handshake.erl
+++ b/lib/ssl/src/tls_handshake.erl
@@ -379,7 +379,7 @@ do_hello(Version, Versions, CipherSuites, Hello, SslOpts, Info, Renegotiation) -
%%--------------------------------------------------------------------
enc_handshake(#hello_request{}, {3, N}) when N < 4 ->
{?HELLO_REQUEST, <<>>};
-enc_handshake(#client_hello{client_version = {Major, Minor},
+enc_handshake(#client_hello{client_version = {Major, Minor} = Version,
random = Random,
session_id = SessionID,
cipher_suites = CipherSuites,
@@ -390,7 +390,7 @@ enc_handshake(#client_hello{client_version = {Major, Minor},
CmLength = byte_size(BinCompMethods),
BinCipherSuites = list_to_binary(CipherSuites),
CsLength = byte_size(BinCipherSuites),
- ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions),
+ ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions, Version),
{?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SIDLength), SessionID/binary,
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 49d20b3ec0..c29366e717 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -39,7 +39,7 @@
%% Create handshake messages
-export([certificate/5,
certificate_verify/4,
- encrypted_extensions/0]).
+ encrypted_extensions/1]).
-export([do_start/2,
do_negotiated/2,
@@ -61,10 +61,10 @@
%% Create handshake messages
%%====================================================================
-server_hello(MsgType, SessionId, KeyShare, ConnectionStates, ALPN) ->
+server_hello(MsgType, SessionId, KeyShare, ConnectionStates) ->
#{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates, read),
- Extensions = server_hello_extensions(MsgType, KeyShare, ALPN),
+ Extensions = server_hello_extensions(MsgType, KeyShare),
#server_hello{server_version = {3,3}, %% legacy_version
cipher_suite = SecParams#security_parameters.cipher_suite,
compression_method = 0, %% legacy attribute
@@ -73,6 +73,7 @@ server_hello(MsgType, SessionId, KeyShare, ConnectionStates, ALPN) ->
extensions = Extensions
}.
+
%% The server's extensions MUST contain "supported_versions".
%% Additionally, it SHOULD contain the minimal set of extensions
%% necessary for the client to generate a correct ClientHello pair. As
@@ -80,18 +81,14 @@ server_hello(MsgType, SessionId, KeyShare, ConnectionStates, ALPN) ->
%% extensions that were not first offered by the client in its
%% ClientHello, with the exception of optionally the "cookie" (see
%% Section 4.2.2) extension.
-server_hello_extensions(hello_retry_request = MsgType, KeyShare, _) ->
+server_hello_extensions(hello_retry_request = MsgType, KeyShare) ->
SupportedVersions = #server_hello_selected_version{selected_version = {3,4}},
Extensions = #{server_hello_selected_version => SupportedVersions},
ssl_handshake:add_server_share(MsgType, Extensions, KeyShare);
-server_hello_extensions(MsgType, KeyShare, undefined) ->
+server_hello_extensions(MsgType, KeyShare) ->
SupportedVersions = #server_hello_selected_version{selected_version = {3,4}},
Extensions = #{server_hello_selected_version => SupportedVersions},
- ssl_handshake:add_server_share(MsgType, Extensions, KeyShare);
-server_hello_extensions(MsgType, KeyShare, ALPN0) ->
- Extensions0 = ssl_handshake:add_selected_version(#{}), %% {3,4} (TLS 1.3)
- Extensions1 = ssl_handshake:add_alpn(Extensions0, ALPN0),
- ssl_handshake:add_server_share(MsgType, Extensions1, KeyShare).
+ ssl_handshake:add_server_share(MsgType, Extensions, KeyShare).
server_hello_random(server_hello, #security_parameters{server_random = Random}) ->
@@ -107,10 +104,14 @@ server_hello_random(hello_retry_request, _) ->
?HELLO_RETRY_REQUEST_RANDOM.
-%% TODO: implement support for encrypted_extensions
-encrypted_extensions() ->
+encrypted_extensions(#state{handshake_env = #handshake_env{alpn = undefined}}) ->
#encrypted_extensions{
extensions = #{}
+ };
+encrypted_extensions(#state{handshake_env = #handshake_env{alpn = ALPNProtocol}}) ->
+ Extensions = ssl_handshake:add_alpn(#{}, ALPNProtocol),
+ #encrypted_extensions{
+ extensions = Extensions
}.
@@ -503,7 +504,8 @@ do_start(#client_hello{cipher_suites = ClientCiphers,
ssl_options = #ssl_options{ciphers = ServerCiphers,
signature_algs = ServerSignAlgs,
supported_groups = ServerGroups0,
- alpn_preferred_protocols = ALPNPreferredProtocols},
+ alpn_preferred_protocols = ALPNPreferredProtocols,
+ honor_cipher_order = HonorCipherOrder},
session = #session{own_certificate = Cert}} = State0) ->
ClientGroups0 = maps:get(elliptic_curves, Extensions, undefined),
ClientGroups = get_supported_groups(ClientGroups0),
@@ -530,7 +532,7 @@ do_start(#client_hello{cipher_suites = ClientCiphers,
%% cipher suite, an (EC)DHE group and key share for key establishment,
%% and a signature algorithm/certificate pair to authenticate itself to
%% the client.
- Cipher = Maybe(select_cipher_suite(ClientCiphers, ServerCiphers)),
+ Cipher = Maybe(select_cipher_suite(HonorCipherOrder, ClientCiphers, ServerCiphers)),
Groups = Maybe(select_common_groups(ServerGroups, ClientGroups)),
Maybe(validate_client_key_share(ClientGroups, ClientShares)),
@@ -673,8 +675,7 @@ do_negotiated(start_handshake,
dh_public_value = ClientPublicKey},
ssl_options = #ssl_options{} = SslOpts,
key_share = KeyShare,
- handshake_env = #handshake_env{tls_handshake_history = _HHistory0,
- alpn = ALPN},
+ handshake_env = #handshake_env{tls_handshake_history = _HHistory0},
connection_env = #connection_env{private_key = CertPrivateKey},
static_env = #static_env{
cert_db = CertDbHandle,
@@ -689,7 +690,7 @@ do_negotiated(start_handshake,
try
%% Create server_hello
%% Extensions: supported_versions, key_share, (pre_shared_key)
- ServerHello = server_hello(server_hello, SessionId, KeyShare, ConnectionStates0, ALPN),
+ ServerHello = server_hello(server_hello, SessionId, KeyShare, ConnectionStates0),
{State1, _} = tls_connection:send_handshake(ServerHello, State0),
@@ -699,7 +700,7 @@ do_negotiated(start_handshake,
State3 = ssl_record:step_encryption_state(State2),
%% Create EncryptedExtensions
- EncryptedExtensions = encrypted_extensions(),
+ EncryptedExtensions = encrypted_extensions(State2),
%% Encode EncryptedExtensions
State4 = tls_connection:queue_handshake(EncryptedExtensions, State3),
@@ -881,12 +882,19 @@ do_wait_sh(#server_hello{cipher_suite = SelectedCipherSuite,
end.
-do_wait_ee(#encrypted_extensions{extensions = _Extensions}, State0) ->
+do_wait_ee(#encrypted_extensions{extensions = Extensions}, State0) ->
+
+ ALPNProtocol0 = maps:get(alpn, Extensions, undefined),
+ ALPNProtocol = get_alpn(ALPNProtocol0),
{Ref,_Maybe} = maybe(),
try
- {State0, wait_cert_cr}
+ %% Update state
+ #state{handshake_env = HsEnv} = State0,
+ State1 = State0#state{handshake_env = HsEnv#handshake_env{alpn = ALPNProtocol}},
+
+ {State1, wait_cert_cr}
catch
{Ref, {insufficient_security, no_suitable_groups}} ->
?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_groups);
@@ -1041,10 +1049,9 @@ compare_verify_data(_, _) ->
{error, decrypt_error}.
-send_hello_retry_request(#state{connection_states = ConnectionStates0,
- handshake_env = #handshake_env{alpn = ALPN}} = State0,
+send_hello_retry_request(#state{connection_states = ConnectionStates0} = State0,
no_suitable_key, KeyShare, SessionId) ->
- ServerHello = server_hello(hello_retry_request, SessionId, KeyShare, ConnectionStates0, ALPN),
+ ServerHello = server_hello(hello_retry_request, SessionId, KeyShare, ConnectionStates0),
{State1, _} = tls_connection:send_handshake(ServerHello, State0),
%% Update handshake history
@@ -1725,15 +1732,19 @@ handle_alpn([ServerProtocol|T], ClientProtocols) ->
end.
-select_cipher_suite([], _) ->
+select_cipher_suite(_, [], _) ->
{error, no_suitable_cipher};
-select_cipher_suite([Cipher|ClientCiphers], ServerCiphers) ->
+%% If honor_cipher_order is set to true, use the server's preference for
+%% cipher suite selection.
+select_cipher_suite(true, ClientCiphers, ServerCiphers) ->
+ select_cipher_suite(false, ServerCiphers, ClientCiphers);
+select_cipher_suite(false, [Cipher|ClientCiphers], ServerCiphers) ->
case lists:member(Cipher, tls_v1:suites('TLS_v1.3')) andalso
lists:member(Cipher, ServerCiphers) of
true ->
{ok, Cipher};
false ->
- select_cipher_suite(ClientCiphers, ServerCiphers)
+ select_cipher_suite(false, ClientCiphers, ServerCiphers)
end.
@@ -1869,6 +1880,14 @@ get_key_shares(#key_share_server_hello{server_share = ServerShare}) ->
get_selected_group(#key_share_hello_retry_request{selected_group = SelectedGroup}) ->
SelectedGroup.
+get_alpn(ALPNProtocol0) ->
+ case ssl_handshake:decode_alpn(ALPNProtocol0) of
+ undefined ->
+ undefined;
+ [ALPNProtocol] ->
+ ALPNProtocol
+ end.
+
maybe() ->
Ref = erlang:make_ref(),
Ok = fun(ok) -> ok;
diff --git a/lib/ssl/src/tls_handshake_1_3.hrl b/lib/ssl/src/tls_handshake_1_3.hrl
index 7ae1b93e1c..eb85f216c8 100644
--- a/lib/ssl/src/tls_handshake_1_3.hrl
+++ b/lib/ssl/src/tls_handshake_1_3.hrl
@@ -74,29 +74,52 @@
y % opaque Y[coordinate_length];
}).
+%% RFC 8446 4.2.9. Pre-Shared Key Exchange Modes
+
+%% enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
-define(PSK_KE, 0).
-define(PSK_DHE_KE, 1).
--record(psk_keyexchange_modes, {
+-record(psk_key_exchange_modes, {
ke_modes % ke_modes<1..255>
}).
+
+%% RFC 8446 4.2.10. Early Data Indication
-record(empty, {
}).
-record(early_data_indication, {
indication % uint32 max_early_data_size (new_session_ticket) |
%% #empty{} (client_hello, encrypted_extensions)
}).
--record(psk_identity, {
- identity, % opaque identity<1..2^16-1>
- obfuscated_ticket_age % uint32
- }).
--record(offered_psks, {
- psk_identity, %identities<7..2^16-1>;
- psk_binder_entry %binders<33..2^16-1>, opaque PskBinderEntry<32..255>
- }).
--record(pre_shared_keyextension,{
- extension %OfferedPsks (client_hello) | uint16 selected_identity (server_hello)
- }).
+
+%% RFC 8446 4.2.11. Pre-Shared Key Extension
+-record(psk_identity,
+ {
+ identity, % opaque identity<1..2^16-1>
+ obfuscated_ticket_age % uint32
+ }).
+
+-record(offered_psks,
+ {
+ identities, % PskIdentity identities<7..2^16-1>;
+ binders % PskBinderEntry binders<33..2^16-1>; opaque PskBinderEntry<32..255>
+ }).
+
+%% struct {
+%% select (Handshake.msg_type) {
+%% case client_hello: OfferedPsks;
+%% case server_hello: uint16 selected_identity;
+%% };
+%% } PreSharedKeyExtension;
+-record(pre_shared_key_client_hello,
+ {
+ offered_psks
+ }).
+
+-record(pre_shared_key_server_hello,
+ {
+ selected_identity
+ }).
%% RFC 8446 B.3.1.2.
-record(cookie, {
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index a5c550a429..2aeab98929 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -514,16 +514,27 @@ validate_tls_record_length(Versions, {_,Size0,_} = Q0, SslOpts, Acc, Type, Versi
end.
-binary_from_front(SplitSize, {Front,Size,Rear}) ->
+binary_from_front(0, Q) ->
+ {<<>>, Q};
+binary_from_front(SplitSize, {Front,Size,Rear}) when SplitSize =< Size ->
binary_from_front(SplitSize, Front, Size, Rear, []).
%%
-binary_from_front(SplitSize, [], Size, [_] = Rear, Acc) ->
- %% Optimize a simple case
- binary_from_front(SplitSize, Rear, Size, [], Acc);
+%% SplitSize > 0 and there is at least SplitSize bytes buffered in Front and Rear
binary_from_front(SplitSize, [], Size, Rear, Acc) ->
- binary_from_front(SplitSize, lists:reverse(Rear), Size, [], Acc);
+ case Rear of
+ %% Avoid lists:reverse/1 for simple cases.
+ %% Case clause for [] to avoid infinite loop.
+ [_] ->
+ binary_from_front(SplitSize, Rear, Size, [], Acc);
+ [Bin2,Bin1] ->
+ binary_from_front(SplitSize, [Bin1,Bin2], Size, [], Acc);
+ [Bin3,Bin2,Bin1] ->
+ binary_from_front(SplitSize, [Bin1,Bin2,Bin3], Size, [], Acc);
+ [_,_,_|_] ->
+ binary_from_front(SplitSize, lists:reverse(Rear), Size, [], Acc)
+ end;
binary_from_front(SplitSize, [Bin|Front], Size, Rear, []) ->
- %% Optimize a frequent case
+ %% Optimize the frequent case when the accumulator is empty
BinSize = byte_size(Bin),
if
SplitSize < BinSize ->
diff --git a/lib/ssl/src/tls_record_1_3.erl b/lib/ssl/src/tls_record_1_3.erl
index 74321a1ae2..d713062284 100644
--- a/lib/ssl/src/tls_record_1_3.erl
+++ b/lib/ssl/src/tls_record_1_3.erl
@@ -138,6 +138,15 @@ decode_cipher_text(#ssl_tls{type = ?ALERT,
{#ssl_tls{type = ?ALERT,
version = {3,4}, %% Internally use real version
fragment = <<2,47>>}, ConnectionStates0};
+%% TLS 1.3 server can receive a User Cancelled Alert when handshake is
+%% paused and then cancelled on the client side.
+decode_cipher_text(#ssl_tls{type = ?ALERT,
+ version = ?LEGACY_VERSION,
+ fragment = <<2,90>>},
+ ConnectionStates0) ->
+ {#ssl_tls{type = ?ALERT,
+ version = {3,4}, %% Internally use real version
+ fragment = <<2,90>>}, ConnectionStates0};
%% RFC8446 - TLS 1.3
%% D.4. Middlebox Compatibility Mode
%% - If not offering early data, the client sends a dummy
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index dba90aaff0..0925c0facc 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -37,14 +37,29 @@ VSN=$(SSL_VSN)
MODULES = \
ssl_test_lib \
+ ssl_app_env_SUITE\
+ ssl_alert_SUITE\
ssl_bench_test_lib \
ssl_dist_test_lib \
- ssl_alpn_handshake_SUITE \
+ ssl_api_SUITE\
+ tls_api_SUITE\
ssl_basic_SUITE \
ssl_bench_SUITE \
ssl_cipher_SUITE \
ssl_cipher_suite_SUITE \
- openssl_server_cipher_suite_SUITE\
+ openssl_cipher_suite_SUITE\
+ ssl_alpn_SUITE \
+ openssl_alpn_SUITE\
+ ssl_npn_SUITE \
+ openssl_npn_SUITE\
+ openssl_sni_SUITE\
+ ssl_renegotiate_SUITE\
+ openssl_renegotiate_SUITE\
+ openssl_reject_SUITE\
+ ssl_cert_tests\
+ ssl_cert_SUITE\
+ openssl_server_cert_SUITE\
+ openssl_client_cert_SUITE\
ssl_certificate_verify_SUITE\
ssl_crl_SUITE\
ssl_dist_SUITE \
@@ -52,12 +67,12 @@ MODULES = \
ssl_engine_SUITE\
ssl_handshake_SUITE \
ssl_npn_hello_SUITE \
- ssl_npn_handshake_SUITE \
ssl_packet_SUITE \
ssl_payload_SUITE \
ssl_pem_cache_SUITE \
+ ssl_session_SUITE \
ssl_session_cache_SUITE \
- ssl_to_openssl_SUITE \
+ openssl_session_SUITE \
ssl_ECC_SUITE \
ssl_ECC_openssl_SUITE \
ssl_ECC\
@@ -65,6 +80,10 @@ MODULES = \
ssl_sni_SUITE \
ssl_eqc_SUITE \
ssl_rfc_5869_SUITE \
+ tls_1_3_record_SUITE\
+ openssl_tls_1_3_version_SUITE\
+ tls_1_3_version_SUITE\
+ ssl_socket_SUITE\
make_certs \
x509_test \
inet_crypto_dist
diff --git a/lib/ssl/test/openssl_alpn_SUITE.erl b/lib/ssl/test/openssl_alpn_SUITE.erl
new file mode 100644
index 0000000000..5008dba922
--- /dev/null
+++ b/lib/ssl/test/openssl_alpn_SUITE.erl
@@ -0,0 +1,421 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(openssl_alpn_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(OPENSSL_QUIT, "Q\n").
+-define(OPENSSL_RENEGOTIATE, "R\n").
+-define(SLEEP, 1000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ %% Note: ALPN not supported in sslv3
+ case ssl_test_lib:openssl_sane_dtls_alpn() of
+ true ->
+ [
+ {group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}];
+ false ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'}]
+ end.
+
+groups() ->
+ case ssl_test_lib:openssl_sane_dtls_alpn() of
+ true ->
+ [
+ {'tlsv1.3', [], alpn_tests()},
+ {'tlsv1.2', [], alpn_tests() ++ alpn_npn_coexist() ++ rengotiation_tests()},
+ {'tlsv1.1', [], alpn_tests() ++ alpn_npn_coexist() ++ rengotiation_tests()},
+ {'tlsv1', [], alpn_tests() ++ alpn_npn_coexist() ++ rengotiation_tests()},
+ {'dtlsv1.2', [], alpn_tests()},
+ {'dtlsv1', [], alpn_tests()}
+ ];
+ false ->
+ [
+ {'tlsv1.3', [], alpn_tests()},
+ {'tlsv1.2', [], alpn_tests() ++ alpn_npn_coexist() ++ rengotiation_tests()},
+ {'tlsv1.1', [], alpn_tests() ++ alpn_npn_coexist() ++ rengotiation_tests()},
+ {'tlsv1', [], alpn_tests() ++ alpn_npn_coexist() ++ rengotiation_tests()}
+ ]
+ end.
+
+alpn_tests() ->
+ [erlang_client_alpn_openssl_server_alpn,
+ erlang_server_alpn_openssl_client_alpn,
+ erlang_client_alpn_openssl_server,
+ erlang_client_openssl_server_alpn,
+ erlang_server_alpn_openssl_client,
+ erlang_server_openssl_client_alpn].
+
+alpn_npn_coexist() ->
+ [
+ erlang_client_alpn_npn_openssl_server_alpn_npn,
+ erlang_server_alpn_npn_openssl_client_alpn_npn
+ ].
+rengotiation_tests() ->
+ case ssl_test_lib:sane_openssl_alpn_npn_renegotiate() of
+ true ->
+ [erlang_client_alpn_openssl_server_alpn_renegotiate,
+ erlang_server_alpn_openssl_client_alpn_renegotiate];
+ false ->
+ []
+ end.
+init_per_suite(Config0) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ case check_openssl_alpn_support(Config0) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
+ end
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ special_init(TestCase, Config).
+
+special_init(TestCase, Config)
+ when TestCase == erlang_client_alpn_openssl_server_alpn_renegotiate;
+ TestCase == erlang_server_alpn_openssl_client_alpn_renegotiate ->
+ {ok, Version} = application:get_env(ssl, protocol_version),
+ ssl_test_lib:check_sane_openssl_renegotaite(Config, Version);
+special_init(TestCase, Config)
+ when TestCase == erlang_client_alpn_npn_openssl_server_alpn_npn;
+ TestCase == erlang_server_alpn_npn_openssl_client_alpn_npn ->
+ ssl_test_lib:check_openssl_npn_support(Config);
+special_init(_, Config) ->
+ Config.
+
+end_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+erlang_client_alpn_openssl_server_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------
+
+erlang_server_alpn_openssl_client_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+
+erlang_client_alpn_openssl_server(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_client_and_openssl_server_with_opts(Config,
+ [{alpn_advertised_protocols, [<<"spdy/2">>]}],
+ [],
+ Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+
+erlang_client_openssl_server_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_client_and_openssl_server_with_opts(Config,
+ [],
+ ["-alpn", "spdy/2"],
+ Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+
+erlang_server_alpn_openssl_client(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_server_and_openssl_client_with_opts(Config,
+ [{alpn_preferred_protocols, [<<"spdy/2">>]}],
+ [],
+ Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+
+erlang_server_openssl_client_alpn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_server_and_openssl_client_with_opts(Config,
+ [],
+ ["-alpn", "spdy/2"],
+ Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------
+
+erlang_client_alpn_openssl_server_alpn_renegotiate(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------
+
+erlang_server_alpn_openssl_client_alpn_renegotiate(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------
+
+erlang_client_alpn_npn_openssl_server_alpn_npn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------
+
+erlang_server_alpn_npn_openssl_client_alpn_npn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_alpn_npn_negotiation(Config, Data, fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------------------
+%%--------------------------------------------------------------------
+check_openssl_alpn_support(Config) ->
+ HelpText = os:cmd("openssl s_client --help"),
+ case string:str(HelpText, "alpn") of
+ 0 ->
+ {skip, "Openssl not compiled with alpn support"};
+ _ ->
+ Config
+ end.
+
+start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts = proplists:get_value(server_rsa_verify_opts, Config),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ClientOpts = [{alpn_advertised_protocols, [<<"spdy/2">>]} | ClientOpts0],
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-accept",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile, "-key", KeyFile],
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ Callback(Client, OpensslPort),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
+
+start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>]} | ServerOpts0],
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_client", "-alpn", "http/1.0,spdy/2", "-msg", "-port",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-host", "localhost"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ Callback(Server, OpenSslPort),
+
+ ssl_test_lib:close(Server),
+
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
+
+start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts = proplists:get_value(server_rsa_verify_opts, Config),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ClientOpts = [{alpn_advertised_protocols, [<<"spdy/2">>]},
+ {client_preferred_next_protocols, {client, [<<"spdy/3">>, <<"http/1.1">>]}} | ClientOpts0],
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-nextprotoneg",
+ "spdy/3", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ Callback(Client, OpensslPort),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
+
+start_erlang_server_and_openssl_client_for_alpn_npn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>]},
+ {next_protocols_advertised, [<<"spdy/3">>, <<"http/1.1">>]} | ServerOpts0],
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_client", "-alpn", "http/1.1,spdy/2", "-nextprotoneg", "spdy/3",
+ "-msg", "-port", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-host", "localhost"],
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ Callback(Server, OpenSslPort),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
+
diff --git a/lib/ssl/test/openssl_server_cipher_suite_SUITE.erl b/lib/ssl/test/openssl_cipher_suite_SUITE.erl
index 6ce34ce7fa..955eb914c0 100644
--- a/lib/ssl/test/openssl_server_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/openssl_cipher_suite_SUITE.erl
@@ -20,7 +20,7 @@
%%
--module(openssl_server_cipher_suite_SUITE).
+-module(openssl_cipher_suite_SUITE).
%% Note: This directive should only be used in test suites.
-compile(export_all).
@@ -31,19 +31,26 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() ->
- [
- {group, 'tlsv1.2'},
+ [
+ {group, openssl_server},
+ {group, openssl_client}
+ ].
+
+all_protocol_groups() ->
+ [{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
{group, 'sslv3'},
{group, 'dtlsv1.2'},
{group, 'dtlsv1'}
- ].
+ ].
groups() ->
%% TODO: Enable SRP, PSK suites (needs OpenSSL s_server conf)
%% TODO: Enable all "kex" on DTLS
[
+ {openssl_server, all_protocol_groups()},
+ {openssl_client, all_protocol_groups()},
{'tlsv1.2', [], kex()},
{'tlsv1.1', [], kex()},
{'tlsv1', [], kex()},
@@ -135,6 +142,9 @@ kex() ->
dtls_kex() -> %% Should be all kex in the future
dtls_rsa() ++ dss() ++ anonymous().
+ssl3_kex() ->
+ ssl3_rsa() ++ ssl3_dss() ++ ssl3_anonymous().
+
rsa() ->
[{group, dhe_rsa},
{group, ecdhe_rsa},
@@ -148,6 +158,11 @@ dtls_rsa() ->
%%,{group, rsa_psk}
].
+ssl3_rsa() ->
+ [{group, dhe_rsa},
+ {group, rsa}
+ ].
+
ecdsa() ->
[{group, ecdhe_ecdsa}].
@@ -156,6 +171,10 @@ dss() ->
%%{group, srp_dss}
].
+ssl3_dss() ->
+ [{group, dhe_dss}
+ ].
+
anonymous() ->
[{group, dh_anon},
{group, ecdh_anon}
@@ -165,6 +184,9 @@ anonymous() ->
%%{group, srp_anon}
].
+ssl3_anonymous() ->
+ [{group, dh_anon}].
+
init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
@@ -177,7 +199,8 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ssl:stop(),
- application:stop(crypto).
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
%%--------------------------------------------------------------------
init_per_group(GroupName, Config) ->
@@ -198,7 +221,12 @@ init_per_group(GroupName, Config) ->
false ->
do_init_per_group(GroupName, Config)
end.
-
+do_init_per_group(openssl_client, Config0) ->
+ Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
+ [{client_type, openssl}, {server_type, erlang} | Config];
+do_init_per_group(openssl_server, Config0) ->
+ Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
+ [{client_type, erlang}, {server_type, openssl} | Config];
do_init_per_group(GroupName, Config) when GroupName == ecdh_anon;
GroupName == ecdhe_rsa;
GroupName == ecdhe_psk ->
@@ -746,8 +774,7 @@ cipher_suite_test(CipherSuite, _Version, Config) ->
ct:log("Testing CipherSuite ~p~n", [CipherSuite]),
ct:log("Server Opts ~p~n", [ServerOpts]),
ct:log("Client Opts ~p~n", [ClientOpts]),
- ssl_test_lib:basic_test([{ciphers, [CipherSuite]} | COpts], SOpts, [{client_type, erlang},
- {server_type, openssl} | Config]).
+ ssl_test_lib:basic_test([{ciphers, [CipherSuite]} | COpts], SOpts, Config).
test_ciphers(Kex, Cipher, Version) ->
diff --git a/lib/ssl/test/openssl_client_cert_SUITE.erl b/lib/ssl/test/openssl_client_cert_SUITE.erl
new file mode 100644
index 0000000000..b327988744
--- /dev/null
+++ b/lib/ssl/test/openssl_client_cert_SUITE.erl
@@ -0,0 +1,350 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(openssl_client_cert_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, openssl_client}
+ ].
+
+groups() ->
+ [
+ {openssl_client, [], protocol_groups()},
+ {'tlsv1.3', [], tls_1_3_protocol_groups()},
+ {'tlsv1.2', [], pre_tls_1_3_protocol_groups()},
+ {'tlsv1.1', [], pre_tls_1_3_protocol_groups()},
+ {'tlsv1', [], pre_tls_1_3_protocol_groups()},
+ {'sslv3', [], ssl_protocol_groups()},
+ {'dtlsv1.2', [], pre_tls_1_3_protocol_groups()},
+ {'dtlsv1', [], pre_tls_1_3_protocol_groups()},
+ {rsa, [], all_version_tests()},
+ {ecdsa, [], all_version_tests()},
+ {dsa, [], all_version_tests()},
+ {rsa_1_3, [], all_version_tests() ++ tls_1_3_tests() ++ [unsupported_sign_algo_client_auth,
+ unsupported_sign_algo_cert_client_auth]},
+ {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
+ ].
+
+protocol_groups() ->
+ [{group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+ssl_protocol_groups() ->
+ [{group, rsa},
+ {group, dsa}].
+
+pre_tls_1_3_protocol_groups() ->
+ [{group, rsa},
+ {group, ecdsa},
+ {group, dsa}].
+
+tls_1_3_protocol_groups() ->
+ [{group, rsa_1_3},
+ {group, ecdsa_1_3}].
+
+tls_1_3_tests() ->
+ [
+ hello_retry_request,
+ custom_groups,
+ hello_retry_client_auth,
+ hello_retry_client_auth_empty_cert_accepted,
+ hello_retry_client_auth_empty_cert_rejected
+ ].
+
+all_version_tests() ->
+ [
+ no_auth,
+ auth,
+ client_auth_empty_cert_accepted,
+ client_auth_empty_cert_rejected,
+ client_auth_partial_chain,
+ client_auth_allow_partial_chain,
+ client_auth_do_not_allow_partial_chain,
+ client_auth_partial_chain_fun_fail,
+ missing_root_cert_no_auth
+ %%invalid_signature_client
+ ].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ Config
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+init_per_group(openssl_client, Config0) ->
+ Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
+ [{client_type, openssl}, {server_type, erlang} | Config];
+init_per_group(Group, Config0) when Group == rsa;
+ Group == rsa_1_3 ->
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ COpts = proplists:get_value(client_rsa_opts, Config),
+ SOpts = proplists:get_value(server_rsa_opts, Config),
+ %% Make sure _rsa* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(fun(dhe_rsa) ->
+ true;
+ (ecdhe_rsa) ->
+ true;
+ (_) ->
+ false
+ end, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, rsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+init_per_group(Group, Config0) when Group == ecdsa;
+ Group == ecdsa_1_3 ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(ecdsa, PKAlg) andalso (lists:member(ecdh, PKAlg) orelse
+ lists:member(dh, PKAlg)) of
+ true ->
+ Config = ssl_test_lib:make_ecdsa_cert(Config0),
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ %% Make sure ecdh* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(fun(ecdh_ecdsa) ->
+ true;
+ (ecdhe_ecdsa) ->
+ true;
+ (_) ->
+ false
+ end, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, ecdsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))]
+ )];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
+init_per_group(Group, Config0) when Group == dsa ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(dss, PKAlg) andalso lists:member(dh, PKAlg) of
+ true ->
+ Config = ssl_test_lib:make_dsa_cert(Config0),
+ COpts = proplists:get_value(client_dsa_opts, Config),
+ SOpts = proplists:get_value(server_dsa_opts, Config),
+ %% Make sure dhe_dss* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(fun(dh_dss) ->
+ true;
+ (dhe_dss) ->
+ true;
+ (_) ->
+ false
+ end, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, dsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+ false ->
+ {skip, "Missing DSS crypto support"}
+ end;
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ [{version, GroupName}
+ | ssl_test_lib:init_tls_version(GroupName, Config)];
+ false ->
+ {skip, "Missing openssl support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+init_per_testcase(TestCase, Config) when
+ TestCase == client_auth_empty_cert_accepted;
+ TestCase == client_auth_empty_cert_rejected ->
+ Version = proplists:get_value(version,Config),
+ case Version of
+ sslv3 ->
+ %% Openssl client sends "No Certificate Reserved" warning ALERT
+ %% instead of sending EMPTY cert message in SSL-3.0 so empty cert test are not
+ %% relevant
+ {skip, openssl_behaves_differently};
+ _ ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config
+ end;
+init_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+no_auth() ->
+ ssl_cert_tests:no_auth().
+
+no_auth(Config) ->
+ ssl_cert_tests:no_auth(Config).
+%%--------------------------------------------------------------------
+auth() ->
+ ssl_cert_tests:auth().
+auth(Config) ->
+ ssl_cert_tests:auth(Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_accepted() ->
+ ssl_cert_tests:client_auth_empty_cert_accepted().
+client_auth_empty_cert_accepted(Config) ->
+ ssl_cert_tests:client_auth_empty_cert_accepted(Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_rejected() ->
+ ssl_cert_tests:client_auth_empty_cert_rejected().
+client_auth_empty_cert_rejected(Config) ->
+ ssl_cert_tests:client_auth_empty_cert_rejected(Config).
+%%--------------------------------------------------------------------
+client_auth_partial_chain() ->
+ ssl_cert_tests:client_auth_partial_chain().
+client_auth_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_partial_chain(Config).
+
+%%--------------------------------------------------------------------
+client_auth_allow_partial_chain() ->
+ ssl_cert_tests:client_auth_allow_partial_chain().
+client_auth_allow_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_allow_partial_chain(Config).
+%%--------------------------------------------------------------------
+client_auth_do_not_allow_partial_chain() ->
+ ssl_cert_tests:client_auth_do_not_allow_partial_chain().
+client_auth_do_not_allow_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_do_not_allow_partial_chain(Config).
+
+%%--------------------------------------------------------------------
+client_auth_partial_chain_fun_fail() ->
+ ssl_cert_tests:client_auth_partial_chain_fun_fail().
+client_auth_partial_chain_fun_fail(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_partial_chain_fun_fail(Config).
+
+%%--------------------------------------------------------------------
+missing_root_cert_no_auth() ->
+ ssl_cert_tests:missing_root_cert_no_auth().
+missing_root_cert_no_auth(Config) when is_list(Config) ->
+ ssl_cert_tests:missing_root_cert_no_auth(Config).
+
+%%--------------------------------------------------------------------
+invalid_signature_client() ->
+ ssl_cert_tests:invalid_signature_client().
+invalid_signature_client(Config) when is_list(Config) ->
+ ssl_cert_tests:invalid_signature_client(Config).
+%%--------------------------------------------------------------------
+invalid_signature_server() ->
+ ssl_cert_tests:invalid_signature_client().
+invalid_signature_server(Config) when is_list(Config) ->
+ ssl_cert_tests:invalid_signature_client(Config).
+
+%%--------------------------------------------------------------------
+%% TLS 1.3 Test Cases ------------------------------------------------
+%%--------------------------------------------------------------------
+hello_retry_request() ->
+ ssl_cert_tests:hello_retry_request().
+hello_retry_request(Config) ->
+ ssl_cert_tests:hello_retry_request(Config).
+%%--------------------------------------------------------------------
+custom_groups() ->
+ ssl_cert_tests:custom_groups().
+custom_groups(Config) ->
+ ssl_cert_tests:custom_groups(Config).
+unsupported_sign_algo_cert_client_auth() ->
+ ssl_cert_tests:unsupported_sign_algo_cert_client_auth().
+unsupported_sign_algo_cert_client_auth(Config) ->
+ ssl_cert_tests:unsupported_sign_algo_cert_client_auth(Config).
+unsupported_sign_algo_client_auth() ->
+ ssl_cert_tests:unsupported_sign_algo_client_auth().
+unsupported_sign_algo_client_auth(Config) ->
+ ssl_cert_tests:unsupported_sign_algo_client_auth(Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth() ->
+ ssl_cert_tests:hello_retry_client_auth().
+hello_retry_client_auth(Config) ->
+ ssl_cert_tests:hello_retry_client_auth(Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_accepted() ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_accepted().
+hello_retry_client_auth_empty_cert_accepted(Config) ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_accepted(Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_rejected() ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_rejected().
+hello_retry_client_auth_empty_cert_rejected(Config) ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_rejected(Config).
diff --git a/lib/ssl/test/openssl_npn_SUITE.erl b/lib/ssl/test/openssl_npn_SUITE.erl
new file mode 100644
index 0000000000..0294f4997f
--- /dev/null
+++ b/lib/ssl/test/openssl_npn_SUITE.erl
@@ -0,0 +1,311 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(openssl_npn_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(OPENSSL_QUIT, "Q\n").
+-define(OPENSSL_RENEGOTIATE, "R\n").
+-define(SLEEP, 1000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ %% NPN is not supported in TLS-1.3 (replaced by ALPN and deprecated in TLS 1.2)
+ %% OpenSSL DTLS support for NPN is either not there or broken.
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'}].
+
+groups() ->
+ [{'tlsv1.2', [], npn_tests() ++ npn_renegotiate_tests()},
+ {'tlsv1.1', [], npn_tests() ++ npn_renegotiate_tests()},
+ {'tlsv1', [], npn_tests() ++ npn_renegotiate_tests()}
+ ].
+
+npn_tests() ->
+ [erlang_client_openssl_server_npn,
+ erlang_server_openssl_client_npn,
+ erlang_server_openssl_client_npn_only_client,
+ erlang_server_openssl_client_npn_only_server,
+ erlang_client_openssl_server_npn_only_client,
+ erlang_client_openssl_server_npn_only_server].
+
+npn_renegotiate_tests() ->
+ case ssl_test_lib:sane_openssl_alpn_npn_renegotiate() of
+ true ->
+ [erlang_server_openssl_client_npn_renegotiate,
+ erlang_client_openssl_server_npn_renegotiate];
+ false ->
+ []
+ end.
+
+init_per_suite(Config0) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ case check_openssl_npn_support(Config0) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
+ end
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ special_init(TestCase, Config).
+
+special_init(TestCase, Config)
+ when TestCase == erlang_client_npn_openssl_server_npn_renegotiate;
+ TestCase == erlang_server_npn_openssl_client_npn_renegotiate ->
+ {ok, Version} = application:get_env(ssl, protocol_version),
+ ssl_test_lib:check_sane_openssl_renegotaite(Config, Version);
+special_init(_, Config) ->
+ Config.
+
+end_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_npn() ->
+ [{doc,"Test erlang client with openssl server doing npn negotiation"}].
+
+erlang_client_openssl_server_npn(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data,
+ fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+
+%%--------------------------------------------------------------------
+erlang_client_openssl_server_npn_renegotiate() ->
+ [{doc,"Test erlang client with openssl server doing npn negotiation and renegotiate"}].
+
+erlang_client_openssl_server_npn_renegotiate(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data,
+ fun(Client, OpensslPort) ->
+ true = port_command(OpensslPort,
+ ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Client, Data)
+ end).
+%%--------------------------------------------------------------------------
+erlang_server_openssl_client_npn() ->
+ [{doc,"Test erlang server with openssl client and npn negotiation"}].
+
+erlang_server_openssl_client_npn(Config) when is_list(Config) ->
+
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data,
+ fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+erlang_server_openssl_client_npn_renegotiate() ->
+ [{doc,"Test erlang server with openssl client and npn negotiation with renegotiation"}].
+
+erlang_server_openssl_client_npn_renegotiate(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data,
+ fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort,
+ ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+%%--------------------------------------------------------------------------
+erlang_client_openssl_server_npn_only_server(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_client_and_openssl_server_with_opts(Config, [],
+ ["-nextprotoneg", "spdy/2"], Data,
+ fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+
+erlang_client_openssl_server_npn_only_client(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_client_and_openssl_server_with_opts(Config,
+ [{client_preferred_next_protocols,
+ {client, [<<"spdy/2">>], <<"http/1.1">>}}], [],
+ Data,
+ fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------------
+erlang_server_openssl_client_npn_only_server(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_server_and_openssl_client_with_opts(Config,
+ [{next_protocols_advertised, [<<"spdy/2">>]}], [],
+ Data,
+ fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+erlang_server_openssl_client_npn_only_client(Config) when is_list(Config) ->
+ Data = "From openssl to erlang",
+ ssl_test_lib:start_erlang_server_and_openssl_client_with_opts(Config, [], ["-nextprotoneg", "spdy/2"],
+ Data,
+ fun(Server, OpensslPort) ->
+ true = port_command(OpensslPort, Data),
+ ssl_test_lib:check_result(Server, Data)
+ end).
+
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------------------
+%%--------------------------------------------------------------------
+
+start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ClientOpts = [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}} | ClientOpts0],
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_server", "-msg", "-nextprotoneg", "http/1.1,spdy/2", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile, "-key", KeyFile],
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ClientOpts}]),
+
+ Callback(Client, OpensslPort),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
+
+start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ServerOpts = [{next_protocols_advertised, [<<"spdy/2">>]} | ServerOpts0],
+
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_client", "-nextprotoneg", "http/1.0,spdy/2", "-msg", "-connect",
+ ssl_test_lib:hostname_format(Hostname) ++ ":"
+ ++ integer_to_list(Port), ssl_test_lib:version_flag(Version)],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ Callback(Server, OpenSslPort),
+
+ ssl_test_lib:close(Server),
+
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
+
+check_openssl_npn_support(Config) ->
+ HelpText = os:cmd("openssl s_client --help"),
+ case string:str(HelpText, "nextprotoneg") of
+ 0 ->
+ {skip, "Openssl not compiled with nextprotoneg support"};
+ _ ->
+ Config
+ end.
diff --git a/lib/ssl/test/openssl_reject_SUITE.erl b/lib/ssl/test/openssl_reject_SUITE.erl
new file mode 100644
index 0000000000..deefd11823
--- /dev/null
+++ b/lib/ssl/test/openssl_reject_SUITE.erl
@@ -0,0 +1,209 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(openssl_reject_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(SLEEP, 1000).
+-define(OPENSSL_GARBAGE, "P\n").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'}].
+
+groups() ->
+ [{'tlsv1.2', [], all_versions_tests()},
+ {'tlsv1.1', [], all_versions_tests()},
+ {'tlsv1', [], all_versions_tests()},
+ {'sslv3', [], all_versions_tests()}
+ ].
+
+all_versions_tests() ->
+ [
+ erlang_client_bad_openssl_server,
+ ssl2_erlang_server_openssl_client
+ ].
+
+init_per_suite(Config0) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ special_init(TestCase, Config).
+
+special_init(ssl2_erlang_server_openssl_client, Config) ->
+ case ssl_test_lib:supports_ssl_tls_version(sslv2) of
+ true ->
+ Config;
+ false ->
+ {skip, "sslv2 not supported by openssl"}
+ end;
+special_init(_, Config) ->
+ Config.
+
+end_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+erlang_client_bad_openssl_server() ->
+ [{doc,"Test what happens if openssl server sends garbage to erlang ssl client"}].
+erlang_client_bad_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile, "-key", KeyFile],
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, server_sent_garbage, []}},
+ {options,
+ [{versions, [Version]} | ClientOpts]}]),
+
+ %% Send garbage
+ true = port_command(OpensslPort, ?OPENSSL_GARBAGE),
+
+ ct:sleep(?SLEEP),
+
+ Client0 ! server_sent_garbage,
+
+ ssl_test_lib:check_result(Client0, true),
+
+ ssl_test_lib:close(Client0),
+
+ %% Make sure openssl does not hang and leave zombie process
+ Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options,
+ [{versions, [Version]} | ClientOpts]}]),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client1),
+ process_flag(trap_exit, false).
+
+%%--------------------------------------------------------------------
+ssl2_erlang_server_openssl_client() ->
+ [{doc,"Test that ssl v2 clients are rejected"}].
+
+ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Exe = "openssl",
+ Args = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
+ "-ssl2", "-msg"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
+ ssl_test_lib:consume_port_exit(OpenSslPort),
+ ssl_test_lib:check_server_alert(Server, unexpected_message),
+ process_flag(trap_exit, false).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+server_sent_garbage(Socket) ->
+ receive
+ server_sent_garbage ->
+ {error, closed} == ssl:send(Socket, "data")
+
+ end.
diff --git a/lib/ssl/test/openssl_renegotiate_SUITE.erl b/lib/ssl/test/openssl_renegotiate_SUITE.erl
new file mode 100644
index 0000000000..91a8175ac6
--- /dev/null
+++ b/lib/ssl/test/openssl_renegotiate_SUITE.erl
@@ -0,0 +1,341 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(openssl_renegotiate_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(SLEEP, 1000).
+-define(OPENSSL_RENEGOTIATE, "R\n").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ case ssl_test_lib:openssl_sane_dtls() of
+ true ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}];
+ false ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'}]
+ end.
+
+groups() ->
+ case ssl_test_lib:openssl_sane_dtls() of
+ true ->
+ [{'tlsv1.2', [], all_versions_tests()},
+ {'tlsv1.1', [], all_versions_tests()},
+ {'tlsv1', [], all_versions_tests()},
+ {'sslv3', [], all_versions_tests()},
+ {'dtlsv1.2', [], all_versions_tests()},
+ {'dtlsv1', [], all_versions_tests()}
+ ];
+ false ->
+ [{'tlsv1.2', [], all_versions_tests()},
+ {'tlsv1.1', [], all_versions_tests()},
+ {'tlsv1', [], all_versions_tests()},
+ {'sslv3', [], all_versions_tests()}
+ ]
+ end.
+
+all_versions_tests() ->
+ [
+ erlang_client_openssl_server_renegotiate,
+ erlang_client_openssl_server_renegotiate_after_client_data,
+ erlang_client_openssl_server_nowrap_seqnum,
+ erlang_server_openssl_client_nowrap_seqnum
+ ].
+
+
+init_per_suite(Config0) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ special_init(TestCase, Config).
+
+special_init(TestCase, Config)
+ when TestCase == erlang_client_openssl_server_renegotiate;
+ TestCase == erlang_client_openssl_server_nowrap_seqnum;
+ TestCase == erlang_server_openssl_client_nowrap_seqnum;
+ TestCase == erlang_client_openssl_server_renegotiate_after_client_data
+ ->
+ {ok, Version} = application:get_env(ssl, protocol_version),
+ ssl_test_lib:check_sane_openssl_renegotaite(Config, Version);
+special_init(_, Config) ->
+ Config.
+
+end_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_renegotiate() ->
+ [{doc,"Test erlang client when openssl server issuses a renegotiate"}].
+erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl",
+ OpenSslData = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ delayed_send, [[ErlData, OpenSslData]]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, OpenSslData),
+
+ ssl_test_lib:check_result(Client, OpenSslData),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+erlang_client_openssl_server_renegotiate_after_client_data() ->
+ [{doc,"Test erlang client when openssl server issuses a renegotiate after reading client data"}].
+erlang_client_openssl_server_renegotiate_after_client_data(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl",
+ OpenSslData = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_wait_send, [[ErlData, OpenSslData]]}},
+ {options, [{reuse_sessions, false} |ClientOpts]}]),
+
+ true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ ct:sleep(?SLEEP),
+ true = port_command(OpensslPort, OpenSslData),
+
+ ssl_test_lib:check_result(Client, OpenSslData),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+erlang_client_openssl_server_nowrap_seqnum() ->
+ [{doc, "Test that erlang client will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."}].
+erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl\n",
+ N = 10,
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile, "-key", KeyFile, "-msg"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[ErlData, N+2]]}},
+ {options, [{reuse_sessions, false},
+ {renegotiate_at, N} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
+%%--------------------------------------------------------------------
+erlang_server_openssl_client_nowrap_seqnum() ->
+ [{doc, "Test that erlang client will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."}].
+erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ N = 10,
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[Data, N+2]]}},
+ {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+ Exe = "openssl",
+ Args = ["s_client","-connect", ssl_test_lib:hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-msg"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ true = port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+delayed_send(Socket, [ErlData, OpenSslData]) ->
+ ct:sleep(?SLEEP),
+ ssl:send(Socket, ErlData),
+ ssl_test_lib:active_recv(Socket, length(OpenSslData)).
+
+
+send_wait_send(Socket, [ErlData, OpenSslData]) ->
+ ssl:send(Socket, ErlData),
+ ct:sleep(?SLEEP),
+ ssl:send(Socket, ErlData),
+ ssl_test_lib:active_recv(Socket, length(OpenSslData)).
+
diff --git a/lib/ssl/test/openssl_server_cert_SUITE.erl b/lib/ssl/test/openssl_server_cert_SUITE.erl
new file mode 100644
index 0000000000..c2af864a92
--- /dev/null
+++ b/lib/ssl/test/openssl_server_cert_SUITE.erl
@@ -0,0 +1,373 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(openssl_server_cert_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, openssl_server}].
+
+groups() ->
+ [
+ {openssl_server, [], protocol_groups()},
+ {'tlsv1.3', [], tls_1_3_protocol_groups()},
+ {'tlsv1.2', [], pre_tls_1_3_protocol_groups()},
+ {'tlsv1.1', [], pre_tls_1_3_protocol_groups()},
+ {'tlsv1', [], pre_tls_1_3_protocol_groups()},
+ {'sslv3', [], ssl_protocol_groups()},
+ {'dtlsv1.2', [], pre_tls_1_3_protocol_groups()},
+ {'dtlsv1', [], pre_tls_1_3_protocol_groups()},
+ {rsa, [], all_version_tests()},
+ {ecdsa, [], all_version_tests()},
+ {dsa, [], all_version_tests()},
+ {rsa_1_3, [], all_version_tests() ++ tls_1_3_tests()},
+ %% TODO: Create proper conf of openssl server
+ %%++ [unsupported_sign_algo_client_auth,
+ %% unsupported_sign_algo_cert_client_auth]},
+ {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
+ ].
+
+protocol_groups() ->
+ [{group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+ssl_protocol_groups() ->
+ [{group, rsa},
+ {group, dsa}].
+
+pre_tls_1_3_protocol_groups() ->
+ [{group, rsa},
+ {group, ecdsa},
+ {group, dsa}].
+
+tls_1_3_protocol_groups() ->
+ [{group, rsa_1_3},
+ {group, ecdsa_1_3}].
+
+tls_1_3_tests() ->
+ [
+ hello_retry_request,
+ custom_groups,
+ hello_retry_client_auth,
+ hello_retry_client_auth_empty_cert_accepted,
+ hello_retry_client_auth_empty_cert_rejected
+ ].
+
+all_version_tests() ->
+ [
+ no_auth,
+ auth,
+ missing_root_cert_no_auth
+ %%invalid_signature_client
+ ].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ Config
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+init_per_group(openssl_server, Config0) ->
+ Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
+ [{client_type, erlang}, {server_type, openssl} | Config];
+init_per_group(rsa = Group, Config0) ->
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ COpts = proplists:get_value(client_rsa_opts, Config),
+ SOpts = proplists:get_value(server_rsa_opts, Config),
+ %% Make sure _rsa* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(fun(dhe_rsa) ->
+ true;
+ (ecdhe_rsa) ->
+ true;
+ (_) ->
+ false
+ end, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, rsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+init_per_group(rsa_1_3 = Group, Config0) ->
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ COpts = proplists:get_value(client_rsa_opts, Config),
+ SOpts = proplists:get_value(server_rsa_opts, Config),
+ %% Make sure _rsa* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(undefined, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, rsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+init_per_group(ecdsa = Group, Config0) ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(ecdsa, PKAlg) andalso (lists:member(ecdh, PKAlg) orelse
+ lists:member(dh, PKAlg)) of
+ true ->
+ Config = ssl_test_lib:make_ecdsa_cert(Config0),
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ %% Make sure ecdh* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(fun(ecdh_ecdsa) ->
+ true;
+ (ecdhe_ecdsa) ->
+ true;
+ (_) ->
+ false
+ end, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, ecdsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))]
+ )];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
+init_per_group(ecdsa_1_3 = Group, Config0) ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(ecdsa, PKAlg) andalso (lists:member(ecdh, PKAlg) orelse
+ lists:member(dh, PKAlg)) of
+ true ->
+ Config = ssl_test_lib:make_ecdsa_cert(Config0),
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ %% Make sure ecdh* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(undefined, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, ecdsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))]
+ )];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
+init_per_group(Group, Config0) when Group == dsa ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(dss, PKAlg) andalso lists:member(dh, PKAlg) of
+ true ->
+ Config = ssl_test_lib:make_dsa_cert(Config0),
+ COpts = proplists:get_value(client_dsa_opts, Config),
+ SOpts = proplists:get_value(server_dsa_opts, Config),
+ %% Make sure dhe_dss* suite is choosen by ssl_test_lib:start_server
+ Version = proplists:get_value(version,Config),
+ Ciphers = ssl_cert_tests:test_ciphers(fun(dh_dss) ->
+ true;
+ (dhe_dss) ->
+ true;
+ (_) ->
+ false
+ end, Version),
+ case Ciphers of
+ [_|_] ->
+ [{cert_key_alg, dsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, [{ciphers, Ciphers} | COpts]},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+ [] ->
+ {skip, {no_sup, Group, Version}}
+ end;
+ false ->
+ {skip, "Missing DSS crypto support"}
+ end;
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ [{version, GroupName}
+ | ssl_test_lib:init_tls_version(GroupName, Config)];
+ false ->
+ {skip, "Missing openssl support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+no_auth() ->
+ ssl_cert_tests:no_auth().
+
+no_auth(Config) ->
+ ssl_cert_tests:no_auth(Config).
+%%--------------------------------------------------------------------
+auth() ->
+ ssl_cert_tests:auth().
+auth(Config) ->
+ ssl_cert_tests:auth(Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_accepted() ->
+ ssl_cert_tests:client_auth_empty_cert_accepted().
+client_auth_empty_cert_accepted(Config) ->
+ ssl_cert_tests:client_auth_empty_cert_accepted(Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_rejected() ->
+ ssl_cert_tests:client_auth_empty_cert_rejected().
+client_auth_empty_cert_rejected(Config) ->
+ ssl_cert_tests:client_auth_empty_cert_rejected(Config).
+%%--------------------------------------------------------------------
+client_auth_partial_chain() ->
+ ssl_cert_tests:client_auth_partial_chain().
+client_auth_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_partial_chain(Config).
+
+%%--------------------------------------------------------------------
+client_auth_allow_partial_chain() ->
+ ssl_cert_tests:client_auth_allow_partial_chain().
+client_auth_allow_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_allow_partial_chain(Config).
+%%--------------------------------------------------------------------
+client_auth_do_not_allow_partial_chain() ->
+ ssl_cert_tests:client_auth_do_not_allow_partial_chain().
+client_auth_do_not_allow_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_do_not_allow_partial_chain(Config).
+
+%%--------------------------------------------------------------------
+client_auth_partial_chain_fun_fail() ->
+ ssl_cert_tests:client_auth_partial_chain_fun_fail().
+client_auth_partial_chain_fun_fail(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_partial_chain_fun_fail(Config).
+
+%%--------------------------------------------------------------------
+missing_root_cert_no_auth() ->
+ ssl_cert_tests:missing_root_cert_no_auth().
+missing_root_cert_no_auth(Config) when is_list(Config) ->
+ ssl_cert_tests:missing_root_cert_no_auth(Config).
+
+%%--------------------------------------------------------------------
+invalid_signature_client() ->
+ ssl_cert_tests:invalid_signature_client().
+invalid_signature_client(Config) when is_list(Config) ->
+ ssl_cert_tests:invalid_signature_client(Config).
+%%--------------------------------------------------------------------
+invalid_signature_server() ->
+ ssl_cert_tests:invalid_signature_client().
+invalid_signature_server(Config) when is_list(Config) ->
+ ssl_cert_tests:invalid_signature_client(Config).
+
+%%--------------------------------------------------------------------
+%% TLS 1.3 Test Cases ------------------------------------------------
+%%--------------------------------------------------------------------
+hello_retry_request() ->
+ ssl_cert_tests:hello_retry_request().
+hello_retry_request(Config) ->
+ ssl_cert_tests:hello_retry_request(Config).
+%%--------------------------------------------------------------------
+custom_groups() ->
+ ssl_cert_tests:custom_groups().
+custom_groups(Config) ->
+ ssl_cert_tests:custom_groups(Config).
+unsupported_sign_algo_cert_client_auth() ->
+ ssl_cert_tests:unsupported_sign_algo_cert_client_auth().
+unsupported_sign_algo_cert_client_auth(Config) ->
+ ssl_cert_tests:unsupported_sign_algo_cert_client_auth(Config).
+unsupported_sign_algo_client_auth() ->
+ ssl_cert_tests:unsupported_sign_algo_client_auth().
+unsupported_sign_algo_client_auth(Config) ->
+ ssl_cert_tests:unsupported_sign_algo_client_auth(Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth() ->
+ ssl_cert_tests:hello_retry_client_auth().
+hello_retry_client_auth(Config) ->
+ ssl_cert_tests:hello_retry_client_auth(Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_accepted() ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_accepted().
+hello_retry_client_auth_empty_cert_accepted(Config) ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_accepted(Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_rejected() ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_rejected().
+hello_retry_client_auth_empty_cert_rejected(Config) ->
+ ssl_cert_tests:hello_retry_client_auth_empty_cert_rejected(Config).
diff --git a/lib/ssl/test/openssl_session_SUITE.erl b/lib/ssl/test/openssl_session_SUITE.erl
new file mode 100644
index 0000000000..24dcaa7817
--- /dev/null
+++ b/lib/ssl/test/openssl_session_SUITE.erl
@@ -0,0 +1,262 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(openssl_session_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(SLEEP, 1000).
+-define(EXPIRE, 10).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ case ssl_test_lib:openssl_sane_dtls() of
+ true ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}];
+ false ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'}]
+ end.
+
+groups() ->
+ case ssl_test_lib:openssl_sane_dtls() of
+ true ->
+ [{'tlsv1.2', [], tests()},
+ {'tlsv1.1', [], tests()},
+ {'tlsv1', [], tests()},
+ {'sslv3', [], tests()},
+ {'dtlsv1.2', [], dtls_tests()},
+ {'dtlsv1', [], dtls_tests()}
+ ];
+ false ->
+ [{'tlsv1.2', [], tests()},
+ {'tlsv1.1', [], tests()},
+ {'tlsv1', [], tests()},
+ {'sslv3', [], tests()}
+ ]
+ end.
+
+tests() ->
+ [
+ reuse_session_erlang_server,
+ reuse_session_erlang_client
+ ].
+
+dtls_tests() ->
+ [
+ reuse_session_erlang_server
+ ].
+
+
+init_per_suite(Config0) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(reuse_session_erlang_client, Config) ->
+ ct:timetrap(?EXPIRE * 1000 * 5),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_lifetime, ?EXPIRE),
+ ssl:start(),
+ Config;
+
+init_per_testcase(TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(reuse_session_erlang_client, Config) ->
+ application:unset_env(ssl, session_lifetime),
+ Config;
+end_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+reuse_session_erlang_server() ->
+ [{doc, "Test erlang server with openssl client that reconnects with the"
+ "same session id, to test reusing of sessions."}].
+reuse_session_erlang_server(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, active_recv, [length(Data)]}},
+ {reconnect_times, 5},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
+ ++ ":" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version),
+ "-reconnect"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ true = port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, Data),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(OpenSslPort).
+
+%%--------------------------------------------------------------------
+
+reuse_session_erlang_client() ->
+ [{doc, "Test erlang ssl client that wants to reuse sessions"}].
+reuse_session_erlang_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ CACertFile = proplists:get_value(cacertfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port),
+ "-cert", CertFile,"-key", KeyFile, "-CAfile", CACertFile],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, tls),
+
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_id, []}},
+ {from, self()}, {options, [{reuse_sessions, save}, {verify, verify_peer}| ClientOpts]}]),
+
+ SID = receive
+ {Client0, Id0} ->
+ Id0
+ end,
+
+ ssl_test_lib:close(Client0),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_id, []}},
+ {from, self()}, {options, [{reuse_session, SID} | ClientOpts]}]),
+ receive
+ {Client1, SID} ->
+ ok
+ after ?SLEEP ->
+ ct:fail(session_not_reused)
+ end,
+
+
+ ssl_test_lib:close(Client1),
+ %% Make sure session is unregistered due to expiration
+ ct:sleep(20000),
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_id, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client2, ID} ->
+ case ID of
+ SID ->
+ ct:fail(expired_session_reused);
+ _ ->
+ ok
+ end
+ end,
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client2).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/openssl_sni_SUITE.erl b/lib/ssl/test/openssl_sni_SUITE.erl
new file mode 100644
index 0000000000..26f08e36c0
--- /dev/null
+++ b/lib/ssl/test/openssl_sni_SUITE.erl
@@ -0,0 +1,251 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(openssl_sni_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(OPENSSL_QUIT, "Q\n").
+-define(OPENSSL_RENEGOTIATE, "R\n").
+-define(SLEEP, 1000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ %% Note: SNI not supported in sslv3
+ case ssl_test_lib:openssl_sane_dtls() of
+ true ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'}
+ %% Seems broken in openssl
+ %%{group, 'dtlsv1.2'},
+ %%{group, 'dtlsv1'}
+ ];
+ false ->
+ [{group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'}]
+ end.
+
+groups() ->
+ case ssl_test_lib:openssl_sane_dtls() of
+ true ->
+ [{'tlsv1.2', [], sni_tests()},
+ {'tlsv1.1', [], sni_tests()},
+ {'tlsv1', [], sni_tests()}
+ %% Seems broken in openssl
+ %%{'dtlsv1.2', [], sni_tests()},
+ %%{'dtlsv1', [], sni_tests()}
+ ];
+ false ->
+ [{'tlsv1.2', [], sni_tests()},
+ {'tlsv1.1', [], sni_tests()},
+ {'tlsv1', [], sni_tests()}
+ ]
+ end.
+
+sni_tests() ->
+ [erlang_server_openssl_client_sni_match,
+ erlang_server_openssl_client_sni_match_fun,
+ erlang_server_openssl_client_sni_no_match,
+ erlang_server_openssl_client_sni_no_match_fun,
+ erlang_server_openssl_client_sni_no_header,
+ erlang_server_openssl_client_sni_no_header_fun].
+
+init_per_suite(Config0) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ case check_openssl_sni_support(Config0) of
+ {skip, _} = Skip ->
+ Skip;
+ _ ->
+ ct:pal("Version: ~p", [os:cmd("openssl version")]),
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ RsaOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ [{sni_server_opts, [{sni_hosts,
+ [{"a.server", [
+ {certfile, proplists:get_value(certfile, RsaOpts)},
+ {keyfile, proplists:get_value(keyfile, RsaOpts)}
+ ]},
+ {"b.server", [
+ {certfile, proplists:get_value(certfile, RsaOpts)},
+ {keyfile, proplists:get_value(keyfile, RsaOpts)}
+ ]}
+ ]}]} | Config]
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end
+ end
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 10}),
+ Config.
+
+
+end_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+erlang_server_openssl_client_sni_no_header(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test(Config, undefined, undefined, "server Peer cert").
+
+erlang_server_openssl_client_sni_no_header_fun(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test_sni_fun(Config, undefined, undefined, "server Peer cert").
+
+erlang_server_openssl_client_sni_match(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test(Config, "a.server", "a.server", "server Peer cert").
+
+erlang_server_openssl_client_sni_match_fun(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test_sni_fun(Config, "a.server", "a.server", "server Peer cert").
+
+erlang_server_openssl_client_sni_no_match(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test(Config, "c.server", undefined, "server Peer cert").
+
+erlang_server_openssl_client_sni_no_match_fun(Config) when is_list(Config) ->
+ erlang_server_openssl_client_sni_test_sni_fun(Config, "c.server", undefined, "server Peer cert").
+
+
+erlang_server_openssl_client_sni_test(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ ct:log("Start running handshake, Config: ~p, SNIHostname: ~p, ExpectedSNIHostname: ~p, ExpectedCN: ~p",
+ [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
+ ServerOptions = proplists:get_value(sni_server_opts, Config) ++ proplists:get_value(server_rsa_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
+ {options, ServerOptions}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Exe = "openssl",
+ ClientArgs = case SNIHostname of
+ undefined ->
+ openssl_client_args(Version, Hostname,Port);
+ _ ->
+ openssl_client_args(Version, Hostname, Port, SNIHostname)
+ end,
+ ClientPort = ssl_test_lib:portable_open_port(Exe, ClientArgs),
+
+ ssl_test_lib:check_result(Server, ExpectedSNIHostname),
+ ssl_test_lib:close_port(ClientPort),
+ ssl_test_lib:close(Server),
+ ok.
+
+
+erlang_server_openssl_client_sni_test_sni_fun(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ ct:log("Start running handshake for sni_fun, Config: ~p, SNIHostname: ~p, ExpectedSNIHostname: ~p, ExpectedCN: ~p",
+ [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
+ [{sni_hosts, ServerSNIConf}] = proplists:get_value(sni_server_opts, Config),
+ SNIFun = fun(Domain) -> proplists:get_value(Domain, ServerSNIConf, undefined) end,
+ ServerOptions = proplists:get_value(server_rsa_opts, Config) ++ [{sni_fun, SNIFun}],
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
+ {options, ServerOptions}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Exe = "openssl",
+ ClientArgs = case SNIHostname of
+ undefined ->
+ openssl_client_args(Version, Hostname,Port);
+ _ ->
+ openssl_client_args(Version, Hostname, Port, SNIHostname)
+ end,
+
+ ClientPort = ssl_test_lib:portable_open_port(Exe, ClientArgs),
+
+ ssl_test_lib:check_result(Server, ExpectedSNIHostname),
+ ssl_test_lib:close_port(ClientPort),
+ ssl_test_lib:close(Server).
+
+send_and_hostname(SSLSocket) ->
+ ssl:send(SSLSocket, "OK"),
+ case ssl:connection_information(SSLSocket, [sni_hostname]) of
+ {ok, []} ->
+ undefined;
+ {ok, [{sni_hostname, Hostname}]} ->
+ Hostname
+ end.
+
+openssl_client_args(Version, Hostname, Port) ->
+ ["s_client", "-connect", Hostname ++ ":" ++ integer_to_list(Port), ssl_test_lib:version_flag(Version)].
+
+openssl_client_args(Version, Hostname, Port, ServerName) ->
+ ["s_client", "-connect", Hostname ++ ":" ++
+ integer_to_list(Port), ssl_test_lib:version_flag(Version), "-servername", ServerName].
+
+check_openssl_sni_support(Config) ->
+ HelpText = os:cmd("openssl s_client --help"),
+ case ssl_test_lib:is_sane_oppenssl_client() of
+ true ->
+ case string:str(HelpText, "-servername") of
+ 0 ->
+ {skip, "Current openssl doesn't support SNI"};
+ _ ->
+ Config
+ end;
+ false ->
+ {skip, "Current openssl doesn't support SNI or extension handling is flawed"}
+ end.
diff --git a/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl b/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl
new file mode 100644
index 0000000000..8a2692ec1d
--- /dev/null
+++ b/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl
@@ -0,0 +1,172 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(openssl_tls_1_3_version_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ %%{group, openssl_server},
+ {group, openssl_client}
+ ].
+
+groups() ->
+ [
+ %%{openssl_server, [{group, 'tlsv1.3'}]},
+ {openssl_client, [{group, 'tlsv1.3'}]},
+ {'tlsv1.3', [], cert_groups()},
+ {rsa, [], tests()},
+ {ecdsa, [], tests()}
+ ].
+
+cert_groups() ->
+ [{group, rsa},
+ {group, ecdsa}].
+
+tests() ->
+ [tls13_client_tls12_server,
+ %%tls13_client_with_ext_tls12_server,
+ tls12_client_tls13_server].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ case ssl_test_lib:check_sane_openssl_version('tlsv1.3') of
+ true ->
+ ssl_test_lib:clean_start(),
+ Config;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+init_per_group(openssl_client, Config0) ->
+ Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
+ [{client_type, openssl}, {server_type, erlang} | Config];
+init_per_group(openssl_server, Config0) ->
+ Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
+ [{client_type, erlang}, {server_type, openssl} | Config];
+init_per_group(rsa, Config0) ->
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ COpts = proplists:get_value(client_rsa_opts, Config),
+ SOpts = proplists:get_value(server_rsa_opts, Config),
+ [{client_cert_opts, COpts}, {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts, lists:delete(client_cert_opts, Config))];
+init_per_group(ecdsa, Config0) ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(ecdsa, PKAlg) andalso
+ (lists:member(ecdh, PKAlg) orelse lists:member(dh, PKAlg)) of
+ true ->
+ Config = ssl_test_lib:make_ecdsa_cert(Config0),
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ [{client_cert_opts, COpts}, {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts, lists:delete(client_cert_opts, Config))];
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
+init_per_group(GroupName, Config) ->
+ ssl_test_lib:clean_tls_version(Config),
+ case ssl_test_lib:is_tls_version(GroupName) andalso
+ ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ _ ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl:start(),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+tls13_client_tls12_server() ->
+ [{doc,"Test that a TLS 1.3 client can connect to a TLS 1.2 server."}].
+
+tls13_client_tls12_server(Config) when is_list(Config) ->
+ ClientOpts = [{versions,
+ ['tlsv1.3', 'tlsv1.2']} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{versions,
+ ['tlsv1.1', 'tlsv1.2']} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%% tls13_client_with_ext_tls12_server() ->
+%% [{doc,"Test basic connection between TLS 1.2 server and TLS 1.3 client when "
+%% "client has TLS 1.3 specsific extensions"}].
+
+%% tls13_client_with_ext_tls12_server(Config) ->
+%% ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+%% ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+%% {ServerOpts, ClientOpts} =
+%% case proplists:get_value(client_type) of
+%% erlang ->
+%% {[{versions, ['tlsv1.2']}|ServerOpts0],
+%% [{versions, ['tlsv1.2','tlsv1.3']},
+%% {signature_algs_cert, [ecdsa_secp384r1_sha384,
+%% ecdsa_secp256r1_sha256,
+%% rsa_pss_rsae_sha256,
+%% rsa_pkcs1_sha256,
+%% {sha256,rsa},{sha256,dsa}]}|ClientOpts0]};
+%% openssl ->
+
+
+%% ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+tls12_client_tls13_server() ->
+ [{doc,"Test that a TLS 1.2 client can connect to a TLS 1.3 server."}].
+
+tls12_client_tls13_server(Config) when is_list(Config) ->
+ ClientOpts = [{versions,
+ ['tlsv1.1', 'tlsv1.2']} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{versions,
+ ['tlsv1.3', 'tlsv1.2']} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
diff --git a/lib/ssl/test/property_test/ssl_eqc_handshake.erl b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
index 38a4b7fb11..2ceb540e15 100644
--- a/lib/ssl/test/property_test/ssl_eqc_handshake.erl
+++ b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
@@ -119,19 +119,27 @@ tls_msg(Version) ->
%%
client_hello(?'TLS_v1.3' = Version) ->
#client_hello{session_id = session_id(),
- client_version = ?'TLS_v1.2',
- cipher_suites = cipher_suites(Version),
+ client_version = ?'TLS_v1.2',
+ cipher_suites = cipher_suites(Version),
+ compression_methods = compressions(Version),
+ random = client_random(Version),
+ extensions = client_hello_extensions(Version)
+ };
+client_hello(Version) ->
+ #client_hello{session_id = session_id(),
+ client_version = Version,
+ cipher_suites = cipher_suites(Version),
compression_methods = compressions(Version),
random = client_random(Version),
extensions = client_hello_extensions(Version)
};
-client_hello(Version) ->
+client_hello(?'SSL_v3' = Version) ->
#client_hello{session_id = session_id(),
client_version = Version,
cipher_suites = cipher_suites(Version),
compression_methods = compressions(Version),
random = client_random(Version),
- extensions = client_hello_extensions(Version)
+ extensions = ssl_handshake:empty_extensions(Version, client_hello)
}.
server_hello(?'TLS_v1.3' = Version) ->
@@ -142,6 +150,14 @@ server_hello(?'TLS_v1.3' = Version) ->
compression_method = compression(Version),
extensions = server_hello_extensions(Version)
};
+server_hello(?'SSL_v3' = Version) ->
+ #server_hello{server_version = Version,
+ session_id = session_id(),
+ random = server_random(Version),
+ cipher_suite = cipher_suite(Version),
+ compression_method = compression(Version),
+ extensions = ssl_handshake:empty_extensions(Version, server_hello)
+ };
server_hello(Version) ->
#server_hello{server_version = Version,
session_id = session_id(),
@@ -291,7 +307,7 @@ pre_shared_keyextension() ->
%% | | |
%% | signature_algorithms_cert (RFC 8446) | CH, CR |
%% +--------------------------------------------------+-------------+
-extensions(?'TLS_v1.3' = Version, client_hello) ->
+extensions(?'TLS_v1.3' = Version, MsgType = client_hello) ->
?LET({
ServerName,
%% MaxFragmentLength,
@@ -306,8 +322,8 @@ extensions(?'TLS_v1.3' = Version, client_hello) ->
%% ServerCertificateType,
%% Padding,
KeyShare,
- %% PreSharedKey,
- %% PSKKeyExchangeModes,
+ PreSharedKey,
+ PSKKeyExchangeModes,
%% EarlyData,
%% Cookie,
SupportedVersions,
@@ -328,9 +344,9 @@ extensions(?'TLS_v1.3' = Version, client_hello) ->
%% oneof([client_cert_type(), undefined]),
%% oneof([server_cert_type(), undefined]),
%% oneof([padding(), undefined]),
- oneof([key_share(client_hello), undefined]),
- %% oneof([pre_shared_key(), undefined]),
- %% oneof([psk_key_exchange_modes(), undefined]),
+ oneof([key_share(MsgType), undefined]),
+ oneof([pre_shared_key(MsgType), undefined]),
+ oneof([psk_key_exchange_modes(), undefined]),
%% oneof([early_data(), undefined]),
%% oneof([cookie(), undefined]),
oneof([client_hello_versions(Version)]),
@@ -357,8 +373,8 @@ extensions(?'TLS_v1.3' = Version, client_hello) ->
%% server_cert_type => ServerCertificateType,
%% padding => Padding,
key_share => KeyShare,
- %% pre_shared_key => PreSharedKey,
- %% psk_key_exhange_modes => PSKKeyExchangeModes,
+ pre_shared_key => PreSharedKey,
+ psk_key_exchange_modes => PSKKeyExchangeModes,
%% early_data => EarlyData,
%% cookie => Cookie,
client_hello_versions => SupportedVersions,
@@ -401,15 +417,15 @@ extensions(Version, client_hello) ->
srp => SRP
%% renegotiation_info => RenegotiationInfo
}));
-extensions(?'TLS_v1.3' = Version, server_hello) ->
+extensions(?'TLS_v1.3' = Version, MsgType = server_hello) ->
?LET({
KeyShare,
- %% PreSharedKeys,
+ PreSharedKey,
SupportedVersions
},
{
- oneof([key_share(server_hello), undefined]),
- %% oneof([pre_shared_keys(), undefined]),
+ oneof([key_share(MsgType), undefined]),
+ oneof([pre_shared_key(MsgType), undefined]),
oneof([server_hello_selected_version()])
},
maps:filter(fun(_, undefined) ->
@@ -419,7 +435,7 @@ extensions(?'TLS_v1.3' = Version, server_hello) ->
end,
#{
key_share => KeyShare,
- %% pre_shared_keys => PreSharedKeys,
+ pre_shared_key => PreSharedKey,
server_hello_selected_version => SupportedVersions
}));
extensions(Version, server_hello) ->
@@ -810,3 +826,58 @@ group_list(N, Pool, Acc) ->
R = rand:uniform(length(Pool)),
G = lists:nth(R, Pool),
group_list(N - 1, Pool -- [G], [G|Acc]).
+
+
+ke_modes() ->
+ oneof([[psk_ke],[psk_dhe_ke],[psk_ke,psk_dhe_ke]]).
+
+psk_key_exchange_modes() ->
+ ?LET(KEModes, ke_modes(),
+ #psk_key_exchange_modes{
+ ke_modes = KEModes}).
+
+pre_shared_key(client_hello) ->
+ ?LET(OfferedPsks, offered_psks(),
+ #pre_shared_key_client_hello{
+ offered_psks = OfferedPsks});
+pre_shared_key(server_hello) ->
+ ?LET(SelectedIdentity, selected_identity(),
+ #pre_shared_key_server_hello{
+ selected_identity = SelectedIdentity}).
+
+selected_identity() ->
+ rand:uniform(32).
+
+offered_psks() ->
+ ?LET(Size, choose(1,5),
+ #offered_psks{
+ identities = psk_identities(Size),
+ binders = psk_binders(Size)}).
+
+psk_identities(Size) ->
+ psk_identities(Size, []).
+%%
+psk_identities(0, Acc) ->
+ Acc;
+psk_identities(N, Acc) ->
+ psk_identities(N - 1, [psk_identity()|Acc]).
+
+psk_identity() ->
+ Len = rand:uniform(32),
+ Identity = crypto:strong_rand_bytes(Len),
+ Age = crypto:strong_rand_bytes(4),
+ #psk_identity{
+ identity = Identity,
+ obfuscated_ticket_age = Age}.
+
+psk_binders(Size) ->
+ psk_binders(Size, []).
+%%
+psk_binders(0, Acc) ->
+ Acc;
+psk_binders(N, Acc) ->
+ psk_binders(N - 1, [psk_binder()|Acc]).
+
+psk_binder() ->
+ Len = rand:uniform(224) + 31,
+ crypto:strong_rand_bytes(Len).
diff --git a/lib/ssl/test/ssl_ECC_openssl_SUITE.erl b/lib/ssl/test/ssl_ECC_openssl_SUITE.erl
index 68d4e910fd..787c08a517 100644
--- a/lib/ssl/test/ssl_ECC_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_ECC_openssl_SUITE.erl
@@ -67,7 +67,8 @@ init_per_suite(Config0) ->
end_per_suite(_Config) ->
application:stop(ssl),
- application:stop(crypto).
+ application:stop(crypto),
+ ssl_test_lib:kill_openssl().
%%--------------------------------------------------------------------
init_per_group(GroupName, Config) ->
diff --git a/lib/ssl/test/ssl_alert_SUITE.erl b/lib/ssl/test/ssl_alert_SUITE.erl
new file mode 100644
index 0000000000..cc0b636580
--- /dev/null
+++ b/lib/ssl/test/ssl_alert_SUITE.erl
@@ -0,0 +1,100 @@
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_alert_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-include_lib("ssl/src/ssl_alert.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ alerts,
+ alert_details,
+ alert_details_not_too_big
+ ].
+
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+alerts() ->
+ [{doc, "Test ssl_alert:alert_txt/1"}].
+alerts(Config) when is_list(Config) ->
+ Descriptions = [?CLOSE_NOTIFY, ?UNEXPECTED_MESSAGE, ?BAD_RECORD_MAC,
+ ?DECRYPTION_FAILED_RESERVED, ?RECORD_OVERFLOW, ?DECOMPRESSION_FAILURE,
+ ?HANDSHAKE_FAILURE, ?BAD_CERTIFICATE, ?UNSUPPORTED_CERTIFICATE,
+ ?CERTIFICATE_REVOKED,?CERTIFICATE_EXPIRED, ?CERTIFICATE_UNKNOWN,
+ ?ILLEGAL_PARAMETER, ?UNKNOWN_CA, ?ACCESS_DENIED, ?DECODE_ERROR,
+ ?DECRYPT_ERROR, ?EXPORT_RESTRICTION, ?PROTOCOL_VERSION,
+ ?INSUFFICIENT_SECURITY, ?INTERNAL_ERROR, ?USER_CANCELED,
+ ?NO_RENEGOTIATION, ?UNSUPPORTED_EXTENSION, ?CERTIFICATE_UNOBTAINABLE,
+ ?UNRECOGNISED_NAME, ?BAD_CERTIFICATE_STATUS_RESPONSE,
+ ?BAD_CERTIFICATE_HASH_VALUE, ?UNKNOWN_PSK_IDENTITY,
+ 255 %% Unsupported/unknow alert will result in a description too
+ ],
+ Alerts = [?ALERT_REC(?WARNING, ?CLOSE_NOTIFY) |
+ [?ALERT_REC(?FATAL, Desc) || Desc <- Descriptions]],
+ lists:foreach(fun(Alert) ->
+ try ssl_alert:alert_txt(Alert)
+ catch
+ C:E:T ->
+ ct:fail({unexpected, {C, E, T}})
+ end
+ end, Alerts).
+%%--------------------------------------------------------------------
+alert_details() ->
+ [{doc, "Test that ssl_alert:alert_txt/1 result contains extendend error description"}].
+alert_details(Config) when is_list(Config) ->
+ Unique = make_ref(),
+ UniqueStr = lists:flatten(io_lib:format("~w", [Unique])),
+ Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY, Unique),
+ case string:str(ssl_alert:alert_txt(Alert), UniqueStr) of
+ 0 ->
+ ct:fail(error_details_missing);
+ _ ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+alert_details_not_too_big() ->
+ [{doc, "Test that ssl_alert:alert_txt/1 limits printed depth of extended error description"}].
+alert_details_not_too_big(Config) when is_list(Config) ->
+ Reason = lists:duplicate(10, lists:duplicate(10, lists:duplicate(10, {some, data}))),
+ Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY, Reason),
+ case length(ssl_alert:alert_txt(Alert)) < 1000 of
+ true ->
+ ok;
+ false ->
+ ct:fail(ssl_alert_text_too_big)
+ end.
diff --git a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl b/lib/ssl/test/ssl_alpn_SUITE.erl
index dfc780479e..82a49e1469 100644
--- a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_alpn_SUITE.erl
@@ -19,7 +19,7 @@
%%
%%
--module(ssl_alpn_handshake_SUITE).
+-module(ssl_alpn_SUITE).
%% Note: This directive should only be used in test suites.
-compile(export_all).
@@ -32,7 +32,9 @@
%%--------------------------------------------------------------------
all() ->
- [{group, 'tlsv1.2'},
+ [
+ {group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
{group, 'sslv3'},
@@ -42,12 +44,13 @@ all() ->
groups() ->
[
- {'tlsv1.2', [], alpn_tests()},
- {'tlsv1.1', [], alpn_tests()},
- {'tlsv1', [], alpn_tests()},
+ {'tlsv1.3', [], alpn_tests() -- [client_renegotiate, session_reused]},
+ {'tlsv1.2', [], alpn_tests() ++ alpn_npn_coexist()},
+ {'tlsv1.1', [], alpn_tests() ++ alpn_npn_coexist()},
+ {'tlsv1', [], alpn_tests() ++ alpn_npn_coexist()},
{'sslv3', [], alpn_not_supported()},
- {'dtlsv1.2', [], alpn_tests() -- [client_renegotiate]},
- {'dtlsv1', [], alpn_tests() -- [client_renegotiate]}
+ {'dtlsv1.2', [], alpn_tests() ++ alpn_npn_coexist()},
+ {'dtlsv1', [], alpn_tests() ++ alpn_npn_coexist()}
].
alpn_tests() ->
@@ -61,12 +64,16 @@ alpn_tests() ->
client_alpn_and_server_no_support,
client_no_support_and_server_alpn,
client_alpn_npn_and_server_alpn,
- client_alpn_npn_and_server_alpn_npn,
- client_alpn_and_server_alpn_npn,
client_renegotiate,
session_reused
].
+alpn_npn_coexist() ->
+ [
+ client_alpn_npn_and_server_alpn_npn,
+ client_alpn_and_server_alpn_npn
+ ].
+
alpn_not_supported() ->
[alpn_not_supported_client,
alpn_not_supported_server
@@ -77,8 +84,7 @@ init_per_suite(Config0) ->
try crypto:start() of
ok ->
ssl_test_lib:clean_start(),
- Config = ssl_test_lib:make_rsa_cert(Config0),
- ssl_test_lib:cert_options(Config)
+ ssl_test_lib:make_rsa_cert(Config0)
catch _:_ ->
{skip, "Crypto did not start"}
end.
diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl
new file mode 100644
index 0000000000..fefecc0b65
--- /dev/null
+++ b/lib/ssl/test/ssl_api_SUITE.erl
@@ -0,0 +1,1976 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_api_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssl/src/ssl_api.hrl").
+
+-define(SLEEP, 500).
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [
+ {group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+groups() ->
+ [
+ {'tlsv1.3', [], ((gen_api_tests() ++ tls13_group() ++ handshake_paus_tests()) -- [dh_params, honor_server_cipher_order, honor_client_cipher_order,
+ new_options_in_handshake])
+ ++ (since_1_2() -- [conf_signature_algs])},
+ {'tlsv1.2', [], gen_api_tests() ++ since_1_2() ++ handshake_paus_tests() ++ pre_1_3()},
+ {'tlsv1.1', [], gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3()},
+ {'tlsv1', [], gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3() ++ beast_mitigation_test()},
+ {'sslv3', [], (gen_api_tests() -- [new_options_in_handshake]) ++ beast_mitigation_test() ++ pre_1_3()},
+ {'dtlsv1.2', [], (gen_api_tests() -- [invalid_keyfile, invalid_certfile, invalid_cacertfile,
+ invalid_options, new_options_in_handshake]) ++ handshake_paus_tests() ++ pre_1_3()},
+ {'dtlsv1', [], (gen_api_tests() -- [invalid_keyfile, invalid_certfile, invalid_cacertfile,
+ invalid_options, new_options_in_handshake]) ++ handshake_paus_tests() ++ pre_1_3()}
+ ].
+
+since_1_2() ->
+ [
+ conf_signature_algs,
+ no_common_signature_algs
+ ].
+
+pre_1_3() ->
+ [
+ default_reject_anonymous
+ ].
+gen_api_tests() ->
+ [
+ peercert,
+ peercert_with_client_cert,
+ connection_information,
+ secret_connection_info,
+ versions,
+ active_n,
+ dh_params,
+ hibernate,
+ hibernate_right_away,
+ listen_socket,
+ recv_active,
+ recv_active_once,
+ recv_active_n,
+ recv_timeout,
+ recv_close,
+ controlling_process,
+ controller_dies,
+ controlling_process_transport_accept_socket,
+ close_with_timeout,
+ close_in_error_state,
+ call_in_error_state,
+ close_transport_accept,
+ abuse_transport_accept_socket,
+ honor_server_cipher_order,
+ honor_client_cipher_order,
+ ipv6,
+ der_input,
+ new_options_in_handshake,
+ max_handshake_size,
+ invalid_certfile,
+ invalid_cacertfile,
+ invalid_keyfile,
+ options_not_proplist,
+ invalid_options
+ ].
+
+handshake_paus_tests() ->
+ [
+ handshake_continue,
+ handshake_continue_timeout,
+ hello_client_cancel,
+ hello_server_cancel
+ ].
+
+%% Only relevant for SSL 3.0 and TLS 1.1
+beast_mitigation_test() ->
+ [%% Original option
+ rizzo_disabled,
+ %% Same effect as disable
+ rizzo_zero_n,
+ %% Same as default
+ rizzo_one_n_minus_one
+ ].
+
+tls13_group() ->
+ [
+ supported_groups,
+ honor_server_cipher_order_tls13,
+ honor_client_cipher_order_tls13
+ ].
+
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ [{client_type, erlang},
+ {server_type, erlang} | ssl_test_lib:init_tls_version(GroupName, Config)];
+ false ->
+ {skip, "Missing crypto support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(prf, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Version = ssl_test_lib:protocol_version(Config),
+ PRFS = [md5, sha, sha256, sha384, sha512],
+ %% All are the result of running tls_v1:prf(PrfAlgo, <<>>, <<>>, <<>>, 16)
+ %% with the specified PRF algorithm
+ ExpectedPrfResults =
+ [{md5, <<96,139,180,171,236,210,13,10,28,32,2,23,88,224,235,199>>},
+ {sha, <<95,3,183,114,33,169,197,187,231,243,19,242,220,228,70,151>>},
+ {sha256, <<166,249,145,171,43,95,158,232,6,60,17,90,183,180,0,155>>},
+ {sha384, <<153,182,217,96,186,130,105,85,65,103,123,247,146,91,47,106>>},
+ {sha512, <<145,8,98,38,243,96,42,94,163,33,53,49,241,4,127,28>>},
+ %% TLS 1.0 and 1.1 PRF:
+ {md5sha, <<63,136,3,217,205,123,200,177,251,211,17,229,132,4,173,80>>}],
+ TestPlan = prf_create_plan([Version], PRFS, ExpectedPrfResults),
+ [{prf_test_plan, TestPlan} | Config];
+init_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(internal_active_n, _Config) ->
+ application:unset_env(ssl, internal_active_n);
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+peercert() ->
+ [{doc,"Test API function peercert/1"}].
+peercert(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ClientOpts}]),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ [{'Certificate', BinCert, _}]= ssl_test_lib:pem_to_der(CertFile),
+
+ ServerMsg = {error, no_peercert},
+ ClientMsg = {ok, BinCert},
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+peercert_with_client_cert() ->
+ [{doc,"Test API function peercert/1"}].
+peercert_with_client_cert(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, [{verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ClientOpts}]),
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ [{'Certificate', ServerBinCert, _}]= ssl_test_lib:pem_to_der(ServerCertFile),
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ [{'Certificate', ClientBinCert, _}]= ssl_test_lib:pem_to_der(ClientCertFile),
+
+ ServerMsg = {ok, ClientBinCert},
+ ClientMsg = {ok, ServerBinCert},
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+connection_information() ->
+ [{doc,"Test the API function ssl:connection_information/1"}].
+connection_information(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_information_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_information_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+
+secret_connection_info() ->
+ [{doc,"Test the API function ssl:connection_information/2"}].
+secret_connection_info(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, secret_connection_info_result, []}},
+ {options, [{verify, verify_peer} | ServerOpts]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, secret_connection_info_result, []}},
+ {options, [{verify, verify_peer} |ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, true, Client, true),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+prf() ->
+ [{doc,"Test that ssl:prf/5 uses the negotiated PRF."}].
+prf(Config) when is_list(Config) ->
+ TestPlan = proplists:get_value(prf_test_plan, Config),
+ case TestPlan of
+ [] -> ct:fail({error, empty_prf_test_plan});
+ _ -> lists:foreach(fun(Suite) ->
+ lists:foreach(
+ fun(Test) ->
+ V = proplists:get_value(tls_ver, Test),
+ C = proplists:get_value(ciphers, Test),
+ E = proplists:get_value(expected, Test),
+ P = proplists:get_value(prf, Test),
+ prf_run_test(Config, V, C, E, P)
+ end, Suite)
+ end, TestPlan)
+ end.
+
+%%--------------------------------------------------------------------
+dh_params() ->
+ [{doc,"Test to specify DH-params file in server."}].
+
+dh_params(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ DataDir = proplists:get_value(data_dir, Config),
+ DHParamFile = filename:join(DataDir, "dHParam.pem"),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{dhfile, DHParamFile} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options,
+ [{ciphers,[{dhe_rsa,aes_256_cbc,sha}]} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+conf_signature_algs() ->
+ [{doc,"Test to set the signature_algs option on both client and server"}].
+conf_signature_algs(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false}, {signature_algs, [{sha256, rsa}]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false}, {signature_algs, [{sha256, rsa}]} | ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+no_common_signature_algs() ->
+ [{doc,"Set the signature_algs option so that there client and server does not share any hash sign algorithms"}].
+no_common_signature_algs(Config) when is_list(Config) ->
+
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{signature_algs, [{sha256, rsa}]}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{signature_algs, [{sha384, rsa}]}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_server_alert(Server, Client, insufficient_security).
+
+%%--------------------------------------------------------------------
+handshake_continue() ->
+ [{doc, "Test API function ssl:handshake_continue/3"}].
+handshake_continue(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ssl_test_lib:ssl_options([{reuseaddr, true},
+ {verify, verify_peer},
+ {handshake, hello} | ServerOpts
+ ],
+ Config)},
+ {continue_options, proplists:delete(reuseaddr, ServerOpts)}
+ ]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ssl_test_lib:ssl_options([{handshake, hello},
+ {verify, verify_peer} | ClientOpts
+ ],
+ Config)},
+ {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%------------------------------------------------------------------
+handshake_continue_timeout() ->
+ [{doc, "Test API function ssl:handshake_continue/3 with short timeout"}].
+handshake_continue_timeout(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 1},
+ {options, ssl_test_lib:ssl_options([{reuseaddr, true}, {handshake, hello},
+ {verify, verify_peer} | ServerOpts],
+ Config)},
+ {continue_options, proplists:delete(reuseaddr, ServerOpts)}
+ ]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error,timeout}),
+ ssl_test_lib:close(Server).
+
+
+%%--------------------------------------------------------------------
+hello_client_cancel() ->
+ [{doc, "Test API function ssl:handshake_cancel/1 on the client side"}].
+hello_client_cancel(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello},
+ {verify, verify_peer} | ServerOpts], Config)},
+ {continue_options, proplists:delete(reuseaddr, ServerOpts)}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ %% That is ssl:handshake_cancel returns ok
+ {connect_failed, ok} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello},
+ {verify, verify_peer} | ClientOpts], Config)},
+ {continue_options, cancel}]),
+ ssl_test_lib:check_server_alert(Server, user_canceled).
+%%--------------------------------------------------------------------
+hello_server_cancel() ->
+ [{doc, "Test API function ssl:handshake_cancel/1 on the server side"}].
+hello_server_cancel(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello},
+ {verify, verify_peer} | ServerOpts
+ ], Config)},
+ {continue_options, cancel}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, ssl_test_lib:ssl_options([{handshake, hello},
+ {verify, verify_peer} | ClientOpts
+ ], Config)},
+ {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
+
+ ssl_test_lib:check_result(Server, ok).
+
+%%--------------------------------------------------------------------
+versions() ->
+ [{doc,"Test API function versions/0"}].
+
+versions(Config) when is_list(Config) ->
+ [_|_] = Versions = ssl:versions(),
+ ct:log("~p~n", [Versions]).
+
+%%--------------------------------------------------------------------
+%% Test case adapted from gen_tcp_misc_SUITE.
+active_n() ->
+ [{doc,"Test {active,N} option"}].
+
+active_n(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ Port = ssl_test_lib:inet_port(node()),
+ N = 3,
+ LS = ok(ssl:listen(Port, [{active,N}|ServerOpts])),
+ [{active,N}] = ok(ssl:getopts(LS, [active])),
+ active_n_common(LS, N),
+ Self = self(),
+ spawn_link(fun() ->
+ S0 = ok(ssl:transport_accept(LS)),
+ {ok, S} = ssl:handshake(S0),
+ ok = ssl:setopts(S, [{active,N}]),
+ [{active,N}] = ok(ssl:getopts(S, [active])),
+ ssl:controlling_process(S, Self),
+ Self ! {server, S}
+ end),
+ C = ok(ssl:connect("localhost", Port, [{active,N}|ClientOpts])),
+ [{active,N}] = ok(ssl:getopts(C, [active])),
+ S = receive
+ {server, S0} -> S0
+ after
+ 1000 ->
+ exit({error, connect})
+ end,
+ active_n_common(C, N),
+ active_n_common(S, N),
+ ok = ssl:setopts(C, [{active,N}]),
+ ok = ssl:setopts(S, [{active,N}]),
+ ReceiveMsg = fun(Socket, Msg) ->
+ receive
+ {ssl,Socket,Msg} ->
+ ok;
+ {ssl,Socket,Begin} ->
+ receive
+ {ssl,Socket,End} ->
+ Msg = Begin ++ End,
+ ok
+ after 1000 ->
+ exit(timeout)
+ end
+ after 1000 ->
+ exit(timeout)
+ end
+ end,
+ repeat(3, fun(I) ->
+ Msg = "message "++integer_to_list(I),
+ ok = ssl:send(C, Msg),
+ ReceiveMsg(S, Msg),
+ ok = ssl:send(S, Msg),
+ ReceiveMsg(C, Msg)
+ end),
+ receive
+ {ssl_passive,S} ->
+ [{active,false}] = ok(ssl:getopts(S, [active]))
+ after
+ 1000 ->
+ exit({error,ssl_passive})
+ end,
+ receive
+ {ssl_passive,C} ->
+ [{active,false}] = ok(ssl:getopts(C, [active]))
+ after
+ 1000 ->
+ exit({error,ssl_passive})
+ end,
+ LS2 = ok(ssl:listen(0, [{active,0}])),
+ receive
+ {ssl_passive,LS2} ->
+ [{active,false}] = ok(ssl:getopts(LS2, [active]))
+ after
+ 1000 ->
+ exit({error,ssl_passive})
+ end,
+ ok = ssl:close(LS2),
+ ok = ssl:close(C),
+ ok = ssl:close(S),
+ ok = ssl:close(LS),
+ ok.
+
+hibernate() ->
+ [{doc,"Check that an SSL connection that is started with option "
+ "{hibernate_after, 1000} indeed hibernates after 1000ms of "
+ "inactivity"}].
+
+hibernate(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {Client, #sslsocket{pid=[Pid|_]}} = ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{hibernate_after, 1000}|ClientOpts]}]),
+ {current_function, _} =
+ process_info(Pid, current_function),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ct:sleep(1500),
+ {current_function, {erlang, hibernate, 3}} =
+ process_info(Pid, current_function),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+hibernate_right_away() ->
+ [{doc,"Check that an SSL connection that is configured to hibernate "
+ "after 0 or 1 milliseconds hibernates as soon as possible and not "
+ "crashes"}].
+
+hibernate_right_away(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ StartServerOpts = [{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}],
+ StartClientOpts = [return_socket,
+ {node, ClientNode},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}}],
+
+ Server1 = ssl_test_lib:start_server(StartServerOpts),
+ Port1 = ssl_test_lib:inet_port(Server1),
+ {Client1, #sslsocket{pid = [Pid1|_]}} = ssl_test_lib:start_client(StartClientOpts ++
+ [{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server1, ok, Client1, ok),
+
+ ct:sleep(1000), %% Schedule out
+
+ {current_function, {erlang, hibernate, 3}} =
+ process_info(Pid1, current_function),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1),
+
+ Server2 = ssl_test_lib:start_server(StartServerOpts),
+ Port2 = ssl_test_lib:inet_port(Server2),
+ {Client2, #sslsocket{pid = [Pid2|_]}} = ssl_test_lib:start_client(StartClientOpts ++
+ [{port, Port2}, {options, [{hibernate_after, 1}|ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server2, ok, Client2, ok),
+
+ ct:sleep(1000), %% Schedule out
+
+ {current_function, {erlang, hibernate, 3}} =
+ process_info(Pid2, current_function),
+
+ ssl_test_lib:close(Server2),
+ ssl_test_lib:close(Client2).
+
+listen_socket() ->
+ [{doc,"Check error handling and inet compliance when calling API functions with listen sockets."}].
+
+listen_socket(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ok, ListenSocket} = ssl:listen(0, ServerOpts),
+
+ %% This can be a valid thing to do as
+ %% options are inherited by the accept socket
+ ok = ssl:controlling_process(ListenSocket, self()),
+
+ {ok, _} = ssl:sockname(ListenSocket),
+
+ {error, enotconn} = ssl:send(ListenSocket, <<"data">>),
+ {error, enotconn} = ssl:recv(ListenSocket, 0),
+ {error, enotconn} = ssl:connection_information(ListenSocket),
+ {error, enotconn} = ssl:peername(ListenSocket),
+ {error, enotconn} = ssl:peercert(ListenSocket),
+ {error, enotconn} = ssl:renegotiate(ListenSocket),
+ {error, enotconn} = ssl:prf(ListenSocket, 'master_secret', <<"Label">>, [client_random], 256),
+ {error, enotconn} = ssl:shutdown(ListenSocket, read_write),
+
+ ok = ssl:close(ListenSocket).
+
+%%--------------------------------------------------------------------
+recv_active() ->
+ [{doc,"Test recv on active socket"}].
+
+recv_active(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, try_recv_active, []}},
+ {options, [{active, true} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, try_recv_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+recv_active_once() ->
+ [{doc,"Test recv on active (once) socket"}].
+
+recv_active_once(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, try_recv_active_once, []}},
+ {options, [{active, once} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, try_recv_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+recv_active_n() ->
+ [{doc,"Test recv on active (n) socket"}].
+
+recv_active_n(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, try_recv_active_once, []}},
+ {options, [{active, 1} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, try_recv_active_once, []}},
+ {options, [{active, 1} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+recv_timeout() ->
+ [{doc,"Test ssl:ssl_accept timeout"}].
+
+recv_timeout(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_timeout_server, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_timeout_client, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+recv_close() ->
+ [{doc,"Special case of call error handling"}].
+recv_close(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, do_recv_close, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {_Client, #sslsocket{} = SslSocket} = ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+ ssl:close(SslSocket),
+ ssl_test_lib:check_result(Server, ok).
+
+
+
+%%--------------------------------------------------------------------
+controlling_process() ->
+ [{doc,"Test API function controlling_process/2"}].
+
+controlling_process(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Server hello",
+ ServerMsg = "Client hello",
+
+ Server = ssl_test_lib:start_server([
+ {node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {Client, CSocket} = ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ServerMsg = ssl_test_lib:active_recv(CSocket, length(ServerMsg)),
+ %% We do not have the TLS server socket but all messages form the client
+ %% socket are now read, so ramining are form the server socket
+ ClientMsg = ssl_active_recv(length(ClientMsg)),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+controller_dies() ->
+ [{doc,"Test that the socket is closed after controlling process dies"}].
+controller_dies(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n", [self(), Client, Server]),
+ ct:sleep(?SLEEP), %% so that they are connected
+
+ process_flag(trap_exit, true),
+
+ %% Test that clients die
+ exit(Client, killed),
+ get_close(Client, ?LINE),
+
+ %% Test that clients die when process disappear
+ Server ! listen,
+ Tester = self(),
+ Connect = fun(Pid) ->
+ {ok, Socket} = ssl:connect(Hostname, Port, ClientOpts),
+ %% Make sure server finishes and verification
+ %% and is in coonection state before
+ %% killing client
+ ct:sleep(?SLEEP),
+ Pid ! {self(), connected, Socket},
+ receive die_nice -> normal end
+ end,
+ Client2 = spawn_link(fun() -> Connect(Tester) end),
+ receive {Client2, connected, _Socket} -> Client2 ! die_nice end,
+
+ get_close(Client2, ?LINE),
+
+ %% Test that clients die when the controlling process have changed
+ Server ! listen,
+
+ Client3 = spawn_link(fun() -> Connect(Tester) end),
+ Controller = spawn_link(fun() -> receive die_nice -> normal end end),
+ receive
+ {Client3, connected, Socket} ->
+ ok = ssl:controlling_process(Socket, Controller),
+ Client3 ! die_nice
+ end,
+
+ ct:log("Wating on exit ~p~n",[Client3]),
+ receive {'EXIT', Client3, normal} -> ok end,
+
+ receive %% Client3 is dead but that doesn't matter, socket should not be closed.
+ Unexpected ->
+ ct:log("Unexpected ~p~n",[Unexpected]),
+ ct:fail({line, ?LINE-1})
+ after 1000 ->
+ ok
+ end,
+ Controller ! die_nice,
+ get_close(Controller, ?LINE),
+
+ %% Test that servers die
+ Server ! listen,
+ LastClient = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+ ct:sleep(?SLEEP), %% so that they are connected
+
+ exit(Server, killed),
+ get_close(Server, ?LINE),
+ process_flag(trap_exit, false),
+ ssl_test_lib:close(LastClient).
+%%--------------------------------------------------------------------
+controlling_process_transport_accept_socket() ->
+ [{doc,"Only ssl:handshake and ssl:controlling_process is allowed for transport_accept:sockets"}].
+controlling_process_transport_accept_socket(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_transport_control([{node, ServerNode},
+ {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ _Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server).
+
+%%--------------------------------------------------------------------
+close_with_timeout() ->
+ [{doc,"Test normal (not downgrade) ssl:close/2"}].
+close_with_timeout(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_close, []}},
+ {options,[{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_close, []}},
+ {options, [{active, false} |ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok).
+
+%%--------------------------------------------------------------------
+close_in_error_state() ->
+ [{doc,"Special case of closing socket in error state"}].
+close_in_error_state(Config) when is_list(Config) ->
+ ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+ ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ _ = spawn_link(?MODULE, run_error_server_close, [[self() | ServerOpts]]),
+ receive
+ {_Pid, Port} ->
+ spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
+ end,
+ receive
+ ok ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end.
+
+%%--------------------------------------------------------------------
+call_in_error_state() ->
+ [{doc,"Special case of call error handling"}].
+call_in_error_state(Config) when is_list(Config) ->
+ ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
+ Pid = spawn_link(?MODULE, run_error_server, [[self() | ServerOpts]]),
+ receive
+ {Pid, Port} ->
+ spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
+ end,
+ receive
+ {error, closed} ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end.
+%%--------------------------------------------------------------------
+close_transport_accept() ->
+ [{doc,"Tests closing ssl socket when waiting on ssl:transport_accept/1"}].
+
+close_transport_accept(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = 0,
+ Opts = [{active, false} | ServerOpts],
+ {ok, ListenSocket} = rpc:call(ServerNode, ssl, listen, [Port, Opts]),
+ spawn_link(fun() ->
+ ct:sleep(?SLEEP),
+ rpc:call(ServerNode, ssl, close, [ListenSocket])
+ end),
+ case rpc:call(ServerNode, ssl, transport_accept, [ListenSocket]) of
+ {error, closed} ->
+ ok;
+ Other ->
+ exit({?LINE, Other})
+ end.
+%%--------------------------------------------------------------------
+abuse_transport_accept_socket() ->
+ [{doc,"Only ssl:handshake and ssl:controlling_process is allowed for transport_accept:sockets"}].
+abuse_transport_accept_socket(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_transport_abuse_socket([{node, ServerNode},
+ {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+invalid_keyfile() ->
+ [{doc,"Test what happens with an invalid key file"}].
+invalid_keyfile(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ BadKeyFile = filename:join([proplists:get_value(priv_dir, Config),
+ "badkey.pem"]),
+ BadOpts = [{keyfile, BadKeyFile}| proplists:delete(keyfile, ServerOpts)],
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, BadOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()}, {options, ClientOpts}]),
+
+ File = proplists:get_value(keyfile,BadOpts),
+ ssl_test_lib:check_result(Server, {error,{options, {keyfile, File, {error,enoent}}}}, Client,
+ {error, closed}).
+
+%%--------------------------------------------------------------------
+honor_server_cipher_order() ->
+ [{doc,"Test API honor server cipher order."}].
+honor_server_cipher_order(Config) when is_list(Config) ->
+ ClientCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac => sha,
+ prf => default_prf}],
+ ServerCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac =>sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}],
+ honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac => sha,
+ prf => default_prf}).
+
+%%--------------------------------------------------------------------
+honor_client_cipher_order() ->
+ [{doc,"Test API honor server cipher order."}].
+honor_client_cipher_order(Config) when is_list(Config) ->
+ ClientCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac => sha,
+ prf => default_prf}],
+ ServerCiphers = [#{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
+ mac =>sha,
+ prf => default_prf},
+ #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}],
+ honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}).
+
+%%--------------------------------------------------------------------
+ipv6() ->
+ [{require, ipv6_hosts},
+ {doc,"Test ipv6."}].
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname0} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
+ true ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} =
+ ssl_test_lib:run_where(Config, ipv6),
+ Server = ssl_test_lib:start_server([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client);
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+%%--------------------------------------------------------------------
+der_input() ->
+ [{doc,"Test to input certs and key as der"}].
+
+der_input(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ DHParamFile = filename:join(DataDir, "dHParam.pem"),
+
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ [CADb | _] = element(6, State),
+
+ Size = ets:info(CADb, size),
+
+ SeverVerifyOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ServerCert, ServerKey, ServerCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
+ SeverVerifyOpts]),
+ ClientVerifyOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ {ClientCert, ClientKey, ClientCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
+ ClientVerifyOpts]),
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true},
+ {dh, DHParams},
+ {cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCaCerts}],
+ ClientOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true},
+ {dh, DHParams},
+ {cert, ClientCert}, {key, ClientKey}, {cacerts, ClientCaCerts}],
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ Size = ets:info(CADb, size).
+
+%%--------------------------------------------------------------------
+invalid_certfile() ->
+ [{doc,"Test what happens with an invalid cert file"}].
+
+invalid_certfile(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ BadCertFile = filename:join([proplists:get_value(priv_dir, Config),
+ "badcert.pem"]),
+ ServerBadOpts = [{certfile, BadCertFile}| proplists:delete(certfile, ServerOpts)],
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerBadOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+ File = proplists:get_value(certfile, ServerBadOpts),
+ ssl_test_lib:check_result(Server, {error,{options, {certfile, File, {error,enoent}}}},
+ Client, {error, closed}).
+
+
+%%--------------------------------------------------------------------
+invalid_cacertfile() ->
+ [{doc,"Test what happens with an invalid cacert file"}].
+
+invalid_cacertfile(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ BadCACertFile = filename:join([proplists:get_value(priv_dir, Config),
+ "badcacert.pem"]),
+ ServerBadOpts = [{cacertfile, BadCACertFile}| proplists:delete(cacertfile, ServerOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {options, ServerBadOpts}]),
+
+ Port0 = ssl_test_lib:inet_port(Server0),
+
+
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port0}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ File0 = proplists:get_value(cacertfile, ServerBadOpts),
+
+ ssl_test_lib:check_result(Server0, {error, {options, {cacertfile, File0,{error,enoent}}}},
+ Client0, {error, closed}),
+
+ File = File0 ++ "do_not_exit.pem",
+ ServerBadOpts1 = [{cacertfile, File}|proplists:delete(cacertfile, ServerBadOpts)],
+
+ Server1 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {options, ServerBadOpts1}]),
+
+ Port1 = ssl_test_lib:inet_port(Server1),
+
+ Client1 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+
+ ssl_test_lib:check_result(Server1, {error, {options, {cacertfile, File,{error,enoent}}}},
+ Client1, {error, closed}),
+ ok.
+
+%%--------------------------------------------------------------------
+new_options_in_handshake() ->
+ [{doc,"Test that you can set ssl options in handshake/3 and not only in tcp upgrade"}].
+new_options_in_handshake(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ Version = ssl_test_lib:protocol_version(Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ [_, Cipher | _] = ssl:filter_cipher_suites(ssl:cipher_suites(all, Version),
+ [{key_exchange,
+ fun(dhe_rsa) ->
+ true;
+ (ecdhe_rsa) ->
+ true;
+ (ecdh_rsa) ->
+ true;
+ (rsa) ->
+ true;
+ (_) ->
+ false
+ end
+ }]),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {ssl_extra_opts, [{versions, [Version]},
+ {ciphers,[Cipher]}]}, %% To be set in ssl_accept/3
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, [{ciphers, [Cipher]} | ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ServerMsg = ClientMsg = {ok, {Version, Cipher}},
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%-------------------------------------------------------------------
+max_handshake_size() ->
+ [{doc,"Test that we can set max_handshake_size to max value."}].
+
+max_handshake_size(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{max_handshake_size, 8388607} |ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{max_handshake_size, 8388607} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok).
+
+
+%%-------------------------------------------------------------------
+options_not_proplist() ->
+ [{doc,"Test what happens if an option is not a key value tuple"}].
+
+options_not_proplist(Config) when is_list(Config) ->
+ BadOption = {client_preferred_next_protocols,
+ client, [<<"spdy/3">>,<<"http/1.1">>], <<"http/1.1">>},
+ {option_not_a_key_value_tuple, BadOption} =
+ ssl:connect("twitter.com", 443, [binary, {active, false},
+ BadOption]).
+
+%%-------------------------------------------------------------------
+invalid_options() ->
+ [{doc,"Test what happens when we give invalid options"}].
+
+invalid_options(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Check = fun(Client, Server, {versions, [sslv2, sslv3]} = Option) ->
+ ssl_test_lib:check_result(Server,
+ {error, {options, {sslv2, Option}}},
+ Client,
+ {error, {options, {sslv2, Option}}});
+ (Client, Server, Option) ->
+ ssl_test_lib:check_result(Server,
+ {error, {options, Option}},
+ Client,
+ {error, {options, Option}})
+ end,
+
+ TestOpts =
+ [{versions, [sslv2, sslv3]},
+ {verify, 4},
+ {verify_fun, function},
+ {fail_if_no_peer_cert, 0},
+ {verify_client_once, 1},
+ {depth, four},
+ {certfile, 'cert.pem'},
+ {keyfile,'key.pem' },
+ {password, foo},
+ {cacertfile, ""},
+ {dhfile,'dh.pem' },
+ {ciphers, [{foo, bar, sha, ignore}]},
+ {reuse_session, foo},
+ {reuse_sessions, 0},
+ {renegotiate_at, "10"},
+ {mode, depech},
+ {packet, 8.0},
+ {packet_size, "2"},
+ {header, a},
+ {active, trice},
+ {key, 'key.pem' }],
+
+ [begin
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [TestOpt | ServerOpts]}]),
+ %% Will never reach a point where port is used.
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, 0},
+ {host, Hostname}, {from, self()},
+ {options, [TestOpt | ClientOpts]}]),
+ Check(Client, Server, TestOpt),
+ ok
+ end || TestOpt <- TestOpts],
+ ok.
+%%-------------------------------------------------------------------
+
+default_reject_anonymous()->
+ [{doc,"Test that by default anonymous cipher suites are rejected "}].
+default_reject_anonymous(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ Version = ssl_test_lib:protocol_version(Config),
+ TLSVersion = ssl_test_lib:tls_version(Version),
+
+ [CipherSuite | _] = ssl_test_lib:ecdh_dh_anonymous_suites(TLSVersion),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_server_alert(Server, Client, insufficient_security).
+
+%%-------------------------------------------------------------------
+%% Note that these test only test that the options are valid to set. As application data
+%% is a stream you can not test that the send acctually splits it up as when it arrives
+%% again at the user layer it may be concatenated. But COVER can show that the split up
+%% code has been run.
+
+rizzo_disabled() ->
+ [{doc, "Test original beast mitigation disable option for SSL 3.0 and TLS 1.0"}].
+
+rizzo_disabled(Config) ->
+ ClientOpts = [{beast_mitigation, disabled} | ssl_test_lib:ssl_options(client_rsa_opts, Config)],
+ ServerOpts = [{beast_mitigation, disabled} | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%-------------------------------------------------------------------
+rizzo_zero_n() ->
+ [{doc, "Test zero_n beast mitigation option (same affect as original disable option) for SSL 3.0 and TLS 1.0"}].
+
+rizzo_zero_n(Config) ->
+ ClientOpts = [{beast_mitigation, zero_n} | ssl_test_lib:ssl_options(client_rsa_opts, Config)],
+ ServerOpts = [{beast_mitigation, zero_n} | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%-------------------------------------------------------------------
+rizzo_one_n_minus_one () ->
+ [{doc, "Test beast_mitigation option one_n_minus_one (same affect as default) for SSL 3.0 and TLS 1.0"}].
+
+rizzo_one_n_minus_one (Config) ->
+ ClientOpts = [{beast_mitigation, one_n_minus_one } | ssl_test_lib:ssl_options(client_rsa_opts, Config)],
+ ServerOpts = [{beast_mitigation, one_n_minus_one} | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+supported_groups() ->
+ [{doc,"Test the supported_groups option in TLS 1.3."}].
+
+supported_groups(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{supported_groups, [x448, x25519]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{supported_groups,[x448]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+honor_client_cipher_order_tls13() ->
+ [{doc,"Test API honor server cipher order in TLS 1.3."}].
+honor_client_cipher_order_tls13(Config) when is_list(Config) ->
+ ClientCiphers = [#{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384},
+ #{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}],
+ ServerCiphers = [#{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256},
+ #{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384}],
+ honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384}).
+
+%%--------------------------------------------------------------------
+honor_server_cipher_order_tls13() ->
+ [{doc,"Test API honor server cipher order in TLS 1.3."}].
+honor_server_cipher_order_tls13(Config) when is_list(Config) ->
+ ClientCiphers = [#{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384},
+ #{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}],
+ ServerCiphers = [#{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256},
+ #{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384}],
+ honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+peercert_result(Socket) ->
+ ssl:peercert(Socket).
+
+connection_information_result(Socket) ->
+ {ok, Info = [_ | _]} = ssl:connection_information(Socket),
+ case length(Info) > 3 of
+ true ->
+ %% Atleast one ssl_option() is set
+ ct:log("Info ~p", [Info]),
+ ok;
+ false ->
+ ct:fail(no_ssl_options_returned)
+ end.
+secret_connection_info_result(Socket) ->
+ {ok, [{protocol, Protocol}]} = ssl:connection_information(Socket, [protocol]),
+ {ok, ConnInfo} = ssl:connection_information(Socket, [client_random, server_random, master_secret]),
+ check_connection_info(Protocol, ConnInfo).
+
+
+%% In TLS 1.3 the master_secret field is used to store multiple secrets from the key schedule and it is a tuple.
+%% client_random and server_random are not used in the TLS 1.3 key schedule.
+check_connection_info('tlsv1.3', [{client_random, ClientRand}, {master_secret, {master_secret, MasterSecret}}]) ->
+ is_binary(ClientRand) andalso is_binary(MasterSecret);
+check_connection_info('tlsv1.3', [{server_random, ServerRand}, {master_secret, {master_secret, MasterSecret}}]) ->
+ is_binary(ServerRand) andalso is_binary(MasterSecret);
+check_connection_info(_, [{client_random, ClientRand}, {server_random, ServerRand}, {master_secret, MasterSecret}]) ->
+ is_binary(ClientRand) andalso is_binary(ServerRand) andalso is_binary(MasterSecret);
+check_connection_info(_, _) ->
+ false.
+
+
+prf_create_plan(TlsVersions, PRFs, Results) ->
+ lists:foldl(fun(Ver, Acc) ->
+ A = prf_ciphers_and_expected(Ver, PRFs, Results),
+ [A|Acc]
+ end, [], TlsVersions).
+
+prf_ciphers_and_expected(TlsVer, PRFs, Results) ->
+ case TlsVer of
+ TlsVer when TlsVer == sslv3 orelse TlsVer == tlsv1
+ orelse TlsVer == 'tlsv1.1' orelse TlsVer == 'dtlsv1' ->
+ Ciphers = ssl:cipher_suites(),
+ {_, Expected} = lists:keyfind(md5sha, 1, Results),
+ [[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected}, {prf, md5sha}]];
+ TlsVer when TlsVer == 'tlsv1.2' orelse TlsVer == 'dtlsv1.2'->
+ lists:foldl(
+ fun(PRF, Acc) ->
+ Ciphers = prf_get_ciphers(TlsVer, PRF),
+ case Ciphers of
+ [] ->
+ ct:log("No ciphers for PRF algorithm ~p. Skipping.", [PRF]),
+ Acc;
+ Ciphers ->
+ {_, Expected} = lists:keyfind(PRF, 1, Results),
+ [[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected},
+ {prf, PRF}] | Acc]
+ end
+ end, [], PRFs)
+ end.
+
+prf_get_ciphers(_, PRF) ->
+ lists:filter(
+ fun(C) when tuple_size(C) == 4 andalso
+ element(4, C) == PRF ->
+ true;
+ (_) ->
+ false
+ end,
+ ssl:cipher_suites()).
+
+prf_run_test(_, TlsVer, [], _, Prf) ->
+ ct:fail({error, cipher_list_empty, TlsVer, Prf});
+prf_run_test(Config, TlsVer, Ciphers, Expected, Prf) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ BaseOpts = [{active, true}, {versions, [TlsVer]}, {ciphers, Ciphers}, {protocol, tls_or_dtls(TlsVer)}],
+ ServerOpts = BaseOpts ++ proplists:get_value(server_opts, Config),
+ ClientOpts = BaseOpts ++ proplists:get_value(client_opts, Config),
+ Server = ssl_test_lib:start_server(
+ [{node, ServerNode}, {port, 0}, {from, self()},
+ {mfa, {?MODULE, prf_verify_value, [TlsVer, Expected, Prf]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client(
+ [{node, ClientNode}, {port, Port},
+ {host, Hostname}, {from, self()},
+ {mfa, {?MODULE, prf_verify_value, [TlsVer, Expected, Prf]}},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+prf_verify_value(Socket, TlsVer, Expected, Algo) ->
+ Ret = ssl:prf(Socket, <<>>, <<>>, [<<>>], 16),
+ case TlsVer of
+ sslv3 ->
+ case Ret of
+ {error, undefined} -> ok;
+ _ ->
+ {error, {expected, {error, undefined},
+ got, Ret, tls_ver, TlsVer, prf_algorithm, Algo}}
+ end;
+ _ ->
+ case Ret of
+ {ok, Expected} -> ok;
+ {ok, Val} -> {error, {expected, Expected, got, Val, tls_ver, TlsVer,
+ prf_algorithm, Algo}}
+ end
+ end.
+
+tls_or_dtls('dtlsv1') ->
+ dtls;
+tls_or_dtls('dtlsv1.2') ->
+ dtls;
+tls_or_dtls(_) ->
+ tls.
+
+active_n_common(S, N) ->
+ ok = ssl:setopts(S, [{active,-N}]),
+ receive
+ {ssl_passive, S} -> ok
+ after
+ 1000 ->
+ error({error,ssl_passive_failure})
+ end,
+ [{active,false}] = ok(ssl:getopts(S, [active])),
+ ok = ssl:setopts(S, [{active,0}]),
+ receive
+ {ssl_passive, S} -> ok
+ after
+ 1000 ->
+ error({error,ssl_passive_failure})
+ end,
+ ok = ssl:setopts(S, [{active,32767}]),
+ {error,{options,_}} = ssl:setopts(S, [{active,1}]),
+ {error,{options,_}} = ssl:setopts(S, [{active,-32769}]),
+ ok = ssl:setopts(S, [{active,-32768}]),
+ receive
+ {ssl_passive, S} -> ok
+ after
+ 1000 ->
+ error({error,ssl_passive_failure})
+ end,
+ [{active,false}] = ok(ssl:getopts(S, [active])),
+ ok = ssl:setopts(S, [{active,N}]),
+ ok = ssl:setopts(S, [{active,true}]),
+ [{active,true}] = ok(ssl:getopts(S, [active])),
+ receive
+ _ -> error({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ ok = ssl:setopts(S, [{active,N}]),
+ ok = ssl:setopts(S, [{active,once}]),
+ [{active,once}] = ok(ssl:getopts(S, [active])),
+ receive
+ _ -> error({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ {error,{options,_}} = ssl:setopts(S, [{active,32768}]),
+ ok = ssl:setopts(S, [{active,false}]),
+ [{active,false}] = ok(ssl:getopts(S, [active])),
+ ok.
+
+ok({ok,V}) -> V.
+
+repeat(N, Fun) ->
+ repeat(N, N, Fun).
+
+repeat(N, T, Fun) when is_integer(N), N > 0 ->
+ Fun(T-N),
+ repeat(N-1, T, Fun);
+repeat(_, _, _) ->
+ ok.
+
+try_recv_active(Socket) ->
+ ssl:send(Socket, "Hello world"),
+ {error, einval} = ssl:recv(Socket, 11),
+ ok.
+try_recv_active_once(Socket) ->
+ {error, einval} = ssl:recv(Socket, 11),
+ ok.
+
+controlling_process_result(Socket, Pid, Msg) ->
+ ok = ssl:controlling_process(Socket, Pid),
+ %% Make sure other side has evaluated controlling_process
+ %% before message is sent
+ ct:sleep(?SLEEP),
+ ssl:send(Socket, Msg),
+ no_result_msg.
+
+controller_dies_result(_Socket, _Pid, _Msg) ->
+ receive Result -> Result end.
+get_close(Pid, Where) ->
+ receive
+ {'EXIT', Pid, _Reason} ->
+ receive
+ {_, {ssl_closed, Socket}} ->
+ ct:log("Socket closed ~p~n",[Socket]);
+ Unexpected ->
+ ct:log("Unexpected ~p~n",[Unexpected]),
+ ct:fail({line, ?LINE-1})
+ after 5000 ->
+ ct:fail({timeout, {line, ?LINE, Where}})
+ end;
+ Unexpected ->
+ ct:log("Unexpected ~p~n",[Unexpected]),
+ ct:fail({line, ?LINE-1})
+ after 5000 ->
+ ct:fail({timeout, {line, ?LINE, Where}})
+ end.
+
+ssl_active_recv(N) ->
+ ssl_active_recv(N, []).
+
+ssl_active_recv(0, Acc) ->
+ Acc;
+ssl_active_recv(N, Acc) ->
+ receive
+ {ssl, _, Bytes} ->
+ ssl_active_recv(N-length(Bytes), Acc ++ Bytes)
+ end.
+
+send_recv_result_timeout_client(Socket) ->
+ {error, timeout} = ssl:recv(Socket, 11, 500),
+ {error, timeout} = ssl:recv(Socket, 11, 0),
+ ssl:send(Socket, "Hello world"),
+ receive
+ Msg ->
+ io:format("Msg ~p~n",[Msg])
+ after 500 ->
+ ok
+ end,
+ {ok, "Hello world"} = ssl:recv(Socket, 11, 500),
+ ok.
+send_recv_result_timeout_server(Socket) ->
+ ssl:send(Socket, "Hello"),
+ {ok, "Hello world"} = ssl:recv(Socket, 11),
+ ssl:send(Socket, " world"),
+ ok.
+
+do_recv_close(Socket) ->
+ {error, closed} = ssl:recv(Socket, 11),
+ receive
+ {_,{error,closed}} ->
+ error_extra_close_sent_to_user_process
+ after 500 ->
+ ok
+ end.
+
+tls_close(Socket) ->
+ ok = ssl_test_lib:send_recv_result(Socket),
+ case ssl:close(Socket, 5000) of
+ ok ->
+ ok;
+ {error, closed} ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end.
+
+run_error_server_close([Pid | Opts]) ->
+ {ok, Listen} = ssl:listen(0, Opts),
+ {ok,{_, Port}} = ssl:sockname(Listen),
+ Pid ! {self(), Port},
+ {ok, Socket} = ssl:transport_accept(Listen),
+ Pid ! ssl:close(Socket).
+
+run_error_server([ Pid | Opts]) ->
+ {ok, Listen} = ssl:listen(0, Opts),
+ {ok,{_, Port}} = ssl:sockname(Listen),
+ Pid ! {self(), Port},
+ {ok, Socket} = ssl:transport_accept(Listen),
+ Pid ! ssl:controlling_process(Socket, self()).
+
+run_client_error([Port, Opts]) ->
+ ssl:connect("localhost", Port, Opts).
+
+honor_cipher_order(Config, Honor, ServerCiphers, ClientCiphers, Expected) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, [{ciphers, ServerCiphers}, {honor_cipher_order, Honor}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, [{ciphers, ClientCiphers}, {honor_cipher_order, Honor}
+ | ClientOpts]}]),
+
+ Version = ssl_test_lib:protocol_version(Config),
+
+ ServerMsg = ClientMsg = {ok, {Version, Expected}},
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connection_info_result(Socket) ->
+ {ok, Info} = ssl:connection_information(Socket, [protocol, selected_cipher_suite]),
+ {ok, {proplists:get_value(protocol, Info), proplists:get_value(selected_cipher_suite, Info)}}.
+
+der_input_opts(Opts) ->
+ Certfile = proplists:get_value(certfile, Opts),
+ CaCertsfile = proplists:get_value(cacertfile, Opts),
+ Keyfile = proplists:get_value(keyfile, Opts),
+ Dhfile = proplists:get_value(dhfile, Opts),
+ [{_, Cert, _}] = ssl_test_lib:pem_to_der(Certfile),
+ [{Asn1Type, Key, _}] = ssl_test_lib:pem_to_der(Keyfile),
+ [{_, DHParams, _}] = ssl_test_lib:pem_to_der(Dhfile),
+ CaCerts =
+ lists:map(fun(Entry) ->
+ {_, CaCert, _} = Entry,
+ CaCert
+ end, ssl_test_lib:pem_to_der(CaCertsfile)),
+ {Cert, {Asn1Type, Key}, CaCerts, DHParams}.
diff --git a/lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem b/lib/ssl/test/ssl_api_SUITE_data/dHParam.pem
index feb581da30..feb581da30 100644
--- a/lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem
+++ b/lib/ssl/test/ssl_api_SUITE_data/dHParam.pem
diff --git a/lib/ssl/test/ssl_app_env_SUITE.erl b/lib/ssl/test/ssl_app_env_SUITE.erl
new file mode 100644
index 0000000000..27fbcb8e47
--- /dev/null
+++ b/lib/ssl/test/ssl_app_env_SUITE.erl
@@ -0,0 +1,171 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_app_env_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssl/src/ssl_api.hrl").
+
+-define(SLEEP, 500).
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [
+ {group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+groups() ->
+ [
+ {'tlsv1.3', [], tests()},
+ {'tlsv1.2', [], tests()},
+ {'tlsv1.1', [], tests()},
+ {'tlsv1', [], tests()},
+ {'sslv3', [], tests()},
+ {'dtlsv1.2', [], tests()},
+ {'dtlsv1', [], tests()}
+ ].
+
+tests() ->
+ [
+ internal_active_1,
+ protocol_versions,
+ empty_protocol_versions
+ ].
+
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ [{client_type, erlang},
+ {server_type, erlang} | ssl_test_lib:init_tls_version(GroupName, Config)];
+ false ->
+ {skip, "Missing crypto support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(internal_active_1, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, internal_active_n, 1),
+ ssl:start(),
+ ct:timetrap({seconds, 5}),
+ Config;
+init_per_testcase(protocol_versions, Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ case atom_to_list(Version) of
+ "d" ++ _ ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, dtls_protocol_version, [Version]),
+ ssl:start();
+ _ ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, protocol_version, [Version]),
+ ssl:start()
+ end,
+ ct:timetrap({seconds, 5}),
+ Config;
+init_per_testcase(empty_protocol_versions, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ ssl_test_lib:clean_env(),
+ application:set_env(ssl, protocol_version, []),
+ application:set_env(ssl, dtls_protocol_version, []),
+ ssl:start(),
+ ct:timetrap({seconds, 5}),
+ Config;
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_, _Config) ->
+ ssl_test_lib:clean_start().
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+internal_active_1() ->
+ [{doc,"Test internal active 1 (behave as internal active once)"}].
+
+internal_active_1(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+protocol_versions() ->
+ [{doc,"Test to set a list of protocol versions in app environment."}].
+
+protocol_versions(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+empty_protocol_versions() ->
+ [{doc,"Test to set an empty list of protocol versions in app environment."}].
+
+empty_protocol_versions(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 86a0aaf67b..355cd31070 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -26,15 +26,8 @@
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
--include_lib("public_key/include/public_key.hrl").
+-include_lib("ssl/src/ssl_api.hrl").
--include("ssl_api.hrl").
--include("ssl_cipher.hrl").
--include("ssl_internal.hrl").
--include("ssl_alert.hrl").
--include("ssl_internal.hrl").
--include("tls_record.hrl").
--include("tls_handshake.hrl").
-define(TIMEOUT, 20000).
-define(EXPIRE, 10).
@@ -49,243 +42,35 @@
all() ->
[
{group, basic},
- {group, basic_tls},
- {group, options},
- {group, options_tls},
- {group, session},
- {group, 'dtlsv1.2'},
- {group, 'dtlsv1'},
- {group, 'tlsv1.3'},
- {group, 'tlsv1.2'},
- {group, 'tlsv1.1'},
- {group, 'tlsv1'},
- {group, 'sslv3'}
+ {group, options}
].
groups() ->
[{basic, [], basic_tests()},
- {basic_tls, [], basic_tests_tls()},
- {options, [], options_tests()},
- {options_tls, [], options_tests_tls()},
- {'dtlsv1.2', [], all_versions_groups()},
- {'dtlsv1', [], all_versions_groups()},
- {'tlsv1.3', [], tls13_test_group()},
- {'tlsv1.2', [], all_versions_groups() ++ tls_versions_groups() ++ [conf_signature_algs, no_common_signature_algs]},
- {'tlsv1.1', [], all_versions_groups() ++ tls_versions_groups()},
- {'tlsv1', [], all_versions_groups() ++ tls_versions_groups() ++ rizzo_tests()},
- {'sslv3', [], all_versions_groups() ++ tls_versions_groups() ++ rizzo_tests() ++ [tls_ciphersuite_vs_version]},
- {api,[], api_tests()},
- {api_tls,[], api_tests_tls()},
- {session, [], session_tests()},
- {renegotiate, [], renegotiate_tests()},
- {ciphers, [], cipher_tests()},
- {error_handling_tests, [], error_handling_tests()},
- {error_handling_tests_tls, [], error_handling_tests_tls()}
+ {options, [], options_tests()}
].
-tls_versions_groups ()->
- [
- {group, api_tls},
- {group, error_handling_tests_tls}].
-
-all_versions_groups ()->
- [{group, api},
- {group, renegotiate},
- {group, ciphers},
- {group, error_handling_tests}].
-
-
basic_tests() ->
[app,
- appup,
- alerts,
- alert_details,
- alert_details_not_too_big,
+ appup,
version_option,
connect_twice,
connect_dist,
- clear_pem_cache,
defaults,
fallback,
cipher_format,
- suite_to_str
- ].
-
-basic_tests_tls() ->
- [tls_send_close
- ].
-
-options_tests() ->
- [der_input,
- ssl_options_not_proplist,
- raw_ssl_option,
- invalid_inet_get_option,
- invalid_inet_get_option_not_list,
- invalid_inet_get_option_improper_list,
- invalid_inet_set_option,
- invalid_inet_set_option_not_list,
- invalid_inet_set_option_improper_list,
- dh_params,
- invalid_certfile,
- invalid_cacertfile,
- invalid_keyfile,
- invalid_options,
- protocol_versions,
- empty_protocol_versions,
- ipv6,
- reuseaddr,
- honor_server_cipher_order,
- honor_client_cipher_order,
- unordered_protocol_versions_server,
- unordered_protocol_versions_client,
- max_handshake_size
-].
-
-options_tests_tls() ->
- [tls_misc_ssl_options,
- tls_tcp_reuseaddr].
-
-api_tests() ->
- [secret_connection_info,
- connection_information,
- peercert,
- peercert_with_client_cert,
- versions,
+ tls_versions_option,
eccs,
- controlling_process,
- getstat,
- close_with_timeout,
- hibernate,
- hibernate_right_away,
- listen_socket,
- ssl_recv_timeout,
- server_name_indication_option,
- accept_pool,
- prf,
- socket_options,
- active_n,
- internal_active_1,
cipher_suites,
- handshake_continue,
- handshake_continue_timeout,
- hello_client_cancel,
- hello_server_cancel
- ].
-
-api_tests_tls() ->
- [tls_versions_option,
- tls_upgrade,
- tls_upgrade_with_timeout,
- tls_ssl_accept_timeout,
- tls_downgrade,
- tls_shutdown,
- tls_shutdown_write,
- tls_shutdown_both,
- tls_shutdown_error,
- peername,
- sockname,
- tls_socket_options,
- new_options_in_accept
- ].
-
-session_tests() ->
- [reuse_session,
- reuse_session_expired,
- server_does_not_want_to_reuse_session,
- no_reuses_session_server_restart_new_cert,
- no_reuses_session_server_restart_new_cert_file].
-
-renegotiate_tests() ->
- [client_renegotiate,
- server_renegotiate,
- client_secure_renegotiate,
- client_secure_renegotiate_fallback,
- client_renegotiate_reused_session,
- server_renegotiate_reused_session,
- client_no_wrap_sequence_number,
- server_no_wrap_sequence_number,
- renegotiate_dos_mitigate_active,
- renegotiate_dos_mitigate_passive,
- renegotiate_dos_mitigate_absolute].
-
-cipher_tests() ->
- [old_cipher_suites,
- cipher_suites_mix,
- default_reject_anonymous].
-
-error_handling_tests()->
- [close_transport_accept,
- recv_active,
- recv_active_once,
- recv_active_n,
- recv_error_handling,
- call_in_error_state,
- close_in_error_state,
- abuse_transport_accept_socket,
- controlling_process_transport_accept_socket
- ].
-
-error_handling_tests_tls()->
- [controller_dies,
- tls_client_closes_socket,
- tls_closed_in_active_once,
- tls_tcp_error_propagation_in_active_mode,
- tls_tcp_connect,
- tls_tcp_connect_big,
- tls_dont_crash_on_handshake_garbage
+ old_cipher_suites,
+ cipher_suites_mix
].
-rizzo_tests() ->
- [rizzo,
- no_rizzo_rc4,
- rizzo_one_n_minus_one,
- rizzo_zero_n,
- rizzo_disabled].
-
-%% For testing TLS 1.3 features and possible regressions
-tls13_test_group() ->
- [handshake_continue_tls13_client,
- tls13_enable_client_side,
- tls13_enable_server_side,
- tls_record_1_3_encode_decode,
- tls13_finished_verify_data,
- tls13_1_RTT_handshake,
- tls12_ssl_server_tls13_ssl_client,
- tls13_basic_ssl_server_openssl_client,
- tls13_basic_ssl_server_ssl_client,
- tls13_basic_openssl_server_ssl_client,
- tls13_custom_groups_ssl_server_openssl_client,
- tls13_custom_groups_ssl_server_ssl_client,
- tls13_hello_retry_request_ssl_server_openssl_client,
- tls13_hello_retry_request_ssl_server_ssl_client,
- tls13_client_auth_empty_cert_alert_ssl_server_openssl_client,
- tls13_client_auth_empty_cert_alert_ssl_server_ssl_client,
- tls13_client_auth_empty_cert_ssl_server_openssl_client,
- tls13_client_auth_empty_cert_ssl_server_ssl_client,
- tls13_client_auth_ssl_server_openssl_client,
- tls13_client_auth_ssl_server_ssl_client,
- tls13_hrr_client_auth_empty_cert_alert_ssl_server_openssl_client,
- tls13_hrr_client_auth_empty_cert_alert_ssl_server_ssl_client,
- tls13_hrr_client_auth_empty_cert_ssl_server_openssl_client,
- tls13_hrr_client_auth_empty_cert_ssl_server_ssl_client,
- tls13_hrr_client_auth_ssl_server_openssl_client,
- tls13_hrr_client_auth_ssl_server_ssl_client,
- tls13_unsupported_sign_algo_client_auth_ssl_server_openssl_client,
- tls13_unsupported_sign_algo_client_auth_ssl_server_ssl_client,
- tls13_unsupported_sign_algo_cert_client_auth_ssl_server_openssl_client,
- tls13_unsupported_sign_algo_cert_client_auth_ssl_server_ssl_client,
- tls13_connection_information,
- tls13_ssl_server_with_alpn_ssl_client,
- tls13_ssl_server_with_alpn_ssl_client_empty_alpn,
- tls13_ssl_server_with_alpn_ssl_client_bad_alpn,
- tls13_ssl_server_with_alpn_ssl_client_alpn,
- tls13_ecdsa_ssl_server_openssl_client,
- tls13_ecdsa_ssl_server_ssl_client,
- tls13_ecdsa_openssl_server_ssl_client,
- tls13_ecdsa_client_auth_ssl_server_ssl_client
- ].
+options_tests() ->
+ [
+ unordered_protocol_versions_server,
+ unordered_protocol_versions_client].
-%%--------------------------------------------------------------------
init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
@@ -308,229 +93,6 @@ end_per_suite(_Config) ->
application:stop(crypto).
%%--------------------------------------------------------------------
-
-init_per_group(GroupName, Config) when GroupName == basic_tls;
- GroupName == options_tls;
- GroupName == options;
- GroupName == basic;
- GroupName == session;
- GroupName == error_handling_tests_tls ->
- ssl_test_lib:clean_tls_version(Config);
-%% Do not automatically configure TLS version for the 'tlsv1.3' group
-init_per_group('tlsv1.3' = GroupName, Config) ->
- case ssl_test_lib:sufficient_crypto_support(GroupName) of
- true ->
- ssl:start(),
- Config;
- false ->
- {skip, "Missing crypto support"}
- end;
-init_per_group(GroupName, Config) ->
- ssl_test_lib:clean_tls_version(Config),
- case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of
- true ->
- ssl_test_lib:init_tls_version(GroupName, Config);
- _ ->
- case ssl_test_lib:sufficient_crypto_support(GroupName) of
- true ->
- ssl:start(),
- Config;
- false ->
- {skip, "Missing crypto support"}
- end
- end.
-
-end_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- ssl_test_lib:clean_tls_version(Config);
- false ->
- Config
- end.
-
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) when Case == unordered_protocol_versions_client;
- Case == unordered_protocol_versions_server->
- case proplists:get_value(supported, ssl:versions()) of
- ['tlsv1.2' | _] ->
- ct:timetrap({seconds, 5}),
- Config;
- _ ->
- {skip, "TLS 1.2 need but not supported on this platform"}
- end;
-
-init_per_testcase(protocol_versions, Config) ->
- ssl:stop(),
- application:load(ssl),
- %% For backwards compatibility sslv2 should be filtered out.
- application:set_env(ssl, protocol_version, [sslv2, sslv3, tlsv1]),
- ssl:start(),
- ct:timetrap({seconds, 5}),
- Config;
-
-init_per_testcase(reuse_session_expired, Config) ->
- ssl:stop(),
- application:load(ssl),
- ssl_test_lib:clean_env(),
- application:set_env(ssl, session_lifetime, ?EXPIRE),
- application:set_env(ssl, session_delay_cleanup_time, 500),
- ssl:start(),
- ct:timetrap({seconds, 30}),
- Config;
-
-init_per_testcase(empty_protocol_versions, Config) ->
- ssl:stop(),
- application:load(ssl),
- ssl_test_lib:clean_env(),
- application:set_env(ssl, protocol_version, []),
- ssl:start(),
- ct:timetrap({seconds, 5}),
- Config;
-
-init_per_testcase(fallback, Config) ->
- case tls_record:highest_protocol_version([]) of
- {3, N} when N > 1 ->
- ct:timetrap({seconds, 5}),
- Config;
- _ ->
- {skip, "Not relevant if highest supported version is less than 3.2"}
- end;
-
-init_per_testcase(TestCase, Config) when TestCase == client_renegotiate;
- TestCase == server_renegotiate;
- TestCase == client_secure_renegotiate;
- TestCase == client_renegotiate_reused_session;
- TestCase == server_renegotiate_reused_session;
- TestCase == client_no_wrap_sequence_number;
- TestCase == server_no_wrap_sequence_number;
- TestCase == renegotiate_dos_mitigate_active;
- TestCase == renegotiate_dos_mitigate_passive;
- TestCase == renegotiate_dos_mitigate_absolute ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, ?SEC_RENEGOTIATION_TIMEOUT + 5}),
- Config;
-
-init_per_testcase(TestCase, Config) when TestCase == versions_option;
- TestCase == tls_tcp_connect_big ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 60}),
- Config;
-
-init_per_testcase(version_option, Config) ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 10}),
- Config;
-
-init_per_testcase(reuse_session, Config) ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 10}),
- Config;
-
-init_per_testcase(rizzo, Config) ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 60}),
- Config;
-
-init_per_testcase(no_rizzo_rc4, Config) ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 60}),
- Config;
-
-init_per_testcase(rizzo_one_n_minus_one, Config) ->
- ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
- ct:timetrap({seconds, 60}),
- rizzo_add_mitigation_option(one_n_minus_one, Config);
-
-init_per_testcase(rizzo_zero_n, Config) ->
- ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
- ct:timetrap({seconds, 60}),
- rizzo_add_mitigation_option(zero_n, Config);
-
-init_per_testcase(rizzo_disabled, Config) ->
- ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
- ct:timetrap({seconds, 60}),
- rizzo_add_mitigation_option(disabled, Config);
-
-init_per_testcase(TestCase, Config) when TestCase == no_reuses_session_server_restart_new_cert_file;
- TestCase == no_reuses_session_server_restart_new_cert ->
- ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
- ct:timetrap({seconds, 15}),
- Config;
-
-init_per_testcase(prf, Config) ->
- ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
- ct:timetrap({seconds, 40}),
- case proplists:get_value(tc_group_path, Config) of
- [] -> Prop = [];
- [Prop] -> Prop
- end,
- case proplists:get_value(name, Prop) of
- undefined -> TlsVersions = [sslv3, tlsv1, 'tlsv1.1', 'tlsv1.2'];
- TlsVersion when is_atom(TlsVersion) ->
- TlsVersions = [TlsVersion]
- end,
- PRFS=[md5, sha, sha256, sha384, sha512],
- %All are the result of running tls_v1:prf(PrfAlgo, <<>>, <<>>, <<>>, 16)
- %with the specified PRF algorithm
- ExpectedPrfResults=
- [{md5, <<96,139,180,171,236,210,13,10,28,32,2,23,88,224,235,199>>},
- {sha, <<95,3,183,114,33,169,197,187,231,243,19,242,220,228,70,151>>},
- {sha256, <<166,249,145,171,43,95,158,232,6,60,17,90,183,180,0,155>>},
- {sha384, <<153,182,217,96,186,130,105,85,65,103,123,247,146,91,47,106>>},
- {sha512, <<145,8,98,38,243,96,42,94,163,33,53,49,241,4,127,28>>},
- %TLS 1.0 and 1.1 PRF:
- {md5sha, <<63,136,3,217,205,123,200,177,251,211,17,229,132,4,173,80>>}],
- TestPlan = prf_create_plan(TlsVersions, PRFS, ExpectedPrfResults),
- [{prf_test_plan, TestPlan} | Config];
-
-init_per_testcase(TestCase, Config) when TestCase == tls_ssl_accept_timeout;
- TestCase == tls_client_closes_socket;
- TestCase == tls_closed_in_active_once;
- TestCase == tls_downgrade ->
- ssl:stop(),
- ssl:start(),
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 15}),
- Config;
-init_per_testcase(TestCase, Config) when TestCase == clear_pem_cache;
- TestCase == der_input;
- TestCase == defaults ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- %% White box test need clean start
- ssl:stop(),
- ssl:start(),
- ct:timetrap({seconds, 20}),
- Config;
-init_per_testcase(raw_ssl_option, Config) ->
- ct:timetrap({seconds, 5}),
- case os:type() of
- {unix,linux} ->
- Config;
- _ ->
- {skip, "Raw options are platform-specific"}
- end;
-
-init_per_testcase(accept_pool, Config) ->
- ct:timetrap({seconds, 5}),
- case proplists:get_value(protocol, Config) of
- dtls ->
- {skip, "Not yet supported on DTLS sockets"};
- _ ->
- ssl_test_lib:ct_log_supported_protocol_versions(Config),
- Config
- end;
-
-init_per_testcase(internal_active_1, Config) ->
- ssl:stop(),
- application:load(ssl),
- application:set_env(ssl, internal_active_n, 1),
- ssl:start(),
- ct:timetrap({seconds, 5}),
- Config;
-
-init_per_testcase(controller_dies, Config) ->
- ct:timetrap({seconds, 10}),
- Config;
init_per_testcase(eccs, Config) ->
case ssl:eccs() of
[] ->
@@ -545,23 +107,8 @@ init_per_testcase(_TestCase, Config) ->
ct:timetrap({seconds, 5}),
Config.
-end_per_testcase(reuse_session_expired, Config) ->
- application:unset_env(ssl, session_lifetime),
- application:unset_env(ssl, session_delay_cleanup_time),
- end_per_testcase(default_action, Config);
-
-end_per_testcase(internal_active_n, Config) ->
- application:unset_env(ssl, internal_active_n),
- end_per_testcase(default_action, Config);
-
-end_per_testcase(Case, Config) when Case == protocol_versions;
- Case == empty_protocol_versions->
- application:unset_env(ssl, protocol_versions),
- end_per_testcase(default_action, Config);
-
end_per_testcase(_TestCase, Config) ->
Config.
-
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -575,669 +122,76 @@ appup() ->
appup(Config) when is_list(Config) ->
ok = ?t:appup_test(ssl).
%%--------------------------------------------------------------------
-alerts() ->
- [{doc, "Test ssl_alert:alert_txt/1"}].
-alerts(Config) when is_list(Config) ->
- Descriptions = [?CLOSE_NOTIFY, ?UNEXPECTED_MESSAGE, ?BAD_RECORD_MAC,
- ?DECRYPTION_FAILED_RESERVED, ?RECORD_OVERFLOW, ?DECOMPRESSION_FAILURE,
- ?HANDSHAKE_FAILURE, ?BAD_CERTIFICATE, ?UNSUPPORTED_CERTIFICATE,
- ?CERTIFICATE_REVOKED,?CERTIFICATE_EXPIRED, ?CERTIFICATE_UNKNOWN,
- ?ILLEGAL_PARAMETER, ?UNKNOWN_CA, ?ACCESS_DENIED, ?DECODE_ERROR,
- ?DECRYPT_ERROR, ?EXPORT_RESTRICTION, ?PROTOCOL_VERSION,
- ?INSUFFICIENT_SECURITY, ?INTERNAL_ERROR, ?USER_CANCELED,
- ?NO_RENEGOTIATION, ?UNSUPPORTED_EXTENSION, ?CERTIFICATE_UNOBTAINABLE,
- ?UNRECOGNISED_NAME, ?BAD_CERTIFICATE_STATUS_RESPONSE,
- ?BAD_CERTIFICATE_HASH_VALUE, ?UNKNOWN_PSK_IDENTITY,
- 255 %% Unsupported/unknow alert will result in a description too
- ],
- Alerts = [?ALERT_REC(?WARNING, ?CLOSE_NOTIFY) |
- [?ALERT_REC(?FATAL, Desc) || Desc <- Descriptions]],
- lists:foreach(fun(Alert) ->
- try ssl_alert:alert_txt(Alert)
- catch
- C:E:T ->
- ct:fail({unexpected, {C, E, T}})
- end
- end, Alerts).
-%%--------------------------------------------------------------------
-alert_details() ->
- [{doc, "Test that ssl_alert:alert_txt/1 result contains extendend error description"}].
-alert_details(Config) when is_list(Config) ->
- Unique = make_ref(),
- UniqueStr = lists:flatten(io_lib:format("~w", [Unique])),
- Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY, Unique),
- case string:str(ssl_alert:alert_txt(Alert), UniqueStr) of
- 0 ->
- ct:fail(error_details_missing);
- _ ->
- ok
- end.
-
-%%--------------------------------------------------------------------
-alert_details_not_too_big() ->
- [{doc, "Test that ssl_alert:alert_txt/1 limits printed depth of extended error description"}].
-alert_details_not_too_big(Config) when is_list(Config) ->
- Reason = lists:duplicate(10, lists:duplicate(10, lists:duplicate(10, {some, data}))),
- Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY, Reason),
- case length(ssl_alert:alert_txt(Alert)) < 1000 of
- true ->
- ok;
- false ->
- ct:fail(ssl_alert_text_too_big)
- end.
-
-%%--------------------------------------------------------------------
-new_options_in_accept() ->
- [{doc,"Test that you can set ssl options in ssl_accept/3 and not only in tcp upgrade"}].
-new_options_in_accept(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_dsa_opts, Config),
- [_ , _ | ServerSslOpts] = ssl_test_lib:ssl_options(server_opts, Config), %% Remove non ssl opts
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Version = ssl_test_lib:protocol_options(Config, [{tls, sslv3}, {dtls, dtlsv1}]),
- Cipher = ssl_test_lib:protocol_options(Config, [{tls, #{key_exchange =>rsa,
- cipher => rc4_128,
- mac => sha,
- prf => default_prf
- }},
- {dtls, #{key_exchange =>rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf
- }}]),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {ssl_extra_opts, [{versions, [Version]},
- {ciphers,[Cipher]} | ServerSslOpts]}, %% To be set in ssl_accept/3
- {mfa, {?MODULE, connection_info_result, []}},
- {options, proplists:delete(cacertfile, ServerOpts0)}]),
-
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, connection_info_result, []}},
- {options, [{versions, [Version]},
- {ciphers,[Cipher]} | ClientOpts]}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ServerMsg = ClientMsg = {ok, {Version, Cipher}},
+version_option() ->
+ [{doc, "Use version option and do no specify ciphers list. Bug specified incorrect ciphers"}].
+version_option(Config) when is_list(Config) ->
+ Versions = proplists:get_value(supported, ssl:versions()),
+ [version_option_test(Config, Version) || Version <- Versions].
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-handshake_continue() ->
- [{doc, "Test API function ssl:handshake_continue/3"}].
-handshake_continue(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ssl_test_lib:ssl_options([{reuseaddr, true}, {handshake, hello}],
- Config)},
- {continue_options, proplists:delete(reuseaddr, ServerOpts)}
- ]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ssl_test_lib:ssl_options([{handshake, hello}],
- Config)},
- {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-%%--------------------------------------------------------------------
-handshake_continue_tls13_client() ->
- [{doc, "Test API function ssl:handshake_continue/3"}].
-handshake_continue_tls13_client(Config) when is_list(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- ClientOptsHello0 = ssl_test_lib:ssl_options([{handshake, hello}], Config),
- ClientOptsHello = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOptsHello0],
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ssl_test_lib:ssl_options([{reuseaddr, true}, {handshake, hello}],
- Config)},
- {continue_options, proplists:delete(reuseaddr, ServerOpts)}
- ]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOptsHello},
- {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-%%------------------------------------------------------------------
-handshake_continue_timeout() ->
- [{doc, "Test API function ssl:handshake_continue/3 with short timeout"}].
-handshake_continue_timeout(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {timeout, 1},
- {options, ssl_test_lib:ssl_options([{reuseaddr, true}, {handshake, hello}],
- Config)},
- {continue_options, proplists:delete(reuseaddr, ServerOpts)}
- ]),
-
- Port = ssl_test_lib:inet_port(Server),
-
-
- {connect_failed, _} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, {error,timeout}),
- ssl_test_lib:close(Server).
-
-
-%%--------------------------------------------------------------------
-hello_client_cancel() ->
- [{doc, "Test API function ssl:handshake_cancel/1 on the client side"}].
-hello_client_cancel(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
- {continue_options, proplists:delete(reuseaddr, ServerOpts)}]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- %% That is ssl:handshake_cancel returns ok
- {connect_failed, ok} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
- {continue_options, cancel}]),
- ssl_test_lib:check_server_alert(Server, user_canceled).
%%--------------------------------------------------------------------
-hello_server_cancel() ->
- [{doc, "Test API function ssl:handshake_cancel/1 on the server side"}].
-hello_server_cancel(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
- {continue_options, cancel}]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- {connect_failed, _} = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, ssl_test_lib:ssl_options([{handshake, hello}], Config)},
- {continue_options, proplists:delete(reuseaddr, ClientOpts)}]),
-
- ssl_test_lib:check_result(Server, ok).
-
-%%--------------------------------------------------------------------
-prf() ->
- [{doc,"Test that ssl:prf/5 uses the negotiated PRF."}].
-prf(Config) when is_list(Config) ->
- TestPlan = proplists:get_value(prf_test_plan, Config),
- case TestPlan of
- [] -> ct:fail({error, empty_prf_test_plan});
- _ -> lists:foreach(fun(Suite) ->
- lists:foreach(
- fun(Test) ->
- V = proplists:get_value(tls_ver, Test),
- C = proplists:get_value(ciphers, Test),
- E = proplists:get_value(expected, Test),
- P = proplists:get_value(prf, Test),
- prf_run_test(Config, V, C, E, P)
- end, Suite)
- end, TestPlan)
- end.
-
-%%--------------------------------------------------------------------
-
-secret_connection_info() ->
- [{doc,"Test the API function ssl:connection_information/2"}].
-secret_connection_info(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, secret_connection_info_result, []}},
- {options, ServerOpts}]),
-
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, secret_connection_info_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, true, Client, true),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-%%--------------------------------------------------------------------
-
-connection_information() ->
- [{doc,"Test the API function ssl:connection_information/1"}].
-connection_information(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, connection_information_result, []}},
- {options, ServerOpts}]),
-
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, connection_information_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ServerMsg = ClientMsg = ok,
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-%%--------------------------------------------------------------------
-protocol_versions() ->
- [{doc,"Test to set a list of protocol versions in app environment."}].
-
-protocol_versions(Config) when is_list(Config) ->
- basic_test(Config).
-
-%%--------------------------------------------------------------------
-empty_protocol_versions() ->
- [{doc,"Test to set an empty list of protocol versions in app environment."}].
-
-empty_protocol_versions(Config) when is_list(Config) ->
- basic_test(Config).
-
-%%--------------------------------------------------------------------
-
-controlling_process() ->
- [{doc,"Test API function controlling_process/2"}].
-
-controlling_process(Config) when is_list(Config) ->
+connect_twice() ->
+ [{doc,""}].
+connect_twice(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- ClientMsg = "Server hello",
- ServerMsg = "Client hello",
-
- Server = ssl_test_lib:start_server([
- {node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- controlling_process_result, [self(),
- ServerMsg]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- {Client, CSocket} = ssl_test_lib:start_client([return_socket,
- {node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- controlling_process_result, [self(),
- ClientMsg]}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ServerMsg = ssl_test_lib:active_recv(CSocket, length(ServerMsg)),
- %% We do not have the TLS server socket but all messages form the client
- %% socket are now read, so ramining are form the server socket
- ClientMsg = ssl_active_recv(length(ClientMsg)),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-getstat() ->
- [{doc,"Test API function getstat/2"}].
-getstat(Config) when is_list(Config) ->
- ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server1 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port1 = ssl_test_lib:inet_port(Server1),
- Server2 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port2 = ssl_test_lib:inet_port(Server2),
- {ok, ActiveC} = rpc:call(ClientNode, ssl, connect,
- [Hostname,Port1,[{active, once}|ClientOpts]]),
- {ok, PassiveC} = rpc:call(ClientNode, ssl, connect,
- [Hostname,Port2,[{active, false}|ClientOpts]]),
-
- ct:log("Testcase ~p, Client ~p Servers ~p, ~p ~n",
- [self(), self(), Server1, Server2]),
-
- %% We only check that the values are non-zero initially
- %% (due to the handshake), and that sending more changes the values.
-
- %% Passive socket.
-
- {ok, InitialStats} = ssl:getstat(PassiveC),
- ct:pal("InitialStats ~p~n", [InitialStats]),
- [true] = lists:usort([0 =/= proplists:get_value(Name, InitialStats)
- || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
-
- ok = ssl:send(PassiveC, "Hello world"),
- wait_for_send(PassiveC),
- {ok, SStats} = ssl:getstat(PassiveC, [send_cnt, send_oct]),
- ct:pal("SStats ~p~n", [SStats]),
- [true] = lists:usort([proplists:get_value(Name, SStats) =/= proplists:get_value(Name, InitialStats)
- || Name <- [send_cnt, send_oct]]),
-
- %% Active socket.
-
- {ok, InitialAStats} = ssl:getstat(ActiveC),
- ct:pal("InitialAStats ~p~n", [InitialAStats]),
- [true] = lists:usort([0 =/= proplists:get_value(Name, InitialAStats)
- || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
- _ = receive
- {ssl, ActiveC, _} ->
- ok
- after
- ?SLEEP ->
- exit(timeout)
- end,
-
- ok = ssl:send(ActiveC, "Hello world"),
- wait_for_send(ActiveC),
- {ok, ASStats} = ssl:getstat(ActiveC, [send_cnt, send_oct]),
- ct:pal("ASStats ~p~n", [ASStats]),
- [true] = lists:usort([proplists:get_value(Name, ASStats) =/= proplists:get_value(Name, InitialAStats)
- || Name <- [send_cnt, send_oct]]),
-
- ok.
-
-%%--------------------------------------------------------------------
-controller_dies() ->
- [{doc,"Test that the socket is closed after controlling process dies"}].
-controller_dies(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- ClientMsg = "Hello server",
- ServerMsg = "Hello client",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- controller_dies_result, [self(),
- ServerMsg]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- controller_dies_result, [self(),
- ClientMsg]}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n", [self(), Client, Server]),
- ct:sleep(?SLEEP), %% so that they are connected
-
- process_flag(trap_exit, true),
-
- %% Test that clients die
- exit(Client, killed),
- get_close(Client, ?LINE),
-
- %% Test that clients die when process disappear
- Server ! listen,
- Tester = self(),
- Connect = fun(Pid) ->
- {ok, Socket} = ssl:connect(Hostname, Port, ClientOpts),
- %% Make sure server finishes and verification
- %% and is in coonection state before
- %% killing client
- ct:sleep(?SLEEP),
- Pid ! {self(), connected, Socket},
- receive die_nice -> normal end
- end,
- Client2 = spawn_link(fun() -> Connect(Tester) end),
- receive {Client2, connected, _Socket} -> Client2 ! die_nice end,
-
- get_close(Client2, ?LINE),
-
- %% Test that clients die when the controlling process have changed
- Server ! listen,
-
- Client3 = spawn_link(fun() -> Connect(Tester) end),
- Controller = spawn_link(fun() -> receive die_nice -> normal end end),
- receive
- {Client3, connected, Socket} ->
- ok = ssl:controlling_process(Socket, Controller),
- Client3 ! die_nice
- end,
-
- ct:log("Wating on exit ~p~n",[Client3]),
- receive {'EXIT', Client3, normal} -> ok end,
-
- receive %% Client3 is dead but that doesn't matter, socket should not be closed.
- Unexpected ->
- ct:log("Unexpected ~p~n",[Unexpected]),
- ct:fail({line, ?LINE-1})
- after 1000 ->
- ok
- end,
- Controller ! die_nice,
- get_close(Controller, ?LINE),
-
- %% Test that servers die
- Server ! listen,
- LastClient = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- controller_dies_result, [self(),
- ClientMsg]}},
- {options, ClientOpts}]),
- ct:sleep(?SLEEP), %% so that they are connected
-
- exit(Server, killed),
- get_close(Server, ?LINE),
- process_flag(trap_exit, false),
- ssl_test_lib:close(LastClient).
-
-%%--------------------------------------------------------------------
-tls_client_closes_socket() ->
- [{doc,"Test what happens when client closes socket before handshake is compleated"}].
-
-tls_client_closes_socket(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TcpOpts = [binary, {reuseaddr, true}],
-
- Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {tcp_options, TcpOpts},
- {ssl_options, ServerOpts}]),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{keepalive, true},{active, false}
+ | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{keepalive, true},{active, false}
+ | ClientOpts]}]),
+ Server ! listen,
- Connect = fun() ->
- {ok, _Socket} = rpc:call(ClientNode, gen_tcp, connect,
- [Hostname, Port, [binary]]),
- %% Make sure that ssl_accept is called before
- %% client process ends and closes socket.
- ct:sleep(?SLEEP)
- end,
-
- _Client = spawn_link(Connect),
-
- ssl_test_lib:check_result(Server, {error,closed}).
-
-%%--------------------------------------------------------------------
-tls_closed_in_active_once() ->
- [{doc, "Test that ssl_closed is delivered in active once with non-empty buffer, check ERL-420."}].
-
-tls_closed_in_active_once(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {_ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TcpOpts = [binary, {reuseaddr, true}],
- Port = ssl_test_lib:inet_port(node()),
- Server = fun() ->
- {ok, Listen} = gen_tcp:listen(Port, TcpOpts),
- {ok, TcpServerSocket} = gen_tcp:accept(Listen),
- {ok, ServerSocket} = ssl:ssl_accept(TcpServerSocket, ServerOpts),
- lists:foreach(
- fun(_) ->
- ssl:send(ServerSocket, "some random message\r\n")
- end, lists:seq(1, 20)),
- %% Close TCP instead of SSL socket to trigger the bug:
- gen_tcp:close(TcpServerSocket),
- gen_tcp:close(Listen)
- end,
- spawn_link(Server),
- {ok, Socket} = ssl:connect(Hostname, Port, [{active, false} | ClientOpts]),
- Result = tls_closed_in_active_once_loop(Socket),
- ssl:close(Socket),
- case Result of
- ok -> ok;
- _ -> ct:fail(Result)
- end.
-
-tls_closed_in_active_once_loop(Socket) ->
- case ssl:setopts(Socket, [{active, once}]) of
- ok ->
- receive
- {ssl, Socket, _} ->
- tls_closed_in_active_once_loop(Socket);
- {ssl_closed, Socket} ->
- ok
- after 5000 ->
- no_ssl_closed_received
- end;
- {error, closed} ->
- ok
- end.
-%%--------------------------------------------------------------------
-connect_dist() ->
- [{doc,"Test a simple connect as is used by distribution"}].
-
-connect_dist(Config) when is_list(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_kc_opts, Config),
- ClientOpts = [{ssl_imp, new},{active, false}, {packet,4}|ClientOpts0],
- ServerOpts0 = ssl_test_lib:ssl_options(server_kc_opts, Config),
- ServerOpts = [{ssl_imp, new},{active, false}, {packet,4}|ServerOpts0],
+ {Client1, #sslsocket{}} =
+ ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{keepalive, true},{active, false}
+ | ClientOpts]}]),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, connect_dist_s, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, connect_dist_c, []}},
- {options, ClientOpts}]),
-
ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:check_result(Server, ok, Client1, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
-clear_pem_cache() ->
- [{doc,"Test that internal reference tabel is cleaned properly even when "
- " the PEM cache is cleared" }].
-clear_pem_cache(Config) when is_list(Config) ->
- {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
- [_, _,_, _, Prop] = StatusInfo,
- State = ssl_test_lib:state(Prop),
- [_,{FilRefDb, _} |_] = element(6, State),
- {Server, Client} = basic_verify_test_no_close(Config),
- CountReferencedFiles = fun({_, -1}, Acc) ->
- Acc;
- ({_, N}, Acc) ->
- N + Acc
- end,
-
- 2 = ets:foldl(CountReferencedFiles, 0, FilRefDb),
- ssl:clear_pem_cache(),
- _ = sys:get_status(whereis(ssl_manager)),
- {Server1, Client1} = basic_verify_test_no_close(Config),
- 4 = ets:foldl(CountReferencedFiles, 0, FilRefDb),
- ssl_test_lib:close(Server),
ssl_test_lib:close(Client),
- ct:sleep(2000),
- _ = sys:get_status(whereis(ssl_manager)),
- 2 = ets:foldl(CountReferencedFiles, 0, FilRefDb),
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client1),
- ct:sleep(2000),
- _ = sys:get_status(whereis(ssl_manager)),
- 0 = ets:foldl(CountReferencedFiles, 0, FilRefDb).
+ ssl_test_lib:close(Client1).
+defaults(Config) when is_list(Config)->
+ Versions = ssl:versions(),
+ true = lists:member(sslv3, proplists:get_value(available, Versions)),
+ false = lists:member(sslv3, proplists:get_value(supported, Versions)),
+ true = lists:member('tlsv1', proplists:get_value(available, Versions)),
+ false = lists:member('tlsv1', proplists:get_value(supported, Versions)),
+ true = lists:member('tlsv1.1', proplists:get_value(available, Versions)),
+ false = lists:member('tlsv1.1', proplists:get_value(supported, Versions)),
+ true = lists:member('tlsv1.2', proplists:get_value(available, Versions)),
+ true = lists:member('tlsv1.2', proplists:get_value(supported, Versions)),
+ false = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites()),
+ true = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites(all)),
+ false = lists:member({rsa,des_cbc,sha}, ssl:cipher_suites()),
+ true = lists:member({rsa,des_cbc,sha}, ssl:cipher_suites(all)),
+ false = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites()),
+ true = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites(all)),
+ true = lists:member('dtlsv1.2', proplists:get_value(available_dtls, Versions)),
+ true = lists:member('dtlsv1', proplists:get_value(available_dtls, Versions)),
+ true = lists:member('dtlsv1.2', proplists:get_value(supported_dtls, Versions)),
+ false = lists:member('dtlsv1', proplists:get_value(supported_dtls, Versions)).
-%%--------------------------------------------------------------------
fallback() ->
[{doc, "Test TLS_FALLBACK_SCSV downgrade prevention"}].
@@ -1263,7 +217,6 @@ fallback(Config) when is_list(Config) ->
| ClientOpts]}]),
ssl_test_lib:check_server_alert(Server, Client, inappropriate_fallback).
-
%%--------------------------------------------------------------------
cipher_format() ->
[{doc, "Test that cipher conversion from maps | tuples | stings to binarys works"}].
@@ -1277,175 +230,6 @@ cipher_format(Config) when is_list(Config) ->
ssl:close(Socket2).
%%--------------------------------------------------------------------
-suite_to_str() ->
- [{doc, "Test that the suite_to_str API works"}].
-suite_to_str(Config) when is_list(Config) ->
- "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" =
- ssl:suite_to_str(#{key_exchange => null,
- cipher => null,
- mac => null,
- prf => null}),
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" =
- ssl:suite_to_str(#{key_exchange => ecdhe_ecdsa,
- cipher => aes_128_gcm,
- mac => aead,
- prf => sha256}),
- "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256" =
- ssl:suite_to_str(#{key_exchange => ecdh_rsa,
- cipher => aes_128_cbc,
- mac => sha256,
- prf => sha256}).
-
-%%--------------------------------------------------------------------
-
-peername() ->
- [{doc,"Test API function peername/1"}].
-
-peername(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, peername_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, peername_result, []}},
- {options, [{port, 0} | ClientOpts]}]),
-
- ClientPort = ssl_test_lib:inet_port(Client),
- ServerIp = ssl_test_lib:node_to_hostip(ServerNode, server),
- ClientIp = ssl_test_lib:node_to_hostip(ClientNode, client),
- ServerMsg = {ok, {ClientIp, ClientPort}},
- ClientMsg = {ok, {ServerIp, Port}},
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-peercert() ->
- [{doc,"Test API function peercert/1"}].
-peercert(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, peercert_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, peercert_result, []}},
- {options, ClientOpts}]),
-
- CertFile = proplists:get_value(certfile, ServerOpts),
- [{'Certificate', BinCert, _}]= ssl_test_lib:pem_to_der(CertFile),
-
- ServerMsg = {error, no_peercert},
- ClientMsg = {ok, BinCert},
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-peercert_result(Socket) ->
- ssl:peercert(Socket).
-%%--------------------------------------------------------------------
-
-peercert_with_client_cert() ->
- [{doc,"Test API function peercert/1"}].
-peercert_with_client_cert(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_dsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_dsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, peercert_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, peercert_result, []}},
- {options, ClientOpts}]),
-
- ServerCertFile = proplists:get_value(certfile, ServerOpts),
- [{'Certificate', ServerBinCert, _}]= ssl_test_lib:pem_to_der(ServerCertFile),
- ClientCertFile = proplists:get_value(certfile, ClientOpts),
- [{'Certificate', ClientBinCert, _}]= ssl_test_lib:pem_to_der(ClientCertFile),
-
- ServerMsg = {ok, ClientBinCert},
- ClientMsg = {ok, ServerBinCert},
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-sockname() ->
- [{doc,"Test API function sockname/1"}].
-sockname(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, sockname_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, sockname_result, []}},
- {options, [{port, 0} | ClientOpts]}]),
-
- ClientPort = ssl_test_lib:inet_port(Client),
- ServerIp =
- case proplists:get_value(protocol, Config) of
- dtls ->
- %% DTLS sockets are not connected on the server side,
- %% so we can only get a ClientIP, ServerIP will always be 0.0.0.0
- {0,0,0,0};
- _ ->
- ssl_test_lib:node_to_hostip(ServerNode, server)
- end,
-
- ClientIp = ssl_test_lib:node_to_hostip(ClientNode, client),
- ServerMsg = {ok, {ServerIp, Port}},
- ClientMsg = {ok, {ClientIp, ClientPort}},
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-sockname_result(S) ->
- ssl:sockname(S).
-
-%%--------------------------------------------------------------------
cipher_suites() ->
[{doc,"Test API function cipher_suites/2, filter_cipher_suites/2"
@@ -1542,2750 +326,95 @@ cipher_suites_mix(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-%%--------------------------------------------------------------------
-tls_socket_options() ->
- [{doc,"Test API function getopts/2 and setopts/2"}].
+unordered_protocol_versions_server() ->
+ [{doc,"Test that the highest protocol is selected even"
+ " when it is not first in the versions list."}].
-tls_socket_options(Config) when is_list(Config) ->
+unordered_protocol_versions_server(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Values = [{mode, list}, {packet, 0}, {header, 0},
- {active, true}],
- %% Shall be the reverse order of Values!
- Options = [active, header, packet, mode],
-
- NewValues = [{mode, binary}, {active, once}],
- %% Shall be the reverse order of NewValues!
- NewOptions = [active, mode],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, tls_socket_options_result,
- [Options, Values, NewOptions, NewValues]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, tls_socket_options_result,
- [Options, Values, NewOptions, NewValues]}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
-
- {ok, Listen} = ssl:listen(0, ServerOpts),
- {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
- ok = ssl:setopts(Listen, [{mode, binary}]),
- {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
- {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
- ssl:close(Listen).
-
-tls_socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
- %% Test get/set emulated opts
- {ok, DefaultValues} = ssl:getopts(Socket, Options),
- ssl:setopts(Socket, NewValues),
- {ok, NewValues} = ssl:getopts(Socket, NewOptions),
- %% Test get/set inet opts
- {ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
- ssl:setopts(Socket, [{nodelay, true}]),
- {ok,[{nodelay, true}]} = ssl:getopts(Socket, [nodelay]),
- {ok, All} = ssl:getopts(Socket, []),
- ct:log("All opts ~p~n", [All]),
- ok.
-
-
-%%--------------------------------------------------------------------
-socket_options() ->
- [{doc,"Test API function getopts/2 and setopts/2"}].
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-socket_options(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Values = [{mode, list}, {active, true}],
- %% Shall be the reverse order of Values!
- Options = [active, mode],
-
- NewValues = [{mode, binary}, {active, once}],
- %% Shall be the reverse order of NewValues!
- NewOptions = [active, mode],
-
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, socket_options_result,
- [Options, Values, NewOptions, NewValues]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, socket_options_result,
- [Options, Values, NewOptions, NewValues]}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
-
- {ok, Listen} = ssl:listen(0, ServerOpts),
- {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
- ok = ssl:setopts(Listen, [{mode, binary}]),
- {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
- {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
- ssl:close(Listen).
-
-
-socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
- %% Test get/set emulated opts
- {ok, DefaultValues} = ssl:getopts(Socket, Options),
- ssl:setopts(Socket, NewValues),
- {ok, NewValues} = ssl:getopts(Socket, NewOptions),
- %% Test get/set inet opts
- {ok,[{reuseaddr, _}]} = ssl:getopts(Socket, [reuseaddr]),
- {ok, All} = ssl:getopts(Socket, []),
- ct:log("All opts ~p~n", [All]),
- ok.
-
-
-%%--------------------------------------------------------------------
-invalid_inet_get_option() ->
- [{doc,"Test handling of invalid inet options in getopts"}].
-
-invalid_inet_get_option(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, get_invalid_inet_option, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-invalid_inet_get_option_not_list() ->
- [{doc,"Test handling of invalid type in getopts"}].
-
-invalid_inet_get_option_not_list(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, get_invalid_inet_option_not_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-get_invalid_inet_option_not_list(Socket) ->
- {error, {options, {socket_options, some_invalid_atom_here}}}
- = ssl:getopts(Socket, some_invalid_atom_here),
- ok.
-
-%%--------------------------------------------------------------------
-invalid_inet_get_option_improper_list() ->
- [{doc,"Test handling of invalid type in getopts"}].
-
-invalid_inet_get_option_improper_list(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, get_invalid_inet_option_improper_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-get_invalid_inet_option_improper_list(Socket) ->
- {error, {options, {socket_options, foo,_}}} = ssl:getopts(Socket, [packet | foo]),
- ok.
-
-%%--------------------------------------------------------------------
-invalid_inet_set_option() ->
- [{doc,"Test handling of invalid inet options in setopts"}].
-
-invalid_inet_set_option(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, set_invalid_inet_option, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-set_invalid_inet_option(Socket) ->
- {error, {options, {socket_options, {packet, foo}}}} = ssl:setopts(Socket, [{packet, foo}]),
- {error, {options, {socket_options, {header, foo}}}} = ssl:setopts(Socket, [{header, foo}]),
- {error, {options, {socket_options, {active, foo}}}} = ssl:setopts(Socket, [{active, foo}]),
- {error, {options, {socket_options, {mode, foo}}}} = ssl:setopts(Socket, [{mode, foo}]),
- ok.
-%%--------------------------------------------------------------------
-invalid_inet_set_option_not_list() ->
- [{doc,"Test handling of invalid type in setopts"}].
-
-invalid_inet_set_option_not_list(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, set_invalid_inet_option_not_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-set_invalid_inet_option_not_list(Socket) ->
- {error, {options, {not_a_proplist, some_invalid_atom_here}}}
- = ssl:setopts(Socket, some_invalid_atom_here),
- ok.
-
-%%--------------------------------------------------------------------
-invalid_inet_set_option_improper_list() ->
- [{doc,"Test handling of invalid tye in setopts"}].
-
-invalid_inet_set_option_improper_list(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, set_invalid_inet_option_improper_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-set_invalid_inet_option_improper_list(Socket) ->
- {error, {options, {not_a_proplist, [{packet, 0} | {foo, 2}]}}} =
- ssl:setopts(Socket, [{packet, 0} | {foo, 2}]),
- ok.
-
-%%--------------------------------------------------------------------
-tls_misc_ssl_options() ->
- [{doc,"Test what happens when we give valid options"}].
-
-tls_misc_ssl_options(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Check that ssl options not tested elsewhere are filtered away e.i. not passed to inet.
- TestOpts = [{depth, 1},
- {key, undefined},
- {password, []},
- {reuse_session, fun(_,_,_,_) -> true end},
- {cb_info, {gen_tcp, tcp, tcp_closed, tcp_error}}],
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, TestOpts ++ ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, TestOpts ++ ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-ssl_options_not_proplist() ->
- [{doc,"Test what happens if an option is not a key value tuple"}].
-
-ssl_options_not_proplist(Config) when is_list(Config) ->
- BadOption = {client_preferred_next_protocols,
- client, [<<"spdy/3">>,<<"http/1.1">>], <<"http/1.1">>},
- {option_not_a_key_value_tuple, BadOption} =
- ssl:connect("twitter.com", 443, [binary, {active, false},
- BadOption]).
-
-%%--------------------------------------------------------------------
-raw_ssl_option() ->
- [{doc,"Ensure that a single 'raw' option is passed to ssl:listen correctly."}].
-
-raw_ssl_option(Config) when is_list(Config) ->
- % 'raw' option values are platform-specific; these are the Linux values:
- IpProtoTcp = 6,
- % Use TCP_KEEPIDLE, because (e.g.) TCP_MAXSEG can't be read back reliably.
- TcpKeepIdle = 4,
- KeepAliveTimeSecs = 55,
- LOptions = [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}],
- {ok, LSocket} = ssl:listen(0, LOptions),
- % Per http://www.erlang.org/doc/man/inet.html#getopts-2, we have to specify
- % exactly which raw option we want, and the size of the buffer.
- {ok, [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}]} = ssl:getopts(LSocket, [{raw, IpProtoTcp, TcpKeepIdle, 4}]).
-
-
-%%--------------------------------------------------------------------
-versions() ->
- [{doc,"Test API function versions/0"}].
-
-versions(Config) when is_list(Config) ->
- [_|_] = Versions = ssl:versions(),
- ct:log("~p~n", [Versions]).
-
-
-%%--------------------------------------------------------------------
-eccs() ->
- [{doc, "Test API functions eccs/0 and eccs/1"}].
-
-eccs(Config) when is_list(Config) ->
- [_|_] = All = ssl:eccs(),
- [] = SSL3 = ssl:eccs(sslv3),
- [_|_] = Tls = ssl:eccs(tlsv1),
- [_|_] = Tls1 = ssl:eccs('tlsv1.1'),
- [_|_] = Tls2 = ssl:eccs('tlsv1.2'),
- [_|_] = Tls1 = ssl:eccs('dtlsv1'),
- [_|_] = Tls2 = ssl:eccs('dtlsv1.2'),
- %% ordering is currently unverified by the test
- true = lists:sort(All) =:= lists:usort(SSL3 ++ Tls ++ Tls1 ++ Tls2),
- ok.
-
-%%--------------------------------------------------------------------
-send_recv() ->
- [{doc,""}].
-send_recv(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ClientOpts]}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_send_close() ->
- [{doc,""}].
-tls_send_close(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- {ok, TcpS} = rpc:call(ClientNode, gen_tcp, connect,
- [Hostname,Port,[binary, {active, false}]]),
- {ok, SslS} = rpc:call(ClientNode, ssl, connect,
- [TcpS,[{active, false}|ClientOpts]]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), self(), Server]),
- ok = ssl:send(SslS, "Hello world"),
- {ok,<<"Hello world">>} = ssl:recv(SslS, 11),
- gen_tcp:close(TcpS),
- {error, _} = ssl:send(SslS, "Hello world").
-
-%%--------------------------------------------------------------------
-version_option() ->
- [{doc, "Use version option and do no specify ciphers list. Bug specified incorrect ciphers"}].
-version_option(Config) when is_list(Config) ->
- Versions = proplists:get_value(supported, ssl:versions()),
- [version_option_test(Config, Version) || Version <- Versions].
-
-%%--------------------------------------------------------------------
-close_transport_accept() ->
- [{doc,"Tests closing ssl socket when waiting on ssl:transport_accept/1"}].
-
-close_transport_accept(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Port = 0,
- Opts = [{active, false} | ServerOpts],
- {ok, ListenSocket} = rpc:call(ServerNode, ssl, listen, [Port, Opts]),
- spawn_link(fun() ->
- ct:sleep(?SLEEP),
- rpc:call(ServerNode, ssl, close, [ListenSocket])
- end),
- case rpc:call(ServerNode, ssl, transport_accept, [ListenSocket]) of
- {error, closed} ->
- ok;
- Other ->
- exit({?LINE, Other})
- end.
-%%--------------------------------------------------------------------
-recv_active() ->
- [{doc,"Test recv on active socket"}].
-
-recv_active(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, try_recv_active, []}},
- {options, [{active, true} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, try_recv_active, []}},
- {options, [{active, true} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-recv_active_once() ->
- [{doc,"Test recv on active (once) socket"}].
-
-recv_active_once(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, try_recv_active_once, []}},
- {options, [{active, once} | ServerOpts]}]),
+ {mfa, {?MODULE, protocol_info_result, []}},
+ {options, [{versions, ['tlsv1.1', 'tlsv1.2']} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, try_recv_active_once, []}},
- {options, [{active, once} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-
-
-
-%%--------------------------------------------------------------------
-recv_active_n() ->
- [{doc,"Test recv on active (n) socket"}].
-
-recv_active_n(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, try_recv_active_once, []}},
- {options, [{active, 1} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, try_recv_active_once, []}},
- {options, [{active, 1} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-%%--------------------------------------------------------------------
-%% Test case adapted from gen_tcp_misc_SUITE.
-active_n() ->
- [{doc,"Test {active,N} option"}].
-
-active_n(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- Port = ssl_test_lib:inet_port(node()),
- N = 3,
- LS = ok(ssl:listen(Port, [{active,N}|ServerOpts])),
- [{active,N}] = ok(ssl:getopts(LS, [active])),
- active_n_common(LS, N),
- Self = self(),
- spawn_link(fun() ->
- S0 = ok(ssl:transport_accept(LS)),
- {ok, S} = ssl:handshake(S0),
- ok = ssl:setopts(S, [{active,N}]),
- [{active,N}] = ok(ssl:getopts(S, [active])),
- ssl:controlling_process(S, Self),
- Self ! {server, S}
- end),
- C = ok(ssl:connect("localhost", Port, [{active,N}|ClientOpts])),
- [{active,N}] = ok(ssl:getopts(C, [active])),
- S = receive
- {server, S0} -> S0
- after
- 1000 ->
- exit({error, connect})
- end,
- active_n_common(C, N),
- active_n_common(S, N),
- ok = ssl:setopts(C, [{active,N}]),
- ok = ssl:setopts(S, [{active,N}]),
- ReceiveMsg = fun(Socket, Msg) ->
- receive
- {ssl,Socket,Msg} ->
- ok;
- {ssl,Socket,Begin} ->
- receive
- {ssl,Socket,End} ->
- Msg = Begin ++ End,
- ok
- after 1000 ->
- exit(timeout)
- end
- after 1000 ->
- exit(timeout)
- end
- end,
- repeat(3, fun(I) ->
- Msg = "message "++integer_to_list(I),
- ok = ssl:send(C, Msg),
- ReceiveMsg(S, Msg),
- ok = ssl:send(S, Msg),
- ReceiveMsg(C, Msg)
- end),
- receive
- {ssl_passive,S} ->
- [{active,false}] = ok(ssl:getopts(S, [active]))
- after
- 1000 ->
- exit({error,ssl_passive})
- end,
- receive
- {ssl_passive,C} ->
- [{active,false}] = ok(ssl:getopts(C, [active]))
- after
- 1000 ->
- exit({error,ssl_passive})
- end,
- LS2 = ok(ssl:listen(0, [{active,0}])),
- receive
- {ssl_passive,LS2} ->
- [{active,false}] = ok(ssl:getopts(LS2, [active]))
- after
- 1000 ->
- exit({error,ssl_passive})
- end,
- ok = ssl:close(LS2),
- ok = ssl:close(C),
- ok = ssl:close(S),
- ok = ssl:close(LS),
- ok.
-
-active_n_common(S, N) ->
- ok = ssl:setopts(S, [{active,-N}]),
- receive
- {ssl_passive, S} -> ok
- after
- 1000 ->
- error({error,ssl_passive_failure})
- end,
- [{active,false}] = ok(ssl:getopts(S, [active])),
- ok = ssl:setopts(S, [{active,0}]),
- receive
- {ssl_passive, S} -> ok
- after
- 1000 ->
- error({error,ssl_passive_failure})
- end,
- ok = ssl:setopts(S, [{active,32767}]),
- {error,{options,_}} = ssl:setopts(S, [{active,1}]),
- {error,{options,_}} = ssl:setopts(S, [{active,-32769}]),
- ok = ssl:setopts(S, [{active,-32768}]),
- receive
- {ssl_passive, S} -> ok
- after
- 1000 ->
- error({error,ssl_passive_failure})
- end,
- [{active,false}] = ok(ssl:getopts(S, [active])),
- ok = ssl:setopts(S, [{active,N}]),
- ok = ssl:setopts(S, [{active,true}]),
- [{active,true}] = ok(ssl:getopts(S, [active])),
- receive
- _ -> error({error,active_n})
- after
- 0 ->
- ok
- end,
- ok = ssl:setopts(S, [{active,N}]),
- ok = ssl:setopts(S, [{active,once}]),
- [{active,once}] = ok(ssl:getopts(S, [active])),
- receive
- _ -> error({error,active_n})
- after
- 0 ->
- ok
- end,
- {error,{options,_}} = ssl:setopts(S, [{active,32768}]),
- ok = ssl:setopts(S, [{active,false}]),
- [{active,false}] = ok(ssl:getopts(S, [active])),
- ok.
-
-ok({ok,V}) -> V.
-
-repeat(N, Fun) ->
- repeat(N, N, Fun).
-
-repeat(N, T, Fun) when is_integer(N), N > 0 ->
- Fun(T-N),
- repeat(N-1, T, Fun);
-repeat(_, _, _) ->
- ok.
-
-%%--------------------------------------------------------------------
-dh_params() ->
- [{doc,"Test to specify DH-params file in server."}].
-
-dh_params(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- DataDir = proplists:get_value(data_dir, Config),
- DHParamFile = filename:join(DataDir, "dHParam.pem"),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{dhfile, DHParamFile} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options,
- [{ciphers,[{dhe_rsa,aes_256_cbc,sha}]} |
- ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_upgrade() ->
- [{doc,"Test that you can upgrade an tcp connection to an ssl connection"}].
-
-tls_upgrade(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TcpOpts = [binary, {reuseaddr, true}],
-
- Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- upgrade_result, []}},
- {tcp_options,
- [{active, false} | TcpOpts]},
- {ssl_options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
- {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, upgrade_result, []}},
- {tcp_options, [binary]},
- {ssl_options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-upgrade_result(Socket) ->
- ssl:setopts(Socket, [{active, true}]),
- ok = ssl:send(Socket, "Hello world"),
- %% Make sure binary is inherited from tcp socket and that we do
- %% not get the list default!
- receive
- {ssl, _, <<"H">>} ->
- receive
- {ssl, _, <<"ello world">>} ->
- ok
- end;
- {ssl, _, <<"Hello world">>} ->
- ok
- end.
-
-
-%%--------------------------------------------------------------------
-internal_active_1() ->
- [{doc,"Test internal active 1 (behave as internal active once)"}].
-
-internal_active_1(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{active, true} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{active, true} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_upgrade_with_timeout() ->
- [{doc,"Test ssl_accept/3"}].
-
-tls_upgrade_with_timeout(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TcpOpts = [binary, {reuseaddr, true}],
-
- Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {timeout, 5000},
- {mfa, {?MODULE,
- upgrade_result, []}},
- {tcp_options,
- [{active, false} | TcpOpts]},
- {ssl_options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
- {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, upgrade_result, []}},
- {tcp_options, TcpOpts},
- {ssl_options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_downgrade() ->
- [{doc,"Test that you can downgarde an ssl connection to an tcp connection"}].
-tls_downgrade(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, tls_downgrade_result, [self()]}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, tls_downgrade_result, [self()]}},
- {options, [{active, false} |ClientOpts]}]),
-
-
- ssl_test_lib:check_result(Server, ready, Client, ready),
-
- Server ! go,
- Client ! go,
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-close_with_timeout() ->
- [{doc,"Test normal (not downgrade) ssl:close/2"}].
-close_with_timeout(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, tls_close, []}},
- {options,[{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, tls_close, []}},
- {options, [{active, false} |ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok).
-
-
-%%--------------------------------------------------------------------
-tls_tcp_connect() ->
- [{doc,"Test what happens when a tcp tries to connect, i,e. a bad (ssl) packet is sent first"}].
-
-tls_tcp_connect(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TcpOpts = [binary, {reuseaddr, true}, {active, false}],
-
- Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {timeout, 5000},
- {mfa, {?MODULE, dummy, []}},
- {tcp_options, TcpOpts},
- {ssl_options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
- ct:log("Testcase ~p connected to Server ~p ~n", [self(), Server]),
- gen_tcp:send(Socket, "<SOME GARBLED NON SSL MESSAGE>"),
-
- receive
- {tcp_closed, Socket} ->
- receive
- {Server, {error, Error}} ->
- ct:log("Error ~p", [Error])
- end
- end.
-%%--------------------------------------------------------------------
-tls_tcp_connect_big() ->
- [{doc,"Test what happens when a tcp tries to connect, i,e. a bad big (ssl) packet is sent first"}].
-
-tls_tcp_connect_big(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TcpOpts = [binary, {reuseaddr, true}],
-
- Rand = crypto:strong_rand_bytes(?MAX_CIPHER_TEXT_LENGTH+1),
- Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {timeout, 5000},
- {mfa, {?MODULE, dummy, []}},
- {tcp_options, TcpOpts},
- {ssl_options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
- ct:log("Testcase ~p connected to Server ~p ~n", [self(), Server]),
-
- gen_tcp:send(Socket, <<?BYTE(0),
- ?BYTE(3), ?BYTE(1), ?UINT16(?MAX_CIPHER_TEXT_LENGTH), Rand/binary>>),
-
- receive
- {tcp_closed, Socket} ->
- receive
- {Server, {error, timeout}} ->
- ct:fail("hangs");
- {Server, {error, Error}} ->
- ct:log("Error ~p", [Error]);
- {'EXIT', Server, _} ->
- ok
- end
- end.
-
-%%--------------------------------------------------------------------
-ipv6() ->
- [{require, ipv6_hosts},
- {doc,"Test ipv6."}].
-ipv6(Config) when is_list(Config) ->
- {ok, Hostname0} = inet:gethostname(),
-
- case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
- true ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} =
- ssl_test_lib:run_where(Config, ipv6),
- Server = ssl_test_lib:start_server([{node, ServerNode},
- {port, 0}, {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options,
- [inet6, {active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options,
- [inet6, {active, false} | ClientOpts]}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client);
- false ->
- {skip, "Host does not support IPv6"}
- end.
-
-%%--------------------------------------------------------------------
-
-invalid_keyfile() ->
- [{doc,"Test what happens with an invalid key file"}].
-invalid_keyfile(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- BadOpts = ssl_test_lib:ssl_options(server_bad_key, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, BadOpts}]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- Client =
- ssl_test_lib:start_client_error([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {from, self()}, {options, ClientOpts}]),
+ {from, self()},
+ {mfa, {?MODULE, protocol_info_result, []}},
+ {options, ClientOpts}]),
- File = proplists:get_value(keyfile,BadOpts),
- ssl_test_lib:check_result(Server, {error,{options, {keyfile, File, {error,enoent}}}}, Client,
- {error, closed}).
+ ServerMsg = ClientMsg = {ok,'tlsv1.2'},
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
%%--------------------------------------------------------------------
+unordered_protocol_versions_client() ->
+ [{doc,"Test that the highest protocol is selected even"
+ " when it is not first in the versions list."}].
-invalid_certfile() ->
- [{doc,"Test what happens with an invalid cert file"}].
-
-invalid_certfile(Config) when is_list(Config) ->
+unordered_protocol_versions_client(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerBadOpts = ssl_test_lib:ssl_options(server_bad_cert, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ServerBadOpts}]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- Client =
- ssl_test_lib:start_client_error([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {from, self()},
- {options, ClientOpts}]),
- File = proplists:get_value(certfile, ServerBadOpts),
- ssl_test_lib:check_result(Server, {error,{options, {certfile, File, {error,enoent}}}},
- Client, {error, closed}).
-
-
-%%--------------------------------------------------------------------
-invalid_cacertfile() ->
- [{doc,"Test what happens with an invalid cacert file"}].
-
-invalid_cacertfile(Config) when is_list(Config) ->
- ClientOpts = [{reuseaddr, true}|ssl_test_lib:ssl_options(client_opts, Config)],
- ServerBadOpts = [{reuseaddr, true}|ssl_test_lib:ssl_options(server_bad_ca, Config)],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server0 =
- ssl_test_lib:start_server_error([{node, ServerNode},
- {port, 0}, {from, self()},
- {options, ServerBadOpts}]),
-
- Port0 = ssl_test_lib:inet_port(Server0),
-
-
- Client0 =
- ssl_test_lib:start_client_error([{node, ClientNode},
- {port, Port0}, {host, Hostname},
- {from, self()},
- {options, ClientOpts}]),
-
- File0 = proplists:get_value(cacertfile, ServerBadOpts),
-
- ssl_test_lib:check_result(Server0, {error, {options, {cacertfile, File0,{error,enoent}}}},
- Client0, {error, closed}),
-
- File = File0 ++ "do_not_exit.pem",
- ServerBadOpts1 = [{cacertfile, File}|proplists:delete(cacertfile, ServerBadOpts)],
-
- Server1 =
- ssl_test_lib:start_server_error([{node, ServerNode},
- {port, 0}, {from, self()},
- {options, ServerBadOpts1}]),
-
- Port1 = ssl_test_lib:inet_port(Server1),
-
- Client1 =
- ssl_test_lib:start_client_error([{node, ClientNode},
- {port, Port1}, {host, Hostname},
- {from, self()},
- {options, ClientOpts}]),
-
-
- ssl_test_lib:check_result(Server1, {error, {options, {cacertfile, File,{error,enoent}}}},
- Client1, {error, closed}),
- ok.
-
-
-
-%%--------------------------------------------------------------------
-invalid_options() ->
- [{doc,"Test what happens when we give invalid options"}].
-
-invalid_options(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Check = fun(Client, Server, {versions, [sslv2, sslv3]} = Option) ->
- ssl_test_lib:check_result(Server,
- {error, {options, {sslv2, Option}}},
- Client,
- {error, {options, {sslv2, Option}}});
- (Client, Server, Option) ->
- ssl_test_lib:check_result(Server,
- {error, {options, Option}},
- Client,
- {error, {options, Option}})
- end,
-
- TestOpts =
- [{versions, [sslv2, sslv3]},
- {verify, 4},
- {verify_fun, function},
- {fail_if_no_peer_cert, 0},
- {verify_client_once, 1},
- {depth, four},
- {certfile, 'cert.pem'},
- {keyfile,'key.pem' },
- {password, foo},
- {cacertfile, ""},
- {dhfile,'dh.pem' },
- {ciphers, [{foo, bar, sha, ignore}]},
- {reuse_session, foo},
- {reuse_sessions, 0},
- {renegotiate_at, "10"},
- {mode, depech},
- {packet, 8.0},
- {packet_size, "2"},
- {header, a},
- {active, trice},
- {key, 'key.pem' }],
-
- [begin
- Server =
- ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, [TestOpt | ServerOpts]}]),
- %% Will never reach a point where port is used.
- Client =
- ssl_test_lib:start_client_error([{node, ClientNode}, {port, 0},
- {host, Hostname}, {from, self()},
- {options, [TestOpt | ClientOpts]}]),
- Check(Client, Server, TestOpt),
- ok
- end || TestOpt <- TestOpts],
- ok.
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-%%--------------------------------------------------------------------
-tls_shutdown() ->
- [{doc,"Test API function ssl:shutdown/2"}].
-tls_shutdown(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, tls_shutdown_result, [server]}},
- {options, [{exit_on_close, false},
- {active, false} | ServerOpts]}]),
+ {mfa, {?MODULE, protocol_info_result, []}},
+ {options, ServerOpts }]),
Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa,
- {?MODULE, tls_shutdown_result, [client]}},
- {options,
- [{exit_on_close, false},
- {active, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_shutdown_write() ->
- [{doc,"Test API function ssl:shutdown/2 with option write."}].
-tls_shutdown_write(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, tls_shutdown_write_result, [server]}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
- {from, self()},
- {mfa, {?MODULE, tls_shutdown_write_result, [client]}},
- {options, [{active, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
-
-%%--------------------------------------------------------------------
-tls_shutdown_both() ->
- [{doc,"Test API function ssl:shutdown/2 with option both."}].
-tls_shutdown_both(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, tls_shutdown_both_result, [server]}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, tls_shutdown_both_result, [client]}},
- {options, [{active, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
-
-%%--------------------------------------------------------------------
-tls_shutdown_error() ->
- [{doc,"Test ssl:shutdown/2 error handling"}].
-tls_shutdown_error(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- Port = ssl_test_lib:inet_port(node()),
- {ok, Listen} = ssl:listen(Port, ServerOpts),
- {error, enotconn} = ssl:shutdown(Listen, read_write),
- ok = ssl:close(Listen),
- {error, closed} = ssl:shutdown(Listen, read_write).
-
-%%--------------------------------------------------------------------
-default_reject_anonymous()->
- [{doc,"Test that by default anonymous cipher suites are rejected "}].
-default_reject_anonymous(Config) when is_list(Config) ->
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- Version = ssl_test_lib:protocol_version(Config),
- TLSVersion = ssl_test_lib:tls_version(Version),
-
- [CipherSuite | _] = ssl_test_lib:ecdh_dh_anonymous_suites(TLSVersion),
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options,
- [{ciphers,[CipherSuite]} |
- ClientOpts]}]),
-
- ssl_test_lib:check_server_alert(Server, Client, insufficient_security).
-
-%%--------------------------------------------------------------------
-reuse_session() ->
- [{doc,"Test reuse of sessions (short handshake)"}].
-reuse_session(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
-%%--------------------------------------------------------------------
-reuse_session_expired() ->
- [{doc,"Test sessions is not reused when it has expired"}].
-reuse_session_expired(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server0 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {tcp_options, [{active, false}]},
- {options, ServerOpts}]),
- Port0 = ssl_test_lib:inet_port(Server0),
-
- Client0 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port0}, {host, Hostname},
- {mfa, {ssl_test_lib, session_id, []}},
- {from, self()}, {options, [{reuse_sessions, save} | ClientOpts]}]),
- Server0 ! listen,
-
- Client1 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port0}, {host, Hostname},
- {mfa, {ssl_test_lib, session_id, []}},
- {from, self()}, {options, ClientOpts}]),
-
- SID = receive
- {Client0, Id0} ->
- Id0
- end,
-
- receive
- {Client1, SID} ->
- ok
- after ?SLEEP ->
- ct:fail(session_not_reused)
- end,
-
- Server0 ! listen,
-
- %% Make sure session is unregistered due to expiration
- ct:sleep((?EXPIRE*2)),
-
- make_sure_expired(Hostname, Port0, SID),
-
- Client2 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port0}, {host, Hostname},
- {mfa, {ssl_test_lib, session_id, []}},
- {from, self()}, {options, ClientOpts}]),
- receive
- {Client2, SID} ->
- ct:fail(session_reused_when_session_expired);
- {Client2, _} ->
- ok
- end,
- process_flag(trap_exit, false),
- ssl_test_lib:close(Server0),
- ssl_test_lib:close(Client0),
- ssl_test_lib:close(Client1),
- ssl_test_lib:close(Client2).
-
-make_sure_expired(Host, Port, Id) ->
- {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
- [_, _,_, _, Prop] = StatusInfo,
- State = ssl_test_lib:state(Prop),
- ClientCache = element(2, State),
-
- case ssl_session_cache:lookup(ClientCache, {{Host, Port}, Id}) of
- undefined ->
- ok;
- #session{is_resumable = false} ->
- ok;
- _ ->
- ct:sleep(?SLEEP),
- make_sure_expired(Host, Port, Id)
- end.
-
-%%--------------------------------------------------------------------
-server_does_not_want_to_reuse_session() ->
- [{doc,"Test reuse of sessions (short handshake)"}].
-server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, session_info_result, []}},
- {options, [{reuse_session, fun(_,_,_,_) ->
- false
- end} |
- ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client0 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
- SessionInfo =
- receive
- {Server, Info} ->
- Info
- end,
-
- Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
-
- %% Make sure session is registered
- ct:sleep(?SLEEP),
- ssl_test_lib:close(Client0),
-
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, session_info_result, []}},
- {from, self()}, {options, ClientOpts}]),
- receive
- {Client1, SessionInfo} ->
- ct:fail(session_reused_when_server_does_not_want_to);
- {Client1, _Other} ->
- ok
- end,
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-client_renegotiate() ->
- [{doc,"Test ssl:renegotiate/1 on client."}].
-client_renegotiate(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate, [Data]}},
- {options, [{reuse_sessions, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-client_secure_renegotiate() ->
- [{doc,"Test ssl:renegotiate/1 on client."}].
-client_secure_renegotiate(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{secure_renegotiate, true} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate, [Data]}},
- {options, [{reuse_sessions, false},
- {secure_renegotiate, true}| ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-client_secure_renegotiate_fallback() ->
- [{doc,"Test that we can set secure_renegotiate to false that is "
- "fallback option, we however do not have a insecure server to test against!"}].
-client_secure_renegotiate_fallback(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{secure_renegotiate, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
+ {mfa, {?MODULE, protocol_info_result, []}},
+ {options, [{versions, ['tlsv1.1', 'tlsv1.2']} | ClientOpts]}]),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate, [Data]}},
- {options, [{reuse_sessions, false},
- {secure_renegotiate, false}| ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
+ ServerMsg = ClientMsg = {ok, 'tlsv1.2'},
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
+
+connect_dist() ->
+ [{doc,"Test a simple connect as is used by distribution"}].
-%%--------------------------------------------------------------------
-server_renegotiate() ->
- [{doc,"Test ssl:renegotiate/1 on server."}].
-server_renegotiate(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+connect_dist(Config) when is_list(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_kc_opts, Config),
+ ClientOpts = [{ssl_imp, new},{active, false}, {packet,4}|ClientOpts0],
+ ServerOpts0 = ssl_test_lib:ssl_options(server_kc_opts, Config),
+ ServerOpts = [{ssl_imp, new},{active, false}, {packet,4}|ServerOpts0],
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Data = "From erlang to erlang",
-
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE,
- renegotiate, [Data]}},
+ {mfa, {?MODULE, connect_dist_s, []}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{reuse_sessions, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-client_renegotiate_reused_session() ->
- [{doc,"Test ssl:renegotiate/1 on client when the ssl session will be reused."}].
-client_renegotiate_reused_session(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate_reuse_session, [Data]}},
- {options, [{reuse_sessions, true} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-%%--------------------------------------------------------------------
-server_renegotiate_reused_session() ->
- [{doc,"Test ssl:renegotiate/1 on server when the ssl session will be reused."}].
-server_renegotiate_reused_session(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate_reuse_session, [Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{reuse_sessions, true} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-%%--------------------------------------------------------------------
-client_no_wrap_sequence_number() ->
- [{doc,"Test that erlang client will renegotiate session when",
- "max sequence number celing is about to be reached. Although"
- "in the testcase we use the test option renegotiate_at"
- " to lower treashold substantially."}].
-
-client_no_wrap_sequence_number(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- ErlData = "From erlang to erlang",
- N = 12,
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Version = ssl_test_lib:protocol_version(Config, tuple),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- trigger_renegotiate, [[ErlData, treashold(N, Version)]]}},
- {options, [{reuse_sessions, false},
- {renegotiate_at, N} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-server_no_wrap_sequence_number() ->
- [{doc, "Test that erlang server will renegotiate session when",
- "max sequence number celing is about to be reached. Although"
- "in the testcase we use the test option renegotiate_at"
- " to lower treashold substantially."}].
-
-server_no_wrap_sequence_number(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
- N = 12,
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- trigger_renegotiate, [[Data, N+2]]}},
- {options, [{renegotiate_at, N} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{reuse_sessions, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-der_input() ->
- [{doc,"Test to input certs and key as der"}].
-
-der_input(Config) when is_list(Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- DHParamFile = filename:join(DataDir, "dHParam.pem"),
-
- {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
- [_, _,_, _, Prop] = StatusInfo,
- State = ssl_test_lib:state(Prop),
- [CADb | _] = element(6, State),
-
- Size = ets:info(CADb, size),
-
- SeverVerifyOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ServerCert, ServerKey, ServerCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
- SeverVerifyOpts]),
- ClientVerifyOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- {ClientCert, ClientKey, ClientCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
- ClientVerifyOpts]),
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true},
- {dh, DHParams},
- {cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCaCerts}],
- ClientOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true},
- {dh, DHParams},
- {cert, ClientCert}, {key, ClientKey}, {cacerts, ClientCaCerts}],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- Size = ets:info(CADb, size).
-
-%%--------------------------------------------------------------------
-der_input_opts(Opts) ->
- Certfile = proplists:get_value(certfile, Opts),
- CaCertsfile = proplists:get_value(cacertfile, Opts),
- Keyfile = proplists:get_value(keyfile, Opts),
- Dhfile = proplists:get_value(dhfile, Opts),
- [{_, Cert, _}] = ssl_test_lib:pem_to_der(Certfile),
- [{Asn1Type, Key, _}] = ssl_test_lib:pem_to_der(Keyfile),
- [{_, DHParams, _}] = ssl_test_lib:pem_to_der(Dhfile),
- CaCerts =
- lists:map(fun(Entry) ->
- {_, CaCert, _} = Entry,
- CaCert
- end, ssl_test_lib:pem_to_der(CaCertsfile)),
- {Cert, {Asn1Type, Key}, CaCerts, DHParams}.
-
-%%--------------------------------------------------------------------
-no_reuses_session_server_restart_new_cert() ->
- [{doc,"Check that a session is not reused if the server is restarted with a new cert."}].
-no_reuses_session_server_restart_new_cert(Config) when is_list(Config) ->
-
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- DsaServerOpts = ssl_test_lib:ssl_options(server_dsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, session_info_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client0 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
- SessionInfo =
- receive
- {Server, Info} ->
- Info
- end,
-
- %% Make sure session is registered
- ct:sleep(?SLEEP),
- Monitor = erlang:monitor(process, Server),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client0),
- receive
- {'DOWN', Monitor, _, _, _} ->
- ok
- end,
-
- Server1 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{reuseaddr, true} | DsaServerOpts]}]),
-
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, session_info_result, []}},
- {from, self()}, {options, ClientOpts}]),
- receive
- {Client1, SessionInfo} ->
- ct:fail(session_reused_when_server_has_new_cert);
- {Client1, _Other} ->
- ok
- end,
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-no_reuses_session_server_restart_new_cert_file() ->
- [{doc,"Check that a session is not reused if a server is restarted with a new "
- "cert contained in a file with the same name as the old cert."}].
-
-no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- DsaServerOpts = ssl_test_lib:ssl_options(server_dsa_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
-
- NewServerOpts0 = new_config(PrivDir, ServerOpts),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, session_info_result, []}},
- {options, NewServerOpts0}]),
- Port = ssl_test_lib:inet_port(Server),
- Client0 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
- SessionInfo =
- receive
- {Server, Info} ->
- Info
- end,
-
- %% Make sure session is registered and we get
- %% new file time stamp when calling new_config!
- ct:sleep(?SLEEP* 2),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client0),
-
- ssl:clear_pem_cache(),
-
- NewServerOpts1 = new_config(PrivDir, DsaServerOpts),
-
- Server1 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{reuseaddr, true} | NewServerOpts1]}]),
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, session_info_result, []}},
- {from, self()}, {options, ClientOpts}]),
- receive
- {Client1, SessionInfo} ->
- ct:fail(session_reused_when_server_has_new_cert);
- {Client1, _Other} ->
- ok
- end,
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-defaults(Config) when is_list(Config)->
- Versions = ssl:versions(),
- true = lists:member(sslv3, proplists:get_value(available, Versions)),
- false = lists:member(sslv3, proplists:get_value(supported, Versions)),
- true = lists:member('tlsv1', proplists:get_value(available, Versions)),
- false = lists:member('tlsv1', proplists:get_value(supported, Versions)),
- true = lists:member('tlsv1.1', proplists:get_value(available, Versions)),
- false = lists:member('tlsv1.1', proplists:get_value(supported, Versions)),
- true = lists:member('tlsv1.2', proplists:get_value(available, Versions)),
- true = lists:member('tlsv1.2', proplists:get_value(supported, Versions)),
- false = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites()),
- true = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites(all)),
- false = lists:member({rsa,des_cbc,sha}, ssl:cipher_suites()),
- true = lists:member({rsa,des_cbc,sha}, ssl:cipher_suites(all)),
- false = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites()),
- true = lists:member({dhe_rsa,des_cbc,sha}, ssl:cipher_suites(all)),
- true = lists:member('dtlsv1.2', proplists:get_value(available_dtls, Versions)),
- true = lists:member('dtlsv1', proplists:get_value(available_dtls, Versions)),
- true = lists:member('dtlsv1.2', proplists:get_value(supported_dtls, Versions)),
- false = lists:member('dtlsv1', proplists:get_value(supported_dtls, Versions)).
-
-%%--------------------------------------------------------------------
-reuseaddr() ->
- [{doc,"Test reuseaddr option"}].
-
-reuseaddr(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, false} | ClientOpts]}]),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
-
- Server1 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server1, ok, Client1, ok),
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-tls_tcp_reuseaddr() ->
- [{doc, "Reference test case."}].
-tls_tcp_reuseaddr(Config) when is_list(Config) ->
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {transport, gen_tcp},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, false}, {reuseaddr, true}]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {transport, gen_tcp},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, false}]}]),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
-
- Server1 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
- {from, self()},
- {transport, gen_tcp},
- {mfa, {?MODULE, tcp_send_recv_result, []}},
- {options, [{active, false}, {reuseaddr, true}]}]),
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {transport, gen_tcp},
- {mfa, {?MODULE, tcp_send_recv_result, []}},
- {options, [{active, false}]}]),
-
- ssl_test_lib:check_result(Server1, ok, Client1, ok),
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-
-honor_server_cipher_order() ->
- [{doc,"Test API honor server cipher order."}].
-honor_server_cipher_order(Config) when is_list(Config) ->
- ClientCiphers = [#{key_exchange => dhe_rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf},
- #{key_exchange => dhe_rsa,
- cipher => aes_256_cbc,
- mac => sha,
- prf => default_prf}],
- ServerCiphers = [#{key_exchange => dhe_rsa,
- cipher => aes_256_cbc,
- mac =>sha,
- prf => default_prf},
- #{key_exchange => dhe_rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf}],
- honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
- cipher => aes_256_cbc,
- mac => sha,
- prf => default_prf}).
-
-honor_client_cipher_order() ->
- [{doc,"Test API honor server cipher order."}].
-honor_client_cipher_order(Config) when is_list(Config) ->
- ClientCiphers = [#{key_exchange => dhe_rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf},
- #{key_exchange => dhe_rsa,
- cipher => aes_256_cbc,
- mac => sha,
- prf => default_prf}],
- ServerCiphers = [#{key_exchange => dhe_rsa,
- cipher => aes_256_cbc,
- mac =>sha,
- prf => default_prf},
- #{key_exchange => dhe_rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf}],
-honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf}).
-
-honor_cipher_order(Config, Honor, ServerCiphers, ClientCiphers, Expected) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, connection_info_result, []}},
- {options, [{ciphers, ServerCiphers}, {honor_cipher_order, Honor}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, connection_info_result, []}},
- {options, [{ciphers, ClientCiphers}, {honor_cipher_order, Honor}
- | ClientOpts]}]),
-
- Version = ssl_test_lib:protocol_version(Config),
-
- ServerMsg = ClientMsg = {ok, {Version, Expected}},
-
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_ciphersuite_vs_version() ->
- [{doc,"Test a SSLv3 client cannot negotiate a TLSv* cipher suite."}].
-tls_ciphersuite_vs_version(Config) when is_list(Config) ->
-
- {_ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {active, false}]),
- ok = gen_tcp:send(Socket,
- <<22, 3,0, 49:16, % handshake, SSL 3.0, length
- 1, 45:24, % client_hello, length
- 3,0, % SSL 3.0
- 16#deadbeef:256, % 32 'random' bytes = 256 bits
- 0, % no session ID
- %% three cipher suites -- null, one with sha256 hash and one with sha hash
- 6:16, 0,255, 0,61, 0,57,
- 1, 0 % no compression
- >>),
- {ok, <<22, RecMajor:8, RecMinor:8, _RecLen:16, 2, HelloLen:24>>} = gen_tcp:recv(Socket, 9, 10000),
- {ok, <<HelloBin:HelloLen/binary>>} = gen_tcp:recv(Socket, HelloLen, 5000),
- ServerHello = tls_handshake:decode_handshake({RecMajor, RecMinor}, 2, HelloBin),
- case ServerHello of
- #server_hello{server_version = {3,0}, cipher_suite = <<0,57>>} ->
- ok;
- _ ->
- ct:fail({unexpected_server_hello, ServerHello})
- end.
-
-%%--------------------------------------------------------------------
-conf_signature_algs() ->
- [{doc,"Test to set the signature_algs option on both client and server"}].
-conf_signature_algs(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false}, {signature_algs, [{sha, rsa}]} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false}, {signature_algs, [{sha, rsa}]} | ClientOpts]}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-%%--------------------------------------------------------------------
-no_common_signature_algs() ->
- [{doc,"Set the signature_algs option so that there client and server does not share any hash sign algorithms"}].
-no_common_signature_algs(Config) when is_list(Config) ->
-
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, [{signature_algs, [{sha256, rsa}]}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, [{signature_algs, [{sha384, rsa}]}
- | ClientOpts]}]),
-
- ssl_test_lib:check_server_alert(Server, Client, insufficient_security).
-
-%%--------------------------------------------------------------------
-
-tls_dont_crash_on_handshake_garbage() ->
- [{doc, "Ensure SSL server worker thows an alert on garbage during handshake "
- "instead of crashing and exposing state to user code"}].
-
-tls_dont_crash_on_handshake_garbage(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {_ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- unlink(Server), monitor(process, Server),
- Port = ssl_test_lib:inet_port(Server),
-
- {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {active, false}]),
-
- % Send hello and garbage record
- ok = gen_tcp:send(Socket,
- [<<22, 3,3, 49:16, 1, 45:24, 3,3, % client_hello
- 16#deadbeef:256, % 32 'random' bytes = 256 bits
- 0, 6:16, 0,255, 0,61, 0,57, 1, 0 >>, % some hello values
-
- <<22, 3,3, 5:16, 92,64,37,228,209>> % garbage
- ]),
- % Send unexpected change_cipher_spec
- ok = gen_tcp:send(Socket, <<20, 3,3, 12:16, 111,40,244,7,137,224,16,109,197,110,249,152>>),
-
- % Ensure we receive an alert, not sudden disconnect
- {ok, <<21, _/binary>>} = drop_handshakes(Socket, 1000).
-
-drop_handshakes(Socket, Timeout) ->
- {ok, <<RecType:8, _RecMajor:8, _RecMinor:8, RecLen:16>> = Header} = gen_tcp:recv(Socket, 5, Timeout),
- {ok, <<Frag:RecLen/binary>>} = gen_tcp:recv(Socket, RecLen, Timeout),
- case RecType of
- 22 -> drop_handshakes(Socket, Timeout);
- _ -> {ok, <<Header/binary, Frag/binary>>}
- end.
-
-
-%%--------------------------------------------------------------------
-
-hibernate() ->
- [{doc,"Check that an SSL connection that is started with option "
- "{hibernate_after, 1000} indeed hibernates after 1000ms of "
- "inactivity"}].
-
-hibernate(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- {Client, #sslsocket{pid=[Pid|_]}} = ssl_test_lib:start_client([return_socket,
- {node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{hibernate_after, 1000}|ClientOpts]}]),
- {current_function, _} =
- process_info(Pid, current_function),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ct:sleep(1500),
- {current_function, {erlang, hibernate, 3}} =
- process_info(Pid, current_function),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
-hibernate_right_away() ->
- [{doc,"Check that an SSL connection that is configured to hibernate "
- "after 0 or 1 milliseconds hibernates as soon as possible and not "
- "crashes"}].
-
-hibernate_right_away(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- StartServerOpts = [{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}],
- StartClientOpts = [return_socket,
- {node, ClientNode},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}}],
-
- Server1 = ssl_test_lib:start_server(StartServerOpts),
- Port1 = ssl_test_lib:inet_port(Server1),
- {Client1, #sslsocket{pid = [Pid1|_]}} = ssl_test_lib:start_client(StartClientOpts ++
- [{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]),
-
- ssl_test_lib:check_result(Server1, ok, Client1, ok),
-
- ct:sleep(1000), %% Schedule out
-
- {current_function, {erlang, hibernate, 3}} =
- process_info(Pid1, current_function),
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client1),
-
- Server2 = ssl_test_lib:start_server(StartServerOpts),
- Port2 = ssl_test_lib:inet_port(Server2),
- {Client2, #sslsocket{pid = [Pid2|_]}} = ssl_test_lib:start_client(StartClientOpts ++
- [{port, Port2}, {options, [{hibernate_after, 1}|ClientOpts]}]),
-
- ssl_test_lib:check_result(Server2, ok, Client2, ok),
-
- ct:sleep(1000), %% Schedule out
-
- {current_function, {erlang, hibernate, 3}} =
- process_info(Pid2, current_function),
-
- ssl_test_lib:close(Server2),
- ssl_test_lib:close(Client2).
-
-%%--------------------------------------------------------------------
-listen_socket() ->
- [{doc,"Check error handling and inet compliance when calling API functions with listen sockets."}].
-
-listen_socket(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {ok, ListenSocket} = ssl:listen(0, ServerOpts),
-
- %% This can be a valid thing to do as
- %% options are inherited by the accept socket
- ok = ssl:controlling_process(ListenSocket, self()),
-
- {ok, _} = ssl:sockname(ListenSocket),
-
- {error, enotconn} = ssl:send(ListenSocket, <<"data">>),
- {error, enotconn} = ssl:recv(ListenSocket, 0),
- {error, enotconn} = ssl:connection_information(ListenSocket),
- {error, enotconn} = ssl:peername(ListenSocket),
- {error, enotconn} = ssl:peercert(ListenSocket),
- {error, enotconn} = ssl:renegotiate(ListenSocket),
- {error, enotconn} = ssl:prf(ListenSocket, 'master_secret', <<"Label">>, [client_random], 256),
- {error, enotconn} = ssl:shutdown(ListenSocket, read_write),
-
- ok = ssl:close(ListenSocket).
-%%--------------------------------------------------------------------
-tls_ssl_accept_timeout() ->
- [{doc,"Test ssl:ssl_accept timeout"}].
-
-tls_ssl_accept_timeout(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {timeout, 5000},
- {mfa, {ssl_test_lib,
- no_result_msg, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- {ok, CSocket} = gen_tcp:connect(Hostname, Port, [binary, {active, true}]),
-
- receive
- {tcp_closed, CSocket} ->
- ssl_test_lib:check_result(Server, {error, timeout}),
- receive
- {'EXIT', Server, _} ->
- %% Make sure supervisor had time to react on process exit
- %% Could we come up with a better solution to this?
- ct:sleep(500),
- [] = supervisor:which_children(tls_connection_sup)
- end
- end.
-
-%%--------------------------------------------------------------------
-ssl_recv_timeout() ->
- [{doc,"Test ssl:ssl_accept timeout"}].
-
-ssl_recv_timeout(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, send_recv_result_timeout_server, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- send_recv_result_timeout_client, []}},
- {options, [{active, false} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-connect_twice() ->
- [{doc,""}].
-connect_twice(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{keepalive, true},{active, false}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{keepalive, true},{active, false}
- | ClientOpts]}]),
- Server ! listen,
-
- {Client1, #sslsocket{}} =
- ssl_test_lib:start_client([return_socket,
- {node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{keepalive, true},{active, false}
- | ClientOpts]}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:check_result(Server, ok, Client1, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-renegotiate_dos_mitigate_active() ->
- [{doc, "Mitigate DOS computational attack by not allowing client to renegotiate many times in a row",
- "immediately after each other"}].
-renegotiate_dos_mitigate_active(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate_immediately, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-renegotiate_dos_mitigate_passive() ->
- [{doc, "Mitigate DOS computational attack by not allowing client to renegotiate many times in a row",
- "immediately after each other"}].
-renegotiate_dos_mitigate_passive(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
{from, self()},
- {mfa, {?MODULE,
- renegotiate_immediately, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-renegotiate_dos_mitigate_absolute() ->
- [{doc, "Mitigate DOS computational attack by not allowing client to initiate renegotiation"}].
-renegotiate_dos_mitigate_absolute(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{client_renegotiation, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- renegotiate_rejected,
- []}},
+ {mfa, {?MODULE, connect_dist_c, []}},
{options, ClientOpts}]),
-
- ssl_test_lib:check_result(Client, ok, Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-tls_tcp_error_propagation_in_active_mode() ->
- [{doc,"Test that process recives {ssl_error, Socket, closed} when tcp error ocurres"}].
-tls_tcp_error_propagation_in_active_mode(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- {Client, #sslsocket{pid=[Pid|_]} = SslSocket} = ssl_test_lib:start_client([return_socket,
- {node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, receive_msg, []}},
- {options, ClientOpts}]),
-
- {status, _, _, StatusInfo} = sys:get_status(Pid),
- [_, _,_, _, Prop] = StatusInfo,
- State = ssl_test_lib:state(Prop),
- StaticEnv = element(2, State),
- Socket = element(11, StaticEnv),
- %% Fake tcp error
- Pid ! {tcp_error, Socket, etimedout},
-
- ssl_test_lib:check_result(Client, {ssl_closed, SslSocket}).
-
-%%--------------------------------------------------------------------
-recv_error_handling() ->
- [{doc,"Special case of call error handling"}].
-recv_error_handling(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, recv_close, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- {_Client, #sslsocket{} = SslSocket} = ssl_test_lib:start_client([return_socket,
- {node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
- ssl:close(SslSocket),
- ssl_test_lib:check_result(Server, ok).
-
-
-
-%%--------------------------------------------------------------------
-call_in_error_state() ->
- [{doc,"Special case of call error handling"}].
-call_in_error_state(Config) when is_list(Config) ->
- ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
- Pid = spawn_link(?MODULE, run_error_server, [[self() | ServerOpts]]),
- receive
- {Pid, Port} ->
- spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
- end,
- receive
- {error, closed} ->
- ok;
- Other ->
- ct:fail(Other)
- end.
-
-run_client_error([Port, Opts]) ->
- ssl:connect("localhost", Port, Opts).
-run_error_server([ Pid | Opts]) ->
- {ok, Listen} = ssl:listen(0, Opts),
- {ok,{_, Port}} = ssl:sockname(Listen),
- Pid ! {self(), Port},
- {ok, Socket} = ssl:transport_accept(Listen),
- Pid ! ssl:controlling_process(Socket, self()).
-
-%%--------------------------------------------------------------------
-
-close_in_error_state() ->
- [{doc,"Special case of closing socket in error state"}].
-close_in_error_state(Config) when is_list(Config) ->
- ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
- ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- _ = spawn_link(?MODULE, run_error_server_close, [[self() | ServerOpts]]),
- receive
- {_Pid, Port} ->
- spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
- end,
- receive
- ok ->
- ok;
- Other ->
- ct:fail(Other)
- end.
-%%--------------------------------------------------------------------
-abuse_transport_accept_socket() ->
- [{doc,"Only ssl:handshake and ssl:controlling_process is allowed for transport_accept:sockets"}].
-abuse_transport_accept_socket(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
- Server = ssl_test_lib:start_server_transport_abuse_socket([{node, ServerNode},
- {port, 0},
- {from, self()},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
- ssl_test_lib:check_result(Server, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-
-
-%%--------------------------------------------------------------------
-controlling_process_transport_accept_socket() ->
- [{doc,"Only ssl:handshake and ssl:controlling_process is allowed for transport_accept:sockets"}].
-controlling_process_transport_accept_socket(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server_transport_control([{node, ServerNode},
- {port, 0},
- {from, self()},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- _Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, ClientOpts}]),
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server).
-
-%%--------------------------------------------------------------------
-run_error_server_close([Pid | Opts]) ->
- {ok, Listen} = ssl:listen(0, Opts),
- {ok,{_, Port}} = ssl:sockname(Listen),
- Pid ! {self(), Port},
- {ok, Socket} = ssl:transport_accept(Listen),
- Pid ! ssl:close(Socket).
-
-%%--------------------------------------------------------------------
-
-rizzo() ->
- [{doc, "Test that there is a 1/n-1-split for non RC4 in 'TLS < 1.1' as it is
- vunrable to Rizzo/Dungon attack"}].
-
-rizzo(Config) when is_list(Config) ->
- Prop = proplists:get_value(tc_group_properties, Config),
- Version = proplists:get_value(name, Prop),
- NVersion = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl:filter_cipher_suites(ssl:cipher_suites(all, NVersion),
- [{key_exchange,
- fun(Alg) when Alg == ecdh_rsa; Alg == ecdhe_rsa->
- true;
- (_) ->
- false
- end},
- {cipher,
- fun(rc4_128) ->
- false;
- (chacha20_poly1305) ->
- false;
- (_) ->
- true
- end}]),
-
- run_send_recv_rizzo(Ciphers, Config, Version,
- {?MODULE, send_recv_result_active_rizzo, []}).
-%%--------------------------------------------------------------------
-no_rizzo_rc4() ->
- [{doc,"Test that there is no 1/n-1-split for RC4 as it is not vunrable to Rizzo/Dungon attack"}].
-
-no_rizzo_rc4(Config) when is_list(Config) ->
- Prop = proplists:get_value(tc_group_properties, Config),
- Version = proplists:get_value(name, Prop),
- NVersion = ssl_test_lib:protocol_version(Config, tuple),
- %% Test uses RSA certs
- Ciphers = ssl:filter_cipher_suites(ssl_test_lib:rc4_suites(NVersion),
- [{key_exchange,
- fun(Alg) when Alg == ecdh_rsa; Alg == ecdhe_rsa->
- true;
- (_) ->
- false
- end}]),
- run_send_recv_rizzo(Ciphers, Config, Version,
- {?MODULE, send_recv_result_active_no_rizzo, []}).
-
-rizzo_one_n_minus_one() ->
- [{doc,"Test that the 1/n-1-split mitigation of Rizzo/Dungon attack can be explicitly selected"}].
-
-rizzo_one_n_minus_one(Config) when is_list(Config) ->
- Prop = proplists:get_value(tc_group_properties, Config),
- Version = proplists:get_value(name, Prop),
- NVersion = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl:filter_cipher_suites(ssl:cipher_suites(all, NVersion),
- [{key_exchange,
- fun(Alg) when Alg == ecdh_rsa; Alg == ecdhe_rsa->
- true;
- (_) ->
- false
- end},
- {cipher,
- fun(rc4_128) ->
- false;
- %% TODO: remove this clause when chacha is fixed!
- (chacha20_poly1305) ->
- false;
- (_) ->
- true
- end}]),
- run_send_recv_rizzo(Ciphers, Config, Version,
- {?MODULE, send_recv_result_active_rizzo, []}).
-
-rizzo_zero_n() ->
- [{doc,"Test that the 0/n-split mitigation of Rizzo/Dungon attack can be explicitly selected"}].
-
-rizzo_zero_n(Config) when is_list(Config) ->
- Prop = proplists:get_value(tc_group_properties, Config),
- Version = proplists:get_value(name, Prop),
- NVersion = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl:filter_cipher_suites(ssl:cipher_suites(default, NVersion),
- [{cipher,
- fun(rc4_128) ->
- false;
- (_) ->
- true
- end}]),
- run_send_recv_rizzo(Ciphers, Config, Version,
- {?MODULE, send_recv_result_active_no_rizzo, []}).
-
-rizzo_disabled() ->
- [{doc,"Test that the mitigation of Rizzo/Dungon attack can be explicitly disabled"}].
-
-rizzo_disabled(Config) when is_list(Config) ->
- Prop = proplists:get_value(tc_group_properties, Config),
- Version = proplists:get_value(name, Prop),
- NVersion = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl:filter_cipher_suites(ssl:cipher_suites(default, NVersion),
- [{cipher,
- fun(rc4_128) ->
- false;
- (_) ->
- true
- end}]),
- run_send_recv_rizzo(Ciphers, Config, Version,
- {?MODULE, send_recv_result_active_no_rizzo, []}).
-
-%%--------------------------------------------------------------------
-new_server_wants_peer_cert() ->
- [{doc, "Test that server configured to do client certification does"
- " not reuse session without a client certificate."}].
-new_server_wants_peer_cert(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
- VServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, peercert_result, []}},
- {options, [ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- Monitor = erlang:monitor(process, Server),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- receive
- {'DOWN', Monitor, _, _, _} ->
- ok
- end,
-
- Server1 = ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
- {from, self()},
- {mfa, {?MODULE, peercert_result, []}},
- {options, VServerOpts}]),
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [ClientOpts]}]),
-
- CertFile = proplists:get_value(certfile, ClientOpts),
- [{'Certificate', BinCert, _}]= ssl_test_lib:pem_to_der(CertFile),
-
- ServerMsg = {error, no_peercert},
- Sever1Msg = {ok, BinCert},
-
- ssl_test_lib:check_result(Server, ServerMsg, Server1, Sever1Msg),
-
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Client),
- ssl_test_lib:close(Client1).
-
-%%--------------------------------------------------------------------
-session_cache_process_list() ->
- [{doc,"Test reuse of sessions (short handshake)"}].
-session_cache_process_list(Config) when is_list(Config) ->
- session_cache_process(list,Config).
-%%--------------------------------------------------------------------
-session_cache_process_mnesia() ->
- [{doc,"Test reuse of sessions (short handshake)"}].
-session_cache_process_mnesia(Config) when is_list(Config) ->
- session_cache_process(mnesia,Config).
+eccs() ->
+ [{doc, "Test API functions eccs/0 and eccs/1"}].
-%%--------------------------------------------------------------------
+eccs(Config) when is_list(Config) ->
+ [_|_] = All = ssl:eccs(),
+ [] = ssl:eccs(sslv3),
+ [_|_] = Tls = ssl:eccs(tlsv1),
+ [_|_] = Tls1 = ssl:eccs('tlsv1.1'),
+ [_|_] = Tls2 = ssl:eccs('tlsv1.2'),
+ [_|_] = Tls1 = ssl:eccs('dtlsv1'),
+ [_|_] = Tls2 = ssl:eccs('dtlsv1.2'),
+ %% ordering is currently not verified by the test
+ true = lists:sort(All) =:= lists:usort(Tls ++ Tls1 ++ Tls2),
+ ok.
tls_versions_option() ->
[{doc,"Test API versions option to connect/listen."}].
@@ -4323,2140 +452,6 @@ tls_versions_option(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-unordered_protocol_versions_server() ->
- [{doc,"Test that the highest protocol is selected even"
- " when it is not first in the versions list."}].
-
-unordered_protocol_versions_server(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, [{versions, ['tlsv1.1', 'tlsv1.2']} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, ClientOpts}]),
-
- ServerMsg = ClientMsg = {ok,'tlsv1.2'},
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
-
-%%--------------------------------------------------------------------
-unordered_protocol_versions_client() ->
- [{doc,"Test that the highest protocol is selected even"
- " when it is not first in the versions list."}].
-
-unordered_protocol_versions_client(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, ServerOpts }]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, [{versions, ['tlsv1.1', 'tlsv1.2']} | ClientOpts]}]),
-
- ServerMsg = ClientMsg = {ok, 'tlsv1.2'},
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
-
-%%--------------------------------------------------------------------
-max_handshake_size() ->
- [{doc,"Test that we can set max_handshake_size to max value."}].
-
-max_handshake_size(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{max_handshake_size, 8388607} |ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{max_handshake_size, 8388607} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok).
-
-%%--------------------------------------------------------------------
-
-server_name_indication_option() ->
- [{doc,"Test API server_name_indication option to connect."}].
-server_name_indication_option(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options,
- [{server_name_indication, disable} |
- ClientOpts]}
- ]),
-
- ssl_test_lib:check_result(Server, ok, Client0, ok),
- Server ! listen,
-
- Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options,
- [{server_name_indication, Hostname} | ClientOpts]
- }]),
- ssl_test_lib:check_result(Server, ok, Client1, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client0),
- ssl_test_lib:close(Client1).
-%%--------------------------------------------------------------------
-
-accept_pool() ->
- [{doc,"Test having an accept pool."}].
-accept_pool(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server0 = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {accepters, 3},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server0),
- [Server1, Server2] = ssl_test_lib:accepters(2),
-
- Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}
- ]),
-
- Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}
- ]),
-
- Client2 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}
- ]),
-
- ssl_test_lib:check_ok([Server0, Server1, Server2, Client0, Client1, Client2]),
-
- ssl_test_lib:close(Server0),
- ssl_test_lib:close(Server1),
- ssl_test_lib:close(Server2),
- ssl_test_lib:close(Client0),
- ssl_test_lib:close(Client1),
- ssl_test_lib:close(Client2).
-
-%%--------------------------------------------------------------------
-%% TLS 1.3
-%%--------------------------------------------------------------------
-
-tls13_enable_client_side() ->
- [{doc,"Test that a TLS 1.3 client can connect to a TLS 1.2 server."}].
-
-tls13_enable_client_side(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, [{versions,
- ['tlsv1.1', 'tlsv1.2']} | ServerOpts] }]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, [{versions,
- ['tlsv1.2', 'tlsv1.3']} | ClientOpts]}]),
-
- ServerMsg = ClientMsg = {ok, 'tlsv1.2'},
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
-
-tls13_enable_server_side() ->
- [{doc,"Test that a TLS 1.2 client can connect to a TLS 1.3 server."}].
-
-tls13_enable_server_side(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, [{versions,
- ['tlsv1.2', 'tlsv1.3']} | ServerOpts] }]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, protocol_info_result, []}},
- {options, [{versions,
- ['tlsv1.2', 'tlsv1.1']} | ClientOpts]}]),
-
- ServerMsg = ClientMsg = {ok, 'tlsv1.2'},
- ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
-
-tls_record_1_3_encode_decode() ->
- [{doc,"Test TLS 1.3 record encode/decode functions"}].
-
-tls_record_1_3_encode_decode(_Config) ->
- ConnectionStates =
- #{current_read =>
- #{beast_mitigation => one_n_minus_one,
- cipher_state =>
- {cipher_state,
- <<14,172,111,243,199,170,242,203,126,205,34,93,122,115,226,14,
- 15,117,155,48,24,112,61,15,113,208,127,51,179,227,194,232>>,
- <<197,54,168,218,54,91,157,58,30,201,197,142,51,58,53,231,228,
- 131,57,122,170,78,82,196,30,48,23,16,95,255,185,236>>,
- undefined,undefined,undefined,16},
- client_verify_data => undefined,compression_state => undefined,
- mac_secret => undefined,secure_renegotiation => undefined,
- security_parameters =>
- {security_parameters,
- <<19,2>>,
- 0,8,2,undefined,undefined,undefined,undefined,undefined,
- sha384,undefined,undefined,
- {handshake_secret,
- <<128,229,186,211,62,127,182,20,62,166,233,23,135,64,121,
- 3,104,251,214,161,253,31,3,2,232,37,8,221,189,72,64,218,
- 121,41,112,148,254,34,68,164,228,60,161,201,132,55,56,
- 157>>},
- undefined,
- <<92,24,205,75,244,60,136,212,250,32,214,20,37,3,213,87,61,207,
- 147,61,168,145,177,118,160,153,33,53,48,108,191,174>>,
- undefined},
- sequence_number => 0,server_verify_data => undefined},
- current_write =>
- #{beast_mitigation => one_n_minus_one,
- cipher_state =>
- {cipher_state,
- <<14,172,111,243,199,170,242,203,126,205,34,93,122,115,226,14,
- 15,117,155,48,24,112,61,15,113,208,127,51,179,227,194,232>>,
- <<197,54,168,218,54,91,157,58,30,201,197,142,51,58,53,231,228,
- 131,57,122,170,78,82,196,30,48,23,16,95,255,185,236>>,
- undefined,undefined,undefined,16},
- client_verify_data => undefined,compression_state => undefined,
- mac_secret => undefined,secure_renegotiation => undefined,
- security_parameters =>
- {security_parameters,
- <<19,2>>,
- 0,8,2,undefined,undefined,undefined,undefined,undefined,
- sha384,undefined,undefined,
- {handshake_secret,
- <<128,229,186,211,62,127,182,20,62,166,233,23,135,64,121,
- 3,104,251,214,161,253,31,3,2,232,37,8,221,189,72,64,218,
- 121,41,112,148,254,34,68,164,228,60,161,201,132,55,56,
- 157>>},
- undefined,
- <<92,24,205,75,244,60,136,212,250,32,214,20,37,3,213,87,61,207,
- 147,61,168,145,177,118,160,153,33,53,48,108,191,174>>,
- undefined},
- sequence_number => 0,server_verify_data => undefined}},
-
- PlainText = [11,
- <<0,2,175>>,
- <<0,0,2,171,0,2,166,48,130,2,162,48,130,1,138,2,9,0,186,57,220,137,88,255,
- 191,235,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,48,18,49,16,48,14,6,3,85,
- 4,3,12,7,84,101,115,116,32,67,65,48,30,23,13,49,56,48,53,48,52,49,52,49,50,
- 51,56,90,23,13,50,56,48,50,48,52,49,52,49,50,51,56,90,48,20,49,18,48,16,6,
- 3,85,4,3,12,9,108,111,99,97,108,104,111,115,116,48,130,1,34,48,13,6,9,42,
- 134,72,134,247,13,1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,169,40,
- 144,176,121,63,134,97,144,126,243,183,225,157,37,131,183,225,87,243,23,88,
- 230,70,9,134,32,147,7,27,167,98,51,81,224,75,199,12,229,251,195,207,75,179,
- 181,78,128,3,255,44,58,39,43,172,142,45,186,58,51,65,187,199,154,153,245,
- 70,133,137,1,27,87,42,116,65,251,129,109,145,233,97,171,71,54,213,185,74,
- 209,166,11,218,189,119,206,86,170,60,212,213,85,189,30,50,215,23,185,53,
- 132,238,132,176,198,250,139,251,198,221,225,128,109,113,23,220,39,143,71,
- 30,59,189,51,244,61,158,214,146,180,196,103,169,189,221,136,78,129,216,148,
- 2,9,8,65,37,224,215,233,13,209,21,235,20,143,33,74,59,53,208,90,152,94,251,
- 54,114,171,39,88,230,227,158,211,135,37,182,67,205,161,59,20,138,58,253,15,
- 53,48,8,157,9,95,197,9,177,116,21,54,9,125,78,109,182,83,20,16,234,223,116,
- 41,155,123,87,77,17,120,153,246,239,124,130,105,219,166,146,242,151,66,198,
- 75,72,63,28,246,86,16,244,223,22,36,50,15,247,222,98,6,152,136,154,72,150,
- 73,127,2,3,1,0,1,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,3,130,1,1,0,76,
- 33,54,160,229,219,219,193,150,116,245,252,18,39,235,145,86,12,167,171,52,
- 117,166,30,83,5,216,245,177,217,247,95,1,136,94,246,212,108,248,230,111,
- 225,202,189,6,129,8,70,128,245,18,204,215,87,82,129,253,227,122,66,182,184,
- 189,30,193,169,144,218,216,109,105,110,215,144,60,104,162,178,101,164,218,
- 122,60,37,41,143,57,150,52,59,51,112,238,113,239,168,114,69,183,143,154,73,
- 61,58,80,247,172,95,251,55,28,186,28,200,206,230,118,243,92,202,189,49,76,
- 124,252,76,0,247,112,85,194,69,59,222,163,228,103,49,110,104,109,251,155,
- 138,9,37,167,49,189,48,134,52,158,185,129,24,96,153,196,251,90,206,76,239,
- 175,119,174,165,133,108,222,125,237,125,187,149,152,83,190,16,202,94,202,
- 201,40,218,22,254,63,189,41,174,97,140,203,70,18,196,118,237,175,134,79,78,
- 246,2,61,54,77,186,112,32,17,193,192,188,217,252,215,200,7,245,180,179,132,
- 183,212,229,155,15,152,206,135,56,81,88,3,123,244,149,110,182,72,109,70,62,
- 146,152,146,151,107,126,216,210,9,93,0,0>>],
-
- {[_Header|Encoded], _} = tls_record_1_3:encode_plain_text(22, PlainText, ConnectionStates),
- CipherText = #ssl_tls{type = 23, version = {3,3}, fragment = Encoded},
-
- {#ssl_tls{type = 22, version = {3,4}, fragment = DecodedText}, _} =
- tls_record_1_3:decode_cipher_text(CipherText, ConnectionStates),
-
- DecodedText = iolist_to_binary(PlainText),
- ct:log("Decoded: ~p ~n", [DecodedText]),
- ok.
-
-tls13_1_RTT_handshake() ->
- [{doc,"Test TLS 1.3 1-RTT Handshake"}].
-
-tls13_1_RTT_handshake(_Config) ->
- %% ConnectionStates with NULL cipher
- ConnStatesNull =
- #{current_write =>
- #{security_parameters =>
- #security_parameters{cipher_suite = ?TLS_NULL_WITH_NULL_NULL},
- sequence_number => 0
- }
- },
-
- %% {client} construct a ClientHello handshake message:
- %%
- %% ClientHello (196 octets): 01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
- %% ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
- %% 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
- %% 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
- %% 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
- %% 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
- %% 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
- %% af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
- %% 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
- %% 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
- %%
- %% {client} send handshake record:
- %%
- %% payload (196 octets): 01 00 00 c0 03 03 cb 34 ec b1 e7 81 63 ba
- %% 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83 02
- %% 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b 00
- %% 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00 12
- %% 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23 00
- %% 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2 3d
- %% 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af
- %% 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03 02
- %% 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06 02
- %% 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
- %%
- %% complete record (201 octets): 16 03 01 00 c4 01 00 00 c0 03 03 cb
- %% 34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
- %% ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
- %% 00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
- %% 00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
- %% 01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
- %% e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
- %% 54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
- %% 04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
- %% 01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
- ClientHello =
- hexstr2bin("01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
- ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
- 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
- 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
- 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
- 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
- 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
- af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
- 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
- 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"),
-
- ClientHelloRecord =
- %% Current implementation always sets
- %% legacy_record_version to Ox0303
- hexstr2bin("16 03 03 00 c4 01 00 00 c0 03 03 cb
- 34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
- ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
- 00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
- 00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
- 01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
- e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
- 54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
- 04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
- 01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"),
-
- {CHEncrypted, _} =
- tls_record:encode_handshake(ClientHello, {3,4}, ConnStatesNull),
- ClientHelloRecord = iolist_to_binary(CHEncrypted),
-
- %% {server} extract secret "early":
- %%
- %% salt: 0 (all zero octets)
- %%
- %% IKM (32 octets): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- %% 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- %%
- %% secret (32 octets): 33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
- %% e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
- HKDFAlgo = sha256,
- Salt = binary:copy(<<?BYTE(0)>>, 32),
- IKM = binary:copy(<<?BYTE(0)>>, 32),
- EarlySecret =
- hexstr2bin("33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
- e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a"),
-
- {early_secret, EarlySecret} = tls_v1:key_schedule(early_secret, HKDFAlgo, {psk, Salt}),
-
- %% {client} create an ephemeral x25519 key pair:
- %%
- %% private key (32 octets): 49 af 42 ba 7f 79 94 85 2d 71 3e f2 78
- %% 4b cb ca a7 91 1d e2 6a dc 56 42 cb 63 45 40 e7 ea 50 05
- %%
- %% public key (32 octets): 99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
- %% ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c
- CPublicKey =
- hexstr2bin("99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
- ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c"),
-
- %% {server} create an ephemeral x25519 key pair:
- %%
- %% private key (32 octets): b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
- %% 52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e
- %%
- %% public key (32 octets): c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
- %% 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f
- SPrivateKey =
- hexstr2bin("b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
- 52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e"),
-
- SPublicKey =
- hexstr2bin("c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
- 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f"),
-
- %% {server} construct a ServerHello handshake message:
- %%
- %% ServerHello (90 octets): 02 00 00 56 03 03 a6 af 06 a4 12 18 60
- %% dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
- %% d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
- %% 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
- %% dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
- ServerHello =
- hexstr2bin("02 00 00 56 03 03 a6 af 06 a4 12 18 60
- dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
- d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
- 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
- dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"),
-
- %% {server} derive secret for handshake "tls13 derived":
- %%
- %% PRK (32 octets): 33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c e2
- %% 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
- %%
- %% hash (32 octets): e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
- %% 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55
- %%
- %% info (49 octets): 00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
- %% 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
- %% 64 9b 93 4c a4 95 99 1b 78 52 b8 55
- %%
- %% expanded (32 octets): 6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
- %% b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
- Hash =
- hexstr2bin("e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
- 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55"),
-
- Hash = crypto:hash(HKDFAlgo, <<>>),
-
- Info =
- hexstr2bin("00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
- 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
- 64 9b 93 4c a4 95 99 1b 78 52 b8 55"),
-
- Info = tls_v1:create_info(<<"derived">>, Hash, ssl_cipher:hash_size(HKDFAlgo)),
-
- Expanded =
- hexstr2bin("6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
- b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba"),
-
- Expanded = tls_v1:derive_secret(EarlySecret, <<"derived">>, <<>>, HKDFAlgo),
-
- %% {server} extract secret "handshake":
- %%
- %% salt (32 octets): 6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba b6 97
- %% 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
- %%
- %% IKM (32 octets): 8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
- %% 35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d
- %%
- %% secret (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
- %% 01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
-
- %% salt = Expanded
- HandshakeIKM =
- hexstr2bin("8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
- 35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d"),
-
- HandshakeSecret =
- hexstr2bin("1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
- 01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac"),
-
- HandshakeIKM = crypto:compute_key(ecdh, CPublicKey, SPrivateKey, x25519),
-
- {handshake_secret, HandshakeSecret} =
- tls_v1:key_schedule(handshake_secret, HKDFAlgo, HandshakeIKM,
- {early_secret, EarlySecret}),
-
- %% {server} derive secret "tls13 c hs traffic":
- %%
- %% PRK (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
- %% 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
- %%
- %% hash (32 octets): 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
- %% d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
- %%
- %% info (54 octets): 00 20 12 74 6c 73 31 33 20 63 20 68 73 20 74 72
- %% 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
- %% ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
- %%
- %% expanded (32 octets): b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
- %% 2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
-
- %% PRK = HandshakeSecret
- CHSTHash =
- hexstr2bin("86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
- d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
-
- CHSTInfo =
- hexstr2bin("00 20 12 74 6c 73 31 33 20 63 20 68 73 20 74 72
- 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
- ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
-
- CHSTrafficSecret =
- hexstr2bin(" b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
- 2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21"),
-
- CHSH = <<ClientHello/binary,ServerHello/binary>>,
- CHSTHash = crypto:hash(HKDFAlgo, CHSH),
- CHSTInfo = tls_v1:create_info(<<"c hs traffic">>, CHSTHash, ssl_cipher:hash_size(HKDFAlgo)),
-
- CHSTrafficSecret =
- tls_v1:client_handshake_traffic_secret(HKDFAlgo, {handshake_secret, HandshakeSecret}, CHSH),
-
- %% {server} derive secret "tls13 s hs traffic":
- %%
- %% PRK (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
- %% 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
- %%
- %% hash (32 octets): 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
- %% d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
- %%
- %% info (54 octets): 00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
- %% 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
- %% ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
- %%
- %% expanded (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
- %% 37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
-
- %% PRK = HandshakeSecret
- %% hash = CHSTHash
- SHSTInfo =
- hexstr2bin("00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
- 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
- ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
-
- SHSTrafficSecret =
- hexstr2bin("b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
- 37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38"),
-
- SHSTInfo = tls_v1:create_info(<<"s hs traffic">>, CHSTHash, ssl_cipher:hash_size(HKDFAlgo)),
-
- SHSTrafficSecret =
- tls_v1:server_handshake_traffic_secret(HKDFAlgo, {handshake_secret, HandshakeSecret}, CHSH),
-
-
- %% {server} derive secret for master "tls13 derived":
- %%
- %% PRK (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
- %% 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
- %%
- %% hash (32 octets): e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
- %% 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55
- %%
- %% info (49 octets): 00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
- %% 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
- %% 64 9b 93 4c a4 95 99 1b 78 52 b8 55
- %%
- %% expanded (32 octets): 43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25
- %% 90 b5 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
-
- %% PRK = HandshakeSecret
- %% hash = Hash
- %% info = Info
- MasterDeriveSecret =
- hexstr2bin("43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25
- 90 b5 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4"),
-
- MasterDeriveSecret = tls_v1:derive_secret(HandshakeSecret, <<"derived">>, <<>>, HKDFAlgo),
-
- %% {server} extract secret "master":
- %%
- %% salt (32 octets): 43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25 90 b5
- %% 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
- %%
- %% IKM (32 octets): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- %% 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- %%
- %% secret (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
- %% 47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
-
- %% salt = MasterDeriveSecret
- %% IKM = IKM
- MasterSecret =
- hexstr2bin("18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
- 47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19"),
-
- {master_secret, MasterSecret} =
- tls_v1:key_schedule(master_secret, HKDFAlgo, {handshake_secret, HandshakeSecret}),
-
- %% {server} send handshake record:
- %%
- %% payload (90 octets): 02 00 00 56 03 03 a6 af 06 a4 12 18 60 dc 5e
- %% 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e d3 e2
- %% 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88 76 11
- %% 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69
- %% b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
- %%
- %% complete record (95 octets): 16 03 03 00 5a 02 00 00 56 03 03 a6
- %% af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
- %% 34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
- %% 1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
- %% cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
-
- %% payload = ServerHello
- ServerHelloRecord =
- hexstr2bin("16 03 03 00 5a 02 00 00 56 03 03 a6
- af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
- 34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
- 1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
- cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"),
-
- {SHEncrypted, _} =
- tls_record:encode_handshake(ServerHello, {3,4}, ConnStatesNull),
- ServerHelloRecord = iolist_to_binary(SHEncrypted),
-
- %% {server} derive write traffic keys for handshake data:
- %%
- %% PRK (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
- %% e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
- %%
- %% key info (13 octets): 00 10 09 74 6c 73 31 33 20 6b 65 79 00
- %%
- %% key expanded (16 octets): 3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e
- %% e4 03 bc
- %%
- %% iv info (12 octets): 00 0c 08 74 6c 73 31 33 20 69 76 00
- %%
- %% iv expanded (12 octets): 5d 31 3e b2 67 12 76 ee 13 00 0b 30
-
- %% PRK = SHSTrafficSecret
- WriteKeyInfo =
- hexstr2bin("00 10 09 74 6c 73 31 33 20 6b 65 79 00"),
-
- WriteKey =
- hexstr2bin("3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e e4 03 bc"),
-
- WriteIVInfo =
- hexstr2bin("00 0c 08 74 6c 73 31 33 20 69 76 00"),
-
- WriteIV =
- hexstr2bin(" 5d 31 3e b2 67 12 76 ee 13 00 0b 30"),
-
- Cipher = aes_128_gcm, %% TODO: get from ServerHello
-
- WriteKeyInfo = tls_v1:create_info(<<"key">>, <<>>, ssl_cipher:key_material(Cipher)),
- %% TODO: remove hardcoded IV size
- WriteIVInfo = tls_v1:create_info(<<"iv">>, <<>>, 12),
-
- {WriteKey, WriteIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, SHSTrafficSecret),
-
- %% {server} construct an EncryptedExtensions handshake message:
- %%
- %% EncryptedExtensions (40 octets): 08 00 00 24 00 22 00 0a 00 14 00
- %% 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
- %% 00 02 40 01 00 00 00 00
- %%
- %% {server} construct a Certificate handshake message:
- %%
- %% Certificate (445 octets): 0b 00 01 b9 00 00 01 b5 00 01 b0 30 82
- %% 01 ac 30 82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48
- %% 86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03
- %% 72 73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17
- %% 0d 32 36 30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06
- %% 03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7
- %% 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f
- %% 82 79 30 3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
- %% d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c
- %% 1a f1 9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52
- %% 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74
- %% 80 30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93
- %% ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03
- %% 01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06
- %% 03 55 1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01
- %% 01 0b 05 00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
- %% 72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea
- %% e8 f8 a5 8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01
- %% 51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be
- %% c1 fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b
- %% 1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8
- %% 96 12 29 ac 91 87 b4 2b 4d e1 00 00
- %%
- %% {server} construct a CertificateVerify handshake message:
- %%
- %% CertificateVerify (136 octets): 0f 00 00 84 08 04 00 80 5a 74 7c
- %% 5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
- %% b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07
- %% 86 53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b
- %% be 8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44
- %% 5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a
- %% 3d a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3
- EncryptedExtensions =
- hexstr2bin("08 00 00 24 00 22 00 0a 00 14 00
- 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
- 00 02 40 01 00 00 00 00"),
-
- Certificate =
- hexstr2bin("0b 00 01 b9 00 00 01 b5 00 01 b0 30 82
- 01 ac 30 82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48
- 86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03
- 72 73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17
- 0d 32 36 30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06
- 03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7
- 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f
- 82 79 30 3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
- d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c
- 1a f1 9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52
- 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74
- 80 30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93
- ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03
- 01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06
- 03 55 1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01
- 01 0b 05 00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
- 72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea
- e8 f8 a5 8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01
- 51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be
- c1 fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b
- 1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8
- 96 12 29 ac 91 87 b4 2b 4d e1 00 00"),
-
- CertificateVerify =
- hexstr2bin("0f 00 00 84 08 04 00 80 5a 74 7c
- 5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
- b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07
- 86 53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b
- be 8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44
- 5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a
- 3d a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3"),
-
- %% {server} calculate finished "tls13 finished":
- %%
- %% PRK (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
- %% e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
- %%
- %% hash (0 octets): (empty)
- %%
- %% info (18 octets): 00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
- %% 64 00
- %%
- %% expanded (32 octets): 00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85
- %% c3 1f c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8
- %%
- %% finished (32 octets): 9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
- %% de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18
-
- %% PRK = SHSTrafficSecret
- FInfo =
- hexstr2bin("00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
- 64 00"),
-
- FExpanded =
- hexstr2bin("00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85
- c3 1f c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8"),
-
- FinishedVerifyData =
- hexstr2bin("9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
- de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18"),
-
- FInfo = tls_v1:create_info(<<"finished">>, <<>>, ssl_cipher:hash_size(HKDFAlgo)),
-
- FExpanded = tls_v1:finished_key(SHSTrafficSecret, HKDFAlgo),
-
- MessageHistory0 = [CertificateVerify,
- Certificate,
- EncryptedExtensions,
- ServerHello,
- ClientHello],
-
- FinishedVerifyData = tls_v1:finished_verify_data(FExpanded, HKDFAlgo, MessageHistory0),
-
- %% {server} construct a Finished handshake message:
- %%
- %% Finished (36 octets): 14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb
- %% dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
- %% 18
- FinishedHSBin =
- hexstr2bin("14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb
- dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
- 18"),
-
- FinishedHS = #finished{verify_data = FinishedVerifyData},
-
- FinishedIOList = tls_handshake:encode_handshake(FinishedHS, {3,4}),
- FinishedHSBin = iolist_to_binary(FinishedIOList),
-
- %% {server} derive secret "tls13 c ap traffic":
- %%
- %% PRK (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
- %% 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
- %%
- %% hash (32 octets): 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
- %% 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
- %%
- %% info (54 octets): 00 20 12 74 6c 73 31 33 20 63 20 61 70 20 74 72
- %% 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
- %% 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
- %%
- %% expanded (32 octets): 9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
- %% 65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5
-
- %% PRK = MasterSecret
- CAPTHash =
- hexstr2bin("96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
- 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
- CAPTInfo =
- hexstr2bin("00 20 12 74 6c 73 31 33 20 63 20 61 70 20 74 72
- 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
- 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
-
- CAPTrafficSecret =
- hexstr2bin("9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
- 65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5"),
-
- CHSF = <<ClientHello/binary,
- ServerHello/binary,
- EncryptedExtensions/binary,
- Certificate/binary,
- CertificateVerify/binary,
- FinishedHSBin/binary>>,
-
- CAPTHash = crypto:hash(HKDFAlgo, CHSF),
-
- CAPTInfo =
- tls_v1:create_info(<<"c ap traffic">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
-
- CAPTrafficSecret =
- tls_v1:client_application_traffic_secret_0(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
-
- %% {server} derive secret "tls13 s ap traffic":
- %%
- %% PRK (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
- %% 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
- %%
- %% hash (32 octets): 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
- %% 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
- %%
- %% info (54 octets): 00 20 12 74 6c 73 31 33 20 73 20 61 70 20 74 72
- %% 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
- %% 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
- %%
- %% expanded (32 octets): a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
- %% 50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
-
- %% PRK = MasterSecret
- %% hash = CAPTHash
- SAPTInfo =
- hexstr2bin(" 00 20 12 74 6c 73 31 33 20 73 20 61 70 20 74 72
- 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
- 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
-
- SAPTrafficSecret =
- hexstr2bin("a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
- 50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43"),
-
- SAPTInfo =
- tls_v1:create_info(<<"s ap traffic">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
-
- SAPTrafficSecret =
- tls_v1:server_application_traffic_secret_0(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
-
- %% {server} derive secret "tls13 exp master":
- %%
- %% PRK (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
- %% 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
- %%
- %% hash (32 octets): 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
- %% 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
- %%
- %% info (52 octets): 00 20 10 74 6c 73 31 33 20 65 78 70 20 6d 61 73
- %% 74 65 72 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a 00
- %% 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
- %%
- %% expanded (32 octets): fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
- %% 92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50
-
- %% PRK = MasterSecret
- %% hash = CAPTHash
- ExporterInfo =
- hexstr2bin("00 20 10 74 6c 73 31 33 20 65 78 70 20 6d 61 73
- 74 65 72 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a 00
- 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
-
- ExporterMasterSecret =
- hexstr2bin("fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
- 92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50"),
-
- ExporterInfo =
- tls_v1:create_info(<<"exp master">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
-
- ExporterMasterSecret =
- tls_v1:exporter_master_secret(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
-
- %% {server} derive write traffic keys for application data:
- %%
- %% PRK (32 octets): a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9 50 32
- %% 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
- %%
- %% key info (13 octets): 00 10 09 74 6c 73 31 33 20 6b 65 79 00
- %%
- %% key expanded (16 octets): 9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac
- %% 92 e3 56
- %%
- %% iv info (12 octets): 00 0c 08 74 6c 73 31 33 20 69 76 00
- %%
- %% iv expanded (12 octets): cf 78 2b 88 dd 83 54 9a ad f1 e9 84
-
- %% PRK = SAPTrafficsecret
- %% key info = WriteKeyInfo
- %% iv info = WrtieIVInfo
- SWKey =
- hexstr2bin("9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac 92 e3 56"),
-
- SWIV =
- hexstr2bin("cf 78 2b 88 dd 83 54 9a ad f1 e9 84"),
-
- {SWKey, SWIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, SAPTrafficSecret),
-
- %% {server} derive read traffic keys for handshake data:
- %%
- %% PRK (32 octets): b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e 2d 8f
- %% 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
- %%
- %% key info (13 octets): 00 10 09 74 6c 73 31 33 20 6b 65 79 00
- %%
- %% key expanded (16 octets): db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50
- %% 25 8d 01
- %%
- %% iv info (12 octets): 00 0c 08 74 6c 73 31 33 20 69 76 00
- %%
- %% iv expanded (12 octets): 5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f
-
- %% PRK = CHSTrafficsecret
- %% key info = WriteKeyInfo
- %% iv info = WrtieIVInfo
- SRKey =
- hexstr2bin("db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50 25 8d 01"),
-
- SRIV =
- hexstr2bin("5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f"),
-
- {SRKey, SRIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, CHSTrafficSecret).
-
-
-tls13_finished_verify_data() ->
- [{doc,"Test TLS 1.3 Finished message handling"}].
-
-tls13_finished_verify_data(_Config) ->
- ClientHello =
- hexstr2bin("01 00 00 c6 03 03 00 01 02 03 04 05 06 07 08 09
- 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19
- 1a 1b 1c 1d 1e 1f 20 e0 e1 e2 e3 e4 e5 e6 e7 e8
- e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8
- f9 fa fb fc fd fe ff 00 06 13 01 13 02 13 03 01
- 00 00 77 00 00 00 18 00 16 00 00 13 65 78 61 6d
- 70 6c 65 2e 75 6c 66 68 65 69 6d 2e 6e 65 74 00
- 0a 00 08 00 06 00 1d 00 17 00 18 00 0d 00 14 00
- 12 04 03 08 04 04 01 05 03 08 05 05 01 08 06 06
- 01 02 01 00 33 00 26 00 24 00 1d 00 20 35 80 72
- d6 36 58 80 d1 ae ea 32 9a df 91 21 38 38 51 ed
- 21 a2 8e 3b 75 e9 65 d0 d2 cd 16 62 54 00 2d 00
- 02 01 01 00 2b 00 03 02 03 04"),
-
- ServerHello =
- hexstr2bin("02 00 00 76 03 03 70 71 72 73 74 75 76 77 78 79
- 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89
- 8a 8b 8c 8d 8e 8f 20 e0 e1 e2 e3 e4 e5 e6 e7 e8
- e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8
- f9 fa fb fc fd fe ff 13 01 00 00 2e 00 33 00 24
- 00 1d 00 20 9f d7 ad 6d cf f4 29 8d d3 f9 6d 5b
- 1b 2a f9 10 a0 53 5b 14 88 d7 f8 fa bb 34 9a 98
- 28 80 b6 15 00 2b 00 02 03 04"),
-
- EncryptedExtensions =
- hexstr2bin("08 00 00 02 00 00"),
-
- Certificate =
- hexstr2bin("0b 00 03 2e 00 00 03 2a 00 03 25 30 82 03 21 30
- 82 02 09 a0 03 02 01 02 02 08 15 5a 92 ad c2 04
- 8f 90 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05
- 00 30 22 31 0b 30 09 06 03 55 04 06 13 02 55 53
- 31 13 30 11 06 03 55 04 0a 13 0a 45 78 61 6d 70
- 6c 65 20 43 41 30 1e 17 0d 31 38 31 30 30 35 30
- 31 33 38 31 37 5a 17 0d 31 39 31 30 30 35 30 31
- 33 38 31 37 5a 30 2b 31 0b 30 09 06 03 55 04 06
- 13 02 55 53 31 1c 30 1a 06 03 55 04 03 13 13 65
- 78 61 6d 70 6c 65 2e 75 6c 66 68 65 69 6d 2e 6e
- 65 74 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d
- 01 01 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82
- 01 01 00 c4 80 36 06 ba e7 47 6b 08 94 04 ec a7
- b6 91 04 3f f7 92 bc 19 ee fb 7d 74 d7 a8 0d 00
- 1e 7b 4b 3a 4a e6 0f e8 c0 71 fc 73 e7 02 4c 0d
- bc f4 bd d1 1d 39 6b ba 70 46 4a 13 e9 4a f8 3d
- f3 e1 09 59 54 7b c9 55 fb 41 2d a3 76 52 11 e1
- f3 dc 77 6c aa 53 37 6e ca 3a ec be c3 aa b7 3b
- 31 d5 6c b6 52 9c 80 98 bc c9 e0 28 18 e2 0b f7
- f8 a0 3a fd 17 04 50 9e ce 79 bd 9f 39 f1 ea 69
- ec 47 97 2e 83 0f b5 ca 95 de 95 a1 e6 04 22 d5
- ee be 52 79 54 a1 e7 bf 8a 86 f6 46 6d 0d 9f 16
- 95 1a 4c f7 a0 46 92 59 5c 13 52 f2 54 9e 5a fb
- 4e bf d7 7a 37 95 01 44 e4 c0 26 87 4c 65 3e 40
- 7d 7d 23 07 44 01 f4 84 ff d0 8f 7a 1f a0 52 10
- d1 f4 f0 d5 ce 79 70 29 32 e2 ca be 70 1f df ad
- 6b 4b b7 11 01 f4 4b ad 66 6a 11 13 0f e2 ee 82
- 9e 4d 02 9d c9 1c dd 67 16 db b9 06 18 86 ed c1
- ba 94 21 02 03 01 00 01 a3 52 30 50 30 0e 06 03
- 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03
- 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03
- 02 06 08 2b 06 01 05 05 07 03 01 30 1f 06 03 55
- 1d 23 04 18 30 16 80 14 89 4f de 5b cc 69 e2 52
- cf 3e a3 00 df b1 97 b8 1d e1 c1 46 30 0d 06 09
- 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01 00
- 59 16 45 a6 9a 2e 37 79 e4 f6 dd 27 1a ba 1c 0b
- fd 6c d7 55 99 b5 e7 c3 6e 53 3e ff 36 59 08 43
- 24 c9 e7 a5 04 07 9d 39 e0 d4 29 87 ff e3 eb dd
- 09 c1 cf 1d 91 44 55 87 0b 57 1d d1 9b df 1d 24
- f8 bb 9a 11 fe 80 fd 59 2b a0 39 8c de 11 e2 65
- 1e 61 8c e5 98 fa 96 e5 37 2e ef 3d 24 8a fd e1
- 74 63 eb bf ab b8 e4 d1 ab 50 2a 54 ec 00 64 e9
- 2f 78 19 66 0d 3f 27 cf 20 9e 66 7f ce 5a e2 e4
- ac 99 c7 c9 38 18 f8 b2 51 07 22 df ed 97 f3 2e
- 3e 93 49 d4 c6 6c 9e a6 39 6d 74 44 62 a0 6b 42
- c6 d5 ba 68 8e ac 3a 01 7b dd fc 8e 2c fc ad 27
- cb 69 d3 cc dc a2 80 41 44 65 d3 ae 34 8c e0 f3
- 4a b2 fb 9c 61 83 71 31 2b 19 10 41 64 1c 23 7f
- 11 a5 d6 5c 84 4f 04 04 84 99 38 71 2b 95 9e d6
- 85 bc 5c 5d d6 45 ed 19 90 94 73 40 29 26 dc b4
- 0e 34 69 a1 59 41 e8 e2 cc a8 4b b6 08 46 36 a0
- 00 00"),
-
- CertificateVerify =
- hexstr2bin("0f 00 01 04 08 04 01 00 17 fe b5 33 ca 6d 00 7d
- 00 58 25 79 68 42 4b bc 3a a6 90 9e 9d 49 55 75
- 76 a5 20 e0 4a 5e f0 5f 0e 86 d2 4f f4 3f 8e b8
- 61 ee f5 95 22 8d 70 32 aa 36 0f 71 4e 66 74 13
- 92 6e f4 f8 b5 80 3b 69 e3 55 19 e3 b2 3f 43 73
- df ac 67 87 06 6d cb 47 56 b5 45 60 e0 88 6e 9b
- 96 2c 4a d2 8d ab 26 ba d1 ab c2 59 16 b0 9a f2
- 86 53 7f 68 4f 80 8a ef ee 73 04 6c b7 df 0a 84
- fb b5 96 7a ca 13 1f 4b 1c f3 89 79 94 03 a3 0c
- 02 d2 9c bd ad b7 25 12 db 9c ec 2e 5e 1d 00 e5
- 0c af cf 6f 21 09 1e bc 4f 25 3c 5e ab 01 a6 79
- ba ea be ed b9 c9 61 8f 66 00 6b 82 44 d6 62 2a
- aa 56 88 7c cf c6 6a 0f 38 51 df a1 3a 78 cf f7
- 99 1e 03 cb 2c 3a 0e d8 7d 73 67 36 2e b7 80 5b
- 00 b2 52 4f f2 98 a4 da 48 7c ac de af 8a 23 36
- c5 63 1b 3e fa 93 5b b4 11 e7 53 ca 13 b0 15 fe
- c7 e4 a7 30 f1 36 9f 9e"),
-
- BaseKey =
- hexstr2bin("a2 06 72 65 e7 f0 65 2a 92 3d 5d 72 ab 04 67 c4
- 61 32 ee b9 68 b6 a3 2d 31 1c 80 58 68 54 88 14"),
-
- VerifyData =
- hexstr2bin("ea 6e e1 76 dc cc 4a f1 85 9e 9e 4e 93 f7 97 ea
- c9 a7 8c e4 39 30 1e 35 27 5a d4 3f 3c dd bd e3"),
-
- Messages = [CertificateVerify,
- Certificate,
- EncryptedExtensions,
- ServerHello,
- ClientHello],
-
- FinishedKey = tls_v1:finished_key(BaseKey, sha256),
- VerifyData = tls_v1:finished_verify_data(FinishedKey, sha256, Messages).
-
-
-tls12_ssl_server_tls13_ssl_client() ->
- [{doc,"Test basic connection between TLS 1.2 server and TLS 1.3 client"}].
-
-tls12_ssl_server_tls13_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2']}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {signature_algs_cert, [ecdsa_secp384r1_sha384,
- rsa_pss_rsae_sha256,
- rsa_pkcs1_sha256,
- {sha256,rsa},{sha256,dsa}]}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_basic_ssl_server_openssl_client() ->
- [{doc,"Test TLS 1.3 basic connection between ssl server and openssl s_client"}].
-
-tls13_basic_ssl_server_openssl_client(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-tls13_basic_ssl_server_ssl_client() ->
- [{doc,"Test TLS 1.3 basic connection between ssl server and ssl client"}].
-
-tls13_basic_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_basic_openssl_server_ssl_client() ->
- [{doc,"Test TLS 1.3 basic connection between openssl server and ssl client"}].
-
-tls13_basic_openssl_server_ssl_client(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
-
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- "-tls1_3",
- "-cert", CertFile, "-CAfile", CaCertFile,
- "-key", KeyFile, "-Verify", "2"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, tls),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-
-tls13_custom_groups_ssl_server_openssl_client() ->
- [{doc,"Test that ssl server can select a common group for key-exchange"}].
-
-tls13_custom_groups_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [x448, secp256r1, secp384r1]}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- ClientOpts = [{groups,"P-384:P-256:X25519"}|ClientOpts0],
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_custom_groups_ssl_server_ssl_client() ->
- [{doc,"Test that ssl server can select a common group for key-exchange"}].
-
-tls13_custom_groups_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [x448, secp256r1, secp384r1]}|ServerOpts0],
- ClientOpts1 = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- ClientOpts = [{supported_groups,[secp384r1, secp256r1, x25519]}|ClientOpts1],
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hello_retry_request_ssl_server_openssl_client() ->
- [{doc,"Test that ssl server can request a new group when the client's first key share"
- "is not supported"}].
-
-tls13_hello_retry_request_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- ClientOpts = [{groups,"P-256:X25519"}|ClientOpts0],
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hello_retry_request_ssl_server_ssl_client() ->
- [{doc,"Test that ssl server can request a new group when the client's first key share"
- "is not supported"}].
-
-tls13_hello_retry_request_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [secp256r1, x25519]}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-tls13_client_auth_empty_cert_alert_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3: Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to true."}].
-
-tls13_client_auth_empty_cert_alert_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts = proplists:delete(keyfile, ClientOpts1),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_server_alert(Server, certificate_required),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_client_auth_empty_cert_alert_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3: Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to true."}].
-
-tls13_client_auth_empty_cert_alert_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts2],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_server_alert(Server, certificate_required),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_client_auth_empty_cert_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3: Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to false."}].
-
-tls13_client_auth_empty_cert_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts = proplists:delete(keyfile, ClientOpts1),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, false}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_client_auth_empty_cert_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3: Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to false."}].
-
-tls13_client_auth_empty_cert_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, false}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts2],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_client_auth_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3: Test client authentication."}].
-
-tls13_client_auth_ssl_server_openssl_client(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_client_auth_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3: Test client authentication."}].
-
-tls13_client_auth_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- %%Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hrr_client_auth_empty_cert_alert_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to true."}].
-
-tls13_hrr_client_auth_empty_cert_alert_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
- ClientOpts = [{groups,"P-256:X25519"}|ClientOpts2],
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_server_alert(Server, certificate_required),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hrr_client_auth_empty_cert_alert_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to true."}].
-
-tls13_hrr_client_auth_empty_cert_alert_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [secp256r1, x25519]}|ClientOpts2],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_server_alert(Server, certificate_required),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hrr_client_auth_empty_cert_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to false."}].
-
-tls13_hrr_client_auth_empty_cert_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
- ClientOpts = [{groups,"P-256:X25519"}|ClientOpts2],
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, false},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hrr_client_auth_empty_cert_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client sends an empty certificate and fail_if_no_peer_cert is set to false."}].
-
-tls13_hrr_client_auth_empty_cert_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- %% Delete Client Cert and Key
- ClientOpts1 = proplists:delete(certfile, ClientOpts0),
- ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, false},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [secp256r1, x25519]}|ClientOpts2],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hrr_client_auth_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication."}].
-
-tls13_hrr_client_auth_ssl_server_openssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ClientOpts = [{groups,"P-256:X25519"}|ClientOpts0],
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_hrr_client_auth_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication."}].
-
-tls13_hrr_client_auth_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true},
- {supported_groups, [x448, x25519]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups, [secp256r1, x25519]}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_unsupported_sign_algo_client_auth_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm"}].
-
-tls13_unsupported_sign_algo_client_auth_ssl_server_openssl_client(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- %% Skip rsa_pkcs1_sha256!
- {signature_algs, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_server_alert(Server, insufficient_security),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_unsupported_sign_algo_client_auth_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm"}].
-
-tls13_unsupported_sign_algo_client_auth_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- %% Skip rsa_pkcs1_sha256!
- {signature_algs, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_server_alert(Server, insufficient_security),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-%% Triggers a Server Alert as openssl s_client does not have a certificate with a
-%% signature algorithm supported by the server (signature_algorithms_cert extension
-%% of CertificateRequest does not contain the algorithm of the client certificate).
-%% openssl s_client sends an empty certificate.
-tls13_unsupported_sign_algo_cert_client_auth_ssl_server_openssl_client() ->
- [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm_cert"}].
-
-tls13_unsupported_sign_algo_cert_client_auth_ssl_server_openssl_client(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {log_level, debug},
- {verify, verify_peer},
- {signature_algs, [rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pss_rsae_sha256]},
- %% Skip rsa_pkcs1_sha256!
- {signature_algs_cert, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_server_alert(Server, certificate_required),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-%% Triggers a Server Alert as ssl client does not have a certificate with a
-%% signature algorithm supported by the server (signature_algorithms_cert extension
-%% of CertificateRequest does not contain the algorithm of the client certificate).
-%% ssl client sends an empty certificate.
-tls13_unsupported_sign_algo_cert_client_auth_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm_cert"}].
-
-tls13_unsupported_sign_algo_cert_client_auth_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {log_level, debug},
- {verify, verify_peer},
- {signature_algs, [rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pss_rsae_sha256]},
- %% Skip rsa_pkcs1_sha256!
- {signature_algs_cert, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_server_alert(Server, certificate_required),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_connection_information() ->
- [{doc,"Test the API function ssl:connection_information/1 in a TLS 1.3 connection"}].
-
-tls13_connection_information(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, connection_information_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_ssl_server_with_alpn_ssl_client() ->
- [{doc,"Test TLS 1.3 between ssl server with ALPN configured and ssl client"}].
-
-tls13_ssl_server_with_alpn_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_preferred_protocols, [<<5,6>>, <<1>>]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_ssl_server_with_alpn_ssl_client_empty_alpn() ->
- [{doc,"Test TLS 1.3 between ssl server with ALPN configured and ssl client with empty ALPN"}].
-
-tls13_ssl_server_with_alpn_ssl_client_empty_alpn(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_preferred_protocols, [<<5,6>>, <<1>>]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_advertised_protocols, []}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_server_alert(Server, no_application_protocol),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_ssl_server_with_alpn_ssl_client_bad_alpn() ->
- [{doc,"Test TLS 1.3 between ssl server with ALPN configured and ssl client with bad ALPN"}].
-
-tls13_ssl_server_with_alpn_ssl_client_bad_alpn(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_preferred_protocols, [<<5,6>>, <<1>>]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_advertised_protocols, [<<1,2,3,4>>]}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_server_alert(Server, no_application_protocol),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-tls13_ssl_server_with_alpn_ssl_client_alpn() ->
- [{doc,"Test TLS 1.3 between ssl server with ALPN configured and ssl client with correct ALPN"}].
-
-tls13_ssl_server_with_alpn_ssl_client_alpn(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_preferred_protocols, [<<5,6>>, <<1>>]}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {alpn_advertised_protocols, [<<1,2,3,4>>, <<5,6>>]}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_ecdsa_ssl_server_openssl_client() ->
- [{doc,"Test TLS 1.3 basic connection between ssl server and openssl s_client using ECDSA certificates"}].
-
-tls13_ecdsa_ssl_server_openssl_client(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_ecdsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_ecdsa_opts, Config),
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
- {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-tls13_ecdsa_ssl_server_ssl_client() ->
- [{doc,"Test TLS 1.3 basic connection between ssl server and ssl client using ECDSA certificates"}].
-
-tls13_ecdsa_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_ecdsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_ecdsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-tls13_ecdsa_openssl_server_ssl_client() ->
- [{doc,"Test TLS 1.3 basic connection between openssl server and ssl client using ECDSA certificates"}].
-
-tls13_ecdsa_openssl_server_ssl_client(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_ecdsa_verify_opts, Config),
- ClientOpts0 = ssl_test_lib:ssl_options(client_ecdsa_opts, Config),
-
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- "-tls1_3",
- "-cert", CertFile, "-CAfile", CaCertFile,
- "-key", KeyFile, "-Verify", "2"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, tls),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-
-tls13_ecdsa_client_auth_ssl_server_ssl_client() ->
- [{doc,"TLS 1.3: Test client authentication with ECDSA certificates."}].
-
-tls13_ecdsa_client_auth_ssl_server_ssl_client(Config) ->
- ClientOpts0 = ssl_test_lib:ssl_options(client_ecdsa_opts, Config),
- ServerOpts0 = ssl_test_lib:ssl_options(server_ecdsa_opts, Config),
-
- %% Set versions
- ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
- {verify, verify_peer},
- {fail_if_no_peer_cert, true}|ServerOpts0],
- ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- %%Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(Client).
-
-
-
-%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
send_recv_result(Socket) ->
@@ -6468,491 +463,9 @@ tcp_send_recv_result(Socket) ->
{ok,"Hello world"} = gen_tcp:recv(Socket, 11),
ok.
-basic_verify_test_no_close(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- {Server, Client}.
-
-basic_test(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-prf_create_plan(TlsVersions, PRFs, Results) ->
- lists:foldl(fun(Ver, Acc) ->
- A = prf_ciphers_and_expected(Ver, PRFs, Results),
- [A|Acc]
- end, [], TlsVersions).
-prf_ciphers_and_expected(TlsVer, PRFs, Results) ->
- case TlsVer of
- TlsVer when TlsVer == sslv3 orelse TlsVer == tlsv1
- orelse TlsVer == 'tlsv1.1' orelse TlsVer == 'dtlsv1' ->
- Ciphers = ssl:cipher_suites(),
- {_, Expected} = lists:keyfind(md5sha, 1, Results),
- [[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected}, {prf, md5sha}]];
- TlsVer when TlsVer == 'tlsv1.2' orelse TlsVer == 'dtlsv1.2'->
- lists:foldl(
- fun(PRF, Acc) ->
- Ciphers = prf_get_ciphers(TlsVer, PRF),
- case Ciphers of
- [] ->
- ct:log("No ciphers for PRF algorithm ~p. Skipping.", [PRF]),
- Acc;
- Ciphers ->
- {_, Expected} = lists:keyfind(PRF, 1, Results),
- [[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected},
- {prf, PRF}] | Acc]
- end
- end, [], PRFs)
- end.
-prf_get_ciphers(_, PRF) ->
- lists:filter(
- fun(C) when tuple_size(C) == 4 andalso
- element(4, C) == PRF ->
- true;
- (_) ->
- false
- end,
- ssl:cipher_suites()).
-prf_run_test(_, TlsVer, [], _, Prf) ->
- ct:fail({error, cipher_list_empty, TlsVer, Prf});
-prf_run_test(Config, TlsVer, Ciphers, Expected, Prf) ->
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- BaseOpts = [{active, true}, {versions, [TlsVer]}, {ciphers, Ciphers}, {protocol, tls_or_dtls(TlsVer)}],
- ServerOpts = BaseOpts ++ proplists:get_value(server_opts, Config),
- ClientOpts = BaseOpts ++ proplists:get_value(client_opts, Config),
- Server = ssl_test_lib:start_server(
- [{node, ServerNode}, {port, 0}, {from, self()},
- {mfa, {?MODULE, prf_verify_value, [TlsVer, Expected, Prf]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client(
- [{node, ClientNode}, {port, Port},
- {host, Hostname}, {from, self()},
- {mfa, {?MODULE, prf_verify_value, [TlsVer, Expected, Prf]}},
- {options, ClientOpts}]),
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-prf_verify_value(Socket, TlsVer, Expected, Algo) ->
- Ret = ssl:prf(Socket, <<>>, <<>>, [<<>>], 16),
- case TlsVer of
- sslv3 ->
- case Ret of
- {error, undefined} -> ok;
- _ ->
- {error, {expected, {error, undefined},
- got, Ret, tls_ver, TlsVer, prf_algorithm, Algo}}
- end;
- _ ->
- case Ret of
- {ok, Expected} -> ok;
- {ok, Val} -> {error, {expected, Expected, got, Val, tls_ver, TlsVer,
- prf_algorithm, Algo}}
- end
- end.
-
-send_recv_result_timeout_client(Socket) ->
- {error, timeout} = ssl:recv(Socket, 11, 500),
- {error, timeout} = ssl:recv(Socket, 11, 0),
- ssl:send(Socket, "Hello world"),
- receive
- Msg ->
- io:format("Msg ~p~n",[Msg])
- after 500 ->
- ok
- end,
- {ok, "Hello world"} = ssl:recv(Socket, 11, 500),
- ok.
-send_recv_result_timeout_server(Socket) ->
- ssl:send(Socket, "Hello"),
- {ok, "Hello world"} = ssl:recv(Socket, 11),
- ssl:send(Socket, " world"),
- ok.
-
-recv_close(Socket) ->
- {error, closed} = ssl:recv(Socket, 11),
- receive
- {_,{error,closed}} ->
- error_extra_close_sent_to_user_process
- after 500 ->
- ok
- end.
-
-
-send_recv_result_active_rizzo(Socket) ->
- ssl:send(Socket, "Hello world"),
- "Hello world" = ssl_test_lib:active_recv(Socket, 11),
- ok.
-
-send_recv_result_active_no_rizzo(Socket) ->
- ssl:send(Socket, "Hello world"),
- "Hello world" = ssl_test_lib:active_recv(Socket, 11),
- ok.
-
-
-ssl_active_recv(N) ->
- ssl_active_recv(N, []).
-
-ssl_active_recv(0, Acc) ->
- Acc;
-ssl_active_recv(N, Acc) ->
- receive
- {ssl, _, Bytes} ->
- ssl_active_recv(N-length(Bytes), Acc ++ Bytes)
- end.
-
result_ok(_Socket) ->
ok.
-renegotiate(Socket, Data) ->
- ct:log("Renegotiating ~n", []),
- Result = ssl:renegotiate(Socket),
- ct:log("Result ~p~n", [Result]),
- ssl:send(Socket, Data),
- case Result of
- ok ->
- ok;
- Other ->
- Other
- end.
-
-renegotiate_reuse_session(Socket, Data) ->
- %% Make sure session is registered
- ct:sleep(?SLEEP),
- renegotiate(Socket, Data).
-
-renegotiate_immediately(Socket) ->
- _ = ssl_test_lib:active_recv(Socket, 11),
- ok = ssl:renegotiate(Socket),
- {error, renegotiation_rejected} = ssl:renegotiate(Socket),
- ct:sleep(?RENEGOTIATION_DISABLE_TIME + ?SLEEP),
- ok = ssl:renegotiate(Socket),
- ct:log("Renegotiated again"),
- ssl:send(Socket, "Hello world"),
- ok.
-
-renegotiate_rejected(Socket) ->
- _ = ssl_test_lib:active_recv(Socket, 11),
- {error, renegotiation_rejected} = ssl:renegotiate(Socket),
- {error, renegotiation_rejected} = ssl:renegotiate(Socket),
- ct:sleep(?RENEGOTIATION_DISABLE_TIME +1),
- {error, renegotiation_rejected} = ssl:renegotiate(Socket),
- ct:log("Failed to renegotiate again"),
- ssl:send(Socket, "Hello world"),
- ok.
-
-rizzo_add_mitigation_option(Value, Config) ->
- lists:foldl(fun(Opt, Acc) ->
- case proplists:get_value(Opt, Acc) of
- undefined -> Acc;
- C ->
- N = lists:keystore(beast_mitigation, 1, C,
- {beast_mitigation, Value}),
- lists:keystore(Opt, 1, Acc, {Opt, N})
- end
- end, Config,
- [client_opts, client_dsa_opts, server_opts, server_dsa_opts,
- server_ecdsa_opts, server_ecdh_rsa_opts]).
-
-new_config(PrivDir, ServerOpts0) ->
- CaCertFile = proplists:get_value(cacertfile, ServerOpts0),
- CertFile = proplists:get_value(certfile, ServerOpts0),
- KeyFile = proplists:get_value(keyfile, ServerOpts0),
- NewCaCertFile = filename:join(PrivDir, "new_ca.pem"),
- NewCertFile = filename:join(PrivDir, "new_cert.pem"),
- NewKeyFile = filename:join(PrivDir, "new_key.pem"),
- file:copy(CaCertFile, NewCaCertFile),
- file:copy(CertFile, NewCertFile),
- file:copy(KeyFile, NewKeyFile),
- ServerOpts1 = proplists:delete(cacertfile, ServerOpts0),
- ServerOpts2 = proplists:delete(certfile, ServerOpts1),
- ServerOpts = proplists:delete(keyfile, ServerOpts2),
-
- {ok, PEM} = file:read_file(NewCaCertFile),
- ct:log("CA file content: ~p~n", [public_key:pem_decode(PEM)]),
-
- [{cacertfile, NewCaCertFile}, {certfile, NewCertFile},
- {keyfile, NewKeyFile} | ServerOpts].
-
-session_cache_process(_Type,Config) when is_list(Config) ->
- reuse_session(Config).
-
-init([Type]) ->
- ets:new(ssl_test, [named_table, public, set]),
- ets:insert(ssl_test, {type, Type}),
- case Type of
- list ->
- spawn(fun() -> session_loop([]) end);
- mnesia ->
- mnesia:start(),
- {atomic,ok} = mnesia:create_table(sess_cache, []),
- sess_cache
- end.
-
-session_cb() ->
- [{type, Type}] = ets:lookup(ssl_test, type),
- Type.
-
-terminate(Cache) ->
- case session_cb() of
- list ->
- Cache ! terminate;
- mnesia ->
- catch {atomic,ok} =
- mnesia:delete_table(sess_cache)
- end.
-
-lookup(Cache, Key) ->
- case session_cb() of
- list ->
- Cache ! {self(), lookup, Key},
- receive {Cache, Res} -> Res end;
- mnesia ->
- case mnesia:transaction(fun() ->
- mnesia:read(sess_cache,
- Key, read)
- end) of
- {atomic, [{sess_cache, Key, Value}]} ->
- Value;
- _ ->
- undefined
- end
- end.
-
-update(Cache, Key, Value) ->
- case session_cb() of
- list ->
- Cache ! {update, Key, Value};
- mnesia ->
- {atomic, ok} =
- mnesia:transaction(fun() ->
- mnesia:write(sess_cache,
- {sess_cache, Key, Value}, write)
- end)
- end.
-
-delete(Cache, Key) ->
- case session_cb() of
- list ->
- Cache ! {delete, Key};
- mnesia ->
- {atomic, ok} =
- mnesia:transaction(fun() ->
- mnesia:delete(sess_cache, Key)
- end)
- end.
-
-foldl(Fun, Acc, Cache) ->
- case session_cb() of
- list ->
- Cache ! {self(),foldl,Fun,Acc},
- receive {Cache, Res} -> Res end;
- mnesia ->
- Foldl = fun() ->
- mnesia:foldl(Fun, Acc, sess_cache)
- end,
- {atomic, Res} = mnesia:transaction(Foldl),
- Res
- end.
-
-select_session(Cache, PartialKey) ->
- case session_cb() of
- list ->
- Cache ! {self(),select_session, PartialKey},
- receive
- {Cache, Res} ->
- Res
- end;
- mnesia ->
- Sel = fun() ->
- mnesia:select(Cache,
- [{{sess_cache,{PartialKey,'$1'}, '$2'},
- [],['$$']}])
- end,
- {atomic, Res} = mnesia:transaction(Sel),
- Res
- end.
-
-session_loop(Sess) ->
- receive
- terminate ->
- ok;
- {Pid, lookup, Key} ->
- case lists:keysearch(Key,1,Sess) of
- {value, {Key,Value}} ->
- Pid ! {self(), Value};
- _ ->
- Pid ! {self(), undefined}
- end,
- session_loop(Sess);
- {update, Key, Value} ->
- NewSess = [{Key,Value}| lists:keydelete(Key,1,Sess)],
- session_loop(NewSess);
- {delete, Key} ->
- session_loop(lists:keydelete(Key,1,Sess));
- {Pid,foldl,Fun,Acc} ->
- Res = lists:foldl(Fun, Acc,Sess),
- Pid ! {self(), Res},
- session_loop(Sess);
- {Pid,select_session,PKey} ->
- Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 ->
- [[Id, Session]|Acc];
- (_,Acc) ->
- Acc
- end,
- Sessions = lists:foldl(Sel, [], Sess),
- Pid ! {self(), Sessions},
- session_loop(Sess)
- end.
-
-
-erlang_ssl_receive(Socket, Data) ->
- case ssl_test_lib:active_recv(Socket, length(Data)) of
- Data ->
- ok;
- Other ->
- ct:fail({{expected, Data}, {got, Other}})
- end.
-
-receive_msg(_) ->
- receive
- Msg ->
- Msg
- end.
-
-controlling_process_result(Socket, Pid, Msg) ->
- ok = ssl:controlling_process(Socket, Pid),
- %% Make sure other side has evaluated controlling_process
- %% before message is sent
- ct:sleep(?SLEEP),
- ssl:send(Socket, Msg),
- no_result_msg.
-
-
-controller_dies_result(_Socket, _Pid, _Msg) ->
- receive Result -> Result end.
-
-get_close(Pid, Where) ->
- receive
- {'EXIT', Pid, _Reason} ->
- receive
- {_, {ssl_closed, Socket}} ->
- ct:log("Socket closed ~p~n",[Socket]);
- Unexpected ->
- ct:log("Unexpected ~p~n",[Unexpected]),
- ct:fail({line, ?LINE-1})
- after 5000 ->
- ct:fail({timeout, {line, ?LINE, Where}})
- end;
- Unexpected ->
- ct:log("Unexpected ~p~n",[Unexpected]),
- ct:fail({line, ?LINE-1})
- after 5000 ->
- ct:fail({timeout, {line, ?LINE, Where}})
- end.
-
-run_send_recv_rizzo(Ciphers, Config, Version, Mfa) ->
- Result = lists:map(fun(Cipher) ->
- rizzo_test(Cipher, Config, Version, Mfa) end,
- Ciphers),
- case lists:flatten(Result) of
- [] ->
- ok;
- Error ->
- ct:log("Cipher suite errors: ~p~n", [Error]),
- ct:fail(cipher_suite_failed_see_test_case_log)
- end.
-
-rizzo_test(Cipher, Config, Version, Mfa) ->
- {ClientOpts, ServerOpts} = client_server_opts(Cipher, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, Mfa},
- {options, [{active, true}, {ciphers, [Cipher]},
- {versions, [Version]}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, Mfa},
- {options, [{active, true}, {ciphers, [Cipher]}| ClientOpts]}]),
-
- Result = ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- case Result of
- ok ->
- [];
- Error ->
- [{Cipher, Error}]
- end.
-
-client_server_opts(#{key_exchange := KeyAlgo}, Config)
- when KeyAlgo == rsa orelse
- KeyAlgo == dhe_rsa orelse
- KeyAlgo == ecdhe_rsa orelse
- KeyAlgo == rsa_psk orelse
- KeyAlgo == srp_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
- ssl_test_lib:ssl_options(server_opts, Config)};
-client_server_opts(#{key_exchange := KeyAlgo}, Config) when KeyAlgo == dss orelse KeyAlgo == dhe_dss ->
- {ssl_test_lib:ssl_options(client_dsa_opts, Config),
- ssl_test_lib:ssl_options(server_dsa_opts, Config)};
-client_server_opts(#{key_exchange := KeyAlgo}, Config) when KeyAlgo == ecdh_ecdsa orelse KeyAlgo == ecdhe_ecdsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
- ssl_test_lib:ssl_options(server_ecdsa_opts, Config)};
-client_server_opts(#{key_exchange := KeyAlgo}, Config) when KeyAlgo == ecdh_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
- ssl_test_lib:ssl_options(server_ecdh_rsa_opts, Config)}.
-
-connection_information_result(Socket) ->
- {ok, Info = [_ | _]} = ssl:connection_information(Socket),
- case length(Info) > 3 of
- true ->
- %% Atleast one ssl_option() is set
- ct:log("Info ~p", [Info]),
- ok;
- false ->
- ct:fail(no_ssl_options_returned)
- end.
-
-connection_info_result(Socket) ->
- {ok, Info} = ssl:connection_information(Socket, [protocol, selected_cipher_suite]),
- {ok, {proplists:get_value(protocol, Info), proplists:get_value(selected_cipher_suite, Info)}}.
protocol_info_result(Socket) ->
{ok, [{protocol, PVersion}]} = ssl:connection_information(Socket, [protocol]),
@@ -6962,11 +475,7 @@ version_info_result(Socket) ->
{ok, [{version, Version}]} = ssl:connection_information(Socket, [version]),
{ok, Version}.
-secret_connection_info_result(Socket) ->
- {ok, [{client_random, ClientRand}, {server_random, ServerRand}, {master_secret, MasterSecret}]}
- = ssl:connection_information(Socket, [client_random, server_random, master_secret]),
- is_binary(ClientRand) andalso is_binary(ServerRand) andalso is_binary(MasterSecret).
-
+
connect_dist_s(S) ->
Msg = term_to_binary({erlang,term}),
ok = ssl:send(S, Msg).
@@ -6976,88 +485,11 @@ connect_dist_c(S) ->
{ok, Test} = ssl:recv(S, 0, 10000),
ok.
-tls_downgrade_result(Socket, Pid) ->
- ok = ssl_test_lib:send_recv_result(Socket),
- Pid ! {self(), ready},
- receive
- go ->
- ok
- end,
- case ssl:close(Socket, {self(), 10000}) of
- {ok, TCPSocket} ->
- inet:setopts(TCPSocket, [{active, true}]),
- gen_tcp:send(TCPSocket, "Downgraded"),
- receive
- {tcp, TCPSocket, <<"Downgraded">>} ->
- ok;
- {tcp_closed, TCPSocket} ->
- ct:fail("Peer timed out, downgrade aborted"),
- ok;
- Other ->
- {error, Other}
- end;
- {error, timeout} ->
- ct:fail("Timed out, downgrade aborted"),
- ok;
- Fail ->
- {error, Fail}
- end.
-
-tls_close(Socket) ->
- ok = ssl_test_lib:send_recv_result(Socket),
- case ssl:close(Socket, 5000) of
- ok ->
- ok;
- {error, closed} ->
- ok;
- Other ->
- ct:fail(Other)
- end.
-
- %% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast
-treashold(N, {3,0}) ->
- (N div 2) + 1;
-treashold(N, {3,1}) ->
- (N div 2) + 1;
-treashold(N, _) ->
- N + 1.
-
-get_invalid_inet_option(Socket) ->
- {error, {options, {socket_options, foo, _}}} = ssl:getopts(Socket, [foo]),
- ok.
-
-tls_shutdown_result(Socket, server) ->
- ssl:send(Socket, "Hej"),
- ok = ssl:shutdown(Socket, write),
- {ok, "Hej hopp"} = ssl:recv(Socket, 8),
- ok;
-
-tls_shutdown_result(Socket, client) ->
- ssl:send(Socket, "Hej hopp"),
- ok = ssl:shutdown(Socket, write),
- {ok, "Hej"} = ssl:recv(Socket, 3),
- ok.
-
-tls_shutdown_write_result(Socket, server) ->
- ct:sleep(?SLEEP),
- ssl:shutdown(Socket, write);
-tls_shutdown_write_result(Socket, client) ->
- ssl:recv(Socket, 0).
-
dummy(_Socket) ->
%% Should not happen as the ssl connection will not be established
%% due to fatal handshake failiure
exit(kill).
-tls_shutdown_both_result(Socket, server) ->
- ct:sleep(?SLEEP),
- ssl:shutdown(Socket, read_write);
-tls_shutdown_both_result(Socket, client) ->
- ssl:recv(Socket, 0).
-
-peername_result(S) ->
- ssl:peername(S).
-
version_option_test(Config, Version) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
@@ -7083,50 +515,3 @@ version_option_test(Config, Version) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-try_recv_active(Socket) ->
- ssl:send(Socket, "Hello world"),
- {error, einval} = ssl:recv(Socket, 11),
- ok.
-try_recv_active_once(Socket) ->
- {error, einval} = ssl:recv(Socket, 11),
- ok.
-
-
-wait_for_send(Socket) ->
- %% Make sure TLS process processed send message event
- _ = ssl:connection_information(Socket).
-
-tls_or_dtls('dtlsv1') ->
- dtls;
-tls_or_dtls('dtlsv1.2') ->
- dtls;
-tls_or_dtls(_) ->
- tls.
-
-hexstr2int(S) ->
- B = hexstr2bin(S),
- Bits = size(B) * 8,
- <<Integer:Bits/integer>> = B,
- Integer.
-
-hexstr2bin(S) when is_binary(S) ->
- hexstr2bin(S, <<>>);
-hexstr2bin(S) ->
- hexstr2bin(list_to_binary(S), <<>>).
-%%
-hexstr2bin(<<>>, Acc) ->
- Acc;
-hexstr2bin(<<C,T/binary>>, Acc) when C =:= 32; %% SPACE
- C =:= 10; %% LF
- C =:= 13 -> %% CR
- hexstr2bin(T, Acc);
-hexstr2bin(<<X,Y,T/binary>>, Acc) ->
- I = hex2int(X) * 16 + hex2int(Y),
- hexstr2bin(T, <<Acc/binary,I>>).
-
-hex2int(C) when $0 =< C, C =< $9 ->
- C - $0;
-hex2int(C) when $A =< C, C =< $F ->
- C - $A + 10;
-hex2int(C) when $a =< C, C =< $f ->
- C - $a + 10.
diff --git a/lib/ssl/test/ssl_bench_SUITE.erl b/lib/ssl/test/ssl_bench_SUITE.erl
index 35efa2b8a3..a297539c36 100644
--- a/lib/ssl/test/ssl_bench_SUITE.erl
+++ b/lib/ssl/test/ssl_bench_SUITE.erl
@@ -174,7 +174,12 @@ do_test(Type, TC, Loop, ParallellConnections, Server) ->
end,
{TimeInMicro, _} = timer:tc(Run),
TotalTests = ParallellConnections * Loop,
- TestPerSecond = 1000000 * TotalTests div TimeInMicro,
+ TestPerSecond = case TimeInMicro of
+ 0 ->
+ undefined;
+ _ ->
+ 1000000 * TotalTests div TimeInMicro
+ end,
io:format("TC ~p ~p ~p ~p 1/s~n", [TC, Type, ParallellConnections, TestPerSecond]),
unlink(SPid),
SPid ! quit,
diff --git a/lib/ssl/test/ssl_cert_SUITE.erl b/lib/ssl/test/ssl_cert_SUITE.erl
new file mode 100644
index 0000000000..fb1695f38a
--- /dev/null
+++ b/lib/ssl/test/ssl_cert_SUITE.erl
@@ -0,0 +1,563 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_cert_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [
+ {group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+groups() ->
+ [
+ {'tlsv1.3', [], tls_1_3_protocol_groups()},
+ {'tlsv1.2', [], pre_tls_1_3_protocol_groups()},
+ {'tlsv1.1', [], pre_tls_1_3_protocol_groups()},
+ {'tlsv1', [], pre_tls_1_3_protocol_groups()},
+ {'sslv3', [], ssl_protocol_groups()},
+ {'dtlsv1.2', [], pre_tls_1_3_protocol_groups()},
+ {'dtlsv1', [], pre_tls_1_3_protocol_groups()},
+ {rsa, [], all_version_tests()},
+ {ecdsa, [], all_version_tests()},
+ {dsa, [], all_version_tests()},
+ {rsa_1_3, [], all_version_tests() ++ tls_1_3_tests() ++ [unsupported_sign_algo_client_auth,
+ unsupported_sign_algo_cert_client_auth]},
+ {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
+ ].
+
+ssl_protocol_groups() ->
+ [{group, rsa},
+ {group, dsa}].
+
+pre_tls_1_3_protocol_groups() ->
+ [{group, rsa},
+ {group, ecdsa},
+ {group, dsa}].
+
+tls_1_3_protocol_groups() ->
+ [{group, rsa_1_3},
+ {group, ecdsa_1_3}].
+
+tls_1_3_tests() ->
+ [
+ hello_retry_request,
+ custom_groups,
+ hello_retry_client_auth,
+ hello_retry_client_auth_empty_cert_accepted,
+ hello_retry_client_auth_empty_cert_rejected
+ ].
+
+all_version_tests() ->
+ [
+ no_auth,
+ auth,
+ client_auth_empty_cert_accepted,
+ client_auth_empty_cert_rejected,
+ client_auth_partial_chain,
+ client_auth_allow_partial_chain,
+ client_auth_do_not_allow_partial_chain,
+ client_auth_partial_chain_fun_fail,
+ missing_root_cert_no_auth,
+ missing_root_cert_auth,
+ missing_root_cert_auth_user_verify_fun_accept,
+ missing_root_cert_auth_user_verify_fun_reject,
+ verify_fun_always_run_client,
+ verify_fun_always_run_server,
+ incomplete_chain_auth
+ %%invalid_signature_client
+ ].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ Config
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+init_per_group(Group, Config0) when Group == rsa;
+ Group == rsa_1_3 ->
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ COpts = proplists:get_value(client_rsa_opts, Config),
+ SOpts = proplists:get_value(server_rsa_opts, Config),
+ [{cert_key_alg, rsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, COpts},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+init_per_group(Group, Config0) when Group == ecdsa;
+ Group == ecdsa_1_3 ->
+
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(ecdsa, PKAlg) andalso (lists:member(ecdh, PKAlg) orelse lists:member(dh, PKAlg)) of
+ true ->
+ Config = ssl_test_lib:make_ecdsa_cert(Config0),
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ [{cert_key_alg, ecdsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, COpts},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))]
+ )];
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
+
+init_per_group(Group, Config0) when Group == dsa ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(dss, PKAlg) andalso lists:member(dh, PKAlg) of
+ true ->
+ Config = ssl_test_lib:make_dsa_cert(Config0),
+ COpts = proplists:get_value(client_dsa_opts, Config),
+ SOpts = proplists:get_value(server_dsa_opts, Config),
+ [{cert_key_alg, dsa} |
+ lists:delete(cert_key_alg,
+ [{client_cert_opts, COpts},
+ {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts,
+ lists:delete(client_cert_opts, Config))])];
+ false ->
+ {skip, "Missing DSS crypto support"}
+ end;
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ [{client_type, erlang},
+ {server_type, erlang}, {version, GroupName}
+ | ssl_test_lib:init_tls_version(GroupName, Config)];
+ false ->
+ {skip, "Missing crypto support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+no_auth() ->
+ ssl_cert_tests:no_auth().
+
+no_auth(Config) ->
+ ssl_cert_tests:no_auth(Config).
+%%--------------------------------------------------------------------
+auth() ->
+ ssl_cert_tests:auth().
+auth(Config) ->
+ ssl_cert_tests:auth(Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_accepted() ->
+ ssl_cert_tests:client_auth_empty_cert_accepted().
+client_auth_empty_cert_accepted(Config) ->
+ ssl_cert_tests:client_auth_empty_cert_accepted(Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_rejected() ->
+ ssl_cert_tests:client_auth_empty_cert_rejected().
+client_auth_empty_cert_rejected(Config) ->
+ ssl_cert_tests:client_auth_empty_cert_rejected(Config).
+%%--------------------------------------------------------------------
+client_auth_partial_chain() ->
+ ssl_cert_tests:client_auth_partial_chain().
+client_auth_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_partial_chain(Config).
+
+%%--------------------------------------------------------------------
+client_auth_allow_partial_chain() ->
+ ssl_cert_tests:client_auth_allow_partial_chain().
+client_auth_allow_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_allow_partial_chain(Config).
+%%--------------------------------------------------------------------
+client_auth_do_not_allow_partial_chain() ->
+ ssl_cert_tests:client_auth_do_not_allow_partial_chain().
+client_auth_do_not_allow_partial_chain(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_do_not_allow_partial_chain(Config).
+
+%%--------------------------------------------------------------------
+client_auth_partial_chain_fun_fail() ->
+ ssl_cert_tests:client_auth_partial_chain_fun_fail().
+client_auth_partial_chain_fun_fail(Config) when is_list(Config) ->
+ ssl_cert_tests:client_auth_partial_chain_fun_fail(Config).
+
+%%--------------------------------------------------------------------
+missing_root_cert_no_auth() ->
+ ssl_cert_tests:missing_root_cert_no_auth().
+missing_root_cert_no_auth(Config) when is_list(Config) ->
+ ssl_cert_tests:missing_root_cert_no_auth(Config).
+
+%%--------------------------------------------------------------------
+missing_root_cert_auth() ->
+ [{doc,"Must have ROOT certs to be able to verify verify peer"}].
+missing_root_cert_auth(Config) when is_list(Config) ->
+ ServerOpts = proplists:delete(cacertfile, ssl_test_lib:ssl_options(server_cert_opts, Config)),
+ {ClientNode, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer}
+ | ServerOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, {options, {cacertfile, ""}}}),
+
+ ClientOpts = proplists:delete(cacertfile, ssl_test_lib:ssl_options(client_cert_opts, Config)),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, {error, {options, {cacertfile, ""}}}).
+
+%%--------------------------------------------------------------------
+missing_root_cert_auth_user_verify_fun_accept() ->
+ [{doc, "Test that the client succeds if the ROOT CA is unknown in verify_peer mode"
+ " with a verify_fun that accepts the unknown CA error"}].
+
+missing_root_cert_auth_user_verify_fun_accept(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ FunAndState = {fun(_,{bad_cert, unknown_ca}, UserState) ->
+ {valid, UserState};
+ (_,{bad_cert, _} = Reason, _) ->
+ {fail, Reason};
+ (_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
+ end, []},
+ ClientOpts = ssl_test_lib:ssl_options([{verify, verify_peer},
+ {verify_fun, FunAndState}], Config),
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+missing_root_cert_auth_user_backwardscompatibility_verify_fun_accept() ->
+ [{doc, "Test old style verify fun"}].
+
+missing_root_cert_auth_user_backwardscompatibility_verify_fun_accept(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ AcceptBadCa = fun({bad_cert,unknown_ca}, Acc) -> Acc;
+ (Other, Acc) -> [Other | Acc]
+ end,
+ VerifyFun =
+ fun(ErrorList) ->
+ case lists:foldl(AcceptBadCa, [], ErrorList) of
+ [] -> true;
+ [_|_] -> false
+ end
+ end,
+
+ ClientOpts = ssl_test_lib:ssl_options([{verify, verify_peer},
+ {verify_fun, VerifyFun}], Config),
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+missing_root_cert_auth_user_verify_fun_reject() ->
+ [{doc, "Test that the client fails if the ROOT CA is unknown in verify_peer mode"
+ " with a verify_fun that rejects the unknown CA error"}].
+
+missing_root_cert_auth_user_verify_fun_reject(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ FunAndState = {fun(_,{bad_cert, unknown_ca} = Reason, _UserState) ->
+ {fail, Reason};
+ (_,{bad_cert, _} = Reason, _) ->
+ {fail, Reason};
+ (_,{extension, UserState}, _) ->
+ {unknown, UserState};
+ (_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
+ end, []},
+ ClientOpts = ssl_test_lib:ssl_options([{verify, verify_peer},
+ {verify_fun, FunAndState}], Config),
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, unknown_ca).
+%%--------------------------------------------------------------------
+incomplete_chain_auth() ->
+ [{doc,"Test that we can verify an incompleat chain when we have the certs to rebuild it"}].
+incomplete_chain_auth(Config) when is_list(Config) ->
+ DefaultCertConf = ssl_test_lib:default_cert_chain_conf(),
+ #{client_config := ClientOpts0,
+ server_config := ServerOpts0} = ssl_test_lib:make_cert_chains_der(proplists:get_value(cert_key_alg, Config),
+ [{server_chain, DefaultCertConf},
+ {client_chain, DefaultCertConf}]),
+ [ServerRoot| _] = ServerCas = proplists:get_value(cacerts, ServerOpts0),
+ ClientCas = proplists:get_value(cacerts, ClientOpts0),
+ ClientOpts = ssl_test_lib:ssl_options([{verify, verify_peer},
+ {cacerts, ServerCas ++ ClientCas} |
+ proplists:delete(cacerts, ClientOpts0)], Config),
+ ServerOpts = ssl_test_lib:ssl_options([{verify, verify_peer},
+ {cacerts, [ServerRoot]} |
+ proplists:delete(cacerts, ServerOpts0)], Config),
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+verify_fun_always_run_client() ->
+ [{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
+
+verify_fun_always_run_client(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ %% If user verify fun is called correctly we fail the connection.
+ %% otherwise we cannot tell this case apart form where we miss
+ %% to call users verify fun
+ FunAndState = {fun(_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (_, valid, [ChainLen]) ->
+ {valid, [ChainLen + 1]};
+ (_, valid_peer, [1]) ->
+ {fail, "verify_fun_was_always_run"};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
+ end, [0]},
+
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options,
+ [{verify, verify_peer},
+ {verify_fun, FunAndState}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_client_alert(Server, Client, handshake_failure).
+
+%%--------------------------------------------------------------------
+verify_fun_always_run_server() ->
+ [{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
+verify_fun_always_run_server(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ %% If user verify fun is called correctly we fail the connection.
+ %% otherwise we cannot tell this case apart form where we miss
+ %% to call users verify fun
+ FunAndState = {fun(_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (_, valid, [ChainLen]) ->
+ {valid, [ChainLen + 1]};
+ (_, valid_peer, [1]) ->
+ {fail, "verify_fun_was_always_run"};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
+ end, [0]},
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options,
+ [{verify, verify_peer},
+ {verify_fun, FunAndState} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ no_result, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_client_alert(Server, Client, handshake_failure).
+
+%%--------------------------------------------------------------------
+invalid_signature_client() ->
+ ssl_cert_tests:invalid_signature_client().
+invalid_signature_client(Config) when is_list(Config) ->
+ ssl_cert_tests:invalid_signature_client(Config).
+%%--------------------------------------------------------------------
+invalid_signature_server() ->
+ ssl_cert_tests:invalid_signature_client().
+invalid_signature_server(Config) when is_list(Config) ->
+ ssl_cert_tests:invalid_signature_client(Config).
+
+%%--------------------------------------------------------------------
+%% TLS 1.3 Test cases -----------------------------------------------
+%%--------------------------------------------------------------------
+hello_retry_request() ->
+ [{doc,"Test that ssl server can request a new group when the client's first key share"
+ "is not supported"}].
+
+hello_retry_request(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [x448, x25519]}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [secp256r1, x25519]}|ClientOpts0],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+custom_groups() ->
+ [{doc,"Test that ssl server can select a common group for key-exchange"}].
+
+custom_groups(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ %% Set versions
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [x448, secp256r1, secp384r1]}|ServerOpts0],
+ ClientOpts1 = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+ ClientOpts = [{supported_groups,[secp384r1, secp256r1, x25519]}|ClientOpts1],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+%% Triggers a Server Alert as ssl client does not have a certificate with a
+%% signature algorithm supported by the server (signature_algorithms_cert extension
+%% of CertificateRequest does not contain the algorithm of the client certificate).
+%% ssl client sends an empty certificate.
+unsupported_sign_algo_cert_client_auth() ->
+ [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm_cert"}].
+
+unsupported_sign_algo_cert_client_auth(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {signature_algs, [rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pss_rsae_sha256]},
+ %% Skip rsa_pkcs1_sha256!
+ {signature_algs_cert, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
+ {fail_if_no_peer_cert, true}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required).
+
+%%--------------------------------------------------------------------
+unsupported_sign_algo_client_auth() ->
+ [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm"}].
+
+unsupported_sign_algo_client_auth(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ %% Skip rsa_pkcs1_sha256!
+ {signature_algs, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
+ {fail_if_no_peer_cert, true}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, insufficient_security).
+%%--------------------------------------------------------------------
+hello_retry_client_auth() ->
+ [{doc, "TLS 1.3 (HelloRetryRequest): Test client authentication."}].
+
+hello_retry_client_auth(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts1 = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [x448, x25519]}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [secp256r1, x25519]}|ClientOpts0],
+ ServerOpts = [{verify, verify_peer},
+ {fail_if_no_peer_cert, true} | ServerOpts1],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_accepted() ->
+ [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client sends an empty "
+ "certificate and fail_if_no_peer_cert is set to true."}].
+
+hello_retry_client_auth_empty_cert_accepted(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ %% Delete Client Cert and Key
+ ClientOpts1 = proplists:delete(certfile, ClientOpts0),
+ ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
+
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ %% Set versions
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {fail_if_no_peer_cert, false},
+ {supported_groups, [x448, x25519]}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [secp256r1, x25519]}|ClientOpts2],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_rejected() ->
+ [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client "
+ "sends an empty certificate and fail_if_no_peer_cert is set to true."}].
+
+hello_retry_client_auth_empty_cert_rejected(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ %% Delete Client Cert and Key
+ ClientOpts1 = proplists:delete(certfile, ClientOpts0),
+ ClientOpts2 = proplists:delete(keyfile, ClientOpts1),
+
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ %% Set versions
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {fail_if_no_peer_cert, true},
+ {supported_groups, [x448, x25519]}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups, [secp256r1, x25519]}|ClientOpts2],
+
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required).
diff --git a/lib/ssl/test/ssl_cert_tests.erl b/lib/ssl/test/ssl_cert_tests.erl
new file mode 100644
index 0000000000..c88daa2185
--- /dev/null
+++ b/lib/ssl/test/ssl_cert_tests.erl
@@ -0,0 +1,386 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_cert_tests).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+no_auth() ->
+ [{doc,"Test connection without authentication"}].
+
+no_auth(Config) ->
+ ClientOpts = [{verify, verify_none} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{verify, verify_none} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+auth() ->
+ [{doc,"Test connection with mutual authentication"}].
+
+auth(Config) ->
+ ClientOpts = [{verify, verify_peer} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{verify, verify_peer} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+client_auth_empty_cert_accepted() ->
+ [{doc,"Test client authentication when client sends an empty certificate and "
+ "fail_if_no_peer_cert is set to false."}].
+
+client_auth_empty_cert_accepted(Config) ->
+ ClientOpts = proplists:delete(keyfile,
+ proplists:delete(certfile,
+ ssl_test_lib:ssl_options(client_cert_opts, Config))),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts = [{verify, verify_peer},
+ {fail_if_no_peer_cert, false} | ServerOpts0],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+client_auth_empty_cert_rejected() ->
+ [{doc,"Test client authentication when client sends an empty certificate and "
+ "fail_if_no_peer_cert is set to true."}].
+
+client_auth_empty_cert_rejected(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ClientOpts0 = ssl_test_lib:ssl_options([], Config),
+ %% Delete Client Cert and Key
+ ClientOpts1 = proplists:delete(certfile, ClientOpts0),
+ ClientOpts = proplists:delete(keyfile, ClientOpts1),
+
+ Version = proplists:get_value(version,Config),
+ case Version of
+ 'tlsv1.3' ->
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required);
+ _ ->
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, handshake_failure)
+ end.
+%%--------------------------------------------------------------------
+client_auth_partial_chain() ->
+ [{doc, "Client sends an incompleate chain, by default not acceptable."}].
+
+client_auth_partial_chain(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ {ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts0)),
+ [{_,RootCA,_} | _] = public_key:pem_decode(ClientCAs),
+ ClientOpts = [{cacerts, [RootCA]} |
+ proplists:delete(cacertfile, ClientOpts0)],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, unknown_ca).
+
+%%--------------------------------------------------------------------
+client_auth_allow_partial_chain() ->
+ [{doc, "Server trusts intermediat CA and accepts a partial chain. (partial_chain option)"}].
+
+client_auth_allow_partial_chain(Config) when is_list(Config) ->
+ ServerOpts0 = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ {ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts)),
+ [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ClientCAs),
+
+ PartialChain = fun(CertChain) ->
+ case lists:member(IntermidiateCA, CertChain) of
+ true ->
+ {trusted_ca, IntermidiateCA};
+ false ->
+ unknown_ca
+ end
+ end,
+ ServerOpts = [{cacerts, [IntermidiateCA]},
+ {partial_chain, PartialChain} |
+ proplists:delete(cacertfile, ServerOpts0)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+ %%--------------------------------------------------------------------
+client_auth_do_not_allow_partial_chain() ->
+ [{doc, "Server does not accept the chain sent by the client as ROOT CA is unkown, "
+ "and we do not choose to trust the intermediate CA. (partial_chain option)"}].
+
+client_auth_do_not_allow_partial_chain(Config) when is_list(Config) ->
+ ServerOpts0 = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts0)),
+ [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
+
+ PartialChain = fun(_CertChain) ->
+ unknown_ca
+ end,
+ ServerOpts = [{cacerts, [IntermidiateCA]},
+ {partial_chain, PartialChain} |
+ proplists:delete(cacertfile, ServerOpts0)],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, unknown_ca).
+
+ %%--------------------------------------------------------------------
+client_auth_partial_chain_fun_fail() ->
+ [{doc, "If parial_chain fun crashes, treat it as if it returned unkown_ca"}].
+
+client_auth_partial_chain_fun_fail(Config) when is_list(Config) ->
+ ServerOpts0 = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_cert_opts, Config),
+
+ {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts0)),
+ [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
+
+ PartialChain = fun(_CertChain) ->
+ true = false %% crash on purpose
+ end,
+ ServerOpts = [{cacerts, [IntermidiateCA]},
+ {partial_chain, PartialChain} |
+ proplists:delete(cacertfile, ServerOpts0)],
+
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, unknown_ca).
+
+%%--------------------------------------------------------------------
+missing_root_cert_no_auth() ->
+ [{doc,"Test that the client succeds if the ROOT CA is unknown in verify_none mode"}].
+
+missing_root_cert_no_auth(Config) ->
+ ClientOpts = [{verify, verify_none} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{verify, verify_none} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+invalid_signature_client() ->
+ [{doc,"Test server with invalid signature"}].
+
+invalid_signature_client(Config) when is_list(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+
+ KeyFile = proplists:get_value(keyfile, ClientOpts0),
+ [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts0),
+ NewClientCertFile = filename:join(PrivDir, "client_invalid_cert.pem"),
+ [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile),
+ ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp),
+ ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
+ NewClientDerCert = public_key:pkix_sign(ClientOTPTbsCert, Key),
+ ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', NewClientDerCert, not_encrypted}]),
+ ClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts0)],
+ ServerOpts = [{verify, verify_peer} | ServerOpts0],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, unknown_ca).
+
+%%--------------------------------------------------------------------
+invalid_signature_server() ->
+ [{doc,"Test client with invalid signature"}].
+
+invalid_signature_server(Config) when is_list(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+
+ KeyFile = proplists:get_value(keyfile, ServerOpts0),
+ [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
+ Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts0),
+ NewServerCertFile = filename:join(PrivDir, "server_invalid_cert.pem"),
+ [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile),
+ ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp),
+ ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
+ NewServerDerCert = public_key:pkix_sign(ServerOTPTbsCert, Key),
+ ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]),
+ ServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts0)],
+ ClientOpts = [{verify, verify_peer} | ClientOpts0],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, unknown_ca).
+
+%%--------------------------------------------------------------------
+%% TLS 1.3 Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+hello_retry_request() ->
+ [{doc,"Test that ssl server can request a new group when the client's first key share"
+ "is not supported"}].
+
+hello_retry_request(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ {ServerOpts, ClientOpts} = group_config(Config,
+ [{versions, ['tlsv1.2','tlsv1.3']} | ServerOpts0],
+ [{versions, ['tlsv1.2','tlsv1.3']} | ClientOpts0]),
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+custom_groups() ->
+ [{doc,"Test that ssl server can select a common group for key-exchange"}].
+
+custom_groups(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ {ServerOpts, ClientOpts} = group_config_custom(Config,
+ [{versions, ['tlsv1.2','tlsv1.3']} | ServerOpts0],
+ [{versions, ['tlsv1.2','tlsv1.3']} | ClientOpts0]),
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+%%--------------------------------------------------------------------
+%% Triggers a Server Alert as ssl client does not have a certificate with a
+%% signature algorithm supported by the server (signature_algorithms_cert extension
+%% of CertificateRequest does not contain the algorithm of the client certificate).
+%% ssl client sends an empty certificate.
+unsupported_sign_algo_cert_client_auth() ->
+ [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm_cert"}].
+
+unsupported_sign_algo_cert_client_auth(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {signature_algs, [rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pss_rsae_sha256]},
+ %% Skip rsa_pkcs1_sha256!
+ {signature_algs_cert, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
+ {fail_if_no_peer_cert, true}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required).
+%%--------------------------------------------------------------------
+unsupported_sign_algo_client_auth() ->
+ [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm"}].
+
+unsupported_sign_algo_client_auth(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ %% Skip rsa_pkcs1_sha256!
+ {signature_algs, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
+ {fail_if_no_peer_cert, true}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, insufficient_security).
+%%--------------------------------------------------------------------
+hello_retry_client_auth() ->
+ [{doc, "TLS 1.3 (HelloRetryRequest): Test client authentication."}].
+
+hello_retry_client_auth(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ {ServerOpts, ClientOpts} = group_config(Config,
+ [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {fail_if_no_peer_cert, true} | ServerOpts0],
+ [{versions, ['tlsv1.2','tlsv1.3']}, {verify, verify_peer} | ClientOpts0]),
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_accepted() ->
+ [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client sends an empty "
+ "certificate and fail_if_no_peer_cert is set to false."}].
+
+hello_retry_client_auth_empty_cert_accepted(Config) ->
+ ClientOpts0 = proplists:delete(keyfile,
+ proplists:delete(certfile,
+ ssl_test_lib:ssl_options(client_cert_opts, Config))),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ {ServerOpts, ClientOpts} = group_config(Config,
+ [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {fail_if_no_peer_cert, false} | ServerOpts0],
+ [{versions, ['tlsv1.2','tlsv1.3']}, {verify, verify_peer} | ClientOpts0]),
+
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+hello_retry_client_auth_empty_cert_rejected() ->
+ [{doc,"TLS 1.3 (HelloRetryRequest): Test client authentication when client "
+ "sends an empty certificate and fail_if_no_peer_cert is set to true."}].
+
+hello_retry_client_auth_empty_cert_rejected(Config) ->
+ ClientOpts0 = proplists:delete(keyfile,
+ proplists:delete(certfile,
+ ssl_test_lib:ssl_options(client_cert_opts, Config))),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ {ServerOpts, ClientOpts} = group_config(Config,
+ [{versions, ['tlsv1.2','tlsv1.3']},
+ {verify, verify_peer},
+ {fail_if_no_peer_cert, true} | ServerOpts0],
+ [{versions, ['tlsv1.2','tlsv1.3']}, {verify, verify_peer} | ClientOpts0]),
+
+ ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------------------
+%%--------------------------------------------------------------------
+
+group_config_custom(Config, ServerOpts, ClientOpts) ->
+ case proplists:get_value(client_type, Config) of
+ erlang ->
+ {[{groups,"X448:P-256:P-384"} | ServerOpts],
+ [{supported_groups, [secp384r1, secp256r1, x25519]} | ClientOpts]};
+ openssl ->
+ {[{supported_groups, [x448, secp256r1, secp384r1]} | ServerOpts],
+ [{groups,"P-384:P-256:X25519"} | ClientOpts]}
+ end.
+
+group_config(Config, ServerOpts, ClientOpts) ->
+ case proplists:get_value(client_type, Config) of
+ erlang ->
+ {[{groups,"X448:X25519"} | ServerOpts],
+ [{supported_groups, [secp256r1, x25519]} | ClientOpts]};
+ openssl ->
+ {[{supported_groups, [x448, x25519]} | ServerOpts],
+ [{groups,"P-256:X25519"} | ClientOpts]}
+ end.
+
+test_ciphers(_, 'tlsv1.3' = Version) ->
+ Ciphers = ssl:cipher_suites(default, Version),
+ ct:log("Version ~p Testing ~p~n", [Version, Ciphers]),
+ OpenSSLCiphers = openssl_ciphers(),
+ ct:log("OpenSSLCiphers ~p~n", [OpenSSLCiphers]),
+ lists:filter(fun(C) ->
+ ct:log("Cipher ~p~n", [C]),
+ lists:member(ssl_cipher_format:suite_map_to_openssl_str(C), OpenSSLCiphers)
+ end, Ciphers);
+test_ciphers(Kex, Version) ->
+ Ciphers = ssl:filter_cipher_suites(ssl:cipher_suites(default, Version),
+ [{key_exchange, Kex}]),
+ ct:log("Version ~p Testing ~p~n", [Version, Ciphers]),
+ OpenSSLCiphers = openssl_ciphers(),
+ ct:log("OpenSSLCiphers ~p~n", [OpenSSLCiphers]),
+ lists:filter(fun(C) ->
+ ct:log("Cipher ~p~n", [C]),
+ lists:member(ssl_cipher_format:suite_map_to_openssl_str(C), OpenSSLCiphers)
+ end, Ciphers).
+
+
+
+openssl_ciphers() ->
+ Str = os:cmd("openssl ciphers"),
+ string:split(string:strip(Str, right, $\n), ":", all).
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 4de4a35e59..f38858e0bf 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -71,37 +71,20 @@ all_protocol_groups() ->
{group, error_handling}].
tests() ->
- [verify_peer,
- verify_none,
- server_require_peer_cert_ok,
- server_require_peer_cert_fail,
- server_require_peer_cert_empty_ok,
- server_require_peer_cert_partial_chain,
- server_require_peer_cert_allow_partial_chain,
- server_require_peer_cert_do_not_allow_partial_chain,
- server_require_peer_cert_partial_chain_fun_fail,
- verify_fun_always_run_client,
- verify_fun_always_run_server,
- cert_expired,
- invalid_signature_client,
- invalid_signature_server,
+ [cert_expired,
+ %invalid_signature_client,
+ %%invalid_signature_server,
extended_key_usage_verify_both,
extended_key_usage_verify_server,
critical_extension_verify_client,
critical_extension_verify_server,
critical_extension_verify_none,
- customize_hostname_check,
- incomplete_chain,
long_chain
].
error_handling_tests()->
[client_with_cert_cipher_suites_handshake,
- server_verify_no_cacerts,
- unknown_server_ca_fail,
- unknown_server_ca_accept_verify_none,
- unknown_server_ca_accept_verify_peer,
- unknown_server_ca_accept_backwardscompatibility,
+ %%unknown_server_ca_accept_backwardscompatibility,
no_authority_key_identifier,
no_authority_key_identifier_keyEncipherment].
@@ -160,61 +143,6 @@ end_per_testcase(_TestCase, Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-
-verify_peer() ->
- [{doc,"Test option verify_peer"}].
-verify_peer(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- Active = proplists:get_value(active, Config),
- ReceiveFunction = proplists:get_value(receive_function, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active}, {verify, verify_peer}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active}, {verify, verify_peer} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-verify_none() ->
- [{doc,"Test option verify_none"}].
-
-verify_none(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- Active = proplists:get_value(active, Config),
- ReceiveFunction = proplists:get_value(receive_function, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active}, {verify, verify_none}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active},
- {verify, verify_none} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
server_verify_client_once() ->
[{doc,"Test server option verify_client_once"}].
@@ -253,309 +181,6 @@ server_verify_client_once(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-server_require_peer_cert_ok() ->
- [{doc,"Test server option fail_if_no_peer_cert when peer sends cert"}].
-
-server_require_peer_cert_ok(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- Active = proplists:get_value(active, Config),
- ReceiveFunction = proplists:get_value(receive_function, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
-server_require_peer_cert_fail() ->
- [{doc,"Test server option fail_if_no_peer_cert when peer doesn't send cert"}].
-
-server_require_peer_cert_fail(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- BadClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
- Active = proplists:get_value(active, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, [{active, Active} | ServerOpts]}]),
-
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {options, [{active, Active} | BadClientOpts]}]),
-
- Version = proplists:get_value(version,Config),
- case Version of
- 'tlsv1.3' ->
- ssl_test_lib:check_server_alert(Server, Client, certificate_required);
- _ ->
- ssl_test_lib:check_server_alert(Server, Client, handshake_failure)
- end.
-
-%%--------------------------------------------------------------------
-server_require_peer_cert_empty_ok() ->
- [{doc,"Test server option fail_if_no_peer_cert when peer sends cert"}].
-
-server_require_peer_cert_empty_ok(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, false}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- Active = proplists:get_value(active, Config),
- ReceiveFunction = proplists:get_value(receive_function, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- ClientOpts = proplists:delete(keyfile, proplists:delete(certfile, ClientOpts0)),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
-server_require_peer_cert_partial_chain() ->
- [{doc, "Client sends an incompleate chain, by default not acceptable."}].
-
-server_require_peer_cert_partial_chain(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- Active = proplists:get_value(active, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- {ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts)),
- [{_,RootCA,_} | _] = public_key:pem_decode(ClientCAs),
-
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, Active} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, Active},
- {cacerts, [RootCA]} |
- proplists:delete(cacertfile, ClientOpts)]}]),
- ssl_test_lib:check_server_alert(Server, Client, unknown_ca).
-
-%%--------------------------------------------------------------------
-server_require_peer_cert_allow_partial_chain() ->
- [{doc, "Server trusts intermediat CA and accepts a partial chain. (partial_chain option)"}].
-
-server_require_peer_cert_allow_partial_chain(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Active = proplists:get_value(active, Config),
- ReceiveFunction = proplists:get_value(receive_function, Config),
-
- {ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts)),
- [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ClientCAs),
-
- PartialChain = fun(CertChain) ->
- case lists:member(IntermidiateCA, CertChain) of
- true ->
- {trusted_ca, IntermidiateCA};
- false ->
- unknown_ca
- end
- end,
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active},
- {cacerts, [IntermidiateCA]},
- {partial_chain, PartialChain} |
- proplists:delete(cacertfile, ServerOpts)]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ClientOpts]}]),
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
- %%--------------------------------------------------------------------
-server_require_peer_cert_do_not_allow_partial_chain() ->
- [{doc, "Server does not accept the chain sent by the client as ROOT CA is unkown, "
- "and we do not choose to trust the intermediate CA. (partial_chain option)"}].
-
-server_require_peer_cert_do_not_allow_partial_chain(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
- [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
-
- PartialChain = fun(_CertChain) ->
- unknown_ca
- end,
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{cacerts, [IntermidiateCA]},
- {partial_chain, PartialChain} |
- proplists:delete(cacertfile, ServerOpts)]}]),
-
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
- ssl_test_lib:check_server_alert(Server, Client, unknown_ca).
- %%--------------------------------------------------------------------
-server_require_peer_cert_partial_chain_fun_fail() ->
- [{doc, "If parial_chain fun crashes, treat it as if it returned unkown_ca"}].
-
-server_require_peer_cert_partial_chain_fun_fail(Config) when is_list(Config) ->
- ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
- [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
-
- PartialChain = fun(_CertChain) ->
- true = false %% crash on purpose
- end,
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, [{cacerts, [IntermidiateCA]},
- {partial_chain, PartialChain} |
- proplists:delete(cacertfile, ServerOpts)]}]),
-
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
- ssl_test_lib:check_server_alert(Server, Client, unknown_ca).
-
-%%--------------------------------------------------------------------
-verify_fun_always_run_client() ->
- [{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
-
-verify_fun_always_run_client(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- no_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- %% If user verify fun is called correctly we fail the connection.
- %% otherwise we cannot tell this case apart form where we miss
- %% to call users verify fun
- FunAndState = {fun(_,{extension, _}, UserState) ->
- {unknown, UserState};
- (_, valid, [ChainLen]) ->
- {valid, [ChainLen + 1]};
- (_, valid_peer, [1]) ->
- {fail, "verify_fun_was_always_run"};
- (_, valid_peer, UserState) ->
- {valid, UserState}
- end, [0]},
-
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- no_result, []}},
- {options,
- [{verify, verify_peer},
- {verify_fun, FunAndState}
- | ClientOpts]}]),
-
- ssl_test_lib:check_client_alert(Server, Client, handshake_failure).
-
-%%--------------------------------------------------------------------
-verify_fun_always_run_server() ->
- [{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
-verify_fun_always_run_server(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- %% If user verify fun is called correctly we fail the connection.
- %% otherwise we cannot tell this case apart form where we miss
- %% to call users verify fun
- FunAndState = {fun(_,{extension, _}, UserState) ->
- {unknown, UserState};
- (_, valid, [ChainLen]) ->
- {valid, [ChainLen + 1]};
- (_, valid_peer, [1]) ->
- {fail, "verify_fun_was_always_run"};
- (_, valid_peer, UserState) ->
- {valid, UserState}
- end, [0]},
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- no_result, []}},
- {options,
- [{verify, verify_peer},
- {verify_fun, FunAndState} |
- ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- no_result, []}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_client_alert(Server, Client, handshake_failure).
-%%--------------------------------------------------------------------
-
cert_expired() ->
[{doc,"Test server with expired certificate"}].
@@ -937,235 +562,6 @@ client_with_cert_cipher_suites_handshake(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-server_verify_no_cacerts() ->
- [{doc,"Test server must have cacerts if it wants to verify client"}].
-server_verify_no_cacerts(Config) when is_list(Config) ->
- ServerOpts = proplists:delete(cacertfile, ssl_test_lib:ssl_options(server_rsa_opts, Config)),
- {_, ServerNode, _} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, [{verify, verify_peer}
- | ServerOpts]}]),
-
- ssl_test_lib:check_result(Server, {error, {options, {cacertfile, ""}}}).
-
-
-%%--------------------------------------------------------------------
-unknown_server_ca_fail() ->
- [{doc,"Test that the client fails if the ca is unknown in verify_peer mode"}].
-unknown_server_ca_fail(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- no_result, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- FunAndState = {fun(_,{bad_cert, unknown_ca} = Reason, _) ->
- {fail, Reason};
- (_,{extension, _}, UserState) ->
- {unknown, UserState};
- (_, valid, UserState) ->
- {valid, [test_to_update_user_state | UserState]};
- (_, valid_peer, UserState) ->
- {valid, UserState}
- end, []},
-
- Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- no_result, []}},
- {options,
- [{verify, verify_peer},
- {verify_fun, FunAndState}
- | ClientOpts]}]),
- ssl_test_lib:check_client_alert(Server, Client, unknown_ca).
-
-%%--------------------------------------------------------------------
-unknown_server_ca_accept_verify_none() ->
- [{doc,"Test that the client succeds if the ca is unknown in verify_none mode"}].
-unknown_server_ca_accept_verify_none(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active, []}},
- {options,
- [{verify, verify_none}| ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-%%--------------------------------------------------------------------
-unknown_server_ca_accept_verify_peer() ->
- [{doc, "Test that the client succeds if the ca is unknown in verify_peer mode"
- " with a verify_fun that accepts the unknown ca error"}].
-unknown_server_ca_accept_verify_peer(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- FunAndState = {fun(_,{bad_cert, unknown_ca}, UserState) ->
- {valid, UserState};
- (_,{bad_cert, _} = Reason, _) ->
- {fail, Reason};
- (_,{extension, _}, UserState) ->
- {unknown, UserState};
- (_, valid, UserState) ->
- {valid, UserState};
- (_, valid_peer, UserState) ->
- {valid, UserState}
- end, []},
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active, []}},
- {options,
- [{verify, verify_peer},
- {verify_fun, FunAndState}| ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-unknown_server_ca_accept_backwardscompatibility() ->
- [{doc,"Test that old style verify_funs will work"}].
-unknown_server_ca_accept_backwardscompatibility(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- AcceptBadCa = fun({bad_cert,unknown_ca}, Acc) -> Acc;
- (Other, Acc) -> [Other | Acc]
- end,
- VerifyFun =
- fun(ErrorList) ->
- case lists:foldl(AcceptBadCa, [], ErrorList) of
- [] -> true;
- [_|_] -> false
- end
- end,
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active, []}},
- {options,
- [{verify, verify_peer},
- {verify_fun, VerifyFun}| ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-
-customize_hostname_check() ->
- [{doc,"Test option customize_hostname_check."}].
-customize_hostname_check(Config) when is_list(Config) ->
- Ext = [#'Extension'{extnID = ?'id-ce-subjectAltName',
- extnValue = [{dNSName, "*.example.org"}],
- critical = false}
- ],
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
- [[],
- [],
- [{extensions, Ext}]
- ]}],
- Config, "https_hostname_convention"),
- ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
- ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
-
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- CustomFun = public_key:pkix_verify_hostname_match_fun(https),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options,
- [{server_name_indication, "other.example.org"},
- {customize_hostname_check,
- [{match_fun, CustomFun}]} | ClientOpts]
- }]),
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
-
- Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}
- ]),
- ssl_test_lib:check_client_alert(Server, Client1, handshake_failure).
-
-incomplete_chain() ->
- [{doc,"Test option verify_peer"}].
-incomplete_chain(Config) when is_list(Config) ->
- DefConf = ssl_test_lib:default_cert_chain_conf(),
- CertChainConf = ssl_test_lib:gen_conf(rsa, rsa, DefConf, DefConf),
- #{server_config := ServerConf,
- client_config := ClientConf} = public_key:pkix_test_data(CertChainConf),
- [ServerRoot| _] = ServerCas = proplists:get_value(cacerts, ServerConf),
- ClientCas = proplists:get_value(cacerts, ClientConf),
-
- Active = proplists:get_value(active, Config),
- ReceiveFunction = proplists:get_value(receive_function, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active}, {verify, verify_peer},
- {cacerts, [ServerRoot]} |
- proplists:delete(cacerts, ServerConf)]}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active},
- {verify, verify_peer},
- {cacerts, ServerCas ++ ClientCas} |
- proplists:delete(cacerts, ClientConf)]}]),
- ssl_test_lib:check_result(Server, ok, Client, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
long_chain() ->
[{doc,"Test option verify_peer"}].
diff --git a/lib/ssl/test/ssl_cipher_suite_SUITE.erl b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
index 51788c29e7..e598d662e9 100644
--- a/lib/ssl/test/ssl_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
@@ -45,7 +45,7 @@ groups() ->
{'tlsv1.2', [], kex()},
{'tlsv1.1', [], kex()},
{'tlsv1', [], kex()},
- {'sslv3', [], kex()},
+ {'sslv3', [], ssl3_kex()},
{'dtlsv1.2', [], kex()},
{'dtlsv1', [], kex()},
{dhe_rsa, [],[dhe_rsa_3des_ede_cbc,
@@ -130,6 +130,11 @@ groups() ->
kex() ->
rsa() ++ ecdsa() ++ dss() ++ anonymous().
+
+ssl3_kex() ->
+ ssl3_rsa() ++ ssl3_dss() ++ ssl3_anonymous().
+
+
rsa() ->
[{group, dhe_rsa},
{group, ecdhe_rsa},
@@ -138,6 +143,11 @@ rsa() ->
{group, rsa_psk}
].
+ssl3_rsa() ->
+ [{group, dhe_rsa},
+ {group, rsa}
+ ].
+
ecdsa() ->
[{group, ecdhe_ecdsa}].
@@ -145,6 +155,10 @@ dss() ->
[{group, dhe_dss},
{group, srp_dss}].
+ssl3_dss() ->
+ [{group, dhe_dss}
+ ].
+
anonymous() ->
[{group, dh_anon},
{group, ecdh_anon},
@@ -154,6 +168,10 @@ anonymous() ->
{group, srp_anon}
].
+ssl3_anonymous() ->
+ [{group, dh_anon}].
+
+
init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 003e1fc448..7cfb2ac0c5 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -311,9 +311,11 @@ listen_port_options(Config) when is_list(Config) ->
catch
_:Reason ->
stop_ssl_node(NH2),
+ stop_ssl_node(NH1),
ct:fail(Reason)
end,
stop_ssl_node(NH2),
+ stop_ssl_node(NH1),
success(Config).
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index 1b432970b6..2750a4a9dc 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -214,7 +214,7 @@ encode_decode_srp(_Config) ->
0,3, % HostNameLength
98,97,114>>, % hostname = "bar"
EncodedExts0 = <<?UINT16(_),EncodedExts/binary>> =
- ssl_handshake:encode_hello_extensions(Exts),
+ ssl_handshake:encode_hello_extensions(Exts, {3,3}),
Exts = ssl_handshake:decode_hello_extensions(EncodedExts, {3,3}, {3,3}, client).
signature_algorithms(Config) ->
diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_SUITE.erl
index 878e983bb9..8a76a3a82b 100644
--- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_SUITE.erl
@@ -19,7 +19,7 @@
%%
%%
--module(ssl_npn_handshake_SUITE).
+-module(ssl_npn_SUITE).
%% Note: This directive should only be used in test suites.
-compile(export_all).
diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl
index 46734ba180..7dbc0c5134 100644
--- a/lib/ssl/test/ssl_npn_hello_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl
@@ -24,10 +24,11 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("ssl_cipher.hrl").
--include("ssl_internal.hrl").
--include("tls_handshake.hrl").
--include("tls_record.hrl").
+
+-include_lib("ssl/src/tls_record.hrl").
+-include_lib("ssl/src/tls_handshake.hrl").
+-include_lib("ssl/src/ssl_cipher.hrl").
+-include_lib("ssl/src/ssl_internal.hrl").
-include_lib("common_test/include/ct.hrl").
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl
index 6f11e2bbe8..3c7f6ab20f 100644
--- a/lib/ssl/test/ssl_pem_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl
@@ -34,7 +34,10 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() ->
- [pem_cleanup, invalid_insert].
+ [
+ pem_cleanup,
+ clear_pem_cache,
+ invalid_insert].
groups() ->
[].
@@ -110,6 +113,37 @@ pem_cleanup(Config)when is_list(Config) ->
ssl_test_lib:close(Client),
false = Size == Size1.
+clear_pem_cache() ->
+ [{doc,"Test that internal reference tabel is cleaned properly even when "
+ " the PEM cache is cleared" }].
+clear_pem_cache(Config) when is_list(Config) ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ [_,{FilRefDb, _} |_] = element(6, State),
+ {Server, Client} = basic_verify_test_no_close(Config),
+ CountReferencedFiles = fun({_, -1}, Acc) ->
+ Acc;
+ ({_, N}, Acc) ->
+ N + Acc
+ end,
+
+ 2 = ets:foldl(CountReferencedFiles, 0, FilRefDb),
+ ssl:clear_pem_cache(),
+ _ = sys:get_status(whereis(ssl_manager)),
+ {Server1, Client1} = basic_verify_test_no_close(Config),
+ 4 = ets:foldl(CountReferencedFiles, 0, FilRefDb),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ct:sleep(2000),
+ _ = sys:get_status(whereis(ssl_manager)),
+ 2 = ets:foldl(CountReferencedFiles, 0, FilRefDb),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1),
+ ct:sleep(2000),
+ _ = sys:get_status(whereis(ssl_manager)),
+ 0 = ets:foldl(CountReferencedFiles, 0, FilRefDb).
+
invalid_insert() ->
[{doc, "Test that insert of invalid pem does not cause empty cache entry"}].
invalid_insert(Config)when is_list(Config) ->
@@ -163,3 +197,22 @@ later()->
Gregorian = calendar:datetime_to_gregorian_seconds(DateTime),
calendar:gregorian_seconds_to_datetime(Gregorian + (2 * ?CLEANUP_INTERVAL)).
+basic_verify_test_no_close(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ {Server, Client}.
diff --git a/lib/ssl/test/ssl_renegotiate_SUITE.erl b/lib/ssl/test/ssl_renegotiate_SUITE.erl
new file mode 100644
index 0000000000..ef3f9ebb52
--- /dev/null
+++ b/lib/ssl/test/ssl_renegotiate_SUITE.erl
@@ -0,0 +1,499 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_renegotiate_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-define(SLEEP, 500).
+-define(RENEGOTIATION_DISABLE_TIME, 12000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+groups() ->
+ [{'dtlsv1.2', [], renegotiate_tests()},
+ {'dtlsv1', [], renegotiate_tests()},
+ {'tlsv1.3', [], renegotiate_tests()},
+ {'tlsv1.2', [], renegotiate_tests()},
+ {'tlsv1.1', [], renegotiate_tests()},
+ {'tlsv1', [], renegotiate_tests()},
+ {'sslv3', [], ssl3_renegotiate_tests()}
+ ].
+
+renegotiate_tests() ->
+ [client_renegotiate,
+ server_renegotiate,
+ client_secure_renegotiate,
+ client_secure_renegotiate_fallback,
+ client_renegotiate_reused_session,
+ server_renegotiate_reused_session,
+ client_no_wrap_sequence_number,
+ server_no_wrap_sequence_number,
+ renegotiate_dos_mitigate_active,
+ renegotiate_dos_mitigate_passive,
+ renegotiate_dos_mitigate_absolute].
+
+ssl3_renegotiate_tests() ->
+ [client_renegotiate,
+ server_renegotiate,
+ client_renegotiate_reused_session,
+ server_renegotiate_reused_session,
+ client_no_wrap_sequence_number,
+ server_no_wrap_sequence_number,
+ renegotiate_dos_mitigate_active,
+ renegotiate_dos_mitigate_passive,
+ renegotiate_dos_mitigate_absolute].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+init_per_group(GroupName, Config) ->
+ ssl_test_lib:clean_tls_version(Config),
+ case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ _ ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl:start(),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+client_renegotiate() ->
+ [{doc,"Test ssl:renegotiate/1 on client."}].
+client_renegotiate(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate, [Data]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+client_secure_renegotiate() ->
+ [{doc,"Test ssl:renegotiate/1 on client."}].
+client_secure_renegotiate(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{secure_renegotiate, true} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate, [Data]}},
+ {options, [{reuse_sessions, false},
+ {secure_renegotiate, true}| ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+client_secure_renegotiate_fallback() ->
+ [{doc,"Test that we can set secure_renegotiate to false that is "
+ "fallback option, we however do not have a insecure server to test against!"}].
+client_secure_renegotiate_fallback(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{secure_renegotiate, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate, [Data]}},
+ {options, [{reuse_sessions, false},
+ {secure_renegotiate, false}| ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_renegotiate() ->
+ [{doc,"Test ssl:renegotiate/1 on server."}].
+server_renegotiate(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+client_renegotiate_reused_session() ->
+ [{doc,"Test ssl:renegotiate/1 on client when the ssl session will be reused."}].
+client_renegotiate_reused_session(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_reuse_session, [Data]}},
+ {options, [{reuse_sessions, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+server_renegotiate_reused_session() ->
+ [{doc,"Test ssl:renegotiate/1 on server when the ssl session will be reused."}].
+server_renegotiate_reused_session(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_reuse_session, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{reuse_sessions, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+client_no_wrap_sequence_number() ->
+ [{doc,"Test that erlang client will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."}].
+
+client_no_wrap_sequence_number(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to erlang",
+ N = 12,
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Version = ssl_test_lib:protocol_version(Config, tuple),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[ErlData, treashold(N, Version)]]}},
+ {options, [{reuse_sessions, false},
+ {renegotiate_at, N} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_no_wrap_sequence_number() ->
+ [{doc, "Test that erlang server will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."}].
+
+server_no_wrap_sequence_number(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+ N = 12,
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[Data, N+2]]}},
+ {options, [{renegotiate_at, N} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+renegotiate_dos_mitigate_active() ->
+ [{doc, "Mitigate DOS computational attack by not allowing client to renegotiate many times in a row",
+ "immediately after each other"}].
+renegotiate_dos_mitigate_active(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_immediately, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+renegotiate_dos_mitigate_passive() ->
+ [{doc, "Mitigate DOS computational attack by not allowing client to renegotiate many times in a row",
+ "immediately after each other"}].
+renegotiate_dos_mitigate_passive(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_immediately, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+renegotiate_dos_mitigate_absolute() ->
+ [{doc, "Mitigate DOS computational attack by not allowing client to initiate renegotiation"}].
+renegotiate_dos_mitigate_absolute(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{client_renegotiation, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate_rejected,
+ []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+renegotiate(Socket, Data) ->
+ ct:log("Renegotiating ~n", []),
+ Result = ssl:renegotiate(Socket),
+ ct:log("Result ~p~n", [Result]),
+ ssl:send(Socket, Data),
+ case Result of
+ ok ->
+ ok;
+ Other ->
+ Other
+ end.
+
+renegotiate_reuse_session(Socket, Data) ->
+ %% Make sure session is registered
+ ct:sleep(?SLEEP),
+ renegotiate(Socket, Data).
+
+renegotiate_immediately(Socket) ->
+ _ = ssl_test_lib:active_recv(Socket, 11),
+ ok = ssl:renegotiate(Socket),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ ct:sleep(?RENEGOTIATION_DISABLE_TIME + ?SLEEP),
+ ok = ssl:renegotiate(Socket),
+ ct:log("Renegotiated again"),
+ ssl:send(Socket, "Hello world"),
+ ok.
+
+renegotiate_rejected(Socket) ->
+ _ = ssl_test_lib:active_recv(Socket, 11),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ ct:sleep(?RENEGOTIATION_DISABLE_TIME +1),
+ {error, renegotiation_rejected} = ssl:renegotiate(Socket),
+ ct:log("Failed to renegotiate again"),
+ ssl:send(Socket, "Hello world"),
+ ok.
+
+%% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast
+treashold(N, {3,0}) ->
+ (N div 2) + 1;
+treashold(N, {3,1}) ->
+ (N div 2) + 1;
+treashold(N, _) ->
+ N + 1.
+
+erlang_ssl_receive(Socket, Data) ->
+ case ssl_test_lib:active_recv(Socket, length(Data)) of
+ Data ->
+ ok;
+ Other ->
+ ct:fail({{expected, Data}, {got, Other}})
+ end.
diff --git a/lib/ssl/test/ssl_session_SUITE.erl b/lib/ssl/test/ssl_session_SUITE.erl
new file mode 100644
index 0000000000..aa79698a72
--- /dev/null
+++ b/lib/ssl/test/ssl_session_SUITE.erl
@@ -0,0 +1,377 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_session_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("tls_handshake.hrl").
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-define(SLEEP, 500).
+-define(EXPIRE, 10).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
+ ].
+
+groups() ->
+ [{'dtlsv1.2', [], session_tests()},
+ {'dtlsv1', [], session_tests()},
+ {'tlsv1.3', [], session_tests()},
+ {'tlsv1.2', [], session_tests()},
+ {'tlsv1.1', [], session_tests()},
+ {'tlsv1', [], session_tests()},
+ {'sslv3', [], session_tests()}
+ ].
+
+session_tests() ->
+ [reuse_session,
+ reuse_session_expired,
+ server_does_not_want_to_reuse_session,
+ no_reuses_session_server_restart_new_cert,
+ no_reuses_session_server_restart_new_cert_file].
+
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ ssl_test_lib:make_dsa_cert(Config)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+init_per_group(GroupName, Config) ->
+ ssl_test_lib:clean_tls_version(Config),
+ case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ _ ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl:start(),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(reuse_session_expired, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ ssl_test_lib:clean_env(),
+ application:set_env(ssl, session_lifetime, ?EXPIRE),
+ application:set_env(ssl, session_delay_cleanup_time, 500),
+ ssl:start(),
+ ct:timetrap({seconds, 30}),
+ Config;
+init_per_testcase(_, Config) ->
+ ct:timetrap({seconds, 15}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+reuse_session() ->
+ [{doc,"Test reuse of sessions (short handshake)"}].
+reuse_session(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+
+ ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
+%%--------------------------------------------------------------------
+reuse_session_expired() ->
+ [{doc,"Test sessions is not reused when it has expired"}].
+reuse_session_expired(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server0 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {tcp_options, [{active, false}]},
+ {options, ServerOpts}]),
+ Port0 = ssl_test_lib:inet_port(Server0),
+
+ Client0 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port0}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_id, []}},
+ {from, self()}, {options, [{reuse_sessions, save} | ClientOpts]}]),
+ Server0 ! listen,
+
+ Client1 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port0}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_id, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SID = receive
+ {Client0, Id0} ->
+ Id0
+ end,
+
+ receive
+ {Client1, SID} ->
+ ok
+ after ?SLEEP ->
+ ct:fail(session_not_reused)
+ end,
+
+ Server0 ! listen,
+
+ %% Make sure session is unregistered due to expiration
+ ct:sleep((?EXPIRE*2)),
+
+ make_sure_expired(Hostname, Port0, SID),
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port0}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_id, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client2, SID} ->
+ ct:fail(session_reused_when_session_expired);
+ {Client2, _} ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ ssl_test_lib:close(Server0),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2).
+
+make_sure_expired(Host, Port, Id) ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ ClientCache = element(2, State),
+
+ case ssl_session_cache:lookup(ClientCache, {{Host, Port}, Id}) of
+ undefined ->
+ ok;
+ #session{is_resumable = false} ->
+ ok;
+ _ ->
+ ct:sleep(?SLEEP),
+ make_sure_expired(Host, Port, Id)
+ end.
+
+%%--------------------------------------------------------------------
+server_does_not_want_to_reuse_session() ->
+ [{doc,"Test reuse of sessions (short handshake)"}].
+server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {options, [{reuse_session, fun(_,_,_,_) ->
+ false
+ end} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+
+ %% Make sure session is registered
+ ct:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ct:fail(session_reused_when_server_does_not_want_to);
+ {Client1, _Other} ->
+ ok
+ end,
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client1).
+
+no_reuses_session_server_restart_new_cert() ->
+ [{doc,"Check that a session is not reused if the server is restarted with a new cert."}].
+no_reuses_session_server_restart_new_cert(Config) when is_list(Config) ->
+
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ DsaServerOpts = ssl_test_lib:ssl_options(server_dsa_verify_opts, Config),
+ DsaClientOpts = ssl_test_lib:ssl_options(client_dsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ %% Make sure session is registered
+ ct:sleep(?SLEEP),
+ Monitor = erlang:monitor(process, Server),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ receive
+ {'DOWN', Monitor, _, _, _} ->
+ ok
+ end,
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{reuseaddr, true} | DsaServerOpts]}]),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {from, self()}, {options, DsaClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ct:fail(session_reused_when_server_has_new_cert);
+ {Client1, _Other} ->
+ ok
+ end,
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+no_reuses_session_server_restart_new_cert_file() ->
+ [{doc,"Check that a session is not reused if a server is restarted with a new "
+ "cert contained in a file with the same name as the old cert."}].
+
+no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ DsaServerOpts = ssl_test_lib:ssl_options(server_dsa_verify_opts, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+
+ NewServerOpts0 = ssl_test_lib:new_config(PrivDir, ServerOpts),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {options, NewServerOpts0}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ %% Make sure session is registered and we get
+ %% new file time stamp when calling new_config!
+ ct:sleep(?SLEEP* 2),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+
+ ssl:clear_pem_cache(),
+
+ NewServerOpts1 = ssl_test_lib:new_config(PrivDir, DsaServerOpts),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{reuseaddr, true} | NewServerOpts1]}]),
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ct:fail(session_reused_when_server_has_new_cert);
+ {Client1, _Other} ->
+ ok
+ end,
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_sni_SUITE.erl b/lib/ssl/test/ssl_sni_SUITE.erl
index 7629d75100..e68ea2c99d 100644
--- a/lib/ssl/test/ssl_sni_SUITE.erl
+++ b/lib/ssl/test/ssl_sni_SUITE.erl
@@ -36,7 +36,6 @@ all() ->
[{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
- {group, 'sslv3'},
{group, 'dtlsv1.2'},
{group, 'dtlsv1'}
].
@@ -46,7 +45,6 @@ groups() ->
{'tlsv1.2', [], sni_tests()},
{'tlsv1.1', [], sni_tests()},
{'tlsv1', [], sni_tests()},
- {'sslv3', [], sni_tests()},
{'dtlsv1.2', [], sni_tests()},
{'dtlsv1', [], sni_tests()}
].
@@ -61,7 +59,8 @@ sni_tests() ->
dns_name,
ip_fallback,
no_ip_fallback,
- dns_name_reuse].
+ dns_name_reuse,
+ customize_hostname_check].
init_per_suite(Config0) ->
catch crypto:stop(),
@@ -88,12 +87,10 @@ end_per_suite(_) ->
ssl:stop(),
application:stop(crypto).
-init_per_testcase(TestCase, Config) when TestCase == ip_fallback;
- TestCase == no_ip_fallback;
- TestCase == dns_name_reuse ->
+init_per_testcase(customize_hostname_check, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]),
- ct:timetrap({seconds, 20}),
+ ssl_test_lib:clean_start(),
+ ct:timetrap({seconds, 5}),
Config;
init_per_testcase(_TestCase, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
@@ -236,7 +233,60 @@ dns_name_reuse(Config) ->
{mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, [{verify, verify_peer} | ClientConf]}]),
- ssl_test_lib:check_client_alert(Client1, handshake_failure).
+ ssl_test_lib:check_client_alert(Client1, handshake_failure),
+ ssl_test_lib:close(Client0).
+
+
+customize_hostname_check() ->
+ [{doc,"Test option customize_hostname_check."}].
+customize_hostname_check(Config) when is_list(Config) ->
+ Ext = [#'Extension'{extnID = ?'id-ce-subjectAltName',
+ extnValue = [{dNSName, "*.example.org"}],
+ critical = false}
+ ],
+ #{server_config := ServerOpts0,
+ client_config := ClientOpts0} = ssl_test_lib:make_cert_chains_pem(rsa, [{server_chain,
+ [[],
+ [],
+ [{extensions, Ext}]
+ ]}],
+ Config, "https_hostname_convention"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ CustomFun = public_key:pkix_verify_hostname_match_fun(https),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options,
+ [{verify, verify_peer},
+ {server_name_indication, "other.example.org"},
+ {customize_hostname_check,
+ [{match_fun, CustomFun}]} | ClientOpts]
+ }]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+
+ Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{verify, verify_peer},
+ {server_name_indication, "other.example.org"} | ClientOpts]}
+ ]),
+ ssl_test_lib:check_client_alert(Server, Client1, handshake_failure).
%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------
diff --git a/lib/ssl/test/ssl_socket_SUITE.erl b/lib/ssl/test/ssl_socket_SUITE.erl
new file mode 100644
index 0000000000..d648f2f9e1
--- /dev/null
+++ b/lib/ssl/test/ssl_socket_SUITE.erl
@@ -0,0 +1,437 @@
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_socket_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-define(SLEEP, 500).
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, tls},
+ {group, dtls}
+ ].
+
+groups() ->
+ [
+ {tls,[], socket_tests() ++ raw_inet_opt()},
+ {dtls,[], socket_tests()}
+ ].
+
+socket_tests() ->
+ [
+ getstat,
+ socket_options,
+ invalid_inet_get_option,
+ invalid_inet_get_option_not_list,
+ invalid_inet_get_option_improper_list,
+ invalid_inet_set_option,
+ invalid_inet_set_option_not_list,
+ invalid_inet_set_option_improper_list
+ ].
+
+raw_inet_opt() ->
+ [
+ raw_inet_option
+ ].
+
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+init_per_group(dtls, Config) ->
+ [{protocol_opts, [{protocol, dtls}]} | proplists:delete(protocol_opts, Config)];
+init_per_group(tls, Config) ->
+ [{protocol_opts, [{protocol, tls}]} | proplists:delete(protocol_opts, Config)];
+init_per_group(_GroupName, Config) ->
+ [{client_type, erlang},
+ {server_type, erlang} | Config].
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(raw_inet_option, Config) ->
+ ct:timetrap({seconds, 5}),
+ case os:type() of
+ {unix,linux} ->
+ Config;
+ _ ->
+ {skip, "Raw options are platform-specific"}
+ end;
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+getstat() ->
+ [{doc,"Test API function getstat/2"}].
+
+getstat(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_rsa_opts, Config),
+ ServerOpts = ?config(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port1 = ssl_test_lib:inet_port(Server1),
+ Server2 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port2 = ssl_test_lib:inet_port(Server2),
+ {ok, ActiveC} = rpc:call(ClientNode, ssl, connect,
+ [Hostname,Port1,[{active, once}|ClientOpts]]),
+ {ok, PassiveC} = rpc:call(ClientNode, ssl, connect,
+ [Hostname,Port2,[{active, false}|ClientOpts]]),
+
+ ct:log("Testcase ~p, Client ~p Servers ~p, ~p ~n",
+ [self(), self(), Server1, Server2]),
+
+ %% We only check that the values are non-zero initially
+ %% (due to the handshake), and that sending more changes the values.
+
+ %% Passive socket.
+
+ {ok, InitialStats} = ssl:getstat(PassiveC),
+ ct:pal("InitialStats ~p~n", [InitialStats]),
+ [true] = lists:usort([0 =/= proplists:get_value(Name, InitialStats)
+ || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
+
+ ok = ssl:send(PassiveC, "Hello world"),
+ wait_for_send(PassiveC),
+ {ok, SStats} = ssl:getstat(PassiveC, [send_cnt, send_oct]),
+ ct:pal("SStats ~p~n", [SStats]),
+ [true] = lists:usort([proplists:get_value(Name, SStats) =/= proplists:get_value(Name, InitialStats)
+ || Name <- [send_cnt, send_oct]]),
+
+ %% Active socket.
+
+ {ok, InitialAStats} = ssl:getstat(ActiveC),
+ ct:pal("InitialAStats ~p~n", [InitialAStats]),
+ [true] = lists:usort([0 =/= proplists:get_value(Name, InitialAStats)
+ || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
+
+ _ = receive
+ {ssl, ActiveC, _} ->
+ ok
+ after
+ ?SLEEP ->
+ exit(timeout)
+ end,
+
+ ok = ssl:send(ActiveC, "Hello world"),
+ wait_for_send(ActiveC),
+ {ok, ASStats} = ssl:getstat(ActiveC, [send_cnt, send_oct]),
+ ct:pal("ASStats ~p~n", [ASStats]),
+ [true] = lists:usort([proplists:get_value(Name, ASStats) =/= proplists:get_value(Name, InitialAStats)
+ || Name <- [send_cnt, send_oct]]),
+
+ ok.
+%%--------------------------------------------------------------------
+socket_options() ->
+ [{doc,"Test API function getopts/2 and setopts/2"}].
+
+socket_options(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, mode],
+
+ NewValues = [{mode, binary}, {active, once}],
+ %% Shall be the reverse order of NewValues!
+ NewOptions = [active, mode],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+
+ {ok, Listen} = ssl:listen(0, ServerOpts),
+ {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
+ ok = ssl:setopts(Listen, [{mode, binary}]),
+ {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
+ {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
+ ssl:close(Listen).
+
+%%--------------------------------------------------------------------
+raw_inet_option() ->
+ [{doc,"Ensure that a single 'raw' option is passed to ssl:listen correctly."}].
+
+raw_inet_option(Config) when is_list(Config) ->
+ % 'raw' option values are platform-specific; these are the Linux values:
+ IpProtoTcp = 6,
+ % Use TCP_KEEPIDLE, because (e.g.) TCP_MAXSEG can't be read back reliably.
+ TcpKeepIdle = 4,
+ KeepAliveTimeSecs = 55,
+ LOptions = [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}],
+ {ok, LSocket} = ssl:listen(0, LOptions),
+ % Per http://www.erlang.org/doc/man/inet.html#getopts-2, we have to specify
+ % exactly which raw option we want, and the size of the buffer.
+ {ok, [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}]} =
+ ssl:getopts(LSocket, [{raw, IpProtoTcp, TcpKeepIdle, 4}]).
+
+%%--------------------------------------------------------------------
+
+invalid_inet_get_option() ->
+ [{doc,"Test handling of invalid inet options in getopts"}].
+
+invalid_inet_get_option(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, get_invalid_inet_option, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option_not_list() ->
+ [{doc,"Test handling of invalid type in getopts"}].
+
+invalid_inet_get_option_not_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, get_invalid_inet_option_not_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option_improper_list() ->
+ [{doc,"Test handling of invalid type in getopts"}].
+
+invalid_inet_get_option_improper_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, get_invalid_inet_option_improper_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option() ->
+ [{doc,"Test handling of invalid inet options in setopts"}].
+
+invalid_inet_set_option(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, set_invalid_inet_option, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option_not_list() ->
+ [{doc,"Test handling of invalid type in setopts"}].
+
+invalid_inet_set_option_not_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, set_invalid_inet_option_not_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option_improper_list() ->
+ [{doc,"Test handling of invalid tye in setopts"}].
+
+invalid_inet_set_option_improper_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, set_invalid_inet_option_improper_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+ %% Test get/set emulated opts
+ {ok, DefaultValues} = ssl:getopts(Socket, Options),
+ ssl:setopts(Socket, NewValues),
+ {ok, NewValues} = ssl:getopts(Socket, NewOptions),
+ %% Test get/set inet opts
+ {ok,[{reuseaddr, _}]} = ssl:getopts(Socket, [reuseaddr]),
+ {ok, All} = ssl:getopts(Socket, []),
+ ct:log("All opts ~p~n", [All]),
+ ok.
+
+get_invalid_inet_option(Socket) ->
+ {error, {options, {socket_options, foo, _}}} = ssl:getopts(Socket, [foo]),
+ ok.
+
+get_invalid_inet_option_not_list(Socket) ->
+ {error, {options, {socket_options, some_invalid_atom_here}}}
+ = ssl:getopts(Socket, some_invalid_atom_here),
+ ok.
+
+get_invalid_inet_option_improper_list(Socket) ->
+ {error, {options, {socket_options, foo,_}}} = ssl:getopts(Socket, [packet | foo]),
+ ok.
+
+set_invalid_inet_option(Socket) ->
+ {error, {options, {socket_options, {packet, foo}}}} = ssl:setopts(Socket, [{packet, foo}]),
+ {error, {options, {socket_options, {header, foo}}}} = ssl:setopts(Socket, [{header, foo}]),
+ {error, {options, {socket_options, {active, foo}}}} = ssl:setopts(Socket, [{active, foo}]),
+ {error, {options, {socket_options, {mode, foo}}}} = ssl:setopts(Socket, [{mode, foo}]),
+ ok.
+
+set_invalid_inet_option_not_list(Socket) ->
+ {error, {options, {not_a_proplist, some_invalid_atom_here}}}
+ = ssl:setopts(Socket, some_invalid_atom_here),
+ ok.
+
+set_invalid_inet_option_improper_list(Socket) ->
+ {error, {options, {not_a_proplist, [{packet, 0} | {foo, 2}]}}} =
+ ssl:setopts(Socket, [{packet, 0} | {foo, 2}]),
+ ok.
+
+wait_for_send(Socket) ->
+ %% Make sure TLS process processed send message event
+ _ = ssl:connection_information(Socket).
+
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index a081d65200..7dd27fb5cb 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -218,6 +218,55 @@ start_server_transport_control(Args) ->
Result
end.
+start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, OpensslServerOpts, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ClientOpts = ErlangClientOpts ++ ClientOpts0,
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = case OpensslServerOpts of
+ [] ->
+ ["s_server", "-accept",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile,"-key", KeyFile];
+ [Opt, Value] ->
+ ["s_server", Opt, Value, "-accept",
+ integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-CAfile", CaCertFile,
+ "-cert", CertFile,"-key", KeyFile]
+ end,
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ active_recv, [length(Data)]}},
+ {options, ClientOpts}]),
+
+ Callback(Client, OpensslPort),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false).
+
transport_accept_abuse(Opts) ->
Port = proplists:get_value(port, Opts),
@@ -233,6 +282,34 @@ transport_accept_abuse(Opts) ->
_ = ssl:handshake(AcceptSocket, infinity),
Pid ! {self(), ok}.
+start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenSSLClientOpts, Data, Callback) ->
+ process_flag(trap_exit, true),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ServerOpts = ErlangServerOpts ++ ServerOpts0,
+
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, active_recv, [length(Data)]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Version = ssl_test_lib:protocol_version(Config),
+
+ Exe = "openssl",
+ Args = ["s_client"] ++ OpenSSLClientOpts ++ ["-msg", "-connect",
+ hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
+ ssl_test_lib:version_flag(Version)],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ Callback(Server, OpenSslPort),
+
+ ssl_test_lib:close(Server),
+
+ ssl_test_lib:close_port(OpenSslPort),
+ process_flag(trap_exit, false).
transport_switch_control(Opts) ->
Port = proplists:get_value(port, Opts),
@@ -571,8 +648,7 @@ cert_options(Config) ->
"badcert.pem"]),
BadKeyFile = filename:join([proplists:get_value(priv_dir, Config),
"badkey.pem"]),
- PskSharedSecret = <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15>>,
-
+
[{client_opts, [{cacertfile, ClientCaCertFile},
{certfile, ClientCertFile},
{keyfile, ClientKeyFile}]},
@@ -586,30 +662,6 @@ cert_options(Config) ->
{ssl_imp, new}]},
{server_opts, [{ssl_imp, new},{reuseaddr, true}, {cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
- {client_psk, [{ssl_imp, new},
- {psk_identity, "Test-User"},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
- {server_psk, [{ssl_imp, new},{reuseaddr, true},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
- {server_psk_hint, [{ssl_imp, new},{reuseaddr, true},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile},
- {psk_identity, "HINT"},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
- {server_psk_anon, [{ssl_imp, new},{reuseaddr, true},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
- {server_psk_anon_hint, [{ssl_imp, new},{reuseaddr, true},
- {psk_identity, "HINT"},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
- {client_srp, [{ssl_imp, new},
- {srp_identity, {"Test-User", "secret"}}]},
- {server_srp, [{ssl_imp, new},{reuseaddr, true},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile},
- {user_lookup_fun, {fun user_lookup/3, undefined}},
- {ciphers, srp_suites()}]},
- {server_srp_anon, [{ssl_imp, new},{reuseaddr, true},
- {user_lookup_fun, {fun user_lookup/3, undefined}},
- {ciphers, srp_anon_suites()}]},
{server_verification_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ClientCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -650,15 +702,32 @@ make_dsa_cert(Config) ->
[{server_dsa_opts, ServerConf},
{server_dsa_verify_opts, [{verify, verify_peer} | ServerConf]},
- {client_dsa_opts, ClientConf},
- {server_srp_dsa, [{user_lookup_fun, {fun user_lookup/3, undefined}},
- {ciphers, srp_dss_suites()} | ServerConf]},
- {client_srp_dsa, [{srp_identity, {"Test-User", "secret"}}
- | ClientConf]}
+ {client_dsa_opts, ClientConf}
| Config];
false ->
Config
end.
+
+
+make_cert_chains_der(Alg, UserConf) ->
+ ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()),
+ CertChainConf = gen_conf(Alg, Alg, ClientChain, ServerChain),
+ public_key:pkix_test_data(CertChainConf).
+
+make_cert_chains_pem(Alg, UserConf, Config, Suffix) ->
+ ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()),
+ CertChainConf = gen_conf(Alg, Alg, ClientChain, ServerChain),
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(Alg) ++ Suffix]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(Alg) ++ Suffix]),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
+ Conf = x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
+ CConf = proplists:get_value(client_config, Conf),
+ SConf = proplists:get_value(server_config, Conf),
+ #{server_config => SConf,
+ client_config => CConf}.
+
make_rsa_cert_chains(UserConf, Config, Suffix) ->
ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()),
ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()),
@@ -1156,6 +1225,52 @@ basic_test(COpts, SOpts, Config) ->
gen_check_result(Server, SType, Client, CType),
stop(Server, Client).
+basic_alert(ClientOpts, ServerOpts, Config, Alert) ->
+ SType = proplists:get_value(server_type, Config),
+ CType = proplists:get_value(client_type, Config),
+ run_basic_alert(SType, CType, ClientOpts, ServerOpts, Config, Alert).
+
+run_basic_alert(erlang, erlang, ClientOpts, ServerOpts, Config, Alert) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ServerOpts}]),
+
+ Port = inet_port(Server),
+
+ Client = start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ check_server_alert(Server, Client, Alert);
+run_basic_alert(openssl = SType, erlang, ClientOpts, ServerOpts, Config, Alert) ->
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+ {_Server, Port} = start_server(SType, ClientOpts, ServerOpts, Config),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+ Client = start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ check_client_alert(Client, Alert);
+run_basic_alert(erlang, openssl = CType, ClientOpts, ServerOpts, Config, Alert) ->
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = start_server_error([{node, ServerNode}, {port, 0},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ServerOpts}]),
+ Port = inet_port(Server),
+ start_client(CType, Port, ClientOpts, Config),
+
+ check_server_alert(Server, Alert).
+
+
ecc_test(Expect, COpts, SOpts, CECCOpts, SECCOpts, Config) ->
{Server, Port} = start_server_ecc(erlang, SOpts, Expect, SECCOpts, Config),
Client = start_client_ecc(erlang, Port, COpts, Expect, CECCOpts, Config),
@@ -1197,15 +1312,22 @@ start_basic_client(openssl, Version, Port, ClientOpts) ->
OpenSslPort.
start_client(openssl, Port, ClientOpts, Config) ->
- Cert = proplists:get_value(certfile, ClientOpts),
- Key = proplists:get_value(keyfile, ClientOpts),
- CA = proplists:get_value(cacertfile, ClientOpts),
Version = ssl_test_lib:protocol_version(Config),
Exe = "openssl",
- Args0 = ["s_client", "-verify", "2", "-port", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", Cert, "-CAfile", CA,
- "-key", Key, "-host","localhost", "-msg", "-debug"],
+ Ciphers = proplists:get_value(ciphers, ClientOpts, ssl:cipher_suites(default,Version)),
+ Groups0 = proplists:get_value(groups, ClientOpts),
+ CertArgs = openssl_cert_options(ClientOpts, client),
+ Exe = "openssl",
+ Args0 = case Groups0 of
+ undefined ->
+ ["s_client", "-verify", "2", "-port", integer_to_list(Port), cipher_flag(Version),
+ ciphers(Ciphers, Version),
+ ssl_test_lib:version_flag(Version)] ++ CertArgs ++ ["-msg", "-debug"];
+ Group ->
+ ["s_client", "-verify", "2", "-port", integer_to_list(Port), cipher_flag(Version),
+ ciphers(Ciphers, Version), "-groups", Group,
+ ssl_test_lib:version_flag(Version)] ++ CertArgs ++ ["-msg", "-debug"]
+ end,
Args = maybe_force_ipv4(Args0),
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, "Hello world"),
@@ -1257,24 +1379,54 @@ start_server(openssl, ClientOpts, ServerOpts, Config) ->
Port = inet_port(node()),
Version = protocol_version(Config),
Exe = "openssl",
- CertArgs = openssl_cert_options(ServerOpts),
- [Cipher|_] = proplists:get_value(ciphers, ClientOpts, ssl:cipher_suites(default,Version)),
- Args = ["s_server", "-accept", integer_to_list(Port), "-cipher",
- ssl_cipher_format:suite_map_to_openssl_str(Cipher),
- ssl_test_lib:version_flag(Version)] ++ CertArgs ++ ["-msg", "-debug"],
+ CertArgs = openssl_cert_options(ServerOpts, server),
+ Ciphers = proplists:get_value(ciphers, ClientOpts, ssl:cipher_suites(default,Version)),
+ Groups0 = proplists:get_value(groups, ServerOpts),
+ Args = case Groups0 of
+ undefined ->
+ ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version),
+ ciphers(Ciphers, Version),
+ ssl_test_lib:version_flag(Version)] ++ CertArgs ++ ["-msg", "-debug"];
+ Group ->
+ ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version),
+ ciphers(Ciphers, Version), "-groups", Group,
+ ssl_test_lib:version_flag(Version)] ++ CertArgs ++ ["-msg", "-debug"]
+ end,
OpenSslPort = portable_open_port(Exe, Args),
true = port_command(OpenSslPort, "Hello world"),
{OpenSslPort, Port};
start_server(erlang, _, ServerOpts, Config) ->
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
KeyEx = proplists:get_value(check_keyex, Config, false),
+ Versions = protocol_versions(Config),
Server = start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib,
check_key_exchange_send_active,
[KeyEx]}},
- {options, [{verify, verify_peer} | ServerOpts]}]),
+ {options, [{verify, verify_peer}, {versions, Versions} | ServerOpts]}]),
{Server, inet_port(Server)}.
+
+cipher_flag('tlsv1.3') ->
+ "-ciphersuites";
+cipher_flag(_) ->
+ "-cipher".
+
+ciphers(Ciphers, Version) ->
+ Strs = [ssl_cipher_format:suite_map_to_openssl_str(Cipher) || Cipher <- Ciphers],
+ ciphers_concat(Version, Strs, "").
+
+ciphers_concat(_, [], [":" | Acc]) ->
+ lists:append(lists:reverse(Acc));
+ciphers_concat('tlsv1.3' = Version, [Head| Tail], Acc) ->
+ case Head of
+ "TLS" ++ _ ->
+ ciphers_concat(Version, Tail, [":", Head | Acc]);
+ _ ->
+ ciphers_concat(Version, Tail, Acc)
+ end;
+ciphers_concat(Version, [Head| Tail], Acc) ->
+ ciphers_concat(Version, Tail, [":", Head | Acc]).
start_server_with_raw_key(erlang, ServerOpts, Config) ->
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
@@ -1329,23 +1481,31 @@ stop(Client, Server) ->
close(Client).
-openssl_cert_options(ServerOpts) ->
- Cert = proplists:get_value(certfile, ServerOpts, undefined),
- Key = proplists:get_value(keyfile, ServerOpts, undefined),
- CA = proplists:get_value(cacertfile, ServerOpts, undefined),
+openssl_cert_options(Opts, Role) ->
+ Cert = proplists:get_value(certfile, Opts, undefined),
+ Key = proplists:get_value(keyfile, Opts, undefined),
+ CA = proplists:get_value(cacertfile, Opts, undefined),
case CA of
undefined ->
case cert_option("-cert", Cert) ++ cert_option("-key", Key) of
- [] ->
+ [] when Role == server ->
["-nocert"];
Other ->
Other
end;
_ ->
cert_option("-cert", Cert) ++ cert_option("-CAfile", CA) ++
- cert_option("-key", Key) ++ ["-verify", "2"]
+ cert_option("-key", Key) ++ openssl_verify(Opts) ++ ["2"]
end.
+openssl_verify(Opts) ->
+ case proplists:get_value(fail_if_no_peer_cert, Opts, undefined) of
+ true ->
+ ["-Verify"];
+ _ ->
+ ["-verify"]
+ end.
+
cert_option(_, undefined) ->
[];
cert_option(Opt, Value) ->
@@ -2005,12 +2165,61 @@ check_sane_openssl_version(Version) ->
false;
{'tlsv1.1', "OpenSSL 0" ++ _} ->
false;
+ {'tlsv1', "OpenSSL 0" ++ _} ->
+ false;
{_, _} ->
true
end;
false ->
false
end.
+check_sane_openssl_renegotaite(Config, Version) when Version == 'tlsv1.1';
+ Version == 'tlsv1.2' ->
+ case os:cmd("openssl version") of
+ "OpenSSL 1.0.1c" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ "OpenSSL 1.0.1b" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ "OpenSSL 1.0.1a" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ "OpenSSL 1.0.1 " ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ _ ->
+ check_sane_openssl_renegotaite(Config)
+ end;
+check_sane_openssl_renegotaite(Config, _) ->
+ check_sane_openssl_renegotaite(Config).
+
+check_sane_openssl_renegotaite(Config) ->
+ case os:cmd("openssl version") of
+ "OpenSSL 1.0.0" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ "OpenSSL 0.9.8" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ "OpenSSL 0.9.7" ++ _ ->
+ {skip, "Known renegotiation bug in OpenSSL"};
+ _ ->
+ Config
+ end.
+
+workaround_openssl_s_clinent() ->
+ %% http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683159
+ %% https://bugs.archlinux.org/task/33919
+ %% Bug seems to manifests it self if TLS version is not
+ %% explicitly specified
+ case os:cmd("openssl version") of
+ "OpenSSL 1.0.1c" ++ _ ->
+ ["-no_tls1_2"];
+ "OpenSSL 1.0.1d" ++ _ ->
+ ["-no_tls1_2"];
+ "OpenSSL 1.0.1e" ++ _ ->
+ ["-no_tls1_2"];
+ "OpenSSL 1.0.1f" ++ _ ->
+ ["-no_tls1_2"];
+ _ ->
+ []
+ end.
+
enough_openssl_crl_support("OpenSSL 0." ++ _) -> false;
enough_openssl_crl_support(_) -> true.
@@ -2060,8 +2269,8 @@ filter_suites(Ciphers0, AtomVersion) ->
++ ssl_cipher:anonymous_suites(Version)
++ ssl_cipher:psk_suites(Version)
++ ssl_cipher:psk_suites_anon(Version)
- ++ ssl_cipher:srp_suites()
- ++ ssl_cipher:srp_suites_anon()
+ ++ ssl_cipher:srp_suites(Version)
+ ++ ssl_cipher:srp_suites_anon(Version)
++ ssl_cipher:rc4_suites(Version),
Supported1 = ssl_cipher:filter_suites(Supported0),
Supported2 = [ssl_cipher_format:suite_bin_to_map(S) || S <- Supported1],
@@ -2178,6 +2387,14 @@ protocol_version(Config, atom) ->
tls_record:protocol_version(protocol_version(Config, tuple))
end.
+protocol_versions(Config) ->
+ Version = protocol_version(Config),
+ case Version of
+ 'tlsv1.3' -> %% TLS-1.3 servers shall also support 1.2
+ ['tlsv1.3', 'tlsv1.2'];
+ _ ->
+ [Version]
+ end.
protocol_options(Config, Options) ->
Protocol = proplists:get_value(protocol, Config, tls),
{Protocol, Opts} = lists:keyfind(Protocol, 1, Options),
@@ -2496,3 +2713,78 @@ digest() ->
_ ->
{digest, sha1}
end.
+
+kill_openssl() ->
+ case os:type() of
+ {unix, _} ->
+ os:cmd("pkill openssl");
+ {win32, _} ->
+ os:cmd("cmd.exe /C \"taskkill /IM openssl.exe /F\"")
+ end.
+
+hostname_format(Hostname) ->
+ case lists:member($., Hostname) of
+ true ->
+ Hostname;
+ false ->
+ "localhost"
+ end.
+
+erlang_ssl_receive_and_assert_negotiated_protocol(Socket, Protocol, Data) ->
+ case ssl:negotiated_protocol(Socket) of
+ {ok, Protocol} ->
+ active_recv(Socket, length(Data));
+ Result ->
+ {error, {{expected, Protocol}, {got, Result}}}
+ end.
+
+check_openssl_npn_support(Config) ->
+ HelpText = os:cmd("openssl s_client --help"),
+ case string:str(HelpText, "nextprotoneg") of
+ 0 ->
+ {skip, "Openssl not compiled with nextprotoneg support"};
+ _ ->
+ Config
+ end.
+
+new_config(PrivDir, ServerOpts0) ->
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts0),
+ CertFile = proplists:get_value(certfile, ServerOpts0),
+ KeyFile = proplists:get_value(keyfile, ServerOpts0),
+ NewCaCertFile = filename:join(PrivDir, "new_ca.pem"),
+ NewCertFile = filename:join(PrivDir, "new_cert.pem"),
+ NewKeyFile = filename:join(PrivDir, "new_key.pem"),
+ file:copy(CaCertFile, NewCaCertFile),
+ file:copy(CertFile, NewCertFile),
+ file:copy(KeyFile, NewKeyFile),
+ ServerOpts1 = proplists:delete(cacertfile, ServerOpts0),
+ ServerOpts2 = proplists:delete(certfile, ServerOpts1),
+ ServerOpts = proplists:delete(keyfile, ServerOpts2),
+
+ {ok, PEM} = file:read_file(NewCaCertFile),
+ ct:log("CA file content: ~p~n", [public_key:pem_decode(PEM)]),
+
+ [{cacertfile, NewCaCertFile}, {certfile, NewCertFile},
+ {keyfile, NewKeyFile} | ServerOpts].
+
+sane_openssl_alpn_npn_renegotiate() ->
+ case os:cmd("openssl version") of
+ "LibreSSL 2.9.1" ++ _ ->
+ false;
+ "LibreSSL 2.6.4" ++ _ ->
+ false;
+ "OpenSSL 1.1.1a-freebsd" ++ _ ->
+ false;
+ _ ->
+ true
+ end.
+
+openssl_sane_dtls_alpn() ->
+ case os:cmd("openssl version") of
+ "OpenSSL 1.1.0g" ++ _ ->
+ false;
+ "OpenSSL 1.1.1a" ++ _ ->
+ false;
+ _->
+ openssl_sane_dtls()
+ end.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
deleted file mode 100644
index 07abddbcf7..0000000000
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ /dev/null
@@ -1,2021 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-
--module(ssl_to_openssl_SUITE).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(SLEEP, 1000).
--define(OPENSSL_RENEGOTIATE, "R\n").
--define(OPENSSL_QUIT, "Q\n").
--define(OPENSSL_GARBAGE, "P\n").
--define(EXPIRE, 10).
-
-%%--------------------------------------------------------------------
-%% Common Test interface functions -----------------------------------
-%%--------------------------------------------------------------------
-
-all() ->
- case ssl_test_lib:openssl_sane_dtls() of
- true ->
- [{group, 'tlsv1.2'},
- {group, 'tlsv1.1'},
- {group, 'tlsv1'},
- {group, 'sslv3'},
- {group, 'dtlsv1.2'},
- {group, 'dtlsv1'}];
- false ->
- [{group, 'tlsv1.2'},
- {group, 'tlsv1.1'},
- {group, 'tlsv1'},
- {group, 'sslv3'}]
- end.
-
-groups() ->
- case ssl_test_lib:openssl_sane_dtls() of
- true ->
- [{'tlsv1.2', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'tlsv1.1', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'tlsv1', [], all_versions_tests()++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'sslv3', [], all_versions_tests()},
- {'dtlsv1.2', [], dtls_all_versions_tests()},
- {'dtlsv1', [], dtls_all_versions_tests()}
- ];
- false ->
- [{'tlsv1.2', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'tlsv1.1', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'tlsv1', [], all_versions_tests()++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'sslv3', [], all_versions_tests()}
- ]
- end.
-
-all_versions_tests() ->
- [
- erlang_client_openssl_server,
- erlang_server_openssl_client,
- erlang_client_openssl_server_dsa_cert,
- erlang_server_openssl_client_dsa_cert,
- erlang_client_openssl_server_anon,
- erlang_server_openssl_client_anon,
- erlang_server_openssl_client_anon_with_cert,
- erlang_server_openssl_client_reuse_session,
- erlang_client_openssl_server_renegotiate,
- erlang_client_openssl_server_renegotiate_after_client_data,
- erlang_client_openssl_server_nowrap_seqnum,
- erlang_server_openssl_client_nowrap_seqnum,
- erlang_client_openssl_server_no_server_ca_cert,
- erlang_client_openssl_server_client_cert,
- erlang_server_openssl_client_client_cert,
- ciphers_rsa_signed_certs,
- ciphers_dsa_signed_certs,
- erlang_client_bad_openssl_server,
- expired_session,
- ssl2_erlang_server_openssl_client
- ].
-
-dtls_all_versions_tests() ->
- case ssl_test_lib:openssl_sane_client_cert() of
- true ->
- [erlang_server_openssl_client_client_cert,
- erlang_client_openssl_server_no_server_ca_cert,
- erlang_client_openssl_server_client_cert
- | dtls_all_versions_tests_2()];
- false ->
- dtls_all_versions_tests_2()
- end.
-
-dtls_all_versions_tests_2() ->
- [erlang_client_openssl_server,
- erlang_server_openssl_client,
- erlang_client_openssl_server_dsa_cert,
- erlang_server_openssl_client_dsa_cert,
- erlang_client_openssl_server_anon,
- erlang_server_openssl_client_anon,
- erlang_server_openssl_client_anon_with_cert,
- erlang_server_openssl_client_reuse_session,
- erlang_client_openssl_server_renegotiate,
- erlang_client_openssl_server_nowrap_seqnum,
- erlang_server_openssl_client_nowrap_seqnum,
- ciphers_rsa_signed_certs,
- ciphers_dsa_signed_certs
- %%expired_session
- ].
-
-alpn_tests() ->
- [erlang_client_alpn_openssl_server_alpn,
- erlang_server_alpn_openssl_client_alpn,
- erlang_client_alpn_openssl_server,
- erlang_client_openssl_server_alpn,
- erlang_server_alpn_openssl_client,
- erlang_server_openssl_client_alpn,
- erlang_client_alpn_openssl_server_alpn_renegotiate,
- erlang_server_alpn_openssl_client_alpn_renegotiate,
- erlang_client_alpn_npn_openssl_server_alpn_npn,
- erlang_server_alpn_npn_openssl_client_alpn_npn].
-
-npn_tests() ->
- [erlang_client_openssl_server_npn,
- erlang_server_openssl_client_npn,
- erlang_server_openssl_client_npn_renegotiate,
- erlang_client_openssl_server_npn_renegotiate,
- erlang_server_openssl_client_npn_only_client,
- erlang_server_openssl_client_npn_only_server,
- erlang_client_openssl_server_npn_only_client,
- erlang_client_openssl_server_npn_only_server].
-
-sni_server_tests() ->
- [erlang_server_openssl_client_sni_match,
- erlang_server_openssl_client_sni_match_fun,
- erlang_server_openssl_client_sni_no_match,
- erlang_server_openssl_client_sni_no_match_fun,
- erlang_server_openssl_client_sni_no_header,
- erlang_server_openssl_client_sni_no_header_fun].
-
-
-init_per_suite(Config0) ->
- case os:find_executable("openssl") of
- false ->
- {skip, "Openssl not found"};
- _ ->
- ct:pal("Version: ~p", [os:cmd("openssl version")]),
- catch crypto:stop(),
- try crypto:start() of
- ok ->
- ssl_test_lib:clean_start(),
- Config =
- case ssl_test_lib:openssl_dsa_support() of
- true ->
- Config1 = ssl_test_lib:make_rsa_cert(Config0),
- ssl_test_lib:make_dsa_cert(Config1);
- false ->
- ssl_test_lib:make_rsa_cert(Config0)
- end,
- ssl_test_lib:cipher_restriction(Config)
- catch _:_ ->
- {skip, "Crypto did not start"}
- end
- end.
-
-end_per_suite(_Config) ->
- ssl:stop(),
- application:stop(crypto).
-
-
-init_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- case ssl_test_lib:supports_ssl_tls_version(GroupName) of
- true ->
- case ssl_test_lib:check_sane_openssl_version(GroupName) of
- true ->
- ssl_test_lib:init_tls_version(GroupName, Config);
- false ->
- {skip, openssl_does_not_support_version}
- end;
- false ->
- {skip, openssl_does_not_support_version}
- end;
- _ ->
- ssl:start(),
- Config
- end.
-
-end_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- ssl_test_lib:clean_tls_version(Config);
- false ->
- Config
- end.
-
-init_per_testcase(expired_session, Config) ->
- ct:timetrap(?EXPIRE * 1000 * 5),
- ssl:stop(),
- application:load(ssl),
- application:set_env(ssl, session_lifetime, ?EXPIRE),
- ssl:start(),
- Config;
-
-init_per_testcase(TestCase, Config) when
- TestCase == ciphers_dsa_signed_certs;
- TestCase == erlang_client_openssl_server_dsa_cert;
- TestCase == erlang_server_openssl_client_dsa_cert;
- TestCase == erlang_client_openssl_server_dsa_cert;
- TestCase == erlang_server_openssl_client_dsa_cert ->
- case ssl_test_lib:openssl_dsa_support() andalso ssl_test_lib:is_sane_oppenssl_client() of
- true ->
- special_init(TestCase, Config);
- false ->
- {skip, "DSA not supported by OpenSSL"}
- end;
-init_per_testcase(TestCase, Config) ->
- ct:timetrap({seconds, 35}),
- special_init(TestCase, Config).
-
-special_init(TestCase, Config) when
- TestCase == ciphers_rsa_signed_certs;
- TestCase == ciphers_dsa_signed_certs->
- ct:timetrap({seconds, 90}),
- Config;
-special_init(TestCase, Config)
- when TestCase == erlang_client_openssl_server_renegotiate;
- TestCase == erlang_client_openssl_server_nowrap_seqnum;
- TestCase == erlang_server_openssl_client_nowrap_seqnum;
- TestCase == erlang_client_openssl_server_renegotiate_after_client_data
- ->
- {ok, Version} = application:get_env(ssl, protocol_version),
- check_sane_openssl_renegotaite(Config, Version);
-
-special_init(ssl2_erlang_server_openssl_client, Config) ->
- case ssl_test_lib:supports_ssl_tls_version(sslv2) of
- true ->
- Config;
- false ->
- {skip, "sslv2 not supported by openssl"}
- end;
-
-special_init(TestCase, Config)
- when TestCase == erlang_client_alpn_openssl_server_alpn;
- TestCase == erlang_server_alpn_openssl_client_alpn;
- TestCase == erlang_client_alpn_openssl_server;
- TestCase == erlang_client_openssl_server_alpn;
- TestCase == erlang_server_alpn_openssl_client;
- TestCase == erlang_server_openssl_client_alpn ->
- check_openssl_alpn_support(Config);
-
-special_init(TestCase, Config)
- when TestCase == erlang_client_alpn_openssl_server_alpn_renegotiate;
- TestCase == erlang_server_alpn_openssl_client_alpn_renegotiate ->
- {ok, Version} = application:get_env(ssl, protocol_version),
- case check_sane_openssl_renegotaite(Config, Version) of
- {skip, _} = Skip ->
- Skip;
- _ ->
- check_openssl_alpn_support(Config)
- end;
-
-special_init(TestCase, Config)
- when TestCase == erlang_client_alpn_npn_openssl_server_alpn_npn;
- TestCase == erlang_server_alpn_npn_openssl_client_alpn_npn ->
- case check_openssl_alpn_support(Config) of
- {skip, _} = Skip ->
- Skip;
- _ ->
- check_openssl_npn_support(Config)
- end;
-
-special_init(TestCase, Config)
- when TestCase == erlang_client_openssl_server_npn;
- TestCase == erlang_server_openssl_client_npn;
- TestCase == erlang_server_openssl_client_npn_only_server;
- TestCase == erlang_server_openssl_client_npn_only_client;
- TestCase == erlang_client_openssl_server_npn_only_client;
- TestCase == erlang_client_openssl_server_npn_only_server ->
- check_openssl_npn_support(Config);
-
-special_init(TestCase, Config)
- when TestCase == erlang_server_openssl_client_npn_renegotiate;
- TestCase == erlang_client_openssl_server_npn_renegotiate ->
- {ok, Version} = application:get_env(ssl, protocol_version),
- case check_sane_openssl_renegotaite(Config, Version) of
- {skip, _} = Skip ->
- Skip;
- _ ->
- check_openssl_npn_support(Config)
- end;
-
-special_init(TestCase, Config0)
- when TestCase == erlang_server_openssl_client_sni_match;
- TestCase == erlang_server_openssl_client_sni_no_match;
- TestCase == erlang_server_openssl_client_sni_no_header;
- TestCase == erlang_server_openssl_client_sni_match_fun;
- TestCase == erlang_server_openssl_client_sni_no_match_fun;
- TestCase == erlang_server_openssl_client_sni_no_header_fun ->
- RsaOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config0),
- Config = [{sni_server_opts, [{sni_hosts,
- [{"a.server", [
- {certfile, proplists:get_value(certfile, RsaOpts)},
- {keyfile, proplists:get_value(keyfile, RsaOpts)}
- ]},
- {"b.server", [
- {certfile, proplists:get_value(certfile, RsaOpts)},
- {keyfile, proplists:get_value(keyfile, RsaOpts)}
- ]}
- ]}]} | Config0],
- check_openssl_sni_support(Config);
-special_init(TestCase, Config)
- when TestCase == erlang_server_openssl_client;
- TestCase == erlang_server_openssl_client_client_cert;
- TestCase == erlang_server_openssl_client_reuse_session ->
- case ssl_test_lib:is_sane_oppenssl_client() of
- true ->
- Config;
- false ->
- {skip, "Broken OpenSSL client"}
- end;
-special_init(_, Config) ->
- Config.
-
-end_per_testcase(reuse_session_expired, Config) ->
- application:unset_env(ssl, session_lifetime),
- Config;
-end_per_testcase(_, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-%% Test Cases --------------------------------------------------------
-%%--------------------------------------------------------------------
-
-erlang_client_openssl_server() ->
- [{doc,"Test erlang client with openssl server"}].
-erlang_client_openssl_server(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-erlang_server_openssl_client() ->
- [{doc,"Test erlang server with openssl client"}].
-erlang_server_openssl_client(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version)],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-erlang_client_openssl_server_dsa_cert() ->
- [{doc,"Test erlang server with openssl client"}].
-erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ClientOpts = ssl_test_lib:ssl_options(client_dsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_dsa_verify_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-CAfile", CaCertFile,
- "-key", KeyFile, "-Verify", "2", "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
-
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
- ok.
-%%--------------------------------------------------------------------
-erlang_server_openssl_client_dsa_cert() ->
- [{doc,"Test erlang server with openssl client"}].
-erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ClientOpts = ssl_test_lib:ssl_options(client_dsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_dsa_verify_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
- CaCertFile = proplists:get_value(cacertfile, ClientOpts),
- CertFile = proplists:get_value(certfile, ClientOpts),
- KeyFile = proplists:get_value(keyfile, ClientOpts),
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile,
- "-CAfile", CaCertFile,
- "-key", KeyFile, "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
- %%--------------------------------------------------------------------
-erlang_client_openssl_server_anon() ->
- [{doc,"Test erlang client with openssl server, anonymous"}].
-erlang_client_openssl_server_anon(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- %% OpenSSL expects a certificate and key, even if the cipher spec
- %% is restructed to aNULL, so we use 'server_rsa_opts' here
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_anon_opts, Config),
- VersionTuple = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl_test_lib:ecdh_dh_anonymous_suites(VersionTuple),
-
- case openssl_has_common_ciphers(Ciphers) of
- false ->
- {skip, not_supported_by_openssl};
- true ->
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile,
- "-cipher", "aNULL", "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, [{ciphers, Ciphers} | ClientOpts]}]),
-
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false)
- end.
-%%--------------------------------------------------------------------
-erlang_server_openssl_client_anon() ->
- [{doc,"Test erlang server with openssl client, anonymous"}].
-erlang_server_openssl_client_anon(Config) when is_list(Config) ->
-
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_anon_opts, Config),
- VersionTuple = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl_test_lib:ecdh_dh_anonymous_suites(VersionTuple),
-
- case openssl_has_common_ciphers(Ciphers) of
- false ->
- {skip, not_supported_by_openssl};
- true ->
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{ciphers, Ciphers} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cipher", "aNULL", "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false)
- end.
-
-%%--------------------------------------------------------------------
-erlang_server_openssl_client_anon_with_cert() ->
- [{doc,"Test erlang server with openssl client, anonymous (with cert)"}].
-erlang_server_openssl_client_anon_with_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- VersionTuple = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl_test_lib:ecdh_dh_anonymous_suites(VersionTuple),
-
- case openssl_has_common_ciphers(Ciphers) of
- false ->
- {skip, not_supported_by_openssl};
- true ->
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, [{ciphers, Ciphers} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cipher", "aNULL", "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false)
- end.
-
- %%--------------------------------------------------------------------
-erlang_server_openssl_client_reuse_session() ->
- [{doc, "Test erlang server with openssl client that reconnects with the"
- "same session id, to test reusing of sessions."}].
-erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {reconnect_times, 5},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname)
- ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-reconnect"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_client_openssl_server_renegotiate() ->
- [{doc,"Test erlang client when openssl server issuses a renegotiate"}].
-erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- ErlData = "From erlang to openssl",
- OpenSslData = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile, "-key", KeyFile, "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- delayed_send, [[ErlData, OpenSslData]]}},
- {options, ClientOpts}]),
-
- true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
- ct:sleep(?SLEEP),
- true = port_command(OpensslPort, OpenSslData),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
- ok.
-%%--------------------------------------------------------------------
-erlang_client_openssl_server_renegotiate_after_client_data() ->
- [{doc,"Test erlang client when openssl server issuses a renegotiate after reading client data"}].
-erlang_client_openssl_server_renegotiate_after_client_data(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- ErlData = "From erlang to openssl",
- OpenSslData = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile, "-key", KeyFile, "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- send_wait_send, [[ErlData, OpenSslData]]}},
- {options, ClientOpts}]),
-
- true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
- ct:sleep(?SLEEP),
- true = port_command(OpensslPort, OpenSslData),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_client_openssl_server_nowrap_seqnum() ->
- [{doc, "Test that erlang client will renegotiate session when",
- "max sequence number celing is about to be reached. Although"
- "in the testcase we use the test option renegotiate_at"
- " to lower treashold substantially."}].
-erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- ErlData = "From erlang to openssl\n",
- N = 10,
-
- Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile, "-key", KeyFile, "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib,
- trigger_renegotiate, [[ErlData, N+2]]}},
- {options, [{reuse_sessions, false},
- {renegotiate_at, N} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-%%--------------------------------------------------------------------
-erlang_server_openssl_client_nowrap_seqnum() ->
- [{doc, "Test that erlang client will renegotiate session when",
- "max sequence number celing is about to be reached. Although"
- "in the testcase we use the test option renegotiate_at"
- " to lower treashold substantially."}].
-erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- N = 10,
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- trigger_renegotiate, [[Data, N+2]]}},
- {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client","-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- true = port_command(OpenSslPort, Data),
-
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-
-erlang_client_openssl_server_no_server_ca_cert() ->
- [{doc, "Test erlang client when openssl server sends a cert chain not"
- "including the ca cert. Explicitly test this even if it is"
- "implicitly tested eleswhere."}].
-erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile, "-msg"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
-
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-erlang_client_openssl_server_client_cert() ->
- [{doc,"Test erlang client with openssl server when client sends cert"}].
-erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-CAfile", CaCertFile,
- "-key", KeyFile, "-Verify", "2"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-erlang_server_openssl_client_client_cert() ->
- [{doc,"Test erlang server with openssl client when client sends cert"}].
-erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options,
- [{verify , verify_peer}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- CaCertFile = proplists:get_value(cacertfile, ClientOpts),
- CertFile = proplists:get_value(certfile, ClientOpts),
- KeyFile = proplists:get_value(keyfile, ClientOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-cert", CertFile,
- "-CAfile", CaCertFile,
- "-key", KeyFile,"-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version)],
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- true = port_command(OpenSslPort, Data),
- ssl_test_lib:check_result(Server, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpenSslPort),
- ssl_test_lib:close(Server),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-erlang_server_erlang_client_client_cert() ->
- [{doc,"Test erlang server with erlang client when client sends cert"}].
-erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = proplists:get_value(server_rsa_verify_opts, Config),
- ClientOpts = proplists:get_value(client_rsa_verify_opts, Config),
- Version = ssl_test_lib:protocol_version(Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From erlang to erlang",
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive,
- %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast
- [Data]}},
- {options,
- [{verify , verify_peer}
- | ServerOpts]}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast
- {mfa, {ssl, send, [Data]}},
- {options,
- [{versions, [Version]} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-
-ciphers_rsa_signed_certs() ->
- [{doc,"Test cipher suites that uses rsa certs"}].
-ciphers_rsa_signed_certs(Config) when is_list(Config) ->
- Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:rsa_suites(openssl),
- run_suites(Ciphers, Version, Config, rsa).
-%%--------------------------------------------------------------------
-
-ciphers_dsa_signed_certs() ->
- [{doc,"Test cipher suites that uses dsa certs"}].
-ciphers_dsa_signed_certs(Config) when is_list(Config) ->
- Version = ssl_test_lib:protocol_version(Config),
- NVersion = ssl_test_lib:protocol_version(Config, tuple),
- Ciphers = ssl_test_lib:dsa_suites(NVersion),
- run_suites(Ciphers, Version, Config, dsa).
-
-%%--------------------------------------------------------------------
-erlang_client_bad_openssl_server() ->
- [{doc,"Test what happens if openssl server sends garbage to erlang ssl client"}].
-erlang_client_bad_openssl_server(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile],
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, server_sent_garbage, []}},
- {options,
- [{versions, [Version]} | ClientOpts]}]),
-
- %% Send garbage
- true = port_command(OpensslPort, ?OPENSSL_GARBAGE),
-
- ct:sleep(?SLEEP),
-
- Client0 ! server_sent_garbage,
-
- ssl_test_lib:check_result(Client0, true),
-
- ssl_test_lib:close(Client0),
-
- %% Make sure openssl does not hang and leave zombie process
- Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options,
- [{versions, [Version]} | ClientOpts]}]),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client1),
- process_flag(trap_exit, false),
- ok.
-
-%%--------------------------------------------------------------------
-
-expired_session() ->
- [{doc, "Test our ssl client handling of expired sessions. Will make"
- "better code coverage of the ssl_manager module"}].
-expired_session(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port),
- "-cert", CertFile,"-key", KeyFile],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, tls),
-
- Client0 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
-
- ssl_test_lib:close(Client0),
-
- %% Make sure session is registered
- ct:sleep(?SLEEP),
-
- Client1 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
-
- ssl_test_lib:close(Client1),
- %% Make sure session is unregistered due to expiration
- ct:sleep((?EXPIRE+1) * 1000),
-
- Client2 =
- ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client2),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-ssl2_erlang_server_openssl_client() ->
- [{doc,"Test that ssl v2 clients are rejected"}].
-
-ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
- {from, self()},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
-
- Exe = "openssl",
- Args = ["s_client", "-connect", hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- "-ssl2", "-msg"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
- ssl_test_lib:consume_port_exit(OpenSslPort),
- ssl_test_lib:check_server_alert(Server, unexpected_message),
- process_flag(trap_exit, false).
-
-%%--------------------------------------------------------------------
-
-erlang_client_alpn_openssl_server_alpn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_server_alpn_openssl_client_alpn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-
-erlang_client_alpn_openssl_server(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_with_opts(Config,
- [{alpn_advertised_protocols, [<<"spdy/2">>]}],
- [],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-
-erlang_client_openssl_server_alpn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_with_opts(Config,
- [],
- ["-alpn", "spdy/2"],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-
-erlang_server_alpn_openssl_client(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_with_opts(Config,
- [{alpn_preferred_protocols, [<<"spdy/2">>]}],
- [],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-
-erlang_server_openssl_client_alpn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_with_opts(Config,
- [],
- ["-alpn", "spdy/2"],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_client_alpn_openssl_server_alpn_renegotiate(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
- ct:sleep(?SLEEP),
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_server_alpn_openssl_client_alpn_renegotiate(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
- ct:sleep(?SLEEP),
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_client_alpn_npn_openssl_server_alpn_npn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-
-erlang_server_alpn_npn_openssl_client_alpn_npn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_for_alpn_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-erlang_client_openssl_server_npn() ->
- [{doc,"Test erlang client with openssl server doing npn negotiation"}].
-
-erlang_client_openssl_server_npn(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, Data),
-
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------
-erlang_client_openssl_server_npn_renegotiate() ->
- [{doc,"Test erlang client with openssl server doing npn negotiation and renegotiate"}].
-
-erlang_client_openssl_server_npn_renegotiate(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, fun(Client, OpensslPort) ->
- true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
- ct:sleep(?SLEEP),
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Client, ok)
- end),
- ok.
-%%--------------------------------------------------------------------------
-erlang_server_openssl_client_npn() ->
- [{doc,"Test erlang server with openssl client and npn negotiation"}].
-
-erlang_server_openssl_client_npn(Config) when is_list(Config) ->
-
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-erlang_server_openssl_client_npn_renegotiate() ->
- [{doc,"Test erlang server with openssl client and npn negotiation with renegotiation"}].
-
-erlang_server_openssl_client_npn_renegotiate(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
- ct:sleep(?SLEEP),
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-%%--------------------------------------------------------------------------
-erlang_client_openssl_server_npn_only_server(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_with_opts(Config, [],
- ["-nextprotoneg", "spdy/2"], Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-
-erlang_client_openssl_server_npn_only_client(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_client_and_openssl_server_with_opts(Config,
- [{client_preferred_next_protocols,
- {client, [<<"spdy/2">>], <<"http/1.1">>}}], [],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-%%--------------------------------------------------------------------------
-erlang_server_openssl_client_npn_only_server(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_with_opts(Config, [{next_protocols_advertised, [<<"spdy/2">>]}], [],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-
-erlang_server_openssl_client_npn_only_client(Config) when is_list(Config) ->
- Data = "From openssl to erlang",
- start_erlang_server_and_openssl_client_with_opts(Config, [], ["-nextprotoneg", "spdy/2"],
- Data, fun(Server, OpensslPort) ->
- true = port_command(OpensslPort, Data),
- ssl_test_lib:check_result(Server, ok)
- end),
- ok.
-%--------------------------------------------------------------------------
-erlang_server_openssl_client_sni_no_header(Config) when is_list(Config) ->
- erlang_server_openssl_client_sni_test(Config, undefined, undefined, "server Peer cert").
-
-erlang_server_openssl_client_sni_no_header_fun(Config) when is_list(Config) ->
- erlang_server_openssl_client_sni_test_sni_fun(Config, undefined, undefined, "server Peer cert").
-
-erlang_server_openssl_client_sni_match(Config) when is_list(Config) ->
- erlang_server_openssl_client_sni_test(Config, "a.server", "a.server", "server Peer cert").
-
-erlang_server_openssl_client_sni_match_fun(Config) when is_list(Config) ->
- erlang_server_openssl_client_sni_test_sni_fun(Config, "a.server", "a.server", "server Peer cert").
-
-erlang_server_openssl_client_sni_no_match(Config) when is_list(Config) ->
- erlang_server_openssl_client_sni_test(Config, "c.server", undefined, "server Peer cert").
-
-erlang_server_openssl_client_sni_no_match_fun(Config) when is_list(Config) ->
- erlang_server_openssl_client_sni_test_sni_fun(Config, "c.server", undefined, "server Peer cert").
-
-
-%%--------------------------------------------------------------------
-%% Internal functions ------------------------------------------------
-%%--------------------------------------------------------------------
-run_suites(Ciphers, Version, Config, Type) ->
- {ClientOpts, ServerOpts} =
- case Type of
- rsa ->
- {ssl_test_lib:ssl_options(client_rsa_opts, Config),
- ssl_test_lib:ssl_options(server_rsa_opts, Config)};
- dsa ->
- {ssl_test_lib:ssl_options(client_dsa_opts, Config),
- ssl_test_lib:ssl_options(server_dsa_verify_opts, Config)}
- end,
-
- Result = lists:map(fun(Cipher) ->
- cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end,
- Ciphers),
- case lists:flatten(Result) of
- [] ->
- ok;
- Error ->
- ct:log("Cipher suite errors: ~p~n", [Error]),
- ct:fail(cipher_suite_failed_see_test_case_log)
- end.
-
-client_read_check([], _Data) ->
- ok;
-client_read_check([Hd | T], Data) ->
- case binary:match(Data, list_to_binary(Hd)) of
- nomatch ->
- nomatch;
- _ ->
- client_read_check(T, Data)
- end.
-client_check_result(Port, DataExpected, DataReceived) ->
- receive
- {Port, {data, TheData}} ->
- Data = list_to_binary(TheData),
- NewData = <<DataReceived/binary, Data/binary>>,
- ct:log("New Data: ~p", [NewData]),
- case client_read_check(DataExpected, NewData) of
- ok ->
- ok;
- _ ->
- client_check_result(Port, DataExpected, NewData)
- end
- after 20000 ->
- ct:fail({"Time out on openSSL Client", {expected, DataExpected},
- {got, DataReceived}})
- end.
-client_check_result(Port, DataExpected) ->
- client_check_result(Port, DataExpected, <<"">>).
-
-send_and_hostname(SSLSocket) ->
- ssl:send(SSLSocket, "OK"),
- case ssl:connection_information(SSLSocket, [sni_hostname]) of
- {ok, []} ->
- undefined;
- {ok, [{sni_hostname, Hostname}]} ->
- Hostname
- end.
-
-erlang_server_openssl_client_sni_test(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
- Version = ssl_test_lib:protocol_version(Config),
- ct:log("Start running handshake, Config: ~p, SNIHostname: ~p, ExpectedSNIHostname: ~p, ExpectedCN: ~p", [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
- ServerOptions = proplists:get_value(sni_server_opts, Config) ++ proplists:get_value(server_rsa_opts, Config),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
- {options, ServerOptions}]),
- Port = ssl_test_lib:inet_port(Server),
- Exe = "openssl",
- ClientArgs = case SNIHostname of
- undefined ->
- openssl_client_args(Version, Hostname,Port);
- _ ->
- openssl_client_args(Version, Hostname, Port, SNIHostname)
- end,
- ClientPort = ssl_test_lib:portable_open_port(Exe, ClientArgs),
-
- ssl_test_lib:check_result(Server, ExpectedSNIHostname),
- ssl_test_lib:close_port(ClientPort),
- ssl_test_lib:close(Server),
- ok.
-
-
-erlang_server_openssl_client_sni_test_sni_fun(Config, SNIHostname, ExpectedSNIHostname, ExpectedCN) ->
- Version = ssl_test_lib:protocol_version(Config),
- ct:log("Start running handshake for sni_fun, Config: ~p, SNIHostname: ~p, ExpectedSNIHostname: ~p, ExpectedCN: ~p", [Config, SNIHostname, ExpectedSNIHostname, ExpectedCN]),
- [{sni_hosts, ServerSNIConf}] = proplists:get_value(sni_server_opts, Config),
- SNIFun = fun(Domain) -> proplists:get_value(Domain, ServerSNIConf, undefined) end,
- ServerOptions = proplists:get_value(server_rsa_opts, Config) ++ [{sni_fun, SNIFun}],
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()}, {mfa, {?MODULE, send_and_hostname, []}},
- {options, ServerOptions}]),
- Port = ssl_test_lib:inet_port(Server),
- Exe = "openssl",
- ClientArgs = case SNIHostname of
- undefined ->
- openssl_client_args(Version, Hostname,Port);
- _ ->
- openssl_client_args(Version, Hostname, Port, SNIHostname)
- end,
-
- ClientPort = ssl_test_lib:portable_open_port(Exe, ClientArgs),
-
- ssl_test_lib:check_result(Server, ExpectedSNIHostname),
- ssl_test_lib:close_port(ClientPort),
- ssl_test_lib:close(Server).
-
-
-cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
- process_flag(trap_exit, true),
- ct:log("Testing CipherSuite ~p~n", [CipherSuite]),
- {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- ConnectionInfo = {ok, {Version, CipherSuite}},
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}},
- {options,
- [{ciphers,[CipherSuite]} |
- ClientOpts]}]),
-
- true = port_command(OpenSslPort, "Hello\n"),
-
- receive
- {Port, {data, _}} when is_port(Port) ->
- ok
- after 500 ->
- ct:log("Time out on openssl port, check that"
- " the messages Hello and world are received"
- " during close of port" , []),
- ok
- end,
-
- true = port_command(OpenSslPort, " world\n"),
-
- Result = ssl_test_lib:wait_for_result(Client, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpenSslPort),
- ssl_test_lib:close(Client),
-
- Return = case Result of
- ok ->
- [];
- Error ->
- [{CipherSuite, Error}]
- end,
- process_flag(trap_exit, false),
- Return.
-
-start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, OpensslServerOpts, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ClientOpts = ErlangClientOpts ++ ClientOpts0,
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = case OpensslServerOpts of
- [] ->
- ["s_server", "-accept",
- integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile,"-key", KeyFile];
- [Opt, Value] ->
- ["s_server", Opt, Value, "-accept",
- integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile,"-key", KeyFile]
- end,
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive, [Data]}},
- {options, ClientOpts}]),
-
- Callback(Client, OpensslPort),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
-
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts = proplists:get_value(server_rsa_verify_opts, Config),
- ClientOpts0 = proplists:get_value(client_rsa_verify_opts, Config),
- ClientOpts = [{alpn_advertised_protocols, [<<"spdy/2">>]} | ClientOpts0],
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile, "-key", KeyFile],
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
- {options, ClientOpts}]),
-
- Callback(Client, OpensslPort),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
-
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-start_erlang_server_and_openssl_client_for_alpn_negotiation(Config, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts0 = proplists:get_value(server_rsa_opts, Config),
- ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>]} | ServerOpts0],
-
- {_, ServerNode, _} = ssl_test_lib:run_where(Config),
-
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_client", "-alpn", "http/1.0,spdy/2", "-msg", "-port",
- integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-host", "localhost"],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- Callback(Server, OpenSslPort),
-
- ssl_test_lib:close(Server),
-
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts = proplists:get_value(server_rsa_opts, Config),
- ClientOpts0 = proplists:get_value(client_rsa_opts, Config),
- ClientOpts = [{alpn_advertised_protocols, [<<"spdy/2">>]},
- {client_preferred_next_protocols, {client, [<<"spdy/3">>, <<"http/1.1">>]}} | ClientOpts0],
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-nextprotoneg",
- "spdy/3", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile, "-key", KeyFile],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
- {options, ClientOpts}]),
-
- Callback(Client, OpensslPort),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
-
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-start_erlang_server_and_openssl_client_for_alpn_npn_negotiation(Config, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts0 = proplists:get_value(server_rsa_opts, Config),
- ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>]},
- {next_protocols_advertised, [<<"spdy/3">>, <<"http/1.1">>]} | ServerOpts0],
-
- {_, ServerNode, _} = ssl_test_lib:run_where(Config),
-
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
- Exe = "openssl",
- Args = ["s_client", "-alpn", "http/1.1,spdy/2", "-nextprotoneg", "spdy/3",
- "-msg", "-port", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-host", "localhost"],
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- Callback(Server, OpenSslPort),
-
- ssl_test_lib:close(Server),
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ClientOpts = [{client_preferred_next_protocols, {client, [<<"spdy/2">>], <<"http/1.1">>}} | ClientOpts0],
-
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Data = "From openssl to erlang",
-
- Port = ssl_test_lib:inet_port(node()),
- CaCertFile = proplists:get_value(cacertfile, ServerOpts),
- CertFile = proplists:get_value(certfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_server", "-msg", "-nextprotoneg", "http/1.1,spdy/2", "-accept", integer_to_list(Port),
- ssl_test_lib:version_flag(Version),
- "-CAfile", CaCertFile,
- "-cert", CertFile, "-key", KeyFile],
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE,
- erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
- {options, ClientOpts}]),
-
- Callback(Client, OpensslPort),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
-
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false).
-
-start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- ServerOpts = [{next_protocols_advertised, [<<"spdy/2">>]}, ServerOpts0],
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive_and_assert_negotiated_protocol, [<<"spdy/2">>, Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_client", "-nextprotoneg", "http/1.0,spdy/2", "-msg", "-connect",
- hostname_format(Hostname) ++ ":"
- ++ integer_to_list(Port), ssl_test_lib:version_flag(Version)],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- Callback(Server, OpenSslPort),
-
- ssl_test_lib:close(Server),
-
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-
-start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenSSLClientOpts, Data, Callback) ->
- process_flag(trap_exit, true),
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
- ServerOpts = ErlangServerOpts ++ ServerOpts0,
-
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Version = ssl_test_lib:protocol_version(Config),
-
- Exe = "openssl",
- Args = ["s_client"] ++ OpenSSLClientOpts ++ ["-msg", "-connect",
- hostname_format(Hostname) ++ ":" ++ integer_to_list(Port),
- ssl_test_lib:version_flag(Version)],
-
- OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- Callback(Server, OpenSslPort),
-
- ssl_test_lib:close(Server),
-
- ssl_test_lib:close_port(OpenSslPort),
- process_flag(trap_exit, false).
-
-
-erlang_ssl_receive_and_assert_negotiated_protocol(Socket, Protocol, Data) ->
- {ok, Protocol} = ssl:negotiated_protocol(Socket),
- erlang_ssl_receive(Socket, Data),
- {ok, Protocol} = ssl:negotiated_protocol(Socket),
- ok.
-
-erlang_ssl_receive(Socket, Data) ->
- ct:log("Connection info: ~p~n",
- [ssl:connection_information(Socket)]),
- receive
- {ssl, Socket, "R\n"} ->
- %% Swallow s_client renegotiation command.
- %% openssl s_client connected commands can appear on
- %% server side with some openssl versions.
- erlang_ssl_receive(Socket,Data);
- {ssl, Socket, Data} ->
- io:format("Received ~p~n",[Data]),
- %% open_ssl server sometimes hangs waiting in blocking read
- ssl:send(Socket, "Got it"),
- ok;
- {ssl, Socket, Byte} when length(Byte) == 1 ->
- erlang_ssl_receive(Socket, tl(Data));
- {Port, {data,Debug}} when is_port(Port) ->
- io:format("openssl ~s~n",[Debug]),
- erlang_ssl_receive(Socket,Data);
- Other ->
- ct:fail({unexpected_message, Other})
- end.
-
-connection_info(Socket, Version) ->
- case ssl:connection_information(Socket, [version]) of
- {ok, [{version, Version}] = Info} ->
- ct:log("Connection info: ~p~n", [Info]),
- ok;
- {ok, [{version, OtherVersion}]} ->
- {wrong_version, OtherVersion}
- end.
-
-connection_info_result(Socket) ->
- ssl:connection_information(Socket).
-
-
-delayed_send(Socket, [ErlData, OpenSslData]) ->
- ct:sleep(?SLEEP),
- ssl:send(Socket, ErlData),
- erlang_ssl_receive(Socket, OpenSslData).
-
-server_sent_garbage(Socket) ->
- receive
- server_sent_garbage ->
- {error, closed} == ssl:send(Socket, "data")
-
- end.
-
-send_wait_send(Socket, [ErlData, OpenSslData]) ->
- ssl:send(Socket, ErlData),
- ct:sleep(?SLEEP),
- ssl:send(Socket, ErlData),
- erlang_ssl_receive(Socket, OpenSslData).
-
-check_openssl_sni_support(Config) ->
- HelpText = os:cmd("openssl s_client --help"),
- case ssl_test_lib:is_sane_oppenssl_client() of
- true ->
- case string:str(HelpText, "-servername") of
- 0 ->
- {skip, "Current openssl doesn't support SNI"};
- _ ->
- Config
- end;
- false ->
- {skip, "Current openssl doesn't support SNI or extension handling is flawed"}
- end.
-
-
-check_openssl_npn_support(Config) ->
- HelpText = os:cmd("openssl s_client --help"),
- case string:str(HelpText, "nextprotoneg") of
- 0 ->
- {skip, "Openssl not compiled with nextprotoneg support"};
- _ ->
- Config
- end.
-
-check_openssl_alpn_support(Config) ->
- HelpText = os:cmd("openssl s_client --help"),
- case string:str(HelpText, "alpn") of
- 0 ->
- {skip, "Openssl not compiled with alpn support"};
- _ ->
- Config
- end.
-
-check_sane_openssl_renegotaite(Config, Version) when Version == 'tlsv1.1';
- Version == 'tlsv1.2' ->
- case os:cmd("openssl version") of
- "OpenSSL 1.0.1c" ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- "OpenSSL 1.0.1b" ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- "OpenSSL 1.0.1a" ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- "OpenSSL 1.0.1 " ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- _ ->
- check_sane_openssl_renegotaite(Config)
- end;
-check_sane_openssl_renegotaite(Config, _) ->
- check_sane_openssl_renegotaite(Config).
-
-check_sane_openssl_renegotaite(Config) ->
- case os:cmd("openssl version") of
- "OpenSSL 1.0.0" ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- "OpenSSL 0.9.8" ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- "OpenSSL 0.9.7" ++ _ ->
- {skip, "Known renegotiation bug in OpenSSL"};
- _ ->
- Config
- end.
-
-workaround_openssl_s_clinent() ->
- %% http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683159
- %% https://bugs.archlinux.org/task/33919
- %% Bug seems to manifests it self if TLS version is not
- %% explicitly specified
- case os:cmd("openssl version") of
- "OpenSSL 1.0.1c" ++ _ ->
- ["-no_tls1_2"];
- "OpenSSL 1.0.1d" ++ _ ->
- ["-no_tls1_2"];
- "OpenSSL 1.0.1e" ++ _ ->
- ["-no_tls1_2"];
- "OpenSSL 1.0.1f" ++ _ ->
- ["-no_tls1_2"];
- _ ->
- []
- end.
-
-openssl_client_args(Version, Hostname, Port) ->
- ["s_client", "-connect", Hostname ++ ":" ++ integer_to_list(Port), ssl_test_lib:version_flag(Version)].
-
-openssl_client_args(Version, Hostname, Port, ServerName) ->
- ["s_client", "-connect", Hostname ++ ":" ++
- integer_to_list(Port), ssl_test_lib:version_flag(Version), "-servername", ServerName].
-
-
-hostname_format(Hostname) ->
- case lists:member($., Hostname) of
- true ->
- Hostname;
- false ->
- "localhost"
- end.
-
-
-openssl_has_common_ciphers(Ciphers) ->
- OCiphers = ssl_test_lib:common_ciphers(openssl),
- has_common_ciphers(Ciphers, OCiphers).
-
-has_common_ciphers([], _) ->
- false;
-has_common_ciphers([Cipher | Rest], OCiphers) ->
- case lists:member(Cipher, OCiphers) of
- true ->
- true;
- _ ->
- has_common_ciphers(Rest, OCiphers)
- end.
diff --git a/lib/ssl/test/tls_1_3_record_SUITE.erl b/lib/ssl/test/tls_1_3_record_SUITE.erl
new file mode 100644
index 0000000000..5df8853b1b
--- /dev/null
+++ b/lib/ssl/test/tls_1_3_record_SUITE.erl
@@ -0,0 +1,973 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(tls_1_3_record_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssl/src/tls_record.hrl").
+-include_lib("ssl/src/tls_handshake.hrl").
+-include_lib("ssl/src/ssl_cipher.hrl").
+-include_lib("ssl/src/ssl_internal.hrl").
+
+all() ->
+ [encode_decode,
+ finished_verify_data,
+ '1_RTT_handshake'].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try (ok == crypto:start()) andalso ssl_test_lib:sufficient_crypto_support('tlsv1.3') of
+ true ->
+ ssl_test_lib:clean_start(),
+ Config;
+ false ->
+ {skip, "Not enough crypto support for TLS-1.3"}
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+encode_decode() ->
+ [{doc,"Test TLS 1.3 record encode/decode functions"}].
+
+encode_decode(_Config) ->
+ ConnectionStates =
+ #{current_read =>
+ #{beast_mitigation => one_n_minus_one,
+ cipher_state =>
+ {cipher_state,
+ <<14,172,111,243,199,170,242,203,126,205,34,93,122,115,226,14,
+ 15,117,155,48,24,112,61,15,113,208,127,51,179,227,194,232>>,
+ <<197,54,168,218,54,91,157,58,30,201,197,142,51,58,53,231,228,
+ 131,57,122,170,78,82,196,30,48,23,16,95,255,185,236>>,
+ undefined,undefined,undefined,16},
+ client_verify_data => undefined,compression_state => undefined,
+ mac_secret => undefined,secure_renegotiation => undefined,
+ security_parameters =>
+ {security_parameters,
+ <<19,2>>,
+ 0,8,2,undefined,undefined,undefined,undefined,undefined,
+ sha384,undefined,undefined,
+ {handshake_secret,
+ <<128,229,186,211,62,127,182,20,62,166,233,23,135,64,121,
+ 3,104,251,214,161,253,31,3,2,232,37,8,221,189,72,64,218,
+ 121,41,112,148,254,34,68,164,228,60,161,201,132,55,56,
+ 157>>},
+ undefined,
+ <<92,24,205,75,244,60,136,212,250,32,214,20,37,3,213,87,61,207,
+ 147,61,168,145,177,118,160,153,33,53,48,108,191,174>>,
+ undefined},
+ sequence_number => 0,server_verify_data => undefined},
+ current_write =>
+ #{beast_mitigation => one_n_minus_one,
+ cipher_state =>
+ {cipher_state,
+ <<14,172,111,243,199,170,242,203,126,205,34,93,122,115,226,14,
+ 15,117,155,48,24,112,61,15,113,208,127,51,179,227,194,232>>,
+ <<197,54,168,218,54,91,157,58,30,201,197,142,51,58,53,231,228,
+ 131,57,122,170,78,82,196,30,48,23,16,95,255,185,236>>,
+ undefined,undefined,undefined,16},
+ client_verify_data => undefined,compression_state => undefined,
+ mac_secret => undefined,secure_renegotiation => undefined,
+ security_parameters =>
+ {security_parameters,
+ <<19,2>>,
+ 0,8,2,undefined,undefined,undefined,undefined,undefined,
+ sha384,undefined,undefined,
+ {handshake_secret,
+ <<128,229,186,211,62,127,182,20,62,166,233,23,135,64,121,
+ 3,104,251,214,161,253,31,3,2,232,37,8,221,189,72,64,218,
+ 121,41,112,148,254,34,68,164,228,60,161,201,132,55,56,
+ 157>>},
+ undefined,
+ <<92,24,205,75,244,60,136,212,250,32,214,20,37,3,213,87,61,207,
+ 147,61,168,145,177,118,160,153,33,53,48,108,191,174>>,
+ undefined},
+ sequence_number => 0,server_verify_data => undefined}},
+
+ PlainText = [11,
+ <<0,2,175>>,
+ <<0,0,2,171,0,2,166,48,130,2,162,48,130,1,138,2,9,0,186,57,220,137,88,255,
+ 191,235,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,48,18,49,16,48,14,6,3,85,
+ 4,3,12,7,84,101,115,116,32,67,65,48,30,23,13,49,56,48,53,48,52,49,52,49,50,
+ 51,56,90,23,13,50,56,48,50,48,52,49,52,49,50,51,56,90,48,20,49,18,48,16,6,
+ 3,85,4,3,12,9,108,111,99,97,108,104,111,115,116,48,130,1,34,48,13,6,9,42,
+ 134,72,134,247,13,1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,169,40,
+ 144,176,121,63,134,97,144,126,243,183,225,157,37,131,183,225,87,243,23,88,
+ 230,70,9,134,32,147,7,27,167,98,51,81,224,75,199,12,229,251,195,207,75,179,
+ 181,78,128,3,255,44,58,39,43,172,142,45,186,58,51,65,187,199,154,153,245,
+ 70,133,137,1,27,87,42,116,65,251,129,109,145,233,97,171,71,54,213,185,74,
+ 209,166,11,218,189,119,206,86,170,60,212,213,85,189,30,50,215,23,185,53,
+ 132,238,132,176,198,250,139,251,198,221,225,128,109,113,23,220,39,143,71,
+ 30,59,189,51,244,61,158,214,146,180,196,103,169,189,221,136,78,129,216,148,
+ 2,9,8,65,37,224,215,233,13,209,21,235,20,143,33,74,59,53,208,90,152,94,251,
+ 54,114,171,39,88,230,227,158,211,135,37,182,67,205,161,59,20,138,58,253,15,
+ 53,48,8,157,9,95,197,9,177,116,21,54,9,125,78,109,182,83,20,16,234,223,116,
+ 41,155,123,87,77,17,120,153,246,239,124,130,105,219,166,146,242,151,66,198,
+ 75,72,63,28,246,86,16,244,223,22,36,50,15,247,222,98,6,152,136,154,72,150,
+ 73,127,2,3,1,0,1,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,3,130,1,1,0,76,
+ 33,54,160,229,219,219,193,150,116,245,252,18,39,235,145,86,12,167,171,52,
+ 117,166,30,83,5,216,245,177,217,247,95,1,136,94,246,212,108,248,230,111,
+ 225,202,189,6,129,8,70,128,245,18,204,215,87,82,129,253,227,122,66,182,184,
+ 189,30,193,169,144,218,216,109,105,110,215,144,60,104,162,178,101,164,218,
+ 122,60,37,41,143,57,150,52,59,51,112,238,113,239,168,114,69,183,143,154,73,
+ 61,58,80,247,172,95,251,55,28,186,28,200,206,230,118,243,92,202,189,49,76,
+ 124,252,76,0,247,112,85,194,69,59,222,163,228,103,49,110,104,109,251,155,
+ 138,9,37,167,49,189,48,134,52,158,185,129,24,96,153,196,251,90,206,76,239,
+ 175,119,174,165,133,108,222,125,237,125,187,149,152,83,190,16,202,94,202,
+ 201,40,218,22,254,63,189,41,174,97,140,203,70,18,196,118,237,175,134,79,78,
+ 246,2,61,54,77,186,112,32,17,193,192,188,217,252,215,200,7,245,180,179,132,
+ 183,212,229,155,15,152,206,135,56,81,88,3,123,244,149,110,182,72,109,70,62,
+ 146,152,146,151,107,126,216,210,9,93,0,0>>],
+
+ {[_Header|Encoded], _} = tls_record_1_3:encode_plain_text(22, PlainText, ConnectionStates),
+ CipherText = #ssl_tls{type = 23, version = {3,3}, fragment = Encoded},
+
+ {#ssl_tls{type = 22, version = {3,4}, fragment = DecodedText}, _} =
+ tls_record_1_3:decode_cipher_text(CipherText, ConnectionStates),
+
+ DecodedText = iolist_to_binary(PlainText),
+ ct:log("Decoded: ~p ~n", [DecodedText]),
+ ok.
+%%--------------------------------------------------------------------
+'1_RTT_handshake'() ->
+ [{doc,"Test TLS 1.3 1-RTT Handshake"}].
+
+'1_RTT_handshake'(_Config) ->
+ %% ConnectionStates with NULL cipher
+ ConnStatesNull =
+ #{current_write =>
+ #{security_parameters =>
+ #security_parameters{cipher_suite = ?TLS_NULL_WITH_NULL_NULL},
+ sequence_number => 0
+ }
+ },
+
+ %% {client} construct a ClientHello handshake message:
+ %%
+ %% ClientHello (196 octets): 01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
+ %% ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
+ %% 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
+ %% 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
+ %% 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
+ %% 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
+ %% 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
+ %% af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
+ %% 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
+ %% 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
+ %%
+ %% {client} send handshake record:
+ %%
+ %% payload (196 octets): 01 00 00 c0 03 03 cb 34 ec b1 e7 81 63 ba
+ %% 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83 02
+ %% 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b 00
+ %% 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00 12
+ %% 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23 00
+ %% 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2 3d
+ %% 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af
+ %% 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03 02
+ %% 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06 02
+ %% 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
+ %%
+ %% complete record (201 octets): 16 03 01 00 c4 01 00 00 c0 03 03 cb
+ %% 34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
+ %% ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
+ %% 00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
+ %% 00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
+ %% 01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
+ %% e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
+ %% 54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
+ %% 04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
+ %% 01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
+ ClientHello =
+ hexstr2bin("01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
+ ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
+ 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
+ 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
+ 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
+ 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
+ 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
+ af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
+ 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
+ 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"),
+
+ ClientHelloRecord =
+ %% Current implementation always sets
+ %% legacy_record_version to Ox0303
+ hexstr2bin("16 03 03 00 c4 01 00 00 c0 03 03 cb
+ 34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
+ ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
+ 00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
+ 00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
+ 01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
+ e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
+ 54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
+ 04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
+ 01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"),
+
+ {CHEncrypted, _} =
+ tls_record:encode_handshake(ClientHello, {3,4}, ConnStatesNull),
+ ClientHelloRecord = iolist_to_binary(CHEncrypted),
+
+ %% {server} extract secret "early":
+ %%
+ %% salt: 0 (all zero octets)
+ %%
+ %% IKM (32 octets): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ %% 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ %%
+ %% secret (32 octets): 33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
+ %% e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
+ HKDFAlgo = sha256,
+ Salt = binary:copy(<<?BYTE(0)>>, 32),
+ IKM = binary:copy(<<?BYTE(0)>>, 32),
+ EarlySecret =
+ hexstr2bin("33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
+ e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a"),
+
+ {early_secret, EarlySecret} = tls_v1:key_schedule(early_secret, HKDFAlgo, {psk, Salt}),
+
+ %% {client} create an ephemeral x25519 key pair:
+ %%
+ %% private key (32 octets): 49 af 42 ba 7f 79 94 85 2d 71 3e f2 78
+ %% 4b cb ca a7 91 1d e2 6a dc 56 42 cb 63 45 40 e7 ea 50 05
+ %%
+ %% public key (32 octets): 99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
+ %% ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c
+ CPublicKey =
+ hexstr2bin("99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
+ ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c"),
+
+ %% {server} create an ephemeral x25519 key pair:
+ %%
+ %% private key (32 octets): b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
+ %% 52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e
+ %%
+ %% public key (32 octets): c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
+ %% 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f
+ SPrivateKey =
+ hexstr2bin("b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
+ 52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e"),
+
+ SPublicKey =
+ hexstr2bin("c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
+ 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f"),
+
+ %% {server} construct a ServerHello handshake message:
+ %%
+ %% ServerHello (90 octets): 02 00 00 56 03 03 a6 af 06 a4 12 18 60
+ %% dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
+ %% d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
+ %% 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
+ %% dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
+ ServerHello =
+ hexstr2bin("02 00 00 56 03 03 a6 af 06 a4 12 18 60
+ dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
+ d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
+ 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
+ dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"),
+
+ %% {server} derive secret for handshake "tls13 derived":
+ %%
+ %% PRK (32 octets): 33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c e2
+ %% 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
+ %%
+ %% hash (32 octets): e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
+ %% 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55
+ %%
+ %% info (49 octets): 00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
+ %% 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
+ %% 64 9b 93 4c a4 95 99 1b 78 52 b8 55
+ %%
+ %% expanded (32 octets): 6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
+ %% b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
+ Hash =
+ hexstr2bin("e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
+ 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55"),
+
+ Hash = crypto:hash(HKDFAlgo, <<>>),
+
+ Info =
+ hexstr2bin("00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
+ 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
+ 64 9b 93 4c a4 95 99 1b 78 52 b8 55"),
+
+ Info = tls_v1:create_info(<<"derived">>, Hash, ssl_cipher:hash_size(HKDFAlgo)),
+
+ Expanded =
+ hexstr2bin("6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
+ b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba"),
+
+ Expanded = tls_v1:derive_secret(EarlySecret, <<"derived">>, <<>>, HKDFAlgo),
+
+ %% {server} extract secret "handshake":
+ %%
+ %% salt (32 octets): 6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba b6 97
+ %% 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
+ %%
+ %% IKM (32 octets): 8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
+ %% 35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d
+ %%
+ %% secret (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
+ %% 01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
+
+ %% salt = Expanded
+ HandshakeIKM =
+ hexstr2bin("8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
+ 35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d"),
+
+ HandshakeSecret =
+ hexstr2bin("1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
+ 01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac"),
+
+ HandshakeIKM = crypto:compute_key(ecdh, CPublicKey, SPrivateKey, x25519),
+
+ {handshake_secret, HandshakeSecret} =
+ tls_v1:key_schedule(handshake_secret, HKDFAlgo, HandshakeIKM,
+ {early_secret, EarlySecret}),
+
+ %% {server} derive secret "tls13 c hs traffic":
+ %%
+ %% PRK (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
+ %% 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
+ %%
+ %% hash (32 octets): 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
+ %% d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
+ %%
+ %% info (54 octets): 00 20 12 74 6c 73 31 33 20 63 20 68 73 20 74 72
+ %% 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
+ %% ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
+ %%
+ %% expanded (32 octets): b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
+ %% 2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
+
+ %% PRK = HandshakeSecret
+ CHSTHash =
+ hexstr2bin("86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
+ d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
+
+ CHSTInfo =
+ hexstr2bin("00 20 12 74 6c 73 31 33 20 63 20 68 73 20 74 72
+ 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
+ ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
+
+ CHSTrafficSecret =
+ hexstr2bin(" b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
+ 2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21"),
+
+ CHSH = <<ClientHello/binary,ServerHello/binary>>,
+ CHSTHash = crypto:hash(HKDFAlgo, CHSH),
+ CHSTInfo = tls_v1:create_info(<<"c hs traffic">>, CHSTHash, ssl_cipher:hash_size(HKDFAlgo)),
+
+ CHSTrafficSecret =
+ tls_v1:client_handshake_traffic_secret(HKDFAlgo, {handshake_secret, HandshakeSecret}, CHSH),
+
+ %% {server} derive secret "tls13 s hs traffic":
+ %%
+ %% PRK (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
+ %% 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
+ %%
+ %% hash (32 octets): 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
+ %% d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
+ %%
+ %% info (54 octets): 00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
+ %% 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
+ %% ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
+ %%
+ %% expanded (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
+ %% 37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
+
+ %% PRK = HandshakeSecret
+ %% hash = CHSTHash
+ SHSTInfo =
+ hexstr2bin("00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
+ 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
+ ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
+
+ SHSTrafficSecret =
+ hexstr2bin("b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
+ 37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38"),
+
+ SHSTInfo = tls_v1:create_info(<<"s hs traffic">>, CHSTHash, ssl_cipher:hash_size(HKDFAlgo)),
+
+ SHSTrafficSecret =
+ tls_v1:server_handshake_traffic_secret(HKDFAlgo, {handshake_secret, HandshakeSecret}, CHSH),
+
+
+ %% {server} derive secret for master "tls13 derived":
+ %%
+ %% PRK (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
+ %% 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
+ %%
+ %% hash (32 octets): e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
+ %% 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55
+ %%
+ %% info (49 octets): 00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
+ %% 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
+ %% 64 9b 93 4c a4 95 99 1b 78 52 b8 55
+ %%
+ %% expanded (32 octets): 43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25
+ %% 90 b5 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
+
+ %% PRK = HandshakeSecret
+ %% hash = Hash
+ %% info = Info
+ MasterDeriveSecret =
+ hexstr2bin("43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25
+ 90 b5 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4"),
+
+ MasterDeriveSecret = tls_v1:derive_secret(HandshakeSecret, <<"derived">>, <<>>, HKDFAlgo),
+
+ %% {server} extract secret "master":
+ %%
+ %% salt (32 octets): 43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25 90 b5
+ %% 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
+ %%
+ %% IKM (32 octets): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ %% 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ %%
+ %% secret (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
+ %% 47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
+
+ %% salt = MasterDeriveSecret
+ %% IKM = IKM
+ MasterSecret =
+ hexstr2bin("18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
+ 47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19"),
+
+ {master_secret, MasterSecret} =
+ tls_v1:key_schedule(master_secret, HKDFAlgo, {handshake_secret, HandshakeSecret}),
+
+ %% {server} send handshake record:
+ %%
+ %% payload (90 octets): 02 00 00 56 03 03 a6 af 06 a4 12 18 60 dc 5e
+ %% 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e d3 e2
+ %% 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88 76 11
+ %% 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69
+ %% b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
+ %%
+ %% complete record (95 octets): 16 03 03 00 5a 02 00 00 56 03 03 a6
+ %% af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
+ %% 34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
+ %% 1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
+ %% cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
+
+ %% payload = ServerHello
+ ServerHelloRecord =
+ hexstr2bin("16 03 03 00 5a 02 00 00 56 03 03 a6
+ af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
+ 34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
+ 1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
+ cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"),
+
+ {SHEncrypted, _} =
+ tls_record:encode_handshake(ServerHello, {3,4}, ConnStatesNull),
+ ServerHelloRecord = iolist_to_binary(SHEncrypted),
+
+ %% {server} derive write traffic keys for handshake data:
+ %%
+ %% PRK (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
+ %% e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
+ %%
+ %% key info (13 octets): 00 10 09 74 6c 73 31 33 20 6b 65 79 00
+ %%
+ %% key expanded (16 octets): 3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e
+ %% e4 03 bc
+ %%
+ %% iv info (12 octets): 00 0c 08 74 6c 73 31 33 20 69 76 00
+ %%
+ %% iv expanded (12 octets): 5d 31 3e b2 67 12 76 ee 13 00 0b 30
+
+ %% PRK = SHSTrafficSecret
+ WriteKeyInfo =
+ hexstr2bin("00 10 09 74 6c 73 31 33 20 6b 65 79 00"),
+
+ WriteKey =
+ hexstr2bin("3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e e4 03 bc"),
+
+ WriteIVInfo =
+ hexstr2bin("00 0c 08 74 6c 73 31 33 20 69 76 00"),
+
+ WriteIV =
+ hexstr2bin(" 5d 31 3e b2 67 12 76 ee 13 00 0b 30"),
+
+ Cipher = aes_128_gcm, %% TODO: get from ServerHello
+
+ WriteKeyInfo = tls_v1:create_info(<<"key">>, <<>>, ssl_cipher:key_material(Cipher)),
+ %% TODO: remove hardcoded IV size
+ WriteIVInfo = tls_v1:create_info(<<"iv">>, <<>>, 12),
+
+ {WriteKey, WriteIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, SHSTrafficSecret),
+
+ %% {server} construct an EncryptedExtensions handshake message:
+ %%
+ %% EncryptedExtensions (40 octets): 08 00 00 24 00 22 00 0a 00 14 00
+ %% 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
+ %% 00 02 40 01 00 00 00 00
+ %%
+ %% {server} construct a Certificate handshake message:
+ %%
+ %% Certificate (445 octets): 0b 00 01 b9 00 00 01 b5 00 01 b0 30 82
+ %% 01 ac 30 82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48
+ %% 86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03
+ %% 72 73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17
+ %% 0d 32 36 30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06
+ %% 03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7
+ %% 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f
+ %% 82 79 30 3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
+ %% d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c
+ %% 1a f1 9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52
+ %% 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74
+ %% 80 30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93
+ %% ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03
+ %% 01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06
+ %% 03 55 1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01
+ %% 01 0b 05 00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
+ %% 72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea
+ %% e8 f8 a5 8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01
+ %% 51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be
+ %% c1 fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b
+ %% 1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8
+ %% 96 12 29 ac 91 87 b4 2b 4d e1 00 00
+ %%
+ %% {server} construct a CertificateVerify handshake message:
+ %%
+ %% CertificateVerify (136 octets): 0f 00 00 84 08 04 00 80 5a 74 7c
+ %% 5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
+ %% b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07
+ %% 86 53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b
+ %% be 8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44
+ %% 5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a
+ %% 3d a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3
+ EncryptedExtensions =
+ hexstr2bin("08 00 00 24 00 22 00 0a 00 14 00
+ 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
+ 00 02 40 01 00 00 00 00"),
+
+ Certificate =
+ hexstr2bin("0b 00 01 b9 00 00 01 b5 00 01 b0 30 82
+ 01 ac 30 82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48
+ 86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03
+ 72 73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17
+ 0d 32 36 30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06
+ 03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7
+ 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f
+ 82 79 30 3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
+ d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c
+ 1a f1 9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52
+ 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74
+ 80 30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93
+ ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03
+ 01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06
+ 03 55 1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01
+ 01 0b 05 00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
+ 72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea
+ e8 f8 a5 8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01
+ 51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be
+ c1 fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b
+ 1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8
+ 96 12 29 ac 91 87 b4 2b 4d e1 00 00"),
+
+ CertificateVerify =
+ hexstr2bin("0f 00 00 84 08 04 00 80 5a 74 7c
+ 5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
+ b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07
+ 86 53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b
+ be 8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44
+ 5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a
+ 3d a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3"),
+
+ %% {server} calculate finished "tls13 finished":
+ %%
+ %% PRK (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
+ %% e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
+ %%
+ %% hash (0 octets): (empty)
+ %%
+ %% info (18 octets): 00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
+ %% 64 00
+ %%
+ %% expanded (32 octets): 00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85
+ %% c3 1f c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8
+ %%
+ %% finished (32 octets): 9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
+ %% de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18
+
+ %% PRK = SHSTrafficSecret
+ FInfo =
+ hexstr2bin("00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
+ 64 00"),
+
+ FExpanded =
+ hexstr2bin("00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85
+ c3 1f c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8"),
+
+ FinishedVerifyData =
+ hexstr2bin("9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
+ de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18"),
+
+ FInfo = tls_v1:create_info(<<"finished">>, <<>>, ssl_cipher:hash_size(HKDFAlgo)),
+
+ FExpanded = tls_v1:finished_key(SHSTrafficSecret, HKDFAlgo),
+
+ MessageHistory0 = [CertificateVerify,
+ Certificate,
+ EncryptedExtensions,
+ ServerHello,
+ ClientHello],
+
+ FinishedVerifyData = tls_v1:finished_verify_data(FExpanded, HKDFAlgo, MessageHistory0),
+
+ %% {server} construct a Finished handshake message:
+ %%
+ %% Finished (36 octets): 14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb
+ %% dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
+ %% 18
+ FinishedHSBin =
+ hexstr2bin("14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb
+ dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
+ 18"),
+
+ FinishedHS = #finished{verify_data = FinishedVerifyData},
+
+ FinishedIOList = tls_handshake:encode_handshake(FinishedHS, {3,4}),
+ FinishedHSBin = iolist_to_binary(FinishedIOList),
+
+ %% {server} derive secret "tls13 c ap traffic":
+ %%
+ %% PRK (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
+ %% 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
+ %%
+ %% hash (32 octets): 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
+ %% 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
+ %%
+ %% info (54 octets): 00 20 12 74 6c 73 31 33 20 63 20 61 70 20 74 72
+ %% 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
+ %% 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
+ %%
+ %% expanded (32 octets): 9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
+ %% 65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5
+
+ %% PRK = MasterSecret
+ CAPTHash =
+ hexstr2bin("96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
+ 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
+ CAPTInfo =
+ hexstr2bin("00 20 12 74 6c 73 31 33 20 63 20 61 70 20 74 72
+ 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
+ 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
+
+ CAPTrafficSecret =
+ hexstr2bin("9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
+ 65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5"),
+
+ CHSF = <<ClientHello/binary,
+ ServerHello/binary,
+ EncryptedExtensions/binary,
+ Certificate/binary,
+ CertificateVerify/binary,
+ FinishedHSBin/binary>>,
+
+ CAPTHash = crypto:hash(HKDFAlgo, CHSF),
+
+ CAPTInfo =
+ tls_v1:create_info(<<"c ap traffic">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
+
+ CAPTrafficSecret =
+ tls_v1:client_application_traffic_secret_0(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
+
+ %% {server} derive secret "tls13 s ap traffic":
+ %%
+ %% PRK (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
+ %% 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
+ %%
+ %% hash (32 octets): 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
+ %% 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
+ %%
+ %% info (54 octets): 00 20 12 74 6c 73 31 33 20 73 20 61 70 20 74 72
+ %% 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
+ %% 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
+ %%
+ %% expanded (32 octets): a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
+ %% 50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
+
+ %% PRK = MasterSecret
+ %% hash = CAPTHash
+ SAPTInfo =
+ hexstr2bin(" 00 20 12 74 6c 73 31 33 20 73 20 61 70 20 74 72
+ 61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
+ 1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
+
+ SAPTrafficSecret =
+ hexstr2bin("a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
+ 50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43"),
+
+ SAPTInfo =
+ tls_v1:create_info(<<"s ap traffic">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
+
+ SAPTrafficSecret =
+ tls_v1:server_application_traffic_secret_0(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
+
+ %% {server} derive secret "tls13 exp master":
+ %%
+ %% PRK (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
+ %% 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
+ %%
+ %% hash (32 octets): 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
+ %% 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
+ %%
+ %% info (52 octets): 00 20 10 74 6c 73 31 33 20 65 78 70 20 6d 61 73
+ %% 74 65 72 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a 00
+ %% 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
+ %%
+ %% expanded (32 octets): fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
+ %% 92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50
+
+ %% PRK = MasterSecret
+ %% hash = CAPTHash
+ ExporterInfo =
+ hexstr2bin("00 20 10 74 6c 73 31 33 20 65 78 70 20 6d 61 73
+ 74 65 72 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a 00
+ 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
+
+ ExporterMasterSecret =
+ hexstr2bin("fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
+ 92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50"),
+
+ ExporterInfo =
+ tls_v1:create_info(<<"exp master">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
+
+ ExporterMasterSecret =
+ tls_v1:exporter_master_secret(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
+
+ %% {server} derive write traffic keys for application data:
+ %%
+ %% PRK (32 octets): a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9 50 32
+ %% 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
+ %%
+ %% key info (13 octets): 00 10 09 74 6c 73 31 33 20 6b 65 79 00
+ %%
+ %% key expanded (16 octets): 9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac
+ %% 92 e3 56
+ %%
+ %% iv info (12 octets): 00 0c 08 74 6c 73 31 33 20 69 76 00
+ %%
+ %% iv expanded (12 octets): cf 78 2b 88 dd 83 54 9a ad f1 e9 84
+
+ %% PRK = SAPTrafficsecret
+ %% key info = WriteKeyInfo
+ %% iv info = WrtieIVInfo
+ SWKey =
+ hexstr2bin("9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac 92 e3 56"),
+
+ SWIV =
+ hexstr2bin("cf 78 2b 88 dd 83 54 9a ad f1 e9 84"),
+
+ {SWKey, SWIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, SAPTrafficSecret),
+
+ %% {server} derive read traffic keys for handshake data:
+ %%
+ %% PRK (32 octets): b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e 2d 8f
+ %% 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
+ %%
+ %% key info (13 octets): 00 10 09 74 6c 73 31 33 20 6b 65 79 00
+ %%
+ %% key expanded (16 octets): db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50
+ %% 25 8d 01
+ %%
+ %% iv info (12 octets): 00 0c 08 74 6c 73 31 33 20 69 76 00
+ %%
+ %% iv expanded (12 octets): 5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f
+
+ %% PRK = CHSTrafficsecret
+ %% key info = WriteKeyInfo
+ %% iv info = WrtieIVInfo
+ SRKey =
+ hexstr2bin("db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50 25 8d 01"),
+
+ SRIV =
+ hexstr2bin("5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f"),
+
+ {SRKey, SRIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, CHSTrafficSecret).
+
+%%--------------------------------------------------------------------
+finished_verify_data() ->
+ [{doc,"Test TLS 1.3 Finished message handling"}].
+
+finished_verify_data(_Config) ->
+ ClientHello =
+ hexstr2bin("01 00 00 c6 03 03 00 01 02 03 04 05 06 07 08 09
+ 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19
+ 1a 1b 1c 1d 1e 1f 20 e0 e1 e2 e3 e4 e5 e6 e7 e8
+ e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8
+ f9 fa fb fc fd fe ff 00 06 13 01 13 02 13 03 01
+ 00 00 77 00 00 00 18 00 16 00 00 13 65 78 61 6d
+ 70 6c 65 2e 75 6c 66 68 65 69 6d 2e 6e 65 74 00
+ 0a 00 08 00 06 00 1d 00 17 00 18 00 0d 00 14 00
+ 12 04 03 08 04 04 01 05 03 08 05 05 01 08 06 06
+ 01 02 01 00 33 00 26 00 24 00 1d 00 20 35 80 72
+ d6 36 58 80 d1 ae ea 32 9a df 91 21 38 38 51 ed
+ 21 a2 8e 3b 75 e9 65 d0 d2 cd 16 62 54 00 2d 00
+ 02 01 01 00 2b 00 03 02 03 04"),
+
+ ServerHello =
+ hexstr2bin("02 00 00 76 03 03 70 71 72 73 74 75 76 77 78 79
+ 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89
+ 8a 8b 8c 8d 8e 8f 20 e0 e1 e2 e3 e4 e5 e6 e7 e8
+ e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8
+ f9 fa fb fc fd fe ff 13 01 00 00 2e 00 33 00 24
+ 00 1d 00 20 9f d7 ad 6d cf f4 29 8d d3 f9 6d 5b
+ 1b 2a f9 10 a0 53 5b 14 88 d7 f8 fa bb 34 9a 98
+ 28 80 b6 15 00 2b 00 02 03 04"),
+
+ EncryptedExtensions =
+ hexstr2bin("08 00 00 02 00 00"),
+
+ Certificate =
+ hexstr2bin("0b 00 03 2e 00 00 03 2a 00 03 25 30 82 03 21 30
+ 82 02 09 a0 03 02 01 02 02 08 15 5a 92 ad c2 04
+ 8f 90 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05
+ 00 30 22 31 0b 30 09 06 03 55 04 06 13 02 55 53
+ 31 13 30 11 06 03 55 04 0a 13 0a 45 78 61 6d 70
+ 6c 65 20 43 41 30 1e 17 0d 31 38 31 30 30 35 30
+ 31 33 38 31 37 5a 17 0d 31 39 31 30 30 35 30 31
+ 33 38 31 37 5a 30 2b 31 0b 30 09 06 03 55 04 06
+ 13 02 55 53 31 1c 30 1a 06 03 55 04 03 13 13 65
+ 78 61 6d 70 6c 65 2e 75 6c 66 68 65 69 6d 2e 6e
+ 65 74 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d
+ 01 01 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82
+ 01 01 00 c4 80 36 06 ba e7 47 6b 08 94 04 ec a7
+ b6 91 04 3f f7 92 bc 19 ee fb 7d 74 d7 a8 0d 00
+ 1e 7b 4b 3a 4a e6 0f e8 c0 71 fc 73 e7 02 4c 0d
+ bc f4 bd d1 1d 39 6b ba 70 46 4a 13 e9 4a f8 3d
+ f3 e1 09 59 54 7b c9 55 fb 41 2d a3 76 52 11 e1
+ f3 dc 77 6c aa 53 37 6e ca 3a ec be c3 aa b7 3b
+ 31 d5 6c b6 52 9c 80 98 bc c9 e0 28 18 e2 0b f7
+ f8 a0 3a fd 17 04 50 9e ce 79 bd 9f 39 f1 ea 69
+ ec 47 97 2e 83 0f b5 ca 95 de 95 a1 e6 04 22 d5
+ ee be 52 79 54 a1 e7 bf 8a 86 f6 46 6d 0d 9f 16
+ 95 1a 4c f7 a0 46 92 59 5c 13 52 f2 54 9e 5a fb
+ 4e bf d7 7a 37 95 01 44 e4 c0 26 87 4c 65 3e 40
+ 7d 7d 23 07 44 01 f4 84 ff d0 8f 7a 1f a0 52 10
+ d1 f4 f0 d5 ce 79 70 29 32 e2 ca be 70 1f df ad
+ 6b 4b b7 11 01 f4 4b ad 66 6a 11 13 0f e2 ee 82
+ 9e 4d 02 9d c9 1c dd 67 16 db b9 06 18 86 ed c1
+ ba 94 21 02 03 01 00 01 a3 52 30 50 30 0e 06 03
+ 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03
+ 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03
+ 02 06 08 2b 06 01 05 05 07 03 01 30 1f 06 03 55
+ 1d 23 04 18 30 16 80 14 89 4f de 5b cc 69 e2 52
+ cf 3e a3 00 df b1 97 b8 1d e1 c1 46 30 0d 06 09
+ 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01 00
+ 59 16 45 a6 9a 2e 37 79 e4 f6 dd 27 1a ba 1c 0b
+ fd 6c d7 55 99 b5 e7 c3 6e 53 3e ff 36 59 08 43
+ 24 c9 e7 a5 04 07 9d 39 e0 d4 29 87 ff e3 eb dd
+ 09 c1 cf 1d 91 44 55 87 0b 57 1d d1 9b df 1d 24
+ f8 bb 9a 11 fe 80 fd 59 2b a0 39 8c de 11 e2 65
+ 1e 61 8c e5 98 fa 96 e5 37 2e ef 3d 24 8a fd e1
+ 74 63 eb bf ab b8 e4 d1 ab 50 2a 54 ec 00 64 e9
+ 2f 78 19 66 0d 3f 27 cf 20 9e 66 7f ce 5a e2 e4
+ ac 99 c7 c9 38 18 f8 b2 51 07 22 df ed 97 f3 2e
+ 3e 93 49 d4 c6 6c 9e a6 39 6d 74 44 62 a0 6b 42
+ c6 d5 ba 68 8e ac 3a 01 7b dd fc 8e 2c fc ad 27
+ cb 69 d3 cc dc a2 80 41 44 65 d3 ae 34 8c e0 f3
+ 4a b2 fb 9c 61 83 71 31 2b 19 10 41 64 1c 23 7f
+ 11 a5 d6 5c 84 4f 04 04 84 99 38 71 2b 95 9e d6
+ 85 bc 5c 5d d6 45 ed 19 90 94 73 40 29 26 dc b4
+ 0e 34 69 a1 59 41 e8 e2 cc a8 4b b6 08 46 36 a0
+ 00 00"),
+
+ CertificateVerify =
+ hexstr2bin("0f 00 01 04 08 04 01 00 17 fe b5 33 ca 6d 00 7d
+ 00 58 25 79 68 42 4b bc 3a a6 90 9e 9d 49 55 75
+ 76 a5 20 e0 4a 5e f0 5f 0e 86 d2 4f f4 3f 8e b8
+ 61 ee f5 95 22 8d 70 32 aa 36 0f 71 4e 66 74 13
+ 92 6e f4 f8 b5 80 3b 69 e3 55 19 e3 b2 3f 43 73
+ df ac 67 87 06 6d cb 47 56 b5 45 60 e0 88 6e 9b
+ 96 2c 4a d2 8d ab 26 ba d1 ab c2 59 16 b0 9a f2
+ 86 53 7f 68 4f 80 8a ef ee 73 04 6c b7 df 0a 84
+ fb b5 96 7a ca 13 1f 4b 1c f3 89 79 94 03 a3 0c
+ 02 d2 9c bd ad b7 25 12 db 9c ec 2e 5e 1d 00 e5
+ 0c af cf 6f 21 09 1e bc 4f 25 3c 5e ab 01 a6 79
+ ba ea be ed b9 c9 61 8f 66 00 6b 82 44 d6 62 2a
+ aa 56 88 7c cf c6 6a 0f 38 51 df a1 3a 78 cf f7
+ 99 1e 03 cb 2c 3a 0e d8 7d 73 67 36 2e b7 80 5b
+ 00 b2 52 4f f2 98 a4 da 48 7c ac de af 8a 23 36
+ c5 63 1b 3e fa 93 5b b4 11 e7 53 ca 13 b0 15 fe
+ c7 e4 a7 30 f1 36 9f 9e"),
+
+ BaseKey =
+ hexstr2bin("a2 06 72 65 e7 f0 65 2a 92 3d 5d 72 ab 04 67 c4
+ 61 32 ee b9 68 b6 a3 2d 31 1c 80 58 68 54 88 14"),
+
+ VerifyData =
+ hexstr2bin("ea 6e e1 76 dc cc 4a f1 85 9e 9e 4e 93 f7 97 ea
+ c9 a7 8c e4 39 30 1e 35 27 5a d4 3f 3c dd bd e3"),
+
+ Messages = [CertificateVerify,
+ Certificate,
+ EncryptedExtensions,
+ ServerHello,
+ ClientHello],
+
+ FinishedKey = tls_v1:finished_key(BaseKey, sha256),
+ VerifyData = tls_v1:finished_verify_data(FinishedKey, sha256, Messages).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+hexstr2int(S) ->
+ B = hexstr2bin(S),
+ Bits = size(B) * 8,
+ <<Integer:Bits/integer>> = B,
+ Integer.
+
+hexstr2bin(S) when is_binary(S) ->
+ hexstr2bin(S, <<>>);
+hexstr2bin(S) ->
+ hexstr2bin(list_to_binary(S), <<>>).
+%%
+hexstr2bin(<<>>, Acc) ->
+ Acc;
+hexstr2bin(<<C,T/binary>>, Acc) when C =:= 32; %% SPACE
+ C =:= 10; %% LF
+ C =:= 13 -> %% CR
+ hexstr2bin(T, Acc);
+hexstr2bin(<<X,Y,T/binary>>, Acc) ->
+ I = hex2int(X) * 16 + hex2int(Y),
+ hexstr2bin(T, <<Acc/binary,I>>).
+
+hex2int(C) when $0 =< C, C =< $9 ->
+ C - $0;
+hex2int(C) when $A =< C, C =< $F ->
+ C - $A + 10;
+hex2int(C) when $a =< C, C =< $f ->
+ C - $a + 10.
diff --git a/lib/ssl/test/tls_1_3_version_SUITE.erl b/lib/ssl/test/tls_1_3_version_SUITE.erl
new file mode 100644
index 0000000000..f0b224d4e5
--- /dev/null
+++ b/lib/ssl/test/tls_1_3_version_SUITE.erl
@@ -0,0 +1,153 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(tls_1_3_version_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, 'tlsv1.3'}
+ ].
+
+groups() ->
+ [
+ {'tlsv1.3', [], cert_groups()},
+ {rsa, [], tests()},
+ {ecdsa, [], tests()}
+ ].
+
+cert_groups() ->
+ [{group, rsa},
+ {group, ecdsa}].
+
+tests() ->
+ [tls13_client_tls12_server,
+ tls13_client_with_ext_tls12_server,
+ tls12_client_tls13_server].
+
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ [{client_type, erlang}, {server_type, erlang} |
+ Config]
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+init_per_group(rsa, Config0) ->
+ Config = ssl_test_lib:make_rsa_cert(Config0),
+ COpts = proplists:get_value(client_rsa_opts, Config),
+ SOpts = proplists:get_value(server_rsa_opts, Config),
+ [{client_cert_opts, COpts}, {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts, lists:delete(client_cert_opts, Config))];
+init_per_group(ecdsa, Config0) ->
+ PKAlg = crypto:supports(public_keys),
+ case lists:member(ecdsa, PKAlg) andalso
+ (lists:member(ecdh, PKAlg) orelse lists:member(dh, PKAlg)) of
+ true ->
+ Config = ssl_test_lib:make_ecdsa_cert(Config0),
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ [{client_cert_opts, COpts}, {server_cert_opts, SOpts} |
+ lists:delete(server_cert_opts, lists:delete(client_cert_opts, Config))];
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
+init_per_group(GroupName, Config) ->
+ ssl_test_lib:clean_tls_version(Config),
+ case ssl_test_lib:is_tls_version(GroupName) andalso
+ ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ _ ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl:start(),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+tls13_client_tls12_server() ->
+ [{doc,"Test that a TLS 1.3 client can connect to a TLS 1.2 server."}].
+
+tls13_client_tls12_server(Config) when is_list(Config) ->
+ ClientOpts = [{versions,
+ ['tlsv1.3', 'tlsv1.2']} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{versions,
+ ['tlsv1.1', 'tlsv1.2']} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+tls13_client_with_ext_tls12_server() ->
+ [{doc,"Test basic connection between TLS 1.2 server and TLS 1.3 client when "
+ "client has TLS 1.3 specsific extensions"}].
+
+tls13_client_with_ext_tls12_server(Config) ->
+ ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
+
+ ServerOpts = [{versions, ['tlsv1.2']}|ServerOpts0],
+ ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']},
+ {signature_algs_cert, [ecdsa_secp384r1_sha384,
+ ecdsa_secp256r1_sha256,
+ rsa_pss_rsae_sha256,
+ rsa_pkcs1_sha256,
+ {sha256,rsa},{sha256,dsa}]}|ClientOpts0],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
+tls12_client_tls13_server() ->
+ [{doc,"Test that a TLS 1.2 client can connect to a TLS 1.3 server."}].
+
+tls12_client_tls13_server(Config) when is_list(Config) ->
+ ClientOpts = [{versions,
+ ['tlsv1.1', 'tlsv1.2']} | ssl_test_lib:ssl_options(client_cert_opts, Config)],
+ ServerOpts = [{versions,
+ ['tlsv1.3', 'tlsv1.2']} | ssl_test_lib:ssl_options(server_cert_opts, Config)],
+ ssl_test_lib:basic_test(ClientOpts, ServerOpts, Config).
+
diff --git a/lib/ssl/test/tls_api_SUITE.erl b/lib/ssl/test/tls_api_SUITE.erl
new file mode 100644
index 0000000000..5a74ec1892
--- /dev/null
+++ b/lib/ssl/test/tls_api_SUITE.erl
@@ -0,0 +1,880 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(tls_api_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssl/src/ssl_record.hrl").
+-include_lib("ssl/src/ssl_internal.hrl").
+-include_lib("ssl/src/ssl_api.hrl").
+-include_lib("ssl/src/tls_handshake.hrl").
+
+-define(SLEEP, 500).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [
+ {group, 'tlsv1.3'},
+ {group, 'tlsv1.2'},
+ {group, 'tlsv1.1'},
+ {group, 'tlsv1'},
+ {group, 'sslv3'}
+ ].
+
+groups() ->
+ [
+ {'tlsv1.3', [], api_tests() -- [sockname]},
+ {'tlsv1.2', [], api_tests()},
+ {'tlsv1.1', [], api_tests()},
+ {'tlsv1', [], api_tests()},
+ {'sslv3', [], api_tests() ++ [ssl3_cipher_suite_limitation]}
+ ].
+
+api_tests() ->
+ [
+ tls_upgrade,
+ tls_upgrade_with_timeout,
+ tls_downgrade,
+ tls_shutdown,
+ tls_shutdown_write,
+ tls_shutdown_both,
+ tls_shutdown_error,
+ tls_client_closes_socket,
+ tls_closed_in_active_once,
+ tls_tcp_msg,
+ tls_tcp_msg_big,
+ tls_dont_crash_on_handshake_garbage,
+ tls_tcp_error_propagation_in_active_mode,
+ peername,
+ sockname,
+ tls_server_handshake_timeout,
+ transport_close,
+ emulated_options,
+ accept_pool,
+ reuseaddr
+ ].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+
+init_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:sufficient_crypto_support(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, "Missing crypto support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case ssl_test_lib:is_tls_version(GroupName) of
+ true ->
+ ssl_test_lib:clean_tls_version(Config);
+ false ->
+ Config
+ end.
+
+init_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+tls_upgrade() ->
+ [{doc,"Test that you can upgrade an tcp connection to an ssl connection"}].
+
+tls_upgrade(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options,
+ [{active, false} | TcpOpts]},
+ {ssl_options, [{verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, [binary]},
+ {ssl_options, [{verify, verify_peer},
+ {server_name_indication, Hostname} | ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+tls_upgrade_with_timeout() ->
+ [{doc,"Test ssl_accept/3"}].
+
+tls_upgrade_with_timeout(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options,
+ [{active, false} | TcpOpts]},
+ {ssl_options, [{verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, [{verify, verify_peer},
+ {server_name_indication, Hostname} | ClientOpts]}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+tls_downgrade() ->
+ [{doc,"Test that you can downgarde an ssl connection to an tcp connection"}].
+tls_downgrade(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_downgrade_result, [self()]}},
+ {options, [{active, false}, {verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_downgrade_result, [self()]}},
+ {options, [{active, false}, {verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ready, Client, ready),
+
+ Server ! go,
+ Client ! go,
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+tls_shutdown() ->
+ [{doc,"Test API function ssl:shutdown/2"}].
+tls_shutdown(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_shutdown_result, [server]}},
+ {options, [{exit_on_close, false},
+ {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, tls_shutdown_result, [client]}},
+ {options,
+ [{exit_on_close, false},
+ {active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+tls_shutdown_write() ->
+ [{doc,"Test API function ssl:shutdown/2 with option write."}].
+tls_shutdown_write(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_shutdown_write_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_shutdown_write_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+%%--------------------------------------------------------------------
+tls_shutdown_both() ->
+ [{doc,"Test API function ssl:shutdown/2 with option both."}].
+tls_shutdown_both(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_shutdown_both_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_shutdown_both_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+%%--------------------------------------------------------------------
+tls_shutdown_error() ->
+ [{doc,"Test ssl:shutdown/2 error handling"}].
+tls_shutdown_error(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ Port = ssl_test_lib:inet_port(node()),
+ {ok, Listen} = ssl:listen(Port, ServerOpts),
+ {error, enotconn} = ssl:shutdown(Listen, read_write),
+ ok = ssl:close(Listen),
+ {error, closed} = ssl:shutdown(Listen, read_write).
+%%--------------------------------------------------------------------
+tls_client_closes_socket() ->
+ [{doc,"Test what happens when client closes socket before handshake is compleated"}].
+
+tls_client_closes_socket(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Connect = fun() ->
+ {ok, _Socket} = rpc:call(ClientNode, gen_tcp, connect,
+ [Hostname, Port, [binary]]),
+ %% Make sure that ssl_accept is called before
+ %% client process ends and closes socket.
+ ct:sleep(?SLEEP)
+ end,
+
+ _Client = spawn_link(Connect),
+
+ ssl_test_lib:check_result(Server, {error,closed}).
+
+%%--------------------------------------------------------------------
+tls_closed_in_active_once() ->
+ [{doc, "Test that ssl_closed is delivered in active once with non-empty buffer, check ERL-420."}].
+
+tls_closed_in_active_once(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {_ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+ Port = ssl_test_lib:inet_port(node()),
+ Server = fun() ->
+ {ok, Listen} = gen_tcp:listen(Port, TcpOpts),
+ {ok, TcpServerSocket} = gen_tcp:accept(Listen),
+ {ok, ServerSocket} = ssl:handshake(TcpServerSocket, ServerOpts),
+ lists:foreach(
+ fun(_) ->
+ ssl:send(ServerSocket, "some random message\r\n")
+ end, lists:seq(1, 20)),
+ %% Close TCP instead of SSL socket to trigger the bug:
+ gen_tcp:close(TcpServerSocket),
+ gen_tcp:close(Listen)
+ end,
+ spawn_link(Server),
+ {ok, Socket} = ssl:connect(Hostname, Port, [{active, false} | ClientOpts]),
+ Result = tls_closed_in_active_once_loop(Socket),
+ ssl:close(Socket),
+ case Result of
+ ok -> ok;
+ _ -> ct:fail(Result)
+ end.
+%%--------------------------------------------------------------------
+tls_tcp_msg() ->
+ [{doc,"Test what happens when a tcp tries to connect, i,e. a bad (ssl) packet is sent first"}].
+
+tls_tcp_msg(Config) when is_list(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}, {active, false}],
+
+ Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, dummy, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
+ ct:log("Testcase ~p connected to Server ~p ~n", [self(), Server]),
+ gen_tcp:send(Socket, "<SOME GARBLED NON SSL MESSAGE>"),
+
+ receive
+ {tcp_closed, Socket} ->
+ receive
+ {Server, {error, Error}} ->
+ ct:log("Error ~p", [Error])
+ end
+ end.
+%%--------------------------------------------------------------------
+tls_tcp_msg_big() ->
+ [{doc,"Test what happens when a tcp tries to connect, i,e. a bad big (ssl) packet is sent first"}].
+
+tls_tcp_msg_big(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Rand = crypto:strong_rand_bytes(?MAX_CIPHER_TEXT_LENGTH+1),
+ Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, dummy, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
+ ct:log("Testcase ~p connected to Server ~p ~n", [self(), Server]),
+
+ gen_tcp:send(Socket, <<?BYTE(0),
+ ?BYTE(3), ?BYTE(1), ?UINT16(?MAX_CIPHER_TEXT_LENGTH), Rand/binary>>),
+
+ receive
+ {tcp_closed, Socket} ->
+ receive
+ {Server, {error, timeout}} ->
+ ct:fail("hangs");
+ {Server, {error, Error}} ->
+ ct:log("Error ~p", [Error]);
+ {'EXIT', Server, _} ->
+ ok
+ end
+ end.
+
+%%--------------------------------------------------------------------
+tls_dont_crash_on_handshake_garbage() ->
+ [{doc, "Ensure SSL server worker thows an alert on garbage during handshake "
+ "instead of crashing and exposing state to user code"}].
+
+tls_dont_crash_on_handshake_garbage(Config) ->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {_ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ unlink(Server), monitor(process, Server),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {active, false}]),
+
+ % Send hello and garbage record
+ ok = gen_tcp:send(Socket,
+ [<<22, 3,3, 49:16, 1, 45:24, 3,3, % client_hello
+ 16#deadbeef:256, % 32 'random' bytes = 256 bits
+ 0, 6:16, 0,255, 0,61, 0,57, 1, 0 >>, % some hello values
+
+ <<22, 3,3, 5:16, 92,64,37,228,209>> % garbage
+ ]),
+ % Send unexpected change_cipher_spec
+ ok = gen_tcp:send(Socket, <<20, 3,3, 12:16, 111,40,244,7,137,224,16,109,197,110,249,152>>),
+
+ % Ensure we receive an alert, not sudden disconnect
+ {ok, <<21, _/binary>>} = drop_handshakes(Socket, 1000).
+
+%%--------------------------------------------------------------------
+tls_tcp_error_propagation_in_active_mode() ->
+ [{doc,"Test that process recives {ssl_error, Socket, closed} when tcp error ocurres"}].
+tls_tcp_error_propagation_in_active_mode(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {Client, #sslsocket{pid=[Pid|_]} = SslSocket} = ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, receive_msg, []}},
+ {options, ClientOpts}]),
+
+ {status, _, _, StatusInfo} = sys:get_status(Pid),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ StaticEnv = element(2, State),
+ Socket = element(11, StaticEnv),
+ %% Fake tcp error
+ Pid ! {tcp_error, Socket, etimedout},
+
+ ssl_test_lib:check_result(Client, {ssl_closed, SslSocket}).
+
+%%--------------------------------------------------------------------
+peername() ->
+ [{doc,"Test API function peername/1"}].
+
+peername(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode, server),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode, client),
+ ServerMsg = {ok, {ClientIp, ClientPort}},
+ ClientMsg = {ok, {ServerIp, Port}},
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+sockname() ->
+ [{doc,"Test API function sockname/1"}].
+sockname(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode, server),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode, client),
+ ServerMsg = {ok, {ServerIp, Port}},
+ ClientMsg = {ok, {ClientIp, ClientPort}},
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+tls_server_handshake_timeout() ->
+ [{doc,"Test server handshake timeout"}].
+
+tls_server_handshake_timeout(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {ssl_test_lib,
+ no_result_msg, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {ok, CSocket} = gen_tcp:connect(Hostname, Port, [binary, {active, true}]),
+
+ receive
+ {tcp_closed, CSocket} ->
+ ssl_test_lib:check_result(Server, {error, timeout}),
+ receive
+ {'EXIT', Server, _} ->
+ %% Make sure supervisor had time to react on process exit
+ %% Could we come up with a better solution to this?
+ ct:sleep(500),
+ [] = supervisor:which_children(tls_connection_sup)
+ end
+ end.
+transport_close() ->
+ [{doc, "Test what happens if socket is closed on TCP level after a while of normal operation"}].
+transport_close(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {ok, TcpS} = rpc:call(ClientNode, gen_tcp, connect,
+ [Hostname,Port,[binary, {active, false}]]),
+ {ok, SslS} = rpc:call(ClientNode, ssl, connect,
+ [TcpS,[{active, false}|ClientOpts]]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), self(), Server]),
+ ok = ssl:send(SslS, "Hello world"),
+ {ok,<<"Hello world">>} = ssl:recv(SslS, 11),
+ gen_tcp:close(TcpS),
+ {error, _} = ssl:send(SslS, "Hello world").
+
+%%--------------------------------------------------------------------
+ssl3_cipher_suite_limitation() ->
+ [{doc,"Test a SSLv3 client cannot negotiate a TLSv* cipher suite."}].
+ssl3_cipher_suite_limitation(Config) when is_list(Config) ->
+
+ {_ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {active, false}]),
+ ok = gen_tcp:send(Socket,
+ <<22, 3,0, 49:16, % handshake, SSL 3.0, length
+ 1, 45:24, % client_hello, length
+ 3,0, % SSL 3.0
+ 16#deadbeef:256, % 32 'random' bytes = 256 bits
+ 0, % no session ID
+ %% three cipher suites -- null, one with sha256 hash and one with sha hash
+ 6:16, 0,255, 0,61, 0,57,
+ 1, 0 % no compression
+ >>),
+ {ok, <<22, RecMajor:8, RecMinor:8, _RecLen:16, 2, HelloLen:24>>} = gen_tcp:recv(Socket, 9, 10000),
+ {ok, <<HelloBin:HelloLen/binary>>} = gen_tcp:recv(Socket, HelloLen, 5000),
+ ServerHello = tls_handshake:decode_handshake({RecMajor, RecMinor}, 2, HelloBin),
+ case ServerHello of
+ #server_hello{server_version = {3,0}, cipher_suite = <<0,57>>} ->
+ ok;
+ _ ->
+ ct:fail({unexpected_server_hello, ServerHello})
+ end.
+%%--------------------------------------------------------------------
+emulated_options() ->
+ [{doc,"Test API function getopts/2 and setopts/2"}].
+
+emulated_options(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {packet, 0}, {header, 0},
+ {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, header, packet, mode],
+
+ NewValues = [{mode, binary}, {active, once}],
+ %% Shall be the reverse order of NewValues!
+ NewOptions = [active, mode],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, tls_socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, tls_socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+
+ {ok, Listen} = ssl:listen(0, ServerOpts),
+ {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
+ ok = ssl:setopts(Listen, [{mode, binary}]),
+ {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
+ {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
+ ssl:close(Listen).
+accept_pool() ->
+ [{doc,"Test having an accept pool."}].
+accept_pool(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server0 = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {accepters, 3},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server0),
+ [Server1, Server2] = ssl_test_lib:accepters(2),
+
+ Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}
+ ]),
+
+ Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}
+ ]),
+
+ Client2 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}
+ ]),
+
+ ssl_test_lib:check_ok([Server0, Server1, Server2, Client0, Client1, Client2]),
+
+ ssl_test_lib:close(Server0),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Server2),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2).
+
+%%--------------------------------------------------------------------
+reuseaddr() ->
+ [{doc,"Test reuseaddr option"}].
+
+reuseaddr(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{active, false}, {reuseaddr, true}| ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false}, {reuseaddr, true} | ServerOpts]}]),
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server1, ok, Client1, ok),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+upgrade_result(Socket) ->
+ ssl:setopts(Socket, [{active, true}]),
+ ok = ssl:send(Socket, "Hello world"),
+ %% Make sure binary is inherited from tcp socket and that we do
+ %% not get the list default!
+ receive
+ {ssl, _, <<"H">>} ->
+ receive
+ {ssl, _, <<"ello world">>} ->
+ ok
+ end;
+ {ssl, _, <<"Hello world">>} ->
+ ok
+ end.
+tls_downgrade_result(Socket, Pid) ->
+ ok = ssl_test_lib:send_recv_result(Socket),
+ Pid ! {self(), ready},
+ receive
+ go ->
+ ok
+ end,
+ case ssl:close(Socket, {self(), 10000}) of
+ {ok, TCPSocket} ->
+ inet:setopts(TCPSocket, [{active, true}]),
+ gen_tcp:send(TCPSocket, "Downgraded"),
+ receive
+ {tcp, TCPSocket, <<"Downgraded">>} ->
+ ok;
+ {tcp_closed, TCPSocket} ->
+ ct:fail("Peer timed out, downgrade aborted"),
+ ok;
+ Other ->
+ {error, Other}
+ end;
+ {error, timeout} ->
+ ct:fail("Timed out, downgrade aborted"),
+ ok;
+ Fail ->
+ {error, Fail}
+ end.
+
+tls_shutdown_result(Socket, server) ->
+ ssl:send(Socket, "Hej"),
+ ok = ssl:shutdown(Socket, write),
+ {ok, "Hej hopp"} = ssl:recv(Socket, 8),
+ ok;
+
+tls_shutdown_result(Socket, client) ->
+ ssl:send(Socket, "Hej hopp"),
+ ok = ssl:shutdown(Socket, write),
+ {ok, "Hej"} = ssl:recv(Socket, 3),
+ ok.
+
+tls_shutdown_write_result(Socket, server) ->
+ ct:sleep(?SLEEP),
+ ssl:shutdown(Socket, write);
+tls_shutdown_write_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+tls_shutdown_both_result(Socket, server) ->
+ ct:sleep(?SLEEP),
+ ssl:shutdown(Socket, read_write);
+tls_shutdown_both_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+tls_closed_in_active_once_loop(Socket) ->
+ case ssl:setopts(Socket, [{active, once}]) of
+ ok ->
+ receive
+ {ssl, Socket, _} ->
+ tls_closed_in_active_once_loop(Socket);
+ {ssl_closed, Socket} ->
+ ok
+ after 5000 ->
+ no_ssl_closed_received
+ end;
+ {error, closed} ->
+ ok
+ end.
+
+drop_handshakes(Socket, Timeout) ->
+ {ok, <<RecType:8, _RecMajor:8, _RecMinor:8, RecLen:16>> = Header} = gen_tcp:recv(Socket, 5, Timeout),
+ {ok, <<Frag:RecLen/binary>>} = gen_tcp:recv(Socket, RecLen, Timeout),
+ case RecType of
+ 22 -> drop_handshakes(Socket, Timeout);
+ _ -> {ok, <<Header/binary, Frag/binary>>}
+ end.
+
+receive_msg(_) ->
+ receive
+ Msg ->
+ Msg
+ end.
+
+sockname_result(S) ->
+ ssl:sockname(S).
+
+peername_result(S) ->
+ ssl:peername(S).
+
+tls_socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+ %% Test get/set emulated opts
+ {ok, DefaultValues} = ssl:getopts(Socket, Options),
+ ssl:setopts(Socket, NewValues),
+ {ok, NewValues} = ssl:getopts(Socket, NewOptions),
+ %% Test get/set inet opts
+ {ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
+ ssl:setopts(Socket, [{nodelay, true}]),
+ {ok,[{nodelay, true}]} = ssl:getopts(Socket, [nodelay]),
+ {ok, All} = ssl:getopts(Socket, []),
+ ct:log("All opts ~p~n", [All]),
+ ok.
+
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 01dee392f5..c9547cae36 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 9.3.3
+SSL_VSN = 9.3.5
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index d7d57941c2..e6c42b9aac 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -108,7 +108,7 @@
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-3.0","kernel-6.0","erts-@OTP-15831:OTP-15836@","crypto-3.3",
+ {runtime_dependencies, ["sasl-3.0","kernel-6.0","erts-@OTP-15831:OTP-15836:OTP-15889@","crypto-3.3",
"compiler-5.0"]}
]}.
diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl
index 9b2033ec4a..be8ab3b98e 100644
--- a/lib/stdlib/test/binary_module_SUITE.erl
+++ b/lib/stdlib/test/binary_module_SUITE.erl
@@ -716,22 +716,22 @@ referenced(Config) when is_list(Config) ->
badarg = ?MASK_ERROR(binary:referenced_byte_size(apa)),
badarg = ?MASK_ERROR(binary:referenced_byte_size({})),
badarg = ?MASK_ERROR(binary:referenced_byte_size(1)),
- A = <<1,2,3>>,
- B = binary:copy(A,1000),
- 3 = binary:referenced_byte_size(A),
- 3000 = binary:referenced_byte_size(B),
- <<_:8,C:2/binary>> = A,
- 3 = binary:referenced_byte_size(C),
- 2 = binary:referenced_byte_size(binary:copy(C)),
- <<_:7,D:2/binary,_:1>> = A,
- 2 = binary:referenced_byte_size(binary:copy(D)),
- 3 = binary:referenced_byte_size(D),
- <<_:8,E:2/binary,_/binary>> = B,
- 3000 = binary:referenced_byte_size(E),
- 2 = binary:referenced_byte_size(binary:copy(E)),
- <<_:7,F:2/binary,_:1,_/binary>> = B,
- 2 = binary:referenced_byte_size(binary:copy(F)),
- 3000 = binary:referenced_byte_size(F),
+ A = <<0:(1024 * 8)>>,
+ B = binary:copy(A, 1000),
+ 1024 = binary:referenced_byte_size(A),
+ 1024000 = binary:referenced_byte_size(B),
+ <<_:8,C:1023/binary>> = A,
+ 1024 = binary:referenced_byte_size(C),
+ 1023 = binary:referenced_byte_size(binary:copy(C)),
+ <<_:7,D:1023/binary,_:1>> = A,
+ 1023 = binary:referenced_byte_size(binary:copy(D)),
+ 1024 = binary:referenced_byte_size(D),
+ <<_:8,E:128/binary,_/binary>> = B,
+ 1024000 = binary:referenced_byte_size(E),
+ 128 = binary:referenced_byte_size(binary:copy(E)),
+ <<_:7,F:128/binary,_:1,_/binary>> = B,
+ 128 = binary:referenced_byte_size(binary:copy(F)),
+ 1024000 = binary:referenced_byte_size(F),
ok.
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput1 b/lib/stdlib/test/re_SUITE_data/testoutput1
index eff8ecc948..e6147e60b9 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput1
+++ b/lib/stdlib/test/re_SUITE_data/testoutput1
@@ -9446,4 +9446,28 @@ No match
>XXX<
0: X
+/ (?<word> \w+ )* \. /xi
+ pokus.
+ 0: pokus.
+ 1: pokus
+
+/(?(DEFINE) (?<word> \w+ ) ) (?&word)* \./xi
+ pokus.
+ 0: pokus.
+
+/(?(DEFINE) (?<word> \w+ ) ) ( (?&word)* ) \./xi
+ pokus.
+ 0: pokus.
+ 1: <unset>
+ 2: pokus
+
+/(?&word)* (?(DEFINE) (?<word> \w+ ) ) \./xi
+ pokus.
+ 0: pokus.
+
+/(?&word)* \. (?<word> \w+ )/xi
+ pokus.hokus
+ 0: pokus.hokus
+ 1: hokus
+
/-- End of testinput1 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput2 b/lib/stdlib/test/re_SUITE_data/testoutput2
index 61ed8d9d4e..4ccda27201 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput2
+++ b/lib/stdlib/test/re_SUITE_data/testoutput2
@@ -14721,4 +14721,8 @@ No need char
0: ab
1: a
+/(?(?=^))b/
+ abc
+ 0: b
+
/-- End of testinput2 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput4 b/lib/stdlib/test/re_SUITE_data/testoutput4
index d43c12392d..69e812cd35 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput4
+++ b/lib/stdlib/test/re_SUITE_data/testoutput4
@@ -1277,4 +1277,8 @@ No match
\\C(\\W?Å¿)'?{{
No match
+/[^\x{100}-\x{ffff}]*[\x80-\xff]/8
+ \x{99}\x{99}\x{99}
+ 0: \x{99}\x{99}\x{99}
+
/-- End of testinput4 --/
diff --git a/lib/stdlib/test/re_testoutput1_replacement_test.erl b/lib/stdlib/test/re_testoutput1_replacement_test.erl
index f14df547ef..bb43047757 100644
--- a/lib/stdlib/test/re_testoutput1_replacement_test.erl
+++ b/lib/stdlib/test/re_testoutput1_replacement_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20014,4 +20014,31 @@ run56() ->
<<" MumdPEeFred:099">> = iolist_to_binary(re:replace(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])","\\1&M&umdPE&e",[global])),
<<" ugxGKrBXEcHyG">> = iolist_to_binary(re:replace(" X","(?=.*X)X$","ugxGKrB&EcHyG",[])),
<<" ugxGKrBXEcHyG">> = iolist_to_binary(re:replace(" X","(?=.*X)X$","ugxGKrB&EcHyG",[global])),
+ <<">MHFvXX<">> = iolist_to_binary(re:replace(">XXX<","X+(?#comment)?","MHFv",[])),
+ <<">MHFvMHFvMHFv<">> = iolist_to_binary(re:replace(">XXX<","X+(?#comment)?","MHFv",[global])),
+ <<"lTpokusldxfHXOpokuswsrRorpokus.">> = iolist_to_binary(re:replace("pokus."," (?<word> \\w+ )* \\. ","lT\\1ldxfHXO\\1wsrRor&",[extended,
+ caseless])),
+ <<"lTpokusldxfHXOpokuswsrRorpokus.">> = iolist_to_binary(re:replace("pokus."," (?<word> \\w+ )* \\. ","lT\\1ldxfHXO\\1wsrRor&",[extended,
+ caseless,
+ global])),
+ <<"Oeapokus.xo">> = iolist_to_binary(re:replace("pokus.","(?(DEFINE) (?<word> \\w+ ) ) (?&word)* \\.","Oea&xo",[extended,
+ caseless])),
+ <<"Oeapokus.xo">> = iolist_to_binary(re:replace("pokus.","(?(DEFINE) (?<word> \\w+ ) ) (?&word)* \\.","Oea&xo",[extended,
+ caseless,
+ global])),
+ <<"Wpokus.pity">> = iolist_to_binary(re:replace("pokus.","(?(DEFINE) (?<word> \\w+ ) ) ( (?&word)* ) \\.","W&pity",[extended,
+ caseless])),
+ <<"Wpokus.pity">> = iolist_to_binary(re:replace("pokus.","(?(DEFINE) (?<word> \\w+ ) ) ( (?&word)* ) \\.","W&pity",[extended,
+ caseless,
+ global])),
+ <<"iujmNtBvmcyi">> = iolist_to_binary(re:replace("pokus.","(?&word)* (?(DEFINE) (?<word> \\w+ ) ) \\.","iuj\\1m\\1NtBvmcyi\\1",[extended,
+ caseless])),
+ <<"iujmNtBvmcyi">> = iolist_to_binary(re:replace("pokus.","(?&word)* (?(DEFINE) (?<word> \\w+ ) ) \\.","iuj\\1m\\1NtBvmcyi\\1",[extended,
+ caseless,
+ global])),
+ <<"Ipokus.hokusbQpokus.hokusB">> = iolist_to_binary(re:replace("pokus.hokus","(?&word)* \\. (?<word> \\w+ )","I&bQ&B",[extended,
+ caseless])),
+ <<"Ipokus.hokusbQpokus.hokusB">> = iolist_to_binary(re:replace("pokus.hokus","(?&word)* \\. (?<word> \\w+ )","I&bQ&B",[extended,
+ caseless,
+ global])),
ok.
diff --git a/lib/stdlib/test/re_testoutput1_split_test.erl b/lib/stdlib/test/re_testoutput1_split_test.erl
index 8218cd9bd2..fcffa89e3f 100644
--- a/lib/stdlib/test/re_testoutput1_split_test.erl
+++ b/lib/stdlib/test/re_testoutput1_split_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -84,1360 +84,1360 @@ run() ->
run56(),
ok.
run0() ->
- <<"">> = iolist_to_binary(join(re:split("the quick brown fox","the quick brown fox",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("the quick brown fox","the quick brown fox",[trim]))),
<<":">> = iolist_to_binary(join(re:split("the quick brown fox","the quick brown fox",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("the quick brown fox","the quick brown fox",[]))),
- <<"The quick brown FOX">> = iolist_to_binary(join(re:split("The quick brown FOX","the quick brown fox",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("the quick brown fox","the quick brown fox",[]))),
+ <<"The quick brown FOX">> = iolist_to_binary(join(re:split("The quick brown FOX","the quick brown fox",[trim]))),
<<"The quick brown FOX">> = iolist_to_binary(join(re:split("The quick brown FOX","the quick brown fox",[{parts,
- 2}]))),
- <<"The quick brown FOX">> = iolist_to_binary(join(re:split("The quick brown FOX","the quick brown fox",[]))),
- <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","the quick brown fox",[trim]))),
+ 2}]))),
+ <<"The quick brown FOX">> = iolist_to_binary(join(re:split("The quick brown FOX","the quick brown fox",[]))),
+ <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","the quick brown fox",[trim]))),
<<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","the quick brown fox",[{parts,
- 2}]))),
- <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","the quick brown fox",[]))),
- <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","the quick brown fox",[trim]))),
+ 2}]))),
+ <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","the quick brown fox",[]))),
+ <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","the quick brown fox",[trim]))),
<<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","the quick brown fox",[{parts,
- 2}]))),
- <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","the quick brown fox",[]))),
+ 2}]))),
+ <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","the quick brown fox",[]))),
<<"">> = iolist_to_binary(join(re:split("the quick brown fox","The quick brown fox",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("the quick brown fox","The quick brown fox",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("the quick brown fox","The quick brown fox",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("the quick brown fox","The quick brown fox",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("The quick brown FOX","The quick brown fox",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("The quick brown FOX","The quick brown fox",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("The quick brown FOX","The quick brown fox",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("The quick brown FOX","The quick brown fox",[caseless]))),
<<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","The quick brown fox",[caseless,
- trim]))),
+ trim]))),
<<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","The quick brown fox",[caseless,
{parts,
- 2}]))),
- <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","The quick brown fox",[caseless]))),
+ 2}]))),
+ <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about the quick brown fox?","The quick brown fox",[caseless]))),
<<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","The quick brown fox",[caseless,
- trim]))),
+ trim]))),
<<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","The quick brown fox",[caseless,
{parts,
- 2}]))),
- <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","The quick brown fox",[caseless]))),
+ 2}]))),
+ <<"What do you know about :?">> = iolist_to_binary(join(re:split("What do you know about THE QUICK BROWN FOX?","The quick brown fox",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("abcd
- 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz",[trim]))),
+ 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd
9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz",[{parts,
- 2}]))),
+ 2}]))),
<<":">> = iolist_to_binary(join(re:split("abcd
- 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz",[]))),
- <<"">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<">>>">> = iolist_to_binary(join(re:split(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<">>>">> = iolist_to_binary(join(re:split(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<">>>:">> = iolist_to_binary(join(re:split(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<">>>:">> = iolist_to_binary(join(re:split(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<">">> = iolist_to_binary(join(re:split(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<">>>:">> = iolist_to_binary(join(re:split(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<">">> = iolist_to_binary(join(re:split(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<">:">> = iolist_to_binary(join(re:split(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<">:">> = iolist_to_binary(join(re:split(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<">>>>">> = iolist_to_binary(join(re:split(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<">:">> = iolist_to_binary(join(re:split(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<">>>>">> = iolist_to_binary(join(re:split(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<">>>>:">> = iolist_to_binary(join(re:split(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<">>>>:">> = iolist_to_binary(join(re:split(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<">>>>:">> = iolist_to_binary(join(re:split(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(join(re:split("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
+ 2}]))),
+ <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(join(re:split("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[trim]))),
<<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[{parts,
- 2}]))),
- <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abczz","^(abc){1,2}zz",[trim]))),
+ 2}]))),
+ <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(join(re:split("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abczz","^(abc){1,2}zz",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abczz","^(abc){1,2}zz",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abczz","^(abc){1,2}zz",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcabczz","^(abc){1,2}zz",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abczz","^(abc){1,2}zz",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabczz","^(abc){1,2}zz",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabczz","^(abc){1,2}zz",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabczz","^(abc){1,2}zz",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(abc){1,2}zz",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabczz","^(abc){1,2}zz",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(abc){1,2}zz",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(abc){1,2}zz",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(abc){1,2}zz",[]))),
- <<"zz">> = iolist_to_binary(join(re:split("zz","^(abc){1,2}zz",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(abc){1,2}zz",[]))),
+ <<"zz">> = iolist_to_binary(join(re:split("zz","^(abc){1,2}zz",[trim]))),
<<"zz">> = iolist_to_binary(join(re:split("zz","^(abc){1,2}zz",[{parts,
- 2}]))),
- <<"zz">> = iolist_to_binary(join(re:split("zz","^(abc){1,2}zz",[]))),
- <<"abcabcabczz">> = iolist_to_binary(join(re:split("abcabcabczz","^(abc){1,2}zz",[trim]))),
+ 2}]))),
+ <<"zz">> = iolist_to_binary(join(re:split("zz","^(abc){1,2}zz",[]))),
+ <<"abcabcabczz">> = iolist_to_binary(join(re:split("abcabcabczz","^(abc){1,2}zz",[trim]))),
<<"abcabcabczz">> = iolist_to_binary(join(re:split("abcabcabczz","^(abc){1,2}zz",[{parts,
- 2}]))),
- <<"abcabcabczz">> = iolist_to_binary(join(re:split("abcabcabczz","^(abc){1,2}zz",[]))),
- <<">>abczz">> = iolist_to_binary(join(re:split(">>abczz","^(abc){1,2}zz",[trim]))),
+ 2}]))),
+ <<"abcabcabczz">> = iolist_to_binary(join(re:split("abcabcabczz","^(abc){1,2}zz",[]))),
+ <<">>abczz">> = iolist_to_binary(join(re:split(">>abczz","^(abc){1,2}zz",[trim]))),
<<">>abczz">> = iolist_to_binary(join(re:split(">>abczz","^(abc){1,2}zz",[{parts,
- 2}]))),
- <<">>abczz">> = iolist_to_binary(join(re:split(">>abczz","^(abc){1,2}zz",[]))),
- <<":b">> = iolist_to_binary(join(re:split("bc","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<">>abczz">> = iolist_to_binary(join(re:split(">>abczz","^(abc){1,2}zz",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("bc","^(b+?|a){1,2}?c",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("bc","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("bc","^(b+?|a){1,2}?c",[]))),
- <<":b">> = iolist_to_binary(join(re:split("bbc","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("bc","^(b+?|a){1,2}?c",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("bbc","^(b+?|a){1,2}?c",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("bbc","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("bbc","^(b+?|a){1,2}?c",[]))),
- <<":bb">> = iolist_to_binary(join(re:split("bbbc","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("bbc","^(b+?|a){1,2}?c",[]))),
+ <<":bb">> = iolist_to_binary(join(re:split("bbbc","^(b+?|a){1,2}?c",[trim]))),
<<":bb:">> = iolist_to_binary(join(re:split("bbbc","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":bb:">> = iolist_to_binary(join(re:split("bbbc","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":bb:">> = iolist_to_binary(join(re:split("bbbc","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aac","^(b+?|a){1,2}?c",[]))),
- <<":bbbbbbbbbbb">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aac","^(b+?|a){1,2}?c",[]))),
+ <<":bbbbbbbbbbb">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+?|a){1,2}?c",[trim]))),
<<":bbbbbbbbbbb:">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":bbbbbbbbbbb:">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":bbbbbbbbbbb:">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+?|a){1,2}?c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+?|a){1,2}?c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+?|a){1,2}?c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+?|a){1,2}?c",[]))),
- <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+?|a){1,2}?c",[]))),
+ <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+?|a){1,2}?c",[trim]))),
<<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+?|a){1,2}?c",[]))),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+?|a){1,2}?c",[]))),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+?|a){1,2}?c",[trim]))),
<<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+?|a){1,2}?c",[]))),
- <<":b">> = iolist_to_binary(join(re:split("bc","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+?|a){1,2}?c",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("bc","^(b+|a){1,2}c",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("bc","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("bc","^(b+|a){1,2}c",[]))),
- <<":bb">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("bc","^(b+|a){1,2}c",[]))),
+ <<":bb">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}c",[trim]))),
<<":bb:">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":bb:">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}c",[]))),
- <<":bbb">> = iolist_to_binary(join(re:split("bbbc","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":bb:">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}c",[]))),
+ <<":bbb">> = iolist_to_binary(join(re:split("bbbc","^(b+|a){1,2}c",[trim]))),
<<":bbb:">> = iolist_to_binary(join(re:split("bbbc","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":bbb:">> = iolist_to_binary(join(re:split("bbbc","^(b+|a){1,2}c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":bbb:">> = iolist_to_binary(join(re:split("bbbc","^(b+|a){1,2}c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aac","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aac","^(b+|a){1,2}c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aac","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aac","^(b+|a){1,2}c",[]))),
- <<":bbbbbbbbbbb">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aac","^(b+|a){1,2}c",[]))),
+ <<":bbbbbbbbbbb">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+|a){1,2}c",[trim]))),
<<":bbbbbbbbbbb:">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":bbbbbbbbbbb:">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+|a){1,2}c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":bbbbbbbbbbb:">> = iolist_to_binary(join(re:split("abbbbbbbbbbbc","^(b+|a){1,2}c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+|a){1,2}c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+|a){1,2}c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbbbbbbbbbac","^(b+|a){1,2}c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+|a){1,2}c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+|a){1,2}c",[]))),
- <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b+|a){1,2}c",[]))),
+ <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+|a){1,2}c",[trim]))),
<<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+|a){1,2}c",[]))),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+|a){1,2}c",[trim]))),
+ 2}]))),
+ <<"aaac">> = iolist_to_binary(join(re:split("aaac","^(b+|a){1,2}c",[]))),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+|a){1,2}c",[trim]))),
<<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+|a){1,2}c",[{parts,
- 2}]))),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+|a){1,2}c",[]))),
- <<":b">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}?bc",[trim]))),
+ 2}]))),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(join(re:split("abbbbbbbbbbbac","^(b+|a){1,2}c",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}?bc",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}?bc",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}?bc",[]))),
- <<":ba">> = iolist_to_binary(join(re:split("babc","^(b*|ba){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("bbc","^(b+|a){1,2}?bc",[]))),
+ <<":ba">> = iolist_to_binary(join(re:split("babc","^(b*|ba){1,2}?bc",[trim]))),
<<":ba:">> = iolist_to_binary(join(re:split("babc","^(b*|ba){1,2}?bc",[{parts,
- 2}]))),
- <<":ba:">> = iolist_to_binary(join(re:split("babc","^(b*|ba){1,2}?bc",[]))),
- <<":ba">> = iolist_to_binary(join(re:split("bbabc","^(b*|ba){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":ba:">> = iolist_to_binary(join(re:split("babc","^(b*|ba){1,2}?bc",[]))),
+ <<":ba">> = iolist_to_binary(join(re:split("bbabc","^(b*|ba){1,2}?bc",[trim]))),
<<":ba:">> = iolist_to_binary(join(re:split("bbabc","^(b*|ba){1,2}?bc",[{parts,
- 2}]))),
- <<":ba:">> = iolist_to_binary(join(re:split("bbabc","^(b*|ba){1,2}?bc",[]))),
- <<":ba">> = iolist_to_binary(join(re:split("bababc","^(b*|ba){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":ba:">> = iolist_to_binary(join(re:split("bbabc","^(b*|ba){1,2}?bc",[]))),
+ <<":ba">> = iolist_to_binary(join(re:split("bababc","^(b*|ba){1,2}?bc",[trim]))),
<<":ba:">> = iolist_to_binary(join(re:split("bababc","^(b*|ba){1,2}?bc",[{parts,
- 2}]))),
- <<":ba:">> = iolist_to_binary(join(re:split("bababc","^(b*|ba){1,2}?bc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b*|ba){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":ba:">> = iolist_to_binary(join(re:split("bababc","^(b*|ba){1,2}?bc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b*|ba){1,2}?bc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b*|ba){1,2}?bc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b*|ba){1,2}?bc",[]))),
- <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(b*|ba){1,2}?bc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(b*|ba){1,2}?bc",[]))),
+ <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(b*|ba){1,2}?bc",[trim]))),
<<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(b*|ba){1,2}?bc",[{parts,
- 2}]))),
- <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(b*|ba){1,2}?bc",[]))),
- <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(b*|ba){1,2}?bc",[trim]))),
+ 2}]))),
+ <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(b*|ba){1,2}?bc",[]))),
+ <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(b*|ba){1,2}?bc",[trim]))),
<<"babababc">> = iolist_to_binary(join(re:split("babababc","^(b*|ba){1,2}?bc",[{parts,
- 2}]))),
- <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(b*|ba){1,2}?bc",[]))),
- <<":ba">> = iolist_to_binary(join(re:split("babc","^(ba|b*){1,2}?bc",[trim]))),
+ 2}]))),
+ <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(b*|ba){1,2}?bc",[]))),
+ <<":ba">> = iolist_to_binary(join(re:split("babc","^(ba|b*){1,2}?bc",[trim]))),
<<":ba:">> = iolist_to_binary(join(re:split("babc","^(ba|b*){1,2}?bc",[{parts,
- 2}]))),
- <<":ba:">> = iolist_to_binary(join(re:split("babc","^(ba|b*){1,2}?bc",[]))),
- <<":ba">> = iolist_to_binary(join(re:split("bbabc","^(ba|b*){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":ba:">> = iolist_to_binary(join(re:split("babc","^(ba|b*){1,2}?bc",[]))),
+ <<":ba">> = iolist_to_binary(join(re:split("bbabc","^(ba|b*){1,2}?bc",[trim]))),
<<":ba:">> = iolist_to_binary(join(re:split("bbabc","^(ba|b*){1,2}?bc",[{parts,
- 2}]))),
- <<":ba:">> = iolist_to_binary(join(re:split("bbabc","^(ba|b*){1,2}?bc",[]))),
- <<":ba">> = iolist_to_binary(join(re:split("bababc","^(ba|b*){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":ba:">> = iolist_to_binary(join(re:split("bbabc","^(ba|b*){1,2}?bc",[]))),
+ <<":ba">> = iolist_to_binary(join(re:split("bababc","^(ba|b*){1,2}?bc",[trim]))),
<<":ba:">> = iolist_to_binary(join(re:split("bababc","^(ba|b*){1,2}?bc",[{parts,
- 2}]))),
- <<":ba:">> = iolist_to_binary(join(re:split("bababc","^(ba|b*){1,2}?bc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ba|b*){1,2}?bc",[trim]))),
+ 2}]))),
+ <<":ba:">> = iolist_to_binary(join(re:split("bababc","^(ba|b*){1,2}?bc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ba|b*){1,2}?bc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ba|b*){1,2}?bc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ba|b*){1,2}?bc",[]))),
- <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(ba|b*){1,2}?bc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ba|b*){1,2}?bc",[]))),
+ <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(ba|b*){1,2}?bc",[trim]))),
<<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(ba|b*){1,2}?bc",[{parts,
- 2}]))),
- <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(ba|b*){1,2}?bc",[]))),
- <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[trim]))),
+ 2}]))),
+ <<"bababbc">> = iolist_to_binary(join(re:split("bababbc","^(ba|b*){1,2}?bc",[]))),
+ <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[trim]))),
<<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[{parts,
- 2}]))),
- <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[]))),
- <<"">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[trim]))),
+ 2}]))),
+ <<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[trim]))),
<<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("bthing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("bthing","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("bthing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("bthing","^[ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("]thing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("bthing","^[ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("]thing","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("]thing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("]thing","^[ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("cthing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("]thing","^[ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("cthing","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("cthing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("cthing","^[ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("dthing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("cthing","^[ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("dthing","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("dthing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("dthing","^[ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("ething","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("dthing","^[ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("ething","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("ething","^[ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("ething","^[ab\\]cde]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("ething","^[ab\\]cde]",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[ab\\]cde]",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[ab\\]cde]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[ab\\]cde]",[]))),
- <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[ab\\]cde]",[]))),
+ <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[ab\\]cde]",[trim]))),
<<"fthing">> = iolist_to_binary(join(re:split("fthing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[ab\\]cde]",[]))),
- <<"[thing">> = iolist_to_binary(join(re:split("[thing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[ab\\]cde]",[]))),
+ <<"[thing">> = iolist_to_binary(join(re:split("[thing","^[ab\\]cde]",[trim]))),
<<"[thing">> = iolist_to_binary(join(re:split("[thing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<"[thing">> = iolist_to_binary(join(re:split("[thing","^[ab\\]cde]",[]))),
- <<"\\thing">> = iolist_to_binary(join(re:split("\\thing","^[ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"[thing">> = iolist_to_binary(join(re:split("[thing","^[ab\\]cde]",[]))),
+ <<"\\thing">> = iolist_to_binary(join(re:split("\\thing","^[ab\\]cde]",[trim]))),
<<"\\thing">> = iolist_to_binary(join(re:split("\\thing","^[ab\\]cde]",[{parts,
- 2}]))),
- <<"\\thing">> = iolist_to_binary(join(re:split("\\thing","^[ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("]thing","^[]cde]",[trim]))),
+ 2}]))),
+ <<"\\thing">> = iolist_to_binary(join(re:split("\\thing","^[ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("]thing","^[]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("]thing","^[]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("]thing","^[]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("cthing","^[]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("]thing","^[]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("cthing","^[]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("cthing","^[]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("cthing","^[]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("dthing","^[]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("cthing","^[]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("dthing","^[]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("dthing","^[]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("dthing","^[]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("ething","^[]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("dthing","^[]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("ething","^[]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("ething","^[]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("ething","^[]cde]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("ething","^[]cde]",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[]cde]",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[]cde]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[]cde]",[]))),
- <<"athing">> = iolist_to_binary(join(re:split("athing","^[]cde]",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[]cde]",[]))),
+ <<"athing">> = iolist_to_binary(join(re:split("athing","^[]cde]",[trim]))),
<<"athing">> = iolist_to_binary(join(re:split("athing","^[]cde]",[{parts,
- 2}]))),
- <<"athing">> = iolist_to_binary(join(re:split("athing","^[]cde]",[]))),
- <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[]cde]",[trim]))),
+ 2}]))),
+ <<"athing">> = iolist_to_binary(join(re:split("athing","^[]cde]",[]))),
+ <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[]cde]",[trim]))),
<<"fthing">> = iolist_to_binary(join(re:split("fthing","^[]cde]",[{parts,
- 2}]))),
- <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"fthing">> = iolist_to_binary(join(re:split("fthing","^[]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("fthing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("[thing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("[thing","^[^ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("[thing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("[thing","^[^ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("\\thing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("[thing","^[^ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("\\thing","^[^ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("\\thing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("\\thing","^[^ab\\]cde]",[]))),
- <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("\\thing","^[^ab\\]cde]",[]))),
+ <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^ab\\]cde]",[trim]))),
<<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^ab\\]cde]",[]))),
- <<"athing">> = iolist_to_binary(join(re:split("athing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^ab\\]cde]",[]))),
+ <<"athing">> = iolist_to_binary(join(re:split("athing","^[^ab\\]cde]",[trim]))),
<<"athing">> = iolist_to_binary(join(re:split("athing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<"athing">> = iolist_to_binary(join(re:split("athing","^[^ab\\]cde]",[]))),
- <<"bthing">> = iolist_to_binary(join(re:split("bthing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"athing">> = iolist_to_binary(join(re:split("athing","^[^ab\\]cde]",[]))),
+ <<"bthing">> = iolist_to_binary(join(re:split("bthing","^[^ab\\]cde]",[trim]))),
<<"bthing">> = iolist_to_binary(join(re:split("bthing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<"bthing">> = iolist_to_binary(join(re:split("bthing","^[^ab\\]cde]",[]))),
- <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"bthing">> = iolist_to_binary(join(re:split("bthing","^[^ab\\]cde]",[]))),
+ <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^ab\\]cde]",[trim]))),
<<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^ab\\]cde]",[]))),
- <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^ab\\]cde]",[]))),
+ <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^ab\\]cde]",[trim]))),
<<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^ab\\]cde]",[]))),
- <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^ab\\]cde]",[]))),
+ <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^ab\\]cde]",[trim]))),
<<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^ab\\]cde]",[]))),
- <<"ething">> = iolist_to_binary(join(re:split("ething","^[^ab\\]cde]",[trim]))),
+ 2}]))),
+ <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^ab\\]cde]",[]))),
+ <<"ething">> = iolist_to_binary(join(re:split("ething","^[^ab\\]cde]",[trim]))),
<<"ething">> = iolist_to_binary(join(re:split("ething","^[^ab\\]cde]",[{parts,
- 2}]))),
- <<"ething">> = iolist_to_binary(join(re:split("ething","^[^ab\\]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("athing","^[^]cde]",[trim]))),
+ 2}]))),
+ <<"ething">> = iolist_to_binary(join(re:split("ething","^[^ab\\]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("athing","^[^]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("athing","^[^]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("athing","^[^]cde]",[]))),
- <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("athing","^[^]cde]",[]))),
+ <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("fthing","^[^]cde]",[{parts,
- 2}]))),
- <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^]cde]",[]))),
- <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^]cde]",[trim]))),
+ 2}]))),
+ <<":thing">> = iolist_to_binary(join(re:split("fthing","^[^]cde]",[]))),
+ <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^]cde]",[trim]))),
<<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^]cde]",[{parts,
- 2}]))),
- <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^]cde]",[]))),
- <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^]cde]",[trim]))),
+ 2}]))),
+ <<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[^]cde]",[]))),
+ <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^]cde]",[trim]))),
<<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^]cde]",[{parts,
- 2}]))),
- <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^]cde]",[]))),
- <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^]cde]",[trim]))),
+ 2}]))),
+ <<"]thing">> = iolist_to_binary(join(re:split("]thing","^[^]cde]",[]))),
+ <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^]cde]",[trim]))),
<<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^]cde]",[{parts,
- 2}]))),
- <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^]cde]",[]))),
- <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^]cde]",[trim]))),
+ 2}]))),
+ <<"cthing">> = iolist_to_binary(join(re:split("cthing","^[^]cde]",[]))),
+ <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^]cde]",[trim]))),
<<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^]cde]",[{parts,
- 2}]))),
- <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^]cde]",[]))),
- <<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[trim]))),
+ 2}]))),
+ <<"dthing">> = iolist_to_binary(join(re:split("dthing","^[^]cde]",[]))),
+ <<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[trim]))),
<<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[{parts,
- 2}]))),
- <<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[]))),
- <<"">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("1","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("2","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("2","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("2","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("2","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("3","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("2","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("3","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("3","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("3","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("4","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("3","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("4","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("4","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("4","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("5","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("4","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("5","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("5","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("5","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("6","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("5","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("6","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("6","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("6","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("7","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("6","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("7","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("7","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("7","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("8","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("7","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("8","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("8","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("8","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("9","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("8","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("9","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("9","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("9","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("10","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("9","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("10","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("10","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("10","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("100","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("10","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("100","^[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("100","^[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("100","^[0-9]+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("100","^[0-9]+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[0-9]+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[0-9]+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[0-9]+$",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^[0-9]+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[0-9]+$",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^[0-9]+$",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^[0-9]+$",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("enter","^.*nter",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("enter","^.*nter",[trim]))),
<<":">> = iolist_to_binary(join(re:split("enter","^.*nter",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("enter","^.*nter",[]))),
- <<"">> = iolist_to_binary(join(re:split("inter","^.*nter",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("enter","^.*nter",[]))),
+ <<"">> = iolist_to_binary(join(re:split("inter","^.*nter",[trim]))),
<<":">> = iolist_to_binary(join(re:split("inter","^.*nter",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("inter","^.*nter",[]))),
- <<"">> = iolist_to_binary(join(re:split("uponter","^.*nter",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("inter","^.*nter",[]))),
+ <<"">> = iolist_to_binary(join(re:split("uponter","^.*nter",[trim]))),
<<":">> = iolist_to_binary(join(re:split("uponter","^.*nter",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("uponter","^.*nter",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("uponter","^.*nter",[]))),
ok.
run1() ->
- <<"">> = iolist_to_binary(join(re:split("xxx0","^xxx[0-9]+$",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("xxx0","^xxx[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("xxx0","^xxx[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("xxx0","^xxx[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("xxx1234","^xxx[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("xxx0","^xxx[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("xxx1234","^xxx[0-9]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("xxx1234","^xxx[0-9]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("xxx1234","^xxx[0-9]+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^xxx[0-9]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("xxx1234","^xxx[0-9]+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^xxx[0-9]+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^xxx[0-9]+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^xxx[0-9]+$",[]))),
- <<"xxx">> = iolist_to_binary(join(re:split("xxx","^xxx[0-9]+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^xxx[0-9]+$",[]))),
+ <<"xxx">> = iolist_to_binary(join(re:split("xxx","^xxx[0-9]+$",[trim]))),
<<"xxx">> = iolist_to_binary(join(re:split("xxx","^xxx[0-9]+$",[{parts,
- 2}]))),
- <<"xxx">> = iolist_to_binary(join(re:split("xxx","^xxx[0-9]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("x123","^.+[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<"xxx">> = iolist_to_binary(join(re:split("xxx","^xxx[0-9]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("x123","^.+[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("x123","^.+[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("x123","^.+[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("xx123","^.+[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("x123","^.+[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("xx123","^.+[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("xx123","^.+[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("xx123","^.+[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("123456","^.+[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("xx123","^.+[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("123456","^.+[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("123456","^.+[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("123456","^.+[0-9][0-9][0-9]$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("123456","^.+[0-9][0-9][0-9]$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+[0-9][0-9][0-9]$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+[0-9][0-9][0-9]$",[]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^.+[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+[0-9][0-9][0-9]$",[]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^.+[0-9][0-9][0-9]$",[trim]))),
<<"123">> = iolist_to_binary(join(re:split("123","^.+[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^.+[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("x1234","^.+[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^.+[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("x1234","^.+[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("x1234","^.+[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("x1234","^.+[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("x123","^.+?[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("x1234","^.+[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("x123","^.+?[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("x123","^.+?[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("x123","^.+?[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("xx123","^.+?[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("x123","^.+?[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("xx123","^.+?[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("xx123","^.+?[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("xx123","^.+?[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("123456","^.+?[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("xx123","^.+?[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("123456","^.+?[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("123456","^.+?[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("123456","^.+?[0-9][0-9][0-9]$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+?[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("123456","^.+?[0-9][0-9][0-9]$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+?[0-9][0-9][0-9]$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+?[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+?[0-9][0-9][0-9]$",[]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^.+?[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.+?[0-9][0-9][0-9]$",[]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^.+?[0-9][0-9][0-9]$",[trim]))),
<<"123">> = iolist_to_binary(join(re:split("123","^.+?[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^.+?[0-9][0-9][0-9]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("x1234","^.+?[0-9][0-9][0-9]$",[trim]))),
+ 2}]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^.+?[0-9][0-9][0-9]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("x1234","^.+?[0-9][0-9][0-9]$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("x1234","^.+?[0-9][0-9][0-9]$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("x1234","^.+?[0-9][0-9][0-9]$",[]))),
- <<":abc:pqr">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("x1234","^.+?[0-9][0-9][0-9]$",[]))),
+ <<":abc:pqr">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
<<":abc:pqr:">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[{parts,
- 2}]))),
- <<":abc:pqr:">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
+ 2}]))),
+ <<":abc:pqr:">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
- <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
+ <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
<<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[{parts,
- 2}]))),
- <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
- <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
+ 2}]))),
+ <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
+ <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
<<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[{parts,
- 2}]))),
- <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
- <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
+ 2}]))),
+ <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
+ <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
<<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[{parts,
- 2}]))),
- <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
- <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
+ 2}]))),
+ <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
+ <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[trim]))),
<<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[{parts,
- 2}]))),
- <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
- <<"Well, we need a colon: somewhere">> = iolist_to_binary(join(re:split("Well, we need a colon: somewhere",":",[trim]))),
+ 2}]))),
+ <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(join(re:split("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$",[]))),
+ <<"Well, we need a colon: somewhere">> = iolist_to_binary(join(re:split("Well, we need a colon: somewhere",":",[trim]))),
<<"Well, we need a colon: somewhere">> = iolist_to_binary(join(re:split("Well, we need a colon: somewhere",":",[{parts,
- 2}]))),
- <<"Well, we need a colon: somewhere">> = iolist_to_binary(join(re:split("Well, we need a colon: somewhere",":",[]))),
- <<"*** Fail if we don't">> = iolist_to_binary(join(re:split("*** Fail if we don't",":",[trim]))),
+ 2}]))),
+ <<"Well, we need a colon: somewhere">> = iolist_to_binary(join(re:split("Well, we need a colon: somewhere",":",[]))),
+ <<"*** Fail if we don't">> = iolist_to_binary(join(re:split("*** Fail if we don't",":",[trim]))),
<<"*** Fail if we don't">> = iolist_to_binary(join(re:split("*** Fail if we don't",":",[{parts,
- 2}]))),
- <<"*** Fail if we don't">> = iolist_to_binary(join(re:split("*** Fail if we don't",":",[]))),
+ 2}]))),
+ <<"*** Fail if we don't">> = iolist_to_binary(join(re:split("*** Fail if we don't",":",[]))),
<<":0abc">> = iolist_to_binary(join(re:split("0abc","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<":0abc:">> = iolist_to_binary(join(re:split("0abc","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<":0abc:">> = iolist_to_binary(join(re:split("0abc","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<":0abc:">> = iolist_to_binary(join(re:split("0abc","([\\da-f:]+)$",[caseless]))),
<<":abc">> = iolist_to_binary(join(re:split("abc","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abc","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abc","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abc","([\\da-f:]+)$",[caseless]))),
<<":fed">> = iolist_to_binary(join(re:split("fed","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<":fed:">> = iolist_to_binary(join(re:split("fed","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<":fed:">> = iolist_to_binary(join(re:split("fed","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<":fed:">> = iolist_to_binary(join(re:split("fed","([\\da-f:]+)$",[caseless]))),
<<":E">> = iolist_to_binary(join(re:split("E","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<":E:">> = iolist_to_binary(join(re:split("E","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<":E:">> = iolist_to_binary(join(re:split("E","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<":E:">> = iolist_to_binary(join(re:split("E","([\\da-f:]+)$",[caseless]))),
<<":::">> = iolist_to_binary(join(re:split("::","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"::::">> = iolist_to_binary(join(re:split("::","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"::::">> = iolist_to_binary(join(re:split("::","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"::::">> = iolist_to_binary(join(re:split("::","([\\da-f:]+)$",[caseless]))),
<<":5f03:12C0::932e">> = iolist_to_binary(join(re:split("5f03:12C0::932e","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<":5f03:12C0::932e:">> = iolist_to_binary(join(re:split("5f03:12C0::932e","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<":5f03:12C0::932e:">> = iolist_to_binary(join(re:split("5f03:12C0::932e","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<":5f03:12C0::932e:">> = iolist_to_binary(join(re:split("5f03:12C0::932e","([\\da-f:]+)$",[caseless]))),
<<"fed :def">> = iolist_to_binary(join(re:split("fed def","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"fed :def:">> = iolist_to_binary(join(re:split("fed def","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"fed :def:">> = iolist_to_binary(join(re:split("fed def","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"fed :def:">> = iolist_to_binary(join(re:split("fed def","([\\da-f:]+)$",[caseless]))),
<<"Any old stu:ff">> = iolist_to_binary(join(re:split("Any old stuff","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"Any old stu:ff:">> = iolist_to_binary(join(re:split("Any old stuff","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"Any old stu:ff:">> = iolist_to_binary(join(re:split("Any old stuff","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"Any old stu:ff:">> = iolist_to_binary(join(re:split("Any old stuff","([\\da-f:]+)$",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","([\\da-f:]+)$",[caseless]))),
<<"0zzz">> = iolist_to_binary(join(re:split("0zzz","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"0zzz">> = iolist_to_binary(join(re:split("0zzz","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"0zzz">> = iolist_to_binary(join(re:split("0zzz","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"0zzz">> = iolist_to_binary(join(re:split("0zzz","([\\da-f:]+)$",[caseless]))),
<<"gzzz">> = iolist_to_binary(join(re:split("gzzz","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"gzzz">> = iolist_to_binary(join(re:split("gzzz","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"gzzz">> = iolist_to_binary(join(re:split("gzzz","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"gzzz">> = iolist_to_binary(join(re:split("gzzz","([\\da-f:]+)$",[caseless]))),
<<"fed ">> = iolist_to_binary(join(re:split("fed ","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"fed ">> = iolist_to_binary(join(re:split("fed ","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"fed ">> = iolist_to_binary(join(re:split("fed ","([\\da-f:]+)$",[caseless]))),
+ 2}]))),
+ <<"fed ">> = iolist_to_binary(join(re:split("fed ","([\\da-f:]+)$",[caseless]))),
<<"Any old rubbish">> = iolist_to_binary(join(re:split("Any old rubbish","([\\da-f:]+)$",[caseless,
- trim]))),
+ trim]))),
<<"Any old rubbish">> = iolist_to_binary(join(re:split("Any old rubbish","([\\da-f:]+)$",[caseless,
{parts,
- 2}]))),
- <<"Any old rubbish">> = iolist_to_binary(join(re:split("Any old rubbish","([\\da-f:]+)$",[caseless]))),
- <<":1:2:3">> = iolist_to_binary(join(re:split(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
+ 2}]))),
+ <<"Any old rubbish">> = iolist_to_binary(join(re:split("Any old rubbish","([\\da-f:]+)$",[caseless]))),
+ <<":1:2:3">> = iolist_to_binary(join(re:split(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
<<":1:2:3:">> = iolist_to_binary(join(re:split(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[{parts,
- 2}]))),
- <<":1:2:3:">> = iolist_to_binary(join(re:split(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
- <<":12:123:0">> = iolist_to_binary(join(re:split("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
+ 2}]))),
+ <<":1:2:3:">> = iolist_to_binary(join(re:split(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
+ <<":12:123:0">> = iolist_to_binary(join(re:split("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
<<":12:123:0:">> = iolist_to_binary(join(re:split("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[{parts,
- 2}]))),
- <<":12:123:0:">> = iolist_to_binary(join(re:split("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
+ 2}]))),
+ <<":12:123:0:">> = iolist_to_binary(join(re:split("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
- <<".1.2.3333">> = iolist_to_binary(join(re:split(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
+ <<".1.2.3333">> = iolist_to_binary(join(re:split(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
<<".1.2.3333">> = iolist_to_binary(join(re:split(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[{parts,
- 2}]))),
- <<".1.2.3333">> = iolist_to_binary(join(re:split(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
- <<"1.2.3">> = iolist_to_binary(join(re:split("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
+ 2}]))),
+ <<".1.2.3333">> = iolist_to_binary(join(re:split(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
+ <<"1.2.3">> = iolist_to_binary(join(re:split("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
<<"1.2.3">> = iolist_to_binary(join(re:split("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[{parts,
- 2}]))),
- <<"1.2.3">> = iolist_to_binary(join(re:split("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
- <<"1234.2.3">> = iolist_to_binary(join(re:split("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
+ 2}]))),
+ <<"1.2.3">> = iolist_to_binary(join(re:split("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
+ <<"1234.2.3">> = iolist_to_binary(join(re:split("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[trim]))),
<<"1234.2.3">> = iolist_to_binary(join(re:split("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[{parts,
- 2}]))),
- <<"1234.2.3">> = iolist_to_binary(join(re:split("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
- <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
+ 2}]))),
+ <<"1234.2.3">> = iolist_to_binary(join(re:split("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",[]))),
+ <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
<<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[{parts,
- 2}]))),
- <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
- <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
+ 2}]))),
+ <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
+ <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
<<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[{parts,
- 2}]))),
- <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
+ 2}]))),
+ <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
- <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(join(re:split("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
+ <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(join(re:split("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
<<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(join(re:split("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[{parts,
- 2}]))),
- <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(join(re:split("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
- <<"">> = iolist_to_binary(join(re:split("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(join(re:split("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<"">> = iolist_to_binary(join(re:split("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<"">> = iolist_to_binary(join(re:split("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<":.pq-r">> = iolist_to_binary(join(re:split("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<":.pq-r">> = iolist_to_binary(join(re:split("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<":.pq-r:">> = iolist_to_binary(join(re:split("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<":.pq-r:">> = iolist_to_binary(join(re:split("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<":.uk">> = iolist_to_binary(join(re:split("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<":.pq-r:">> = iolist_to_binary(join(re:split("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<":.uk">> = iolist_to_binary(join(re:split("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<":.uk:">> = iolist_to_binary(join(re:split("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<":.uk:">> = iolist_to_binary(join(re:split("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<":.y-">> = iolist_to_binary(join(re:split("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<":.uk:">> = iolist_to_binary(join(re:split("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<":.y-">> = iolist_to_binary(join(re:split("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<":.y-:">> = iolist_to_binary(join(re:split("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<":.y-:">> = iolist_to_binary(join(re:split("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<":.y-:">> = iolist_to_binary(join(re:split("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<"-abc.peq.">> = iolist_to_binary(join(re:split("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<"-abc.peq.">> = iolist_to_binary(join(re:split("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[trim]))),
<<"-abc.peq.">> = iolist_to_binary(join(re:split("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[{parts,
- 2}]))),
- <<"-abc.peq.">> = iolist_to_binary(join(re:split("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
- <<"">> = iolist_to_binary(join(re:split("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<"-abc.peq.">> = iolist_to_binary(join(re:split("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<"::::">> = iolist_to_binary(join(re:split("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<"::::">> = iolist_to_binary(join(re:split("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<":0-a">> = iolist_to_binary(join(re:split("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<"::::">> = iolist_to_binary(join(re:split("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<":0-a">> = iolist_to_binary(join(re:split("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<":0-a:::">> = iolist_to_binary(join(re:split("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<":0-a:::">> = iolist_to_binary(join(re:split("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<":3-b:.c">> = iolist_to_binary(join(re:split("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<":0-a:::">> = iolist_to_binary(join(re:split("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<":3-b:.c">> = iolist_to_binary(join(re:split("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<":3-b:.c::">> = iolist_to_binary(join(re:split("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<":3-b:.c::">> = iolist_to_binary(join(re:split("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<":-a:.b-c:-c">> = iolist_to_binary(join(re:split("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<":3-b:.c::">> = iolist_to_binary(join(re:split("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<":-a:.b-c:-c">> = iolist_to_binary(join(re:split("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<":-a:.b-c:-c:">> = iolist_to_binary(join(re:split("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<":-a:.b-c:-c:">> = iolist_to_binary(join(re:split("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<":-a:.b-c:-c:">> = iolist_to_binary(join(re:split("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<"*.0">> = iolist_to_binary(join(re:split("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<"*.0">> = iolist_to_binary(join(re:split("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<"*.0">> = iolist_to_binary(join(re:split("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<"*.0">> = iolist_to_binary(join(re:split("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<"*.a-">> = iolist_to_binary(join(re:split("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<"*.0">> = iolist_to_binary(join(re:split("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<"*.a-">> = iolist_to_binary(join(re:split("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<"*.a-">> = iolist_to_binary(join(re:split("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<"*.a-">> = iolist_to_binary(join(re:split("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<"*.a-b.c-">> = iolist_to_binary(join(re:split("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<"*.a-">> = iolist_to_binary(join(re:split("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<"*.a-b.c-">> = iolist_to_binary(join(re:split("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<"*.a-b.c-">> = iolist_to_binary(join(re:split("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<"*.a-b.c-">> = iolist_to_binary(join(re:split("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<"*.c-a.0-c">> = iolist_to_binary(join(re:split("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
+ 2}]))),
+ <<"*.a-b.c-">> = iolist_to_binary(join(re:split("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<"*.c-a.0-c">> = iolist_to_binary(join(re:split("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[trim]))),
<<"*.c-a.0-c">> = iolist_to_binary(join(re:split("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[{parts,
- 2}]))),
- <<"*.c-a.0-c">> = iolist_to_binary(join(re:split("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
- <<":de:abd:e">> = iolist_to_binary(join(re:split("abde","^(?=ab(de))(abd)(e)",[trim]))),
+ 2}]))),
+ <<"*.c-a.0-c">> = iolist_to_binary(join(re:split("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$",[]))),
+ <<":de:abd:e">> = iolist_to_binary(join(re:split("abde","^(?=ab(de))(abd)(e)",[trim]))),
<<":de:abd:e:">> = iolist_to_binary(join(re:split("abde","^(?=ab(de))(abd)(e)",[{parts,
- 2}]))),
- <<":de:abd:e:">> = iolist_to_binary(join(re:split("abde","^(?=ab(de))(abd)(e)",[]))),
- <<"::abd:f">> = iolist_to_binary(join(re:split("abdf","^(?!(ab)de|x)(abd)(f)",[trim]))),
+ 2}]))),
+ <<":de:abd:e:">> = iolist_to_binary(join(re:split("abde","^(?=ab(de))(abd)(e)",[]))),
+ <<"::abd:f">> = iolist_to_binary(join(re:split("abdf","^(?!(ab)de|x)(abd)(f)",[trim]))),
<<"::abd:f:">> = iolist_to_binary(join(re:split("abdf","^(?!(ab)de|x)(abd)(f)",[{parts,
- 2}]))),
- <<"::abd:f:">> = iolist_to_binary(join(re:split("abdf","^(?!(ab)de|x)(abd)(f)",[]))),
- <<":abcd:cd:ab:cd">> = iolist_to_binary(join(re:split("abcd","^(?=(ab(cd)))(ab)",[trim]))),
+ 2}]))),
+ <<"::abd:f:">> = iolist_to_binary(join(re:split("abdf","^(?!(ab)de|x)(abd)(f)",[]))),
+ <<":abcd:cd:ab:cd">> = iolist_to_binary(join(re:split("abcd","^(?=(ab(cd)))(ab)",[trim]))),
<<":abcd:cd:ab:cd">> = iolist_to_binary(join(re:split("abcd","^(?=(ab(cd)))(ab)",[{parts,
- 2}]))),
- <<":abcd:cd:ab:cd">> = iolist_to_binary(join(re:split("abcd","^(?=(ab(cd)))(ab)",[]))),
+ 2}]))),
+ <<":abcd:cd:ab:cd">> = iolist_to_binary(join(re:split("abcd","^(?=(ab(cd)))(ab)",[]))),
<<":.d">> = iolist_to_binary(join(re:split("a.b.c.d","^[\\da-f](\\.[\\da-f])*$",[caseless,
- trim]))),
+ trim]))),
<<":.d:">> = iolist_to_binary(join(re:split("a.b.c.d","^[\\da-f](\\.[\\da-f])*$",[caseless,
{parts,
- 2}]))),
- <<":.d:">> = iolist_to_binary(join(re:split("a.b.c.d","^[\\da-f](\\.[\\da-f])*$",[caseless]))),
+ 2}]))),
+ <<":.d:">> = iolist_to_binary(join(re:split("a.b.c.d","^[\\da-f](\\.[\\da-f])*$",[caseless]))),
<<":.D">> = iolist_to_binary(join(re:split("A.B.C.D","^[\\da-f](\\.[\\da-f])*$",[caseless,
- trim]))),
+ trim]))),
<<":.D:">> = iolist_to_binary(join(re:split("A.B.C.D","^[\\da-f](\\.[\\da-f])*$",[caseless,
{parts,
- 2}]))),
- <<":.D:">> = iolist_to_binary(join(re:split("A.B.C.D","^[\\da-f](\\.[\\da-f])*$",[caseless]))),
+ 2}]))),
+ <<":.D:">> = iolist_to_binary(join(re:split("A.B.C.D","^[\\da-f](\\.[\\da-f])*$",[caseless]))),
<<":.C">> = iolist_to_binary(join(re:split("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$",[caseless,
- trim]))),
+ trim]))),
<<":.C:">> = iolist_to_binary(join(re:split("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$",[caseless,
{parts,
- 2}]))),
- <<":.C:">> = iolist_to_binary(join(re:split("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("\"1234\"","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
+ 2}]))),
+ <<":.C:">> = iolist_to_binary(join(re:split("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("\"1234\"","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("\"1234\"","^\\\".*\\\"\\s*(;.*)?$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("\"1234\"","^\\\".*\\\"\\s*(;.*)?$",[]))),
- <<":;">> = iolist_to_binary(join(re:split("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("\"1234\"","^\\\".*\\\"\\s*(;.*)?$",[]))),
+ <<":;">> = iolist_to_binary(join(re:split("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
<<":;:">> = iolist_to_binary(join(re:split("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$",[{parts,
- 2}]))),
- <<":;:">> = iolist_to_binary(join(re:split("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$",[]))),
- <<":; rhubarb">> = iolist_to_binary(join(re:split("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
+ 2}]))),
+ <<":;:">> = iolist_to_binary(join(re:split("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$",[]))),
+ <<":; rhubarb">> = iolist_to_binary(join(re:split("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
<<":; rhubarb:">> = iolist_to_binary(join(re:split("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$",[{parts,
- 2}]))),
- <<":; rhubarb:">> = iolist_to_binary(join(re:split("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
+ 2}]))),
+ <<":; rhubarb:">> = iolist_to_binary(join(re:split("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\\".*\\\"\\s*(;.*)?$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\\".*\\\"\\s*(;.*)?$",[]))),
- <<"\"1234\" : things">> = iolist_to_binary(join(re:split("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\\".*\\\"\\s*(;.*)?$",[]))),
+ <<"\"1234\" : things">> = iolist_to_binary(join(re:split("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$",[trim]))),
<<"\"1234\" : things">> = iolist_to_binary(join(re:split("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$",[{parts,
- 2}]))),
- <<"\"1234\" : things">> = iolist_to_binary(join(re:split("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$",[]))),
- <<"">> = iolist_to_binary(join(re:split("","^$",[trim]))),
+ 2}]))),
+ <<"\"1234\" : things">> = iolist_to_binary(join(re:split("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("","^$",[trim]))),
<<"">> = iolist_to_binary(join(re:split("","^$",[{parts,
- 2}]))),
- <<"">> = iolist_to_binary(join(re:split("","^$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^$",[trim]))),
+ 2}]))),
+ <<"">> = iolist_to_binary(join(re:split("","^$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^$",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^$",[]))),
<<"">> = iolist_to_binary(join(re:split("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
<<"abc">> = iolist_to_binary(join(re:split("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
- trim]))),
+ trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
<<"ab cde">> = iolist_to_binary(join(re:split("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
- trim]))),
+ trim]))),
<<"ab cde">> = iolist_to_binary(join(re:split("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended,
{parts,
- 2}]))),
- <<"ab cde">> = iolist_to_binary(join(re:split("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
- <<"">> = iolist_to_binary(join(re:split("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
+ 2}]))),
+ <<"ab cde">> = iolist_to_binary(join(re:split("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[extended]))),
+ <<"">> = iolist_to_binary(join(re:split("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
- <<"ab cde">> = iolist_to_binary(join(re:split("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
+ <<"ab cde">> = iolist_to_binary(join(re:split("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[trim]))),
<<"ab cde">> = iolist_to_binary(join(re:split("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[{parts,
- 2}]))),
- <<"ab cde">> = iolist_to_binary(join(re:split("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
+ 2}]))),
+ <<"ab cde">> = iolist_to_binary(join(re:split("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)",[]))),
<<"">> = iolist_to_binary(join(re:split("a bcd","^ a\\ b[c ]d $",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("a bcd","^ a\\ b[c ]d $",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a bcd","^ a\\ b[c ]d $",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a bcd","^ a\\ b[c ]d $",[extended]))),
<<"">> = iolist_to_binary(join(re:split("a b d","^ a\\ b[c ]d $",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("a b d","^ a\\ b[c ]d $",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a b d","^ a\\ b[c ]d $",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a b d","^ a\\ b[c ]d $",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^ a\\ b[c ]d $",[extended,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^ a\\ b[c ]d $",[extended,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^ a\\ b[c ]d $",[extended]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^ a\\ b[c ]d $",[extended]))),
<<"abcd">> = iolist_to_binary(join(re:split("abcd","^ a\\ b[c ]d $",[extended,
- trim]))),
+ trim]))),
<<"abcd">> = iolist_to_binary(join(re:split("abcd","^ a\\ b[c ]d $",[extended,
{parts,
- 2}]))),
- <<"abcd">> = iolist_to_binary(join(re:split("abcd","^ a\\ b[c ]d $",[extended]))),
+ 2}]))),
+ <<"abcd">> = iolist_to_binary(join(re:split("abcd","^ a\\ b[c ]d $",[extended]))),
<<"ab d">> = iolist_to_binary(join(re:split("ab d","^ a\\ b[c ]d $",[extended,
- trim]))),
+ trim]))),
<<"ab d">> = iolist_to_binary(join(re:split("ab d","^ a\\ b[c ]d $",[extended,
{parts,
- 2}]))),
- <<"ab d">> = iolist_to_binary(join(re:split("ab d","^ a\\ b[c ]d $",[extended]))),
- <<":abc:bc:c:def:ef:f:hij:ij:j:klm:lm:m">> = iolist_to_binary(join(re:split("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$",[trim]))),
+ 2}]))),
+ <<"ab d">> = iolist_to_binary(join(re:split("ab d","^ a\\ b[c ]d $",[extended]))),
+ <<":abc:bc:c:def:ef:f:hij:ij:j:klm:lm:m">> = iolist_to_binary(join(re:split("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$",[trim]))),
<<":abc:bc:c:def:ef:f:hij:ij:j:klm:lm:m:">> = iolist_to_binary(join(re:split("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$",[{parts,
- 2}]))),
- <<":abc:bc:c:def:ef:f:hij:ij:j:klm:lm:m:">> = iolist_to_binary(join(re:split("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$",[]))),
+ 2}]))),
+ <<":abc:bc:c:def:ef:f:hij:ij:j:klm:lm:m:">> = iolist_to_binary(join(re:split("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$",[]))),
ok.
run2() ->
- <<":bc:c:ef:f:ij:j:lm:m">> = iolist_to_binary(join(re:split("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$",[trim]))),
+ <<":bc:c:ef:f:ij:j:lm:m">> = iolist_to_binary(join(re:split("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$",[trim]))),
<<":bc:c:ef:f:ij:j:lm:m:">> = iolist_to_binary(join(re:split("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$",[{parts,
- 2}]))),
- <<":bc:c:ef:f:ij:j:lm:m:">> = iolist_to_binary(join(re:split("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$",[]))),
+ 2}]))),
+ <<":bc:c:ef:f:ij:j:lm:m:">> = iolist_to_binary(join(re:split("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$",[]))),
<<"">> = iolist_to_binary(join(re:split("a+ Z0+
-","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]",[trim]))),
+","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a+ Z0+
","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]",[{parts,
- 2}]))),
+ 2}]))),
<<":">> = iolist_to_binary(join(re:split("a+ Z0+
-","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]",[]))),
- <<"">> = iolist_to_binary(join(re:split(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+",[trim]))),
+","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]",[]))),
+ <<"">> = iolist_to_binary(join(re:split(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("z","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("z","^a*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("z","^a*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("z","^a*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("az","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("z","^a*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("az","^a*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("az","^a*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("az","^a*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaz","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("az","^a*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaz","^a*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaz","^a*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaz","^a*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaz","^a*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^a*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","^a*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","^a*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aa","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","^a*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa","^a*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aa","^a*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aa","^a*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa","^a*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","^a*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w",[]))),
- <<":+">> = iolist_to_binary(join(re:split("a+","^a*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w",[]))),
+ <<":+">> = iolist_to_binary(join(re:split("a+","^a*\\w",[trim]))),
<<":+">> = iolist_to_binary(join(re:split("a+","^a*\\w",[{parts,
- 2}]))),
- <<":+">> = iolist_to_binary(join(re:split("a+","^a*\\w",[]))),
- <<":+">> = iolist_to_binary(join(re:split("aa+","^a*\\w",[trim]))),
+ 2}]))),
+ <<":+">> = iolist_to_binary(join(re:split("a+","^a*\\w",[]))),
+ <<":+">> = iolist_to_binary(join(re:split("aa+","^a*\\w",[trim]))),
<<":+">> = iolist_to_binary(join(re:split("aa+","^a*\\w",[{parts,
- 2}]))),
- <<":+">> = iolist_to_binary(join(re:split("aa+","^a*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("z","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":+">> = iolist_to_binary(join(re:split("aa+","^a*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("z","^a*?\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("z","^a*?\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("z","^a*?\\w",[]))),
- <<":z">> = iolist_to_binary(join(re:split("az","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("z","^a*?\\w",[]))),
+ <<":z">> = iolist_to_binary(join(re:split("az","^a*?\\w",[trim]))),
<<":z">> = iolist_to_binary(join(re:split("az","^a*?\\w",[{parts,
- 2}]))),
- <<":z">> = iolist_to_binary(join(re:split("az","^a*?\\w",[]))),
- <<":aaz">> = iolist_to_binary(join(re:split("aaaz","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":z">> = iolist_to_binary(join(re:split("az","^a*?\\w",[]))),
+ <<":aaz">> = iolist_to_binary(join(re:split("aaaz","^a*?\\w",[trim]))),
<<":aaz">> = iolist_to_binary(join(re:split("aaaz","^a*?\\w",[{parts,
- 2}]))),
- <<":aaz">> = iolist_to_binary(join(re:split("aaaz","^a*?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":aaz">> = iolist_to_binary(join(re:split("aaaz","^a*?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^a*?\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","^a*?\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","^a*?\\w",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aa","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","^a*?\\w",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aa","^a*?\\w",[trim]))),
<<":a">> = iolist_to_binary(join(re:split("aa","^a*?\\w",[{parts,
- 2}]))),
- <<":a">> = iolist_to_binary(join(re:split("aa","^a*?\\w",[]))),
- <<":aaa">> = iolist_to_binary(join(re:split("aaaa","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":a">> = iolist_to_binary(join(re:split("aa","^a*?\\w",[]))),
+ <<":aaa">> = iolist_to_binary(join(re:split("aaaa","^a*?\\w",[trim]))),
<<":aaa">> = iolist_to_binary(join(re:split("aaaa","^a*?\\w",[{parts,
- 2}]))),
- <<":aaa">> = iolist_to_binary(join(re:split("aaaa","^a*?\\w",[]))),
- <<":+">> = iolist_to_binary(join(re:split("a+","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":aaa">> = iolist_to_binary(join(re:split("aaaa","^a*?\\w",[]))),
+ <<":+">> = iolist_to_binary(join(re:split("a+","^a*?\\w",[trim]))),
<<":+">> = iolist_to_binary(join(re:split("a+","^a*?\\w",[{parts,
- 2}]))),
- <<":+">> = iolist_to_binary(join(re:split("a+","^a*?\\w",[]))),
- <<":a+">> = iolist_to_binary(join(re:split("aa+","^a*?\\w",[trim]))),
+ 2}]))),
+ <<":+">> = iolist_to_binary(join(re:split("a+","^a*?\\w",[]))),
+ <<":a+">> = iolist_to_binary(join(re:split("aa+","^a*?\\w",[trim]))),
<<":a+">> = iolist_to_binary(join(re:split("aa+","^a*?\\w",[{parts,
- 2}]))),
- <<":a+">> = iolist_to_binary(join(re:split("aa+","^a*?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("az","^a+\\w",[trim]))),
+ 2}]))),
+ <<":a+">> = iolist_to_binary(join(re:split("aa+","^a*?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("az","^a+\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("az","^a+\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("az","^a+\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaz","^a+\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("az","^a+\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaz","^a+\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaz","^a+\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaz","^a+\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aa","^a+\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaz","^a+\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa","^a+\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aa","^a+\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aa","^a+\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","^a+\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa","^a+\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","^a+\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^a+\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^a+\\w",[]))),
- <<":+">> = iolist_to_binary(join(re:split("aa+","^a+\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^a+\\w",[]))),
+ <<":+">> = iolist_to_binary(join(re:split("aa+","^a+\\w",[trim]))),
<<":+">> = iolist_to_binary(join(re:split("aa+","^a+\\w",[{parts,
- 2}]))),
- <<":+">> = iolist_to_binary(join(re:split("aa+","^a+\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("az","^a+?\\w",[trim]))),
+ 2}]))),
+ <<":+">> = iolist_to_binary(join(re:split("aa+","^a+\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("az","^a+?\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("az","^a+?\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("az","^a+?\\w",[]))),
- <<":az">> = iolist_to_binary(join(re:split("aaaz","^a+?\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("az","^a+?\\w",[]))),
+ <<":az">> = iolist_to_binary(join(re:split("aaaz","^a+?\\w",[trim]))),
<<":az">> = iolist_to_binary(join(re:split("aaaz","^a+?\\w",[{parts,
- 2}]))),
- <<":az">> = iolist_to_binary(join(re:split("aaaz","^a+?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aa","^a+?\\w",[trim]))),
+ 2}]))),
+ <<":az">> = iolist_to_binary(join(re:split("aaaz","^a+?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa","^a+?\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aa","^a+?\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aa","^a+?\\w",[]))),
- <<":aa">> = iolist_to_binary(join(re:split("aaaa","^a+?\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa","^a+?\\w",[]))),
+ <<":aa">> = iolist_to_binary(join(re:split("aaaa","^a+?\\w",[trim]))),
<<":aa">> = iolist_to_binary(join(re:split("aaaa","^a+?\\w",[{parts,
- 2}]))),
- <<":aa">> = iolist_to_binary(join(re:split("aaaa","^a+?\\w",[]))),
- <<":+">> = iolist_to_binary(join(re:split("aa+","^a+?\\w",[trim]))),
+ 2}]))),
+ <<":aa">> = iolist_to_binary(join(re:split("aaaa","^a+?\\w",[]))),
+ <<":+">> = iolist_to_binary(join(re:split("aa+","^a+?\\w",[trim]))),
<<":+">> = iolist_to_binary(join(re:split("aa+","^a+?\\w",[{parts,
- 2}]))),
- <<":+">> = iolist_to_binary(join(re:split("aa+","^a+?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("1234567890","^\\d{8}\\w{2,}",[trim]))),
+ 2}]))),
+ <<":+">> = iolist_to_binary(join(re:split("aa+","^a+?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1234567890","^\\d{8}\\w{2,}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1234567890","^\\d{8}\\w{2,}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1234567890","^\\d{8}\\w{2,}",[]))),
- <<"">> = iolist_to_binary(join(re:split("12345678ab","^\\d{8}\\w{2,}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1234567890","^\\d{8}\\w{2,}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12345678ab","^\\d{8}\\w{2,}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12345678ab","^\\d{8}\\w{2,}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12345678ab","^\\d{8}\\w{2,}",[]))),
- <<"">> = iolist_to_binary(join(re:split("12345678__","^\\d{8}\\w{2,}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12345678ab","^\\d{8}\\w{2,}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12345678__","^\\d{8}\\w{2,}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12345678__","^\\d{8}\\w{2,}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12345678__","^\\d{8}\\w{2,}",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8}\\w{2,}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12345678__","^\\d{8}\\w{2,}",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8}\\w{2,}",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8}\\w{2,}",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8}\\w{2,}",[]))),
- <<"1234567">> = iolist_to_binary(join(re:split("1234567","^\\d{8}\\w{2,}",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8}\\w{2,}",[]))),
+ <<"1234567">> = iolist_to_binary(join(re:split("1234567","^\\d{8}\\w{2,}",[trim]))),
<<"1234567">> = iolist_to_binary(join(re:split("1234567","^\\d{8}\\w{2,}",[{parts,
- 2}]))),
- <<"1234567">> = iolist_to_binary(join(re:split("1234567","^\\d{8}\\w{2,}",[]))),
- <<"">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}$",[trim]))),
+ 2}]))),
+ <<"1234567">> = iolist_to_binary(join(re:split("1234567","^\\d{8}\\w{2,}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}$",[]))),
- <<"">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}$",[]))),
- <<"">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}$",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[aeiou\\d]{4,5}$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[aeiou\\d]{4,5}$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[aeiou\\d]{4,5}$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[aeiou\\d]{4,5}$",[]))),
- <<"123456">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[aeiou\\d]{4,5}$",[]))),
+ <<"123456">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}$",[trim]))),
<<"123456">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}$",[{parts,
- 2}]))),
- <<"123456">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}$",[]))),
- <<"">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}?",[trim]))),
+ 2}]))),
+ <<"123456">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}?",[trim]))),
<<":">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}?",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}?",[]))),
- <<"">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}?",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("uoie","^[aeiou\\d]{4,5}?",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}?",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}?",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}?",[]))),
- <<":5">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}?",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1234","^[aeiou\\d]{4,5}?",[]))),
+ <<":5">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}?",[trim]))),
<<":5">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}?",[{parts,
- 2}]))),
- <<":5">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}?",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}?",[trim]))),
+ 2}]))),
+ <<":5">> = iolist_to_binary(join(re:split("12345","^[aeiou\\d]{4,5}?",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}?",[trim]))),
<<":a">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}?",[{parts,
- 2}]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}?",[]))),
- <<":56">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}?",[trim]))),
+ 2}]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaa","^[aeiou\\d]{4,5}?",[]))),
+ <<":56">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}?",[trim]))),
<<":56">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}?",[{parts,
- 2}]))),
- <<":56">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}?",[]))),
- <<":abc:abc">> = iolist_to_binary(join(re:split("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
+ 2}]))),
+ <<":56">> = iolist_to_binary(join(re:split("123456","^[aeiou\\d]{4,5}?",[]))),
+ <<":abc:abc">> = iolist_to_binary(join(re:split("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
<<":abc:abc:">> = iolist_to_binary(join(re:split("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z",[{parts,
- 2}]))),
- <<":abc:abc:">> = iolist_to_binary(join(re:split("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
- <<":def:def">> = iolist_to_binary(join(re:split("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
+ 2}]))),
+ <<":abc:abc:">> = iolist_to_binary(join(re:split("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
+ <<":def:def">> = iolist_to_binary(join(re:split("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
<<":def:def:">> = iolist_to_binary(join(re:split("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z",[{parts,
- 2}]))),
- <<":def:def:">> = iolist_to_binary(join(re:split("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
+ 2}]))),
+ <<":def:def:">> = iolist_to_binary(join(re:split("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
- <<"abc=defdef">> = iolist_to_binary(join(re:split("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
+ <<"abc=defdef">> = iolist_to_binary(join(re:split("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z",[trim]))),
<<"abc=defdef">> = iolist_to_binary(join(re:split("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z",[{parts,
- 2}]))),
- <<"abc=defdef">> = iolist_to_binary(join(re:split("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
- <<":a:b:c:d:e:f:g:h:i:j:k:cd">> = iolist_to_binary(join(re:split("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[trim]))),
+ 2}]))),
+ <<"abc=defdef">> = iolist_to_binary(join(re:split("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z",[]))),
+ <<":a:b:c:d:e:f:g:h:i:j:k:cd">> = iolist_to_binary(join(re:split("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[trim]))),
<<":a:b:c:d:e:f:g:h:i:j:k:cd:">> = iolist_to_binary(join(re:split("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[{parts,
- 2}]))),
- <<":a:b:c:d:e:f:g:h:i:j:k:cd:">> = iolist_to_binary(join(re:split("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[]))),
- <<":a:b:c:d:e:f:g:h:i:j:k:cd">> = iolist_to_binary(join(re:split("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[trim]))),
+ 2}]))),
+ <<":a:b:c:d:e:f:g:h:i:j:k:cd:">> = iolist_to_binary(join(re:split("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[]))),
+ <<":a:b:c:d:e:f:g:h:i:j:k:cd">> = iolist_to_binary(join(re:split("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[trim]))),
<<":a:b:c:d:e:f:g:h:i:j:k:cd:">> = iolist_to_binary(join(re:split("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[{parts,
- 2}]))),
- <<":a:b:c:d:e:f:g:h:i:j:k:cd:">> = iolist_to_binary(join(re:split("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[]))),
- <<":cataract:aract:ract::3">> = iolist_to_binary(join(re:split("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[trim]))),
+ 2}]))),
+ <<":a:b:c:d:e:f:g:h:i:j:k:cd:">> = iolist_to_binary(join(re:split("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$",[]))),
+ <<":cataract:aract:ract::3">> = iolist_to_binary(join(re:split("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[trim]))),
<<":cataract:aract:ract::3:">> = iolist_to_binary(join(re:split("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[{parts,
- 2}]))),
- <<":cataract:aract:ract::3:">> = iolist_to_binary(join(re:split("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[]))),
- <<":catatonic:atonic:tonic::3">> = iolist_to_binary(join(re:split("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[trim]))),
+ 2}]))),
+ <<":cataract:aract:ract::3:">> = iolist_to_binary(join(re:split("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[]))),
+ <<":catatonic:atonic:tonic::3">> = iolist_to_binary(join(re:split("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[trim]))),
<<":catatonic:atonic:tonic::3:">> = iolist_to_binary(join(re:split("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[{parts,
- 2}]))),
- <<":catatonic:atonic:tonic::3:">> = iolist_to_binary(join(re:split("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[]))),
- <<":caterpillar:erpillar:::3">> = iolist_to_binary(join(re:split("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[trim]))),
+ 2}]))),
+ <<":catatonic:atonic:tonic::3:">> = iolist_to_binary(join(re:split("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[]))),
+ <<":caterpillar:erpillar:::3">> = iolist_to_binary(join(re:split("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[trim]))),
<<":caterpillar:erpillar:::3:">> = iolist_to_binary(join(re:split("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[{parts,
- 2}]))),
- <<":caterpillar:erpillar:::3:">> = iolist_to_binary(join(re:split("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[]))),
- <<":abcd::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]",[trim]))),
+ 2}]))),
+ <<":caterpillar:erpillar:::3:">> = iolist_to_binary(join(re:split("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)",[]))),
+ <<":abcd::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]",[trim]))),
<<":abcd::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]",[{parts,
- 2}]))),
- <<":abcd::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]",[]))),
- <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
+ 2}]))),
+ <<":abcd::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]",[]))),
+ <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
<<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[{parts,
- 2}]))),
- <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
- <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
+ 2}]))),
+ <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
+ <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
<<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[{parts,
- 2}]))),
- <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
+ 2}]))),
+ <<":Sep ::02 1997">> = iolist_to_binary(join(re:split("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
- <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(join(re:split("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
+ <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(join(re:split("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[trim]))),
<<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(join(re:split("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[{parts,
- 2}]))),
- <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(join(re:split("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
+ 2}]))),
+ <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(join(re:split("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d",[]))),
<<"">> = iolist_to_binary(join(re:split("12
-34","^12.34",[dotall,trim]))),
+34","^12.34",[dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("12
-34","^12.34",[dotall,{parts,2}]))),
+34","^12.34",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("12
-34","^12.34",[dotall]))),
+34","^12.34",[dotall]))),
<<"">> = iolist_to_binary(join(re:split("12 34","^12.34",[dotall,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("12 34","^12.34",[dotall,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12 34","^12.34",[dotall]))),
- <<"the quick : fox">> = iolist_to_binary(join(re:split("the quick brown fox","\\w+(?=\\t)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12 34","^12.34",[dotall]))),
+ <<"the quick : fox">> = iolist_to_binary(join(re:split("the quick brown fox","\\w+(?=\\t)",[trim]))),
<<"the quick : fox">> = iolist_to_binary(join(re:split("the quick brown fox","\\w+(?=\\t)",[{parts,
- 2}]))),
- <<"the quick : fox">> = iolist_to_binary(join(re:split("the quick brown fox","\\w+(?=\\t)",[]))),
- <<"foobar is :lish see?">> = iolist_to_binary(join(re:split("foobar is foolish see?","foo(?!bar)(.*)",[trim]))),
+ 2}]))),
+ <<"the quick : fox">> = iolist_to_binary(join(re:split("the quick brown fox","\\w+(?=\\t)",[]))),
+ <<"foobar is :lish see?">> = iolist_to_binary(join(re:split("foobar is foolish see?","foo(?!bar)(.*)",[trim]))),
<<"foobar is :lish see?:">> = iolist_to_binary(join(re:split("foobar is foolish see?","foo(?!bar)(.*)",[{parts,
- 2}]))),
- <<"foobar is :lish see?:">> = iolist_to_binary(join(re:split("foobar is foolish see?","foo(?!bar)(.*)",[]))),
- <<"foobar c: etc">> = iolist_to_binary(join(re:split("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
+ 2}]))),
+ <<"foobar is :lish see?:">> = iolist_to_binary(join(re:split("foobar is foolish see?","foo(?!bar)(.*)",[]))),
+ <<"foobar c: etc">> = iolist_to_binary(join(re:split("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
<<"foobar c: etc:">> = iolist_to_binary(join(re:split("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)",[{parts,
- 2}]))),
- <<"foobar c: etc:">> = iolist_to_binary(join(re:split("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
- <<":rel">> = iolist_to_binary(join(re:split("barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
+ 2}]))),
+ <<"foobar c: etc:">> = iolist_to_binary(join(re:split("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
+ <<":rel">> = iolist_to_binary(join(re:split("barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
<<":rel:">> = iolist_to_binary(join(re:split("barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[{parts,
- 2}]))),
- <<":rel:">> = iolist_to_binary(join(re:split("barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
- <<":rel">> = iolist_to_binary(join(re:split("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
+ 2}]))),
+ <<":rel:">> = iolist_to_binary(join(re:split("barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
+ <<":rel">> = iolist_to_binary(join(re:split("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
<<":rel:">> = iolist_to_binary(join(re:split("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[{parts,
- 2}]))),
- <<":rel:">> = iolist_to_binary(join(re:split("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
- <<":rel">> = iolist_to_binary(join(re:split("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
+ 2}]))),
+ <<":rel:">> = iolist_to_binary(join(re:split("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
+ <<":rel">> = iolist_to_binary(join(re:split("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[trim]))),
<<":rel:">> = iolist_to_binary(join(re:split("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[{parts,
- 2}]))),
- <<":rel:">> = iolist_to_binary(join(re:split("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
- <<":abc:456">> = iolist_to_binary(join(re:split("abc456","^(\\D*)(?=\\d)(?!123)",[trim]))),
+ 2}]))),
+ <<":rel:">> = iolist_to_binary(join(re:split("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)",[]))),
+ <<":abc:456">> = iolist_to_binary(join(re:split("abc456","^(\\D*)(?=\\d)(?!123)",[trim]))),
<<":abc:456">> = iolist_to_binary(join(re:split("abc456","^(\\D*)(?=\\d)(?!123)",[{parts,
- 2}]))),
- <<":abc:456">> = iolist_to_binary(join(re:split("abc456","^(\\D*)(?=\\d)(?!123)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[trim]))),
+ 2}]))),
+ <<":abc:456">> = iolist_to_binary(join(re:split("abc456","^(\\D*)(?=\\d)(?!123)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[]))),
- <<"abc123">> = iolist_to_binary(join(re:split("abc123","^(\\D*)(?=\\d)(?!123)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[]))),
+ <<"abc123">> = iolist_to_binary(join(re:split("abc123","^(\\D*)(?=\\d)(?!123)",[trim]))),
<<"abc123">> = iolist_to_binary(join(re:split("abc123","^(\\D*)(?=\\d)(?!123)",[{parts,
- 2}]))),
- <<"abc123">> = iolist_to_binary(join(re:split("abc123","^(\\D*)(?=\\d)(?!123)",[]))),
+ 2}]))),
+ <<"abc123">> = iolist_to_binary(join(re:split("abc123","^(\\D*)(?=\\d)(?!123)",[]))),
ok.
run3() ->
<<"">> = iolist_to_binary(join(re:split("1234","^1234(?# test newlines
- inside)",[trim]))),
+ inside)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1234","^1234(?# test newlines
- inside)",[{parts,2}]))),
+ inside)",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("1234","^1234(?# test newlines
- inside)",[]))),
+ inside)",[]))),
<<"">> = iolist_to_binary(join(re:split("1234","^1234 #comment in extended re
- ",[extended,trim]))),
+ ",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("1234","^1234 #comment in extended re
- ",[extended,{parts,2}]))),
+ ",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("1234","^1234 #comment in extended re
- ",[extended]))),
+ ",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abcd","#rhubarb
- abcd",[extended,trim]))),
+ abcd",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd","#rhubarb
- abcd",[extended,{parts,2}]))),
+ abcd",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abcd","#rhubarb
- abcd",[extended]))),
+ abcd",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abcd","^abcd#rhubarb",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd","^abcd#rhubarb",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcd","^abcd#rhubarb",[extended]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aaab","^(a)\\1{2,3}(.)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcd","^abcd#rhubarb",[extended]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aaab","^(a)\\1{2,3}(.)",[trim]))),
<<":a:b:">> = iolist_to_binary(join(re:split("aaab","^(a)\\1{2,3}(.)",[{parts,
- 2}]))),
- <<":a:b:">> = iolist_to_binary(join(re:split("aaab","^(a)\\1{2,3}(.)",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aaaab","^(a)\\1{2,3}(.)",[trim]))),
+ 2}]))),
+ <<":a:b:">> = iolist_to_binary(join(re:split("aaab","^(a)\\1{2,3}(.)",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aaaab","^(a)\\1{2,3}(.)",[trim]))),
<<":a:b:">> = iolist_to_binary(join(re:split("aaaab","^(a)\\1{2,3}(.)",[{parts,
- 2}]))),
- <<":a:b:">> = iolist_to_binary(join(re:split("aaaab","^(a)\\1{2,3}(.)",[]))),
- <<":a:a:b">> = iolist_to_binary(join(re:split("aaaaab","^(a)\\1{2,3}(.)",[trim]))),
+ 2}]))),
+ <<":a:b:">> = iolist_to_binary(join(re:split("aaaab","^(a)\\1{2,3}(.)",[]))),
+ <<":a:a:b">> = iolist_to_binary(join(re:split("aaaaab","^(a)\\1{2,3}(.)",[trim]))),
<<":a:a:b">> = iolist_to_binary(join(re:split("aaaaab","^(a)\\1{2,3}(.)",[{parts,
- 2}]))),
- <<":a:a:b">> = iolist_to_binary(join(re:split("aaaaab","^(a)\\1{2,3}(.)",[]))),
- <<":a:a:ab">> = iolist_to_binary(join(re:split("aaaaaab","^(a)\\1{2,3}(.)",[trim]))),
+ 2}]))),
+ <<":a:a:b">> = iolist_to_binary(join(re:split("aaaaab","^(a)\\1{2,3}(.)",[]))),
+ <<":a:a:ab">> = iolist_to_binary(join(re:split("aaaaaab","^(a)\\1{2,3}(.)",[trim]))),
<<":a:a:ab">> = iolist_to_binary(join(re:split("aaaaaab","^(a)\\1{2,3}(.)",[{parts,
- 2}]))),
- <<":a:a:ab">> = iolist_to_binary(join(re:split("aaaaaab","^(a)\\1{2,3}(.)",[]))),
- <<"the ">> = iolist_to_binary(join(re:split("the abc","(?!^)abc",[trim]))),
+ 2}]))),
+ <<":a:a:ab">> = iolist_to_binary(join(re:split("aaaaaab","^(a)\\1{2,3}(.)",[]))),
+ <<"the ">> = iolist_to_binary(join(re:split("the abc","(?!^)abc",[trim]))),
<<"the :">> = iolist_to_binary(join(re:split("the abc","(?!^)abc",[{parts,
- 2}]))),
- <<"the :">> = iolist_to_binary(join(re:split("the abc","(?!^)abc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?!^)abc",[trim]))),
+ 2}]))),
+ <<"the :">> = iolist_to_binary(join(re:split("the abc","(?!^)abc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?!^)abc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?!^)abc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?!^)abc",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(?!^)abc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?!^)abc",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(?!^)abc",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(?!^)abc",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(?!^)abc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","(?=^)abc",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(?!^)abc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","(?=^)abc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","(?=^)abc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","(?=^)abc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=^)abc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","(?=^)abc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=^)abc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=^)abc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=^)abc",[]))),
- <<"the abc">> = iolist_to_binary(join(re:split("the abc","(?=^)abc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=^)abc",[]))),
+ <<"the abc">> = iolist_to_binary(join(re:split("the abc","(?=^)abc",[trim]))),
<<"the abc">> = iolist_to_binary(join(re:split("the abc","(?=^)abc",[{parts,
- 2}]))),
- <<"the abc">> = iolist_to_binary(join(re:split("the abc","(?=^)abc",[]))),
- <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*|b)",[trim]))),
+ 2}]))),
+ <<"the abc">> = iolist_to_binary(join(re:split("the abc","(?=^)abc",[]))),
+ <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*|b)",[trim]))),
<<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*|b)",[{parts,
- 2}]))),
- <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*|b)",[]))),
- <<":abbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*|b)",[trim]))),
+ 2}]))),
+ <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*|b)",[]))),
+ <<":abbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*|b)",[trim]))),
<<":abbbbb:">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*|b)",[{parts,
- 2}]))),
- <<":abbbbb:">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*|b)",[]))),
- <<":a:bbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*?|b)",[trim]))),
+ 2}]))),
+ <<":abbbbb:">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*|b)",[]))),
+ <<":a:bbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*?|b)",[trim]))),
<<":a:bbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*?|b)",[{parts,
- 2}]))),
- <<":a:bbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*?|b)",[]))),
- <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*?|b)",[trim]))),
+ 2}]))),
+ <<":a:bbbbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}?(ab*?|b)",[]))),
+ <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*?|b)",[trim]))),
<<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*?|b)",[{parts,
- 2}]))),
- <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*?|b)",[]))),
+ 2}]))),
+ <<":b:bbb">> = iolist_to_binary(join(re:split("aabbbbb","^[ab]{1,3}(ab*?|b)",[]))),
<<"Alan Other <user.ain>">> = iolist_to_binary(join(re:split("Alan Other <user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1630,7 +1630,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"Alan Other <user.ain>">> = iolist_to_binary(join(re:split("Alan Other <user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1824,7 +1824,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"Alan Other <user.ain>">> = iolist_to_binary(join(re:split("Alan Other <user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2017,7 +2017,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"<user.ain>">> = iolist_to_binary(join(re:split("<user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2210,7 +2210,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"<user.ain>">> = iolist_to_binary(join(re:split("<user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2404,7 +2404,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"<user.ain>">> = iolist_to_binary(join(re:split("<user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2597,7 +2597,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"user.ain">> = iolist_to_binary(join(re:split("user.ain"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2790,7 +2790,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"user.ain">> = iolist_to_binary(join(re:split("user.ain"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2984,7 +2984,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"user.ain">> = iolist_to_binary(join(re:split("user.ain"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3177,7 +3177,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("\"A. Other\" <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3370,7 +3370,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("\"A. Other\" <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3564,7 +3564,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("\"A. Other\" <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3757,7 +3757,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("A. Other <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3950,7 +3950,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("A. Other <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4144,7 +4144,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("A. Other <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4337,7 +4337,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(join(re:split("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4530,7 +4530,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(join(re:split("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4724,7 +4724,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(join(re:split("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4917,7 +4917,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"A missing angle <user.where">> = iolist_to_binary(join(re:split("A missing angle <user.where"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -5110,7 +5110,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"A missing angle <user.where">> = iolist_to_binary(join(re:split("A missing angle <user.where"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -5304,7 +5304,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"A missing angle <user.where">> = iolist_to_binary(join(re:split("A missing angle <user.where"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -5497,7 +5497,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -5690,7 +5690,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -5884,7 +5884,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -6077,7 +6077,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -6270,7 +6270,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended,trim]))),
+\\) )* # optional trailing comment",[extended,trim]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -6464,7 +6464,7 @@ run3() ->
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional trailing comment",[extended,
- {parts,2}]))),
+ {parts,2}]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -6657,7 +6657,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment",[extended]))),
+\\) )* # optional trailing comment",[extended]))),
<<"Alan Other <user.ain>">> = iolist_to_binary(join(re:split("Alan Other <user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -7238,7 +7238,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"Alan Other <user.ain>">> = iolist_to_binary(join(re:split("Alan Other <user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -7819,7 +7819,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"Alan Other <user.ain>">> = iolist_to_binary(join(re:split("Alan Other <user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -8400,7 +8400,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"<user.ain>">> = iolist_to_binary(join(re:split("<user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -8981,7 +8981,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"<user.ain>">> = iolist_to_binary(join(re:split("<user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -9562,7 +9562,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"<user.ain>">> = iolist_to_binary(join(re:split("<user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -10143,7 +10143,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"user.ain">> = iolist_to_binary(join(re:split("user.ain","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -10724,7 +10724,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"user.ain">> = iolist_to_binary(join(re:split("user.ain","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -11305,7 +11305,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"user.ain">> = iolist_to_binary(join(re:split("user.ain","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -11886,7 +11886,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("\"A. Other\" <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -12467,7 +12467,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("\"A. Other\" <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -13048,7 +13048,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("\"A. Other\" <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -13629,7 +13629,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("A. Other <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -14210,7 +14210,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("A. Other <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -14791,7 +14791,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(join(re:split("A. Other <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -15372,7 +15372,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(join(re:split("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -15953,7 +15953,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(join(re:split("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -16534,7 +16534,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(join(re:split("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -17115,7 +17115,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"A missing angle <user.where">> = iolist_to_binary(join(re:split("A missing angle <user.where","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -17696,7 +17696,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"A missing angle <user.where">> = iolist_to_binary(join(re:split("A missing angle <user.where","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -18277,7 +18277,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"A missing angle <user.where">> = iolist_to_binary(join(re:split("A missing angle <user.where","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -18858,7 +18858,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -19439,7 +19439,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -20020,7 +20020,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -20601,7 +20601,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
+)",[extended]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -21182,7 +21182,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,trim]))),
+)",[extended,trim]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -21763,7 +21763,7 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended,{parts,2}]))),
+)",[extended,{parts,2}]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -22344,5763 +22344,5763 @@ run3() ->
# address spec
> # >
# name and address
-)",[extended]))),
- <<"abcdefpqrxyz0AB">> = iolist_to_binary(join(re:split("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB",[trim]))),
+)",[extended]))),
+ <<"abcdefpqrxyz0AB">> = iolist_to_binary(join(re:split("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB",[trim]))),
<<"abcdefpqrxyz0AB">> = iolist_to_binary(join(re:split("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB",[{parts,
- 2}]))),
- <<"abcdefpqrxyz0AB">> = iolist_to_binary(join(re:split("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB",[]))),
- <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(join(re:split("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB",[trim]))),
+ 2}]))),
+ <<"abcdefpqrxyz0AB">> = iolist_to_binary(join(re:split("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB",[]))),
+ <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(join(re:split("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB",[trim]))),
<<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(join(re:split("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB",[{parts,
- 2}]))),
- <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(join(re:split("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB",[]))),
- <<"abc efpqr0xyz00AB">> = iolist_to_binary(join(re:split("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[trim]))),
+ 2}]))),
+ <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(join(re:split("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB",[]))),
+ <<"abc efpqr0xyz00AB">> = iolist_to_binary(join(re:split("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[trim]))),
<<"abc efpqr0xyz00AB">> = iolist_to_binary(join(re:split("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[{parts,
- 2}]))),
- <<"abc efpqr0xyz00AB">> = iolist_to_binary(join(re:split("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[]))),
- <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(join(re:split("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[trim]))),
+ 2}]))),
+ <<"abc efpqr0xyz00AB">> = iolist_to_binary(join(re:split("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[]))),
+ <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(join(re:split("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[trim]))),
<<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(join(re:split("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[{parts,
- 2}]))),
- <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(join(re:split("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[]))),
- <<"A">> = iolist_to_binary(join(re:split("A","^[\\000-\\037]",[trim]))),
+ 2}]))),
+ <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(join(re:split("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB",[]))),
+ <<"A">> = iolist_to_binary(join(re:split("A","^[\\000-\\037]",[trim]))),
<<"A">> = iolist_to_binary(join(re:split("A","^[\\000-\\037]",[{parts,
- 2}]))),
- <<"A">> = iolist_to_binary(join(re:split("A","^[\\000-\\037]",[]))),
- <<":B">> = iolist_to_binary(join(re:split("B","^[\\000-\\037]",[trim]))),
+ 2}]))),
+ <<"A">> = iolist_to_binary(join(re:split("A","^[\\000-\\037]",[]))),
+ <<":B">> = iolist_to_binary(join(re:split("B","^[\\000-\\037]",[trim]))),
<<":B">> = iolist_to_binary(join(re:split("B","^[\\000-\\037]",[{parts,
- 2}]))),
- <<":B">> = iolist_to_binary(join(re:split("B","^[\\000-\\037]",[]))),
- <<":C">> = iolist_to_binary(join(re:split("C","^[\\000-\\037]",[trim]))),
+ 2}]))),
+ <<":B">> = iolist_to_binary(join(re:split("B","^[\\000-\\037]",[]))),
+ <<":C">> = iolist_to_binary(join(re:split("C","^[\\000-\\037]",[trim]))),
<<":C">> = iolist_to_binary(join(re:split("C","^[\\000-\\037]",[{parts,
- 2}]))),
- <<":C">> = iolist_to_binary(join(re:split("C","^[\\000-\\037]",[]))),
- <<"">> = iolist_to_binary(join(re:split("","\\0*",[trim]))),
+ 2}]))),
+ <<":C">> = iolist_to_binary(join(re:split("C","^[\\000-\\037]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("","\\0*",[trim]))),
<<"">> = iolist_to_binary(join(re:split("","\\0*",[{parts,
- 2}]))),
- <<"">> = iolist_to_binary(join(re:split("","\\0*",[]))),
- <<"The AZ">> = iolist_to_binary(join(re:split("The AZ","A\\x0{2,3}Z",[trim]))),
+ 2}]))),
+ <<"">> = iolist_to_binary(join(re:split("","\\0*",[]))),
+ <<"The AZ">> = iolist_to_binary(join(re:split("The AZ","A\\x0{2,3}Z",[trim]))),
<<"The AZ">> = iolist_to_binary(join(re:split("The AZ","A\\x0{2,3}Z",[{parts,
- 2}]))),
- <<"The AZ">> = iolist_to_binary(join(re:split("The AZ","A\\x0{2,3}Z",[]))),
- <<"An AZ">> = iolist_to_binary(join(re:split("An AZ","A\\x0{2,3}Z",[trim]))),
+ 2}]))),
+ <<"The AZ">> = iolist_to_binary(join(re:split("The AZ","A\\x0{2,3}Z",[]))),
+ <<"An AZ">> = iolist_to_binary(join(re:split("An AZ","A\\x0{2,3}Z",[trim]))),
<<"An AZ">> = iolist_to_binary(join(re:split("An AZ","A\\x0{2,3}Z",[{parts,
- 2}]))),
- <<"An AZ">> = iolist_to_binary(join(re:split("An AZ","A\\x0{2,3}Z",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","A\\x0{2,3}Z",[trim]))),
+ 2}]))),
+ <<"An AZ">> = iolist_to_binary(join(re:split("An AZ","A\\x0{2,3}Z",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","A\\x0{2,3}Z",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","A\\x0{2,3}Z",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","A\\x0{2,3}Z",[]))),
- <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","A\\x0{2,3}Z",[]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[trim]))),
<<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[{parts,
- 2}]))),
- <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[]))),
- <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[trim]))),
+ 2}]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[trim]))),
<<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[{parts,
- 2}]))),
- <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[]))),
- <<":cow:bell">> = iolist_to_binary(join(re:split("cowcowbell","^(cow|)\\1(bell)",[trim]))),
+ 2}]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","A\\x0{2,3}Z",[]))),
+ <<":cow:bell">> = iolist_to_binary(join(re:split("cowcowbell","^(cow|)\\1(bell)",[trim]))),
<<":cow:bell:">> = iolist_to_binary(join(re:split("cowcowbell","^(cow|)\\1(bell)",[{parts,
- 2}]))),
- <<":cow:bell:">> = iolist_to_binary(join(re:split("cowcowbell","^(cow|)\\1(bell)",[]))),
- <<"::bell">> = iolist_to_binary(join(re:split("bell","^(cow|)\\1(bell)",[trim]))),
+ 2}]))),
+ <<":cow:bell:">> = iolist_to_binary(join(re:split("cowcowbell","^(cow|)\\1(bell)",[]))),
+ <<"::bell">> = iolist_to_binary(join(re:split("bell","^(cow|)\\1(bell)",[trim]))),
<<"::bell:">> = iolist_to_binary(join(re:split("bell","^(cow|)\\1(bell)",[{parts,
- 2}]))),
- <<"::bell:">> = iolist_to_binary(join(re:split("bell","^(cow|)\\1(bell)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(cow|)\\1(bell)",[trim]))),
+ 2}]))),
+ <<"::bell:">> = iolist_to_binary(join(re:split("bell","^(cow|)\\1(bell)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(cow|)\\1(bell)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(cow|)\\1(bell)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(cow|)\\1(bell)",[]))),
- <<"cowbell">> = iolist_to_binary(join(re:split("cowbell","^(cow|)\\1(bell)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(cow|)\\1(bell)",[]))),
+ <<"cowbell">> = iolist_to_binary(join(re:split("cowbell","^(cow|)\\1(bell)",[trim]))),
<<"cowbell">> = iolist_to_binary(join(re:split("cowbell","^(cow|)\\1(bell)",[{parts,
- 2}]))),
- <<"cowbell">> = iolist_to_binary(join(re:split("cowbell","^(cow|)\\1(bell)",[]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
+ 2}]))),
+ <<"cowbell">> = iolist_to_binary(join(re:split("cowbell","^(cow|)\\1(bell)",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[{parts,
- 2}]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
+ 2}]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[{parts,
- 2}]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
+ 2}]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
<<":abc">> = iolist_to_binary(join(re:split("
-abc","^\\s",[trim]))),
+abc","^\\s",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split("
-abc","^\\s",[{parts,2}]))),
+abc","^\\s",[{parts,2}]))),
<<":abc">> = iolist_to_binary(join(re:split("
-abc","^\\s",[]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
+abc","^\\s",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[{parts,
- 2}]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
+ 2}]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[{parts,
- 2}]))),
- <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\s",[trim]))),
+ 2}]))),
+ <<":abc">> = iolist_to_binary(join(re:split(" abc","^\\s",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\s",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\s",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\s",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^\\s",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\s",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^\\s",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^\\s",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^\\s",[]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^\\s",[]))),
ok.
run4() ->
<<"">> = iolist_to_binary(join(re:split("abc","^a b
- c",[extended,trim]))),
+ c",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^a b
- c",[extended,{parts,2}]))),
+ c",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc","^a b
- c",[extended]))),
- <<":a">> = iolist_to_binary(join(re:split("ab","^(a|)\\1*b",[trim]))),
+ c",[extended]))),
+ <<":a">> = iolist_to_binary(join(re:split("ab","^(a|)\\1*b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","^(a|)\\1*b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ab","^(a|)\\1*b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1*b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ab","^(a|)\\1*b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1*b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1*b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1*b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1*b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1*b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1*b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1*b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1*b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1*b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1*b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1*b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1*b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1*b",[]))),
- <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1*b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1*b",[]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1*b",[trim]))),
<<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1*b",[{parts,
- 2}]))),
- <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1*b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aab","^(a|)\\1+b",[trim]))),
+ 2}]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1*b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aab","^(a|)\\1+b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aab","^(a|)\\1+b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aab","^(a|)\\1+b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1+b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aab","^(a|)\\1+b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1+b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1+b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1+b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1+b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1+b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1+b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1+b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1+b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1+b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1+b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1+b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1+b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1+b",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1+b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1+b",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1+b",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1+b",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1+b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("ab","^(a|)\\1?b",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1+b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("ab","^(a|)\\1?b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","^(a|)\\1?b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ab","^(a|)\\1?b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aab","^(a|)\\1?b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ab","^(a|)\\1?b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aab","^(a|)\\1?b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aab","^(a|)\\1?b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aab","^(a|)\\1?b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1?b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aab","^(a|)\\1?b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1?b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1?b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1?b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1?b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1?b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1?b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1?b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1?b",[]))),
- <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1?b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1?b",[]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1?b",[trim]))),
<<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1?b",[{parts,
- 2}]))),
- <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1?b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2}b",[trim]))),
+ 2}]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","^(a|)\\1?b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2}b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2}b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2}b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2}b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2}b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2}b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2}b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2}b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2}b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2}b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2}b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2}b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2}b",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2}b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2}b",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2}b",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2}b",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2}b",[]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2}b",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2}b",[]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2}b",[trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2}b",[{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2}b",[]))),
- <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2}b",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2}b",[]))),
+ <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2}b",[trim]))),
<<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2}b",[{parts,
- 2}]))),
- <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2}b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2}b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2,3}b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2,3}b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaab","^(a|)\\1{2,3}b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2,3}b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2,3}b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a|)\\1{2,3}b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2,3}b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2,3}b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","^(a|)\\1{2,3}b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2,3}b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2,3}b",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a|)\\1{2,3}b",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2,3}b",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2,3}b",[]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a|)\\1{2,3}b",[]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2,3}b",[trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2,3}b",[]))),
- <<"aaaaab">> = iolist_to_binary(join(re:split("aaaaab","^(a|)\\1{2,3}b",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^(a|)\\1{2,3}b",[]))),
+ <<"aaaaab">> = iolist_to_binary(join(re:split("aaaaab","^(a|)\\1{2,3}b",[trim]))),
<<"aaaaab">> = iolist_to_binary(join(re:split("aaaaab","^(a|)\\1{2,3}b",[{parts,
- 2}]))),
- <<"aaaaab">> = iolist_to_binary(join(re:split("aaaaab","^(a|)\\1{2,3}b",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<"aaaaab">> = iolist_to_binary(join(re:split("aaaaab","^(a|)\\1{2,3}b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbc","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbc","ab{1,3}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbc","ab{1,3}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbc","ab{1,3}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbc","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbc","ab{1,3}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbc","ab{1,3}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbc","ab{1,3}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbc","ab{1,3}bc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbc","ab{1,3}bc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{1,3}bc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{1,3}bc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{1,3}bc",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{1,3}bc",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","ab{1,3}bc",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","ab{1,3}bc",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","ab{1,3}bc",[]))),
- <<"abbbbbc">> = iolist_to_binary(join(re:split("abbbbbc","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","ab{1,3}bc",[]))),
+ <<"abbbbbc">> = iolist_to_binary(join(re:split("abbbbbc","ab{1,3}bc",[trim]))),
<<"abbbbbc">> = iolist_to_binary(join(re:split("abbbbbc","ab{1,3}bc",[{parts,
- 2}]))),
- <<"abbbbbc">> = iolist_to_binary(join(re:split("abbbbbc","ab{1,3}bc",[]))),
- <<":track1:title:Blah blah blah">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[trim]))),
+ 2}]))),
+ <<"abbbbbc">> = iolist_to_binary(join(re:split("abbbbbc","ab{1,3}bc",[]))),
+ <<":track1:title:Blah blah blah">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[trim]))),
<<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[{parts,
- 2}]))),
- <<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[]))),
+ 2}]))),
+ <<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[]))),
<<":track1:title:Blah blah blah">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[caseless,
- trim]))),
+ trim]))),
<<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[caseless,
{parts,
- 2}]))),
- <<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[caseless]))),
+ 2}]))),
+ <<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)",[caseless]))),
<<":track1:title:Blah blah blah">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)",[caseless,
- trim]))),
+ trim]))),
<<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)",[caseless,
{parts,
- 2}]))),
- <<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[trim]))),
+ 2}]))),
+ <<":track1:title:Blah blah blah:">> = iolist_to_binary(join(re:split("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-c]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-c]+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-c]+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-c]+$",[]))),
- <<"wxy">> = iolist_to_binary(join(re:split("wxy","^[W-c]+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-c]+$",[]))),
+ <<"wxy">> = iolist_to_binary(join(re:split("wxy","^[W-c]+$",[trim]))),
<<"wxy">> = iolist_to_binary(join(re:split("wxy","^[W-c]+$",[{parts,
- 2}]))),
- <<"wxy">> = iolist_to_binary(join(re:split("wxy","^[W-c]+$",[]))),
+ 2}]))),
+ <<"wxy">> = iolist_to_binary(join(re:split("wxy","^[W-c]+$",[]))),
<<"">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[W-c]+$",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("wxy_^ABC","^[W-c]+$",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("wxy_^ABC","^[W-c]+$",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("wxy_^ABC","^[W-c]+$",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("wxy_^ABC","^[W-c]+$",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("WXY_^abc","^[\\x3f-\\x5F]+$",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[\\x3f-\\x5F]+$",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[\\x3f-\\x5F]+$",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("WXY_^abc","^[\\x3f-\\x5F]+$",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("wxy_^ABC","^[\\x3f-\\x5F]+$",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("wxy_^ABC","^[\\x3f-\\x5F]+$",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("wxy_^ABC","^[\\x3f-\\x5F]+$",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("wxy_^ABC","^[\\x3f-\\x5F]+$",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("abc","^abc$",[multiline,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^abc$",[multiline,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","^abc$",[multiline]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","^abc$",[multiline]))),
<<"qqq
">> = iolist_to_binary(join(re:split("qqq
-abc","^abc$",[multiline,trim]))),
+abc","^abc$",[multiline,trim]))),
<<"qqq
:">> = iolist_to_binary(join(re:split("qqq
-abc","^abc$",[multiline,{parts,2}]))),
+abc","^abc$",[multiline,{parts,2}]))),
<<"qqq
:">> = iolist_to_binary(join(re:split("qqq
-abc","^abc$",[multiline]))),
+abc","^abc$",[multiline]))),
<<":
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","^abc$",[multiline,trim]))),
+zzz","^abc$",[multiline,trim]))),
<<":
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","^abc$",[multiline,{parts,2}]))),
+zzz","^abc$",[multiline,{parts,2}]))),
<<":
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","^abc$",[multiline]))),
+zzz","^abc$",[multiline]))),
<<"qqq
:
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","^abc$",[multiline,trim]))),
+zzz","^abc$",[multiline,trim]))),
<<"qqq
:
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","^abc$",[multiline,{parts,2}]))),
+zzz","^abc$",[multiline,{parts,2}]))),
<<"qqq
:
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","^abc$",[multiline]))),
- <<"">> = iolist_to_binary(join(re:split("abc","^abc$",[trim]))),
+zzz","^abc$",[multiline]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","^abc$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^abc$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","^abc$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","^abc$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","^abc$",[trim]))),
+abc","^abc$",[trim]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","^abc$",[{parts,2}]))),
+abc","^abc$",[{parts,2}]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","^abc$",[]))),
+abc","^abc$",[]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","^abc$",[trim]))),
+zzz","^abc$",[trim]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","^abc$",[{parts,2}]))),
+zzz","^abc$",[{parts,2}]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","^abc$",[]))),
+zzz","^abc$",[]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","^abc$",[trim]))),
+zzz","^abc$",[trim]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","^abc$",[{parts,2}]))),
+zzz","^abc$",[{parts,2}]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","^abc$",[]))),
+zzz","^abc$",[]))),
<<"">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline]))),
<<"">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\Z",[multiline]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\Z",[multiline,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\Z",[multiline,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\Z",[multiline]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\Z",[multiline]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","\\Aabc\\Z",[multiline,trim]))),
+abc","\\Aabc\\Z",[multiline,trim]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","\\Aabc\\Z",[multiline,{parts,2}]))),
+abc","\\Aabc\\Z",[multiline,{parts,2}]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","\\Aabc\\Z",[multiline]))),
+abc","\\Aabc\\Z",[multiline]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","\\Aabc\\Z",[multiline,trim]))),
+zzz","\\Aabc\\Z",[multiline,trim]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","\\Aabc\\Z",[multiline,{parts,2}]))),
+zzz","\\Aabc\\Z",[multiline,{parts,2}]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","\\Aabc\\Z",[multiline]))),
+zzz","\\Aabc\\Z",[multiline]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","\\Aabc\\Z",[multiline,trim]))),
+zzz","\\Aabc\\Z",[multiline,trim]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","\\Aabc\\Z",[multiline,{parts,2}]))),
+zzz","\\Aabc\\Z",[multiline,{parts,2}]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","\\Aabc\\Z",[multiline]))),
+zzz","\\Aabc\\Z",[multiline]))),
<<":f">> = iolist_to_binary(join(re:split("abc
-def","\\A(.)*\\Z",[dotall,trim]))),
+def","\\A(.)*\\Z",[dotall,trim]))),
<<":f:">> = iolist_to_binary(join(re:split("abc
-def","\\A(.)*\\Z",[dotall,{parts,2}]))),
+def","\\A(.)*\\Z",[dotall,{parts,2}]))),
<<":f:">> = iolist_to_binary(join(re:split("abc
-def","\\A(.)*\\Z",[dotall]))),
+def","\\A(.)*\\Z",[dotall]))),
<<":s">> = iolist_to_binary(join(re:split("*** Failers","\\A(.)*\\Z",[multiline,
- trim]))),
+ trim]))),
<<":s:">> = iolist_to_binary(join(re:split("*** Failers","\\A(.)*\\Z",[multiline,
{parts,
- 2}]))),
- <<":s:">> = iolist_to_binary(join(re:split("*** Failers","\\A(.)*\\Z",[multiline]))),
+ 2}]))),
+ <<":s:">> = iolist_to_binary(join(re:split("*** Failers","\\A(.)*\\Z",[multiline]))),
<<"abc
def">> = iolist_to_binary(join(re:split("abc
-def","\\A(.)*\\Z",[multiline,trim]))),
+def","\\A(.)*\\Z",[multiline,trim]))),
<<"abc
def">> = iolist_to_binary(join(re:split("abc
-def","\\A(.)*\\Z",[multiline,{parts,2}]))),
+def","\\A(.)*\\Z",[multiline,{parts,2}]))),
<<"abc
def">> = iolist_to_binary(join(re:split("abc
-def","\\A(.)*\\Z",[multiline]))),
- <<"::c">> = iolist_to_binary(join(re:split("b::c","(?:b)|(?::+)",[trim]))),
+def","\\A(.)*\\Z",[multiline]))),
+ <<"::c">> = iolist_to_binary(join(re:split("b::c","(?:b)|(?::+)",[trim]))),
<<":::c">> = iolist_to_binary(join(re:split("b::c","(?:b)|(?::+)",[{parts,
- 2}]))),
- <<"::c">> = iolist_to_binary(join(re:split("b::c","(?:b)|(?::+)",[]))),
- <<"c">> = iolist_to_binary(join(re:split("c::b","(?:b)|(?::+)",[trim]))),
+ 2}]))),
+ <<"::c">> = iolist_to_binary(join(re:split("b::c","(?:b)|(?::+)",[]))),
+ <<"c">> = iolist_to_binary(join(re:split("c::b","(?:b)|(?::+)",[trim]))),
<<"c:b">> = iolist_to_binary(join(re:split("c::b","(?:b)|(?::+)",[{parts,
- 2}]))),
- <<"c::">> = iolist_to_binary(join(re:split("c::b","(?:b)|(?::+)",[]))),
- <<"">> = iolist_to_binary(join(re:split("az-","[-az]+",[trim]))),
+ 2}]))),
+ <<"c::">> = iolist_to_binary(join(re:split("c::b","(?:b)|(?::+)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("az-","[-az]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("az-","[-az]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("az-","[-az]+",[]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[-az]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("az-","[-az]+",[]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[-az]+",[trim]))),
<<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[-az]+",[{parts,
- 2}]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[-az]+",[]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[-az]+",[trim]))),
+ 2}]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[-az]+",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[-az]+",[trim]))),
<<"b">> = iolist_to_binary(join(re:split("b","[-az]+",[{parts,
- 2}]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[-az]+",[]))),
+ 2}]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[-az]+",[]))),
ok.
run5() ->
- <<"">> = iolist_to_binary(join(re:split("za-","[az-]+",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("za-","[az-]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("za-","[az-]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("za-","[az-]+",[]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[az-]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("za-","[az-]+",[]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[az-]+",[trim]))),
<<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[az-]+",[{parts,
- 2}]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[az-]+",[]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[az-]+",[trim]))),
+ 2}]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[az-]+",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[az-]+",[trim]))),
<<"b">> = iolist_to_binary(join(re:split("b","[az-]+",[{parts,
- 2}]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[az-]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-z","[a\\-z]+",[trim]))),
+ 2}]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[az-]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-z","[a\\-z]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-z","[a\\-z]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-z","[a\\-z]+",[]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[a\\-z]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-z","[a\\-z]+",[]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[a\\-z]+",[trim]))),
<<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[a\\-z]+",[{parts,
- 2}]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[a\\-z]+",[]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[a\\-z]+",[trim]))),
+ 2}]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[a\\-z]+",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[a\\-z]+",[trim]))),
<<"b">> = iolist_to_binary(join(re:split("b","[a\\-z]+",[{parts,
- 2}]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[a\\-z]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcdxyz","[a-z]+",[trim]))),
+ 2}]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[a\\-z]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcdxyz","[a-z]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcdxyz","[a-z]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcdxyz","[a-z]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("12-34","[\\d-]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcdxyz","[a-z]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12-34","[\\d-]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12-34","[\\d-]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12-34","[\\d-]+",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12-34","[\\d-]+",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-]+",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-]+",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-]+",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-]+",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-]+",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-]+",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-]+",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("12-34z","[\\d-z]+",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12-34z","[\\d-z]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12-34z","[\\d-z]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12-34z","[\\d-z]+",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-z]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12-34z","[\\d-z]+",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-z]+",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-z]+",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-z]+",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-z]+",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\d-z]+",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-z]+",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-z]+",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-z]+",[]))),
- <<": ">> = iolist_to_binary(join(re:split("\\ ","\\x5c",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","[\\d-z]+",[]))),
+ <<": ">> = iolist_to_binary(join(re:split("\\ ","\\x5c",[trim]))),
<<": ">> = iolist_to_binary(join(re:split("\\ ","\\x5c",[{parts,
- 2}]))),
- <<": ">> = iolist_to_binary(join(re:split("\\ ","\\x5c",[]))),
- <<"the:oo">> = iolist_to_binary(join(re:split("the Zoo","\\x20Z",[trim]))),
+ 2}]))),
+ <<": ">> = iolist_to_binary(join(re:split("\\ ","\\x5c",[]))),
+ <<"the:oo">> = iolist_to_binary(join(re:split("the Zoo","\\x20Z",[trim]))),
<<"the:oo">> = iolist_to_binary(join(re:split("the Zoo","\\x20Z",[{parts,
- 2}]))),
- <<"the:oo">> = iolist_to_binary(join(re:split("the Zoo","\\x20Z",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\x20Z",[trim]))),
+ 2}]))),
+ <<"the:oo">> = iolist_to_binary(join(re:split("the Zoo","\\x20Z",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\x20Z",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\x20Z",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\x20Z",[]))),
- <<"Zulu">> = iolist_to_binary(join(re:split("Zulu","\\x20Z",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\x20Z",[]))),
+ <<"Zulu">> = iolist_to_binary(join(re:split("Zulu","\\x20Z",[trim]))),
<<"Zulu">> = iolist_to_binary(join(re:split("Zulu","\\x20Z",[{parts,
- 2}]))),
- <<"Zulu">> = iolist_to_binary(join(re:split("Zulu","\\x20Z",[]))),
+ 2}]))),
+ <<"Zulu">> = iolist_to_binary(join(re:split("Zulu","\\x20Z",[]))),
<<":abc">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[caseless,
- trim]))),
+ trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[caseless,
{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[caseless]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[caseless]))),
<<":ABC">> = iolist_to_binary(join(re:split("ABCabc","(abc)\\1",[caseless,
- trim]))),
+ trim]))),
<<":ABC:">> = iolist_to_binary(join(re:split("ABCabc","(abc)\\1",[caseless,
{parts,
- 2}]))),
- <<":ABC:">> = iolist_to_binary(join(re:split("ABCabc","(abc)\\1",[caseless]))),
+ 2}]))),
+ <<":ABC:">> = iolist_to_binary(join(re:split("ABCabc","(abc)\\1",[caseless]))),
<<":abc">> = iolist_to_binary(join(re:split("abcABC","(abc)\\1",[caseless,
- trim]))),
+ trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcABC","(abc)\\1",[caseless,
{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcABC","(abc)\\1",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("ab{3cd","ab{3cd",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcABC","(abc)\\1",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("ab{3cd","ab{3cd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab{3cd","ab{3cd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab{3cd","ab{3cd",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab{3,cd","ab{3,cd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab{3cd","ab{3cd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab{3,cd","ab{3,cd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab{3,cd","ab{3,cd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab{3,cd","ab{3,cd",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab{3,4a}cd","ab{3,4a}cd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab{3,cd","ab{3,cd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab{3,4a}cd","ab{3,4a}cd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab{3,4a}cd","ab{3,4a}cd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab{3,4a}cd","ab{3,4a}cd",[]))),
- <<"">> = iolist_to_binary(join(re:split("{4,5a}bc","{4,5a}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab{3,4a}cd","ab{3,4a}cd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("{4,5a}bc","{4,5a}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("{4,5a}bc","{4,5a}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("{4,5a}bc","{4,5a}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","abc$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("{4,5a}bc","{4,5a}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","abc$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","abc$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","abc$",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","abc$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","abc$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","abc$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","abc$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","abc$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","abc$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[]))),
<<"abc
def">> = iolist_to_binary(join(re:split("abc
-def","abc$",[trim]))),
+def","abc$",[trim]))),
<<"abc
def">> = iolist_to_binary(join(re:split("abc
-def","abc$",[{parts,2}]))),
+def","abc$",[{parts,2}]))),
<<"abc
def">> = iolist_to_binary(join(re:split("abc
-def","abc$",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[trim]))),
+def","abc$",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abc“","(abc)\\223",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abc“","(abc)\\223",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abc“","(abc)\\223",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abc“","(abc)\\223",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abc“","(abc)\\223",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<":A:B:C:D:E:F:G:H:I">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
+ <<":A:B:C:D:E:F:G:H:I">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[trim]))),
<<":A:B:C:D:E:F:G:H:I:">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[{parts,
- 2}]))),
- <<":A:B:C:D:E:F:G:H:I:">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[]))),
+ 2}]))),
+ <<":A:B:C:D:E:F:G:H:I:">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[]))),
ok.
run6() ->
- <<"">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[]))),
- <<":a:b:c:d:e:f:g:h:i:j:k:l">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[]))),
+ <<":a:b:c:d:e:f:g:h:i:j:k:l">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[trim]))),
<<":a:b:c:d:e:f:g:h:i:j:k:l:">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[{parts,
- 2}]))),
- <<":a:b:c:d:e:f:g:h:i:j:k:l:">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[]))),
+ 2}]))),
+ <<":a:b:c:d:e:f:g:h:i:j:k:l:">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[]))),
<<":a:b:c:d:e:f:g:h:i:j:k">> = iolist_to_binary(join(re:split("abcdefghijk
-S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123",[trim]))),
+S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123",[trim]))),
<<":a:b:c:d:e:f:g:h:i:j:k:">> = iolist_to_binary(join(re:split("abcdefghijk
-S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123",[{parts,2}]))),
+S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123",[{parts,2}]))),
<<":a:b:c:d:e:f:g:h:i:j:k:">> = iolist_to_binary(join(re:split("abcdefghijk
-S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123",[]))),
- <<"">> = iolist_to_binary(join(re:split("abidef","ab\\idef",[trim]))),
+S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abidef","ab\\idef",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abidef","ab\\idef",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abidef","ab\\idef",[]))),
- <<"">> = iolist_to_binary(join(re:split("bc","a{0}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abidef","ab\\idef",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bc","a{0}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("bc","a{0}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("bc","a{0}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("xyz","(a|(bc)){0,0}?xyz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("bc","a{0}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("xyz","(a|(bc)){0,0}?xyz",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("xyz","(a|(bc)){0,0}?xyz",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("xyz","(a|(bc)){0,0}?xyz",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcde","abc[\\10]de",[trim]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("xyz","(a|(bc)){0,0}?xyz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcde","abc[\\10]de",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcde","abc[\\10]de",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcde","abc[\\10]de",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcde","abc[\\1]de",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcde","abc[\\10]de",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcde","abc[\\1]de",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcde","abc[\\1]de",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcde","abc[\\1]de",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcde","(abc)[\\1]de",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcde","abc[\\1]de",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcde","(abc)[\\1]de",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcde","(abc)[\\1]de",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcde","(abc)[\\1]de",[]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcde","(abc)[\\1]de",[]))),
<<"">> = iolist_to_binary(join(re:split("a
-b","(?s)a.b",[trim]))),
+b","(?s)a.b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","(?s)a.b",[{parts,2}]))),
+b","(?s)a.b",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","(?s)a.b",[]))),
- <<":b:a:NOT:cccc:d">> = iolist_to_binary(join(re:split("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+b","(?s)a.b",[]))),
+ <<":b:a:NOT:cccc:d">> = iolist_to_binary(join(re:split("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<":b:a:NOT:cccc:d">> = iolist_to_binary(join(re:split("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<":b:a:NOT:cccc:d">> = iolist_to_binary(join(re:split("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<":b:a:NOT:ccc:d">> = iolist_to_binary(join(re:split("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<":b:a:NOT:cccc:d">> = iolist_to_binary(join(re:split("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<":b:a:NOT:ccc:d">> = iolist_to_binary(join(re:split("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<":b:a:NOT:ccc:d">> = iolist_to_binary(join(re:split("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<":b:a:NOT:ccc:d">> = iolist_to_binary(join(re:split("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<":b:a:NO:Tcc:d">> = iolist_to_binary(join(re:split("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<":b:a:NOT:ccc:d">> = iolist_to_binary(join(re:split("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<":b:a:NO:Tcc:d">> = iolist_to_binary(join(re:split("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<":b:a:NO:Tcc:d">> = iolist_to_binary(join(re:split("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<":b:a:NO:Tcc:d">> = iolist_to_binary(join(re:split("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<":b:a::ccc:d">> = iolist_to_binary(join(re:split("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<":b:a:NO:Tcc:d">> = iolist_to_binary(join(re:split("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<":b:a::ccc:d">> = iolist_to_binary(join(re:split("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<":b:a::ccc:d">> = iolist_to_binary(join(re:split("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<":b:a::ccc:d">> = iolist_to_binary(join(re:split("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<":*:*:* Fail:ers">> = iolist_to_binary(join(re:split("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<":b:a::ccc:d">> = iolist_to_binary(join(re:split("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<":*:*:* Fail:ers">> = iolist_to_binary(join(re:split("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<":*:*:* Fail:ers:">> = iolist_to_binary(join(re:split("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<":*:*:* Fail:ers:">> = iolist_to_binary(join(re:split("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<"anything">> = iolist_to_binary(join(re:split("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<":*:*:* Fail:ers:">> = iolist_to_binary(join(re:split("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<"anything">> = iolist_to_binary(join(re:split("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<"anything">> = iolist_to_binary(join(re:split("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<"anything">> = iolist_to_binary(join(re:split("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<"bc">> = iolist_to_binary(join(re:split("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<"anything">> = iolist_to_binary(join(re:split("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<"bc">> = iolist_to_binary(join(re:split("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<"bc">> = iolist_to_binary(join(re:split("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<"bc">> = iolist_to_binary(join(re:split("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<"baccd">> = iolist_to_binary(join(re:split("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
+ 2}]))),
+ <<"bc">> = iolist_to_binary(join(re:split("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<"baccd">> = iolist_to_binary(join(re:split("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[trim]))),
<<"baccd">> = iolist_to_binary(join(re:split("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[{parts,
- 2}]))),
- <<"baccd">> = iolist_to_binary(join(re:split("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
- <<"">> = iolist_to_binary(join(re:split("Abc","[^a]",[trim]))),
+ 2}]))),
+ <<"baccd">> = iolist_to_binary(join(re:split("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})",[]))),
+ <<"">> = iolist_to_binary(join(re:split("Abc","[^a]",[trim]))),
<<":bc">> = iolist_to_binary(join(re:split("Abc","[^a]",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("Abc","[^a]",[]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("Abc","[^a]",[]))),
<<"A">> = iolist_to_binary(join(re:split("Abc","[^a]",[caseless,
- trim]))),
+ trim]))),
<<"A:c">> = iolist_to_binary(join(re:split("Abc","[^a]",[caseless,
{parts,
- 2}]))),
- <<"A::">> = iolist_to_binary(join(re:split("Abc","[^a]",[caseless]))),
- <<":a">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[trim]))),
+ 2}]))),
+ <<"A::">> = iolist_to_binary(join(re:split("Abc","[^a]",[caseless]))),
+ <<":a">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[trim]))),
<<":aAbc">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[]))),
<<"AAAaA">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[caseless,
- trim]))),
+ trim]))),
<<"AAAaA:">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[caseless,
{parts,
- 2}]))),
- <<"AAAaA:">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[caseless]))),
+ 2}]))),
+ <<"AAAaA:">> = iolist_to_binary(join(re:split("AAAaAbc","[^a]+",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("bbb
-ccc","[^a]+",[trim]))),
+ccc","[^a]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("bbb
-ccc","[^a]+",[{parts,2}]))),
+ccc","[^a]+",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("bbb
-ccc","[^a]+",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("abc","[^k]$",[trim]))),
+ccc","[^a]+",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abc","[^k]$",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abc","[^k]$",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abc","[^k]$",[]))),
- <<"*** Failer">> = iolist_to_binary(join(re:split("*** Failers","[^k]$",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abc","[^k]$",[]))),
+ <<"*** Failer">> = iolist_to_binary(join(re:split("*** Failers","[^k]$",[trim]))),
<<"*** Failer:">> = iolist_to_binary(join(re:split("*** Failers","[^k]$",[{parts,
- 2}]))),
- <<"*** Failer:">> = iolist_to_binary(join(re:split("*** Failers","[^k]$",[]))),
- <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]$",[trim]))),
+ 2}]))),
+ <<"*** Failer:">> = iolist_to_binary(join(re:split("*** Failers","[^k]$",[]))),
+ <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]$",[trim]))),
<<"abk">> = iolist_to_binary(join(re:split("abk","[^k]$",[{parts,
- 2}]))),
- <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]$",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","[^k]{2,3}$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","[^k]{2,3}$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","[^k]{2,3}$",[]))),
- <<"k">> = iolist_to_binary(join(re:split("kbc","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","[^k]{2,3}$",[]))),
+ <<"k">> = iolist_to_binary(join(re:split("kbc","[^k]{2,3}$",[trim]))),
<<"k:">> = iolist_to_binary(join(re:split("kbc","[^k]{2,3}$",[{parts,
- 2}]))),
- <<"k:">> = iolist_to_binary(join(re:split("kbc","[^k]{2,3}$",[]))),
- <<"k">> = iolist_to_binary(join(re:split("kabc","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<"k:">> = iolist_to_binary(join(re:split("kbc","[^k]{2,3}$",[]))),
+ <<"k">> = iolist_to_binary(join(re:split("kabc","[^k]{2,3}$",[trim]))),
<<"k:">> = iolist_to_binary(join(re:split("kabc","[^k]{2,3}$",[{parts,
- 2}]))),
- <<"k:">> = iolist_to_binary(join(re:split("kabc","[^k]{2,3}$",[]))),
- <<"*** Fail">> = iolist_to_binary(join(re:split("*** Failers","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<"k:">> = iolist_to_binary(join(re:split("kabc","[^k]{2,3}$",[]))),
+ <<"*** Fail">> = iolist_to_binary(join(re:split("*** Failers","[^k]{2,3}$",[trim]))),
<<"*** Fail:">> = iolist_to_binary(join(re:split("*** Failers","[^k]{2,3}$",[{parts,
- 2}]))),
- <<"*** Fail:">> = iolist_to_binary(join(re:split("*** Failers","[^k]{2,3}$",[]))),
- <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<"*** Fail:">> = iolist_to_binary(join(re:split("*** Failers","[^k]{2,3}$",[]))),
+ <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]{2,3}$",[trim]))),
<<"abk">> = iolist_to_binary(join(re:split("abk","[^k]{2,3}$",[{parts,
- 2}]))),
- <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]{2,3}$",[]))),
- <<"akb">> = iolist_to_binary(join(re:split("akb","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<"abk">> = iolist_to_binary(join(re:split("abk","[^k]{2,3}$",[]))),
+ <<"akb">> = iolist_to_binary(join(re:split("akb","[^k]{2,3}$",[trim]))),
<<"akb">> = iolist_to_binary(join(re:split("akb","[^k]{2,3}$",[{parts,
- 2}]))),
- <<"akb">> = iolist_to_binary(join(re:split("akb","[^k]{2,3}$",[]))),
- <<"akk">> = iolist_to_binary(join(re:split("akk","[^k]{2,3}$",[trim]))),
+ 2}]))),
+ <<"akb">> = iolist_to_binary(join(re:split("akb","[^k]{2,3}$",[]))),
+ <<"akk">> = iolist_to_binary(join(re:split("akk","[^k]{2,3}$",[trim]))),
<<"akk">> = iolist_to_binary(join(re:split("akk","[^k]{2,3}$",[{parts,
- 2}]))),
- <<"akk">> = iolist_to_binary(join(re:split("akk","[^k]{2,3}$",[]))),
- <<"12345678.b.c.d">> = iolist_to_binary(join(re:split("12345678.b.c.d","^\\d{8,}\\@.+[^k]$",[trim]))),
+ 2}]))),
+ <<"akk">> = iolist_to_binary(join(re:split("akk","[^k]{2,3}$",[]))),
+ <<"12345678.b.c.d">> = iolist_to_binary(join(re:split("12345678.b.c.d","^\\d{8,}\\@.+[^k]$",[trim]))),
<<"12345678.b.c.d">> = iolist_to_binary(join(re:split("12345678.b.c.d","^\\d{8,}\\@.+[^k]$",[{parts,
- 2}]))),
- <<"12345678.b.c.d">> = iolist_to_binary(join(re:split("12345678.b.c.d","^\\d{8,}\\@.+[^k]$",[]))),
- <<"123456789.y.z">> = iolist_to_binary(join(re:split("123456789.y.z","^\\d{8,}\\@.+[^k]$",[trim]))),
+ 2}]))),
+ <<"12345678.b.c.d">> = iolist_to_binary(join(re:split("12345678.b.c.d","^\\d{8,}\\@.+[^k]$",[]))),
+ <<"123456789.y.z">> = iolist_to_binary(join(re:split("123456789.y.z","^\\d{8,}\\@.+[^k]$",[trim]))),
<<"123456789.y.z">> = iolist_to_binary(join(re:split("123456789.y.z","^\\d{8,}\\@.+[^k]$",[{parts,
- 2}]))),
- <<"123456789.y.z">> = iolist_to_binary(join(re:split("123456789.y.z","^\\d{8,}\\@.+[^k]$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8,}\\@.+[^k]$",[trim]))),
+ 2}]))),
+ <<"123456789.y.z">> = iolist_to_binary(join(re:split("123456789.y.z","^\\d{8,}\\@.+[^k]$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8,}\\@.+[^k]$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8,}\\@.+[^k]$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8,}\\@.+[^k]$",[]))),
- <<"12345678.y.uk">> = iolist_to_binary(join(re:split("12345678.y.uk","^\\d{8,}\\@.+[^k]$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\d{8,}\\@.+[^k]$",[]))),
+ <<"12345678.y.uk">> = iolist_to_binary(join(re:split("12345678.y.uk","^\\d{8,}\\@.+[^k]$",[trim]))),
<<"12345678.y.uk">> = iolist_to_binary(join(re:split("12345678.y.uk","^\\d{8,}\\@.+[^k]$",[{parts,
- 2}]))),
- <<"12345678.y.uk">> = iolist_to_binary(join(re:split("12345678.y.uk","^\\d{8,}\\@.+[^k]$",[]))),
- <<"1234567.b.c.d">> = iolist_to_binary(join(re:split("1234567.b.c.d","^\\d{8,}\\@.+[^k]$",[trim]))),
+ 2}]))),
+ <<"12345678.y.uk">> = iolist_to_binary(join(re:split("12345678.y.uk","^\\d{8,}\\@.+[^k]$",[]))),
+ <<"1234567.b.c.d">> = iolist_to_binary(join(re:split("1234567.b.c.d","^\\d{8,}\\@.+[^k]$",[trim]))),
<<"1234567.b.c.d">> = iolist_to_binary(join(re:split("1234567.b.c.d","^\\d{8,}\\@.+[^k]$",[{parts,
- 2}]))),
- <<"1234567.b.c.d">> = iolist_to_binary(join(re:split("1234567.b.c.d","^\\d{8,}\\@.+[^k]$",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaaaaaa","(a)\\1{8,}",[trim]))),
+ 2}]))),
+ <<"1234567.b.c.d">> = iolist_to_binary(join(re:split("1234567.b.c.d","^\\d{8,}\\@.+[^k]$",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaaaaaa","(a)\\1{8,}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaaaaaaa","(a)\\1{8,}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaaa","(a)\\1{8,}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaaaaaaa","(a)\\1{8,}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaaa","(a)\\1{8,}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaaaaaaa","(a)\\1{8,}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","(a)\\1{8,}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","(a)\\1{8,}",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a)\\1{8,}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","(a)\\1{8,}",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a)\\1{8,}",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a)\\1{8,}",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a)\\1{8,}",[]))),
- <<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a)\\1{8,}",[]))),
+ <<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[trim]))),
<<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[{parts,
- 2}]))),
- <<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[]))),
+ 2}]))),
+ <<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[]))),
ok.
run7() ->
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[trim]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[trim]))),
<<"aaaa:cd">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[{parts,
- 2}]))),
- <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[]))),
- <<"aa:a">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[trim]))),
+ 2}]))),
+ <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[]))),
+ <<"aa:a">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[trim]))),
<<"aa:abcd">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[{parts,
- 2}]))),
- <<"aa:a:::">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[]))),
+ 2}]))),
+ <<"aa:a:::">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[]))),
<<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[caseless,
- trim]))),
+ trim]))),
<<"aaaa:cd">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[caseless,
{parts,
- 2}]))),
- <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[caseless]))),
+ 2}]))),
+ <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[caseless]))),
<<"aaAa">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[caseless,
- trim]))),
+ trim]))),
<<"aaAa:cd">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[caseless,
{parts,
- 2}]))),
- <<"aaAa:::">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[caseless]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[trim]))),
+ 2}]))),
+ <<"aaAa:::">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[caseless]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[trim]))),
<<"aaaa:cd">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[{parts,
- 2}]))),
- <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[]))),
- <<"aa:a">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[trim]))),
+ 2}]))),
+ <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[]))),
+ <<"aa:a">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[trim]))),
<<"aa:abcd">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[{parts,
- 2}]))),
- <<"aa:a:::">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[]))),
+ 2}]))),
+ <<"aa:a:::">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[]))),
<<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[caseless,
- trim]))),
+ trim]))),
<<"aaaa:cd">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[caseless,
{parts,
- 2}]))),
- <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[caseless]))),
+ 2}]))),
+ <<"aaaa:::">> = iolist_to_binary(join(re:split("aaaabcd","[^az]",[caseless]))),
<<"aaAa">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[caseless,
- trim]))),
+ trim]))),
<<"aaAa:cd">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[caseless,
{parts,
- 2}]))),
- <<"aaAa:::">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[caseless]))),
- <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL",[trim]))),
+ 2}]))),
+ <<"aaAa:::">> = iolist_to_binary(join(re:split("aaAabcd","[^az]",[caseless]))),
+ <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL",[trim]))),
<<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL",[{parts,
- 2}]))),
- <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL",[]))),
- <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL",[trim]))),
+ 2}]))),
+ <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL",[]))),
+ <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL",[trim]))),
<<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL",[{parts,
- 2}]))),
- <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL",[]))),
- <<"1:.23">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d[1-9]?)\\d+",[trim]))),
+ 2}]))),
+ <<"xxxxxxxxxxx:xxxxxxxxx">> = iolist_to_binary(join(re:split("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL",[]))),
+ <<"1:.23">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d[1-9]?)\\d+",[trim]))),
<<"1:.23:">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d[1-9]?)\\d+",[{parts,
- 2}]))),
- <<"1:.23:">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d[1-9]?)\\d+",[]))),
- <<"1:.875">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d[1-9]?)\\d+",[trim]))),
+ 2}]))),
+ <<"1:.23:">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d[1-9]?)\\d+",[]))),
+ <<"1:.875">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d[1-9]?)\\d+",[trim]))),
<<"1:.875:">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d[1-9]?)\\d+",[{parts,
- 2}]))),
- <<"1:.875:">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d[1-9]?)\\d+",[]))),
- <<"1:.23">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d[1-9]?)\\d+",[trim]))),
+ 2}]))),
+ <<"1:.875:">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d[1-9]?)\\d+",[]))),
+ <<"1:.23">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d[1-9]?)\\d+",[trim]))),
<<"1:.23:">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d[1-9]?)\\d+",[{parts,
- 2}]))),
- <<"1:.23:">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d[1-9]?)\\d+",[]))),
- <<"1:.23::0003938">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
+ 2}]))),
+ <<"1:.23:">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d[1-9]?)\\d+",[]))),
+ <<"1:.23::0003938">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
<<"1:.23::0003938">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[{parts,
- 2}]))),
- <<"1:.23::0003938">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
- <<"1:.875:5:000282">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
+ 2}]))),
+ <<"1:.23::0003938">> = iolist_to_binary(join(re:split("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
+ <<"1:.875:5:000282">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
<<"1:.875:5:000282">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[{parts,
- 2}]))),
- <<"1:.875:5:000282">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
+ 2}]))),
+ <<"1:.875:5:000282">> = iolist_to_binary(join(re:split("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
- <<"1.235">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
+ <<"1.235">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[trim]))),
<<"1.235">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[{parts,
- 2}]))),
- <<"1.235">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab","a(?)b",[trim]))),
+ 2}]))),
+ <<"1.235">> = iolist_to_binary(join(re:split("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","a(?)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","a(?)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","a(?)b",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","a(?)b",[]))),
<<"Food is on the :foo:table">> = iolist_to_binary(join(re:split("Food is on the foo table","\\b(foo)\\s+(\\w+)",[caseless,
- trim]))),
+ trim]))),
<<"Food is on the :foo:table:">> = iolist_to_binary(join(re:split("Food is on the foo table","\\b(foo)\\s+(\\w+)",[caseless,
{parts,
- 2}]))),
- <<"Food is on the :foo:table:">> = iolist_to_binary(join(re:split("Food is on the foo table","\\b(foo)\\s+(\\w+)",[caseless]))),
- <<"The :d is under the bar in the :n.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*)bar",[trim]))),
+ 2}]))),
+ <<"Food is on the :foo:table:">> = iolist_to_binary(join(re:split("Food is on the foo table","\\b(foo)\\s+(\\w+)",[caseless]))),
+ <<"The :d is under the bar in the :n.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*)bar",[trim]))),
<<"The :d is under the bar in the :n.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*)bar",[{parts,
- 2}]))),
- <<"The :d is under the bar in the :n.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*)bar",[]))),
- <<"The :d is under the : in the barn.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*?)bar",[trim]))),
+ 2}]))),
+ <<"The :d is under the bar in the :n.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*)bar",[]))),
+ <<"The :d is under the : in the barn.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*?)bar",[trim]))),
<<"The :d is under the : in the barn.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*?)bar",[{parts,
- 2}]))),
- <<"The :d is under the : in the barn.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*?)bar",[]))),
- <<":I have 2 numbers: 53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d*)",[trim]))),
+ 2}]))),
+ <<"The :d is under the : in the barn.">> = iolist_to_binary(join(re:split("The food is under the bar in the barn.","foo(.*?)bar",[]))),
+ <<":I have 2 numbers: 53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d*)",[trim]))),
<<":I have 2 numbers: 53147::">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d*)",[{parts,
- 2}]))),
- <<":I have 2 numbers: 53147::">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d*)",[]))),
- <<":I have 2 numbers: 5314:7">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)",[trim]))),
+ 2}]))),
+ <<":I have 2 numbers: 53147::">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d*)",[]))),
+ <<":I have 2 numbers: 5314:7">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)",[trim]))),
<<":I have 2 numbers: 5314:7:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)",[{parts,
- 2}]))),
- <<":I have 2 numbers: 5314:7:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)",[]))),
- <<":I::: :::h:::a:::v:::e::: :2:: :::n:::u:::m:::b:::e:::r:::s::::::: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d*)",[trim]))),
+ 2}]))),
+ <<":I have 2 numbers: 5314:7:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)",[]))),
+ <<":I::: :::h:::a:::v:::e::: :2:: :::n:::u:::m:::b:::e:::r:::s::::::: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d*)",[trim]))),
<<":I:: have 2 numbers: 53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d*)",[{parts,
- 2}]))),
- <<":I::: :::h:::a:::v:::e::: :2:: :::n:::u:::m:::b:::e:::r:::s::::::: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d*)",[]))),
- <<":I have :2:: numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)",[trim]))),
+ 2}]))),
+ <<":I::: :::h:::a:::v:::e::: :2:: :::n:::u:::m:::b:::e:::r:::s::::::: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d*)",[]))),
+ <<":I have :2:: numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)",[trim]))),
<<":I have :2: numbers: 53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)",[{parts,
- 2}]))),
- <<":I have :2:: numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)",[]))),
- <<":I have 2 numbers: 5314:7">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)$",[trim]))),
+ 2}]))),
+ <<":I have :2:: numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)",[]))),
+ <<":I have 2 numbers: 5314:7">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)$",[trim]))),
<<":I have 2 numbers: 5314:7:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)$",[{parts,
- 2}]))),
- <<":I have 2 numbers: 5314:7:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)$",[]))),
- <<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)$",[trim]))),
+ 2}]))),
+ <<":I have 2 numbers: 5314:7:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)(\\d+)$",[]))),
+ <<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)$",[trim]))),
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)$",[{parts,
- 2}]))),
- <<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)$",[]))),
- <<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[trim]))),
+ 2}]))),
+ <<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*?)(\\d+)$",[]))),
+ <<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[trim]))),
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[{parts,
- 2}]))),
- <<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[]))),
+ 2}]))),
+ <<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[]))),
ok.
run8() ->
- <<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[trim]))),
+ <<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[trim]))),
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[{parts,
- 2}]))),
- <<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[]))),
- <<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[trim]))),
+ 2}]))),
+ <<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[]))),
+ <<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[trim]))),
<<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[{parts,
- 2}]))),
- <<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[]))),
- <<":ABC:445">> = iolist_to_binary(join(re:split("ABC445","^(\\D*)(?=\\d)(?!123)",[trim]))),
+ 2}]))),
+ <<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[]))),
+ <<":ABC:445">> = iolist_to_binary(join(re:split("ABC445","^(\\D*)(?=\\d)(?!123)",[trim]))),
<<":ABC:445">> = iolist_to_binary(join(re:split("ABC445","^(\\D*)(?=\\d)(?!123)",[{parts,
- 2}]))),
- <<":ABC:445">> = iolist_to_binary(join(re:split("ABC445","^(\\D*)(?=\\d)(?!123)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[trim]))),
+ 2}]))),
+ <<":ABC:445">> = iolist_to_binary(join(re:split("ABC445","^(\\D*)(?=\\d)(?!123)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[]))),
- <<"ABC123">> = iolist_to_binary(join(re:split("ABC123","^(\\D*)(?=\\d)(?!123)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\D*)(?=\\d)(?!123)",[]))),
+ <<"ABC123">> = iolist_to_binary(join(re:split("ABC123","^(\\D*)(?=\\d)(?!123)",[trim]))),
<<"ABC123">> = iolist_to_binary(join(re:split("ABC123","^(\\D*)(?=\\d)(?!123)",[{parts,
- 2}]))),
- <<"ABC123">> = iolist_to_binary(join(re:split("ABC123","^(\\D*)(?=\\d)(?!123)",[]))),
- <<":789">> = iolist_to_binary(join(re:split("W46]789","^[W-]46]",[trim]))),
+ 2}]))),
+ <<"ABC123">> = iolist_to_binary(join(re:split("ABC123","^(\\D*)(?=\\d)(?!123)",[]))),
+ <<":789">> = iolist_to_binary(join(re:split("W46]789","^[W-]46]",[trim]))),
<<":789">> = iolist_to_binary(join(re:split("W46]789","^[W-]46]",[{parts,
- 2}]))),
- <<":789">> = iolist_to_binary(join(re:split("W46]789","^[W-]46]",[]))),
- <<":789">> = iolist_to_binary(join(re:split("-46]789","^[W-]46]",[trim]))),
+ 2}]))),
+ <<":789">> = iolist_to_binary(join(re:split("W46]789","^[W-]46]",[]))),
+ <<":789">> = iolist_to_binary(join(re:split("-46]789","^[W-]46]",[trim]))),
<<":789">> = iolist_to_binary(join(re:split("-46]789","^[W-]46]",[{parts,
- 2}]))),
- <<":789">> = iolist_to_binary(join(re:split("-46]789","^[W-]46]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-]46]",[trim]))),
+ 2}]))),
+ <<":789">> = iolist_to_binary(join(re:split("-46]789","^[W-]46]",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-]46]",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-]46]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-]46]",[]))),
- <<"Wall">> = iolist_to_binary(join(re:split("Wall","^[W-]46]",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-]46]",[]))),
+ <<"Wall">> = iolist_to_binary(join(re:split("Wall","^[W-]46]",[trim]))),
<<"Wall">> = iolist_to_binary(join(re:split("Wall","^[W-]46]",[{parts,
- 2}]))),
- <<"Wall">> = iolist_to_binary(join(re:split("Wall","^[W-]46]",[]))),
- <<"Zebra">> = iolist_to_binary(join(re:split("Zebra","^[W-]46]",[trim]))),
+ 2}]))),
+ <<"Wall">> = iolist_to_binary(join(re:split("Wall","^[W-]46]",[]))),
+ <<"Zebra">> = iolist_to_binary(join(re:split("Zebra","^[W-]46]",[trim]))),
<<"Zebra">> = iolist_to_binary(join(re:split("Zebra","^[W-]46]",[{parts,
- 2}]))),
- <<"Zebra">> = iolist_to_binary(join(re:split("Zebra","^[W-]46]",[]))),
- <<"42">> = iolist_to_binary(join(re:split("42","^[W-]46]",[trim]))),
+ 2}]))),
+ <<"Zebra">> = iolist_to_binary(join(re:split("Zebra","^[W-]46]",[]))),
+ <<"42">> = iolist_to_binary(join(re:split("42","^[W-]46]",[trim]))),
<<"42">> = iolist_to_binary(join(re:split("42","^[W-]46]",[{parts,
- 2}]))),
- <<"42">> = iolist_to_binary(join(re:split("42","^[W-]46]",[]))),
- <<"[abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-]46]",[trim]))),
+ 2}]))),
+ <<"42">> = iolist_to_binary(join(re:split("42","^[W-]46]",[]))),
+ <<"[abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-]46]",[trim]))),
<<"[abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-]46]",[{parts,
- 2}]))),
- <<"[abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-]46]",[]))),
- <<"]abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-]46]",[trim]))),
+ 2}]))),
+ <<"[abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-]46]",[]))),
+ <<"]abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-]46]",[trim]))),
<<"]abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-]46]",[{parts,
- 2}]))),
- <<"]abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-]46]",[]))),
- <<":46]789">> = iolist_to_binary(join(re:split("W46]789","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<"]abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-]46]",[]))),
+ <<":46]789">> = iolist_to_binary(join(re:split("W46]789","^[W-\\]46]",[trim]))),
<<":46]789">> = iolist_to_binary(join(re:split("W46]789","^[W-\\]46]",[{parts,
- 2}]))),
- <<":46]789">> = iolist_to_binary(join(re:split("W46]789","^[W-\\]46]",[]))),
- <<":all">> = iolist_to_binary(join(re:split("Wall","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":46]789">> = iolist_to_binary(join(re:split("W46]789","^[W-\\]46]",[]))),
+ <<":all">> = iolist_to_binary(join(re:split("Wall","^[W-\\]46]",[trim]))),
<<":all">> = iolist_to_binary(join(re:split("Wall","^[W-\\]46]",[{parts,
- 2}]))),
- <<":all">> = iolist_to_binary(join(re:split("Wall","^[W-\\]46]",[]))),
- <<":ebra">> = iolist_to_binary(join(re:split("Zebra","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":all">> = iolist_to_binary(join(re:split("Wall","^[W-\\]46]",[]))),
+ <<":ebra">> = iolist_to_binary(join(re:split("Zebra","^[W-\\]46]",[trim]))),
<<":ebra">> = iolist_to_binary(join(re:split("Zebra","^[W-\\]46]",[{parts,
- 2}]))),
- <<":ebra">> = iolist_to_binary(join(re:split("Zebra","^[W-\\]46]",[]))),
- <<":ylophone">> = iolist_to_binary(join(re:split("Xylophone","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":ebra">> = iolist_to_binary(join(re:split("Zebra","^[W-\\]46]",[]))),
+ <<":ylophone">> = iolist_to_binary(join(re:split("Xylophone","^[W-\\]46]",[trim]))),
<<":ylophone">> = iolist_to_binary(join(re:split("Xylophone","^[W-\\]46]",[{parts,
- 2}]))),
- <<":ylophone">> = iolist_to_binary(join(re:split("Xylophone","^[W-\\]46]",[]))),
- <<":2">> = iolist_to_binary(join(re:split("42","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":ylophone">> = iolist_to_binary(join(re:split("Xylophone","^[W-\\]46]",[]))),
+ <<":2">> = iolist_to_binary(join(re:split("42","^[W-\\]46]",[trim]))),
<<":2">> = iolist_to_binary(join(re:split("42","^[W-\\]46]",[{parts,
- 2}]))),
- <<":2">> = iolist_to_binary(join(re:split("42","^[W-\\]46]",[]))),
- <<":abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":2">> = iolist_to_binary(join(re:split("42","^[W-\\]46]",[]))),
+ <<":abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-\\]46]",[trim]))),
<<":abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-\\]46]",[{parts,
- 2}]))),
- <<":abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-\\]46]",[]))),
- <<":abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":abcd]">> = iolist_to_binary(join(re:split("[abcd]","^[W-\\]46]",[]))),
+ <<":abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-\\]46]",[trim]))),
<<":abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-\\]46]",[{parts,
- 2}]))),
- <<":abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-\\]46]",[]))),
- <<":backslash">> = iolist_to_binary(join(re:split("\\backslash","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":abcd[">> = iolist_to_binary(join(re:split("]abcd[","^[W-\\]46]",[]))),
+ <<":backslash">> = iolist_to_binary(join(re:split("\\backslash","^[W-\\]46]",[trim]))),
<<":backslash">> = iolist_to_binary(join(re:split("\\backslash","^[W-\\]46]",[{parts,
- 2}]))),
- <<":backslash">> = iolist_to_binary(join(re:split("\\backslash","^[W-\\]46]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<":backslash">> = iolist_to_binary(join(re:split("\\backslash","^[W-\\]46]",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-\\]46]",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-\\]46]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-\\]46]",[]))),
- <<"-46]789">> = iolist_to_binary(join(re:split("-46]789","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[W-\\]46]",[]))),
+ <<"-46]789">> = iolist_to_binary(join(re:split("-46]789","^[W-\\]46]",[trim]))),
<<"-46]789">> = iolist_to_binary(join(re:split("-46]789","^[W-\\]46]",[{parts,
- 2}]))),
- <<"-46]789">> = iolist_to_binary(join(re:split("-46]789","^[W-\\]46]",[]))),
- <<"well">> = iolist_to_binary(join(re:split("well","^[W-\\]46]",[trim]))),
+ 2}]))),
+ <<"-46]789">> = iolist_to_binary(join(re:split("-46]789","^[W-\\]46]",[]))),
+ <<"well">> = iolist_to_binary(join(re:split("well","^[W-\\]46]",[trim]))),
<<"well">> = iolist_to_binary(join(re:split("well","^[W-\\]46]",[{parts,
- 2}]))),
- <<"well">> = iolist_to_binary(join(re:split("well","^[W-\\]46]",[]))),
- <<"">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[trim]))),
+ 2}]))),
+ <<"well">> = iolist_to_binary(join(re:split("well","^[W-\\]46]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[trim]))),
<<":">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[trim]))),
<<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[{parts,
- 2}]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword",[trim]))),
+ 2}]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword",[]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword",[trim]))),
<<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword",[{parts,
- 2}]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,0}",[trim]))),
+ 2}]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,0}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,0}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,0}",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(a){0,0}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,0}",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(a){0,0}",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^(a){0,0}",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(a){0,0}",[]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^(a){0,0}",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(a){0,0}",[]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^(a){0,0}",[trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","^(a){0,0}",[{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^(a){0,0}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,1}",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^(a){0,0}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,1}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,1}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,1}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,1}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,1}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,1}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,1}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,1}",[]))),
- <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){0,1}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,1}",[]))),
+ <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){0,1}",[trim]))),
<<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){0,1}",[{parts,
- 2}]))),
- <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){0,1}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,2}",[trim]))),
+ 2}]))),
+ <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){0,1}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,2}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,2}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,2}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,2}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,2}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,2}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,2}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,2}",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,2}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,2}",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,2}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,2}",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,2}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,3}",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,2}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,3}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,3}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,3}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,3}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,3}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,3}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,3}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,3}",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,3}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,3}",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,3}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,3}",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,3}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){0,3}",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,3}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){0,3}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){0,3}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){0,3}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){0,3}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){0,}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,}",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){0,}",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,}",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){0,}",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){0,}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){0,}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){0,}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){0,}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){0,}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){0,}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){0,}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){0,}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){0,}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,1}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){0,}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,1}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,1}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,1}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,1}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,1}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,1}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,1}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,1}",[]))),
- <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){1,1}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,1}",[]))),
+ <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){1,1}",[trim]))),
<<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){1,1}",[{parts,
- 2}]))),
- <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){1,1}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,2}",[trim]))),
+ 2}]))),
+ <<":a:ab">> = iolist_to_binary(join(re:split("aab","^(a){1,1}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,2}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,2}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,2}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,2}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,2}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,2}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,2}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,2}",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,2}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,2}",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,2}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,2}",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,2}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,3}",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,2}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,3}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,3}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,3}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,3}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,3}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,3}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,3}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,3}",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,3}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,3}",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,3}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,3}",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,3}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){1,3}",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,3}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){1,3}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){1,3}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){1,3}",[]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){1,3}",[]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,}",[trim]))),
<<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,}",[{parts,
- 2}]))),
- <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,}",[]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,}",[trim]))),
+ 2}]))),
+ <<"bcd">> = iolist_to_binary(join(re:split("bcd","^(a){1,}",[]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,}",[trim]))),
<<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,}",[{parts,
- 2}]))),
- <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,}",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,}",[trim]))),
+ 2}]))),
+ <<":a:bc">> = iolist_to_binary(join(re:split("abc","^(a){1,}",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,}",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){1,}",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("aab","^(a){1,}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","^(a){1,}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){1,}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){1,}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){1,}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","^(a){1,}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){1,}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){1,}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){1,}",[]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a){1,}",[]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[trim]))),
+no",".*\\.gif",[trim]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[{parts,2}]))),
+no",".*\\.gif",[{parts,2}]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[]))),
+no",".*\\.gif",[]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".{0,}\\.gif",[trim]))),
+no",".{0,}\\.gif",[trim]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".{0,}\\.gif",[{parts,2}]))),
+no",".{0,}\\.gif",[{parts,2}]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".{0,}\\.gif",[]))),
+no",".{0,}\\.gif",[]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[multiline,trim]))),
+no",".*\\.gif",[multiline,trim]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[multiline,{parts,2}]))),
+no",".*\\.gif",[multiline,{parts,2}]))),
<<"borfle
:
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[multiline]))),
+no",".*\\.gif",[multiline]))),
ok.
run9() ->
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[dotall,trim]))),
+no",".*\\.gif",[dotall,trim]))),
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[dotall,{parts,2}]))),
+no",".*\\.gif",[dotall,{parts,2}]))),
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[dotall]))),
+no",".*\\.gif",[dotall]))),
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[multiline,dotall,trim]))),
+no",".*\\.gif",[multiline,dotall,trim]))),
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[multiline,dotall,{parts,2}]))),
+no",".*\\.gif",[multiline,dotall,{parts,2}]))),
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*\\.gif",[multiline,dotall]))),
+no",".*\\.gif",[multiline,dotall]))),
<<"borfle
bib.gif
">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[trim]))),
+no",".*$",[trim]))),
<<"borfle
bib.gif
:">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[{parts,2}]))),
+no",".*$",[{parts,2}]))),
<<"borfle
bib.gif
:">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[]))),
+no",".*$",[]))),
<<":
:
">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,trim]))),
+no",".*$",[multiline,trim]))),
<<":
bib.gif
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,{parts,2}]))),
+no",".*$",[multiline,{parts,2}]))),
<<":
:
:">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline]))),
+no",".*$",[multiline]))),
<<"">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[dotall,trim]))),
+no",".*$",[dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[dotall,{parts,2}]))),
+no",".*$",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[dotall]))),
+no",".*$",[dotall]))),
<<"">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,dotall,trim]))),
+no",".*$",[multiline,dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,dotall,{parts,2}]))),
+no",".*$",[multiline,dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,dotall]))),
+no",".*$",[multiline,dotall]))),
<<"borfle
bib.gif
">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[trim]))),
+no",".*$",[trim]))),
<<"borfle
bib.gif
:">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[{parts,2}]))),
+no",".*$",[{parts,2}]))),
<<"borfle
bib.gif
:">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[]))),
+no",".*$",[]))),
<<":
:
">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,trim]))),
+no",".*$",[multiline,trim]))),
<<":
bib.gif
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,{parts,2}]))),
+no",".*$",[multiline,{parts,2}]))),
<<":
:
:">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline]))),
+no",".*$",[multiline]))),
<<"">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[dotall,trim]))),
+no",".*$",[dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[dotall,{parts,2}]))),
+no",".*$",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[dotall]))),
+no",".*$",[dotall]))),
<<"">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,dotall,trim]))),
+no",".*$",[multiline,dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,dotall,{parts,2}]))),
+no",".*$",[multiline,dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("borfle
bib.gif
-no",".*$",[multiline,dotall]))),
+no",".*$",[multiline,dotall]))),
<<"abcde
:1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[trim]))),
+1234Xyz","(.*X|^B)",[trim]))),
<<"abcde
:1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[{parts,2}]))),
+1234Xyz","(.*X|^B)",[{parts,2}]))),
<<"abcde
:1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[]))),
- <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[trim]))),
+1234Xyz","(.*X|^B)",[]))),
+ <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[trim]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[{parts,
- 2}]))),
- <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[trim]))),
+ 2}]))),
+ <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[trim]))),
+Bar","(.*X|^B)",[trim]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[{parts,2}]))),
+Bar","(.*X|^B)",[{parts,2}]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[]))),
+Bar","(.*X|^B)",[]))),
<<"abcde
:1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[multiline,trim]))),
+1234Xyz","(.*X|^B)",[multiline,trim]))),
<<"abcde
:1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[multiline,{parts,2}]))),
+1234Xyz","(.*X|^B)",[multiline,{parts,2}]))),
<<"abcde
:1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[multiline]))),
+1234Xyz","(.*X|^B)",[multiline]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline,
- trim]))),
+ trim]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline,
{parts,
- 2}]))),
- <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline]))),
+ 2}]))),
+ <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline]))),
<<"abcde
:B:ar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[multiline,trim]))),
+Bar","(.*X|^B)",[multiline,trim]))),
<<"abcde
:B:ar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[multiline,{parts,2}]))),
+Bar","(.*X|^B)",[multiline,{parts,2}]))),
<<"abcde
:B:ar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[multiline]))),
+Bar","(.*X|^B)",[multiline]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[dotall,trim]))),
+1234Xyz","(.*X|^B)",[dotall,trim]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[dotall,{parts,2}]))),
+1234Xyz","(.*X|^B)",[dotall,{parts,2}]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[dotall]))),
+1234Xyz","(.*X|^B)",[dotall]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[dotall,
- trim]))),
+ trim]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[dotall,
{parts,
- 2}]))),
- <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[dotall]))),
+ 2}]))),
+ <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[dotall]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[dotall,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[dotall,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[dotall]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(.*X|^B)",[dotall]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[dotall,trim]))),
+Bar","(.*X|^B)",[dotall,trim]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[dotall,{parts,2}]))),
+Bar","(.*X|^B)",[dotall,{parts,2}]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[dotall]))),
+Bar","(.*X|^B)",[dotall]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[multiline,dotall,trim]))),
+1234Xyz","(.*X|^B)",[multiline,dotall,trim]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[multiline,dotall,{parts,2}]))),
+1234Xyz","(.*X|^B)",[multiline,dotall,{parts,2}]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(.*X|^B)",[multiline,dotall]))),
+1234Xyz","(.*X|^B)",[multiline,dotall]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline,
dotall,
- trim]))),
+ trim]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline,
dotall,
{parts,
- 2}]))),
+ 2}]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(.*X|^B)",[multiline,
- dotall]))),
+ dotall]))),
<<"abcde
:B:ar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[multiline,dotall,trim]))),
+Bar","(.*X|^B)",[multiline,dotall,trim]))),
<<"abcde
:B:ar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[multiline,dotall,{parts,2}]))),
+Bar","(.*X|^B)",[multiline,dotall,{parts,2}]))),
<<"abcde
:B:ar">> = iolist_to_binary(join(re:split("abcde
-Bar","(.*X|^B)",[multiline,dotall]))),
+Bar","(.*X|^B)",[multiline,dotall]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(?s)(.*X|^B)",[trim]))),
+1234Xyz","(?s)(.*X|^B)",[trim]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(?s)(.*X|^B)",[{parts,2}]))),
+1234Xyz","(?s)(.*X|^B)",[{parts,2}]))),
<<":abcde
1234X:yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(?s)(.*X|^B)",[]))),
- <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s)(.*X|^B)",[trim]))),
+1234Xyz","(?s)(.*X|^B)",[]))),
+ <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s)(.*X|^B)",[trim]))),
<<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s)(.*X|^B)",[{parts,
- 2}]))),
- <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s)(.*X|^B)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s)(.*X|^B)",[trim]))),
+ 2}]))),
+ <<":B:arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s)(.*X|^B)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s)(.*X|^B)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s)(.*X|^B)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s)(.*X|^B)",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s)(.*X|^B)",[]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(?s)(.*X|^B)",[trim]))),
+Bar","(?s)(.*X|^B)",[trim]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(?s)(.*X|^B)",[{parts,2}]))),
+Bar","(?s)(.*X|^B)",[{parts,2}]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(?s)(.*X|^B)",[]))),
+Bar","(?s)(.*X|^B)",[]))),
<<":yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(?s:.*X|^B)",[trim]))),
+1234Xyz","(?s:.*X|^B)",[trim]))),
<<":yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(?s:.*X|^B)",[{parts,2}]))),
+1234Xyz","(?s:.*X|^B)",[{parts,2}]))),
<<":yz">> = iolist_to_binary(join(re:split("abcde
-1234Xyz","(?s:.*X|^B)",[]))),
- <<":arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s:.*X|^B)",[trim]))),
+1234Xyz","(?s:.*X|^B)",[]))),
+ <<":arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s:.*X|^B)",[trim]))),
<<":arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s:.*X|^B)",[{parts,
- 2}]))),
- <<":arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s:.*X|^B)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s:.*X|^B)",[trim]))),
+ 2}]))),
+ <<":arFoo">> = iolist_to_binary(join(re:split("BarFoo","(?s:.*X|^B)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s:.*X|^B)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s:.*X|^B)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s:.*X|^B)",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s:.*X|^B)",[]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(?s:.*X|^B)",[trim]))),
+Bar","(?s:.*X|^B)",[trim]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(?s:.*X|^B)",[{parts,2}]))),
+Bar","(?s:.*X|^B)",[{parts,2}]))),
<<"abcde
Bar">> = iolist_to_binary(join(re:split("abcde
-Bar","(?s:.*X|^B)",[]))),
- <<"**** Failers">> = iolist_to_binary(join(re:split("**** Failers","^.*B",[trim]))),
+Bar","(?s:.*X|^B)",[]))),
+ <<"**** Failers">> = iolist_to_binary(join(re:split("**** Failers","^.*B",[trim]))),
<<"**** Failers">> = iolist_to_binary(join(re:split("**** Failers","^.*B",[{parts,
- 2}]))),
- <<"**** Failers">> = iolist_to_binary(join(re:split("**** Failers","^.*B",[]))),
+ 2}]))),
+ <<"**** Failers">> = iolist_to_binary(join(re:split("**** Failers","^.*B",[]))),
<<"abc
B">> = iolist_to_binary(join(re:split("abc
-B","^.*B",[trim]))),
+B","^.*B",[trim]))),
<<"abc
B">> = iolist_to_binary(join(re:split("abc
-B","^.*B",[{parts,2}]))),
+B","^.*B",[{parts,2}]))),
<<"abc
B">> = iolist_to_binary(join(re:split("abc
-B","^.*B",[]))),
+B","^.*B",[]))),
<<"">> = iolist_to_binary(join(re:split("abc
-B","(?s)^.*B",[trim]))),
+B","(?s)^.*B",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc
-B","(?s)^.*B",[{parts,2}]))),
+B","(?s)^.*B",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc
-B","(?s)^.*B",[]))),
+B","(?s)^.*B",[]))),
<<"abc
">> = iolist_to_binary(join(re:split("abc
-B","(?m)^.*B",[trim]))),
+B","(?m)^.*B",[trim]))),
<<"abc
:">> = iolist_to_binary(join(re:split("abc
-B","(?m)^.*B",[{parts,2}]))),
+B","(?m)^.*B",[{parts,2}]))),
<<"abc
:">> = iolist_to_binary(join(re:split("abc
-B","(?m)^.*B",[]))),
+B","(?m)^.*B",[]))),
<<"">> = iolist_to_binary(join(re:split("abc
-B","(?ms)^.*B",[trim]))),
+B","(?ms)^.*B",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc
-B","(?ms)^.*B",[{parts,2}]))),
+B","(?ms)^.*B",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc
-B","(?ms)^.*B",[]))),
+B","(?ms)^.*B",[]))),
ok.
run10() ->
<<"abc
">> = iolist_to_binary(join(re:split("abc
-B","(?ms)^B",[trim]))),
+B","(?ms)^B",[trim]))),
<<"abc
:">> = iolist_to_binary(join(re:split("abc
-B","(?ms)^B",[{parts,2}]))),
+B","(?ms)^B",[{parts,2}]))),
<<"abc
:">> = iolist_to_binary(join(re:split("abc
-B","(?ms)^B",[]))),
- <<"">> = iolist_to_binary(join(re:split("B","(?s)B$",[trim]))),
+B","(?ms)^B",[]))),
+ <<"">> = iolist_to_binary(join(re:split("B","(?s)B$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("B","(?s)B$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("B","(?s)B$",[]))),
- <<"">> = iolist_to_binary(join(re:split("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("B","(?s)B$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",[]))),
- <<"">> = iolist_to_binary(join(re:split("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d",[]))),
- <<"">> = iolist_to_binary(join(re:split("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcabcabcabc","^[abc]{12}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcabcabcabc","^[abc]{12}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcabcabcabc","^[abc]{12}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcabcabcabc","^[abc]{12}",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcabcabcabc","^[a-c]{12}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcabcabcabc","^[abc]{12}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcabcabcabc","^[a-c]{12}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcabcabcabc","^[a-c]{12}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcabcabcabc","^[a-c]{12}",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abcabcabcabc","^(a|b|c){12}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcabcabcabc","^[a-c]{12}",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abcabcabcabc","^(a|b|c){12}",[trim]))),
<<":c:">> = iolist_to_binary(join(re:split("abcabcabcabc","^(a|b|c){12}",[{parts,
- 2}]))),
- <<":c:">> = iolist_to_binary(join(re:split("abcabcabcabc","^(a|b|c){12}",[]))),
- <<"">> = iolist_to_binary(join(re:split("n","^[abcdefghijklmnopqrstuvwxy0123456789]",[trim]))),
+ 2}]))),
+ <<":c:">> = iolist_to_binary(join(re:split("abcabcabcabc","^(a|b|c){12}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("n","^[abcdefghijklmnopqrstuvwxy0123456789]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("n","^[abcdefghijklmnopqrstuvwxy0123456789]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("n","^[abcdefghijklmnopqrstuvwxy0123456789]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("n","^[abcdefghijklmnopqrstuvwxy0123456789]",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]",[]))),
- <<"z">> = iolist_to_binary(join(re:split("z","^[abcdefghijklmnopqrstuvwxy0123456789]",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]",[]))),
+ <<"z">> = iolist_to_binary(join(re:split("z","^[abcdefghijklmnopqrstuvwxy0123456789]",[trim]))),
<<"z">> = iolist_to_binary(join(re:split("z","^[abcdefghijklmnopqrstuvwxy0123456789]",[{parts,
- 2}]))),
- <<"z">> = iolist_to_binary(join(re:split("z","^[abcdefghijklmnopqrstuvwxy0123456789]",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcd","abcde{0,0}",[trim]))),
+ 2}]))),
+ <<"z">> = iolist_to_binary(join(re:split("z","^[abcdefghijklmnopqrstuvwxy0123456789]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcd","abcde{0,0}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd","abcde{0,0}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcd","abcde{0,0}",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abcde{0,0}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcd","abcde{0,0}",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abcde{0,0}",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abcde{0,0}",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abcde{0,0}",[]))),
- <<"abce">> = iolist_to_binary(join(re:split("abce","abcde{0,0}",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abcde{0,0}",[]))),
+ <<"abce">> = iolist_to_binary(join(re:split("abce","abcde{0,0}",[trim]))),
<<"abce">> = iolist_to_binary(join(re:split("abce","abcde{0,0}",[{parts,
- 2}]))),
- <<"abce">> = iolist_to_binary(join(re:split("abce","abcde{0,0}",[]))),
- <<"">> = iolist_to_binary(join(re:split("abe","ab[cd]{0,0}e",[trim]))),
+ 2}]))),
+ <<"abce">> = iolist_to_binary(join(re:split("abce","abcde{0,0}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abe","ab[cd]{0,0}e",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abe","ab[cd]{0,0}e",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abe","ab[cd]{0,0}e",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab[cd]{0,0}e",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abe","ab[cd]{0,0}e",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab[cd]{0,0}e",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab[cd]{0,0}e",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab[cd]{0,0}e",[]))),
- <<"abcde">> = iolist_to_binary(join(re:split("abcde","ab[cd]{0,0}e",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab[cd]{0,0}e",[]))),
+ <<"abcde">> = iolist_to_binary(join(re:split("abcde","ab[cd]{0,0}e",[trim]))),
<<"abcde">> = iolist_to_binary(join(re:split("abcde","ab[cd]{0,0}e",[{parts,
- 2}]))),
- <<"abcde">> = iolist_to_binary(join(re:split("abcde","ab[cd]{0,0}e",[]))),
- <<"">> = iolist_to_binary(join(re:split("abd","ab(c){0,0}d",[trim]))),
+ 2}]))),
+ <<"abcde">> = iolist_to_binary(join(re:split("abcde","ab[cd]{0,0}e",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abd","ab(c){0,0}d",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("abd","ab(c){0,0}d",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abd","ab(c){0,0}d",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab(c){0,0}d",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abd","ab(c){0,0}d",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab(c){0,0}d",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab(c){0,0}d",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab(c){0,0}d",[]))),
- <<"abcd">> = iolist_to_binary(join(re:split("abcd","ab(c){0,0}d",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab(c){0,0}d",[]))),
+ <<"abcd">> = iolist_to_binary(join(re:split("abcd","ab(c){0,0}d",[trim]))),
<<"abcd">> = iolist_to_binary(join(re:split("abcd","ab(c){0,0}d",[{parts,
- 2}]))),
- <<"abcd">> = iolist_to_binary(join(re:split("abcd","ab(c){0,0}d",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","a(b*)",[trim]))),
+ 2}]))),
+ <<"abcd">> = iolist_to_binary(join(re:split("abcd","ab(c){0,0}d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","a(b*)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","a(b*)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","a(b*)",[]))),
- <<":b">> = iolist_to_binary(join(re:split("ab","a(b*)",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","a(b*)",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("ab","a(b*)",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","a(b*)",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("ab","a(b*)",[]))),
- <<":bbbb">> = iolist_to_binary(join(re:split("abbbb","a(b*)",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("ab","a(b*)",[]))),
+ <<":bbbb">> = iolist_to_binary(join(re:split("abbbb","a(b*)",[trim]))),
<<":bbbb:">> = iolist_to_binary(join(re:split("abbbb","a(b*)",[{parts,
- 2}]))),
- <<":bbbb:">> = iolist_to_binary(join(re:split("abbbb","a(b*)",[]))),
- <<"*** F::ilers">> = iolist_to_binary(join(re:split("*** Failers","a(b*)",[trim]))),
+ 2}]))),
+ <<":bbbb:">> = iolist_to_binary(join(re:split("abbbb","a(b*)",[]))),
+ <<"*** F::ilers">> = iolist_to_binary(join(re:split("*** Failers","a(b*)",[trim]))),
<<"*** F::ilers">> = iolist_to_binary(join(re:split("*** Failers","a(b*)",[{parts,
- 2}]))),
- <<"*** F::ilers">> = iolist_to_binary(join(re:split("*** Failers","a(b*)",[]))),
- <<"bbbbb">> = iolist_to_binary(join(re:split("bbbbb","a(b*)",[trim]))),
+ 2}]))),
+ <<"*** F::ilers">> = iolist_to_binary(join(re:split("*** Failers","a(b*)",[]))),
+ <<"bbbbb">> = iolist_to_binary(join(re:split("bbbbb","a(b*)",[trim]))),
<<"bbbbb">> = iolist_to_binary(join(re:split("bbbbb","a(b*)",[{parts,
- 2}]))),
- <<"bbbbb">> = iolist_to_binary(join(re:split("bbbbb","a(b*)",[]))),
- <<"">> = iolist_to_binary(join(re:split("abe","ab\\d{0}e",[trim]))),
+ 2}]))),
+ <<"bbbbb">> = iolist_to_binary(join(re:split("bbbbb","a(b*)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abe","ab\\d{0}e",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abe","ab\\d{0}e",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abe","ab\\d{0}e",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab\\d{0}e",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abe","ab\\d{0}e",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab\\d{0}e",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab\\d{0}e",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab\\d{0}e",[]))),
- <<"ab1e">> = iolist_to_binary(join(re:split("ab1e","ab\\d{0}e",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab\\d{0}e",[]))),
+ <<"ab1e">> = iolist_to_binary(join(re:split("ab1e","ab\\d{0}e",[trim]))),
<<"ab1e">> = iolist_to_binary(join(re:split("ab1e","ab\\d{0}e",[{parts,
- 2}]))),
- <<"ab1e">> = iolist_to_binary(join(re:split("ab1e","ab\\d{0}e",[]))),
- <<"the :quick: brown fox">> = iolist_to_binary(join(re:split("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"",[trim]))),
+ 2}]))),
+ <<"ab1e">> = iolist_to_binary(join(re:split("ab1e","ab\\d{0}e",[]))),
+ <<"the :quick: brown fox">> = iolist_to_binary(join(re:split("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"",[trim]))),
<<"the :quick: brown fox">> = iolist_to_binary(join(re:split("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"",[{parts,
- 2}]))),
- <<"the :quick: brown fox">> = iolist_to_binary(join(re:split("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"",[]))),
- <<": brown fox">> = iolist_to_binary(join(re:split("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"",[trim]))),
+ 2}]))),
+ <<"the :quick: brown fox">> = iolist_to_binary(join(re:split("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"",[]))),
+ <<": brown fox">> = iolist_to_binary(join(re:split("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"",[trim]))),
<<": brown fox:">> = iolist_to_binary(join(re:split("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"",[{parts,
- 2}]))),
- <<": brown fox:">> = iolist_to_binary(join(re:split("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"",[]))),
- <<"a:b:c">> = iolist_to_binary(join(re:split("abc","",[trim]))),
+ 2}]))),
+ <<": brown fox:">> = iolist_to_binary(join(re:split("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"",[]))),
+ <<"a:b:c">> = iolist_to_binary(join(re:split("abc","",[trim]))),
<<"a:bc">> = iolist_to_binary(join(re:split("abc","",[{parts,
- 2}]))),
- <<"a:b:c:">> = iolist_to_binary(join(re:split("abc","",[]))),
- <<"">> = iolist_to_binary(join(re:split("acb","a[^a]b",[trim]))),
+ 2}]))),
+ <<"a:b:c:">> = iolist_to_binary(join(re:split("abc","",[]))),
+ <<"">> = iolist_to_binary(join(re:split("acb","a[^a]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("acb","a[^a]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("acb","a[^a]b",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("acb","a[^a]b",[]))),
<<"">> = iolist_to_binary(join(re:split("a
-b","a[^a]b",[trim]))),
+b","a[^a]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","a[^a]b",[{parts,2}]))),
+b","a[^a]b",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","a[^a]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("acb","a.b",[trim]))),
+b","a[^a]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("acb","a.b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("acb","a.b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("acb","a.b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("acb","a.b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.b",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.b",[]))),
<<"a
b">> = iolist_to_binary(join(re:split("a
-b","a.b",[trim]))),
+b","a.b",[trim]))),
<<"a
b">> = iolist_to_binary(join(re:split("a
-b","a.b",[{parts,2}]))),
+b","a.b",[{parts,2}]))),
<<"a
b">> = iolist_to_binary(join(re:split("a
-b","a.b",[]))),
+b","a.b",[]))),
<<"">> = iolist_to_binary(join(re:split("acb","a[^a]b",[dotall,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("acb","a[^a]b",[dotall,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("acb","a[^a]b",[dotall]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("acb","a[^a]b",[dotall]))),
<<"">> = iolist_to_binary(join(re:split("a
-b","a[^a]b",[dotall,trim]))),
+b","a[^a]b",[dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","a[^a]b",[dotall,{parts,2}]))),
+b","a[^a]b",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","a[^a]b",[dotall]))),
+b","a[^a]b",[dotall]))),
ok.
run11() ->
<<"">> = iolist_to_binary(join(re:split("acb","a.b",[dotall,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("acb","a.b",[dotall,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("acb","a.b",[dotall]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("acb","a.b",[dotall]))),
<<"">> = iolist_to_binary(join(re:split("a
-b","a.b",[dotall,trim]))),
+b","a.b",[dotall,trim]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","a.b",[dotall,{parts,2}]))),
+b","a.b",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a
-b","a.b",[dotall]))),
- <<":a">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[trim]))),
+b","a.b",[dotall]))),
+ <<":a">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbbac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbbac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbbbac","^(b+?|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbbac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbbbac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbbbac","^(b+?|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbbbac","^(b+?|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbbbac","^(b+?|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bac","^(b+|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbac","^(b+|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbac","^(b+|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbac","^(b+|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbac","^(b+|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbac","^(b+|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbbac","^(b+|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbac","^(b+|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbbac","^(b+|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbbac","^(b+|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbbac","^(b+|a){1,2}?c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("bbbbbac","^(b+|a){1,2}?c",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbbac","^(b+|a){1,2}?c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("bbbbbac","^(b+|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bbbbbac","^(b+|a){1,2}?c",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("bbbbbac","^(b+|a){1,2}?c",[]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("bbbbbac","^(b+|a){1,2}?c",[]))),
<<"x
b">> = iolist_to_binary(join(re:split("x
-b","(?!\\A)x",[multiline,trim]))),
+b","(?!\\A)x",[multiline,trim]))),
<<"x
b">> = iolist_to_binary(join(re:split("x
-b","(?!\\A)x",[multiline,{parts,2}]))),
+b","(?!\\A)x",[multiline,{parts,2}]))),
<<"x
b">> = iolist_to_binary(join(re:split("x
-b","(?!\\A)x",[multiline]))),
+b","(?!\\A)x",[multiline]))),
<<"a">> = iolist_to_binary(join(re:split("ax","(?!\\A)x",[multiline,
- trim]))),
+ trim]))),
<<"a:">> = iolist_to_binary(join(re:split("ax","(?!\\A)x",[multiline,
{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("ax","(?!\\A)x",[multiline]))),
- <<"{ab}">> = iolist_to_binary(join(re:split("{ab}","\\x0{ab}",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("ax","(?!\\A)x",[multiline]))),
+ <<"{ab}">> = iolist_to_binary(join(re:split("{ab}","\\x0{ab}",[trim]))),
<<"{ab}">> = iolist_to_binary(join(re:split("{ab}","\\x0{ab}",[{parts,
- 2}]))),
- <<"{ab}">> = iolist_to_binary(join(re:split("{ab}","\\x0{ab}",[]))),
- <<"">> = iolist_to_binary(join(re:split("CD","(A|B)*?CD",[trim]))),
+ 2}]))),
+ <<"{ab}">> = iolist_to_binary(join(re:split("{ab}","\\x0{ab}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("CD","(A|B)*?CD",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("CD","(A|B)*?CD",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("CD","(A|B)*?CD",[]))),
- <<"">> = iolist_to_binary(join(re:split("CD","(A|B)*CD",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("CD","(A|B)*?CD",[]))),
+ <<"">> = iolist_to_binary(join(re:split("CD","(A|B)*CD",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("CD","(A|B)*CD",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("CD","(A|B)*CD",[]))),
- <<":AB:AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*?\\1",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("CD","(A|B)*CD",[]))),
+ <<":AB:AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*?\\1",[trim]))),
<<":AB:AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*?\\1",[{parts,
- 2}]))),
- <<":AB:AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*?\\1",[]))),
- <<":AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*\\1",[trim]))),
+ 2}]))),
+ <<":AB:AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*?\\1",[]))),
+ <<":AB">> = iolist_to_binary(join(re:split("ABABAB","(AB)*\\1",[trim]))),
<<":AB:">> = iolist_to_binary(join(re:split("ABABAB","(AB)*\\1",[{parts,
- 2}]))),
- <<":AB:">> = iolist_to_binary(join(re:split("ABABAB","(AB)*\\1",[]))),
- <<"">> = iolist_to_binary(join(re:split("foo","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<":AB:">> = iolist_to_binary(join(re:split("ABABAB","(AB)*\\1",[]))),
+ <<"">> = iolist_to_binary(join(re:split("foo","(?<!bar)foo",[trim]))),
<<":">> = iolist_to_binary(join(re:split("foo","(?<!bar)foo",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("foo","(?<!bar)foo",[]))),
- <<"cat:d">> = iolist_to_binary(join(re:split("catfood","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("foo","(?<!bar)foo",[]))),
+ <<"cat:d">> = iolist_to_binary(join(re:split("catfood","(?<!bar)foo",[trim]))),
<<"cat:d">> = iolist_to_binary(join(re:split("catfood","(?<!bar)foo",[{parts,
- 2}]))),
- <<"cat:d">> = iolist_to_binary(join(re:split("catfood","(?<!bar)foo",[]))),
- <<"ar:tle">> = iolist_to_binary(join(re:split("arfootle","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"cat:d">> = iolist_to_binary(join(re:split("catfood","(?<!bar)foo",[]))),
+ <<"ar:tle">> = iolist_to_binary(join(re:split("arfootle","(?<!bar)foo",[trim]))),
<<"ar:tle">> = iolist_to_binary(join(re:split("arfootle","(?<!bar)foo",[{parts,
- 2}]))),
- <<"ar:tle">> = iolist_to_binary(join(re:split("arfootle","(?<!bar)foo",[]))),
- <<"r:sh">> = iolist_to_binary(join(re:split("rfoosh","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"ar:tle">> = iolist_to_binary(join(re:split("arfootle","(?<!bar)foo",[]))),
+ <<"r:sh">> = iolist_to_binary(join(re:split("rfoosh","(?<!bar)foo",[trim]))),
<<"r:sh">> = iolist_to_binary(join(re:split("rfoosh","(?<!bar)foo",[{parts,
- 2}]))),
- <<"r:sh">> = iolist_to_binary(join(re:split("rfoosh","(?<!bar)foo",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"r:sh">> = iolist_to_binary(join(re:split("rfoosh","(?<!bar)foo",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<!bar)foo",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<!bar)foo",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<!bar)foo",[]))),
- <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<!bar)foo",[]))),
+ <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<!bar)foo",[trim]))),
<<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<!bar)foo",[{parts,
- 2}]))),
- <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<!bar)foo",[]))),
- <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<!bar)foo",[]))),
+ <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","(?<!bar)foo",[trim]))),
<<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","(?<!bar)foo",[{parts,
- 2}]))),
- <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","(?<!bar)foo",[]))),
- <<":d">> = iolist_to_binary(join(re:split("catfood","\\w{3}(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","(?<!bar)foo",[]))),
+ <<":d">> = iolist_to_binary(join(re:split("catfood","\\w{3}(?<!bar)foo",[trim]))),
<<":d">> = iolist_to_binary(join(re:split("catfood","\\w{3}(?<!bar)foo",[{parts,
- 2}]))),
- <<":d">> = iolist_to_binary(join(re:split("catfood","\\w{3}(?<!bar)foo",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\w{3}(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<":d">> = iolist_to_binary(join(re:split("catfood","\\w{3}(?<!bar)foo",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\w{3}(?<!bar)foo",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\w{3}(?<!bar)foo",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\w{3}(?<!bar)foo",[]))),
- <<"foo">> = iolist_to_binary(join(re:split("foo","\\w{3}(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\w{3}(?<!bar)foo",[]))),
+ <<"foo">> = iolist_to_binary(join(re:split("foo","\\w{3}(?<!bar)foo",[trim]))),
<<"foo">> = iolist_to_binary(join(re:split("foo","\\w{3}(?<!bar)foo",[{parts,
- 2}]))),
- <<"foo">> = iolist_to_binary(join(re:split("foo","\\w{3}(?<!bar)foo",[]))),
- <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","\\w{3}(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"foo">> = iolist_to_binary(join(re:split("foo","\\w{3}(?<!bar)foo",[]))),
+ <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","\\w{3}(?<!bar)foo",[trim]))),
<<"barfoo">> = iolist_to_binary(join(re:split("barfoo","\\w{3}(?<!bar)foo",[{parts,
- 2}]))),
- <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","\\w{3}(?<!bar)foo",[]))),
- <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","\\w{3}(?<!bar)foo",[trim]))),
+ 2}]))),
+ <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","\\w{3}(?<!bar)foo",[]))),
+ <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","\\w{3}(?<!bar)foo",[trim]))),
<<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","\\w{3}(?<!bar)foo",[{parts,
- 2}]))),
- <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","\\w{3}(?<!bar)foo",[]))),
- <<"fooa:foo">> = iolist_to_binary(join(re:split("fooabar","(?<=(foo)a)bar",[trim]))),
+ 2}]))),
+ <<"towbarfoo">> = iolist_to_binary(join(re:split("towbarfoo","\\w{3}(?<!bar)foo",[]))),
+ <<"fooa:foo">> = iolist_to_binary(join(re:split("fooabar","(?<=(foo)a)bar",[trim]))),
<<"fooa:foo:">> = iolist_to_binary(join(re:split("fooabar","(?<=(foo)a)bar",[{parts,
- 2}]))),
- <<"fooa:foo:">> = iolist_to_binary(join(re:split("fooabar","(?<=(foo)a)bar",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo)a)bar",[trim]))),
+ 2}]))),
+ <<"fooa:foo:">> = iolist_to_binary(join(re:split("fooabar","(?<=(foo)a)bar",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo)a)bar",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo)a)bar",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo)a)bar",[]))),
- <<"bar">> = iolist_to_binary(join(re:split("bar","(?<=(foo)a)bar",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo)a)bar",[]))),
+ <<"bar">> = iolist_to_binary(join(re:split("bar","(?<=(foo)a)bar",[trim]))),
<<"bar">> = iolist_to_binary(join(re:split("bar","(?<=(foo)a)bar",[{parts,
- 2}]))),
- <<"bar">> = iolist_to_binary(join(re:split("bar","(?<=(foo)a)bar",[]))),
- <<"foobbar">> = iolist_to_binary(join(re:split("foobbar","(?<=(foo)a)bar",[trim]))),
+ 2}]))),
+ <<"bar">> = iolist_to_binary(join(re:split("bar","(?<=(foo)a)bar",[]))),
+ <<"foobbar">> = iolist_to_binary(join(re:split("foobbar","(?<=(foo)a)bar",[trim]))),
<<"foobbar">> = iolist_to_binary(join(re:split("foobbar","(?<=(foo)a)bar",[{parts,
- 2}]))),
- <<"foobbar">> = iolist_to_binary(join(re:split("foobbar","(?<=(foo)a)bar",[]))),
+ 2}]))),
+ <<"foobbar">> = iolist_to_binary(join(re:split("foobbar","(?<=(foo)a)bar",[]))),
<<"">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\z",[multiline,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\z",[multiline,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\z",[multiline]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc\\z",[multiline]))),
<<"">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc\\z",[multiline]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","\\Aabc\\z",[multiline,trim]))),
+abc","\\Aabc\\z",[multiline,trim]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","\\Aabc\\z",[multiline,{parts,2}]))),
+abc","\\Aabc\\z",[multiline,{parts,2}]))),
<<"qqq
abc">> = iolist_to_binary(join(re:split("qqq
-abc","\\Aabc\\z",[multiline]))),
+abc","\\Aabc\\z",[multiline]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","\\Aabc\\z",[multiline,trim]))),
+zzz","\\Aabc\\z",[multiline,trim]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","\\Aabc\\z",[multiline,{parts,2}]))),
+zzz","\\Aabc\\z",[multiline,{parts,2}]))),
<<"abc
zzz">> = iolist_to_binary(join(re:split("abc
-zzz","\\Aabc\\z",[multiline]))),
+zzz","\\Aabc\\z",[multiline]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","\\Aabc\\z",[multiline,trim]))),
+zzz","\\Aabc\\z",[multiline,trim]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","\\Aabc\\z",[multiline,{parts,2}]))),
+zzz","\\Aabc\\z",[multiline,{parts,2}]))),
<<"qqq
abc
zzz">> = iolist_to_binary(join(re:split("qqq
abc
-zzz","\\Aabc\\z",[multiline]))),
- <<"1:.23">> = iolist_to_binary(join(re:split("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
+zzz","\\Aabc\\z",[multiline]))),
+ <<"1:.23">> = iolist_to_binary(join(re:split("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
<<"1:.23:">> = iolist_to_binary(join(re:split("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+",[{parts,
- 2}]))),
- <<"1:.23:">> = iolist_to_binary(join(re:split("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
- <<"1:.875">> = iolist_to_binary(join(re:split("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
+ 2}]))),
+ <<"1:.23:">> = iolist_to_binary(join(re:split("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
+ <<"1:.875">> = iolist_to_binary(join(re:split("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
<<"1:.875:">> = iolist_to_binary(join(re:split("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+",[{parts,
- 2}]))),
- <<"1:.875:">> = iolist_to_binary(join(re:split("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
+ 2}]))),
+ <<"1:.875:">> = iolist_to_binary(join(re:split("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
- <<"1.235">> = iolist_to_binary(join(re:split("1.235","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
+ <<"1.235">> = iolist_to_binary(join(re:split("1.235","(?>(\\.\\d\\d[1-9]?))\\d+",[trim]))),
<<"1.235">> = iolist_to_binary(join(re:split("1.235","(?>(\\.\\d\\d[1-9]?))\\d+",[{parts,
- 2}]))),
- <<"1.235">> = iolist_to_binary(join(re:split("1.235","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
- <<":party">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$",[trim]))),
+ 2}]))),
+ <<"1.235">> = iolist_to_binary(join(re:split("1.235","(?>(\\.\\d\\d[1-9]?))\\d+",[]))),
+ <<":party">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$",[trim]))),
<<":party:">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$",[{parts,
- 2}]))),
- <<":party:">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((?>\\w+)|(?>\\s+))*$",[trim]))),
+ 2}]))),
+ <<":party:">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((?>\\w+)|(?>\\s+))*$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((?>\\w+)|(?>\\s+))*$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((?>\\w+)|(?>\\s+))*$",[]))),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((?>\\w+)|(?>\\s+))*$",[]))),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$",[trim]))),
<<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$",[{parts,
- 2}]))),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$",[]))),
- <<":12345:a">> = iolist_to_binary(join(re:split("12345a","(\\d+)(\\w)",[trim]))),
+ 2}]))),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$",[]))),
+ <<":12345:a">> = iolist_to_binary(join(re:split("12345a","(\\d+)(\\w)",[trim]))),
<<":12345:a:">> = iolist_to_binary(join(re:split("12345a","(\\d+)(\\w)",[{parts,
- 2}]))),
- <<":12345:a:">> = iolist_to_binary(join(re:split("12345a","(\\d+)(\\w)",[]))),
- <<":1234:5:+">> = iolist_to_binary(join(re:split("12345+","(\\d+)(\\w)",[trim]))),
+ 2}]))),
+ <<":12345:a:">> = iolist_to_binary(join(re:split("12345a","(\\d+)(\\w)",[]))),
+ <<":1234:5:+">> = iolist_to_binary(join(re:split("12345+","(\\d+)(\\w)",[trim]))),
<<":1234:5:+">> = iolist_to_binary(join(re:split("12345+","(\\d+)(\\w)",[{parts,
- 2}]))),
- <<":1234:5:+">> = iolist_to_binary(join(re:split("12345+","(\\d+)(\\w)",[]))),
- <<":12345:a">> = iolist_to_binary(join(re:split("12345a","((?>\\d+))(\\w)",[trim]))),
+ 2}]))),
+ <<":1234:5:+">> = iolist_to_binary(join(re:split("12345+","(\\d+)(\\w)",[]))),
+ <<":12345:a">> = iolist_to_binary(join(re:split("12345a","((?>\\d+))(\\w)",[trim]))),
<<":12345:a:">> = iolist_to_binary(join(re:split("12345a","((?>\\d+))(\\w)",[{parts,
- 2}]))),
- <<":12345:a:">> = iolist_to_binary(join(re:split("12345a","((?>\\d+))(\\w)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?>\\d+))(\\w)",[trim]))),
+ 2}]))),
+ <<":12345:a:">> = iolist_to_binary(join(re:split("12345a","((?>\\d+))(\\w)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?>\\d+))(\\w)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?>\\d+))(\\w)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?>\\d+))(\\w)",[]))),
- <<"12345+">> = iolist_to_binary(join(re:split("12345+","((?>\\d+))(\\w)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?>\\d+))(\\w)",[]))),
+ <<"12345+">> = iolist_to_binary(join(re:split("12345+","((?>\\d+))(\\w)",[trim]))),
<<"12345+">> = iolist_to_binary(join(re:split("12345+","((?>\\d+))(\\w)",[{parts,
- 2}]))),
- <<"12345+">> = iolist_to_binary(join(re:split("12345+","((?>\\d+))(\\w)",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[trim]))),
+ 2}]))),
+ <<"12345+">> = iolist_to_binary(join(re:split("12345+","((?>\\d+))(\\w)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[]))),
ok.
run12() ->
- <<":aaab">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[trim]))),
+ <<":aaab">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[trim]))),
<<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[{parts,
- 2}]))),
- <<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[]))),
- <<":aaa">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[trim]))),
+ 2}]))),
+ <<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[]))),
+ <<":aaa">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[trim]))),
<<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[{parts,
- 2}]))),
- <<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[]))),
- <<"aaa:ccc">> = iolist_to_binary(join(re:split("aaabbbccc","(?>b)+",[trim]))),
+ 2}]))),
+ <<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[]))),
+ <<"aaa:ccc">> = iolist_to_binary(join(re:split("aaabbbccc","(?>b)+",[trim]))),
<<"aaa:ccc">> = iolist_to_binary(join(re:split("aaabbbccc","(?>b)+",[{parts,
- 2}]))),
- <<"aaa:ccc">> = iolist_to_binary(join(re:split("aaabbbccc","(?>b)+",[]))),
- <<"::::d">> = iolist_to_binary(join(re:split("aaabbbbccccd","(?>a+|b+|c+)*c",[trim]))),
+ 2}]))),
+ <<"aaa:ccc">> = iolist_to_binary(join(re:split("aaabbbccc","(?>b)+",[]))),
+ <<"::::d">> = iolist_to_binary(join(re:split("aaabbbbccccd","(?>a+|b+|c+)*c",[trim]))),
<<":cccd">> = iolist_to_binary(join(re:split("aaabbbbccccd","(?>a+|b+|c+)*c",[{parts,
- 2}]))),
- <<"::::d">> = iolist_to_binary(join(re:split("aaabbbbccccd","(?>a+|b+|c+)*c",[]))),
- <<"((:x">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[trim]))),
+ 2}]))),
+ <<"::::d">> = iolist_to_binary(join(re:split("aaabbbbccccd","(?>a+|b+|c+)*c",[]))),
+ <<"((:x">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[trim]))),
<<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[{parts,
- 2}]))),
- <<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
- <<":xyz">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
+ <<":xyz">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
<<":xyz:">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<":xyz:">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<":xyz:">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[trim]))),
<<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
+ 2}]))),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)",[]))),
<<"">> = iolist_to_binary(join(re:split("ab","a(?-i)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","a(?-i)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","a(?-i)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","a(?-i)b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("Ab","a(?-i)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("Ab","a(?-i)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("Ab","a(?-i)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("Ab","a(?-i)b",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?-i)b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?-i)b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?-i)b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?-i)b",[caseless]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","a(?-i)b",[caseless,
- trim]))),
+ trim]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","a(?-i)b",[caseless,
{parts,
- 2}]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","a(?-i)b",[caseless]))),
+ 2}]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","a(?-i)b",[caseless]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","a(?-i)b",[caseless,
- trim]))),
+ trim]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","a(?-i)b",[caseless,
{parts,
- 2}]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","a(?-i)b",[caseless]))),
- <<":a bc">> = iolist_to_binary(join(re:split("a bcd e","(a (?x)b c)d e",[trim]))),
+ 2}]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","a(?-i)b",[caseless]))),
+ <<":a bc">> = iolist_to_binary(join(re:split("a bcd e","(a (?x)b c)d e",[trim]))),
<<":a bc:">> = iolist_to_binary(join(re:split("a bcd e","(a (?x)b c)d e",[{parts,
- 2}]))),
- <<":a bc:">> = iolist_to_binary(join(re:split("a bcd e","(a (?x)b c)d e",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a (?x)b c)d e",[trim]))),
+ 2}]))),
+ <<":a bc:">> = iolist_to_binary(join(re:split("a bcd e","(a (?x)b c)d e",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a (?x)b c)d e",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a (?x)b c)d e",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a (?x)b c)d e",[]))),
- <<"a b cd e">> = iolist_to_binary(join(re:split("a b cd e","(a (?x)b c)d e",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a (?x)b c)d e",[]))),
+ <<"a b cd e">> = iolist_to_binary(join(re:split("a b cd e","(a (?x)b c)d e",[trim]))),
<<"a b cd e">> = iolist_to_binary(join(re:split("a b cd e","(a (?x)b c)d e",[{parts,
- 2}]))),
- <<"a b cd e">> = iolist_to_binary(join(re:split("a b cd e","(a (?x)b c)d e",[]))),
- <<"abcd e">> = iolist_to_binary(join(re:split("abcd e","(a (?x)b c)d e",[trim]))),
+ 2}]))),
+ <<"a b cd e">> = iolist_to_binary(join(re:split("a b cd e","(a (?x)b c)d e",[]))),
+ <<"abcd e">> = iolist_to_binary(join(re:split("abcd e","(a (?x)b c)d e",[trim]))),
<<"abcd e">> = iolist_to_binary(join(re:split("abcd e","(a (?x)b c)d e",[{parts,
- 2}]))),
- <<"abcd e">> = iolist_to_binary(join(re:split("abcd e","(a (?x)b c)d e",[]))),
- <<"a bcde">> = iolist_to_binary(join(re:split("a bcde","(a (?x)b c)d e",[trim]))),
+ 2}]))),
+ <<"abcd e">> = iolist_to_binary(join(re:split("abcd e","(a (?x)b c)d e",[]))),
+ <<"a bcde">> = iolist_to_binary(join(re:split("a bcde","(a (?x)b c)d e",[trim]))),
<<"a bcde">> = iolist_to_binary(join(re:split("a bcde","(a (?x)b c)d e",[{parts,
- 2}]))),
- <<"a bcde">> = iolist_to_binary(join(re:split("a bcde","(a (?x)b c)d e",[]))),
- <<":a bcde f">> = iolist_to_binary(join(re:split("a bcde f","(a b(?x)c d (?-x)e f)",[trim]))),
+ 2}]))),
+ <<"a bcde">> = iolist_to_binary(join(re:split("a bcde","(a (?x)b c)d e",[]))),
+ <<":a bcde f">> = iolist_to_binary(join(re:split("a bcde f","(a b(?x)c d (?-x)e f)",[trim]))),
<<":a bcde f:">> = iolist_to_binary(join(re:split("a bcde f","(a b(?x)c d (?-x)e f)",[{parts,
- 2}]))),
- <<":a bcde f:">> = iolist_to_binary(join(re:split("a bcde f","(a b(?x)c d (?-x)e f)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a b(?x)c d (?-x)e f)",[trim]))),
+ 2}]))),
+ <<":a bcde f:">> = iolist_to_binary(join(re:split("a bcde f","(a b(?x)c d (?-x)e f)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a b(?x)c d (?-x)e f)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a b(?x)c d (?-x)e f)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a b(?x)c d (?-x)e f)",[]))),
- <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","(a b(?x)c d (?-x)e f)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a b(?x)c d (?-x)e f)",[]))),
+ <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","(a b(?x)c d (?-x)e f)",[trim]))),
<<"abcdef">> = iolist_to_binary(join(re:split("abcdef","(a b(?x)c d (?-x)e f)",[{parts,
- 2}]))),
- <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","(a b(?x)c d (?-x)e f)",[]))),
- <<":ab">> = iolist_to_binary(join(re:split("abc","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","(a b(?x)c d (?-x)e f)",[]))),
+ <<":ab">> = iolist_to_binary(join(re:split("abc","(a(?i)b)c",[trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("abc","(a(?i)b)c",[{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("abc","(a(?i)b)c",[]))),
- <<":aB">> = iolist_to_binary(join(re:split("aBc","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("abc","(a(?i)b)c",[]))),
+ <<":aB">> = iolist_to_binary(join(re:split("aBc","(a(?i)b)c",[trim]))),
<<":aB:">> = iolist_to_binary(join(re:split("aBc","(a(?i)b)c",[{parts,
- 2}]))),
- <<":aB:">> = iolist_to_binary(join(re:split("aBc","(a(?i)b)c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<":aB:">> = iolist_to_binary(join(re:split("aBc","(a(?i)b)c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)b)c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)b)c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)b)c",[]))),
- <<"abC">> = iolist_to_binary(join(re:split("abC","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)b)c",[]))),
+ <<"abC">> = iolist_to_binary(join(re:split("abC","(a(?i)b)c",[trim]))),
<<"abC">> = iolist_to_binary(join(re:split("abC","(a(?i)b)c",[{parts,
- 2}]))),
- <<"abC">> = iolist_to_binary(join(re:split("abC","(a(?i)b)c",[]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"abC">> = iolist_to_binary(join(re:split("abC","(a(?i)b)c",[]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","(a(?i)b)c",[trim]))),
<<"aBC">> = iolist_to_binary(join(re:split("aBC","(a(?i)b)c",[{parts,
- 2}]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","(a(?i)b)c",[]))),
- <<"Abc">> = iolist_to_binary(join(re:split("Abc","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","(a(?i)b)c",[]))),
+ <<"Abc">> = iolist_to_binary(join(re:split("Abc","(a(?i)b)c",[trim]))),
<<"Abc">> = iolist_to_binary(join(re:split("Abc","(a(?i)b)c",[{parts,
- 2}]))),
- <<"Abc">> = iolist_to_binary(join(re:split("Abc","(a(?i)b)c",[]))),
- <<"ABc">> = iolist_to_binary(join(re:split("ABc","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"Abc">> = iolist_to_binary(join(re:split("Abc","(a(?i)b)c",[]))),
+ <<"ABc">> = iolist_to_binary(join(re:split("ABc","(a(?i)b)c",[trim]))),
<<"ABc">> = iolist_to_binary(join(re:split("ABc","(a(?i)b)c",[{parts,
- 2}]))),
- <<"ABc">> = iolist_to_binary(join(re:split("ABc","(a(?i)b)c",[]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"ABc">> = iolist_to_binary(join(re:split("ABc","(a(?i)b)c",[]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","(a(?i)b)c",[trim]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","(a(?i)b)c",[{parts,
- 2}]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","(a(?i)b)c",[]))),
- <<"AbC">> = iolist_to_binary(join(re:split("AbC","(a(?i)b)c",[trim]))),
+ 2}]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","(a(?i)b)c",[]))),
+ <<"AbC">> = iolist_to_binary(join(re:split("AbC","(a(?i)b)c",[trim]))),
<<"AbC">> = iolist_to_binary(join(re:split("AbC","(a(?i)b)c",[{parts,
- 2}]))),
- <<"AbC">> = iolist_to_binary(join(re:split("AbC","(a(?i)b)c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","a(?i:b)c",[trim]))),
+ 2}]))),
+ <<"AbC">> = iolist_to_binary(join(re:split("AbC","(a(?i)b)c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","a(?i:b)c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","a(?i:b)c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","a(?i:b)c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aBc","a(?i:b)c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","a(?i:b)c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aBc","a(?i:b)c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aBc","a(?i:b)c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aBc","a(?i:b)c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aBc","a(?i:b)c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)c",[]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","a(?i:b)c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)c",[]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","a(?i:b)c",[trim]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","a(?i:b)c",[{parts,
- 2}]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","a(?i:b)c",[]))),
- <<"abC">> = iolist_to_binary(join(re:split("abC","a(?i:b)c",[trim]))),
+ 2}]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","a(?i:b)c",[]))),
+ <<"abC">> = iolist_to_binary(join(re:split("abC","a(?i:b)c",[trim]))),
<<"abC">> = iolist_to_binary(join(re:split("abC","a(?i:b)c",[{parts,
- 2}]))),
- <<"abC">> = iolist_to_binary(join(re:split("abC","a(?i:b)c",[]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)c",[trim]))),
+ 2}]))),
+ <<"abC">> = iolist_to_binary(join(re:split("abC","a(?i:b)c",[]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)c",[trim]))),
<<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)c",[{parts,
- 2}]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aBc","a(?i:b)*c",[trim]))),
+ 2}]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aBc","a(?i:b)*c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aBc","a(?i:b)*c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aBc","a(?i:b)*c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aBBc","a(?i:b)*c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aBc","a(?i:b)*c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aBBc","a(?i:b)*c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aBBc","a(?i:b)*c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aBBc","a(?i:b)*c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)*c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aBBc","a(?i:b)*c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)*c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)*c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)*c",[]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)*c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?i:b)*c",[]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)*c",[trim]))),
<<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)*c",[{parts,
- 2}]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)*c",[]))),
- <<"aBBC">> = iolist_to_binary(join(re:split("aBBC","a(?i:b)*c",[trim]))),
+ 2}]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","a(?i:b)*c",[]))),
+ <<"aBBC">> = iolist_to_binary(join(re:split("aBBC","a(?i:b)*c",[trim]))),
<<"aBBC">> = iolist_to_binary(join(re:split("aBBC","a(?i:b)*c",[{parts,
- 2}]))),
- <<"aBBC">> = iolist_to_binary(join(re:split("aBBC","a(?i:b)*c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcd","a(?=b(?i)c)\\w\\wd",[trim]))),
+ 2}]))),
+ <<"aBBC">> = iolist_to_binary(join(re:split("aBBC","a(?i:b)*c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcd","a(?=b(?i)c)\\w\\wd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd","a(?=b(?i)c)\\w\\wd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcd","a(?=b(?i)c)\\w\\wd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abCd","a(?=b(?i)c)\\w\\wd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcd","a(?=b(?i)c)\\w\\wd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abCd","a(?=b(?i)c)\\w\\wd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abCd","a(?=b(?i)c)\\w\\wd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abCd","a(?=b(?i)c)\\w\\wd",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?=b(?i)c)\\w\\wd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abCd","a(?=b(?i)c)\\w\\wd",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?=b(?i)c)\\w\\wd",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?=b(?i)c)\\w\\wd",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?=b(?i)c)\\w\\wd",[]))),
- <<"aBCd">> = iolist_to_binary(join(re:split("aBCd","a(?=b(?i)c)\\w\\wd",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?=b(?i)c)\\w\\wd",[]))),
+ <<"aBCd">> = iolist_to_binary(join(re:split("aBCd","a(?=b(?i)c)\\w\\wd",[trim]))),
<<"aBCd">> = iolist_to_binary(join(re:split("aBCd","a(?=b(?i)c)\\w\\wd",[{parts,
- 2}]))),
- <<"aBCd">> = iolist_to_binary(join(re:split("aBCd","a(?=b(?i)c)\\w\\wd",[]))),
- <<"abcD">> = iolist_to_binary(join(re:split("abcD","a(?=b(?i)c)\\w\\wd",[trim]))),
+ 2}]))),
+ <<"aBCd">> = iolist_to_binary(join(re:split("aBCd","a(?=b(?i)c)\\w\\wd",[]))),
+ <<"abcD">> = iolist_to_binary(join(re:split("abcD","a(?=b(?i)c)\\w\\wd",[trim]))),
<<"abcD">> = iolist_to_binary(join(re:split("abcD","a(?=b(?i)c)\\w\\wd",[{parts,
- 2}]))),
- <<"abcD">> = iolist_to_binary(join(re:split("abcD","a(?=b(?i)c)\\w\\wd",[]))),
+ 2}]))),
+ <<"abcD">> = iolist_to_binary(join(re:split("abcD","a(?=b(?i)c)\\w\\wd",[]))),
<<"">> = iolist_to_binary(join(re:split("more than million","(?s-i:more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("more than million","(?s-i:more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("more than million","(?s-i:more.*than).*million",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("more than million","(?s-i:more.*than).*million",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("more than MILLION","(?s-i:more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("more than MILLION","(?s-i:more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("more than MILLION","(?s-i:more.*than).*million",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("more than MILLION","(?s-i:more.*than).*million",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("more
- than Million","(?s-i:more.*than).*million",[caseless,trim]))),
+ than Million","(?s-i:more.*than).*million",[caseless,trim]))),
<<":">> = iolist_to_binary(join(re:split("more
- than Million","(?s-i:more.*than).*million",[caseless,{parts,2}]))),
+ than Million","(?s-i:more.*than).*million",[caseless,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("more
- than Million","(?s-i:more.*than).*million",[caseless]))),
+ than Million","(?s-i:more.*than).*million",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s-i:more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s-i:more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s-i:more.*than).*million",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?s-i:more.*than).*million",[caseless]))),
<<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?s-i:more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?s-i:more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?s-i:more.*than).*million",[caseless]))),
+ 2}]))),
+ <<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?s-i:more.*than).*million",[caseless]))),
<<"more
than
million">> = iolist_to_binary(join(re:split("more
than
- million","(?s-i:more.*than).*million",[caseless,trim]))),
+ million","(?s-i:more.*than).*million",[caseless,trim]))),
<<"more
than
million">> = iolist_to_binary(join(re:split("more
than
- million","(?s-i:more.*than).*million",[caseless,{parts,2}]))),
+ million","(?s-i:more.*than).*million",[caseless,{parts,2}]))),
<<"more
than
million">> = iolist_to_binary(join(re:split("more
than
- million","(?s-i:more.*than).*million",[caseless]))),
+ million","(?s-i:more.*than).*million",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("more than million","(?:(?s-i)more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("more than million","(?:(?s-i)more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("more than million","(?:(?s-i)more.*than).*million",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("more than million","(?:(?s-i)more.*than).*million",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("more than MILLION","(?:(?s-i)more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("more than MILLION","(?:(?s-i)more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("more than MILLION","(?:(?s-i)more.*than).*million",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("more than MILLION","(?:(?s-i)more.*than).*million",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("more
- than Million","(?:(?s-i)more.*than).*million",[caseless,trim]))),
+ than Million","(?:(?s-i)more.*than).*million",[caseless,trim]))),
<<":">> = iolist_to_binary(join(re:split("more
- than Million","(?:(?s-i)more.*than).*million",[caseless,{parts,2}]))),
+ than Million","(?:(?s-i)more.*than).*million",[caseless,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("more
- than Million","(?:(?s-i)more.*than).*million",[caseless]))),
+ than Million","(?:(?s-i)more.*than).*million",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?s-i)more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?s-i)more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?s-i)more.*than).*million",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?s-i)more.*than).*million",[caseless]))),
<<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?:(?s-i)more.*than).*million",[caseless,
- trim]))),
+ trim]))),
<<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?:(?s-i)more.*than).*million",[caseless,
{parts,
- 2}]))),
- <<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?:(?s-i)more.*than).*million",[caseless]))),
+ 2}]))),
+ <<"MORE THAN MILLION">> = iolist_to_binary(join(re:split("MORE THAN MILLION","(?:(?s-i)more.*than).*million",[caseless]))),
<<"more
than
million">> = iolist_to_binary(join(re:split("more
than
- million","(?:(?s-i)more.*than).*million",[caseless,trim]))),
+ million","(?:(?s-i)more.*than).*million",[caseless,trim]))),
<<"more
than
million">> = iolist_to_binary(join(re:split("more
than
- million","(?:(?s-i)more.*than).*million",[caseless,{parts,2}]))),
+ million","(?:(?s-i)more.*than).*million",[caseless,{parts,2}]))),
<<"more
than
million">> = iolist_to_binary(join(re:split("more
than
- million","(?:(?s-i)more.*than).*million",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("abc","(?>a(?i)b+)+c",[trim]))),
+ million","(?:(?s-i)more.*than).*million",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","(?>a(?i)b+)+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","(?>a(?i)b+)+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aBbc","(?>a(?i)b+)+c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","(?>a(?i)b+)+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aBbc","(?>a(?i)b+)+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aBbc","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aBbc","(?>a(?i)b+)+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aBBc","(?>a(?i)b+)+c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aBbc","(?>a(?i)b+)+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aBBc","(?>a(?i)b+)+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aBBc","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aBBc","(?>a(?i)b+)+c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>a(?i)b+)+c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aBBc","(?>a(?i)b+)+c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>a(?i)b+)+c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>a(?i)b+)+c",[]))),
- <<"Abc">> = iolist_to_binary(join(re:split("Abc","(?>a(?i)b+)+c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>a(?i)b+)+c",[]))),
+ <<"Abc">> = iolist_to_binary(join(re:split("Abc","(?>a(?i)b+)+c",[trim]))),
<<"Abc">> = iolist_to_binary(join(re:split("Abc","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<"Abc">> = iolist_to_binary(join(re:split("Abc","(?>a(?i)b+)+c",[]))),
- <<"abAb">> = iolist_to_binary(join(re:split("abAb","(?>a(?i)b+)+c",[trim]))),
+ 2}]))),
+ <<"Abc">> = iolist_to_binary(join(re:split("Abc","(?>a(?i)b+)+c",[]))),
+ <<"abAb">> = iolist_to_binary(join(re:split("abAb","(?>a(?i)b+)+c",[trim]))),
<<"abAb">> = iolist_to_binary(join(re:split("abAb","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<"abAb">> = iolist_to_binary(join(re:split("abAb","(?>a(?i)b+)+c",[]))),
- <<"abbC">> = iolist_to_binary(join(re:split("abbC","(?>a(?i)b+)+c",[trim]))),
+ 2}]))),
+ <<"abAb">> = iolist_to_binary(join(re:split("abAb","(?>a(?i)b+)+c",[]))),
+ <<"abbC">> = iolist_to_binary(join(re:split("abbC","(?>a(?i)b+)+c",[trim]))),
<<"abbC">> = iolist_to_binary(join(re:split("abbC","(?>a(?i)b+)+c",[{parts,
- 2}]))),
- <<"abbC">> = iolist_to_binary(join(re:split("abbC","(?>a(?i)b+)+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","(?=a(?i)b)\\w\\wc",[trim]))),
+ 2}]))),
+ <<"abbC">> = iolist_to_binary(join(re:split("abbC","(?>a(?i)b+)+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","(?=a(?i)b)\\w\\wc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","(?=a(?i)b)\\w\\wc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","(?=a(?i)b)\\w\\wc",[]))),
- <<"">> = iolist_to_binary(join(re:split("aBc","(?=a(?i)b)\\w\\wc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","(?=a(?i)b)\\w\\wc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aBc","(?=a(?i)b)\\w\\wc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aBc","(?=a(?i)b)\\w\\wc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aBc","(?=a(?i)b)\\w\\wc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=a(?i)b)\\w\\wc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aBc","(?=a(?i)b)\\w\\wc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=a(?i)b)\\w\\wc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=a(?i)b)\\w\\wc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=a(?i)b)\\w\\wc",[]))),
- <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?=a(?i)b)\\w\\wc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?=a(?i)b)\\w\\wc",[]))),
+ <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?=a(?i)b)\\w\\wc",[trim]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?=a(?i)b)\\w\\wc",[{parts,
- 2}]))),
- <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?=a(?i)b)\\w\\wc",[]))),
- <<"abC">> = iolist_to_binary(join(re:split("abC","(?=a(?i)b)\\w\\wc",[trim]))),
+ 2}]))),
+ <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?=a(?i)b)\\w\\wc",[]))),
+ <<"abC">> = iolist_to_binary(join(re:split("abC","(?=a(?i)b)\\w\\wc",[trim]))),
<<"abC">> = iolist_to_binary(join(re:split("abC","(?=a(?i)b)\\w\\wc",[{parts,
- 2}]))),
- <<"abC">> = iolist_to_binary(join(re:split("abC","(?=a(?i)b)\\w\\wc",[]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","(?=a(?i)b)\\w\\wc",[trim]))),
+ 2}]))),
+ <<"abC">> = iolist_to_binary(join(re:split("abC","(?=a(?i)b)\\w\\wc",[]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","(?=a(?i)b)\\w\\wc",[trim]))),
<<"aBC">> = iolist_to_binary(join(re:split("aBC","(?=a(?i)b)\\w\\wc",[{parts,
- 2}]))),
- <<"aBC">> = iolist_to_binary(join(re:split("aBC","(?=a(?i)b)\\w\\wc",[]))),
- <<"ab:xx">> = iolist_to_binary(join(re:split("abxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
+ 2}]))),
+ <<"aBC">> = iolist_to_binary(join(re:split("aBC","(?=a(?i)b)\\w\\wc",[]))),
+ <<"ab:xx">> = iolist_to_binary(join(re:split("abxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
<<"ab:xx:">> = iolist_to_binary(join(re:split("abxxc","(?<=a(?i)b)(\\w\\w)c",[{parts,
- 2}]))),
- <<"ab:xx:">> = iolist_to_binary(join(re:split("abxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
- <<"aB:xx">> = iolist_to_binary(join(re:split("aBxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
+ 2}]))),
+ <<"ab:xx:">> = iolist_to_binary(join(re:split("abxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
+ <<"aB:xx">> = iolist_to_binary(join(re:split("aBxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
<<"aB:xx:">> = iolist_to_binary(join(re:split("aBxxc","(?<=a(?i)b)(\\w\\w)c",[{parts,
- 2}]))),
- <<"aB:xx:">> = iolist_to_binary(join(re:split("aBxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a(?i)b)(\\w\\w)c",[trim]))),
+ 2}]))),
+ <<"aB:xx:">> = iolist_to_binary(join(re:split("aBxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a(?i)b)(\\w\\w)c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a(?i)b)(\\w\\w)c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a(?i)b)(\\w\\w)c",[]))),
- <<"Abxxc">> = iolist_to_binary(join(re:split("Abxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a(?i)b)(\\w\\w)c",[]))),
+ <<"Abxxc">> = iolist_to_binary(join(re:split("Abxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
<<"Abxxc">> = iolist_to_binary(join(re:split("Abxxc","(?<=a(?i)b)(\\w\\w)c",[{parts,
- 2}]))),
- <<"Abxxc">> = iolist_to_binary(join(re:split("Abxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
- <<"ABxxc">> = iolist_to_binary(join(re:split("ABxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
+ 2}]))),
+ <<"Abxxc">> = iolist_to_binary(join(re:split("Abxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
+ <<"ABxxc">> = iolist_to_binary(join(re:split("ABxxc","(?<=a(?i)b)(\\w\\w)c",[trim]))),
<<"ABxxc">> = iolist_to_binary(join(re:split("ABxxc","(?<=a(?i)b)(\\w\\w)c",[{parts,
- 2}]))),
- <<"ABxxc">> = iolist_to_binary(join(re:split("ABxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
- <<"abxxC">> = iolist_to_binary(join(re:split("abxxC","(?<=a(?i)b)(\\w\\w)c",[trim]))),
+ 2}]))),
+ <<"ABxxc">> = iolist_to_binary(join(re:split("ABxxc","(?<=a(?i)b)(\\w\\w)c",[]))),
+ <<"abxxC">> = iolist_to_binary(join(re:split("abxxC","(?<=a(?i)b)(\\w\\w)c",[trim]))),
<<"abxxC">> = iolist_to_binary(join(re:split("abxxC","(?<=a(?i)b)(\\w\\w)c",[{parts,
- 2}]))),
- <<"abxxC">> = iolist_to_binary(join(re:split("abxxC","(?<=a(?i)b)(\\w\\w)c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aA","(?:(a)|b)(?(1)A|B)",[trim]))),
+ 2}]))),
+ <<"abxxC">> = iolist_to_binary(join(re:split("abxxC","(?<=a(?i)b)(\\w\\w)c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aA","(?:(a)|b)(?(1)A|B)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aA","(?:(a)|b)(?(1)A|B)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aA","(?:(a)|b)(?(1)A|B)",[]))),
- <<"">> = iolist_to_binary(join(re:split("bB","(?:(a)|b)(?(1)A|B)",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aA","(?:(a)|b)(?(1)A|B)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bB","(?:(a)|b)(?(1)A|B)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("bB","(?:(a)|b)(?(1)A|B)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("bB","(?:(a)|b)(?(1)A|B)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(a)|b)(?(1)A|B)",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("bB","(?:(a)|b)(?(1)A|B)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(a)|b)(?(1)A|B)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(a)|b)(?(1)A|B)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(a)|b)(?(1)A|B)",[]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(a)|b)(?(1)A|B)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(a)|b)(?(1)A|B)",[]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(a)|b)(?(1)A|B)",[trim]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","(?:(a)|b)(?(1)A|B)",[{parts,
- 2}]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(a)|b)(?(1)A|B)",[]))),
- <<"bA">> = iolist_to_binary(join(re:split("bA","(?:(a)|b)(?(1)A|B)",[trim]))),
+ 2}]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(a)|b)(?(1)A|B)",[]))),
+ <<"bA">> = iolist_to_binary(join(re:split("bA","(?:(a)|b)(?(1)A|B)",[trim]))),
<<"bA">> = iolist_to_binary(join(re:split("bA","(?:(a)|b)(?(1)A|B)",[{parts,
- 2}]))),
- <<"bA">> = iolist_to_binary(join(re:split("bA","(?:(a)|b)(?(1)A|B)",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aa","^(a)?(?(1)a|b)+$",[trim]))),
+ 2}]))),
+ <<"bA">> = iolist_to_binary(join(re:split("bA","(?:(a)|b)(?(1)A|B)",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aa","^(a)?(?(1)a|b)+$",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aa","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aa","^(a)?(?(1)a|b)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^(a)?(?(1)a|b)+$",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aa","^(a)?(?(1)a|b)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^(a)?(?(1)a|b)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","^(a)?(?(1)a|b)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("bb","^(a)?(?(1)a|b)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","^(a)?(?(1)a|b)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bb","^(a)?(?(1)a|b)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("bb","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("bb","^(a)?(?(1)a|b)+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("bb","^(a)?(?(1)a|b)+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[]))),
ok.
run13() ->
- <<"">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
- <<"">> = iolist_to_binary(join(re:split("12","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
<<"123">> = iolist_to_binary(join(re:split("123","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
- 2}]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
+ 2}]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
<<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
- 2}]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
+ 2}]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
- <<"">> = iolist_to_binary(join(re:split("12","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("12","^(?(?!abc)\\d\\d|\\w{3}:)$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
<<"123">> = iolist_to_binary(join(re:split("123","^(?(?!abc)\\d\\d|\\w{3}:)$",[{parts,
- 2}]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
+ 2}]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
<<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$",[{parts,
- 2}]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
- <<"foo">> = iolist_to_binary(join(re:split("foobar","(?(?<=foo)bar|cat)",[trim]))),
+ 2}]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$",[]))),
+ <<"foo">> = iolist_to_binary(join(re:split("foobar","(?(?<=foo)bar|cat)",[trim]))),
<<"foo:">> = iolist_to_binary(join(re:split("foobar","(?(?<=foo)bar|cat)",[{parts,
- 2}]))),
- <<"foo:">> = iolist_to_binary(join(re:split("foobar","(?(?<=foo)bar|cat)",[]))),
- <<"">> = iolist_to_binary(join(re:split("cat","(?(?<=foo)bar|cat)",[trim]))),
+ 2}]))),
+ <<"foo:">> = iolist_to_binary(join(re:split("foobar","(?(?<=foo)bar|cat)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("cat","(?(?<=foo)bar|cat)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("cat","(?(?<=foo)bar|cat)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("cat","(?(?<=foo)bar|cat)",[]))),
- <<"f">> = iolist_to_binary(join(re:split("fcat","(?(?<=foo)bar|cat)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("cat","(?(?<=foo)bar|cat)",[]))),
+ <<"f">> = iolist_to_binary(join(re:split("fcat","(?(?<=foo)bar|cat)",[trim]))),
<<"f:">> = iolist_to_binary(join(re:split("fcat","(?(?<=foo)bar|cat)",[{parts,
- 2}]))),
- <<"f:">> = iolist_to_binary(join(re:split("fcat","(?(?<=foo)bar|cat)",[]))),
- <<"fo">> = iolist_to_binary(join(re:split("focat","(?(?<=foo)bar|cat)",[trim]))),
+ 2}]))),
+ <<"f:">> = iolist_to_binary(join(re:split("fcat","(?(?<=foo)bar|cat)",[]))),
+ <<"fo">> = iolist_to_binary(join(re:split("focat","(?(?<=foo)bar|cat)",[trim]))),
<<"fo:">> = iolist_to_binary(join(re:split("focat","(?(?<=foo)bar|cat)",[{parts,
- 2}]))),
- <<"fo:">> = iolist_to_binary(join(re:split("focat","(?(?<=foo)bar|cat)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<=foo)bar|cat)",[trim]))),
+ 2}]))),
+ <<"fo:">> = iolist_to_binary(join(re:split("focat","(?(?<=foo)bar|cat)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<=foo)bar|cat)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<=foo)bar|cat)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<=foo)bar|cat)",[]))),
- <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<=foo)bar|cat)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<=foo)bar|cat)",[]))),
+ <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<=foo)bar|cat)",[trim]))),
<<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<=foo)bar|cat)",[{parts,
- 2}]))),
- <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<=foo)bar|cat)",[]))),
- <<"foo">> = iolist_to_binary(join(re:split("foobar","(?(?<!foo)cat|bar)",[trim]))),
+ 2}]))),
+ <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<=foo)bar|cat)",[]))),
+ <<"foo">> = iolist_to_binary(join(re:split("foobar","(?(?<!foo)cat|bar)",[trim]))),
<<"foo:">> = iolist_to_binary(join(re:split("foobar","(?(?<!foo)cat|bar)",[{parts,
- 2}]))),
- <<"foo:">> = iolist_to_binary(join(re:split("foobar","(?(?<!foo)cat|bar)",[]))),
- <<"">> = iolist_to_binary(join(re:split("cat","(?(?<!foo)cat|bar)",[trim]))),
+ 2}]))),
+ <<"foo:">> = iolist_to_binary(join(re:split("foobar","(?(?<!foo)cat|bar)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("cat","(?(?<!foo)cat|bar)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("cat","(?(?<!foo)cat|bar)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("cat","(?(?<!foo)cat|bar)",[]))),
- <<"f">> = iolist_to_binary(join(re:split("fcat","(?(?<!foo)cat|bar)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("cat","(?(?<!foo)cat|bar)",[]))),
+ <<"f">> = iolist_to_binary(join(re:split("fcat","(?(?<!foo)cat|bar)",[trim]))),
<<"f:">> = iolist_to_binary(join(re:split("fcat","(?(?<!foo)cat|bar)",[{parts,
- 2}]))),
- <<"f:">> = iolist_to_binary(join(re:split("fcat","(?(?<!foo)cat|bar)",[]))),
- <<"fo">> = iolist_to_binary(join(re:split("focat","(?(?<!foo)cat|bar)",[trim]))),
+ 2}]))),
+ <<"f:">> = iolist_to_binary(join(re:split("fcat","(?(?<!foo)cat|bar)",[]))),
+ <<"fo">> = iolist_to_binary(join(re:split("focat","(?(?<!foo)cat|bar)",[trim]))),
<<"fo:">> = iolist_to_binary(join(re:split("focat","(?(?<!foo)cat|bar)",[{parts,
- 2}]))),
- <<"fo:">> = iolist_to_binary(join(re:split("focat","(?(?<!foo)cat|bar)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<!foo)cat|bar)",[trim]))),
+ 2}]))),
+ <<"fo:">> = iolist_to_binary(join(re:split("focat","(?(?<!foo)cat|bar)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<!foo)cat|bar)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<!foo)cat|bar)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<!foo)cat|bar)",[]))),
- <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<!foo)cat|bar)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?<!foo)cat|bar)",[]))),
+ <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<!foo)cat|bar)",[trim]))),
<<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<!foo)cat|bar)",[{parts,
- 2}]))),
- <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<!foo)cat|bar)",[]))),
+ 2}]))),
+ <<"foocat">> = iolist_to_binary(join(re:split("foocat","(?(?<!foo)cat|bar)",[]))),
<<"">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
- trim]))),
+ trim]))),
<<"::">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
<<":(">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
- trim]))),
+ trim]))),
<<":(:">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
{parts,
- 2}]))),
- <<":(:">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
+ 2}]))),
+ <<":(:">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
<<":::(">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
- trim]))),
+ trim]))),
<<"::(abcd) fox">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
{parts,
- 2}]))),
- <<":::(:::">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
+ 2}]))),
+ <<":::(:::">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
<<"(">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
- trim]))),
+ trim]))),
<<"(::">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended,
{parts,
- 2}]))),
- <<"(::">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
+ 2}]))),
+ <<"(::">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) |) ",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
- trim]))),
+ trim]))),
<<"::">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
<<":(">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
- trim]))),
+ trim]))),
<<":(:">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
{parts,
- 2}]))),
- <<":(:">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
+ 2}]))),
+ <<":(:">> = iolist_to_binary(join(re:split("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
<<":::(">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
- trim]))),
+ trim]))),
<<"::(abcd) fox">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
{parts,
- 2}]))),
- <<":::(:::">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
+ 2}]))),
+ <<":::(:::">> = iolist_to_binary(join(re:split("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
<<"(">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
- trim]))),
+ trim]))),
<<"(::">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended,
{parts,
- 2}]))),
- <<"(::">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
- <<":1:2">> = iolist_to_binary(join(re:split("12","^(?(2)a|(1)(2))+$",[trim]))),
+ 2}]))),
+ <<"(::">> = iolist_to_binary(join(re:split("(abcd","( \\( )? [^()]+ (?(1) \\) ) ",[extended]))),
+ <<":1:2">> = iolist_to_binary(join(re:split("12","^(?(2)a|(1)(2))+$",[trim]))),
<<":1:2:">> = iolist_to_binary(join(re:split("12","^(?(2)a|(1)(2))+$",[{parts,
- 2}]))),
- <<":1:2:">> = iolist_to_binary(join(re:split("12","^(?(2)a|(1)(2))+$",[]))),
- <<":1:2">> = iolist_to_binary(join(re:split("12a","^(?(2)a|(1)(2))+$",[trim]))),
+ 2}]))),
+ <<":1:2:">> = iolist_to_binary(join(re:split("12","^(?(2)a|(1)(2))+$",[]))),
+ <<":1:2">> = iolist_to_binary(join(re:split("12a","^(?(2)a|(1)(2))+$",[trim]))),
<<":1:2:">> = iolist_to_binary(join(re:split("12a","^(?(2)a|(1)(2))+$",[{parts,
- 2}]))),
- <<":1:2:">> = iolist_to_binary(join(re:split("12a","^(?(2)a|(1)(2))+$",[]))),
- <<":1:2">> = iolist_to_binary(join(re:split("12aa","^(?(2)a|(1)(2))+$",[trim]))),
+ 2}]))),
+ <<":1:2:">> = iolist_to_binary(join(re:split("12a","^(?(2)a|(1)(2))+$",[]))),
+ <<":1:2">> = iolist_to_binary(join(re:split("12aa","^(?(2)a|(1)(2))+$",[trim]))),
<<":1:2:">> = iolist_to_binary(join(re:split("12aa","^(?(2)a|(1)(2))+$",[{parts,
- 2}]))),
- <<":1:2:">> = iolist_to_binary(join(re:split("12aa","^(?(2)a|(1)(2))+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(2)a|(1)(2))+$",[trim]))),
+ 2}]))),
+ <<":1:2:">> = iolist_to_binary(join(re:split("12aa","^(?(2)a|(1)(2))+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(2)a|(1)(2))+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(2)a|(1)(2))+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(2)a|(1)(2))+$",[]))),
- <<"1234">> = iolist_to_binary(join(re:split("1234","^(?(2)a|(1)(2))+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?(2)a|(1)(2))+$",[]))),
+ <<"1234">> = iolist_to_binary(join(re:split("1234","^(?(2)a|(1)(2))+$",[trim]))),
<<"1234">> = iolist_to_binary(join(re:split("1234","^(?(2)a|(1)(2))+$",[{parts,
- 2}]))),
- <<"1234">> = iolist_to_binary(join(re:split("1234","^(?(2)a|(1)(2))+$",[]))),
- <<":blah">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<"1234">> = iolist_to_binary(join(re:split("1234","^(?(2)a|(1)(2))+$",[]))),
+ <<":blah">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+\\1",[trim]))),
<<":blah:">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<":blah:">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+\\1",[]))),
- <<":BLAH">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<":blah:">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+\\1",[]))),
+ <<":BLAH">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+\\1",[trim]))),
<<":BLAH:">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<":BLAH:">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+\\1",[]))),
- <<":Blah">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<":BLAH:">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+\\1",[]))),
+ <<":Blah">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+\\1",[trim]))),
<<":Blah:">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<":Blah:">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+\\1",[]))),
- <<":blaH">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<":Blah:">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+\\1",[]))),
+ <<":blaH">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+\\1",[trim]))),
<<":blaH:">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<":blaH:">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+\\1",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<":blaH:">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+\\1",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)blah)\\s+\\1",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)blah)\\s+\\1",[]))),
- <<"blah BLAH">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)blah)\\s+\\1",[]))),
+ <<"blah BLAH">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+\\1",[trim]))),
<<"blah BLAH">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<"blah BLAH">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+\\1",[]))),
- <<"Blah blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<"blah BLAH">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+\\1",[]))),
+ <<"Blah blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+\\1",[trim]))),
<<"Blah blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<"Blah blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+\\1",[]))),
- <<"blaH blah">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+\\1",[trim]))),
+ 2}]))),
+ <<"Blah blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+\\1",[]))),
+ <<"blaH blah">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+\\1",[trim]))),
<<"blaH blah">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+\\1",[{parts,
- 2}]))),
- <<"blaH blah">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+\\1",[]))),
- <<":blah">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<"blaH blah">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+\\1",[]))),
+ <<":blah">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":blah:">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":blah:">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+(?i:\\1)",[]))),
- <<":BLAH">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<":blah:">> = iolist_to_binary(join(re:split("blah blah","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<":BLAH">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":BLAH:">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":BLAH:">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+(?i:\\1)",[]))),
- <<":Blah">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<":BLAH:">> = iolist_to_binary(join(re:split("BLAH BLAH","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<":Blah">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":Blah:">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":Blah:">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+(?i:\\1)",[]))),
- <<":blaH">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<":Blah:">> = iolist_to_binary(join(re:split("Blah Blah","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<":blaH">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":blaH:">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":blaH:">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+(?i:\\1)",[]))),
- <<":blah">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<":blaH:">> = iolist_to_binary(join(re:split("blaH blaH","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<":blah">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":blah:">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":blah:">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+(?i:\\1)",[]))),
- <<":Blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<":blah:">> = iolist_to_binary(join(re:split("blah BLAH","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<":Blah">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":Blah:">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":Blah:">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+(?i:\\1)",[]))),
- <<":blaH">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
+ 2}]))),
+ <<":Blah:">> = iolist_to_binary(join(re:split("Blah blah","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<":blaH">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+(?i:\\1)",[trim]))),
<<":blaH:">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+(?i:\\1)",[{parts,
- 2}]))),
- <<":blaH:">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+(?i:\\1)",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","(?>a*)*",[trim]))),
+ 2}]))),
+ <<":blaH:">> = iolist_to_binary(join(re:split("blaH blah","((?i)blah)\\s+(?i:\\1)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","(?>a*)*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","(?>a*)*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","(?>a*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("aa","(?>a*)*",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","(?>a*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa","(?>a*)*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aa","(?>a*)*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aa","(?>a*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","(?>a*)*",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa","(?>a*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","(?>a*)*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","(?>a*)*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","(?>a*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","(abc|)+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","(?>a*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","(abc|)+",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("abc","(abc|)+",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abc","(abc|)+",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcabc","(abc|)+",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abc","(abc|)+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcabc","(abc|)+",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("abcabc","(abc|)+",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abcabc","(abc|)+",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcabcabc","(abc|)+",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abcabc","(abc|)+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcabcabc","(abc|)+",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("abcabcabc","(abc|)+",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abcabcabc","(abc|)+",[]))),
- <<"x::y::z">> = iolist_to_binary(join(re:split("xyz","(abc|)+",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abcabcabc","(abc|)+",[]))),
+ <<"x::y::z">> = iolist_to_binary(join(re:split("xyz","(abc|)+",[trim]))),
<<"x::yz">> = iolist_to_binary(join(re:split("xyz","(abc|)+",[{parts,
- 2}]))),
- <<"x::y::z::">> = iolist_to_binary(join(re:split("xyz","(abc|)+",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","([a]*)*",[trim]))),
+ 2}]))),
+ <<"x::y::z::">> = iolist_to_binary(join(re:split("xyz","(abc|)+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","([a]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","([a]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","([a]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaa","([a]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","([a]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaa","([a]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaa","([a]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaaaa","([a]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","([ab]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaaaa","([a]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","([ab]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","([ab]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","([ab]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","([ab]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","([ab]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","([ab]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","([ab]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","([ab]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("ababab","([ab]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","([ab]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ababab","([ab]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("ababab","([ab]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ababab","([ab]*)*",[]))),
- <<"::c::d::e">> = iolist_to_binary(join(re:split("aaaabcde","([ab]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ababab","([ab]*)*",[]))),
+ <<"::c::d::e">> = iolist_to_binary(join(re:split("aaaabcde","([ab]*)*",[trim]))),
<<"::cde">> = iolist_to_binary(join(re:split("aaaabcde","([ab]*)*",[{parts,
- 2}]))),
- <<"::c::d::e::">> = iolist_to_binary(join(re:split("aaaabcde","([ab]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("bbbb","([ab]*)*",[trim]))),
+ 2}]))),
+ <<"::c::d::e::">> = iolist_to_binary(join(re:split("aaaabcde","([ab]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bbbb","([ab]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("bbbb","([ab]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("bbbb","([ab]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","([^a]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("bbbb","([ab]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","([^a]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","([^a]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","([^a]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("bbbb","([^a]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","([^a]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bbbb","([^a]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("bbbb","([^a]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("bbbb","([^a]*)*",[]))),
- <<"a::a::a">> = iolist_to_binary(join(re:split("aaa","([^a]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("bbbb","([^a]*)*",[]))),
+ <<"a::a::a">> = iolist_to_binary(join(re:split("aaa","([^a]*)*",[trim]))),
<<"a::aa">> = iolist_to_binary(join(re:split("aaa","([^a]*)*",[{parts,
- 2}]))),
- <<"a::a::a::">> = iolist_to_binary(join(re:split("aaa","([^a]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("cccc","([^ab]*)*",[trim]))),
+ 2}]))),
+ <<"a::a::a::">> = iolist_to_binary(join(re:split("aaa","([^a]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("cccc","([^ab]*)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("cccc","([^ab]*)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("cccc","([^ab]*)*",[]))),
- <<"a::b::a::b">> = iolist_to_binary(join(re:split("abab","([^ab]*)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("cccc","([^ab]*)*",[]))),
+ <<"a::b::a::b">> = iolist_to_binary(join(re:split("abab","([^ab]*)*",[trim]))),
<<"a::bab">> = iolist_to_binary(join(re:split("abab","([^ab]*)*",[{parts,
- 2}]))),
- <<"a::b::a::b::">> = iolist_to_binary(join(re:split("abab","([^ab]*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","([a]*?)*",[trim]))),
+ 2}]))),
+ <<"a::b::a::b::">> = iolist_to_binary(join(re:split("abab","([^ab]*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","([a]*?)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","([a]*?)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","([a]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","([a]*?)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","([a]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","([a]*?)*",[trim]))),
<<"::aaa">> = iolist_to_binary(join(re:split("aaaa","([a]*?)*",[{parts,
- 2}]))),
- <<"::::::::">> = iolist_to_binary(join(re:split("aaaa","([a]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","([ab]*?)*",[trim]))),
+ 2}]))),
+ <<"::::::::">> = iolist_to_binary(join(re:split("aaaa","([a]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","([ab]*?)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","([ab]*?)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","([ab]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","([ab]*?)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","([ab]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","([ab]*?)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","([ab]*?)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","([ab]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("abab","([ab]*?)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","([ab]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abab","([ab]*?)*",[trim]))),
<<"::bab">> = iolist_to_binary(join(re:split("abab","([ab]*?)*",[{parts,
- 2}]))),
- <<"::::::::">> = iolist_to_binary(join(re:split("abab","([ab]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("baba","([ab]*?)*",[trim]))),
+ 2}]))),
+ <<"::::::::">> = iolist_to_binary(join(re:split("abab","([ab]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("baba","([ab]*?)*",[trim]))),
<<"::aba">> = iolist_to_binary(join(re:split("baba","([ab]*?)*",[{parts,
- 2}]))),
- <<"::::::::">> = iolist_to_binary(join(re:split("baba","([ab]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","([^a]*?)*",[trim]))),
+ 2}]))),
+ <<"::::::::">> = iolist_to_binary(join(re:split("baba","([ab]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","([^a]*?)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","([^a]*?)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","([^a]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("bbbb","([^a]*?)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","([^a]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bbbb","([^a]*?)*",[trim]))),
<<"::bbb">> = iolist_to_binary(join(re:split("bbbb","([^a]*?)*",[{parts,
- 2}]))),
- <<"::::::::">> = iolist_to_binary(join(re:split("bbbb","([^a]*?)*",[]))),
- <<"a::a::a">> = iolist_to_binary(join(re:split("aaa","([^a]*?)*",[trim]))),
+ 2}]))),
+ <<"::::::::">> = iolist_to_binary(join(re:split("bbbb","([^a]*?)*",[]))),
+ <<"a::a::a">> = iolist_to_binary(join(re:split("aaa","([^a]*?)*",[trim]))),
<<"a::aa">> = iolist_to_binary(join(re:split("aaa","([^a]*?)*",[{parts,
- 2}]))),
- <<"a::a::a::">> = iolist_to_binary(join(re:split("aaa","([^a]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("c","([^ab]*?)*",[trim]))),
+ 2}]))),
+ <<"a::a::a::">> = iolist_to_binary(join(re:split("aaa","([^a]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("c","([^ab]*?)*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("c","([^ab]*?)*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("c","([^ab]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("cccc","([^ab]*?)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("c","([^ab]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("cccc","([^ab]*?)*",[trim]))),
<<"::ccc">> = iolist_to_binary(join(re:split("cccc","([^ab]*?)*",[{parts,
- 2}]))),
- <<"::::::::">> = iolist_to_binary(join(re:split("cccc","([^ab]*?)*",[]))),
- <<"b::a::b::a">> = iolist_to_binary(join(re:split("baba","([^ab]*?)*",[trim]))),
+ 2}]))),
+ <<"::::::::">> = iolist_to_binary(join(re:split("cccc","([^ab]*?)*",[]))),
+ <<"b::a::b::a">> = iolist_to_binary(join(re:split("baba","([^ab]*?)*",[trim]))),
<<"b::aba">> = iolist_to_binary(join(re:split("baba","([^ab]*?)*",[{parts,
- 2}]))),
- <<"b::a::b::a::">> = iolist_to_binary(join(re:split("baba","([^ab]*?)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","(?>a*)*",[trim]))),
+ 2}]))),
+ <<"b::a::b::a::">> = iolist_to_binary(join(re:split("baba","([^ab]*?)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","(?>a*)*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","(?>a*)*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","(?>a*)*",[]))),
- <<":b:c:d:e">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","(?>a*)*",[]))),
+ <<":b:c:d:e">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[trim]))),
<<":bcde">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[{parts,
- 2}]))),
- <<":b:c:d:e:">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[]))),
+ 2}]))),
+ <<":b:c:d:e:">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[]))),
ok.
run14() ->
- <<"">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[]))),
- <<"::b::b">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[]))),
+ <<"::b::b">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[trim]))),
<<"::bbaa">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[{parts,
- 2}]))),
- <<"::b::b::">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[]))),
- <<"a::a::a::a::a">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[trim]))),
+ 2}]))),
+ <<"::b::b::">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[]))),
+ <<"a::a::a::a::a">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[trim]))),
<<"a::aaaa">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[{parts,
- 2}]))),
- <<"a::a::a::a::a::">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[]))),
- <<"a::a::b::b::a::a">> = iolist_to_binary(join(re:split("aabbaa","((?>a*?))*",[trim]))),
+ 2}]))),
+ <<"a::a::a::a::a::">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[]))),
+ <<"a::a::b::b::a::a">> = iolist_to_binary(join(re:split("aabbaa","((?>a*?))*",[trim]))),
<<"a::abbaa">> = iolist_to_binary(join(re:split("aabbaa","((?>a*?))*",[{parts,
- 2}]))),
- <<"a::a::b::b::a::a::">> = iolist_to_binary(join(re:split("aabbaa","((?>a*?))*",[]))),
+ 2}]))),
+ <<"a::a::b::b::a::a::">> = iolist_to_binary(join(re:split("aabbaa","((?>a*?))*",[]))),
<<"">> = iolist_to_binary(join(re:split("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
<<"">> = iolist_to_binary(join(re:split("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
<<"sep-12-98">> = iolist_to_binary(join(re:split("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
- trim]))),
+ trim]))),
<<"sep-12-98">> = iolist_to_binary(join(re:split("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended,
{parts,
- 2}]))),
- <<"sep-12-98">> = iolist_to_binary(join(re:split("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
- <<"foo:foo">> = iolist_to_binary(join(re:split("foobarfoo","(?<=(foo))bar\\1",[trim]))),
+ 2}]))),
+ <<"sep-12-98">> = iolist_to_binary(join(re:split("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ",[extended]))),
+ <<"foo:foo">> = iolist_to_binary(join(re:split("foobarfoo","(?<=(foo))bar\\1",[trim]))),
<<"foo:foo:">> = iolist_to_binary(join(re:split("foobarfoo","(?<=(foo))bar\\1",[{parts,
- 2}]))),
- <<"foo:foo:">> = iolist_to_binary(join(re:split("foobarfoo","(?<=(foo))bar\\1",[]))),
- <<"foo:foo:tling">> = iolist_to_binary(join(re:split("foobarfootling","(?<=(foo))bar\\1",[trim]))),
+ 2}]))),
+ <<"foo:foo:">> = iolist_to_binary(join(re:split("foobarfoo","(?<=(foo))bar\\1",[]))),
+ <<"foo:foo:tling">> = iolist_to_binary(join(re:split("foobarfootling","(?<=(foo))bar\\1",[trim]))),
<<"foo:foo:tling">> = iolist_to_binary(join(re:split("foobarfootling","(?<=(foo))bar\\1",[{parts,
- 2}]))),
- <<"foo:foo:tling">> = iolist_to_binary(join(re:split("foobarfootling","(?<=(foo))bar\\1",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo))bar\\1",[trim]))),
+ 2}]))),
+ <<"foo:foo:tling">> = iolist_to_binary(join(re:split("foobarfootling","(?<=(foo))bar\\1",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo))bar\\1",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo))bar\\1",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo))bar\\1",[]))),
- <<"foobar">> = iolist_to_binary(join(re:split("foobar","(?<=(foo))bar\\1",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(foo))bar\\1",[]))),
+ <<"foobar">> = iolist_to_binary(join(re:split("foobar","(?<=(foo))bar\\1",[trim]))),
<<"foobar">> = iolist_to_binary(join(re:split("foobar","(?<=(foo))bar\\1",[{parts,
- 2}]))),
- <<"foobar">> = iolist_to_binary(join(re:split("foobar","(?<=(foo))bar\\1",[]))),
- <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<=(foo))bar\\1",[trim]))),
+ 2}]))),
+ <<"foobar">> = iolist_to_binary(join(re:split("foobar","(?<=(foo))bar\\1",[]))),
+ <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<=(foo))bar\\1",[trim]))),
<<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<=(foo))bar\\1",[{parts,
- 2}]))),
- <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<=(foo))bar\\1",[]))),
- <<"">> = iolist_to_binary(join(re:split("saturday","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<"barfoo">> = iolist_to_binary(join(re:split("barfoo","(?<=(foo))bar\\1",[]))),
+ <<"">> = iolist_to_binary(join(re:split("saturday","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("saturday","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("saturday","(?i:saturday|sunday)",[]))),
- <<"">> = iolist_to_binary(join(re:split("sunday","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("saturday","(?i:saturday|sunday)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("sunday","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("sunday","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("sunday","(?i:saturday|sunday)",[]))),
- <<"">> = iolist_to_binary(join(re:split("Saturday","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("sunday","(?i:saturday|sunday)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("Saturday","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("Saturday","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("Saturday","(?i:saturday|sunday)",[]))),
- <<"">> = iolist_to_binary(join(re:split("Sunday","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("Saturday","(?i:saturday|sunday)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("Sunday","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("Sunday","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("Sunday","(?i:saturday|sunday)",[]))),
- <<"">> = iolist_to_binary(join(re:split("SATURDAY","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("Sunday","(?i:saturday|sunday)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("SATURDAY","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("SATURDAY","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("SATURDAY","(?i:saturday|sunday)",[]))),
- <<"">> = iolist_to_binary(join(re:split("SUNDAY","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("SATURDAY","(?i:saturday|sunday)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("SUNDAY","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("SUNDAY","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("SUNDAY","(?i:saturday|sunday)",[]))),
- <<"">> = iolist_to_binary(join(re:split("SunDay","(?i:saturday|sunday)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("SUNDAY","(?i:saturday|sunday)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("SunDay","(?i:saturday|sunday)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("SunDay","(?i:saturday|sunday)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("SunDay","(?i:saturday|sunday)",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcx","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("SunDay","(?i:saturday|sunday)",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcx","(a(?i)bc|BB)x",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcx","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcx","(a(?i)bc|BB)x",[]))),
- <<":aBC">> = iolist_to_binary(join(re:split("aBCx","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcx","(a(?i)bc|BB)x",[]))),
+ <<":aBC">> = iolist_to_binary(join(re:split("aBCx","(a(?i)bc|BB)x",[trim]))),
<<":aBC:">> = iolist_to_binary(join(re:split("aBCx","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<":aBC:">> = iolist_to_binary(join(re:split("aBCx","(a(?i)bc|BB)x",[]))),
- <<":bb">> = iolist_to_binary(join(re:split("bbx","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<":aBC:">> = iolist_to_binary(join(re:split("aBCx","(a(?i)bc|BB)x",[]))),
+ <<":bb">> = iolist_to_binary(join(re:split("bbx","(a(?i)bc|BB)x",[trim]))),
<<":bb:">> = iolist_to_binary(join(re:split("bbx","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<":bb:">> = iolist_to_binary(join(re:split("bbx","(a(?i)bc|BB)x",[]))),
- <<":BB">> = iolist_to_binary(join(re:split("BBx","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<":bb:">> = iolist_to_binary(join(re:split("bbx","(a(?i)bc|BB)x",[]))),
+ <<":BB">> = iolist_to_binary(join(re:split("BBx","(a(?i)bc|BB)x",[trim]))),
<<":BB:">> = iolist_to_binary(join(re:split("BBx","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<":BB:">> = iolist_to_binary(join(re:split("BBx","(a(?i)bc|BB)x",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<":BB:">> = iolist_to_binary(join(re:split("BBx","(a(?i)bc|BB)x",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)bc|BB)x",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)bc|BB)x",[]))),
- <<"abcX">> = iolist_to_binary(join(re:split("abcX","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(a(?i)bc|BB)x",[]))),
+ <<"abcX">> = iolist_to_binary(join(re:split("abcX","(a(?i)bc|BB)x",[trim]))),
<<"abcX">> = iolist_to_binary(join(re:split("abcX","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<"abcX">> = iolist_to_binary(join(re:split("abcX","(a(?i)bc|BB)x",[]))),
- <<"aBCX">> = iolist_to_binary(join(re:split("aBCX","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<"abcX">> = iolist_to_binary(join(re:split("abcX","(a(?i)bc|BB)x",[]))),
+ <<"aBCX">> = iolist_to_binary(join(re:split("aBCX","(a(?i)bc|BB)x",[trim]))),
<<"aBCX">> = iolist_to_binary(join(re:split("aBCX","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<"aBCX">> = iolist_to_binary(join(re:split("aBCX","(a(?i)bc|BB)x",[]))),
- <<"bbX">> = iolist_to_binary(join(re:split("bbX","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<"aBCX">> = iolist_to_binary(join(re:split("aBCX","(a(?i)bc|BB)x",[]))),
+ <<"bbX">> = iolist_to_binary(join(re:split("bbX","(a(?i)bc|BB)x",[trim]))),
<<"bbX">> = iolist_to_binary(join(re:split("bbX","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<"bbX">> = iolist_to_binary(join(re:split("bbX","(a(?i)bc|BB)x",[]))),
- <<"BBX">> = iolist_to_binary(join(re:split("BBX","(a(?i)bc|BB)x",[trim]))),
+ 2}]))),
+ <<"bbX">> = iolist_to_binary(join(re:split("bbX","(a(?i)bc|BB)x",[]))),
+ <<"BBX">> = iolist_to_binary(join(re:split("BBX","(a(?i)bc|BB)x",[trim]))),
<<"BBX">> = iolist_to_binary(join(re:split("BBX","(a(?i)bc|BB)x",[{parts,
- 2}]))),
- <<"BBX">> = iolist_to_binary(join(re:split("BBX","(a(?i)bc|BB)x",[]))),
- <<":ac">> = iolist_to_binary(join(re:split("ac","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<"BBX">> = iolist_to_binary(join(re:split("BBX","(a(?i)bc|BB)x",[]))),
+ <<":ac">> = iolist_to_binary(join(re:split("ac","^([ab](?i)[cd]|[ef])",[trim]))),
<<":ac:">> = iolist_to_binary(join(re:split("ac","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":ac:">> = iolist_to_binary(join(re:split("ac","^([ab](?i)[cd]|[ef])",[]))),
- <<":aC">> = iolist_to_binary(join(re:split("aC","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":ac:">> = iolist_to_binary(join(re:split("ac","^([ab](?i)[cd]|[ef])",[]))),
+ <<":aC">> = iolist_to_binary(join(re:split("aC","^([ab](?i)[cd]|[ef])",[trim]))),
<<":aC:">> = iolist_to_binary(join(re:split("aC","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":aC:">> = iolist_to_binary(join(re:split("aC","^([ab](?i)[cd]|[ef])",[]))),
- <<":bD">> = iolist_to_binary(join(re:split("bD","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":aC:">> = iolist_to_binary(join(re:split("aC","^([ab](?i)[cd]|[ef])",[]))),
+ <<":bD">> = iolist_to_binary(join(re:split("bD","^([ab](?i)[cd]|[ef])",[trim]))),
<<":bD:">> = iolist_to_binary(join(re:split("bD","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":bD:">> = iolist_to_binary(join(re:split("bD","^([ab](?i)[cd]|[ef])",[]))),
- <<":e:lephant">> = iolist_to_binary(join(re:split("elephant","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":bD:">> = iolist_to_binary(join(re:split("bD","^([ab](?i)[cd]|[ef])",[]))),
+ <<":e:lephant">> = iolist_to_binary(join(re:split("elephant","^([ab](?i)[cd]|[ef])",[trim]))),
<<":e:lephant">> = iolist_to_binary(join(re:split("elephant","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":e:lephant">> = iolist_to_binary(join(re:split("elephant","^([ab](?i)[cd]|[ef])",[]))),
- <<":E:urope">> = iolist_to_binary(join(re:split("Europe","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":e:lephant">> = iolist_to_binary(join(re:split("elephant","^([ab](?i)[cd]|[ef])",[]))),
+ <<":E:urope">> = iolist_to_binary(join(re:split("Europe","^([ab](?i)[cd]|[ef])",[trim]))),
<<":E:urope">> = iolist_to_binary(join(re:split("Europe","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":E:urope">> = iolist_to_binary(join(re:split("Europe","^([ab](?i)[cd]|[ef])",[]))),
- <<":f:rog">> = iolist_to_binary(join(re:split("frog","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":E:urope">> = iolist_to_binary(join(re:split("Europe","^([ab](?i)[cd]|[ef])",[]))),
+ <<":f:rog">> = iolist_to_binary(join(re:split("frog","^([ab](?i)[cd]|[ef])",[trim]))),
<<":f:rog">> = iolist_to_binary(join(re:split("frog","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":f:rog">> = iolist_to_binary(join(re:split("frog","^([ab](?i)[cd]|[ef])",[]))),
- <<":F:rance">> = iolist_to_binary(join(re:split("France","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":f:rog">> = iolist_to_binary(join(re:split("frog","^([ab](?i)[cd]|[ef])",[]))),
+ <<":F:rance">> = iolist_to_binary(join(re:split("France","^([ab](?i)[cd]|[ef])",[trim]))),
<<":F:rance">> = iolist_to_binary(join(re:split("France","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<":F:rance">> = iolist_to_binary(join(re:split("France","^([ab](?i)[cd]|[ef])",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<":F:rance">> = iolist_to_binary(join(re:split("France","^([ab](?i)[cd]|[ef])",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([ab](?i)[cd]|[ef])",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([ab](?i)[cd]|[ef])",[]))),
- <<"Africa">> = iolist_to_binary(join(re:split("Africa","^([ab](?i)[cd]|[ef])",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^([ab](?i)[cd]|[ef])",[]))),
+ <<"Africa">> = iolist_to_binary(join(re:split("Africa","^([ab](?i)[cd]|[ef])",[trim]))),
<<"Africa">> = iolist_to_binary(join(re:split("Africa","^([ab](?i)[cd]|[ef])",[{parts,
- 2}]))),
- <<"Africa">> = iolist_to_binary(join(re:split("Africa","^([ab](?i)[cd]|[ef])",[]))),
- <<":ab">> = iolist_to_binary(join(re:split("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<"Africa">> = iolist_to_binary(join(re:split("Africa","^([ab](?i)[cd]|[ef])",[]))),
+ <<":ab">> = iolist_to_binary(join(re:split("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<":aBd">> = iolist_to_binary(join(re:split("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<":aBd">> = iolist_to_binary(join(re:split("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<":aBd:">> = iolist_to_binary(join(re:split("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<":aBd:">> = iolist_to_binary(join(re:split("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<":xy">> = iolist_to_binary(join(re:split("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<":aBd:">> = iolist_to_binary(join(re:split("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<":xy">> = iolist_to_binary(join(re:split("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<":xy:">> = iolist_to_binary(join(re:split("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<":xy:">> = iolist_to_binary(join(re:split("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<":xY">> = iolist_to_binary(join(re:split("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<":xy:">> = iolist_to_binary(join(re:split("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<":xY">> = iolist_to_binary(join(re:split("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<":xY:">> = iolist_to_binary(join(re:split("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<":xY:">> = iolist_to_binary(join(re:split("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<":z:ebra">> = iolist_to_binary(join(re:split("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<":xY:">> = iolist_to_binary(join(re:split("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<":z:ebra">> = iolist_to_binary(join(re:split("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<":z:ebra">> = iolist_to_binary(join(re:split("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<":z:ebra">> = iolist_to_binary(join(re:split("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<":Z:ambesi">> = iolist_to_binary(join(re:split("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<":z:ebra">> = iolist_to_binary(join(re:split("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<":Z:ambesi">> = iolist_to_binary(join(re:split("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<":Z:ambesi">> = iolist_to_binary(join(re:split("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<":Z:ambesi">> = iolist_to_binary(join(re:split("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<":Z:ambesi">> = iolist_to_binary(join(re:split("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<"aCD">> = iolist_to_binary(join(re:split("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<"aCD">> = iolist_to_binary(join(re:split("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<"aCD">> = iolist_to_binary(join(re:split("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<"aCD">> = iolist_to_binary(join(re:split("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
- <<"XY">> = iolist_to_binary(join(re:split("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
+ 2}]))),
+ <<"aCD">> = iolist_to_binary(join(re:split("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ <<"XY">> = iolist_to_binary(join(re:split("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[trim]))),
<<"XY">> = iolist_to_binary(join(re:split("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[{parts,
- 2}]))),
- <<"XY">> = iolist_to_binary(join(re:split("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
+ 2}]))),
+ <<"XY">> = iolist_to_binary(join(re:split("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)",[]))),
<<"foo
">> = iolist_to_binary(join(re:split("foo
-bar","(?<=foo\\n)^bar",[multiline,trim]))),
+bar","(?<=foo\\n)^bar",[multiline,trim]))),
<<"foo
:">> = iolist_to_binary(join(re:split("foo
-bar","(?<=foo\\n)^bar",[multiline,{parts,2}]))),
+bar","(?<=foo\\n)^bar",[multiline,{parts,2}]))),
<<"foo
:">> = iolist_to_binary(join(re:split("foo
-bar","(?<=foo\\n)^bar",[multiline]))),
+bar","(?<=foo\\n)^bar",[multiline]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=foo\\n)^bar",[multiline,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=foo\\n)^bar",[multiline,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=foo\\n)^bar",[multiline]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=foo\\n)^bar",[multiline]))),
<<"bar">> = iolist_to_binary(join(re:split("bar","(?<=foo\\n)^bar",[multiline,
- trim]))),
+ trim]))),
<<"bar">> = iolist_to_binary(join(re:split("bar","(?<=foo\\n)^bar",[multiline,
{parts,
- 2}]))),
- <<"bar">> = iolist_to_binary(join(re:split("bar","(?<=foo\\n)^bar",[multiline]))),
+ 2}]))),
+ <<"bar">> = iolist_to_binary(join(re:split("bar","(?<=foo\\n)^bar",[multiline]))),
<<"baz
bar">> = iolist_to_binary(join(re:split("baz
-bar","(?<=foo\\n)^bar",[multiline,trim]))),
+bar","(?<=foo\\n)^bar",[multiline,trim]))),
<<"baz
bar">> = iolist_to_binary(join(re:split("baz
-bar","(?<=foo\\n)^bar",[multiline,{parts,2}]))),
+bar","(?<=foo\\n)^bar",[multiline,{parts,2}]))),
<<"baz
bar">> = iolist_to_binary(join(re:split("baz
-bar","(?<=foo\\n)^bar",[multiline]))),
- <<"bar">> = iolist_to_binary(join(re:split("barbaz","(?<=(?<!foo)bar)baz",[trim]))),
+bar","(?<=foo\\n)^bar",[multiline]))),
+ <<"bar">> = iolist_to_binary(join(re:split("barbaz","(?<=(?<!foo)bar)baz",[trim]))),
<<"bar:">> = iolist_to_binary(join(re:split("barbaz","(?<=(?<!foo)bar)baz",[{parts,
- 2}]))),
- <<"bar:">> = iolist_to_binary(join(re:split("barbaz","(?<=(?<!foo)bar)baz",[]))),
- <<"barbar">> = iolist_to_binary(join(re:split("barbarbaz","(?<=(?<!foo)bar)baz",[trim]))),
+ 2}]))),
+ <<"bar:">> = iolist_to_binary(join(re:split("barbaz","(?<=(?<!foo)bar)baz",[]))),
+ <<"barbar">> = iolist_to_binary(join(re:split("barbarbaz","(?<=(?<!foo)bar)baz",[trim]))),
<<"barbar:">> = iolist_to_binary(join(re:split("barbarbaz","(?<=(?<!foo)bar)baz",[{parts,
- 2}]))),
- <<"barbar:">> = iolist_to_binary(join(re:split("barbarbaz","(?<=(?<!foo)bar)baz",[]))),
- <<"koobar">> = iolist_to_binary(join(re:split("koobarbaz","(?<=(?<!foo)bar)baz",[trim]))),
+ 2}]))),
+ <<"barbar:">> = iolist_to_binary(join(re:split("barbarbaz","(?<=(?<!foo)bar)baz",[]))),
+ <<"koobar">> = iolist_to_binary(join(re:split("koobarbaz","(?<=(?<!foo)bar)baz",[trim]))),
<<"koobar:">> = iolist_to_binary(join(re:split("koobarbaz","(?<=(?<!foo)bar)baz",[{parts,
- 2}]))),
- <<"koobar:">> = iolist_to_binary(join(re:split("koobarbaz","(?<=(?<!foo)bar)baz",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?<!foo)bar)baz",[trim]))),
+ 2}]))),
+ <<"koobar:">> = iolist_to_binary(join(re:split("koobarbaz","(?<=(?<!foo)bar)baz",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?<!foo)bar)baz",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?<!foo)bar)baz",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?<!foo)bar)baz",[]))),
- <<"baz">> = iolist_to_binary(join(re:split("baz","(?<=(?<!foo)bar)baz",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?<!foo)bar)baz",[]))),
+ <<"baz">> = iolist_to_binary(join(re:split("baz","(?<=(?<!foo)bar)baz",[trim]))),
<<"baz">> = iolist_to_binary(join(re:split("baz","(?<=(?<!foo)bar)baz",[{parts,
- 2}]))),
- <<"baz">> = iolist_to_binary(join(re:split("baz","(?<=(?<!foo)bar)baz",[]))),
- <<"foobarbaz">> = iolist_to_binary(join(re:split("foobarbaz","(?<=(?<!foo)bar)baz",[trim]))),
+ 2}]))),
+ <<"baz">> = iolist_to_binary(join(re:split("baz","(?<=(?<!foo)bar)baz",[]))),
+ <<"foobarbaz">> = iolist_to_binary(join(re:split("foobarbaz","(?<=(?<!foo)bar)baz",[trim]))),
<<"foobarbaz">> = iolist_to_binary(join(re:split("foobarbaz","(?<=(?<!foo)bar)baz",[{parts,
- 2}]))),
- <<"foobarbaz">> = iolist_to_binary(join(re:split("foobarbaz","(?<=(?<!foo)bar)baz",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"foobarbaz">> = iolist_to_binary(join(re:split("foobarbaz","(?<=(?<!foo)bar)baz",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?){4}$",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?){4}$",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?){4}$",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?){4}$",[trim]))),
<<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?){4}$",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?){4}$",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?){4}$",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?){4}$",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?){4}$",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?){4}$",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?){4}$",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?){4}$",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?){4}$",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[]))),
- <<":aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<":aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<":a:a:a:a">> = iolist_to_binary(join(re:split("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<":a:a:a:a">> = iolist_to_binary(join(re:split("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<":a:a:a:a:">> = iolist_to_binary(join(re:split("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<":a:a:a:a:">> = iolist_to_binary(join(re:split("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<":a:aa:a:a">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<":a:a:a:a:">> = iolist_to_binary(join(re:split("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<":a:aa:a:a">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<":a:aa:a:a:">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<":a:aa:a:a:">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<":a:aa:a:aa">> = iolist_to_binary(join(re:split("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<":a:aa:a:a:">> = iolist_to_binary(join(re:split("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<":a:aa:a:aa">> = iolist_to_binary(join(re:split("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<":a:aa:a:aa:">> = iolist_to_binary(join(re:split("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<":a:aa:a:aa:">> = iolist_to_binary(join(re:split("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<":a:aa:aaa:a">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<":a:aa:a:aa:">> = iolist_to_binary(join(re:split("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<":a:aa:aaa:a">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<":a:aa:aaa:a:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<":a:aa:aaa:a:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<":a:aa:aaa:a:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<":a:aa:aaa:aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<":a:aa:aaa:aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<":a:aa:aaa:aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<":a:aa:aaa:aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<":a:aa:aaa:aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[trim]))),
<<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","abc",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","abc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","abc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","abc",[]))),
- <<"x:y">> = iolist_to_binary(join(re:split("xabcy","abc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","abc",[]))),
+ <<"x:y">> = iolist_to_binary(join(re:split("xabcy","abc",[trim]))),
<<"x:y">> = iolist_to_binary(join(re:split("xabcy","abc",[{parts,
- 2}]))),
- <<"x:y">> = iolist_to_binary(join(re:split("xabcy","abc",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ababc","abc",[trim]))),
+ 2}]))),
+ <<"x:y">> = iolist_to_binary(join(re:split("xabcy","abc",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ababc","abc",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("ababc","abc",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("ababc","abc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("ababc","abc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[]))),
- <<"xbc">> = iolist_to_binary(join(re:split("xbc","abc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[]))),
+ <<"xbc">> = iolist_to_binary(join(re:split("xbc","abc",[trim]))),
<<"xbc">> = iolist_to_binary(join(re:split("xbc","abc",[{parts,
- 2}]))),
- <<"xbc">> = iolist_to_binary(join(re:split("xbc","abc",[]))),
- <<"axc">> = iolist_to_binary(join(re:split("axc","abc",[trim]))),
+ 2}]))),
+ <<"xbc">> = iolist_to_binary(join(re:split("xbc","abc",[]))),
+ <<"axc">> = iolist_to_binary(join(re:split("axc","abc",[trim]))),
<<"axc">> = iolist_to_binary(join(re:split("axc","abc",[{parts,
- 2}]))),
- <<"axc">> = iolist_to_binary(join(re:split("axc","abc",[]))),
- <<"abx">> = iolist_to_binary(join(re:split("abx","abc",[trim]))),
+ 2}]))),
+ <<"axc">> = iolist_to_binary(join(re:split("axc","abc",[]))),
+ <<"abx">> = iolist_to_binary(join(re:split("abx","abc",[trim]))),
<<"abx">> = iolist_to_binary(join(re:split("abx","abc",[{parts,
- 2}]))),
- <<"abx">> = iolist_to_binary(join(re:split("abx","abc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","ab*c",[trim]))),
+ 2}]))),
+ <<"abx">> = iolist_to_binary(join(re:split("abx","abc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","ab*c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","ab*c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","ab*c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","ab*bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","ab*c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","ab*bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","ab*bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","ab*bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbc","ab*bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","ab*bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbc","ab*bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbc","ab*bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbc","ab*bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab*bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbc","ab*bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab*bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab*bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab*bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc",".{1}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab*bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc",".{1}",[trim]))),
<<":bbbbc">> = iolist_to_binary(join(re:split("abbbbc",".{1}",[{parts,
- 2}]))),
- <<"::::::">> = iolist_to_binary(join(re:split("abbbbc",".{1}",[]))),
- <<":bc">> = iolist_to_binary(join(re:split("abbbbc",".{3,4}",[trim]))),
+ 2}]))),
+ <<"::::::">> = iolist_to_binary(join(re:split("abbbbc",".{1}",[]))),
+ <<":bc">> = iolist_to_binary(join(re:split("abbbbc",".{3,4}",[trim]))),
<<":bc">> = iolist_to_binary(join(re:split("abbbbc",".{3,4}",[{parts,
- 2}]))),
- <<":bc">> = iolist_to_binary(join(re:split("abbbbc",".{3,4}",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{0,}bc",[trim]))),
+ 2}]))),
+ <<":bc">> = iolist_to_binary(join(re:split("abbbbc",".{3,4}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{0,}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab{0,}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{0,}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbc","ab+bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{0,}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbc","ab+bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbc","ab+bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbc","ab+bc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbc","ab+bc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","ab+bc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","ab+bc",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","ab+bc",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","ab+bc",[]))),
- <<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","ab+bc",[]))),
+ <<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[trim]))),
<<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[{parts,
- 2}]))),
- <<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[]))),
+ 2}]))),
+ <<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[]))),
ok.
run15() ->
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{3,4}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,3}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbbbc","ab{3,4}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab{3,4}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{3,4}bc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbbbc","ab{3,4}bc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}bc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}bc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}bc",[]))),
- <<"abq">> = iolist_to_binary(join(re:split("abq","ab{4,5}bc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}bc",[]))),
+ <<"abq">> = iolist_to_binary(join(re:split("abq","ab{4,5}bc",[trim]))),
<<"abq">> = iolist_to_binary(join(re:split("abq","ab{4,5}bc",[{parts,
- 2}]))),
- <<"abq">> = iolist_to_binary(join(re:split("abq","ab{4,5}bc",[]))),
- <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","ab{4,5}bc",[trim]))),
+ 2}]))),
+ <<"abq">> = iolist_to_binary(join(re:split("abq","ab{4,5}bc",[]))),
+ <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","ab{4,5}bc",[trim]))),
<<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","ab{4,5}bc",[{parts,
- 2}]))),
- <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","ab{4,5}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abbc","ab?bc",[trim]))),
+ 2}]))),
+ <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","ab{4,5}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abbc","ab?bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbc","ab?bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abbc","ab?bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","ab?bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abbc","ab?bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","ab?bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","ab?bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","ab?bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","ab{0,1}bc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","ab?bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","ab{0,1}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","ab{0,1}bc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","ab{0,1}bc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","ab?c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","ab{0,1}bc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","ab?c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","ab?c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","ab?c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","ab{0,1}c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","ab?c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","ab{0,1}c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","ab{0,1}c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","ab{0,1}c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","^abc$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","ab{0,1}c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","^abc$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^abc$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","^abc$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","^abc$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[]))),
- <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","^abc$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[]))),
+ <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","^abc$",[trim]))),
<<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","^abc$",[{parts,
- 2}]))),
- <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","^abc$",[]))),
- <<"abcc">> = iolist_to_binary(join(re:split("abcc","^abc$",[trim]))),
+ 2}]))),
+ <<"abbbbc">> = iolist_to_binary(join(re:split("abbbbc","^abc$",[]))),
+ <<"abcc">> = iolist_to_binary(join(re:split("abcc","^abc$",[trim]))),
<<"abcc">> = iolist_to_binary(join(re:split("abcc","^abc$",[{parts,
- 2}]))),
- <<"abcc">> = iolist_to_binary(join(re:split("abcc","^abc$",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abcc","^abc",[trim]))),
+ 2}]))),
+ <<"abcc">> = iolist_to_binary(join(re:split("abcc","^abc$",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abcc","^abc",[trim]))),
<<":c">> = iolist_to_binary(join(re:split("abcc","^abc",[{parts,
- 2}]))),
- <<":c">> = iolist_to_binary(join(re:split("abcc","^abc",[]))),
- <<"a">> = iolist_to_binary(join(re:split("aabc","abc$",[trim]))),
+ 2}]))),
+ <<":c">> = iolist_to_binary(join(re:split("abcc","^abc",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("aabc","abc$",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aabc","abc$",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aabc","abc$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aabc","abc$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[]))),
- <<"a">> = iolist_to_binary(join(re:split("aabc","abc$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc$",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("aabc","abc$",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aabc","abc$",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aabc","abc$",[]))),
- <<"aabcd">> = iolist_to_binary(join(re:split("aabcd","abc$",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aabc","abc$",[]))),
+ <<"aabcd">> = iolist_to_binary(join(re:split("aabcd","abc$",[trim]))),
<<"aabcd">> = iolist_to_binary(join(re:split("aabcd","abc$",[{parts,
- 2}]))),
- <<"aabcd">> = iolist_to_binary(join(re:split("aabcd","abc$",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^",[trim]))),
+ 2}]))),
+ <<"aabcd">> = iolist_to_binary(join(re:split("aabcd","abc$",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","$",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","$",[trim]))),
<<"abc:">> = iolist_to_binary(join(re:split("abc","$",[{parts,
- 2}]))),
- <<"abc:">> = iolist_to_binary(join(re:split("abc","$",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","a.c",[trim]))),
+ 2}]))),
+ <<"abc:">> = iolist_to_binary(join(re:split("abc","$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","a.c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","a.c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","a.c",[]))),
- <<"">> = iolist_to_binary(join(re:split("axc","a.c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","a.c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("axc","a.c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("axc","a.c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("axc","a.c",[]))),
- <<"">> = iolist_to_binary(join(re:split("axyzc","a.*c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("axc","a.c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("axyzc","a.*c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("axyzc","a.*c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("axyzc","a.*c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abd","a[bc]d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("axyzc","a.*c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abd","a[bc]d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abd","a[bc]d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abd","a[bc]d",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bc]d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abd","a[bc]d",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bc]d",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bc]d",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bc]d",[]))),
- <<"axyzd">> = iolist_to_binary(join(re:split("axyzd","a[bc]d",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bc]d",[]))),
+ <<"axyzd">> = iolist_to_binary(join(re:split("axyzd","a[bc]d",[trim]))),
<<"axyzd">> = iolist_to_binary(join(re:split("axyzd","a[bc]d",[{parts,
- 2}]))),
- <<"axyzd">> = iolist_to_binary(join(re:split("axyzd","a[bc]d",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","a[bc]d",[trim]))),
+ 2}]))),
+ <<"axyzd">> = iolist_to_binary(join(re:split("axyzd","a[bc]d",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","a[bc]d",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","a[bc]d",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","a[bc]d",[]))),
- <<"">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","a[bc]d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[]))),
ok.
run16() ->
- <<"a">> = iolist_to_binary(join(re:split("aac","a[b-d]",[trim]))),
+ <<"a">> = iolist_to_binary(join(re:split("aac","a[b-d]",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aac","a[b-d]",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aac","a[b-d]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-","a[-b]",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aac","a[b-d]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-","a[-b]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-","a[-b]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-","a[-b]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-","a[b-]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-","a[-b]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-","a[b-]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-","a[b-]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-","a[b-]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a]","a]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-","a[b-]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a]","a]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a]","a]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a]","a]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a]b","a[]]b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a]","a]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a]b","a[]]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a]b","a[]]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a]b","a[]]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("aed","a[^bc]d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a]b","a[]]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aed","a[^bc]d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aed","a[^bc]d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aed","a[^bc]d",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^bc]d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aed","a[^bc]d",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^bc]d",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^bc]d",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^bc]d",[]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^bc]d",[]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[trim]))),
<<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[{parts,
- 2}]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[trim]))),
+ 2}]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[trim]))),
<<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[{parts,
- 2}]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[]))),
- <<"">> = iolist_to_binary(join(re:split("adc","a[^-b]c",[trim]))),
+ 2}]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","a[^bc]d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("adc","a[^-b]c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("adc","a[^-b]c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("adc","a[^-b]c",[]))),
- <<"">> = iolist_to_binary(join(re:split("adc","a[^]b]c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("adc","a[^-b]c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("adc","a[^]b]c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("adc","a[^]b]c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("adc","a[^]b]c",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^]b]c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("adc","a[^]b]c",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^]b]c",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^]b]c",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^]b]c",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-c","a[^]b]c",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^]b]c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-c","a[^]b]c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-c","a[^]b]c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-c","a[^]b]c",[]))),
- <<"a]c">> = iolist_to_binary(join(re:split("a]c","a[^]b]c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-c","a[^]b]c",[]))),
+ <<"a]c">> = iolist_to_binary(join(re:split("a]c","a[^]b]c",[trim]))),
<<"a]c">> = iolist_to_binary(join(re:split("a]c","a[^]b]c",[{parts,
- 2}]))),
- <<"a]c">> = iolist_to_binary(join(re:split("a]c","a[^]b]c",[]))),
- <<":-">> = iolist_to_binary(join(re:split("a-","\\ba\\b",[trim]))),
+ 2}]))),
+ <<"a]c">> = iolist_to_binary(join(re:split("a]c","a[^]b]c",[]))),
+ <<":-">> = iolist_to_binary(join(re:split("a-","\\ba\\b",[trim]))),
<<":-">> = iolist_to_binary(join(re:split("a-","\\ba\\b",[{parts,
- 2}]))),
- <<":-">> = iolist_to_binary(join(re:split("a-","\\ba\\b",[]))),
- <<"-">> = iolist_to_binary(join(re:split("-a","\\ba\\b",[trim]))),
+ 2}]))),
+ <<":-">> = iolist_to_binary(join(re:split("a-","\\ba\\b",[]))),
+ <<"-">> = iolist_to_binary(join(re:split("-a","\\ba\\b",[trim]))),
<<"-:">> = iolist_to_binary(join(re:split("-a","\\ba\\b",[{parts,
- 2}]))),
- <<"-:">> = iolist_to_binary(join(re:split("-a","\\ba\\b",[]))),
- <<"-:-">> = iolist_to_binary(join(re:split("-a-","\\ba\\b",[trim]))),
+ 2}]))),
+ <<"-:">> = iolist_to_binary(join(re:split("-a","\\ba\\b",[]))),
+ <<"-:-">> = iolist_to_binary(join(re:split("-a-","\\ba\\b",[trim]))),
<<"-:-">> = iolist_to_binary(join(re:split("-a-","\\ba\\b",[{parts,
- 2}]))),
- <<"-:-">> = iolist_to_binary(join(re:split("-a-","\\ba\\b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\by\\b",[trim]))),
+ 2}]))),
+ <<"-:-">> = iolist_to_binary(join(re:split("-a-","\\ba\\b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\by\\b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\by\\b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\by\\b",[]))),
- <<"xy">> = iolist_to_binary(join(re:split("xy","\\by\\b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\by\\b",[]))),
+ <<"xy">> = iolist_to_binary(join(re:split("xy","\\by\\b",[trim]))),
<<"xy">> = iolist_to_binary(join(re:split("xy","\\by\\b",[{parts,
- 2}]))),
- <<"xy">> = iolist_to_binary(join(re:split("xy","\\by\\b",[]))),
- <<"yz">> = iolist_to_binary(join(re:split("yz","\\by\\b",[trim]))),
+ 2}]))),
+ <<"xy">> = iolist_to_binary(join(re:split("xy","\\by\\b",[]))),
+ <<"yz">> = iolist_to_binary(join(re:split("yz","\\by\\b",[trim]))),
<<"yz">> = iolist_to_binary(join(re:split("yz","\\by\\b",[{parts,
- 2}]))),
- <<"yz">> = iolist_to_binary(join(re:split("yz","\\by\\b",[]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","\\by\\b",[trim]))),
+ 2}]))),
+ <<"yz">> = iolist_to_binary(join(re:split("yz","\\by\\b",[]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","\\by\\b",[trim]))),
<<"xyz">> = iolist_to_binary(join(re:split("xyz","\\by\\b",[{parts,
- 2}]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","\\by\\b",[]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","\\Ba\\B",[trim]))),
+ 2}]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","\\by\\b",[]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","\\Ba\\B",[trim]))),
<<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","\\Ba\\B",[{parts,
- 2}]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","\\Ba\\B",[]))),
- <<"a-">> = iolist_to_binary(join(re:split("a-","\\Ba\\B",[trim]))),
+ 2}]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","\\Ba\\B",[]))),
+ <<"a-">> = iolist_to_binary(join(re:split("a-","\\Ba\\B",[trim]))),
<<"a-">> = iolist_to_binary(join(re:split("a-","\\Ba\\B",[{parts,
- 2}]))),
- <<"a-">> = iolist_to_binary(join(re:split("a-","\\Ba\\B",[]))),
- <<"-a">> = iolist_to_binary(join(re:split("-a","\\Ba\\B",[trim]))),
+ 2}]))),
+ <<"a-">> = iolist_to_binary(join(re:split("a-","\\Ba\\B",[]))),
+ <<"-a">> = iolist_to_binary(join(re:split("-a","\\Ba\\B",[trim]))),
<<"-a">> = iolist_to_binary(join(re:split("-a","\\Ba\\B",[{parts,
- 2}]))),
- <<"-a">> = iolist_to_binary(join(re:split("-a","\\Ba\\B",[]))),
- <<"-a-">> = iolist_to_binary(join(re:split("-a-","\\Ba\\B",[trim]))),
+ 2}]))),
+ <<"-a">> = iolist_to_binary(join(re:split("-a","\\Ba\\B",[]))),
+ <<"-a-">> = iolist_to_binary(join(re:split("-a-","\\Ba\\B",[trim]))),
<<"-a-">> = iolist_to_binary(join(re:split("-a-","\\Ba\\B",[{parts,
- 2}]))),
- <<"-a-">> = iolist_to_binary(join(re:split("-a-","\\Ba\\B",[]))),
- <<"x">> = iolist_to_binary(join(re:split("xy","\\By\\b",[trim]))),
+ 2}]))),
+ <<"-a-">> = iolist_to_binary(join(re:split("-a-","\\Ba\\B",[]))),
+ <<"x">> = iolist_to_binary(join(re:split("xy","\\By\\b",[trim]))),
<<"x:">> = iolist_to_binary(join(re:split("xy","\\By\\b",[{parts,
- 2}]))),
- <<"x:">> = iolist_to_binary(join(re:split("xy","\\By\\b",[]))),
- <<":z">> = iolist_to_binary(join(re:split("yz","\\by\\B",[trim]))),
+ 2}]))),
+ <<"x:">> = iolist_to_binary(join(re:split("xy","\\By\\b",[]))),
+ <<":z">> = iolist_to_binary(join(re:split("yz","\\by\\B",[trim]))),
<<":z">> = iolist_to_binary(join(re:split("yz","\\by\\B",[{parts,
- 2}]))),
- <<":z">> = iolist_to_binary(join(re:split("yz","\\by\\B",[]))),
- <<"x:z">> = iolist_to_binary(join(re:split("xyz","\\By\\B",[trim]))),
+ 2}]))),
+ <<":z">> = iolist_to_binary(join(re:split("yz","\\by\\B",[]))),
+ <<"x:z">> = iolist_to_binary(join(re:split("xyz","\\By\\B",[trim]))),
<<"x:z">> = iolist_to_binary(join(re:split("xyz","\\By\\B",[{parts,
- 2}]))),
- <<"x:z">> = iolist_to_binary(join(re:split("xyz","\\By\\B",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","\\w",[trim]))),
+ 2}]))),
+ <<"x:z">> = iolist_to_binary(join(re:split("xyz","\\By\\B",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","\\W",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","\\W",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","\\W",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","\\W",[]))),
- <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","\\W",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","\\W",[]))),
+ <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","\\W",[trim]))),
<<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\W",[{parts,
- 2}]))),
- <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","\\W",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","\\W",[trim]))),
+ 2}]))),
+ <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","\\W",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","\\W",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","\\W",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","\\W",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","\\W",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","\\W",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","\\W",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","\\W",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","\\W",[]))),
- <<"">> = iolist_to_binary(join(re:split("a b","a\\sb",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","\\W",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a b","a\\sb",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a b","a\\sb",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a b","a\\sb",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a b","a\\sb",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Sb",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Sb",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Sb",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Sb",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Sb",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[]))),
- <<"a b">> = iolist_to_binary(join(re:split("a b","a\\Sb",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-b","a\\Sb",[]))),
+ <<"a b">> = iolist_to_binary(join(re:split("a b","a\\Sb",[trim]))),
<<"a b">> = iolist_to_binary(join(re:split("a b","a\\Sb",[{parts,
- 2}]))),
- <<"a b">> = iolist_to_binary(join(re:split("a b","a\\Sb",[]))),
- <<"">> = iolist_to_binary(join(re:split("1","\\d",[trim]))),
+ 2}]))),
+ <<"a b">> = iolist_to_binary(join(re:split("a b","a\\Sb",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1","\\d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1","\\d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1","\\d",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","\\D",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1","\\d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","\\D",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","\\D",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","\\D",[]))),
- <<"">> = iolist_to_binary(join(re:split("*** Failers","\\D",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","\\D",[]))),
+ <<"">> = iolist_to_binary(join(re:split("*** Failers","\\D",[trim]))),
<<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\D",[{parts,
- 2}]))),
- <<":::::::::::">> = iolist_to_binary(join(re:split("*** Failers","\\D",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","\\D",[trim]))),
+ 2}]))),
+ <<":::::::::::">> = iolist_to_binary(join(re:split("*** Failers","\\D",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","\\D",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","\\D",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","\\D",[]))),
- <<"1">> = iolist_to_binary(join(re:split("1","\\D",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","\\D",[]))),
+ <<"1">> = iolist_to_binary(join(re:split("1","\\D",[trim]))),
<<"1">> = iolist_to_binary(join(re:split("1","\\D",[{parts,
- 2}]))),
- <<"1">> = iolist_to_binary(join(re:split("1","\\D",[]))),
+ 2}]))),
+ <<"1">> = iolist_to_binary(join(re:split("1","\\D",[]))),
ok.
run17() ->
- <<"">> = iolist_to_binary(join(re:split("a","[\\w]",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("a","[\\w]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","[\\w]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","[\\w]",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","[\\W]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","[\\w]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","[\\W]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","[\\W]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","[\\W]",[]))),
- <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\W]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","[\\W]",[]))),
+ <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\W]",[trim]))),
<<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\W]",[{parts,
- 2}]))),
- <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\W]",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","[\\W]",[trim]))),
+ 2}]))),
+ <<"::::Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\W]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","[\\W]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","[\\W]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","[\\W]",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","[\\W]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","[\\W]",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","[\\W]",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","[\\W]",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","[\\W]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a b","a[\\s]b",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","[\\W]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a b","a[\\s]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a b","a[\\s]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a b","a[\\s]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a b","a[\\s]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[\\S]b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[\\S]b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[\\S]b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[\\S]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[\\S]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[]))),
- <<"a b">> = iolist_to_binary(join(re:split("a b","a[\\S]b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a-b","a[\\S]b",[]))),
+ <<"a b">> = iolist_to_binary(join(re:split("a b","a[\\S]b",[trim]))),
<<"a b">> = iolist_to_binary(join(re:split("a b","a[\\S]b",[{parts,
- 2}]))),
- <<"a b">> = iolist_to_binary(join(re:split("a b","a[\\S]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("1","[\\d]",[trim]))),
+ 2}]))),
+ <<"a b">> = iolist_to_binary(join(re:split("a b","a[\\S]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1","[\\d]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1","[\\d]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1","[\\d]",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","[\\D]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1","[\\d]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","[\\D]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","[\\D]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","[\\D]",[]))),
- <<"">> = iolist_to_binary(join(re:split("*** Failers","[\\D]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","[\\D]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("*** Failers","[\\D]",[trim]))),
<<":** Failers">> = iolist_to_binary(join(re:split("*** Failers","[\\D]",[{parts,
- 2}]))),
- <<":::::::::::">> = iolist_to_binary(join(re:split("*** Failers","[\\D]",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","[\\D]",[trim]))),
+ 2}]))),
+ <<":::::::::::">> = iolist_to_binary(join(re:split("*** Failers","[\\D]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","[\\D]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","[\\D]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","[\\D]",[]))),
- <<"1">> = iolist_to_binary(join(re:split("1","[\\D]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","[\\D]",[]))),
+ <<"1">> = iolist_to_binary(join(re:split("1","[\\D]",[trim]))),
<<"1">> = iolist_to_binary(join(re:split("1","[\\D]",[{parts,
- 2}]))),
- <<"1">> = iolist_to_binary(join(re:split("1","[\\D]",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","ab|cd",[trim]))),
+ 2}]))),
+ <<"1">> = iolist_to_binary(join(re:split("1","[\\D]",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","ab|cd",[trim]))),
<<":c">> = iolist_to_binary(join(re:split("abc","ab|cd",[{parts,
- 2}]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","ab|cd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcd","ab|cd",[trim]))),
+ 2}]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","ab|cd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcd","ab|cd",[trim]))),
<<":cd">> = iolist_to_binary(join(re:split("abcd","ab|cd",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abcd","ab|cd",[]))),
- <<"d">> = iolist_to_binary(join(re:split("def","()ef",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abcd","ab|cd",[]))),
+ <<"d">> = iolist_to_binary(join(re:split("def","()ef",[trim]))),
<<"d::">> = iolist_to_binary(join(re:split("def","()ef",[{parts,
- 2}]))),
- <<"d::">> = iolist_to_binary(join(re:split("def","()ef",[]))),
- <<"">> = iolist_to_binary(join(re:split("a(b","a\\(b",[trim]))),
+ 2}]))),
+ <<"d::">> = iolist_to_binary(join(re:split("def","()ef",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a(b","a\\(b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a(b","a\\(b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a(b","a\\(b",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab","a\\(*b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a(b","a\\(b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","a\\(*b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","a\\(*b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","a\\(*b",[]))),
- <<"">> = iolist_to_binary(join(re:split("a((b","a\\(*b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","a\\(*b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a((b","a\\(*b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a((b","a\\(*b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a((b","a\\(*b",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","a\\\\b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a((b","a\\(*b",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","a\\\\b",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","a\\\\b",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","a\\\\b",[]))),
- <<":a:a:bc">> = iolist_to_binary(join(re:split("abc","((a))",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","a\\\\b",[]))),
+ <<":a:a:bc">> = iolist_to_binary(join(re:split("abc","((a))",[trim]))),
<<":a:a:bc">> = iolist_to_binary(join(re:split("abc","((a))",[{parts,
- 2}]))),
- <<":a:a:bc">> = iolist_to_binary(join(re:split("abc","((a))",[]))),
- <<":a:c">> = iolist_to_binary(join(re:split("abc","(a)b(c)",[trim]))),
+ 2}]))),
+ <<":a:a:bc">> = iolist_to_binary(join(re:split("abc","((a))",[]))),
+ <<":a:c">> = iolist_to_binary(join(re:split("abc","(a)b(c)",[trim]))),
<<":a:c:">> = iolist_to_binary(join(re:split("abc","(a)b(c)",[{parts,
- 2}]))),
- <<":a:c:">> = iolist_to_binary(join(re:split("abc","(a)b(c)",[]))),
- <<"aabb">> = iolist_to_binary(join(re:split("aabbabc","a+b+c",[trim]))),
+ 2}]))),
+ <<":a:c:">> = iolist_to_binary(join(re:split("abc","(a)b(c)",[]))),
+ <<"aabb">> = iolist_to_binary(join(re:split("aabbabc","a+b+c",[trim]))),
<<"aabb:">> = iolist_to_binary(join(re:split("aabbabc","a+b+c",[{parts,
- 2}]))),
- <<"aabb:">> = iolist_to_binary(join(re:split("aabbabc","a+b+c",[]))),
- <<"aabb">> = iolist_to_binary(join(re:split("aabbabc","a{1,}b{1,}c",[trim]))),
+ 2}]))),
+ <<"aabb:">> = iolist_to_binary(join(re:split("aabbabc","a+b+c",[]))),
+ <<"aabb">> = iolist_to_binary(join(re:split("aabbabc","a{1,}b{1,}c",[trim]))),
<<"aabb:">> = iolist_to_binary(join(re:split("aabbabc","a{1,}b{1,}c",[{parts,
- 2}]))),
- <<"aabb:">> = iolist_to_binary(join(re:split("aabbabc","a{1,}b{1,}c",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcabc","a.+?c",[trim]))),
+ 2}]))),
+ <<"aabb:">> = iolist_to_binary(join(re:split("aabbabc","a{1,}b{1,}c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcabc","a.+?c",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split("abcabc","a.+?c",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abcabc","a.+?c",[]))),
- <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b)*",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abcabc","a.+?c",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b)*",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)*",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)*",[]))),
- <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b){0,}",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)*",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b){0,}",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){0,}",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){0,}",[]))),
- <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){0,}",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[]))),
ok.
run18() ->
- <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[trim]))),
+ <<":b">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[]))),
- <<":a::b">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[]))),
+ <<":a::b">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[{parts,
- 2}]))),
- <<":a::b:">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[]))),
- <<":a::b">> = iolist_to_binary(join(re:split("ab","(a+|b){0,1}",[trim]))),
+ 2}]))),
+ <<":a::b:">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[]))),
+ <<":a::b">> = iolist_to_binary(join(re:split("ab","(a+|b){0,1}",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("ab","(a+|b){0,1}",[{parts,
- 2}]))),
- <<":a::b:">> = iolist_to_binary(join(re:split("ab","(a+|b){0,1}",[]))),
- <<"">> = iolist_to_binary(join(re:split("cde","[^ab]*",[trim]))),
+ 2}]))),
+ <<":a::b:">> = iolist_to_binary(join(re:split("ab","(a+|b){0,1}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("cde","[^ab]*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("cde","[^ab]*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("cde","[^ab]*",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("cde","[^ab]*",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[]))),
- <<"b">> = iolist_to_binary(join(re:split("b","abc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","abc",[trim]))),
<<"b">> = iolist_to_binary(join(re:split("b","abc",[{parts,
- 2}]))),
- <<"b">> = iolist_to_binary(join(re:split("b","abc",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abbbcd","([abc])*d",[trim]))),
+ 2}]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","abc",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abbbcd","([abc])*d",[trim]))),
<<":c:">> = iolist_to_binary(join(re:split("abbbcd","([abc])*d",[{parts,
- 2}]))),
- <<":c:">> = iolist_to_binary(join(re:split("abbbcd","([abc])*d",[]))),
- <<":a">> = iolist_to_binary(join(re:split("abcd","([abc])*bcd",[trim]))),
+ 2}]))),
+ <<":c:">> = iolist_to_binary(join(re:split("abbbcd","([abc])*d",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("abcd","([abc])*bcd",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("abcd","([abc])*bcd",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("abcd","([abc])*bcd",[]))),
- <<"">> = iolist_to_binary(join(re:split("e","a|b|c|d|e",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("abcd","([abc])*bcd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("e","a|b|c|d|e",[trim]))),
<<":">> = iolist_to_binary(join(re:split("e","a|b|c|d|e",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("e","a|b|c|d|e",[]))),
- <<":e">> = iolist_to_binary(join(re:split("ef","(a|b|c|d|e)f",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("e","a|b|c|d|e",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("ef","(a|b|c|d|e)f",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("ef","(a|b|c|d|e)f",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("ef","(a|b|c|d|e)f",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcdefg","abcd*efg",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("ef","(a|b|c|d|e)f",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcdefg","abcd*efg",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcdefg","abcd*efg",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcdefg","abcd*efg",[]))),
- <<"x:y:z">> = iolist_to_binary(join(re:split("xabyabbbz","ab*",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcdefg","abcd*efg",[]))),
+ <<"x:y:z">> = iolist_to_binary(join(re:split("xabyabbbz","ab*",[trim]))),
<<"x:yabbbz">> = iolist_to_binary(join(re:split("xabyabbbz","ab*",[{parts,
- 2}]))),
- <<"x:y:z">> = iolist_to_binary(join(re:split("xabyabbbz","ab*",[]))),
- <<"x:y:z">> = iolist_to_binary(join(re:split("xayabbbz","ab*",[trim]))),
+ 2}]))),
+ <<"x:y:z">> = iolist_to_binary(join(re:split("xabyabbbz","ab*",[]))),
+ <<"x:y:z">> = iolist_to_binary(join(re:split("xayabbbz","ab*",[trim]))),
<<"x:yabbbz">> = iolist_to_binary(join(re:split("xayabbbz","ab*",[{parts,
- 2}]))),
- <<"x:y:z">> = iolist_to_binary(join(re:split("xayabbbz","ab*",[]))),
- <<"ab:cd">> = iolist_to_binary(join(re:split("abcde","(ab|cd)e",[trim]))),
+ 2}]))),
+ <<"x:y:z">> = iolist_to_binary(join(re:split("xayabbbz","ab*",[]))),
+ <<"ab:cd">> = iolist_to_binary(join(re:split("abcde","(ab|cd)e",[trim]))),
<<"ab:cd:">> = iolist_to_binary(join(re:split("abcde","(ab|cd)e",[{parts,
- 2}]))),
- <<"ab:cd:">> = iolist_to_binary(join(re:split("abcde","(ab|cd)e",[]))),
- <<"">> = iolist_to_binary(join(re:split("hij","[abhgefdc]ij",[trim]))),
+ 2}]))),
+ <<"ab:cd:">> = iolist_to_binary(join(re:split("abcde","(ab|cd)e",[]))),
+ <<"">> = iolist_to_binary(join(re:split("hij","[abhgefdc]ij",[trim]))),
<<":">> = iolist_to_binary(join(re:split("hij","[abhgefdc]ij",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("hij","[abhgefdc]ij",[]))),
- <<"abcd">> = iolist_to_binary(join(re:split("abcdef","(abc|)ef",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("hij","[abhgefdc]ij",[]))),
+ <<"abcd">> = iolist_to_binary(join(re:split("abcdef","(abc|)ef",[trim]))),
<<"abcd::">> = iolist_to_binary(join(re:split("abcdef","(abc|)ef",[{parts,
- 2}]))),
- <<"abcd::">> = iolist_to_binary(join(re:split("abcdef","(abc|)ef",[]))),
- <<"a:b">> = iolist_to_binary(join(re:split("abcd","(a|b)c*d",[trim]))),
+ 2}]))),
+ <<"abcd::">> = iolist_to_binary(join(re:split("abcdef","(abc|)ef",[]))),
+ <<"a:b">> = iolist_to_binary(join(re:split("abcd","(a|b)c*d",[trim]))),
<<"a:b:">> = iolist_to_binary(join(re:split("abcd","(a|b)c*d",[{parts,
- 2}]))),
- <<"a:b:">> = iolist_to_binary(join(re:split("abcd","(a|b)c*d",[]))),
- <<":a">> = iolist_to_binary(join(re:split("abc","(ab|ab*)bc",[trim]))),
+ 2}]))),
+ <<"a:b:">> = iolist_to_binary(join(re:split("abcd","(a|b)c*d",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("abc","(ab|ab*)bc",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("abc","(ab|ab*)bc",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("abc","(ab|ab*)bc",[]))),
- <<":bc">> = iolist_to_binary(join(re:split("abc","a([bc]*)c*",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("abc","(ab|ab*)bc",[]))),
+ <<":bc">> = iolist_to_binary(join(re:split("abc","a([bc]*)c*",[trim]))),
<<":bc:">> = iolist_to_binary(join(re:split("abc","a([bc]*)c*",[{parts,
- 2}]))),
- <<":bc:">> = iolist_to_binary(join(re:split("abc","a([bc]*)c*",[]))),
- <<":bc:d">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[trim]))),
+ 2}]))),
+ <<":bc:">> = iolist_to_binary(join(re:split("abc","a([bc]*)c*",[]))),
+ <<":bc:d">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[trim]))),
<<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[{parts,
- 2}]))),
- <<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[]))),
+ 2}]))),
+ <<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[]))),
ok.
run19() ->
- <<":bc:d">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[trim]))),
+ <<":bc:d">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[trim]))),
<<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[{parts,
- 2}]))),
- <<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[]))),
- <<":b:cd">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[trim]))),
+ 2}]))),
+ <<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[]))),
+ <<":b:cd">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[trim]))),
<<":b:cd:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[{parts,
- 2}]))),
- <<":b:cd:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[]))),
- <<"">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]*dcdcde",[trim]))),
+ 2}]))),
+ <<":b:cd:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]*dcdcde",[trim]))),
<<":">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]*dcdcde",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]*dcdcde",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bcd]+dcdcde",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]*dcdcde",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bcd]+dcdcde",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bcd]+dcdcde",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bcd]+dcdcde",[]))),
- <<"abcde">> = iolist_to_binary(join(re:split("abcde","a[bcd]+dcdcde",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[bcd]+dcdcde",[]))),
+ <<"abcde">> = iolist_to_binary(join(re:split("abcde","a[bcd]+dcdcde",[trim]))),
<<"abcde">> = iolist_to_binary(join(re:split("abcde","a[bcd]+dcdcde",[{parts,
- 2}]))),
- <<"abcde">> = iolist_to_binary(join(re:split("abcde","a[bcd]+dcdcde",[]))),
- <<"adcdcde">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]+dcdcde",[trim]))),
+ 2}]))),
+ <<"abcde">> = iolist_to_binary(join(re:split("abcde","a[bcd]+dcdcde",[]))),
+ <<"adcdcde">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]+dcdcde",[trim]))),
<<"adcdcde">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]+dcdcde",[{parts,
- 2}]))),
- <<"adcdcde">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]+dcdcde",[]))),
- <<":ab">> = iolist_to_binary(join(re:split("abc","(ab|a)b*c",[trim]))),
+ 2}]))),
+ <<"adcdcde">> = iolist_to_binary(join(re:split("adcdcde","a[bcd]+dcdcde",[]))),
+ <<":ab">> = iolist_to_binary(join(re:split("abc","(ab|a)b*c",[trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("abc","(ab|a)b*c",[{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("abc","(ab|a)b*c",[]))),
- <<":abc:a:b:d">> = iolist_to_binary(join(re:split("abcd","((a)(b)c)(d)",[trim]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("abc","(ab|a)b*c",[]))),
+ <<":abc:a:b:d">> = iolist_to_binary(join(re:split("abcd","((a)(b)c)(d)",[trim]))),
<<":abc:a:b:d:">> = iolist_to_binary(join(re:split("abcd","((a)(b)c)(d)",[{parts,
- 2}]))),
- <<":abc:a:b:d:">> = iolist_to_binary(join(re:split("abcd","((a)(b)c)(d)",[]))),
- <<"">> = iolist_to_binary(join(re:split("alpha","[a-zA-Z_][a-zA-Z0-9_]*",[trim]))),
+ 2}]))),
+ <<":abc:a:b:d:">> = iolist_to_binary(join(re:split("abcd","((a)(b)c)(d)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("alpha","[a-zA-Z_][a-zA-Z0-9_]*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("alpha","[a-zA-Z_][a-zA-Z0-9_]*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("alpha","[a-zA-Z_][a-zA-Z0-9_]*",[]))),
- <<"a">> = iolist_to_binary(join(re:split("abh","^a(bc+|b[eh])g|.h$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("alpha","[a-zA-Z_][a-zA-Z0-9_]*",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("abh","^a(bc+|b[eh])g|.h$",[trim]))),
<<"a::">> = iolist_to_binary(join(re:split("abh","^a(bc+|b[eh])g|.h$",[{parts,
- 2}]))),
- <<"a::">> = iolist_to_binary(join(re:split("abh","^a(bc+|b[eh])g|.h$",[]))),
- <<":effgz">> = iolist_to_binary(join(re:split("effgz","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
+ 2}]))),
+ <<"a::">> = iolist_to_binary(join(re:split("abh","^a(bc+|b[eh])g|.h$",[]))),
+ <<":effgz">> = iolist_to_binary(join(re:split("effgz","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
<<":effgz::">> = iolist_to_binary(join(re:split("effgz","(bc+d$|ef*g.|h?i(j|k))",[{parts,
- 2}]))),
- <<":effgz::">> = iolist_to_binary(join(re:split("effgz","(bc+d$|ef*g.|h?i(j|k))",[]))),
- <<":ij:j">> = iolist_to_binary(join(re:split("ij","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
+ 2}]))),
+ <<":effgz::">> = iolist_to_binary(join(re:split("effgz","(bc+d$|ef*g.|h?i(j|k))",[]))),
+ <<":ij:j">> = iolist_to_binary(join(re:split("ij","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
<<":ij:j:">> = iolist_to_binary(join(re:split("ij","(bc+d$|ef*g.|h?i(j|k))",[{parts,
- 2}]))),
- <<":ij:j:">> = iolist_to_binary(join(re:split("ij","(bc+d$|ef*g.|h?i(j|k))",[]))),
- <<"r:effgz">> = iolist_to_binary(join(re:split("reffgz","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
+ 2}]))),
+ <<":ij:j:">> = iolist_to_binary(join(re:split("ij","(bc+d$|ef*g.|h?i(j|k))",[]))),
+ <<"r:effgz">> = iolist_to_binary(join(re:split("reffgz","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
<<"r:effgz::">> = iolist_to_binary(join(re:split("reffgz","(bc+d$|ef*g.|h?i(j|k))",[{parts,
- 2}]))),
- <<"r:effgz::">> = iolist_to_binary(join(re:split("reffgz","(bc+d$|ef*g.|h?i(j|k))",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
+ 2}]))),
+ <<"r:effgz::">> = iolist_to_binary(join(re:split("reffgz","(bc+d$|ef*g.|h?i(j|k))",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[]))),
- <<"effg">> = iolist_to_binary(join(re:split("effg","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[]))),
+ <<"effg">> = iolist_to_binary(join(re:split("effg","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
<<"effg">> = iolist_to_binary(join(re:split("effg","(bc+d$|ef*g.|h?i(j|k))",[{parts,
- 2}]))),
- <<"effg">> = iolist_to_binary(join(re:split("effg","(bc+d$|ef*g.|h?i(j|k))",[]))),
- <<"bcdd">> = iolist_to_binary(join(re:split("bcdd","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
+ 2}]))),
+ <<"effg">> = iolist_to_binary(join(re:split("effg","(bc+d$|ef*g.|h?i(j|k))",[]))),
+ <<"bcdd">> = iolist_to_binary(join(re:split("bcdd","(bc+d$|ef*g.|h?i(j|k))",[trim]))),
<<"bcdd">> = iolist_to_binary(join(re:split("bcdd","(bc+d$|ef*g.|h?i(j|k))",[{parts,
- 2}]))),
- <<"bcdd">> = iolist_to_binary(join(re:split("bcdd","(bc+d$|ef*g.|h?i(j|k))",[]))),
- <<":a:a:a:a:a:a:a:a:a:a">> = iolist_to_binary(join(re:split("a","((((((((((a))))))))))",[trim]))),
+ 2}]))),
+ <<"bcdd">> = iolist_to_binary(join(re:split("bcdd","(bc+d$|ef*g.|h?i(j|k))",[]))),
+ <<":a:a:a:a:a:a:a:a:a:a">> = iolist_to_binary(join(re:split("a","((((((((((a))))))))))",[trim]))),
<<":a:a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("a","((((((((((a))))))))))",[{parts,
- 2}]))),
- <<":a:a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("a","((((((((((a))))))))))",[]))),
- <<":a:a:a:a:a:a:a:a:a:a">> = iolist_to_binary(join(re:split("aa","((((((((((a))))))))))\\10",[trim]))),
+ 2}]))),
+ <<":a:a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("a","((((((((((a))))))))))",[]))),
+ <<":a:a:a:a:a:a:a:a:a:a">> = iolist_to_binary(join(re:split("aa","((((((((((a))))))))))\\10",[trim]))),
<<":a:a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("aa","((((((((((a))))))))))\\10",[{parts,
- 2}]))),
- <<":a:a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("aa","((((((((((a))))))))))\\10",[]))),
- <<":a:a:a:a:a:a:a:a:a">> = iolist_to_binary(join(re:split("a","(((((((((a)))))))))",[trim]))),
+ 2}]))),
+ <<":a:a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("aa","((((((((((a))))))))))\\10",[]))),
+ <<":a:a:a:a:a:a:a:a:a">> = iolist_to_binary(join(re:split("a","(((((((((a)))))))))",[trim]))),
<<":a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("a","(((((((((a)))))))))",[{parts,
- 2}]))),
- <<":a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("a","(((((((((a)))))))))",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[trim]))),
+ 2}]))),
+ <<":a:a:a:a:a:a:a:a:a:">> = iolist_to_binary(join(re:split("a","(((((((((a)))))))))",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","multiple words of text",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","multiple words of text",[trim]))),
<<"aa">> = iolist_to_binary(join(re:split("aa","multiple words of text",[{parts,
- 2}]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","multiple words of text",[]))),
- <<"uh-uh">> = iolist_to_binary(join(re:split("uh-uh","multiple words of text",[trim]))),
+ 2}]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","multiple words of text",[]))),
+ <<"uh-uh">> = iolist_to_binary(join(re:split("uh-uh","multiple words of text",[trim]))),
<<"uh-uh">> = iolist_to_binary(join(re:split("uh-uh","multiple words of text",[{parts,
- 2}]))),
- <<"uh-uh">> = iolist_to_binary(join(re:split("uh-uh","multiple words of text",[]))),
- <<":, yeah">> = iolist_to_binary(join(re:split("multiple words, yeah","multiple words",[trim]))),
+ 2}]))),
+ <<"uh-uh">> = iolist_to_binary(join(re:split("uh-uh","multiple words of text",[]))),
+ <<":, yeah">> = iolist_to_binary(join(re:split("multiple words, yeah","multiple words",[trim]))),
<<":, yeah">> = iolist_to_binary(join(re:split("multiple words, yeah","multiple words",[{parts,
- 2}]))),
- <<":, yeah">> = iolist_to_binary(join(re:split("multiple words, yeah","multiple words",[]))),
- <<":ab:de">> = iolist_to_binary(join(re:split("abcde","(.*)c(.*)",[trim]))),
+ 2}]))),
+ <<":, yeah">> = iolist_to_binary(join(re:split("multiple words, yeah","multiple words",[]))),
+ <<":ab:de">> = iolist_to_binary(join(re:split("abcde","(.*)c(.*)",[trim]))),
<<":ab:de:">> = iolist_to_binary(join(re:split("abcde","(.*)c(.*)",[{parts,
- 2}]))),
- <<":ab:de:">> = iolist_to_binary(join(re:split("abcde","(.*)c(.*)",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("(a, b)","\\((.*), (.*)\\)",[trim]))),
+ 2}]))),
+ <<":ab:de:">> = iolist_to_binary(join(re:split("abcde","(.*)c(.*)",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("(a, b)","\\((.*), (.*)\\)",[trim]))),
<<":a:b:">> = iolist_to_binary(join(re:split("(a, b)","\\((.*), (.*)\\)",[{parts,
- 2}]))),
- <<":a:b:">> = iolist_to_binary(join(re:split("(a, b)","\\((.*), (.*)\\)",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcd","abcd",[trim]))),
+ 2}]))),
+ <<":a:b:">> = iolist_to_binary(join(re:split("(a, b)","\\((.*), (.*)\\)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcd","abcd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd","abcd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcd","abcd",[]))),
- <<":bc">> = iolist_to_binary(join(re:split("abcd","a(bc)d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcd","abcd",[]))),
+ <<":bc">> = iolist_to_binary(join(re:split("abcd","a(bc)d",[trim]))),
<<":bc:">> = iolist_to_binary(join(re:split("abcd","a(bc)d",[{parts,
- 2}]))),
- <<":bc:">> = iolist_to_binary(join(re:split("abcd","a(bc)d",[]))),
- <<"">> = iolist_to_binary(join(re:split("ac","a[-]?c",[trim]))),
+ 2}]))),
+ <<":bc:">> = iolist_to_binary(join(re:split("abcd","a(bc)d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ac","a[-]?c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ac","a[-]?c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ac","a[-]?c",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ac","a[-]?c",[]))),
ok.
run20() ->
- <<":abc">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[trim]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[]))),
- <<":a">> = iolist_to_binary(join(re:split("a","(a)|\\1",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("a","(a)|\\1",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("a","(a)|\\1",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("a","(a)|\\1",[]))),
- <<"*** F:a:ilers">> = iolist_to_binary(join(re:split("*** Failers","(a)|\\1",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("a","(a)|\\1",[]))),
+ <<"*** F:a:ilers">> = iolist_to_binary(join(re:split("*** Failers","(a)|\\1",[trim]))),
<<"*** F:a:ilers">> = iolist_to_binary(join(re:split("*** Failers","(a)|\\1",[{parts,
- 2}]))),
- <<"*** F:a:ilers">> = iolist_to_binary(join(re:split("*** Failers","(a)|\\1",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("ab","(a)|\\1",[trim]))),
+ 2}]))),
+ <<"*** F:a:ilers">> = iolist_to_binary(join(re:split("*** Failers","(a)|\\1",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("ab","(a)|\\1",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("ab","(a)|\\1",[{parts,
- 2}]))),
- <<":a:b">> = iolist_to_binary(join(re:split("ab","(a)|\\1",[]))),
- <<"x">> = iolist_to_binary(join(re:split("x","(a)|\\1",[trim]))),
+ 2}]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("ab","(a)|\\1",[]))),
+ <<"x">> = iolist_to_binary(join(re:split("x","(a)|\\1",[trim]))),
<<"x">> = iolist_to_binary(join(re:split("x","(a)|\\1",[{parts,
- 2}]))),
- <<"x">> = iolist_to_binary(join(re:split("x","(a)|\\1",[]))),
- <<":bb:b:b:cbc:c">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2)*",[trim]))),
+ 2}]))),
+ <<"x">> = iolist_to_binary(join(re:split("x","(a)|\\1",[]))),
+ <<":bb:b:b:cbc:c">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2)*",[trim]))),
<<":bb:b:bcbc">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2)*",[{parts,
- 2}]))),
- <<":bb:b:b:cbc:c:">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2)*",[]))),
- <<":cbc:c">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2){3}",[trim]))),
+ 2}]))),
+ <<":bb:b:b:cbc:c:">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2)*",[]))),
+ <<":cbc:c">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2){3}",[trim]))),
<<":cbc:c:">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2){3}",[{parts,
- 2}]))),
- <<":cbc:c:">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2){3}",[]))),
- <<"aaaxabaxbaax:bbax:b:a">> = iolist_to_binary(join(re:split("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+",[trim]))),
+ 2}]))),
+ <<":cbc:c:">> = iolist_to_binary(join(re:split("ababbbcbc","(([a-c])b*?\\2){3}",[]))),
+ <<"aaaxabaxbaax:bbax:b:a">> = iolist_to_binary(join(re:split("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+",[trim]))),
<<"aaaxabaxbaax:bbax:b:a:">> = iolist_to_binary(join(re:split("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+",[{parts,
- 2}]))),
- <<"aaaxabaxbaax:bbax:b:a:">> = iolist_to_binary(join(re:split("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+",[]))),
- <<"bbaababbabaaaaa:bba:b:a">> = iolist_to_binary(join(re:split("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}",[trim]))),
+ 2}]))),
+ <<"aaaxabaxbaax:bbax:b:a:">> = iolist_to_binary(join(re:split("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+",[]))),
+ <<"bbaababbabaaaaa:bba:b:a">> = iolist_to_binary(join(re:split("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}",[trim]))),
<<"bbaababbabaaaaa:bba:b:a:">> = iolist_to_binary(join(re:split("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}",[{parts,
- 2}]))),
- <<"bbaababbabaaaaa:bba:b:a:">> = iolist_to_binary(join(re:split("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}",[]))),
+ 2}]))),
+ <<"bbaababbabaaaaa:bba:b:a:">> = iolist_to_binary(join(re:split("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}",[]))),
<<"">> = iolist_to_binary(join(re:split("ABC","abc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","abc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","abc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","abc",[caseless]))),
<<"X:Y">> = iolist_to_binary(join(re:split("XABCY","abc",[caseless,
- trim]))),
+ trim]))),
<<"X:Y">> = iolist_to_binary(join(re:split("XABCY","abc",[caseless,
{parts,
- 2}]))),
- <<"X:Y">> = iolist_to_binary(join(re:split("XABCY","abc",[caseless]))),
+ 2}]))),
+ <<"X:Y">> = iolist_to_binary(join(re:split("XABCY","abc",[caseless]))),
<<"AB">> = iolist_to_binary(join(re:split("ABABC","abc",[caseless,
- trim]))),
+ trim]))),
<<"AB:">> = iolist_to_binary(join(re:split("ABABC","abc",[caseless,
{parts,
- 2}]))),
- <<"AB:">> = iolist_to_binary(join(re:split("ABABC","abc",[caseless]))),
+ 2}]))),
+ <<"AB:">> = iolist_to_binary(join(re:split("ABABC","abc",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","abc",[caseless]))),
<<"aaxabxbaxbbx">> = iolist_to_binary(join(re:split("aaxabxbaxbbx","abc",[caseless,
- trim]))),
+ trim]))),
<<"aaxabxbaxbbx">> = iolist_to_binary(join(re:split("aaxabxbaxbbx","abc",[caseless,
{parts,
- 2}]))),
- <<"aaxabxbaxbbx">> = iolist_to_binary(join(re:split("aaxabxbaxbbx","abc",[caseless]))),
+ 2}]))),
+ <<"aaxabxbaxbbx">> = iolist_to_binary(join(re:split("aaxabxbaxbbx","abc",[caseless]))),
<<"XBC">> = iolist_to_binary(join(re:split("XBC","abc",[caseless,
- trim]))),
+ trim]))),
<<"XBC">> = iolist_to_binary(join(re:split("XBC","abc",[caseless,
{parts,
- 2}]))),
- <<"XBC">> = iolist_to_binary(join(re:split("XBC","abc",[caseless]))),
+ 2}]))),
+ <<"XBC">> = iolist_to_binary(join(re:split("XBC","abc",[caseless]))),
<<"AXC">> = iolist_to_binary(join(re:split("AXC","abc",[caseless,
- trim]))),
+ trim]))),
<<"AXC">> = iolist_to_binary(join(re:split("AXC","abc",[caseless,
{parts,
- 2}]))),
- <<"AXC">> = iolist_to_binary(join(re:split("AXC","abc",[caseless]))),
+ 2}]))),
+ <<"AXC">> = iolist_to_binary(join(re:split("AXC","abc",[caseless]))),
<<"ABX">> = iolist_to_binary(join(re:split("ABX","abc",[caseless,
- trim]))),
+ trim]))),
<<"ABX">> = iolist_to_binary(join(re:split("ABX","abc",[caseless,
{parts,
- 2}]))),
- <<"ABX">> = iolist_to_binary(join(re:split("ABX","abc",[caseless]))),
+ 2}]))),
+ <<"ABX">> = iolist_to_binary(join(re:split("ABX","abc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","ab*c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab*c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","ab*c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","ab*c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","ab*bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab*bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","ab*bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","ab*bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBC","ab*bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBC","ab*bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBC","ab*bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBC","ab*bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBBBC","ab*?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBBBC","ab*?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab*?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab*?bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBBBC","ab{0,}?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{0,}?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{0,}?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{0,}?bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBC","ab+?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBC","ab+?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBC","ab+?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBC","ab+?bc",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab+bc",[caseless]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","ab+bc",[caseless,
- trim]))),
+ trim]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","ab+bc",[caseless,
{parts,
- 2}]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","ab+bc",[caseless]))),
+ 2}]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","ab+bc",[caseless]))),
<<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab+bc",[caseless,
- trim]))),
+ trim]))),
<<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab+bc",[caseless,
{parts,
- 2}]))),
- <<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab+bc",[caseless]))),
+ 2}]))),
+ <<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab+bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBBBC","ab+bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBBBC","ab+bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab+bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab+bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,}?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,}?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,}?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,}?bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,3}?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,3}?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,3}?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{1,3}?bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABBBBC","ab{3,4}?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{3,4}?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{3,4}?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBBBC","ab{3,4}?bc",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}?bc",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}?bc",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}?bc",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","ab{4,5}?bc",[caseless]))),
<<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab{4,5}?bc",[caseless,
- trim]))),
+ trim]))),
<<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab{4,5}?bc",[caseless,
{parts,
- 2}]))),
- <<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab{4,5}?bc",[caseless]))),
+ 2}]))),
+ <<"ABQ">> = iolist_to_binary(join(re:split("ABQ","ab{4,5}?bc",[caseless]))),
<<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","ab{4,5}?bc",[caseless,
- trim]))),
+ trim]))),
<<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","ab{4,5}?bc",[caseless,
{parts,
- 2}]))),
- <<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","ab{4,5}?bc",[caseless]))),
+ 2}]))),
+ <<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","ab{4,5}?bc",[caseless]))),
ok.
run21() ->
<<"">> = iolist_to_binary(join(re:split("ABBC","ab??bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBC","ab??bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABBC","ab??bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABBC","ab??bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","ab??bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab??bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","ab??bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","ab??bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?bc",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?bc",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?bc",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?bc",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","ab??c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab??c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","ab??c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","ab??c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","^abc$",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","^abc$",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","^abc$",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","^abc$",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^abc$",[caseless]))),
<<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","^abc$",[caseless,
- trim]))),
+ trim]))),
<<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","^abc$",[caseless,
{parts,
- 2}]))),
- <<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","^abc$",[caseless]))),
+ 2}]))),
+ <<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","^abc$",[caseless]))),
<<"ABCC">> = iolist_to_binary(join(re:split("ABCC","^abc$",[caseless,
- trim]))),
+ trim]))),
<<"ABCC">> = iolist_to_binary(join(re:split("ABCC","^abc$",[caseless,
{parts,
- 2}]))),
- <<"ABCC">> = iolist_to_binary(join(re:split("ABCC","^abc$",[caseless]))),
+ 2}]))),
+ <<"ABCC">> = iolist_to_binary(join(re:split("ABCC","^abc$",[caseless]))),
<<":C">> = iolist_to_binary(join(re:split("ABCC","^abc",[caseless,
- trim]))),
+ trim]))),
<<":C">> = iolist_to_binary(join(re:split("ABCC","^abc",[caseless,
{parts,
- 2}]))),
- <<":C">> = iolist_to_binary(join(re:split("ABCC","^abc",[caseless]))),
+ 2}]))),
+ <<":C">> = iolist_to_binary(join(re:split("ABCC","^abc",[caseless]))),
<<"A">> = iolist_to_binary(join(re:split("AABC","abc$",[caseless,
- trim]))),
+ trim]))),
<<"A:">> = iolist_to_binary(join(re:split("AABC","abc$",[caseless,
{parts,
- 2}]))),
- <<"A:">> = iolist_to_binary(join(re:split("AABC","abc$",[caseless]))),
+ 2}]))),
+ <<"A:">> = iolist_to_binary(join(re:split("AABC","abc$",[caseless]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","^",[caseless,
- trim]))),
+ trim]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","^",[caseless,
{parts,
- 2}]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","^",[caseless]))),
+ 2}]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","^",[caseless]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","$",[caseless,
- trim]))),
+ trim]))),
<<"ABC:">> = iolist_to_binary(join(re:split("ABC","$",[caseless,
{parts,
- 2}]))),
- <<"ABC:">> = iolist_to_binary(join(re:split("ABC","$",[caseless]))),
+ 2}]))),
+ <<"ABC:">> = iolist_to_binary(join(re:split("ABC","$",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABC","a.c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","a.c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABC","a.c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABC","a.c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("AXC","a.c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("AXC","a.c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("AXC","a.c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("AXC","a.c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("AXYZC","a.*?c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("AXYZC","a.*?c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("AXYZC","a.*?c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("AXYZC","a.*?c",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.*c",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.*c",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.*c",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a.*c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("AABC","a.*c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("AABC","a.*c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("AABC","a.*c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("AABC","a.*c",[caseless]))),
<<"AXYZD">> = iolist_to_binary(join(re:split("AXYZD","a.*c",[caseless,
- trim]))),
+ trim]))),
<<"AXYZD">> = iolist_to_binary(join(re:split("AXYZD","a.*c",[caseless,
{parts,
- 2}]))),
- <<"AXYZD">> = iolist_to_binary(join(re:split("AXYZD","a.*c",[caseless]))),
+ 2}]))),
+ <<"AXYZD">> = iolist_to_binary(join(re:split("AXYZD","a.*c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABD","a[bc]d",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABD","a[bc]d",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABD","a[bc]d",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABD","a[bc]d",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ACE","a[b-d]e",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ACE","a[b-d]e",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ACE","a[b-d]e",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ACE","a[b-d]e",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[b-d]e",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[b-d]e",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[b-d]e",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[b-d]e",[caseless]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","a[b-d]e",[caseless,
- trim]))),
+ trim]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","a[b-d]e",[caseless,
{parts,
- 2}]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","a[b-d]e",[caseless]))),
+ 2}]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","a[b-d]e",[caseless]))),
<<"ABD">> = iolist_to_binary(join(re:split("ABD","a[b-d]e",[caseless,
- trim]))),
+ trim]))),
<<"ABD">> = iolist_to_binary(join(re:split("ABD","a[b-d]e",[caseless,
{parts,
- 2}]))),
- <<"ABD">> = iolist_to_binary(join(re:split("ABD","a[b-d]e",[caseless]))),
+ 2}]))),
+ <<"ABD">> = iolist_to_binary(join(re:split("ABD","a[b-d]e",[caseless]))),
<<"A">> = iolist_to_binary(join(re:split("AAC","a[b-d]",[caseless,
- trim]))),
+ trim]))),
<<"A:">> = iolist_to_binary(join(re:split("AAC","a[b-d]",[caseless,
{parts,
- 2}]))),
- <<"A:">> = iolist_to_binary(join(re:split("AAC","a[b-d]",[caseless]))),
+ 2}]))),
+ <<"A:">> = iolist_to_binary(join(re:split("AAC","a[b-d]",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("A-","a[-b]",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("A-","a[-b]",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A-","a[-b]",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A-","a[-b]",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("A-","a[b-]",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("A-","a[b-]",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A-","a[b-]",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A-","a[b-]",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("A]","a]",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("A]","a]",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A]","a]",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A]","a]",[caseless]))),
ok.
run22() ->
<<"">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("AED","a[^bc]d",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("AED","a[^bc]d",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("AED","a[^bc]d",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("AED","a[^bc]d",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ADC","a[^-b]c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ADC","a[^-b]c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ADC","a[^-b]c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ADC","a[^-b]c",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^-b]c",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^-b]c",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^-b]c",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a[^-b]c",[caseless]))),
<<"ABD">> = iolist_to_binary(join(re:split("ABD","a[^-b]c",[caseless,
- trim]))),
+ trim]))),
<<"ABD">> = iolist_to_binary(join(re:split("ABD","a[^-b]c",[caseless,
{parts,
- 2}]))),
- <<"ABD">> = iolist_to_binary(join(re:split("ABD","a[^-b]c",[caseless]))),
+ 2}]))),
+ <<"ABD">> = iolist_to_binary(join(re:split("ABD","a[^-b]c",[caseless]))),
<<"A-C">> = iolist_to_binary(join(re:split("A-C","a[^-b]c",[caseless,
- trim]))),
+ trim]))),
<<"A-C">> = iolist_to_binary(join(re:split("A-C","a[^-b]c",[caseless,
{parts,
- 2}]))),
- <<"A-C">> = iolist_to_binary(join(re:split("A-C","a[^-b]c",[caseless]))),
+ 2}]))),
+ <<"A-C">> = iolist_to_binary(join(re:split("A-C","a[^-b]c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ADC","a[^]b]c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ADC","a[^]b]c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ADC","a[^]b]c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ADC","a[^]b]c",[caseless]))),
<<":C">> = iolist_to_binary(join(re:split("ABC","ab|cd",[caseless,
- trim]))),
+ trim]))),
<<":C">> = iolist_to_binary(join(re:split("ABC","ab|cd",[caseless,
{parts,
- 2}]))),
- <<":C">> = iolist_to_binary(join(re:split("ABC","ab|cd",[caseless]))),
+ 2}]))),
+ <<":C">> = iolist_to_binary(join(re:split("ABC","ab|cd",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABCD","ab|cd",[caseless,
- trim]))),
+ trim]))),
<<":CD">> = iolist_to_binary(join(re:split("ABCD","ab|cd",[caseless,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ABCD","ab|cd",[caseless]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ABCD","ab|cd",[caseless]))),
<<"D">> = iolist_to_binary(join(re:split("DEF","()ef",[caseless,
- trim]))),
+ trim]))),
<<"D::">> = iolist_to_binary(join(re:split("DEF","()ef",[caseless,
{parts,
- 2}]))),
- <<"D::">> = iolist_to_binary(join(re:split("DEF","()ef",[caseless]))),
+ 2}]))),
+ <<"D::">> = iolist_to_binary(join(re:split("DEF","()ef",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","$b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","$b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","$b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","$b",[caseless]))),
<<"A]C">> = iolist_to_binary(join(re:split("A]C","$b",[caseless,
- trim]))),
+ trim]))),
<<"A]C">> = iolist_to_binary(join(re:split("A]C","$b",[caseless,
{parts,
- 2}]))),
- <<"A]C">> = iolist_to_binary(join(re:split("A]C","$b",[caseless]))),
+ 2}]))),
+ <<"A]C">> = iolist_to_binary(join(re:split("A]C","$b",[caseless]))),
<<"B">> = iolist_to_binary(join(re:split("B","$b",[caseless,
- trim]))),
+ trim]))),
<<"B">> = iolist_to_binary(join(re:split("B","$b",[caseless,
{parts,
- 2}]))),
- <<"B">> = iolist_to_binary(join(re:split("B","$b",[caseless]))),
+ 2}]))),
+ <<"B">> = iolist_to_binary(join(re:split("B","$b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("A(B","a\\(b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("A(B","a\\(b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A(B","a\\(b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A(B","a\\(b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("AB","a\\(*b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("AB","a\\(*b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("AB","a\\(*b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("AB","a\\(*b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("A((B","a\\(*b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("A((B","a\\(*b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("A((B","a\\(*b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A((B","a\\(*b",[caseless]))),
<<"A">> = iolist_to_binary(join(re:split("A","a\\\\b",[caseless,
notbol,
- trim]))),
+ trim]))),
<<"A">> = iolist_to_binary(join(re:split("A","a\\\\b",[caseless,
notbol,
{parts,
- 2}]))),
+ 2}]))),
<<"A">> = iolist_to_binary(join(re:split("A","a\\\\b",[caseless,
- notbol]))),
+ notbol]))),
<<":A:A:BC">> = iolist_to_binary(join(re:split("ABC","((a))",[caseless,
- trim]))),
+ trim]))),
<<":A:A:BC">> = iolist_to_binary(join(re:split("ABC","((a))",[caseless,
{parts,
- 2}]))),
- <<":A:A:BC">> = iolist_to_binary(join(re:split("ABC","((a))",[caseless]))),
+ 2}]))),
+ <<":A:A:BC">> = iolist_to_binary(join(re:split("ABC","((a))",[caseless]))),
<<":A:C">> = iolist_to_binary(join(re:split("ABC","(a)b(c)",[caseless,
- trim]))),
+ trim]))),
<<":A:C:">> = iolist_to_binary(join(re:split("ABC","(a)b(c)",[caseless,
{parts,
- 2}]))),
- <<":A:C:">> = iolist_to_binary(join(re:split("ABC","(a)b(c)",[caseless]))),
+ 2}]))),
+ <<":A:C:">> = iolist_to_binary(join(re:split("ABC","(a)b(c)",[caseless]))),
<<"AABB">> = iolist_to_binary(join(re:split("AABBABC","a+b+c",[caseless,
- trim]))),
+ trim]))),
<<"AABB:">> = iolist_to_binary(join(re:split("AABBABC","a+b+c",[caseless,
{parts,
- 2}]))),
- <<"AABB:">> = iolist_to_binary(join(re:split("AABBABC","a+b+c",[caseless]))),
+ 2}]))),
+ <<"AABB:">> = iolist_to_binary(join(re:split("AABBABC","a+b+c",[caseless]))),
<<"AABB">> = iolist_to_binary(join(re:split("AABBABC","a{1,}b{1,}c",[caseless,
- trim]))),
+ trim]))),
<<"AABB:">> = iolist_to_binary(join(re:split("AABBABC","a{1,}b{1,}c",[caseless,
{parts,
- 2}]))),
- <<"AABB:">> = iolist_to_binary(join(re:split("AABBABC","a{1,}b{1,}c",[caseless]))),
+ 2}]))),
+ <<"AABB:">> = iolist_to_binary(join(re:split("AABBABC","a{1,}b{1,}c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABCABC","a.+?c",[caseless,
- trim]))),
+ trim]))),
<<":ABC">> = iolist_to_binary(join(re:split("ABCABC","a.+?c",[caseless,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ABCABC","a.+?c",[caseless]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ABCABC","a.+?c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABCABC","a.*?c",[caseless,
- trim]))),
+ trim]))),
<<":ABC">> = iolist_to_binary(join(re:split("ABCABC","a.*?c",[caseless,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ABCABC","a.*?c",[caseless]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ABCABC","a.*?c",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABCABC","a.{0,5}?c",[caseless,
- trim]))),
+ trim]))),
<<":ABC">> = iolist_to_binary(join(re:split("ABCABC","a.{0,5}?c",[caseless,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ABCABC","a.{0,5}?c",[caseless]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ABCABC","a.{0,5}?c",[caseless]))),
<<":B">> = iolist_to_binary(join(re:split("AB","(a+|b)*",[caseless,
- trim]))),
+ trim]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)*",[caseless,
{parts,
- 2}]))),
- <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)*",[caseless]))),
+ 2}]))),
+ <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)*",[caseless]))),
<<":B">> = iolist_to_binary(join(re:split("AB","(a+|b){0,}",[caseless,
- trim]))),
+ trim]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,}",[caseless,
{parts,
- 2}]))),
- <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,}",[caseless]))),
+ 2}]))),
+ <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,}",[caseless]))),
<<":B">> = iolist_to_binary(join(re:split("AB","(a+|b)+",[caseless,
- trim]))),
+ trim]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)+",[caseless,
{parts,
- 2}]))),
- <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)+",[caseless]))),
+ 2}]))),
+ <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)+",[caseless]))),
ok.
run23() ->
<<":B">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless,
- trim]))),
+ trim]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless,
{parts,
- 2}]))),
- <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless]))),
+ 2}]))),
+ <<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless]))),
<<":A::B">> = iolist_to_binary(join(re:split("AB","(a+|b)?",[caseless,
- trim]))),
+ trim]))),
<<":A:B">> = iolist_to_binary(join(re:split("AB","(a+|b)?",[caseless,
{parts,
- 2}]))),
- <<":A::B:">> = iolist_to_binary(join(re:split("AB","(a+|b)?",[caseless]))),
+ 2}]))),
+ <<":A::B:">> = iolist_to_binary(join(re:split("AB","(a+|b)?",[caseless]))),
<<":A::B">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}",[caseless,
- trim]))),
+ trim]))),
<<":A:B">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}",[caseless,
{parts,
- 2}]))),
- <<":A::B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}",[caseless]))),
+ 2}]))),
+ <<":A::B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}",[caseless]))),
<<":A::B">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}?",[caseless,
- trim]))),
+ trim]))),
<<":A:B">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}?",[caseless,
{parts,
- 2}]))),
- <<":A::B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}?",[caseless]))),
+ 2}]))),
+ <<":A::B:">> = iolist_to_binary(join(re:split("AB","(a+|b){0,1}?",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("CDE","[^ab]*",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("CDE","[^ab]*",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("CDE","[^ab]*",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("CDE","[^ab]*",[caseless]))),
<<":C">> = iolist_to_binary(join(re:split("ABBBCD","([abc])*d",[caseless,
- trim]))),
+ trim]))),
<<":C:">> = iolist_to_binary(join(re:split("ABBBCD","([abc])*d",[caseless,
{parts,
- 2}]))),
- <<":C:">> = iolist_to_binary(join(re:split("ABBBCD","([abc])*d",[caseless]))),
+ 2}]))),
+ <<":C:">> = iolist_to_binary(join(re:split("ABBBCD","([abc])*d",[caseless]))),
<<":A">> = iolist_to_binary(join(re:split("ABCD","([abc])*bcd",[caseless,
- trim]))),
+ trim]))),
<<":A:">> = iolist_to_binary(join(re:split("ABCD","([abc])*bcd",[caseless,
{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("ABCD","([abc])*bcd",[caseless]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("ABCD","([abc])*bcd",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("E","a|b|c|d|e",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("E","a|b|c|d|e",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("E","a|b|c|d|e",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("E","a|b|c|d|e",[caseless]))),
<<":E">> = iolist_to_binary(join(re:split("EF","(a|b|c|d|e)f",[caseless,
- trim]))),
+ trim]))),
<<":E:">> = iolist_to_binary(join(re:split("EF","(a|b|c|d|e)f",[caseless,
{parts,
- 2}]))),
- <<":E:">> = iolist_to_binary(join(re:split("EF","(a|b|c|d|e)f",[caseless]))),
+ 2}]))),
+ <<":E:">> = iolist_to_binary(join(re:split("EF","(a|b|c|d|e)f",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ABCDEFG","abcd*efg",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABCDEFG","abcd*efg",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABCDEFG","abcd*efg",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABCDEFG","abcd*efg",[caseless]))),
<<"X:Y:Z">> = iolist_to_binary(join(re:split("XABYABBBZ","ab*",[caseless,
- trim]))),
+ trim]))),
<<"X:YABBBZ">> = iolist_to_binary(join(re:split("XABYABBBZ","ab*",[caseless,
{parts,
- 2}]))),
- <<"X:Y:Z">> = iolist_to_binary(join(re:split("XABYABBBZ","ab*",[caseless]))),
+ 2}]))),
+ <<"X:Y:Z">> = iolist_to_binary(join(re:split("XABYABBBZ","ab*",[caseless]))),
<<"X:Y:Z">> = iolist_to_binary(join(re:split("XAYABBBZ","ab*",[caseless,
- trim]))),
+ trim]))),
<<"X:YABBBZ">> = iolist_to_binary(join(re:split("XAYABBBZ","ab*",[caseless,
{parts,
- 2}]))),
- <<"X:Y:Z">> = iolist_to_binary(join(re:split("XAYABBBZ","ab*",[caseless]))),
+ 2}]))),
+ <<"X:Y:Z">> = iolist_to_binary(join(re:split("XAYABBBZ","ab*",[caseless]))),
<<"AB:CD">> = iolist_to_binary(join(re:split("ABCDE","(ab|cd)e",[caseless,
- trim]))),
+ trim]))),
<<"AB:CD:">> = iolist_to_binary(join(re:split("ABCDE","(ab|cd)e",[caseless,
{parts,
- 2}]))),
- <<"AB:CD:">> = iolist_to_binary(join(re:split("ABCDE","(ab|cd)e",[caseless]))),
+ 2}]))),
+ <<"AB:CD:">> = iolist_to_binary(join(re:split("ABCDE","(ab|cd)e",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("HIJ","[abhgefdc]ij",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("HIJ","[abhgefdc]ij",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("HIJ","[abhgefdc]ij",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("HIJ","[abhgefdc]ij",[caseless]))),
<<"ABCDE">> = iolist_to_binary(join(re:split("ABCDE","^(ab|cd)e",[caseless,
- trim]))),
+ trim]))),
<<"ABCDE">> = iolist_to_binary(join(re:split("ABCDE","^(ab|cd)e",[caseless,
{parts,
- 2}]))),
- <<"ABCDE">> = iolist_to_binary(join(re:split("ABCDE","^(ab|cd)e",[caseless]))),
+ 2}]))),
+ <<"ABCDE">> = iolist_to_binary(join(re:split("ABCDE","^(ab|cd)e",[caseless]))),
<<"ABCD">> = iolist_to_binary(join(re:split("ABCDEF","(abc|)ef",[caseless,
- trim]))),
+ trim]))),
<<"ABCD::">> = iolist_to_binary(join(re:split("ABCDEF","(abc|)ef",[caseless,
{parts,
- 2}]))),
- <<"ABCD::">> = iolist_to_binary(join(re:split("ABCDEF","(abc|)ef",[caseless]))),
+ 2}]))),
+ <<"ABCD::">> = iolist_to_binary(join(re:split("ABCDEF","(abc|)ef",[caseless]))),
<<"A:B">> = iolist_to_binary(join(re:split("ABCD","(a|b)c*d",[caseless,
- trim]))),
+ trim]))),
<<"A:B:">> = iolist_to_binary(join(re:split("ABCD","(a|b)c*d",[caseless,
{parts,
- 2}]))),
- <<"A:B:">> = iolist_to_binary(join(re:split("ABCD","(a|b)c*d",[caseless]))),
+ 2}]))),
+ <<"A:B:">> = iolist_to_binary(join(re:split("ABCD","(a|b)c*d",[caseless]))),
<<":A">> = iolist_to_binary(join(re:split("ABC","(ab|ab*)bc",[caseless,
- trim]))),
+ trim]))),
<<":A:">> = iolist_to_binary(join(re:split("ABC","(ab|ab*)bc",[caseless,
{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("ABC","(ab|ab*)bc",[caseless]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("ABC","(ab|ab*)bc",[caseless]))),
<<":BC">> = iolist_to_binary(join(re:split("ABC","a([bc]*)c*",[caseless,
- trim]))),
+ trim]))),
<<":BC:">> = iolist_to_binary(join(re:split("ABC","a([bc]*)c*",[caseless,
{parts,
- 2}]))),
- <<":BC:">> = iolist_to_binary(join(re:split("ABC","a([bc]*)c*",[caseless]))),
+ 2}]))),
+ <<":BC:">> = iolist_to_binary(join(re:split("ABC","a([bc]*)c*",[caseless]))),
ok.
run24() ->
<<":BC:D">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless,
- trim]))),
+ trim]))),
<<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless,
{parts,
- 2}]))),
- <<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless]))),
+ 2}]))),
+ <<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless]))),
<<":BC:D">> = iolist_to_binary(join(re:split("ABCD","a([bc]+)(c*d)",[caseless,
- trim]))),
+ trim]))),
<<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]+)(c*d)",[caseless,
{parts,
- 2}]))),
- <<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]+)(c*d)",[caseless]))),
+ 2}]))),
+ <<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]+)(c*d)",[caseless]))),
<<":B:CD">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c+d)",[caseless,
- trim]))),
+ trim]))),
<<":B:CD:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c+d)",[caseless,
{parts,
- 2}]))),
- <<":B:CD:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c+d)",[caseless]))),
+ 2}]))),
+ <<":B:CD:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c+d)",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ADCDCDE","a[bcd]*dcdcde",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ADCDCDE","a[bcd]*dcdcde",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ADCDCDE","a[bcd]*dcdcde",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ADCDCDE","a[bcd]*dcdcde",[caseless]))),
<<":AB">> = iolist_to_binary(join(re:split("ABC","(ab|a)b*c",[caseless,
- trim]))),
+ trim]))),
<<":AB:">> = iolist_to_binary(join(re:split("ABC","(ab|a)b*c",[caseless,
{parts,
- 2}]))),
- <<":AB:">> = iolist_to_binary(join(re:split("ABC","(ab|a)b*c",[caseless]))),
+ 2}]))),
+ <<":AB:">> = iolist_to_binary(join(re:split("ABC","(ab|a)b*c",[caseless]))),
<<":ABC:A:B:D">> = iolist_to_binary(join(re:split("ABCD","((a)(b)c)(d)",[caseless,
- trim]))),
+ trim]))),
<<":ABC:A:B:D:">> = iolist_to_binary(join(re:split("ABCD","((a)(b)c)(d)",[caseless,
{parts,
- 2}]))),
- <<":ABC:A:B:D:">> = iolist_to_binary(join(re:split("ABCD","((a)(b)c)(d)",[caseless]))),
+ 2}]))),
+ <<":ABC:A:B:D:">> = iolist_to_binary(join(re:split("ABCD","((a)(b)c)(d)",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*",[caseless]))),
<<"A">> = iolist_to_binary(join(re:split("ABH","^a(bc+|b[eh])g|.h$",[caseless,
- trim]))),
+ trim]))),
<<"A::">> = iolist_to_binary(join(re:split("ABH","^a(bc+|b[eh])g|.h$",[caseless,
{parts,
- 2}]))),
- <<"A::">> = iolist_to_binary(join(re:split("ABH","^a(bc+|b[eh])g|.h$",[caseless]))),
+ 2}]))),
+ <<"A::">> = iolist_to_binary(join(re:split("ABH","^a(bc+|b[eh])g|.h$",[caseless]))),
<<":EFFGZ">> = iolist_to_binary(join(re:split("EFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<":EFFGZ::">> = iolist_to_binary(join(re:split("EFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<":EFFGZ::">> = iolist_to_binary(join(re:split("EFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<":EFFGZ::">> = iolist_to_binary(join(re:split("EFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<":IJ:J">> = iolist_to_binary(join(re:split("IJ","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<":IJ:J:">> = iolist_to_binary(join(re:split("IJ","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<":IJ:J:">> = iolist_to_binary(join(re:split("IJ","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<":IJ:J:">> = iolist_to_binary(join(re:split("IJ","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<"R:EFFGZ">> = iolist_to_binary(join(re:split("REFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<"R:EFFGZ::">> = iolist_to_binary(join(re:split("REFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<"R:EFFGZ::">> = iolist_to_binary(join(re:split("REFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<"R:EFFGZ::">> = iolist_to_binary(join(re:split("REFFGZ","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<"ADCDCDE">> = iolist_to_binary(join(re:split("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<"ADCDCDE">> = iolist_to_binary(join(re:split("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<"ADCDCDE">> = iolist_to_binary(join(re:split("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<"ADCDCDE">> = iolist_to_binary(join(re:split("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<"EFFG">> = iolist_to_binary(join(re:split("EFFG","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<"EFFG">> = iolist_to_binary(join(re:split("EFFG","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<"EFFG">> = iolist_to_binary(join(re:split("EFFG","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<"EFFG">> = iolist_to_binary(join(re:split("EFFG","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<"BCDD">> = iolist_to_binary(join(re:split("BCDD","(bc+d$|ef*g.|h?i(j|k))",[caseless,
- trim]))),
+ trim]))),
<<"BCDD">> = iolist_to_binary(join(re:split("BCDD","(bc+d$|ef*g.|h?i(j|k))",[caseless,
{parts,
- 2}]))),
- <<"BCDD">> = iolist_to_binary(join(re:split("BCDD","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
+ 2}]))),
+ <<"BCDD">> = iolist_to_binary(join(re:split("BCDD","(bc+d$|ef*g.|h?i(j|k))",[caseless]))),
<<":A:A:A:A:A:A:A:A:A:A">> = iolist_to_binary(join(re:split("A","((((((((((a))))))))))",[caseless,
- trim]))),
+ trim]))),
<<":A:A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("A","((((((((((a))))))))))",[caseless,
{parts,
- 2}]))),
- <<":A:A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("A","((((((((((a))))))))))",[caseless]))),
+ 2}]))),
+ <<":A:A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("A","((((((((((a))))))))))",[caseless]))),
<<":A:A:A:A:A:A:A:A:A:A">> = iolist_to_binary(join(re:split("AA","((((((((((a))))))))))\\10",[caseless,
- trim]))),
+ trim]))),
<<":A:A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("AA","((((((((((a))))))))))\\10",[caseless,
{parts,
- 2}]))),
- <<":A:A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("AA","((((((((((a))))))))))\\10",[caseless]))),
+ 2}]))),
+ <<":A:A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("AA","((((((((((a))))))))))\\10",[caseless]))),
<<":A:A:A:A:A:A:A:A:A">> = iolist_to_binary(join(re:split("A","(((((((((a)))))))))",[caseless,
- trim]))),
+ trim]))),
<<":A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("A","(((((((((a)))))))))",[caseless,
{parts,
- 2}]))),
- <<":A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("A","(((((((((a)))))))))",[caseless]))),
+ 2}]))),
+ <<":A:A:A:A:A:A:A:A:A:">> = iolist_to_binary(join(re:split("A","(((((((((a)))))))))",[caseless]))),
<<":A">> = iolist_to_binary(join(re:split("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))",[caseless,
- trim]))),
+ trim]))),
<<":A:">> = iolist_to_binary(join(re:split("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))",[caseless,
{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))",[caseless]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))",[caseless]))),
<<":C">> = iolist_to_binary(join(re:split("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))",[caseless,
- trim]))),
+ trim]))),
<<":C:">> = iolist_to_binary(join(re:split("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))",[caseless,
{parts,
- 2}]))),
- <<":C:">> = iolist_to_binary(join(re:split("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))",[caseless]))),
+ 2}]))),
+ <<":C:">> = iolist_to_binary(join(re:split("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","multiple words of text",[caseless]))),
<<"AA">> = iolist_to_binary(join(re:split("AA","multiple words of text",[caseless,
- trim]))),
+ trim]))),
<<"AA">> = iolist_to_binary(join(re:split("AA","multiple words of text",[caseless,
{parts,
- 2}]))),
- <<"AA">> = iolist_to_binary(join(re:split("AA","multiple words of text",[caseless]))),
+ 2}]))),
+ <<"AA">> = iolist_to_binary(join(re:split("AA","multiple words of text",[caseless]))),
<<"UH-UH">> = iolist_to_binary(join(re:split("UH-UH","multiple words of text",[caseless,
- trim]))),
+ trim]))),
<<"UH-UH">> = iolist_to_binary(join(re:split("UH-UH","multiple words of text",[caseless,
{parts,
- 2}]))),
- <<"UH-UH">> = iolist_to_binary(join(re:split("UH-UH","multiple words of text",[caseless]))),
+ 2}]))),
+ <<"UH-UH">> = iolist_to_binary(join(re:split("UH-UH","multiple words of text",[caseless]))),
<<":, YEAH">> = iolist_to_binary(join(re:split("MULTIPLE WORDS, YEAH","multiple words",[caseless,
- trim]))),
+ trim]))),
<<":, YEAH">> = iolist_to_binary(join(re:split("MULTIPLE WORDS, YEAH","multiple words",[caseless,
{parts,
- 2}]))),
- <<":, YEAH">> = iolist_to_binary(join(re:split("MULTIPLE WORDS, YEAH","multiple words",[caseless]))),
+ 2}]))),
+ <<":, YEAH">> = iolist_to_binary(join(re:split("MULTIPLE WORDS, YEAH","multiple words",[caseless]))),
<<":AB:DE">> = iolist_to_binary(join(re:split("ABCDE","(.*)c(.*)",[caseless,
- trim]))),
+ trim]))),
<<":AB:DE:">> = iolist_to_binary(join(re:split("ABCDE","(.*)c(.*)",[caseless,
{parts,
- 2}]))),
- <<":AB:DE:">> = iolist_to_binary(join(re:split("ABCDE","(.*)c(.*)",[caseless]))),
+ 2}]))),
+ <<":AB:DE:">> = iolist_to_binary(join(re:split("ABCDE","(.*)c(.*)",[caseless]))),
<<":A:B">> = iolist_to_binary(join(re:split("(A, B)","\\((.*), (.*)\\)",[caseless,
- trim]))),
+ trim]))),
<<":A:B:">> = iolist_to_binary(join(re:split("(A, B)","\\((.*), (.*)\\)",[caseless,
{parts,
- 2}]))),
- <<":A:B:">> = iolist_to_binary(join(re:split("(A, B)","\\((.*), (.*)\\)",[caseless]))),
+ 2}]))),
+ <<":A:B:">> = iolist_to_binary(join(re:split("(A, B)","\\((.*), (.*)\\)",[caseless]))),
ok.
run25() ->
<<"">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless]))),
<<":BC">> = iolist_to_binary(join(re:split("ABCD","a(bc)d",[caseless,
- trim]))),
+ trim]))),
<<":BC:">> = iolist_to_binary(join(re:split("ABCD","a(bc)d",[caseless,
{parts,
- 2}]))),
- <<":BC:">> = iolist_to_binary(join(re:split("ABCD","a(bc)d",[caseless]))),
+ 2}]))),
+ <<":BC:">> = iolist_to_binary(join(re:split("ABCD","a(bc)d",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("AC","a[-]?c",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("AC","a[-]?c",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("AC","a[-]?c",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("AC","a[-]?c",[caseless]))),
<<":ABC">> = iolist_to_binary(join(re:split("ABCABC","(abc)\\1",[caseless,
- trim]))),
+ trim]))),
<<":ABC:">> = iolist_to_binary(join(re:split("ABCABC","(abc)\\1",[caseless,
{parts,
- 2}]))),
- <<":ABC:">> = iolist_to_binary(join(re:split("ABCABC","(abc)\\1",[caseless]))),
+ 2}]))),
+ <<":ABC:">> = iolist_to_binary(join(re:split("ABCABC","(abc)\\1",[caseless]))),
<<":ABC">> = iolist_to_binary(join(re:split("ABCABC","([a-c]*)\\1",[caseless,
- trim]))),
+ trim]))),
<<":ABC:">> = iolist_to_binary(join(re:split("ABCABC","([a-c]*)\\1",[caseless,
{parts,
- 2}]))),
- <<":ABC:">> = iolist_to_binary(join(re:split("ABCABC","([a-c]*)\\1",[caseless]))),
- <<"ab">> = iolist_to_binary(join(re:split("abad","a(?!b).",[trim]))),
+ 2}]))),
+ <<":ABC:">> = iolist_to_binary(join(re:split("ABCABC","([a-c]*)\\1",[caseless]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abad","a(?!b).",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abad","a(?!b).",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abad","a(?!b).",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("abad","a(?=d).",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abad","a(?!b).",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abad","a(?=d).",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abad","a(?=d).",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abad","a(?=d).",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("abad","a(?=c|d).",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abad","a(?=d).",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abad","a(?=c|d).",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abad","a(?=c|d).",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abad","a(?=c|d).",[]))),
- <<":e">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)(.)",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abad","a(?=c|d).",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)(.)",[]))),
- <<":e">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)*(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)(.)",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)*(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)*(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)*(.)",[]))),
- <<":e">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)+?(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)*(.)",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)+?(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)+?(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)+?(.)",[]))),
- <<":d:bcdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+?(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("ace","a(?:b|c|d)+?(.)",[]))),
+ <<":d:bcdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+?(.)",[trim]))),
<<":d:bcdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+?(.)",[{parts,
- 2}]))),
- <<":d:bcdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+?(.)",[]))),
- <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+(.)",[trim]))),
+ 2}]))),
+ <<":d:bcdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+?(.)",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+(.)",[]))),
- <<":b:cdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){2}(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d)+(.)",[]))),
+ <<":b:cdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){2}(.)",[trim]))),
<<":b:cdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){2}(.)",[{parts,
- 2}]))),
- <<":b:cdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){2}(.)",[]))),
- <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}(.)",[trim]))),
+ 2}]))),
+ <<":b:cdbe">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){2}(.)",[]))),
+ <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}(.)",[trim]))),
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}(.)",[{parts,
- 2}]))),
- <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}(.)",[]))),
- <<":d:be">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}?(.)",[trim]))),
+ 2}]))),
+ <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}(.)",[]))),
+ <<":d:be">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}?(.)",[trim]))),
<<":d:be">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}?(.)",[{parts,
- 2}]))),
- <<":d:be">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}?(.)",[]))),
- <<":bar:foo:bar">> = iolist_to_binary(join(re:split("foobar","((foo)|(bar))*",[trim]))),
+ 2}]))),
+ <<":d:be">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){4,5}?(.)",[]))),
+ <<":bar:foo:bar">> = iolist_to_binary(join(re:split("foobar","((foo)|(bar))*",[trim]))),
<<":bar:foo:bar:">> = iolist_to_binary(join(re:split("foobar","((foo)|(bar))*",[{parts,
- 2}]))),
- <<":bar:foo:bar:">> = iolist_to_binary(join(re:split("foobar","((foo)|(bar))*",[]))),
- <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}(.)",[trim]))),
+ 2}]))),
+ <<":bar:foo:bar:">> = iolist_to_binary(join(re:split("foobar","((foo)|(bar))*",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}(.)",[]))),
- <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}?(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}(.)",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}?(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}?(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}?(.)",[]))),
- <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){6,7}?(.)",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}(.)",[]))),
- <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}(.)",[]))),
+ <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[trim]))),
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[{parts,
- 2}]))),
- <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[]))),
+ 2}]))),
+ <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[]))),
ok.
run26() ->
- <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[trim]))),
+ <<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[]))),
- <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[]))),
+ <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[trim]))),
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[{parts,
- 2}]))),
- <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[]))),
- <<":c:e">> = iolist_to_binary(join(re:split("ace","a(?:b|(c|e){1,2}?|d)+?(.)",[trim]))),
+ 2}]))),
+ <<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[]))),
+ <<":c:e">> = iolist_to_binary(join(re:split("ace","a(?:b|(c|e){1,2}?|d)+?(.)",[trim]))),
<<":c:e:">> = iolist_to_binary(join(re:split("ace","a(?:b|(c|e){1,2}?|d)+?(.)",[{parts,
- 2}]))),
- <<":c:e:">> = iolist_to_binary(join(re:split("ace","a(?:b|(c|e){1,2}?|d)+?(.)",[]))),
- <<":A">> = iolist_to_binary(join(re:split("AB","^(.+)?B",[trim]))),
+ 2}]))),
+ <<":c:e:">> = iolist_to_binary(join(re:split("ace","a(?:b|(c|e){1,2}?|d)+?(.)",[]))),
+ <<":A">> = iolist_to_binary(join(re:split("AB","^(.+)?B",[trim]))),
<<":A:">> = iolist_to_binary(join(re:split("AB","^(.+)?B",[{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("AB","^(.+)?B",[]))),
- <<":.">> = iolist_to_binary(join(re:split(".","^([^a-z])|(\\^)$",[trim]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("AB","^(.+)?B",[]))),
+ <<":.">> = iolist_to_binary(join(re:split(".","^([^a-z])|(\\^)$",[trim]))),
<<":.::">> = iolist_to_binary(join(re:split(".","^([^a-z])|(\\^)$",[{parts,
- 2}]))),
- <<":.::">> = iolist_to_binary(join(re:split(".","^([^a-z])|(\\^)$",[]))),
- <<":OUT">> = iolist_to_binary(join(re:split("<&OUT","^[<>]&",[trim]))),
+ 2}]))),
+ <<":.::">> = iolist_to_binary(join(re:split(".","^([^a-z])|(\\^)$",[]))),
+ <<":OUT">> = iolist_to_binary(join(re:split("<&OUT","^[<>]&",[trim]))),
<<":OUT">> = iolist_to_binary(join(re:split("<&OUT","^[<>]&",[{parts,
- 2}]))),
- <<":OUT">> = iolist_to_binary(join(re:split("<&OUT","^[<>]&",[]))),
- <<":aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<":OUT">> = iolist_to_binary(join(re:split("<&OUT","^[<>]&",[]))),
+ <<":aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a\\1?){4}$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a\\1?){4}$",[]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a\\1?){4}$",[]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","^(a\\1?){4}$",[trim]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[trim]))),
<<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[]))),
- <<":aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a(?(1)\\1)){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a\\1?){4}$",[]))),
+ <<":aaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a(?(1)\\1)){4}$",[trim]))),
<<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a(?(1)\\1)){4}$",[{parts,
- 2}]))),
- <<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a(?(1)\\1)){4}$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a(?(1)\\1)){4}$",[trim]))),
+ 2}]))),
+ <<":aaaa:">> = iolist_to_binary(join(re:split("aaaaaaaaaa","^(a(?(1)\\1)){4}$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a(?(1)\\1)){4}$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a(?(1)\\1)){4}$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a(?(1)\\1)){4}$",[]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a(?(1)\\1)){4}$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a(?(1)\\1)){4}$",[]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a(?(1)\\1)){4}$",[trim]))),
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a(?(1)\\1)){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a(?(1)\\1)){4}$",[]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a(?(1)\\1)){4}$",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a(?(1)\\1)){4}$",[]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a(?(1)\\1)){4}$",[trim]))),
<<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a(?(1)\\1)){4}$",[{parts,
- 2}]))),
- <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a(?(1)\\1)){4}$",[]))),
- <<":f:o:o:b:a:r">> = iolist_to_binary(join(re:split("foobar","(?:(f)(o)(o)|(b)(a)(r))*",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaa","^(a(?(1)\\1)){4}$",[]))),
+ <<":f:o:o:b:a:r">> = iolist_to_binary(join(re:split("foobar","(?:(f)(o)(o)|(b)(a)(r))*",[trim]))),
<<":f:o:o:b:a:r:">> = iolist_to_binary(join(re:split("foobar","(?:(f)(o)(o)|(b)(a)(r))*",[{parts,
- 2}]))),
- <<":f:o:o:b:a:r:">> = iolist_to_binary(join(re:split("foobar","(?:(f)(o)(o)|(b)(a)(r))*",[]))),
- <<"a">> = iolist_to_binary(join(re:split("ab","(?<=a)b",[trim]))),
+ 2}]))),
+ <<":f:o:o:b:a:r:">> = iolist_to_binary(join(re:split("foobar","(?:(f)(o)(o)|(b)(a)(r))*",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("ab","(?<=a)b",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("ab","(?<=a)b",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("ab","(?<=a)b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a)b",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("ab","(?<=a)b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a)b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a)b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a)b",[]))),
- <<"cb">> = iolist_to_binary(join(re:split("cb","(?<=a)b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=a)b",[]))),
+ <<"cb">> = iolist_to_binary(join(re:split("cb","(?<=a)b",[trim]))),
<<"cb">> = iolist_to_binary(join(re:split("cb","(?<=a)b",[{parts,
- 2}]))),
- <<"cb">> = iolist_to_binary(join(re:split("cb","(?<=a)b",[]))),
- <<"b">> = iolist_to_binary(join(re:split("b","(?<=a)b",[trim]))),
+ 2}]))),
+ <<"cb">> = iolist_to_binary(join(re:split("cb","(?<=a)b",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","(?<=a)b",[trim]))),
<<"b">> = iolist_to_binary(join(re:split("b","(?<=a)b",[{parts,
- 2}]))),
- <<"b">> = iolist_to_binary(join(re:split("b","(?<=a)b",[]))),
- <<"a">> = iolist_to_binary(join(re:split("ab","(?<!c)b",[trim]))),
+ 2}]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","(?<=a)b",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("ab","(?<!c)b",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("ab","(?<!c)b",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("ab","(?<!c)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","(?<!c)b",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("ab","(?<!c)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","(?<!c)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("b","(?<!c)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("b","(?<!c)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","(?<!c)b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("b","(?<!c)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","(?<!c)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("b","(?<!c)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("b","(?<!c)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("aba","(?:..)*a",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("b","(?<!c)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aba","(?:..)*a",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aba","(?:..)*a",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aba","(?:..)*a",[]))),
- <<":b">> = iolist_to_binary(join(re:split("aba","(?:..)*?a",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aba","(?:..)*a",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("aba","(?:..)*?a",[trim]))),
<<":ba">> = iolist_to_binary(join(re:split("aba","(?:..)*?a",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("aba","(?:..)*?a",[]))),
- <<":b:c">> = iolist_to_binary(join(re:split("abc","^(?:b|a(?=(.)))*\\1",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("aba","(?:..)*?a",[]))),
+ <<":b:c">> = iolist_to_binary(join(re:split("abc","^(?:b|a(?=(.)))*\\1",[trim]))),
<<":b:c">> = iolist_to_binary(join(re:split("abc","^(?:b|a(?=(.)))*\\1",[{parts,
- 2}]))),
- <<":b:c">> = iolist_to_binary(join(re:split("abc","^(?:b|a(?=(.)))*\\1",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(){3,5}",[trim]))),
+ 2}]))),
+ <<":b:c">> = iolist_to_binary(join(re:split("abc","^(?:b|a(?=(.)))*\\1",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(){3,5}",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^(){3,5}",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(){3,5}",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aax","^(a+)*ax",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(){3,5}",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aax","^(a+)*ax",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aax","^(a+)*ax",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aax","^(a+)*ax",[]))),
- <<":a:a">> = iolist_to_binary(join(re:split("aax","^((a|b)+)*ax",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aax","^(a+)*ax",[]))),
+ <<":a:a">> = iolist_to_binary(join(re:split("aax","^((a|b)+)*ax",[trim]))),
<<":a:a:">> = iolist_to_binary(join(re:split("aax","^((a|b)+)*ax",[{parts,
- 2}]))),
- <<":a:a:">> = iolist_to_binary(join(re:split("aax","^((a|b)+)*ax",[]))),
- <<":a:a">> = iolist_to_binary(join(re:split("aax","^((a|bc)+)*ax",[trim]))),
+ 2}]))),
+ <<":a:a:">> = iolist_to_binary(join(re:split("aax","^((a|b)+)*ax",[]))),
+ <<":a:a">> = iolist_to_binary(join(re:split("aax","^((a|bc)+)*ax",[trim]))),
<<":a:a:">> = iolist_to_binary(join(re:split("aax","^((a|bc)+)*ax",[{parts,
- 2}]))),
- <<":a:a:">> = iolist_to_binary(join(re:split("aax","^((a|bc)+)*ax",[]))),
- <<"c">> = iolist_to_binary(join(re:split("cab","(a|x)*ab",[trim]))),
+ 2}]))),
+ <<":a:a:">> = iolist_to_binary(join(re:split("aax","^((a|bc)+)*ax",[]))),
+ <<"c">> = iolist_to_binary(join(re:split("cab","(a|x)*ab",[trim]))),
<<"c::">> = iolist_to_binary(join(re:split("cab","(a|x)*ab",[{parts,
- 2}]))),
- <<"c::">> = iolist_to_binary(join(re:split("cab","(a|x)*ab",[]))),
- <<"c">> = iolist_to_binary(join(re:split("cab","(a)*ab",[trim]))),
+ 2}]))),
+ <<"c::">> = iolist_to_binary(join(re:split("cab","(a|x)*ab",[]))),
+ <<"c">> = iolist_to_binary(join(re:split("cab","(a)*ab",[trim]))),
<<"c::">> = iolist_to_binary(join(re:split("cab","(a)*ab",[{parts,
- 2}]))),
- <<"c::">> = iolist_to_binary(join(re:split("cab","(a)*ab",[]))),
+ 2}]))),
+ <<"c::">> = iolist_to_binary(join(re:split("cab","(a)*ab",[]))),
ok.
run27() ->
- <<"">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("Ab","(?:(?i)a)b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("Ab","(?:(?i)a)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("Ab","(?:(?i)a)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("Ab","(?:(?i)a)b",[]))),
- <<":A">> = iolist_to_binary(join(re:split("Ab","((?i)a)b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("Ab","(?:(?i)a)b",[]))),
+ <<":A">> = iolist_to_binary(join(re:split("Ab","((?i)a)b",[trim]))),
<<":A:">> = iolist_to_binary(join(re:split("Ab","((?i)a)b",[{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("Ab","((?i)a)b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?i)a)b",[trim]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("Ab","((?i)a)b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?i)a)b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?i)a)b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?i)a)b",[]))),
- <<"cb">> = iolist_to_binary(join(re:split("cb","(?:(?i)a)b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?i)a)b",[]))),
+ <<"cb">> = iolist_to_binary(join(re:split("cb","(?:(?i)a)b",[trim]))),
<<"cb">> = iolist_to_binary(join(re:split("cb","(?:(?i)a)b",[{parts,
- 2}]))),
- <<"cb">> = iolist_to_binary(join(re:split("cb","(?:(?i)a)b",[]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(?i)a)b",[trim]))),
+ 2}]))),
+ <<"cb">> = iolist_to_binary(join(re:split("cb","(?:(?i)a)b",[]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(?i)a)b",[trim]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","(?:(?i)a)b",[{parts,
- 2}]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(?i)a)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab","(?i:a)b",[trim]))),
+ 2}]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?:(?i)a)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","(?i:a)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?i:a)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","(?i:a)b",[]))),
- <<":a">> = iolist_to_binary(join(re:split("ab","((?i:a))b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","(?i:a)b",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("ab","((?i:a))b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","((?i:a))b",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ab","((?i:a))b",[]))),
- <<"">> = iolist_to_binary(join(re:split("Ab","(?i:a)b",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ab","((?i:a))b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("Ab","(?i:a)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("Ab","(?i:a)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("Ab","(?i:a)b",[]))),
- <<":A">> = iolist_to_binary(join(re:split("Ab","((?i:a))b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("Ab","(?i:a)b",[]))),
+ <<":A">> = iolist_to_binary(join(re:split("Ab","((?i:a))b",[trim]))),
<<":A:">> = iolist_to_binary(join(re:split("Ab","((?i:a))b",[{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("Ab","((?i:a))b",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i:a)b",[trim]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("Ab","((?i:a))b",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i:a)b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i:a)b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i:a)b",[]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i:a)b",[]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[trim]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[{parts,
- 2}]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[trim]))),
+ 2}]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[trim]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[{parts,
- 2}]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[]))),
+ 2}]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:a)b",[]))),
<<"">> = iolist_to_binary(join(re:split("ab","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","(?:(?-i)a)b",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("ab","((?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","((?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ab","((?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ab","((?-i)a)b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aB","(?:(?-i)a)b",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless]))),
ok.
run28() ->
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?:(?-i)a)b",[caseless]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?:(?-i)a)b",[caseless,
- trim]))),
+ trim]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?:(?-i)a)b",[caseless,
{parts,
- 2}]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","(?:(?-i)a)b",[caseless]))),
+ 2}]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","(?:(?-i)a)b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("ab","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","(?-i:a)b",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("ab","((?-i:a))b",[caseless,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","((?-i:a))b",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ab","((?-i:a))b",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ab","((?-i:a))b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless]))),
<<"">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aB","(?-i:a)b",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aB","((?-i:a))b",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?-i:a)b",[caseless]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<"Ab">> = iolist_to_binary(join(re:split("Ab","(?-i:a)b",[caseless]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless,
- trim]))),
+ trim]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless,
{parts,
- 2}]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless]))),
+ 2}]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","(?-i:a)b",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?-i:a.))b",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?-i:a.))b",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?-i:a.))b",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?-i:a.))b",[caseless]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","((?-i:a.))b",[caseless,
- trim]))),
+ trim]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","((?-i:a.))b",[caseless,
{parts,
- 2}]))),
- <<"AB">> = iolist_to_binary(join(re:split("AB","((?-i:a.))b",[caseless]))),
+ 2}]))),
+ <<"AB">> = iolist_to_binary(join(re:split("AB","((?-i:a.))b",[caseless]))),
<<"a
B">> = iolist_to_binary(join(re:split("a
-B","((?-i:a.))b",[caseless,trim]))),
+B","((?-i:a.))b",[caseless,trim]))),
<<"a
B">> = iolist_to_binary(join(re:split("a
-B","((?-i:a.))b",[caseless,{parts,2}]))),
+B","((?-i:a.))b",[caseless,{parts,2}]))),
<<"a
B">> = iolist_to_binary(join(re:split("a
-B","((?-i:a.))b",[caseless]))),
+B","((?-i:a.))b",[caseless]))),
<<":a
">> = iolist_to_binary(join(re:split("a
-B","((?s-i:a.))b",[caseless,trim]))),
+B","((?s-i:a.))b",[caseless,trim]))),
<<":a
:">> = iolist_to_binary(join(re:split("a
-B","((?s-i:a.))b",[caseless,{parts,2}]))),
+B","((?s-i:a.))b",[caseless,{parts,2}]))),
<<":a
:">> = iolist_to_binary(join(re:split("a
-B","((?s-i:a.))b",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))",[trim]))),
+B","((?s-i:a.))b",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))",[trim]))),
<<":">> = iolist_to_binary(join(re:split("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))",[]))),
- <<"">> = iolist_to_binary(join(re:split("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))",[]))),
+ <<"">> = iolist_to_binary(join(re:split("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))",[trim]))),
<<":">> = iolist_to_binary(join(re:split("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))",[]))),
<<":Ab">> = iolist_to_binary(join(re:split("Ab4ab","(ab)\\d\\1",[caseless,
- trim]))),
+ trim]))),
<<":Ab:">> = iolist_to_binary(join(re:split("Ab4ab","(ab)\\d\\1",[caseless,
{parts,
- 2}]))),
- <<":Ab:">> = iolist_to_binary(join(re:split("Ab4ab","(ab)\\d\\1",[caseless]))),
+ 2}]))),
+ <<":Ab:">> = iolist_to_binary(join(re:split("Ab4ab","(ab)\\d\\1",[caseless]))),
<<":ab">> = iolist_to_binary(join(re:split("ab4Ab","(ab)\\d\\1",[caseless,
- trim]))),
+ trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("ab4Ab","(ab)\\d\\1",[caseless,
{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("ab4Ab","(ab)\\d\\1",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("foobar1234baz","foo\\w*\\d{4}baz",[trim]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("ab4Ab","(ab)\\d\\1",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("foobar1234baz","foo\\w*\\d{4}baz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("foobar1234baz","foo\\w*\\d{4}baz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("foobar1234baz","foo\\w*\\d{4}baz",[]))),
- <<":~~">> = iolist_to_binary(join(re:split("x~~","x(~~)*(?:(?:F)?)?",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("foobar1234baz","foo\\w*\\d{4}baz",[]))),
+ <<":~~">> = iolist_to_binary(join(re:split("x~~","x(~~)*(?:(?:F)?)?",[trim]))),
<<":~~:">> = iolist_to_binary(join(re:split("x~~","x(~~)*(?:(?:F)?)?",[{parts,
- 2}]))),
- <<":~~:">> = iolist_to_binary(join(re:split("x~~","x(~~)*(?:(?:F)?)?",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[trim]))),
+ 2}]))),
+ <<":~~:">> = iolist_to_binary(join(re:split("x~~","x(~~)*(?:(?:F)?)?",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[]))),
ok.
run29() ->
<<"">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[]))),
<<"B
B">> = iolist_to_binary(join(re:split("B
-B","(?<![cd])b",[trim]))),
+B","(?<![cd])b",[trim]))),
<<"B
B">> = iolist_to_binary(join(re:split("B
-B","(?<![cd])b",[{parts,2}]))),
+B","(?<![cd])b",[{parts,2}]))),
<<"B
B">> = iolist_to_binary(join(re:split("B
-B","(?<![cd])b",[]))),
- <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","(?<![cd])b",[trim]))),
+B","(?<![cd])b",[]))),
+ <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","(?<![cd])b",[trim]))),
<<"dbcb">> = iolist_to_binary(join(re:split("dbcb","(?<![cd])b",[{parts,
- 2}]))),
- <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","(?<![cd])b",[]))),
- <<"db::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<![cd])[ab]",[trim]))),
+ 2}]))),
+ <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","(?<![cd])b",[]))),
+ <<"db::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<![cd])[ab]",[trim]))),
<<"db:acb">> = iolist_to_binary(join(re:split("dbaacb","(?<![cd])[ab]",[{parts,
- 2}]))),
- <<"db::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<![cd])[ab]",[]))),
- <<"db::::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<!(c|d))[ab]",[trim]))),
+ 2}]))),
+ <<"db::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<![cd])[ab]",[]))),
+ <<"db::::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<!(c|d))[ab]",[trim]))),
<<"db::acb">> = iolist_to_binary(join(re:split("dbaacb","(?<!(c|d))[ab]",[{parts,
- 2}]))),
- <<"db::::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<!(c|d))[ab]",[]))),
- <<"cdacc">> = iolist_to_binary(join(re:split("cdaccb","(?<!cd)[ab]",[trim]))),
+ 2}]))),
+ <<"db::::cb">> = iolist_to_binary(join(re:split("dbaacb","(?<!(c|d))[ab]",[]))),
+ <<"cdacc">> = iolist_to_binary(join(re:split("cdaccb","(?<!cd)[ab]",[trim]))),
<<"cdacc:">> = iolist_to_binary(join(re:split("cdaccb","(?<!cd)[ab]",[{parts,
- 2}]))),
- <<"cdacc:">> = iolist_to_binary(join(re:split("cdaccb","(?<!cd)[ab]",[]))),
- <<"">> = iolist_to_binary(join(re:split("","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<"cdacc:">> = iolist_to_binary(join(re:split("cdaccb","(?<!cd)[ab]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("","^(?:a?b?)*$",[trim]))),
<<"">> = iolist_to_binary(join(re:split("","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<"">> = iolist_to_binary(join(re:split("","^(?:a?b?)*$",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<"">> = iolist_to_binary(join(re:split("","^(?:a?b?)*$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^(?:a?b?)*$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","^(?:a?b?)*$",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","^(?:a?b?)*$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","^(?:a?b?)*$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","^(?:a?b?)*$",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaa","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","^(?:a?b?)*$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaa","^(?:a?b?)*$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaa","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaa","^(?:a?b?)*$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaa","^(?:a?b?)*$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:a?b?)*$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:a?b?)*$",[]))),
- <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:a?b?)*$",[]))),
+ <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","^(?:a?b?)*$",[trim]))),
<<"dbcb">> = iolist_to_binary(join(re:split("dbcb","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","^(?:a?b?)*$",[]))),
- <<"a--">> = iolist_to_binary(join(re:split("a--","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<"dbcb">> = iolist_to_binary(join(re:split("dbcb","^(?:a?b?)*$",[]))),
+ <<"a--">> = iolist_to_binary(join(re:split("a--","^(?:a?b?)*$",[trim]))),
<<"a--">> = iolist_to_binary(join(re:split("a--","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<"a--">> = iolist_to_binary(join(re:split("a--","^(?:a?b?)*$",[]))),
- <<"aa--">> = iolist_to_binary(join(re:split("aa--","^(?:a?b?)*$",[trim]))),
+ 2}]))),
+ <<"a--">> = iolist_to_binary(join(re:split("a--","^(?:a?b?)*$",[]))),
+ <<"aa--">> = iolist_to_binary(join(re:split("aa--","^(?:a?b?)*$",[trim]))),
<<"aa--">> = iolist_to_binary(join(re:split("aa--","^(?:a?b?)*$",[{parts,
- 2}]))),
- <<"aa--">> = iolist_to_binary(join(re:split("aa--","^(?:a?b?)*$",[]))),
+ 2}]))),
+ <<"aa--">> = iolist_to_binary(join(re:split("aa--","^(?:a?b?)*$",[]))),
<<":a
:
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?s)^a(.))((?m)^b$)",[trim]))),
+c","((?s)^a(.))((?m)^b$)",[trim]))),
<<":a
:
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?s)^a(.))((?m)^b$)",[{parts,2}]))),
+c","((?s)^a(.))((?m)^b$)",[{parts,2}]))),
<<":a
:
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?s)^a(.))((?m)^b$)",[]))),
+c","((?s)^a(.))((?m)^b$)",[]))),
<<"a
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?m)^b$)",[trim]))),
+c","((?m)^b$)",[trim]))),
<<"a
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?m)^b$)",[{parts,2}]))),
+c","((?m)^b$)",[{parts,2}]))),
<<"a
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?m)^b$)",[]))),
+c","((?m)^b$)",[]))),
<<"a
">> = iolist_to_binary(join(re:split("a
-b","(?m)^b",[trim]))),
+b","(?m)^b",[trim]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","(?m)^b",[{parts,2}]))),
+b","(?m)^b",[{parts,2}]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","(?m)^b",[]))),
+b","(?m)^b",[]))),
<<"a
:b">> = iolist_to_binary(join(re:split("a
-b","(?m)^(b)",[trim]))),
+b","(?m)^(b)",[trim]))),
<<"a
:b:">> = iolist_to_binary(join(re:split("a
-b","(?m)^(b)",[{parts,2}]))),
+b","(?m)^(b)",[{parts,2}]))),
<<"a
:b:">> = iolist_to_binary(join(re:split("a
-b","(?m)^(b)",[]))),
+b","(?m)^(b)",[]))),
<<"a
:b">> = iolist_to_binary(join(re:split("a
-b","((?m)^b)",[trim]))),
+b","((?m)^b)",[trim]))),
<<"a
:b:">> = iolist_to_binary(join(re:split("a
-b","((?m)^b)",[{parts,2}]))),
+b","((?m)^b)",[{parts,2}]))),
<<"a
:b:">> = iolist_to_binary(join(re:split("a
-b","((?m)^b)",[]))),
+b","((?m)^b)",[]))),
<<"a:b">> = iolist_to_binary(join(re:split("a
-b","\\n((?m)^b)",[trim]))),
+b","\\n((?m)^b)",[trim]))),
<<"a:b:">> = iolist_to_binary(join(re:split("a
-b","\\n((?m)^b)",[{parts,2}]))),
+b","\\n((?m)^b)",[{parts,2}]))),
<<"a:b:">> = iolist_to_binary(join(re:split("a
-b","\\n((?m)^b)",[]))),
+b","\\n((?m)^b)",[]))),
<<"a
b:
">> = iolist_to_binary(join(re:split("a
b
-c","((?s).)c(?!.)",[trim]))),
+c","((?s).)c(?!.)",[trim]))),
<<"a
b:
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s).)c(?!.)",[{parts,2}]))),
+c","((?s).)c(?!.)",[{parts,2}]))),
<<"a
b:
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s).)c(?!.)",[]))),
+c","((?s).)c(?!.)",[]))),
<<"a
b:
">> = iolist_to_binary(join(re:split("a
b
-c","((?s).)c(?!.)",[trim]))),
+c","((?s).)c(?!.)",[trim]))),
<<"a
b:
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s).)c(?!.)",[{parts,2}]))),
+c","((?s).)c(?!.)",[{parts,2}]))),
<<"a
b:
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s).)c(?!.)",[]))),
+c","((?s).)c(?!.)",[]))),
<<"a
:b
">> = iolist_to_binary(join(re:split("a
b
-c","((?s)b.)c(?!.)",[trim]))),
+c","((?s)b.)c(?!.)",[trim]))),
<<"a
:b
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s)b.)c(?!.)",[{parts,2}]))),
+c","((?s)b.)c(?!.)",[{parts,2}]))),
<<"a
:b
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s)b.)c(?!.)",[]))),
+c","((?s)b.)c(?!.)",[]))),
<<"a
:b
">> = iolist_to_binary(join(re:split("a
b
-c","((?s)b.)c(?!.)",[trim]))),
+c","((?s)b.)c(?!.)",[trim]))),
<<"a
:b
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s)b.)c(?!.)",[{parts,2}]))),
+c","((?s)b.)c(?!.)",[{parts,2}]))),
<<"a
:b
:">> = iolist_to_binary(join(re:split("a
b
-c","((?s)b.)c(?!.)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","()^b",[trim]))),
+c","((?s)b.)c(?!.)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","()^b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","()^b",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","()^b",[]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","()^b",[]))),
<<"a
b
c">> = iolist_to_binary(join(re:split("a
b
-c","()^b",[trim]))),
+c","()^b",[trim]))),
<<"a
b
c">> = iolist_to_binary(join(re:split("a
b
-c","()^b",[{parts,2}]))),
+c","()^b",[{parts,2}]))),
<<"a
b
c">> = iolist_to_binary(join(re:split("a
b
-c","()^b",[]))),
+c","()^b",[]))),
<<"a
b
c">> = iolist_to_binary(join(re:split("a
b
-c","()^b",[trim]))),
+c","()^b",[trim]))),
<<"a
b
c">> = iolist_to_binary(join(re:split("a
b
-c","()^b",[{parts,2}]))),
+c","()^b",[{parts,2}]))),
<<"a
b
c">> = iolist_to_binary(join(re:split("a
b
-c","()^b",[]))),
+c","()^b",[]))),
<<"a
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?m)^b)",[trim]))),
+c","((?m)^b)",[trim]))),
<<"a
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?m)^b)",[{parts,2}]))),
+c","((?m)^b)",[{parts,2}]))),
<<"a
:b:
c">> = iolist_to_binary(join(re:split("a
b
-c","((?m)^b)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(x)?(?(1)a|b)",[trim]))),
+c","((?m)^b)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(x)?(?(1)a|b)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(x)?(?(1)a|b)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(x)?(?(1)a|b)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(x)?(?(1)a|b)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(x)?(?(1)a|b)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[]))),
ok.
run30() ->
- <<"">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[]))),
- <<":(:)">> = iolist_to_binary(join(re:split("(blah)","^(\\()?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[]))),
+ <<":(:)">> = iolist_to_binary(join(re:split("(blah)","^(\\()?blah(?(1)(\\)))$",[trim]))),
<<":(:):">> = iolist_to_binary(join(re:split("(blah)","^(\\()?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<":(:):">> = iolist_to_binary(join(re:split("(blah)","^(\\()?blah(?(1)(\\)))$",[]))),
- <<"">> = iolist_to_binary(join(re:split("blah","^(\\()?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<":(:):">> = iolist_to_binary(join(re:split("(blah)","^(\\()?blah(?(1)(\\)))$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("blah","^(\\()?blah(?(1)(\\)))$",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("blah","^(\\()?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("blah","^(\\()?blah(?(1)(\\)))$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\()?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("blah","^(\\()?blah(?(1)(\\)))$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\()?blah(?(1)(\\)))$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\()?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\()?blah(?(1)(\\)))$",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(\\()?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\()?blah(?(1)(\\)))$",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(\\()?blah(?(1)(\\)))$",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","^(\\()?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(\\()?blah(?(1)(\\)))$",[]))),
- <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\()?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(\\()?blah(?(1)(\\)))$",[]))),
+ <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\()?blah(?(1)(\\)))$",[trim]))),
<<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\()?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\()?blah(?(1)(\\)))$",[]))),
- <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\()?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\()?blah(?(1)(\\)))$",[]))),
+ <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\()?blah(?(1)(\\)))$",[trim]))),
<<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\()?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\()?blah(?(1)(\\)))$",[]))),
- <<":(:)">> = iolist_to_binary(join(re:split("(blah)","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\()?blah(?(1)(\\)))$",[]))),
+ <<":(:)">> = iolist_to_binary(join(re:split("(blah)","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
<<":(:):">> = iolist_to_binary(join(re:split("(blah)","^(\\(+)?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<":(:):">> = iolist_to_binary(join(re:split("(blah)","^(\\(+)?blah(?(1)(\\)))$",[]))),
- <<"">> = iolist_to_binary(join(re:split("blah","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<":(:):">> = iolist_to_binary(join(re:split("(blah)","^(\\(+)?blah(?(1)(\\)))$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("blah","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("blah","^(\\(+)?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("blah","^(\\(+)?blah(?(1)(\\)))$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("blah","^(\\(+)?blah(?(1)(\\)))$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\(+)?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\(+)?blah(?(1)(\\)))$",[]))),
- <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\(+)?blah(?(1)(\\)))$",[]))),
+ <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
<<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\(+)?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\(+)?blah(?(1)(\\)))$",[]))),
- <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
+ 2}]))),
+ <<"blah)">> = iolist_to_binary(join(re:split("blah)","^(\\(+)?blah(?(1)(\\)))$",[]))),
+ <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\(+)?blah(?(1)(\\)))$",[trim]))),
<<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\(+)?blah(?(1)(\\)))$",[{parts,
- 2}]))),
- <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\(+)?blah(?(1)(\\)))$",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","(?(?!a)b|a)",[trim]))),
+ 2}]))),
+ <<"(blah">> = iolist_to_binary(join(re:split("(blah","^(\\(+)?blah(?(1)(\\)))$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","(?(?!a)b|a)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","(?(?!a)b|a)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","(?(?!a)b|a)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=a)b|a)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","(?(?!a)b|a)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=a)b|a)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=a)b|a)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=a)b|a)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?(?=a)b|a)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","(?(?=a)a|b)",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(?(?=a)b|a)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","(?(?=a)a|b)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","(?(?=a)a|b)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","(?(?=a)a|b)",[]))),
- <<"a:a:aab">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","(?(?=a)a|b)",[]))),
+ <<"a:a:aab">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[trim]))),
<<"a:a:aab:">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[{parts,
- 2}]))),
- <<"a:a:aab:">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[]))),
- <<":one:">> = iolist_to_binary(join(re:split("one:","(\\w+:)+",[trim]))),
+ 2}]))),
+ <<"a:a:aab:">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[]))),
+ <<":one:">> = iolist_to_binary(join(re:split("one:","(\\w+:)+",[trim]))),
<<":one::">> = iolist_to_binary(join(re:split("one:","(\\w+:)+",[{parts,
- 2}]))),
- <<":one::">> = iolist_to_binary(join(re:split("one:","(\\w+:)+",[]))),
- <<"a:a">> = iolist_to_binary(join(re:split("a","$(?<=^(a))",[trim]))),
+ 2}]))),
+ <<":one::">> = iolist_to_binary(join(re:split("one:","(\\w+:)+",[]))),
+ <<"a:a">> = iolist_to_binary(join(re:split("a","$(?<=^(a))",[trim]))),
<<"a:a:">> = iolist_to_binary(join(re:split("a","$(?<=^(a))",[{parts,
- 2}]))),
- <<"a:a:">> = iolist_to_binary(join(re:split("a","$(?<=^(a))",[]))),
- <<"a:a:aab">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[trim]))),
+ 2}]))),
+ <<"a:a:">> = iolist_to_binary(join(re:split("a","$(?<=^(a))",[]))),
+ <<"a:a:aab">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[trim]))),
<<"a:a:aab:">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[{parts,
- 2}]))),
- <<"a:a:aab:">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?=(a+?))\\1ab",[trim]))),
+ 2}]))),
+ <<"a:a:aab:">> = iolist_to_binary(join(re:split("aaab","(?=(a+?))(\\1ab)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?=(a+?))\\1ab",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?=(a+?))\\1ab",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?=(a+?))\\1ab",[]))),
- <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?=(a+?))\\1ab",[]))),
+ <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[trim]))),
<<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[{parts,
- 2}]))),
- <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[]))),
- <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[trim]))),
+ 2}]))),
+ <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[]))),
+ <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[trim]))),
<<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[{parts,
- 2}]))),
- <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[]))),
- <<"::abcd">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<"aaab">> = iolist_to_binary(join(re:split("aaab","^(?=(a+?))\\1ab",[]))),
+ <<"::abcd">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[trim]))),
<<"::abcd:">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<"::abcd:">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[]))),
- <<":xy:z::::abcd">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<"::abcd:">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[]))),
+ <<":xy:z::::abcd">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[trim]))),
<<":xy:z::::abcd:">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<":xy:z::::abcd:">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[]))),
- <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[trim]))),
+ 2}]))),
+ <<":xy:z::::abcd:">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[]))),
+ <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[trim]))),
<<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[{parts,
- 2}]))),
- <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[]))),
- <<"c:aa">> = iolist_to_binary(join(re:split("caab","(a*)b+",[trim]))),
+ 2}]))),
+ <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[]))),
+ <<"c:aa">> = iolist_to_binary(join(re:split("caab","(a*)b+",[trim]))),
<<"c:aa:">> = iolist_to_binary(join(re:split("caab","(a*)b+",[{parts,
- 2}]))),
- <<"c:aa:">> = iolist_to_binary(join(re:split("caab","(a*)b+",[]))),
- <<"::abcd">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<"c:aa:">> = iolist_to_binary(join(re:split("caab","(a*)b+",[]))),
+ <<"::abcd">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[trim]))),
<<"::abcd:">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<"::abcd:">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[]))),
- <<":xy:z::::abcd">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<"::abcd:">> = iolist_to_binary(join(re:split("abcd","([\\w:]+::)?(\\w+)$",[]))),
+ <<":xy:z::::abcd">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[trim]))),
<<":xy:z::::abcd:">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<":xy:z::::abcd:">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[]))),
- <<"*** ::Failers">> = iolist_to_binary(join(re:split("*** Failers","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<":xy:z::::abcd:">> = iolist_to_binary(join(re:split("xy:z:::abcd","([\\w:]+::)?(\\w+)$",[]))),
+ <<"*** ::Failers">> = iolist_to_binary(join(re:split("*** Failers","([\\w:]+::)?(\\w+)$",[trim]))),
<<"*** ::Failers:">> = iolist_to_binary(join(re:split("*** Failers","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<"*** ::Failers:">> = iolist_to_binary(join(re:split("*** Failers","([\\w:]+::)?(\\w+)$",[]))),
- <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<"*** ::Failers:">> = iolist_to_binary(join(re:split("*** Failers","([\\w:]+::)?(\\w+)$",[]))),
+ <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[trim]))),
<<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[]))),
- <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[trim]))),
+ 2}]))),
+ <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[]))),
+ <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[trim]))),
<<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[{parts,
- 2}]))),
- <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[]))),
- <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[trim]))),
+ 2}]))),
+ <<"abcd:">> = iolist_to_binary(join(re:split("abcd:","([\\w:]+::)?(\\w+)$",[]))),
+ <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[trim]))),
<<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[{parts,
- 2}]))),
- <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[]))),
+ 2}]))),
+ <<":c:d">> = iolist_to_binary(join(re:split("aexycd","^[^bcd]*(c+)",[]))),
ok.
run31() ->
- <<"">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[]))),
- <<"a::[:b]::">> = iolist_to_binary(join(re:split("a:[b]:","([[:]+)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[]))),
+ <<"a::[:b]::">> = iolist_to_binary(join(re:split("a:[b]:","([[:]+)",[trim]))),
<<"a::[:b]:">> = iolist_to_binary(join(re:split("a:[b]:","([[:]+)",[{parts,
- 2}]))),
- <<"a::[:b]:::">> = iolist_to_binary(join(re:split("a:[b]:","([[:]+)",[]))),
- <<"a:=[:b]:=">> = iolist_to_binary(join(re:split("a=[b]=","([[=]+)",[trim]))),
+ 2}]))),
+ <<"a::[:b]:::">> = iolist_to_binary(join(re:split("a:[b]:","([[:]+)",[]))),
+ <<"a:=[:b]:=">> = iolist_to_binary(join(re:split("a=[b]=","([[=]+)",[trim]))),
<<"a:=[:b]=">> = iolist_to_binary(join(re:split("a=[b]=","([[=]+)",[{parts,
- 2}]))),
- <<"a:=[:b]:=:">> = iolist_to_binary(join(re:split("a=[b]=","([[=]+)",[]))),
- <<"a:.[:b]:.">> = iolist_to_binary(join(re:split("a.[b].","([[.]+)",[trim]))),
+ 2}]))),
+ <<"a:=[:b]:=:">> = iolist_to_binary(join(re:split("a=[b]=","([[=]+)",[]))),
+ <<"a:.[:b]:.">> = iolist_to_binary(join(re:split("a.[b].","([[.]+)",[trim]))),
<<"a:.[:b].">> = iolist_to_binary(join(re:split("a.[b].","([[.]+)",[{parts,
- 2}]))),
- <<"a:.[:b]:.:">> = iolist_to_binary(join(re:split("a.[b].","([[.]+)",[]))),
- <<":aaab">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[trim]))),
+ 2}]))),
+ <<"a:.[:b]:.:">> = iolist_to_binary(join(re:split("a.[b].","([[.]+)",[]))),
+ <<":aaab">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[trim]))),
<<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[{parts,
- 2}]))),
- <<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[]))),
- <<":aaa">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[trim]))),
+ 2}]))),
+ <<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[]))),
+ <<":aaa">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[trim]))),
<<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[{parts,
- 2}]))),
- <<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[]))),
- <<"((:x">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[trim]))),
+ 2}]))),
+ <<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[]))),
+ <<"((:x">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[trim]))),
<<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[{parts,
- 2}]))),
- <<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Z",[trim]))),
+ 2}]))),
+ <<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Z",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Z",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Z",[]))),
- <<"aaab">> = iolist_to_binary(join(re:split("aaab","a\\Z",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a\\Z",[]))),
+ <<"aaab">> = iolist_to_binary(join(re:split("aaab","a\\Z",[trim]))),
<<"aaab">> = iolist_to_binary(join(re:split("aaab","a\\Z",[{parts,
- 2}]))),
- <<"aaab">> = iolist_to_binary(join(re:split("aaab","a\\Z",[]))),
+ 2}]))),
+ <<"aaab">> = iolist_to_binary(join(re:split("aaab","a\\Z",[]))),
<<"a
b">> = iolist_to_binary(join(re:split("a
-b","a\\Z",[trim]))),
+b","a\\Z",[trim]))),
<<"a
b">> = iolist_to_binary(join(re:split("a
-b","a\\Z",[{parts,2}]))),
+b","a\\Z",[{parts,2}]))),
<<"a
b">> = iolist_to_binary(join(re:split("a
-b","a\\Z",[]))),
+b","a\\Z",[]))),
<<"a
">> = iolist_to_binary(join(re:split("a
-b","b\\Z",[trim]))),
+b","b\\Z",[trim]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","b\\Z",[{parts,2}]))),
+b","b\\Z",[{parts,2}]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","b\\Z",[]))),
+b","b\\Z",[]))),
<<"a
">> = iolist_to_binary(join(re:split("a
-b","b\\Z",[trim]))),
+b","b\\Z",[trim]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","b\\Z",[{parts,2}]))),
+b","b\\Z",[{parts,2}]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","b\\Z",[]))),
+b","b\\Z",[]))),
<<"a
">> = iolist_to_binary(join(re:split("a
-b","b\\z",[trim]))),
+b","b\\z",[trim]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","b\\z",[{parts,2}]))),
+b","b\\z",[{parts,2}]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-b","b\\z",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","b\\z",[trim]))),
+b","b\\z",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","b\\z",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","b\\z",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","b\\z",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","b\\z",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"">> = iolist_to_binary(join(re:split("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"">> = iolist_to_binary(join(re:split("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"">> = iolist_to_binary(join(re:split("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<".a">> = iolist_to_binary(join(re:split(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"">> = iolist_to_binary(join(re:split("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<".a">> = iolist_to_binary(join(re:split(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<".a">> = iolist_to_binary(join(re:split(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<".a">> = iolist_to_binary(join(re:split(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"-a">> = iolist_to_binary(join(re:split("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<".a">> = iolist_to_binary(join(re:split(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"-a">> = iolist_to_binary(join(re:split("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"-a">> = iolist_to_binary(join(re:split("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"-a">> = iolist_to_binary(join(re:split("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"a-">> = iolist_to_binary(join(re:split("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"-a">> = iolist_to_binary(join(re:split("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"a-">> = iolist_to_binary(join(re:split("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"a-">> = iolist_to_binary(join(re:split("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"a-">> = iolist_to_binary(join(re:split("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"a.">> = iolist_to_binary(join(re:split("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"a-">> = iolist_to_binary(join(re:split("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"a.">> = iolist_to_binary(join(re:split("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"a.">> = iolist_to_binary(join(re:split("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"a.">> = iolist_to_binary(join(re:split("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"a_b">> = iolist_to_binary(join(re:split("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"a.">> = iolist_to_binary(join(re:split("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"a_b">> = iolist_to_binary(join(re:split("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"a_b">> = iolist_to_binary(join(re:split("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"a_b">> = iolist_to_binary(join(re:split("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"a.-">> = iolist_to_binary(join(re:split("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"a_b">> = iolist_to_binary(join(re:split("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"a.-">> = iolist_to_binary(join(re:split("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"a.-">> = iolist_to_binary(join(re:split("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"a.-">> = iolist_to_binary(join(re:split("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"a..">> = iolist_to_binary(join(re:split("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"a.-">> = iolist_to_binary(join(re:split("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"a..">> = iolist_to_binary(join(re:split("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"a..">> = iolist_to_binary(join(re:split("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"a..">> = iolist_to_binary(join(re:split("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"ab..bc">> = iolist_to_binary(join(re:split("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"a..">> = iolist_to_binary(join(re:split("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"ab..bc">> = iolist_to_binary(join(re:split("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"ab..bc">> = iolist_to_binary(join(re:split("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"ab..bc">> = iolist_to_binary(join(re:split("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"the.quick.brown.fox-">> = iolist_to_binary(join(re:split("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"ab..bc">> = iolist_to_binary(join(re:split("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"the.quick.brown.fox-">> = iolist_to_binary(join(re:split("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"the.quick.brown.fox-">> = iolist_to_binary(join(re:split("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"the.quick.brown.fox-">> = iolist_to_binary(join(re:split("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"the.quick.brown.fox.">> = iolist_to_binary(join(re:split("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"the.quick.brown.fox-">> = iolist_to_binary(join(re:split("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"the.quick.brown.fox.">> = iolist_to_binary(join(re:split("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"the.quick.brown.fox.">> = iolist_to_binary(join(re:split("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"the.quick.brown.fox.">> = iolist_to_binary(join(re:split("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"the.quick.brown.fox_">> = iolist_to_binary(join(re:split("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"the.quick.brown.fox.">> = iolist_to_binary(join(re:split("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"the.quick.brown.fox_">> = iolist_to_binary(join(re:split("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"the.quick.brown.fox_">> = iolist_to_binary(join(re:split("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"the.quick.brown.fox_">> = iolist_to_binary(join(re:split("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<"the.quick.brown.fox+">> = iolist_to_binary(join(re:split("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
+ 2}]))),
+ <<"the.quick.brown.fox_">> = iolist_to_binary(join(re:split("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<"the.quick.brown.fox+">> = iolist_to_binary(join(re:split("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[trim]))),
<<"the.quick.brown.fox+">> = iolist_to_binary(join(re:split("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[{parts,
- 2}]))),
- <<"the.quick.brown.fox+">> = iolist_to_binary(join(re:split("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
- <<":abcd">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd|wxyz))",[trim]))),
+ 2}]))),
+ <<"the.quick.brown.fox+">> = iolist_to_binary(join(re:split("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$",[]))),
+ <<":abcd">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd|wxyz))",[trim]))),
<<":abcd:">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd|wxyz))",[{parts,
- 2}]))),
- <<":abcd:">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd|wxyz))",[]))),
- <<":wxyz">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd|wxyz))",[trim]))),
+ 2}]))),
+ <<":abcd:">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd|wxyz))",[]))),
+ <<":wxyz">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd|wxyz))",[trim]))),
<<":wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd|wxyz))",[{parts,
- 2}]))),
- <<":wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd|wxyz))",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>.*)(?<=(abcd|wxyz))",[trim]))),
+ 2}]))),
+ <<":wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd|wxyz))",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>.*)(?<=(abcd|wxyz))",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>.*)(?<=(abcd|wxyz))",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>.*)(?<=(abcd|wxyz))",[]))),
- <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(join(re:split("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?>.*)(?<=(abcd|wxyz))",[]))),
+ <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(join(re:split("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))",[trim]))),
<<"a rather long string that doesn't end with one of them">> = iolist_to_binary(join(re:split("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))",[{parts,
- 2}]))),
- <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(join(re:split("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))",[]))),
- <<"">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[trim]))),
+ 2}]))),
+ <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(join(re:split("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))",[]))),
+ <<"">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[trim]))),
<<":">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[trim]))),
<<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[{parts,
- 2}]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword",[trim]))),
+ 2}]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword",[]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword",[trim]))),
<<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword",[{parts,
- 2}]))),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword",[]))),
- <<"999">> = iolist_to_binary(join(re:split("999foo","(?<=\\d{3}(?!999))foo",[trim]))),
+ 2}]))),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(join(re:split("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword",[]))),
+ <<"999">> = iolist_to_binary(join(re:split("999foo","(?<=\\d{3}(?!999))foo",[trim]))),
<<"999:">> = iolist_to_binary(join(re:split("999foo","(?<=\\d{3}(?!999))foo",[{parts,
- 2}]))),
- <<"999:">> = iolist_to_binary(join(re:split("999foo","(?<=\\d{3}(?!999))foo",[]))),
- <<"123999">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999))foo",[trim]))),
+ 2}]))),
+ <<"999:">> = iolist_to_binary(join(re:split("999foo","(?<=\\d{3}(?!999))foo",[]))),
+ <<"123999">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999))foo",[trim]))),
<<"123999:">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999))foo",[{parts,
- 2}]))),
- <<"123999:">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999))foo",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999))foo",[trim]))),
+ 2}]))),
+ <<"123999:">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999))foo",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999))foo",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999))foo",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999))foo",[]))),
- <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999))foo",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999))foo",[]))),
+ <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999))foo",[trim]))),
<<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999))foo",[{parts,
- 2}]))),
- <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999))foo",[]))),
- <<"999">> = iolist_to_binary(join(re:split("999foo","(?<=(?!...999)\\d{3})foo",[trim]))),
+ 2}]))),
+ <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999))foo",[]))),
+ <<"999">> = iolist_to_binary(join(re:split("999foo","(?<=(?!...999)\\d{3})foo",[trim]))),
<<"999:">> = iolist_to_binary(join(re:split("999foo","(?<=(?!...999)\\d{3})foo",[{parts,
- 2}]))),
- <<"999:">> = iolist_to_binary(join(re:split("999foo","(?<=(?!...999)\\d{3})foo",[]))),
- <<"123999">> = iolist_to_binary(join(re:split("123999foo","(?<=(?!...999)\\d{3})foo",[trim]))),
+ 2}]))),
+ <<"999:">> = iolist_to_binary(join(re:split("999foo","(?<=(?!...999)\\d{3})foo",[]))),
+ <<"123999">> = iolist_to_binary(join(re:split("123999foo","(?<=(?!...999)\\d{3})foo",[trim]))),
<<"123999:">> = iolist_to_binary(join(re:split("123999foo","(?<=(?!...999)\\d{3})foo",[{parts,
- 2}]))),
- <<"123999:">> = iolist_to_binary(join(re:split("123999foo","(?<=(?!...999)\\d{3})foo",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?!...999)\\d{3})foo",[trim]))),
+ 2}]))),
+ <<"123999:">> = iolist_to_binary(join(re:split("123999foo","(?<=(?!...999)\\d{3})foo",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?!...999)\\d{3})foo",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?!...999)\\d{3})foo",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?!...999)\\d{3})foo",[]))),
- <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=(?!...999)\\d{3})foo",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=(?!...999)\\d{3})foo",[]))),
+ <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=(?!...999)\\d{3})foo",[trim]))),
<<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=(?!...999)\\d{3})foo",[{parts,
- 2}]))),
- <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=(?!...999)\\d{3})foo",[]))),
- <<"123abc">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999)...)foo",[trim]))),
+ 2}]))),
+ <<"123abcfoo">> = iolist_to_binary(join(re:split("123abcfoo","(?<=(?!...999)\\d{3})foo",[]))),
+ <<"123abc">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999)...)foo",[trim]))),
<<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999)...)foo",[{parts,
- 2}]))),
- <<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999)...)foo",[]))),
- <<"123456">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}(?!999)...)foo",[trim]))),
+ 2}]))),
+ <<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}(?!999)...)foo",[]))),
+ <<"123456">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}(?!999)...)foo",[trim]))),
<<"123456:">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}(?!999)...)foo",[{parts,
- 2}]))),
- <<"123456:">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}(?!999)...)foo",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999)...)foo",[trim]))),
+ 2}]))),
+ <<"123456:">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}(?!999)...)foo",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999)...)foo",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999)...)foo",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999)...)foo",[]))),
- <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}(?!999)...)foo",[]))),
+ <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[trim]))),
<<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[{parts,
- 2}]))),
- <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[]))),
+ 2}]))),
+ <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[]))),
ok.
run32() ->
- <<"123abc">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
+ <<"123abc">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
<<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[{parts,
- 2}]))),
- <<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[]))),
- <<"123456">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
+ 2}]))),
+ <<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[]))),
+ <<"123456">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
<<"123456:">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}...)(?<!999)foo",[{parts,
- 2}]))),
- <<"123456:">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}...)(?<!999)foo",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}...)(?<!999)foo",[trim]))),
+ 2}]))),
+ <<"123456:">> = iolist_to_binary(join(re:split("123456foo","(?<=\\d{3}...)(?<!999)foo",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}...)(?<!999)foo",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}...)(?<!999)foo",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}...)(?<!999)foo",[]))),
- <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<=\\d{3}...)(?<!999)foo",[]))),
+ <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
<<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[{parts,
- 2}]))),
- <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[]))),
+ 2}]))),
+ <<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
@@ -28108,20 +28108,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
@@ -28129,20 +28129,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
@@ -28150,20 +28150,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
@@ -28171,20 +28171,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
@@ -28192,20 +28192,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
@@ -28213,20 +28213,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
@@ -28234,20 +28234,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
@@ -28255,20 +28255,20 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":\":abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
+ extended]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
extended,
- trim]))),
+ trim]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
@@ -28276,303 +28276,303 @@ run32() ->
dotall,
extended,
{parts,
- 2}]))),
+ 2}]))),
<<":':abcd xyz pqr:: cats">> = iolist_to_binary(join(re:split("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
# quote, otherwise match up to next space",[caseless,
dotall,
- extended]))),
- <<":A:Z:B:::C:::D:::E:::F:::G">> = iolist_to_binary(join(re:split("ZABCDEFG","((Z)+|A)*",[trim]))),
+ extended]))),
+ <<":A:Z:B:::C:::D:::E:::F:::G">> = iolist_to_binary(join(re:split("ZABCDEFG","((Z)+|A)*",[trim]))),
<<":A:Z:BCDEFG">> = iolist_to_binary(join(re:split("ZABCDEFG","((Z)+|A)*",[{parts,
- 2}]))),
- <<":A:Z:B:::C:::D:::E:::F:::G:::">> = iolist_to_binary(join(re:split("ZABCDEFG","((Z)+|A)*",[]))),
- <<":A::B:::C:::D:::E:::F:::G">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z()|A)*",[trim]))),
+ 2}]))),
+ <<":A:Z:B:::C:::D:::E:::F:::G:::">> = iolist_to_binary(join(re:split("ZABCDEFG","((Z)+|A)*",[]))),
+ <<":A::B:::C:::D:::E:::F:::G">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z()|A)*",[trim]))),
<<":A::BCDEFG">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z()|A)*",[{parts,
- 2}]))),
- <<":A::B:::C:::D:::E:::F:::G:::">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z()|A)*",[]))),
- <<":A:::B::::C::::D::::E::::F::::G">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z(())|A)*",[trim]))),
+ 2}]))),
+ <<":A::B:::C:::D:::E:::F:::G:::">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z()|A)*",[]))),
+ <<":A:::B::::C::::D::::E::::F::::G">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z(())|A)*",[trim]))),
<<":A:::BCDEFG">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z(())|A)*",[{parts,
- 2}]))),
- <<":A:::B::::C::::D::::E::::F::::G::::">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z(())|A)*",[]))),
- <<":A:B::C::D::E::F::G">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>Z)+|A)*",[trim]))),
+ 2}]))),
+ <<":A:::B::::C::::D::::E::::F::::G::::">> = iolist_to_binary(join(re:split("ZABCDEFG","(Z(())|A)*",[]))),
+ <<":A:B::C::D::E::F::G">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>Z)+|A)*",[trim]))),
<<":A:BCDEFG">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>Z)+|A)*",[{parts,
- 2}]))),
- <<":A:B::C::D::E::F::G::">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>Z)+|A)*",[]))),
- <<"Z::::B::C::D::E::F::G">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>)+|A)*",[trim]))),
+ 2}]))),
+ <<":A:B::C::D::E::F::G::">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>Z)+|A)*",[]))),
+ <<"Z::::B::C::D::E::F::G">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>)+|A)*",[trim]))),
<<"Z::ABCDEFG">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>)+|A)*",[{parts,
- 2}]))),
- <<"Z::::B::C::D::E::F::G::">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>)+|A)*",[]))),
- <<":b:b:b">> = iolist_to_binary(join(re:split("abbab","a*",[trim]))),
+ 2}]))),
+ <<"Z::::B::C::D::E::F::G::">> = iolist_to_binary(join(re:split("ZABCDEFG","((?>)+|A)*",[]))),
+ <<":b:b:b">> = iolist_to_binary(join(re:split("abbab","a*",[trim]))),
<<":bbab">> = iolist_to_binary(join(re:split("abbab","a*",[{parts,
- 2}]))),
- <<":b:b:b:">> = iolist_to_binary(join(re:split("abbab","a*",[]))),
- <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[trim]))),
+ 2}]))),
+ <<":b:b:b:">> = iolist_to_binary(join(re:split("abbab","a*",[]))),
+ <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[trim]))),
<<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[{parts,
- 2}]))),
- <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[]))),
- <<":things">> = iolist_to_binary(join(re:split("-things","^[\\d-a]",[trim]))),
+ 2}]))),
+ <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[]))),
+ <<":things">> = iolist_to_binary(join(re:split("-things","^[\\d-a]",[trim]))),
<<":things">> = iolist_to_binary(join(re:split("-things","^[\\d-a]",[{parts,
- 2}]))),
- <<":things">> = iolist_to_binary(join(re:split("-things","^[\\d-a]",[]))),
- <<":digit">> = iolist_to_binary(join(re:split("0digit","^[\\d-a]",[trim]))),
+ 2}]))),
+ <<":things">> = iolist_to_binary(join(re:split("-things","^[\\d-a]",[]))),
+ <<":digit">> = iolist_to_binary(join(re:split("0digit","^[\\d-a]",[trim]))),
<<":digit">> = iolist_to_binary(join(re:split("0digit","^[\\d-a]",[{parts,
- 2}]))),
- <<":digit">> = iolist_to_binary(join(re:split("0digit","^[\\d-a]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[\\d-a]",[trim]))),
+ 2}]))),
+ <<":digit">> = iolist_to_binary(join(re:split("0digit","^[\\d-a]",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[\\d-a]",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[\\d-a]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[\\d-a]",[]))),
- <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[\\d-a]",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[\\d-a]",[]))),
+ <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[\\d-a]",[trim]))),
<<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[\\d-a]",[{parts,
- 2}]))),
- <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[\\d-a]",[]))),
+ 2}]))),
+ <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[\\d-a]",[]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","[[:space:]]+",[trim]))),
+ <","[[:space:]]+",[trim]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","[[:space:]]+",[{parts,2}]))),
+ <","[[:space:]]+",[{parts,2}]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","[[:space:]]+",[]))),
+ <","[[:space:]]+",[]))),
<<">:
<">> = iolist_to_binary(join(re:split(">
- <","[[:blank:]]+",[trim]))),
+ <","[[:blank:]]+",[trim]))),
<<">:
<">> = iolist_to_binary(join(re:split(">
- <","[[:blank:]]+",[{parts,2}]))),
+ <","[[:blank:]]+",[{parts,2}]))),
<<">:
<">> = iolist_to_binary(join(re:split(">
- <","[[:blank:]]+",[]))),
+ <","[[:blank:]]+",[]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","[\\s]+",[trim]))),
+ <","[\\s]+",[trim]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","[\\s]+",[{parts,2}]))),
+ <","[\\s]+",[{parts,2}]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","[\\s]+",[]))),
+ <","[\\s]+",[]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","\\s+",[trim]))),
+ <","\\s+",[trim]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","\\s+",[{parts,2}]))),
+ <","\\s+",[{parts,2}]))),
<<">:<">> = iolist_to_binary(join(re:split(">
- <","\\s+",[]))),
+ <","\\s+",[]))),
<<"">> = iolist_to_binary(join(re:split("ab","a b",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","a b",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","a b",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","a b",[extended]))),
<<"a
:b">> = iolist_to_binary(join(re:split("a
-xb","(?!\\A)x",[multiline,trim]))),
+xb","(?!\\A)x",[multiline,trim]))),
<<"a
:b">> = iolist_to_binary(join(re:split("a
-xb","(?!\\A)x",[multiline,{parts,2}]))),
+xb","(?!\\A)x",[multiline,{parts,2}]))),
<<"a
:b">> = iolist_to_binary(join(re:split("a
-xb","(?!\\A)x",[multiline]))),
+xb","(?!\\A)x",[multiline]))),
<<"a
xb">> = iolist_to_binary(join(re:split("a
-xb","(?!^)x",[multiline,trim]))),
+xb","(?!^)x",[multiline,trim]))),
<<"a
xb">> = iolist_to_binary(join(re:split("a
-xb","(?!^)x",[multiline,{parts,2}]))),
+xb","(?!^)x",[multiline,{parts,2}]))),
<<"a
xb">> = iolist_to_binary(join(re:split("a
-xb","(?!^)x",[multiline]))),
- <<"">> = iolist_to_binary(join(re:split("abcabcabc","abc\\Qabc\\Eabc",[trim]))),
+xb","(?!^)x",[multiline]))),
+ <<"">> = iolist_to_binary(join(re:split("abcabcabc","abc\\Qabc\\Eabc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcabcabc","abc\\Qabc\\Eabc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcabcabc","abc\\Qabc\\Eabc",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc(*+|abc","abc\\Q(*+|\\Eabc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcabcabc","abc\\Qabc\\Eabc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc(*+|abc","abc\\Q(*+|\\Eabc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc(*+|abc","abc\\Q(*+|\\Eabc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc(*+|abc","abc\\Q(*+|\\Eabc",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc(*+|abc","abc\\Q(*+|\\Eabc",[]))),
ok.
run33() ->
<<"">> = iolist_to_binary(join(re:split("abc abcabc"," abc\\Q abc\\Eabc",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("abc abcabc"," abc\\Q abc\\Eabc",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc abcabc"," abc\\Q abc\\Eabc",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc abcabc"," abc\\Q abc\\Eabc",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," abc\\Q abc\\Eabc",[extended,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," abc\\Q abc\\Eabc",[extended,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," abc\\Q abc\\Eabc",[extended]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers"," abc\\Q abc\\Eabc",[extended]))),
<<"abcabcabc">> = iolist_to_binary(join(re:split("abcabcabc"," abc\\Q abc\\Eabc",[extended,
- trim]))),
+ trim]))),
<<"abcabcabc">> = iolist_to_binary(join(re:split("abcabcabc"," abc\\Q abc\\Eabc",[extended,
{parts,
- 2}]))),
- <<"abcabcabc">> = iolist_to_binary(join(re:split("abcabcabc"," abc\\Q abc\\Eabc",[extended]))),
+ 2}]))),
+ <<"abcabcabc">> = iolist_to_binary(join(re:split("abcabcabc"," abc\\Q abc\\Eabc",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E",[extended,trim]))),
+ literal\\E",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E",[extended,{parts,2}]))),
+ literal\\E",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E",[extended]))),
+ literal\\E",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal",[extended,trim]))),
+ literal",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal",[extended,{parts,2}]))),
+ literal",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal",[extended]))),
+ literal",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
literal\\E #more comment
- ",[extended,trim]))),
+ ",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
literal\\E #more comment
- ",[extended,{parts,2}]))),
+ ",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
literal\\E #more comment
- ",[extended]))),
+ ",[extended]))),
<<"">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E #more comment",[extended,trim]))),
+ literal\\E #more comment",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E #more comment",[extended,{parts,2}]))),
+ literal\\E #more comment",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E #more comment",[extended]))),
- <<"">> = iolist_to_binary(join(re:split("abc\\$xyz","\\Qabc\\$xyz\\E",[trim]))),
+ literal\\E #more comment",[extended]))),
+ <<"">> = iolist_to_binary(join(re:split("abc\\$xyz","\\Qabc\\$xyz\\E",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc\\$xyz","\\Qabc\\$xyz\\E",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc\\$xyz","\\Qabc\\$xyz\\E",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc\\$xyz","\\Qabc\\$xyz\\E",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","\\Aabc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","\\Aabc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","\\Aabc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","\\Aabc",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc",[]))),
- <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","\\Aabc",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\Aabc",[]))),
+ <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","\\Aabc",[trim]))),
<<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","\\Aabc",[{parts,
- 2}]))),
- <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","\\Aabc",[]))),
- <<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","\\Aabc.",[trim]))),
+ 2}]))),
+ <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","\\Aabc",[]))),
+ <<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","\\Aabc.",[trim]))),
<<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","\\Aabc.",[{parts,
- 2}]))),
- <<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","\\Aabc.",[]))),
- <<"::xyz">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","abc.",[trim]))),
+ 2}]))),
+ <<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","\\Aabc.",[]))),
+ <<"::xyz">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","abc.",[trim]))),
<<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","abc.",[{parts,
- 2}]))),
- <<"::xyz:">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","abc.",[]))),
- <<"X:Y">> = iolist_to_binary(join(re:split("XabcdY","a(?x: b c )d",[trim]))),
+ 2}]))),
+ <<"::xyz:">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","abc.",[]))),
+ <<"X:Y">> = iolist_to_binary(join(re:split("XabcdY","a(?x: b c )d",[trim]))),
<<"X:Y">> = iolist_to_binary(join(re:split("XabcdY","a(?x: b c )d",[{parts,
- 2}]))),
- <<"X:Y">> = iolist_to_binary(join(re:split("XabcdY","a(?x: b c )d",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?x: b c )d",[trim]))),
+ 2}]))),
+ <<"X:Y">> = iolist_to_binary(join(re:split("XabcdY","a(?x: b c )d",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?x: b c )d",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?x: b c )d",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?x: b c )d",[]))),
- <<"Xa b c d Y">> = iolist_to_binary(join(re:split("Xa b c d Y","a(?x: b c )d",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","a(?x: b c )d",[]))),
+ <<"Xa b c d Y">> = iolist_to_binary(join(re:split("Xa b c d Y","a(?x: b c )d",[trim]))),
<<"Xa b c d Y">> = iolist_to_binary(join(re:split("Xa b c d Y","a(?x: b c )d",[{parts,
- 2}]))),
- <<"Xa b c d Y">> = iolist_to_binary(join(re:split("Xa b c d Y","a(?x: b c )d",[]))),
- <<"X:abc:Y">> = iolist_to_binary(join(re:split("XabcY","((?x)x y z | a b c)",[trim]))),
+ 2}]))),
+ <<"Xa b c d Y">> = iolist_to_binary(join(re:split("Xa b c d Y","a(?x: b c )d",[]))),
+ <<"X:abc:Y">> = iolist_to_binary(join(re:split("XabcY","((?x)x y z | a b c)",[trim]))),
<<"X:abc:Y">> = iolist_to_binary(join(re:split("XabcY","((?x)x y z | a b c)",[{parts,
- 2}]))),
- <<"X:abc:Y">> = iolist_to_binary(join(re:split("XabcY","((?x)x y z | a b c)",[]))),
- <<"A:xyz:B">> = iolist_to_binary(join(re:split("AxyzB","((?x)x y z | a b c)",[trim]))),
+ 2}]))),
+ <<"X:abc:Y">> = iolist_to_binary(join(re:split("XabcY","((?x)x y z | a b c)",[]))),
+ <<"A:xyz:B">> = iolist_to_binary(join(re:split("AxyzB","((?x)x y z | a b c)",[trim]))),
<<"A:xyz:B">> = iolist_to_binary(join(re:split("AxyzB","((?x)x y z | a b c)",[{parts,
- 2}]))),
- <<"A:xyz:B">> = iolist_to_binary(join(re:split("AxyzB","((?x)x y z | a b c)",[]))),
- <<"X:Y">> = iolist_to_binary(join(re:split("XabCY","(?i)AB(?-i)C",[trim]))),
+ 2}]))),
+ <<"A:xyz:B">> = iolist_to_binary(join(re:split("AxyzB","((?x)x y z | a b c)",[]))),
+ <<"X:Y">> = iolist_to_binary(join(re:split("XabCY","(?i)AB(?-i)C",[trim]))),
<<"X:Y">> = iolist_to_binary(join(re:split("XabCY","(?i)AB(?-i)C",[{parts,
- 2}]))),
- <<"X:Y">> = iolist_to_binary(join(re:split("XabCY","(?i)AB(?-i)C",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i)AB(?-i)C",[trim]))),
+ 2}]))),
+ <<"X:Y">> = iolist_to_binary(join(re:split("XabCY","(?i)AB(?-i)C",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i)AB(?-i)C",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i)AB(?-i)C",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i)AB(?-i)C",[]))),
- <<"XabcY">> = iolist_to_binary(join(re:split("XabcY","(?i)AB(?-i)C",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?i)AB(?-i)C",[]))),
+ <<"XabcY">> = iolist_to_binary(join(re:split("XabcY","(?i)AB(?-i)C",[trim]))),
<<"XabcY">> = iolist_to_binary(join(re:split("XabcY","(?i)AB(?-i)C",[{parts,
- 2}]))),
- <<"XabcY">> = iolist_to_binary(join(re:split("XabcY","(?i)AB(?-i)C",[]))),
- <<":abC">> = iolist_to_binary(join(re:split("abCE","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<"XabcY">> = iolist_to_binary(join(re:split("XabcY","(?i)AB(?-i)C",[]))),
+ <<":abC">> = iolist_to_binary(join(re:split("abCE","((?i)AB(?-i)C|D)E",[trim]))),
<<":abC:">> = iolist_to_binary(join(re:split("abCE","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<":abC:">> = iolist_to_binary(join(re:split("abCE","((?i)AB(?-i)C|D)E",[]))),
- <<":D">> = iolist_to_binary(join(re:split("DE","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<":abC:">> = iolist_to_binary(join(re:split("abCE","((?i)AB(?-i)C|D)E",[]))),
+ <<":D">> = iolist_to_binary(join(re:split("DE","((?i)AB(?-i)C|D)E",[trim]))),
<<":D:">> = iolist_to_binary(join(re:split("DE","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<":D:">> = iolist_to_binary(join(re:split("DE","((?i)AB(?-i)C|D)E",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<":D:">> = iolist_to_binary(join(re:split("DE","((?i)AB(?-i)C|D)E",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)AB(?-i)C|D)E",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)AB(?-i)C|D)E",[]))),
- <<"abcE">> = iolist_to_binary(join(re:split("abcE","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((?i)AB(?-i)C|D)E",[]))),
+ <<"abcE">> = iolist_to_binary(join(re:split("abcE","((?i)AB(?-i)C|D)E",[trim]))),
<<"abcE">> = iolist_to_binary(join(re:split("abcE","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<"abcE">> = iolist_to_binary(join(re:split("abcE","((?i)AB(?-i)C|D)E",[]))),
- <<"abCe">> = iolist_to_binary(join(re:split("abCe","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<"abcE">> = iolist_to_binary(join(re:split("abcE","((?i)AB(?-i)C|D)E",[]))),
+ <<"abCe">> = iolist_to_binary(join(re:split("abCe","((?i)AB(?-i)C|D)E",[trim]))),
<<"abCe">> = iolist_to_binary(join(re:split("abCe","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<"abCe">> = iolist_to_binary(join(re:split("abCe","((?i)AB(?-i)C|D)E",[]))),
- <<"dE">> = iolist_to_binary(join(re:split("dE","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<"abCe">> = iolist_to_binary(join(re:split("abCe","((?i)AB(?-i)C|D)E",[]))),
+ <<"dE">> = iolist_to_binary(join(re:split("dE","((?i)AB(?-i)C|D)E",[trim]))),
<<"dE">> = iolist_to_binary(join(re:split("dE","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<"dE">> = iolist_to_binary(join(re:split("dE","((?i)AB(?-i)C|D)E",[]))),
- <<"De">> = iolist_to_binary(join(re:split("De","((?i)AB(?-i)C|D)E",[trim]))),
+ 2}]))),
+ <<"dE">> = iolist_to_binary(join(re:split("dE","((?i)AB(?-i)C|D)E",[]))),
+ <<"De">> = iolist_to_binary(join(re:split("De","((?i)AB(?-i)C|D)E",[trim]))),
<<"De">> = iolist_to_binary(join(re:split("De","((?i)AB(?-i)C|D)E",[{parts,
- 2}]))),
- <<"De">> = iolist_to_binary(join(re:split("De","((?i)AB(?-i)C|D)E",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[trim]))),
+ 2}]))),
+ <<"De">> = iolist_to_binary(join(re:split("De","((?i)AB(?-i)C|D)E",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[]))),
- <<"a:bc">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[]))),
+ <<"a:bc">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[trim]))),
<<"a:bc:">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[{parts,
- 2}]))),
- <<"a:bc:">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[]))),
+ 2}]))),
+ <<"a:bc:">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[]))),
<<":abc">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[dotall,
- trim]))),
+ trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[dotall,
{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[dotall]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abc123abc","(.*)\\d+\\1",[dotall]))),
<<"a:bc">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[dotall,
- trim]))),
+ trim]))),
<<"a:bc:">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[dotall,
{parts,
- 2}]))),
- <<"a:bc:">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[dotall]))),
- <<":abc:abc">> = iolist_to_binary(join(re:split("abc123abc","((.*))\\d+\\1",[trim]))),
+ 2}]))),
+ <<"a:bc:">> = iolist_to_binary(join(re:split("abc123bc","(.*)\\d+\\1",[dotall]))),
+ <<":abc:abc">> = iolist_to_binary(join(re:split("abc123abc","((.*))\\d+\\1",[trim]))),
<<":abc:abc:">> = iolist_to_binary(join(re:split("abc123abc","((.*))\\d+\\1",[{parts,
- 2}]))),
- <<":abc:abc:">> = iolist_to_binary(join(re:split("abc123abc","((.*))\\d+\\1",[]))),
- <<"a:bc:bc">> = iolist_to_binary(join(re:split("abc123bc","((.*))\\d+\\1",[trim]))),
+ 2}]))),
+ <<":abc:abc:">> = iolist_to_binary(join(re:split("abc123abc","((.*))\\d+\\1",[]))),
+ <<"a:bc:bc">> = iolist_to_binary(join(re:split("abc123bc","((.*))\\d+\\1",[trim]))),
<<"a:bc:bc:">> = iolist_to_binary(join(re:split("abc123bc","((.*))\\d+\\1",[{parts,
- 2}]))),
- <<"a:bc:bc:">> = iolist_to_binary(join(re:split("abc123bc","((.*))\\d+\\1",[]))),
+ 2}]))),
+ <<"a:bc:bc:">> = iolist_to_binary(join(re:split("abc123bc","((.*))\\d+\\1",[]))),
<<"">> = iolist_to_binary(join(re:split("a123::a123","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28581,7 +28581,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::">> = iolist_to_binary(join(re:split("a123::a123","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28590,7 +28590,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::">> = iolist_to_binary(join(re:split("a123::a123","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28599,7 +28599,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"">> = iolist_to_binary(join(re:split("a123:b342::abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28608,7 +28608,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::">> = iolist_to_binary(join(re:split("a123:b342::abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28617,7 +28617,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::">> = iolist_to_binary(join(re:split("a123:b342::abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28626,7 +28626,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"">> = iolist_to_binary(join(re:split("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28635,7 +28635,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::">> = iolist_to_binary(join(re:split("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28644,7 +28644,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::">> = iolist_to_binary(join(re:split("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28653,7 +28653,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"">> = iolist_to_binary(join(re:split("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28662,7 +28662,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::">> = iolist_to_binary(join(re:split("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28671,7 +28671,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::">> = iolist_to_binary(join(re:split("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28680,7 +28680,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"">> = iolist_to_binary(join(re:split("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28689,7 +28689,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::">> = iolist_to_binary(join(re:split("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28698,7 +28698,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::">> = iolist_to_binary(join(re:split("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28707,7 +28707,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"">> = iolist_to_binary(join(re:split("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28716,7 +28716,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::">> = iolist_to_binary(join(re:split("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28725,7 +28725,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::">> = iolist_to_binary(join(re:split("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28734,7 +28734,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28743,7 +28743,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28752,7 +28752,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28761,7 +28761,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"1:2:3:4:5:6:7:8">> = iolist_to_binary(join(re:split("1:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28770,7 +28770,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"1:2:3:4:5:6:7:8">> = iolist_to_binary(join(re:split("1:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28779,7 +28779,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"1:2:3:4:5:6:7:8">> = iolist_to_binary(join(re:split("1:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28788,7 +28788,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"a123:bce:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(join(re:split("a123:bce:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28797,7 +28797,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"a123:bce:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(join(re:split("a123:bce:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28806,7 +28806,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"a123:bce:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(join(re:split("a123:bce:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28815,7 +28815,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"a123::9999:b342::324e:dcba:abcd">> = iolist_to_binary(join(re:split("a123::9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28824,7 +28824,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"a123::9999:b342::324e:dcba:abcd">> = iolist_to_binary(join(re:split("a123::9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28833,7 +28833,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"a123::9999:b342::324e:dcba:abcd">> = iolist_to_binary(join(re:split("a123::9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28842,7 +28842,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"abcde:2:3:4:5:6:7:8">> = iolist_to_binary(join(re:split("abcde:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28851,7 +28851,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"abcde:2:3:4:5:6:7:8">> = iolist_to_binary(join(re:split("abcde:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28860,7 +28860,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"abcde:2:3:4:5:6:7:8">> = iolist_to_binary(join(re:split("abcde:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28869,7 +28869,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"::1">> = iolist_to_binary(join(re:split("::1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28878,7 +28878,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"::1">> = iolist_to_binary(join(re:split("::1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28887,7 +28887,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"::1">> = iolist_to_binary(join(re:split("::1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28896,7 +28896,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"abcd:fee0:123::">> = iolist_to_binary(join(re:split("abcd:fee0:123::","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28905,7 +28905,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"abcd:fee0:123::">> = iolist_to_binary(join(re:split("abcd:fee0:123::","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28914,7 +28914,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"abcd:fee0:123::">> = iolist_to_binary(join(re:split("abcd:fee0:123::","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28923,7 +28923,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<":1">> = iolist_to_binary(join(re:split(":1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28932,7 +28932,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<":1">> = iolist_to_binary(join(re:split(":1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28941,7 +28941,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<":1">> = iolist_to_binary(join(re:split(":1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28950,7 +28950,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
+ ",[extended,caseless]))),
<<"1:">> = iolist_to_binary(join(re:split("1:","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28959,7 +28959,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,trim]))),
+ ",[extended,caseless,trim]))),
<<"1:">> = iolist_to_binary(join(re:split("1:","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28968,7 +28968,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless,{parts,2}]))),
+ ",[extended,caseless,{parts,2}]))),
<<"1:">> = iolist_to_binary(join(re:split("1:","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -28977,3098 +28977,3147 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ",[extended,caseless]))),
- <<"">> = iolist_to_binary(join(re:split("z","[z\\Qa-d]\\E]",[trim]))),
+ ",[extended,caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("z","[z\\Qa-d]\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("z","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("z","[z\\Qa-d]\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","[z\\Qa-d]\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("z","[z\\Qa-d]\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","[z\\Qa-d]\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","[z\\Qa-d]\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","[z\\Qa-d]\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","[z\\Qa-d]\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","[z\\Qa-d]\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","[z\\Qa-d]\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("d","[z\\Qa-d]\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","[z\\Qa-d]\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("d","[z\\Qa-d]\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("d","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("d","[z\\Qa-d]\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("]","[z\\Qa-d]\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("d","[z\\Qa-d]\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("]","[z\\Qa-d]\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("]","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("]","[z\\Qa-d]\\E]",[]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[z\\Qa-d]\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("]","[z\\Qa-d]\\E]",[]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[z\\Qa-d]\\E]",[trim]))),
<<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[z\\Qa-d]\\E]",[]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[z\\Qa-d]\\E]",[trim]))),
+ 2}]))),
+ <<"*** F:ilers">> = iolist_to_binary(join(re:split("*** Failers","[z\\Qa-d]\\E]",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[z\\Qa-d]\\E]",[trim]))),
<<"b">> = iolist_to_binary(join(re:split("b","[z\\Qa-d]\\E]",[{parts,
- 2}]))),
- <<"b">> = iolist_to_binary(join(re:split("b","[z\\Qa-d]\\E]",[]))),
+ 2}]))),
+ <<"b">> = iolist_to_binary(join(re:split("b","[z\\Qa-d]\\E]",[]))),
ok.
run34() ->
- <<"">> = iolist_to_binary(join(re:split("z","[\\z\\C]",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("z","[\\z\\C]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("z","[\\z\\C]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("z","[\\z\\C]",[]))),
- <<"">> = iolist_to_binary(join(re:split("C","[\\z\\C]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("z","[\\z\\C]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("C","[\\z\\C]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("C","[\\z\\C]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("C","[\\z\\C]",[]))),
- <<"">> = iolist_to_binary(join(re:split("M","\\M",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("C","[\\z\\C]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("M","\\M",[trim]))),
<<":">> = iolist_to_binary(join(re:split("M","\\M",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("M","\\M",[]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("M","\\M",[]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[trim]))),
<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[]))),
- <<"„XAZ">> = iolist_to_binary(join(re:split("„XAZXB","(?<=Z)X.",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[]))),
+ <<"„XAZ">> = iolist_to_binary(join(re:split("„XAZXB","(?<=Z)X.",[trim]))),
<<"„XAZ:">> = iolist_to_binary(join(re:split("„XAZXB","(?<=Z)X.",[{parts,
- 2}]))),
- <<"„XAZ:">> = iolist_to_binary(join(re:split("„XAZXB","(?<=Z)X.",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[trim]))),
+ 2}]))),
+ <<"„XAZ:">> = iolist_to_binary(join(re:split("„XAZXB","(?<=Z)X.",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab cddefg","ab cd(?x) de fg",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab cddefg","ab cd(?x) de fg",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab cddefg","ab cd(?x) de fg",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab cddefg","ab cd(?x) de fg",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","ab cd(?x) de fg",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab cddefg","ab cd(?x) de fg",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","ab cd(?x) de fg",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","ab cd(?x) de fg",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","ab cd(?x) de fg",[]))),
- <<"abcddefg">> = iolist_to_binary(join(re:split("abcddefg","ab cd(?x) de fg",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","ab cd(?x) de fg",[]))),
+ <<"abcddefg">> = iolist_to_binary(join(re:split("abcddefg","ab cd(?x) de fg",[trim]))),
<<"abcddefg">> = iolist_to_binary(join(re:split("abcddefg","ab cd(?x) de fg",[{parts,
- 2}]))),
- <<"abcddefg">> = iolist_to_binary(join(re:split("abcddefg","ab cd(?x) de fg",[]))),
- <<"foo:bar:X">> = iolist_to_binary(join(re:split("foobarX","(?<![^f]oo)(bar)",[trim]))),
+ 2}]))),
+ <<"abcddefg">> = iolist_to_binary(join(re:split("abcddefg","ab cd(?x) de fg",[]))),
+ <<"foo:bar:X">> = iolist_to_binary(join(re:split("foobarX","(?<![^f]oo)(bar)",[trim]))),
<<"foo:bar:X">> = iolist_to_binary(join(re:split("foobarX","(?<![^f]oo)(bar)",[{parts,
- 2}]))),
- <<"foo:bar:X">> = iolist_to_binary(join(re:split("foobarX","(?<![^f]oo)(bar)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f]oo)(bar)",[trim]))),
+ 2}]))),
+ <<"foo:bar:X">> = iolist_to_binary(join(re:split("foobarX","(?<![^f]oo)(bar)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f]oo)(bar)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f]oo)(bar)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f]oo)(bar)",[]))),
- <<"boobarX">> = iolist_to_binary(join(re:split("boobarX","(?<![^f]oo)(bar)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f]oo)(bar)",[]))),
+ <<"boobarX">> = iolist_to_binary(join(re:split("boobarX","(?<![^f]oo)(bar)",[trim]))),
<<"boobarX">> = iolist_to_binary(join(re:split("boobarX","(?<![^f]oo)(bar)",[{parts,
- 2}]))),
- <<"boobarX">> = iolist_to_binary(join(re:split("boobarX","(?<![^f]oo)(bar)",[]))),
- <<"off">> = iolist_to_binary(join(re:split("offX","(?<![^f])X",[trim]))),
+ 2}]))),
+ <<"boobarX">> = iolist_to_binary(join(re:split("boobarX","(?<![^f]oo)(bar)",[]))),
+ <<"off">> = iolist_to_binary(join(re:split("offX","(?<![^f])X",[trim]))),
<<"off:">> = iolist_to_binary(join(re:split("offX","(?<![^f])X",[{parts,
- 2}]))),
- <<"off:">> = iolist_to_binary(join(re:split("offX","(?<![^f])X",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f])X",[trim]))),
+ 2}]))),
+ <<"off:">> = iolist_to_binary(join(re:split("offX","(?<![^f])X",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f])X",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f])X",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f])X",[]))),
- <<"onyX">> = iolist_to_binary(join(re:split("onyX","(?<![^f])X",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<![^f])X",[]))),
+ <<"onyX">> = iolist_to_binary(join(re:split("onyX","(?<![^f])X",[trim]))),
<<"onyX">> = iolist_to_binary(join(re:split("onyX","(?<![^f])X",[{parts,
- 2}]))),
- <<"onyX">> = iolist_to_binary(join(re:split("onyX","(?<![^f])X",[]))),
- <<"ony">> = iolist_to_binary(join(re:split("onyX","(?<=[^f])X",[trim]))),
+ 2}]))),
+ <<"onyX">> = iolist_to_binary(join(re:split("onyX","(?<![^f])X",[]))),
+ <<"ony">> = iolist_to_binary(join(re:split("onyX","(?<=[^f])X",[trim]))),
<<"ony:">> = iolist_to_binary(join(re:split("onyX","(?<=[^f])X",[{parts,
- 2}]))),
- <<"ony:">> = iolist_to_binary(join(re:split("onyX","(?<=[^f])X",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^f])X",[trim]))),
+ 2}]))),
+ <<"ony:">> = iolist_to_binary(join(re:split("onyX","(?<=[^f])X",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^f])X",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^f])X",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^f])X",[]))),
- <<"offX">> = iolist_to_binary(join(re:split("offX","(?<=[^f])X",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^f])X",[]))),
+ <<"offX">> = iolist_to_binary(join(re:split("offX","(?<=[^f])X",[trim]))),
<<"offX">> = iolist_to_binary(join(re:split("offX","(?<=[^f])X",[{parts,
- 2}]))),
- <<"offX">> = iolist_to_binary(join(re:split("offX","(?<=[^f])X",[]))),
+ 2}]))),
+ <<"offX">> = iolist_to_binary(join(re:split("offX","(?<=[^f])X",[]))),
<<"a
:b
:c">> = iolist_to_binary(join(re:split("a
b
-c","^",[multiline,trim]))),
+c","^",[multiline,trim]))),
<<"a
:b
c">> = iolist_to_binary(join(re:split("a
b
-c","^",[multiline,{parts,2}]))),
+c","^",[multiline,{parts,2}]))),
<<"a
:b
:c">> = iolist_to_binary(join(re:split("a
b
-c","^",[multiline]))),
+c","^",[multiline]))),
<<"">> = iolist_to_binary(join(re:split("","^",[multiline,
- trim]))),
+ trim]))),
<<"">> = iolist_to_binary(join(re:split("","^",[multiline,
{parts,
- 2}]))),
- <<"">> = iolist_to_binary(join(re:split("","^",[multiline]))),
+ 2}]))),
+ <<"">> = iolist_to_binary(join(re:split("","^",[multiline]))),
<<"A
C
:C">> = iolist_to_binary(join(re:split("A
C
-C","(?<=C\\n)^",[multiline,trim]))),
+C","(?<=C\\n)^",[multiline,trim]))),
<<"A
C
:C">> = iolist_to_binary(join(re:split("A
C
-C","(?<=C\\n)^",[multiline,{parts,2}]))),
+C","(?<=C\\n)^",[multiline,{parts,2}]))),
<<"A
C
:C">> = iolist_to_binary(join(re:split("A
C
-C","(?<=C\\n)^",[multiline]))),
- <<":X">> = iolist_to_binary(join(re:split("bXaX","(?:(?(1)a|b)(X))+",[trim]))),
+C","(?<=C\\n)^",[multiline]))),
+ <<":X">> = iolist_to_binary(join(re:split("bXaX","(?:(?(1)a|b)(X))+",[trim]))),
<<":X:">> = iolist_to_binary(join(re:split("bXaX","(?:(?(1)a|b)(X))+",[{parts,
- 2}]))),
- <<":X:">> = iolist_to_binary(join(re:split("bXaX","(?:(?(1)a|b)(X))+",[]))),
- <<":Y">> = iolist_to_binary(join(re:split("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+",[trim]))),
+ 2}]))),
+ <<":X:">> = iolist_to_binary(join(re:split("bXaX","(?:(?(1)a|b)(X))+",[]))),
+ <<":Y">> = iolist_to_binary(join(re:split("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+",[trim]))),
<<":Y:">> = iolist_to_binary(join(re:split("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+",[{parts,
- 2}]))),
- <<":Y:">> = iolist_to_binary(join(re:split("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+",[]))),
- <<":X:YaXXaX">> = iolist_to_binary(join(re:split("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+",[trim]))),
+ 2}]))),
+ <<":Y:">> = iolist_to_binary(join(re:split("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+",[]))),
+ <<":X:YaXXaX">> = iolist_to_binary(join(re:split("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+",[trim]))),
<<":X:YaXXaX">> = iolist_to_binary(join(re:split("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+",[{parts,
- 2}]))),
- <<":X:YaXXaX">> = iolist_to_binary(join(re:split("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+",[]))),
- <<"::::::::::X:XaYYaY">> = iolist_to_binary(join(re:split("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+",[trim]))),
+ 2}]))),
+ <<":X:YaXXaX">> = iolist_to_binary(join(re:split("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+",[]))),
+ <<"::::::::::X:XaYYaY">> = iolist_to_binary(join(re:split("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+",[trim]))),
<<"::::::::::X:XaYYaY">> = iolist_to_binary(join(re:split("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+",[{parts,
- 2}]))),
- <<"::::::::::X:XaYYaY">> = iolist_to_binary(join(re:split("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc]","[[,abc,]+]",[trim]))),
+ 2}]))),
+ <<"::::::::::X:XaYYaY">> = iolist_to_binary(join(re:split("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc]","[[,abc,]+]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc]","[[,abc,]+]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc]","[[,abc,]+]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a,b]","[[,abc,]+]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc]","[[,abc,]+]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a,b]","[[,abc,]+]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a,b]","[[,abc,]+]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a,b]","[[,abc,]+]",[]))),
- <<"">> = iolist_to_binary(join(re:split("[a,b,c]","[[,abc,]+]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a,b]","[[,abc,]+]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("[a,b,c]","[[,abc,]+]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("[a,b,c]","[[,abc,]+]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("[a,b,c]","[[,abc,]+]",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("[a,b,c]","[[,abc,]+]",[]))),
<<"A:B">> = iolist_to_binary(join(re:split("A B","(?-x: )",[extended,
- trim]))),
+ trim]))),
<<"A:B">> = iolist_to_binary(join(re:split("A B","(?-x: )",[extended,
{parts,
- 2}]))),
- <<"A:B">> = iolist_to_binary(join(re:split("A B","(?-x: )",[extended]))),
- <<"A:B">> = iolist_to_binary(join(re:split("A # B","(?x)(?-x: \\s*#\\s*)",[trim]))),
+ 2}]))),
+ <<"A:B">> = iolist_to_binary(join(re:split("A B","(?-x: )",[extended]))),
+ <<"A:B">> = iolist_to_binary(join(re:split("A # B","(?x)(?-x: \\s*#\\s*)",[trim]))),
<<"A:B">> = iolist_to_binary(join(re:split("A # B","(?x)(?-x: \\s*#\\s*)",[{parts,
- 2}]))),
- <<"A:B">> = iolist_to_binary(join(re:split("A # B","(?x)(?-x: \\s*#\\s*)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x)(?-x: \\s*#\\s*)",[trim]))),
+ 2}]))),
+ <<"A:B">> = iolist_to_binary(join(re:split("A # B","(?x)(?-x: \\s*#\\s*)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x)(?-x: \\s*#\\s*)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x)(?-x: \\s*#\\s*)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x)(?-x: \\s*#\\s*)",[]))),
- <<"#">> = iolist_to_binary(join(re:split("#","(?x)(?-x: \\s*#\\s*)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x)(?-x: \\s*#\\s*)",[]))),
+ <<"#">> = iolist_to_binary(join(re:split("#","(?x)(?-x: \\s*#\\s*)",[trim]))),
<<"#">> = iolist_to_binary(join(re:split("#","(?x)(?-x: \\s*#\\s*)",[{parts,
- 2}]))),
- <<"#">> = iolist_to_binary(join(re:split("#","(?x)(?-x: \\s*#\\s*)",[]))),
- <<"A">> = iolist_to_binary(join(re:split("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
+ 2}]))),
+ <<"#">> = iolist_to_binary(join(re:split("#","(?x)(?-x: \\s*#\\s*)",[]))),
+ <<"A">> = iolist_to_binary(join(re:split("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
<<"A:">> = iolist_to_binary(join(re:split("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[{parts,
- 2}]))),
- <<"A:">> = iolist_to_binary(join(re:split("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
+ 2}]))),
+ <<"A:">> = iolist_to_binary(join(re:split("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
- <<"A#include">> = iolist_to_binary(join(re:split("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
+ <<"A#include">> = iolist_to_binary(join(re:split("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
<<"A#include">> = iolist_to_binary(join(re:split("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[{parts,
- 2}]))),
- <<"A#include">> = iolist_to_binary(join(re:split("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
- <<"A #Include">> = iolist_to_binary(join(re:split("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
+ 2}]))),
+ <<"A#include">> = iolist_to_binary(join(re:split("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
+ <<"A #Include">> = iolist_to_binary(join(re:split("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[trim]))),
<<"A #Include">> = iolist_to_binary(join(re:split("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[{parts,
- 2}]))),
- <<"A #Include">> = iolist_to_binary(join(re:split("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
+ 2}]))),
+ <<"A #Include">> = iolist_to_binary(join(re:split("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include",[]))),
ok.
run35() ->
- <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b*\\w",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","a*b*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","a*b*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","a*b*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","a*b*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","a*b*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","a*b*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","a*b*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a*b*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b?\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a*b*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b?\\w",[trim]))),
<<":bb">> = iolist_to_binary(join(re:split("aaabbbb","a*b?\\w",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaabbbb","a*b?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","a*b?\\w",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaabbbb","a*b?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","a*b?\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","a*b?\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","a*b?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","a*b?\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","a*b?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","a*b?\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b?\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a*b?\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,4}\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a*b?\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,4}\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,4}\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,4}\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","a*b{0,4}\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,4}\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","a*b{0,4}\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","a*b{0,4}\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","a*b{0,4}\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","a*b{0,4}\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","a*b{0,4}\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","a*b{0,4}\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b{0,4}\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a*b{0,4}\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,}\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a*b{0,4}\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,}\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,}\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,}\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","a*b{0,}\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaabbbb","a*b{0,}\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","a*b{0,}\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","a*b{0,}\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","a*b{0,}\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","a*b{0,}\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","a*b{0,}\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","a*b{0,}\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b{0,}\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a*b{0,}\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("0a","a*\\d*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a*b{0,}\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("0a","a*\\d*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("0a","a*\\d*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("0a","a*\\d*\\w",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","a*\\d*\\w",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("0a","a*\\d*\\w",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","a*\\d*\\w",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*\\d*\\w",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a*\\d*\\w",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a*\\d*\\w",[]))),
<<"">> = iolist_to_binary(join(re:split("a","a*b *\\w",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b *\\w",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a*b *\\w",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a*b *\\w",[extended]))),
<<"">> = iolist_to_binary(join(re:split("a","a*b#comment
- *\\w",[extended,trim]))),
+ *\\w",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b#comment
- *\\w",[extended,{parts,2}]))),
+ *\\w",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a","a*b#comment
- *\\w",[extended]))),
+ *\\w",[extended]))),
<<"">> = iolist_to_binary(join(re:split("a","a* b *\\w",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("a","a* b *\\w",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","a* b *\\w",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","a* b *\\w",[extended]))),
<<"::
pqr">> = iolist_to_binary(join(re:split("abc=xyz\\
-pqr","^\\w+=.*(\\\\\\n.*)*",[trim]))),
+pqr","^\\w+=.*(\\\\\\n.*)*",[trim]))),
<<"::
pqr">> = iolist_to_binary(join(re:split("abc=xyz\\
-pqr","^\\w+=.*(\\\\\\n.*)*",[{parts,2}]))),
+pqr","^\\w+=.*(\\\\\\n.*)*",[{parts,2}]))),
<<"::
pqr">> = iolist_to_binary(join(re:split("abc=xyz\\
-pqr","^\\w+=.*(\\\\\\n.*)*",[]))),
- <<":abcd">> = iolist_to_binary(join(re:split("abcd:","(?=(\\w+))\\1:",[trim]))),
+pqr","^\\w+=.*(\\\\\\n.*)*",[]))),
+ <<":abcd">> = iolist_to_binary(join(re:split("abcd:","(?=(\\w+))\\1:",[trim]))),
<<":abcd:">> = iolist_to_binary(join(re:split("abcd:","(?=(\\w+))\\1:",[{parts,
- 2}]))),
- <<":abcd:">> = iolist_to_binary(join(re:split("abcd:","(?=(\\w+))\\1:",[]))),
- <<":abcd">> = iolist_to_binary(join(re:split("abcd:","^(?=(\\w+))\\1:",[trim]))),
+ 2}]))),
+ <<":abcd:">> = iolist_to_binary(join(re:split("abcd:","(?=(\\w+))\\1:",[]))),
+ <<":abcd">> = iolist_to_binary(join(re:split("abcd:","^(?=(\\w+))\\1:",[trim]))),
<<":abcd:">> = iolist_to_binary(join(re:split("abcd:","^(?=(\\w+))\\1:",[{parts,
- 2}]))),
- <<":abcd:">> = iolist_to_binary(join(re:split("abcd:","^(?=(\\w+))\\1:",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","^\\Eabc",[trim]))),
+ 2}]))),
+ <<":abcd:">> = iolist_to_binary(join(re:split("abcd:","^(?=(\\w+))\\1:",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","^\\Eabc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^\\Eabc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","^\\Eabc",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^[\\Eabc]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","^\\Eabc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^[\\Eabc]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","^[\\Eabc]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","^[\\Eabc]",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\Eabc]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","^[\\Eabc]",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\Eabc]",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\Eabc]",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\Eabc]",[]))),
- <<"E">> = iolist_to_binary(join(re:split("E","^[\\Eabc]",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\Eabc]",[]))),
+ <<"E">> = iolist_to_binary(join(re:split("E","^[\\Eabc]",[trim]))),
<<"E">> = iolist_to_binary(join(re:split("E","^[\\Eabc]",[{parts,
- 2}]))),
- <<"E">> = iolist_to_binary(join(re:split("E","^[\\Eabc]",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^[a-\\Ec]",[trim]))),
+ 2}]))),
+ <<"E">> = iolist_to_binary(join(re:split("E","^[\\Eabc]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^[a-\\Ec]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("b","^[a-\\Ec]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("b","^[a-\\Ec]",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a-\\Ec]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("b","^[a-\\Ec]",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a-\\Ec]",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a-\\Ec]",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a-\\Ec]",[]))),
- <<"-">> = iolist_to_binary(join(re:split("-","^[a-\\Ec]",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a-\\Ec]",[]))),
+ <<"-">> = iolist_to_binary(join(re:split("-","^[a-\\Ec]",[trim]))),
<<"-">> = iolist_to_binary(join(re:split("-","^[a-\\Ec]",[{parts,
- 2}]))),
- <<"-">> = iolist_to_binary(join(re:split("-","^[a-\\Ec]",[]))),
- <<"E">> = iolist_to_binary(join(re:split("E","^[a-\\Ec]",[trim]))),
+ 2}]))),
+ <<"-">> = iolist_to_binary(join(re:split("-","^[a-\\Ec]",[]))),
+ <<"E">> = iolist_to_binary(join(re:split("E","^[a-\\Ec]",[trim]))),
<<"E">> = iolist_to_binary(join(re:split("E","^[a-\\Ec]",[{parts,
- 2}]))),
- <<"E">> = iolist_to_binary(join(re:split("E","^[a-\\Ec]",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^[a\\E\\E-\\Ec]",[trim]))),
+ 2}]))),
+ <<"E">> = iolist_to_binary(join(re:split("E","^[a-\\Ec]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^[a\\E\\E-\\Ec]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("b","^[a\\E\\E-\\Ec]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("b","^[a\\E\\E-\\Ec]",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a\\E\\E-\\Ec]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("b","^[a\\E\\E-\\Ec]",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a\\E\\E-\\Ec]",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a\\E\\E-\\Ec]",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a\\E\\E-\\Ec]",[]))),
- <<"-">> = iolist_to_binary(join(re:split("-","^[a\\E\\E-\\Ec]",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[a\\E\\E-\\Ec]",[]))),
+ <<"-">> = iolist_to_binary(join(re:split("-","^[a\\E\\E-\\Ec]",[trim]))),
<<"-">> = iolist_to_binary(join(re:split("-","^[a\\E\\E-\\Ec]",[{parts,
- 2}]))),
- <<"-">> = iolist_to_binary(join(re:split("-","^[a\\E\\E-\\Ec]",[]))),
- <<"E">> = iolist_to_binary(join(re:split("E","^[a\\E\\E-\\Ec]",[trim]))),
+ 2}]))),
+ <<"-">> = iolist_to_binary(join(re:split("-","^[a\\E\\E-\\Ec]",[]))),
+ <<"E">> = iolist_to_binary(join(re:split("E","^[a\\E\\E-\\Ec]",[trim]))),
<<"E">> = iolist_to_binary(join(re:split("E","^[a\\E\\E-\\Ec]",[{parts,
- 2}]))),
- <<"E">> = iolist_to_binary(join(re:split("E","^[a\\E\\E-\\Ec]",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","^[\\E\\Qa\\E-\\Qz\\E]+",[trim]))),
+ 2}]))),
+ <<"E">> = iolist_to_binary(join(re:split("E","^[a\\E\\E-\\Ec]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","^[\\E\\Qa\\E-\\Qz\\E]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("b","^[\\E\\Qa\\E-\\Qz\\E]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("b","^[\\E\\Qa\\E-\\Qz\\E]+",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("b","^[\\E\\Qa\\E-\\Qz\\E]+",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+",[]))),
- <<"-">> = iolist_to_binary(join(re:split("-","^[\\E\\Qa\\E-\\Qz\\E]+",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+",[]))),
+ <<"-">> = iolist_to_binary(join(re:split("-","^[\\E\\Qa\\E-\\Qz\\E]+",[trim]))),
<<"-">> = iolist_to_binary(join(re:split("-","^[\\E\\Qa\\E-\\Qz\\E]+",[{parts,
- 2}]))),
- <<"-">> = iolist_to_binary(join(re:split("-","^[\\E\\Qa\\E-\\Qz\\E]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^[a\\Q]bc\\E]",[trim]))),
+ 2}]))),
+ <<"-">> = iolist_to_binary(join(re:split("-","^[\\E\\Qa\\E-\\Qz\\E]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^[a\\Q]bc\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","^[a\\Q]bc\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","^[a\\Q]bc\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("]","^[a\\Q]bc\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","^[a\\Q]bc\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("]","^[a\\Q]bc\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("]","^[a\\Q]bc\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("]","^[a\\Q]bc\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("c","^[a\\Q]bc\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("]","^[a\\Q]bc\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("c","^[a\\Q]bc\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("c","^[a\\Q]bc\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("c","^[a\\Q]bc\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","^[a-\\Q\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("c","^[a\\Q]bc\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","^[a-\\Q\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","^[a-\\Q\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","^[a-\\Q\\E]",[]))),
- <<"">> = iolist_to_binary(join(re:split("-","^[a-\\Q\\E]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","^[a-\\Q\\E]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("-","^[a-\\Q\\E]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","^[a-\\Q\\E]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("-","^[a-\\Q\\E]",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaa","^(a()*)*",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("-","^[a-\\Q\\E]",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaa","^(a()*)*",[trim]))),
<<":a::">> = iolist_to_binary(join(re:split("aaaa","^(a()*)*",[{parts,
- 2}]))),
- <<":a::">> = iolist_to_binary(join(re:split("aaaa","^(a()*)*",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))*)*",[trim]))),
+ 2}]))),
+ <<":a::">> = iolist_to_binary(join(re:split("aaaa","^(a()*)*",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))*)*",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))*)*",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))*)*",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))*)*",[]))),
ok.
run36() ->
- <<":a">> = iolist_to_binary(join(re:split("aaaa","^(a()+)+",[trim]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaa","^(a()+)+",[trim]))),
<<":a::">> = iolist_to_binary(join(re:split("aaaa","^(a()+)+",[{parts,
- 2}]))),
- <<":a::">> = iolist_to_binary(join(re:split("aaaa","^(a()+)+",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))+)+",[trim]))),
+ 2}]))),
+ <<":a::">> = iolist_to_binary(join(re:split("aaaa","^(a()+)+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))+)+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))+)+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))+)+",[]))),
- <<":a">> = iolist_to_binary(join(re:split("abbD","(a){0,3}(?(1)b|(c|))*D",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^(?:a(?:(?:))+)+",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("abbD","(a){0,3}(?(1)b|(c|))*D",[trim]))),
<<":a::">> = iolist_to_binary(join(re:split("abbD","(a){0,3}(?(1)b|(c|))*D",[{parts,
- 2}]))),
- <<":a::">> = iolist_to_binary(join(re:split("abbD","(a){0,3}(?(1)b|(c|))*D",[]))),
- <<"">> = iolist_to_binary(join(re:split("ccccD","(a){0,3}(?(1)b|(c|))*D",[trim]))),
+ 2}]))),
+ <<":a::">> = iolist_to_binary(join(re:split("abbD","(a){0,3}(?(1)b|(c|))*D",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ccccD","(a){0,3}(?(1)b|(c|))*D",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("ccccD","(a){0,3}(?(1)b|(c|))*D",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("ccccD","(a){0,3}(?(1)b|(c|))*D",[]))),
- <<"">> = iolist_to_binary(join(re:split("D","(a){0,3}(?(1)b|(c|))*D",[trim]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("ccccD","(a){0,3}(?(1)b|(c|))*D",[]))),
+ <<"">> = iolist_to_binary(join(re:split("D","(a){0,3}(?(1)b|(c|))*D",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("D","(a){0,3}(?(1)b|(c|))*D",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("D","(a){0,3}(?(1)b|(c|))*D",[]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d",[trim]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("D","(a){0,3}(?(1)b|(c|))*D",[]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d",[trim]))),
<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d",[]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d",[]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d",[trim]))),
<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d",[]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d",[]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d",[trim]))),
<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d",[{parts,
- 2}]))),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d",[trim]))),
+ 2}]))),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","\\Z",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","\\Z",[trim]))),
<<"abc:">> = iolist_to_binary(join(re:split("abc","\\Z",[{parts,
- 2}]))),
- <<"abc:">> = iolist_to_binary(join(re:split("abc","\\Z",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[trim]))),
+ 2}]))),
+ <<"abc:">> = iolist_to_binary(join(re:split("abc","\\Z",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","^(?s)(?>.*)(?<!\\n)",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","^(?![^\\n]*\\n\\z)",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[trim]))),
<<"abc:">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[{parts,
- 2}]))),
- <<"abc:">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[trim]))),
+ 2}]))),
+ <<"abc:">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[trim]))),
<<"abc:">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[{parts,
- 2}]))),
- <<"abc:">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcd","(.*(.)?)*",[trim]))),
+ 2}]))),
+ <<"abc:">> = iolist_to_binary(join(re:split("abc","\\z(?<!\\n)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcd","(.*(.)?)*",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("abcd","(.*(.)?)*",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("abcd","(.*(.)?)*",[]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("abcd","(.*(.)?)*",[]))),
<<"a:::b:::c:::d">> = iolist_to_binary(join(re:split("abcd","( (A | (?(1)0|) )* )",[extended,
- trim]))),
+ trim]))),
<<"a:::bcd">> = iolist_to_binary(join(re:split("abcd","( (A | (?(1)0|) )* )",[extended,
{parts,
- 2}]))),
- <<"a:::b:::c:::d:::">> = iolist_to_binary(join(re:split("abcd","( (A | (?(1)0|) )* )",[extended]))),
+ 2}]))),
+ <<"a:::b:::c:::d:::">> = iolist_to_binary(join(re:split("abcd","( (A | (?(1)0|) )* )",[extended]))),
<<"a:::b:::c:::d">> = iolist_to_binary(join(re:split("abcd","( ( (?(1)0|) )* )",[extended,
- trim]))),
+ trim]))),
<<"a:::bcd">> = iolist_to_binary(join(re:split("abcd","( ( (?(1)0|) )* )",[extended,
{parts,
- 2}]))),
- <<"a:::b:::c:::d:::">> = iolist_to_binary(join(re:split("abcd","( ( (?(1)0|) )* )",[extended]))),
+ 2}]))),
+ <<"a:::b:::c:::d:::">> = iolist_to_binary(join(re:split("abcd","( ( (?(1)0|) )* )",[extended]))),
<<"a::b::c::d">> = iolist_to_binary(join(re:split("abcd","( (?(1)0|)* )",[extended,
- trim]))),
+ trim]))),
<<"a::bcd">> = iolist_to_binary(join(re:split("abcd","( (?(1)0|)* )",[extended,
{parts,
- 2}]))),
- <<"a::b::c::d::">> = iolist_to_binary(join(re:split("abcd","( (?(1)0|)* )",[extended]))),
- <<"">> = iolist_to_binary(join(re:split("a]","[[:abcd:xyz]]",[trim]))),
+ 2}]))),
+ <<"a::b::c::d::">> = iolist_to_binary(join(re:split("abcd","( (?(1)0|)* )",[extended]))),
+ <<"">> = iolist_to_binary(join(re:split("a]","[[:abcd:xyz]]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a]","[[:abcd:xyz]]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a]","[[:abcd:xyz]]",[]))),
- <<"">> = iolist_to_binary(join(re:split(":]","[[:abcd:xyz]]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a]","[[:abcd:xyz]]",[]))),
+ <<"">> = iolist_to_binary(join(re:split(":]","[[:abcd:xyz]]",[trim]))),
<<":">> = iolist_to_binary(join(re:split(":]","[[:abcd:xyz]]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(":]","[[:abcd:xyz]]",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","[abc[:x\\]pqr]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(":]","[[:abcd:xyz]]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","[abc[:x\\]pqr]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","[abc[:x\\]pqr]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("a","[abc[:x\\]pqr]",[]))),
- <<"">> = iolist_to_binary(join(re:split("[","[abc[:x\\]pqr]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("a","[abc[:x\\]pqr]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("[","[abc[:x\\]pqr]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("[","[abc[:x\\]pqr]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("[","[abc[:x\\]pqr]",[]))),
- <<"">> = iolist_to_binary(join(re:split(":","[abc[:x\\]pqr]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("[","[abc[:x\\]pqr]",[]))),
+ <<"">> = iolist_to_binary(join(re:split(":","[abc[:x\\]pqr]",[trim]))),
<<":">> = iolist_to_binary(join(re:split(":","[abc[:x\\]pqr]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(":","[abc[:x\\]pqr]",[]))),
- <<"">> = iolist_to_binary(join(re:split("]","[abc[:x\\]pqr]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(":","[abc[:x\\]pqr]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("]","[abc[:x\\]pqr]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("]","[abc[:x\\]pqr]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("]","[abc[:x\\]pqr]",[]))),
- <<"">> = iolist_to_binary(join(re:split("p","[abc[:x\\]pqr]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("]","[abc[:x\\]pqr]",[]))),
+ <<"">> = iolist_to_binary(join(re:split("p","[abc[:x\\]pqr]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("p","[abc[:x\\]pqr]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("p","[abc[:x\\]pqr]",[]))),
- <<"fooabcfoo">> = iolist_to_binary(join(re:split("fooabcfoo",".*[op][xyz]",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("p","[abc[:x\\]pqr]",[]))),
+ <<"fooabcfoo">> = iolist_to_binary(join(re:split("fooabcfoo",".*[op][xyz]",[trim]))),
<<"fooabcfoo">> = iolist_to_binary(join(re:split("fooabcfoo",".*[op][xyz]",[{parts,
- 2}]))),
- <<"fooabcfoo">> = iolist_to_binary(join(re:split("fooabcfoo",".*[op][xyz]",[]))),
- <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)",[trim]))),
+ 2}]))),
+ <<"fooabcfoo">> = iolist_to_binary(join(re:split("fooabcfoo",".*[op][xyz]",[]))),
+ <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)",[trim]))),
<<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)",[{parts,
- 2}]))),
- <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)",[]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)",[trim]))),
+ 2}]))),
+ <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)",[]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)",[trim]))),
<<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)",[{parts,
- 2}]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)",[]))),
- <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=^.*b)b|^)",[trim]))),
+ 2}]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)",[]))),
+ <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=^.*b)b|^)",[trim]))),
<<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=^.*b)b|^)",[{parts,
- 2}]))),
- <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=^.*b)b|^)",[]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(?(?=^.*b)b|^)",[trim]))),
+ 2}]))),
+ <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=^.*b)b|^)",[]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(?(?=^.*b)b|^)",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(?(?=^.*b)b|^)",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(?(?=^.*b)b|^)",[]))),
- <<"a:d:c">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)*",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(?(?=^.*b)b|^)",[]))),
+ <<"a:d:c">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)*",[trim]))),
<<"a:dc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)*",[{parts,
- 2}]))),
- <<"a:d:c:">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)*",[]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)*",[trim]))),
+ 2}]))),
+ <<"a:d:c:">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)*",[]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)*",[trim]))),
<<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)*",[{parts,
- 2}]))),
- <<"a:c:">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)*",[]))),
+ 2}]))),
+ <<"a:c:">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)*",[]))),
ok.
run37() ->
- <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)+",[trim]))),
+ <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)+",[trim]))),
<<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)+",[{parts,
- 2}]))),
- <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)+",[]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)+",[trim]))),
+ 2}]))),
+ <<"adc">> = iolist_to_binary(join(re:split("adc","(?(?=.*b)b|^)+",[]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)+",[trim]))),
<<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)+",[{parts,
- 2}]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)+",[]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=b).*b|^d)",[trim]))),
+ 2}]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b)b|^)+",[]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=b).*b|^d)",[trim]))),
<<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=b).*b|^d)",[{parts,
- 2}]))),
- <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=b).*b|^d)",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b).*b|^d)",[trim]))),
+ 2}]))),
+ <<"a:c">> = iolist_to_binary(join(re:split("abc","(?(?=b).*b|^d)",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b).*b|^d)",[trim]))),
<<":c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b).*b|^d)",[{parts,
- 2}]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b).*b|^d)",[]))),
- <<"">> = iolist_to_binary(join(re:split("%ab%","^%((?(?=[a])[^%])|b)*%$",[trim]))),
+ 2}]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","(?(?=.*b).*b|^d)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("%ab%","^%((?(?=[a])[^%])|b)*%$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("%ab%","^%((?(?=[a])[^%])|b)*%$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("%ab%","^%((?(?=[a])[^%])|b)*%$",[]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XabX","(?i)a(?-i)b|c",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("%ab%","^%((?(?=[a])[^%])|b)*%$",[]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XabX","(?i)a(?-i)b|c",[trim]))),
<<"X:X">> = iolist_to_binary(join(re:split("XabX","(?i)a(?-i)b|c",[{parts,
- 2}]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XabX","(?i)a(?-i)b|c",[]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XAbX","(?i)a(?-i)b|c",[trim]))),
+ 2}]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XabX","(?i)a(?-i)b|c",[]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XAbX","(?i)a(?-i)b|c",[trim]))),
<<"X:X">> = iolist_to_binary(join(re:split("XAbX","(?i)a(?-i)b|c",[{parts,
- 2}]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XAbX","(?i)a(?-i)b|c",[]))),
- <<"C:C">> = iolist_to_binary(join(re:split("CcC","(?i)a(?-i)b|c",[trim]))),
+ 2}]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XAbX","(?i)a(?-i)b|c",[]))),
+ <<"C:C">> = iolist_to_binary(join(re:split("CcC","(?i)a(?-i)b|c",[trim]))),
<<"C:C">> = iolist_to_binary(join(re:split("CcC","(?i)a(?-i)b|c",[{parts,
- 2}]))),
- <<"C:C">> = iolist_to_binary(join(re:split("CcC","(?i)a(?-i)b|c",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?i)a(?-i)b|c",[trim]))),
+ 2}]))),
+ <<"C:C">> = iolist_to_binary(join(re:split("CcC","(?i)a(?-i)b|c",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?i)a(?-i)b|c",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?i)a(?-i)b|c",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?i)a(?-i)b|c",[]))),
- <<"XABX">> = iolist_to_binary(join(re:split("XABX","(?i)a(?-i)b|c",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?i)a(?-i)b|c",[]))),
+ <<"XABX">> = iolist_to_binary(join(re:split("XABX","(?i)a(?-i)b|c",[trim]))),
<<"XABX">> = iolist_to_binary(join(re:split("XABX","(?i)a(?-i)b|c",[{parts,
- 2}]))),
- <<"XABX">> = iolist_to_binary(join(re:split("XABX","(?i)a(?-i)b|c",[]))),
+ 2}]))),
+ <<"XABX">> = iolist_to_binary(join(re:split("XABX","(?i)a(?-i)b|c",[]))),
<<"">> = iolist_to_binary(join(re:split("
- ","[\\x00-\\xff\\s]+",[trim]))),
+ ","[\\x00-\\xff\\s]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("
- ","[\\x00-\\xff\\s]+",[{parts,2}]))),
+ ","[\\x00-\\xff\\s]+",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("
- ","[\\x00-\\xff\\s]+",[]))),
+ ","[\\x00-\\xff\\s]+",[]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[caseless,
- trim]))),
+ trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[caseless,
{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[caseless]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[trim]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[caseless]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[{parts,
- 2}]))),
- <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[]))),
+ 2}]))),
+ <<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[]))),
<<":a">> = iolist_to_binary(join(re:split("12abc","[^a]*",[caseless,
- trim]))),
+ trim]))),
<<":abc">> = iolist_to_binary(join(re:split("12abc","[^a]*",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("12abc","[^a]*",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("12abc","[^a]*",[caseless]))),
<<":A">> = iolist_to_binary(join(re:split("12ABC","[^a]*",[caseless,
- trim]))),
+ trim]))),
<<":ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]*",[caseless,
{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("12ABC","[^a]*",[caseless]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("12ABC","[^a]*",[caseless]))),
<<":a">> = iolist_to_binary(join(re:split("12abc","[^a]*+",[caseless,
- trim]))),
+ trim]))),
<<":abc">> = iolist_to_binary(join(re:split("12abc","[^a]*+",[caseless,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("12abc","[^a]*+",[caseless]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("12abc","[^a]*+",[caseless]))),
<<":A">> = iolist_to_binary(join(re:split("12ABC","[^a]*+",[caseless,
- trim]))),
+ trim]))),
<<":ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]*+",[caseless,
{parts,
- 2}]))),
- <<":A:">> = iolist_to_binary(join(re:split("12ABC","[^a]*+",[caseless]))),
+ 2}]))),
+ <<":A:">> = iolist_to_binary(join(re:split("12ABC","[^a]*+",[caseless]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]*?X",[caseless,
- trim]))),
+ trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]*?X",[caseless,
{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]*?X",[caseless]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]*?X",[caseless]))),
<<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]*?X",[caseless,
- trim]))),
+ trim]))),
<<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]*?X",[caseless,
{parts,
- 2}]))),
- <<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]*?X",[caseless]))),
+ 2}]))),
+ <<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]*?X",[caseless]))),
<<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]*?X",[caseless,
- trim]))),
+ trim]))),
<<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]*?X",[caseless,
{parts,
- 2}]))),
- <<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]*?X",[caseless]))),
+ 2}]))),
+ <<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]*?X",[caseless]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]+?X",[caseless,
- trim]))),
+ trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]+?X",[caseless,
{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]+?X",[caseless]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","[^a]+?X",[caseless]))),
<<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]+?X",[caseless,
- trim]))),
+ trim]))),
<<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]+?X",[caseless,
{parts,
- 2}]))),
- <<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]+?X",[caseless]))),
+ 2}]))),
+ <<"12abc">> = iolist_to_binary(join(re:split("12abc","[^a]+?X",[caseless]))),
<<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]+?X",[caseless,
- trim]))),
+ trim]))),
<<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]+?X",[caseless,
{parts,
- 2}]))),
- <<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]+?X",[caseless]))),
+ 2}]))),
+ <<"12ABC">> = iolist_to_binary(join(re:split("12ABC","[^a]+?X",[caseless]))),
<<"12a:b">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?X",[caseless,
- trim]))),
+ trim]))),
<<"12a:bcX">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?X",[caseless,
{parts,
- 2}]))),
- <<"12a:b:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?X",[caseless]))),
+ 2}]))),
+ <<"12a:b:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?X",[caseless]))),
<<"12A:B">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?X",[caseless,
- trim]))),
+ trim]))),
<<"12A:BCX">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?X",[caseless,
{parts,
- 2}]))),
- <<"12A:B:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?X",[caseless]))),
+ 2}]))),
+ <<"12A:B:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?X",[caseless]))),
<<"B">> = iolist_to_binary(join(re:split("BCX","[^a]?X",[caseless,
- trim]))),
+ trim]))),
<<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]?X",[caseless,
{parts,
- 2}]))),
- <<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]?X",[caseless]))),
+ 2}]))),
+ <<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]?X",[caseless]))),
<<"12a:b">> = iolist_to_binary(join(re:split("12aXbcX","[^a]??X",[caseless,
- trim]))),
+ trim]))),
<<"12a:bcX">> = iolist_to_binary(join(re:split("12aXbcX","[^a]??X",[caseless,
{parts,
- 2}]))),
- <<"12a:b:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]??X",[caseless]))),
+ 2}]))),
+ <<"12a:b:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]??X",[caseless]))),
<<"12A:B">> = iolist_to_binary(join(re:split("12AXBCX","[^a]??X",[caseless,
- trim]))),
+ trim]))),
<<"12A:BCX">> = iolist_to_binary(join(re:split("12AXBCX","[^a]??X",[caseless,
{parts,
- 2}]))),
- <<"12A:B:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]??X",[caseless]))),
+ 2}]))),
+ <<"12A:B:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]??X",[caseless]))),
<<"B">> = iolist_to_binary(join(re:split("BCX","[^a]??X",[caseless,
- trim]))),
+ trim]))),
<<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]??X",[caseless,
{parts,
- 2}]))),
- <<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]??X",[caseless]))),
+ 2}]))),
+ <<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]??X",[caseless]))),
<<"12aXb">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?+X",[caseless,
- trim]))),
+ trim]))),
<<"12aXb:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?+X",[caseless,
{parts,
- 2}]))),
- <<"12aXb:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?+X",[caseless]))),
+ 2}]))),
+ <<"12aXb:">> = iolist_to_binary(join(re:split("12aXbcX","[^a]?+X",[caseless]))),
<<"12AXB">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?+X",[caseless,
- trim]))),
+ trim]))),
<<"12AXB:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?+X",[caseless,
{parts,
- 2}]))),
- <<"12AXB:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?+X",[caseless]))),
+ 2}]))),
+ <<"12AXB:">> = iolist_to_binary(join(re:split("12AXBCX","[^a]?+X",[caseless]))),
<<"B">> = iolist_to_binary(join(re:split("BCX","[^a]?+X",[caseless,
- trim]))),
+ trim]))),
<<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]?+X",[caseless,
{parts,
- 2}]))),
- <<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]?+X",[caseless]))),
+ 2}]))),
+ <<"B:">> = iolist_to_binary(join(re:split("BCX","[^a]?+X",[caseless]))),
<<"a">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}",[caseless,
- trim]))),
+ trim]))),
<<"a:ef">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}",[caseless,
{parts,
- 2}]))),
- <<"a::">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}",[caseless]))),
+ 2}]))),
+ <<"a::">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}",[caseless]))),
<<"A">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}",[caseless,
- trim]))),
+ trim]))),
<<"A:EF">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}",[caseless,
{parts,
- 2}]))),
- <<"A::">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}",[caseless]))),
+ 2}]))),
+ <<"A::">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}",[caseless]))),
<<"a::f">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}?",[caseless,
- trim]))),
+ trim]))),
<<"a:def">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}?",[caseless,
{parts,
- 2}]))),
- <<"a::f">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}?",[caseless]))),
+ 2}]))),
+ <<"a::f">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}?",[caseless]))),
<<"A::F">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}?",[caseless,
- trim]))),
+ trim]))),
<<"A:DEF">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}?",[caseless,
{parts,
- 2}]))),
- <<"A::F">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}?",[caseless]))),
+ 2}]))),
+ <<"A::F">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}?",[caseless]))),
<<"a">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}+",[caseless,
- trim]))),
+ trim]))),
<<"a:ef">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}+",[caseless,
{parts,
- 2}]))),
- <<"a::">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}+",[caseless]))),
+ 2}]))),
+ <<"a::">> = iolist_to_binary(join(re:split("abcdef","[^a]{2,3}+",[caseless]))),
<<"A">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}+",[caseless,
- trim]))),
+ trim]))),
<<"A:EF">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}+",[caseless,
{parts,
- 2}]))),
- <<"A::">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}+",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("Z","((a|)+)+Z",[trim]))),
+ 2}]))),
+ <<"A::">> = iolist_to_binary(join(re:split("ABCDEF","[^a]{2,3}+",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("Z","((a|)+)+Z",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("Z","((a|)+)+Z",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("Z","((a|)+)+Z",[]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("Z","((a|)+)+Z",[]))),
ok.
run38() ->
- <<"::a">> = iolist_to_binary(join(re:split("ac","(a)b|(a)c",[trim]))),
+ <<"::a">> = iolist_to_binary(join(re:split("ac","(a)b|(a)c",[trim]))),
<<"::a:">> = iolist_to_binary(join(re:split("ac","(a)b|(a)c",[{parts,
- 2}]))),
- <<"::a:">> = iolist_to_binary(join(re:split("ac","(a)b|(a)c",[]))),
- <<"::a">> = iolist_to_binary(join(re:split("ac","(?>(a))b|(a)c",[trim]))),
+ 2}]))),
+ <<"::a:">> = iolist_to_binary(join(re:split("ac","(a)b|(a)c",[]))),
+ <<"::a">> = iolist_to_binary(join(re:split("ac","(?>(a))b|(a)c",[trim]))),
<<"::a:">> = iolist_to_binary(join(re:split("ac","(?>(a))b|(a)c",[{parts,
- 2}]))),
- <<"::a:">> = iolist_to_binary(join(re:split("ac","(?>(a))b|(a)c",[]))),
- <<"::a">> = iolist_to_binary(join(re:split("ac","(?=(a))ab|(a)c",[trim]))),
+ 2}]))),
+ <<"::a:">> = iolist_to_binary(join(re:split("ac","(?>(a))b|(a)c",[]))),
+ <<"::a">> = iolist_to_binary(join(re:split("ac","(?=(a))ab|(a)c",[trim]))),
<<"::a:">> = iolist_to_binary(join(re:split("ac","(?=(a))ab|(a)c",[{parts,
- 2}]))),
- <<"::a:">> = iolist_to_binary(join(re:split("ac","(?=(a))ab|(a)c",[]))),
- <<":ac::a">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)",[trim]))),
+ 2}]))),
+ <<"::a:">> = iolist_to_binary(join(re:split("ac","(?=(a))ab|(a)c",[]))),
+ <<":ac::a">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)",[trim]))),
<<":ac::a:">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)",[{parts,
- 2}]))),
- <<":ac::a:">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)",[]))),
- <<":ac::a">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)++",[trim]))),
+ 2}]))),
+ <<":ac::a:">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)",[]))),
+ <<":ac::a">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)++",[trim]))),
<<":ac::a:">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)++",[{parts,
- 2}]))),
- <<":ac::a:">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)++",[]))),
- <<"::a">> = iolist_to_binary(join(re:split("ac","(?:(?>(a))b|(a)c)++",[trim]))),
+ 2}]))),
+ <<":ac::a:">> = iolist_to_binary(join(re:split("ac","((?>(a))b|(a)c)++",[]))),
+ <<"::a">> = iolist_to_binary(join(re:split("ac","(?:(?>(a))b|(a)c)++",[trim]))),
<<"::a:">> = iolist_to_binary(join(re:split("ac","(?:(?>(a))b|(a)c)++",[{parts,
- 2}]))),
- <<"::a:">> = iolist_to_binary(join(re:split("ac","(?:(?>(a))b|(a)c)++",[]))),
- <<"::a:ac">> = iolist_to_binary(join(re:split("ac","(?=(?>(a))b|(a)c)(..)",[trim]))),
+ 2}]))),
+ <<"::a:">> = iolist_to_binary(join(re:split("ac","(?:(?>(a))b|(a)c)++",[]))),
+ <<"::a:ac">> = iolist_to_binary(join(re:split("ac","(?=(?>(a))b|(a)c)(..)",[trim]))),
<<"::a:ac:">> = iolist_to_binary(join(re:split("ac","(?=(?>(a))b|(a)c)(..)",[{parts,
- 2}]))),
- <<"::a:ac:">> = iolist_to_binary(join(re:split("ac","(?=(?>(a))b|(a)c)(..)",[]))),
- <<"::a">> = iolist_to_binary(join(re:split("ac","(?>(?>(a))b|(a)c)",[trim]))),
+ 2}]))),
+ <<"::a:ac:">> = iolist_to_binary(join(re:split("ac","(?=(?>(a))b|(a)c)(..)",[]))),
+ <<"::a">> = iolist_to_binary(join(re:split("ac","(?>(?>(a))b|(a)c)",[trim]))),
<<"::a:">> = iolist_to_binary(join(re:split("ac","(?>(?>(a))b|(a)c)",[{parts,
- 2}]))),
- <<"::a:">> = iolist_to_binary(join(re:split("ac","(?>(?>(a))b|(a)c)",[]))),
- <<":aaaabaaabaabab:aaa:aabab">> = iolist_to_binary(join(re:split("aaaabaaabaabab","((?>(a+)b)+(aabab))",[trim]))),
+ 2}]))),
+ <<"::a:">> = iolist_to_binary(join(re:split("ac","(?>(?>(a))b|(a)c)",[]))),
+ <<":aaaabaaabaabab:aaa:aabab">> = iolist_to_binary(join(re:split("aaaabaaabaabab","((?>(a+)b)+(aabab))",[trim]))),
<<":aaaabaaabaabab:aaa:aabab:">> = iolist_to_binary(join(re:split("aaaabaaabaabab","((?>(a+)b)+(aabab))",[{parts,
- 2}]))),
- <<":aaaabaaabaabab:aaa:aabab:">> = iolist_to_binary(join(re:split("aaaabaaabaabab","((?>(a+)b)+(aabab))",[]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+?c",[trim]))),
+ 2}]))),
+ <<":aaaabaaabaabab:aaa:aabab:">> = iolist_to_binary(join(re:split("aaaabaaabaabab","((?>(a+)b)+(aabab))",[]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+?c",[trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+?c",[{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+?c",[]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+c",[trim]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+?c",[]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+c",[trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+c",[{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aabc","(?:a+|ab)+c",[trim]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","(?>a+|ab)+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aabc","(?:a+|ab)+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","(?:a+|ab)+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","(?:a+|ab)+c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("a","(?(?=(a))a)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","(?:a+|ab)+c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("a","(?(?=(a))a)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("a","(?(?=(a))a)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("a","(?(?=(a))a)",[]))),
- <<":a:b">> = iolist_to_binary(join(re:split("ab","(?(?=(a))a)(b)",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("a","(?(?=(a))a)",[]))),
+ <<":a:b">> = iolist_to_binary(join(re:split("ab","(?(?=(a))a)(b)",[trim]))),
<<":a:b:">> = iolist_to_binary(join(re:split("ab","(?(?=(a))a)(b)",[{parts,
- 2}]))),
- <<":a:b:">> = iolist_to_binary(join(re:split("ab","(?(?=(a))a)(b)",[]))),
- <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)++c",[trim]))),
+ 2}]))),
+ <<":a:b:">> = iolist_to_binary(join(re:split("ab","(?(?=(a))a)(b)",[]))),
+ <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)++c",[trim]))),
<<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)++c",[{parts,
- 2}]))),
- <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)++c",[]))),
- <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?>a|ab)++c",[trim]))),
+ 2}]))),
+ <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)++c",[]))),
+ <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?>a|ab)++c",[trim]))),
<<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?>a|ab)++c",[{parts,
- 2}]))),
- <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?>a|ab)++c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)+c",[trim]))),
+ 2}]))),
+ <<"aaaabc">> = iolist_to_binary(join(re:split("aaaabc","^(?>a|ab)++c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("xyz","(?=abc){0}xyz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaabc","^(?:a|ab)+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("xyz","(?=abc){0}xyz",[trim]))),
<<":">> = iolist_to_binary(join(re:split("xyz","(?=abc){0}xyz",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("xyz","(?=abc){0}xyz",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?=abc){1}xyz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("xyz","(?=abc){0}xyz",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?=abc){1}xyz",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?=abc){1}xyz",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?=abc){1}xyz",[]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","(?=abc){1}xyz",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?=abc){1}xyz",[]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","(?=abc){1}xyz",[trim]))),
<<"xyz">> = iolist_to_binary(join(re:split("xyz","(?=abc){1}xyz",[{parts,
- 2}]))),
- <<"xyz">> = iolist_to_binary(join(re:split("xyz","(?=abc){1}xyz",[]))),
- <<":a">> = iolist_to_binary(join(re:split("ab","(?=(a))?.",[trim]))),
+ 2}]))),
+ <<"xyz">> = iolist_to_binary(join(re:split("xyz","(?=abc){1}xyz",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("ab","(?=(a))?.",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("ab","(?=(a))?.",[{parts,
- 2}]))),
- <<":a:::">> = iolist_to_binary(join(re:split("ab","(?=(a))?.",[]))),
- <<"">> = iolist_to_binary(join(re:split("bc","(?=(a))?.",[trim]))),
+ 2}]))),
+ <<":a:::">> = iolist_to_binary(join(re:split("ab","(?=(a))?.",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bc","(?=(a))?.",[trim]))),
<<"::c">> = iolist_to_binary(join(re:split("bc","(?=(a))?.",[{parts,
- 2}]))),
- <<"::::">> = iolist_to_binary(join(re:split("bc","(?=(a))?.",[]))),
+ 2}]))),
+ <<"::::">> = iolist_to_binary(join(re:split("bc","(?=(a))?.",[]))),
ok.
run39() ->
- <<"">> = iolist_to_binary(join(re:split("ab","(?=(a))??.",[trim]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","(?=(a))??.",[trim]))),
<<"::b">> = iolist_to_binary(join(re:split("ab","(?=(a))??.",[{parts,
- 2}]))),
- <<"::::">> = iolist_to_binary(join(re:split("ab","(?=(a))??.",[]))),
- <<"">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[trim]))),
+ 2}]))),
+ <<"::::">> = iolist_to_binary(join(re:split("ab","(?=(a))??.",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[trim]))),
<<"::c">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[{parts,
- 2}]))),
- <<"::::">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[]))),
- <<":b">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[trim]))),
+ 2}]))),
+ <<"::::">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[]))),
+ <<":b">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[{parts,
- 2}]))),
- <<":b:">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[]))),
- <<":c:xx">> = iolist_to_binary(join(re:split("zcdxx","^(?=(?1))?[az]([abc])d",[trim]))),
+ 2}]))),
+ <<":b:">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[]))),
+ <<":c:xx">> = iolist_to_binary(join(re:split("zcdxx","^(?=(?1))?[az]([abc])d",[trim]))),
<<":c:xx">> = iolist_to_binary(join(re:split("zcdxx","^(?=(?1))?[az]([abc])d",[{parts,
- 2}]))),
- <<":c:xx">> = iolist_to_binary(join(re:split("zcdxx","^(?=(?1))?[az]([abc])d",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaa","^(?!a){0}\\w+",[trim]))),
+ 2}]))),
+ <<":c:xx">> = iolist_to_binary(join(re:split("zcdxx","^(?=(?1))?[az]([abc])d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaa","^(?!a){0}\\w+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaa","^(?!a){0}\\w+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaa","^(?!a){0}\\w+",[]))),
- <<"abc:abc">> = iolist_to_binary(join(re:split("abcxyz","(?<=(abc))?xyz",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaa","^(?!a){0}\\w+",[]))),
+ <<"abc:abc">> = iolist_to_binary(join(re:split("abcxyz","(?<=(abc))?xyz",[trim]))),
<<"abc:abc:">> = iolist_to_binary(join(re:split("abcxyz","(?<=(abc))?xyz",[{parts,
- 2}]))),
- <<"abc:abc:">> = iolist_to_binary(join(re:split("abcxyz","(?<=(abc))?xyz",[]))),
- <<"pqr">> = iolist_to_binary(join(re:split("pqrxyz","(?<=(abc))?xyz",[trim]))),
+ 2}]))),
+ <<"abc:abc:">> = iolist_to_binary(join(re:split("abcxyz","(?<=(abc))?xyz",[]))),
+ <<"pqr">> = iolist_to_binary(join(re:split("pqrxyz","(?<=(abc))?xyz",[trim]))),
<<"pqr::">> = iolist_to_binary(join(re:split("pqrxyz","(?<=(abc))?xyz",[{parts,
- 2}]))),
- <<"pqr::">> = iolist_to_binary(join(re:split("pqrxyz","(?<=(abc))?xyz",[]))),
- <<"">> = iolist_to_binary(join(re:split("ggg<<<aaa>>>","^[\\g<a>]+",[trim]))),
+ 2}]))),
+ <<"pqr::">> = iolist_to_binary(join(re:split("pqrxyz","(?<=(abc))?xyz",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ggg<<<aaa>>>","^[\\g<a>]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ggg<<<aaa>>>","^[\\g<a>]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ggg<<<aaa>>>","^[\\g<a>]+",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\g<a>]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ggg<<<aaa>>>","^[\\g<a>]+",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\g<a>]+",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\g<a>]+",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\g<a>]+",[]))),
- <<"\\ga">> = iolist_to_binary(join(re:split("\\ga","^[\\g<a>]+",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^[\\g<a>]+",[]))),
+ <<"\\ga">> = iolist_to_binary(join(re:split("\\ga","^[\\g<a>]+",[trim]))),
<<"\\ga">> = iolist_to_binary(join(re:split("\\ga","^[\\g<a>]+",[{parts,
- 2}]))),
- <<"\\ga">> = iolist_to_binary(join(re:split("\\ga","^[\\g<a>]+",[]))),
- <<":xyz">> = iolist_to_binary(join(re:split("gggagagaxyz","^[\\ga]+",[trim]))),
+ 2}]))),
+ <<"\\ga">> = iolist_to_binary(join(re:split("\\ga","^[\\g<a>]+",[]))),
+ <<":xyz">> = iolist_to_binary(join(re:split("gggagagaxyz","^[\\ga]+",[trim]))),
<<":xyz">> = iolist_to_binary(join(re:split("gggagagaxyz","^[\\ga]+",[{parts,
- 2}]))),
- <<":xyz">> = iolist_to_binary(join(re:split("gggagagaxyz","^[\\ga]+",[]))),
- <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::Z","^[:a[:digit:]]+",[trim]))),
+ 2}]))),
+ <<":xyz">> = iolist_to_binary(join(re:split("gggagagaxyz","^[\\ga]+",[]))),
+ <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::Z","^[:a[:digit:]]+",[trim]))),
<<":Z">> = iolist_to_binary(join(re:split("aaaa444:::Z","^[:a[:digit:]]+",[{parts,
- 2}]))),
- <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::Z","^[:a[:digit:]]+",[]))),
- <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::bbbZ","^[:a[:digit:]:b]+",[trim]))),
+ 2}]))),
+ <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::Z","^[:a[:digit:]]+",[]))),
+ <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::bbbZ","^[:a[:digit:]:b]+",[trim]))),
<<":Z">> = iolist_to_binary(join(re:split("aaaa444:::bbbZ","^[:a[:digit:]:b]+",[{parts,
- 2}]))),
- <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::bbbZ","^[:a[:digit:]:b]+",[]))),
- <<"">> = iolist_to_binary(join(re:split(":xxx:","[:a]xxx[b:]",[trim]))),
+ 2}]))),
+ <<":Z">> = iolist_to_binary(join(re:split("aaaa444:::bbbZ","^[:a[:digit:]:b]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split(":xxx:","[:a]xxx[b:]",[trim]))),
<<":">> = iolist_to_binary(join(re:split(":xxx:","[:a]xxx[b:]",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(":xxx:","[:a]xxx[b:]",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(":xxx:","[:a]xxx[b:]",[]))),
<<"xaa:c">> = iolist_to_binary(join(re:split("xaabc","(?<=a{2})b",[caseless,
- trim]))),
+ trim]))),
<<"xaa:c">> = iolist_to_binary(join(re:split("xaabc","(?<=a{2})b",[caseless,
{parts,
- 2}]))),
- <<"xaa:c">> = iolist_to_binary(join(re:split("xaabc","(?<=a{2})b",[caseless]))),
+ 2}]))),
+ <<"xaa:c">> = iolist_to_binary(join(re:split("xaabc","(?<=a{2})b",[caseless]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=a{2})b",[caseless,
- trim]))),
+ trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=a{2})b",[caseless,
{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=a{2})b",[caseless]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=a{2})b",[caseless]))),
<<"xabc">> = iolist_to_binary(join(re:split("xabc","(?<=a{2})b",[caseless,
- trim]))),
+ trim]))),
<<"xabc">> = iolist_to_binary(join(re:split("xabc","(?<=a{2})b",[caseless,
{parts,
- 2}]))),
- <<"xabc">> = iolist_to_binary(join(re:split("xabc","(?<=a{2})b",[caseless]))),
+ 2}]))),
+ <<"xabc">> = iolist_to_binary(join(re:split("xabc","(?<=a{2})b",[caseless]))),
<<"xa:c">> = iolist_to_binary(join(re:split("xabc","(?<!a{2})b",[caseless,
- trim]))),
+ trim]))),
<<"xa:c">> = iolist_to_binary(join(re:split("xabc","(?<!a{2})b",[caseless,
{parts,
- 2}]))),
- <<"xa:c">> = iolist_to_binary(join(re:split("xabc","(?<!a{2})b",[caseless]))),
+ 2}]))),
+ <<"xa:c">> = iolist_to_binary(join(re:split("xabc","(?<!a{2})b",[caseless]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<!a{2})b",[caseless,
- trim]))),
+ trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<!a{2})b",[caseless,
{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<!a{2})b",[caseless]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<!a{2})b",[caseless]))),
<<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<!a{2})b",[caseless,
- trim]))),
+ trim]))),
<<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<!a{2})b",[caseless,
{parts,
- 2}]))),
- <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<!a{2})b",[caseless]))),
- <<"xa ">> = iolist_to_binary(join(re:split("xa c","(?<=a\\h)c",[trim]))),
+ 2}]))),
+ <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<!a{2})b",[caseless]))),
+ <<"xa ">> = iolist_to_binary(join(re:split("xa c","(?<=a\\h)c",[trim]))),
<<"xa :">> = iolist_to_binary(join(re:split("xa c","(?<=a\\h)c",[{parts,
- 2}]))),
- <<"xa :">> = iolist_to_binary(join(re:split("xa c","(?<=a\\h)c",[]))),
- <<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[trim]))),
+ 2}]))),
+ <<"xa :">> = iolist_to_binary(join(re:split("xa c","(?<=a\\h)c",[]))),
+ <<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[trim]))),
<<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[{parts,
- 2}]))),
- <<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[]))),
- <<"aAA:c">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[trim]))),
+ 2}]))),
+ <<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[]))),
+ <<"aAA:c">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[trim]))),
<<"aAA:c">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[{parts,
- 2}]))),
- <<"aAA:c">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[trim]))),
+ 2}]))),
+ <<"aAA:c">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[]))),
- <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[]))),
+ <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[trim]))),
<<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[{parts,
- 2}]))),
- <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[]))),
+ 2}]))),
+ <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[]))),
<<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[caseless,
- trim]))),
+ trim]))),
<<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[caseless,
{parts,
- 2}]))),
- <<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[caseless]))),
+ 2}]))),
+ <<"axx:c">> = iolist_to_binary(join(re:split("axxbc","(?<=[^a]{2})b",[caseless]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[caseless,
- trim]))),
+ trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[caseless,
{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[caseless]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=[^a]{2})b",[caseless]))),
<<"aAAbc">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[caseless,
- trim]))),
+ trim]))),
<<"aAAbc">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[caseless,
{parts,
- 2}]))),
- <<"aAAbc">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[caseless]))),
+ 2}]))),
+ <<"aAAbc">> = iolist_to_binary(join(re:split("aAAbc","(?<=[^a]{2})b",[caseless]))),
<<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[caseless,
- trim]))),
+ trim]))),
<<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[caseless,
{parts,
- 2}]))),
- <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[caseless]))),
- <<"ab">> = iolist_to_binary(join(re:split("abc","(?<=a\\H)c",[trim]))),
+ 2}]))),
+ <<"xaabc">> = iolist_to_binary(join(re:split("xaabc","(?<=[^a]{2})b",[caseless]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abc","(?<=a\\H)c",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abc","(?<=a\\H)c",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abc","(?<=a\\H)c",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("abc","(?<=a\\V)c",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abc","(?<=a\\H)c",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abc","(?<=a\\V)c",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abc","(?<=a\\V)c",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abc","(?<=a\\V)c",[]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abc","(?<=a\\V)c",[]))),
<<"a
">> = iolist_to_binary(join(re:split("a
-c","(?<=a\\v)c",[trim]))),
+c","(?<=a\\v)c",[trim]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-c","(?<=a\\v)c",[{parts,2}]))),
+c","(?<=a\\v)c",[{parts,2}]))),
<<"a
:">> = iolist_to_binary(join(re:split("a
-c","(?<=a\\v)c",[]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)++Y",[trim]))),
+c","(?<=a\\v)c",[]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)++Y",[trim]))),
<<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)++Y",[{parts,
- 2}]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)++Y",[]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[trim]))),
+ 2}]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)++Y",[]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[trim]))),
<<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[{parts,
- 2}]))),
- <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[]))),
- <<":aaa">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[trim]))),
+ 2}]))),
+ <<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[]))),
+ <<":aaa">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[trim]))),
<<":aaa:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[{parts,
- 2}]))),
- <<":aaa:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3}){2,}+a",[trim]))),
+ 2}]))),
+ <<":aaa:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3}){2,}+a",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3}){2,}+a",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3}){2,}+a",[]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3}){2,}+a",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3}){2,}+a",[]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3}){2,}+a",[trim]))),
<<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3}){2,}+a",[{parts,
- 2}]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3}){2,}+a",[]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[trim]))),
+ 2}]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3}){2,}+a",[]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[trim]))),
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[{parts,
- 2}]))),
- <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[]))),
+ 2}]))),
+ <<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[]))),
ok.
run40() ->
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[trim]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})++a",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})++a",[trim]))),
<<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})++a",[{parts,
- 2}]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})++a",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})*+a",[trim]))),
+ 2}]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})++a",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})*+a",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})*+a",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})*+a",[]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})*+a",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})*+a",[]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})*+a",[trim]))),
<<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})*+a",[{parts,
- 2}]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})*+a",[]))),
- <<"">> = iolist_to_binary(join(re:split("abXde","ab\\Cde",[trim]))),
+ 2}]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(a{2,3})*+a",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abXde","ab\\Cde",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abXde","ab\\Cde",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abXde","ab\\Cde",[]))),
- <<"abZde">> = iolist_to_binary(join(re:split("abZdeX","(?<=ab\\Cde)X",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abXde","ab\\Cde",[]))),
+ <<"abZde">> = iolist_to_binary(join(re:split("abZdeX","(?<=ab\\Cde)X",[trim]))),
<<"abZde:">> = iolist_to_binary(join(re:split("abZdeX","(?<=ab\\Cde)X",[{parts,
- 2}]))),
- <<"abZde:">> = iolist_to_binary(join(re:split("abZdeX","(?<=ab\\Cde)X",[]))),
- <<"">> = iolist_to_binary(join(re:split("aCb","a[\\CD]b",[trim]))),
+ 2}]))),
+ <<"abZde:">> = iolist_to_binary(join(re:split("abZdeX","(?<=ab\\Cde)X",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aCb","a[\\CD]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aCb","a[\\CD]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aCb","a[\\CD]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("aDb","a[\\CD]b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aCb","a[\\CD]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aDb","a[\\CD]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aDb","a[\\CD]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aDb","a[\\CD]b",[]))),
- <<"">> = iolist_to_binary(join(re:split("aJb","a[\\C-X]b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aDb","a[\\CD]b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aJb","a[\\C-X]b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aJb","a[\\C-X]b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aJb","a[\\C-X]b",[]))),
- <<"X X">> = iolist_to_binary(join(re:split("X X","\\H\\h\\V\\v",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aJb","a[\\C-X]b",[]))),
+ <<"X X">> = iolist_to_binary(join(re:split("X X","\\H\\h\\V\\v",[trim]))),
<<"X X">> = iolist_to_binary(join(re:split("X X","\\H\\h\\V\\v",[{parts,
- 2}]))),
- <<"X X">> = iolist_to_binary(join(re:split("X X","\\H\\h\\V\\v",[]))),
- <<"">> = iolist_to_binary(join(re:split("X X ","\\H\\h\\V\\v",[trim]))),
+ 2}]))),
+ <<"X X">> = iolist_to_binary(join(re:split("X X","\\H\\h\\V\\v",[]))),
+ <<"">> = iolist_to_binary(join(re:split("X X ","\\H\\h\\V\\v",[trim]))),
<<":">> = iolist_to_binary(join(re:split("X X ","\\H\\h\\V\\v",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("X X ","\\H\\h\\V\\v",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H\\h\\V\\v",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("X X ","\\H\\h\\V\\v",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H\\h\\V\\v",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H\\h\\V\\v",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H\\h\\V\\v",[]))),
- <<"  X">> = iolist_to_binary(join(re:split("  X","\\H\\h\\V\\v",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H\\h\\V\\v",[]))),
+ <<"  X">> = iolist_to_binary(join(re:split("  X","\\H\\h\\V\\v",[trim]))),
<<"  X">> = iolist_to_binary(join(re:split("  X","\\H\\h\\V\\v",[{parts,
- 2}]))),
- <<"  X">> = iolist_to_binary(join(re:split("  X","\\H\\h\\V\\v",[]))),
+ 2}]))),
+ <<"  X">> = iolist_to_binary(join(re:split("  X","\\H\\h\\V\\v",[]))),
<<"">> = iolist_to_binary(join(re:split("  X
- ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("  X
- ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("  X
- ","\\H*\\h+\\V?\\v{3,4}",[]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[]))),
<<"">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[]))),
<<"">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H*\\h+\\V?\\v{3,4}",[trim]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H*\\h+\\V?\\v{3,4}",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H*\\h+\\V?\\v{3,4}",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H*\\h+\\V?\\v{3,4}",[]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\H*\\h+\\V?\\v{3,4}",[]))),
<<"  
">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[trim]))),
<<"  
">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[{parts,2}]))),
<<"  
">> = iolist_to_binary(join(re:split("  
- ","\\H*\\h+\\V?\\v{3,4}",[]))),
- <<"XY :E">> = iolist_to_binary(join(re:split("XY ABCDE","\\H{3,4}",[trim]))),
+ ","\\H*\\h+\\V?\\v{3,4}",[]))),
+ <<"XY :E">> = iolist_to_binary(join(re:split("XY ABCDE","\\H{3,4}",[trim]))),
<<"XY :E">> = iolist_to_binary(join(re:split("XY ABCDE","\\H{3,4}",[{parts,
- 2}]))),
- <<"XY :E">> = iolist_to_binary(join(re:split("XY ABCDE","\\H{3,4}",[]))),
- <<"XY : ST">> = iolist_to_binary(join(re:split("XY PQR ST","\\H{3,4}",[trim]))),
+ 2}]))),
+ <<"XY :E">> = iolist_to_binary(join(re:split("XY ABCDE","\\H{3,4}",[]))),
+ <<"XY : ST">> = iolist_to_binary(join(re:split("XY PQR ST","\\H{3,4}",[trim]))),
<<"XY : ST">> = iolist_to_binary(join(re:split("XY PQR ST","\\H{3,4}",[{parts,
- 2}]))),
- <<"XY : ST">> = iolist_to_binary(join(re:split("XY PQR ST","\\H{3,4}",[]))),
- <<"XY A:QRS">> = iolist_to_binary(join(re:split("XY AB PQRS",".\\h{3,4}.",[trim]))),
+ 2}]))),
+ <<"XY : ST">> = iolist_to_binary(join(re:split("XY PQR ST","\\H{3,4}",[]))),
+ <<"XY A:QRS">> = iolist_to_binary(join(re:split("XY AB PQRS",".\\h{3,4}.",[trim]))),
<<"XY A:QRS">> = iolist_to_binary(join(re:split("XY AB PQRS",".\\h{3,4}.",[{parts,
- 2}]))),
- <<"XY A:QRS">> = iolist_to_binary(join(re:split("XY AB PQRS",".\\h{3,4}.",[]))),
- <<">">> = iolist_to_binary(join(re:split(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
+ 2}]))),
+ <<"XY A:QRS">> = iolist_to_binary(join(re:split("XY AB PQRS",".\\h{3,4}.",[]))),
+ <<">">> = iolist_to_binary(join(re:split(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
<<">:">> = iolist_to_binary(join(re:split(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z",[{parts,
- 2}]))),
- <<">:">> = iolist_to_binary(join(re:split(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z",[]))),
- <<">">> = iolist_to_binary(join(re:split("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
+ 2}]))),
+ <<">:">> = iolist_to_binary(join(re:split(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z",[]))),
+ <<">">> = iolist_to_binary(join(re:split("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
<<">:">> = iolist_to_binary(join(re:split("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z",[{parts,
- 2}]))),
- <<">:">> = iolist_to_binary(join(re:split("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
+ 2}]))),
+ <<">:">> = iolist_to_binary(join(re:split("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\h*X\\h?\\H+Y\\H?Z",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\h*X\\h?\\H+Y\\H?Z",[]))),
- <<">XYZ">> = iolist_to_binary(join(re:split(">XYZ","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\h*X\\h?\\H+Y\\H?Z",[]))),
+ <<">XYZ">> = iolist_to_binary(join(re:split(">XYZ","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
<<">XYZ">> = iolist_to_binary(join(re:split(">XYZ","\\h*X\\h?\\H+Y\\H?Z",[{parts,
- 2}]))),
- <<">XYZ">> = iolist_to_binary(join(re:split(">XYZ","\\h*X\\h?\\H+Y\\H?Z",[]))),
- <<"> X NY Z">> = iolist_to_binary(join(re:split("> X NY Z","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
+ 2}]))),
+ <<">XYZ">> = iolist_to_binary(join(re:split(">XYZ","\\h*X\\h?\\H+Y\\H?Z",[]))),
+ <<"> X NY Z">> = iolist_to_binary(join(re:split("> X NY Z","\\h*X\\h?\\H+Y\\H?Z",[trim]))),
<<"> X NY Z">> = iolist_to_binary(join(re:split("> X NY Z","\\h*X\\h?\\H+Y\\H?Z",[{parts,
- 2}]))),
- <<"> X NY Z">> = iolist_to_binary(join(re:split("> X NY Z","\\h*X\\h?\\H+Y\\H?Z",[]))),
+ 2}]))),
+ <<"> X NY Z">> = iolist_to_binary(join(re:split("> X NY Z","\\h*X\\h?\\H+Y\\H?Z",[]))),
<<">">> = iolist_to_binary(join(re:split(">XY
Z
-A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[trim]))),
+A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[trim]))),
<<">:">> = iolist_to_binary(join(re:split(">XY
Z
A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[{parts,
- 2}]))),
+ 2}]))),
<<">:">> = iolist_to_binary(join(re:split(">XY
Z
-A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[]))),
+A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[]))),
<<">">> = iolist_to_binary(join(re:split(">
X
Y
ZZZ
-AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[trim]))),
+AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[trim]))),
<<">:">> = iolist_to_binary(join(re:split(">
X
Y
ZZZ
AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[{parts,
- 2}]))),
+ 2}]))),
<<">:">> = iolist_to_binary(join(re:split(">
X
Y
ZZZ
-AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[]))),
- <<"foo:foo">> = iolist_to_binary(join(re:split("foobar","(foo)\\Kbar",[trim]))),
+AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[]))),
+ <<"foo:foo">> = iolist_to_binary(join(re:split("foobar","(foo)\\Kbar",[trim]))),
<<"foo:foo:">> = iolist_to_binary(join(re:split("foobar","(foo)\\Kbar",[{parts,
- 2}]))),
- <<"foo:foo:">> = iolist_to_binary(join(re:split("foobar","(foo)\\Kbar",[]))),
- <<"foo:foo:bar">> = iolist_to_binary(join(re:split("foobar","(foo)(\\Kbar|baz)",[trim]))),
+ 2}]))),
+ <<"foo:foo:">> = iolist_to_binary(join(re:split("foobar","(foo)\\Kbar",[]))),
+ <<"foo:foo:bar">> = iolist_to_binary(join(re:split("foobar","(foo)(\\Kbar|baz)",[trim]))),
<<"foo:foo:bar:">> = iolist_to_binary(join(re:split("foobar","(foo)(\\Kbar|baz)",[{parts,
- 2}]))),
- <<"foo:foo:bar:">> = iolist_to_binary(join(re:split("foobar","(foo)(\\Kbar|baz)",[]))),
- <<":foo:baz">> = iolist_to_binary(join(re:split("foobaz","(foo)(\\Kbar|baz)",[trim]))),
+ 2}]))),
+ <<"foo:foo:bar:">> = iolist_to_binary(join(re:split("foobar","(foo)(\\Kbar|baz)",[]))),
+ <<":foo:baz">> = iolist_to_binary(join(re:split("foobaz","(foo)(\\Kbar|baz)",[trim]))),
<<":foo:baz:">> = iolist_to_binary(join(re:split("foobaz","(foo)(\\Kbar|baz)",[{parts,
- 2}]))),
- <<":foo:baz:">> = iolist_to_binary(join(re:split("foobaz","(foo)(\\Kbar|baz)",[]))),
- <<"foo:foobar">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[trim]))),
+ 2}]))),
+ <<":foo:baz:">> = iolist_to_binary(join(re:split("foobaz","(foo)(\\Kbar|baz)",[]))),
+ <<"foo:foobar">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[trim]))),
<<"foo:foobar:">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[{parts,
- 2}]))),
- <<"foo:foobar:">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[]))),
- <<":tom">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[trim]))),
+ 2}]))),
+ <<"foo:foobar:">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[]))),
+ <<":tom">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[trim]))),
<<":tom:">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[{parts,
- 2}]))),
- <<":tom:">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[]))),
- <<":bon">> = iolist_to_binary(join(re:split("bon-bon","(?<A>tom|bon)-\\g{A}",[trim]))),
+ 2}]))),
+ <<":tom:">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[]))),
+ <<":bon">> = iolist_to_binary(join(re:split("bon-bon","(?<A>tom|bon)-\\g{A}",[trim]))),
<<":bon:">> = iolist_to_binary(join(re:split("bon-bon","(?<A>tom|bon)-\\g{A}",[{parts,
- 2}]))),
- <<":bon:">> = iolist_to_binary(join(re:split("bon-bon","(?<A>tom|bon)-\\g{A}",[]))),
- <<"bacxxx">> = iolist_to_binary(join(re:split("bacxxx","(^(a|b\\g{-1}))",[trim]))),
+ 2}]))),
+ <<":bon:">> = iolist_to_binary(join(re:split("bon-bon","(?<A>tom|bon)-\\g{A}",[]))),
+ <<"bacxxx">> = iolist_to_binary(join(re:split("bacxxx","(^(a|b\\g{-1}))",[trim]))),
<<"bacxxx">> = iolist_to_binary(join(re:split("bacxxx","(^(a|b\\g{-1}))",[{parts,
- 2}]))),
- <<"bacxxx">> = iolist_to_binary(join(re:split("bacxxx","(^(a|b\\g{-1}))",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))\\1",[trim]))),
+ 2}]))),
+ <<"bacxxx">> = iolist_to_binary(join(re:split("bacxxx","(^(a|b\\g{-1}))",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))\\1",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))\\1",[]))),
- <<":xyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))\\1",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))\\1",[]))),
+ <<":xyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))\\1",[trim]))),
<<":xyz:">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))\\1",[{parts,
- 2}]))),
- <<":xyz:">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))\\1",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))\\1",[trim]))),
+ 2}]))),
+ <<":xyz:">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))\\1",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))\\1",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))\\1",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))\\1",[]))),
- <<"abcxyz">> = iolist_to_binary(join(re:split("abcxyz","(?|(abc)|(xyz))\\1",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))\\1",[]))),
+ <<"abcxyz">> = iolist_to_binary(join(re:split("abcxyz","(?|(abc)|(xyz))\\1",[trim]))),
<<"abcxyz">> = iolist_to_binary(join(re:split("abcxyz","(?|(abc)|(xyz))\\1",[{parts,
- 2}]))),
- <<"abcxyz">> = iolist_to_binary(join(re:split("abcxyz","(?|(abc)|(xyz))\\1",[]))),
- <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[trim]))),
+ 2}]))),
+ <<"abcxyz">> = iolist_to_binary(join(re:split("abcxyz","(?|(abc)|(xyz))\\1",[]))),
+ <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[trim]))),
<<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[{parts,
- 2}]))),
- <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[trim]))),
+ 2}]))),
+ <<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[]))),
- <<":xyz">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))(?1)",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[]))),
+ <<":xyz">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))(?1)",[trim]))),
<<":xyz:">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))(?1)",[{parts,
- 2}]))),
- <<":xyz:">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))(?1)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))(?1)",[trim]))),
+ 2}]))),
+ <<":xyz:">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))(?1)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))(?1)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))(?1)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))(?1)",[]))),
- <<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?|(abc)|(xyz))(?1)",[]))),
+ <<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[trim]))),
<<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[{parts,
- 2}]))),
- <<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[]))),
+ 2}]))),
+ <<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[]))),
ok.
run41() ->
- <<":a:b:c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[trim]))),
+ <<":a:b:c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[trim]))),
<<":a:b:c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[{parts,
- 2}]))),
- <<":a:b:c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[]))),
- <<":a:b:::c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)",[trim]))),
+ 2}]))),
+ <<":a:b:c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[]))),
+ <<":a:b:::c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)",[trim]))),
<<":a:b:::c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)",[{parts,
- 2}]))),
- <<":a:b:::c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)",[]))),
- <<":a:b:::c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)",[trim]))),
+ 2}]))),
+ <<":a:b:::c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)",[]))),
+ <<":a:b:::c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)",[trim]))),
<<":a:b:::c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)",[{parts,
- 2}]))),
- <<":a:b:::c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)",[]))),
- <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
+ 2}]))),
+ <<":a:b:::c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)",[]))),
+ <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
<<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}",[{parts,
- 2}]))),
- <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
- <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
+ 2}]))),
+ <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
+ <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
<<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}",[{parts,
- 2}]))),
- <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
+ 2}]))),
+ <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\k<abc>{2}",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\k<abc>{2}",[]))),
- <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\k<abc>{2}",[]))),
+ <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
<<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\k<abc>{2}",[{parts,
- 2}]))),
- <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
- <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
+ 2}]))),
+ <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
+ <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}",[trim]))),
<<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}",[{parts,
- 2}]))),
- <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
- <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
+ 2}]))),
+ <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}",[]))),
+ <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
<<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}",[{parts,
- 2}]))),
- <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
- <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
+ 2}]))),
+ <<":a:xyz">> = iolist_to_binary(join(re:split("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
+ <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
<<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}",[{parts,
- 2}]))),
- <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
+ 2}]))),
+ <<":ab:xyz">> = iolist_to_binary(join(re:split("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\g{abc}{2}",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\g{abc}{2}",[]))),
- <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?'abc'\\w+):\\g{abc}{2}",[]))),
+ <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
<<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\g{abc}{2}",[{parts,
- 2}]))),
- <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
- <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
+ 2}]))),
+ <<"a:axyz">> = iolist_to_binary(join(re:split("a:axyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
+ <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}",[trim]))),
<<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}",[{parts,
- 2}]))),
- <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
+ 2}]))),
+ <<"ab:abxyz">> = iolist_to_binary(join(re:split("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}",[]))),
<<":a">> = iolist_to_binary(join(re:split("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended,
- trim]))),
+ trim]))),
<<":a:">> = iolist_to_binary(join(re:split("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended,
{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended]))),
<<"">> = iolist_to_binary(join(re:split("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended,
- trim]))),
+ trim]))),
<<"::">> = iolist_to_binary(join(re:split("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended,
{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended]))),
- <<":aX">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g-1Z",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)",[extended]))),
+ <<":aX">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g-1Z",[trim]))),
<<":aX:">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g-1Z",[{parts,
- 2}]))),
- <<":aX:">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g-1Z",[]))),
- <<":aX">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g{-1}Z",[trim]))),
+ 2}]))),
+ <<":aX:">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g-1Z",[]))),
+ <<":aX">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g{-1}Z",[trim]))),
<<":aX:">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g{-1}Z",[{parts,
- 2}]))),
- <<":aX:">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g{-1}Z",[]))),
+ 2}]))),
+ <<":aX:">> = iolist_to_binary(join(re:split("aXaXZ","^(a.)\\g{-1}Z",[]))),
<<":::cd">> = iolist_to_binary(join(re:split("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ",[extended,
- trim]))),
+ trim]))),
<<":::cd">> = iolist_to_binary(join(re:split("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ",[extended,
{parts,
- 2}]))),
- <<":::cd">> = iolist_to_binary(join(re:split("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ",[extended]))),
+ 2}]))),
+ <<":::cd">> = iolist_to_binary(join(re:split("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ",[extended]))),
<<":metcalfe:33">> = iolist_to_binary(join(re:split("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
(?(DEFINE)
(?<NAME_PAT>[a-z]+)
(?<ADDRESS_PAT>\\d+)
- )",[extended,trim]))),
+ )",[extended,trim]))),
<<":metcalfe:33:::">> = iolist_to_binary(join(re:split("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
(?(DEFINE)
(?<NAME_PAT>[a-z]+)
(?<ADDRESS_PAT>\\d+)
- )",[extended,{parts,2}]))),
+ )",[extended,{parts,2}]))),
<<":metcalfe:33:::">> = iolist_to_binary(join(re:split("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
(?(DEFINE)
(?<NAME_PAT>[a-z]+)
(?<ADDRESS_PAT>\\d+)
- )",[extended]))),
- <<"::.4">> = iolist_to_binary(join(re:split("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
+ )",[extended]))),
+ <<"::.4">> = iolist_to_binary(join(re:split("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
<<"::.4:">> = iolist_to_binary(join(re:split("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[{parts,
- 2}]))),
- <<"::.4:">> = iolist_to_binary(join(re:split("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
- <<"::.206">> = iolist_to_binary(join(re:split("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
+ 2}]))),
+ <<"::.4:">> = iolist_to_binary(join(re:split("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
+ <<"::.206">> = iolist_to_binary(join(re:split("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
<<"::.206:">> = iolist_to_binary(join(re:split("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[{parts,
- 2}]))),
- <<"::.206:">> = iolist_to_binary(join(re:split("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
- <<"::.0">> = iolist_to_binary(join(re:split("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
+ 2}]))),
+ <<"::.206:">> = iolist_to_binary(join(re:split("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
+ <<"::.0">> = iolist_to_binary(join(re:split("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
<<"::.0:">> = iolist_to_binary(join(re:split("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[{parts,
- 2}]))),
- <<"::.0:">> = iolist_to_binary(join(re:split("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
+ 2}]))),
+ <<"::.0:">> = iolist_to_binary(join(re:split("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
- <<"10.6">> = iolist_to_binary(join(re:split("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
+ <<"10.6">> = iolist_to_binary(join(re:split("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
<<"10.6">> = iolist_to_binary(join(re:split("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[{parts,
- 2}]))),
- <<"10.6">> = iolist_to_binary(join(re:split("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
- <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
+ 2}]))),
+ <<"10.6">> = iolist_to_binary(join(re:split("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
+ <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[trim]))),
<<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[{parts,
- 2}]))),
- <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
- <<":.4">> = iolist_to_binary(join(re:split("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
+ 2}]))),
+ <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}",[]))),
+ <<":.4">> = iolist_to_binary(join(re:split("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
<<":.4::">> = iolist_to_binary(join(re:split("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[{parts,
- 2}]))),
- <<":.4::">> = iolist_to_binary(join(re:split("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
- <<":.206">> = iolist_to_binary(join(re:split("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
+ 2}]))),
+ <<":.4::">> = iolist_to_binary(join(re:split("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
+ <<":.206">> = iolist_to_binary(join(re:split("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
<<":.206::">> = iolist_to_binary(join(re:split("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[{parts,
- 2}]))),
- <<":.206::">> = iolist_to_binary(join(re:split("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
- <<":.0">> = iolist_to_binary(join(re:split("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
+ 2}]))),
+ <<":.206::">> = iolist_to_binary(join(re:split("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
+ <<":.0">> = iolist_to_binary(join(re:split("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
<<":.0::">> = iolist_to_binary(join(re:split("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[{parts,
- 2}]))),
- <<":.0::">> = iolist_to_binary(join(re:split("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
+ 2}]))),
+ <<":.0::">> = iolist_to_binary(join(re:split("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
- <<"10.6">> = iolist_to_binary(join(re:split("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
+ <<"10.6">> = iolist_to_binary(join(re:split("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
<<"10.6">> = iolist_to_binary(join(re:split("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[{parts,
- 2}]))),
- <<"10.6">> = iolist_to_binary(join(re:split("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
- <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
+ 2}]))),
+ <<"10.6">> = iolist_to_binary(join(re:split("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
+ <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[trim]))),
<<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[{parts,
- 2}]))),
- <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
- <<":party">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$",[trim]))),
+ 2}]))),
+ <<"455.3.4.5">> = iolist_to_binary(join(re:split("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))",[]))),
+ <<":party">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$",[trim]))),
<<":party:">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$",[{parts,
- 2}]))),
- <<":party:">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\w++|\\s++)*$",[trim]))),
+ 2}]))),
+ <<":party:">> = iolist_to_binary(join(re:split("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\w++|\\s++)*$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\w++|\\s++)*$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\w++|\\s++)*$",[]))),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^(\\w++|\\s++)*$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\w++|\\s++)*$",[]))),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^(\\w++|\\s++)*$",[trim]))),
<<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^(\\w++|\\s++)*$",[{parts,
- 2}]))),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^(\\w++|\\s++)*$",[]))),
- <<":12345:a">> = iolist_to_binary(join(re:split("12345a","(\\d++)(\\w)",[trim]))),
+ 2}]))),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(join(re:split("this is not a line with only words and spaces!","^(\\w++|\\s++)*$",[]))),
+ <<":12345:a">> = iolist_to_binary(join(re:split("12345a","(\\d++)(\\w)",[trim]))),
<<":12345:a:">> = iolist_to_binary(join(re:split("12345a","(\\d++)(\\w)",[{parts,
- 2}]))),
- <<":12345:a:">> = iolist_to_binary(join(re:split("12345a","(\\d++)(\\w)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\d++)(\\w)",[trim]))),
+ 2}]))),
+ <<":12345:a:">> = iolist_to_binary(join(re:split("12345a","(\\d++)(\\w)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\d++)(\\w)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\d++)(\\w)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\d++)(\\w)",[]))),
- <<"12345+">> = iolist_to_binary(join(re:split("12345+","(\\d++)(\\w)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(\\d++)(\\w)",[]))),
+ <<"12345+">> = iolist_to_binary(join(re:split("12345+","(\\d++)(\\w)",[trim]))),
<<"12345+">> = iolist_to_binary(join(re:split("12345+","(\\d++)(\\w)",[{parts,
- 2}]))),
- <<"12345+">> = iolist_to_binary(join(re:split("12345+","(\\d++)(\\w)",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaab","a++b",[trim]))),
+ 2}]))),
+ <<"12345+">> = iolist_to_binary(join(re:split("12345+","(\\d++)(\\w)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaab","a++b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaab","a++b",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaab","a++b",[]))),
- <<":aaab">> = iolist_to_binary(join(re:split("aaab","(a++b)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaab","a++b",[]))),
+ <<":aaab">> = iolist_to_binary(join(re:split("aaab","(a++b)",[trim]))),
<<":aaab:">> = iolist_to_binary(join(re:split("aaab","(a++b)",[{parts,
- 2}]))),
- <<":aaab:">> = iolist_to_binary(join(re:split("aaab","(a++b)",[]))),
- <<":aaa">> = iolist_to_binary(join(re:split("aaab","(a++)b",[trim]))),
+ 2}]))),
+ <<":aaab:">> = iolist_to_binary(join(re:split("aaab","(a++b)",[]))),
+ <<":aaa">> = iolist_to_binary(join(re:split("aaab","(a++)b",[trim]))),
<<":aaa:">> = iolist_to_binary(join(re:split("aaab","(a++)b",[{parts,
- 2}]))),
- <<":aaa:">> = iolist_to_binary(join(re:split("aaab","(a++)b",[]))),
- <<"((:x">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+",[trim]))),
+ 2}]))),
+ <<":aaa:">> = iolist_to_binary(join(re:split("aaab","(a++)b",[]))),
+ <<"((:x">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+",[trim]))),
<<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+",[{parts,
- 2}]))),
- <<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("(abc)","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<"((:x:">> = iolist_to_binary(join(re:split("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("(abc)","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("(abc)","\\(([^()]++|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("(abc)","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
- <<":xyz">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("(abc)","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
+ <<":xyz">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
<<":xyz:">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<":xyz:">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<":xyz:">> = iolist_to_binary(join(re:split("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[trim]))),
<<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[{parts,
- 2}]))),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[trim]))),
<<":c:">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<":c:">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[]))),
- <<":c">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<":c:">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[trim]))),
<<":c:">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<":c:">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[]))),
- <<":d">> = iolist_to_binary(join(re:split("a(b(c))d","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<":c:">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[]))),
+ <<":d">> = iolist_to_binary(join(re:split("a(b(c))d","^([^()]|\\((?1)*\\))*$",[trim]))),
<<":d:">> = iolist_to_binary(join(re:split("a(b(c))d","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<":d:">> = iolist_to_binary(join(re:split("a(b(c))d","^([^()]|\\((?1)*\\))*$",[]))),
- <<"*** Failers)">> = iolist_to_binary(join(re:split("*** Failers)","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<":d:">> = iolist_to_binary(join(re:split("a(b(c))d","^([^()]|\\((?1)*\\))*$",[]))),
+ <<"*** Failers)">> = iolist_to_binary(join(re:split("*** Failers)","^([^()]|\\((?1)*\\))*$",[trim]))),
<<"*** Failers)">> = iolist_to_binary(join(re:split("*** Failers)","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<"*** Failers)">> = iolist_to_binary(join(re:split("*** Failers)","^([^()]|\\((?1)*\\))*$",[]))),
- <<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<"*** Failers)">> = iolist_to_binary(join(re:split("*** Failers)","^([^()]|\\((?1)*\\))*$",[]))),
+ <<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[trim]))),
<<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[]))),
+ 2}]))),
+ <<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[]))),
ok.
run42() ->
- <<":3">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
+ <<":3">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
<<":3:">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[{parts,
- 2}]))),
- <<":3:">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[]))),
- <<":3">> = iolist_to_binary(join(re:split(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
+ 2}]))),
+ <<":3:">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[]))),
+ <<":3">> = iolist_to_binary(join(re:split(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
<<":3:">> = iolist_to_binary(join(re:split(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[{parts,
- 2}]))),
- <<":3:">> = iolist_to_binary(join(re:split(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[]))),
- <<":(1(2)3)">> = iolist_to_binary(join(re:split(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
+ 2}]))),
+ <<":3:">> = iolist_to_binary(join(re:split(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[]))),
+ <<":(1(2)3)">> = iolist_to_binary(join(re:split(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
<<":(1(2)3):">> = iolist_to_binary(join(re:split(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[{parts,
- 2}]))),
- <<":(1(2)3):">> = iolist_to_binary(join(re:split(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[]))),
+ 2}]))),
+ <<":(1(2)3):">> = iolist_to_binary(join(re:split(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[]))),
<<":1221:1">> = iolist_to_binary(join(re:split("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
- trim]))),
+ trim]))),
<<":1221:1:::">> = iolist_to_binary(join(re:split("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
{parts,
- 2}]))),
- <<":1221:1:::">> = iolist_to_binary(join(re:split("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
+ 2}]))),
+ <<":1221:1:::">> = iolist_to_binary(join(re:split("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
<<":::Satanoscillatemymetallicsonatas:S">> = iolist_to_binary(join(re:split("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
- trim]))),
+ trim]))),
<<":::Satanoscillatemymetallicsonatas:S:">> = iolist_to_binary(join(re:split("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
{parts,
- 2}]))),
- <<":::Satanoscillatemymetallicsonatas:S:">> = iolist_to_binary(join(re:split("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
+ 2}]))),
+ <<":::Satanoscillatemymetallicsonatas:S:">> = iolist_to_binary(join(re:split("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
<<":::AmanaplanacanalPanama:A">> = iolist_to_binary(join(re:split("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
- trim]))),
+ trim]))),
<<":::AmanaplanacanalPanama:A:">> = iolist_to_binary(join(re:split("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
{parts,
- 2}]))),
- <<":::AmanaplanacanalPanama:A:">> = iolist_to_binary(join(re:split("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
+ 2}]))),
+ <<":::AmanaplanacanalPanama:A:">> = iolist_to_binary(join(re:split("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
<<":::AblewasIereIsawElba:A">> = iolist_to_binary(join(re:split("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
- trim]))),
+ trim]))),
<<":::AblewasIereIsawElba:A:">> = iolist_to_binary(join(re:split("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
{parts,
- 2}]))),
- <<":::AblewasIereIsawElba:A:">> = iolist_to_binary(join(re:split("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
+ 2}]))),
+ <<":::AblewasIereIsawElba:A:">> = iolist_to_binary(join(re:split("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
<<"Thequickbrownfox">> = iolist_to_binary(join(re:split("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
- trim]))),
+ trim]))),
<<"Thequickbrownfox">> = iolist_to_binary(join(re:split("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless,
{parts,
- 2}]))),
- <<"Thequickbrownfox">> = iolist_to_binary(join(re:split("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
- <<":12">> = iolist_to_binary(join(re:split("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
+ 2}]))),
+ <<"Thequickbrownfox">> = iolist_to_binary(join(re:split("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$",[caseless]))),
+ <<":12">> = iolist_to_binary(join(re:split("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
<<":12::">> = iolist_to_binary(join(re:split("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[{parts,
- 2}]))),
- <<":12::">> = iolist_to_binary(join(re:split("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
- <<":(((2+2)*-3)-7):-">> = iolist_to_binary(join(re:split("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
+ 2}]))),
+ <<":12::">> = iolist_to_binary(join(re:split("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
+ <<":(((2+2)*-3)-7):-">> = iolist_to_binary(join(re:split("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
<<":(((2+2)*-3)-7):-:">> = iolist_to_binary(join(re:split("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[{parts,
- 2}]))),
- <<":(((2+2)*-3)-7):-:">> = iolist_to_binary(join(re:split("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
- <<":-12">> = iolist_to_binary(join(re:split("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
+ 2}]))),
+ <<":(((2+2)*-3)-7):-:">> = iolist_to_binary(join(re:split("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
+ <<":-12">> = iolist_to_binary(join(re:split("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
<<":-12::">> = iolist_to_binary(join(re:split("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[{parts,
- 2}]))),
- <<":-12::">> = iolist_to_binary(join(re:split("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
+ 2}]))),
+ <<":-12::">> = iolist_to_binary(join(re:split("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
- <<"((2+2)*-3)-7)">> = iolist_to_binary(join(re:split("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
+ <<"((2+2)*-3)-7)">> = iolist_to_binary(join(re:split("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[trim]))),
<<"((2+2)*-3)-7)">> = iolist_to_binary(join(re:split("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[{parts,
- 2}]))),
- <<"((2+2)*-3)-7)">> = iolist_to_binary(join(re:split("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
- <<":xyz:y">> = iolist_to_binary(join(re:split("xyz","^(x(y|(?1){2})z)",[trim]))),
+ 2}]))),
+ <<"((2+2)*-3)-7)">> = iolist_to_binary(join(re:split("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$",[]))),
+ <<":xyz:y">> = iolist_to_binary(join(re:split("xyz","^(x(y|(?1){2})z)",[trim]))),
<<":xyz:y:">> = iolist_to_binary(join(re:split("xyz","^(x(y|(?1){2})z)",[{parts,
- 2}]))),
- <<":xyz:y:">> = iolist_to_binary(join(re:split("xyz","^(x(y|(?1){2})z)",[]))),
- <<":xxyzxyzz:xyzxyz">> = iolist_to_binary(join(re:split("xxyzxyzz","^(x(y|(?1){2})z)",[trim]))),
+ 2}]))),
+ <<":xyz:y:">> = iolist_to_binary(join(re:split("xyz","^(x(y|(?1){2})z)",[]))),
+ <<":xxyzxyzz:xyzxyz">> = iolist_to_binary(join(re:split("xxyzxyzz","^(x(y|(?1){2})z)",[trim]))),
<<":xxyzxyzz:xyzxyz:">> = iolist_to_binary(join(re:split("xxyzxyzz","^(x(y|(?1){2})z)",[{parts,
- 2}]))),
- <<":xxyzxyzz:xyzxyz:">> = iolist_to_binary(join(re:split("xxyzxyzz","^(x(y|(?1){2})z)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(x(y|(?1){2})z)",[trim]))),
+ 2}]))),
+ <<":xxyzxyzz:xyzxyz:">> = iolist_to_binary(join(re:split("xxyzxyzz","^(x(y|(?1){2})z)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(x(y|(?1){2})z)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(x(y|(?1){2})z)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(x(y|(?1){2})z)",[]))),
- <<"xxyzz">> = iolist_to_binary(join(re:split("xxyzz","^(x(y|(?1){2})z)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(x(y|(?1){2})z)",[]))),
+ <<"xxyzz">> = iolist_to_binary(join(re:split("xxyzz","^(x(y|(?1){2})z)",[trim]))),
<<"xxyzz">> = iolist_to_binary(join(re:split("xxyzz","^(x(y|(?1){2})z)",[{parts,
- 2}]))),
- <<"xxyzz">> = iolist_to_binary(join(re:split("xxyzz","^(x(y|(?1){2})z)",[]))),
- <<"xxyzxyzxyzz">> = iolist_to_binary(join(re:split("xxyzxyzxyzz","^(x(y|(?1){2})z)",[trim]))),
+ 2}]))),
+ <<"xxyzz">> = iolist_to_binary(join(re:split("xxyzz","^(x(y|(?1){2})z)",[]))),
+ <<"xxyzxyzxyzz">> = iolist_to_binary(join(re:split("xxyzxyzxyzz","^(x(y|(?1){2})z)",[trim]))),
<<"xxyzxyzxyzz">> = iolist_to_binary(join(re:split("xxyzxyzxyzz","^(x(y|(?1){2})z)",[{parts,
- 2}]))),
- <<"xxyzxyzxyzz">> = iolist_to_binary(join(re:split("xxyzxyzxyzz","^(x(y|(?1){2})z)",[]))),
+ 2}]))),
+ <<"xxyzxyzxyzz">> = iolist_to_binary(join(re:split("xxyzxyzxyzz","^(x(y|(?1){2})z)",[]))),
<<":<>:<>">> = iolist_to_binary(join(re:split("<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<":<>:<>:">> = iolist_to_binary(join(re:split("<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<":<>:<>:">> = iolist_to_binary(join(re:split("<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<":<>:<>:">> = iolist_to_binary(join(re:split("<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<":<abcd>:<abcd>">> = iolist_to_binary(join(re:split("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<":<abcd>:<abcd>:">> = iolist_to_binary(join(re:split("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<":<abcd>:<abcd>:">> = iolist_to_binary(join(re:split("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<":<abcd>:<abcd>:">> = iolist_to_binary(join(re:split("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<":<abc <123> hij>:<abc <123> hij>">> = iolist_to_binary(join(re:split("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<":<abc <123> hij>:<abc <123> hij>:">> = iolist_to_binary(join(re:split("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<":<abc <123> hij>:<abc <123> hij>:">> = iolist_to_binary(join(re:split("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<":<abc <123> hij>:<abc <123> hij>:">> = iolist_to_binary(join(re:split("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<"<abc :<def>:<def>: hij>">> = iolist_to_binary(join(re:split("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<"<abc :<def>:<def>: hij>">> = iolist_to_binary(join(re:split("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<"<abc :<def>:<def>: hij>">> = iolist_to_binary(join(re:split("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<"<abc :<def>:<def>: hij>">> = iolist_to_binary(join(re:split("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<":<abc<>def>:<abc<>def>">> = iolist_to_binary(join(re:split("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<":<abc<>def>:<abc<>def>:">> = iolist_to_binary(join(re:split("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<":<abc<>def>:<abc<>def>:">> = iolist_to_binary(join(re:split("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<":<abc<>def>:<abc<>def>:">> = iolist_to_binary(join(re:split("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<"<abc:<>:<>">> = iolist_to_binary(join(re:split("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<"<abc:<>:<>:">> = iolist_to_binary(join(re:split("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<"<abc:<>:<>:">> = iolist_to_binary(join(re:split("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<"<abc:<>:<>:">> = iolist_to_binary(join(re:split("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
<<"<abc">> = iolist_to_binary(join(re:split("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
- trim]))),
+ trim]))),
<<"<abc">> = iolist_to_binary(join(re:split("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended,
{parts,
- 2}]))),
- <<"<abc">> = iolist_to_binary(join(re:split("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^a+(*FAIL)",[trim]))),
+ 2}]))),
+ <<"<abc">> = iolist_to_binary(join(re:split("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))",[extended]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^a+(*FAIL)",[trim]))),
<<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^a+(*FAIL)",[{parts,
- 2}]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^a+(*FAIL)",[]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?c+(*FAIL)",[trim]))),
+ 2}]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^a+(*FAIL)",[]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?c+(*FAIL)",[trim]))),
<<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?c+(*FAIL)",[{parts,
- 2}]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?c+(*FAIL)",[]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*PRUNE)c+(*FAIL)",[trim]))),
+ 2}]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?c+(*FAIL)",[]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*PRUNE)c+(*FAIL)",[trim]))),
<<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*PRUNE)c+(*FAIL)",[{parts,
- 2}]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*PRUNE)c+(*FAIL)",[]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*COMMIT)c+(*FAIL)",[trim]))),
+ 2}]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*PRUNE)c+(*FAIL)",[]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*COMMIT)c+(*FAIL)",[trim]))),
<<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*COMMIT)c+(*FAIL)",[{parts,
- 2}]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*COMMIT)c+(*FAIL)",[]))),
- <<"aaabcccaaabccc">> = iolist_to_binary(join(re:split("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)",[trim]))),
+ 2}]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*COMMIT)c+(*FAIL)",[]))),
+ <<"aaabcccaaabccc">> = iolist_to_binary(join(re:split("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)",[trim]))),
<<"aaabcccaaabccc">> = iolist_to_binary(join(re:split("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)",[{parts,
- 2}]))),
- <<"aaabcccaaabccc">> = iolist_to_binary(join(re:split("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<"aaabcccaaabccc">> = iolist_to_binary(join(re:split("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<"">> = iolist_to_binary(join(re:split("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":">> = iolist_to_binary(join(re:split("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<"">> = iolist_to_binary(join(re:split("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<"">> = iolist_to_binary(join(re:split("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":">> = iolist_to_binary(join(re:split("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":++++">> = iolist_to_binary(join(re:split("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":++++">> = iolist_to_binary(join(re:split("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":++++">> = iolist_to_binary(join(re:split("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":++++">> = iolist_to_binary(join(re:split("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":++++">> = iolist_to_binary(join(re:split("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":aaaxxxxxx">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":aaaxxxxxx">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":aaaxxxxxx:">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":aaaxxxxxx:">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":aaa:++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":aaaxxxxxx:">> = iolist_to_binary(join(re:split("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":aaa:++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":aaa:++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":aaa:++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":bbbxxxxx">> = iolist_to_binary(join(re:split("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":aaa:++++++">> = iolist_to_binary(join(re:split("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":bbbxxxxx">> = iolist_to_binary(join(re:split("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":bbbxxxxx:">> = iolist_to_binary(join(re:split("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":bbbxxxxx:">> = iolist_to_binary(join(re:split("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":bbb:+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":bbbxxxxx:">> = iolist_to_binary(join(re:split("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":bbb:+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":bbb:+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":bbb:+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":cccxxxx">> = iolist_to_binary(join(re:split("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":bbb:+++++">> = iolist_to_binary(join(re:split("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":cccxxxx">> = iolist_to_binary(join(re:split("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":cccxxxx:">> = iolist_to_binary(join(re:split("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":cccxxxx:">> = iolist_to_binary(join(re:split("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":ccc:++++">> = iolist_to_binary(join(re:split("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":cccxxxx:">> = iolist_to_binary(join(re:split("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":ccc:++++">> = iolist_to_binary(join(re:split("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":ccc:++++">> = iolist_to_binary(join(re:split("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":ccc:++++">> = iolist_to_binary(join(re:split("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<":ddd:ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
+ 2}]))),
+ <<":ccc:++++">> = iolist_to_binary(join(re:split("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<":ddd:ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[trim]))),
<<":ddd:ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[{parts,
- 2}]))),
- <<":ddd:ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*THEN)c+(*FAIL)",[trim]))),
+ 2}]))),
+ <<":ddd:ddddd">> = iolist_to_binary(join(re:split("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})",[]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*THEN)c+(*FAIL)",[trim]))),
<<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*THEN)c+(*FAIL)",[{parts,
- 2}]))),
- <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*THEN)c+(*FAIL)",[]))),
+ 2}]))),
+ <<"aaabccc">> = iolist_to_binary(join(re:split("aaabccc","a+b?(*THEN)c+(*FAIL)",[]))),
<<":AB:B">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
<<":AB:B::X">> = iolist_to_binary(join(re:split("ABX","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<":AB:B::X">> = iolist_to_binary(join(re:split("ABX","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<":AB:B::X">> = iolist_to_binary(join(re:split("ABX","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<":AB:B::X">> = iolist_to_binary(join(re:split("ABX","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
<<":AAD:A:E">> = iolist_to_binary(join(re:split("AADE","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<":AAD:A:E:">> = iolist_to_binary(join(re:split("AADE","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<":AAD:A:E:">> = iolist_to_binary(join(re:split("AADE","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<":AAD:A:E:">> = iolist_to_binary(join(re:split("AADE","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
<<":ACD:C:E">> = iolist_to_binary(join(re:split("ACDE","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<":ACD:C:E:">> = iolist_to_binary(join(re:split("ACDE","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<":ACD:C:E:">> = iolist_to_binary(join(re:split("ACDE","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<":ACD:C:E:">> = iolist_to_binary(join(re:split("ACDE","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
<<"AD">> = iolist_to_binary(join(re:split("AD","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<"AD">> = iolist_to_binary(join(re:split("AD","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<"AD">> = iolist_to_binary(join(re:split("AD","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<"AD">> = iolist_to_binary(join(re:split("AD","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
<<":1221:1">> = iolist_to_binary(join(re:split("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
- trim]))),
+ trim]))),
<<":1221:1:::">> = iolist_to_binary(join(re:split("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
{parts,
- 2}]))),
- <<":1221:1:::">> = iolist_to_binary(join(re:split("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
+ 2}]))),
+ <<":1221:1:::">> = iolist_to_binary(join(re:split("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
<<":::Satan, oscillate my metallic sonatas:S">> = iolist_to_binary(join(re:split("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
- trim]))),
+ trim]))),
<<":::Satan, oscillate my metallic sonatas:S:">> = iolist_to_binary(join(re:split("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
{parts,
- 2}]))),
- <<":::Satan, oscillate my metallic sonatas:S:">> = iolist_to_binary(join(re:split("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
+ 2}]))),
+ <<":::Satan, oscillate my metallic sonatas:S:">> = iolist_to_binary(join(re:split("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
<<":::A man, a plan, a canal: Panama:A">> = iolist_to_binary(join(re:split("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
- trim]))),
+ trim]))),
<<":::A man, a plan, a canal: Panama:A:">> = iolist_to_binary(join(re:split("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
{parts,
- 2}]))),
- <<":::A man, a plan, a canal: Panama:A:">> = iolist_to_binary(join(re:split("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
+ 2}]))),
+ <<":::A man, a plan, a canal: Panama:A:">> = iolist_to_binary(join(re:split("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
<<":::Able was I ere I saw Elba:A">> = iolist_to_binary(join(re:split("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
- trim]))),
+ trim]))),
<<":::Able was I ere I saw Elba:A:">> = iolist_to_binary(join(re:split("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
{parts,
- 2}]))),
- <<":::Able was I ere I saw Elba:A:">> = iolist_to_binary(join(re:split("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
+ 2}]))),
+ <<":::Able was I ere I saw Elba:A:">> = iolist_to_binary(join(re:split("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
- trim]))),
+ trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
- trim]))),
+ trim]))),
<<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless,
{parts,
- 2}]))),
- <<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
- <<":a">> = iolist_to_binary(join(re:split("a","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<"The quick brown fox">> = iolist_to_binary(join(re:split("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$",[caseless]))),
+ <<":a">> = iolist_to_binary(join(re:split("a","^((.)(?1)\\2|.)$",[trim]))),
<<":a::">> = iolist_to_binary(join(re:split("a","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<":a::">> = iolist_to_binary(join(re:split("a","^((.)(?1)\\2|.)$",[]))),
- <<":aba:a">> = iolist_to_binary(join(re:split("aba","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<":a::">> = iolist_to_binary(join(re:split("a","^((.)(?1)\\2|.)$",[]))),
+ <<":aba:a">> = iolist_to_binary(join(re:split("aba","^((.)(?1)\\2|.)$",[trim]))),
<<":aba:a:">> = iolist_to_binary(join(re:split("aba","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<":aba:a:">> = iolist_to_binary(join(re:split("aba","^((.)(?1)\\2|.)$",[]))),
- <<":aabaa:a">> = iolist_to_binary(join(re:split("aabaa","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<":aba:a:">> = iolist_to_binary(join(re:split("aba","^((.)(?1)\\2|.)$",[]))),
+ <<":aabaa:a">> = iolist_to_binary(join(re:split("aabaa","^((.)(?1)\\2|.)$",[trim]))),
<<":aabaa:a:">> = iolist_to_binary(join(re:split("aabaa","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<":aabaa:a:">> = iolist_to_binary(join(re:split("aabaa","^((.)(?1)\\2|.)$",[]))),
- <<":abcdcba:a">> = iolist_to_binary(join(re:split("abcdcba","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<":aabaa:a:">> = iolist_to_binary(join(re:split("aabaa","^((.)(?1)\\2|.)$",[]))),
+ <<":abcdcba:a">> = iolist_to_binary(join(re:split("abcdcba","^((.)(?1)\\2|.)$",[trim]))),
<<":abcdcba:a:">> = iolist_to_binary(join(re:split("abcdcba","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<":abcdcba:a:">> = iolist_to_binary(join(re:split("abcdcba","^((.)(?1)\\2|.)$",[]))),
- <<":pqaabaaqp:p">> = iolist_to_binary(join(re:split("pqaabaaqp","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<":abcdcba:a:">> = iolist_to_binary(join(re:split("abcdcba","^((.)(?1)\\2|.)$",[]))),
+ <<":pqaabaaqp:p">> = iolist_to_binary(join(re:split("pqaabaaqp","^((.)(?1)\\2|.)$",[trim]))),
<<":pqaabaaqp:p:">> = iolist_to_binary(join(re:split("pqaabaaqp","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<":pqaabaaqp:p:">> = iolist_to_binary(join(re:split("pqaabaaqp","^((.)(?1)\\2|.)$",[]))),
- <<":ablewasiereisawelba:a">> = iolist_to_binary(join(re:split("ablewasiereisawelba","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<":pqaabaaqp:p:">> = iolist_to_binary(join(re:split("pqaabaaqp","^((.)(?1)\\2|.)$",[]))),
+ <<":ablewasiereisawelba:a">> = iolist_to_binary(join(re:split("ablewasiereisawelba","^((.)(?1)\\2|.)$",[trim]))),
<<":ablewasiereisawelba:a:">> = iolist_to_binary(join(re:split("ablewasiereisawelba","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<":ablewasiereisawelba:a:">> = iolist_to_binary(join(re:split("ablewasiereisawelba","^((.)(?1)\\2|.)$",[]))),
- <<"rhubarb">> = iolist_to_binary(join(re:split("rhubarb","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<":ablewasiereisawelba:a:">> = iolist_to_binary(join(re:split("ablewasiereisawelba","^((.)(?1)\\2|.)$",[]))),
+ <<"rhubarb">> = iolist_to_binary(join(re:split("rhubarb","^((.)(?1)\\2|.)$",[trim]))),
<<"rhubarb">> = iolist_to_binary(join(re:split("rhubarb","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<"rhubarb">> = iolist_to_binary(join(re:split("rhubarb","^((.)(?1)\\2|.)$",[]))),
- <<"the quick brown fox">> = iolist_to_binary(join(re:split("the quick brown fox","^((.)(?1)\\2|.)$",[trim]))),
+ 2}]))),
+ <<"rhubarb">> = iolist_to_binary(join(re:split("rhubarb","^((.)(?1)\\2|.)$",[]))),
+ <<"the quick brown fox">> = iolist_to_binary(join(re:split("the quick brown fox","^((.)(?1)\\2|.)$",[trim]))),
<<"the quick brown fox">> = iolist_to_binary(join(re:split("the quick brown fox","^((.)(?1)\\2|.)$",[{parts,
- 2}]))),
- <<"the quick brown fox">> = iolist_to_binary(join(re:split("the quick brown fox","^((.)(?1)\\2|.)$",[]))),
- <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(a)(?<=b(?1))",[trim]))),
+ 2}]))),
+ <<"the quick brown fox">> = iolist_to_binary(join(re:split("the quick brown fox","^((.)(?1)\\2|.)$",[]))),
+ <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(a)(?<=b(?1))",[trim]))),
<<"b:a:z">> = iolist_to_binary(join(re:split("baz","(a)(?<=b(?1))",[{parts,
- 2}]))),
- <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(a)(?<=b(?1))",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)(?<=b(?1))",[trim]))),
+ 2}]))),
+ <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(a)(?<=b(?1))",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)(?<=b(?1))",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)(?<=b(?1))",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)(?<=b(?1))",[]))),
- <<"caz">> = iolist_to_binary(join(re:split("caz","(a)(?<=b(?1))",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)(?<=b(?1))",[]))),
+ <<"caz">> = iolist_to_binary(join(re:split("caz","(a)(?<=b(?1))",[trim]))),
<<"caz">> = iolist_to_binary(join(re:split("caz","(a)(?<=b(?1))",[{parts,
- 2}]))),
- <<"caz">> = iolist_to_binary(join(re:split("caz","(a)(?<=b(?1))",[]))),
- <<"zba:a:z">> = iolist_to_binary(join(re:split("zbaaz","(?<=b(?1))(a)",[trim]))),
+ 2}]))),
+ <<"caz">> = iolist_to_binary(join(re:split("caz","(a)(?<=b(?1))",[]))),
+ <<"zba:a:z">> = iolist_to_binary(join(re:split("zbaaz","(?<=b(?1))(a)",[trim]))),
<<"zba:a:z">> = iolist_to_binary(join(re:split("zbaaz","(?<=b(?1))(a)",[{parts,
- 2}]))),
- <<"zba:a:z">> = iolist_to_binary(join(re:split("zbaaz","(?<=b(?1))(a)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=b(?1))(a)",[trim]))),
+ 2}]))),
+ <<"zba:a:z">> = iolist_to_binary(join(re:split("zbaaz","(?<=b(?1))(a)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=b(?1))(a)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=b(?1))(a)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=b(?1))(a)",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","(?<=b(?1))(a)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=b(?1))(a)",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","(?<=b(?1))(a)",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","(?<=b(?1))(a)",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","(?<=b(?1))(a)",[]))),
- <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","(?<=b(?1))(a)",[]))),
+ <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[trim]))),
<<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[{parts,
- 2}]))),
- <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[trim]))),
+ 2}]))),
+ <<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[]))),
- <<":def">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))\\1",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[]))),
+ <<":def">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))\\1",[trim]))),
<<":def:">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))\\1",[{parts,
- 2}]))),
- <<":def:">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))\\1",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))\\1",[trim]))),
+ 2}]))),
+ <<":def:">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))\\1",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))\\1",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))\\1",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))\\1",[]))),
- <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))\\1",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))\\1",[]))),
+ <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))\\1",[trim]))),
<<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))\\1",[{parts,
- 2}]))),
- <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))\\1",[]))),
- <<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[trim]))),
+ 2}]))),
+ <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))\\1",[]))),
+ <<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[trim]))),
<<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[{parts,
- 2}]))),
- <<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[]))),
+ 2}]))),
+ <<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[]))),
ok.
run43() ->
- <<":abc">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[trim]))),
+ <<":abc">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[{parts,
- 2}]))),
- <<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[]))),
- <<":def">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))(?1)",[trim]))),
+ 2}]))),
+ <<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[]))),
+ <<":def">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))(?1)",[trim]))),
<<":def:">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))(?1)",[{parts,
- 2}]))),
- <<":def:">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))(?1)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))(?1)",[trim]))),
+ 2}]))),
+ <<":def:">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))(?1)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))(?1)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))(?1)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))(?1)",[]))),
- <<"defdef">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))(?1)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?|(abc)|(def))(?1)",[]))),
+ <<"defdef">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))(?1)",[trim]))),
<<"defdef">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))(?1)",[{parts,
- 2}]))),
- <<"defdef">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))(?1)",[]))),
- <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))(?1)",[trim]))),
+ 2}]))),
+ <<"defdef">> = iolist_to_binary(join(re:split("defdef","^(?|(abc)|(def))(?1)",[]))),
+ <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))(?1)",[trim]))),
<<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))(?1)",[{parts,
- 2}]))),
- <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))(?1)",[]))),
- <<"A:C:D">> = iolist_to_binary(join(re:split("ABCD","(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"abcdef">> = iolist_to_binary(join(re:split("abcdef","^(?|(abc)|(def))(?1)",[]))),
+ <<"A:C:D">> = iolist_to_binary(join(re:split("ABCD","(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"A:C:D">> = iolist_to_binary(join(re:split("ABCD","(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"A:C:D">> = iolist_to_binary(join(re:split("ABCD","(?:(?1)|B)(A(*F)|C)",[]))),
- <<":C:D">> = iolist_to_binary(join(re:split("CCD","(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"A:C:D">> = iolist_to_binary(join(re:split("ABCD","(?:(?1)|B)(A(*F)|C)",[]))),
+ <<":C:D">> = iolist_to_binary(join(re:split("CCD","(?:(?1)|B)(A(*F)|C)",[trim]))),
<<":C:D">> = iolist_to_binary(join(re:split("CCD","(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<":C:D">> = iolist_to_binary(join(re:split("CCD","(?:(?1)|B)(A(*F)|C)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<":C:D">> = iolist_to_binary(join(re:split("CCD","(?:(?1)|B)(A(*F)|C)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*F)|C)",[]))),
- <<"CAD">> = iolist_to_binary(join(re:split("CAD","(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*F)|C)",[]))),
+ <<"CAD">> = iolist_to_binary(join(re:split("CAD","(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"CAD">> = iolist_to_binary(join(re:split("CAD","(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"CAD">> = iolist_to_binary(join(re:split("CAD","(?:(?1)|B)(A(*F)|C)",[]))),
- <<":C:D">> = iolist_to_binary(join(re:split("CCD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"CAD">> = iolist_to_binary(join(re:split("CAD","(?:(?1)|B)(A(*F)|C)",[]))),
+ <<":C:D">> = iolist_to_binary(join(re:split("CCD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
<<":C:D">> = iolist_to_binary(join(re:split("CCD","^(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<":C:D">> = iolist_to_binary(join(re:split("CCD","^(?:(?1)|B)(A(*F)|C)",[]))),
- <<":C:D">> = iolist_to_binary(join(re:split("BCD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<":C:D">> = iolist_to_binary(join(re:split("CCD","^(?:(?1)|B)(A(*F)|C)",[]))),
+ <<":C:D">> = iolist_to_binary(join(re:split("BCD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
<<":C:D">> = iolist_to_binary(join(re:split("BCD","^(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<":C:D">> = iolist_to_binary(join(re:split("BCD","^(?:(?1)|B)(A(*F)|C)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<":C:D">> = iolist_to_binary(join(re:split("BCD","^(?:(?1)|B)(A(*F)|C)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:(?1)|B)(A(*F)|C)",[]))),
- <<"ABCD">> = iolist_to_binary(join(re:split("ABCD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:(?1)|B)(A(*F)|C)",[]))),
+ <<"ABCD">> = iolist_to_binary(join(re:split("ABCD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"ABCD">> = iolist_to_binary(join(re:split("ABCD","^(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"ABCD">> = iolist_to_binary(join(re:split("ABCD","^(?:(?1)|B)(A(*F)|C)",[]))),
- <<"CAD">> = iolist_to_binary(join(re:split("CAD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"ABCD">> = iolist_to_binary(join(re:split("ABCD","^(?:(?1)|B)(A(*F)|C)",[]))),
+ <<"CAD">> = iolist_to_binary(join(re:split("CAD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"CAD">> = iolist_to_binary(join(re:split("CAD","^(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"CAD">> = iolist_to_binary(join(re:split("CAD","^(?:(?1)|B)(A(*F)|C)",[]))),
- <<"BAD">> = iolist_to_binary(join(re:split("BAD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
+ 2}]))),
+ <<"CAD">> = iolist_to_binary(join(re:split("CAD","^(?:(?1)|B)(A(*F)|C)",[]))),
+ <<"BAD">> = iolist_to_binary(join(re:split("BAD","^(?:(?1)|B)(A(*F)|C)",[trim]))),
<<"BAD">> = iolist_to_binary(join(re:split("BAD","^(?:(?1)|B)(A(*F)|C)",[{parts,
- 2}]))),
- <<"BAD">> = iolist_to_binary(join(re:split("BAD","^(?:(?1)|B)(A(*F)|C)",[]))),
- <<":A:D">> = iolist_to_binary(join(re:split("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<"BAD">> = iolist_to_binary(join(re:split("BAD","^(?:(?1)|B)(A(*F)|C)",[]))),
+ <<":A:D">> = iolist_to_binary(join(re:split("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<":A:D">> = iolist_to_binary(join(re:split("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<":A:D">> = iolist_to_binary(join(re:split("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<":C">> = iolist_to_binary(join(re:split("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<":A:D">> = iolist_to_binary(join(re:split("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<":C">> = iolist_to_binary(join(re:split("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<":C:">> = iolist_to_binary(join(re:split("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<":C:">> = iolist_to_binary(join(re:split("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<":A:D">> = iolist_to_binary(join(re:split("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<":C:">> = iolist_to_binary(join(re:split("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<":A:D">> = iolist_to_binary(join(re:split("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<":A:D">> = iolist_to_binary(join(re:split("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<":A:D">> = iolist_to_binary(join(re:split("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<":C">> = iolist_to_binary(join(re:split("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<":A:D">> = iolist_to_binary(join(re:split("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<":C">> = iolist_to_binary(join(re:split("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<":C:">> = iolist_to_binary(join(re:split("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<":C:">> = iolist_to_binary(join(re:split("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<":A:X">> = iolist_to_binary(join(re:split("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<":C:">> = iolist_to_binary(join(re:split("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<":A:X">> = iolist_to_binary(join(re:split("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<":A:X">> = iolist_to_binary(join(re:split("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<":A:X">> = iolist_to_binary(join(re:split("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<":A:X">> = iolist_to_binary(join(re:split("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<"ACX">> = iolist_to_binary(join(re:split("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<"ACX">> = iolist_to_binary(join(re:split("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<"ACX">> = iolist_to_binary(join(re:split("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<"ACX">> = iolist_to_binary(join(re:split("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
+ 2}]))),
+ <<"ACX">> = iolist_to_binary(join(re:split("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[trim]))),
<<"ABC">> = iolist_to_binary(join(re:split("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[{parts,
- 2}]))),
- <<"ABC">> = iolist_to_binary(join(re:split("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
- <<"">> = iolist_to_binary(join(re:split("BAC","(?(DEFINE)(A))B(?1)C",[trim]))),
+ 2}]))),
+ <<"ABC">> = iolist_to_binary(join(re:split("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D",[]))),
+ <<"">> = iolist_to_binary(join(re:split("BAC","(?(DEFINE)(A))B(?1)C",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("BAC","(?(DEFINE)(A))B(?1)C",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("BAC","(?(DEFINE)(A))B(?1)C",[]))),
- <<"">> = iolist_to_binary(join(re:split("BAAC","(?(DEFINE)((A)\\2))B(?1)C",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("BAC","(?(DEFINE)(A))B(?1)C",[]))),
+ <<"">> = iolist_to_binary(join(re:split("BAAC","(?(DEFINE)((A)\\2))B(?1)C",[trim]))),
<<":::">> = iolist_to_binary(join(re:split("BAAC","(?(DEFINE)((A)\\2))B(?1)C",[{parts,
- 2}]))),
- <<":::">> = iolist_to_binary(join(re:split("BAAC","(?(DEFINE)((A)\\2))B(?1)C",[]))),
+ 2}]))),
+ <<":::">> = iolist_to_binary(join(re:split("BAAC","(?(DEFINE)((A)\\2))B(?1)C",[]))),
<<":(ab(cd)ef):ef">> = iolist_to_binary(join(re:split("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )",[extended,
- trim]))),
+ trim]))),
<<":(ab(cd)ef):ef:">> = iolist_to_binary(join(re:split("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )",[extended,
{parts,
- 2}]))),
- <<":(ab(cd)ef):ef:">> = iolist_to_binary(join(re:split("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )",[extended]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*SKIP)b|ac)",[trim]))),
+ 2}]))),
+ <<":(ab(cd)ef):ef:">> = iolist_to_binary(join(re:split("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )",[extended]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*SKIP)b|ac)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*SKIP)b|ac)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*SKIP)b|ac)",[]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*SKIP)b|ac)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*SKIP)b|ac)",[]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*SKIP)b|ac)",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*SKIP)b|ac)",[{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*SKIP)b|ac)",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(?=a(*PRUNE)b)",[trim]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*SKIP)b|ac)",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(?=a(*PRUNE)b)",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","^(?=a(*PRUNE)b)",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","^(?=a(*PRUNE)b)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*PRUNE)b)",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","^(?=a(*PRUNE)b)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*PRUNE)b)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*PRUNE)b)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*PRUNE)b)",[]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*PRUNE)b)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?=a(*PRUNE)b)",[]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*PRUNE)b)",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*PRUNE)b)",[{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*PRUNE)b)",[]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*ACCEPT)b)",[trim]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*PRUNE)b)",[]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*ACCEPT)b)",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*ACCEPT)b)",[{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*ACCEPT)b)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("ab","(?>a\\Kb)",[trim]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?=a(*ACCEPT)b)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("ab","(?>a\\Kb)",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("ab","(?>a\\Kb)",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("ab","(?>a\\Kb)",[]))),
- <<"a:ab">> = iolist_to_binary(join(re:split("ab","((?>a\\Kb))",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("ab","(?>a\\Kb)",[]))),
+ <<"a:ab">> = iolist_to_binary(join(re:split("ab","((?>a\\Kb))",[trim]))),
<<"a:ab:">> = iolist_to_binary(join(re:split("ab","((?>a\\Kb))",[{parts,
- 2}]))),
- <<"a:ab:">> = iolist_to_binary(join(re:split("ab","((?>a\\Kb))",[]))),
- <<"a:ab">> = iolist_to_binary(join(re:split("ab","(a\\Kb)",[trim]))),
+ 2}]))),
+ <<"a:ab:">> = iolist_to_binary(join(re:split("ab","((?>a\\Kb))",[]))),
+ <<"a:ab">> = iolist_to_binary(join(re:split("ab","(a\\Kb)",[trim]))),
<<"a:ab:">> = iolist_to_binary(join(re:split("ab","(a\\Kb)",[{parts,
- 2}]))),
- <<"a:ab:">> = iolist_to_binary(join(re:split("ab","(a\\Kb)",[]))),
- <<"">> = iolist_to_binary(join(re:split("ac","^a\\Kcz|ac",[trim]))),
+ 2}]))),
+ <<"a:ab:">> = iolist_to_binary(join(re:split("ab","(a\\Kb)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ac","^a\\Kcz|ac",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ac","^a\\Kcz|ac",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ac","^a\\Kcz|ac",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab","(?>a\\Kbz|ab)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ac","^a\\Kcz|ac",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","(?>a\\Kbz|ab)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?>a\\Kbz|ab)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ab","(?>a\\Kbz|ab)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","(?>a\\Kbz|ab)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$",[trim]))),
<<"a::">> = iolist_to_binary(join(re:split("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$",[{parts,
- 2}]))),
- <<"a::">> = iolist_to_binary(join(re:split("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$",[]))),
- <<":c">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<"a::">> = iolist_to_binary(join(re:split("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[trim]))),
<<":c:">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<":c:">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[]))),
- <<":e">> = iolist_to_binary(join(re:split("a(b(c)d)e","^([^()]|\\((?1)*\\))*$",[trim]))),
+ 2}]))),
+ <<":c:">> = iolist_to_binary(join(re:split("a(b)c","^([^()]|\\((?1)*\\))*$",[]))),
+ <<":e">> = iolist_to_binary(join(re:split("a(b(c)d)e","^([^()]|\\((?1)*\\))*$",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("a(b(c)d)e","^([^()]|\\((?1)*\\))*$",[{parts,
- 2}]))),
- <<":e:">> = iolist_to_binary(join(re:split("a(b(c)d)e","^([^()]|\\((?1)*\\))*$",[]))),
- <<":0">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[trim]))),
+ 2}]))),
+ <<":e:">> = iolist_to_binary(join(re:split("a(b(c)d)e","^([^()]|\\((?1)*\\))*$",[]))),
+ <<":0">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[trim]))),
<<":0::">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[{parts,
- 2}]))),
- <<":0::">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
- <<":00:0">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[trim]))),
+ 2}]))),
+ <<":0::">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
+ <<":00:0">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[trim]))),
<<":00:0:">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[{parts,
- 2}]))),
- <<":00:0:">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
- <<":0000:0">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[trim]))),
+ 2}]))),
+ <<":00:0:">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
+ <<":0000:0">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[trim]))),
<<":0000:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[{parts,
- 2}]))),
- <<":0000:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
- <<":0:0">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
+ 2}]))),
+ <<":0000:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
+ <<":0:0">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
<<":0:0:">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[{parts,
- 2}]))),
- <<":0:0:">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
- <<":0:0::0:0">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
+ 2}]))),
+ <<":0:0:">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
+ <<":0:0::0:0">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
<<":0:0:0">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[{parts,
- 2}]))),
- <<":0:0::0:0:">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
- <<":0:0::0:0::0:0::0:0">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
+ 2}]))),
+ <<":0:0::0:0:">> = iolist_to_binary(join(re:split("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
+ <<":0:0::0:0::0:0::0:0">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
<<":0:0:000">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[{parts,
- 2}]))),
- <<":0:0::0:0::0:0::0:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
+ 2}]))),
+ <<":0:0::0:0::0:0::0:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
ok.
run44() ->
- <<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[trim]))),
+ <<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[trim]))),
<<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[{parts,
- 2}]))),
- <<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[]))),
- <<":A:B:C:DEFG">> = iolist_to_binary(join(re:split("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)",[trim]))),
+ 2}]))),
+ <<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[]))),
+ <<":A:B:C:DEFG">> = iolist_to_binary(join(re:split("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)",[trim]))),
<<":A:B:C:DEFG">> = iolist_to_binary(join(re:split("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)",[{parts,
- 2}]))),
- <<":A:B:C:DEFG">> = iolist_to_binary(join(re:split("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(*COMMIT)(A|P)(B|P)(C|P)",[trim]))),
+ 2}]))),
+ <<":A:B:C:DEFG">> = iolist_to_binary(join(re:split("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(*COMMIT)(A|P)(B|P)(C|P)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(*COMMIT)(A|P)(B|P)(C|P)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(*COMMIT)(A|P)(B|P)(C|P)",[]))),
- <<"DEFGABC">> = iolist_to_binary(join(re:split("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(*COMMIT)(A|P)(B|P)(C|P)",[]))),
+ <<"DEFGABC">> = iolist_to_binary(join(re:split("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)",[trim]))),
<<"DEFGABC">> = iolist_to_binary(join(re:split("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)",[{parts,
- 2}]))),
- <<"DEFGABC">> = iolist_to_binary(join(re:split("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)",[]))),
- <<":a">> = iolist_to_binary(join(re:split("abbb","(\\w+)(?>b(*COMMIT))\\w{2}",[trim]))),
+ 2}]))),
+ <<"DEFGABC">> = iolist_to_binary(join(re:split("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("abbb","(\\w+)(?>b(*COMMIT))\\w{2}",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("abbb","(\\w+)(?>b(*COMMIT))\\w{2}",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("abbb","(\\w+)(?>b(*COMMIT))\\w{2}",[]))),
- <<"abbb">> = iolist_to_binary(join(re:split("abbb","(\\w+)b(*COMMIT)\\w{2}",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("abbb","(\\w+)(?>b(*COMMIT))\\w{2}",[]))),
+ <<"abbb">> = iolist_to_binary(join(re:split("abbb","(\\w+)b(*COMMIT)\\w{2}",[trim]))),
<<"abbb">> = iolist_to_binary(join(re:split("abbb","(\\w+)b(*COMMIT)\\w{2}",[{parts,
- 2}]))),
- <<"abbb">> = iolist_to_binary(join(re:split("abbb","(\\w+)b(*COMMIT)\\w{2}",[]))),
- <<"b::c">> = iolist_to_binary(join(re:split("bac","(?&t)(?#()(?(DEFINE)(?<t>a))",[trim]))),
+ 2}]))),
+ <<"abbb">> = iolist_to_binary(join(re:split("abbb","(\\w+)b(*COMMIT)\\w{2}",[]))),
+ <<"b::c">> = iolist_to_binary(join(re:split("bac","(?&t)(?#()(?(DEFINE)(?<t>a))",[trim]))),
<<"b::c">> = iolist_to_binary(join(re:split("bac","(?&t)(?#()(?(DEFINE)(?<t>a))",[{parts,
- 2}]))),
- <<"b::c">> = iolist_to_binary(join(re:split("bac","(?&t)(?#()(?(DEFINE)(?<t>a))",[]))),
- <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?",[trim]))),
+ 2}]))),
+ <<"b::c">> = iolist_to_binary(join(re:split("bac","(?&t)(?#()(?(DEFINE)(?<t>a))",[]))),
+ <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?",[trim]))),
<<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?",[{parts,
- 2}]))),
- <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?",[]))),
- <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[trim]))),
+ 2}]))),
+ <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?",[]))),
+ <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[trim]))),
<<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[{parts,
- 2}]))),
- <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[]))),
- <<"">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[trim]))),
+ 2}]))),
+ <<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[]))),
- <<"a">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[]))),
ok.
run45() ->
- <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[trim]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)b",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)b",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)b",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)b",[]))),
- <<"x::x::x">> = iolist_to_binary(join(re:split("xxx","(?P<abn>(?P=abn)xxx|)+",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)b",[]))),
+ <<"x::x::x">> = iolist_to_binary(join(re:split("xxx","(?P<abn>(?P=abn)xxx|)+",[trim]))),
<<"x::xx">> = iolist_to_binary(join(re:split("xxx","(?P<abn>(?P=abn)xxx|)+",[{parts,
- 2}]))),
- <<"x::x::x::">> = iolist_to_binary(join(re:split("xxx","(?P<abn>(?P=abn)xxx|)+",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aa","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<"x::x::x::">> = iolist_to_binary(join(re:split("xxx","(?P<abn>(?P=abn)xxx|)+",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aa","(?i:([^b]))(?1)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aa","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aa","(?i:([^b]))(?1)",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aA","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aa","(?i:([^b]))(?1)",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aA","(?i:([^b]))(?1)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aA","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aA","(?i:([^b]))(?1)",[]))),
- <<":*:: ::a::l::r">> = iolist_to_binary(join(re:split("** Failers","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aA","(?i:([^b]))(?1)",[]))),
+ <<":*:: ::a::l::r">> = iolist_to_binary(join(re:split("** Failers","(?i:([^b]))(?1)",[trim]))),
<<":*: Failers">> = iolist_to_binary(join(re:split("** Failers","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<":*:: ::a::l::r:">> = iolist_to_binary(join(re:split("** Failers","(?i:([^b]))(?1)",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<":*:: ::a::l::r:">> = iolist_to_binary(join(re:split("** Failers","(?i:([^b]))(?1)",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","(?i:([^b]))(?1)",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","(?i:([^b]))(?1)",[]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","(?i:([^b]))(?1)",[]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:([^b]))(?1)",[trim]))),
<<"aB">> = iolist_to_binary(join(re:split("aB","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:([^b]))(?1)",[]))),
- <<"Ba">> = iolist_to_binary(join(re:split("Ba","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<"aB">> = iolist_to_binary(join(re:split("aB","(?i:([^b]))(?1)",[]))),
+ <<"Ba">> = iolist_to_binary(join(re:split("Ba","(?i:([^b]))(?1)",[trim]))),
<<"Ba">> = iolist_to_binary(join(re:split("Ba","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<"Ba">> = iolist_to_binary(join(re:split("Ba","(?i:([^b]))(?1)",[]))),
- <<"ba">> = iolist_to_binary(join(re:split("ba","(?i:([^b]))(?1)",[trim]))),
+ 2}]))),
+ <<"Ba">> = iolist_to_binary(join(re:split("Ba","(?i:([^b]))(?1)",[]))),
+ <<"ba">> = iolist_to_binary(join(re:split("ba","(?i:([^b]))(?1)",[trim]))),
<<"ba">> = iolist_to_binary(join(re:split("ba","(?i:([^b]))(?1)",[{parts,
- 2}]))),
- <<"ba">> = iolist_to_binary(join(re:split("ba","(?i:([^b]))(?1)",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[trim]))),
+ 2}]))),
+ <<"ba">> = iolist_to_binary(join(re:split("ba","(?i:([^b]))(?1)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[trim]))),
<<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[{parts,
- 2}]))),
- <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[trim]))),
+ 2}]))),
+ <<"aaaaaa">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[]))),
- <<":a:X">> = iolist_to_binary(join(re:split("aaaaX","^(a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$",[]))),
+ <<":a:X">> = iolist_to_binary(join(re:split("aaaaX","^(a)*+(\\w)",[trim]))),
<<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a)*+(\\w)",[{parts,
- 2}]))),
- <<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a)*+(\\w)",[]))),
- <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a)*+(\\w)",[]))),
+ <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)*+(\\w)",[trim]))),
<<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)*+(\\w)",[{parts,
- 2}]))),
- <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)*+(\\w)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)*+(\\w)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)*+(\\w)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)*+(\\w)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)*+(\\w)",[]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)*+(\\w)",[]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)*+(\\w)",[trim]))),
<<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)*+(\\w)",[{parts,
- 2}]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)*+(\\w)",[]))),
- <<":X">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)*+(\\w)",[]))),
+ <<":X">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)*+(\\w)",[trim]))),
<<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)*+(\\w)",[{parts,
- 2}]))),
- <<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)*+(\\w)",[]))),
- <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)*+(\\w)",[]))),
+ <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)*+(\\w)",[trim]))),
<<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)*+(\\w)",[{parts,
- 2}]))),
- <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)*+(\\w)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)*+(\\w)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)*+(\\w)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)*+(\\w)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)*+(\\w)",[]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)*+(\\w)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)*+(\\w)",[]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)*+(\\w)",[trim]))),
<<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)*+(\\w)",[{parts,
- 2}]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)*+(\\w)",[]))),
- <<":a:X">> = iolist_to_binary(join(re:split("aaaaX","^(a)++(\\w)",[trim]))),
+ 2}]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)*+(\\w)",[]))),
+ <<":a:X">> = iolist_to_binary(join(re:split("aaaaX","^(a)++(\\w)",[trim]))),
<<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a)++(\\w)",[{parts,
- 2}]))),
- <<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a)++(\\w)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)++(\\w)",[trim]))),
+ 2}]))),
+ <<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a)++(\\w)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)++(\\w)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)++(\\w)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)++(\\w)",[]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)++(\\w)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a)++(\\w)",[]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)++(\\w)",[trim]))),
<<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)++(\\w)",[{parts,
- 2}]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)++(\\w)",[]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a)++(\\w)",[trim]))),
+ 2}]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(a)++(\\w)",[]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a)++(\\w)",[trim]))),
<<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a)++(\\w)",[{parts,
- 2}]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a)++(\\w)",[]))),
- <<":X">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)++(\\w)",[trim]))),
+ 2}]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a)++(\\w)",[]))),
+ <<":X">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)++(\\w)",[trim]))),
<<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)++(\\w)",[{parts,
- 2}]))),
- <<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)++(\\w)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)++(\\w)",[trim]))),
+ 2}]))),
+ <<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)++(\\w)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)++(\\w)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)++(\\w)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)++(\\w)",[]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)++(\\w)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a)++(\\w)",[]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)++(\\w)",[trim]))),
<<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)++(\\w)",[{parts,
- 2}]))),
- <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)++(\\w)",[]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a)++(\\w)",[trim]))),
+ 2}]))),
+ <<"aaaa">> = iolist_to_binary(join(re:split("aaaa","^(?:a)++(\\w)",[]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a)++(\\w)",[trim]))),
<<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a)++(\\w)",[{parts,
- 2}]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a)++(\\w)",[]))),
- <<":a:a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(a)?+(\\w)",[trim]))),
+ 2}]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a)++(\\w)",[]))),
+ <<":a:a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(a)?+(\\w)",[trim]))),
<<":a:a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(a)?+(\\w)",[{parts,
- 2}]))),
- <<":a:a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(a)?+(\\w)",[]))),
- <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)?+(\\w)",[trim]))),
+ 2}]))),
+ <<":a:a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(a)?+(\\w)",[]))),
+ <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)?+(\\w)",[trim]))),
<<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)?+(\\w)",[{parts,
- 2}]))),
- <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)?+(\\w)",[]))),
- <<":a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)?+(\\w)",[trim]))),
+ 2}]))),
+ <<"::Y:Z">> = iolist_to_binary(join(re:split("YZ","^(a)?+(\\w)",[]))),
+ <<":a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)?+(\\w)",[trim]))),
<<":a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)?+(\\w)",[{parts,
- 2}]))),
- <<":a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)?+(\\w)",[]))),
- <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)?+(\\w)",[trim]))),
+ 2}]))),
+ <<":a:aaX">> = iolist_to_binary(join(re:split("aaaaX","^(?:a)?+(\\w)",[]))),
+ <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)?+(\\w)",[trim]))),
<<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)?+(\\w)",[{parts,
- 2}]))),
- <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)?+(\\w)",[]))),
- <<":a:X">> = iolist_to_binary(join(re:split("aaaaX","^(a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<":Y:Z">> = iolist_to_binary(join(re:split("YZ","^(?:a)?+(\\w)",[]))),
+ <<":a:X">> = iolist_to_binary(join(re:split("aaaaX","^(a){2,}+(\\w)",[trim]))),
<<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a){2,}+(\\w)",[{parts,
- 2}]))),
- <<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a){2,}+(\\w)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<":a:X:">> = iolist_to_binary(join(re:split("aaaaX","^(a){2,}+(\\w)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a){2,}+(\\w)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a){2,}+(\\w)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a){2,}+(\\w)",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a){2,}+(\\w)",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a){2,}+(\\w)",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a){2,}+(\\w)",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a){2,}+(\\w)",[]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(a){2,}+(\\w)",[]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a){2,}+(\\w)",[trim]))),
<<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a){2,}+(\\w)",[{parts,
- 2}]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a){2,}+(\\w)",[]))),
- <<":X">> = iolist_to_binary(join(re:split("aaaaX","^(?:a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(a){2,}+(\\w)",[]))),
+ <<":X">> = iolist_to_binary(join(re:split("aaaaX","^(?:a){2,}+(\\w)",[trim]))),
<<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a){2,}+(\\w)",[{parts,
- 2}]))),
- <<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a){2,}+(\\w)",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<":X:">> = iolist_to_binary(join(re:split("aaaaX","^(?:a){2,}+(\\w)",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a){2,}+(\\w)",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a){2,}+(\\w)",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a){2,}+(\\w)",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(?:a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(?:a){2,}+(\\w)",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(?:a){2,}+(\\w)",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^(?:a){2,}+(\\w)",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(?:a){2,}+(\\w)",[]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a){2,}+(\\w)",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^(?:a){2,}+(\\w)",[]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a){2,}+(\\w)",[trim]))),
<<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a){2,}+(\\w)",[{parts,
- 2}]))),
- <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a){2,}+(\\w)",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","(a|)*(?1)b",[trim]))),
+ 2}]))),
+ <<"YZ">> = iolist_to_binary(join(re:split("YZ","^(?:a){2,}+(\\w)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","(a|)*(?1)b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","(a|)*(?1)b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","(a|)*(?1)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("ab","(a|)*(?1)b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","(a|)*(?1)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ab","(a|)*(?1)b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("ab","(a|)*(?1)b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ab","(a|)*(?1)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("aab","(a|)*(?1)b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ab","(a|)*(?1)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aab","(a|)*(?1)b",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aab","(a|)*(?1)b",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aab","(a|)*(?1)b",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)++(?1)b",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aab","(a|)*(?1)b",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)++(?1)b",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)++(?1)b",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)++(?1)b",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","(a)++(?1)b",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)++(?1)b",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","(a)++(?1)b",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","(a)++(?1)b",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","(a)++(?1)b",[]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","(a)++(?1)b",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","(a)++(?1)b",[]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","(a)++(?1)b",[trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","(a)++(?1)b",[{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","(a)++(?1)b",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)*+(?1)b",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","(a)++(?1)b",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)*+(?1)b",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)*+(?1)b",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)*+(?1)b",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","(a)*+(?1)b",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(a)*+(?1)b",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","(a)*+(?1)b",[trim]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","(a)*+(?1)b",[{parts,
- 2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","(a)*+(?1)b",[]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","(a)*+(?1)b",[trim]))),
+ 2}]))),
+ <<"ab">> = iolist_to_binary(join(re:split("ab","(a)*+(?1)b",[]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","(a)*+(?1)b",[trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","(a)*+(?1)b",[{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","(a)*+(?1)b",[]))),
- <<"">> = iolist_to_binary(join(re:split("b","(?1)(?:(b)){0}",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","(a)*+(?1)b",[]))),
+ <<"">> = iolist_to_binary(join(re:split("b","(?1)(?:(b)){0}",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("b","(?1)(?:(b)){0}",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("b","(?1)(?:(b)){0}",[]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("b","(?1)(?:(b)){0}",[]))),
<<":foo(bar(baz)+baz(bop)):(bar(baz)+baz(bop)):bar(baz)+baz(bop)">> = iolist_to_binary(join(re:split("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )",[extended,
- trim]))),
+ trim]))),
<<":foo(bar(baz)+baz(bop)):(bar(baz)+baz(bop)):bar(baz)+baz(bop):">> = iolist_to_binary(join(re:split("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )",[extended,
{parts,
- 2}]))),
- <<":foo(bar(baz)+baz(bop)):(bar(baz)+baz(bop)):bar(baz)+baz(bop):">> = iolist_to_binary(join(re:split("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )",[extended]))),
+ 2}]))),
+ <<":foo(bar(baz)+baz(bop)):(bar(baz)+baz(bop)):bar(baz)+baz(bop):">> = iolist_to_binary(join(re:split("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )",[extended]))),
<<":AB:B">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
- trim]))),
+ trim]))),
<<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
- 2}]))),
- <<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ 2}]))),
+ <<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
ok.
run46() ->
- <<":a">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[trim]))),
+ <<":a">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[]))),
- <<"">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)++",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)++",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)++",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)++",[]))),
- <<":a">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)++",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)++",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)++",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)++",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)++",[]))),
- <<"">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc|d)",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)++",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc|d)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc|d)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc|d)",[]))),
- <<":b:eetle">> = iolist_to_binary(join(re:split("beetle","(?:(b))++",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc|d)",[]))),
+ <<":b:eetle">> = iolist_to_binary(join(re:split("beetle","(?:(b))++",[trim]))),
<<":b:eetle">> = iolist_to_binary(join(re:split("beetle","(?:(b))++",[{parts,
- 2}]))),
- <<":b:eetle">> = iolist_to_binary(join(re:split("beetle","(?:(b))++",[]))),
- <<":a">> = iolist_to_binary(join(re:split("a","(?(?=(a(*ACCEPT)z))a)",[trim]))),
+ 2}]))),
+ <<":b:eetle">> = iolist_to_binary(join(re:split("beetle","(?:(b))++",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("a","(?(?=(a(*ACCEPT)z))a)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("a","(?(?=(a(*ACCEPT)z))a)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("a","(?(?=(a(*ACCEPT)z))a)",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)+ab",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("a","(?(?=(a(*ACCEPT)z))a)",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)+ab",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)+ab",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)+ab",[]))),
- <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)++ab",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)+ab",[]))),
+ <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)++ab",[trim]))),
<<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)++ab",[{parts,
- 2}]))),
- <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)++ab",[]))),
- <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","(?(DEFINE)(a))?b(?1)",[trim]))),
+ 2}]))),
+ <<"aaaab">> = iolist_to_binary(join(re:split("aaaab","^(a)(?1)++ab",[]))),
+ <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","(?(DEFINE)(a))?b(?1)",[trim]))),
<<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","(?(DEFINE)(a))?b(?1)",[{parts,
- 2}]))),
- <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","(?(DEFINE)(a))?b(?1)",[]))),
+ 2}]))),
+ <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","(?(DEFINE)(a))?b(?1)",[]))),
<<":
def">> = iolist_to_binary(join(re:split("abc
-def","^\\N+",[trim]))),
+def","^\\N+",[trim]))),
<<":
def">> = iolist_to_binary(join(re:split("abc
-def","^\\N+",[{parts,2}]))),
+def","^\\N+",[{parts,2}]))),
<<":
def">> = iolist_to_binary(join(re:split("abc
-def","^\\N+",[]))),
+def","^\\N+",[]))),
<<":
def">> = iolist_to_binary(join(re:split("abc
-def","^\\N{1,}",[trim]))),
+def","^\\N{1,}",[trim]))),
<<":
def">> = iolist_to_binary(join(re:split("abc
-def","^\\N{1,}",[{parts,2}]))),
+def","^\\N{1,}",[{parts,2}]))),
<<":
def">> = iolist_to_binary(join(re:split("abc
-def","^\\N{1,}",[]))),
- <<":cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|(?R)b)",[trim]))),
+def","^\\N{1,}",[]))),
+ <<":cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|(?R)b)",[trim]))),
<<":cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|(?R)b)",[{parts,
- 2}]))),
- <<":cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|(?R)b)",[]))),
- <<":aaaa:cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|((?R))b)",[trim]))),
+ 2}]))),
+ <<":cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|(?R)b)",[]))),
+ <<":aaaa:cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|((?R))b)",[trim]))),
<<":aaaa:cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|((?R))b)",[{parts,
- 2}]))),
- <<":aaaa:cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|((?R))b)",[]))),
- <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R)a+|(?1)b))",[trim]))),
+ 2}]))),
+ <<":aaaa:cde">> = iolist_to_binary(join(re:split("aaaabcde","(?(R)a+|((?R))b)",[]))),
+ <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R)a+|(?1)b))",[trim]))),
<<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R)a+|(?1)b))",[{parts,
- 2}]))),
- <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R)a+|(?1)b))",[]))),
- <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[trim]))),
+ 2}]))),
+ <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R)a+|(?1)b))",[]))),
+ <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[trim]))),
<<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[{parts,
- 2}]))),
- <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[trim]))),
+ 2}]))),
+ <<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[]))),
- <<":a">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[]))),
- <<"">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
- <<"b">> = iolist_to_binary(join(re:split("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
+ <<"b">> = iolist_to_binary(join(re:split("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
<<"b::">> = iolist_to_binary(join(re:split("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[{parts,
- 2}]))),
- <<"b::">> = iolist_to_binary(join(re:split("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
- <<"bb">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
+ 2}]))),
+ <<"b::">> = iolist_to_binary(join(re:split("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
+ <<"bb">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
<<"bb::">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[{parts,
- 2}]))),
- <<"bb::">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
+ 2}]))),
+ <<"bb::">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
ok.
run47() ->
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended]))),
<<":ab">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F)) c",[extended,
- trim]))),
+ trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F)) c",[extended,
{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F)) c",[extended]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F)) c",[extended]))),
<<":ab:ab">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) | (*F) ) c",[extended,
- trim]))),
+ trim]))),
<<":ab:ab:">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) | (*F) ) c",[extended,
{parts,
- 2}]))),
- <<":ab:ab:">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) | (*F) ) c",[extended]))),
+ 2}]))),
+ <<":ab:ab:">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) | (*F) ) c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) ) c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) ) c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) ) c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b) ) c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b) c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b) c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b) c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b) c",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F)) c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F)) c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F)) c",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F)) c",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) ) c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) ) c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) ) c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b) ) c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b) c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b) c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b) c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b) c",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b|(*F)) c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b|(*F)) c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b|(*F)) c",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?>a(*THEN)b|(*F)) c",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) ) c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) ) c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) ) c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?> (?>a(*THEN)b) ) c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b)++ c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b)++ c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b)++ c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b)++ c",[extended]))),
<<":ab">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F))++ c",[extended,
- trim]))),
+ trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F))++ c",[extended,
{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F))++ c",[extended]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F))++ c",[extended]))),
<<":ab:ab">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c",[extended,
- trim]))),
+ trim]))),
<<":ab:ab:">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c",[extended,
{parts,
- 2}]))),
- <<":ab:ab:">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c",[extended]))),
+ 2}]))),
+ <<":ab:ab:">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ )++ c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ )++ c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ )++ c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ )++ c",[extended]))),
ok.
run48() ->
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F))++ c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F))++ c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F))++ c",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F))++ c",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c",[extended]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c",[extended,
- trim]))),
+ trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c",[extended,
{parts,
- 2}]))),
- <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c",[extended]))),
- <<"">> = iolist_to_binary(join(re:split("ac","^(?(?=a(*THEN)b)ab|ac)",[trim]))),
+ 2}]))),
+ <<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c",[extended]))),
+ <<"">> = iolist_to_binary(join(re:split("ac","^(?(?=a(*THEN)b)ab|ac)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ac","^(?(?=a(*THEN)b)ab|ac)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ac","^(?(?=a(*THEN)b)ab|ac)",[]))),
- <<"ba">> = iolist_to_binary(join(re:split("ba","^.*?(?(?=a)a|b(*THEN)c)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ac","^(?(?=a(*THEN)b)ab|ac)",[]))),
+ <<"ba">> = iolist_to_binary(join(re:split("ba","^.*?(?(?=a)a|b(*THEN)c)",[trim]))),
<<"ba">> = iolist_to_binary(join(re:split("ba","^.*?(?(?=a)a|b(*THEN)c)",[{parts,
- 2}]))),
- <<"ba">> = iolist_to_binary(join(re:split("ba","^.*?(?(?=a)a|b(*THEN)c)",[]))),
- <<"">> = iolist_to_binary(join(re:split("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)",[trim]))),
+ 2}]))),
+ <<"ba">> = iolist_to_binary(join(re:split("ba","^.*?(?(?=a)a|b(*THEN)c)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)",[]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^.*?(?(?=a)a(*THEN)b|c)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)",[]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^.*?(?(?=a)a(*THEN)b|c)",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","^.*?(?(?=a)a(*THEN)b|c)",[{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^.*?(?(?=a)a(*THEN)b|c)",[]))),
- <<":abc">> = iolist_to_binary(join(re:split("aabc","^.*(?=a(*THEN)b)",[trim]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^.*?(?(?=a)a(*THEN)b|c)",[]))),
+ <<":abc">> = iolist_to_binary(join(re:split("aabc","^.*(?=a(*THEN)b)",[trim]))),
<<":abc">> = iolist_to_binary(join(re:split("aabc","^.*(?=a(*THEN)b)",[{parts,
- 2}]))),
- <<":abc">> = iolist_to_binary(join(re:split("aabc","^.*(?=a(*THEN)b)",[]))),
- <<"xa:d">> = iolist_to_binary(join(re:split("xacd","(?<=a(*ACCEPT)b)c",[trim]))),
+ 2}]))),
+ <<":abc">> = iolist_to_binary(join(re:split("aabc","^.*(?=a(*THEN)b)",[]))),
+ <<"xa:d">> = iolist_to_binary(join(re:split("xacd","(?<=a(*ACCEPT)b)c",[trim]))),
<<"xa:d">> = iolist_to_binary(join(re:split("xacd","(?<=a(*ACCEPT)b)c",[{parts,
- 2}]))),
- <<"xa:d">> = iolist_to_binary(join(re:split("xacd","(?<=a(*ACCEPT)b)c",[]))),
- <<"xa:a:d">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*ACCEPT)b))c",[trim]))),
+ 2}]))),
+ <<"xa:d">> = iolist_to_binary(join(re:split("xacd","(?<=a(*ACCEPT)b)c",[]))),
+ <<"xa:a:d">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*ACCEPT)b))c",[trim]))),
<<"xa:a:d">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*ACCEPT)b))c",[{parts,
- 2}]))),
- <<"xa:a:d">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*ACCEPT)b))c",[]))),
- <<"xab:ab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=(a(*COMMIT)b))c",[trim]))),
+ 2}]))),
+ <<"xa:a:d">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*ACCEPT)b))c",[]))),
+ <<"xab:ab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=(a(*COMMIT)b))c",[trim]))),
<<"xab:ab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=(a(*COMMIT)b))c",[{parts,
- 2}]))),
- <<"xab:ab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=(a(*COMMIT)b))c",[]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=(a(*COMMIT)b))c",[trim]))),
+ 2}]))),
+ <<"xab:ab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=(a(*COMMIT)b))c",[]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=(a(*COMMIT)b))c",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=(a(*COMMIT)b))c",[{parts,
- 2}]))),
- <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=(a(*COMMIT)b))c",[]))),
- <<"xacd">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*COMMIT)b))c",[trim]))),
+ 2}]))),
+ <<"** Failers">> = iolist_to_binary(join(re:split("** Failers","(?<=(a(*COMMIT)b))c",[]))),
+ <<"xacd">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*COMMIT)b))c",[trim]))),
<<"xacd">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*COMMIT)b))c",[{parts,
- 2}]))),
- <<"xacd">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*COMMIT)b))c",[]))),
- <<"x:d">> = iolist_to_binary(join(re:split("xcd","(?<!a(*FAIL)b)c",[trim]))),
+ 2}]))),
+ <<"xacd">> = iolist_to_binary(join(re:split("xacd","(?<=(a(*COMMIT)b))c",[]))),
+ <<"x:d">> = iolist_to_binary(join(re:split("xcd","(?<!a(*FAIL)b)c",[trim]))),
<<"x:d">> = iolist_to_binary(join(re:split("xcd","(?<!a(*FAIL)b)c",[{parts,
- 2}]))),
- <<"x:d">> = iolist_to_binary(join(re:split("xcd","(?<!a(*FAIL)b)c",[]))),
- <<"a:d">> = iolist_to_binary(join(re:split("acd","(?<!a(*FAIL)b)c",[trim]))),
+ 2}]))),
+ <<"x:d">> = iolist_to_binary(join(re:split("xcd","(?<!a(*FAIL)b)c",[]))),
+ <<"a:d">> = iolist_to_binary(join(re:split("acd","(?<!a(*FAIL)b)c",[trim]))),
<<"a:d">> = iolist_to_binary(join(re:split("acd","(?<!a(*FAIL)b)c",[{parts,
- 2}]))),
- <<"a:d">> = iolist_to_binary(join(re:split("acd","(?<!a(*FAIL)b)c",[]))),
- <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*PRUNE)b)c",[trim]))),
+ 2}]))),
+ <<"a:d">> = iolist_to_binary(join(re:split("acd","(?<!a(*FAIL)b)c",[]))),
+ <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*PRUNE)b)c",[trim]))),
<<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*PRUNE)b)c",[{parts,
- 2}]))),
- <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*PRUNE)b)c",[]))),
- <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*SKIP)b)c",[trim]))),
+ 2}]))),
+ <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*PRUNE)b)c",[]))),
+ <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*SKIP)b)c",[trim]))),
<<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*SKIP)b)c",[{parts,
- 2}]))),
- <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*SKIP)b)c",[]))),
- <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[trim]))),
+ 2}]))),
+ <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*SKIP)b)c",[]))),
+ <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[trim]))),
<<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[{parts,
- 2}]))),
- <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[]))),
+ 2}]))),
+ <<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[]))),
ok.
run49() ->
- <<":a:d">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[trim]))),
+ <<":a:d">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[trim]))),
<<":a:d:">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[{parts,
- 2}]))),
- <<":a:d:">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[]))),
- <<"hello world ">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[trim]))),
+ 2}]))),
+ <<":a:d:">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[]))),
+ <<"hello world ">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[trim]))),
<<"hello world :::">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[{parts,
- 2}]))),
- <<"hello world :::">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[]))),
- <<"hello world test">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1+)test",[trim]))),
+ 2}]))),
+ <<"hello world :::">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[]))),
+ <<"hello world test">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1+)test",[trim]))),
<<"hello world test">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1+)test",[{parts,
- 2}]))),
- <<"hello world test">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1+)test",[]))),
- <<"">> = iolist_to_binary(join(re:split("aac","(a(*COMMIT)b){0}a(?1)|aac",[trim]))),
+ 2}]))),
+ <<"hello world test">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1+)test",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aac","(a(*COMMIT)b){0}a(?1)|aac",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aac","(a(*COMMIT)b){0}a(?1)|aac",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aac","(a(*COMMIT)b){0}a(?1)|aac",[]))),
- <<"">> = iolist_to_binary(join(re:split("aac","((?:a?)*)*c",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aac","(a(*COMMIT)b){0}a(?1)|aac",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aac","((?:a?)*)*c",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aac","((?:a?)*)*c",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aac","((?:a?)*)*c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aac","((?>a?)*)*c",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aac","((?:a?)*)*c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aac","((?>a?)*)*c",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aac","((?>a?)*)*c",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("aac","((?>a?)*)*c",[]))),
- <<"a">> = iolist_to_binary(join(re:split("aba","(?>.*?a)(?<=ba)",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("aac","((?>a?)*)*c",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("aba","(?>.*?a)(?<=ba)",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aba","(?>.*?a)(?<=ba)",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aba","(?>.*?a)(?<=ba)",[]))),
- <<"">> = iolist_to_binary(join(re:split("aba","(?:.*?a)(?<=ba)",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aba","(?>.*?a)(?<=ba)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aba","(?:.*?a)(?<=ba)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aba","(?:.*?a)(?<=ba)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aba","(?:.*?a)(?<=ba)",[]))),
- <<"a">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aba","(?:.*?a)(?<=ba)",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[]))),
<<"a">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[dotall,
- trim]))),
+ trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[dotall,
{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[dotall]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*PRUNE)b",[dotall]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","^a(*PRUNE)b",[dotall,
- trim]))),
+ trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","^a(*PRUNE)b",[dotall,
{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","^a(*PRUNE)b",[dotall]))),
- <<"a">> = iolist_to_binary(join(re:split("aab",".*?a(*SKIP)b",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","^a(*PRUNE)b",[dotall]))),
+ <<"a">> = iolist_to_binary(join(re:split("aab",".*?a(*SKIP)b",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*SKIP)b",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*SKIP)b",[]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aab",".*?a(*SKIP)b",[]))),
<<"a">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[dotall,
- trim]))),
+ trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[dotall,
{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[dotall]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[dotall]))),
ok.
run50() ->
- <<"a">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[trim]))),
+ <<"a">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","(?>^a)b",[dotall,
- trim]))),
+ trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","(?>^a)b",[dotall,
{parts,
- 2}]))),
- <<"aab">> = iolist_to_binary(join(re:split("aab","(?>^a)b",[dotall]))),
- <<"alphabetabcd:abcd">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))",[trim]))),
+ 2}]))),
+ <<"aab">> = iolist_to_binary(join(re:split("aab","(?>^a)b",[dotall]))),
+ <<"alphabetabcd:abcd">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))",[trim]))),
<<"alphabetabcd:abcd::">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))",[{parts,
- 2}]))),
- <<"alphabetabcd:abcd::">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))",[]))),
- <<"endingwxyz::wxyz">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))",[trim]))),
+ 2}]))),
+ <<"alphabetabcd:abcd::">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))",[]))),
+ <<"endingwxyz::wxyz">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))",[trim]))),
<<"endingwxyz::wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))",[{parts,
- 2}]))),
- <<"endingwxyz::wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))",[]))),
- <<":abcd">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))",[trim]))),
+ 2}]))),
+ <<"endingwxyz::wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))",[]))),
+ <<":abcd">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))",[trim]))),
<<":abcd::">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))",[{parts,
- 2}]))),
- <<":abcd::">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))",[]))),
- <<"::wxyz">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))",[trim]))),
+ 2}]))),
+ <<":abcd::">> = iolist_to_binary(join(re:split("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))",[]))),
+ <<"::wxyz">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))",[trim]))),
<<"::wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))",[{parts,
- 2}]))),
- <<"::wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))",[]))),
- <<"abcdfooxyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*)foo",[trim]))),
+ 2}]))),
+ <<"::wxyz:">> = iolist_to_binary(join(re:split("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))",[]))),
+ <<"abcdfooxyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*)foo",[trim]))),
<<"abcdfooxyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*)foo",[{parts,
- 2}]))),
- <<"abcdfooxyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*)foo",[]))),
- <<"abcd:xyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*?)foo",[trim]))),
+ 2}]))),
+ <<"abcdfooxyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*)foo",[]))),
+ <<"abcd:xyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*?)foo",[trim]))),
<<"abcd:xyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*?)foo",[{parts,
- 2}]))),
- <<"abcd:xyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*?)foo",[]))),
- <<"">> = iolist_to_binary(join(re:split("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)",[trim]))),
+ 2}]))),
+ <<"abcd:xyz">> = iolist_to_binary(join(re:split("abcdfooxyz","(?>.*?)foo",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)",[]))),
- <<"">> = iolist_to_binary(join(re:split("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)",[{parts,
- 2}]))),
- <<"::">> = iolist_to_binary(join(re:split("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","(?<=(*SKIP)ac)a",[trim]))),
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","(?<=(*SKIP)ac)a",[trim]))),
<<"aa">> = iolist_to_binary(join(re:split("aa","(?<=(*SKIP)ac)a",[{parts,
- 2}]))),
- <<"aa">> = iolist_to_binary(join(re:split("aa","(?<=(*SKIP)ac)a",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aa","(?<=(*SKIP)ac)a",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)b|a+c",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)b|a+c",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c",[]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c",[]))),
ok.
run51() ->
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)b|a+c",[trim]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)b|a+c",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)b|a+c",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)b|a+c",[]))),
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)b|a+c",[]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c",[]))),
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c",[]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c",[]))),
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c",[]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c",[]))),
- <<"aaaaaac">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c",[]))),
+ <<"aaaaaac">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)b|a+c",[trim]))),
<<"aaaaaac">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)b|a+c",[{parts,
- 2}]))),
- <<"aaaaaac">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)b|a+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaaaaac">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)b|a+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)b|a+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)b|a+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)b|a+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*THEN)b|a+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c",[]))),
ok.
run52() ->
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+",[trim]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+",[]))),
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+",[]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+",[]))),
- <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+",[]))),
+ <<"aaaaa">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[trim]))),
<<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[{parts,
- 2}]))),
- <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaaaa:">> = iolist_to_binary(join(re:split("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c",[trim]))),
<<"aaa:">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c",[{parts,
- 2}]))),
- <<"aaa:">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c",[]))),
- <<"aa">> = iolist_to_binary(join(re:split("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c",[trim]))),
+ 2}]))),
+ <<"aaa:">> = iolist_to_binary(join(re:split("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c",[]))),
+ <<"aa">> = iolist_to_binary(join(re:split("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c",[trim]))),
<<"aa:">> = iolist_to_binary(join(re:split("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c",[{parts,
- 2}]))),
- <<"aa:">> = iolist_to_binary(join(re:split("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c",[trim]))),
+ 2}]))),
+ <<"aa:">> = iolist_to_binary(join(re:split("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c",[trim]))),
<<"aaa:">> = iolist_to_binary(join(re:split("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c",[{parts,
- 2}]))),
- <<"aaa:">> = iolist_to_binary(join(re:split("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c",[]))),
- <<":a">> = iolist_to_binary(join(re:split("ba",".?(a|b(*THEN)c)",[trim]))),
+ 2}]))),
+ <<"aaa:">> = iolist_to_binary(join(re:split("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("ba",".?(a|b(*THEN)c)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ba",".?(a|b(*THEN)c)",[{parts,
- 2}]))),
- <<":a:">> = iolist_to_binary(join(re:split("ba",".?(a|b(*THEN)c)",[]))),
- <<":ab">> = iolist_to_binary(join(re:split("abc","(a(*COMMIT)b)c|abd",[trim]))),
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("ba",".?(a|b(*THEN)c)",[]))),
+ <<":ab">> = iolist_to_binary(join(re:split("abc","(a(*COMMIT)b)c|abd",[trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("abc","(a(*COMMIT)b)c|abd",[{parts,
- 2}]))),
- <<":ab:">> = iolist_to_binary(join(re:split("abc","(a(*COMMIT)b)c|abd",[]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","(a(*COMMIT)b)c|abd",[trim]))),
+ 2}]))),
+ <<":ab:">> = iolist_to_binary(join(re:split("abc","(a(*COMMIT)b)c|abd",[]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","(a(*COMMIT)b)c|abd",[trim]))),
<<"abd">> = iolist_to_binary(join(re:split("abd","(a(*COMMIT)b)c|abd",[{parts,
- 2}]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","(a(*COMMIT)b)c|abd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","(?=a(*COMMIT)b)abc|abd",[trim]))),
+ 2}]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","(a(*COMMIT)b)c|abd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","(?=a(*COMMIT)b)abc|abd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","(?=a(*COMMIT)b)abc|abd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","(?=a(*COMMIT)b)abc|abd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abd","(?=a(*COMMIT)b)abc|abd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","(?=a(*COMMIT)b)abc|abd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abd","(?=a(*COMMIT)b)abc|abd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abd","(?=a(*COMMIT)b)abc|abd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abd","(?=a(*COMMIT)b)abc|abd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abc","(?>a(*COMMIT)b)c|abd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abd","(?=a(*COMMIT)b)abc|abd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abc","(?>a(*COMMIT)b)c|abd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc","(?>a(*COMMIT)b)c|abd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abc","(?>a(*COMMIT)b)c|abd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abc","(?>a(*COMMIT)b)c|abd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","a(?=b(*COMMIT)c)[^d]|abd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","a(?=b(*COMMIT)c)[^d]|abd",[trim]))),
<<"abd">> = iolist_to_binary(join(re:split("abd","a(?=b(*COMMIT)c)[^d]|abd",[{parts,
- 2}]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","a(?=b(*COMMIT)c)[^d]|abd",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","a(?=b(*COMMIT)c)[^d]|abd",[trim]))),
+ 2}]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","a(?=b(*COMMIT)c)[^d]|abd",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","a(?=b(*COMMIT)c)[^d]|abd",[trim]))),
<<":c">> = iolist_to_binary(join(re:split("abc","a(?=b(*COMMIT)c)[^d]|abd",[{parts,
- 2}]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","a(?=b(*COMMIT)c)[^d]|abd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abd","a(?=bc).|abd",[trim]))),
+ 2}]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","a(?=b(*COMMIT)c)[^d]|abd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abd","a(?=bc).|abd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abd","a(?=bc).|abd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abd","a(?=bc).|abd",[]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","a(?=bc).|abd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abd","a(?=bc).|abd",[]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","a(?=bc).|abd",[trim]))),
<<":c">> = iolist_to_binary(join(re:split("abc","a(?=bc).|abd",[{parts,
- 2}]))),
- <<":c">> = iolist_to_binary(join(re:split("abc","a(?=bc).|abd",[]))),
- <<"abceabd">> = iolist_to_binary(join(re:split("abceabd","a(?>b(*COMMIT)c)d|abd",[trim]))),
+ 2}]))),
+ <<":c">> = iolist_to_binary(join(re:split("abc","a(?=bc).|abd",[]))),
+ <<"abceabd">> = iolist_to_binary(join(re:split("abceabd","a(?>b(*COMMIT)c)d|abd",[trim]))),
<<"abceabd">> = iolist_to_binary(join(re:split("abceabd","a(?>b(*COMMIT)c)d|abd",[{parts,
- 2}]))),
- <<"abceabd">> = iolist_to_binary(join(re:split("abceabd","a(?>b(*COMMIT)c)d|abd",[]))),
- <<"abce">> = iolist_to_binary(join(re:split("abceabd","a(?>bc)d|abd",[trim]))),
+ 2}]))),
+ <<"abceabd">> = iolist_to_binary(join(re:split("abceabd","a(?>b(*COMMIT)c)d|abd",[]))),
+ <<"abce">> = iolist_to_binary(join(re:split("abceabd","a(?>bc)d|abd",[trim]))),
<<"abce:">> = iolist_to_binary(join(re:split("abceabd","a(?>bc)d|abd",[{parts,
- 2}]))),
- <<"abce:">> = iolist_to_binary(join(re:split("abceabd","a(?>bc)d|abd",[]))),
- <<"">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[trim]))),
+ 2}]))),
+ <<"abce:">> = iolist_to_binary(join(re:split("abceabd","a(?>bc)d|abd",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)c)d|abd",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)b)c|abd",[]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)c)d|abd",[trim]))),
<<"abd">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)c)d|abd",[{parts,
- 2}]))),
- <<"abd">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)c)d|abd",[]))),
- <<"::c">> = iolist_to_binary(join(re:split("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))",[trim]))),
+ 2}]))),
+ <<"abd">> = iolist_to_binary(join(re:split("abd","(?>a(*COMMIT)c)d|abd",[]))),
+ <<"::c">> = iolist_to_binary(join(re:split("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))",[trim]))),
<<"::c:">> = iolist_to_binary(join(re:split("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))",[{parts,
- 2}]))),
- <<"::c:">> = iolist_to_binary(join(re:split("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))",[]))),
+ 2}]))),
+ <<"::c:">> = iolist_to_binary(join(re:split("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))",[]))),
ok.
run53() ->
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[trim]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(a)?(?(1)a|b)+$",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^(a)?(?(1)a|b)+$",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(a)?(?(1)a|b)+$",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","^(a)?(?(1)a|b)+$",[{parts,
- 2}]))),
- <<"a">> = iolist_to_binary(join(re:split("a","^(a)?(?(1)a|b)+$",[]))),
- <<"a">> = iolist_to_binary(join(re:split("ab","(?=a\\Kb)ab",[trim]))),
+ 2}]))),
+ <<"a">> = iolist_to_binary(join(re:split("a","^(a)?(?(1)a|b)+$",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("ab","(?=a\\Kb)ab",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("ab","(?=a\\Kb)ab",[{parts,
- 2}]))),
- <<"a:">> = iolist_to_binary(join(re:split("ab","(?=a\\Kb)ab",[]))),
- <<"">> = iolist_to_binary(join(re:split("ac","(?!a\\Kb)ac",[trim]))),
+ 2}]))),
+ <<"a:">> = iolist_to_binary(join(re:split("ab","(?=a\\Kb)ab",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ac","(?!a\\Kb)ac",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ac","(?!a\\Kb)ac",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ac","(?!a\\Kb)ac",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("abcd","^abc(?<=b\\Kc)d",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ac","(?!a\\Kb)ac",[]))),
+ <<"ab">> = iolist_to_binary(join(re:split("abcd","^abc(?<=b\\Kc)d",[trim]))),
<<"ab:">> = iolist_to_binary(join(re:split("abcd","^abc(?<=b\\Kc)d",[{parts,
- 2}]))),
- <<"ab:">> = iolist_to_binary(join(re:split("abcd","^abc(?<=b\\Kc)d",[]))),
- <<"">> = iolist_to_binary(join(re:split("abcd","^abc(?<!b\\Kq)d",[trim]))),
+ 2}]))),
+ <<"ab:">> = iolist_to_binary(join(re:split("abcd","^abc(?<=b\\Kc)d",[]))),
+ <<"">> = iolist_to_binary(join(re:split("abcd","^abc(?<!b\\Kq)d",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abcd","^abc(?<!b\\Kq)d",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("abcd","^abc(?<!b\\Kq)d",[]))),
- <<":abcd">> = iolist_to_binary(join(re:split("abcd","^((abc|abcx)(*THEN)y|abcd)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("abcd","^abc(?<!b\\Kq)d",[]))),
+ <<":abcd">> = iolist_to_binary(join(re:split("abcd","^((abc|abcx)(*THEN)y|abcd)",[trim]))),
<<":abcd::">> = iolist_to_binary(join(re:split("abcd","^((abc|abcx)(*THEN)y|abcd)",[{parts,
- 2}]))),
- <<":abcd::">> = iolist_to_binary(join(re:split("abcd","^((abc|abcx)(*THEN)y|abcd)",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((abc|abcx)(*THEN)y|abcd)",[trim]))),
+ 2}]))),
+ <<":abcd::">> = iolist_to_binary(join(re:split("abcd","^((abc|abcx)(*THEN)y|abcd)",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((abc|abcx)(*THEN)y|abcd)",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((abc|abcx)(*THEN)y|abcd)",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((abc|abcx)(*THEN)y|abcd)",[]))),
- <<"abcxy">> = iolist_to_binary(join(re:split("abcxy","^((abc|abcx)(*THEN)y|abcd)",[trim]))),
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^((abc|abcx)(*THEN)y|abcd)",[]))),
+ <<"abcxy">> = iolist_to_binary(join(re:split("abcxy","^((abc|abcx)(*THEN)y|abcd)",[trim]))),
<<"abcxy">> = iolist_to_binary(join(re:split("abcxy","^((abc|abcx)(*THEN)y|abcd)",[{parts,
- 2}]))),
- <<"abcxy">> = iolist_to_binary(join(re:split("abcxy","^((abc|abcx)(*THEN)y|abcd)",[]))),
- <<"yes">> = iolist_to_binary(join(re:split("yes","^((yes|no)(*THEN)(*F))?",[trim]))),
+ 2}]))),
+ <<"abcxy">> = iolist_to_binary(join(re:split("abcxy","^((abc|abcx)(*THEN)y|abcd)",[]))),
+ <<"yes">> = iolist_to_binary(join(re:split("yes","^((yes|no)(*THEN)(*F))?",[trim]))),
<<"yes">> = iolist_to_binary(join(re:split("yes","^((yes|no)(*THEN)(*F))?",[{parts,
- 2}]))),
- <<"yes">> = iolist_to_binary(join(re:split("yes","^((yes|no)(*THEN)(*F))?",[]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|ac)ac|ac",[trim]))),
+ 2}]))),
+ <<"yes">> = iolist_to_binary(join(re:split("yes","^((yes|no)(*THEN)(*F))?",[]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|ac)ac|ac",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|ac)ac|ac",[{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|ac)ac|ac",[]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|ac)ac|ac",[]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c",[extended,
- trim]))),
+ trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c",[extended,
{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c",[extended]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*THEN)a)bn|bnn)",[trim]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c",[extended]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*THEN)a)bn|bnn)",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*THEN)a)bn|bnn)",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*THEN)a)bn|bnn)",[]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*SKIP)a)bn|bnn",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*THEN)a)bn|bnn)",[]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*SKIP)a)bn|bnn",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*SKIP)a)bn|bnn",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*SKIP)a)bn|bnn",[]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*SKIP)a)bn|bnn)",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*SKIP)a)bn|bnn",[]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*SKIP)a)bn|bnn)",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*SKIP)a)bn|bnn)",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*SKIP)a)bn|bnn)",[]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*PRUNE)a)bn|bnn",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*SKIP)a)bn|bnn)",[]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*PRUNE)a)bn|bnn",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*PRUNE)a)bn|bnn",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*PRUNE)a)bn|bnn",[]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*PRUNE)a)bn|bnn)",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*PRUNE)a)bn|bnn",[]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*PRUNE)a)bn|bnn)",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*PRUNE)a)bn|bnn)",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*PRUNE)a)bn|bnn)",[]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*COMMIT)a)bn|bnn",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*PRUNE)a)bn|bnn)",[]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*COMMIT)a)bn|bnn",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*COMMIT)a)bn|bnn",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*COMMIT)a)bn|bnn",[]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*COMMIT)a)bn|bnn)",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?!b(*COMMIT)a)bn|bnn",[]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*COMMIT)a)bn|bnn)",[trim]))),
<<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*COMMIT)a)bn|bnn)",[{parts,
- 2}]))),
- <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*COMMIT)a)bn|bnn)",[]))),
- <<"bnn">> = iolist_to_binary(join(re:split("bnn","(?=b(*SKIP)a)bn|bnn",[trim]))),
+ 2}]))),
+ <<":n">> = iolist_to_binary(join(re:split("bnn","(?(?!b(*COMMIT)a)bn|bnn)",[]))),
+ <<"bnn">> = iolist_to_binary(join(re:split("bnn","(?=b(*SKIP)a)bn|bnn",[trim]))),
<<"bnn">> = iolist_to_binary(join(re:split("bnn","(?=b(*SKIP)a)bn|bnn",[{parts,
- 2}]))),
- <<"bnn">> = iolist_to_binary(join(re:split("bnn","(?=b(*SKIP)a)bn|bnn",[]))),
- <<"">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[trim]))),
+ 2}]))),
+ <<"bnn">> = iolist_to_binary(join(re:split("bnn","(?=b(*SKIP)a)bn|bnn",[]))),
+ <<"">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[trim]))),
<<":">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[]))),
ok.
run54() ->
- <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[trim]))),
+ <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[trim]))),
<<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[{parts,
- 2}]))),
- <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[trim]))),
+ 2}]))),
+ <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[{parts,
- 2}]))),
- <<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[]))),
- <<":d">> = iolist_to_binary(join(re:split("acd","^(?!a(*PRUNE)b)..",[trim]))),
+ 2}]))),
+ <<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[]))),
+ <<":d">> = iolist_to_binary(join(re:split("acd","^(?!a(*PRUNE)b)..",[trim]))),
<<":d">> = iolist_to_binary(join(re:split("acd","^(?!a(*PRUNE)b)..",[{parts,
- 2}]))),
- <<":d">> = iolist_to_binary(join(re:split("acd","^(?!a(*PRUNE)b)..",[]))),
- <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*PRUNE)b)..",[trim]))),
+ 2}]))),
+ <<":d">> = iolist_to_binary(join(re:split("acd","^(?!a(*PRUNE)b)..",[]))),
+ <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*PRUNE)b)..",[trim]))),
<<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*PRUNE)b)..",[{parts,
- 2}]))),
- <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*PRUNE)b)..",[]))),
- <<"">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)",[trim]))),
+ 2}]))),
+ <<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*PRUNE)b)..",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)",[]))),
- <<":CD">> = iolist_to_binary(join(re:split("CD","^(A(*THEN)B|C(*THEN)D)",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ba","\\A.*?(?:a|bc)",[]))),
+ <<":CD">> = iolist_to_binary(join(re:split("CD","^(A(*THEN)B|C(*THEN)D)",[trim]))),
<<":CD:">> = iolist_to_binary(join(re:split("CD","^(A(*THEN)B|C(*THEN)D)",[{parts,
- 2}]))),
- <<":CD:">> = iolist_to_binary(join(re:split("CD","^(A(*THEN)B|C(*THEN)D)",[]))),
- <<"">> = iolist_to_binary(join(re:split("1234","^\\d*\\w{4}",[trim]))),
+ 2}]))),
+ <<":CD:">> = iolist_to_binary(join(re:split("CD","^(A(*THEN)B|C(*THEN)D)",[]))),
+ <<"">> = iolist_to_binary(join(re:split("1234","^\\d*\\w{4}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("1234","^\\d*\\w{4}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("1234","^\\d*\\w{4}",[]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^\\d*\\w{4}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("1234","^\\d*\\w{4}",[]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^\\d*\\w{4}",[trim]))),
<<"123">> = iolist_to_binary(join(re:split("123","^\\d*\\w{4}",[{parts,
- 2}]))),
- <<"123">> = iolist_to_binary(join(re:split("123","^\\d*\\w{4}",[]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[trim]))),
+ 2}]))),
+ <<"123">> = iolist_to_binary(join(re:split("123","^\\d*\\w{4}",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[]))),
<<"">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^[^b]*\\w{4}",[caseless]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[caseless,
- trim]))),
+ trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[caseless,
{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[caseless]))),
- <<"">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^[^b]*\\w{4}",[caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[]))),
<<"">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[caseless,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[caseless,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[caseless]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaa","^a*\\w{4}",[caseless]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[caseless,
- trim]))),
+ trim]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[caseless,
{parts,
- 2}]))),
- <<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[caseless]))),
- <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
+ 2}]))),
+ <<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[caseless]))),
+ <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
<<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[{parts,
- 2}]))),
- <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
- <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[trim]))),
+ 2}]))),
+ <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[trim]))),
<<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[{parts,
- 2}]))),
- <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[]))),
- <<"">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[trim]))),
+ 2}]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[]))),
<<"">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
- + b $ ",[extended,trim]))),
+ + b $ ",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
- + b $ ",[extended,{parts,2}]))),
+ + b $ ",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
- + b $ ",[extended]))),
+ + b $ ",[extended]))),
<<"">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
#comment
- + b $ ",[extended,trim]))),
+ + b $ ",[extended,trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
#comment
- + b $ ",[extended,{parts,2}]))),
+ + b $ ",[extended,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
#comment
- + b $ ",[extended]))),
+ + b $ ",[extended]))),
ok.
run55() ->
<<"">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended,
- trim]))),
+ trim]))),
<<":">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended,
{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended]))),
<<":aaaa">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended,
- trim]))),
+ trim]))),
<<":aaaa:">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended,
{parts,
- 2}]))),
- <<":aaaa:">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended]))),
- <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[trim]))),
+ 2}]))),
+ <<":aaaa:">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[trim]))),
<<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[{parts,
- 2}]))),
- <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[]))),
- <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[trim]))),
+ 2}]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[trim]))),
<<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[{parts,
- 2}]))),
- <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[]))),
- <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[trim]))),
+ 2}]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[trim]))),
<<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[{parts,
- 2}]))),
- <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[]))),
- <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[trim]))),
+ 2}]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[trim]))),
<<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[{parts,
- 2}]))),
- <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[]))),
- <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[trim]))),
+ 2}]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[]))),
+ <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[trim]))),
<<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[{parts,
- 2}]))),
- <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[]))),
- <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[trim]))),
+ 2}]))),
+ <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[]))),
+ <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[trim]))),
<<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[{parts,
- 2}]))),
- <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[]))),
- <<":a">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ 2}]))),
+ <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
<<":a::">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
- 2}]))),
- <<":a::">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
- <<"::b">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ 2}]))),
+ <<":a::">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"::b">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
<<"::b:">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
- 2}]))),
- <<"::b:">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
- <<"a">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ 2}]))),
+ <<"::b:">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
<<"a:::">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
- 2}]))),
- <<"a:::">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
- <<"bc">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ 2}]))),
+ <<"a:::">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"bc">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
<<"bc:::">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
- 2}]))),
- <<"bc:::">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
- <<"">> = iolist_to_binary(join(re:split(" abc","\\sabc",[trim]))),
+ 2}]))),
+ <<"bc:::">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"">> = iolist_to_binary(join(re:split(" abc","\\sabc",[trim]))),
<<":">> = iolist_to_binary(join(re:split(" abc","\\sabc",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(" abc","\\sabc",[]))),
- <<"">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(" abc","\\sabc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[trim]))),
<<":">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[]))),
- <<"1::::::2::::::3::::::4:abcd:abcd">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[trim]))),
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[]))),
+ <<"1::::::2::::::3::::::4:abcd:abcd">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[trim]))),
<<"1::::::234abcd">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[{parts,
- 2}]))),
- <<"1::::::2::::::3::::::4:abcd:abcd::::">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[]))),
+ 2}]))),
+ <<"1::::::2::::::3::::::4:abcd:abcd::::">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[]))),
ok.
run56() ->
- <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[trim]))),
+ <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[trim]))),
<<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[{parts,
- 2}]))),
- <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[]))),
- <<"a::b::c::d">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[trim]))),
+ 2}]))),
+ <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[]))),
+ <<"a::b::c::d">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[trim]))),
<<"a::bcd">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[{parts,
- 2}]))),
- <<"a::b::c::d::">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[]))),
- <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[trim]))),
+ 2}]))),
+ <<"a::b::c::d::">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[]))),
+ <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[trim]))),
<<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[{parts,
- 2}]))),
- <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[]))),
- <<" ">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[trim]))),
+ 2}]))),
+ <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[]))),
+ <<" ">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[trim]))),
<<" :">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[{parts,
- 2}]))),
- <<" :">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[]))),
+ 2}]))),
+ <<" :">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[]))),
+ <<">:::<">> = iolist_to_binary(join(re:split(">XXX<","X+(?#comment)?",[trim]))),
+ <<">:XX<">> = iolist_to_binary(join(re:split(">XXX<","X+(?#comment)?",[{parts,
+ 2}]))),
+ <<">:::<">> = iolist_to_binary(join(re:split(">XXX<","X+(?#comment)?",[]))),
+ <<":pokus">> = iolist_to_binary(join(re:split("pokus."," (?<word> \\w+ )* \\. ",[extended,
+ caseless,
+ trim]))),
+ <<":pokus:">> = iolist_to_binary(join(re:split("pokus."," (?<word> \\w+ )* \\. ",[extended,
+ caseless,
+ {parts,
+ 2}]))),
+ <<":pokus:">> = iolist_to_binary(join(re:split("pokus."," (?<word> \\w+ )* \\. ",[extended,
+ caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("pokus.","(?(DEFINE) (?<word> \\w+ ) ) (?&word)* \\.",[extended,
+ caseless,
+ trim]))),
+ <<"::">> = iolist_to_binary(join(re:split("pokus.","(?(DEFINE) (?<word> \\w+ ) ) (?&word)* \\.",[extended,
+ caseless,
+ {parts,
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("pokus.","(?(DEFINE) (?<word> \\w+ ) ) (?&word)* \\.",[extended,
+ caseless]))),
+ <<"::pokus">> = iolist_to_binary(join(re:split("pokus.","(?(DEFINE) (?<word> \\w+ ) ) ( (?&word)* ) \\.",[extended,
+ caseless,
+ trim]))),
+ <<"::pokus:">> = iolist_to_binary(join(re:split("pokus.","(?(DEFINE) (?<word> \\w+ ) ) ( (?&word)* ) \\.",[extended,
+ caseless,
+ {parts,
+ 2}]))),
+ <<"::pokus:">> = iolist_to_binary(join(re:split("pokus.","(?(DEFINE) (?<word> \\w+ ) ) ( (?&word)* ) \\.",[extended,
+ caseless]))),
+ <<"">> = iolist_to_binary(join(re:split("pokus.","(?&word)* (?(DEFINE) (?<word> \\w+ ) ) \\.",[extended,
+ caseless,
+ trim]))),
+ <<"::">> = iolist_to_binary(join(re:split("pokus.","(?&word)* (?(DEFINE) (?<word> \\w+ ) ) \\.",[extended,
+ caseless,
+ {parts,
+ 2}]))),
+ <<"::">> = iolist_to_binary(join(re:split("pokus.","(?&word)* (?(DEFINE) (?<word> \\w+ ) ) \\.",[extended,
+ caseless]))),
+ <<":hokus">> = iolist_to_binary(join(re:split("pokus.hokus","(?&word)* \\. (?<word> \\w+ )",[extended,
+ caseless,
+ trim]))),
+ <<":hokus:">> = iolist_to_binary(join(re:split("pokus.hokus","(?&word)* \\. (?<word> \\w+ )",[extended,
+ caseless,
+ {parts,
+ 2}]))),
+ <<":hokus:">> = iolist_to_binary(join(re:split("pokus.hokus","(?&word)* \\. (?<word> \\w+ )",[extended,
+ caseless]))),
ok.
diff --git a/make/otp.mk.in b/make/otp.mk.in
index cdddb90734..cc76f00e7e 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -110,6 +110,10 @@ ifdef BOOTSTRAP
else
ERL_COMPILE_FLAGS += +debug_info
endif
+ifeq ($(USE_ESOCK),yes)
+ERL_COMPILE_FLAGS += -DUSE_ESOCK=true
+endif
+
ERLC_WFLAGS = -W
ERLC = erlc $(ERLC_WFLAGS) $(ERLC_FLAGS)
ERL = erl -boot start_clean
diff --git a/make/otp_version_tickets_in_merge b/make/otp_version_tickets_in_merge
index fd9b36720a..e69de29bb2 100644
--- a/make/otp_version_tickets_in_merge
+++ b/make/otp_version_tickets_in_merge
@@ -1,6 +0,0 @@
-OTP-15805
-OTP-15819
-OTP-15867
-OTP-15879
-OTP-15887
-OTP-15888
diff --git a/otp_versions.table b/otp_versions.table
index 92e04a3035..47b95b7ee1 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,8 +1,13 @@
+OTP-22.0.7 : compiler-7.4.4 # asn1-5.0.9 common_test-1.17.3 crypto-4.5.1 debugger-4.2.7 dialyzer-4.0.3 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19.1 inets-7.0.9 jinterface-1.10 kernel-6.4.1 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3.5 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
+OTP-22.0.6 : compiler-7.4.3 dialyzer-4.0.3 hipe-3.19.1 ssl-9.3.5 # asn1-5.0.9 common_test-1.17.3 crypto-4.5.1 debugger-4.2.7 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 inets-7.0.9 jinterface-1.10 kernel-6.4.1 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
+OTP-22.0.5 : dialyzer-4.0.2 erts-10.4.4 inets-7.0.9 ssl-9.3.4 # asn1-5.0.9 common_test-1.17.3 compiler-7.4.2 crypto-4.5.1 debugger-4.2.7 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 jinterface-1.10 kernel-6.4.1 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0.4 : erts-10.4.3 kernel-6.4.1 ssl-9.3.3 # asn1-5.0.9 common_test-1.17.3 compiler-7.4.2 crypto-4.5.1 debugger-4.2.7 dialyzer-4.0.1 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0.3 : compiler-7.4.2 dialyzer-4.0.1 erts-10.4.2 ssl-9.3.2 stdlib-3.9.2 # asn1-5.0.9 common_test-1.17.3 crypto-4.5.1 debugger-4.2.7 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0.2 : compiler-7.4.1 crypto-4.5.1 erts-10.4.1 stdlib-3.9.1 # asn1-5.0.9 common_test-1.17.3 debugger-4.2.7 dialyzer-4.0 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3.1 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0.1 : ssl-9.3.1 # asn1-5.0.9 common_test-1.17.3 compiler-7.4 crypto-4.5 debugger-4.2.7 dialyzer-4.0 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0 : asn1-5.0.9 common_test-1.17.3 compiler-7.4 crypto-4.5 debugger-4.2.7 dialyzer-4.0 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3 stdlib-3.9 syntax_tools-2.2 tools-3.2 wx-1.8.8 xmerl-1.3.21 # diameter-2.2.1 et-1.6.4 eunit-2.3.7 ftp-1.0.2 parsetools-2.1.8 tftp-1.0.1 :
+OTP-21.3.8.6 : ssl-9.2.3.5 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 erts-10.3.5.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 kernel-6.3.1.2 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 stdlib-3.8.2.2 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
+OTP-21.3.8.5 : erts-10.3.5.4 ssl-9.2.3.4 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 kernel-6.3.1.2 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 stdlib-3.8.2.2 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
OTP-21.3.8.4 : common_test-1.17.2.1 erts-10.3.5.3 kernel-6.3.1.2 public_key-1.6.6.1 ssl-9.2.3.3 stdlib-3.8.2.2 # asn1-5.0.8 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
OTP-21.3.8.3 : erts-10.3.5.2 kernel-6.3.1.1 ssl-9.2.3.2 stdlib-3.8.2.1 # asn1-5.0.8 common_test-1.17.2 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
OTP-21.3.8.2 : xmerl-1.3.20.1 # asn1-5.0.8 common_test-1.17.2 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 erts-10.3.5.1 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 kernel-6.3.1 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 ssl-9.2.3.1 stdlib-3.8.2 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 :
diff --git a/scripts/build-otp b/scripts/build-otp
index abf8d5d67f..55023ba7d8 100755
--- a/scripts/build-otp
+++ b/scripts/build-otp
@@ -44,6 +44,8 @@ fi
do_and_log "Autoconfing" ./otp_build autoconf
do_and_log "Configuring" ./otp_build configure
+echo Configure result:
+tail -n 20 $log
do_and_log "Building OTP" ./otp_build boot -a
if [ "$1" = "release" ]; then
diff --git a/system/COPYRIGHT b/system/COPYRIGHT
index 91cf0bbfb3..57ea16e95c 100644
--- a/system/COPYRIGHT
+++ b/system/COPYRIGHT
@@ -62,7 +62,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2018 University of Cambridge
+Copyright (c) 1997-2019 University of Cambridge
All rights reserved.
@@ -71,9 +71,9 @@ PCRE JUST-IN-TIME COMPILATION SUPPORT
Written by: Zoltan Herczeg
Email local part: hzmester
-Emain domain: freemail.hu
+Email domain: freemail.hu
-Copyright(c) 2010-2018 Zoltan Herczeg
+Copyright(c) 2010-2019 Zoltan Herczeg
All rights reserved.
@@ -82,9 +82,9 @@ STACK-LESS JUST-IN-TIME COMPILER
Written by: Zoltan Herczeg
Email local part: hzmester
-Emain domain: freemail.hu
+Email domain: freemail.hu
-Copyright(c) 2009-2018 Zoltan Herczeg
+Copyright(c) 2009-2019 Zoltan Herczeg
All rights reserved.