aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HOWTO/INSTALL-CROSS.md4
-rw-r--r--OTP_VERSION2
-rw-r--r--bootstrap/lib/compiler/ebin/cerl.beambin32024 -> 32416 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin53472 -> 54256 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_controller.beambin32148 -> 32180 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin28532 -> 28572 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erts_debug.beambin4048 -> 4312 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin14528 -> 14500 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin28428 -> 28540 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin30708 -> 30744 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin22504 -> 22692 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin89740 -> 89824 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin75044 -> 75012 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_tar.beambin15320 -> 15664 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin7932 -> 7944 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/maps.beambin1644 -> 1752 bytes
-rw-r--r--configure.in6
-rw-r--r--erts/autoconf/vxworks/sed.general1
-rw-r--r--erts/configure.in25
-rw-r--r--erts/doc/src/epmd.xml41
-rw-r--r--erts/doc/src/erl.xml18
-rw-r--r--erts/doc/src/erl_prim_loader.xml16
-rw-r--r--erts/doc/src/erlang.xml9
-rw-r--r--erts/doc/src/erts_alloc.xml14
-rw-r--r--erts/doc/src/notes.xml217
-rw-r--r--erts/emulator/beam/atom.names2
-rw-r--r--erts/emulator/beam/bif.c7
-rw-r--r--erts/emulator/beam/bif.h118
-rw-r--r--erts/emulator/beam/bif.tab8
-rw-r--r--erts/emulator/beam/binary.c1157
-rw-r--r--erts/emulator/beam/erl_alloc_util.c9
-rw-r--r--erts/emulator/beam/erl_bif_binary.c11
-rw-r--r--[-rwxr-xr-x]erts/emulator/beam/erl_bif_info.c53
-rw-r--r--erts/emulator/beam/erl_binary.h33
-rw-r--r--erts/emulator/beam/erl_init.c2
-rw-r--r--erts/emulator/beam/erl_lock_check.c17
-rw-r--r--erts/emulator/beam/erl_lock_count.c161
-rw-r--r--erts/emulator/beam/erl_lock_count.h20
-rw-r--r--erts/emulator/beam/erl_message.c37
-rw-r--r--erts/emulator/beam/erl_port_task.c9
-rw-r--r--erts/emulator/beam/erl_process.c6
-rw-r--r--erts/emulator/beam/erl_unicode.c2
-rw-r--r--erts/emulator/beam/external.c144
-rw-r--r--[-rwxr-xr-x]erts/emulator/beam/global.h53
-rw-r--r--erts/emulator/beam/io.c2
-rw-r--r--erts/emulator/beam/sys.h2
-rw-r--r--erts/emulator/beam/utils.c493
-rw-r--r--erts/emulator/drivers/common/inet_drv.c35
-rw-r--r--erts/emulator/hipe/hipe_bif_list.m413
-rw-r--r--[-rwxr-xr-x]erts/emulator/sys/win32/sys.c0
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/async_ports_SUITE.erl118
-rw-r--r--erts/emulator/test/async_ports_SUITE_data/Makefile.src15
-rw-r--r--erts/emulator/test/async_ports_SUITE_data/cport.c81
-rw-r--r--erts/emulator/test/binary_SUITE.erl272
-rw-r--r--erts/emulator/test/driver_SUITE.erl3
-rw-r--r--erts/emulator/test/system_info_SUITE.erl1
-rw-r--r--erts/emulator/test/trace_SUITE.erl22
-rw-r--r--erts/etc/unix/etp-commands.in146
-rw-r--r--erts/include/internal/ethread.h22
-rw-r--r--erts/include/internal/ethread_inline.h49
-rw-r--r--erts/include/internal/win/ethr_membar.h8
-rw-r--r--erts/lib_src/Makefile.in1
-rw-r--r--erts/lib_src/common/erl_misc_utils.c7
-rw-r--r--erts/lib_src/common/ethr_aux.c6
-rw-r--r--erts/lib_src/common/ethr_mutex.c6
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin54768 -> 56176 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin98248 -> 97740 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin4456 -> 4160 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin48780 -> 48800 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1460 -> 1464 bytes
-rw-r--r--erts/preloaded/ebin/prim_eval.beambin1340 -> 1332 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin44892 -> 44900 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin72912 -> 73128 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin23424 -> 23432 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin13176 -> 13180 bytes
-rw-r--r--erts/preloaded/src/add_abstract_code14
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl38
-rw-r--r--erts/preloaded/src/erlang.erl35
-rw-r--r--erts/preloaded/src/erts_internal.erl12
-rw-r--r--erts/preloaded/src/prim_inet.erl9
-rw-r--r--erts/test/upgrade_SUITE.erl2
-rw-r--r--erts/vsn.mk2
-rw-r--r--lib/asn1/doc/src/notes.xml17
-rw-r--r--lib/asn1/src/Makefile1
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl58
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl3
-rw-r--r--lib/asn1/src/asn1ct_func.erl12
-rw-r--r--lib/asn1/src/asn1ct_gen.erl354
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl338
-rw-r--r--lib/asn1/src/asn1ct_gen_check.erl271
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl10
-rw-r--r--lib/asn1/src/asn1ct_imm.erl78
-rw-r--r--lib/asn1/src/asn1rtt_ber.erl221
-rw-r--r--lib/asn1/src/asn1rtt_check.erl300
-rw-r--r--lib/asn1/src/asn1rtt_per_common.erl13
-rw-r--r--lib/asn1/test/asn1_SUITE.erl22
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constraints.py7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Default.asn23
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Set.py4
-rw-r--r--lib/asn1/test/asn1_app_test.erl4
-rw-r--r--lib/asn1/test/asn1_test_lib.erl55
-rw-r--r--lib/asn1/test/testNBAPsystem.erl15
-rw-r--r--lib/asn1/test/testSeqSetDefaultVal.erl349
-rw-r--r--lib/asn1/test/testTcapsystem.erl78
-rw-r--r--lib/asn1/vsn.mk2
-rw-r--r--[-rwxr-xr-x]lib/common_test/configure.in0
-rw-r--r--lib/common_test/doc/src/cover_chapter.xml25
-rw-r--r--lib/common_test/doc/src/notes.xml65
-rw-r--r--[-rwxr-xr-x]lib/common_test/priv/run_test.in0
-rw-r--r--lib/common_test/src/ct_cover.erl30
-rw-r--r--lib/common_test/src/ct_framework.erl33
-rw-r--r--lib/common_test/src/ct_logs.erl49
-rw-r--r--lib/common_test/src/ct_run.erl191
-rw-r--r--lib/common_test/test/Makefile3
-rw-r--r--lib/common_test/test/ct_cover_SUITE.erl15
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE.erl221
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl63
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl75
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl68
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_test_mod.erl4
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/local.spec6
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/remote.spec6
-rw-r--r--lib/common_test/test/ct_cover_nomerge_SUITE_data/remote_nostop.spec6
-rw-r--r--lib/common_test/test/ct_snmp_SUITE_data/snmp.cfg16
-rw-r--r--lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl26
-rw-r--r--lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE_data/target_addr.conf4
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/notes.xml31
-rw-r--r--lib/compiler/src/v3_core.erl51
-rw-r--r--lib/compiler/test/warnings_SUITE.erl14
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/crypto/c_src/crypto.c21
-rw-r--r--lib/crypto/c_src/crypto_callback.c2
-rw-r--r--lib/crypto/doc/src/notes.xml36
-rw-r--r--lib/crypto/test/crypto_SUITE.erl28
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/notes.xml18
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/doc/src/dialyzer.xml7
-rw-r--r--lib/dialyzer/doc/src/notes.xml44
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl250
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl8
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl22
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/simple19
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/timer2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl60
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl4
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/results/compiler4
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/results/asn12
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/confusing_record_warning3
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/literals14
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/my_sofs4
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring3
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/record_pat2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/record_test2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning3
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/fun2ms.erl21
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/literals.erl33
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/pretty_bitstring.erl8
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/relevant_record_warning.erl (renamed from lib/dialyzer/test/small_SUITE_data/src/confusing_record_warning.erl)6
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/diameter/doc/src/notes.xml129
-rw-r--r--lib/diameter/src/diameter.appup.src4
-rw-r--r--lib/edoc/doc/src/notes.xml19
-rw-r--r--lib/edoc/src/edoc.erl35
-rw-r--r--lib/edoc/src/edoc_layout.erl12
-rw-r--r--lib/edoc/test/edoc_SUITE.erl22
-rw-r--r--lib/edoc/test/edoc_SUITE_data/map_module.erl42
-rw-r--r--lib/edoc/test/edoc_SUITE_data/un1.erl7
-rw-r--r--lib/edoc/test/edoc_SUITE_data/un2.erl8
-rw-r--r--lib/edoc/test/edoc_SUITE_data/un3.erl8
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/erl_docgen/src/docgen_otp_specs.erl23
-rw-r--r--lib/erl_interface/configure.in20
-rw-r--r--lib/erl_interface/doc/src/notes.xml15
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/eunit/src/eunit_data.erl9
-rw-r--r--lib/hipe/cerl/cerl_prettypr.erl17
-rw-r--r--lib/hipe/cerl/erl_types.erl61
-rw-r--r--lib/hipe/doc/src/notes.xml35
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/inets/doc/src/notes.xml17
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl9
-rw-r--r--lib/inets/src/inets_app/inets.appup.src20
-rw-r--r--lib/inets/test/httpd_SUITE.erl154
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl2
-rw-r--r--lib/inets/test/old_httpd_SUITE.erl31
-rw-r--r--lib/inets/vsn.mk2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java10
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java16
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java5
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java4
-rw-r--r--lib/kernel/doc/src/file.xml8
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml7
-rw-r--r--lib/kernel/doc/src/gen_udp.xml7
-rw-r--r--lib/kernel/doc/src/notes.xml91
-rw-r--r--lib/kernel/src/code_server.erl7
-rw-r--r--lib/kernel/src/erl_boot_server.erl6
-rw-r--r--lib/kernel/src/file.erl10
-rw-r--r--lib/kernel/src/inet.erl33
-rw-r--r--lib/kernel/src/kernel.app.src2
-rw-r--r--lib/kernel/test/application_SUITE.erl11
-rw-r--r--lib/kernel/test/code_SUITE.erl74
-rw-r--r--lib/kernel/test/code_SUITE_data/calendar.erl23
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl26
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE.erl41
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE_data/Makefile.src9
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c60
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl4
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/configure.in20
-rw-r--r--lib/mnesia/doc/src/notes.xml25
-rw-r--r--lib/mnesia/src/mnesia_locker.erl20
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/doc/src/notes.xml23
-rw-r--r--lib/observer/src/observer_wx.erl9
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/odbc/configure.in20
-rw-r--r--lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl84
-rw-r--r--lib/orber/doc/src/ch_naming_service.xml41
-rw-r--r--lib/orber/doc/src/corba.xml17
-rw-r--r--lib/orber/doc/src/notes.xml41
-rw-r--r--lib/orber/doc/src/orber.xml9
-rw-r--r--lib/orber/src/Makefile3
-rw-r--r--lib/orber/src/corba.erl45
-rw-r--r--lib/orber/src/corba_request.erl384
-rw-r--r--lib/orber/src/orber_env.erl7
-rw-r--r--lib/orber/src/orber_iiop.hrl4
-rw-r--r--lib/orber/src/orber_iiop_net.erl70
-rw-r--r--lib/orber/src/orber_iiop_outproxy.erl38
-rw-r--r--lib/orber/src/orber_socket.erl40
-rw-r--r--lib/orber/test/Makefile3
-rw-r--r--lib/orber/test/ip_v4v6_interop_SUITE.erl199
-rw-r--r--lib/orber/test/multi_ORB_SUITE.erl4
-rw-r--r--lib/orber/test/orber_firewall_ipv6_in_SUITE.erl49
-rw-r--r--lib/orber/test/orber_test_lib.erl8
-rw-r--r--lib/orber/vsn.mk2
-rw-r--r--lib/os_mon/doc/src/disksup.xml11
-rw-r--r--lib/os_mon/src/disksup.erl19
-rw-r--r--lib/os_mon/test/disksup_SUITE.erl38
-rw-r--r--lib/reltool/doc/src/notes.xml18
-rw-r--r--lib/reltool/src/reltool_server.erl4
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl7
-rw-r--r--lib/reltool/vsn.mk2
-rw-r--r--lib/sasl/doc/src/alarm_handler.xml12
-rw-r--r--lib/snmp/doc/src/notes.xml24
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl78
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl109
-rw-r--r--lib/snmp/src/agent/snmp_generic.erl30
-rw-r--r--lib/snmp/src/agent/snmp_notification_mib.erl24
-rw-r--r--lib/snmp/src/agent/snmp_standard_mib.erl23
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl214
-rw-r--r--lib/snmp/src/agent/snmp_user_based_sm_mib.erl14
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl23
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl17
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl585
-rw-r--r--lib/snmp/src/agent/snmpa_local_db.erl6
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl120
-rw-r--r--lib/snmp/src/agent/snmpa_net_if.erl1288
-rw-r--r--lib/snmp/src/agent/snmpa_net_if_filter.erl56
-rw-r--r--lib/snmp/src/agent/snmpa_network_interface_filter.erl13
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl172
-rw-r--r--lib/snmp/src/app/snmp.appup.src4
-rw-r--r--lib/snmp/src/manager/snmpm.erl49
-rw-r--r--lib/snmp/src/manager/snmpm_conf.erl247
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl1315
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl76
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl382
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_filter.erl60
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_mt.erl496
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl660
-rw-r--r--lib/snmp/src/manager/snmpm_user.erl23
-rw-r--r--lib/snmp/src/manager/snmpm_user_default.erl16
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl737
-rw-r--r--lib/snmp/src/misc/snmp_config.erl539
-rw-r--r--lib/snmp/src/misc/snmp_log.erl209
-rw-r--r--lib/snmp/src/misc/snmp_pdus.erl8
-rw-r--r--lib/snmp/test/Makefile5
-rw-r--r--lib/snmp/test/klas3.erl13
-rw-r--r--lib/snmp/test/modules.mk1
-rw-r--r--lib/snmp/test/snmp_SUITE.erl29
-rw-r--r--lib/snmp/test/snmp_agent_test.erl445
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl77
-rw-r--r--lib/snmp/test/snmp_conf_test.erl8
-rw-r--r--lib/snmp/test/snmp_manager_config_test.erl23
-rw-r--r--lib/snmp/test/snmp_manager_test.erl147
-rw-r--r--lib/snmp/test/snmp_test_lib.erl7
-rw-r--r--lib/snmp/test/snmp_test_lib.hrl19
-rw-r--r--lib/snmp/test/snmp_test_manager.erl6
-rw-r--r--lib/snmp/test/snmp_test_mgr.erl36
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl52
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE.erl433
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.binbin0 -> 3640 bytes
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib71
-rwxr-xr-xlib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper47
-rw-r--r--lib/snmp/vsn.mk2
-rw-r--r--lib/ssh/doc/src/notes.xml42
-rw-r--r--lib/ssh/doc/src/ssh.xml6
-rw-r--r--lib/ssh/src/ssh.appup.src16
-rw-r--r--lib/ssh/src/ssh.erl32
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl28
-rw-r--r--lib/ssh/src/ssh_message.erl27
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl148
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml114
-rw-r--r--lib/ssl/src/ssl.erl13
-rw-r--r--lib/ssl/src/ssl_connection.erl32
-rw-r--r--lib/ssl/src/ssl_connection.hrl1
-rw-r--r--lib/ssl/src/ssl_handshake.erl12
-rw-r--r--lib/ssl/src/ssl_manager.erl4
-rw-r--r--lib/ssl/src/tls_connection.erl10
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl5
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl8
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml4
-rw-r--r--lib/stdlib/doc/src/gen_server.xml2
-rw-r--r--lib/stdlib/doc/src/notes.xml112
-rw-r--r--lib/stdlib/doc/src/sys.xml5
-rw-r--r--lib/stdlib/src/dets.erl5
-rw-r--r--lib/stdlib/src/epp.erl16
-rw-r--r--lib/stdlib/src/erl_eval.erl2
-rw-r--r--lib/stdlib/src/erl_expand_records.erl26
-rw-r--r--lib/stdlib/src/filelib.erl14
-rw-r--r--lib/stdlib/src/io_lib_format.erl2
-rw-r--r--lib/stdlib/src/maps.erl6
-rw-r--r--lib/stdlib/src/shell.erl8
-rw-r--r--lib/stdlib/src/stdlib.app.src2
-rw-r--r--lib/stdlib/src/stdlib.appup.src6
-rw-r--r--lib/stdlib/src/sys.erl10
-rw-r--r--lib/stdlib/test/dets_SUITE.erl6
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl112
-rw-r--r--lib/stdlib/test/io_SUITE.erl10
-rw-r--r--lib/stdlib/test/shell_SUITE.erl5
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/doc/src/notes.xml39
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl28
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl13
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/test_server/doc/src/notes.xml39
-rw-r--r--lib/test_server/src/test_server.erl118
-rw-r--r--lib/test_server/src/test_server_ctrl.erl133
-rw-r--r--lib/test_server/src/test_server_internal.hrl9
-rw-r--r--lib/test_server/src/ts.erl9
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/doc/src/notes.xml18
-rw-r--r--lib/tools/emacs/erlang.el2
-rw-r--r--lib/tools/src/lcnt.erl359
-rw-r--r--lib/tools/test/lcnt_SUITE.erl153
-rw-r--r--lib/tools/test/lcnt_SUITE_data/ehb_3_3_hist.lcntbin0 -> 601135 bytes
-rw-r--r--lib/tools/test/xref_SUITE.erl2
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/typer/doc/src/notes.xml15
-rw-r--r--lib/typer/vsn.mk2
-rw-r--r--lib/wx/api_gen/wx_doxygen.conf1
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl32
-rw-r--r--lib/wx/api_gen/wxapi.conf15
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h16
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp12
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp152
-rw-r--r--lib/wx/c_src/gen/wxe_init.cpp6
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h3331
-rw-r--r--lib/wx/c_src/wxe_impl.cpp13
-rw-r--r--lib/wx/c_src/wxe_impl.h1
-rw-r--r--lib/wx/c_src/wxe_memory.h3
-rw-r--r--[-rwxr-xr-x]lib/wx/configure.in21
-rw-r--r--lib/wx/doc/src/notes.xml30
-rw-r--r--lib/wx/include/wx.hrl11
-rw-r--r--lib/wx/src/gen/wxActivateEvent.erl72
-rw-r--r--lib/wx/src/gen/wxPopupTransientWindow.erl506
-rw-r--r--lib/wx/src/gen/wxPopupWindow.erl503
-rw-r--r--lib/wx/src/gen/wxTextCtrl.erl16
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl3330
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl3330
-rw-r--r--lib/wx/test/wx_class_SUITE.erl49
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/motorcycles2html.erl17
-rw-r--r--otp_versions.table4
-rw-r--r--system/doc/efficiency_guide/advanced.xml2
-rw-r--r--system/doc/reference_manual/data_types.xml2
-rw-r--r--system/doc/reference_manual/expressions.xml1
-rw-r--r--system/doc/reference_manual/processes.xml4
-rw-r--r--system/doc/system_principles/versions.xml2
389 files changed, 20523 insertions, 11750 deletions
diff --git a/HOWTO/INSTALL-CROSS.md b/HOWTO/INSTALL-CROSS.md
index af4b38f292..7f852860c9 100644
--- a/HOWTO/INSTALL-CROSS.md
+++ b/HOWTO/INSTALL-CROSS.md
@@ -566,8 +566,8 @@ under the License.
[$ERL_TOP/HOWTO/INSTALL.md]: INSTALL.md
- [Building in Git]: INSTALL.md#How-to-Build-and-Install-ErlangOTP_Building-in-Git
- [How to Build the Documentation]: INSTALL.md#The-ErlangOTP-Documentation_How-to-Build-the-Documentation
+ [Building in Git]: INSTALL.md#How-to-Build-and-Install-ErlangOTP
+ [How to Build the Documentation]: INSTALL.md#How-to-Build-and-Install-ErlangOTP_How-to-Build-the-Documentation
[cross configuration variables]: #Currently-Used-Configuration-Variables
[DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html
[?TOC]: true
diff --git a/OTP_VERSION b/OTP_VERSION
index b7aba827ff..8fad390b2f 100644
--- a/OTP_VERSION
+++ b/OTP_VERSION
@@ -1 +1 @@
-17.1-rc0
+17.2
diff --git a/bootstrap/lib/compiler/ebin/cerl.beam b/bootstrap/lib/compiler/ebin/cerl.beam
index ff6f0ea0fd..0f0670c9ae 100644
--- a/bootstrap/lib/compiler/ebin/cerl.beam
+++ b/bootstrap/lib/compiler/ebin/cerl.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam
index ac24c6a6cb..5da654686a 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/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam
index 659f29e35e..2a4525c27f 100644
--- a/bootstrap/lib/kernel/ebin/application_controller.beam
+++ b/bootstrap/lib/kernel/ebin/application_controller.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code_server.beam b/bootstrap/lib/kernel/ebin/code_server.beam
index 430c2e0733..340c5feed9 100644
--- a/bootstrap/lib/kernel/ebin/code_server.beam
+++ b/bootstrap/lib/kernel/ebin/code_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erts_debug.beam b/bootstrap/lib/kernel/ebin/erts_debug.beam
index 7d059d10cf..17320342bc 100644
--- a/bootstrap/lib/kernel/ebin/erts_debug.beam
+++ b/bootstrap/lib/kernel/ebin/erts_debug.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam
index 4444b79bf7..25f2506078 100644
--- a/bootstrap/lib/kernel/ebin/file.beam
+++ b/bootstrap/lib/kernel/ebin/file.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 7013e29466..83469557cd 100644
--- a/bootstrap/lib/stdlib/ebin/epp.beam
+++ b/bootstrap/lib/stdlib/ebin/epp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam
index aab2f38b91..95454c885a 100644
--- a/bootstrap/lib/stdlib/ebin/erl_eval.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
index 9f7ad7265d..ff84000ac0 100644
--- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index 9481dc6ef5..8ae35899d0 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_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam
index 3d36ee85b7..998bb0b209 100644
--- a/bootstrap/lib/stdlib/ebin/erl_parse.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_tar.beam b/bootstrap/lib/stdlib/ebin/erl_tar.beam
index 6401818109..76f5f95270 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/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam
index b70aa54301..1f84adafa5 100644
--- a/bootstrap/lib/stdlib/ebin/filelib.beam
+++ b/bootstrap/lib/stdlib/ebin/filelib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/maps.beam b/bootstrap/lib/stdlib/ebin/maps.beam
index f524bc516c..4268a97fec 100644
--- a/bootstrap/lib/stdlib/ebin/maps.beam
+++ b/bootstrap/lib/stdlib/ebin/maps.beam
Binary files differ
diff --git a/configure.in b/configure.in
index be906dcb4e..780e660f9d 100644
--- a/configure.in
+++ b/configure.in
@@ -366,6 +366,12 @@ elif test X"$TMPSYS" '=' X"Darwin-i386"; then
export LDFLAGS
fi
+m4_define(DEFAULT_SANITIZERS, [address,undefined])
+AC_ARG_ENABLE(sanitizers,
+ AS_HELP_STRING(
+ [--enable-sanitizers@<:@=comma-separated list of sanitizers@:>@],
+ [Default=DEFAULT_SANITIZERS]))
+
AC_ARG_ENABLE([silent-rules], [dnl
AS_HELP_STRING(
[--enable-silent-rules],
diff --git a/erts/autoconf/vxworks/sed.general b/erts/autoconf/vxworks/sed.general
index dbb9420b67..efa4e99054 100644
--- a/erts/autoconf/vxworks/sed.general
+++ b/erts/autoconf/vxworks/sed.general
@@ -57,6 +57,7 @@ s|@ETHR_LIB_NAME@||
s|@ETHR_DEFS@||
s|@ETHR_THR_LIB_BASE@||
s|@ETHR_THR_LIB_BASE_DIR@||
+s|@SYSTEMD_DAEMON_LIBS@||
s|@EMU_THR_DEFS@||
s|@EMU_THR_LIBS@||
s|@EMU_THR_LIB_NAME@|ethread|
diff --git a/erts/configure.in b/erts/configure.in
index 04303da4f8..40b335849c 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -673,6 +673,7 @@ case $chk_arch_ in
x86_64) ARCH=amd64;;
amd64) ARCH=amd64;;
macppc) ARCH=ppc;;
+ powerpc) ARCH=ppc;;
ppc) ARCH=ppc;;
ppc64) ARCH=ppc64;;
"Power Macintosh") ARCH=ppc;;
@@ -680,8 +681,10 @@ case $chk_arch_ in
armv5teb) ARCH=arm;;
armv5tel) ARCH=arm;;
armv5tejl) ARCH=arm;;
- armv6l) ARCH=arm;;
+ armv6l) ARCH=arm;;
+ armv6hl) ARCH=arm;;
armv7l) ARCH=arm;;
+ armv7hl) ARCH=arm;;
tile) ARCH=tile;;
*) ARCH=noarch;;
esac
@@ -4818,6 +4821,26 @@ if test "x$GCC" = xyes; then
fi
dnl ----------------------------------------------------------------------
+dnl Enable -fsanitize= flags.
+dnl ----------------------------------------------------------------------
+
+m4_define(DEFAULT_SANITIZERS, [address,undefined])
+AC_ARG_ENABLE(
+ sanitizers,
+ AS_HELP_STRING(
+ [--enable-sanitizers@<:@=comma-separated list of sanitizers@:>@],
+ [Default=DEFAULT_SANITIZERS]),
+[
+case "$enableval" in
+ no) sanitizers= ;;
+ yes) sanitizers="-fsanitize=DEFAULT_SANITIZERS" ;;
+ *) sanitizers="-fsanitize=$enableval" ;;
+esac
+CFLAGS="$CFLAGS $sanitizers"
+LDFLAGS="$LDFLAGS $sanitizers"
+])
+
+dnl ----------------------------------------------------------------------
dnl Output the result.
dnl ----------------------------------------------------------------------
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
index 963d35c3c8..25f819ab50 100644
--- a/erts/doc/src/epmd.xml
+++ b/erts/doc/src/epmd.xml
@@ -58,12 +58,12 @@
of the IP address and a port number. The name of the node is
an atom on the form of <c><![CDATA[Name@Node]]></c>.
The job of the <c><![CDATA[epmd]]></c> daemon is to keep track of which
- node name listens on which address. Hence, <c><![CDATA[epmd]]></c> map
+ node name listens on which address. Hence, <c><![CDATA[epmd]]></c> maps
symbolic node names to machine addresses.</p>
<p>The TCP/IP <c>epmd</c> daemon actually only keeps track of
- the <c>Name</c> (first) part of an Erlang node name, the <c>Host</c>
- part (whatever is after the <c><![CDATA[@]]></c> is implicit in the
+ the <c>Name</c> (first) part of an Erlang node name. The <c>Host</c>
+ part (whatever is after the <c><![CDATA[@]]></c>) is implicit in the
node name where the <c>epmd</c> daemon was actually contacted,
as is the IP address where the Erlang node can be
reached. Consistent and correct TCP naming services are
@@ -77,12 +77,12 @@
<p>The daemon is started automatically by the <c>erl</c>
command if the node is to be distributed and there is no
running instance present. If automatically launched,
- environment variables has to be used to alter the behavior of
+ environment variables have to be used to alter the behavior of
the daemon. See the <seealso
marker="#environment_variables">Environment
variables</seealso> section below.</p>
- <p>If the -daemon argument is not given, the
+ <p>If the -daemon argument is not given,
<c><![CDATA[epmd]]></c> runs as a normal program with the
controlling terminal of the shell in which it is
started. Normally, it should run as a daemon.</p>
@@ -122,7 +122,7 @@
comma-separated list of IP addresses and on the loopback address
(which is implicitly added to the list if it has not been
specified). This can also be set using the
- <c><![CDATA[ERL_EPMD_ADDRESS]]></c> environment variable, see the
+ <c><![CDATA[ERL_EPMD_ADDRESS]]></c> environment variable. See the
section <seealso marker="#environment_variables">Environment
variables</seealso> below.</p>
</item>
@@ -130,7 +130,7 @@
<item>
<p>Let this instance of epmd listen to another TCP port than
default 4369. This can also be set using the
- <c><![CDATA[ERL_EPMD_PORT]]></c> environment variable, see the
+ <c><![CDATA[ERL_EPMD_PORT]]></c> environment variable. See the
section <seealso marker="#environment_variables">Environment
variables</seealso> below</p>
</item>
@@ -153,7 +153,7 @@
<p>With relaxed command checking, the <c>epmd</c> daemon can be killed from the localhost with i.e. <c>epmd -kill</c> even if there are active nodes registered. Normally only daemons with an empty node database can be killed with the <c>epmd -kill</c> command.</p>
</item>
<item>
- <p>The <c>epmd -stop</c> command (and the corresponding messages to epmd, as can be given using <c>erl_interface/ei</c>) is normally always ignored, as it opens up for strange situation when two nodes of the same name can be alive at the same time. A node unregisters itself by just closing the connection to epmd, why the <c>stop</c> command was only intended for use in debugging situations.</p>
+ <p>The <c>epmd -stop</c> command (and the corresponding messages to epmd, as can be given using <c>erl_interface/ei</c>) is normally always ignored, as it opens up the possibility of a strange situation where two nodes of the same name can be alive at the same time. A node unregisters itself by just closing the connection to epmd, which is why the <c>stop</c> command was only intended for use in debugging situations.</p>
<p>With relaxed command checking enabled, you can forcibly unregister live nodes.</p>
</item>
</list>
@@ -166,7 +166,7 @@
<section>
<marker id="debug_flags"></marker>
<title>DbgExtra options</title>
- <p>These options are purely for debugging and testing epmd clients, they should not be used in normal operation.</p>
+ <p>These options are purely for debugging and testing epmd clients. They should not be used in normal operation.</p>
<taglist>
<tag><c><![CDATA[-packet_timeout Seconds]]></c></tag>
@@ -177,9 +177,9 @@
</item>
<tag><c><![CDATA[-delay_accept Seconds]]></c></tag>
<item>
- <p>To simulate a busy server you can insert a delay between epmd
- gets notified about that a new connection is requested and
- when the connections gets accepted.</p>
+ <p>To simulate a busy server you can insert a delay between when epmd
+ gets notified that a new connection is requested and
+ when the connection gets accepted.</p>
</item>
<tag><c><![CDATA[-delay_write Seconds]]></c></tag>
<item>
@@ -191,15 +191,15 @@
<section>
<marker id="interactive_flags"></marker>
<title>Interactive options</title>
- <p>These options make <c>epmd</c> run as an interactive command displaying the results of sending queries ta an already running instance of <c>epmd</c>. The epmd contacted is always on the local node, but the <c>-port</c> option can be used to select between instances if several are running using different port on the host.</p>
+ <p>These options make <c>epmd</c> run as an interactive command, displaying the results of sending queries to an already running instance of <c>epmd</c>. The epmd contacted is always on the local node, but the <c>-port</c> option can be used to select between instances if several are running using different ports on the host.</p>
<taglist>
<tag><c><![CDATA[-port No]]></c></tag>
<item>
<p>Contacts the <c>epmd</c> listening on the given TCP port number
(default 4369). This can also be set using the
- <c><![CDATA[ERL_EPMD_PORT]]></c> environment variable, see the
+ <c><![CDATA[ERL_EPMD_PORT]]></c> environment variable. See the
section <seealso marker="#environment_variables">Environment
- variables</seealso> below</p>
+ variables</seealso> below.</p>
</item>
<tag><c><![CDATA[-names]]></c></tag>
<item>
@@ -210,7 +210,7 @@
<p>Kill the currently running <c>epmd</c>.</p>
<p>Killing the running <c>epmd</c> is only allowed if <c>epmd
- -names</c> show an empty database or
+ -names</c> shows an empty database or
<c>-relaxed_command_check</c> was given when the running
instance of <c>epmd</c> was started. Note that
<c>-relaxed_command_check</c> is given when starting the
@@ -228,7 +228,7 @@
<p>This command can only be used when contacting <c>epmd</c>
instances started with the <c>-relaxed_command_check</c>
flag. Note that relaxed command checking has to be enabled for
- the <c>epmd</c> daemon contacted, When running epmd
+ the <c>epmd</c> daemon contacted. When running epmd
interactively,
<c>-relaxed_command_check</c> has no effect.</p>
</item>
@@ -259,7 +259,7 @@
<item>
<p>If set prior to start, the <c>epmd</c> daemon will behave
as if the <c>-relaxed_command_check</c> option was given at
- start-up. If consequently setting this option before starting
+ start-up. Consequently, if this option is set before starting
the Erlang virtual machine, the automatically started
<c>epmd</c> will accept the <c>-kill</c> and <c>-stop</c>
commands without restrictions.</p>
@@ -287,8 +287,8 @@
remote hosts. However, only the query commands are answered (and
acted upon) if the query comes from a remote host. It is always an
error to try to register a nodename if the client is not a process
- located on the same host as the <c>epmd</c> instance is running on,
- why such requests are considered hostile and the connection is
+ located on the same host as the <c>epmd</c> instance is running on-
+ such requests are considered hostile and the connection is
immediately closed.</p>
<p>The queries accepted from remote nodes are:</p>
@@ -307,3 +307,4 @@
</comref>
+
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 9724a1345a..5bde285311 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -495,7 +495,7 @@
<c><![CDATA[werl]]></c>, not <c><![CDATA[erl]]></c> (<c><![CDATA[oldshell]]></c>). Note also that
<c><![CDATA[Ctrl-Break]]></c> is used instead of <c><![CDATA[Ctrl-C]]></c> on Windows.</p>
</item>
- <tag><c><![CDATA[+c]]></c></tag>
+ <tag><marker id="+c"><c><![CDATA[+c]]></c></marker></tag>
<item>
<p>Disable compensation for sudden changes of system time.</p>
<p>Normally, <c><![CDATA[erlang:now/0]]></c> will not immediately reflect
@@ -510,6 +510,9 @@
reflect the current system time. Note that timers are based
on <c><![CDATA[erlang:now/0]]></c>. If the system time jumps, timers
then time out at the wrong time.</p>
+ <p><em>NOTE</em>: You can check whether the adjustment is enabled or
+ disabled by calling
+ <seealso marker="erlang#system_info_tolerant_timeofday">erlang:system_info(tolerant_timeofday)</seealso>.</p>
</item>
<tag><c><![CDATA[+d]]></c></tag>
<item>
@@ -848,6 +851,19 @@
</p>
</item>
<tag><marker id="+SDio"><c><![CDATA[+SDio IOSchedulers]]></c></marker></tag>
+ <item>
+ <p>Sets the number of dirty I/O scheduler threads to create when threading
+ support has been enabled. The valid range is 0-1024. By default, the number
+ of dirty I/O scheduler threads created is 10, same as the default number of
+ threads in the <seealso marker="#async_thread_pool_size">async thread pool
+ </seealso>.
+ </p>
+ <p>This option is ignored if the emulator doesn't have threading support
+ enabled. Currently, <em>this option is experimental</em> and is supported only
+ if the emulator was configured and built with support for dirty schedulers
+ enabled (it's disabled by default).
+ </p>
+ </item>
<tag><c><![CDATA[+sFlag Value]]></c></tag>
<item>
<p>Scheduling specific flags.</p>
diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml
index 6751deda4d..171f84decc 100644
--- a/erts/doc/src/erl_prim_loader.xml
+++ b/erts/doc/src/erl_prim_loader.xml
@@ -148,6 +148,22 @@
</desc>
</func>
<func>
+ <name name="read_link_info" arity="1"/>
+ <fsummary>Get information about a link or file</fsummary>
+ <desc>
+ <p>This function works like
+ <seealso marker="#read_file_info/1">read_file_info/1</seealso>
+ except that if <c><anno>Filename</anno></c> is a symbolic link,
+ information about the link will be returned in the <c>file_info</c>
+ record and the <c>type</c> field of the record will be set to
+ <c>symlink</c>.</p>
+ <p>If <c><anno>Filename</anno></c> is not a symbolic link, this function
+ returns exactly the same result as <c>read_file_info/1</c>.
+ On platforms that do not support symbolic links, this function
+ is always equivalent to <c>read_file_info/1</c>.</p>
+ </desc>
+ </func>
+ <func>
<name name="set_path" arity="1"/>
<fsummary>Set the path of the loader</fsummary>
<desc>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 0f4dfc0f98..84168397f6 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4968,7 +4968,7 @@ true</pre>
<desc>
<p>Note that the run-time is the sum of the run-time for all
threads in the Erlang run-time system and may therefore be greater
- than the wall-clock time.</p>
+ than the wall-clock time. The time is returned in milliseconds.</p>
<pre>
> <input>statistics(runtime).</input>
{1690,1620}
@@ -6295,6 +6295,13 @@ ok
(<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>)
as an integer.</p>
</item>
+ <tag><marker id="system_info_tolerant_timeofday"><c>tolerant_timeofday</c></marker></tag>
+ <item>
+ <p>Returns whether compensation for sudden changes of system
+ time is <c>enabled</c> or <c>disabled</c>.</p>
+ <p>See also <seealso marker="erts:erl#+c">+c</seealso>
+ command line flag.</p>
+ </item>
<tag><c>trace_control_word</c></tag>
<item>
<p>Returns the value of the node's trace control word.
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index c9eca39a99..1ade41f1aa 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2002</year><year>2013</year>
+ <year>2002</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -531,15 +531,9 @@
<p>Multiple, thread specific instances of the allocator.
This option will only have any effect on the runtime system
with SMP support. Default behaviour on the runtime system with
- SMP support:</p>
- <taglist>
- <tag><c>ll_alloc</c></tag>
- <item><c>1</c> instance.</item>
- <tag>Other allocators</tag>
- <item><c>NoSchedulers+1</c> instances. Each scheduler will use
- a lock-free instance of its own and other threads will use
- a common instance.</item>
- </taglist>
+ SMP support is <c>NoSchedulers+1</c> instances. Each scheduler will use
+ a lock-free instance of its own and other threads will use
+ a common instance.</p>
<p>It was previously (before ERTS version 5.9) possible to configure
a smaller amount of thread specific instances than schedulers.
This is, however, not possible any more.</p>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 68feaa027a..5c4bb3ed25 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -30,6 +30,190 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 6.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ OTP-11850 fixed filelib:wildcard/1 to work with broken
+ symlinks. This correction, however, introduced problems
+ since symlinks were no longer followed for functions like
+ filelib:ensure_dir/1, filelib:is_dir/1,
+ filelib:file_size/1, etc. This is now corrected.</p>
+ <p>
+ Own Id: OTP-12054 Aux Id: seq12660 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 6.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed ETHR_FORCE_INLINE which caused the build to break
+ on some platforms without adequate thread support
+ (VxWorks).</p>
+ <p>
+ Own Id: OTP-12010</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The documentation for <c>spawn_opt/5</c> now has a
+ note mentioning that the <c>monitor</c> option is not
+ supported.</p>
+ <p>
+ Own Id: OTP-11849</p>
+ </item>
+ <item>
+ <p>
+ Fix broken system monitoring of <c>large_heap</c> for
+ non-smp VM. No message for <c>large_heap</c> was ever
+ sent on non-smp VM. Bug exist since R16B.</p>
+ <p>
+ Own Id: OTP-11852</p>
+ </item>
+ <item>
+ <p>
+ The emulator without SMP support crashed when passing a
+ message to a process without enough heap space for the
+ message. This bug was introduced in <c>erts-6.0</c>.</p>
+ <p>
+ Own Id: OTP-11887 Aux Id: OTP-11388 </p>
+ </item>
+ <item>
+ <p>
+ Fix race between ETS table deletion and unfixation that
+ could cause VM crash. The race could happen between a
+ terminating process that does not own the table but has a
+ fixation on it and another process that deletes the table
+ (maybe the owner terminating) at the same time. Bug
+ existed since R15B02.</p>
+ <p>
+ Own Id: OTP-11892</p>
+ </item>
+ <item>
+ <p>The string following the <c>-eval</c> option when
+ invoking <c>erl</c> would not be properly translated from
+ UTF-8 to a list of Unicode characters (as would the
+ arguments for <c>-run</c>).</p>
+ <p>That bug would cause the build of Erlang/OTP to fail
+ when building in a directory whose pathname contained
+ non-US ASCII characters encoded in UTF-8. (Thanks to Eric
+ Pailleau for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-11916</p>
+ </item>
+ <item>
+ <p>
+ Fix erts_debug:size/1 to handle Map sizes</p>
+ <p>
+ Own Id: OTP-11923</p>
+ </item>
+ <item>
+ <p>
+ Removed <c>erlang:bitstr_to_list/1</c> and
+ <c>erlang:list_to_bitstr/1</c>. They were added by
+ mistake, and have always raised an <c>undefined</c>
+ exception when called.</p>
+ <p>
+ Own Id: OTP-11942</p>
+ </item>
+ <item>
+ <p>
+ Fixed compilation using mingw-w64 on Windows.</p>
+ <p>
+ Thanks to Jani Hakala.</p>
+ <p>
+ Own Id: OTP-11945</p>
+ </item>
+ <item>
+ <p>
+ The git sha is no longer printed in the shell start
+ header when erlang is built from a tagged git release.</p>
+ <p>
+ Own Id: OTP-11961</p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug where <c>send</c> trace events were
+ erroneously dropped when the send was done to a
+ registered process. This bug was introduced in R16B.</p>
+ <p>
+ Own Id: OTP-11968</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The following native functions now bump an appropriate
+ amount of reductions and yield when out of
+ reductions:</p> <list>
+ <item><c>erlang:binary_to_list/1</c></item>
+ <item><c>erlang:binary_to_list/3</c></item>
+ <item><c>erlang:bitstring_to_list/1</c></item>
+ <item><c>erlang:list_to_binary/1</c></item>
+ <item><c>erlang:iolist_to_binary/1</c></item>
+ <item><c>erlang:list_to_bitstring/1</c></item>
+ <item><c>binary:list_to_bin/1</c></item> </list>
+ <p>Characteristics impact:</p> <taglist>
+ <tag>Performance</tag> <item>The functions converting
+ from lists got a performance loss for very small lists,
+ and a performance gain for very large lists.</item>
+ <tag>Priority</tag> <item>Previously a process executing
+ one of these functions effectively got an unfair priority
+ boost. This priority boost depended on the input size.
+ The larger the input was, the larger the priority boost
+ got. This unfair priority boost is now lost. </item>
+ </taglist>
+ <p>
+ Own Id: OTP-11888</p>
+ </item>
+ <item>
+ <p>
+ The systemd features of epmd have been removed from epmd
+ by default. To enable them you have to build erlang with
+ the configure option --enable-systemd.</p>
+ <p>
+ Own Id: OTP-11921</p>
+ </item>
+ <item>
+ <p>
+ Removed Erlang wrapper code used when calling
+ <c>binary_to_term/1</c>, and <c>binary_to_term/2</c>.
+ This improves the performance of these BIFs especially
+ when they are called with small binaries as input.</p>
+ <p>
+ Own Id: OTP-11931</p>
+ </item>
+ <item>
+ <p>
+ Add erlang:system_info(tolerant_timeofday), an API to
+ check whether compensation for sudden changes of system
+ time is enabled or not.</p>
+ <p>
+ Own Id: OTP-11970</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 6.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -595,9 +779,9 @@
"hi" := V1, a := V2, b := V3} = M2. % match keys with
values</c></item> </taglist></p>
<p>
- For information on how to use Maps please see the
- <seealso marker="doc/reference_manual:maps">Reference
- Manual</seealso>.</p>
+ For information on how to use Maps please see Map Expressions in the
+ <seealso marker="doc/reference_manual:expressions#map_expressions">
+ Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
features: <taglist> <item>No variable keys</item>
@@ -756,6 +940,27 @@
Thanks to Matwey V. Kornilov</p>
<p>
Own Id: OTP-11829</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.10.4.1</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ When using gen_tcp:connect and the <c>fd</c> option with
+ <c>port</c> and/or <c>ip</c>, the <c>port</c> and
+ <c>ip</c> options were ignored. This has been fixed so
+ that if <c>port</c> and/or <c>ip</c> is specified
+ together with <c>fd</c> a bind is requested for that
+ <c>fd</c>. If <c>port</c> and/or <c>ip</c> is not
+ specified bind will not be called.</p>
+ <p>
+ Own Id: OTP-12061</p>
</item>
</list>
</section>
@@ -4854,7 +5059,7 @@
<item>
<p>
The <c>configure</c> command line argument <seealso
- marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--enable-ethread-pre-pentium4-compatibility</seealso>
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP">--enable-ethread-pre-pentium4-compatibility</seealso>
had no effect. This option is now also automatically
enabled if required on the build machine.</p>
<p>
@@ -5433,7 +5638,7 @@
platforms than before. If <c>configure</c> warns about no
atomic implementation available, try using the
<c>libatomic_ops</c> library. Use the <seealso
- marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--with-libatomic_ops=PATH</seealso>
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP">--with-libatomic_ops=PATH</seealso>
<c>configure</c> command line argument when specifying
where the <c>libatomic_ops</c> installation is located.
The <c>libatomic_ops</c> library can be downloaded from:
@@ -5451,7 +5656,7 @@
the pentium 4 processor. If you want the runtime system
to be compatible with older processors (back to 486) you
need to pass the <seealso
- marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--enable-ethread-pre-pentium4-compatibility</seealso>
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP">--enable-ethread-pre-pentium4-compatibility</seealso>
<c>configure</c> command line argument when configuring
the system.</p>
<p>
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index d28e519ae1..5d06a32941 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -116,6 +116,7 @@ atom binary_longest_prefix_trap
atom binary_longest_suffix_trap
atom binary_match_trap
atom binary_matches_trap
+atom binary_to_list_continue
atom binary_to_term_trap
atom block
atom blocked
@@ -315,6 +316,7 @@ atom line_length
atom linked_in_driver
atom links
atom list
+atom list_to_binary_continue
atom little
atom loaded
atom load_cancelled
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 06a1230ca0..fcbeb6cf5c 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1886,8 +1886,13 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) {
Eterm id = erts_whereis_name_to_id(p, to);
rp = erts_proc_lookup(id);
- if (rp)
+ if (rp) {
+ if (IS_TRACED(p))
+ trace_send(p, to, msg);
+ if (ERTS_PROC_GET_SAVED_CALLS_BUF(p))
+ save_calls(p, &exp_send);
goto send_message;
+ }
pt = erts_port_lookup(id,
(erts_port_synchronous_ops
diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h
index 51b77a95ed..72c55ccb55 100644
--- a/erts/emulator/beam/bif.h
+++ b/erts/emulator/beam/bif.h
@@ -124,12 +124,85 @@ do { \
return THE_NON_VALUE; \
} while(0)
+#define ERTS_BIF_ERROR_TRAPPED0(Proc, Reason, Bif) \
+do { \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ return THE_NON_VALUE; \
+} while (0)
+
+#define ERTS_BIF_ERROR_TRAPPED1(Proc, Reason, Bif, A0) \
+do { \
+ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ reg[0] = (Eterm) (A0); \
+ return THE_NON_VALUE; \
+} while (0)
+
+#define ERTS_BIF_ERROR_TRAPPED2(Proc, Reason, Bif, A0, A1) \
+do { \
+ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ reg[0] = (Eterm) (A0); \
+ reg[1] = (Eterm) (A1); \
+ return THE_NON_VALUE; \
+} while (0)
+
+#define ERTS_BIF_ERROR_TRAPPED3(Proc, Reason, Bif, A0, A1, A2) \
+do { \
+ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ reg[0] = (Eterm) (A0); \
+ reg[1] = (Eterm) (A1); \
+ reg[2] = (Eterm) (A2); \
+ return THE_NON_VALUE; \
+} while (0)
+
#define ERTS_BIF_PREP_ERROR(Ret, Proc, Reason) \
do { \
(Proc)->freason = (Reason); \
(Ret) = THE_NON_VALUE; \
} while (0)
+#define ERTS_BIF_PREP_ERROR_TRAPPED0(Ret, Proc, Reason, Bif) \
+do { \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ (Ret) = THE_NON_VALUE; \
+} while (0)
+
+#define ERTS_BIF_PREP_ERROR_TRAPPED1(Ret, Proc, Reason, Bif, A0) \
+do { \
+ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ reg[0] = (Eterm) (A0); \
+ (Ret) = THE_NON_VALUE; \
+} while (0)
+
+#define ERTS_BIF_PREP_ERROR_TRAPPED2(Ret, Proc, Reason, Bif, A0, A1) \
+do { \
+ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ reg[0] = (Eterm) (A0); \
+ reg[1] = (Eterm) (A1); \
+ (Ret) = THE_NON_VALUE; \
+} while (0)
+
+#define ERTS_BIF_PREP_ERROR_TRAPPED3(Ret, Proc, Reason, Bif, A0, A1, A2) \
+do { \
+ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \
+ (Proc)->freason = (Reason); \
+ (Proc)->current = (Bif)->code; \
+ reg[0] = (Eterm) (A0); \
+ reg[1] = (Eterm) (A1); \
+ reg[2] = (Eterm) (A2); \
+ (Ret) = THE_NON_VALUE; \
+} while (0)
#define ERTS_BIF_PREP_TRAP0(Ret, Trap, Proc) \
do { \
@@ -392,6 +465,51 @@ erts_bif_prep_await_proc_exit_apply_trap(Process *c_p,
Eterm args[],
int nargs);
+#ifndef HIPE
+
+#define HIPE_WRAPPER_BIF_DISABLE_GC(BIF_NAME, ARITY)
+
+#else
+
+#include "erl_fun.h"
+#include "hipe_mode_switch.h"
+
+/*
+ * Hipe wrappers used by native code for BIFs that disable GC while trapping.
+ * Also add usage of the wrapper in ../hipe/hipe_bif_list.m4
+ *
+ * Problem:
+ * When native code calls a BIF that traps, hipe_mode_switch will push a
+ * "trap frame" on the Erlang stack in order to find its way back from beam_emu
+ * back to native caller when finally done. If GC is disabled and stack/heap
+ * is full there is no place to push the "trap frame".
+ *
+ * Solution:
+ * We reserve space on stack for the "trap frame" here before the BIF is called.
+ * If the BIF does not trap, the space is reclaimed here before returning.
+ * If the BIF traps, hipe_push_beam_trap_frame() will detect that a "trap frame"
+ * already is reserved and use it.
+ */
+
+
+#define HIPE_WRAPPER_BIF_DISABLE_GC(BIF_NAME, ARITY) \
+BIF_RETTYPE hipe_wrapper_ ## BIF_NAME ## _ ## ARITY (Process* c_p, \
+ Eterm* args); \
+BIF_RETTYPE hipe_wrapper_ ## BIF_NAME ## _ ## ARITY (Process* c_p, \
+ Eterm* args) \
+{ \
+ BIF_RETTYPE res; \
+ hipe_reserve_beam_trap_frame(c_p, args, ARITY); \
+ res = BIF_NAME ## _ ## ARITY (c_p, args); \
+ if (is_value(res) || c_p->freason != TRAP) { \
+ hipe_unreserve_beam_trap_frame(c_p); \
+ } \
+ return res; \
+}
+
+#endif
+
+
#include "erl_bif_table.h"
#endif
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index fbdddf09db..011e49f1fe 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -45,6 +45,7 @@ bif erlang:apply/3
bif erlang:atom_to_list/1
bif erlang:binary_to_list/1
bif erlang:binary_to_list/3
+bif erlang:binary_to_term/1
bif erlang:crc32/1
bif erlang:crc32/2
bif erlang:crc32_combine/3
@@ -151,8 +152,6 @@ bif erts_internal:port_command/3
bif erts_internal:port_control/3
bif erts_internal:port_close/1
bif erts_internal:port_connect/2
-bif erts_internal:binary_to_term/1
-bif erts_internal:binary_to_term/2
bif erts_internal:request_system_task/3
bif erts_internal:check_process_code/2
@@ -481,6 +480,11 @@ bif erlang:call_on_load_function/1
bif erlang:finish_after_on_load/2
#
+# New Bifs in R13B04
+#
+bif erlang:binary_to_term/2
+
+#
# The binary match bifs (New in R14A - EEP9)
#
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index c7926f18af..f50d484576 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -31,12 +31,11 @@
#include "erl_binary.h"
#include "erl_bits.h"
-#ifdef DEBUG
-static int list_to_bitstr_buf(Eterm obj, char* buf, Uint len);
-#else
-static int list_to_bitstr_buf(Eterm obj, char* buf);
-#endif
-static int bitstr_list_len(Eterm obj, Uint* num_bytes);
+static Export binary_to_list_continue_export;
+static Export list_to_binary_continue_export;
+
+static BIF_RETTYPE binary_to_list_continue(BIF_ALIST_1);
+static BIF_RETTYPE list_to_binary_continue(BIF_ALIST_1);
void
erts_init_binary(void)
@@ -49,6 +48,15 @@ erts_init_binary(void)
"Internal error: Address of orig_bytes[0] of a Binary"
" is *not* 8-byte aligned\n");
}
+
+ erts_init_trap_export(&binary_to_list_continue_export,
+ am_erts_internal, am_binary_to_list_continue, 1,
+ &binary_to_list_continue);
+
+ erts_init_trap_export(&list_to_binary_continue_export,
+ am_erts_internal, am_list_to_binary_continue, 1,
+ &list_to_binary_continue);
+
}
/*
@@ -333,6 +341,132 @@ BIF_RETTYPE integer_to_binary_1(BIF_ALIST_1)
BIF_RET(res);
}
+#define ERTS_B2L_BYTES_PER_REDUCTION 256
+
+typedef struct {
+ Eterm res;
+ Eterm *hp;
+#ifdef DEBUG
+ Eterm *hp_end;
+#endif
+ byte *bytes;
+ Uint size;
+ Uint bitoffs;
+} ErtsB2LState;
+
+static void b2l_state_destructor(Binary *mbp)
+{
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(mbp) == b2l_state_destructor);
+}
+
+static BIF_RETTYPE
+binary_to_list_chunk(Process *c_p,
+ Eterm mb_eterm,
+ ErtsB2LState* sp,
+ int reds_left,
+ int gc_disabled)
+{
+ BIF_RETTYPE ret;
+ int bump_reds;
+ Uint size;
+ byte *bytes;
+
+ size = (reds_left + 1)*ERTS_B2L_BYTES_PER_REDUCTION;
+ if (size > sp->size)
+ size = sp->size;
+ bytes = sp->bytes + (sp->size - size);
+
+ bump_reds = (size - 1)/ERTS_B2L_BYTES_PER_REDUCTION + 1;
+ BUMP_REDS(c_p, bump_reds);
+
+ ASSERT(is_list(sp->res) || is_nil(sp->res));
+
+ sp->res = erts_bin_bytes_to_list(sp->res,
+ sp->hp,
+ bytes,
+ size,
+ sp->bitoffs);
+ sp->size -= size;
+ sp->hp += 2*size;
+
+ if (sp->size > 0) {
+
+ if (!gc_disabled)
+ erts_set_gc_state(c_p, 0);
+
+ ASSERT(c_p->flags & F_DISABLE_GC);
+ ASSERT(is_value(mb_eterm));
+ ERTS_BIF_PREP_TRAP1(ret,
+ &binary_to_list_continue_export,
+ c_p,
+ mb_eterm);
+ }
+ else {
+
+ ASSERT(sp->hp == sp->hp_end);
+ ASSERT(sp->size == 0);
+
+ if (!gc_disabled || !erts_set_gc_state(c_p, 1))
+ ERTS_BIF_PREP_RET(ret, sp->res);
+ else
+ ERTS_BIF_PREP_YIELD_RETURN(ret, c_p, sp->res);
+ ASSERT(!(c_p->flags & F_DISABLE_GC));
+ }
+
+ return ret;
+}
+
+static ERTS_INLINE BIF_RETTYPE
+binary_to_list(Process *c_p, Eterm *hp, Eterm tail, byte *bytes, Uint size, Uint bitoffs)
+{
+ int reds_left = ERTS_BIF_REDS_LEFT(c_p);
+ if (size < reds_left*ERTS_B2L_BYTES_PER_REDUCTION) {
+ Eterm res;
+ BIF_RETTYPE ret;
+ int bump_reds = (size - 1)/ERTS_B2L_BYTES_PER_REDUCTION + 1;
+ BUMP_REDS(c_p, bump_reds);
+ res = erts_bin_bytes_to_list(tail, hp, bytes, size, bitoffs);
+ ERTS_BIF_PREP_RET(ret, res);
+ return ret;
+ }
+ else {
+ Binary *mbp = erts_create_magic_binary(sizeof(ErtsB2LState),
+ b2l_state_destructor);
+ ErtsB2LState *sp = ERTS_MAGIC_BIN_DATA(mbp);
+ Eterm mb;
+
+ sp->res = tail;
+ sp->hp = hp;
+#ifdef DEBUG
+ sp->hp_end = sp->hp + 2*size;
+#endif
+ sp->bytes = bytes;
+ sp->size = size;
+ sp->bitoffs = bitoffs;
+
+ hp = HAlloc(c_p, PROC_BIN_SIZE);
+ mb = erts_mk_magic_binary_term(&hp, &MSO(c_p), mbp);
+ return binary_to_list_chunk(c_p, mb, sp, reds_left, 0);
+ }
+}
+
+static BIF_RETTYPE binary_to_list_continue(BIF_ALIST_1)
+{
+ Binary *mbp = ((ProcBin *) binary_val(BIF_ARG_1))->val;
+
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(mbp) == b2l_state_destructor);
+
+ ASSERT(BIF_P->flags & F_DISABLE_GC);
+
+ return binary_to_list_chunk(BIF_P,
+ BIF_ARG_1,
+ (ErtsB2LState*) ERTS_MAGIC_BIN_DATA(mbp),
+ ERTS_BIF_REDS_LEFT(BIF_P),
+ 1);
+}
+
+HIPE_WRAPPER_BIF_DISABLE_GC(binary_to_list, 1)
+
BIF_RETTYPE binary_to_list_1(BIF_ALIST_1)
{
Eterm real_bin;
@@ -354,14 +488,15 @@ BIF_RETTYPE binary_to_list_1(BIF_ALIST_1)
} else {
Eterm* hp = HAlloc(BIF_P, 2 * size);
byte* bytes = binary_bytes(real_bin)+offset;
-
- BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes, size, bitoffs));
+ return binary_to_list(BIF_P, hp, NIL, bytes, size, bitoffs);
}
error:
BIF_ERROR(BIF_P, BADARG);
}
+HIPE_WRAPPER_BIF_DISABLE_GC(binary_to_list, 3)
+
BIF_RETTYPE binary_to_list_3(BIF_ALIST_3)
{
byte* bytes;
@@ -387,12 +522,13 @@ BIF_RETTYPE binary_to_list_3(BIF_ALIST_3)
}
i = stop-start+1;
hp = HAlloc(BIF_P, 2*i);
- BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes+start-1, i, bitoffs));
-
+ return binary_to_list(BIF_P, hp, NIL, bytes+start-1, i, bitoffs);
error:
BIF_ERROR(BIF_P, BADARG);
}
+HIPE_WRAPPER_BIF_DISABLE_GC(bitstring_to_list, 1)
+
BIF_RETTYPE bitstring_to_list_1(BIF_ALIST_1)
{
Eterm real_bin;
@@ -431,124 +567,441 @@ BIF_RETTYPE bitstring_to_list_1(BIF_ALIST_1)
previous = CONS(hp, make_binary(last), previous);
hp += 2;
}
- BIF_RET(erts_bin_bytes_to_list(previous, hp, bytes, size, bitoffs));
+
+ return binary_to_list(BIF_P, hp, previous, bytes, size, bitoffs);
}
/* Turn a possibly deep list of ints (and binaries) into */
/* One large binary object */
-/*
- * This bif also exists in the binary module, under the name
- * binary:list_to_bin/1, why it's divided into interface and
- * implementation. Also the backend for iolist_to_binary_1.
- */
+typedef enum {
+ ERTS_L2B_OK,
+ ERTS_L2B_YIELD,
+ ERTS_L2B_TYPE_ERROR,
+ ERTS_L2B_OVERFLOW_ERROR
+} ErtsL2BResult;
-BIF_RETTYPE erts_list_to_binary_bif(Process *p, Eterm arg)
-{
+#define ERTS_L2B_STATE_INITER(C_P, ARG, BIF, SZFunc, TBufFunc) \
+ {ERTS_IOLIST2BUF_STATE_INITER((C_P), (ARG)), \
+ (ARG), THE_NON_VALUE, (BIF), (SZFunc), (TBufFunc)}
+
+#define ERTS_L2B_STATE_MOVE(TO, FROM) \
+ sys_memcpy((void *) (TO), (void *) (FROM), sizeof(ErtsL2BState))
+
+typedef struct ErtsL2BState_ ErtsL2BState;
+
+struct ErtsL2BState_ {
+ ErtsIOList2BufState buf;
+ Eterm arg;
Eterm bin;
- Eterm h,t;
- ErlDrvSizeT size;
- byte* bytes;
-#ifdef DEBUG
- ErlDrvSizeT offset;
-#endif
+ Export *bif;
+ int (*iolist_to_buf_size)(ErtsIOListState *);
+ ErlDrvSizeT (*iolist_to_buf)(ErtsIOList2BufState *);
+};
+
+static ERTS_INLINE ErtsL2BResult
+list_to_binary_engine(ErtsL2BState *sp)
+{
+ ErlDrvSizeT res;
+ Process *c_p = sp->buf.iolist.c_p;
+
+ /*
+ * have_size == 0 while sp->iolist_to_buf_size()
+ * has not finished the calculation.
+ */
+
+ if (!sp->buf.iolist.have_size) {
+ switch (sp->iolist_to_buf_size(&sp->buf.iolist)) {
+ case ERTS_IOLIST_YIELD:
+ return ERTS_L2B_YIELD;
+ case ERTS_IOLIST_OVERFLOW:
+ return ERTS_L2B_OVERFLOW_ERROR;
+ case ERTS_IOLIST_TYPE:
+ return ERTS_L2B_TYPE_ERROR;
+ case ERTS_IOLIST_OK:
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ ASSERT(sp->buf.iolist.have_size);
+
+ /*
+ * Size calculated... Setup state for
+ * sp->iolist_to_buf_*()
+ */
+
+ sp->bin = new_binary(c_p,
+ (byte *) NULL,
+ sp->buf.iolist.size);
+
+ if (sp->buf.iolist.size == 0)
+ return ERTS_L2B_OK;
+
+ sp->buf.buf = (char *) binary_bytes(sp->bin);
+ sp->buf.len = sp->buf.iolist.size;
+ sp->buf.iolist.obj = sp->arg;
- if (is_nil(arg)) {
- BIF_RET(new_binary(p,(byte*)"",0));
+ if (sp->buf.iolist.reds_left <= 0) {
+ BUMP_ALL_REDS(c_p);
+ return ERTS_L2B_YIELD;
+ }
}
- if (is_not_list(arg)) {
- goto error;
+
+ ASSERT(sp->buf.iolist.size != 0);
+ ASSERT(is_value(sp->bin));
+ ASSERT(sp->buf.buf);
+
+ res = sp->iolist_to_buf(&sp->buf);
+
+ if (!ERTS_IOLIST_TO_BUF_FAILED(res)) {
+ ASSERT(res == 0);
+ return ERTS_L2B_OK;
}
- /* check for [binary()] case */
- h = CAR(list_val(arg));
- t = CDR(list_val(arg));
- if (is_binary(h) && is_nil(t) && !(
- HEADER_SUB_BIN == *(binary_val(h)) && (
- ((ErlSubBin *)binary_val(h))->bitoffs != 0 ||
- ((ErlSubBin *)binary_val(h))->bitsize != 0
- ))) {
- return h;
- }
- switch (erts_iolist_size(arg, &size)) {
- case ERTS_IOLIST_OVERFLOW: BIF_ERROR(p, SYSTEM_LIMIT);
- case ERTS_IOLIST_TYPE: goto error;
- default: ;
- }
- bin = new_binary(p, (byte *)NULL, size);
- bytes = binary_bytes(bin);
-#ifdef DEBUG
- offset =
-#endif
- erts_iolist_to_buf(arg, (char*) bytes, size);
- ASSERT(offset == 0);
- BIF_RET(bin);
+ switch (res) {
+ case ERTS_IOLIST_TO_BUF_YIELD:
+ return ERTS_L2B_YIELD;
+ case ERTS_IOLIST_TO_BUF_OVERFLOW:
+ return ERTS_L2B_OVERFLOW_ERROR;
+ case ERTS_IOLIST_TO_BUF_TYPE_ERROR:
+ return ERTS_L2B_TYPE_ERROR;
+ default:
+ ERTS_INTERNAL_ERROR("Invalid return value from iolist_to_buf_yielding()");
+ return ERTS_L2B_TYPE_ERROR;
+ }
+}
+
+static void
+l2b_state_destructor(Binary *mbp)
+{
+ ErtsL2BState *sp = ERTS_MAGIC_BIN_DATA(mbp);
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(mbp) == l2b_state_destructor);
+ DESTROY_SAVED_ESTACK(&sp->buf.iolist.estack);
+}
+
+static ERTS_INLINE Eterm
+l2b_final_touch(Process *c_p, ErtsL2BState *sp)
+{
+ Eterm *hp;
+ ErlSubBin* sbin;
+ if (sp->buf.offset == 0)
+ return sp->bin;
+
+ hp = HAlloc(c_p, ERL_SUB_BIN_SIZE);
+ ASSERT(sp->buf.offset > 0);
+ sbin = (ErlSubBin *) hp;
+ sbin->thing_word = HEADER_SUB_BIN;
+ sbin->size = sp->buf.iolist.size-1;
+ sbin->offs = 0;
+ sbin->orig = sp->bin;
+ sbin->bitoffs = 0;
+ sbin->bitsize = sp->buf.offset;
+ sbin->is_writable = 0;
+ return make_binary(sbin);
+}
+
+static BIF_RETTYPE
+list_to_binary_chunk(Eterm mb_eterm,
+ ErtsL2BState* sp,
+ int reds_left,
+ int gc_disabled)
+{
+ Eterm err = BADARG;
+ BIF_RETTYPE ret;
+ Process *c_p = sp->buf.iolist.c_p;
+
+ sp->buf.iolist.reds_left = reds_left;
- error:
- BIF_ERROR(p, BADARG);
+ switch (list_to_binary_engine(sp)) {
+
+ case ERTS_L2B_OK: {
+ Eterm result = l2b_final_touch(c_p, sp);
+ if (!gc_disabled || !erts_set_gc_state(c_p, 1))
+ ERTS_BIF_PREP_RET(ret, result);
+ else
+ ERTS_BIF_PREP_YIELD_RETURN(ret, c_p, result);
+ ASSERT(!(c_p->flags & F_DISABLE_GC));
+ break;
+ }
+ case ERTS_L2B_YIELD:
+ if (!gc_disabled) {
+ /* first yield... */
+ Eterm *hp;
+ Binary *mbp = erts_create_magic_binary(sizeof(ErtsL2BState),
+ l2b_state_destructor);
+ ErtsL2BState *new_sp = ERTS_MAGIC_BIN_DATA(mbp);
+
+ ERTS_L2B_STATE_MOVE(new_sp, sp);
+ sp = new_sp;
+
+ hp = HAlloc(c_p, PROC_BIN_SIZE);
+ mb_eterm = erts_mk_magic_binary_term(&hp, &MSO(c_p), mbp);
+
+ ASSERT(is_value(mb_eterm));
+
+ erts_set_gc_state(c_p, 0);
+ }
+
+ ASSERT(c_p->flags & F_DISABLE_GC);
+
+ ERTS_BIF_PREP_TRAP1(ret,
+ &list_to_binary_continue_export,
+ c_p,
+ mb_eterm);
+ break;
+
+ case ERTS_L2B_OVERFLOW_ERROR:
+ err = SYSTEM_LIMIT;
+ /* fall through */
+
+ case ERTS_L2B_TYPE_ERROR:
+ if (!gc_disabled)
+ ERTS_BIF_PREP_ERROR(ret, c_p, err);
+ else {
+ if (erts_set_gc_state(c_p, 1))
+ ERTS_VBUMP_ALL_REDS(c_p);
+
+ ERTS_BIF_PREP_ERROR_TRAPPED1(ret,
+ c_p,
+ err,
+ sp->bif,
+ sp->arg);
+ }
+
+ ASSERT(!(c_p->flags & F_DISABLE_GC));
+ break;
+
+ default:
+ ERTS_INTERNAL_ERROR("Invalid return value from list_to_binary_engine()");
+ ERTS_BIF_PREP_ERROR(ret,c_p, EXC_INTERNAL_ERROR);
+ break;
+ }
+ return ret;
}
+static BIF_RETTYPE list_to_binary_continue(BIF_ALIST_1)
+{
+ Binary *mbp = ((ProcBin *) binary_val(BIF_ARG_1))->val;
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(mbp) == l2b_state_destructor);
+
+ ASSERT(BIF_P->flags & F_DISABLE_GC);
+
+ return list_to_binary_chunk(BIF_ARG_1,
+ ERTS_MAGIC_BIN_DATA(mbp),
+ ERTS_BIF_REDS_LEFT(BIF_P),
+ 1);
+}
+
+BIF_RETTYPE erts_list_to_binary_bif(Process *c_p, Eterm arg, Export *bif)
+{
+ BIF_RETTYPE ret;
+
+ if (is_nil(arg))
+ ERTS_BIF_PREP_RET(ret, new_binary(c_p, (byte *) "", 0));
+ else if (is_not_list(arg))
+ ERTS_BIF_PREP_ERROR(ret, c_p, BADARG);
+ else {
+ /* check for [binary()] case */
+ Eterm h = CAR(list_val(arg));
+ Eterm t = CDR(list_val(arg));
+ if (is_binary(h)
+ && is_nil(t)
+ && !(HEADER_SUB_BIN == *(binary_val(h))
+ && (((ErlSubBin *)binary_val(h))->bitoffs != 0
+ || ((ErlSubBin *)binary_val(h))->bitsize != 0))) {
+ ERTS_BIF_PREP_RET(ret, h);
+ }
+ else {
+ ErtsL2BState state = ERTS_L2B_STATE_INITER(c_p,
+ arg,
+ bif,
+ erts_iolist_size_yielding,
+ erts_iolist_to_buf_yielding);
+ int orig_reds_left = ERTS_BIF_REDS_LEFT(c_p);
+
+ /*
+ * First try to do it all at once without having to use
+ * yielding iolist_to_buf().
+ */
+ state.buf.iolist.reds_left = orig_reds_left;
+ switch (erts_iolist_size_yielding(&state.buf.iolist)) {
+ case ERTS_IOLIST_OK: {
+ ErlDrvSizeT size = state.buf.iolist.size;
+ Eterm bin;
+ char *buf;
+
+ if (size == 0) {
+ ERTS_BIF_PREP_RET(ret, new_binary(c_p, (byte *) NULL, 0));
+ break; /* done */
+ }
+
+ bin = new_binary(c_p, (byte *) NULL, size);
+ buf = (char *) binary_bytes(bin);
+
+ if (size < ERTS_IOLIST_TO_BUF_BYTES_PER_RED*CONTEXT_REDS) {
+ /* An (over) estimation of reductions needed */
+ int reds_left = state.buf.iolist.reds_left;
+ int to_buf_reds = orig_reds_left - reds_left;
+ to_buf_reds += size/ERTS_IOLIST_TO_BUF_BYTES_PER_RED;
+ if (to_buf_reds <= reds_left) {
+ ErlDrvSizeT res;
+
+ res = erts_iolist_to_buf(arg, buf, size);
+ if (res == 0) {
+ BUMP_REDS(c_p, to_buf_reds);
+ ERTS_BIF_PREP_RET(ret, bin);
+ break; /* done */
+ }
+ if (!ERTS_IOLIST_TO_BUF_FAILED(res))
+ ERTS_INTERNAL_ERROR("iolist_size/iolist_to_buf missmatch");
+ if (res == ERTS_IOLIST_TO_BUF_OVERFLOW)
+ goto overflow;
+ goto type_error;
+ }
+ }
+ /*
+ * Since size has been computed list_to_binary_chunk() expects
+ * state prepared for iolist_to_buf.
+ */
+ state.bin = bin;
+ state.buf.buf = buf;
+ state.buf.len = size;
+ state.buf.iolist.obj = arg;
+ /* Fall through... */
+ }
+ case ERTS_IOLIST_YIELD:
+ ret = list_to_binary_chunk(THE_NON_VALUE,
+ &state,
+ state.buf.iolist.reds_left,
+ 0);
+ break;
+ case ERTS_IOLIST_OVERFLOW:
+ overflow:
+ ERTS_BIF_PREP_ERROR(ret, c_p, SYSTEM_LIMIT);
+ break;
+ case ERTS_IOLIST_TYPE:
+ type_error:
+ default:
+ ERTS_BIF_PREP_ERROR(ret, c_p, BADARG);
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+HIPE_WRAPPER_BIF_DISABLE_GC(list_to_binary, 1)
+
BIF_RETTYPE list_to_binary_1(BIF_ALIST_1)
{
- return erts_list_to_binary_bif(BIF_P, BIF_ARG_1);
+ return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_list_to_binary_1]);
}
-/* Turn a possibly deep list of ints (and binaries) into */
-/* One large binary object */
+HIPE_WRAPPER_BIF_DISABLE_GC(iolist_to_binary, 1)
BIF_RETTYPE iolist_to_binary_1(BIF_ALIST_1)
{
if (is_binary(BIF_ARG_1)) {
BIF_RET(BIF_ARG_1);
}
- return erts_list_to_binary_bif(BIF_P, BIF_ARG_1);
+ return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_iolist_to_binary_1]);
}
+static int bitstr_list_len(ErtsIOListState *);
+static ErlDrvSizeT list_to_bitstr_buf_yielding(ErtsIOList2BufState *);
+static ErlDrvSizeT list_to_bitstr_buf_not_yielding(ErtsIOList2BufState *);
+
+HIPE_WRAPPER_BIF_DISABLE_GC(list_to_bitstring, 1)
+
BIF_RETTYPE list_to_bitstring_1(BIF_ALIST_1)
{
- Eterm bin;
- Uint sz;
- int offset;
- byte* bytes;
- ErlSubBin* sb1;
- Eterm* hp;
-
- if (is_nil(BIF_ARG_1)) {
- BIF_RET(new_binary(BIF_P,(byte*)"",0));
- }
- if (is_not_list(BIF_ARG_1)) {
- error:
- BIF_ERROR(BIF_P, BADARG);
- }
- switch (bitstr_list_len(BIF_ARG_1, &sz)) {
- case ERTS_IOLIST_TYPE:
- goto error;
- case ERTS_IOLIST_OVERFLOW:
- BIF_ERROR(BIF_P, SYSTEM_LIMIT);
- }
- bin = new_binary(BIF_P, (byte *)NULL, sz);
- bytes = binary_bytes(bin);
-#ifdef DEBUG
- offset = list_to_bitstr_buf(BIF_ARG_1, (char*) bytes, sz);
-#else
- offset = list_to_bitstr_buf(BIF_ARG_1, (char*) bytes);
-#endif
- ASSERT(offset >= 0);
- if (offset > 0) {
- hp = HAlloc(BIF_P, ERL_SUB_BIN_SIZE);
- sb1 = (ErlSubBin *) hp;
- sb1->thing_word = HEADER_SUB_BIN;
- sb1->size = sz-1;
- sb1->offs = 0;
- sb1->orig = bin;
- sb1->bitoffs = 0;
- sb1->bitsize = offset;
- sb1->is_writable = 0;
- bin = make_binary(sb1);
+ BIF_RETTYPE ret;
+
+ if (is_nil(BIF_ARG_1))
+ ERTS_BIF_PREP_RET(ret, new_binary(BIF_P, (byte *) "", 0));
+ else if (is_not_list(BIF_ARG_1))
+ ERTS_BIF_PREP_ERROR(ret, BIF_P, BADARG);
+ else {
+ /* check for [bitstring()] case */
+ Eterm h = CAR(list_val(BIF_ARG_1));
+ Eterm t = CDR(list_val(BIF_ARG_1));
+ if (is_binary(h) && is_nil(t)) {
+ ERTS_BIF_PREP_RET(ret, h);
+ }
+ else {
+ ErtsL2BState state = ERTS_L2B_STATE_INITER(BIF_P,
+ BIF_ARG_1,
+ bif_export[BIF_list_to_bitstring_1],
+ bitstr_list_len,
+ list_to_bitstr_buf_yielding);
+ int orig_reds_left = ERTS_BIF_REDS_LEFT(BIF_P);
+
+ /*
+ * First try to do it all at once without having to use
+ * yielding list_to_bitstr_buf().
+ */
+ state.buf.iolist.reds_left = orig_reds_left;
+ switch (bitstr_list_len(&state.buf.iolist)) {
+ case ERTS_IOLIST_OK: {
+ ErlDrvSizeT size = state.buf.iolist.size;
+
+ state.bin = new_binary(BIF_P, (byte *) NULL, size);
+ state.buf.buf = (char *) binary_bytes(state.bin);
+ state.buf.len = size;
+ state.buf.iolist.obj = BIF_ARG_1;
+
+ if (size < ERTS_IOLIST_TO_BUF_BYTES_PER_RED*CONTEXT_REDS) {
+ /* An (over) estimation of reductions needed */
+ int reds_left = state.buf.iolist.reds_left;
+ int to_buf_reds = orig_reds_left - reds_left;
+ to_buf_reds += size/ERTS_IOLIST_TO_BUF_BYTES_PER_RED;
+ if (to_buf_reds <= reds_left) {
+ ErlDrvSizeT res;
+
+ res = list_to_bitstr_buf_not_yielding(&state.buf);
+ if (res == 0) {
+ Eterm res_bin = l2b_final_touch(BIF_P, &state);
+ BUMP_REDS(BIF_P, to_buf_reds);
+ ERTS_BIF_PREP_RET(ret, res_bin);
+ break; /* done */
+ }
+ if (!ERTS_IOLIST_TO_BUF_FAILED(res))
+ ERTS_INTERNAL_ERROR("iolist_size/iolist_to_buf missmatch");
+ if (res == ERTS_IOLIST_TO_BUF_OVERFLOW)
+ goto overflow;
+ goto type_error;
+ }
+ }
+ /*
+ * Since size has been computed list_to_binary_chunk() expects
+ * the state prepared for list_to_bitstr_buf.
+ */
+
+ /* Fall through... */
+ }
+ case ERTS_IOLIST_YIELD:
+ ret = list_to_binary_chunk(THE_NON_VALUE,
+ &state,
+ state.buf.iolist.reds_left,
+ 0);
+ break;
+ case ERTS_IOLIST_OVERFLOW:
+ overflow:
+ ERTS_BIF_PREP_ERROR(ret, BIF_P, SYSTEM_LIMIT);
+ break;
+ case ERTS_IOLIST_TYPE:
+ type_error:
+ default:
+ ERTS_BIF_PREP_ERROR(ret, BIF_P, BADARG);
+ break;
+ }
+ }
}
-
- BIF_RET(bin);
+
+ return ret;
}
BIF_RETTYPE split_binary_2(BIF_ALIST_2)
@@ -605,123 +1058,353 @@ BIF_RETTYPE split_binary_2(BIF_ALIST_2)
* Local functions.
*/
+static int
+list_to_bitstr_buf_bcopy(ErtsIOList2BufState *state, Eterm obj, int *yield_countp);
+
/*
* The input list is assumed to be type-correct and the buffer is
* assumed to be of sufficient size. Those assumptions are verified in
* the DEBUG-built emulator.
*/
-static int
+static ErlDrvSizeT
+list_to_bitstr_buf(int yield_support, ErtsIOList2BufState *state)
+{
+
+#undef LIST_TO_BITSTR_BUF_BCOPY_DBG
+#undef LIST_TO_BITSTR_BUF_BCOPY
#ifdef DEBUG
-list_to_bitstr_buf(Eterm obj, char* buf, Uint len)
+#define LIST_TO_BITSTR_BUF_BCOPY_DBG \
+ len -= size + (offset>7);
#else
-list_to_bitstr_buf(Eterm obj, char* buf)
+#define LIST_TO_BITSTR_BUF_BCOPY_DBG
#endif
-{
- Eterm* objp;
- int offset = 0;
+#define LIST_TO_BITSTR_BUF_BCOPY(CONSP) \
+ do { \
+ byte* bptr; \
+ Uint bitsize; \
+ Uint bitoffs; \
+ Uint num_bits; \
+ size_t size = binary_size(obj); \
+ if (yield_support) { \
+ size_t max_size = ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT; \
+ if (yield_count > 0) \
+ max_size *= yield_count+1; \
+ if (size > max_size) { \
+ state->objp = CONSP; \
+ goto L_bcopy_yield; \
+ } \
+ if (size >= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT) { \
+ int cost = (int) size; \
+ cost /= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT; \
+ yield_count -= cost; \
+ } \
+ } \
+ ASSERT(size <= len); \
+ ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize); \
+ num_bits = 8*size+bitsize; \
+ copy_binary_to_buffer(buf, offset, bptr, bitoffs, num_bits); \
+ offset += bitsize; \
+ buf += size + (offset>7); \
+ LIST_TO_BITSTR_BUF_BCOPY_DBG; \
+ offset = offset & 7; \
+ } while(0)
+
+#ifdef DEBUG
+ ErlDrvSizeT len;
+#endif
+ Eterm obj;
+ char *buf;
+ Eterm *objp = NULL;
+ int offset;
+ int init_yield_count = 0, yield_count;
DECLARE_ESTACK(s);
- goto L_again;
-
- while (!ESTACK_ISEMPTY(s)) {
- obj = ESTACK_POP(s);
- L_again:
- if (is_list(obj)) {
- L_iter_list:
- objp = list_val(obj);
- obj = CAR(objp);
- if (is_byte(obj)) {
- ASSERT(len > 0);
- if (offset == 0) {
- *buf++ = unsigned_val(obj);
- } else {
- *buf = (char)((unsigned_val(obj) >> offset) |
- ((*buf >> (8-offset)) << (8-offset)));
- buf++;
- *buf = (unsigned_val(obj) << (8-offset));
- }
+
+ obj = state->iolist.obj;
+ buf = state->buf;
+ offset = state->offset;
#ifdef DEBUG
- len--;
+ len = state->len;
#endif
- } else if (is_binary(obj)) {
- byte* bptr;
- size_t size = binary_size(obj);
- Uint bitsize;
- Uint bitoffs;
- Uint num_bits;
-
- ASSERT(size <= len);
- ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
- num_bits = 8*size+bitsize;
- copy_binary_to_buffer(buf, offset, bptr, bitoffs, num_bits);
- offset += bitsize;
- buf += size + (offset>7);
+
+ if (!yield_support) {
+ yield_count = init_yield_count = 0; /* Shut up faulty warning... >:-( */
+ goto L_again;
+ }
+ else {
+
+ if (state->iolist.reds_left <= 0)
+ return ERTS_IOLIST_TO_BUF_YIELD;
+
+ ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
+ init_yield_count = (ERTS_IOLIST_TO_BUF_YIELD_COUNT_PER_RED
+ * state->iolist.reds_left);
+ yield_count = init_yield_count;
+
+ if (!state->iolist.estack.start)
+ goto L_again;
+ else {
+ int chk_stack;
+ /* Restart; restore state... */
+ ESTACK_RESTORE(s, &state->iolist.estack);
+
+ if (!state->bcopy.bptr)
+ chk_stack = 0;
+ else {
+ chk_stack = 1;
+ if (list_to_bitstr_buf_bcopy(state, THE_NON_VALUE, &yield_count)) {
+ /* Yield again... */
+ BUMP_ALL_REDS(state->iolist.c_p);
+ state->iolist.reds_left = 0;
+ ESTACK_SAVE(s, &state->iolist.estack);
+ return ERTS_IOLIST_TO_BUF_YIELD;
+ }
+ buf = state->buf;
+ offset = state->offset;
#ifdef DEBUG
- len -= size + (offset>7);
+ len = state->len;
#endif
- offset = offset & 7;
- } else if (is_list(obj)) {
- ESTACK_PUSH(s, CDR(objp));
- goto L_iter_list; /* on head */
- } else {
- ASSERT(is_nil(obj));
}
- obj = CDR(objp);
- if (is_list(obj)) {
- goto L_iter_list; /* on tail */
- } else if (is_binary(obj)) {
- byte* bptr;
- size_t size = binary_size(obj);
- Uint bitsize;
- Uint bitoffs;
- Uint num_bits;
-
- ASSERT(size <= len);
- ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
- num_bits = 8*size+bitsize;
- copy_binary_to_buffer(buf, offset, bptr, bitoffs, num_bits);
- offset += bitsize;
- buf += size+(offset>7);
+ objp = state->objp;
+ state->objp = NULL;
+
+ if (objp)
+ goto L_tail;
+ if (!chk_stack)
+ goto L_again;
+ /* check stack */
+ }
+ }
+
+ while (!ESTACK_ISEMPTY(s)) {
+ obj = ESTACK_POP(s);
+ L_again:
+ if (is_list(obj)) {
+ while (1) { /* Tail loop */
+ while (1) { /* Head loop */
+ if (yield_support && --yield_count <= 0)
+ goto L_yield;
+ objp = list_val(obj);
+ obj = CAR(objp);
+ if (is_byte(obj)) {
+ ASSERT(len > 0);
+ if (offset == 0) {
+ *buf++ = unsigned_val(obj);
+ } else {
+ *buf = (char)((unsigned_val(obj) >> offset) |
+ ((*buf >> (8-offset)) << (8-offset)));
+ buf++;
+ *buf = (unsigned_val(obj) << (8-offset));
+ }
#ifdef DEBUG
- len -= size+(offset>7);
+ len--;
#endif
- offset = offset & 7;
- } else {
- ASSERT(is_nil(obj));
+ } else if (is_binary(obj)) {
+ LIST_TO_BITSTR_BUF_BCOPY(objp);
+ } else if (is_list(obj)) {
+ ESTACK_PUSH(s, CDR(objp));
+ continue; /* Head loop */
+ } else {
+ ASSERT(is_nil(obj));
+ }
+ break;
+ }
+
+ L_tail:
+
+ obj = CDR(objp);
+ if (is_list(obj)) {
+ continue; /* Tail loop */
+ } else if (is_binary(obj)) {
+ LIST_TO_BITSTR_BUF_BCOPY(NULL);
+ } else {
+ ASSERT(is_nil(obj));
+ }
+ break;
}
} else if (is_binary(obj)) {
- byte* bptr;
- size_t size = binary_size(obj);
- Uint bitsize;
- Uint bitoffs;
- Uint num_bits;
-
- ASSERT(size <= len);
- ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
- num_bits = 8*size+bitsize;
- copy_binary_to_buffer(buf, offset, bptr, bitoffs, num_bits);
- offset += bitsize;
- buf += size + (offset>7);
-#ifdef DEBUG
- len -= size + (offset>7);
-#endif
- offset = offset & 7;
+ LIST_TO_BITSTR_BUF_BCOPY(NULL);
} else {
+ if (yield_support && --yield_count <= 0)
+ goto L_yield;
ASSERT(is_nil(obj));
}
}
DESTROY_ESTACK(s);
- return offset;
+
+ if (yield_support) {
+ int reds;
+ CLEAR_SAVED_ESTACK(&state->iolist.estack);
+ reds = ((init_yield_count - yield_count - 1)
+ / ERTS_IOLIST_TO_BUF_YIELD_COUNT_PER_RED) + 1;
+ BUMP_REDS(state->iolist.c_p, reds);
+ state->iolist.reds_left -= reds;
+ if (state->iolist.reds_left < 0)
+ state->iolist.reds_left = 0;
+ }
+ state->buf = buf;
+ state->offset = offset;
+ return 0;
+
+L_bcopy_yield:
+
+ state->buf = buf;
+ state->offset = offset;
+#ifdef DEBUG
+ state->len = len;
+#endif
+
+ if (list_to_bitstr_buf_bcopy(state, obj, &yield_count) == 0)
+ ERTS_INTERNAL_ERROR("Missing yield");
+
+ BUMP_ALL_REDS(state->iolist.c_p);
+ state->iolist.reds_left = 0;
+ ESTACK_SAVE(s, &state->iolist.estack);
+ return ERTS_IOLIST_TO_BUF_YIELD;
+
+L_yield:
+
+ BUMP_ALL_REDS(state->iolist.c_p);
+ state->iolist.reds_left = 0;
+ state->iolist.obj = obj;
+ state->buf = buf;
+ state->offset = offset;
+ ESTACK_SAVE(s, &state->iolist.estack);
+#ifdef DEBUG
+ state->len = len;
+#endif
+ return ERTS_IOLIST_TO_BUF_YIELD;
+
+
+#undef LIST_TO_BITSTR_BUF_BCOPY_DBG
+#undef LIST_TO_BITSTR_BUF_BCOPY
+
+}
+
+static ErlDrvSizeT
+list_to_bitstr_buf_yielding(ErtsIOList2BufState *state)
+{
+ return list_to_bitstr_buf(1, state);
+}
+
+static ErlDrvSizeT
+list_to_bitstr_buf_not_yielding(ErtsIOList2BufState *state)
+{
+ return list_to_bitstr_buf(0, state);
}
static int
-bitstr_list_len(Eterm obj, Uint* num_bytes)
+list_to_bitstr_buf_bcopy(ErtsIOList2BufState *state, Eterm obj, int *yield_countp)
+{
+ int res;
+ char *buf = state->buf;
+ char *next_buf;
+ int offset = state->offset;
+ int next_offset;
+#ifdef DEBUG
+ ErlDrvSizeT len = state->len;
+ ErlDrvSizeT next_len;
+#endif
+ byte* bptr;
+ size_t size;
+ size_t max_size;
+ Uint bitoffs;
+ Uint num_bits;
+ Uint bitsize;
+ int yield_count = *yield_countp;
+
+ if (state->bcopy.bptr) {
+ bptr = state->bcopy.bptr;
+ size = state->bcopy.size;
+ bitoffs = state->bcopy.bitoffs;
+ bitsize = state->bcopy.bitsize;
+ state->bcopy.bptr = NULL;
+ }
+ else {
+
+ ASSERT(is_binary(obj));
+
+ size = binary_size(obj);
+
+ ASSERT(size <= len);
+
+ ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
+ }
+
+ max_size = (size_t) ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT;
+ if (yield_count > 0)
+ max_size *= (size_t) (yield_count+1);
+
+ if (size <= max_size) {
+ if (size >= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT) {
+ int cost = (int) size;
+ cost /= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT;
+ yield_count -= cost;
+ }
+ next_offset = offset + bitsize;
+ next_buf = buf + size+(next_offset>7);
+#ifdef DEBUG
+ next_len = len - size+(next_offset>7);
+#endif
+ next_offset &= 7;
+ num_bits = 8*size+bitsize;
+ res = 0;
+ }
+ else {
+ ASSERT(0 < max_size && max_size < size);
+ yield_count = 0;
+ state->bcopy.bptr = bptr + max_size;
+ state->bcopy.bitoffs = bitoffs;
+ state->bcopy.bitsize = bitsize;
+ state->bcopy.size = size - max_size;
+ next_buf = buf + max_size;
+#ifdef DEBUG
+ next_len = len - max_size;
+#endif
+ next_offset = offset;
+ num_bits = 8*max_size;
+ size = max_size;
+ res = 1;
+ }
+
+ copy_binary_to_buffer(buf, offset, bptr, bitoffs, num_bits);
+
+ state->offset = next_offset;
+ state->buf = next_buf;
+#ifdef DEBUG
+ state->len = next_len;
+#endif
+ *yield_countp = yield_count;
+
+ return res;
+}
+
+static int
+bitstr_list_len(ErtsIOListState *state)
{
Eterm* objp;
- Uint len = 0;
- Uint offs = 0;
+ Eterm obj;
+ Uint len, offs;
+ int res, init_yield_count, yield_count;
DECLARE_ESTACK(s);
+
+ if (state->reds_left <= 0)
+ return ERTS_IOLIST_YIELD;
+
+ len = (Uint) state->size;
+ offs = state->offs;
+ obj = state->obj;
+
+ ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
+ init_yield_count = ERTS_IOLIST_SIZE_YIELDS_COUNT_PER_RED;
+ init_yield_count *= state->reds_left;
+ yield_count = init_yield_count;
+ if (state->estack.start) {
+ /* Restart; restore estack... */
+ ESTACK_RESTORE(s, &state->estack);
+ }
+
goto L_again;
#define SAFE_ADD(Var, Val) \
@@ -748,46 +1431,55 @@ bitstr_list_len(Eterm obj, Uint* num_bytes)
obj = ESTACK_POP(s);
L_again:
if (is_list(obj)) {
- L_iter_list:
- objp = list_val(obj);
- /* Head */
- obj = CAR(objp);
- if (is_byte(obj)) {
- len++;
- if (len == 0) {
- goto L_overflow_error;
+ while (1) { /* Tail loop */
+ while (1) { /* Head loop */
+ if (--yield_count <= 0)
+ goto L_yield;
+ objp = list_val(obj);
+ /* Head */
+ obj = CAR(objp);
+ if (is_byte(obj)) {
+ len++;
+ if (len == 0) {
+ goto L_overflow_error;
+ }
+ } else if (is_binary(obj)) {
+ SAFE_ADD(len, binary_size(obj));
+ SAFE_ADD_BITSIZE(offs, obj);
+ } else if (is_list(obj)) {
+ ESTACK_PUSH(s, CDR(objp));
+ continue; /* Head loop */
+ } else if (is_not_nil(obj)) {
+ goto L_type_error;
+ }
+ break;
}
- } else if (is_binary(obj)) {
- SAFE_ADD(len, binary_size(obj));
- SAFE_ADD_BITSIZE(offs, obj);
- } else if (is_list(obj)) {
- ESTACK_PUSH(s, CDR(objp));
- goto L_iter_list; /* on head */
- } else if (is_not_nil(obj)) {
- goto L_type_error;
+ /* Tail */
+ obj = CDR(objp);
+ if (is_list(obj))
+ continue; /* Tail loop */
+ else if (is_binary(obj)) {
+ SAFE_ADD(len, binary_size(obj));
+ SAFE_ADD_BITSIZE(offs, obj);
+ } else if (is_not_nil(obj)) {
+ goto L_type_error;
+ }
+ break;
}
- /* Tail */
- obj = CDR(objp);
- if (is_list(obj))
- goto L_iter_list; /* on tail */
- else if (is_binary(obj)) {
+ } else {
+ if (--yield_count <= 0)
+ goto L_yield;
+ if (is_binary(obj)) {
SAFE_ADD(len, binary_size(obj));
SAFE_ADD_BITSIZE(offs, obj);
} else if (is_not_nil(obj)) {
goto L_type_error;
}
- } else if (is_binary(obj)) {
- SAFE_ADD(len, binary_size(obj));
- SAFE_ADD_BITSIZE(offs, obj);
- } else if (is_not_nil(obj)) {
- goto L_type_error;
}
}
#undef SAFE_ADD
#undef SAFE_ADD_BITSIZE
- DESTROY_ESTACK(s);
-
/*
* Make sure that the number of bits in the bitstring will fit
* in an Uint to ensure that the binary can be matched using
@@ -800,15 +1492,42 @@ bitstr_list_len(Eterm obj, Uint* num_bytes)
if (len << 3 < len) {
goto L_overflow_error;
}
- *num_bytes = len;
- return ERTS_IOLIST_OK;
+ state->size = len;
- L_type_error:
- DESTROY_ESTACK(s);
- return ERTS_IOLIST_TYPE;
+ res = ERTS_IOLIST_OK;
+
+ L_return: {
+ int yc = init_yield_count - yield_count;
+ int reds;
+
+ DESTROY_ESTACK(s);
+ CLEAR_SAVED_ESTACK(&state->estack);
+
+ reds = (yc - 1)/ERTS_IOLIST_SIZE_YIELDS_COUNT_PER_RED + 1;
+ BUMP_REDS(state->c_p, reds);
+ state->reds_left -= reds;
+ state->size = (ErlDrvSizeT) len;
+ state->have_size = 1;
+ return res;
+ }
L_overflow_error:
- DESTROY_ESTACK(s);
- return ERTS_IOLIST_OVERFLOW;
+ res = ERTS_IOLIST_OVERFLOW;
+ len = 0;
+ goto L_return;
+
+ L_type_error:
+ res = ERTS_IOLIST_TYPE;
+ len = 0;
+ goto L_return;
+
+ L_yield:
+ BUMP_ALL_REDS(state->c_p);
+ state->reds_left = 0;
+ state->size = len;
+ state->offs = offs;
+ state->obj = obj;
+ ESTACK_SAVE(s, &state->estack);
+ return ERTS_IOLIST_YIELD;
}
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 45f0cc4312..a4e164bf51 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -3274,6 +3274,15 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
ASSERT(!(flags & CFLG_FORCE_MSEG && flags & CFLG_FORCE_SYS_ALLOC));
+ if (umem_sz > (ERTS_UINT_MAX - ERTS_UINT_MAX/100)) {
+ /* Do an overly conservative _overflow_ check here so we don't
+ * have to deal with it from here on. I guess we could be more accurate
+ * but I don't think the need to allocate over 99% of the address space
+ * will ever arise on any machine, neither 32 nor 64 bit.
+ */
+ return NULL;
+ }
+
blk_sz = UMEMSZ2BLKSZ(allctr, umem_sz);
#ifdef ERTS_SMP
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index ff775691b3..7e0e825a0d 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -2294,18 +2294,11 @@ BIF_RETTYPE binary_bin_to_list_1(BIF_ALIST_1)
BIF_ERROR(BIF_P,BADARG);
}
-/*
- * Ok, erlang:list_to_binary does not interrupt, and we really don't want
- * an alternative implementation for the exact same thing, why we
- * have descided to use the old non-restarting implementation for now.
- * In reality, there are seldom many iterations involved in doing this, so the
- * problem of long-running bifs is not really that big in this case.
- * So, for now we use the old implementation also in the module binary.
- */
+HIPE_WRAPPER_BIF_DISABLE_GC(binary_list_to_bin, 1)
BIF_RETTYPE binary_list_to_bin_1(BIF_ALIST_1)
{
- return erts_list_to_binary_bif(BIF_P, BIF_ARG_1);
+ return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_binary_list_to_bin_1]);
}
typedef struct {
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 2adba9b240..6915765dab 100755..100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -2691,6 +2691,11 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
else if (ERTS_IS_ATOM_STR("ets_limit",BIF_ARG_1)) {
BIF_RET(make_small(erts_db_get_max_tabs()));
}
+ else if (ERTS_IS_ATOM_STR("tolerant_timeofday",BIF_ARG_1)) {
+ BIF_RET(erts_disable_tolerant_timeofday
+ ? am_disabled
+ : am_enabled);
+ }
BIF_ERROR(BIF_P, BADARG);
}
@@ -3851,16 +3856,19 @@ static Eterm lcnt_build_lock_stats_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_s
Uint tries = 0, colls = 0;
unsigned long timer_s = 0, timer_ns = 0, timer_n = 0;
unsigned int line = 0;
+ unsigned int i;
Eterm af, uil;
Eterm uit, uic;
Eterm uits, uitns, uitn;
Eterm tt, tstat, tloc, t;
+ Eterm thist, vhist[ERTS_LCNT_HISTOGRAM_SLOT_SIZE];
/* term:
- * [{{file, line}, {tries, colls, {seconds, nanoseconds, n_blocks}}}]
+ * [{{file, line}, {tries, colls, {seconds, nanoseconds, n_blocks}},
+ * { .. histogram .. }]
*/
-
+
tries = (Uint) ethr_atomic_read(&stats->tries);
colls = (Uint) ethr_atomic_read(&stats->colls);
@@ -3869,23 +3877,27 @@ static Eterm lcnt_build_lock_stats_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_s
timer_ns = stats->timer.ns;
timer_n = stats->timer_n;
- af = erts_atom_put(stats->file, strlen(stats->file), ERTS_ATOM_ENC_LATIN1, 1);
+ af = erts_atom_put((byte *)stats->file, strlen(stats->file), ERTS_ATOM_ENC_LATIN1, 1);
uil = erts_bld_uint( hpp, szp, line);
tloc = erts_bld_tuple(hpp, szp, 2, af, uil);
- uit = erts_bld_uint( hpp, szp, tries);
- uic = erts_bld_uint( hpp, szp, colls);
-
+ uit = erts_bld_uint( hpp, szp, tries);
+ uic = erts_bld_uint( hpp, szp, colls);
+
uits = erts_bld_uint( hpp, szp, timer_s);
uitns = erts_bld_uint( hpp, szp, timer_ns);
uitn = erts_bld_uint( hpp, szp, timer_n);
tt = erts_bld_tuple(hpp, szp, 3, uits, uitns, uitn);
tstat = erts_bld_tuple(hpp, szp, 3, uit, uic, tt);
-
- t = erts_bld_tuple(hpp, szp, 2, tloc, tstat);
-
- res = erts_bld_cons( hpp, szp, t, res);
+
+ for(i = 0; i < ERTS_LCNT_HISTOGRAM_SLOT_SIZE; i++) {
+ vhist[i] = erts_bld_uint(hpp, szp, stats->hist.ns[i]);
+ }
+ thist = erts_bld_tuplev(hpp, szp, ERTS_LCNT_HISTOGRAM_SLOT_SIZE, vhist);
+
+ t = erts_bld_tuple(hpp, szp, 3, tloc, tstat, thist);
+ res = erts_bld_cons( hpp, szp, t, res);
return res;
}
@@ -3906,13 +3918,13 @@ static Eterm lcnt_build_lock_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_t *lock
ASSERT(ltype);
- type = erts_atom_put(ltype, strlen(ltype), ERTS_ATOM_ENC_LATIN1, 1);
- name = erts_atom_put(lock->name, strlen(lock->name), ERTS_ATOM_ENC_LATIN1, 1);
+ type = erts_atom_put((byte *)ltype, strlen(ltype), ERTS_ATOM_ENC_LATIN1, 1);
+ name = erts_atom_put((byte *)lock->name, strlen(lock->name), ERTS_ATOM_ENC_LATIN1, 1);
if (lock->flag & ERTS_LCNT_LT_ALLOC) {
/* use allocator types names as id's for allocator locks */
ltype = (char *) ERTS_ALC_A2AD(signed_val(lock->id));
- id = erts_atom_put(ltype, strlen(ltype), ERTS_ATOM_ENC_LATIN1, 1);
+ id = erts_atom_put((byte *)ltype, strlen(ltype), ERTS_ATOM_ENC_LATIN1, 1);
} else if (lock->flag & ERTS_LCNT_LT_PROCLOCK) {
/* use registered names as id's for process locks if available */
proc = erts_proc_lookup(lock->id);
@@ -3923,16 +3935,15 @@ static Eterm lcnt_build_lock_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_t *lock
id = lock->id;
}
} else {
- id = lock->id;
+ id = lock->id;
}
-
+
for (i = 0; i < lock->n_stats; i++) {
stats = lcnt_build_lock_stats_term(hpp, szp, &(lock->stats[i]), stats);
}
-
- t = erts_bld_tuple(hpp, szp, 4, name, id, type, stats);
-
- res = erts_bld_cons( hpp, szp, t, res);
+
+ t = erts_bld_tuple(hpp, szp, 4, name, id, type, stats);
+ res = erts_bld_cons( hpp, szp, t, res);
return res;
}
@@ -3952,12 +3963,12 @@ static Eterm lcnt_build_result_term(Eterm **hpp, Uint *szp, erts_lcnt_data_t *da
dtns = erts_bld_uint( hpp, szp, data->duration.ns);
tdt = erts_bld_tuple(hpp, szp, 2, dts, dtns);
- adur = erts_atom_put(str_duration, strlen(str_duration), ERTS_ATOM_ENC_LATIN1, 1);
+ adur = erts_atom_put((byte *)str_duration, strlen(str_duration), ERTS_ATOM_ENC_LATIN1, 1);
tdur = erts_bld_tuple(hpp, szp, 2, adur, tdt);
/* lock tuple */
- aloc = erts_atom_put(str_locks, strlen(str_locks), ERTS_ATOM_ENC_LATIN1, 1);
+ aloc = erts_atom_put((byte *)str_locks, strlen(str_locks), ERTS_ATOM_ENC_LATIN1, 1);
for (lock = data->current_locks->head; lock != NULL ; lock = lock->next ) {
lloc = lcnt_build_lock_term(hpp, szp, lock, lloc);
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index 819b19e566..06dfeb1260 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -166,7 +166,7 @@ Eterm erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size,
* Common implementation for erlang:list_to_binary/1 and binary:list_to_bin/1
*/
-BIF_RETTYPE erts_list_to_binary_bif(Process *p, Eterm arg);
+BIF_RETTYPE erts_list_to_binary_bif(Process *p, Eterm arg, Export *bif);
BIF_RETTYPE erts_gc_binary_part(Process *p, Eterm *reg, Eterm live, int range_is_tuple);
BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen);
@@ -236,6 +236,8 @@ erts_bin_drv_alloc_fnf(Uint size)
{
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
void *res;
+ if (bsize < size) /* overflow */
+ return NULL;
res = erts_alloc_fnf(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
return (Binary *) res;
@@ -246,6 +248,8 @@ erts_bin_drv_alloc(Uint size)
{
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
void *res;
+ if (bsize < size) /* overflow */
+ erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, size);
res = erts_alloc(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
return (Binary *) res;
@@ -257,6 +261,8 @@ erts_bin_nrml_alloc(Uint size)
{
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
void *res;
+ 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);
return (Binary *) res;
@@ -267,11 +273,12 @@ erts_bin_realloc_fnf(Binary *bp, Uint size)
{
Binary *nbp;
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
+ ErtsAlcType_t type = (bp->flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY
+ : ERTS_ALC_T_BINARY;
ASSERT((bp->flags & BIN_FLAG_MAGIC) == 0);
- if (bp->flags & BIN_FLAG_DRV)
- nbp = erts_realloc_fnf(ERTS_ALC_T_DRV_BINARY, (void *) bp, bsize);
- else
- nbp = erts_realloc_fnf(ERTS_ALC_T_BINARY, (void *) bp, bsize);
+ if (bsize < size) /* overflow */
+ return NULL;
+ nbp = erts_realloc_fnf(type, (void *) bp, bsize);
ERTS_CHK_BIN_ALIGNMENT(nbp);
return nbp;
}
@@ -281,17 +288,14 @@ erts_bin_realloc(Binary *bp, Uint size)
{
Binary *nbp;
Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
+ ErtsAlcType_t type = (bp->flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY
+ : ERTS_ALC_T_BINARY;
ASSERT((bp->flags & BIN_FLAG_MAGIC) == 0);
- if (bp->flags & BIN_FLAG_DRV)
- nbp = erts_realloc_fnf(ERTS_ALC_T_DRV_BINARY, (void *) bp, bsize);
- else
- nbp = erts_realloc_fnf(ERTS_ALC_T_BINARY, (void *) bp, bsize);
+ if (bsize < size) /* overflow */
+ erts_realloc_enomem(type, bp, size);
+ nbp = erts_realloc_fnf(type, (void *) bp, bsize);
if (!nbp)
- erts_realloc_n_enomem(ERTS_ALC_T2N(bp->flags & BIN_FLAG_DRV
- ? ERTS_ALC_T_DRV_BINARY
- : ERTS_ALC_T_BINARY),
- bp,
- bsize);
+ erts_realloc_enomem(type, bp, bsize);
ERTS_CHK_BIN_ALIGNMENT(nbp);
return nbp;
}
@@ -312,6 +316,7 @@ erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
{
Uint bsize = ERTS_MAGIC_BIN_SIZE(size);
Binary* bptr = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize);
+ ASSERT(bsize > size);
if (!bptr)
erts_alloc_n_enomem(ERTS_ALC_T2N(ERTS_ALC_T_BINARY), bsize);
ERTS_CHK_BIN_ALIGNMENT(bptr);
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index d54658f1ea..5e6d812242 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -324,7 +324,6 @@ erl_init(int ncpu,
BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0);
erts_init_trace();
- erts_init_binary();
erts_init_bits();
erts_code_ix_init();
erts_init_fun_table();
@@ -337,6 +336,7 @@ erl_init(int ncpu,
erts_ddll_init();
init_emulator();
erts_ptab_init(); /* Must be after init_emulator() */
+ erts_init_binary(); /* Must be after init_emulator() */
erts_bp_init();
init_db(); /* Must be after init_emulator */
erts_bif_timer_init();
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index c13eb87012..c665aa51a2 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -227,8 +227,7 @@ rw_op_str(Uint16 flags)
case ERTS_LC_FLG_LO_READ:
return " (r)";
case ERTS_LC_FLG_LO_WRITE:
- erts_fprintf(stderr, "\nInternal error\n");
- lc_abort();
+ ERTS_INTERNAL_ERROR("Only write flag present");
default:
break;
}
@@ -311,8 +310,7 @@ static ERTS_INLINE void lc_free(void *p)
static void *lc_core_alloc(void)
{
lc_unlock();
- erts_fprintf(stderr, "Lock checker out of memory!\n");
- lc_abort();
+ ERTS_INTERNAL_ERROR("Lock checker out of memory!\n");
}
#else
@@ -325,8 +323,7 @@ static void *lc_core_alloc(void)
fbs = (erts_lc_free_block_t *) malloc(sizeof(erts_lc_free_block_t)
* ERTS_LC_FB_CHUNK_SIZE);
if (!fbs) {
- erts_fprintf(stderr, "Lock checker failed to allocate memory!\n");
- lc_abort();
+ ERTS_INTERNAL_ERROR("Lock checker failed to allocate memory!");
}
for (i = 1; i < ERTS_LC_FB_CHUNK_SIZE - 1; i++) {
#ifdef DEBUG
@@ -366,11 +363,11 @@ create_locked_locks(char *thread_name)
{
erts_lc_locked_locks_t *l_lcks = malloc(sizeof(erts_lc_locked_locks_t));
if (!l_lcks)
- lc_abort();
+ ERTS_INTERNAL_ERROR("Lock checker failed to allocate memory!");
l_lcks->thread_name = strdup(thread_name ? thread_name : "unknown");
if (!l_lcks->thread_name)
- lc_abort();
+ ERTS_INTERNAL_ERROR("Lock checker failed to allocate memory!");
l_lcks->emu_thread = 0;
l_lcks->tid = erts_thr_self();
@@ -691,7 +688,7 @@ erts_lc_set_thread_name(char *thread_name)
free((void *) l_lcks->thread_name);
l_lcks->thread_name = strdup(thread_name ? thread_name : "unknown");
if (!l_lcks->thread_name)
- lc_abort();
+ ERTS_INTERNAL_ERROR("strdup failed");
}
l_lcks->emu_thread = 1;
}
@@ -1330,7 +1327,7 @@ erts_lc_init(void)
#endif /* #ifdef ERTS_LC_STATIC_ALLOC */
if (ethr_spinlock_init(&free_blocks_lock) != 0)
- lc_abort();
+ ERTS_INTERNAL_ERROR("spinlock_init failed");
erts_tsd_key_create(&locks_key,"erts_lock_check_key");
}
diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index 6f44bf097b..cf6996ea06 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -61,6 +61,25 @@ static ERTS_INLINE void lcnt_unlock(void) {
ethr_mutex_unlock(&lcnt_data_lock);
}
+const int log2_tab64[64] = {
+ 63, 0, 58, 1, 59, 47, 53, 2,
+ 60, 39, 48, 27, 54, 33, 42, 3,
+ 61, 51, 37, 40, 49, 18, 28, 20,
+ 55, 30, 34, 11, 43, 14, 22, 4,
+ 62, 57, 46, 52, 38, 26, 32, 41,
+ 50, 36, 17, 19, 29, 10, 13, 21,
+ 56, 45, 25, 31, 35, 16, 9, 12,
+ 44, 24, 15, 8, 23, 7, 6, 5};
+
+static ERTS_INLINE int lcnt_log2(Uint64 v) {
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v |= v >> 32;
+ return log2_tab64[((Uint64)((v - (v >> 1))*0x07EDD5E59A4E28C2)) >> 58];
+}
static char* lcnt_lock_type(Uint16 flag) {
switch(flag & ERTS_LCNT_LT_ALL) {
@@ -81,19 +100,20 @@ static void lcnt_clear_stats(erts_lcnt_lock_stats_t *stats) {
stats->timer_n = 0;
stats->file = (char *)str_undefined;
stats->line = 0;
+ sys_memzero(stats->hist.ns, sizeof(stats->hist.ns));
}
static void lcnt_time(erts_lcnt_time_t *time) {
-#ifdef HAVE_GETHRTIME
+#if 0 || defined(HAVE_GETHRTIME)
SysHrTime hr_time;
hr_time = sys_gethrtime();
time->s = (unsigned long)(hr_time / 1000000000LL);
time->ns = (unsigned long)(hr_time - 1000000000LL*time->s);
-#else
- SysTimeval tv;
- sys_gettimeofday(&tv);
- time->s = tv.tv_sec;
- time->ns = tv.tv_usec*1000LL;
+#else
+ SysTimeval tv;
+ sys_gettimeofday(&tv);
+ time->s = tv.tv_sec;
+ time->ns = tv.tv_usec*1000LL;
#endif
}
@@ -111,28 +131,29 @@ static void lcnt_time_diff(erts_lcnt_time_t *d, erts_lcnt_time_t *t1, erts_lcnt_
dns += 1000000000LL;
}
+ ASSERT(ds >= 0);
+
d->s = ds;
d->ns = dns;
}
-/* difference d must be positive */
+/* difference d must be non-negative */
static void lcnt_time_add(erts_lcnt_time_t *t, erts_lcnt_time_t *d) {
- unsigned long ngns = 0;
-
t->s += d->s;
t->ns += d->ns;
- ngns = t->ns / 1000000000LL;
+ t->s += t->ns / 1000000000LL;
t->ns = t->ns % 1000000000LL;
-
- t->s += ngns;
}
static erts_lcnt_thread_data_t *lcnt_thread_data_alloc(void) {
erts_lcnt_thread_data_t *eltd;
eltd = (erts_lcnt_thread_data_t*)malloc(sizeof(erts_lcnt_thread_data_t));
+ if (!eltd) {
+ ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
+ }
eltd->timer_set = 0;
eltd->lock_in_conflict = 0;
@@ -158,59 +179,64 @@ static char* lock_opt(Uint16 flag) {
return "--";
}
-static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action, char *extra) {
- erts_aint_t colls, tries, w_state, r_state;
- erts_lcnt_lock_stats_t *stats = NULL;
-
+static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action) {
+ erts_aint_t w_state, r_state;
char *type;
- int i;
-
+
+ if (strcmp(lock->name, "run_queue") != 0) return;
type = lcnt_lock_type(lock->flag);
r_state = ethr_atomic_read(&lock->r_state);
w_state = ethr_atomic_read(&lock->w_state);
-
if (lock->flag & flag) {
- erts_printf("%20s [%30s] [r/w state %4ld/%4ld] id %T %s\r\n",
- action,
- lock->name,
- r_state,
- w_state,
- lock->id,
- extra);
+ erts_fprintf(stderr,"%10s [%24s] [r/w state %4ld/%4ld] %2s id %T\r\n",
+ action,
+ lock->name,
+ r_state,
+ w_state,
+ type,
+ lock->id);
}
}
-
-static void print_lock(erts_lcnt_lock_t *lock, char *action) {
- if (strcmp(lock->name, "proc_main") == 0) {
- print_lock_x(lock, ERTS_LCNT_LT_ALL, action, "");
- }
-}
-
#endif
static erts_lcnt_lock_stats_t *lcnt_get_lock_stats(erts_lcnt_lock_t *lock, char *file, unsigned int line) {
unsigned int i;
erts_lcnt_lock_stats_t *stats = NULL;
-
- for (i = 0; i < lock->n_stats; i++) {
- if ((lock->stats[i].file == file) && (lock->stats[i].line == line)) {
- return &(lock->stats[i]);
- }
- }
- if (lock->n_stats < ERTS_LCNT_MAX_LOCK_LOCATIONS) {
- stats = &lock->stats[lock->n_stats];
- lock->n_stats++;
- stats->file = file;
- stats->line = line;
- return stats;
+ if (erts_lcnt_rt_options & ERTS_LCNT_OPT_LOCATION) {
+ for (i = 0; i < lock->n_stats; i++) {
+ if ((lock->stats[i].file == file) && (lock->stats[i].line == line)) {
+ return &(lock->stats[i]);
+ }
+ }
+ if (lock->n_stats < ERTS_LCNT_MAX_LOCK_LOCATIONS) {
+ stats = &lock->stats[lock->n_stats];
+ lock->n_stats++;
+ stats->file = file;
+ stats->line = line;
+ return stats;
+ }
}
return &lock->stats[0];
+}
+static void lcnt_update_stats_hist(erts_lcnt_hist_t *hist, erts_lcnt_time_t *time_wait) {
+ int idx;
+ unsigned long r;
+
+ if (time_wait->s > 0 || time_wait->ns > ERTS_LCNT_HISTOGRAM_MAX_NS) {
+ idx = ERTS_LCNT_HISTOGRAM_SLOT_SIZE - 1;
+ } else {
+ r = time_wait->ns >> ERTS_LCNT_HISTOGRAM_RSHIFT;
+ if (r) idx = lcnt_log2(r);
+ else idx = 0;
+ }
+ hist->ns[idx]++;
}
-static void lcnt_update_stats(erts_lcnt_lock_stats_t *stats, int lock_in_conflict, erts_lcnt_time_t *time_wait) {
+static void lcnt_update_stats(erts_lcnt_lock_stats_t *stats, int lock_in_conflict,
+ erts_lcnt_time_t *time_wait) {
ethr_atomic_inc(&stats->tries);
@@ -220,6 +246,7 @@ static void lcnt_update_stats(erts_lcnt_lock_stats_t *stats, int lock_in_conflic
if (time_wait) {
lcnt_time_add(&(stats->timer), time_wait);
stats->timer_n++;
+ lcnt_update_stats_hist(&stats->hist,time_wait);
}
}
@@ -248,6 +275,9 @@ void erts_lcnt_init() {
/* init lcnt structure */
erts_lcnt_data = (erts_lcnt_data_t*)malloc(sizeof(erts_lcnt_data_t));
+ if (!erts_lcnt_data) {
+ ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
+ }
erts_lcnt_data->current_locks = erts_lcnt_list_init();
erts_lcnt_data->deleted_locks = erts_lcnt_list_init();
@@ -269,6 +299,9 @@ erts_lcnt_lock_list_t *erts_lcnt_list_init(void) {
erts_lcnt_lock_list_t *list;
list = (erts_lcnt_lock_list_t*)malloc(sizeof(erts_lcnt_lock_list_t));
+ if (!list) {
+ ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
+ }
list->head = NULL;
list->tail = NULL;
list->n = 0;
@@ -330,8 +363,9 @@ void erts_lcnt_list_delete(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock)
/* interface to erl_threads.h */
/* only lock on init and destroy, all others should use atomics */
void erts_lcnt_init_lock(erts_lcnt_lock_t *lock, char *name, Uint16 flag ) {
- erts_lcnt_init_lock_x(lock, name, flag, am_undefined);
+ erts_lcnt_init_lock_x(lock, name, flag, NIL);
}
+
void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eterm id) {
int i;
if (!name) {
@@ -360,7 +394,6 @@ void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eter
}
erts_lcnt_list_insert(erts_lcnt_data->current_locks, lock);
-
lcnt_unlock();
}
@@ -375,6 +408,9 @@ void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock) {
/* copy structure and insert the copy */
deleted_lock = (erts_lcnt_lock_t*)malloc(sizeof(erts_lcnt_lock_t));
+ if (!deleted_lock) {
+ ERTS_INTERNAL_ERROR("Lock counter failed to allocate memory!");
+ }
memcpy(deleted_lock, lock, sizeof(erts_lcnt_lock_t));
deleted_lock->next = NULL;
@@ -417,8 +453,9 @@ void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
if ((w_state > 0) || (r_state > 0)) {
eltd->lock_in_conflict = 1;
- if (eltd->timer_set == 0)
+ if (eltd->timer_set == 0) {
lcnt_time(&eltd->timer);
+ }
eltd->timer_set++;
} else {
eltd->lock_in_conflict = 0;
@@ -433,7 +470,7 @@ void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
w_state = ethr_atomic_read(&lock->w_state);
- ethr_atomic_inc( &lock->w_state);
+ ethr_atomic_inc(&lock->w_state);
eltd = lcnt_get_thread_data();
@@ -446,10 +483,10 @@ void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
* 'atomicly'. All other locks will block the thread if w_state > 0
* i.e. locked.
*/
- if (eltd->timer_set == 0)
+ if (eltd->timer_set == 0) {
lcnt_time(&eltd->timer);
+ }
eltd->timer_set++;
-
} else {
eltd->lock_in_conflict = 0;
}
@@ -459,11 +496,10 @@ void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
void erts_lcnt_lock_unaquire(erts_lcnt_lock_t *lock) {
/* should check if this thread was "waiting" */
-
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
if (!ERTS_LCNT_LOCK_TYPE(lock)) return;
- ethr_atomic_dec( &lock->w_state);
+ ethr_atomic_dec(&lock->w_state);
}
/* erts_lcnt_lock_post
@@ -491,7 +527,7 @@ void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line
if (!(lock->flag & (ERTS_LCNT_LT_RWMUTEX | ERTS_LCNT_LT_RWSPINLOCK))) {
flowstate = ethr_atomic_read(&lock->flowstate);
ASSERT(flowstate == 0);
- ethr_atomic_inc( &lock->flowstate);
+ ethr_atomic_inc(&lock->flowstate);
}
#endif
@@ -500,19 +536,12 @@ void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line
ASSERT(eltd);
/* if lock was in conflict, time it */
-
- if (erts_lcnt_rt_options & ERTS_LCNT_OPT_LOCATION) {
- stats = lcnt_get_lock_stats(lock, file, line);
- } else {
- stats = &lock->stats[0];
- }
-
+ stats = lcnt_get_lock_stats(lock, file, line);
if (eltd->timer_set) {
lcnt_time(&timer);
lcnt_time_diff(&time_wait, &timer, &(eltd->timer));
lcnt_update_stats(stats, eltd->lock_in_conflict, &time_wait);
-
eltd->timer_set--;
ASSERT(eltd->timer_set >= 0);
} else {
@@ -541,11 +570,11 @@ void erts_lcnt_unlock(erts_lcnt_lock_t *lock) {
/* flowstate */
flowstate = ethr_atomic_read(&lock->flowstate);
ASSERT(flowstate == 1);
- ethr_atomic_dec( &lock->flowstate);
+ ethr_atomic_dec(&lock->flowstate);
/* write state */
w_state = ethr_atomic_read(&lock->w_state);
- ASSERT(w_state > 0)
+ ASSERT(w_state > 0);
#endif
ethr_atomic_dec(&lock->w_state);
}
@@ -582,9 +611,7 @@ void erts_lcnt_trylock(erts_lcnt_lock_t *lock, int res) {
ethr_atomic_inc( &lock->flowstate);
#endif
ethr_atomic_inc(&lock->w_state);
-
lcnt_update_stats(&(lock->stats[0]), 0, NULL);
-
} else {
ethr_atomic_inc(&lock->stats[0].tries);
ethr_atomic_inc(&lock->stats[0].colls);
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h
index 75f7cd028b..ffbb93da1b 100644
--- a/erts/emulator/beam/erl_lock_count.h
+++ b/erts/emulator/beam/erl_lock_count.h
@@ -35,6 +35,10 @@
* | | | - collisions (including trylock busy)
* | | | - timer (time spent in waiting for lock)
* | | | - n_timer (collisions excluding trylock busy)
+ * | | | - histogram
+ * | | | | - # 0 = log2(lock wait_time ns)
+ * | | | | - ...
+ * | | | | - # n = log2(lock wait_time ns)
*
* Each instance of a lock is the unique lock, i.e. set and id in that set.
* For each lock there is a set of statistics with where and what impact
@@ -68,8 +72,17 @@
#include "ethread.h"
+#define ERTS_LCNT_MAX_LOCK_LOCATIONS (10)
-#define ERTS_LCNT_MAX_LOCK_LOCATIONS (10)
+/* histogram */
+#define ERTS_LCNT_HISTOGRAM_MAX_NS (((unsigned long)1LL << 28) - 1)
+#if 0 || defined(HAVE_GETHRTIME)
+#define ERTS_LCNT_HISTOGRAM_SLOT_SIZE (30)
+#define ERTS_LCNT_HISTOGRAM_RSHIFT (0)
+#else
+#define ERTS_LCNT_HISTOGRAM_SLOT_SIZE (20)
+#define ERTS_LCNT_HISTOGRAM_RSHIFT (10)
+#endif
#define ERTS_LCNT_LT_SPINLOCK (((Uint16) 1) << 0)
#define ERTS_LCNT_LT_RWSPINLOCK (((Uint16) 1) << 1)
@@ -104,6 +117,10 @@ typedef struct {
extern erts_lcnt_time_t timer_start;
+typedef struct {
+ Uint32 ns[ERTS_LCNT_HISTOGRAM_SLOT_SIZE]; /* log2 array of nano seconds occurences */
+} erts_lcnt_hist_t;
+
typedef struct erts_lcnt_lock_stats_s {
/* "tries" and "colls" needs to be atomic since
* trylock busy does not aquire a lock and there
@@ -118,6 +135,7 @@ typedef struct erts_lcnt_lock_stats_s {
unsigned long timer_n; /* #times waited for lock */
erts_lcnt_time_t timer; /* total wait time for lock */
+ erts_lcnt_hist_t hist;
} erts_lcnt_lock_stats_t;
/* rw locks uses both states, other locks only uses w_state */
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 0eb8117980..59a677a12c 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -1032,7 +1032,6 @@ erts_send_message(Process* sender,
}
BM_SWAP_TIMER(send,system);
} else {
-#ifdef ERTS_SMP
ErlOffHeap *ohp;
Eterm *hp;
erts_aint32_t state;
@@ -1064,42 +1063,6 @@ erts_send_message(Process* sender,
#endif
);
BM_SWAP_TIMER(send,system);
-#else
- ErlMessage* mp = message_alloc();
- Eterm *hp;
- BM_SWAP_TIMER(send,size);
- msize = size_object(message);
- BM_SWAP_TIMER(size,send);
-
- if (receiver->stop - receiver->htop <= msize) {
- BM_SWAP_TIMER(send,system);
- erts_garbage_collect(receiver, msize, receiver->arg_reg, receiver->arity);
- BM_SWAP_TIMER(system,send);
- }
- hp = receiver->htop;
- receiver->htop = hp + msize;
- BM_SWAP_TIMER(send,copy);
- message = copy_struct(message, msize, &hp, &receiver->off_heap);
- BM_MESSAGE_COPIED(msize);
- BM_SWAP_TIMER(copy,send);
- DTRACE6(message_send, sender_name, receiver_name,
- (uint32_t)msize, tok_label, tok_lastcnt, tok_serial);
- ERL_MESSAGE_TERM(mp) = message;
- ERL_MESSAGE_TOKEN(mp) = NIL;
-#ifdef USE_VM_PROBES
- ERL_MESSAGE_DT_UTAG(mp) = NIL;
-#endif
- mp->next = NULL;
- mp->data.attached = NULL;
- LINK_MESSAGE(receiver, mp);
- res = receiver->msg.len;
- erts_proc_notify_new_message(receiver);
-
- if (IS_TRACED_FL(receiver, F_TRACE_RECEIVE)) {
- trace_receive(receiver, message);
- }
- BM_SWAP_TIMER(send,system);
-#endif /* #ifndef ERTS_SMP */
}
return res;
}
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 31d9a1e26e..2fc95ed5d8 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -798,12 +798,13 @@ schedule_port_task_handle_list_free(ErtsPortTaskHandleList *pthlp)
static ERTS_INLINE void
abort_nosuspend_task(Port *pp,
ErtsPortTaskType type,
- ErtsPortTaskTypeData *tdp)
+ ErtsPortTaskTypeData *tdp,
+ int bpq_data)
{
ASSERT(type == ERTS_PORT_TASK_PROC_SIG);
- if (!pp->sched.taskq.bpq)
+ if (!bpq_data)
tdp->psig.callback(NULL,
ERTS_PORT_SFLG_INVALID,
ERTS_PROC2PORT_SIG_ABORT_NOSUSPEND,
@@ -1345,7 +1346,7 @@ erts_port_task_abort_nosuspend_tasks(Port *pp)
#endif
schedule_port_task_handle_list_free(pthlp);
- abort_nosuspend_task(pp, type, &td);
+ abort_nosuspend_task(pp, type, &td, pp->sched.taskq.bpq != NULL);
}
}
@@ -1525,7 +1526,7 @@ abort_nosuspend:
erts_port_dec_refc(pp);
#endif
- abort_nosuspend_task(pp, ptp->type, &ptp->u.alive.td);
+ abort_nosuspend_task(pp, ptp->type, &ptp->u.alive.td, 0);
ASSERT(ns_pthlp);
erts_free(ERTS_ALC_T_PT_HNDL_LIST, ns_pthlp);
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index b73f9b7f92..1606ad119d 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -2211,6 +2211,9 @@ aux_work_timeout_early_init(int no_schedulers)
p = (UWord) malloc((sizeof(ErtsAuxWorkTmo)
+ sizeof(erts_atomic32_t)*(no_schedulers+1))
+ ERTS_CACHE_LINE_SIZE-1);
+ if (!p) {
+ ERTS_INTERNAL_ERROR("malloc failed to allocate memory!");
+ }
if (p & ERTS_CACHE_LINE_MASK)
p = (p & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE;
ASSERT((p & ERTS_CACHE_LINE_MASK) == 0);
@@ -7818,6 +7821,9 @@ erts_start_schedulers(void)
#ifdef ETHR_HAVE_THREAD_NAMES
opts.name = malloc(80);
+ if (!opts.name) {
+ ERTS_INTERNAL_ERROR("malloc failed to allocate memory!");
+ }
#endif
#ifdef ERTS_SMP
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 3a968594f3..f8e1431a53 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -2126,6 +2126,8 @@ Eterm erts_convert_native_to_filename(Process *p, byte *bytes)
mac = 1;
case ERL_FILENAME_UTF8:
size = strlen((char *) bytes);
+ if (size == 0)
+ return NIL;
if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK) {
goto noconvert;
}
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 656de7c49a..8d240355b0 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -44,9 +44,6 @@
#include "erl_zlib.h"
#include "erl_map.h"
-#ifdef HIPE
-#include "hipe_mode_switch.h"
-#endif
#define in_area(ptr,start,nbytes) ((UWord)((char*)(ptr) - (char*)(start)) < (nbytes))
#define MAX_STRING_LEN 0xffff
@@ -111,26 +108,17 @@ static int encode_size_struct_int(struct TTBSizeContext_*, ErtsAtomCacheMap *acm
static Export binary_to_term_trap_export;
static BIF_RETTYPE binary_to_term_trap_1(BIF_ALIST_1);
-static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* context_b);
+static BIF_RETTYPE binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* context_b,
+ Export *bif, Eterm arg0, Eterm arg1);
void erts_init_external(void) {
-#if 1 /* In R16 */
erts_init_trap_export(&term_to_binary_trap_export,
- am_erlang, am_term_to_binary_trap, 1,
+ am_erts_internal, am_term_to_binary_trap, 1,
&term_to_binary_trap_1);
erts_init_trap_export(&binary_to_term_trap_export,
- am_erlang, am_binary_to_term_trap, 1,
+ am_erts_internal, am_binary_to_term_trap, 1,
&binary_to_term_trap_1);
-#else
- sys_memset((void *) &term_to_binary_trap_export, 0, sizeof(Export));
- term_to_binary_trap_export.address = &term_to_binary_trap_export.code[3];
- term_to_binary_trap_export.code[0] = am_erlang;
- term_to_binary_trap_export.code[1] = am_term_to_binary_trap;
- term_to_binary_trap_export.code[2] = 1;
- term_to_binary_trap_export.code[3] = (BeamInstr) em_apply_bif;
- term_to_binary_trap_export.code[4] = (BeamInstr) &term_to_binary_trap_1;
-#endif
return;
}
@@ -1069,6 +1057,8 @@ static BIF_RETTYPE term_to_binary_trap_1(BIF_ALIST_1)
}
}
+HIPE_WRAPPER_BIF_DISABLE_GC(term_to_binary, 1)
+
BIF_RETTYPE term_to_binary_1(BIF_ALIST_1)
{
Eterm res = erts_term_to_binary_int(BIF_P, BIF_ARG_1, 0, TERM_TO_BINARY_DFLAGS, NULL);
@@ -1081,6 +1071,8 @@ BIF_RETTYPE term_to_binary_1(BIF_ALIST_1)
}
}
+HIPE_WRAPPER_BIF_DISABLE_GC(term_to_binary, 2)
+
BIF_RETTYPE term_to_binary_2(BIF_ALIST_2)
{
Process* p = BIF_P;
@@ -1185,6 +1177,8 @@ typedef struct B2TContext_t {
Uint32 flags;
SWord reds;
Eterm trap_bin;
+ Export *bif;
+ Eterm arg[2];
enum B2TState state;
union {
B2TSizeContext sc;
@@ -1356,7 +1350,8 @@ static BIF_RETTYPE binary_to_term_trap_1(BIF_ALIST_1)
Binary *context_bin = ((ProcBin *) binary_val(BIF_ARG_1))->val;
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(context_bin) == b2t_context_destructor);
- return binary_to_term_int(BIF_P, 0, THE_NON_VALUE, context_bin);
+ return binary_to_term_int(BIF_P, 0, THE_NON_VALUE, context_bin, NULL,
+ THE_NON_VALUE, THE_NON_VALUE);
}
@@ -1391,8 +1386,10 @@ static B2TContext* b2t_export_context(Process* p, B2TContext* src)
return ctx;
}
-static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* context_b)
+static BIF_RETTYPE binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* context_b,
+ Export *bif_init, Eterm arg0, Eterm arg1)
{
+ BIF_RETTYPE ret_val;
#ifdef EXTREME_B2T_TRAPPING
SWord initial_reds = 1 + b2t_rand() % 4;
#else
@@ -1409,6 +1406,9 @@ static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* con
ctx->state = B2TPrepare;
ctx->aligned_alloc = NULL;
ctx->flags = flags;
+ ctx->bif = bif_init;
+ ctx->arg[0] = arg0;
+ ctx->arg[1] = arg1;
IF_DEBUG(ctx->trap_bin = THE_NON_VALUE;)
} else {
is_first_call = 0;
@@ -1504,12 +1504,24 @@ static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* con
HRelease(p, ctx->u.dc.hp_end, ctx->u.dc.hp_start);
/*fall through*/
case B2TBadArg:
- b2t_destroy_context(ctx);
- if (!is_first_call) {
- erts_set_gc_state(p, 1);
- }
BUMP_REDS(p, (initial_reds - ctx->reds) / B2T_BYTES_PER_REDUCTION);
- BIF_ERROR(p, BADARG & ~EXF_SAVETRACE);
+
+ ASSERT(ctx->bif == bif_export[BIF_binary_to_term_1]
+ || ctx->bif == bif_export[BIF_binary_to_term_2]);
+
+ if (is_first_call)
+ ERTS_BIF_PREP_ERROR(ret_val, p, BADARG);
+ else {
+ erts_set_gc_state(p, 1);
+ if (is_non_value(ctx->arg[1]))
+ ERTS_BIF_PREP_ERROR_TRAPPED1(ret_val, p, BADARG, ctx->bif,
+ ctx->arg[0]);
+ else
+ ERTS_BIF_PREP_ERROR_TRAPPED2(ret_val, p, BADARG, ctx->bif,
+ ctx->arg[0], ctx->arg[1]);
+ }
+ b2t_destroy_context(ctx);
+ return ret_val;
case B2TDone:
b2t_destroy_context(ctx);
@@ -1524,7 +1536,8 @@ static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* con
erts_set_gc_state(p, 1);
}
BUMP_REDS(p, (initial_reds - ctx->reds) / B2T_BYTES_PER_REDUCTION);
- return ctx->u.dc.res;
+ ERTS_BIF_PREP_RET(ret_val, ctx->u.dc.res);
+ return ret_val;
default:
ASSERT(!"Unknown state in binary_to_term");
@@ -1541,15 +1554,24 @@ static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* con
erts_set_gc_state(p, 0);
}
BUMP_ALL_REDS(p);
- BIF_TRAP1(&binary_to_term_trap_export, p, ctx->trap_bin);
+
+ ERTS_BIF_PREP_TRAP1(ret_val, &binary_to_term_trap_export,
+ p, ctx->trap_bin);
+
+ return ret_val;
}
-BIF_RETTYPE erts_internal_binary_to_term_1(BIF_ALIST_1)
+HIPE_WRAPPER_BIF_DISABLE_GC(binary_to_term, 1)
+
+BIF_RETTYPE binary_to_term_1(BIF_ALIST_1)
{
- return binary_to_term_int(BIF_P, 0, BIF_ARG_1, NULL);
+ return binary_to_term_int(BIF_P, 0, BIF_ARG_1, NULL, bif_export[BIF_binary_to_term_1],
+ BIF_ARG_1, THE_NON_VALUE);
}
-BIF_RETTYPE erts_internal_binary_to_term_2(BIF_ALIST_2)
+HIPE_WRAPPER_BIF_DISABLE_GC(binary_to_term, 2)
+
+BIF_RETTYPE binary_to_term_2(BIF_ALIST_2)
{
Eterm opts;
Eterm opt;
@@ -1570,7 +1592,8 @@ BIF_RETTYPE erts_internal_binary_to_term_2(BIF_ALIST_2)
if (is_not_nil(opts))
goto error;
- return binary_to_term_int(BIF_P, flags, BIF_ARG_1, NULL);
+ return binary_to_term_int(BIF_P, flags, BIF_ARG_1, NULL, bif_export[BIF_binary_to_term_2],
+ BIF_ARG_1, BIF_ARG_2);
error:
BIF_ERROR(BIF_P, BADARG);
@@ -4440,66 +4463,3 @@ error:
#undef SKIP2
#undef CHKSIZE
}
-
-
-#ifdef HIPE
-BIF_RETTYPE hipe_wrapper_term_to_binary_1(BIF_ALIST_1);
-BIF_RETTYPE hipe_wrapper_term_to_binary_2(BIF_ALIST_2);
-BIF_RETTYPE hipe_wrapper_erts_internal_binary_to_term_1(BIF_ALIST_1);
-BIF_RETTYPE hipe_wrapper_erts_internal_binary_to_term_2(BIF_ALIST_2);
-
-/* Hipe wrappers used by native code for BIFs that disable GC while trapping.
- *
- * Problem:
- * When native code calls a BIF that traps, hipe_mode_switch will push a
- * "trap frame" on the Erlang stack in order to find its way back from beam_emu
- * back to native caller when finally done. If GC is disabled and stack/heap
- * is full there is no place to push the "trap frame".
- *
- * Solution:
- * We reserve space on stack for the "trap frame" here before the BIF is called.
- * If the BIF does not trap, the space is reclaimed here before returning.
- * If the BIF traps, hipe_push_beam_trap_frame() will detect that a "trap frame"
- * already is reserved and use it.
- */
-BIF_RETTYPE hipe_wrapper_term_to_binary_1(BIF_ALIST_1)
-{
- Eterm res;
- hipe_reserve_beam_trap_frame(BIF_P, BIF__ARGS, 1);
- res = term_to_binary_1(BIF_P, BIF__ARGS);
- if (is_value(res) || BIF_P->freason != TRAP) {
- hipe_unreserve_beam_trap_frame(BIF_P);
- }
- return res;
-}
-BIF_RETTYPE hipe_wrapper_term_to_binary_2(BIF_ALIST_2)
-{
- Eterm res;
- hipe_reserve_beam_trap_frame(BIF_P, BIF__ARGS, 2);
- res = term_to_binary_2(BIF_P, BIF__ARGS);
- if (is_value(res) || BIF_P->freason != TRAP) {
- hipe_unreserve_beam_trap_frame(BIF_P);
- }
- return res;
-}
-BIF_RETTYPE hipe_wrapper_erts_internal_binary_to_term_1(BIF_ALIST_1)
-{
- Eterm res;
- hipe_reserve_beam_trap_frame(BIF_P, BIF__ARGS, 1);
- res = erts_internal_binary_to_term_1(BIF_P, BIF__ARGS);
- if (is_value(res) || BIF_P->freason != TRAP) {
- hipe_unreserve_beam_trap_frame(BIF_P);
- }
- return res;
-}
-BIF_RETTYPE hipe_wrapper_erts_internal_binary_to_term_2(BIF_ALIST_2)
-{
- Eterm res;
- hipe_reserve_beam_trap_frame(BIF_P, BIF__ARGS, 2);
- res = erts_internal_binary_to_term_2(BIF_P, BIF__ARGS);
- if (is_value(res) || BIF_P->freason != TRAP) {
- hipe_unreserve_beam_trap_frame(BIF_P);
- }
- return res;
-}
-#endif /*HIPE*/
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 8fcb95d0e2..891046a8b5 100755..100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -435,6 +435,8 @@ do {\
}\
} while(0)
+#define CLEAR_SAVED_ESTACK(estack) ((void) ((estack)->start = NULL))
+
/*
* Use on empty stack, only the allocator can be changed before this.
* The src stack is reset to NULL.
@@ -551,6 +553,8 @@ do {\
}\
} while(0)
+#define CLEAR_SAVED_WSTACK(wstack) ((void) ((wstack)->wstart = NULL))
+
/*
* Use on empty stack, only the allocator can be changed before this.
* The src stack is reset to NULL.
@@ -951,20 +955,67 @@ struct Sint_buf {
};
char* Sint_to_buf(Sint, struct Sint_buf*);
+#define ERTS_IOLIST_STATE_INITER(C_P, OBJ) \
+ {(C_P), 0, 0, (OBJ), {NULL, NULL, NULL, ERTS_ALC_T_INVALID}, 0, 0}
+
+#define ERTS_IOLIST_STATE_MOVE(TO, FROM) \
+ sys_memcpy((void *) (TO), (void *) (FROM), sizeof(ErtsIOListState))
+
+#define ERTS_IOLIST_SIZE_YIELDS_COUNT_PER_RED 8
+
+typedef struct {
+ Process *c_p;
+ ErlDrvSizeT size;
+ Uint offs;
+ Eterm obj;
+ ErtsEStack estack;
+ int reds_left;
+ int have_size;
+} ErtsIOListState;
+
+#define ERTS_IOLIST2BUF_STATE_INITER(C_P, OBJ) \
+ {ERTS_IOLIST_STATE_INITER((C_P), (OBJ)), {NULL, 0, 0, 0}, NULL, 0, NULL, 0}
+
+#define ERTS_IOLIST2BUF_STATE_MOVE(TO, FROM) \
+ sys_memcpy((void *) (TO), (void *) (FROM), sizeof(ErtsIOList2BufState))
+
+#define ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT 32
+#define ERTS_IOLIST_TO_BUF_YIELD_COUNT_PER_RED 8
+#define ERTS_IOLIST_TO_BUF_BYTES_PER_RED \
+ (ERTS_IOLIST_TO_BUF_YIELD_COUNT_PER_RED*ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT)
+
+typedef struct {
+ ErtsIOListState iolist;
+ struct {
+ byte *bptr;
+ size_t size;
+ Uint bitoffs;
+ Uint bitsize;
+ } bcopy;
+ char *buf;
+ ErlDrvSizeT len;
+ Eterm *objp;
+ int offset;
+} ErtsIOList2BufState;
+
#define ERTS_IOLIST_OK 0
#define ERTS_IOLIST_OVERFLOW 1
#define ERTS_IOLIST_TYPE 2
+#define ERTS_IOLIST_YIELD 3
Eterm buf_to_intlist(Eterm**, const char*, size_t, Eterm); /* most callers pass plain char*'s */
#define ERTS_IOLIST_TO_BUF_OVERFLOW (~((ErlDrvSizeT) 0))
#define ERTS_IOLIST_TO_BUF_TYPE_ERROR (~((ErlDrvSizeT) 1))
+#define ERTS_IOLIST_TO_BUF_YIELD (~((ErlDrvSizeT) 2))
#define ERTS_IOLIST_TO_BUF_FAILED(R) \
- (((R) & (~((ErlDrvSizeT) 1))) == (~((ErlDrvSizeT) 1)))
+ (((R) & (~((ErlDrvSizeT) 3))) == (~((ErlDrvSizeT) 3)))
#define ERTS_IOLIST_TO_BUF_SUCCEEDED(R) \
(!ERTS_IOLIST_TO_BUF_FAILED((R)))
ErlDrvSizeT erts_iolist_to_buf(Eterm, char*, ErlDrvSizeT);
+ErlDrvSizeT erts_iolist_to_buf_yielding(ErtsIOList2BufState *);
+int erts_iolist_size_yielding(ErtsIOListState *state);
int erts_iolist_size(Eterm, ErlDrvSizeT *);
int is_string(Eterm);
void erl_at_exit(void (*) (void*), void*);
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index c34a5b17d0..0f86d8e41d 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -6129,7 +6129,7 @@ driver_pdl_create(ErlDrvPort dp)
return NULL;
pdl = erts_alloc(ERTS_ALC_T_PORT_DATA_LOCK,
sizeof(struct erl_drv_port_data_lock));
- erts_mtx_init(&pdl->mtx, "port_data_lock");
+ erts_mtx_init_x(&pdl->mtx, "port_data_lock", pp->common.id, 1);
pdl_init_refc(pdl);
erts_port_inc_refc(pp);
pdl->prt = pp;
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 05f07e57b2..3d8dd9c6d0 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -274,6 +274,7 @@ __decl_noreturn void __noreturn erl_assert_error(const char* expr, const char *f
typedef unsigned int Eterm;
typedef unsigned int Uint;
typedef int Sint;
+#define ERTS_UINT_MAX UINT_MAX
#define ERTS_SIZEOF_ETERM SIZEOF_INT
#define ErtsStrToSint strtol
#else
@@ -347,6 +348,7 @@ typedef long long Sint;
typedef Uint UWord;
typedef Sint SWord;
+#define ERTS_UINT_MAX ERTS_UWORD_MAX
#endif /* HALFWORD_HEAP */
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 738f793020..55f9e68e78 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -3197,106 +3197,303 @@ buf_to_intlist(Eterm** hpp, const char *buf, size_t len, Eterm tail)
**
*/
-ErlDrvSizeT erts_iolist_to_buf(Eterm obj, char* buf, ErlDrvSizeT alloced_len)
+typedef enum {
+ ERTS_IL2B_BCOPY_OK,
+ ERTS_IL2B_BCOPY_YIELD,
+ ERTS_IL2B_BCOPY_OVERFLOW,
+ ERTS_IL2B_BCOPY_TYPE_ERROR
+} ErtsIL2BBCopyRes;
+
+static ErtsIL2BBCopyRes
+iolist_to_buf_bcopy(ErtsIOList2BufState *state, Eterm obj, int *yield_countp);
+
+static ERTS_INLINE ErlDrvSizeT
+iolist_to_buf(const int yield_support,
+ ErtsIOList2BufState *state,
+ Eterm obj,
+ char* buf,
+ ErlDrvSizeT alloced_len)
{
- ErlDrvSizeT len = (ErlDrvSizeT) alloced_len;
- Eterm* objp;
+#undef IOLIST_TO_BUF_BCOPY
+#define IOLIST_TO_BUF_BCOPY(CONSP) \
+do { \
+ size_t size = binary_size(obj); \
+ if (size > 0) { \
+ Uint bitsize; \
+ byte* bptr; \
+ Uint bitoffs; \
+ Uint num_bits; \
+ if (yield_support) { \
+ size_t max_size = ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT; \
+ if (yield_count > 0) \
+ max_size *= yield_count+1; \
+ if (size > max_size) { \
+ state->objp = CONSP; \
+ goto L_bcopy_yield; \
+ } \
+ if (size >= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT) { \
+ int cost = (int) size; \
+ cost /= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT; \
+ yield_count -= cost; \
+ } \
+ } \
+ if (len < size) \
+ goto L_overflow; \
+ ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize); \
+ if (bitsize != 0) \
+ goto L_type_error; \
+ num_bits = 8*size; \
+ copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits); \
+ buf += size; \
+ len -= size; \
+ } \
+} while (0)
+
+ ErlDrvSizeT res, len;
+ Eterm* objp = NULL;
+ int init_yield_count;
+ int yield_count;
DECLARE_ESTACK(s);
- goto L_again;
-
- while (!ESTACK_ISEMPTY(s)) {
- obj = ESTACK_POP(s);
- L_again:
- if (is_list(obj)) {
- L_iter_list:
- objp = list_val(obj);
- obj = CAR(objp);
- if (is_byte(obj)) {
- if (len == 0) {
- goto L_overflow;
- }
- *buf++ = unsigned_val(obj);
- len--;
- } else if (is_binary(obj)) {
- byte* bptr;
- size_t size = binary_size(obj);
- Uint bitsize;
- Uint bitoffs;
- Uint num_bits;
-
- if (len < size) {
+
+ len = (ErlDrvSizeT) alloced_len;
+
+ if (!yield_support) {
+ yield_count = init_yield_count = 0; /* Shut up faulty warning... >:-( */
+ goto L_again;
+ }
+ else {
+
+ if (state->iolist.reds_left <= 0)
+ return ERTS_IOLIST_TO_BUF_YIELD;
+
+ ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
+ init_yield_count = (ERTS_IOLIST_TO_BUF_YIELD_COUNT_PER_RED
+ * state->iolist.reds_left);
+ yield_count = init_yield_count;
+
+ if (!state->iolist.estack.start)
+ goto L_again;
+ else {
+ int chk_stack;
+ /* Restart; restore state... */
+ ESTACK_RESTORE(s, &state->iolist.estack);
+
+ if (!state->bcopy.bptr)
+ chk_stack = 0;
+ else {
+ chk_stack = 1;
+ switch (iolist_to_buf_bcopy(state, THE_NON_VALUE, &yield_count)) {
+ case ERTS_IL2B_BCOPY_OK:
+ break;
+ case ERTS_IL2B_BCOPY_YIELD:
+ BUMP_ALL_REDS(state->iolist.c_p);
+ state->iolist.reds_left = 0;
+ ESTACK_SAVE(s, &state->iolist.estack);
+ return ERTS_IOLIST_TO_BUF_YIELD;
+ case ERTS_IL2B_BCOPY_OVERFLOW:
goto L_overflow;
- }
- ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
- if (bitsize != 0) {
+ case ERTS_IL2B_BCOPY_TYPE_ERROR:
goto L_type_error;
}
- num_bits = 8*size;
- copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);
- buf += size;
- len -= size;
- } else if (is_list(obj)) {
- ESTACK_PUSH(s, CDR(objp));
- goto L_iter_list; /* on head */
- } else if (is_not_nil(obj)) {
- goto L_type_error;
}
- obj = CDR(objp);
- if (is_list(obj)) {
- goto L_iter_list; /* on tail */
- } else if (is_binary(obj)) {
- byte* bptr;
- size_t size = binary_size(obj);
- Uint bitsize;
- Uint bitoffs;
- Uint num_bits;
- if (len < size) {
- goto L_overflow;
+ obj = state->iolist.obj;
+ buf = state->buf;
+ len = state->len;
+ objp = state->objp;
+ state->objp = NULL;
+ if (objp)
+ goto L_tail;
+ if (!chk_stack)
+ goto L_again;
+ /* check stack */
+ }
+ }
+
+ while (!ESTACK_ISEMPTY(s)) {
+ obj = ESTACK_POP(s);
+ L_again:
+ if (is_list(obj)) {
+ while (1) { /* Tail loop */
+ while (1) { /* Head loop */
+ if (yield_support && --yield_count <= 0)
+ goto L_yield;
+ objp = list_val(obj);
+ obj = CAR(objp);
+ if (is_byte(obj)) {
+ if (len == 0) {
+ goto L_overflow;
+ }
+ *buf++ = unsigned_val(obj);
+ len--;
+ } else if (is_binary(obj)) {
+ IOLIST_TO_BUF_BCOPY(objp);
+ } else if (is_list(obj)) {
+ ESTACK_PUSH(s, CDR(objp));
+ continue; /* Head loop */
+ } else if (is_not_nil(obj)) {
+ goto L_type_error;
+ }
+ break;
}
- ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
- if (bitsize != 0) {
+
+ L_tail:
+
+ obj = CDR(objp);
+
+ if (is_list(obj)) {
+ continue; /* Tail loop */
+ } else if (is_binary(obj)) {
+ IOLIST_TO_BUF_BCOPY(NULL);
+ } else if (is_not_nil(obj)) {
goto L_type_error;
}
- num_bits = 8*size;
- copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);
- buf += size;
- len -= size;
- } else if (is_not_nil(obj)) {
- goto L_type_error;
+ break;
}
} else if (is_binary(obj)) {
- byte* bptr;
- size_t size = binary_size(obj);
- Uint bitsize;
- Uint bitoffs;
- Uint num_bits;
- if (len < size) {
- goto L_overflow;
- }
- ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
- if (bitsize != 0) {
- goto L_type_error;
- }
- num_bits = 8*size;
- copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);
- buf += size;
- len -= size;
+ IOLIST_TO_BUF_BCOPY(NULL);
} else if (is_not_nil(obj)) {
goto L_type_error;
- }
+ } else if (yield_support && --yield_count <= 0)
+ goto L_yield;
}
+ res = len;
+
+ L_return:
+
DESTROY_ESTACK(s);
- return len;
+
+ if (yield_support) {
+ int reds;
+ CLEAR_SAVED_ESTACK(&state->iolist.estack);
+ reds = ((init_yield_count - yield_count - 1)
+ / ERTS_IOLIST_TO_BUF_YIELD_COUNT_PER_RED) + 1;
+ BUMP_REDS(state->iolist.c_p, reds);
+ state->iolist.reds_left -= reds;
+ if (state->iolist.reds_left < 0)
+ state->iolist.reds_left = 0;
+ }
+
+
+ return res;
L_type_error:
- DESTROY_ESTACK(s);
- return ERTS_IOLIST_TO_BUF_TYPE_ERROR;
+ res = ERTS_IOLIST_TO_BUF_TYPE_ERROR;
+ goto L_return;
L_overflow:
- DESTROY_ESTACK(s);
- return ERTS_IOLIST_TO_BUF_OVERFLOW;
+ res = ERTS_IOLIST_TO_BUF_OVERFLOW;
+ goto L_return;
+
+ L_bcopy_yield:
+
+ state->buf = buf;
+ state->len = len;
+
+ switch (iolist_to_buf_bcopy(state, obj, &yield_count)) {
+ case ERTS_IL2B_BCOPY_OK:
+ ERTS_INTERNAL_ERROR("Missing yield");
+ case ERTS_IL2B_BCOPY_YIELD:
+ BUMP_ALL_REDS(state->iolist.c_p);
+ state->iolist.reds_left = 0;
+ ESTACK_SAVE(s, &state->iolist.estack);
+ return ERTS_IOLIST_TO_BUF_YIELD;
+ case ERTS_IL2B_BCOPY_OVERFLOW:
+ goto L_overflow;
+ case ERTS_IL2B_BCOPY_TYPE_ERROR:
+ goto L_type_error;
+ }
+
+ L_yield:
+
+ BUMP_ALL_REDS(state->iolist.c_p);
+ state->iolist.reds_left = 0;
+ state->iolist.obj = obj;
+ state->buf = buf;
+ state->len = len;
+ ESTACK_SAVE(s, &state->iolist.estack);
+ return ERTS_IOLIST_TO_BUF_YIELD;
+
+#undef IOLIST_TO_BUF_BCOPY
+}
+
+static ErtsIL2BBCopyRes
+iolist_to_buf_bcopy(ErtsIOList2BufState *state, Eterm obj, int *yield_countp)
+{
+ ErtsIL2BBCopyRes res;
+ char *buf = state->buf;
+ ErlDrvSizeT len = state->len;
+ byte* bptr;
+ size_t size;
+ size_t max_size;
+ Uint bitoffs;
+ Uint num_bits;
+ int yield_count = *yield_countp;
+
+ if (state->bcopy.bptr) {
+ bptr = state->bcopy.bptr;
+ size = state->bcopy.size;
+ bitoffs = state->bcopy.bitoffs;
+ state->bcopy.bptr = NULL;
+ }
+ else {
+ Uint bitsize;
+
+ ASSERT(is_binary(obj));
+
+ size = binary_size(obj);
+ if (size <= 0)
+ return ERTS_IL2B_BCOPY_OK;
+
+ if (len < size)
+ return ERTS_IL2B_BCOPY_OVERFLOW;
+
+ ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);
+ if (bitsize != 0)
+ return ERTS_IL2B_BCOPY_TYPE_ERROR;
+ }
+
+ ASSERT(size > 0);
+ max_size = (size_t) ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT;
+ if (yield_count > 0)
+ max_size *= (size_t) (yield_count+1);
+
+ if (size <= max_size) {
+ if (size >= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT) {
+ int cost = (int) size;
+ cost /= ERTS_IOLIST_TO_BUF_BYTES_PER_YIELD_COUNT;
+ yield_count -= cost;
+ }
+ res = ERTS_IL2B_BCOPY_OK;
+ }
+ else {
+ ASSERT(0 < max_size && max_size < size);
+ yield_count = 0;
+ state->bcopy.bptr = bptr + max_size;
+ state->bcopy.bitoffs = bitoffs;
+ state->bcopy.size = size - max_size;
+ size = max_size;
+ res = ERTS_IL2B_BCOPY_YIELD;
+ }
+
+ num_bits = 8*size;
+ copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);
+ state->buf += size;
+ state->len -= size;
+ *yield_countp = yield_count;
+
+ return res;
+}
+
+ErlDrvSizeT erts_iolist_to_buf_yielding(ErtsIOList2BufState *state)
+{
+ return iolist_to_buf(1, state, state->iolist.obj, state->buf, state->len);
+}
+
+ErlDrvSizeT erts_iolist_to_buf(Eterm obj, char* buf, ErlDrvSizeT alloced_len)
+{
+ return iolist_to_buf(0, NULL, obj, buf, alloced_len);
}
/*
@@ -3307,11 +3504,32 @@ ErlDrvSizeT erts_iolist_to_buf(Eterm obj, char* buf, ErlDrvSizeT alloced_len)
* Any input term error detected in erts_iolist_to_buf should also
* be detected in this function!
*/
-int erts_iolist_size(Eterm obj, ErlDrvSizeT* sizep)
+
+static ERTS_INLINE int
+iolist_size(const int yield_support, ErtsIOListState *state, Eterm obj, ErlDrvSizeT* sizep)
{
+ int res, init_yield_count, yield_count;
Eterm* objp;
- Uint size = 0; /* Intentionally Uint due to halfword heap */
+ Uint size = (Uint) *sizep; /* Intentionally Uint due to halfword heap */
DECLARE_ESTACK(s);
+
+ if (!yield_support)
+ yield_count = init_yield_count = 0; /* Shut up faulty warning... >:-( */
+ else {
+ if (state->reds_left <= 0)
+ return ERTS_IOLIST_YIELD;
+ ESTACK_CHANGE_ALLOCATOR(s, ERTS_ALC_T_SAVED_ESTACK);
+ init_yield_count = ERTS_IOLIST_SIZE_YIELDS_COUNT_PER_RED;
+ init_yield_count *= state->reds_left;
+ yield_count = init_yield_count;
+ if (state->estack.start) {
+ /* Restart; restore state... */
+ ESTACK_RESTORE(s, &state->estack);
+ size = (Uint) state->size;
+ obj = state->obj;
+ }
+ }
+
goto L_again;
#define SAFE_ADD(Var, Val) \
@@ -3327,51 +3545,101 @@ int erts_iolist_size(Eterm obj, ErlDrvSizeT* sizep)
obj = ESTACK_POP(s);
L_again:
if (is_list(obj)) {
- L_iter_list:
- objp = list_val(obj);
- /* Head */
- obj = CAR(objp);
- if (is_byte(obj)) {
- size++;
- if (size == 0) {
- goto L_overflow_error;
+ while (1) { /* Tail loop */
+ while (1) { /* Head loop */
+ if (yield_support && --yield_count <= 0)
+ goto L_yield;
+ objp = list_val(obj);
+ /* Head */
+ obj = CAR(objp);
+ if (is_byte(obj)) {
+ size++;
+ if (size == 0) {
+ goto L_overflow_error;
+ }
+ } else if (is_binary(obj) && binary_bitsize(obj) == 0) {
+ SAFE_ADD(size, binary_size(obj));
+ } else if (is_list(obj)) {
+ ESTACK_PUSH(s, CDR(objp));
+ continue; /* Head loop */
+ } else if (is_not_nil(obj)) {
+ goto L_type_error;
+ }
+ break;
}
- } else if (is_binary(obj) && binary_bitsize(obj) == 0) {
- SAFE_ADD(size, binary_size(obj));
- } else if (is_list(obj)) {
- ESTACK_PUSH(s, CDR(objp));
- goto L_iter_list; /* on head */
- } else if (is_not_nil(obj)) {
- goto L_type_error;
+ /* Tail */
+ obj = CDR(objp);
+ if (is_list(obj))
+ continue; /* Tail loop */
+ else if (is_binary(obj) && binary_bitsize(obj) == 0) {
+ SAFE_ADD(size, binary_size(obj));
+ } else if (is_not_nil(obj)) {
+ goto L_type_error;
+ }
+ break;
}
- /* Tail */
- obj = CDR(objp);
- if (is_list(obj))
- goto L_iter_list; /* on tail */
- else if (is_binary(obj) && binary_bitsize(obj) == 0) {
+ } else {
+ if (yield_support && --yield_count <= 0)
+ goto L_yield;
+ if (is_binary(obj) && binary_bitsize(obj) == 0) { /* Tail was binary */
SAFE_ADD(size, binary_size(obj));
} else if (is_not_nil(obj)) {
goto L_type_error;
}
- } else if (is_binary(obj) && binary_bitsize(obj) == 0) { /* Tail was binary */
- SAFE_ADD(size, binary_size(obj));
- } else if (is_not_nil(obj)) {
- goto L_type_error;
}
}
#undef SAFE_ADD
- DESTROY_ESTACK(s);
*sizep = (ErlDrvSizeT) size;
- return ERTS_IOLIST_OK;
- L_overflow_error:
+ res = ERTS_IOLIST_OK;
+
+ L_return:
+
DESTROY_ESTACK(s);
- return ERTS_IOLIST_OVERFLOW;
+
+ if (yield_support) {
+ int yc, reds;
+ CLEAR_SAVED_ESTACK(&state->estack);
+ yc = init_yield_count - yield_count;
+ reds = ((yc - 1) / ERTS_IOLIST_SIZE_YIELDS_COUNT_PER_RED) + 1;
+ BUMP_REDS(state->c_p, reds);
+ state->reds_left -= reds;
+ state->size = (ErlDrvSizeT) size;
+ state->have_size = 1;
+ }
+
+ return res;
+
+ L_overflow_error:
+ res = ERTS_IOLIST_OVERFLOW;
+ size = 0;
+ goto L_return;
L_type_error:
- DESTROY_ESTACK(s);
- return ERTS_IOLIST_TYPE;
+ res = ERTS_IOLIST_TYPE;
+ size = 0;
+ goto L_return;
+
+ L_yield:
+ BUMP_ALL_REDS(state->c_p);
+ state->reds_left = 0;
+ state->size = size;
+ state->obj = obj;
+ ESTACK_SAVE(s, &state->estack);
+ return ERTS_IOLIST_YIELD;
+}
+
+int erts_iolist_size_yielding(ErtsIOListState *state)
+{
+ ErlDrvSizeT size = state->size;
+ return iolist_size(1, state, state->obj, &size);
+}
+
+int erts_iolist_size(Eterm obj, ErlDrvSizeT* sizep)
+{
+ *sizep = 0;
+ return iolist_size(0, NULL, obj, sizep);
}
/* return 0 if item is not a non-empty flat list of bytes */
@@ -3680,6 +3948,9 @@ erts_save_emu_args(int argc, char **argv)
size += sz+1;
}
ptr = (char *) malloc(size);
+ if (!ptr) {
+ ERTS_INTERNAL_ERROR("malloc failed to allocate memory!");
+ }
#ifdef DEBUG
end_ptr = ptr + size;
#endif
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 09bada457d..09d90f4984 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -4372,7 +4372,7 @@ static int erl_inet_close(inet_descriptor* desc)
desc_close(desc);
desc->state = INET_STATE_CLOSED;
} else if (desc->prebound && (desc->s != INVALID_SOCKET)) {
- sock_select(desc, FD_READ | FD_WRITE | FD_CLOSE, 0);
+ sock_select(desc, FD_READ | FD_WRITE | FD_CLOSE | ERL_DRV_USE_NO_CALLBACK, 0);
desc->event_mask = 0;
#ifdef __WIN32__
desc->forced_events = 0;
@@ -4536,7 +4536,8 @@ static ErlDrvSSizeT inet_ctl_open(inet_descriptor* desc, int domain, int type,
/* as inet_open but pass in an open socket (MUST BE OF RIGHT TYPE) */
static ErlDrvSSizeT inet_ctl_fdopen(inet_descriptor* desc, int domain, int type,
- SOCKET s, char** rbuf, ErlDrvSizeT rsize)
+ SOCKET s, Uint32 bound,
+ char** rbuf, ErlDrvSizeT rsize)
{
inet_address name;
unsigned int sz = sizeof(name);
@@ -4560,7 +4561,12 @@ static ErlDrvSSizeT inet_ctl_fdopen(inet_descriptor* desc, int domain, int type,
#ifdef __WIN32__
driver_select(desc->port, desc->event, ERL_DRV_READ, 1);
#endif
- desc->state = INET_STATE_BOUND; /* assume bound */
+
+ if (bound)
+ desc->state = INET_STATE_BOUND;
+ else
+ desc->state = INET_STATE_OPEN;
+
if (type == SOCK_STREAM) { /* check if connected */
sz = sizeof(name);
if (!IS_SOCKET_ERROR(sock_peer(s, (struct sockaddr*) &name, &sz))) {
@@ -9121,10 +9127,11 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
break;
}
- case INET_REQ_FDOPEN: { /* pass in an open socket */
+ case INET_REQ_FDOPEN: { /* pass in an open (and optionally bound) socket */
int domain;
+ int bound;
DEBUGF(("tcp_inet_ctl(%ld): FDOPEN\r\n", (long)desc->inet.port));
- if (len != 6) return ctl_error(EINVAL, rbuf, rsize);
+ if (len != 6 && len != 10) return ctl_error(EINVAL, rbuf, rsize);
switch(buf[0]) {
case INET_AF_INET:
domain = AF_INET;
@@ -9142,8 +9149,13 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
return ctl_error(EINVAL, rbuf, rsize);
}
if (buf[1] != INET_TYPE_STREAM) return ctl_error(EINVAL, rbuf, rsize);
+
+ if (len == 6) bound = 1;
+ else bound = get_int32(buf+2+4);
+
return inet_ctl_fdopen(INETP(desc), domain, SOCK_STREAM,
- (SOCKET) get_int32(buf+2), rbuf, rsize);
+ (SOCKET) get_int32(buf+2),
+ bound, rbuf, rsize);
break;
}
@@ -11116,10 +11128,11 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf,
return replen;
- case INET_REQ_FDOPEN: { /* pass in an open (and bound) socket */
+ case INET_REQ_FDOPEN: { /* pass in an open (and optionally bound) socket */
SOCKET s;
+ int bound;
DEBUGF(("packet inet_ctl(%ld): FDOPEN\r\n", (long)desc->port));
- if (len != 6) {
+ if (len != 6 && len != 10) {
return ctl_error(EINVAL, rbuf, rsize);
}
switch (buf[0]) {
@@ -11144,7 +11157,11 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf,
return ctl_error(EINVAL, rbuf, rsize);
}
s = (SOCKET)get_int32(buf+2);
- replen = inet_ctl_fdopen(desc, af, type, s, rbuf, rsize);
+
+ if (len == 6) bound = 1;
+ else bound = get_int32(buf+2+4);
+
+ replen = inet_ctl_fdopen(desc, af, type, s, bound, rbuf, rsize);
if ((*rbuf)[0] != INET_REP_ERROR) {
if (desc->active)
diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4
index 0997d81b2f..5f92b6bac4 100644
--- a/erts/emulator/hipe/hipe_bif_list.m4
+++ b/erts/emulator/hipe/hipe_bif_list.m4
@@ -268,9 +268,16 @@ noproc_primop_interface_1(nbif_atomic_inc, hipe_atomic_inc)
*/
define(CFUN,`ifelse($1,term_to_binary_1,hipe_wrapper_term_to_binary_1,
ifelse($1,term_to_binary_2,hipe_wrapper_term_to_binary_2,
-ifelse($1,erts_internal_binary_to_term_1,hipe_wrapper_erts_internal_binary_to_term_1,
-ifelse($1,erts_internal_binary_to_term_2,hipe_wrapper_erts_internal_binary_to_term_2,
-$1))))')
+ifelse($1,binary_to_term_1,hipe_wrapper_binary_to_term_1,
+ifelse($1,binary_to_term_2,hipe_wrapper_binary_to_term_2,
+ifelse($1,binary_to_list_1,hipe_wrapper_binary_to_list_1,
+ifelse($1,binary_to_list_3,hipe_wrapper_binary_to_list_3,
+ifelse($1,bitstring_to_list_1,hipe_wrapper_bitstring_to_list_1,
+ifelse($1,list_to_binary_1,hipe_wrapper_list_to_binary_1,
+ifelse($1,iolist_to_binary_1,hipe_wrapper_iolist_to_binary_1,
+ifelse($1,binary_list_to_bin_1,hipe_wrapper_binary_list_to_bin_1,
+ifelse($1,list_to_bitstring_1,hipe_wrapper_list_to_bitstring_1,
+$1)))))))))))')
define(BIF_LIST,`standard_bif_interface_$3(nbif_$4, CFUN($4))')
include(TARGET/`erl_bif_list.h')
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index 0ded6b274e..0ded6b274e 100755..100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 0b0568c31a..dfbe47786a 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -31,6 +31,7 @@ MODULES= \
a_SUITE \
after_SUITE \
alloc_SUITE \
+ async_ports_SUITE \
beam_SUITE \
beam_literals_SUITE \
bif_SUITE \
diff --git a/erts/emulator/test/async_ports_SUITE.erl b/erts/emulator/test/async_ports_SUITE.erl
new file mode 100644
index 0000000000..c89b3655ff
--- /dev/null
+++ b/erts/emulator/test/async_ports_SUITE.erl
@@ -0,0 +1,118 @@
+-module(async_ports_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+-define(PACKET_SIZE, (10 * 1024 * 8)).
+-define(CPORT_DELAY, 100).
+-define(TEST_LOOPS_COUNT, 100000).
+-define(SLEEP_BEFORE_CHECK, 1000).
+-define(TEST_PROCS_COUNT, 2).
+-define(TC_TIMETRAP_SECONDS, 10).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [
+ permanent_busy_test
+ ].
+
+permanent_busy_test(Config) ->
+ ct:timetrap({seconds, ?TC_TIMETRAP_SECONDS}),
+ ExePath = filename:join(?config(data_dir, Config), "cport"),
+
+ Self = self(),
+ spawn_link(
+ fun() ->
+ Block = <<0:?PACKET_SIZE>>,
+
+ Port = open_port(ExePath),
+
+ Testers =
+ lists:map(
+ fun(_) ->
+ erlang:spawn_link(?MODULE, run_loop,
+ [Self,
+ Port,
+ Block,
+ ?TEST_LOOPS_COUNT,
+ 0])
+ end,
+ lists:seq(1, ?TEST_PROCS_COUNT)),
+ Self ! {test_info, Port, Testers},
+ endless_flush(Port)
+ end),
+
+ receive
+ {test_info, Port, Testers} ->
+ MaxWaitTime = round(0.7 * ?TC_TIMETRAP_SECONDS * 1000),
+ ct:log("wait testers, maximum ~w mcsec~n", [MaxWaitTime]),
+ ok = wait_testers(MaxWaitTime, Testers),
+ timer:sleep(?SLEEP_BEFORE_CHECK),
+ case erlang:port_command(Port, <<"test">>, [nosuspend]) of
+ false ->
+ exit(port_dead);
+ true ->
+ ok
+ end
+ end.
+
+wait_testers(Timeout, Testers) ->
+ lists:foldl(
+ fun(Pid, AccIn) ->
+ StartWait = os:timestamp(),
+ receive
+ {Pid, port_dead} ->
+ recalc_timeout(AccIn, StartWait)
+ after AccIn ->
+ Pid ! stop,
+ recalc_timeout(AccIn, StartWait)
+ end
+ end, Timeout, Testers),
+ ok.
+
+recalc_timeout(TimeoutIn, WaitStart) ->
+ erlang:max(0, TimeoutIn - round(timer:now_diff(os:timestamp(), WaitStart)) div 1000).
+
+open_port(ExePath) ->
+ erlang:open_port({spawn, ExePath ++ " 100"}, [{packet, 4}, eof, exit_status, use_stdio, binary]).
+
+run_loop(RootProc, Port, Block, CheckLimit, BusyCnt) ->
+ receive
+ stop ->
+ ok
+ after 0 ->
+ case erlang:port_command(Port, Block, [nosuspend]) of
+ true ->
+ run_loop(RootProc, Port, Block, CheckLimit, 0);
+ false ->
+ if
+ BusyCnt + 1 > CheckLimit ->
+ check_dead(RootProc, Port, Block, CheckLimit);
+ true ->
+ run_loop(RootProc, Port, Block, CheckLimit, BusyCnt + 1)
+ end
+ end
+ end.
+
+check_dead(RootProc, Port, Block, CheckLimit) ->
+ ct:log("~p: check port dead~n", [self()]),
+ timer:sleep(?SLEEP_BEFORE_CHECK),
+ case erlang:port_command(Port, Block, [nosuspend]) of
+ true ->
+ ct:log("not dead~n"),
+ run_loop(RootProc, Port, Block, CheckLimit, 0);
+ false ->
+ ct:log("port dead: ~p~n", [Port]),
+ RootProc ! {self(), port_dead},
+ ok
+ end.
+
+endless_flush(Port) ->
+ receive
+ {Port, {data, _}} ->
+ endless_flush(Port);
+ {Port, SomethingWrong} ->
+ erlang:error({someting_wrong, SomethingWrong})
+ end.
diff --git a/erts/emulator/test/async_ports_SUITE_data/Makefile.src b/erts/emulator/test/async_ports_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..56da3fbe12
--- /dev/null
+++ b/erts/emulator/test/async_ports_SUITE_data/Makefile.src
@@ -0,0 +1,15 @@
+CC = @CC@
+LD = @LD@
+CFLAGS = @CFLAGS@ @DEFS@
+CROSSLDFLAGS = @CROSSLDFLAGS@
+
+PROGS = cport@exe@
+
+
+all: $(PROGS)
+
+cport@exe@: cport@obj@
+ $(LD) $(CROSSLDFLAGS) -o cport cport@obj@ @LIBS@
+
+cport@obj@: cport.c
+ $(CC) -c -o cport@obj@ $(CFLAGS) cport.c
diff --git a/erts/emulator/test/async_ports_SUITE_data/cport.c b/erts/emulator/test/async_ports_SUITE_data/cport.c
new file mode 100644
index 0000000000..033aff382a
--- /dev/null
+++ b/erts/emulator/test/async_ports_SUITE_data/cport.c
@@ -0,0 +1,81 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#ifdef __WIN32__
+# include "windows.h"
+# include "winbase.h"
+#else
+# include <unistd.h>
+#endif
+
+typedef unsigned char byte;
+
+int read_cmd(byte *buf)
+{
+ int len;
+ if (read_exact(buf, 4) != 4)
+ return(-1);
+
+ len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ return read_exact(buf, len);
+}
+
+int write_cmd(byte *buf, int len)
+{
+ byte li[4];
+ li[0] = (len >> 24) & 0xff;
+ li[1] = (len >> 16) & 0xff;
+ li[2] = (len >> 8) & 0xff;
+ li[3] = len & 0xff;
+ write_exact(&li, 4);
+
+ return write_exact(buf, len);
+}
+
+int read_exact(byte *buf, int len)
+{
+ int i, got=0;
+ do {
+ if ((i = read(0, buf+got, len-got)) <= 0)
+ {
+ return(i);
+ }
+ got += i;
+ } while (got<len);
+ return len;
+}
+
+int write_exact(byte *buf, int len)
+{
+ int i, wrote = 0;
+ do {
+ if ((i = write(1, buf+wrote, len-wrote)) < 0)
+ return (i);
+ wrote += i;
+ } while (wrote<len);
+ return len;
+}
+
+byte static_buf[31457280]; // 30 mb
+
+int main(int argc, char **argv) {
+ int sleep_time = atoi(argv[1]);
+ int fn, arg, res;
+ byte *buf = &static_buf[0];
+ int len = 0;
+ if (sleep_time <= 0)
+ sleep_time = 0;
+#ifdef __WIN32__
+ else
+ sleep_time = ((sleep_time - 1) / 1000) + 1; /* Milli seconds */
+#endif
+ while ((len = read_cmd(buf)) > 0) {
+#ifdef __WIN32__
+ Sleep((DWORD) sleep_time);
+#else
+ usleep(sleep_time);
+#endif
+ write_cmd(buf, len);
+ }
+}
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 7aba367e33..44e9e4f243 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -58,7 +58,8 @@
ordering/1,unaligned_order/1,gc_test/1,
bit_sized_binary_sizes/1,
otp_6817/1,deep/1,obsolete_funs/1,robustness/1,otp_8117/1,
- otp_8180/1, trapping/1]).
+ otp_8180/1, trapping/1, large/1,
+ error_after_yield/1, cmp_old_impl/1]).
%% Internal exports.
-export([sleeper/0,trapping_loop/4]).
@@ -76,7 +77,8 @@ all() ->
bad_term_to_binary, more_bad_terms, otp_5484, otp_5933,
ordering, unaligned_order, gc_test,
bit_sized_binary_sizes, otp_6817, otp_8117, deep,
- obsolete_funs, robustness, otp_8180, trapping].
+ obsolete_funs, robustness, otp_8180, trapping, large,
+ error_after_yield, cmp_old_impl].
groups() ->
[].
@@ -1351,7 +1353,16 @@ trapping(Config) when is_list(Config)->
do_trapping(5, term_to_binary,
fun() -> [lists:duplicate(2000000,2000000)] end),
do_trapping(5, binary_to_term,
- fun() -> [term_to_binary(lists:duplicate(2000000,2000000))] end).
+ fun() -> [term_to_binary(lists:duplicate(2000000,2000000))] end),
+ do_trapping(5, binary_to_list,
+ fun() -> [list_to_binary(lists:duplicate(2000000,$x))] end),
+ do_trapping(5, list_to_binary,
+ fun() -> [lists:duplicate(2000000,$x)] end),
+ do_trapping(5, bitstring_to_list,
+ fun() -> [list_to_bitstring([lists:duplicate(2000000,$x),<<7:4>>])] end),
+ do_trapping(5, list_to_bitstring,
+ fun() -> [[lists:duplicate(2000000,$x),<<7:4>>]] end)
+ .
do_trapping(0, _, _) ->
ok;
@@ -1384,9 +1395,189 @@ trapping_loop2(Bif,Args,N) ->
apply(erlang,Bif,Args),
trapping_loop2(Bif, Args, N-1).
+large(Config) when is_list(Config) ->
+ List = lists:flatten(lists:map(fun (_) ->
+ [0,1,2,3,4,5,6,7,8]
+ end,
+ lists:seq(1, 131072))),
+ Bin = list_to_binary(List),
+ List = binary_to_list(Bin),
+ PartList = lists:reverse(tl(tl(lists:reverse(tl(tl(List)))))),
+ PartList = binary_to_list(Bin, 3, length(List)-2),
+ ListBS = List ++ [<<7:4>>],
+ ListBS = bitstring_to_list(list_to_bitstring(ListBS)),
+ BitStr1 = list_to_bitstring(lists:duplicate(1024*1024, [<<1,5:3>>])),
+ BitStr1 = list_to_bitstring(bitstring_to_list(BitStr1)),
+ BitStr2 = list_to_bitstring([lists:duplicate(512*1024, [<<1,5:3>>]),
+ Bin]),
+ BitStr2 = list_to_bitstring(bitstring_to_list(BitStr2)),
+ ok.
+
+error_after_yield(Config) when is_list(Config) ->
+ L2BTrap = {erts_internal, list_to_binary_continue, 1},
+ error_after_yield(badarg, erlang, list_to_binary, 1, fun () -> [[mk_list(1000000), oops]] end, L2BTrap),
+ error_after_yield(badarg, erlang, iolist_to_binary, 1, fun () -> [[list2iolist(mk_list(1000000)), oops]] end, L2BTrap),
+ error_after_yield(badarg, erlang, list_to_bitstring, 1, fun () -> [[list2bitstrlist(mk_list(1000000)), oops]] end, L2BTrap),
+ error_after_yield(badarg, binary, list_to_bin, 1, fun () -> [[mk_list(1000000), oops]] end, L2BTrap),
+
+ B2TTrap = {erts_internal, binary_to_term_trap, 1},
+
+ error_after_yield(badarg, erlang, binary_to_term, 1, fun () -> [error_after_yield_bad_ext_term()] end, B2TTrap),
+ error_after_yield(badarg, erlang, binary_to_term, 2, fun () -> [error_after_yield_bad_ext_term(), [safe]] end, B2TTrap),
+
+ case erlang:system_info(wordsize) of
+ 4 ->
+ SysLimitSz = 1 bsl 32,
+ error_after_yield(system_limit, erlang, list_to_binary, 1, fun () -> [[huge_iolist(SysLimitSz), $x]] end, L2BTrap),
+ error_after_yield(system_limit, erlang, iolist_to_binary, 1, fun () -> [[huge_iolist(SysLimitSz), $x]] end, L2BTrap),
+ error_after_yield(system_limit, erlang, list_to_bitstring, 1, fun () -> [[huge_iolist(SysLimitSz), $x]] end, L2BTrap),
+ error_after_yield(system_limit, binary, list_to_bin, 1, fun () -> [[huge_iolist(SysLimitSz), $x]] end, L2BTrap);
+ 8 ->
+ % Takes waaaay to long time to test system_limit on 64-bit archs...
+ ok
+ end,
+ ok.
+
+error_after_yield(Type, M, F, AN, AFun, TrapFunc) ->
+ io:format("Testing ~p for ~p:~p/~p~n", [Type, M, F, AN]),
+ Tracer = self(),
+ {Pid, Mon} = spawn_monitor(fun () ->
+ A = AFun(),
+ try
+ erlang:yield(),
+ erlang:trace(self(),true,[running,{tracer,Tracer}]),
+ apply(M, F, A),
+ exit({unexpected_success, {M, F, A}})
+ catch
+ error:Type ->
+ erlang:trace(self(),false,[running,{tracer,Tracer}]),
+ %% We threw the exception from the native
+ %% function we trapped to, but we want
+ %% the BIF that originally was called
+ %% to appear in the stack trace.
+ [{M, F, A, _} | _] = erlang:get_stacktrace()
+ end
+ end),
+ receive
+ {'DOWN', Mon, process, Pid, Reason} ->
+ normal = Reason
+ end,
+ TD = erlang:trace_delivered(Pid),
+ receive
+ {trace_delivered, Pid, TD} ->
+ NoYields = error_after_yield_sched(Pid, TrapFunc, 0),
+ io:format("No of yields: ~p~n", [NoYields]),
+ true = NoYields > 2
+ end,
+ ok.
+
+error_after_yield_sched(P, TrapFunc, N) ->
+ receive
+ {trace, P, out, TrapFunc} ->
+ receive
+ {trace, P, in, TrapFunc} ->
+ error_after_yield_sched(P, TrapFunc, N+1)
+ after 0 ->
+ exit(trap_sched_mismatch)
+ end;
+ {trace, P, out, Func} ->
+ receive
+ {trace, P, in, Func} ->
+ error_after_yield_sched(P, TrapFunc, N)
+ after 0 ->
+ exit(other_sched_mismatch)
+ end
+ after 0 ->
+ N
+ end.
+
+error_after_yield_bad_ext_term() ->
+ TupleSz = 2000000,
+ <<131, % Version magic
+ AtomExt/binary>> = term_to_binary(an_atom_we_use_for_this),
+ BadAtomExt = [100, %% ATOM_EXT
+ 255, 255, % Invalid size of 65535 bytes
+ "oops"],
+
+ %% Produce a large tuple where the last element is invalid
+ list_to_binary([131, %% Version magic
+ 105, %% LARGE_TUPLE_EXT
+ <<TupleSz:32/big>>, %% Tuple size
+ lists:duplicate(TupleSz-1, AtomExt), %% Valid atoms
+ BadAtomExt]). %% Invalid atom at the end
+
+cmp_old_impl(Config) when is_list(Config) ->
+ %% Compare results from new yielding implementations with
+ %% old non yielding implementations
+ Cookie = atom_to_list(erlang:get_cookie()),
+ Rel = "r16b_latest",
+ case test_server:is_release_available(Rel) of
+ false ->
+ {skipped, "No "++Rel++" available"};
+ true ->
+ {ok, Node} = ?t:start_node(list_to_atom(atom_to_list(?MODULE)++"_"++Rel),
+ peer,
+ [{args, " -setcookie "++Cookie},
+ {erl, [{release, Rel}]}]),
+
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(1))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(10))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(100))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(1000))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(10000))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(100000))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(1000000))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list(10000000))]}),
+ cmp_node(Node, {erlang, list_to_binary, [list2iolist(mk_list_lb(10000000))]}),
+
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(1))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(10))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(100))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(1000))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(10000))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(100000))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(1000000))]}),
+ cmp_node(Node, {erlang, binary_to_list, [list_to_binary(mk_list(10000000))]}),
+
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(1))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(10))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(100))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(1000))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(10000))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(100000))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(1000000))]}),
+ cmp_node(Node, {erlang, list_to_bitstring, [list2bitstrlist(mk_list(10000000))]}),
+
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(1)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(10)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(100)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(1000)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(10000)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(100000)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(1000000)))]}),
+ cmp_node(Node, {erlang, bitstring_to_list, [list_to_bitstring(list2bitstrlist(mk_list(10000000)))]}),
+
+ ?t:stop_node(Node),
+
+ ok
+ end.
%% Utilities.
+huge_iolist(Lim) ->
+ Sz = 1024,
+ huge_iolist(list_to_binary(mk_list(Sz)), Sz, Lim).
+
+huge_iolist(X, Sz, Lim) when Sz >= Lim ->
+ X;
+huge_iolist(X, Sz, Lim) ->
+ huge_iolist([X, X], Sz*2, Lim).
+
+cmp_node(Node, {M, F, A}) ->
+ Res = rpc:call(Node, M, F, A),
+ Res = apply(M, F, A),
+ ok.
+
make_sub_binary(Bin) when is_binary(Bin) ->
{_,B} = split_binary(list_to_binary([0,1,3,Bin]), 3),
B;
@@ -1467,3 +1658,78 @@ get_reds() ->
erts_debug:set_internal_state(available_internal_state, true),
get_reds()
end.
+
+-define(LARGE_BIN, (512*1024+10)).
+-define(LARGE_BIN_LIM, (1024*1024)).
+
+mk_list(0, Acc) ->
+ Acc;
+mk_list(Sz, Acc) ->
+ mk_list(Sz-1, [$A+(Sz band 63) | Acc]).
+
+mk_list(Sz) when Sz >= ?LARGE_BIN_LIM ->
+ SzLeft = Sz - ?LARGE_BIN,
+ SzHd = SzLeft div 2,
+ SzTl = SzLeft - SzHd,
+ [mk_list(SzHd, []), erlang:list_to_binary(mk_list(?LARGE_BIN, [])), mk_list(SzTl, [])];
+mk_list(Sz) ->
+ mk_list(Sz, []).
+
+mk_list_lb(Sz) when Sz >= ?LARGE_BIN_LIM ->
+ SzLeft = Sz - ?LARGE_BIN,
+ SzHd = SzLeft div 2,
+ SzTl = SzLeft - SzHd,
+ [mk_list(SzHd, []), erlang:list_to_binary(mk_list(?LARGE_BIN, [])), mk_list(SzTl, [])];
+mk_list_lb(Sz) ->
+ mk_list(Sz, []).
+
+
+list2iolist(List) ->
+ list2iolist(List, []).
+
+list2iolist([], Acc) ->
+ Acc;
+list2iolist([X0, X1, X2, X3, X4, X5 | Xs], Acc) when is_integer(X0), 0 =< X0, X0 < 256,
+ is_integer(X1), 0 =< X1, X1 < 256,
+ is_integer(X2), 0 =< X2, X2 < 256,
+ is_integer(X3), 0 =< X3, X3 < 256,
+ is_integer(X4), 0 =< X4, X4 < 256,
+ is_integer(X5), 0 =< X5, X5 < 256 ->
+ NewAcc = case (X0+X1+X2+X3+X4+X5) band 3 of
+ 0 ->
+ [Acc, [[[[[[[[[[[[X0,[],<<"">>,X1]]]]]]]]],[X2,X3]],[],[],[],[],X4],X5]];
+ 1 ->
+ [Acc, [], erlang:list_to_binary([X0, X1, X2, X3, X4, X5])];
+ 2 ->
+ [Acc, [[[[X0|erlang:list_to_binary([X1])],[X2|erlang:list_to_binary([X3])],[X4|erlang:list_to_binary([X5])]]]|<<"">>]];
+ 3 ->
+ [Acc, X0, X1, X2, <<"">>, [], X3, X4 | erlang:list_to_binary([X5])]
+ end,
+ list2iolist(Xs, NewAcc);
+list2iolist([X | Xs], Acc) ->
+ list2iolist(Xs, [Acc,X]).
+
+list2bitstrlist(List) ->
+ [list2bitstrlist(List, []), <<4:7>>].
+
+list2bitstrlist([], Acc) ->
+ Acc;
+list2bitstrlist([X0, X1, X2, X3, X4, X5 | Xs], Acc) when is_integer(X0), 0 =< X0, X0 < 256,
+ is_integer(X1), 0 =< X1, X1 < 256,
+ is_integer(X2), 0 =< X2, X2 < 256,
+ is_integer(X3), 0 =< X3, X3 < 256,
+ is_integer(X4), 0 =< X4, X4 < 256,
+ is_integer(X5), 0 =< X5, X5 < 256 ->
+ NewAcc = case (X0+X1+X2+X3+X4+X5) band 3 of
+ 0 ->
+ [Acc, [[[[[[[[[[[[X0,[],<<"">>,X1]]]]]]]]],[X2,X3]],[],[],[],[],X4],X5]];
+ 1 ->
+ [Acc, [], <<X0:X1>>, <<X2:X3>>, <<X4:X5>>];
+ 2 ->
+ [Acc, [[[[X0|<<X1:X2>>],X3]],[X4|erlang:list_to_binary([X5])]|<<"">>]];
+ 3 ->
+ [Acc, X0, X1, X2, <<"">>, [], X3, X4 | erlang:list_to_binary([X5])]
+ end,
+ list2bitstrlist(Xs, NewAcc);
+list2bitstrlist([X | Xs], Acc) ->
+ list2bitstrlist(Xs, [Acc,X]).
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index c62bc0c454..344bde7c91 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -1062,10 +1062,9 @@ otp_6602(Config) when is_list(Config) ->
%% Inet driver use port locking...
{ok, S} = gen_udp:open(0),
{ok, Fd} = inet:getfd(S),
- {ok, Port} = inet:port(S),
%% Steal fd (lock checker used to
%% trigger here).
- {ok, _S2} = gen_udp:open(Port,[{fd,Fd}]),
+ {ok, _S2} = gen_udp:open(0,[{fd,Fd}]),
Parent ! Done
end),
?line receive Done -> ok end,
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index ceb4afb5cf..f959714be7 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -155,6 +155,7 @@ misc_smoke_tests(Config) when is_list(Config) ->
?line true = is_binary(erlang:system_info(loaded)),
?line true = is_binary(erlang:system_info(dist)),
?line ok = try erlang:system_info({cpu_topology,erts_get_cpu_topology_error_case}), fail catch error:badarg -> ok end,
+ true = lists:member(erlang:system_info(tolerant_timeofday), [enabled, disabled]),
?line ok.
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 2251575e5a..4d7598cf1f 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -181,6 +181,13 @@ send_trace(Config) when is_list(Config) ->
?line {trace, Sender, send, to_receiver, Receiver} = receive_first(),
?line receive_nothing(),
+ %% Check that a message sent to another registered process is traced.
+ register(?MODULE,Receiver),
+ Sender ! {send_please, ?MODULE, to_receiver},
+ {trace, Sender, send, to_receiver, ?MODULE} = receive_first(),
+ receive_nothing(),
+ unregister(?MODULE),
+
%% Check that a message sent to this process is traced.
?line Sender ! {send_please, self(), to_myself},
?line receive to_myself -> ok end,
@@ -188,6 +195,21 @@ send_trace(Config) when is_list(Config) ->
?line {trace, Sender, send, to_myself, Self} = receive_first(),
?line receive_nothing(),
+ %% Check that a message sent to dead process is traced.
+ {Pid,Ref} = spawn_monitor(fun() -> ok end),
+ receive {'DOWN',Ref,_,_,_} -> ok end,
+ Sender ! {send_please, Pid, to_dead},
+ {trace, Sender, send_to_non_existing_process, to_dead, Pid} = receive_first(),
+ receive_nothing(),
+
+ %% Check that a message sent to unknown registrated process is traced.
+ BadargSender = fun_spawn(fun sender/0),
+ 1 = erlang:trace(BadargSender, true, [send]),
+ unlink(BadargSender),
+ BadargSender ! {send_please, not_registered, to_unknown},
+ {trace, BadargSender, send, to_unknown, not_registered} = receive_first(),
+ receive_nothing(),
+
%% Another process should not be able to trace Sender.
?line Intruder = fun_spawn(fun() -> erlang:trace(Sender, true, [send]) end),
?line {'EXIT', Intruder, {badarg, _}} = receive_first(),
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 19c92681d0..bf6eb00314 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -2842,6 +2842,152 @@ document etp-search-alloc
end
+define etp-alloc-stats
+ printf "\nIx Name Inst. Blocks Bytes Carriers Crr.bytes Util\n"
+ set $etp_tot_block_no = 0
+ set $etp_tot_block_sz = 0
+ set $etp_tot_crr_no = 0
+ set $etp_tot_crr_sz = 0
+ set $etp_ERTS_ALC_A_MIN = 1
+ set $etp_ERTS_ALC_A_MAX = (sizeof(erts_allctrs) / sizeof(*erts_allctrs)) - 1
+
+ set $etp_ix = $etp_ERTS_ALC_A_MIN
+ while $etp_ix <= $etp_ERTS_ALC_A_MAX
+ set $etp_allctr = 0
+ set $etp_alloc = erts_allctrs[$etp_ix].alloc
+ if $etp_alloc != erts_sys_alloc
+ if $etp_alloc == erts_alcu_alloc_thr_spec || \
+ $etp_alloc == erts_alcu_alloc_thr_pref
+ set $etp_instance = 0
+ set $etp_block_no = 0
+ set $etp_block_sz = 0
+ set $etp_crr_no = 0
+ set $etp_crr_sz = 0
+ set $etp_tspec = (ErtsAllocatorThrSpec_t *) erts_allctrs[$etp_ix].extra
+ if $etp_tspec->enabled
+ while $etp_instance < $etp_tspec->size
+ set $etp_allctr = $etp_tspec->allctr[$etp_instance]
+ set $etp_block_no = $etp_block_no + $etp_allctr->mbcs.blocks.curr.no \
+ + $etp_allctr->sbcs.blocks.curr.no
+ set $etp_block_sz = $etp_block_sz + $etp_allctr->mbcs.blocks.curr.size \
+ + $etp_allctr->sbcs.blocks.curr.size
+ set $etp_crr_no = $etp_crr_no + $etp_allctr->mbcs.curr.norm.mseg.no \
+ + $etp_allctr->sbcs.curr.norm.mseg.no \
+ + $etp_allctr->mbcs.curr.norm.sys_alloc.no \
+ + $etp_allctr->sbcs.curr.norm.sys_alloc.no
+ set $etp_crr_sz = $etp_crr_sz + $etp_allctr->mbcs.curr.norm.mseg.size \
+ + $etp_allctr->sbcs.curr.norm.mseg.size \
+ + $etp_allctr->mbcs.curr.norm.sys_alloc.size \
+ + $etp_allctr->sbcs.curr.norm.sys_alloc.size
+ set $etp_instance = $etp_instance + 1
+ end
+ else
+ printf "erts_allctr[%d]: Disabled (thread specific)\n", $etp_ix
+ end
+ else
+ if $etp_alloc == erts_alcu_alloc_ts || $etp_alloc == erts_alcu_alloc
+ set $etp_allctr = (Allctr_t*) erts_allctrs[$etp_ix].extra
+ set $etp_block_no = $etp_allctr->mbcs.blocks.curr.no \
+ + $etp_allctr->sbcs.blocks.curr.no
+ set $etp_block_sz = $etp_allctr->mbcs.blocks.curr.size \
+ + $etp_allctr->sbcs.blocks.curr.size
+ set $etp_crr_no = $etp_allctr->mbcs.curr.norm.mseg.no \
+ + $etp_allctr->sbcs.curr.norm.mseg.no \
+ + $etp_allctr->mbcs.curr.norm.sys_alloc.no \
+ + $etp_allctr->sbcs.curr.norm.sys_alloc.no
+ set $etp_crr_sz = $etp_allctr->mbcs.curr.norm.mseg.size \
+ + $etp_allctr->sbcs.curr.norm.mseg.size \
+ + $etp_allctr->mbcs.curr.norm.sys_alloc.size \
+ + $etp_allctr->sbcs.curr.norm.sys_alloc.size
+ set $etp_instance = 1
+ else
+ printf "erts_allctr[%d]: Unknown allocation function: ", $etp_ix
+ p $etp_alloc
+ end
+ end
+ end
+ if $etp_allctr != 0
+ printf "%2d %-8s%2d%12lu%13lu%12lu%13lu", $etp_ix, $etp_allctr->name_prefix, \
+ $etp_instance, \
+ $etp_block_no, $etp_block_sz, $etp_crr_no, $etp_crr_sz
+ if $etp_crr_sz != 0
+ printf "%5lu%%", ($etp_block_sz * 100) / $etp_crr_sz
+ end
+ printf "\n"
+ set $etp_tot_block_no = $etp_tot_block_no + $etp_block_no
+ set $etp_tot_block_sz = $etp_tot_block_sz + $etp_block_sz
+ set $etp_tot_crr_no = $etp_tot_crr_no + $etp_crr_no
+ set $etp_tot_crr_sz = $etp_tot_crr_sz + $etp_crr_sz
+ end
+ set $etp_ix = $etp_ix + 1
+ end
+ printf "\nTotal: %12lu%13lu%12lu%13lu", $etp_tot_block_no, $etp_tot_block_sz, \
+ $etp_tot_crr_no, $etp_tot_crr_sz
+ if $etp_tot_crr_sz != 0
+ printf "%5lu%%", ($etp_tot_block_sz * 100) / $etp_tot_crr_sz
+ end
+ printf "\n"
+end
+
+document etp-alloc-stats
+%---------------------------------------------------------------------------
+% etp-alloc-stats
+%
+% Combine and print allocator statistics
+%---------------------------------------------------------------------------
+end
+
+
+define etp-alloc-instances
+ set $etp_ERTS_ALC_A_MIN = 1
+ set $etp_ERTS_ALC_A_MAX = (sizeof(erts_allctrs) / sizeof(*erts_allctrs)) - 1
+
+ set $etp_ix = $arg0
+ if $etp_ix >= $etp_ERTS_ALC_A_MIN && $etp_ix <= $etp_ERTS_ALC_A_MAX
+ set $etp_allctr = 0
+ set $etp_alloc = erts_allctrs[$etp_ix].alloc
+ if $etp_alloc == erts_sys_alloc
+ printf "Allocator %d is sys_alloc\n", $etp_ix
+ else
+ if $etp_alloc == erts_alcu_alloc_thr_spec || \
+ $etp_alloc == erts_alcu_alloc_thr_pref
+ set $etp_instance = 0
+ set $etp_tspec = (ErtsAllocatorThrSpec_t *) erts_allctrs[$etp_ix].extra
+ if $etp_tspec->enabled
+ printf "All instances for allocator '%s'\n", $etp_tspec->allctr[0]->name_prefix
+ while $etp_instance < $etp_tspec->size
+ p $etp_tspec->allctr[$etp_instance]
+ set $etp_instance = $etp_instance + 1
+ end
+ else
+ printf "erts_allctr[%d]: Disabled (thread specific)\n", $etp_ix
+ end
+ else
+ if $etp_alloc == erts_alcu_alloc_ts || $etp_alloc == erts_alcu_alloc
+ set $etp_allctr = (Allctr_t*) erts_allctrs[$etp_ix].extra
+ printf "Single instances for allocator '%s'\n", $etp_allctr->name_prefix
+ p $etp_allctr
+ else
+ printf "erts_allctr[%d]: Unknown allocation function: ", $etp_ix
+ p $etp_alloc
+ end
+ end
+ end
+ else
+ printf "Allocator type not between %d and %d\n", $etp_ERTS_ALC_A_MIN, $etp_ERTS_ALC_A_MAX
+ end
+end
+
+document etp-alloc-instances
+%---------------------------------------------------------------------------
+% etp-alloc-instances
+%
+% Print pointers to all allocator instances for a specific type (Ix)
+%---------------------------------------------------------------------------
+end
+
+
+
define etp-overlapped-heaps
# Args:
diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h
index 54acd1295a..72c054b588 100644
--- a/erts/include/internal/ethread.h
+++ b/erts/include/internal/ethread.h
@@ -31,6 +31,7 @@
#endif
#include <stdlib.h>
+#include "ethread_inline.h"
#include "erl_errno.h"
#if defined(DEBUG)
@@ -51,16 +52,12 @@
# endif
#endif
-#undef ETHR_INLINE
-#if defined(__GNUC__)
-# define ETHR_INLINE __inline__
-#elif defined(__WIN32__)
-# define ETHR_INLINE __forceinline
-#endif
#if defined(ETHR_DEBUG) || !defined(ETHR_INLINE) || ETHR_XCHK \
|| (defined(__GNUC__) && defined(ERTS_MIXED_CYGWIN_VC))
# undef ETHR_INLINE
# define ETHR_INLINE
+# undef ETHR_FORCE_INLINE
+# define ETHR_FORCE_INLINE
# undef ETHR_TRY_INLINE_FUNCS
#endif
@@ -285,19 +282,6 @@ ETHR_PROTO_NORETURN__ ethr_fatal_error__(const char *file,
const char *func,
int err);
-#if !defined(__GNUC__)
-# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) 0
-#elif !defined(__GNUC_MINOR__)
-# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) \
- ((__GNUC__ << 24) >= (((MAJ) << 24) | ((MIN) << 12) | (PL)))
-#elif !defined(__GNUC_PATCHLEVEL__)
-# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) \
- (((__GNUC__ << 24) | (__GNUC_MINOR__ << 12)) >= (((MAJ) << 24) | ((MIN) << 12) | (PL)))
-#else
-# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) \
- (((__GNUC__ << 24) | (__GNUC_MINOR__ << 12) | __GNUC_PATCHLEVEL__) >= (((MAJ) << 24) | ((MIN) << 12) | (PL)))
-#endif
-
#if !ETHR_AT_LEAST_GCC_VSN__(2, 96, 0)
#define __builtin_expect(X, Y) (X)
#endif
diff --git a/erts/include/internal/ethread_inline.h b/erts/include/internal/ethread_inline.h
new file mode 100644
index 0000000000..ffb756c84f
--- /dev/null
+++ b/erts/include/internal/ethread_inline.h
@@ -0,0 +1,49 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2014. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifndef ETHREAD_INLINE_H__
+#define ETHREAD_INLINE_H__
+
+#if !defined(__GNUC__)
+# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) 0
+#elif !defined(__GNUC_MINOR__)
+# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) \
+ ((__GNUC__ << 24) >= (((MAJ) << 24) | ((MIN) << 12) | (PL)))
+#elif !defined(__GNUC_PATCHLEVEL__)
+# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) \
+ (((__GNUC__ << 24) | (__GNUC_MINOR__ << 12)) >= (((MAJ) << 24) | ((MIN) << 12) | (PL)))
+#else
+# define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) \
+ (((__GNUC__ << 24) | (__GNUC_MINOR__ << 12) | __GNUC_PATCHLEVEL__) >= (((MAJ) << 24) | ((MIN) << 12) | (PL)))
+#endif
+
+#undef ETHR_INLINE
+#if defined(__GNUC__)
+# define ETHR_INLINE __inline__
+# if ETHR_AT_LEAST_GCC_VSN__(3, 1, 1)
+# define ETHR_FORCE_INLINE __inline__ __attribute__((__always_inline__))
+# else
+# define ETHR_FORCE_INLINE __inline__
+# endif
+#elif defined(__WIN32__)
+# define ETHR_INLINE __forceinline
+# define ETHR_FORCE_INLINE __forceinline
+#endif
+
+#endif /* #ifndef ETHREAD_INLINE_H__ */
diff --git a/erts/include/internal/win/ethr_membar.h b/erts/include/internal/win/ethr_membar.h
index 8237660b2c..a17f2459fc 100644
--- a/erts/include/internal/win/ethr_membar.h
+++ b/erts/include/internal/win/ethr_membar.h
@@ -63,13 +63,13 @@ do { \
#pragma intrinsic(_mm_sfence)
#pragma intrinsic(_mm_lfence)
-static __forceinline void
+static ETHR_FORCE_INLINE void
ethr_cfence__(void)
{
_ReadWriteBarrier();
}
-static __forceinline void
+static ETHR_FORCE_INLINE void
ethr_mfence__(void)
{
#if ETHR_SIZEOF_PTR == 4
@@ -80,7 +80,7 @@ ethr_mfence__(void)
_mm_mfence();
}
-static __forceinline void
+static ETHR_FORCE_INLINE void
ethr_sfence__(void)
{
#if ETHR_SIZEOF_PTR == 4
@@ -91,7 +91,7 @@ ethr_sfence__(void)
_mm_sfence();
}
-static __forceinline void
+static ETHR_FORCE_INLINE void
ethr_lfence__(void)
{
#if ETHR_SIZEOF_PTR == 4
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index cf1aef518a..b680c03b1d 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -465,6 +465,7 @@ RELEASE_LIBS=$(ERTS_LIBS)
INTERNAL_RELEASE_INCLUDES= \
$(ERTS_INCL_INT)/README \
$(ERTS_INCL_INT)/ethread.h \
+ $(ERTS_INCL_INT)/ethread_inline.h \
$(ERTS_INCL_INT)/ethr_mutex.h \
$(ERTS_INCL_INT)/ethr_optimized_fallbacks.h \
$(ERTS_INCL_INT)/ethr_atomics.h \
diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c
index 5a271c5268..d58a28b5cb 100644
--- a/erts/lib_src/common/erl_misc_utils.c
+++ b/erts/lib_src/common/erl_misc_utils.c
@@ -25,6 +25,7 @@
# include <windows.h>
#endif
+#include "ethread_inline.h"
#include "erl_misc_utils.h"
#if defined(__WIN32__)
@@ -191,7 +192,7 @@ struct erts_cpu_info_t_ {
#if defined(__WIN32__)
-static __forceinline int
+static ETHR_FORCE_INLINE int
get_proc_affinity(erts_cpu_info_t *cpuinfo, cpu_set_t *cpuset)
{
DWORD_PTR pamask;
@@ -206,7 +207,7 @@ get_proc_affinity(erts_cpu_info_t *cpuinfo, cpu_set_t *cpuset)
}
}
-static __forceinline int
+static ETHR_FORCE_INLINE int
set_thr_affinity(cpu_set_t *set)
{
if (*set == (cpu_set_t) 0)
@@ -1157,7 +1158,7 @@ read_topology(erts_cpu_info_t *cpuinfo)
#define ERTS_MU_RELATION_CACHE 2 /* RelationCache */
#define ERTS_MU_RELATION_PROCESSOR_PACKAGE 3 /* RelationProcessorPackage */
-static __forceinline int
+static ETHR_FORCE_INLINE int
rel_cmp_val(int r)
{
switch (r) {
diff --git a/erts/lib_src/common/ethr_aux.c b/erts/lib_src/common/ethr_aux.c
index ceecdcef64..b77f2178f2 100644
--- a/erts/lib_src/common/ethr_aux.c
+++ b/erts/lib_src/common/ethr_aux.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2014. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -360,10 +360,10 @@ static ethr_ts_event *ts_event_pool(int size, ethr_ts_event **endpp)
int i;
ethr_aligned_ts_event *atsev;
atsev = ethr_mem__.std.alloc(sizeof(ethr_aligned_ts_event) * size
- + ETHR_CACHE_LINE_SIZE);
+ + ETHR_CACHE_LINE_SIZE - 1);
if (!atsev)
return NULL;
- if ((((ethr_uint_t) atsev) & ETHR_CACHE_LINE_MASK) == 0)
+ if ((((ethr_uint_t) atsev) & ETHR_CACHE_LINE_MASK) != 0)
atsev = ((ethr_aligned_ts_event *)
((((ethr_uint_t) atsev) & ~ETHR_CACHE_LINE_MASK)
+ ETHR_CACHE_LINE_SIZE));
diff --git a/erts/lib_src/common/ethr_mutex.c b/erts/lib_src/common/ethr_mutex.c
index 72b44033ad..4e56efaf8b 100644
--- a/erts/lib_src/common/ethr_mutex.c
+++ b/erts/lib_src/common/ethr_mutex.c
@@ -1433,7 +1433,7 @@ void LeaveCriticalSection(CRITICAL_SECTION *cs)
#define ETHR_CND_WAIT__ ((ethr_sint32_t) 0x11dead11)
#define ETHR_CND_WAKEUP__ ((ethr_sint32_t) 0x11beef11)
-static __forceinline void
+static ETHR_FORCE_INLINE void
cond_wakeup(ethr_ts_event *tse)
{
ETHR_ASSERT(ethr_atomic32_read(&tse->uaflgs) == ETHR_CND_WAIT__);
@@ -1574,7 +1574,7 @@ ethr_cond_wait(ethr_cond *cnd, ethr_mutex *mtx)
return 0;
}
-static __forceinline void
+static ETHR_FORCE_INLINE void
posix_compliant_mtx_enqueue(ethr_mutex *mtx,
ethr_ts_event *tse_start,
ethr_ts_event *tse_end)
@@ -1614,7 +1614,7 @@ posix_compliant_mtx_enqueue(ethr_mutex *mtx,
}
}
-static __forceinline void
+static ETHR_FORCE_INLINE void
enqueue_cond_wakeups(ethr_ts_event *queue, int posix_compliant)
{
if (queue) {
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index f1e588320b..5f2b619322 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index e19bb370bc..260badbcb3 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index 3d650aff74..7dc7407a81 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 26f779500c..5c139c4550 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 4d22d8bace..cf32b79e8d 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam
index efc8347b6e..37ed8d0365 100644
--- a/erts/preloaded/ebin/prim_eval.beam
+++ b/erts/preloaded/ebin/prim_eval.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 6c49b5185e..d49578abfa 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index fe5431c5ff..8420052533 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_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index 73be297bbb..8dc8cb961b 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 193cebdc31..7507efb076 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/add_abstract_code b/erts/preloaded/src/add_abstract_code
index e670156d21..211a60c930 100644
--- a/erts/preloaded/src/add_abstract_code
+++ b/erts/preloaded/src/add_abstract_code
@@ -27,8 +27,18 @@
main([BeamFile,AbstrFile]) ->
{ok,_,Chunks0} = beam_lib:all_chunks(BeamFile),
{ok,Abstr} = file:consult(AbstrFile),
- Chunks = lists:keyreplace("Abst", 1, Chunks0,
- {"Abst",term_to_binary({raw_abstract_v1,Abstr})}),
+ Chunks1 = lists:keyreplace("Abst", 1, Chunks0,
+ {"Abst",term_to_binary({raw_abstract_v1,Abstr})}),
+ {"CInf",CInf0} = lists:keyfind("CInf", 1, Chunks1),
+ CInf = fix_options(CInf0),
+ Chunks = lists:keyreplace("CInf", 1, Chunks1, {"CInf",CInf}),
{ok,Module} = beam_lib:build_module(Chunks),
ok = file:write_file(BeamFile, Module),
init:stop().
+
+fix_options(CInf0) ->
+ CInf1 = binary_to_term(CInf0),
+ {options,Opts0} = lists:keyfind(options, 1, CInf1),
+ Opts = Opts0 -- [from_asm],
+ CInf = lists:keyreplace(options, 1, CInf1, {options,Opts}),
+ term_to_binary(CInf).
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index 578913b633..466e0b0020 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -42,11 +42,11 @@
%% Public
-export([start/3, set_path/1, get_path/0, get_file/1, get_files/2,
- list_dir/1, read_file_info/1, get_cwd/0, get_cwd/1]).
+ list_dir/1, read_file_info/1, read_link_info/1, get_cwd/0, get_cwd/1]).
%% Used by erl_boot_server
-export([prim_init/0, prim_get_file/2, prim_list_dir/2,
- prim_read_file_info/2, prim_get_cwd/2]).
+ prim_read_file_info/3, prim_get_cwd/2]).
%% Used by escript and code
-export([set_primary_archive/4, release_archives/0]).
@@ -223,6 +223,12 @@ list_dir(Dir) ->
read_file_info(File) ->
check_file_result(read_file_info, File, request({read_file_info,File})).
+-spec read_link_info(Filename) -> {'ok', FileInfo} | 'error' when
+ Filename :: string(),
+ FileInfo :: file:file_info().
+read_link_info(File) ->
+ check_file_result(read_link_info, File, request({read_link_info,File})).
+
-spec get_cwd() -> {'ok', string()} | 'error'.
get_cwd() ->
check_file_result(get_cwd, [], request({get_cwd,[]})).
@@ -325,6 +331,9 @@ loop(State, Parent, Paths) ->
{read_file_info,File} ->
{Res,State1} = handle_read_file_info(State, File),
{Res,State1,Paths};
+ {read_link_info,File} ->
+ {Res,State1} = handle_read_link_info(State, File),
+ {Res,State1,Paths};
{get_cwd,[]} ->
{Res,State1} = handle_get_cwd(State, []),
{Res,State1,Paths};
@@ -387,10 +396,15 @@ handle_list_dir(State = #state{loader = inet}, Dir) ->
?SAFE2(inet_list_dir(State, Dir), State).
handle_read_file_info(State = #state{loader = efile}, File) ->
- ?SAFE2(efile_read_file_info(State, File), State);
+ ?SAFE2(efile_read_file_info(State, File, true), State);
handle_read_file_info(State = #state{loader = inet}, File) ->
?SAFE2(inet_read_file_info(State, File), State).
+handle_read_link_info(State = #state{loader = efile}, File) ->
+ ?SAFE2(efile_read_file_info(State, File, false), State);
+handle_read_link_info(State = #state{loader = inet}, File) ->
+ ?SAFE2(inet_read_link_info(State, File), State).
+
handle_get_cwd(State = #state{loader = efile}, Drive) ->
?SAFE2(efile_get_cwd(State, Drive), State);
handle_get_cwd(State = #state{loader = inet}, Drive) ->
@@ -514,8 +528,8 @@ efile_list_dir(#state{prim_state = PS} = State, Dir) ->
{Res, PS2} = prim_list_dir(PS, Dir),
{Res, State#state{prim_state = PS2}}.
-efile_read_file_info(#state{prim_state = PS} = State, File) ->
- {Res, PS2} = prim_read_file_info(PS, File),
+efile_read_file_info(#state{prim_state = PS} = State, File, FollowLinks) ->
+ {Res, PS2} = prim_read_file_info(PS, File, FollowLinks),
{Res, State#state{prim_state = PS2}}.
efile_get_cwd(#state{prim_state = PS} = State, Drive) ->
@@ -718,6 +732,10 @@ inet_list_dir(State, Dir) ->
inet_read_file_info(State, File) ->
inet_send_and_rcv({read_file_info,File}, read_file_info, State).
+%% -> {{ok,Info},State} | {{error,Reason},State}
+inet_read_link_info(State, File) ->
+ inet_send_and_rcv({read_link_info,File}, read_link_info, State).
+
%% -> {{ok,Cwd},State} | {{error,Reason},State}
inet_get_cwd(State, []) ->
inet_send_and_rcv(get_cwd, get_cwd, State);
@@ -951,16 +969,18 @@ prim_list_dir(PS, Dir) ->
debug(PS, {return, Res2}),
{Res2, PS3}.
--spec prim_read_file_info(prim_state(), file:filename()) ->
+-spec prim_read_file_info(prim_state(), file:filename(), boolean()) ->
{{'ok', #file_info{}}, prim_state()}
| {{'error', term()}, prim_state()}.
-prim_read_file_info(PS, File) ->
+prim_read_file_info(PS, File, FollowLinks) ->
debug(PS, {read_file_info, File}),
{Res2, PS2} =
case name_split(PS#prim_state.primary_archive, File) of
{file, PrimFile} ->
- Res = prim_file:read_file_info(PrimFile),
- {Res, PS};
+ case FollowLinks of
+ true -> {prim_file:read_file_info(PrimFile), PS};
+ false -> {prim_file:read_link_info(PrimFile), PS}
+ end;
{archive, ArchiveFile, []} ->
%% Fake top directory
debug(PS, {archive_read_file_info, ArchiveFile}),
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 1508eed9ee..4ff0513321 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -79,7 +79,7 @@
-export([binary_to_integer/1,binary_to_integer/2]).
-export([binary_to_list/1]).
-export([binary_to_list/3, binary_to_term/1, binary_to_term/2]).
--export([bit_size/1, bitsize/1, bitstr_to_list/1, bitstring_to_list/1]).
+-export([bit_size/1, bitsize/1, bitstring_to_list/1]).
-export([bump_reductions/1, byte_size/1, call_on_load_function/1]).
-export([cancel_timer/1, check_old_code/1, check_process_code/2,
check_process_code/3, crc32/1]).
@@ -100,7 +100,7 @@
-export([integer_to_binary/1, integer_to_list/1]).
-export([iolist_size/1, iolist_to_binary/1]).
-export([is_alive/0, is_builtin/3, is_process_alive/1, length/1, link/1]).
--export([list_to_atom/1, list_to_binary/1, list_to_bitstr/1]).
+-export([list_to_atom/1, list_to_binary/1]).
-export([list_to_bitstring/1, list_to_existing_atom/1, list_to_float/1]).
-export([list_to_integer/1, list_to_integer/2]).
-export([list_to_pid/1, list_to_tuple/1, loaded/0]).
@@ -361,25 +361,15 @@ binary_to_list(_Binary, _Start, _Stop) ->
%% binary_to_term/1
-spec binary_to_term(Binary) -> term() when
Binary :: ext_binary().
-binary_to_term(Binary) ->
- %% This BIF may throw badarg while trapping
- try
- erts_internal:binary_to_term(Binary)
- catch
- error:Reason -> erlang:error(Reason,[Binary])
- end.
+binary_to_term(_Binary) ->
+ erlang:nif_error(undefined).
%% binary_to_term/2
-spec binary_to_term(Binary, Opts) -> term() when
Binary :: ext_binary(),
Opts :: [safe].
-binary_to_term(Binary, Opts) ->
- %% This BIF may throw badarg while trapping
- try
- erts_internal:binary_to_term(Binary,Opts)
- catch
- error:Reason -> erlang:error(Reason,[Binary,Opts])
- end.
+binary_to_term(_Binary, _Opts) ->
+ erlang:nif_error(undefined).
%% bit_size/1
%% Shadowed by erl_bif_types: erlang:bit_size/1
@@ -394,12 +384,6 @@ bit_size(_Bitstring) ->
bitsize(_P1) ->
erlang:nif_error(undefined).
-%% bitstr_to_list/1
--spec erlang:bitstr_to_list(P1) -> [byte() | bitstring()] when
- P1 :: bitstring().
-bitstr_to_list(_P1) ->
- erlang:nif_error(undefined).
-
%% bitstring_to_list/1
-spec bitstring_to_list(Bitstring) -> [byte() | bitstring()] when
Bitstring :: bitstring().
@@ -1082,12 +1066,6 @@ list_to_atom(_String) ->
list_to_binary(_IoList) ->
erlang:nif_error(undefined).
-%% list_to_bitstr/1
--spec erlang:list_to_bitstr(P1) -> bitstring() when
- P1 :: bitstring_list().
-list_to_bitstr(_P1) ->
- erlang:nif_error(undefined).
-
%% list_to_bitstring/1
-spec list_to_bitstring(BitstringList) -> bitstring() when
BitstringList :: bitstring_list().
@@ -2286,6 +2264,7 @@ tuple_to_list(_Tuple) ->
(system_architecture) -> string();
(threads) -> boolean();
(thread_pool_size) -> non_neg_integer();
+ (tolerant_timeofday) -> enabled | disabled;
(trace_control_word) -> non_neg_integer();
(update_cpu_info) -> changed | unchanged;
(version) -> string();
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index 764d7730aa..2c5bd82cf0 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -29,7 +29,6 @@
-module(erts_internal).
-export([await_port_send_result/3]).
--export([binary_to_term/1, binary_to_term/2]).
-export([cmp_term/2]).
-export([map_to_tuple_keys/1]).
-export([port_command/3, port_connect/2, port_close/1,
@@ -162,17 +161,6 @@ request_system_task(_Pid, _Prio, _Request) ->
check_process_code(_Module, _OptionList) ->
erlang:nif_error(undefined).
--spec binary_to_term(Binary) -> term() when
- Binary :: binary().
-binary_to_term(_Binary) ->
- erlang:nif_error(undefined).
-
--spec binary_to_term(Binary, Opts) -> term() when
- Binary :: binary(),
- Opts :: [safe].
-binary_to_term(_Binary, _Opts) ->
- erlang:nif_error(undefined).
-
%% term compare where integer() < float() = true
-spec cmp_term(A,B) -> Result when
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index 143c718130..79ff013c77 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -25,7 +25,7 @@
%% Primitive inet_drv interface
--export([open/3, open/4, fdopen/4, close/1]).
+-export([open/3, open/4, fdopen/4, fdopen/5, close/1]).
-export([bind/3, listen/1, listen/2, peeloff/2]).
-export([connect/3, connect/4, async_connect/4]).
-export([accept/1, accept/2, async_accept/2]).
@@ -70,7 +70,12 @@ open(Protocol, Family, Type, Opts) ->
open(Protocol, Family, Type, Opts, ?INET_REQ_OPEN, []).
fdopen(Protocol, Family, Type, Fd) when is_integer(Fd) ->
- open(Protocol, Family, Type, [], ?INET_REQ_FDOPEN, ?int32(Fd)).
+ fdopen(Protocol, Family, Type, Fd, true).
+
+fdopen(Protocol, Family, Type, Fd, Bound)
+ when is_integer(Fd), Bound == true orelse Bound == false ->
+ open(Protocol, Family, Type, [], ?INET_REQ_FDOPEN,
+ [?int32(Fd), enc_value_2(bool, Bound)]).
open(Protocol, Family, Type, Opts, Req, Data) ->
Drv = protocol2drv(Protocol),
diff --git a/erts/test/upgrade_SUITE.erl b/erts/test/upgrade_SUITE.erl
index ee84a5dfd7..d5a920e03d 100644
--- a/erts/test/upgrade_SUITE.erl
+++ b/erts/test/upgrade_SUITE.erl
@@ -264,7 +264,7 @@ do_upgrade(FromVsn,FromApps,ToRel,ToApps,InstallDir) ->
%%%-----------------------------------------------------------------
%%% Library functions
previous_major("17") ->
- "r16";
+ "r16b";
previous_major(Rel) ->
integer_to_list(list_to_integer(Rel)-1).
diff --git a/erts/vsn.mk b/erts/vsn.mk
index fff334c89f..0db4370ea8 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -17,7 +17,7 @@
# %CopyrightEnd%
#
-VSN = 6.0.2
+VSN = 6.1.2
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index cb89bb298b..11de9ad98f 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -31,6 +31,23 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 3.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The ASN.1 compiler now generates code that don't trigger
+ Dialyzer warnings. Along the way, a few minor bugs were
+ fixed.</p>
+ <p>
+ Own Id: OTP-11372 Aux Id: seq12397 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Asn1 3.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile
index 500f4a1358..6798da0072 100644
--- a/lib/asn1/src/Makefile
+++ b/lib/asn1/src/Makefile
@@ -52,6 +52,7 @@ CT_MODULES= \
asn1ct_pretty_format \
asn1ct_func \
asn1ct_gen \
+ asn1ct_gen_check \
asn1ct_gen_per \
asn1ct_name \
asn1ct_constructed_per \
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
index a38da8bcc2..5fadd0495a 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -962,8 +962,7 @@ gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj)
WhatKind = asn1ct_gen:type(InnerType),
emit(IndDeep),
emit(Assign),
- gen_optormand_case(OptOrMand,Erules,TopType,Cname,Type,InnerType,WhatKind,
- Element),
+ gen_optormand_case(OptOrMand, Erules, TopType, Cname, Type, Element),
case {Type,asn1ct_gen:get_constraint(Type#type.constraint,
componentrelation)} of
% #type{constraint=[{tableconstraint_info,RefedFieldName}],
@@ -1029,26 +1028,19 @@ gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj)
emit([nl,indent(7),"end"])
end.
-gen_optormand_case(mandatory,_Erules,_TopType,_Cname,_Type,_InnerType,_WhatKind,
- _Element) ->
+gen_optormand_case(mandatory, _Erules, _TopType, _Cname, _Type, _Element) ->
ok;
-gen_optormand_case('OPTIONAL',Erules,_TopType,_Cname,_Type,_InnerType,_WhatKind,
- Element) ->
+gen_optormand_case('OPTIONAL', Erules, _TopType, _Cname, _Type, Element) ->
emit([" case ",Element," of",nl]),
emit([indent(9),"asn1_NOVALUE -> {",
empty_lb(Erules),",0};",nl]),
emit([indent(9),"_ ->",nl,indent(12)]);
-gen_optormand_case({'DEFAULT',DefaultValue},Erules,TopType,Cname,Type,
- InnerType,WhatKind,Element) ->
+gen_optormand_case({'DEFAULT',DefaultValue}, Erules, _TopType,
+ _Cname, Type, Element) ->
CurrMod = get(currmod),
case catch lists:member(der,get(encoding_options)) of
true ->
- emit(" case catch "),
- asn1ct_gen:gen_check_call(TopType,Cname,Type,InnerType,
- WhatKind,{asis,DefaultValue},
- Element),
- emit([" of",nl]),
- emit([indent(12),"true -> {[],0};",nl]);
+ asn1ct_gen_check:emit(Type, DefaultValue, Element);
_ ->
emit([" case ",Element," of",nl]),
emit([indent(9),"asn1_DEFAULT -> {",
@@ -1063,10 +1055,9 @@ gen_optormand_case({'DEFAULT',DefaultValue},Erules,TopType,Cname,Type,
emit([indent(9),{asis,
DefaultValue}," -> {",
empty_lb(Erules),",0};",nl])
- end
- end,
- emit([indent(9),"_ ->",nl,indent(12)]).
-
+ end,
+ emit([indent(9),"_ ->",nl,indent(12)])
+ end.
gen_dec_line(Erules,TopType,Cname,CTags,Type,OptOrMand,DecObjInf) ->
@@ -1210,11 +1201,11 @@ gen_dec_call({typefield,_},_,_,Cname,Type,BytesVar,Tag,_,_,_DecObjInf,OptOrMandC
(Type#type.def)#'ObjectClassFieldType'.fieldname,
[{Cname,RefedFieldName,asn1ct_gen:mk_var(asn1ct_name:curr(term)),
asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}];
-gen_dec_call(InnerType,Erules,TopType,Cname,Type,BytesVar,Tag,PrimOptOrMand,
- OptOrMand,DecObjInf,_) ->
+gen_dec_call(InnerType, _Erules, TopType, Cname, Type, BytesVar,
+ Tag, _PrimOptOrMand, _OptOrMand, DecObjInf,_) ->
WhatKind = asn1ct_gen:type(InnerType),
- gen_dec_call1(WhatKind,InnerType,Erules,TopType,Cname,Type,BytesVar,Tag,
- PrimOptOrMand,OptOrMand),
+ gen_dec_call1(WhatKind, InnerType, TopType, Cname,
+ Type, BytesVar, Tag),
case DecObjInf of
{Cname,{_,OSet,_UniqueFName,ValIndex}} ->
Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)),
@@ -1226,8 +1217,9 @@ gen_dec_call(InnerType,Erules,TopType,Cname,Type,BytesVar,Tag,PrimOptOrMand,
ok
end,
[].
-gen_dec_call1({primitive,bif},InnerType,Erules,TopType,Cname,Type,BytesVar,
- Tag,OptOrMand,_) ->
+
+gen_dec_call1({primitive,bif}, InnerType, TopType, Cname,
+ Type, BytesVar, Tag) ->
case {asn1ct:get_gen_state_field(namelist),InnerType} of
{[{Cname,undecoded}|Rest],_} ->
asn1ct:add_generated_refed_func({[Cname|TopType],undecoded,
@@ -1236,11 +1228,10 @@ gen_dec_call1({primitive,bif},InnerType,Erules,TopType,Cname,Type,BytesVar,
emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',",
BytesVar,"}"]);
_ ->
- ?ASN1CT_GEN_BER:gen_dec_prim(Erules,Type,BytesVar,Tag,[],
- ?PRIMITIVE,OptOrMand)
+ ?ASN1CT_GEN_BER:gen_dec_prim(Type, BytesVar, Tag)
end;
-gen_dec_call1('ASN1_OPEN_TYPE',_InnerType,Erules,TopType,Cname,Type,BytesVar,
- Tag,OptOrMand,_) ->
+gen_dec_call1('ASN1_OPEN_TYPE', _InnerType, TopType, Cname,
+ Type, BytesVar, Tag) ->
case {asn1ct:get_gen_state_field(namelist),Type#type.def} of
{[{Cname,undecoded}|Rest],_} ->
asn1ct:add_generated_refed_func({[Cname|TopType],undecoded,
@@ -1249,15 +1240,12 @@ gen_dec_call1('ASN1_OPEN_TYPE',_InnerType,Erules,TopType,Cname,Type,BytesVar,
emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',",
BytesVar,"}"]);
{_,#'ObjectClassFieldType'{type=OpenType}} ->
- ?ASN1CT_GEN_BER:gen_dec_prim(Erules,#type{def=OpenType},
- BytesVar,Tag,[],
- ?PRIMITIVE,OptOrMand);
+ ?ASN1CT_GEN_BER:gen_dec_prim(#type{def=OpenType},
+ BytesVar, Tag);
_ ->
- ?ASN1CT_GEN_BER:gen_dec_prim(Erules,Type,BytesVar,Tag,[],
- ?PRIMITIVE,OptOrMand)
+ ?ASN1CT_GEN_BER:gen_dec_prim(Type, BytesVar, Tag)
end;
-gen_dec_call1(WhatKind,_,_Erules,TopType,Cname,Type,BytesVar,
- Tag,_,_OptOrMand) ->
+gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
case asn1ct:get_gen_state_field(namelist) of
[{Cname,undecoded}|Rest] ->
asn1ct:add_generated_refed_func({[Cname|TopType],undecoded,
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index ed3f6f886e..a91404ed54 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -426,8 +426,7 @@ gen_dec_open_type(Erule, Val, {Xmod,Xtype}, LeadingAttr,
emit([Term," = ",{asis,F},"(",TmpTerm,", ",Val,")"]).
dec_objset_optional(N, {'DEFAULT',Val}) ->
- dec_objset_optional_1(N, Val),
- dec_objset_optional_1(N, asn1_DEFAULT);
+ dec_objset_optional_1(N, Val);
dec_objset_optional(N, 'OPTIONAL') ->
dec_objset_optional_1(N, asn1_NOVALUE);
dec_objset_optional(_N, mandatory) -> ok.
diff --git a/lib/asn1/src/asn1ct_func.erl b/lib/asn1/src/asn1ct_func.erl
index 33f998722a..fb94f65b32 100644
--- a/lib/asn1/src/asn1ct_func.erl
+++ b/lib/asn1/src/asn1ct_func.erl
@@ -19,7 +19,8 @@
%%
-module(asn1ct_func).
--export([start_link/0,need/1,call/3,call_gen/3,call_gen/4,generate/1]).
+-export([start_link/0,need/1,call/3,call_gen/3,call_gen/4,
+ generate/1,is_used/1]).
-export([init/1,handle_call/3,handle_cast/2,terminate/2]).
start_link() ->
@@ -63,6 +64,10 @@ generate(Fd) ->
Funcs = sofs:to_external(Funcs0),
ok = file:write(Fd, Funcs).
+is_used({_,_,_}=MFA) ->
+ req({is_used,MFA}).
+
+
req(Req) ->
gen_server:call(get(?MODULE), Req, infinity).
@@ -103,7 +108,10 @@ handle_call({gen_func,Prefix,Key,GenFun}, _From, #st{gen=G0,gc=Gc0}=St) ->
{reply,Name,St#st{gen=G,gc=Gc}};
{value,{Name,_}} ->
{reply,Name,St}
- end.
+ end;
+handle_call({is_used,MFA}, _From, #st{used=Used}=St) ->
+ {reply,gb_sets:is_member(MFA, Used),St}.
+
terminate(_, _) ->
ok.
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 44b050e59d..450d309688 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -29,7 +29,6 @@
list2rname/1,
constructed_suffix/2,
unify_if_string/1,
- gen_check_call/7,
get_constraint/2,
insert_once/2,
ct_gen_module/1,
@@ -43,6 +42,8 @@
-export([gen_encode_constructed/4,
gen_decode_constructed/4]).
+-define(SUPPRESSION_FUNC, 'dialyzer-suppressions').
+
%% pgen(Outfile, Erules, Module, TypeOrVal, Options)
%% Generate Erlang module (.erl) and (.hrl) file corresponding to an ASN.1 module
%% .hrl file is only generated if necessary
@@ -85,12 +86,18 @@ pgen_module(OutFile,Erules,Module,
"%%%",nl,
"%%% Run-time functions.",nl,
"%%%",nl]),
+ dialyzer_suppressions(Erules),
Fd = get(gen_file_out),
asn1ct_func:generate(Fd),
close_output_file(),
_ = erase(outfile),
asn1ct:verbose("--~p--~n",[{generated,ErlFile}],Options).
+dialyzer_suppressions(Erules) ->
+ emit([nl,
+ {asis,?SUPPRESSION_FUNC},"(Arg) ->",nl]),
+ Rtmod = ct_gen_module(Erules),
+ Rtmod:dialyzer_suppressions(Erules).
pgen_typeorval(Erules,Module,N2nConvEnums,{Types,Values,_Ptypes,_Classes,Objects,ObjectSets}) ->
Rtmod = ct_gen_module(Erules),
@@ -98,11 +105,6 @@ pgen_typeorval(Erules,Module,N2nConvEnums,{Types,Values,_Ptypes,_Classes,Objects
pgen_values(Erules,Module,Values),
pgen_objects(Rtmod,Erules,Module,Objects),
pgen_objectsets(Rtmod,Erules,Module,ObjectSets),
- case catch lists:member(der,get(encoding_options)) of
- true ->
- pgen_check_defaultval(Erules,Module);
- _ -> ok
- end,
pgen_partial_decode(Rtmod,Erules,Module).
pgen_values(_,_,[]) ->
@@ -178,23 +180,6 @@ pgen_objectsets(Rtmod,Erules,Module,[H|T]) ->
Rtmod:gen_objectset_code(Erules,TypeDef),
pgen_objectsets(Rtmod,Erules,Module,T).
-pgen_check_defaultval(Erules,Module) ->
- CheckObjects = asn1ct_table:to_list(check_functions),
- case get(asndebug) of
- true ->
- FileName = lists:concat([Module,".table"]),
- {ok,IoDevice} = file:open(FileName,[write]),
- Fun =
- fun(X)->
- io:format(IoDevice,"~n~n************~n~n~p~n~n*****"
- "********~n~n",[X])
- end,
- lists:foreach(Fun,CheckObjects),
- ok = file:close(IoDevice);
- _ -> ok
- end,
- gen_check_defaultval(Erules,Module,CheckObjects).
-
pgen_partial_decode(Rtmod,Erule,Module) when Erule == ber ->
pgen_partial_inc_dec(Rtmod,Erule,Module),
pgen_partial_dec(Rtmod,Erule,Module);
@@ -542,8 +527,7 @@ gen_part_decode_funcs({constructed,bif},TypeName,
emit([" 'dec_",TypeName,"'(Data,",{asis,Tag},")"]);
gen_part_decode_funcs({primitive,bif},_TypeName,
{_Name,undecoded,Tag,Type}) ->
- % Argument no 6 is 0, i.e. bit 6 for primitive encoding.
- asn1ct_gen_ber_bin_v2:gen_dec_prim(ber_bin_v2,Type,"Data",Tag,[],0,", mandatory, ");
+ asn1ct_gen_ber_bin_v2:gen_dec_prim(Type, "Data", Tag);
gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) ->
throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}).
@@ -576,131 +560,6 @@ gen_types(Erules,Tname,Type) when is_record(Type,type) ->
asn1ct_name:clear(),
Rtmod:gen_decode(Erules,Tname,Type).
-gen_check_defaultval(Erules,Module,[{Name,Type}|Rest]) ->
- gen_check_func(Name,Type),
- gen_check_defaultval(Erules,Module,Rest);
-gen_check_defaultval(_,_,[]) ->
- ok.
-
-gen_check_func(Name,FType = #type{def=Def}) ->
- EncName = ensure_atom(Name),
- emit({{asis,EncName},"(_V,asn1_DEFAULT) ->",nl," true;",nl}),
- emit({{asis,EncName},"(V,V) ->",nl," true;",nl}),
- emit({{asis,EncName},"(V,{_,V}) ->",nl," true;",nl}),
- case Def of
- {'SEQUENCE OF',Type} ->
- gen_check_sof(Name,'SEQOF',Type);
- {'SET OF',Type} ->
- gen_check_sof(Name,'SETOF',Type);
- #'SEQUENCE'{components=Components} ->
- gen_check_sequence(Name,Components);
- #'SET'{components=Components} ->
- gen_check_sequence(Name,Components);
- {'CHOICE',Components} ->
- gen_check_choice(Name,Components);
- #'Externaltypereference'{type=T} ->
- emit({{asis,EncName},"(DefaultValue,Value) ->",nl}),
- emit({" '",list2name([T,check]),"'(DefaultValue,Value).",nl});
- MaybePrim ->
- InnerType = get_inner(MaybePrim),
- case type(InnerType) of
- {primitive,bif} ->
- emit({{asis,EncName},"(DefaultValue,Value) ->",nl," "}),
- gen_prim_check_call(get_inner(InnerType),"DefaultValue","Value",
- FType),
- emit({".",nl,nl});
- _ ->
- throw({asn1_error,{unknown,type,MaybePrim}})
- end
- end.
-
-gen_check_sof(Name,SOF,Type) ->
- EncName = ensure_atom(Name),
- NewName = ensure_atom(list2name([sorted,Name])),
- emit({{asis,EncName},"(V1,V2) ->",nl}),
- emit({" ",{asis,NewName},"(lists:sort(V1),lists:sort(V2)).",nl,nl}),
- emit({{asis,NewName},"([],[]) ->",nl," true;",nl}),
- emit({{asis,NewName},"([DV|DVs],[V|Vs]) ->",nl," "}),
- InnerType = get_inner(Type#type.def),
- case type(InnerType) of
- {primitive,bif} ->
- gen_prim_check_call(get_inner(InnerType),"DV","V",Type),
- emit({",",nl});
- {constructed,bif} ->
- emit([{asis,ensure_atom(list2name([SOF,Name]))},"(DV, V),",nl]);
- #'Externaltypereference'{type=T} ->
- emit([{asis,ensure_atom(list2name([T,check]))},"(DV,V),",nl]);
- 'ASN1_OPEN_TYPE' ->
- emit(["DV = V,",nl]);
- _ ->
- emit(["DV = V,",nl])
- end,
- emit({" ",{asis,NewName},"(DVs,Vs).",nl,nl}).
-
-gen_check_sequence(Name, []) ->
- emit([{asis,ensure_atom(Name)},"(_,_) ->",nl,
- " throw(badval).",nl,nl]);
-gen_check_sequence(Name,Components) ->
- emit([{asis,ensure_atom(Name)},"(DefaultValue,Value) ->",nl]),
- gen_check_sequence(Name,Components,1).
-
-gen_check_sequence(Name,[#'ComponentType'{name=N,typespec=Type}|Cs],Num) ->
- InnerType = get_inner(Type#type.def),
- NthDefV = ["element(",Num+1,",DefaultValue)"],
- NthV = ["element(",Num+1,",Value)"],
- gen_check_func_call(Name,Type,InnerType,NthDefV,NthV,N),
- case Cs of
- [] ->
- emit({".",nl,nl});
- _ ->
- emit({",",nl}),
- gen_check_sequence(Name,Cs,Num+1)
- end.
-
-gen_check_choice(Name,CList=[#'ComponentType'{}|_Cs]) ->
- emit([{asis,ensure_atom(Name)},"({Id,DefaultValue},{Id,Value}) ->",nl]),
- emit([" case Id of",nl]),
- gen_check_choice_components(Name,CList,1).
-
-gen_check_choice_components(_,[],_)->
- ok;
-gen_check_choice_components(Name,[#'ComponentType'{name=N,typespec=Type}|
- Cs],Num) ->
- Ind6 = " ",
- InnerType = get_inner(Type#type.def),
- emit({Ind6,"'",N,"' ->",nl,Ind6}),
- gen_check_func_call(Name,Type,InnerType,{var,"defaultValue"},
- {var,"value"},N),
- case Cs of
- [] ->
- emit({nl," end.",nl,nl});
- _ ->
- emit({";",nl}),
- gen_check_choice_components(Name,Cs,Num+1)
- end.
-
-gen_check_func_call(Name,Type,InnerType,DefVal,Val,N) ->
- case type(InnerType) of
- {primitive,bif} ->
- emit(" "),
- gen_prim_check_call(get_inner(InnerType),DefVal,Val,Type);
- #'Externaltypereference'{type=T} ->
- emit({" ",{asis,ensure_atom(list2name([T,check]))},"(",DefVal,",",Val,")"});
- 'ASN1_OPEN_TYPE' ->
- emit([" if",nl,
- " ",DefVal," == ",Val," -> true;",nl,
- " true -> throw({error,{asn1_open_type}})",nl,
- " end",nl]);
- {constructed,bif} ->
- emit([" ",{asis,ensure_atom(list2name([N,Name]))},"(",DefVal,",",Val,")"]);
- _ ->
- emit([" if",nl,
- " ",DefVal," == ",Val," -> true;",nl,
- " true -> throw({error,{asn1_open_type}})",nl,
- " end",nl])
- end.
-
-
%% VARIOUS GENERATOR STUFF
%% *************************************************
%%**************************************************
@@ -790,8 +649,9 @@ gen_decode_constructed(Erules,Typename,InnerType,D) when is_record(D,typedef) ->
pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) ->
- emit(["-export([encoding_rule/0,bit_string_format/0,"
+ emit(["-export([encoding_rule/0,bit_string_format/0,",nl,
" legacy_erlang_types/0]).",nl]),
+ emit(["-export([",{asis,?SUPPRESSION_FUNC},"/1]).",nl]),
case Types of
[] -> ok;
_ ->
@@ -1077,9 +937,10 @@ gen_partial_inc_dispatcher() ->
ok;
{Data1,Data2} ->
% io:format("partial_incomplete_decode: ~p~ninc_type_pattern: ~p~n",[Data,Data2]),
- gen_partial_inc_dispatcher(Data1,Data2)
+ gen_partial_inc_dispatcher(Data1, Data2, "")
end.
-gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest],TypePattern) ->
+
+gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest], TypePattern, Sep) ->
TPattern =
case lists:keysearch(FuncName,1,TypePattern) of
{value,{_,TP}} -> TP;
@@ -1093,13 +954,13 @@ gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest],TypePattern) ->
_ ->
atom_to_list(TopType)
end,
- emit(["decode_partial_inc_disp('",TopTypeName,"',Data) ->",nl,
+ emit([Sep,
+ "decode_partial_inc_disp('",TopTypeName,"',Data) ->",nl,
" ",{asis,list_to_atom(lists:concat(["dec-inc-",FuncName2]))},
- "(Data);",nl]),
- gen_partial_inc_dispatcher(Rest,TypePattern);
-gen_partial_inc_dispatcher([],_) ->
- emit(["decode_partial_inc_disp(Type,_Data) ->",nl,
- " exit({error,{asn1,{undefined_type,Type}}}).",nl]).
+ "(Data)"]),
+ gen_partial_inc_dispatcher(Rest, TypePattern, ";\n");
+gen_partial_inc_dispatcher([], _, _) ->
+ emit([".",nl]).
gen_dispatcher([F1,F2|T],FuncName,Prefix,ExtraArg) ->
emit([FuncName,"('",F1,"',Data) -> '",Prefix,F1,"'(Data",ExtraArg,")",";",nl]),
@@ -1465,171 +1326,6 @@ to_textual_order(Cs=[#'ComponentType'{textual_order=undefined}|_]) ->
to_textual_order(Cs) when is_list(Cs) ->
lists:keysort(#'ComponentType'.textual_order,Cs).
-
-gen_check_call(TopType,Cname,Type,InnerType,WhatKind,DefaultValue,Element) ->
- case WhatKind of
- {primitive,bif} ->
- gen_prim_check_call(InnerType,DefaultValue,Element,Type);
- #'Externaltypereference'{module=M,type=T} ->
- %% generate function call
- Name = list2name([T,check]),
- emit({"'",Name,"'(",DefaultValue,", ",Element,")"}),
- %% insert in ets table and do look ahead check
- Typedef = asn1_db:dbget(M,T),
- RefType = Typedef#typedef.typespec,
- InType = asn1ct_gen:get_inner(RefType#type.def),
- case insert_once(check_functions,{Name,RefType}) of
- true ->
- lookahead_innertype([T],InType,RefType);
- _ ->
- ok
- end;
- {constructed,bif} ->
- NameList = [Cname|TopType],
- Name = list2name(NameList ++ [check]),
- emit({"'",Name,"'(",DefaultValue,", ",Element,")"}),
- asn1ct_table:insert(check_functions, {Name, Type}),
- %% Must look for check functions in InnerType,
- %% that may be referenced or internal defined
- %% constructed types not used elsewhere.
- lookahead_innertype(NameList,InnerType,Type);
- _ ->
- %% Generate Dummy function call i.e. anything is accepted
- emit(["fun() -> true end ()"])
- end.
-
-gen_prim_check_call(PrimType, Default, Element, Type) ->
- case unify_if_string(PrimType) of
- 'BOOLEAN' ->
- check_call(check_bool, [Default,Element]);
- 'INTEGER' ->
- NNL = case Type#type.def of
- {_,NamedNumberList} -> NamedNumberList;
- _ -> []
- end,
- check_call(check_int, [Default,Element,{asis,NNL}]);
- 'BIT STRING' ->
- case Type#type.def of
- {_,[]} ->
- check_call(check_bitstring,
- [Default,Element]);
- {_,[_|_]=NBL} ->
- check_call(check_named_bitstring,
- [Default,Element,{asis,NBL}])
- end;
- 'OCTET STRING' ->
- check_call(check_octetstring, [Default,Element]);
- 'NULL' ->
- check_call(check_null, [Default,Element]);
- 'OBJECT IDENTIFIER' ->
- check_call(check_objectidentifier, [Default,Element]);
- 'RELATIVE-OID' ->
- check_call(check_objectidentifier, [Default,Element]);
- 'ObjectDescriptor' ->
- check_call(check_objectdescriptor, [Default,Element]);
- 'REAL' ->
- check_call(check_real, [Default,Element]);
- 'ENUMERATED' ->
- {_,Enumerations} = Type#type.def,
- check_call(check_enum, [Default,Element,{asis,Enumerations}]);
- restrictedstring ->
- check_call(check_restrictedstring, [Default,Element])
- end.
-
-check_call(F, Args) ->
- asn1ct_func:call(check, F, Args).
-
-%% lokahead_innertype/3 traverses Type and checks if check functions
-%% have to be generated, i.e. for all constructed or referenced types.
-lookahead_innertype(Name,'SEQUENCE',Type) ->
- Components = (Type#type.def)#'SEQUENCE'.components,
- lookahead_components(Name,Components);
-lookahead_innertype(Name,'SET',Type) ->
- Components = (Type#type.def)#'SET'.components,
- lookahead_components(Name,Components);
-lookahead_innertype(Name,'CHOICE',Type) ->
- {_,Components} = Type#type.def,
- lookahead_components(Name,Components);
-lookahead_innertype(Name,'SEQUENCE OF',SeqOf) ->
- lookahead_sof(Name,'SEQOF',SeqOf);
-lookahead_innertype(Name,'SET OF',SeqOf) ->
- lookahead_sof(Name,'SETOF',SeqOf);
-lookahead_innertype(_Name,#'Externaltypereference'{module=M,type=T},_) ->
- Typedef = asn1_db:dbget(M,T),
- RefType = Typedef#typedef.typespec,
- insert_once(check_functions,{list2name([T,check]),RefType}),
- InType = asn1ct_gen:get_inner(RefType#type.def),
- case type(InType) of
- {constructed,bif} ->
- lookahead_innertype([T],InType,RefType);
- Ref = #'Externaltypereference'{} ->
- lookahead_reference(Ref);
- _ ->
- ok
- end;
-lookahead_innertype(_,_,_) ->
- ok.
-
-lookahead_components(_,[]) -> ok;
-lookahead_components(Name,[C|Cs]) ->
- #'ComponentType'{name=Cname,typespec=Type} = C,
- InType = asn1ct_gen:get_inner(Type#type.def),
- case asn1ct_gen:type(InType) of
- {constructed,bif} ->
- case insert_once(check_functions,
- {list2name([Cname|Name] ++ [check]),Type}) of
- true ->
- lookahead_innertype([Cname|Name],InType,Type);
- _ ->
- ok
- end;
- #'Externaltypereference'{module=RefMod,type=RefName} ->
- Typedef = asn1_db:dbget(RefMod,RefName),
- RefType = Typedef#typedef.typespec,
- case insert_once(check_functions,{list2name([RefName,check]),
- RefType}) of
- true ->
- lookahead_innertype([RefName],InType,RefType);
- _ ->
- ok
- end;
- _ ->
- ok
- end,
- lookahead_components(Name,Cs).
-
-lookahead_sof(Name,SOF,SOFType) ->
- Type = case SOFType#type.def of
- {_,_Type} -> _Type;
- _Type -> _Type
- end,
- InnerType = asn1ct_gen:get_inner(Type#type.def),
- case asn1ct_gen:type(InnerType) of
- {constructed,bif} ->
- %% this is if a constructed type is defined in
- %% the SEQUENCE OF type
- NameList = [SOF|Name],
- insert_once(check_functions,
- {list2name(NameList ++ [check]),Type}),
- lookahead_innertype(NameList,InnerType,Type);
- Ref = #'Externaltypereference'{} ->
- lookahead_reference(Ref);
- _ ->
- ok
- end.
-
-lookahead_reference(#'Externaltypereference'{module=M,type=T}) ->
- Typedef = asn1_db:dbget(M,T),
- RefType = Typedef#typedef.typespec,
- InType = get_inner(RefType#type.def),
- case insert_once(check_functions,
- {list2name([T,check]),RefType}) of
- true ->
- lookahead_innertype([T],InType,RefType);
- _ ->
- ok
- end.
-
insert_once(Table,Object) ->
case asn1ct_table:lookup(Table, element(1, Object)) of
[] ->
@@ -1683,6 +1379,11 @@ conform_value(#type{def={'BIT STRING',[]}}, Bs) ->
bitstring when is_bitstring(Bs) ->
Bs
end;
+conform_value(#type{def='OCTET STRING'}, String) ->
+ case asn1ct:use_legacy_types() of
+ false -> String;
+ true -> binary_to_list(String)
+ end;
conform_value(_, Value) -> Value.
named_bitstring_value(List, Names) ->
@@ -1901,11 +1602,6 @@ get_constraint(C,Key) ->
{value,Cnstr} ->
Cnstr
end.
-
-ensure_atom(Atom) when is_atom(Atom) ->
- Atom;
-ensure_atom(List) when is_list(List) ->
- list_to_atom(List).
get_record_name_prefix() ->
case lists:keysearch(record_name_prefix,1,get(encoding_options)) of
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index bea0ec8968..e51b0898be 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -27,11 +27,12 @@
-export([decode_class/1, decode_type/1]).
-export([gen_encode/2,gen_encode/3,gen_decode/2,gen_decode/3]).
-export([gen_encode_prim/4]).
--export([gen_dec_prim/7]).
+-export([gen_dec_prim/3]).
-export([gen_objectset_code/2, gen_obj_code/3]).
-export([encode_tag_val/3]).
-export([gen_inc_decode/2,gen_decode_selected/3]).
-export([extaddgroup2sequence/1]).
+-export([dialyzer_suppressions/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -65,6 +66,23 @@
%%===============================================================================
%%===============================================================================
+dialyzer_suppressions(_) ->
+ case asn1ct:use_legacy_types() of
+ false -> ok;
+ true -> suppress({ber,encode_bit_string,4})
+ end,
+ suppress({ber,decode_selective,2}),
+ emit([" ok.",nl]).
+
+suppress({M,F,A}=MFA) ->
+ case asn1ct_func:is_used(MFA) of
+ false ->
+ ok;
+ true ->
+ Args = [lists:concat(["element(",I,", Arg)"]) || I <- lists:seq(1, A)],
+ emit([" ",{call,M,F,Args},com,nl])
+ end.
+
%%===============================================================================
%% encode #{typedef, {pos, name, typespec}}
%%===============================================================================
@@ -163,6 +181,12 @@ gen_encode_user(Erules, #typedef{}=D, Wrapper) ->
gen_encode_prim(_Erules, #type{}=D, DoTag, Value) ->
BitStringConstraint = get_size_constraint(D#type.constraint),
+ MaxBitStrSize = case BitStringConstraint of
+ [] -> none;
+ {_,'MAX'} -> none;
+ {_,Max} -> Max;
+ Max when is_integer(Max) -> Max
+ end,
asn1ct_name:new(enumval),
Type = case D#type.def of
'OCTET STRING' -> restricted_string;
@@ -208,11 +232,11 @@ gen_encode_prim(_Erules, #type{}=D, DoTag, Value) ->
"end"]);
{'BIT STRING',[]} ->
case asn1ct:use_legacy_types() of
- false when BitStringConstraint =:= [] ->
+ false when MaxBitStrSize =:= none ->
call(encode_unnamed_bit_string, [Value,DoTag]);
false ->
call(encode_unnamed_bit_string,
- [{asis,BitStringConstraint},Value,DoTag]);
+ [{asis,MaxBitStrSize},Value,DoTag]);
true ->
call(encode_bit_string,
[{asis,BitStringConstraint},Value,
@@ -220,12 +244,12 @@ gen_encode_prim(_Erules, #type{}=D, DoTag, Value) ->
end;
{'BIT STRING',NamedNumberList} ->
case asn1ct:use_legacy_types() of
- false when BitStringConstraint =:= [] ->
+ false when MaxBitStrSize =:= none ->
call(encode_named_bit_string,
[Value,{asis,NamedNumberList},DoTag]);
false ->
call(encode_named_bit_string,
- [{asis,BitStringConstraint},Value,
+ [{asis,MaxBitStrSize},Value,
{asis,NamedNumberList},DoTag]);
true ->
call(encode_bit_string,
@@ -254,14 +278,20 @@ emit_enc_enumerated_cases(L, Tags) ->
emit_enc_enumerated_cases(L, Tags, noext).
emit_enc_enumerated_cases([{EnumName,EnumVal}|T], Tags, Ext) ->
+ Bytes = encode_pos_integer(EnumVal, []),
+ Len = length(Bytes),
emit([{asis,EnumName}," -> ",
- {call,ber,encode_enumerated,[EnumVal,Tags]},";",nl]),
+ {call,ber,encode_tags,[Tags,{asis,Bytes},Len]},";",nl]),
emit_enc_enumerated_cases(T, Tags, Ext);
emit_enc_enumerated_cases([], _Tags, _Ext) ->
%% FIXME: Should extension be handled?
emit([{curr,enumval}," -> exit({error,{asn1, {enumerated_not_in_range,",{curr, enumval},"}}})"]),
emit([nl,"end"]).
+encode_pos_integer(0, [B|_Acc] = L) when B < 128 ->
+ L;
+encode_pos_integer(N, Acc) ->
+ encode_pos_integer(N bsr 8, [N band 255|Acc]).
%%===============================================================================
%%===============================================================================
@@ -339,15 +369,11 @@ gen_decode_selected_type(_Erules,TypeDef) ->
case asn1ct_gen:type(InnerType) of
'ASN1_OPEN_TYPE' ->
asn1ct_name:new(len),
- gen_dec_prim(ber, Def#type{def='ASN1_OPEN_TYPE'},
- BytesVar,Tag, [] ,
- ?PRIMITIVE,"OptOrMand");
-% emit({";",nl});
+ gen_dec_prim(Def#type{def='ASN1_OPEN_TYPE'},
+ BytesVar, Tag);
{primitive,bif} ->
asn1ct_name:new(len),
- gen_dec_prim(ber, Def, BytesVar,Tag,[] ,
- ?PRIMITIVE,"OptOrMand");
-% emit([";",nl]);
+ gen_dec_prim(Def, BytesVar, Tag);
{constructed,bif} ->
TopType = case TypeDef#typedef.name of
A when is_atom(A) -> [A];
@@ -461,14 +487,12 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
case asn1ct_gen:type(InnerType) of
'ASN1_OPEN_TYPE' ->
asn1ct_name:new(len),
- gen_dec_prim(ber, Def#type{def='ASN1_OPEN_TYPE'},
- BytesVar,{string,"TagIn"}, [] ,
- ?PRIMITIVE,"OptOrMand"),
+ gen_dec_prim(Def#type{def='ASN1_OPEN_TYPE'},
+ BytesVar, {string,"TagIn"}),
emit({".",nl,nl});
{primitive,bif} ->
asn1ct_name:new(len),
- gen_dec_prim(ber, Def, BytesVar,{string,"TagIn"},[] ,
- ?PRIMITIVE,"OptOrMand"),
+ gen_dec_prim(Def, BytesVar, {string,"TagIn"}),
emit([".",nl,nl]);
{constructed,bif} ->
asn1ct:update_namelist(D#typedef.name),
@@ -481,17 +505,10 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
end.
-gen_dec_prim(_Erules, Att, BytesVar, DoTag, _TagIn, _Form, _OptOrMand) ->
+gen_dec_prim(Att, BytesVar, DoTag) ->
Typename = Att#type.def,
-%% Currently not used for BER replaced with [] as place holder
-%% Constraint = Att#type.constraint,
-%% Constraint = [],
Constraint = get_size_constraint(Att#type.constraint),
IntConstr = int_constr(Att#type.constraint),
- AsBin = case get(binary_strings) of
- true -> "_as_bin";
- _ -> ""
- end,
NewTypeName = case Typename of
'NumericString' -> restricted_string;
'TeletexString' -> restricted_string;
@@ -505,107 +522,77 @@ gen_dec_prim(_Erules, Att, BytesVar, DoTag, _TagIn, _Form, _OptOrMand) ->
'ObjectDescriptor'-> restricted_string;
'UTCTime' -> restricted_string;
'GeneralizedTime' -> restricted_string;
+ 'OCTET STRING' ->
+ case asn1ct:use_legacy_types() of
+ true -> restricted_string;
+ false -> Typename
+ end;
_ -> Typename
end,
+ TagStr = case DoTag of
+ {string,Tag1} -> Tag1;
+ _ when is_list(DoTag) -> {asis,DoTag}
+ end,
case NewTypeName of
'BOOLEAN'->
- emit(["decode_boolean(",BytesVar,","]),
- need(decode_boolean, 2);
+ call(decode_boolean, [BytesVar,TagStr]);
'INTEGER' ->
- case IntConstr of
- [] ->
- emit(["decode_integer(",BytesVar,","]),
- need(decode_integer, 2);
- {_,_} ->
- emit(["decode_integer(",BytesVar,",",
- {asis,IntConstr},","]),
- need(decode_integer, 3)
- end;
- {'INTEGER',NamedNumberList} ->
- case IntConstr of
- [] ->
- emit(["decode_named_integer(",BytesVar,",",
- {asis,NamedNumberList},","]),
- need(decode_named_integer, 3);
- {_,_} ->
- emit(["decode_named_integer(",BytesVar,",",
- {asis,IntConstr},",",
- {asis,NamedNumberList},","]),
- need(decode_named_integer, 4)
- end;
- {'ENUMERATED',NamedNumberList} ->
- emit(["decode_enumerated(",BytesVar,",",
- {asis,NamedNumberList},","]),
- need(decode_enumerated, 3);
+ check_constraint(decode_integer, [BytesVar,TagStr],
+ IntConstr,
+ identity,
+ identity);
+ {'INTEGER',NNL} ->
+ check_constraint(decode_integer,
+ [BytesVar,TagStr],
+ IntConstr,
+ identity,
+ fun(Val) ->
+ asn1ct_name:new(val),
+ emit([{curr,val}," = "]),
+ Val(),
+ emit([com,nl,
+ {call,ber,number2name,
+ [{curr,val},{asis,NNL}]}])
+ end);
+ {'ENUMERATED',NNL} ->
+ gen_dec_enumerated(BytesVar, NNL, TagStr);
'REAL' ->
- ok;
- {'BIT STRING',_NamedNumberList} ->
- ok;
+ asn1ct_name:new(tmpbuf),
+ emit(["begin",nl,
+ {curr,tmpbuf}," = ",
+ {call,ber,match_tags,[BytesVar,TagStr]},com,nl,
+ {call,real_common,decode_real,[{curr,tmpbuf}]},nl,
+ "end",nl]);
+ {'BIT STRING',NNL} ->
+ gen_dec_bit_string(BytesVar, Constraint, NNL, TagStr);
'NULL' ->
- emit(["decode_null(",BytesVar,","]),
- need(decode_null, 2);
+ call(decode_null, [BytesVar,TagStr]);
'OBJECT IDENTIFIER' ->
- emit(["decode_object_identifier(",BytesVar,","]),
- need(decode_object_identifier, 2);
+ call(decode_object_identifier, [BytesVar,TagStr]);
'RELATIVE-OID' ->
- emit(["decode_relative_oid(",BytesVar,","]),
- need(decode_relative_oid, 2);
+ call(decode_relative_oid, [BytesVar,TagStr]);
'OCTET STRING' ->
- F = case asn1ct:use_legacy_types() of
- false -> decode_octet_string;
- true -> decode_restricted_string
- end,
- emit([{asis,F},"(",BytesVar,","]),
- case Constraint of
- [] ->
- need(F, 2);
- _ ->
- emit([{asis,Constraint},","]),
- need(F, 3)
- end;
+ check_constraint(decode_octet_string, [BytesVar,TagStr],
+ Constraint, {erlang,byte_size}, identity);
restricted_string ->
- emit(["decode_restricted_string",AsBin,"(",BytesVar,","]),
- case Constraint of
- [] ->
- need(decode_restricted_string, 2);
- _ ->
- emit([{asis,Constraint},","]),
- need(decode_restricted_string, 3)
- end;
+ check_constraint(decode_restricted_string, [BytesVar,TagStr],
+ Constraint,
+ {erlang,byte_size},
+ fun(Val) ->
+ emit("binary_to_list("),
+ Val(),
+ emit(")")
+ end);
'UniversalString' ->
- emit(["decode_universal_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},","]),
- need(decode_universal_string, 3);
+ check_constraint(decode_universal_string, [BytesVar,TagStr],
+ Constraint, {erlang,length}, identity);
'UTF8String' ->
- emit(["decode_UTF8_string",AsBin,"(",
- BytesVar,","]),
- need(decode_UTF8_string, 2);
+ call(decode_UTF8_string, [BytesVar,TagStr]);
'BMPString' ->
- emit(["decode_BMP_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},","]),
- need(decode_BMP_string, 3);
+ check_constraint(decode_BMP_string, [BytesVar,TagStr],
+ Constraint, {erlang,length}, identity);
'ASN1_OPEN_TYPE' ->
- emit(["decode_open_type_as_binary(",
- BytesVar,","]),
- need(decode_open_type_as_binary, 2)
- end,
-
- TagStr = case DoTag of
- {string,Tag1} -> Tag1;
- _ when is_list(DoTag) -> {asis,DoTag}
- end,
- case NewTypeName of
- {'BIT STRING',NNL} ->
- gen_dec_bit_string(BytesVar, Constraint, NNL, TagStr);
- 'REAL' ->
- asn1ct_name:new(tmpbuf),
- emit(["begin",nl,
- {curr,tmpbuf}," = ",
- {call,ber,match_tags,[BytesVar,TagStr]},com,nl,
- {call,real_common,decode_real,[{curr,tmpbuf}]},nl,
- "end",nl]);
- _ ->
- emit([TagStr,")"])
+ call(decode_open_type_as_binary, [BytesVar,TagStr])
end.
%% Simplify an integer constraint so that we can efficiently test it.
@@ -621,7 +608,7 @@ int_constr(C) ->
[{'ValueRange',{_,_}=Range}] ->
Range;
[{'SingleValue',Sv}] ->
- {Sv,Sv};
+ Sv;
[] ->
[]
end.
@@ -632,16 +619,108 @@ gen_dec_bit_string(BytesVar, _Constraint, [_|_]=NNL, TagStr) ->
gen_dec_bit_string(BytesVar, Constraint, [], TagStr) ->
case asn1ct:get_bit_string_format() of
compact ->
- call(decode_compact_bit_string,
- [BytesVar,{asis,Constraint},TagStr]);
+ check_constraint(decode_compact_bit_string,
+ [BytesVar,TagStr],
+ Constraint,
+ {ber,compact_bit_string_size},
+ identity);
legacy ->
- call(decode_legacy_bit_string,
- [BytesVar,{asis,Constraint},TagStr]);
+ check_constraint(decode_native_bit_string,
+ [BytesVar,TagStr],
+ Constraint,
+ {erlang,bit_size},
+ fun(Val) ->
+ asn1ct_name:new(val),
+ emit([{curr,val}," = "]),
+ Val(),
+ emit([com,nl,
+ {call,ber,native_to_legacy_bit_string,
+ [{curr,val}]}])
+ end);
bitstring ->
- call(decode_native_bit_string,
- [BytesVar,{asis,Constraint},TagStr])
+ check_constraint(decode_native_bit_string,
+ [BytesVar,TagStr],
+ Constraint,
+ {erlang,bit_size},
+ identity)
+ end.
+
+check_constraint(F, Args, Constr, PreConstr0, ReturnVal0) ->
+ PreConstr = case PreConstr0 of
+ identity ->
+ fun(V) -> V end;
+ {Mod,Name} ->
+ fun(V) ->
+ asn1ct_name:new(c),
+ emit([{curr,c}," = ",
+ {call,Mod,Name,[V]},com,nl]),
+ {curr,c}
+ end
+ end,
+ ReturnVal = case ReturnVal0 of
+ identity -> fun(Val) -> Val() end;
+ _ -> ReturnVal0
+ end,
+ case Constr of
+ [] when ReturnVal0 =:= identity ->
+ %% No constraint, no complications.
+ call(F, Args);
+ [] ->
+ %% No constraint, but the return value could consist
+ %% of more than one statement.
+ emit(["begin",nl]),
+ ReturnVal(fun() -> call(F, Args) end),
+ emit([nl,
+ "end",nl]);
+ _ ->
+ %% There is a constraint.
+ asn1ct_name:new(val),
+ emit(["begin",nl,
+ {curr,val}," = ",{call,ber,F,Args},com,nl]),
+ PreVal0 = asn1ct_gen:mk_var(asn1ct_name:curr(val)),
+ PreVal = PreConstr(PreVal0),
+ emit("if "),
+ case Constr of
+ {Min,Max} ->
+ emit([{asis,Min}," =< ",PreVal,", ",
+ PreVal," =< ",{asis,Max}]);
+ Sv when is_integer(Sv) ->
+ emit([PreVal," =:= ",{asis,Sv}])
+ end,
+ emit([" ->",nl]),
+ ReturnVal(fun() -> emit(PreVal0) end),
+ emit([";",nl,
+ "true ->",nl,
+ "exit({error,{asn1,bad_range}})",nl,
+ "end",nl,
+ "end"])
end.
+gen_dec_enumerated(BytesVar, NNL0, TagStr) ->
+ asn1ct_name:new(enum),
+ emit(["case ",
+ {call,ber,decode_integer,[BytesVar,TagStr]},
+ " of",nl]),
+ NNL = case NNL0 of
+ {L1,L2} ->
+ L1 ++ L2 ++ [accept];
+ [_|_] ->
+ NNL0 ++ [error]
+ end,
+ gen_dec_enumerated_1(NNL),
+ emit("end").
+
+gen_dec_enumerated_1([accept]) ->
+ asn1ct_name:new(default),
+ emit([{curr,default}," -> {asn1_enum,",{curr,default},"}",nl]);
+gen_dec_enumerated_1([error]) ->
+ asn1ct_name:new(default),
+ emit([{curr,default}," -> exit({error,{asn1,{illegal_enumerated,",
+ {curr,default},"}}})",nl]);
+gen_dec_enumerated_1([{V,K}|T]) ->
+ emit([{asis,K}," -> ",{asis,V},";",nl]),
+ gen_dec_enumerated_1(T).
+
%% Object code generating for encoding and decoding
%% ------------------------------------------------
@@ -986,9 +1065,8 @@ gen_decode_field_call(ObjName,FieldName,Bytes,Type) ->
Tag = [(decode_class(X#tag.class) bsl 10) + X#tag.number ||
X <- OTag],
case Type#typedef.name of
- {primitive,bif} -> %%tag should be the primitive tag
- gen_dec_prim(ber,Def,Bytes,Tag,"TagIn",?PRIMITIVE,
- opt_or_default),
+ {primitive,bif} ->
+ gen_dec_prim(Def, Bytes, Tag),
[];
{constructed,bif} ->
emit({" 'dec_",ObjName,'_',FieldName,
@@ -1016,8 +1094,7 @@ gen_decode_default_call(ClassName,FieldName,Bytes,Type) ->
FieldName])),
typespec=Type}];
{primitive,bif} ->
- gen_dec_prim(ber,Type,Bytes,Tag,"TagIn",
- ?PRIMITIVE,opt_or_default),
+ gen_dec_prim(Type, Bytes, Tag),
[];
#'Externaltypereference'{module=CurrentMod,type=Etype} ->
emit([" 'dec_",Etype,"'(",Bytes, " ,",{asis,Tag},")",nl]),
@@ -1386,7 +1463,7 @@ emit_dec_open_type(I) ->
end,
emit(S).
-emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},Prop,
+emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type}, _Prop,
InternalDefFunName) ->
OTag = Type#type.tag,
%% Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
@@ -1394,8 +1471,7 @@ emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},Prop,
case {ExtName,Name} of
{primitive,bif} ->
emit(indent(12)),
- gen_dec_prim(ber,Type,"Bytes",Tag,"TagIn",
- ?PRIMITIVE,Prop),
+ gen_dec_prim(Type, "Bytes", Tag),
0;
{constructed,bif} ->
emit([indent(12),"'dec_",
@@ -1412,7 +1488,7 @@ emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},Prop,
emit_inner_of_decfun(#typedef{name=Name},_Prop,_) ->
emit([indent(12),"'dec_",Name,"'(Bytes)"]),
0;
-emit_inner_of_decfun(Type,Prop,_) when is_record(Type,type) ->
+emit_inner_of_decfun(#type{}=Type, _Prop, _) ->
OTag = Type#type.tag,
%% Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
Tag = [(decode_class(X#tag.class) bsl 10) + X#tag.number || X <- OTag],
@@ -1423,8 +1499,7 @@ emit_inner_of_decfun(Type,Prop,_) when is_record(Type,type) ->
case WhatKind of
{primitive,bif} ->
emit([indent(9),Def," ->",nl,indent(12)]),
- gen_dec_prim(ber,Type,"Bytes",Tag,"TagIn",
- ?PRIMITIVE,Prop);
+ gen_dec_prim(Type, "Bytes", Tag);
#'Externaltypereference'{module=CurrMod,type=T} ->
emit([indent(9),T," ->",nl,indent(12),"'dec_",T,
% "'(Bytes, ",Prop,")"]);
@@ -1561,6 +1636,3 @@ extaddgroup2sequence(ExtList) when is_list(ExtList) ->
call(F, Args) ->
asn1ct_func:call(ber, F, Args).
-
-need(F, Arity) ->
- asn1ct_func:need({ber,F,Arity}).
diff --git a/lib/asn1/src/asn1ct_gen_check.erl b/lib/asn1/src/asn1ct_gen_check.erl
new file mode 100644
index 0000000000..d80a02dfbf
--- /dev/null
+++ b/lib/asn1/src/asn1ct_gen_check.erl
@@ -0,0 +1,271 @@
+%% vim: tabstop=8:shiftwidth=4
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(asn1ct_gen_check).
+-export([emit/3]).
+
+-import(asn1ct_gen, [emit/1]).
+-include("asn1_records.hrl").
+
+emit(Type, Default, Value) ->
+ Key = {Type,Default},
+ Gen = fun(Fd, Name) ->
+ file:write(Fd, gen(Name, Type, Default))
+ end,
+ emit(" case "),
+ asn1ct_func:call_gen("is_default_", Key, Gen, [Value]),
+ emit([" of",nl,
+ "true -> {[],0};",nl,
+ "false ->",nl]).
+
+gen(Name, #type{def=T}, Default) ->
+ NameStr = atom_to_list(Name),
+ [NameStr,"(asn1_DEFAULT) ->\n",
+ "true;\n"|case do_gen(T, Default) of
+ {literal,Literal} ->
+ [NameStr,"(",term2str(Literal),") ->\n","true;\n",
+ NameStr,"(_) ->\n","false.\n\n"];
+ {exception,Func,Args} ->
+ [NameStr,"(Value) ->\n",
+ "try ",Func,"(Value",arg2str(Args),") of\n",
+ "_ -> true\n"
+ "catch throw:false -> false\n"
+ "end.\n\n"]
+ end].
+
+do_gen(_, asn1_NOVALUE) ->
+ {literal,asn1_NOVALUE};
+do_gen(#'Externaltypereference'{module=M,type=T}, Default) ->
+ #typedef{typespec=#type{def=Td}} = asn1_db:dbget(M, T),
+ do_gen(Td, Default);
+do_gen('BOOLEAN', Default) ->
+ {literal,Default};
+do_gen({'BIT STRING',[]}, Default) ->
+ true = is_bitstring(Default), %Assertion.
+ case asn1ct:use_legacy_types() of
+ false ->
+ {literal,Default};
+ true ->
+ {exception,need(check_legacy_bitstring, 2),[Default]}
+ end;
+do_gen({'BIT STRING',[_|_]=NBL}, Default) ->
+ do_named_bitstring(NBL, Default);
+do_gen({'ENUMERATED',_}, Default) ->
+ {literal,Default};
+do_gen('INTEGER', Default) ->
+ {literal,Default};
+do_gen({'INTEGER',NNL}, Default) ->
+ {exception,need(check_int, 3),[Default,NNL]};
+do_gen('NULL', Default) ->
+ {literal,Default};
+do_gen('OCTET STRING', Default) ->
+ true = is_binary(Default), %Assertion.
+ case asn1ct:use_legacy_types() of
+ false ->
+ {literal,Default};
+ true ->
+ {exception,need(check_octetstring, 2),[Default]}
+ end;
+do_gen('OBJECT IDENTIFIER', Default0) ->
+ Default = pre_process_oid(Default0),
+ {exception,need(check_objectidentifier, 2),[Default]};
+do_gen({'CHOICE',Cs}, Default) ->
+ {Tag,Value} = Default,
+ [Type] = [Type || #'ComponentType'{name=T,typespec=Type} <- Cs,
+ T =:= Tag],
+ case do_gen(Type#type.def, Value) of
+ {literal,Lit} ->
+ {literal,{Tag,Lit}};
+ {exception,Func0,Args} ->
+ Key = {Tag,Func0,Args},
+ Gen = fun(Fd, Name) ->
+ S = gen_choice(Name, Tag, Func0, Args),
+ ok = file:write(Fd, S)
+ end,
+ Func = asn1ct_func:call_gen("is_default_choice", Key, Gen),
+ {exception,atom_to_list(Func),[]}
+ end;
+do_gen(#'SEQUENCE'{components=Cs}, Default) ->
+ do_seq_set(Cs, Default);
+do_gen({'SEQUENCE OF',Type}, Default) ->
+ do_sof(Type, Default);
+do_gen(#'SET'{components=Cs}, Default) ->
+ do_seq_set(Cs, Default);
+do_gen({'SET OF',Type}, Default) ->
+ do_sof(Type, Default);
+do_gen(Type, Default) ->
+ case asn1ct_gen:unify_if_string(Type) of
+ restrictedstring ->
+ {exception,need(check_restrictedstring, 2),[Default]};
+ _ ->
+ %% Open type. Do our best.
+ {literal,Default}
+ end.
+
+do_named_bitstring(NBL, Default0) when is_list(Default0) ->
+ Default = lists:sort(Default0),
+ Bs = asn1ct_gen:named_bitstring_value(Default, NBL),
+ Func = case asn1ct:use_legacy_types() of
+ false -> check_named_bitstring;
+ true -> check_legacy_named_bitstring
+ end,
+ {exception,need(Func, 4),[Default,Bs,bit_size(Bs)]};
+do_named_bitstring(_, Default) when is_bitstring(Default) ->
+ Func = case asn1ct:use_legacy_types() of
+ false -> check_named_bitstring;
+ true -> check_legacy_named_bitstring
+ end,
+ {exception,need(Func, 3),[Default,bit_size(Default)]}.
+
+do_seq_set(Cs0, Default) ->
+ Tag = element(1, Default),
+ Cs1 = [T || #'ComponentType'{typespec=T} <- Cs0],
+ Cs = components(Cs1, tl(tuple_to_list(Default))),
+ case are_all_literals(Cs) of
+ true ->
+ Literal = list_to_tuple([Tag|[L || {literal,L} <- Cs]]),
+ {literal,Literal};
+ false ->
+ Key = {Cs,Default},
+ Gen = fun(Fd, Name) ->
+ S = gen_components(Name, Tag, Cs),
+ ok = file:write(Fd, S)
+ end,
+ Func = asn1ct_func:call_gen("is_default_cs_", Key, Gen),
+ {exception,atom_to_list(Func),[]}
+ end.
+
+do_sof(Type, Default0) ->
+ Default = lists:sort(Default0),
+ Cs0 = lists:duplicate(length(Default), Type),
+ Cs = components(Cs0, Default),
+ case are_all_literals(Cs) of
+ true ->
+ Literal = [Lit || {literal,Lit} <- Cs],
+ {exception,need(check_literal_sof, 2),[Literal]};
+ false ->
+ Key = Cs,
+ Gen = fun(Fd, Name) ->
+ S = gen_sof(Name, Cs),
+ ok = file:write(Fd, S)
+ end,
+ Func = asn1ct_func:call_gen("is_default_sof", Key, Gen),
+ {exception,atom_to_list(Func),[]}
+ end.
+
+are_all_literals([{literal,_}|T]) ->
+ are_all_literals(T);
+are_all_literals([_|_]) ->
+ false;
+are_all_literals([]) -> true.
+
+gen_components(Name, Tag, Cs) ->
+ [atom_to_list(Name),"(Value) ->\n",
+ "case Value of\n",
+ "{",term2str(Tag)|gen_cs_1(Cs, 1, [])].
+
+gen_cs_1([{literal,Lit}|T], I, Acc) ->
+ [",\n",term2str(Lit)|gen_cs_1(T, I, Acc)];
+gen_cs_1([H|T], I, Acc) ->
+ Var = "E"++integer_to_list(I),
+ [",\n",Var|gen_cs_1(T, I+1, [{Var,H}|Acc])];
+gen_cs_1([], _, Acc) ->
+ ["} ->\n"|gen_cs_2(Acc, "")].
+
+gen_cs_2([{Var,{exception,Func,Args}}|T], Sep) ->
+ [Sep,Func,"(",Var,arg2str(Args),")"|gen_cs_2(T, ",\n")];
+gen_cs_2([], _) ->
+ [";\n",
+ "_ ->\n"
+ "throw(false)\n"
+ "end.\n"].
+
+gen_sof(Name, Cs) ->
+ [atom_to_list(Name),"(Value) ->\n",
+ "case length(Value) of\n",
+ integer_to_list(length(Cs))," -> ok;\n"
+ "_ -> throw(false)\n"
+ "end,\n"
+ "T0 = lists:sort(Value)"|gen_sof_1(Cs, 1)].
+
+gen_sof_1([{exception,Func,Args}|Cs], I) ->
+ NumStr = integer_to_list(I),
+ H = "H" ++ NumStr,
+ T = "T" ++ NumStr,
+ Prev = "T" ++ integer_to_list(I-1),
+ [",\n",
+ "[",H,case Cs of
+ [] -> [];
+ [_|_] -> ["|",T]
+ end,"] = ",Prev,",\n",
+ Func,"(",H,arg2str(Args),")"|gen_sof_1(Cs, I+1)];
+gen_sof_1([], _) ->
+ ".\n".
+
+components([#type{def=Def}|Ts], [V|Vs]) ->
+ [do_gen(Def, V)|components(Ts, Vs)];
+components([], []) -> [].
+
+gen_choice(Name, Tag, Func, Args) ->
+ NameStr = atom_to_list(Name),
+ [NameStr,"({",term2str(Tag),",Value}) ->\n"
+ " ",Func,"(Value",arg2str(Args),");\n",
+ NameStr,"(_) ->\n"
+ " throw(false).\n"].
+
+pre_process_oid(Oid) ->
+ Reserved = reserved_oid(),
+ pre_process_oid(tuple_to_list(Oid), Reserved, []).
+
+pre_process_oid([H|T]=Tail, Res0, Acc) ->
+ case lists:keyfind(H, 2, Res0) of
+ false ->
+ {lists:reverse(Acc),Tail};
+ {Names0,H,Res} ->
+ Names = case is_list(Names0) of
+ false -> [Names0];
+ true -> Names0
+ end,
+ Keys = [H|Names],
+ pre_process_oid(T, Res, [Keys|Acc])
+ end.
+
+reserved_oid() ->
+ [{['itu-t',ccitt],0,
+ [{recommendation,0,[]},
+ {question,1,[]},
+ {administration,2,[]},
+ {'network-operator',3,[]},
+ {'identified-organization',4,[]}]},
+ {iso,1,[{standard,0,[]},
+ {'member-body',2,[]},
+ {'identified-organization',3,[]}]},
+ {['joint-iso-itu-t','joint-iso-ccitt'],2,[]}].
+
+arg2str(Args) ->
+ [", "++term2str(Arg) || Arg <- Args].
+
+term2str(T) ->
+ io_lib:format("~w", [T]).
+
+need(F, A) ->
+ asn1ct_func:need({check,F,A}),
+ atom_to_list(F).
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 519ce9f054..39cc0536f8 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -32,6 +32,7 @@
-export([gen_encode/2, gen_encode/3]).
-export([gen_dec_external/2]).
-export([extaddgroup2sequence/1]).
+-export([dialyzer_suppressions/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
-import(asn1ct_func, [call/3]).
@@ -40,6 +41,15 @@
%% Generate ENCODING ******************************
%%****************************************x
+dialyzer_suppressions(Erules) ->
+ case asn1ct_func:is_used({Erules,complete,1}) of
+ false ->
+ ok;
+ true ->
+ emit([" _ = complete(Arg),",nl])
+ end,
+ emit([" ok.",nl]).
+
gen_encode(Erules,Type) when is_record(Type,typedef) ->
gen_encode_user(Erules,Type).
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index fde39c674e..bdd14871d1 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -82,15 +82,8 @@ per_dec_enumerated(NamedList0, Aligned) ->
Ub = length(NamedList0) - 1,
Constraint = [{'ValueRange',{0,Ub}}],
Int = per_dec_integer(Constraint, Aligned),
- EnumTail = case matched_range(Int) of
- {0,Ub} ->
- %% The error case can never happen.
- [];
- _ ->
- [enum_error]
- end,
- NamedList = per_dec_enumerated_fix_list(NamedList0, EnumTail, 0),
- {map,Int,NamedList}.
+ NamedList = per_dec_enumerated_fix_list(NamedList0, [enum_error], 0),
+ {map,Int,opt_map(NamedList, Int)}.
per_dec_enumerated(BaseNamedList, NamedListExt0, Aligned) ->
Base = per_dec_enumerated(BaseNamedList, Aligned),
@@ -124,7 +117,7 @@ per_dec_length(no, AllowZero, Aligned) ->
per_dec_named_integer(Constraint, NamedList0, Aligned) ->
Int = per_dec_integer(Constraint, Aligned),
NamedList = [{K,V} || {V,K} <- NamedList0] ++ [integer_default],
- {map,Int,NamedList}.
+ {map,Int,opt_map(NamedList, Int)}.
per_dec_k_m_string(StringType, Constraint, Aligned) ->
SzConstr = effective_constraint(bitstring, Constraint),
@@ -175,6 +168,8 @@ per_enc_bit_string(Val0, NNL0, Constraint0, Aligned) ->
ToBs = case ExtraArgs of
[] ->
{call,per_common,bs_drop_trailing_zeroes,[Val]};
+ [0] ->
+ {call,per_common,bs_drop_trailing_zeroes,[Val]};
[Lower] ->
{call,per_common,adjust_trailing_zeroes,[Val,Lower]}
end,
@@ -203,6 +198,7 @@ per_enc_legacy_bit_string(Val0, NNL0, Constraint0, Aligned) ->
Constraint = effective_constraint(bitstring, Constraint0),
ExtraArgs = case constr_min_size(Constraint) of
no -> [];
+ 0 -> [];
Lb -> [Lb]
end,
B ++ [{'try',
@@ -265,10 +261,6 @@ per_enc_k_m_string(Val0, StringType, Constraint, Aligned) ->
SzConstraint = effective_constraint(bitstring, Constraint),
Unit = string_num_bits(StringType, Constraint, Aligned),
Chars0 = char_tab(Constraint, StringType, Unit),
- Args = case enc_char_tab(Chars0) of
- notab -> [Val,Unit];
- Chars -> [Val,Unit,Chars]
- end,
Enc = case Unit of
16 ->
{call,per_common,encode_chars_16bit,[Val],Bin};
@@ -277,7 +269,15 @@ per_enc_k_m_string(Val0, StringType, Constraint, Aligned) ->
8 ->
{call,erlang,list_to_binary,[Val],Bin};
_ ->
- {call,per_common,encode_chars,Args,Bin}
+ case enc_char_tab(Chars0) of
+ notab ->
+ {call,per_common,encode_chars,[Val,Unit],Bin};
+ {tab,Tab} ->
+ {call,per_common,encode_chars,[Val,Unit,Tab],Bin};
+ {compact_map,Map} ->
+ {call,per_common,encode_chars_compact_map,
+ [Val,Unit,Map],Bin}
+ end
end,
case Unit of
8 ->
@@ -581,14 +581,42 @@ per_num_bits(N) when N =< 64 -> 6;
per_num_bits(N) when N =< 128 -> 7;
per_num_bits(N) when N =< 255 -> 8.
+opt_map(Map, Imm) ->
+ case matched_range(Imm) of
+ unknown -> Map;
+ {Lb,Ub} -> opt_map_1(Map, Lb, Ub)
+ end.
+
+opt_map_1([{I,_}=Pair|T], Lb, Ub) ->
+ if
+ I =:= Lb, I =< Ub ->
+ [Pair|opt_map_1(T, Lb+1, Ub)];
+ Lb < I, I =< Ub ->
+ [Pair|opt_map_1(T, Lb, Ub)];
+ true ->
+ opt_map_1(T, Lb, Ub)
+ end;
+opt_map_1(Map, Lb, Ub) ->
+ if
+ Lb =< Ub ->
+ Map;
+ true ->
+ []
+ end.
+
matched_range({get_bits,Bits0,[U|Flags]}) when is_integer(U) ->
- case lists:member(signed, Flags) of
- false ->
+ case not lists:member(signed, Flags) andalso is_integer(Bits0) of
+ true ->
Bits = U*Bits0,
{0,(1 bsl Bits) - 1};
- true ->
+ false ->
unknown
end;
+matched_range({add,Imm,Add}) ->
+ case matched_range(Imm) of
+ unknown -> unknown;
+ {Lb,Ub} -> {Lb+Add,Ub+Add}
+ end;
matched_range(_Op) -> unknown.
string_num_bits(StringType, Constraint, Aligned) ->
@@ -1289,6 +1317,8 @@ eval_cond_1({eq,[],[]}) ->
true;
eval_cond_1({eq,I,N}) when is_integer(I), is_integer(N) ->
I =:= N;
+eval_cond_1({ge,I,N}) when is_integer(I), is_integer(N) ->
+ I >= N;
eval_cond_1({lt,I,N}) when is_integer(I), is_integer(N) ->
I < N;
eval_cond_1(_) -> maybe.
@@ -1303,9 +1333,15 @@ prepend_to_cond_1([Check|T], Code) ->
enc_char_tab(notab) ->
notab;
enc_char_tab(Tab0) ->
- Tab = tuple_to_list(Tab0),
- First = hd(Tab),
- {First-1,list_to_tuple(enc_char_tab_1(Tab, First, 0))}.
+ Tab1 = tuple_to_list(Tab0),
+ First = hd(Tab1),
+ Tab = enc_char_tab_1(Tab1, First, 0),
+ case lists:member(ill, Tab) of
+ false ->
+ {compact_map,{First,tuple_size(Tab0)}};
+ true ->
+ {tab,{First-1,list_to_tuple(Tab)}}
+ end.
enc_char_tab_1([H|T], H, I) ->
[I|enc_char_tab_1(T, H+1, I+1)];
diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl
index 4bd814769f..c4cd872368 100644
--- a/lib/asn1/src/asn1rtt_ber.erl
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -26,25 +26,24 @@
skip_ExtensionAdditions/2]).
-export([encode_boolean/2,decode_boolean/2,
encode_integer/2,encode_integer/3,
- decode_integer/2,decode_integer/3,
- decode_named_integer/3,decode_named_integer/4,
- encode_enumerated/2,decode_enumerated/3,
+ decode_integer/2,
+ number2name/2,
encode_unnamed_bit_string/2,encode_unnamed_bit_string/3,
encode_named_bit_string/3,encode_named_bit_string/4,
encode_bit_string/4,
decode_named_bit_string/3,
- decode_compact_bit_string/3,
- decode_legacy_bit_string/3,
- decode_native_bit_string/3,
+ decode_compact_bit_string/2,compact_bit_string_size/1,
+ decode_native_bit_string/2,
+ native_to_legacy_bit_string/1,
encode_null/2,decode_null/2,
encode_relative_oid/2,decode_relative_oid/2,
encode_object_identifier/2,decode_object_identifier/2,
encode_restricted_string/2,
- decode_octet_string/2,decode_octet_string/3,
- decode_restricted_string/2,decode_restricted_string/3,
- encode_universal_string/2,decode_universal_string/3,
+ decode_octet_string/2,
+ decode_restricted_string/2,
+ encode_universal_string/2,decode_universal_string/2,
encode_UTF8_string/2,decode_UTF8_string/2,
- encode_BMP_string/2,decode_BMP_string/3]).
+ encode_BMP_string/2,decode_BMP_string/2]).
-export([encode_open_type/2,decode_open_type/2,
decode_open_type_as_binary/2]).
@@ -591,8 +590,6 @@ encode_tags(TagIn, {BytesSoFar,LenSoFar}) ->
encode_open_type(Val, T) when is_list(Val) ->
encode_open_type(list_to_binary(Val), T);
-encode_open_type(Val, []) ->
- {Val,byte_size(Val)};
encode_open_type(Val, Tag) ->
encode_tags(Tag, Val, byte_size(Val)).
@@ -697,41 +694,14 @@ encode_integer_neg(N, Acc) ->
%%===============================================================================
%% decode integer
-%% (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
-%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
%%===============================================================================
-decode_named_integer(Tlv, NamedNumberList, TagIn) ->
- V = match_tags(Tlv, TagIn),
- Int = decode_integer(V),
- number2name(Int, NamedNumberList).
-
-decode_named_integer(Tlv, Range, NamedNumberList, TagIn) ->
- V = match_tags(Tlv, TagIn),
- Int = range_check_integer(decode_integer(V), Range),
- number2name(Int, NamedNumberList).
-
decode_integer(Tlv, TagIn) ->
- V = match_tags(Tlv, TagIn),
- decode_integer(V).
-
-decode_integer(Tlv, Range, TagIn) ->
- V = match_tags(Tlv, TagIn),
- Int = decode_integer(V),
- range_check_integer(Int, Range).
-
-decode_integer(Bin) ->
+ Bin = match_tags(Tlv, TagIn),
Len = byte_size(Bin),
<<Int:Len/signed-unit:8>> = Bin,
Int.
-range_check_integer(Int, {Lb,Ub}) when Lb =< Int, Int =< Ub ->
- Int;
-range_check_integer(Int, Range) ->
- exit({error,{asn1,{integer_range,Range,Int}}}).
-
-number2name(Int, []) ->
- Int;
number2name(Int, NamedNumberList) ->
case lists:keyfind(Int, 2, NamedNumberList) of
{NamedVal,_} ->
@@ -740,49 +710,6 @@ number2name(Int, NamedNumberList) ->
Int
end.
-
-%%============================================================================
-%% Enumerated value, ITU_T X.690 Chapter 8.4
-
-%% encode enumerated value
-%%============================================================================
-encode_enumerated(Val, TagIn) when is_integer(Val) ->
- encode_tags(TagIn, encode_integer(Val)).
-
-%%============================================================================
-%% decode enumerated value
-%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> Value
-%%===========================================================================
-decode_enumerated(Tlv, NamedNumberList, Tags) ->
- Buffer = match_tags(Tlv, Tags),
- decode_enumerated_notag(Buffer, NamedNumberList, Tags).
-
-decode_enumerated_notag(Buffer, {NamedNumberList,ExtList}, _Tags) ->
- IVal = decode_integer(Buffer),
- case decode_enumerated1(IVal, NamedNumberList) of
- {asn1_enum,IVal} ->
- decode_enumerated1(IVal,ExtList);
- EVal ->
- EVal
- end;
-decode_enumerated_notag(Buffer, NNList, _Tags) ->
- IVal = decode_integer(Buffer),
- case decode_enumerated1(IVal, NNList) of
- {asn1_enum,_} ->
- exit({error,{asn1, {illegal_enumerated, IVal}}});
- EVal ->
- EVal
- end.
-
-decode_enumerated1(Val, NamedNumberList) ->
- %% it must be a named integer
- case lists:keyfind(Val, 2, NamedNumberList) of
- {NamedVal, _} ->
- NamedVal;
- _ ->
- {asn1_enum,Val}
- end.
-
%%============================================================================
%% Bitstring value, ITU_T X.690 Chapter 8.6
%%
@@ -794,45 +721,46 @@ encode_unnamed_bit_string(Bits, TagIn) ->
Bin = <<Unused,Bits/bitstring,0:Unused>>,
encode_tags(TagIn, Bin, byte_size(Bin)).
-encode_unnamed_bit_string(C, Bits, TagIn) ->
+encode_unnamed_bit_string(MaxBits, Bits, TagIn) ->
NumBits = bit_size(Bits),
Unused = (8 - (NumBits band 7)) band 7,
Bin = <<Unused,Bits/bitstring,0:Unused>>,
- case C of
- {_Min,Max} ->
- if
- NumBits > Max ->
- exit({error,{asn1,
- {bitstring_length,
- {{was,NumBits},{maximum,Max}}}}});
- true ->
- ok
- end;
- Size ->
- if NumBits =< Size ->
- ok;
- true ->
- exit({error,{asn1,
- {bitstring_length,
- {{was,NumBits},{should_be,Size}}}}})
- end
- end,
- encode_tags(TagIn, Bin, byte_size(Bin)).
+ if
+ NumBits > MaxBits ->
+ exit({error,{asn1,
+ {bitstring_length,
+ {{was,NumBits},{maximum,MaxBits}}}}});
+ true ->
+ encode_tags(TagIn, Bin, byte_size(Bin))
+ end.
encode_named_bit_string([H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
- encode_bit_string_named([], Bits, NamedBitList, TagIn);
+ do_encode_named_bit_string(Bits, NamedBitList, TagIn);
encode_named_bit_string([{bit,_}|_]=Bits, NamedBitList, TagIn) ->
- encode_bit_string_named([], Bits, NamedBitList, TagIn);
+ do_encode_named_bit_string(Bits, NamedBitList, TagIn);
encode_named_bit_string(Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
encode_unnamed_bit_string(Bits, TagIn).
encode_named_bit_string(C, [H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
- encode_bit_string_named(C, Bits, NamedBitList, TagIn);
+ do_encode_named_bit_string(C, Bits, NamedBitList, TagIn);
encode_named_bit_string(C, [{bit,_}|_]=Bits, NamedBitList, TagIn) ->
- encode_bit_string_named(C, Bits, NamedBitList, TagIn);
+ do_encode_named_bit_string(C, Bits, NamedBitList, TagIn);
encode_named_bit_string(C, Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
encode_unnamed_bit_string(C, Bits, TagIn).
+do_encode_named_bit_string([FirstVal | RestVal], NamedBitList, TagIn) ->
+ ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
+ Size = lists:max(ToSetPos) + 1,
+ BitList = make_and_set_list(Size, ToSetPos, 0),
+ {Len,Unused,OctetList} = encode_bitstring(BitList),
+ encode_tags(TagIn, [Unused|OctetList],Len+1).
+
+do_encode_named_bit_string(Size, [FirstVal | RestVal], NamedBitList, TagIn) ->
+ ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
+ BitList = make_and_set_list(Size, ToSetPos, 0),
+ {Len, Unused, OctetList} = encode_bitstring(BitList),
+ encode_tags(TagIn, [Unused|OctetList], Len+1).
+
%%============================================================================
%% Bitstring value, ITU_T X.690 Chapter 8.6
%%
@@ -932,15 +860,14 @@ remove_unused_then_dotag(TagIn,Unused,BinBits) ->
encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn) ->
ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
- Size =
- case C of
- [] ->
- lists:max(ToSetPos)+1;
- {_Min,Max} ->
- Max;
- TSize ->
- TSize
- end,
+ Size = case C of
+ [] ->
+ lists:max(ToSetPos) + 1;
+ {_Min,Max} ->
+ Max;
+ TSize ->
+ TSize
+ end,
BitList = make_and_set_list(Size, ToSetPos, 0),
{Len, Unused, OctetList} = encode_bitstring(BitList),
encode_tags(TagIn, [Unused|OctetList],Len+1).
@@ -1098,33 +1025,23 @@ unused_bitlist([Bit | Rest], Trail, Ack) ->
%% decode bitstring value
%%============================================================================
-decode_compact_bit_string(Buffer, Range, Tags) ->
+decode_compact_bit_string(Buffer, Tags) ->
case match_and_collect(Buffer, Tags) of
- <<0>> ->
- check_restricted_string({0,<<>>}, 0, Range);
- <<Unused,Bits/binary>> ->
- Val = {Unused,Bits},
- Len = bit_size(Bits) - Unused,
- check_restricted_string(Val, Len, Range)
+ <<0>> -> {0,<<>>};
+ <<Unused,Bits/binary>> -> {Unused,Bits}
end.
-decode_legacy_bit_string(Buffer, Range, Tags) ->
- Val = case match_and_collect(Buffer, Tags) of
- <<0>> ->
- [];
- <<Unused,Bits/binary>> ->
- decode_bitstring2(byte_size(Bits), Unused, Bits)
- end,
- check_restricted_string(Val, length(Val), Range).
+compact_bit_string_size({Unused,Bits}) ->
+ bit_size(Bits) - Unused.
-decode_native_bit_string(Buffer, Range, Tags) ->
+decode_native_bit_string(Buffer, Tags) ->
case match_and_collect(Buffer, Tags) of
<<0>> ->
- check_restricted_string(<<>>, 0, Range);
+ <<>>;
<<Unused,Bits/binary>> ->
Size = bit_size(Bits) - Unused,
<<Val:Size/bitstring,_:Unused/bitstring>> = Bits,
- check_restricted_string(Val, Size, Range)
+ Val
end.
decode_named_bit_string(Buffer, NamedNumberList, Tags) ->
@@ -1147,6 +1064,9 @@ decode_bitstring2(Len, Unused,
[B7,B6,B5,B4,B3,B2,B1,B0|
decode_bitstring2(Len - 1, Unused, Buffer)].
+native_to_legacy_bit_string(Bits) ->
+ [B || <<B:1>> <= Bits].
+
%%----------------------------------------
%% Decode the bitlist to names
%%----------------------------------------
@@ -1310,31 +1230,12 @@ decode_octet_string(Tlv, TagsIn) ->
Bin = match_and_collect(Tlv, TagsIn),
binary:copy(Bin).
-decode_octet_string(Tlv, Range, TagsIn) ->
- Bin0 = match_and_collect(Tlv, TagsIn),
- Bin = binary:copy(Bin0),
- check_restricted_string(Bin, byte_size(Bin), Range).
-
%%============================================================================
%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
%%============================================================================
decode_restricted_string(Tlv, TagsIn) ->
- Bin = match_and_collect(Tlv, TagsIn),
- binary_to_list(Bin).
-
-decode_restricted_string(Tlv, Range, TagsIn) ->
- Bin = match_and_collect(Tlv, TagsIn),
- check_restricted_string(binary_to_list(Bin), byte_size(Bin), Range).
-
-check_restricted_string(Val, _Len, []) ->
- Val;
-check_restricted_string(Val, Len, {Lb,Ub}) when Lb =< Len, Len =< Ub ->
- Val;
-check_restricted_string(Val, Len, Len) ->
- Val;
-check_restricted_string(Val, _Len, Range) ->
- exit({error,{asn1,{length,Range,Val}}}).
+ match_and_collect(Tlv, TagsIn).
%%============================================================================
%% encode Universal string
@@ -1360,10 +1261,9 @@ mk_uni_list([H|T],List) ->
%% {String, Remain, RemovedBytes}
%%===========================================================================
-decode_universal_string(Buffer, Range, Tags) ->
+decode_universal_string(Buffer, Tags) ->
Bin = match_and_collect(Buffer, Tags),
- Val = mk_universal_string(binary_to_list(Bin)),
- check_restricted_string(Val, length(Val), Range).
+ mk_universal_string(binary_to_list(Bin)).
mk_universal_string(In) ->
mk_universal_string(In, []).
@@ -1423,10 +1323,9 @@ mk_BMP_list([H|T], List) ->
%% (Buffer, Range, StringType, HasTag, TotalLen) ->
%% {String, Remain, RemovedBytes}
%%============================================================================
-decode_BMP_string(Buffer, Range, Tags) ->
+decode_BMP_string(Buffer, Tags) ->
Bin = match_and_collect(Buffer, Tags),
- Val = mk_BMP_string(binary_to_list(Bin)),
- check_restricted_string(Val, length(Val), Range).
+ mk_BMP_string(binary_to_list(Bin)).
mk_BMP_string(In) ->
mk_BMP_string(In,[]).
diff --git a/lib/asn1/src/asn1rtt_check.erl b/lib/asn1/src/asn1rtt_check.erl
index be4f9c8bff..0083867a10 100644
--- a/lib/asn1/src/asn1rtt_check.erl
+++ b/lib/asn1/src/asn1rtt_check.erl
@@ -18,43 +18,41 @@
%%
-module(asn1rtt_check).
--export([check_bool/2,
+-export([check_fail/1,
check_int/3,
- check_bitstring/2,check_named_bitstring/3,
+ check_legacy_bitstring/2,
+ check_legacy_named_bitstring/3,
+ check_legacy_named_bitstring/4,
+ check_named_bitstring/3,
+ check_named_bitstring/4,
+ check_literal_sof/2,
check_octetstring/2,
- check_null/2,
check_objectidentifier/2,
check_objectdescriptor/2,
check_real/2,
- check_enum/3,
check_restrictedstring/2]).
-check_bool(_Bool, asn1_DEFAULT) ->
- true;
-check_bool(Bool, Bool) when is_boolean(Bool) ->
- true;
-check_bool(_Bool1, Bool2) ->
- throw({error,Bool2}).
+check_fail(_) ->
+ throw(false).
-check_int(_, asn1_DEFAULT, _) ->
- true;
check_int(Value, Value, _) when is_integer(Value) ->
true;
-check_int(DefValue, Value, NNL) when is_atom(Value) ->
+check_int(Value, DefValue, NNL) when is_atom(Value) ->
case lists:keyfind(Value, 1, NNL) of
{_,DefValue} ->
true;
_ ->
- throw({error,DefValue})
+ throw(false)
end;
-check_int(DefaultValue, _Value, _) ->
- throw({error,DefaultValue}).
+check_int(_, _, _) ->
+ throw(false).
+
+check_legacy_bitstring(Value, Default) ->
+ check_bitstring(Default, Value).
%% check_bitstring(Default, UserBitstring) -> true|false
%% Default = bitstring()
%% UserBitstring = integeger() | list(0|1) | {Unused,binary()} | bitstring()
-check_bitstring(_, asn1_DEFAULT) ->
- true;
check_bitstring(DefVal, {Unused,Binary}) ->
%% User value in compact format.
Sz = bit_size(Binary) - Unused,
@@ -62,7 +60,7 @@ check_bitstring(DefVal, {Unused,Binary}) ->
check_bitstring(DefVal, Val);
check_bitstring(DefVal, Val) when is_bitstring(Val) ->
case Val =:= DefVal of
- false -> throw(error);
+ false -> throw(false);
true -> true
end;
check_bitstring(Def, Val) when is_list(Val) ->
@@ -75,178 +73,95 @@ check_bitstring_list(<<H:1,T1/bitstring>>, [H|T2]) ->
check_bitstring_list(<<>>, []) ->
true;
check_bitstring_list(_, _) ->
- throw(error).
+ throw(false).
check_bitstring_integer(<<H:1,T1/bitstring>>, Int) when H =:= Int band 1 ->
check_bitstring_integer(T1, Int bsr 1);
check_bitstring_integer(<<>>, 0) ->
true;
check_bitstring_integer(_, _) ->
- throw(error).
-
-check_named_bitstring(_, asn1_DEFAULT, _) ->
- true;
-check_named_bitstring(V, V, _) ->
- true;
-%% Default value and user value as lists of ones and zeros
-check_named_bitstring(L1=[H1|_T1], L2=[H2|_T2], NBL=[_H|_T]) when is_integer(H1), is_integer(H2) ->
- L2new = remove_trailing_zeros(L2),
- check_named_bitstring(L1, L2new, NBL);
-%% Default value as a list of 1 and 0 and user value as a list of atoms
-check_named_bitstring(L1=[H1|_T1], L2=[H2|_T2], NBL) when is_integer(H1), is_atom(H2) ->
- L3 = bit_list_to_nbl(L1, NBL, 0, []),
- check_named_bitstring(L3, L2, NBL);
-%% Both default value and user value as a list of atoms
-check_named_bitstring(L1=[H1|T1], L2=[H2|_T2], _)
- when is_atom(H1), is_atom(H2), length(L1) =:= length(L2) ->
- case lists:member(H1, L2) of
- true ->
- check_bitstring1(T1, L2);
- false -> throw({error,L2})
- end;
-%% Default value as a list of atoms and user value as a list of 1 and 0
-check_named_bitstring(L1=[H1|_T1], L2=[H2|_T2], NBL) when is_atom(H1), is_integer(H2) ->
- L3 = bit_list_to_nbl(L2, NBL, 0, []),
- check_named_bitstring(L1, L3, NBL);
-%% User value in compact format
-check_named_bitstring(DefVal,CBS={_,_}, NBL) ->
- NewVal = cbs_to_bit_list(CBS),
- check_named_bitstring(DefVal, NewVal, NBL);
-%% User value as a binary
-check_named_bitstring(DefVal, CBS, NBL) when is_binary(CBS) ->
- NewVal = cbs_to_bit_list({0,CBS}),
- check_named_bitstring(DefVal, NewVal, NBL);
-%% User value as a bitstring
-check_named_bitstring(DefVal, CBS, NBL) when is_bitstring(CBS) ->
- BitSize = bit_size(CBS),
- Unused = 8 - (BitSize band 7),
- NewVal = cbs_to_bit_list({Unused,<<CBS:BitSize/bits,0:Unused>>}),
- check_named_bitstring(DefVal, NewVal, NBL);
-check_named_bitstring(DV, V, _) ->
- throw({error,DV,V}).
-
-int_to_bit_list(0, Acc, 0) ->
- Acc;
-int_to_bit_list(Int, Acc, Len) when Len > 0 ->
- int_to_bit_list(Int bsr 1, [Int band 1|Acc], Len - 1).
-
-bit_list_to_nbl([0|T], NBL, Pos, Acc) ->
- bit_list_to_nbl(T, NBL, Pos+1, Acc);
-bit_list_to_nbl([1|T], NBL, Pos, Acc) ->
- case lists:keyfind(Pos, 2, NBL) of
- {N,_} ->
- bit_list_to_nbl(T, NBL, Pos+1, [N|Acc]);
+ throw(false).
+
+check_legacy_named_bitstring([Int|_]=Val, Bs, BsSize) when is_integer(Int) ->
+ check_named_bitstring(<< <<B:1>> || B <- Val >>, Bs, BsSize);
+check_legacy_named_bitstring({Unused,Val0}, Bs, BsSize) ->
+ Sz = bit_size(Val0) - Unused,
+ <<Val:Sz/bits,_/bits>> = Val0,
+ check_named_bitstring(Val, Bs, BsSize);
+check_legacy_named_bitstring(Val, Bs, BsSize) when is_integer(Val) ->
+ L = legacy_int_to_bitlist(Val),
+ check_named_bitstring(<< <<B:1>> || B <- L >>, Bs, BsSize);
+check_legacy_named_bitstring(Val, Bs, BsSize) ->
+ check_named_bitstring(Val, Bs, BsSize).
+
+check_legacy_named_bitstring([Int|_]=Val, Names, Bs, BsSize) when is_integer(Int) ->
+ check_named_bitstring(<< <<B:1>> || B <- Val >>, Names, Bs, BsSize);
+check_legacy_named_bitstring({Unused,Val0}, Names, Bs, BsSize) ->
+ Sz = bit_size(Val0) - Unused,
+ <<Val:Sz/bits,_/bits>> = Val0,
+ check_named_bitstring(Val, Names, Bs, BsSize);
+check_legacy_named_bitstring(Val, Names, Bs, BsSize) when is_integer(Val) ->
+ L = legacy_int_to_bitlist(Val),
+ check_named_bitstring(<< <<B:1>> || B <- L >>, Names, Bs, BsSize);
+check_legacy_named_bitstring(Val, Names, Bs, BsSize) ->
+ check_named_bitstring(Val, Names, Bs, BsSize).
+
+legacy_int_to_bitlist(0) ->
+ [];
+legacy_int_to_bitlist(Int) ->
+ [Int band 1|legacy_int_to_bitlist(Int bsr 1)].
+
+check_named_bitstring(Bs, Bs, _) ->
+ true;
+check_named_bitstring(Val, Bs, BsSize) ->
+ Rest = bit_size(Val) - BsSize,
+ case Val of
+ <<Bs:BsSize/bits,0:Rest>> ->
+ true;
_ ->
- throw({error,{no,named,element,at,pos,Pos}})
- end;
-bit_list_to_nbl([], _, _, Acc) ->
- Acc.
-
-remove_trailing_zeros(L2) ->
- remove_trailing_zeros1(lists:reverse(L2)).
-remove_trailing_zeros1(L) ->
- lists:reverse(lists:dropwhile(fun(0)->true;
- (_) ->false
- end,
- L)).
-
-check_bitstring1([H|T], NBL) ->
- case lists:member(H, NBL) of
- true -> check_bitstring1(T, NBL);
- V -> throw({error,V})
- end;
-check_bitstring1([], _) ->
- true.
-
-cbs_to_bit_list({Unused, <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Rest/binary>>}) when byte_size(Rest) >= 1 ->
- [B7,B6,B5,B4,B3,B2,B1,B0|cbs_to_bit_list({Unused,Rest})];
-cbs_to_bit_list({0,<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1>>}) ->
- [B7,B6,B5,B4,B3,B2,B1,B0];
-cbs_to_bit_list({Unused,Bin}) when byte_size(Bin) =:= 1 ->
- Used = 8-Unused,
- <<Int:Used,_:Unused>> = Bin,
- int_to_bit_list(Int, [], Used).
-
+ throw(false)
+ end.
-check_octetstring(_, asn1_DEFAULT) ->
- true;
-check_octetstring(L, L) ->
- true;
-check_octetstring(L, Int) when is_list(L), is_integer(Int) ->
- case integer_to_octetlist(Int) of
- L -> true;
- V -> throw({error,V})
+check_named_bitstring([_|_]=Val, Names, _, _) ->
+ case lists:sort(Val) of
+ Names -> true;
+ _ -> throw(false)
end;
-check_octetstring(_, V) ->
- throw({error,V}).
-
-integer_to_octetlist(Int) ->
- integer_to_octetlist(Int, []).
-integer_to_octetlist(0, Acc) ->
- Acc;
-integer_to_octetlist(Int, Acc) ->
- integer_to_octetlist(Int bsr 8, [(Int band 255)|Acc]).
-
-check_null(_, asn1_DEFAULT) ->
+check_named_bitstring(Bs, _, Bs, _) ->
true;
-check_null('NULL', 'NULL') ->
- true;
-check_null(_, V) ->
- throw({error,V}).
+check_named_bitstring(Val, _, Bs, BsSize) ->
+ Rest = bit_size(Val) - BsSize,
+ case Val of
+ <<Bs:BsSize/bits,0:Rest>> ->
+ true;
+ _ ->
+ throw(false)
+ end.
-check_objectidentifier(_, asn1_DEFAULT) ->
- true;
-check_objectidentifier(OI, OI) ->
+check_octetstring(V, V) ->
true;
-check_objectidentifier(DOI, OI) when is_tuple(DOI), is_tuple(OI) ->
- check_objectidentifier1(tuple_to_list(DOI), tuple_to_list(OI));
-check_objectidentifier(_, OI) ->
- throw({error,OI}).
-
-check_objectidentifier1([V|Rest1], [V|Rest2]) ->
- check_objectidentifier1(Rest1, Rest2, V);
-check_objectidentifier1([V1|Rest1], [V2|Rest2]) ->
- case reserved_objectid(V2, []) of
- V1 ->
- check_objectidentifier1(Rest1, Rest2, [V1]);
- V ->
- throw({error,V})
- end.
-check_objectidentifier1([V|Rest1], [V|Rest2], Above) ->
- check_objectidentifier1(Rest1, Rest2, [V|Above]);
-check_objectidentifier1([V1|Rest1], [V2|Rest2], Above) ->
- case reserved_objectid(V2, Above) of
- V1 ->
- check_objectidentifier1(Rest1, Rest2, [V1|Above]);
- V ->
- throw({error,V})
+check_octetstring(V, Def) when is_list(V) ->
+ case list_to_binary(V) of
+ Def -> true;
+ _ -> throw(false)
+ end;
+check_octetstring(_, _) ->
+ throw(false).
+
+check_objectidentifier(Value, {Prefix,Tail}) when is_tuple(Value) ->
+ check_oid(tuple_to_list(Value), Prefix, Tail);
+check_objectidentifier(_, _) ->
+ throw(false).
+
+check_oid([H|T], [K|Ks], Tail) ->
+ case lists:member(H, K) of
+ false -> throw(false);
+ true -> check_oid(T, Ks, Tail)
end;
-check_objectidentifier1([], [], _) ->
+check_oid(Tail, [], Tail) ->
true;
-check_objectidentifier1(_, V, _) ->
- throw({error,object,identifier,V}).
-
-%% ITU-T Rec. X.680 Annex B - D
-reserved_objectid('itu-t', []) -> 0;
-reserved_objectid('ccitt', []) -> 0;
-%% arcs below "itu-t"
-reserved_objectid('recommendation', [0]) -> 0;
-reserved_objectid('question', [0]) -> 1;
-reserved_objectid('administration', [0]) -> 2;
-reserved_objectid('network-operator', [0]) -> 3;
-reserved_objectid('identified-organization', [0]) -> 4;
-
-reserved_objectid(iso, []) -> 1;
-%% arcs below "iso", note that number 1 is not used
-reserved_objectid('standard', [1]) -> 0;
-reserved_objectid('member-body', [1]) -> 2;
-reserved_objectid('identified-organization', [1]) -> 3;
-
-reserved_objectid('joint-iso-itu-t', []) -> 2;
-reserved_objectid('joint-iso-ccitt', []) -> 2;
-
-reserved_objectid(_, _) -> false.
-
+check_oid(_, _, _) ->
+ throw(false).
check_objectdescriptor(_, asn1_DEFAULT) ->
true;
@@ -262,21 +177,6 @@ check_real(R, R) ->
check_real(_, _) ->
throw({error,{not_implemented_yet,check_real}}).
-check_enum(_, asn1_DEFAULT, _) ->
- true;
-check_enum(Val, Val, _) ->
- true;
-check_enum(Int, Atom, Enumerations) when is_integer(Int), is_atom(Atom) ->
- case lists:keyfind(Atom, 1, Enumerations) of
- {_,Int} -> true;
- _ -> throw({error,{enumerated,Int,Atom}})
- end;
-check_enum(DefVal, Val, _) ->
- throw({error,{enumerated,DefVal,Val}}).
-
-
-check_restrictedstring(_, asn1_DEFAULT) ->
- true;
check_restrictedstring(Val, Val) ->
true;
check_restrictedstring([V|Rest1], [V|Rest2]) ->
@@ -295,7 +195,15 @@ check_restrictedstring({V1,V2,V3,V4}, [V1,V2,V3,V4]) ->
check_restrictedstring([V1,V2,V3,V4], {V1,V2,V3,V4}) ->
true;
%% character string list
-check_restrictedstring(V1, V2) when is_list(V1), is_tuple(V2) ->
- check_restrictedstring(V1, tuple_to_list(V2));
-check_restrictedstring(V1, V2) ->
- throw({error,{restricted,string,V1,V2}}).
+check_restrictedstring(V1, V2) when is_tuple(V1) ->
+ check_restrictedstring(tuple_to_list(V1), V2);
+check_restrictedstring(_, _) ->
+ throw(false).
+
+check_literal_sof(Value, Default) ->
+ case lists:sort(Value) of
+ Default ->
+ true;
+ _ ->
+ throw(false)
+ end.
diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl
index 71fec411a0..0290c75a28 100644
--- a/lib/asn1/src/asn1rtt_per_common.erl
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -30,6 +30,7 @@
decode_big_chars/2,
decode_oid/1,decode_relative_oid/1,
encode_chars/2,encode_chars/3,
+ encode_chars_compact_map/3,
encode_chars_16bit/1,encode_big_chars/1,
encode_fragmented/2,
encode_oid/1,encode_relative_oid/1,
@@ -108,6 +109,9 @@ encode_chars(Val, NumBits) ->
encode_chars(Val, NumBits, {Lb,Tab}) ->
<< <<(enc_char(C, Lb, Tab)):NumBits>> || C <- Val >>.
+encode_chars_compact_map(Val, NumBits, {Lb,Limit}) ->
+ << <<(enc_char_cm(C, Lb, Limit)):NumBits>> || C <- Val >>.
+
encode_chars_16bit(Val) ->
L = [case C of
{0,0,A,B} -> [A,B];
@@ -383,6 +387,15 @@ enc_char(C0, Lb, Tab) ->
illegal_char_error()
end.
+enc_char_cm(C0, Lb, Limit) ->
+ C = C0 - Lb,
+ if
+ 0 =< C, C < Limit ->
+ C;
+ true ->
+ illegal_char_error()
+ end.
+
illegal_char_error() ->
error({error,{asn1,"value forbidden by FROM constraint"}}).
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index 782217ed2d..11d1b82fb4 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -50,13 +50,14 @@ all() ->
{group, performance}].
groups() ->
- [{compile, parallel([]),
+ Parallel = asn1_test_lib:parallel(),
+ [{compile, Parallel,
[c_syntax,
c_string,
c_implicit_before_choice,
constraint_equivalence]},
- {ber, parallel([]),
+ {ber, Parallel,
[ber_choiceinseq,
% Uses 'SOpttest'
ber_optional]},
@@ -65,7 +66,7 @@ groups() ->
{appup_test, [], [{asn1_appup_test, all}]},
- {parallel, parallel([]),
+ {parallel, Parallel,
[cover,
xref,
{group, ber},
@@ -173,13 +174,6 @@ groups() ->
testTimer_per,
testTimer_uper]}].
-parallel(Options) ->
- case erlang:system_info(smp_support) andalso
- erlang:system_info(schedulers) > 1 of
- true -> [parallel|Options];
- false -> Options
- end.
-
%%------------------------------------------------------------------------------
%% Init/end
%%------------------------------------------------------------------------------
@@ -428,14 +422,12 @@ testMultipleLevels(Config, Rule, Opts) ->
asn1_test_lib:compile("MultipleLevels", Config, [Rule|Opts]),
testMultipleLevels:main(Rule).
-testDef(Config) -> test(Config, fun testDef/3).
-testDef(Config, Rule, Opts) ->
- asn1_test_lib:compile("Def", Config, [Rule|Opts]),
- testDef:main(Rule).
-
testDEFAULT(Config) ->
test(Config, fun testDEFAULT/3, [ber,{ber,[der]},per,uper]).
testDEFAULT(Config, Rule, Opts) ->
+ asn1_test_lib:compile_all(["Def","Default"], Config, [Rule|Opts]),
+ testDef:main(Rule),
+ testSeqSetDefaultVal:main(Rule, Opts),
asn1_test_lib:compile_all(["Def","Default"], Config,
[legacy_erlang_types,Rule|Opts]),
testDef:main(Rule),
diff --git a/lib/asn1/test/asn1_SUITE_data/Constraints.py b/lib/asn1/test/asn1_SUITE_data/Constraints.py
index c3b3aebd6d..3495cd841b 100644
--- a/lib/asn1/test/asn1_SUITE_data/Constraints.py
+++ b/lib/asn1/test/asn1_SUITE_data/Constraints.py
@@ -16,6 +16,7 @@ SemiConstrained ::= INTEGER (100..MAX)
NegSemiConstrained ::= INTEGER (-128..MAX)
SemiConstrainedExt ::= INTEGER (42..MAX, ...)
NegSemiConstrainedExt ::= INTEGER (-128..MAX, ...)
+SemiNamed ::= INTEGER {a(100), b(200)} (100..MAX)
-- Extensions --
LongLongExt ::= INTEGER (0..18446744073709551615, ..., -5000..-1)
Range256to65536Ext ::= INTEGER (256..65536, ..., 1000000..9000000)
@@ -65,10 +66,12 @@ Wednesday ::= Day(wednesday)
Thing ::= INTEGER {fred (0),fred2 (1),fred3 (2)}
-
-
AnotherThing ::= Thing (fred | fred2)
+OneMoreThing ::= INTEGER {wilma(0), fred(1), betty(3), barney(2)}
+OneMoreThing-1 ::= OneMoreThing (wilma | fred)
+OneMoreThing-2 ::= OneMoreThing (fred | barney)
+
I ::= INTEGER (0|15..269) -- OTP-5457
X1 ::= INTEGER (1..4 | 8 | 10 | 20) -- OTP-9946
diff --git a/lib/asn1/test/asn1_SUITE_data/Default.asn b/lib/asn1/test/asn1_SUITE_data/Default.asn
index 168ce50bb2..b91660381a 100644
--- a/lib/asn1/test/asn1_SUITE_data/Default.asn
+++ b/lib/asn1/test/asn1_SUITE_data/Default.asn
@@ -25,6 +25,10 @@ SeqBS ::= SEQUENCE {
e BIT STRING DEFAULT '01011010'B
}
+SeqBS2 ::= SEQUENCE {
+ bs BIT STRING {a(0), z(25)} DEFAULT '101'B
+}
+
SetBS ::= SET {
a BIT STRING DEFAULT '1010110'B,
b BIT STRING DEFAULT 'A8A'H,
@@ -156,4 +160,23 @@ four INTEGER ::= 4
cr IA5String ::= {0,13}
+SeqNamedInts ::= SEQUENCE {
+ i1 INTEGER {first(0), last(31)} DEFAULT 15,
+ i2 INTEGER {first(0), last(31)} DEFAULT 31
+}
+
+S5 ::= SEQUENCE {
+ s3 S3 DEFAULT {},
+ so SEQUENCE OF OBJECT IDENTIFIER DEFAULT {
+ {itu-t question 999},
+ {itu-t question 555}
+ },
+ soe SEQUENCE OF OBJECT IDENTIFIER DEFAULT { }
+}
+
+SOI ::= SEQUENCE {
+ soi SEQUENCE OF OBJECT IDENTIFIER
+ DEFAULT { {iso member-body f(250) 9 55}, {iso member-body f(250) 3 4} }
+}
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/Set.py b/lib/asn1/test/asn1_SUITE_data/Set.py
index 4062f6b804..3928004e6b 100644
--- a/lib/asn1/test/asn1_SUITE_data/Set.py
+++ b/lib/asn1/test/asn1_SUITE_data/Set.py
@@ -80,8 +80,8 @@ SetOpt3 ::= SET
SetIn ::= SET
{
- boolIn BOOLEAN,
- intIn INTEGER
+ boolIn BOOLEAN OPTIONAL,
+ intIn INTEGER OPTIONAL
}
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl
index 1225e36778..d800846b3f 100644
--- a/lib/asn1/test/asn1_app_test.erl
+++ b/lib/asn1/test/asn1_app_test.erl
@@ -134,13 +134,13 @@ get_ebin_mods(App) ->
check_asn1ct_modules(Extra) ->
ASN1CTMods = [asn1ct,asn1ct_check,asn1_db,asn1ct_pretty_format,
- asn1ct_gen,asn1ct_gen_per,asn1ct_gen_per_rt2ct,
+ asn1ct_gen,asn1ct_gen_check,asn1ct_gen_per,
asn1ct_name,asn1ct_constructed_per,asn1ct_constructed_ber,
asn1ct_gen_ber,asn1ct_constructed_ber_bin_v2,
asn1ct_gen_ber_bin_v2,asn1ct_value,
asn1ct_tok,asn1ct_parser2,asn1ct_table,
asn1ct_imm,asn1ct_func,asn1ct_rtt,
- asn1ct_eval_ext,asn1ct_eval_per,asn1ct_eval_uper],
+ asn1ct_eval_ext],
case Extra -- ASN1CTMods of
[] ->
ok;
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
index 417380159e..06e9b2c093 100644
--- a/lib/asn1/test/asn1_test_lib.erl
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -21,19 +21,72 @@
-export([compile/3,compile_all/3,compile_erlang/3,
hex_to_bin/1,
+ parallel/0,
roundtrip/3,roundtrip/4,roundtrip_enc/3,roundtrip_enc/4]).
-include_lib("test_server/include/test_server.hrl").
+run_dialyzer() ->
+ false.
+
compile(File, Config, Options) -> compile_all([File], Config, Options).
compile_all(Files, Config, Options) ->
DataDir = ?config(data_dir, Config),
CaseDir = ?config(case_dir, Config),
- [compile_file(filename:join(DataDir, F), [{outdir, CaseDir}|Options])
+ [compile_file(filename:join(DataDir, F), [{outdir, CaseDir},
+ debug_info|Options])
|| F <- Files],
+ dialyze(Files, Options),
ok.
+parallel() ->
+ case erlang:system_info(schedulers) > 1 andalso not run_dialyzer() of
+ true -> [parallel];
+ false -> []
+ end.
+
+dialyze(Files, Options) ->
+ case not run_dialyzer() orelse lists:member(abs, Options) of
+ true -> ok;
+ false -> dialyze(Files)
+ end.
+
+dialyze(Files) ->
+ Beams0 = [code:which(module(F)) || F <- Files],
+ Beams = [code:which(asn1rt_nif)|Beams0],
+ case dialyzer:run([{files,Beams},
+ {warnings,[no_improper_lists]},
+ {get_warnings,true}]) of
+ [] ->
+ ok;
+ [_|_]=Ws ->
+ io:put_chars([[B,$\n] || B <- Beams]),
+ io:put_chars([dialyzer:format_warning(W) || W <- Ws]),
+ error(dialyzer_warnings)
+ end.
+
+module(F0) ->
+ F1 = filename:basename(F0),
+ F2 = case filename:extension(F1) of
+ ".asn" ->
+ filename:rootname(F1);
+ ".asn1" ->
+ filename:rootname(F1);
+ ".py" ->
+ filename:rootname(F1);
+ "" ->
+ F1
+ end,
+ F = case filename:extension(F2) of
+ ".set" ->
+ filename:rootname(F2);
+ "" ->
+ F2
+ end,
+ list_to_atom(F).
+%% filename:join(CaseDir, F ++ ".beam").
+
compile_file(File, Options) ->
try
ok = asn1ct:compile(File, [warnings_as_errors|Options])
diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl
index 57cb483374..e37e22163a 100644
--- a/lib/asn1/test/testNBAPsystem.erl
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -79,13 +79,14 @@ powerRaiseLimit, dLPowerAveragingWindowSize, 'iE-Extensions' = asn1_NOVALUE}).
compile(Config, Options) ->
- [asn1_test_lib:compile(filename:join([nbapsystem, M]), Config, Options)
- || M <- ["NBAP-CommonDataTypes.asn",
- "NBAP-IEs.asn",
- "NBAP-PDU-Contents.asn",
- "NBAP-PDU-Discriptions.asn",
- "NBAP-Constants.asn",
- "NBAP-Containers.asn"]],
+ Fs = [filename:join("nbapsystem", M) ||
+ M <- ["NBAP-CommonDataTypes.asn",
+ "NBAP-IEs.asn",
+ "NBAP-PDU-Contents.asn",
+ "NBAP-PDU-Discriptions.asn",
+ "NBAP-Constants.asn",
+ "NBAP-Containers.asn"]],
+ asn1_test_lib:compile_all(Fs, Config, Options),
ok.
diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl
index 79992a0a94..c3d9ce33b7 100644
--- a/lib/asn1/test/testSeqSetDefaultVal.erl
+++ b/lib/asn1/test/testSeqSetDefaultVal.erl
@@ -36,6 +36,7 @@
c = asn1_DEFAULT,
d = asn1_DEFAULT,
e = asn1_DEFAULT}).
+-record('SeqBS2',{bs = asn1_DEFAULT}).
-record('SetBS',{a = asn1_DEFAULT,
b = asn1_DEFAULT,
c = asn1_DEFAULT,
@@ -93,6 +94,13 @@
b = asn1_DEFAULT}).
-record('S4_b',{ba = asn1_DEFAULT,
bb = asn1_DEFAULT}).
+-record('SeqNamedInts',
+ {i1 = asn1_DEFAULT,
+ i2 = asn1_DEFAULT}).
+-record('S5',{s3 = asn1_DEFAULT,
+ so = asn1_DEFAULT,
+ soe = asn1_DEFAULT}).
+-record('SOI', {soi = asn1_DEFAULT}).
main(ber, []) ->
%% Nothing to test because plain BER will only use
@@ -105,7 +113,11 @@ main(Rule, Opts) ->
case {Rule,Opts} of
{ber,[der]} ->
- der();
+ der(),
+ case 'Default':legacy_erlang_types() of
+ false -> der_new_types();
+ true -> der_legacy()
+ end;
{_,_} ->
ok
end,
@@ -118,45 +130,45 @@ main(Rule, Opts) ->
{#'SeqBS'{},
[{#'SeqBS'.a,
- [asn1_DEFAULT,
- 2#0110101,
+ [asn1_DEFAULT, %Always.
+ <<1:1,0:1,1:1,0:1,1:1,1:1,0:1>>],
+ [2#0110101, %Legacy only.
[1,0,1,0,1,1,0],
- {1,<<16#AC>>},
- <<1:1,0:1,1:1,0:1,1:1,1:1,0:1>>]},
+ {1,<<16#AC>>}]},
{#'SeqBS'.b,
[asn1_DEFAULT,
- 2#10100010101,
+ <<16#A8:8,16#A:4>>],
+ [2#10100010101,
[1,0,1,0,1,0,0,0,1,0,1,0],
- {4,<<16#A8,16#A0>>},
- <<16#A8:8,16#A:4>>]},
+ {4,<<16#A8,16#A0>>}]},
{#'SeqBS'.c,
[asn1_DEFAULT,
[second],
- [0,1],
- {6,<<0:1,1:1,0:6>>},
- <<1:2>>]},
+ <<1:2>>],
+ [[0,1],
+ {6,<<0:1,1:1,0:6>>}]},
{#'SeqBS'.c, %Zeroes on the right
[asn1_DEFAULT,
[second],
- [0,1,0,0,0],
- {4,<<0:1,1:1,0:6>>},
- <<1:2,0:17>>]},
+ <<1:2,0:17>>],
+ [[0,1,0,0,0],
+ {4,<<0:1,1:1,0:6>>}]},
{#'SeqBS'.d,
[asn1_DEFAULT,
- 2#1001,
+ <<2#1001:4>>],
+ [2#1001,
[1,0,0,1],
- {4,<<2#1001:4,0:4>>},
- <<2#1001:4>>]},
+ {4,<<2#1001:4,0:4>>}]},
{#'SeqBS'.e,
[asn1_DEFAULT,
- [0,1,0,1,1,0,1,0],
- {0,<<2#01011010:8>>},
- <<2#01011010:8>>]},
+ <<2#01011010:8>>],
+ [[0,1,0,1,1,0,1,0],
+ {0,<<2#01011010:8>>}]},
%% Not EQUAL to DEFAULT.
{#'SeqBS'.b,
+ [<<6:3>>],
[[1,1,0], %Not equal to DEFAULT
- {5,<<6:3,0:5>>},
- <<6:3>>]}
+ {5,<<6:3,0:5>>}]}
]},
{#'SeqOS'{},
@@ -170,15 +182,14 @@ main(Rule, Opts) ->
{1,2,14,15}]},
{#'SeqOI'.b,
[asn1_DEFAULT,
-%% {iso,'member-body',250,3,4},
+ %% {iso,'member-body',250,3,4},
{1,2,250,3,4}]},
{#'SeqOI'.c,
[asn1_DEFAULT,
-%% {iso,standard,8571,2,250,4},
+ %% {iso,standard,8571,2,250,4},
{1,0,8571,2,250,4}]}]}
],
- io:format("~p\n", [Ts]),
- R0 = [[consistency(Rec, Pos, Vs) || {Pos,Vs} <- Fs] || {Rec,Fs} <- Ts],
+ R0 = [[consistency(Rec, PosVs) || PosVs <- Fs] || {Rec,Fs} <- Ts],
case lists:flatten(R0) of
[] ->
ok;
@@ -187,8 +198,20 @@ main(Rule, Opts) ->
?t:fail()
end.
-consistency(Rec0, Pos, [V|Vs]) ->
+legacy_filter({_,_}=Keep) ->
+ Keep;
+legacy_filter({Rec,Standard,Legacy}) ->
+ case 'Default':legacy_erlang_types() of
+ false ->
+ {Rec,Standard};
+ true ->
+ {Rec,Standard++Legacy}
+ end.
+
+consistency(Rec0, PosVs) ->
+ {Pos,[V|Vs]=AllVs} = legacy_filter(PosVs),
T = element(1, Rec0),
+ io:format("~p: ~p\n", [T,AllVs]),
Rec = setelement(Pos, Rec0, V),
{ok,Enc} = 'Default':encode(T, Rec),
{ok,_SmokeTest} = 'Default':decode(T, Enc),
@@ -206,7 +229,7 @@ consistency_1([V|Vs], Rec0, Pos, Enc) ->
consistency_1([], _, _, _) -> [].
der() ->
- io:put_chars("Peforming DER-specific tests..."),
+ io:put_chars("Performing DER-specific tests..."),
roundtrip(<<48,0>>,
'SeqInts',
#'SeqInts'{a=asn1_DEFAULT,b=asn1_DEFAULT,
@@ -227,98 +250,6 @@ der() ->
#'SetInts'{a=1,b=-1,c=three,d=1},
#'SetInts'{a=1,b=-1,c=3,d=1}),
-
- roundtrip(<<48,0>>,
- 'SeqBS',
- #'SeqBS'{a=2#0110101,
- b=2#010100010101,
- c=[second],
- d=[1,0,0,1]},
- #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<2#1001:4>>,
- e = <<2#01011010:8>>}),
- roundtrip(<<48,0>>,
- 'SeqBS',
- #'SeqBS'{a=[1,0,1,0,1,1,0],
- b=[1,0,1,0,1,0,0,0,1,0,1,0],
- c={5,<<64>>},
- d=2#1001},
- #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<2#1001:4>>,
- e = <<2#01011010:8>>}),
- roundtrip(<<48,3,131,1,0>>,
- 'SeqBS',
- #'SeqBS'{a=[1,0,1,0,1,1,0],
- b=[1,0,1,0,1,0,0,0,1,0,1,0],
- c={5,<<64>>},
- d=0},
- #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<>>,
- e = <<2#01011010:8>>}),
- roundtrip(<<48,3,131,1,0>>,
- 'SeqBS',
- #'SeqBS'{a = <<1:1,0:1,1:1,0:1,1:1,1:1,0:1>>,
- b = <<1:1,0:1,1:1,0:1,1:1,0:1,0:1,0:1,1:1,0:1,1:1,0:1>>,
- c = <<2:3>>,
- d=0,
- e = <<16#5A:8>>},
- #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<>>,
- e = <<2#01011010:8>>}),
-
- %% None of the default values are used.
- roundtrip(<<48,19,128,2,7,128,129,2,5,64,130,2,5,32,131,1,0,132,2,5,224>>,
- 'SeqBS',
- #'SeqBS'{a = <<1:1>>,
- b = {5,<<64>>},
- c = [third],
- d = 0,
- e = <<7:3>>},
- #'SeqBS'{a = <<1:1>>,
- b = <<2:3>>,
- c = [third],
- d = <<>>,
- e = <<7:3>>}),
-
- roundtrip(<<49,0>>,
- 'SetBS',
- #'SetBS'{a=2#0110101,
- b=2#010100010101,
- c=[second],
- d=[1,0,0,1]},
- #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<2#1001:4>>}),
- roundtrip(<<49,0>>,
- 'SetBS',
- #'SetBS'{a=[1,0,1,0,1,1,0],
- b=[1,0,1,0,1,0,0,0,1,0,1,0],
- c={5,<<64>>},
- d=9},
- #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<2#1001:4>>}),
- roundtrip(<<49,3,131,1,0>>,
- 'SetBS',
- #'SetBS'{a=[1,0,1,0,1,1,0],
- b=[1,0,1,0,1,0,0,0,1,0,1,0],
- c={5,<<64>>},
- d=0},
- #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<>>}),
- roundtrip(<<49,3,131,1,0>>,
- 'SetBS',
- #'SetBS'{a = <<1:1,0:1,1:1,0:1,1:1,1:1,0:1>>,
- b = <<1:1,0:1,1:1,0:1,1:1,0:1,0:1,0:1,1:1,0:1,1:1,0:1>>,
- c = <<2:3>>,
- d=0},
- #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
- c=[second], d = <<>>}),
-
- roundtrip(<<48,0>>, 'SeqOS',
- #'SeqOS'{a = <<172>>,b = <<16#A8,16#A0>>,c='NULL'}),
-
- roundtrip(<<49,0>>, 'SetOS',
- #'SetOS'{a = <<172>>,b = <<16#A8,16#A0>>,c='NULL'}),
-
roundtrip(<<48,0>>,
'SeqOI',
#'SeqOI'{a={1,2,14,15},
@@ -443,6 +374,184 @@ der() ->
#'S4'{a=#'S2'{a=1,b=asn1_NOVALUE},b=#'S4_b'{ba=true,bb=0}},
#'S4'{a=#'S2'{a=1,b=asn1_NOVALUE},b=#'S4_b'{ba=true,bb=0}}),
+ roundtrip(<<48,0>>,
+ 'SeqBS',
+ #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<2#1001:4>>,
+ e = <<2#01011010:8>>}),
+ roundtrip(<<49,0>>,
+ 'SetBS',
+ #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<2#1001:4>>}),
+
+ %% None of the default values are used.
+ roundtrip(<<48,19,128,2,7,128,129,2,5,64,130,2,5,32,131,1,0,132,2,5,224>>,
+ 'SeqBS',
+ #'SeqBS'{a = <<1:1>>,
+ b = <<2:3>>,
+ c = [third],
+ d = <<>>,
+ e = <<7:3>>}),
+ roundtrip(<<49,3,131,1,0>>,
+ 'SetBS',
+ #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<>>}),
+
+ %% SeqNamedInts
+ roundtrip(<<48,0>>,
+ 'SeqNamedInts',
+ #'SeqNamedInts'{i1=15,i2=31}),
+ roundtrip(<<48,0>>,
+ 'SeqNamedInts',
+ #'SeqNamedInts'{},
+ #'SeqNamedInts'{i1=15,i2=31}),
+ roundtrip(<<48,0>>,
+ 'SeqNamedInts',
+ #'SeqNamedInts'{i2=last},
+ #'SeqNamedInts'{i1=15,i2=31}),
+ roundtrip(<<48,3,128,1,0>>,
+ 'SeqNamedInts',
+ #'SeqNamedInts'{i1=first,i2=31},
+ #'SeqNamedInts'{i1=first,i2=31}),
+
+ %% S5
+ roundtrip(<<48,0>>,
+ 'S5',
+ #'S5'{s3=#'S3'{a=[11,12,13],
+ b=[{a,11},{b,true},{c,13}],
+ c=[1,2,3,4],
+ d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]},
+ so=[{0,1,999},{0,1,555}],
+ soe=[]}),
+ roundtrip(<<48,0>>,
+ 'S5',
+ #'S5'{},
+ #'S5'{s3=#'S3'{a=[11,12,13],
+ b=[{a,11},{b,true},{c,13}],
+ c=[1,2,3,4],
+ d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]},
+ so=[{0,1,999},{0,1,555}],
+ soe=[]}),
+
+ %% SOI
+ roundtrip(<<48,0>>,
+ 'SOI',
+ #'SOI'{},
+ #'SOI'{soi=[{1,2,250,9,55},{1,2,250,3,4}]}),
+
+ %% SeqBS2
+ roundtrip(<<48,0>>,
+ 'SeqBS2',
+ #'SeqBS2'{bs= <<16#5:3>>}),
+ roundtrip(<<48,0>>,
+ 'SeqBS2',
+ #'SeqBS2'{bs= <<16#5:3,0:4>>},
+ #'SeqBS2'{bs= <<16#5:3>>}),
+
+ ok.
+
+der_new_types() ->
+ io:put_chars("Performing DER-specific tests with new types..."),
+
+ roundtrip(<<48,0>>, 'SeqOS',
+ #'SeqOS'{a = <<172>>,b = <<16#A8,16#A0>>,c='NULL'}),
+
+ roundtrip(<<49,0>>, 'SetOS',
+ #'SetOS'{a = <<172>>,b = <<16#A8,16#A0>>,c='NULL'}),
+ ok.
+
+der_legacy() ->
+ io:put_chars("Performing DER-specific tests with legacy types..."),
+
+ roundtrip(<<48,0>>, 'SeqOS',
+ #'SeqOS'{a=[172],b=[16#A8,16#A0],c='NULL'}),
+ roundtrip(<<49,0>>, 'SetOS',
+ #'SetOS'{a=[172],b=[16#A8,16#A0],c='NULL'}),
+
+ roundtrip(<<48,0>>,
+ 'SeqBS',
+ #'SeqBS'{a=2#0110101,
+ b=2#010100010101,
+ c=[second],
+ d=[1,0,0,1]},
+ #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<2#1001:4>>,
+ e = <<2#01011010:8>>}),
+ roundtrip(<<48,0>>,
+ 'SeqBS',
+ #'SeqBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=2#1001},
+ #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<2#1001:4>>,
+ e = <<2#01011010:8>>}),
+ roundtrip(<<48,3,131,1,0>>,
+ 'SeqBS',
+ #'SeqBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=0},
+ #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<>>,
+ e = <<2#01011010:8>>}),
+ roundtrip(<<48,3,131,1,0>>,
+ 'SeqBS',
+ #'SeqBS'{a = <<1:1,0:1,1:1,0:1,1:1,1:1,0:1>>,
+ b = <<1:1,0:1,1:1,0:1,1:1,0:1,0:1,0:1,1:1,0:1,1:1,0:1>>,
+ c = <<2:3>>,
+ d=0,
+ e = <<16#5A:8>>},
+ #'SeqBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<>>,
+ e = <<2#01011010:8>>}),
+
+ %% None of the default values are used.
+ roundtrip(<<48,19,128,2,7,128,129,2,5,64,130,2,5,32,131,1,0,132,2,5,224>>,
+ 'SeqBS',
+ #'SeqBS'{a = <<1:1>>,
+ b = {5,<<64>>},
+ c = [third],
+ d = 0,
+ e = <<7:3>>},
+ #'SeqBS'{a = <<1:1>>,
+ b = <<2:3>>,
+ c = [third],
+ d = <<>>,
+ e = <<7:3>>}),
+ roundtrip(<<49,0>>,
+ 'SetBS',
+ #'SetBS'{a=2#0110101,
+ b=2#010100010101,
+ c=[second],
+ d=[1,0,0,1]},
+ #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<2#1001:4>>}),
+ roundtrip(<<49,0>>,
+ 'SetBS',
+ #'SetBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=9},
+ #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<2#1001:4>>}),
+ roundtrip(<<49,3,131,1,0>>,
+ 'SetBS',
+ #'SetBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=0},
+ #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<>>}),
+ roundtrip(<<49,3,131,1,0>>,
+ 'SetBS',
+ #'SetBS'{a = <<1:1,0:1,1:1,0:1,1:1,1:1,0:1>>,
+ b = <<1:1,0:1,1:1,0:1,1:1,0:1,0:1,0:1,1:1,0:1,1:1,0:1>>,
+ c = <<2:3>>,
+ d=0},
+ #'SetBS'{a = <<2#1010110:7>>, b = <<16#A8A:12>>,
+ c=[second], d = <<>>}),
+
ok.
roundtrip(Encoded, Type, Value) ->
diff --git a/lib/asn1/test/testTcapsystem.erl b/lib/asn1/test/testTcapsystem.erl
index 4979a385b2..fcc9e084e0 100644
--- a/lib/asn1/test/testTcapsystem.erl
+++ b/lib/asn1/test/testTcapsystem.erl
@@ -21,44 +21,42 @@
-export([compile/2]).
--include_lib("test_server/include/test_server.hrl").
-
compile(Config, Options) ->
- [asn1_test_lib:compile(filename:join([tcapsystem, M]), Config, Options)
- || M <- ["DialoguePDUs.asn",
- "MAP-ApplicationContexts.asn",
- "MAP-BS-Code.asn",
- "MAP-CallHandlingOperations.asn",
- "MAP-CH-DataTypes.asn",
- "MAP-CommonDataTypes.asn",
- "MAP-DialogueInformation.asn",
- "MAP-ER-DataTypes.asn",
- "MAP-Errors.asn",
- "MAP-ExtensionDataTypes.asn",
- "MAP-GR-DataTypes.asn",
- "MAP-Group-Call-Operations.asn",
- "MAP-LCS-DataTypes.asn",
- "MAP-LocationServiceOperations.asn",
- "MAP-MobileServiceOperations.asn",
- "MAP-MS-DataTypes.asn",
- "MAP-OM-DataTypes.asn",
- "MAP-OperationAndMaintenanceOperations.asn",
- "MAP-Protocol.asn",
- "MAP-SecureTransportOperations.asn",
- "MAP-ShortMessageServiceOperations.asn",
- "MAP-SM-DataTypes.asn",
- "MAP-SS-Code.asn",
- "MAP-SS-DataTypes.asn",
- "MAP-ST-DataTypes.asn",
- "MAP-SupplementaryServiceOperations.asn",
- "MAP-TS-Code.asn",
- "MobileDomainDefinitions.asn",
- "Remote-Operations-Generic-ROS-PDUs.asn",
- "Remote-Operations-Information-Objects.asn",
- "Remote-Operations-Useful-Definitions.asn",
- "TCAP-Examples.asn",
- "TCAPMessages.asn",
- "TCAP-Tools.asn",
- "TC-Notation-Extensions.asn",
- "UnidialoguePDUs.asn"]],
- ok.
+ Fs = [filename:join("tcapsystem", M) ||
+ M <- ["DialoguePDUs.asn",
+ "MAP-ApplicationContexts.asn",
+ "MAP-BS-Code.asn",
+ "MAP-CallHandlingOperations.asn",
+ "MAP-CH-DataTypes.asn",
+ "MAP-CommonDataTypes.asn",
+ "MAP-DialogueInformation.asn",
+ "MAP-ER-DataTypes.asn",
+ "MAP-Errors.asn",
+ "MAP-ExtensionDataTypes.asn",
+ "MAP-GR-DataTypes.asn",
+ "MAP-Group-Call-Operations.asn",
+ "MAP-LCS-DataTypes.asn",
+ "MAP-LocationServiceOperations.asn",
+ "MAP-MobileServiceOperations.asn",
+ "MAP-MS-DataTypes.asn",
+ "MAP-OM-DataTypes.asn",
+ "MAP-OperationAndMaintenanceOperations.asn",
+ "MAP-Protocol.asn",
+ "MAP-SecureTransportOperations.asn",
+ "MAP-ShortMessageServiceOperations.asn",
+ "MAP-SM-DataTypes.asn",
+ "MAP-SS-Code.asn",
+ "MAP-SS-DataTypes.asn",
+ "MAP-ST-DataTypes.asn",
+ "MAP-SupplementaryServiceOperations.asn",
+ "MAP-TS-Code.asn",
+ "MobileDomainDefinitions.asn",
+ "Remote-Operations-Generic-ROS-PDUs.asn",
+ "Remote-Operations-Information-Objects.asn",
+ "Remote-Operations-Useful-Definitions.asn",
+ "TCAP-Examples.asn",
+ "TCAPMessages.asn",
+ "TCAP-Tools.asn",
+ "TC-Notation-Extensions.asn",
+ "UnidialoguePDUs.asn"]],
+ asn1_test_lib:compile_all(Fs, Config, Options).
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index 1f16f31f6b..37c843204a 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1,2 +1,2 @@
#next version number to use is 2.0
-ASN1_VSN = 3.0
+ASN1_VSN = 3.0.1
diff --git a/lib/common_test/configure.in b/lib/common_test/configure.in
index b2e6ad997a..b2e6ad997a 100755..100644
--- a/lib/common_test/configure.in
+++ b/lib/common_test/configure.in
diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml
index a215c8c2f3..accb94e1a9 100644
--- a/lib/common_test/doc/src/cover_chapter.xml
+++ b/lib/common_test/doc/src/cover_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2013</year>
+ <year>2006</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -81,10 +81,7 @@
specify that previously exported data should be imported and
included in the analysis for a test (you can specify multiple
import files). This way it is possible to analyse total code coverage
- without necessarily running all tests at once. Note that even if
- you run separate tests in one test run, code coverage data will
- not be passed on from one test to another unless you specify an
- export file for Common Test to use for this purpose.</p>
+ without necessarily running all tests at once.</p>
<p>To activate the code coverage support, you simply specify the
name of the cover specification file as you start Common Test.
@@ -266,10 +263,20 @@ ct_cover:cross_cover_analyse(Level, [{s1,S1LogDir},{s2,S2LogDir}]).</code>
<section>
<title>Logging</title>
- <p>To view the result of a code coverage test, follow the
- "Coverage log" link on the test suite results page. This
- takes you to the code coverage overview page. If you have
- successfully performed a detailed coverage analysis, you
+ <p>To view the result of a code coverage test, click the button
+ labled "COVER LOG" in the top level index page for the test run.</p>
+
+ <p>Prior to Erlang/OTP 17.1, if your test run consisted of
+ multiple tests, cover would be started and stopped for each test
+ within the test run. Separate logs would be available via the
+ "Coverage log" link on the test suite result pages. These links
+ are still available, but now they all point to the same page as
+ the button on the top level index page. The log contains the
+ accumulated results for the complete test run. See the release
+ notes for more information about this change.</p>
+
+ <p>The buttonc takes you to the code coverage overview page. If you
+ have successfully performed a detailed coverage analysis, you
find links to each individual module coverage page here.</p>
<p>If cross cover analysis has been performed, and there are
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index ddfeb0964b..b53ba32e6c 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -32,6 +32,71 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Substrings in long telnet messages would sometimes get
+ wrongly reversed. This error has been corrected.</p>
+ <p>
+ Own Id: OTP-11871 Aux Id: seq12581 </p>
+ </item>
+ <item>
+ <p>
+ The basic_html logging mode in Common Test (for
+ compatibility with old browsers) generated HTML code with
+ unbalanced tags. This has been fixed.</p>
+ <p>
+ Own Id: OTP-11917 Aux Id: seq12598 </p>
+ </item>
+ <item>
+ <p>
+ The mechanism for running code cover analysis with
+ common_test has been improved. Earlier, if a test run
+ consisted of multiple tests, cover would be started and
+ stopped for each test. This would give "intermediate"
+ cover logs available from the "Coverage log" link on the
+ test suite result pages. To accumulate cover data over
+ all tests, the 'export' option had to be used in the
+ cover spec file. This was not well documented, and the
+ functionality was quite confusing.</p>
+ <p>
+ Using the 'nodes' option in the cover spec file would
+ fail when the test run consisted of multiple tests, since
+ the specified nodes would only be included in the cover
+ analysis of the first test.</p>
+ <p>
+ The repeated compilation and analysis of the same modules
+ was also very time consuming.</p>
+ <p>
+ To overcome these problems, ct will now only cover
+ compile and analyze modules once per test run, i.e. once
+ for each cover spec file. The log file is available via a
+ new button on the top level index page. The old "Coverage
+ log" links on the test suite result pages still exist,
+ but they all point to the same log containing the
+ accumulated result.</p>
+ <p>
+ Own Id: OTP-11971</p>
+ </item>
+ <item>
+ <p>
+ If multiple tests would run simultaneously on different
+ Erlang nodes, writing their logs to the same directory,
+ then there would often be entries in the all_runs.html
+ log file showing incomplete results (all zeroes) upon
+ completion. This problem was caused by a bug in the
+ Common Test log cache mechanism, which has been fixed.</p>
+ <p>
+ Own Id: OTP-11988 Aux Id: seq12611 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/priv/run_test.in b/lib/common_test/priv/run_test.in
index 1508751e4f..1508751e4f 100755..100644
--- a/lib/common_test/priv/run_test.in
+++ b/lib/common_test/priv/run_test.in
diff --git a/lib/common_test/src/ct_cover.erl b/lib/common_test/src/ct_cover.erl
index ae671c750a..cf2860ae25 100644
--- a/lib/common_test/src/ct_cover.erl
+++ b/lib/common_test/src/ct_cover.erl
@@ -47,18 +47,21 @@ add_nodes(Nodes) ->
undefined ->
{error,cover_not_running};
_ ->
- {File,Nodes0,Import,Export,AppInfo} = ct_util:get_testdata(cover),
+ Nodes0 = cover:which_nodes(),
Nodes1 = [Node || Node <- Nodes,
lists:member(Node,Nodes0) == false],
ct_logs:log("COVER INFO",
"Adding nodes to cover test: ~w", [Nodes1]),
case cover:start(Nodes1) of
- Result = {ok,_} ->
- ct_util:set_testdata({cover,{File,Nodes1++Nodes0,
- Import,Export,AppInfo}}),
-
+ Result = {ok,StartedNodes} ->
+ ct_logs:log("COVER INFO",
+ "Successfully added nodes to cover test: ~w",
+ [StartedNodes]),
Result;
Error ->
+ ct_logs:log("COVER INFO",
+ "Failed to add nodes to cover test: ~tp",
+ [Error]),
Error
end
end.
@@ -81,19 +84,20 @@ remove_nodes(Nodes) ->
undefined ->
{error,cover_not_running};
_ ->
- {File,Nodes0,Import,Export,AppInfo} = ct_util:get_testdata(cover),
+ Nodes0 = cover:which_nodes(),
ToRemove = [Node || Node <- Nodes, lists:member(Node,Nodes0)],
ct_logs:log("COVER INFO",
- "Removing nodes from cover test: ~w", [ToRemove]),
+ "Removing nodes from cover test: ~w", [ToRemove]),
case cover:stop(ToRemove) of
ok ->
- Nodes1 = lists:foldl(fun(N,Deleted) ->
- lists:delete(N,Deleted)
- end, Nodes0, ToRemove),
- ct_util:set_testdata({cover,{File,Nodes1,
- Import,Export,AppInfo}}),
+ ct_logs:log("COVER INFO",
+ "Successfully removed nodes from cover test.",
+ []),
ok;
Error ->
+ ct_logs:log("COVER INFO",
+ "Failed to remove nodes from cover test: ~tp",
+ [Error]),
Error
end
end.
@@ -149,7 +153,7 @@ get_spec_test(File) ->
{value,{_,[Exp]}} ->
filename:absname(Exp);
_ ->
- []
+ undefined
end,
Nodes =
case lists:keysearch(nodes, 1, Terms) of
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index 20903607dc..e8ea7992b4 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -1244,38 +1244,7 @@ report(What,Data) ->
ct_logs:make_all_suites_index({TestName,RunDir}),
ok;
tests_start ->
- case ct_util:get_testdata(cover) of
- undefined ->
- ok;
- {_CovFile,_CovNodes,CovImport,CovExport,_CovAppData} ->
- %% Always import cover data from files specified by CovImport
- %% if no CovExport defined. If CovExport is defined, only
- %% import from CovImport files initially, then use CovExport
- %% to pass coverdata between proceeding tests (in the same run).
- Imps =
- case CovExport of
- [] -> % don't export data between tests
- CovImport;
- _ ->
- case filelib:is_file(CovExport) of
- true ->
- [CovExport];
- false ->
- CovImport
- end
- end,
- lists:foreach(
- fun(Imp) ->
- case cover:import(Imp) of
- ok ->
- ok;
- {error,Reason} ->
- ct_logs:log("COVER INFO",
- "Importing cover data from: ~ts fails! "
- "Reason: ~p", [Imp,Reason])
- end
- end, Imps)
- end;
+ ok;
tests_done ->
ok;
severe_error ->
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index a4ad65c0a4..43eabb18d5 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -62,6 +62,7 @@
-define(totals_name, "totals.info").
-define(log_cache_name, "ct_log_cache").
-define(misc_io_log, "misc_io.log.html").
+-define(coverlog_name, "cover.html"). % must be same as in test_server_ctrl
-define(table_color1,"#ADD8E6").
-define(table_color2,"#E4F0FE").
@@ -1304,7 +1305,8 @@ total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) ->
"<td align=right>",integer_to_list(AllSkip),
" (",UserSkipStr,"/",AutoSkipStr,")</td>\n",
"<td align=right><b>",integer_to_list(NotBuilt),"<b></td>\n",
- AllInfo, "</tr>\n</tfoot>\n"].
+ AllInfo, "</tr>\n",
+ xhtml("","</tfoot>\n")].
not_built(_BaseName,_LogDir,_All,[]) ->
0;
@@ -1368,6 +1370,19 @@ index_header(Label, StartTime) ->
format_time(StartTime),
{[],[1],[2,3,4,5]})
end,
+ Cover =
+ case filelib:is_regular(?abs(?coverlog_name)) of
+ true ->
+ xhtml(["<p><a href=\"",?coverlog_name,
+ "\">Cover Log</a></p><br>\n"],
+ ["<br />"
+ "<div id=\"button_holder\" class=\"btn\">\n"
+ "<a href=\"",?coverlog_name,
+ "\">COVER LOG</a>\n</div><br /><br />"]);
+ false ->
+ xhtml("<br>\n", "<br /><br /><br />\n")
+ end,
+
[Head |
["<center>\n",
xhtml(["<p><a href=\"",?ct_log_name,
@@ -1375,8 +1390,8 @@ index_header(Label, StartTime) ->
["<br />"
"<div id=\"button_holder\" class=\"btn\">\n"
"<a href=\"",?ct_log_name,
- "\">COMMON TEST FRAMEWORK LOG</a>\n</div>"]),
- xhtml("<br>\n", "<br /><br /><br />\n"),
+ "\">COMMON TEST FRAMEWORK LOG</a>\n</div><br>\n"]),
+ Cover,
xhtml(["<table border=\"3\" cellpadding=\"5\" "
"bgcolor=\"",?table_color3,"\">\n"],
["<table id=\"",?sortable_table_name,"\">\n",
@@ -1519,7 +1534,8 @@ all_suites_index_footer() ->
xhtml("<br><br>\n", "<br /><br />\n") | footer()].
all_runs_index_footer() ->
- ["</tbody>\n</table>\n",
+ [xhtml("", "</tbody>\n"),
+ "</table>\n",
"</center>\n",
xhtml("<br><br>\n", "<br /><br />\n") | footer()].
@@ -1676,7 +1692,7 @@ config_table(Vars) ->
config_table_header() ->
[
xhtml(["<h2>Configuration</h2>\n"
- "<table border=\"3\" cellpadding=\"5\" bgcolor=\"",?table_color1,"\"\n"],
+ "<table border=\"3\" cellpadding=\"5\" bgcolor=\"",?table_color1,"\">\n"],
["<h4>CONFIGURATION</h4>\n",
"<table id=\"",?sortable_table_name,"\">\n",
"<thead>\n"]),
@@ -1692,7 +1708,7 @@ config_table1([{Key,Value}|Vars]) ->
"<td>", io_lib:format("~p",[Value]), "</td>\n</tr>\n"]) |
config_table1(Vars)];
config_table1([]) ->
- ["</tbody>\n</table>\n"].
+ [xhtml("","</tbody>\n"),"</table>\n"].
make_all_runs_index(When) ->
@@ -1842,14 +1858,27 @@ dir_diff_all_runs(LogDirs=[Dir|Dirs], Cached=[CElem|CElems],
LatestInCache, AllRunsDirs) ->
DirDate = datestr_from_dirname(Dir),
if DirDate > LatestInCache ->
- %% Dir is a new run entry
+ %% Dir is a new run entry (not cached)
dir_diff_all_runs(Dirs, Cached, LatestInCache,
[Dir|AllRunsDirs]);
DirDate == LatestInCache, CElems /= [] ->
- %% Dir is an existing run entry
+ %% Dir is an existing (cached) run entry
+
+ %% Only add the cached element instead of Dir if the totals
+ %% are "non-empty" (a test might be executing on a different
+ %% node and results haven't been saved yet)
+ ElemToAdd =
+ case CElem of
+ {_CDir,{_NodeStr,_Label,_Logs,{0,0,0,0,0}},_IxLink} ->
+ %% "empty" element in cache - this could be an
+ %% incomplete test and should be checked again
+ Dir;
+ _ ->
+ CElem
+ end,
dir_diff_all_runs(Dirs, CElems,
datestr_from_dirname(element(1,hd(CElems))),
- [CElem|AllRunsDirs]);
+ [ElemToAdd|AllRunsDirs]);
DirDate == LatestInCache, CElems == [] ->
%% we're done, Dirs must all be new
lists:reverse(Dirs)++[CElem|AllRunsDirs];
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index 03cf06abed..00d0aab507 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1646,7 +1646,7 @@ do_run(Tests, Misc, LogDir, LogOpts) when is_list(Misc),
do_run(Tests, [], Opts#opts{logdir = LogDir}, []);
do_run(Tests, Skip, Opts, Args) when is_record(Opts, opts) ->
- #opts{label = Label, profile = Profile, cover = Cover,
+ #opts{label = Label, profile = Profile,
verbosity = VLvls} = Opts,
%% label - used by ct_logs
TestLabel =
@@ -1670,22 +1670,6 @@ do_run(Tests, Skip, Opts, Args) when is_record(Opts, opts) ->
non_existing ->
{error,no_path_to_test_server};
_ ->
- Opts1 = if Cover == undefined ->
- Opts;
- true ->
- case ct_cover:get_spec(Cover) of
- {error,Reason} ->
- exit({error,Reason});
- CoverSpec ->
- CoverStop =
- case Opts#opts.cover_stop of
- undefined -> true;
- Stop -> Stop
- end,
- Opts#opts{coverspec = CoverSpec,
- cover_stop = CoverStop}
- end
- end,
%% This env variable is used by test_server to determine
%% which framework it runs under.
case os:getenv("TEST_SERVER_FRAMEWORK") of
@@ -1711,7 +1695,7 @@ do_run(Tests, Skip, Opts, Args) when is_record(Opts, opts) ->
_Pid ->
ct_util:set_testdata({starter,Opts#opts.starter}),
compile_and_run(Tests, Skip,
- Opts1#opts{verbosity=Verbosity}, Args)
+ Opts#opts{verbosity=Verbosity}, Args)
end
end.
@@ -2146,67 +2130,11 @@ check_and_add([{TestDir0,M,_} | Tests], Added, PA) ->
check_and_add([], _, PA) ->
{ok,PA}.
-do_run_test(Tests, Skip, Opts) ->
+do_run_test(Tests, Skip, Opts0) ->
case check_and_add(Tests, [], []) of
{ok,AddedToPath} ->
ct_util:set_testdata({stats,{0,0,{0,0}}}),
- ct_util:set_testdata({cover,undefined}),
test_server_ctrl:start_link(local),
- case Opts#opts.coverspec of
- CovData={CovFile,
- CovNodes,
- _CovImport,
- CovExport,
- #cover{app = CovApp,
- level = CovLevel,
- excl_mods = CovExcl,
- incl_mods = CovIncl,
- cross = CovCross,
- src = _CovSrc}} ->
- ct_logs:log("COVER INFO",
- "Using cover specification file: ~ts~n"
- "App: ~w~n"
- "Cross cover: ~w~n"
- "Including ~w modules~n"
- "Excluding ~w modules",
- [CovFile,CovApp,CovCross,
- length(CovIncl),length(CovExcl)]),
-
- %% cover export file will be used for export and import
- %% between tests so make sure it doesn't exist initially
- case filelib:is_file(CovExport) of
- true ->
- DelResult = file:delete(CovExport),
- ct_logs:log("COVER INFO",
- "Warning! "
- "Export file ~ts already exists. "
- "Deleting with result: ~p",
- [CovExport,DelResult]);
- false ->
- ok
- end,
-
- %% tell test_server which modules should be cover compiled
- %% note that actual compilation is done when tests start
- test_server_ctrl:cover(CovApp, CovFile, CovExcl, CovIncl,
- CovCross, CovExport, CovLevel,
- Opts#opts.cover_stop),
- %% save cover data (used e.g. to add nodes dynamically)
- ct_util:set_testdata({cover,CovData}),
- %% start cover on specified nodes
- if (CovNodes /= []) and (CovNodes /= undefined) ->
- ct_logs:log("COVER INFO",
- "Nodes included in cover "
- "session: ~w",
- [CovNodes]),
- cover:start(CovNodes);
- true ->
- ok
- end,
- true;
- _ ->
- false
- end,
%% let test_server expand the test tuples and count no of cases
{Suites,NoOfCases} = count_test_cases(Tests, Skip),
@@ -2231,24 +2159,31 @@ do_run_test(Tests, Skip, Opts) ->
end,
%% if the verbosity level is set lower than ?STD_IMPORTANCE, tell
%% test_server to ignore stdout printouts to the test case log file
- case proplists:get_value(default, Opts#opts.verbosity) of
+ case proplists:get_value(default, Opts0#opts.verbosity) of
VLvl when is_integer(VLvl), (?STD_IMPORTANCE < (100-VLvl)) ->
test_server_ctrl:reject_io_reqs(true);
_Lower ->
ok
end,
- test_server_ctrl:multiply_timetraps(Opts#opts.multiply_timetraps),
- test_server_ctrl:scale_timetraps(Opts#opts.scale_timetraps),
+ test_server_ctrl:multiply_timetraps(Opts0#opts.multiply_timetraps),
+ test_server_ctrl:scale_timetraps(Opts0#opts.scale_timetraps),
test_server_ctrl:create_priv_dir(choose_val(
- Opts#opts.create_priv_dir,
+ Opts0#opts.create_priv_dir,
auto_per_run)),
+
+ {ok,LogDir} = ct_logs:get_log_dir(true),
+ {TsCoverInfo,Opts} = maybe_start_cover(Opts0, LogDir),
+
ct_event:notify(#event{name=start_info,
node=node(),
data={NoOfTests,NoOfSuites,NoOfCases}}),
CleanUp = add_jobs(Tests, Skip, Opts, []),
unlink(whereis(test_server_ctrl)),
catch test_server_ctrl:wait_finish(),
+
+ maybe_stop_cover(Opts, TsCoverInfo, LogDir),
+
%% check if last testcase has left a "dead" trace window
%% behind, and if so, kill it
case ct_util:get_testdata(interpret) of
@@ -2281,6 +2216,102 @@ do_run_test(Tests, Skip, Opts) ->
exit(Error)
end.
+maybe_start_cover(Opts=#opts{cover=Cover,cover_stop=CoverStop0},LogDir) ->
+ if Cover == undefined ->
+ {undefined,Opts};
+ true ->
+ case ct_cover:get_spec(Cover) of
+ {error,Reason} ->
+ exit({error,Reason});
+ CoverSpec ->
+ CoverStop =
+ case CoverStop0 of
+ undefined -> true;
+ Stop -> Stop
+ end,
+ start_cover(Opts#opts{coverspec=CoverSpec,
+ cover_stop=CoverStop},
+ LogDir)
+ end
+ end.
+
+start_cover(Opts=#opts{coverspec=CovData,cover_stop=CovStop},LogDir) ->
+ {CovFile,
+ CovNodes,
+ CovImport,
+ _CovExport,
+ #cover{app = CovApp,
+ level = CovLevel,
+ excl_mods = CovExcl,
+ incl_mods = CovIncl,
+ cross = CovCross,
+ src = _CovSrc}} = CovData,
+ ct_logs:log("COVER INFO",
+ "Using cover specification file: ~ts~n"
+ "App: ~w~n"
+ "Cross cover: ~w~n"
+ "Including ~w modules~n"
+ "Excluding ~w modules",
+ [CovFile,CovApp,CovCross,
+ length(CovIncl),length(CovExcl)]),
+
+ %% Tell test_server to print a link in its coverlog
+ %% pointing to the real coverlog which will be written in
+ %% maybe_stop_cover/2
+ test_server_ctrl:cover({log,LogDir}),
+
+ %% Cover compile all modules
+ {ok,TsCoverInfo} = test_server_ctrl:cover_compile(CovApp,CovFile,
+ CovExcl,CovIncl,
+ CovCross,CovLevel,
+ CovStop),
+ ct_logs:log("COVER INFO",
+ "Compilation completed - test_server cover info: ~tp",
+ [TsCoverInfo]),
+
+ %% start cover on specified nodes
+ if (CovNodes /= []) and (CovNodes /= undefined) ->
+ ct_logs:log("COVER INFO",
+ "Nodes included in cover "
+ "session: ~w",
+ [CovNodes]),
+ cover:start(CovNodes);
+ true ->
+ ok
+ end,
+ lists:foreach(
+ fun(Imp) ->
+ case cover:import(Imp) of
+ ok ->
+ ok;
+ {error,Reason} ->
+ ct_logs:log("COVER INFO",
+ "Importing cover data from: ~ts fails! "
+ "Reason: ~p", [Imp,Reason])
+ end
+ end, CovImport),
+ {TsCoverInfo,Opts}.
+
+maybe_stop_cover(_,undefined,_) ->
+ ok;
+maybe_stop_cover(#opts{coverspec=CovData},TsCoverInfo,LogDir) ->
+ {_CovFile,
+ _CovNodes,
+ _CovImport,
+ CovExport,
+ _AppData} = CovData,
+ case CovExport of
+ undefined -> ok;
+ _ ->
+ ct_logs:log("COVER INFO","Exporting cover data to ~tp",[CovExport]),
+ cover:export(CovExport)
+ end,
+ ct_logs:log("COVER INFO","Analysing cover data to ~tp",[LogDir]),
+ test_server_ctrl:cover_analyse(TsCoverInfo,LogDir),
+ ct_logs:log("COVER INFO","Analysis completed.",[]),
+ ok.
+
+
delete_dups([S | Suites]) ->
Suites1 = lists:delete(S, Suites),
[S | delete_dups(Suites1)];
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index 085f19d023..a0ac47f12a 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2013. All Rights Reserved.
+# Copyright Ericsson AB 2008-2014. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -61,6 +61,7 @@ MODULES= \
ct_snmp_SUITE \
ct_group_leader_SUITE \
ct_cover_SUITE \
+ ct_cover_nomerge_SUITE \
ct_groups_search_SUITE \
ct_surefire_SUITE \
ct_telnet_SUITE
diff --git a/lib/common_test/test/ct_cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE.erl
index ec2680f664..47080b5577 100644
--- a/lib/common_test/test/ct_cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE.erl
@@ -172,8 +172,8 @@ cross(Config) ->
check_calls(Events2,1),
%% Get the log dirs for each test and run cross cover analyse
- [D11,D12] = lists:sort(get_run_dirs(Events1)),
- [D21,D22] = lists:sort(get_run_dirs(Events2)),
+ [D11,D12] = lists:sort(get_log_dirs(Events1)),
+ [D21,D22] = lists:sort(get_log_dirs(Events2)),
ct_cover:cross_cover_analyse(details,[{cross1,D11},{cross2,D21}]),
ct_cover:cross_cover_analyse(details,[{cross1,D12},{cross2,D22}]),
@@ -267,18 +267,17 @@ check_cover(Node) when is_atom(Node) ->
false
end.
-%% Get the log dir "run.<timestamp>" for all (both!) tests
-get_run_dirs(Events) ->
- [filename:dirname(TCLog) ||
+%% Get the log dir "ct_run.<timestamp>" for all (both!) tests
+get_log_dirs(Events) ->
+ [LogDir ||
{ct_test_support_eh,
- {event,tc_logfile,_Node,
- {{?suite,init_per_suite},TCLog}}} <- Events].
+ {event,start_logging,_Node,LogDir}} <- Events].
%% Check that each coverlog includes N calls to ?mod:foo/0
check_calls(Events,N) ->
check_calls(Events,{?mod,foo,0},N).
check_calls(Events,MFA,N) ->
- CoverLogs = [filename:join(D,"all.coverdata") || D <- get_run_dirs(Events)],
+ CoverLogs = [filename:join(D,"all.coverdata") || D <- get_log_dirs(Events)],
do_check_logs(CoverLogs,MFA,N).
do_check_logs([CoverLog|CoverLogs],{Mod,_,_} = MFA,N) ->
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE.erl
new file mode 100644
index 0000000000..8e2ee1b500
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE.erl
@@ -0,0 +1,221 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_cover_nomerge_SUITE
+%%%
+%%% Description:
+%%% Test code cover analysis support when merge_tests=false
+%%%
+%%%-------------------------------------------------------------------
+-module(ct_cover_nomerge_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+-define(mod, cover_test_mod).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ case test_server:is_cover() of
+ true ->
+ {skip,"Test server is running cover already - skipping"};
+ false ->
+ ct_test_support:init_per_suite(Config)
+ end.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ try apply(?MODULE,TestCase,[cleanup,Config])
+ catch error:undef -> ok
+ end,
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [
+ local,
+ remote,
+ remote_nostop
+ ].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+local(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Spec = filename:join(DataDir, "local.spec"),
+ CoverSpec = [{incl_mods,[?mod]}],
+ CoverFile = create_cover_file(local,CoverSpec,Config),
+ {Opts,ERPid} = setup([{spec,Spec},{label,local},{cover,CoverFile}], Config),
+ {ok,Events} = execute(local, local, Opts, ERPid, Config),
+ false = check_cover(Config),
+ check_calls(Events,2),
+ ok.
+
+remote(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Spec = filename:join(DataDir, "remote.spec"),
+ %% extending some timers for slow test hosts
+ {ok,Node} = ct_slave:start(ct_nomerge,[{boot_timeout,15},
+ {init_timeout,15},
+ {startup_timeout,15}]),
+
+ CoverSpec = [{nodes,[Node]},
+ {incl_mods,[?mod]}],
+ CoverFile = create_cover_file(remote,CoverSpec,Config),
+ {Opts,ERPid} = setup([{spec,Spec},{label,remote},{cover,CoverFile}], Config),
+ {ok,Events} = execute(remote, remote, Opts, ERPid, Config),
+ false = check_cover(Config),
+ check_calls(Events,2),
+ ok.
+remote(cleanup,_Config) ->
+ {ok,_} = ct_slave:stop(ct_nomerge),
+ ok.
+
+remote_nostop(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Spec = filename:join(DataDir, "remote_nostop.spec"),
+ %% extending some timers for slow test hosts
+ {ok,Node} = ct_slave:start(ct_nomerge,[{boot_timeout,15},
+ {init_timeout,15},
+ {startup_timeout,15}]),
+
+ CoverSpec = [{nodes,[Node]},
+ {incl_mods,[?mod]}],
+ CoverFile = create_cover_file(remote_nostop,CoverSpec,Config),
+ {Opts,ERPid} = setup([{spec,Spec},{label,remote_nostop},
+ {cover,CoverFile},{cover_stop,false}],
+ Config),
+ {ok,Events} = execute(remote_nostop, remote_nostop, Opts, ERPid, Config),
+ {true,[Node],[cover_test_mod]} = check_cover(Config),
+ check_calls(Events,2),
+ ok.
+remote_nostop(cleanup,Config) ->
+ CtNode = ?config(ct_node,Config),
+ ok = rpc:call(CtNode,cover,stop,[]),
+ {ok,_} = ct_slave:stop(ct_nomerge),
+ ok.
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+execute(Name, Testcase, Opts, ERPid, Config) ->
+ ok = ct_test_support:run(Opts, Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(Name,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config),
+ Opts),
+ TestEvents = events_to_check(Testcase),
+ R = ct_test_support:verify_events(TestEvents, Events, Config),
+ {R,Events}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+
+events_to_check(local) ->
+ events_to_check1(cover_nomerge_local_SUITE);
+events_to_check(remote) ->
+ events_to_check1(cover_nomerge_remote_SUITE);
+events_to_check(remote_nostop) ->
+ events_to_check1(cover_nomerge_remote_nostop_SUITE).
+events_to_check1(Suite) ->
+ OneTest =
+ [{?eh,start_logging,{'DEF','RUNDIR'}}] ++
+ [{?eh,tc_done,{Suite,t1,ok}}] ++
+ [{?eh,tc_done,{Suite,t2,ok}}] ++
+ [{?eh,stop_logging,[]}],
+
+ %% 2 tests (ct:run_test + script_start) is default
+ OneTest ++ OneTest.
+
+check_cover(Config) when is_list(Config) ->
+ CTNode = proplists:get_value(ct_node, Config),
+ check_cover(CTNode);
+check_cover(Node) when is_atom(Node) ->
+ case rpc:call(Node,test_server,is_cover,[]) of
+ true ->
+ {true,
+ rpc:call(Node,cover,which_nodes,[]),
+ rpc:call(Node,cover,modules,[])};
+ false ->
+ false
+ end.
+
+%% Get the log dir "ct_run.<timestamp>" for all (both!) tests
+get_log_dirs(Events) ->
+ [LogDir ||
+ {ct_test_support_eh,
+ {event,start_logging,_Node,LogDir}} <- Events].
+
+%% Check that each coverlog includes N calls to ?mod:foo/0
+check_calls(Events,N) ->
+ check_calls(Events,{?mod,foo,0},N).
+check_calls(Events,MFA,N) ->
+ CoverLogs = [filename:join(D,"all.coverdata") || D <- get_log_dirs(Events)],
+ do_check_logs(CoverLogs,MFA,N).
+
+do_check_logs([CoverLog|CoverLogs],{Mod,_,_} = MFA,N) ->
+ {ok,_} = cover:start(),
+ ok = cover:import(CoverLog),
+ {ok,Calls} = cover:analyse(Mod,calls,function),
+ ok = cover:stop(),
+ {MFA,N} = lists:keyfind(MFA,1,Calls),
+ do_check_logs(CoverLogs,MFA,N);
+do_check_logs([],_,_) ->
+ ok.
+
+create_cover_file(Filename,Terms,Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ File = filename:join(PrivDir,Filename) ++ ".cover",
+ {ok,Fd} = file:open(File,[write]),
+ lists:foreach(fun(Term) ->
+ file:write(Fd,io_lib:format("~p.~n",[Term]))
+ end,Terms),
+ ok = file:close(Fd),
+ File.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl
new file mode 100644
index 0000000000..e1fe3b5fc9
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_local_SUITE.erl
@@ -0,0 +1,63 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+-module(cover_nomerge_local_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+suite() ->
+ [].
+
+all() ->
+ [t1,t2].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+break(_Config) ->
+ test_server:break(""),
+ ok.
+
+t1(_Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ ok = cover_test_mod:foo(),
+ ok.
+
+t2(_Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ ok = cover_test_mod:foo(),
+ ok.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl
new file mode 100644
index 0000000000..a77ae0c2db
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_SUITE.erl
@@ -0,0 +1,75 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+-module(cover_nomerge_remote_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+suite() ->
+ [].
+
+all() ->
+ [t1,t2].
+
+init_per_suite(Config) ->
+ {ok,Host} = inet:gethostname(),
+ Node = list_to_atom("ct_nomerge@"++Host),
+ pong = net_adm:ping(Node),
+
+%% Include this row, and exclude the equivalent row in end_per_suite =>
+%% fails every now and then with missing data. Why?
+%% ct_cover:remove_nodes([Node]),
+ ct_cover:add_nodes([Node]),
+ [{node,Node}|Config].
+
+end_per_suite(Config) ->
+ Node = ?config(node,Config),
+ ct_cover:remove_nodes([Node]),
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+break(_Config) ->
+ test_server:break(""),
+ ok.
+
+t1(Config) ->
+ Node = ?config(node,Config),
+ cover_compiled = rpc:call(Node, code, which, [cover_test_mod]),
+ ok = rpc:call(Node, cover_test_mod, foo, []),
+ ok.
+
+t2(Config) ->
+ Node = ?config(node,Config),
+ cover_compiled = rpc:call(Node, code, which, [cover_test_mod]),
+ ok = rpc:call(Node, cover_test_mod, foo, []),
+ ok.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl
new file mode 100644
index 0000000000..0b3159f2c3
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_nomerge_remote_nostop_SUITE.erl
@@ -0,0 +1,68 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+-module(cover_nomerge_remote_nostop_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+suite() ->
+ [].
+
+all() ->
+ [t1,t2].
+
+init_per_suite(Config) ->
+ {ok,Host} = inet:gethostname(),
+ Node = list_to_atom("ct_nomerge@"++Host),
+ pong = net_adm:ping(Node),
+ [{node,Node}|Config].
+
+end_per_suite(Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+break(_Config) ->
+ test_server:break(""),
+ ok.
+
+t1(Config) ->
+ Node = ?config(node,Config),
+ cover_compiled = rpc:call(Node, code, which, [cover_test_mod]),
+ ok = rpc:call(Node, cover_test_mod, foo, []),
+ ok.
+
+t2(Config) ->
+ Node = ?config(node,Config),
+ cover_compiled = rpc:call(Node, code, which, [cover_test_mod]),
+ ok = rpc:call(Node, cover_test_mod, foo, []),
+ ok.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_test_mod.erl b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_test_mod.erl
new file mode 100644
index 0000000000..d4f69452c3
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/cover_test_mod.erl
@@ -0,0 +1,4 @@
+-module(cover_test_mod).
+-compile(export_all).
+foo() ->
+ ok.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/local.spec b/lib/common_test/test/ct_cover_nomerge_SUITE_data/local.spec
new file mode 100644
index 0000000000..893c48b010
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/local.spec
@@ -0,0 +1,6 @@
+{merge_tests,false}.
+
+{alias,dir,"."}.
+
+{cases, dir, cover_nomerge_local_SUITE, [t1]}.
+{cases, dir, cover_nomerge_local_SUITE, [t2]}.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/remote.spec b/lib/common_test/test/ct_cover_nomerge_SUITE_data/remote.spec
new file mode 100644
index 0000000000..78c4332270
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/remote.spec
@@ -0,0 +1,6 @@
+{merge_tests,false}.
+
+{alias,dir,"."}.
+
+{cases, dir, cover_nomerge_remote_SUITE, [t1]}.
+{cases, dir, cover_nomerge_remote_SUITE, [t2]}.
diff --git a/lib/common_test/test/ct_cover_nomerge_SUITE_data/remote_nostop.spec b/lib/common_test/test/ct_cover_nomerge_SUITE_data/remote_nostop.spec
new file mode 100644
index 0000000000..049f586c72
--- /dev/null
+++ b/lib/common_test/test/ct_cover_nomerge_SUITE_data/remote_nostop.spec
@@ -0,0 +1,6 @@
+{merge_tests,false}.
+
+{alias,dir,"."}.
+
+{cases, dir, cover_nomerge_remote_nostop_SUITE, [t1]}.
+{cases, dir, cover_nomerge_remote_nostop_SUITE, [t2]}.
diff --git a/lib/common_test/test/ct_snmp_SUITE_data/snmp.cfg b/lib/common_test/test/ct_snmp_SUITE_data/snmp.cfg
index 895e097de6..7ff356e49a 100644
--- a/lib/common_test/test/ct_snmp_SUITE_data/snmp.cfg
+++ b/lib/common_test/test/ct_snmp_SUITE_data/snmp.cfg
@@ -22,23 +22,23 @@
{agent_target_param_def,{data_dir_file,"target_params.conf"}},
{agent_vacm,{data_dir_file,"vacm.conf"}}]}.
{snmp_app1,[{manager, [{config, [{verbosity, silence}]},
- {server,[{verbosity,silence}]},
- {net_if,[{verbosity,silence}]},
+ {server,[{verbosity,log}]},
+ {net_if,[{verbosity,log}]},
{versions,[v2]}
]},
{agent, [{config, [{verbosity, silence}]},
- {net_if,[{verbosity,silence}]},
+ {net_if,[{verbosity,log}]},
{mib_server,[{verbosity,silence}]},
{local_db,[{verbosity,silence}]},
- {agent_verbosity,silence}
+ {agent_verbosity,log}
]}]}.
{snmp_app2,[{manager, [{config, [{verbosity, silence}]},
- {server,[{verbosity,silence}]},
- {net_if,[{verbosity,silence}]}
+ {server,[{verbosity,log}]},
+ {net_if,[{verbosity,log}]}
]},
{agent, [{config, [{verbosity, silence}]},
- {net_if,[{verbosity,silence}]},
+ {net_if,[{verbosity,log}]},
{mib_server,[{verbosity,silence}]},
{local_db,[{verbosity,silence}]},
- {agent_verbosity,silence}
+ {agent_verbosity,log}
]}]}.
diff --git a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl
index 16b2b5690c..e20832e1e7 100644
--- a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl
+++ b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -288,6 +288,9 @@ override_usm(Config) ->
%% Check that usm.conf is overwritten
{ok,MyUsm} = snmpa_conf:read_usm_config(DataDir),
{ok,UsedUsm} = snmpa_conf:read_usm_config(ConfDir),
+ ct:pal(
+ "MyUsm = ~p~nUsedUsm = ~p",
+ [MyUsm, UsedUsm]),
true = (MyUsm == UsedUsm),
%% Check that the usm user is actually configured...
@@ -304,6 +307,9 @@ override_standard(Config) ->
%% Check that standard.conf is overwritten
{ok,MyStandard} = snmpa_conf:read_standard_config(DataDir),
{ok,UsedStandard} = snmpa_conf:read_standard_config(ConfDir),
+ ct:pal(
+ "MyStandard = ~p~nUsedStandard = ~p",
+ [MyStandard, UsedStandard]),
true = (MyStandard == UsedStandard),
%% Check that the values from standard.conf is actually configured...
@@ -319,6 +325,9 @@ override_context(Config) ->
%% Check that context.conf is overwritten
{ok,MyContext} = snmpa_conf:read_context_config(DataDir),
{ok,UsedContext} = snmpa_conf:read_context_config(ConfDir),
+ ct:pal(
+ "MyContext = ~p~nUsedContext = ~p",
+ [MyContext, UsedContext]),
true = (MyContext == UsedContext),
ok.
@@ -330,6 +339,9 @@ override_community(Config) ->
%% Check that community.conf is overwritten
{ok,MyCommunity} = snmpa_conf:read_community_config(DataDir),
{ok,UsedCommunity} = snmpa_conf:read_community_config(ConfDir),
+ ct:pal(
+ "MyCommunity = ~p~nUsedCommunity = ~p",
+ [MyCommunity, UsedCommunity]),
true = (MyCommunity == UsedCommunity),
ok.
@@ -341,6 +353,9 @@ override_notify(Config) ->
%% Check that notify.conf is overwritten
{ok,MyNotify} = snmpa_conf:read_notify_config(DataDir),
{ok,UsedNotify} = snmpa_conf:read_notify_config(ConfDir),
+ ct:pal(
+ "MyNotify = ~p~nUsedNotify = ~p",
+ [MyNotify, UsedNotify]),
true = (MyNotify == UsedNotify),
ok.
@@ -352,6 +367,9 @@ override_target_addr(Config) ->
%% Check that target_addr.conf is overwritten
{ok,MyTargetAddr} = snmpa_conf:read_target_addr_config(DataDir),
{ok,UsedTargetAddr} = snmpa_conf:read_target_addr_config(ConfDir),
+ ct:pal(
+ "MyTargetAddr = ~p~nUsedTargetAddr = ~p",
+ [MyTargetAddr, UsedTargetAddr]),
true = (MyTargetAddr == UsedTargetAddr),
ok.
@@ -363,6 +381,9 @@ override_target_params(Config) ->
%% Check that target_params.conf is overwritten
{ok,MyTargetParams} = snmpa_conf:read_target_params_config(DataDir),
{ok,UsedTargetParams} = snmpa_conf:read_target_params_config(ConfDir),
+ ct:pal(
+ "MyTargetParams = ~p~nUsedTargetParams = ~p",
+ [MyTargetParams, UsedTargetParams]),
true = (MyTargetParams == UsedTargetParams),
ok.
@@ -374,6 +395,9 @@ override_vacm(Config) ->
%% Check that vacm.conf is overwritten
{ok,MyVacm} = snmpa_conf:read_vacm_config(DataDir),
{ok,UsedVacm} = snmpa_conf:read_vacm_config(ConfDir),
+ ct:pal(
+ "MyVacm = ~p~nUsedVacm = ~p",
+ [MyVacm, UsedVacm]),
true = (MyVacm == UsedVacm),
ok.
diff --git a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE_data/target_addr.conf b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE_data/target_addr.conf
index d02672a074..d3ce2fa60e 100644
--- a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE_data/target_addr.conf
+++ b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE_data/target_addr.conf
@@ -1,2 +1,2 @@
-{"target1", snmpUDPDomain, [147,214,122,73], 5000, 1500, 3, "std_trap", "target_v3", "", [], 2048}.
-{"target2", snmpUDPDomain, [147,214,122,73], 5000, 1500, 3, "std_inform", "target_v3", "", [], 2048}.
+{"target1", snmpUDPDomain, {[147,214,122,73], 5000}, 1500, 3, "std_trap", "target_v3", "", [], 2048}.
+{"target2", snmpUDPDomain, {[147,214,122,73], 5000}, 1500, 3, "std_inform", "target_v3", "", [], 2048}.
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index f8a5aab686..def8a6a6f4 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1 +1 @@
-COMMON_TEST_VSN = 1.8
+COMMON_TEST_VSN = 1.8.1
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index a0f2e617cb..55e9661d7d 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -31,6 +31,29 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 5.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A Dialyzer crash involving analysis of Map types has now
+ been fixed.</p>
+ <p>
+ Own Id: OTP-11947</p>
+ </item>
+ <item>
+ <p>The compiler would fail to compile a file with a
+ latin-1 character in the false branch of an <c>-ifdef</c>
+ or <c>-indef</c>.</p>
+ <p>
+ Own Id: OTP-11987</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 5.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -211,10 +234,10 @@
"hello"}, % add new associations</c></item> <item><c>#{
"hi" := V1, a := V2, b := V3} = M2. % match keys with
values</c></item> </taglist></p>
- <p>
- For information on how to use Maps please see the
- <seealso marker="doc/reference_manual:maps">Reference
- Manual</seealso>.</p>
+ <p>
+ For information on how to use Maps please see Map Expressions in the
+ <seealso marker="doc/reference_manual:expressions#map_expressions">
+ Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
features: <taglist> <item>No variable keys</item>
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 8c18f6a9f7..83cf76f241 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -82,6 +82,8 @@
-include("core_parse.hrl").
+-define(REC_OFFSET, 100000000). % Also in erl_expand_records.
+
%% Internal core expressions and help functions.
%% N.B. annotations fields in place as normal Core expressions.
@@ -501,7 +503,7 @@ expr({cons,L,H0,T0}, St0) ->
{H1,Hps,St1} = safe(H0, St0),
{T1,Tps,St2} = safe(T0, St1),
A = lineno_anno(L, St2),
- {ann_c_cons(A, H1, T1),Hps ++ Tps,St2};
+ {annotate_cons(A, H1, T1, St2),Hps ++ Tps,St2};
expr({lc,L,E,Qs0}, St0) ->
{Qs1,St1} = preprocess_quals(L, Qs0, St0),
lc_tq(L, E, Qs1, #c_literal{anno=lineno_anno(L, St1),val=[]}, St1);
@@ -509,8 +511,8 @@ expr({bc,L,E,Qs}, St) ->
bc_tq(L, E, Qs, {nil,L}, St);
expr({tuple,L,Es0}, St0) ->
{Es1,Eps,St1} = safe_list(Es0, St0),
- A = lineno_anno(L, St1),
- {ann_c_tuple(A, Es1),Eps,St1};
+ A = record_anno(L, St1),
+ {annotate_tuple(A, Es1, St1),Eps,St1};
expr({map,L,Es0}, St0) ->
% erl_lint should make sure only #{ K => V } are allowed
% in map construction.
@@ -1557,9 +1559,9 @@ pattern({atom,L,A}, St) -> #c_literal{anno=lineno_anno(L, St),val=A};
pattern({string,L,S}, St) -> #c_literal{anno=lineno_anno(L, St),val=S};
pattern({nil,L}, St) -> #c_literal{anno=lineno_anno(L, St),val=[]};
pattern({cons,L,H,T}, St) ->
- ann_c_cons(lineno_anno(L, St), pattern(H, St), pattern(T, St));
+ annotate_cons(lineno_anno(L, St), pattern(H, St), pattern(T, St), St);
pattern({tuple,L,Ps}, St) ->
- ann_c_tuple(lineno_anno(L, St), pattern_list(Ps, St));
+ annotate_tuple(record_anno(L, St), pattern_list(Ps, St), St);
pattern({map,L,Ps}, St) ->
#c_map{anno=lineno_anno(L, St), es=pattern_map_pairs(Ps, St)};
pattern({bin,L,Ps}, St) ->
@@ -1721,6 +1723,26 @@ fail_clause(Pats, Anno, Arg) ->
body=[#iprimop{anno=#a{anno=Anno},name=#c_literal{val=match_fail},
args=[Arg]}]}.
+annotate_tuple(A, Es, St) ->
+ case member(dialyzer, St#core.opts) of
+ true ->
+ %% Do not coalesce constant tuple elements. A Hack.
+ Node = cerl:ann_c_tuple(A, [cerl:c_var(any)]),
+ cerl:update_c_tuple_skel(Node, Es);
+ false ->
+ ann_c_tuple(A, Es)
+ end.
+
+annotate_cons(A, H, T, St) ->
+ case member(dialyzer, St#core.opts) of
+ true ->
+ %% Do not coalesce constant conses. A Hack.
+ Node= cerl:ann_c_cons(A, cerl:c_var(any), cerl:c_var(any)),
+ cerl:update_c_cons_skel(Node, H, T);
+ false ->
+ ann_c_cons(A, H, T)
+ end.
+
ubody(B, St) -> uexpr(B, [], St).
%% uclauses([Lclause], [KnownVar], State) -> {[Lclause],State}.
@@ -2238,6 +2260,23 @@ bitstr_vars(Segs, Vs) ->
lit_vars(V, lit_vars(S, Vs0))
end, Vs, Segs).
+record_anno(L, St) when L >= ?REC_OFFSET ->
+ case member(dialyzer, St#core.opts) of
+ true ->
+ [record | lineno_anno(L - ?REC_OFFSET, St)];
+ false ->
+ lineno_anno(L, St)
+ end;
+record_anno(L, St) when L < -?REC_OFFSET ->
+ case member(dialyzer, St#core.opts) of
+ true ->
+ [record | lineno_anno(L + ?REC_OFFSET, St)];
+ false ->
+ lineno_anno(L, St)
+ end;
+record_anno(L, St) ->
+ lineno_anno(L, St).
+
lineno_anno(L, St) ->
{line, Line} = erl_parse:get_attribute(L, line),
if
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index ad4ad91f74..0637041873 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -662,6 +662,20 @@ latin1_fallback(Conf) when is_list(Conf) ->
{warnings,[{1,compile,reparsing_invalid_unicode}]}
}],
[] = run(Conf, Ts2),
+
+ Ts3 = [{latin1_fallback3,
+ %% Test that the compiler fall backs to latin-1 with
+ %% a warning if a file has no encoding and does not
+ %% contain correct UTF-8 sequences.
+ <<"-ifdef(NOTDEFINED).
+ t(_) -> \"",246,"\";
+ t(x) -> ok.
+ -endif.
+ ">>,
+ [],
+ {warnings,[{2,compile,reparsing_invalid_unicode}]}}],
+ [] = run(Conf, Ts3),
+
ok.
%%%
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index c0c3d56472..0a86352f40 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 5.0
+COMPILER_VSN = 5.0.1
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 948093d69c..e55a03d26a 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -507,6 +507,15 @@ static int init_ose_crypto() {
#endif
#ifdef HAVE_DYNAMIC_CRYPTO_LIB
+
+# if defined(DEBUG)
+static char crypto_callback_name[] = "crypto_callback.debug";
+# elif defined(VALGRIND)
+static char crypto_callback_name[] = "crypto_callback.valgrind";
+# else
+static char crypto_callback_name[] = "crypto_callback";
+# endif
+
static int change_basename(ErlNifBinary* bin, char* buf, int bufsz, const char* newfile)
{
int i;
@@ -613,7 +622,7 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
#ifdef HAVE_DYNAMIC_CRYPTO_LIB
{
void* handle;
- if (!change_basename(&lib_bin, lib_buf, sizeof(lib_buf), "crypto_callback")) {
+ if (!change_basename(&lib_bin, lib_buf, sizeof(lib_buf), crypto_callback_name)) {
return 0;
}
if (!(handle = enif_dlopen(lib_buf, &error_handler, NULL))) {
@@ -2897,8 +2906,8 @@ static ERL_NIF_TERM srp_user_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_
/* a + (u * x) */
bn_exp2 = BN_new();
- BN_mod_mul(bn_result, bn_u, bn_exponent, bn_prime, bn_ctx);
- BN_mod_add(bn_exp2, bn_a, bn_result, bn_prime, bn_ctx);
+ BN_mul(bn_result, bn_u, bn_exponent, bn_ctx);
+ BN_add(bn_exp2, bn_a, bn_result);
/* (B - (k * g^x)) ^ (a + (u * x)) % N */
BN_mod_exp(bn_result, bn_base, bn_exp2, bn_prime, bn_ctx);
@@ -3244,6 +3253,7 @@ out:
if (bn_order) BN_free(bn_order);
if (cofactor) BN_free(cofactor);
if (group) EC_GROUP_free(group);
+ if (point) EC_POINT_free(point);
return key;
}
@@ -3406,8 +3416,11 @@ static ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM
EC_KEY_free(key);
return enif_make_tuple2(env, pub_key, priv_key);
}
- else
+ else {
+ if (key)
+ EC_KEY_free(key);
return enif_make_badarg(env);
+ }
#else
return atom_notsup;
#endif
diff --git a/lib/crypto/c_src/crypto_callback.c b/lib/crypto/c_src/crypto_callback.c
index a08dcec463..b4c175ae43 100644
--- a/lib/crypto/c_src/crypto_callback.c
+++ b/lib/crypto/c_src/crypto_callback.c
@@ -107,8 +107,6 @@ static INLINE void locking(int mode, ErlNifRWLock* lock)
static void locking_function(int mode, int n, const char *file, int line)
{
- ASSERT(n>=0 && n<CRYPTO_num_locks());
-
locking(mode, lock_vec[n]);
}
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 34f2e3c469..1bd2034b93 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -30,6 +30,42 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix memory leak in <c>crypto:hmac_init/upgrade/final</c>
+ functions for all data and in <c>crypto:hmac/3/4</c> for
+ data larger than 20000 bytes. Bug exists since OTP 17.0.</p>
+ <p>
+ Own Id: OTP-11953</p>
+ </item>
+ <item>
+ <p>
+ Fix memory leak in <c>crypto</c> for elliptic curve.</p>
+ <p>
+ Own Id: OTP-11999</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add <c>aes_cfb8</c> cypher to <c>crypto:block_encrypt</c>
+ and <c>block_decrypt</c>.</p>
+ <p>
+ Own Id: OTP-11911</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 479c947029..03aa3964a5 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -690,7 +690,7 @@ group_config(ecdsa = Type, Config) ->
SignVerify = [{Type, sha, Public, Private, Msg}],
[{sign_verify, SignVerify} | Config];
group_config(srp, Config) ->
- GenerateCompute = [srp3(), srp6(), srp6a()],
+ GenerateCompute = [srp3(), srp6(), srp6a(), srp6a_smaller_prime()],
[{generate_compute, GenerateCompute} | Config];
group_config(ecdh, Config) ->
Compute = ecdh(),
@@ -1496,6 +1496,32 @@ srp6() ->
ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
+
+srp6a_smaller_prime() ->
+ Username = <<"alice">>,
+ Password = <<"password123">>,
+ Salt = <<"mystrongsalt">>,
+ Prime = hexstr2bin("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"),
+ Generator = <<7>>,
+ Version = '6a',
+ Scrambler = hexstr2bin("18DE4A002AD05EF464B19AE2B6929F9B1319C7AA"),
+ Verifier = hexstr2bin("867401D5DE10964768184EAF246B322760C847604075FA66A4423907"
+ "8428BCA5"),
+ ClientPrivate = hexstr2bin("C49F832EE8D67ECF9E7F2785EB0622D8B3FE2344C00F96E1AEF4103C"
+ "A44D51F9"),
+ ServerPrivate = hexstr2bin("6C78CCEAAEC15E69068A87795B2A20ED7B45CFC5A254EBE2F17F144A"
+ "4D99DB18"),
+ ClientPublic = hexstr2bin("2452A57166BBBF690DB77539BAF9C57CD1ED99D5AA15ED925AD9B5C3"
+ "64BBEDFF"),
+ ServerPublic = hexstr2bin("2C0464DE84B91E4963A3546CAC0EFE55F31F49208C3F0AD7EE55F444"
+ "8F38BA7F"),
+
+ SessionKey = hexstr2bin("65581B2302580BD26F522A5A421CF969B9CCBCE4051196B034A2A9D22065D848"),
+ UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
+ Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
+ ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
+ srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
+
srp6a() ->
Username = <<"alice">>,
Password = <<"password123">>,
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index a2bd6f851a..b2bb1d7dfb 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 3.3
+CRYPTO_VSN = 3.4
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 8832f99fc3..c1ba1eec6b 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -32,6 +32,24 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 4.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix evaluation of map updates in the debugger and
+ erl_eval</p>
+ <p>
+ Reported-by: José Valim</p>
+ <p>
+ Own Id: OTP-11922</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Debugger 4.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index cd107599e9..33481a1537 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 4.0
+DEBUGGER_VSN = 4.0.1
diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml
index 3de60b2f7a..4e26a9e95e 100644
--- a/lib/dialyzer/doc/src/dialyzer.xml
+++ b/lib/dialyzer/doc/src/dialyzer.xml
@@ -139,12 +139,7 @@
<tag><c><![CDATA[-Wwarn]]></c></tag>
<item>A family of options which selectively turn on/off warnings
(for help on the names of warnings use
- <c><![CDATA[dialyzer -Whelp]]></c>).
- Note that the options can also be given in the file with a
- <c>-dialyzer({nowarn_tag, WarningTags})</c> attribute.
- See <seealso
- marker="doc/reference_manual:typespec#suppression">Erlang Reference
- Manual</seealso> for details.</item>
+ <c><![CDATA[dialyzer -Whelp]]></c>).</item>
<tag><c><![CDATA[--shell]]></c></tag>
<item>Do not disable the Erlang shell while running the GUI.</item>
<tag><c><![CDATA[--version]]></c> (or <c><![CDATA[-v]]></c>)</tag>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 05baa93557..bdd9c61c5c 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -31,6 +31,44 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix a bug concerning opaque types. Thanks to Shayan
+ Pooya for pointing out the bug.</p>
+ <p>
+ Own Id: OTP-11869</p>
+ </item>
+ <item>
+ <p> A bug where Dialyzer failed to handle typed records
+ with fields containing remote types has been fixed.
+ Thanks to Erik Søe Sørensen for reporting the bug. </p>
+ <p>
+ Own Id: OTP-11918</p>
+ </item>
+ <item>
+ <p> Make sure that only literal records are checked
+ against the types of record definitions. Until now the
+ elements of tuples have been checked against record field
+ types if the tag och size of the tuple matches the record
+ definition, often with surprising results. </p>
+ <p>
+ Own Id: OTP-11935 Aux Id: seq12590 </p>
+ </item>
+ <item>
+ <p>
+ A Dialyzer crash involving analysis of Map types has now
+ been fixed.</p>
+ <p>
+ Own Id: OTP-11947</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 2.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -167,9 +205,9 @@
"hi" := V1, a := V2, b := V3} = M2. % match keys with
values</c></item> </taglist></p>
<p>
- For information on how to use Maps please see the
- <seealso marker="doc/reference_manual:maps">Reference
- Manual</seealso>.</p>
+ For information on how to use Maps please see Map Expressions in the
+ <seealso marker="doc/reference_manual:expressions#map_expressions">
+ Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
features: <taglist> <item>No variable keys</item>
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index e0873b17f8..92aab68ad6 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -53,7 +53,7 @@
t_bitstr/0, t_bitstr/2, t_bitstr_concat/1, t_bitstr_match/2,
t_cons/0, t_cons/2, t_cons_hd/2, t_cons_tl/2,
t_contains_opaque/2,
- t_find_opaque_mismatch/2, t_float/0, t_from_range/2, t_from_term/1,
+ t_find_opaque_mismatch/3, t_float/0, t_from_range/2, t_from_term/1,
t_fun/0, t_fun/2, t_fun_args/1, t_fun_args/2, t_fun_range/1,
t_fun_range/2, t_integer/0, t_integers/1,
t_is_any/1, t_is_atom/1, t_is_atom/2, t_is_any_atom/3,
@@ -136,11 +136,10 @@
get_warnings(Tree, Plt, Callgraph, Records, NoWarnUnused) ->
State1 = analyze_module(Tree, Plt, Callgraph, Records, true),
- State2 = find_mismatched_record_patterns(Tree, State1),
- State3 =
- state__renew_warnings(state__get_warnings(State2, NoWarnUnused), State2),
- State4 = state__get_race_warnings(State3),
- {State4#state.warnings, state__all_fun_types(State4)}.
+ State2 =
+ state__renew_warnings(state__get_warnings(State1, NoWarnUnused), State1),
+ State3 = state__get_race_warnings(State2),
+ {State3#state.warnings, state__all_fun_types(State3)}.
-spec get_fun_types(cerl:c_module(), dialyzer_plt:plt(),
dialyzer_callgraph:callgraph(),
@@ -277,13 +276,8 @@ traverse(Tree, Map, State) ->
{State1, Map1} = lists:foldl(FoldFun, {State, Map}, Defs),
traverse(Body, Map1, State1);
literal ->
- %% This is needed for finding records
- case cerl:unfold_literal(Tree) of
- Tree ->
- Type = literal_type(Tree),
- {State, Map, Type};
- NewTree -> traverse(NewTree, Map, State)
- end;
+ Type = literal_type(Tree),
+ {State, Map, Type};
module ->
handle_module(Tree, Map, State);
primop ->
@@ -1110,7 +1104,7 @@ handle_tuple(Tree, Map, State) ->
%% Let's find out if this is a record
case Elements of
[Tag|Left] ->
- case cerl:is_c_atom(Tag) of
+ case cerl:is_c_atom(Tag) andalso is_literal_record(Tree) of
true ->
TagVal = cerl:atom_val(Tag),
case state__lookup_record(TagVal, length(Left), State1) of
@@ -1240,15 +1234,10 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
false ->
{State1, Map, t_none(), ArgType0};
true ->
- PatString =
- case ErrorType of
- bind -> format_patterns(Pats);
- record -> format_patterns(Pats);
- opaque -> format_patterns(NewPats)
- end,
{Msg, Force} =
case t_is_none(ArgType0) of
true ->
+ PatString = format_patterns(Pats),
PatTypes = [PatString, format_type(OrigArgType, State1)],
%% See if this is covered by an earlier clause or if it
%% simply cannot match
@@ -1298,6 +1287,12 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
false ->
true
end,
+ PatString =
+ case ErrorType of
+ bind -> format_patterns(Pats);
+ record -> format_patterns(NewPats);
+ opaque -> format_patterns(NewPats)
+ end,
PatTypes = case ErrorType of
bind -> [PatString, format_type(ArgType0, State1)];
record -> [PatString, format_type(Type, State1)];
@@ -1444,7 +1439,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
BinType = t_inf(t_bitstr(), Type, Opaques),
case t_is_none(BinType) of
true ->
- case t_find_opaque_mismatch(t_bitstr(), Type) of
+ case t_find_opaque_mismatch(t_bitstr(), Type, Opaques) of
{ok, T1, T2} ->
bind_error([Pat], T1, T2, opaque);
error ->
@@ -1460,7 +1455,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
Cons = t_inf(Type, t_cons(), Opaques),
case t_is_none(Cons) of
true ->
- bind_opaque_pats(t_cons(), Type, Pat, Map, State, Rev);
+ bind_opaque_pats(t_cons(), Type, Pat, State);
false ->
{Map1, [HdType, TlType]} =
bind_pat_vars([cerl:cons_hd(Pat), cerl:cons_tl(Pat)],
@@ -1473,7 +1468,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
Literal = literal_type(Pat),
case t_is_none(t_inf(Literal, Type, Opaques)) of
true ->
- bind_opaque_pats(Literal, Type, Pat, Map, State, Rev);
+ bind_opaque_pats(Literal, Type, Pat, State);
false -> {Map, Literal}
end;
map ->
@@ -1484,7 +1479,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
case Es of
[] -> {false, t_tuple([])};
[Tag|Left] ->
- case cerl:is_c_atom(Tag) of
+ case cerl:is_c_atom(Tag) andalso is_literal_record(Pat) of
true ->
TagAtom = cerl:atom_val(Tag),
case state__lookup_record(TagAtom, length(Left), State) of
@@ -1500,7 +1495,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
Tuple = t_inf(Prototype, Type, Opaques),
case t_is_none(Tuple) of
true ->
- bind_opaque_pats(Prototype, Type, Pat, Map, State, Rev);
+ bind_opaque_pats(Prototype, Type, Pat, State);
false ->
SubTuples = t_tuple_subtypes(Tuple, Opaques),
%% Need to call the top function to get the try-catch wrapper
@@ -1549,7 +1544,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
VarType2 = t_inf(VarType1, Type, Opaques),
case t_is_none(VarType2) of
true ->
- case t_find_opaque_mismatch(VarType1, Type) of
+ case t_find_opaque_mismatch(VarType1, Type, Opaques) of
{ok, T1, T2} ->
bind_error([Pat], T1, T2, opaque);
error ->
@@ -1631,21 +1626,26 @@ bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) ->
bind_bin_segs([], _BinType, Acc, Map, _State) ->
{Map, lists:reverse(Acc)}.
-bind_error(Pats, Type, OpaqueType, Error) ->
+bind_error(Pats, Type, OpaqueType, Error0) ->
+ Error = case {Error0, Pats} of
+ {bind, [Pat]} ->
+ case is_literal_record(Pat) of
+ true -> record;
+ false -> Error0
+ end;
+ _ -> Error0
+ end,
throw({error, Error, Pats, Type, OpaqueType}).
-bind_opaque_pats(GenType, Type, Pat, Map, State, Rev) ->
- case t_find_opaque_mismatch(GenType, Type) of
+-spec bind_opaque_pats(type(), type(), cerl:c_literal(), state()) ->
+ no_return().
+
+bind_opaque_pats(GenType, Type, Pat, State) ->
+ case t_find_opaque_mismatch(GenType, Type, State#state.opaques) of
{ok, T1, T2} ->
- case erl_types:is_opaque_type(T2, State#state.opaques) of
- true ->
- NewType = erl_types:t_struct_from_opaque(Type, [T2]),
- {Map1, _} =
- bind_pat_vars([Pat], [NewType], [], Map, State, Rev),
- {Map1, T2};
- false -> bind_error([Pat], T1, T2, opaque)
- end;
- error -> bind_error([Pat], Type, t_none(), bind)
+ bind_error([Pat], T1, T2, opaque);
+ error ->
+ bind_error([Pat], Type, t_none(), bind)
end.
%%----------------------------------------
@@ -1843,9 +1843,9 @@ handle_guard_comp(Guard, Comp, Map, Env, Eval, State) ->
[Type1, Type2] = ArgTypes,
IsInt1 = t_is_integer(Type1, Opaques),
IsInt2 = t_is_integer(Type2, Opaques),
- case {cerl:type(Arg1), cerl:type(Arg2)} of
- {literal, literal} ->
- case erlang:Comp(cerl:concrete(Arg1), cerl:concrete(Arg2)) of
+ case {type(Arg1), type(Arg2)} of
+ {{literal, Lit1}, {literal, Lit2}} ->
+ case erlang:Comp(cerl:concrete(Lit1), cerl:concrete(Lit2)) of
true when Eval =:= pos -> {Map, t_atom(true)};
true when Eval =:= dont_know -> {Map, t_atom(true)};
true when Eval =:= neg -> {Map, t_atom(true)};
@@ -1854,13 +1854,13 @@ handle_guard_comp(Guard, Comp, Map, Env, Eval, State) ->
false when Eval =:= dont_know -> {Map, t_atom(false)};
false when Eval =:= neg -> {Map, t_atom(false)}
end;
- {literal, var} when IsInt1 andalso IsInt2 andalso (Eval =:= pos) ->
- case bind_comp_literal_var(Arg1, Arg2, Type2, Comp, Map1, Opaques) of
+ {{literal, Lit1}, var} when IsInt1 andalso IsInt2 andalso (Eval =:= pos) ->
+ case bind_comp_literal_var(Lit1, Arg2, Type2, Comp, Map1, Opaques) of
error -> signal_guard_fail(Eval, Guard, ArgTypes, State);
{ok, NewMap} -> {NewMap, t_atom(true)}
end;
- {var, literal} when IsInt1 andalso IsInt2 andalso (Eval =:= pos) ->
- case bind_comp_literal_var(Arg2, Arg1, Type1, invert_comp(Comp),
+ {var, {literal, Lit2}} when IsInt1 andalso IsInt2 andalso (Eval =:= pos) ->
+ case bind_comp_literal_var(Lit2, Arg1, Type1, invert_comp(Comp),
Map1, Opaques) of
error -> signal_guard_fail(Eval, Guard, ArgTypes, State);
{ok, NewMap} -> {NewMap, t_atom(true)}
@@ -1980,15 +1980,15 @@ handle_guard_is_record(Guard, Map, Env, Eval, State) ->
handle_guard_eq(Guard, Map, Env, Eval, State) ->
[Arg1, Arg2] = cerl:call_args(Guard),
- case {cerl:type(Arg1), cerl:type(Arg2)} of
- {literal, literal} ->
- case cerl:concrete(Arg1) =:= cerl:concrete(Arg2) of
+ case {type(Arg1), type(Arg2)} of
+ {{literal, Lit1}, {literal, Lit2}} ->
+ case cerl:concrete(Lit1) =:= cerl:concrete(Lit2) of
true ->
if
Eval =:= pos -> {Map, t_atom(true)};
Eval =:= neg ->
- ArgTypes = [t_from_term(cerl:concrete(Arg1)),
- t_from_term(cerl:concrete(Arg2))],
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
signal_guard_fail(Eval, Guard, ArgTypes, State);
Eval =:= dont_know -> {Map, t_atom(true)}
end;
@@ -1997,28 +1997,28 @@ handle_guard_eq(Guard, Map, Env, Eval, State) ->
Eval =:= neg -> {Map, t_atom(false)};
Eval =:= dont_know -> {Map, t_atom(false)};
Eval =:= pos ->
- ArgTypes = [t_from_term(cerl:concrete(Arg1)),
- t_from_term(cerl:concrete(Arg2))],
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
signal_guard_fail(Eval, Guard, ArgTypes, State)
end
end;
- {literal, _} when Eval =:= pos ->
- case cerl:concrete(Arg1) of
+ {{literal, Lit1}, _} when Eval =:= pos ->
+ case cerl:concrete(Lit1) of
Atom when is_atom(Atom) ->
- bind_eqeq_guard_lit_other(Guard, Arg1, Arg2, Map, Env, State);
+ bind_eqeq_guard_lit_other(Guard, Lit1, Arg2, Map, Env, State);
[] ->
- bind_eqeq_guard_lit_other(Guard, Arg1, Arg2, Map, Env, State);
+ bind_eqeq_guard_lit_other(Guard, Lit1, Arg2, Map, Env, State);
_ ->
- bind_eq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State)
+ bind_eq_guard(Guard, Lit1, Arg2, Map, Env, Eval, State)
end;
- {_, literal} when Eval =:= pos ->
- case cerl:concrete(Arg2) of
+ {_, {literal, Lit2}} when Eval =:= pos ->
+ case cerl:concrete(Lit2) of
Atom when is_atom(Atom) ->
- bind_eqeq_guard_lit_other(Guard, Arg2, Arg1, Map, Env, State);
+ bind_eqeq_guard_lit_other(Guard, Lit2, Arg1, Map, Env, State);
[] ->
- bind_eqeq_guard_lit_other(Guard, Arg2, Arg1, Map, Env, State);
+ bind_eqeq_guard_lit_other(Guard, Lit2, Arg1, Map, Env, State);
_ ->
- bind_eq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State)
+ bind_eq_guard(Guard, Arg1, Lit2, Map, Env, Eval, State)
end;
{_, _} ->
bind_eq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State)
@@ -2050,13 +2050,14 @@ bind_eq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State) ->
handle_guard_eqeq(Guard, Map, Env, Eval, State) ->
[Arg1, Arg2] = cerl:call_args(Guard),
- case {cerl:type(Arg1), cerl:type(Arg2)} of
- {literal, literal} ->
- case cerl:concrete(Arg1) =:= cerl:concrete(Arg2) of
+ case {type(Arg1), type(Arg2)} of
+ {{literal, Lit1}, {literal, Lit2}} ->
+
+ case cerl:concrete(Lit1) =:= cerl:concrete(Lit2) of
true ->
if Eval =:= neg ->
- ArgTypes = [t_from_term(cerl:concrete(Arg1)),
- t_from_term(cerl:concrete(Arg2))],
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
signal_guard_fail(Eval, Guard, ArgTypes, State);
Eval =:= pos -> {Map, t_atom(true)};
Eval =:= dont_know -> {Map, t_atom(true)}
@@ -2065,15 +2066,15 @@ handle_guard_eqeq(Guard, Map, Env, Eval, State) ->
if Eval =:= neg -> {Map, t_atom(false)};
Eval =:= dont_know -> {Map, t_atom(false)};
Eval =:= pos ->
- ArgTypes = [t_from_term(cerl:concrete(Arg1)),
- t_from_term(cerl:concrete(Arg2))],
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
signal_guard_fail(Eval, Guard, ArgTypes, State)
end
end;
- {literal, _} when Eval =:= pos ->
- bind_eqeq_guard_lit_other(Guard, Arg1, Arg2, Map, Env, State);
- {_, literal} when Eval =:= pos ->
- bind_eqeq_guard_lit_other(Guard, Arg2, Arg1, Map, Env, State);
+ {{literal, Lit1}, _} when Eval =:= pos ->
+ bind_eqeq_guard_lit_other(Guard, Lit1, Arg2, Map, Env, State);
+ {_, {literal, Lit2}} when Eval =:= pos ->
+ bind_eqeq_guard_lit_other(Guard, Lit2, Arg1, Map, Env, State);
{_, _} ->
bind_eqeq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State)
end.
@@ -3282,12 +3283,17 @@ get_file([_|Tail]) -> get_file(Tail).
is_compiler_generated(Ann) ->
lists:member(compiler_generated, Ann) orelse (get_line(Ann) < 1).
+is_literal_record(Tree) ->
+ Ann = cerl:get_ann(Tree),
+ lists:member(record, Ann).
+
-spec format_args([cerl:cerl()], [type()], state()) ->
nonempty_string().
format_args([], [], _State) ->
"()";
-format_args(ArgList, TypeList, State) ->
+format_args(ArgList0, TypeList, State) ->
+ ArgList = fold_literals(ArgList0),
"(" ++ format_args_1(ArgList, TypeList, State) ++ ")".
format_args_1([Arg], [Type], State) ->
@@ -3346,7 +3352,8 @@ format_cerl(Tree) ->
{ribbon, 100000} %% newlines.
]).
-format_patterns(Pats) ->
+format_patterns(Pats0) ->
+ Pats = fold_literals(Pats0),
NewPats = map_pats(cerl:c_values(Pats)),
String = format_cerl(NewPats),
case Pats of
@@ -3378,6 +3385,23 @@ map_pats(Pats) ->
end,
cerl_trees:map(Fun, Pats).
+fold_literals(TreeList) ->
+ [cerl:fold_literal(Tree) || Tree <- TreeList].
+
+type(Tree) ->
+ Folded = cerl:fold_literal(Tree),
+ case cerl:type(Folded) of
+ literal -> {literal, Folded};
+ Type -> Type
+ end.
+
+is_literal(Tree) ->
+ Folded = cerl:fold_literal(Tree),
+ case cerl:is_literal(Folded) of
+ true -> {yes, Folded};
+ false -> no
+ end.
+
parent_allows_this(FunLbl, #state{callgraph = Callgraph, plt = Plt} =State) ->
case state__is_escaping(FunLbl, State) of
false -> false; % if it isn't escaping it can't be a return value
@@ -3422,18 +3446,18 @@ find_terminals(Tree) ->
M0 = cerl:call_module(Tree),
F0 = cerl:call_name(Tree),
A = length(cerl:call_args(Tree)),
- case cerl:is_literal(M0) andalso cerl:is_literal(F0) of
- false ->
- %% We cannot make assumptions. Say that both are true.
- {true, true};
- true ->
- M = cerl:concrete(M0),
- F = cerl:concrete(F0),
+ case {is_literal(M0), is_literal(F0)} of
+ {{yes, LitM}, {yes, LitF}} ->
+ M = cerl:concrete(LitM),
+ F = cerl:concrete(LitF),
case (erl_bif_types:is_known(M, F, A)
andalso t_is_none(erl_bif_types:type(M, F, A))) of
true -> {true, false};
false -> {false, true}
- end
+ end;
+ _ ->
+ %% We cannot make assumptions. Say that both are true.
+ {true, true}
end;
'case' -> find_terminals_list(cerl:case_clauses(Tree));
'catch' -> find_terminals(cerl:catch_body(Tree));
@@ -3478,66 +3502,6 @@ find_terminals_list([], Explicit, Normal) ->
%%----------------------------------------------------------------------------
-%% If you write a record pattern in a matching that violates the
-%% definition it will never match. However, the warning is lost in the
-%% regular analysis. This after-pass catches it.
-
-find_mismatched_record_patterns(Tree, State) ->
- cerl_trees:fold(
- fun(SubTree, AccState) ->
- case cerl:is_c_clause(SubTree) of
- true -> lists:foldl(fun(P, AccState1) ->
- find_rec_warnings(P, AccState1)
- end, AccState, cerl:clause_pats(SubTree));
- false -> AccState
- end
- end, State, Tree).
-
-find_rec_warnings(Tree, State) ->
- cerl_trees:fold(
- fun(SubTree, AccState) ->
- case cerl:is_c_tuple(SubTree) of
- true -> find_rec_warnings_tuple(SubTree, AccState);
- false -> AccState
- end
- end, State, Tree).
-
-find_rec_warnings_tuple(Tree, State) ->
- Elements = cerl:tuple_es(Tree),
- {_, _, EsType} = traverse_list(Elements, map__new(), State),
- TupleType = t_tuple(EsType),
- case t_is_none(TupleType) of
- true -> State;
- false ->
- %% Let's find out if this is a record construction.
- case Elements of
- [Tag|Left] ->
- case cerl:is_c_atom(Tag) of
- true ->
- TagVal = cerl:atom_val(Tag),
- case state__lookup_record(TagVal, length(Left), State) of
- error -> State;
- {ok, Prototype} ->
- InfTupleType = t_inf(Prototype, TupleType),
- case t_is_none(InfTupleType) of
- true ->
- Msg = {record_matching,
- [format_patterns([Tree]), TagVal]},
- state__add_warning(State, ?WARN_MATCHING, Tree, Msg);
- false ->
- State
- end
- end;
- false ->
- State
- end;
- _ ->
- State
- end
- end.
-
-%%----------------------------------------------------------------------------
-
-ifdef(DEBUG_PP).
debug_pp(Tree, true) ->
io:put_chars(cerl_prettypr:format(Tree, [{hook, cerl_typean:pp_hook()}])),
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index 28c2ad2c0b..2a8aba5d8f 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -1848,7 +1848,8 @@ ets_tuple_argtypes1(Str, Tuple, TupleList, NestingLevel) ->
end.
format_arg(?bypassed) -> ?no_label;
-format_arg(Arg) ->
+format_arg(Arg0) ->
+ Arg = cerl:fold_literal(Arg0),
case cerl:type(Arg) of
var -> cerl_trees:get_label(Arg);
tuple -> list_to_tuple([format_arg(A) || A <- cerl:tuple_es(Arg)]);
@@ -1878,7 +1879,7 @@ format_args_1([Arg|Args], [Type|Types], CleanState) ->
case Arg =:= ?bypassed of
true -> [?no_label, format_type(Type, CleanState)];
false ->
- case cerl:is_literal(Arg) of
+ case cerl:is_literal(cerl:fold_literal(Arg)) of
true -> [?no_label, format_cerl(Arg)];
false -> [format_arg(Arg), format_type(Type, CleanState)]
end
@@ -2148,7 +2149,8 @@ race_var_map_guard_helper1(Arg, Pats, RaceVarMap, Op) ->
end
end.
-race_var_map_guard_helper2(Arg, Pat, Bool, RaceVarMap, Op) ->
+race_var_map_guard_helper2(Arg, Pat0, Bool, RaceVarMap, Op) ->
+ Pat = cerl:fold_literal(Pat0),
case cerl:type(Pat) of
literal ->
[Arg1, Arg2] = cerl:call_args(Arg),
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index 31ceaf5ac5..3d03ed3ab3 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -389,13 +389,8 @@ traverse(Tree, DefinedVars, State) ->
{State2, _} = traverse_list(Funs, DefinedVars1, State1),
traverse(Body, DefinedVars1, State2);
literal ->
- %% This is needed for finding records
- case cerl:unfold_literal(Tree) of
- Tree ->
- Type = t_from_term(cerl:concrete(Tree)),
- {State, Type};
- NewTree -> traverse(NewTree, DefinedVars, State)
- end;
+ Type = t_from_term(cerl:concrete(Tree)),
+ {State, Type};
module ->
Defs = cerl:module_defs(Tree),
Funs = [Fun || {_Var, Fun} <- Defs],
@@ -462,7 +457,7 @@ traverse(Tree, DefinedVars, State) ->
end,
case Elements of
[Tag|Fields] ->
- case cerl:is_c_atom(Tag) of
+ case cerl:is_c_atom(Tag) andalso is_literal_record(Tree) of
true ->
%% Check if a record is constructed.
Arity = length(Fields),
@@ -874,7 +869,8 @@ get_underapprox_from_guard(Tree, Map) ->
MFA ->
case get_type_test(MFA) of
{ok, Type} ->
- [Arg] = cerl:call_args(Tree),
+ [Arg0] = cerl:call_args(Tree),
+ Arg = cerl:fold_literal(Arg0),
{ArgType, Map1} = get_underapprox_from_guard(Arg, Map),
Inf = t_inf(Type, ArgType),
case t_is_none(Inf) of
@@ -891,7 +887,9 @@ get_underapprox_from_guard(Tree, Map) ->
{erlang, '=:=', 2} -> throw(dont_know);
{erlang, '==', 2} -> throw(dont_know);
{erlang, 'and', 2} ->
- [Arg1, Arg2] = cerl:call_args(Tree),
+ [Arg1_0, Arg2_0] = cerl:call_args(Tree),
+ Arg1 = cerl:fold_literal(Arg1_0),
+ Arg2 = cerl:fold_literal(Arg2_0),
case ((cerl:is_c_var(Arg1) orelse cerl:is_literal(Arg1))
andalso
(cerl:is_c_var(Arg2) orelse cerl:is_literal(Arg2))) of
@@ -3272,6 +3270,10 @@ lookup_record(Records, Tag, Arity) ->
error
end.
+is_literal_record(Tree) ->
+ Ann = cerl:get_ann(Tree),
+ lists:member(record, Ann).
+
family(L) ->
sofs:to_external(sofs:rel2fam(sofs:relation(L))).
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 21183e3459..e1bcd72c0b 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -402,7 +402,7 @@ sets_filter([Mod|Mods], ExpTypes) ->
src_compiler_opts() ->
[no_copt, to_core, binary, return_errors,
no_inline, strict_record_tests, strict_record_updates,
- no_is_record_optimization].
+ dialyzer].
-spec get_module(abstract_code()) -> module().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/simple b/lib/dialyzer/test/opaque_SUITE_data/results/simple
index 072ac9be8f..29864d6065 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/simple
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/simple
@@ -14,12 +14,17 @@ is_rec.erl:53: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1()
is_rec.erl:57: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opaqueness of its argument
is_rec.erl:61: The record #r{f1::simple1_adt:d1()} violates the declared type for #r{}
is_rec.erl:65: The call erlang:is_record({simple1_adt:d1(),1},'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions
-rec_api.erl:22: Record construction #r1{f1::10} violates the declared type of field f1::'undefined' | rec_api:a()
-rec_api.erl:23: The pattern {'r1', 10} violates the declared type for #r1{}
-rec_api.erl:27: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opaqueness of the term
-rec_api.erl:29: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1::'a'}) -> #r1{f1::'a'}
-rec_api.erl:34: Invalid type specification for function rec_api:adt_r1/0. The success typing is () -> #r1{f1::'a'}
-rec_api.erl:77: The attempt to match a term of type rec_api:f() against the variable _ breaks the opaqueness of the term
+rec_api.erl:104: Matching of pattern {'r2', 10} tagged with a record name violates the declared type of #r2{f1::10}
+rec_api.erl:113: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opaqueness of queue:queue(_)
+rec_api.erl:118: Record construction #r3{f1::10} violates the declared type of field f1::queue:queue(_)
+rec_api.erl:123: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opaqueness of queue:queue(_)
+rec_api.erl:24: Record construction #r1{f1::10} violates the declared type of field f1::'undefined' | rec_api:a()
+rec_api.erl:29: Matching of pattern {'r1', 10} tagged with a record name violates the declared type of #r1{f1::10}
+rec_api.erl:33: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opaqueness of the term
+rec_api.erl:35: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1::'a'}) -> #r1{f1::'a'}
+rec_api.erl:40: Invalid type specification for function rec_api:adt_r1/0. The success typing is () -> #r1{f1::'a'}
+rec_api.erl:85: The attempt to match a term of type rec_api:f() against the variable _ breaks the opaqueness of rec_adt:f()
+rec_api.erl:99: Record construction #r2{f1::10} violates the declared type of field f1::rec_api:a()
simple1_api.erl:113: The test simple1_api:d1() =:= simple1_api:d2() can never evaluate to 'true'
simple1_api.erl:118: Guard test simple1_api:d2() =:= A::simple1_api:d1() can never succeed
simple1_api.erl:142: Attempt to test for equality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1()
@@ -58,7 +63,7 @@ simple1_api.erl:381: Invalid type specification for function simple1_api:bool_ad
simple1_api.erl:407: The size simple1_adt:i1() breaks the opaqueness of A
simple1_api.erl:418: The attempt to match a term of type non_neg_integer() against the variable A breaks the opaqueness of simple1_adt:i1()
simple1_api.erl:425: The attempt to match a term of type non_neg_integer() against the variable B breaks the opaqueness of simple1_adt:i1()
-simple1_api.erl:432: The attempt to match a term of type non_neg_integer() against the variable B breaks the opaqueness of simple1_api:o1()
+simple1_api.erl:432: The pattern <<_:B/integer-unit:1>> can never match the type any()
simple1_api.erl:448: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opaqueness of simple1_adt:i1()
simple1_api.erl:460: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary-unit:8>> breaks the opaqueness of the term
simple1_api.erl:478: The call 'foo':A(A::simple1_adt:a()) breaks the opaqueness of the term A :: simple1_adt:a()
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/timer b/lib/dialyzer/test/opaque_SUITE_data/results/timer
index e917b76b08..b1cfcd4e9f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/timer
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/timer
@@ -1,4 +1,4 @@
timer_use.erl:16: The pattern 'gazonk' can never match the type {'error',_} | {'ok',timer:tref()}
-timer_use.erl:17: The attempt to match a term of type {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opaqueness of timer:tref()
+timer_use.erl:17: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opaqueness of timer:tref()
timer_use.erl:18: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opaqueness of timer:tref()
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
index d9b1d59f0c..fb6d59d263 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
@@ -1,9 +1,9 @@
-module(rec_api).
--export([t1/0, t2/0, adt_t1/0, adt_t1/1, adt_r1/0,
- t/1, t_adt/0, r/0, r_adt/0]).
+-export([t1/0, t2/0, t3/0, adt_t1/0, adt_t1/1, adt_r1/0,
+ t/1, t_adt/0, r/0, r_adt/0, u1/0, u2/0, u3/0, v1/0, v2/0, v3/0]).
--export_type([{a,0},{r1,0}]).
+-export_type([{a,0},{r1,0}, r2/0, r3/0]).
-export_type([f/0, op_t/0, r/0, tup/0]).
@@ -19,8 +19,14 @@ t1() ->
{r1, a} = A.
t2() ->
- A = {r1, 10}, % violates the type of #r1{}
- {r1, 10} = A. % violates the type of #r1{}
+ A = {r1, 10},
+ {r1, 10} = A,
+ A = #r1{f1 = 10}, % violates the type of field f1
+ #r1{f1 = 10} = A.
+
+t3() ->
+ A = {r1, 10},
+ #r1{f1 = 10} = A. % violates the type of #r1{}
adt_t1() ->
R = rec_adt:r1(),
@@ -66,7 +72,8 @@ t_adt() ->
-spec r() -> _.
r() ->
- {r, f(), 2}. % OK, f() is a local opaque type
+ {{r, f(), 2},
+ #r{f = f(), o = 2}}. % OK, f() is a local opaque type
-spec f() -> f().
@@ -74,4 +81,43 @@ f() ->
fun(_) -> 3 end.
r_adt() ->
- {r, rec_adt:f(), 2}. % breaks the opaqueness
+ {{r, rec_adt:f(), 2},
+ #r{f = rec_adt:f(), o = 2}}. % breaks the opaqueness
+
+-record(r2, % like #r1{}, but with initial value
+ {f1 = a :: a()}).
+
+-opaque r2() :: #r2{}.
+
+u1() ->
+ A = #r2{f1 = a},
+ {r2, a} = A.
+
+u2() ->
+ A = {r2, 10},
+ {r2, 10} = A,
+ A = #r2{f1 = 10}, % violates the type of field f1
+ #r2{f1 = 10} = A.
+
+u3() ->
+ A = {r2, 10},
+ #r2{f1 = 10} = A. % violates the type of #r2{}
+
+-record(r3, % like #r1{}, but an opaque type
+ {f1 = queue:new():: queue:queue()}).
+
+-opaque r3() :: #r3{}.
+
+v1() ->
+ A = #r3{f1 = queue:new()},
+ {r3, a} = A. % breaks the opaqueness
+
+v2() ->
+ A = {r3, 10},
+ {r3, 10} = A,
+ A = #r3{f1 = 10}, % violates the type of field f1
+ #r3{f1 = 10} = A.
+
+v3() ->
+ A = {r3, 10},
+ #r3{f1 = 10} = A. % breaks the opaqueness
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
index 5135eb8e59..eef2074e0c 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
@@ -428,8 +428,8 @@ bit_adt_t3(A) ->
bit_t5(A) ->
B = o1(),
- case none:none() of
- <<A:B>> -> 1 % breaks the opaqueness
+ case none:none() of % the type is any(); should fix that XXX
+ <<A:B>> -> 1 % can never match (local opaque type is OK)
end.
-spec bit_t4(<<_:1>>) -> integer().
diff --git a/lib/dialyzer/test/options1_SUITE_data/results/compiler b/lib/dialyzer/test/options1_SUITE_data/results/compiler
index 6399e3e36b..30b6f4814a 100644
--- a/lib/dialyzer/test/options1_SUITE_data/results/compiler
+++ b/lib/dialyzer/test/options1_SUITE_data/results/compiler
@@ -4,7 +4,7 @@ beam_bool.erl:193: The pattern {[], _} can never match the type {[{_,_,_,_},...]
beam_bool.erl:510: The pattern [{'set', [Dst], _, _}, {'%live', _}] can never match the type [{_,_,_,_}]
beam_disasm.erl:537: The variable X can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
beam_type.erl:284: The pattern <'pi', 0> can never match the type <_,1 | 2>
-beam_validator.erl:396: The pattern <{'jump', {'f', _}}, Vst = {'vst', 'none', _}> can never match the type <_,#vst{current::#st{ct::[]}}>
+beam_validator.erl:396: Matching of pattern {'vst', 'none', _} tagged with a record name violates the declared type of #vst{current::#st{ct::[]}}
beam_validator.erl:690: The pattern <'term', OldT> can never match the type <{'tuple',[any(),...]},_>
beam_validator.erl:693: Guard test 'or'('false','false') can never succeed
beam_validator.erl:700: Guard test 'or'('false','false') can never succeed
@@ -33,4 +33,4 @@ core_lint.erl:473: The pattern <{'c_atom', _, 'all'}, 'binary', _Def, St> can ne
core_lint.erl:505: The pattern <_Req, 'unknown', St> can never match the type <non_neg_integer(),non_neg_integer(),_>
v3_codegen.erl:1569: The call v3_codegen:load_reg_1(V::any(),I::0,Rs::any(),pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0)
v3_codegen.erl:1571: The call v3_codegen:load_reg_1(V::any(),I::0,[],pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0)
-v3_core.erl:646: The pattern <Prim = {'iprimop', _, _, _}, St> can never match the type <#c_nil{anno::[any(),...]} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple' | 'c_var' | 'ibinary' | 'icatch' | 'ireceive1',[any(),...] | {_,_,_,_},_} | #c_cons{anno::[any(),...]} | #c_fname{anno::[any(),...]} | #iletrec{anno::{_,_,_,_},defs::[any(),...],body::[any(),...]} | #icase{anno::{_,_,_,_},args::[any()],clauses::[any()],fc::{_,_,_,_,_,_}} | #ireceive2{anno::{_,_,_,_},clauses::[any()],action::[any()]} | #ifun{anno::{_,_,_,_},id::[any(),...],vars::[any()],clauses::[any(),...],fc::{_,_,_,_,_,_}} | #imatch{anno::{_,_,_,_},guard::[],fc::{_,_,_,_,_,_}} | #itry{anno::{_,_,_,_},args::[any()],vars::[any(),...],body::[any(),...],evars::[any(),...],handler::[any(),...]},_>
+v3_core.erl:646: Matching of pattern {'iprimop', _, _, _} tagged with a record name violates the declared type of #c_nil{anno::[any(),...]} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple' | 'c_var' | 'ibinary' | 'icatch' | 'ireceive1',[any(),...] | {_,_,_,_},_} | #c_cons{anno::[any(),...]} | #c_fname{anno::[any(),...]} | #iletrec{anno::{_,_,_,_},defs::[any(),...],body::[any(),...]} | #icase{anno::{_,_,_,_},args::[any()],clauses::[any()],fc::{_,_,_,_,_,_}} | #ireceive2{anno::{_,_,_,_},clauses::[any()],action::[any()]} | #ifun{anno::{_,_,_,_},id::[any(),...],vars::[any()],clauses::[any(),...],fc::{_,_,_,_,_,_}} | #imatch{anno::{_,_,_,_},guard::[],fc::{_,_,_,_,_,_}} | #itry{anno::{_,_,_,_},args::[any()],vars::[any(),...],body::[any(),...],evars::[any(),...],handler::[any(),...]}
diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/asn1 b/lib/dialyzer/test/r9c_SUITE_data/results/asn1
index c11105b76d..1cf03346ee 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/results/asn1
+++ b/lib/dialyzer/test/r9c_SUITE_data/results/asn1
@@ -5,7 +5,7 @@ asn1ct.erl:1673: The pattern 'all' can never match the type 'asn1_module' | 'exc
asn1ct.erl:672: The pattern <{'false', Result}, _, _> can never match the type <{'true','true'},atom() | binary() | [atom() | [any()] | char()],[any()]>
asn1ct.erl:909: Guard test is_atom(Ext::[49 | 97 | 98 | 100 | 110 | 115]) can never succeed
asn1ct_check.erl:1698: The pattern {'error', _} can never match the type [any()]
-asn1ct_check.erl:2733: The pattern {'type', Tag, _, _, _, _} can never match the type 'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_}
+asn1ct_check.erl:2733: Matching of pattern {'type', Tag, _, _, _, _} tagged with a record name violates the declared type of 'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_}
asn1ct_check.erl:2738: The pattern <_S, _> can never match since previous clauses completely covered the type <#state{},#'ObjectClassFieldType'{class::#objectclass{fields::maybe_improper_list() | {_,_,_,_}},fieldname::{_,maybe_improper_list()},type::'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_}}>
asn1ct_check.erl:2887: The variable Other can never match since previous clauses completely covered the type any()
asn1ct_check.erl:3188: The pattern <_S, [], B> can never match the type <#state{},{'SingleValue',_},{'ValueRange',_}>
diff --git a/lib/dialyzer/test/small_SUITE_data/results/confusing_record_warning b/lib/dialyzer/test/small_SUITE_data/results/confusing_record_warning
deleted file mode 100644
index ac3d89b02b..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/results/confusing_record_warning
+++ /dev/null
@@ -1,3 +0,0 @@
-
-confusing_record_warning.erl:18: Function test/1 has no local return
-confusing_record_warning.erl:18: Matching of pattern {'r', [_]} tagged with a record name violates the declared type of #r{field::'binary' | 'undefined'}
diff --git a/lib/dialyzer/test/small_SUITE_data/results/literals b/lib/dialyzer/test/small_SUITE_data/results/literals
new file mode 100644
index 0000000000..03e161ca71
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/literals
@@ -0,0 +1,14 @@
+
+literals.erl:11: Function t1/0 has no local return
+literals.erl:12: Record construction #r{id::'a'} violates the declared type of field id::'integer' | 'undefined'
+literals.erl:14: Function t2/0 has no local return
+literals.erl:15: Record construction #r{id::'a'} violates the declared type of field id::'integer' | 'undefined'
+literals.erl:17: Function t3/0 has no local return
+literals.erl:18: Record construction #r{id::'a'} violates the declared type of field id::'integer' | 'undefined'
+literals.erl:21: Record construction #r{id::'a'} violates the declared type of field id::'integer' | 'undefined'
+literals.erl:23: Function m1/1 has no local return
+literals.erl:23: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer' | 'undefined'}
+literals.erl:26: Function m2/1 has no local return
+literals.erl:26: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer' | 'undefined'}
+literals.erl:29: Function m3/1 has no local return
+literals.erl:29: The pattern {{'r', 'a'}} can never match the type any()
diff --git a/lib/dialyzer/test/small_SUITE_data/results/my_sofs b/lib/dialyzer/test/small_SUITE_data/results/my_sofs
index bc97c08d62..0b933e6cd7 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/my_sofs
+++ b/lib/dialyzer/test/small_SUITE_data/results/my_sofs
@@ -1,3 +1,3 @@
-my_sofs.erl:34: The pattern {'Set', _, _} can never match the type #'OrdSet'{}
-my_sofs.erl:54: The pattern {'Set', _, _} can never match the type #'OrdSet'{}
+my_sofs.erl:34: Matching of pattern {'Set', _, _} tagged with a record name violates the declared type of #'OrdSet'{}
+my_sofs.erl:54: Matching of pattern {'Set', _, _} tagged with a record name violates the declared type of #'OrdSet'{}
diff --git a/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring b/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring
new file mode 100644
index 0000000000..0ad6eee766
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring
@@ -0,0 +1,3 @@
+
+pretty_bitstring.erl:7: Function t/0 has no local return
+pretty_bitstring.erl:8: The call binary:copy(#{#<1>(8, 1, 'integer', ['unsigned', 'big']), #<2>(8, 1, 'integer', ['unsigned', 'big']), #<3>(3, 1, 'integer', ['unsigned', 'big'])}#,2) breaks the contract (Subject,N) -> binary() when is_subtype(Subject,binary()), is_subtype(N,non_neg_integer())
diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_pat b/lib/dialyzer/test/small_SUITE_data/results/record_pat
index 9a3f925e42..a46be6c451 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/record_pat
+++ b/lib/dialyzer/test/small_SUITE_data/results/record_pat
@@ -1,2 +1,2 @@
-record_pat.erl:14: The pattern {'foo', 'baz'} violates the declared type for #foo{}
+record_pat.erl:14: Matching of pattern {'foo', 'baz'} tagged with a record name violates the declared type of #foo{bar::'undefined' | integer()}
diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_test b/lib/dialyzer/test/small_SUITE_data/results/record_test
index 9715f0dcfb..7060bfa200 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/record_test
+++ b/lib/dialyzer/test/small_SUITE_data/results/record_test
@@ -1,3 +1,3 @@
-record_test.erl:19: The pattern {'foo', _} can never match the type 'foo'
+record_test.erl:19: Matching of pattern {'foo', _} tagged with a record name violates the declared type of 'foo'
record_test.erl:21: The variable _ can never match since previous clauses completely covered the type 'foo'
diff --git a/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning b/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning
new file mode 100644
index 0000000000..2e417e1b2a
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning
@@ -0,0 +1,3 @@
+
+relevant_record_warning.erl:22: Function test/1 has no local return
+relevant_record_warning.erl:23: Record construction #r{field::<<_:8>>} violates the declared type of field field::'binary' | 'undefined'
diff --git a/lib/dialyzer/test/small_SUITE_data/src/fun2ms.erl b/lib/dialyzer/test/small_SUITE_data/src/fun2ms.erl
new file mode 100644
index 0000000000..9e7df85e4c
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/fun2ms.erl
@@ -0,0 +1,21 @@
+-module(fun2ms).
+-export([return/0]).
+-include_lib("stdlib/include/ms_transform.hrl").
+
+-record(snapshot, {id :: integer(), arg1 :: atom(), arg2 :: tuple()}).
+
+return() ->
+ TableId = ets:new(table, [public, {keypos, #snapshot.id}]),
+
+ ets:insert(TableId, [#snapshot{id = 1, arg1 = hard, arg2 = {1,2}},
+ #snapshot{id = 2, arg1 = rock, arg2 = {1,2}},
+ #snapshot{id = 3, arg1 = hallelujah, arg2 =
+ {1,2}}]),
+
+
+ Example = ets:fun2ms(
+ fun(#snapshot{id = Arg1, arg1 = Arg2}) ->
+ {Arg1, Arg2}
+ end),
+
+ ets:select(TableId, Example).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/literals.erl b/lib/dialyzer/test/small_SUITE_data/src/literals.erl
new file mode 100644
index 0000000000..abd7033712
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/literals.erl
@@ -0,0 +1,33 @@
+-module(literals).
+
+%% Bad records inside structures used to be ignored. The reason:
+%% v3_core:unfold() does not annotate the parts of a literal.
+%% This example does not work perfectly yet, in particular Maps.
+
+-export([t1/0, t2/0, t3/0, t4/0, m1/1, m2/1, m3/1, m4/1]).
+
+-record(r, {id :: integer}).
+
+t1() ->
+ #r{id = a}. % violation
+
+t2() ->
+ [#r{id = a}]. % violation
+
+t3() ->
+ {#r{id = a}}. % violation
+
+t4() ->
+ #{a => #r{id = a}}. % violation found, but t4() returns... (bug)
+
+m1(#r{id = a}) -> % violation
+ ok.
+
+m2([#r{id = a}]) -> % violation
+ ok.
+
+m3({#r{id = a}}) -> % can never match; not so good
+ ok.
+
+m4(#{a := #r{id = a}}) -> % violation not found
+ ok.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/pretty_bitstring.erl b/lib/dialyzer/test/small_SUITE_data/src/pretty_bitstring.erl
new file mode 100644
index 0000000000..3dbf5ab7a7
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/pretty_bitstring.erl
@@ -0,0 +1,8 @@
+%% Prettyprint bitstrings.
+
+-module(pretty_bitstring).
+
+-export([t/0]).
+
+t() ->
+ binary:copy(<<1,2,3:3>>,2).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/confusing_record_warning.erl b/lib/dialyzer/test/small_SUITE_data/src/relevant_record_warning.erl
index 8af74e0914..3ff65458df 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/confusing_record_warning.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/relevant_record_warning.erl
@@ -1,3 +1,7 @@
+%% Formerly confusing_record_warning.erl.
+%% The warning output is relevant as of Erlang/OTP 17.1.
+%% The original comment kept below.
+
%%---------------------------------------------------------------------
%% A user complained that dialyzer produces a weird warning for the
%% following program. I explained to him that there is an implicit
@@ -9,7 +13,7 @@
%% The pattern {'r', [_]} can never match the type any()
%% We should clearly give some less confusing warning in this case.
%%---------------------------------------------------------------------
--module(confusing_record_warning).
+-module(relevant_record_warning).
-export([test/1]).
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 95d2464e1d..b0cb3ec4f9 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 2.7
+DIALYZER_VSN = 2.7.1
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index 68e69dbfeb..d89e1dfd26 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -42,6 +42,135 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>diameter 1.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Improve robustness.</p>
+ <p>
+ Counters returned by diameter:service_info/2 now only
+ count messages known to the dictionary in question, so
+ that an attacker cannot cause arbitrarily many counters
+ to be created.</p>
+ <p>
+ Messages to the Erlang log have been minimized, and those
+ related to traffic have been removed entirely since an
+ attacker could cause a node to be logged to death.
+ Consequently, the default answer_errors configuration has
+ been changed from report to discard. A service needs to
+ be restarted for the change in default to take effect.</p>
+ <p>
+ Own Id: OTP-11721</p>
+ </item>
+ <item>
+ <p>
+ Fix request table leak.</p>
+ <p>
+ Outgoing Diameter requests are stored in a table until an
+ answer is received or times out. Calling
+ diameter:stop_service/1 before this took place would
+ orphan the entries, resulting in a memory leak.</p>
+ <p>
+ Own Id: OTP-11893</p>
+ </item>
+ <item>
+ <p>
+ Fix broken SCTP transport.</p>
+ <p>
+ OTP-11593 caused the sending of answer messages over SCTP
+ to fail.</p>
+ <p>
+ Own Id: OTP-11901 Aux Id: OTP-11593 </p>
+ </item>
+ <item>
+ <p>
+ Fix watchdog process leak.</p>
+ <p>
+ A failed capabilities exchange on a listening transport
+ would orphan a process, causing a memory leak.</p>
+ <p>
+ Own Id: OTP-11934</p>
+ </item>
+ <item>
+ <p>
+ Fix incorrect handling of incoming DPR.</p>
+ <p>
+ In the case of a listening transport, a reconnection by a
+ peer following DPR could transition the watchdog state to
+ REOPEN instead of OKAY.</p>
+ <p>
+ Own Id: OTP-11938</p>
+ </item>
+ <item>
+ <p>
+ Fix handling of AVP length errors on unknown AVPs.</p>
+ <p>
+ An AVP (Header) length that pointed past the end of the
+ message was not flagged as a 5014 error in this case.
+ Moreover, encoding such an AVP in the Failed-AVP of an
+ answer message as a consequence of other errors (eg.
+ M-bit, resulting in 5001) failed if the AVP contained a
+ complete header.</p>
+ <p>
+ Own Id: OTP-11946</p>
+ </item>
+ <item>
+ <p>
+ Fix broken check in dictionary compilation.</p>
+ <p>
+ That an AVP specified in the content of a @codecs or
+ @custom_types section was undefined went undetected,
+ causing compilation to fail when attempting to lookup the
+ AVP's type.</p>
+ <p>
+ Own Id: OTP-11958</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add result code counters for CEA, DWA, and DPA.</p>
+ <p>
+ In addition to the existing result code counters on other
+ answer messages.</p>
+ <p>
+ Own Id: OTP-11891</p>
+ </item>
+ <item>
+ <p>
+ Add best-effort decode of AVPs within Failed-AVP.</p>
+ <p>
+ OTP-11007 disabled the decode of AVPs in Failed-AVP since
+ errors could cause the decode of Failed-AVP itself to
+ fail. Component AVPs are now decoded if possible,
+ otherwise not. AVPs of type Grouped are decoded as much
+ as possible, as deeply as possible.</p>
+ <p>
+ Own Id: OTP-11936 Aux Id: OTP-11007 </p>
+ </item>
+ <item>
+ <p>
+ Add counters for encode errors in outgoing Diameter
+ messages.</p>
+ <p>
+ In addition to the existing counters on decode errors.
+ The latter now count independently of result codes in
+ answer messages since decode errors do not preclude the
+ presence of a result code.</p>
+ <p>
+ Own Id: OTP-11937</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>diameter 1.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src
index b7b9662383..3b6e259f5a 100644
--- a/lib/diameter/src/diameter.appup.src
+++ b/lib/diameter/src/diameter.appup.src
@@ -43,7 +43,7 @@
{load_module, diameter_gen_base_rfc6733},
{load_module, diameter_gen_acct_rfc6733},
{load_module, diameter_gen_base_rfc3588},
- {load_module, diameter_gen_accounting},
+ {load_module, diameter_gen_base_accounting},
{load_module, diameter_gen_relay},
{load_module, diameter_codec},
{load_module, diameter_sctp}]}
@@ -67,7 +67,7 @@
{"1.6", [{load_module, diameter_sctp},
{load_module, diameter_codec},
{load_module, diameter_gen_relay},
- {load_module, diameter_gen_accounting},
+ {load_module, diameter_gen_base_accounting},
{load_module, diameter_gen_base_rfc3588},
{load_module, diameter_gen_acct_rfc6733},
{load_module, diameter_gen_base_rfc6733},
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index d7cbfa1fdc..b3440ce6e1 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -31,6 +31,25 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.14</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The default encoding for Erlang source files is now
+ UTF-8. As a temporary measure to ease the transition from
+ the old default of Latin-1, if EDoc encounters byte
+ sequences that are not valid UTF-8 sequences, EDoc will
+ re-try in Latin-1 mode. This workaround will be removed
+ in a future release. </p>
+ <p>
+ Own Id: OTP-12008</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.13</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/edoc/src/edoc.erl b/lib/edoc/src/edoc.erl
index a87a8471e3..983f04e8b6 100644
--- a/lib/edoc/src/edoc.erl
+++ b/lib/edoc/src/edoc.erl
@@ -696,15 +696,44 @@ read_source_2(Name, Opts) ->
%% The line of the dot token will be copied to the integer token.
parse_file(Name, Includes, Macros) ->
- case epp:open(Name, Includes, Macros) of
- {ok, Epp} ->
- try {ok, parse_file(Epp)}
+ case parse_file(utf8, Name, Includes, Macros) of
+ invalid_unicode ->
+ parse_file(latin1, Name, Includes, Macros);
+ Ret ->
+ Ret
+ end.
+
+parse_file(DefEncoding, Name, Includes, Macros) ->
+ Options = [{name, Name},
+ {includes, Includes},
+ {macros, Macros},
+ {default_encoding, DefEncoding}],
+ case epp:open([extra | Options]) of
+ {ok, Epp, Extra} ->
+ try parse_file(Epp) of
+ Forms ->
+ Encoding = proplists:get_value(encoding, Extra),
+ case find_invalid_unicode(Forms) of
+ invalid_unicode when Encoding =/= utf8 ->
+ invalid_unicode;
+ _ ->
+ {ok, Forms}
+ end
after _ = epp:close(Epp)
end;
Error ->
Error
end.
+find_invalid_unicode([H|T]) ->
+ case H of
+ {error,{_Line,file_io_server,invalid_unicode}} ->
+ invalid_unicode;
+ _Other ->
+ find_invalid_unicode(T)
+ end;
+find_invalid_unicode([]) -> none.
+
parse_file(Epp) ->
case scan_and_parse(Epp) of
{ok, Form} ->
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index e164ff060f..f4e78e8f3a 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -885,7 +885,7 @@ t_map(Es) ->
["#{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
t_map_field([K,V]) ->
- [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)].
+ t_utype_elem(K) ++ [" => "] ++ t_utype_elem(V).
t_record(E, Es) ->
Name = ["#"] ++ t_type(get_elem(atom, Es)),
@@ -1082,6 +1082,10 @@ ot_type([#xmlElement{name = nonempty_list, content = Es}]) ->
ot_nonempty_list(Es);
ot_type([#xmlElement{name = tuple, content = Es}]) ->
ot_tuple(Es);
+ot_type([#xmlElement{name = map, content = Es}]) ->
+ ot_map(Es);
+ot_type([#xmlElement{name = map_field, content = Es}]) ->
+ ot_map_field(Es);
ot_type([#xmlElement{name = 'fun', content = Es}]) ->
ot_fun(Es);
ot_type([#xmlElement{name = record, content = Es}]) ->
@@ -1138,6 +1142,12 @@ ot_nonempty_list(Es) ->
ot_tuple(Es) ->
{type,0,tuple,[ot_utype_elem(E) || E <- Es]}.
+ot_map(Es) ->
+ {type,0,map,[ot_utype_elem(E) || E <- Es]}.
+
+ot_map_field(Es) ->
+ {type,0,map_field_assoc,[ot_utype_elem(E) || E <- Es]}.
+
ot_fun(Es) ->
Range = ot_utype(get_elem(type, Es)),
Args = [ot_utype_elem(A) || A <- get_content(argtypes, Es)],
diff --git a/lib/edoc/test/edoc_SUITE.erl b/lib/edoc/test/edoc_SUITE.erl
index c9c7811afb..c63660c8c0 100644
--- a/lib/edoc/test/edoc_SUITE.erl
+++ b/lib/edoc/test/edoc_SUITE.erl
@@ -22,12 +22,12 @@
init_per_group/2,end_per_group/2]).
%% Test cases
--export([app/1,appup/1,build_std/1,build_map_module/1]).
+-export([app/1,appup/1,build_std/1,build_map_module/1,otp_12008/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app,appup,build_std,build_map_module].
+ [app,appup,build_std,build_map_module,otp_12008].
groups() ->
[].
@@ -77,3 +77,21 @@ build_map_module(Config) when is_list(Config) ->
Filename = filename:join(DataDir, "map_module.erl"),
ok = edoc:file(Filename, [{dir, PrivDir}]),
ok.
+
+otp_12008(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Un1 = filename:join(DataDir, "un1.erl"),
+ Un2 = filename:join(DataDir, "un2.erl"),
+ Un3 = filename:join(DataDir, "un3.erl"),
+ %% epp_dodger
+ Opts1 = [{dir, PrivDir}],
+ ok = edoc:files([Un1], Opts1),
+ ok = edoc:files([Un2], Opts1),
+ {'EXIT', error} = (catch edoc:files([Un3], Opts1)),
+ %% epp
+ Opts2 = [{preprocess, true}, {dir, PrivDir}],
+ ok = edoc:files([Un1], Opts2),
+ ok = edoc:files([Un2], Opts2),
+ {'EXIT', error} = (catch edoc:files([Un3], Opts2)),
+ ok.
diff --git a/lib/edoc/test/edoc_SUITE_data/map_module.erl b/lib/edoc/test/edoc_SUITE_data/map_module.erl
index 94ee7e6f26..f242721637 100644
--- a/lib/edoc/test/edoc_SUITE_data/map_module.erl
+++ b/lib/edoc/test/edoc_SUITE_data/map_module.erl
@@ -1,6 +1,6 @@
-module(map_module).
--export([foo1/1,foo2/3]).
+-export([foo1/1,foo2/3,start_child/2]).
%% @type wazzup() = integer()
%% @type some_type() = map()
@@ -25,3 +25,43 @@ foo1(#{ a:= 1, b := V}) -> V.
Map :: #{ get => 'value', 'value' => binary()}) -> binary().
foo2(Type1, {a,#{ "a" := _}}, #{get := value, value := B}) when is_map(Type1) -> B.
+
+%% from supervisor 18.0
+
+-type child() :: 'undefined' | pid().
+-type child_id() :: term().
+-type mfargs() :: {M :: module(), F :: atom(), A :: [term()] | undefined}.
+-type modules() :: [module()] | 'dynamic'.
+-type restart() :: 'permanent' | 'transient' | 'temporary'.
+-type shutdown() :: 'brutal_kill' | timeout().
+-type worker() :: 'worker' | 'supervisor'.
+-type sup_ref() :: (Name :: atom())
+ | {Name :: atom(), Node :: node()}
+ | {'global', Name :: atom()}
+ | {'via', Module :: module(), Name :: any()}
+ | pid().
+-type child_spec() :: #{name => child_id(), % mandatory
+ start => mfargs(), % mandatory
+ restart => restart(), % optional
+ shutdown => shutdown(), % optional
+ type => worker(), % optional
+ modules => modules()} % optional
+ | {Id :: child_id(),
+ StartFunc :: mfargs(),
+ Restart :: restart(),
+ Shutdown :: shutdown(),
+ Type :: worker(),
+ Modules :: modules()}.
+
+-type startchild_err() :: 'already_present'
+ | {'already_started', Child :: child()} | term().
+-type startchild_ret() :: {'ok', Child :: child()}
+ | {'ok', Child :: child(), Info :: term()}
+ | {'error', startchild_err()}.
+
+
+-spec start_child(SupRef, ChildSpec) -> startchild_ret() when
+ SupRef :: sup_ref(),
+ ChildSpec :: child_spec() | (List :: [term()]).
+start_child(Supervisor, ChildSpec) ->
+ {Supervisor,ChildSpec}.
diff --git a/lib/edoc/test/edoc_SUITE_data/un1.erl b/lib/edoc/test/edoc_SUITE_data/un1.erl
new file mode 100644
index 0000000000..0c48e7f940
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/un1.erl
@@ -0,0 +1,7 @@
+-module(un1).
+
+-export([t/0]).
+
+%% @doc F�pp
+t() ->
+ �rlig.
diff --git a/lib/edoc/test/edoc_SUITE_data/un2.erl b/lib/edoc/test/edoc_SUITE_data/un2.erl
new file mode 100644
index 0000000000..a6d13f4723
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/un2.erl
@@ -0,0 +1,8 @@
+-module(un2).
+%% coding: latin-1
+
+-export([t/0]).
+
+%% @doc F�pp
+t() ->
+ �rlig.
diff --git a/lib/edoc/test/edoc_SUITE_data/un3.erl b/lib/edoc/test/edoc_SUITE_data/un3.erl
new file mode 100644
index 0000000000..fbe9591dce
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/un3.erl
@@ -0,0 +1,8 @@
+-module(un3).
+%% coding: utf-8
+
+-export([t/0]).
+
+%% @doc F�pp
+t() ->
+ �rlig.
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index 0172aac48b..281a792118 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.13
+EDOC_VSN = 0.7.14
diff --git a/lib/erl_docgen/src/docgen_otp_specs.erl b/lib/erl_docgen/src/docgen_otp_specs.erl
index 886194598f..cbdbbbee80 100644
--- a/lib/erl_docgen/src/docgen_otp_specs.erl
+++ b/lib/erl_docgen/src/docgen_otp_specs.erl
@@ -388,8 +388,10 @@ t_type([#xmlElement{name = nonempty_list, content = Es}]) ->
t_nonempty_list(Es);
t_type([#xmlElement{name = tuple, content = Es}]) ->
t_tuple(Es);
-t_type([#xmlElement{name = map}]) ->
- t_map();
+t_type([#xmlElement{name = map, content = Es}]) ->
+ t_map(Es);
+t_type([#xmlElement{name = map_field, content = Es}]) ->
+ t_map_field(Es);
t_type([#xmlElement{name = 'fun', content = Es}]) ->
["fun("] ++ t_fun(Es) ++ [")"];
t_type([E = #xmlElement{name = record, content = Es}]) ->
@@ -432,8 +434,11 @@ t_nonempty_list(Es) ->
t_tuple(Es) ->
["{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
-t_map() ->
- ["map()"].
+t_map(Es) ->
+ ["#{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
+
+t_map_field([K,V]) ->
+ [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)].
t_fun(Es) ->
["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es),
@@ -550,6 +555,10 @@ ot_type([#xmlElement{name = nonempty_list, content = Es}]) ->
ot_nonempty_list(Es);
ot_type([#xmlElement{name = tuple, content = Es}]) ->
ot_tuple(Es);
+ot_type([#xmlElement{name = map, content = Es}]) ->
+ ot_map(Es);
+ot_type([#xmlElement{name = map_field, content = Es}]) ->
+ ot_map_field(Es);
ot_type([#xmlElement{name = 'fun', content = Es}]) ->
ot_fun(Es);
ot_type([#xmlElement{name = record, content = Es}]) ->
@@ -606,6 +615,12 @@ ot_nonempty_list(Es) ->
ot_tuple(Es) ->
{type,0,tuple,[ot_utype_elem(E) || E <- Es]}.
+ot_map(Es) ->
+ {type,0,map,[ot_utype_elem(E) || E <- Es]}.
+
+ot_map_field(Es) ->
+ {type,0,map_field_assoc,[ot_utype_elem(E) || E <- Es]}.
+
ot_fun(Es) ->
Range = ot_utype(get_elem(type, Es)),
Args = [ot_utype_elem(A) || A <- get_content(argtypes, Es)],
diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in
index d511f2e240..ef78f0f87b 100644
--- a/lib/erl_interface/configure.in
+++ b/lib/erl_interface/configure.in
@@ -311,6 +311,26 @@ else
fi
fi
+dnl ----------------------------------------------------------------------
+dnl Enable -fsanitize= flags.
+dnl ----------------------------------------------------------------------
+
+m4_define(DEFAULT_SANITIZERS, [address,undefined])
+AC_ARG_ENABLE(
+ sanitizers,
+ AS_HELP_STRING(
+ [--enable-sanitizers@<:@=comma-separated list of sanitizers@:>@],
+ [Default=DEFAULT_SANITIZERS]),
+[
+case "$enableval" in
+ no) sanitizers= ;;
+ yes) sanitizers="-fsanitize=DEFAULT_SANITIZERS" ;;
+ *) sanitizers="-fsanitize=$enableval" ;;
+esac
+CFLAGS="$CFLAGS $sanitizers"
+LDFLAGS="$LDFLAGS $sanitizers"
+])
+
# ---------------------------------------------------------------------------
# XXX
# ---------------------------------------------------------------------------
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index ab6f4179d6..3f85af8956 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -30,6 +30,21 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.7.17</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Now works with Visual Studio.</p>
+ <p>
+ Own Id: OTP-11984</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.7.16</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index 8731283265..b1e612a9eb 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1,2 +1,2 @@
-EI_VSN = 3.7.16
+EI_VSN = 3.7.17
ERL_INTERFACE_VSN = $(EI_VSN)
diff --git a/lib/eunit/src/eunit_data.erl b/lib/eunit/src/eunit_data.erl
index 0350f9bf6e..cbbc6fbc15 100644
--- a/lib/eunit/src/eunit_data.erl
+++ b/lib/eunit/src/eunit_data.erl
@@ -440,13 +440,8 @@ parse_function({M, F}) when is_atom(M), is_atom(F) ->
parse_function(F) ->
bad_test(F).
-check_arity(F, N, T) when is_function(F) ->
- case erlang:fun_info(F, arity) of
- {arity, N} ->
- ok;
- _ ->
- bad_test(T)
- end;
+check_arity(F, N, _) when is_function(F, N) ->
+ ok;
check_arity(_, _, T) ->
bad_test(T).
diff --git a/lib/hipe/cerl/cerl_prettypr.erl b/lib/hipe/cerl/cerl_prettypr.erl
index 9a3873f46d..f4a67439d6 100644
--- a/lib/hipe/cerl/cerl_prettypr.erl
+++ b/lib/hipe/cerl/cerl_prettypr.erl
@@ -1,7 +1,7 @@
%% =====================================================================
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -476,13 +476,20 @@ lay_literal(Node, Ctxt) ->
%% that could represent printable characters - we
%% always print an integer.
text(int_lit(Node));
- V when is_binary(V) ->
- lay_binary(c_binary([c_bitstr(abstract(B),
- abstract(8),
+ V when is_bitstring(V) ->
+ Val = fun(I) when is_integer(I) -> I;
+ (B) when is_bitstring(B) ->
+ BZ = bit_size(B), <<BV:BZ>> = B, BV
+ end,
+ Sz = fun(I) when is_integer(I) -> 8;
+ (B) when is_bitstring(B) -> bit_size(B)
+ end,
+ lay_binary(c_binary([c_bitstr(abstract(Val(B)),
+ abstract(Sz(B)),
abstract(1),
abstract(integer),
abstract([unsigned, big]))
- || B <- binary_to_list(V)]),
+ || B <- bitstring_to_list(V)]),
Ctxt);
[] ->
text("[]");
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 67661130a5..0927c17b6b 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -72,7 +72,7 @@
t_contains_opaque/1, t_contains_opaque/2,
t_decorate_with_opaque/3,
t_elements/1,
- t_find_opaque_mismatch/2,
+ t_find_opaque_mismatch/3,
t_find_unknown_opaque/3,
t_fixnum/0,
t_map/2,
@@ -530,39 +530,51 @@ list_contains_opaque(List, Opaques) ->
%% The first argument of the function is the pattern and its second
%% argument the type we are matching against the pattern.
--spec t_find_opaque_mismatch(erl_type(), erl_type()) -> 'error' | {'ok', erl_type(), erl_type()}.
+-spec t_find_opaque_mismatch(erl_type(), erl_type(), [erl_type()]) ->
+ 'error' | {'ok', erl_type(), erl_type()}.
-t_find_opaque_mismatch(T1, T2) ->
- t_find_opaque_mismatch(T1, T2, T2).
+t_find_opaque_mismatch(T1, T2, Opaques) ->
+ t_find_opaque_mismatch(T1, T2, T2, Opaques).
-t_find_opaque_mismatch(?any, _Type, _TopType) -> error;
-t_find_opaque_mismatch(?none, _Type, _TopType) -> error;
-t_find_opaque_mismatch(?list(T1, Tl1, _), ?list(T2, Tl2, _), TopType) ->
- t_find_opaque_mismatch_ordlists([T1, Tl1], [T2, Tl2], TopType);
-t_find_opaque_mismatch(_T1, ?opaque(_) = T2, TopType) -> {ok, TopType, T2};
-t_find_opaque_mismatch(?opaque(_) = T1, _T2, TopType) ->
+t_find_opaque_mismatch(?any, _Type, _TopType, _Opaques) -> error;
+t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> error;
+t_find_opaque_mismatch(?list(T1, Tl1, _), ?list(T2, Tl2, _), TopType, Opaques) ->
+ t_find_opaque_mismatch_ordlists([T1, Tl1], [T2, Tl2], TopType, Opaques);
+t_find_opaque_mismatch(T1, ?opaque(_) = T2, TopType, Opaques) ->
+ case is_opaque_type(T2, Opaques) of
+ false -> {ok, TopType, T2};
+ true ->
+ t_find_opaque_mismatch(T1, t_opaque_structure(T2), TopType, Opaques)
+ end;
+t_find_opaque_mismatch(?opaque(_) = T1, T2, TopType, Opaques) ->
%% The generated message is somewhat misleading:
- {ok, TopType, T1};
-t_find_opaque_mismatch(?product(T1), ?product(T2), TopType) ->
- t_find_opaque_mismatch_ordlists(T1, T2, TopType);
-t_find_opaque_mismatch(?tuple(T1, Arity, _), ?tuple(T2, Arity, _), TopType) ->
- t_find_opaque_mismatch_ordlists(T1, T2, TopType);
-t_find_opaque_mismatch(?tuple(_, _, _) = T1, ?tuple_set(_) = T2, TopType) ->
+ case is_opaque_type(T1, Opaques) of
+ false -> {ok, TopType, T1};
+ true ->
+ t_find_opaque_mismatch(t_opaque_structure(T1), T2, TopType, Opaques)
+ end;
+t_find_opaque_mismatch(?product(T1), ?product(T2), TopType, Opaques) ->
+ t_find_opaque_mismatch_ordlists(T1, T2, TopType, Opaques);
+t_find_opaque_mismatch(?tuple(T1, Arity, _), ?tuple(T2, Arity, _),
+ TopType, Opaques) ->
+ t_find_opaque_mismatch_ordlists(T1, T2, TopType, Opaques);
+t_find_opaque_mismatch(?tuple(_, _, _) = T1, ?tuple_set(_) = T2,
+ TopType, Opaques) ->
Tuples1 = t_tuple_subtypes(T1),
Tuples2 = t_tuple_subtypes(T2),
- t_find_opaque_mismatch_lists(Tuples1, Tuples2, TopType);
-t_find_opaque_mismatch(T1, ?union(U2), TopType) ->
- t_find_opaque_mismatch_lists([T1], U2, TopType);
-t_find_opaque_mismatch(_T1, _T2, _TopType) -> error.
+ t_find_opaque_mismatch_lists(Tuples1, Tuples2, TopType, Opaques);
+t_find_opaque_mismatch(T1, ?union(U2), TopType, Opaques) ->
+ t_find_opaque_mismatch_lists([T1], U2, TopType, Opaques);
+t_find_opaque_mismatch(_T1, _T2, _TopType, _Opaques) -> error.
-t_find_opaque_mismatch_ordlists(L1, L2, TopType) ->
+t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
List = lists:zipwith(fun(T1, T2) ->
- t_find_opaque_mismatch(T1, T2, TopType)
+ t_find_opaque_mismatch(T1, T2, TopType, Opaques)
end, L1, L2),
t_find_opaque_mismatch_list(List).
-t_find_opaque_mismatch_lists(L1, L2, _TopType) ->
- List = [t_find_opaque_mismatch(T1, T2, T2) || T1 <- L1, T2 <- L2],
+t_find_opaque_mismatch_lists(L1, L2, _TopType, Opaques) ->
+ List = [t_find_opaque_mismatch(T1, T2, T2, Opaques) || T1 <- L1, T2 <- L2],
t_find_opaque_mismatch_list(List).
t_find_opaque_mismatch_list([]) -> error;
@@ -1423,7 +1435,6 @@ t_number_vals(Type) ->
t_number_vals(Type, Opaques) ->
do_opaque(Type, Opaques, fun number_vals/1).
-number_vals(?int_set(?any)) -> unknown;
number_vals(?int_set(Set)) -> set_to_list(Set);
number_vals(?number(_, _)) -> unknown;
number_vals(?opaque(_)) -> unknown;
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index c7faf733c7..e8552eabcc 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -30,6 +30,35 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A Dialyzer crash involving analysis of Map types has now
+ been fixed.</p>
+ <p>
+ Own Id: OTP-11947</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Handle Maps instructions get_map_elements, put_map_assoc,
+ put_map_exact in HiPE compiler.</p>
+ <p>
+ Own Id: OTP-11900</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.10.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -118,9 +147,9 @@
"hi" := V1, a := V2, b := V3} = M2. % match keys with
values</c></item> </taglist></p>
<p>
- For information on how to use Maps please see the
- <seealso marker="doc/reference_manual:maps">Reference
- Manual</seealso>.</p>
+ For information on how to use Maps please see Map Expressions in the
+ <seealso marker="doc/reference_manual:expressions#map_expressions">
+ Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
features: <taglist> <item>No variable keys</item>
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index fb7e4b91a0..c30695d4f0 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.10.3
+HIPE_VSN = 3.11
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 596c0d77f4..d586536b0a 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,7 +32,22 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 5.10.1</title>
+ <section><title>Inets 5.10.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ httpc: Fix streaming bugs when handling small responses</p>
+ <p>
+ Own Id: OTP-11992</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 5.10.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index b3c9cbc46a..9bea58cc9e 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -35,6 +35,7 @@
-include("http_internal.hrl").
-include("httpd_internal.hrl").
+-define(HANDSHAKE_TIMEOUT, 5000).
-record(state, {mod, %% #mod{}
manager, %% pid()
status, %% accept | busy | blocked
@@ -96,15 +97,13 @@ init([Manager, ConfigDB, AcceptTimeout]) ->
{SocketType, Socket} = await_socket_ownership_transfer(AcceptTimeout),
- TimeOut = httpd_util:lookup(ConfigDB, keep_alive_timeout, 150000),
- Then = erlang:now(),
+ KeepAliveTimeOut = httpd_util:lookup(ConfigDB, keep_alive_timeout, 150000),
- case http_transport:negotiate(SocketType, Socket, TimeOut) of
+ case http_transport:negotiate(SocketType, Socket, ?HANDSHAKE_TIMEOUT) of
{error, _Error} ->
exit(shutdown); %% Can be 'normal'.
ok ->
- NewTimeout = TimeOut - timer:now_diff(now(),Then) div 1000,
- continue_init(Manager, ConfigDB, SocketType, Socket, NewTimeout)
+ continue_init(Manager, ConfigDB, SocketType, Socket, KeepAliveTimeOut)
end.
continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) ->
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 5499596bbd..6991fb6d04 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -17,8 +17,16 @@
%% %CopyrightEnd%
{"%VSN%",
[
+ {"5.10.1",
+ [{load_module, httpc_handler, soft_purge, soft_purge, []},
+ {load_module, httpd, soft_purge, soft_purge, []},
+ {load_module, httpd_manager, soft_purge, soft_purge, []},
+ {load_module, httpd_request, soft_purge, soft_purge, []},
+ {load_module, httpd_request_handler, soft_purge, soft_purge,
+ []}]},
{"5.10",
- [{load_module, httpd, soft_purge, soft_purge, []},
+ [{load_module, httpc_handler, soft_purge, soft_purge, []},
+ {load_module, httpd, soft_purge, soft_purge, []},
{load_module, httpd_manager, soft_purge, soft_purge, []},
{load_module, httpd_request, soft_purge, soft_purge, []},
{load_module, httpd_request_handler, soft_purge, soft_purge,
@@ -26,8 +34,16 @@
{<<"5\\..*">>,[{restart_application, inets}]}
],
[
+ {"5.10.1",
+ [{load_module, httpc_handler, soft_purge, soft_purge, []},
+ {load_module, httpd, soft_purge, soft_purge, []},
+ {load_module, httpd_manager, soft_purge, soft_purge, []},
+ {load_module, httpd_request, soft_purge, soft_purge, []},
+ {load_module, httpd_request_handler, soft_purge, soft_purge,
+ []}]},
{"5.10",
- [{load_module, httpd, soft_purge, soft_purge, []},
+ [{load_module, httpc_handler, soft_purge, soft_purge, []},
+ {load_module, httpd, soft_purge, soft_purge, []},
{load_module, httpd_manager, soft_purge, soft_purge, []},
{load_module, httpd_request, soft_purge, soft_purge, []},
{load_module, httpd_request_handler, soft_purge, soft_purge, []}]},
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 4be20d3a69..de47760e6e 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -39,6 +39,7 @@
-define(FAIL_EXPIRE_TIME,1).
%% Seconds before successful auths timeout.
-define(AUTH_TIMEOUT,5).
+-define(URL_START, "http://").
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
@@ -63,7 +64,9 @@ all() ->
{group, http_htaccess},
{group, https_htaccess},
{group, http_security},
- {group, https_security}
+ {group, https_security},
+ {group, http_reload},
+ {group, https_reload}
].
groups() ->
@@ -84,7 +87,18 @@ groups() ->
{https_htaccess, [], [{group, htaccess}]},
{http_security, [], [{group, security}]},
{https_security, [], [{group, security}]},
+ {http_reload, [], [{group, reload}]},
+ {https_reload, [], [{group, reload}]},
{limit, [], [max_clients_1_1, max_clients_1_0, max_clients_0_9]},
+ {reload, [], [non_disturbing_reconfiger_dies,
+ disturbing_reconfiger_dies,
+ non_disturbing_1_1,
+ non_disturbing_1_0,
+ non_disturbing_0_9,
+ disturbing_1_1,
+ disturbing_1_0,
+ disturbing_0_9
+ ]},
{basic_auth, [], [basic_auth_1_1, basic_auth_1_0, basic_auth_0_9]},
{auth_api, [], [auth_api_1_1, auth_api_1_0, auth_api_0_9
]},
@@ -150,7 +164,8 @@ init_per_group(Group, Config0) when Group == https_basic;
Group == https_auth_api;
Group == https_auth_api_dets;
Group == https_auth_api_mnesia;
- Group == https_security
+ Group == https_security;
+ Group == https_reload
->
init_ssl(Group, Config0);
init_per_group(Group, Config0) when Group == http_basic;
@@ -159,7 +174,8 @@ init_per_group(Group, Config0) when Group == http_basic;
Group == http_auth_api;
Group == http_auth_api_dets;
Group == http_auth_api_mnesia;
- Group == http_security
+ Group == http_security;
+ Group == http_reload
->
ok = start_apps(Group),
init_httpd(Group, [{type, ip_comm} | Config0]);
@@ -202,17 +218,19 @@ end_per_group(Group, _Config) when Group == http_basic;
Group == http_auth_api_dets;
Group == http_auth_api_mnesia;
Group == http_htaccess;
- Group == http_security
+ Group == http_security;
+ Group == http_reload
->
inets:stop();
end_per_group(Group, _Config) when Group == https_basic;
Group == https_limit;
Group == https_basic_auth;
Group == https_auth_api;
- Group == http_auth_api_dets;
- Group == http_auth_api_mnesia;
+ Group == https_auth_api_dets;
+ Group == https_auth_api_mnesia;
Group == https_htaccess;
- Group == http_security
+ Group == https_security;
+ Group == https_reload
->
ssl:stop(),
inets:stop();
@@ -1088,12 +1106,114 @@ security(Config) ->
[{statuscode, 401}]),
true = unblock_user(Node, "two", Port, OpenDir).
+
+%%-------------------------------------------------------------------------
+non_disturbing_reconfiger_dies(Config) when is_list(Config) ->
+ do_reconfiger_dies([{http_version, "HTTP/1.1"} | Config], non_disturbing).
+disturbing_reconfiger_dies(Config) when is_list(Config) ->
+ do_reconfiger_dies([{http_version, "HTTP/1.1"} | Config], disturbing).
+
+do_reconfiger_dies(Config, DisturbingType) ->
+ Server = ?config(server_pid, Config),
+ Version = ?config(http_version, Config),
+ Host = ?config(host, Config),
+ Port = ?config(port, Config),
+ Type = ?config(type, Config),
+
+ HttpdConfig = httpd:info(Server),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ Pid = spawn(fun() -> httpd:reload_config([{server_name, "httpd_kill_" ++ Version},
+ {port, Port}|
+ proplists:delete(server_name, HttpdConfig)], DisturbingType)
+ end),
+ monitor(process, Pid),
+ exit(Pid, kill),
+ receive
+ {'DOWN', _, _, _, _} ->
+ ok
+ end,
+ inets_test_lib:close(Type, Socket),
+ [{server_name, "httpd_test"}] = httpd:info(Server, [server_name]).
+%%-------------------------------------------------------------------------
+disturbing_1_1(Config) when is_list(Config) ->
+ disturbing([{http_version, "HTTP/1.1"} | Config]).
+
+disturbing_1_0(Config) when is_list(Config) ->
+ disturbing([{http_version, "HTTP/1.0"} | Config]).
+
+disturbing_0_9(Config) when is_list(Config) ->
+ disturbing([{http_version, "HTTP/0.9"} | Config]).
+
+disturbing(Config) when is_list(Config)->
+ Server = ?config(server_pid, Config),
+ Version = ?config(http_version, Config),
+ Host = ?config(host, Config),
+ Port = ?config(port, Config),
+ Type = ?config(type, Config),
+ HttpdConfig = httpd:info(Server),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ ok = httpd:reload_config([{server_name, "httpd_disturbing_" ++ Version}, {port, Port}|
+ proplists:delete(server_name, HttpdConfig)], disturbing),
+ Close = list_to_atom((typestr(Type)) ++ "_closed"),
+ receive
+ {Close, Socket} ->
+ ok;
+ Msg ->
+ ct:fail({{expected, {Close, Socket}}, {got, Msg}})
+ end,
+ inets_test_lib:close(Type, Socket),
+ [{server_name, "httpd_disturbing_" ++ Version}] = httpd:info(Server, [server_name]).
+%%-------------------------------------------------------------------------
+non_disturbing_1_1(Config) when is_list(Config) ->
+ non_disturbing([{http_version, "HTTP/1.1"} | Config]).
+
+non_disturbing_1_0(Config) when is_list(Config) ->
+ non_disturbing([{http_version, "HTTP/1.0"} | Config]).
+
+non_disturbing_0_9(Config) when is_list(Config) ->
+ non_disturbing([{http_version, "HTTP/0.9"} | Config]).
+
+non_disturbing(Config) when is_list(Config)->
+ Server = ?config(server_pid, Config),
+ Version = ?config(http_version, Config),
+ Host = ?config(host, Config),
+ Port = ?config(port, Config),
+ Type = ?config(type, Config),
+
+ HttpdConfig = httpd:info(Server),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ ok = httpd:reload_config([{server_name, "httpd_non_disturbing_" ++ Version}, {port, Port}|
+ proplists:delete(server_name, HttpdConfig)], non_disturbing),
+ Transport = type(Type),
+ receive
+ {Transport, Socket, Msg} ->
+ ct:pal("Received message ~p~n", [Msg]),
+ ok
+ after 2000 ->
+ ct:fail(timeout)
+ end,
+ inets_test_lib:close(Type, Socket),
+ [{server_name, "httpd_non_disturbing_" ++ Version}] = httpd:info(Server, [server_name]).
%%--------------------------------------------------------------------
%% Internal functions -----------------------------------
%%--------------------------------------------------------------------
+url(http, End, Config) ->
+ Port = ?config(port, Config),
+ {ok,Host} = inet:gethostname(),
+ ?URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End.
+
do_max_clients(Config) ->
Version = ?config(http_version, Config),
Host = ?config(host, Config),
@@ -1171,7 +1291,9 @@ start_apps(Group) when Group == https_basic;
Group == https_auth_api_dets;
Group == https_auth_api_mnesia;
Group == http_htaccess;
- Group == http_security ->
+ Group == http_security;
+ Group == http_reload
+ ->
inets_test_lib:start_apps([inets, asn1, crypto, public_key, ssl]);
start_apps(Group) when Group == http_basic;
Group == http_limit;
@@ -1180,7 +1302,8 @@ start_apps(Group) when Group == http_basic;
Group == http_auth_api_dets;
Group == http_auth_api_mnesia;
Group == https_htaccess;
- Group == https_security ->
+ Group == https_security;
+ Group == https_reload->
inets_test_lib:start_apps([inets]).
server_start(_, HttpdConfig) ->
@@ -1224,6 +1347,10 @@ server_config(http_basic, Config) ->
basic_conf() ++ server_config(http, Config);
server_config(https_basic, Config) ->
basic_conf() ++ server_config(https, Config);
+server_config(http_reload, Config) ->
+ [{keep_alive_timeout, 2}] ++ server_config(http, Config);
+server_config(https_reload, Config) ->
+ [{keep_alive_timeout, 2}] ++ server_config(https, Config);
server_config(http_limit, Config) ->
[{max_clients, 1}] ++ server_config(http, Config);
server_config(https_limit, Config) ->
@@ -1792,3 +1919,12 @@ event(What, Port, Dir, Data) ->
global:send(mod_security_test, Msg)
end.
+type(ip_comm) ->
+ tcp;
+type(_) ->
+ ssl.
+
+typestr(ip_comm) ->
+ "tcp";
+typestr(_) ->
+ "ssl".
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
index 1fcc5f257e..baef699629 100644
--- a/lib/inets/test/httpd_basic_SUITE.erl
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -129,7 +129,7 @@ end_per_suite(_Config) ->
%% Note: This function is free to add any key/value pairs to the Config
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
+init_per_testcase(_Case, Config) ->
Config.
diff --git a/lib/inets/test/old_httpd_SUITE.erl b/lib/inets/test/old_httpd_SUITE.erl
index 19c2bc129e..74c11f71ba 100644
--- a/lib/inets/test/old_httpd_SUITE.erl
+++ b/lib/inets/test/old_httpd_SUITE.erl
@@ -186,20 +186,23 @@ groups() ->
%% Only used through load_config
%% but we still need these tests
%% should be cleaned up and moved to new test suite
- ip_restart_no_block,
- ip_restart_disturbing_block,
- ip_restart_non_disturbing_block,
- ip_block_disturbing_idle,
- ip_block_non_disturbing_idle,
- ip_block_503,
- ip_block_disturbing_active,
- ip_block_non_disturbing_active,
- ip_block_disturbing_active_timeout_not_released,
- ip_block_disturbing_active_timeout_released,
- ip_block_non_disturbing_active_timeout_not_released,
- ip_block_non_disturbing_active_timeout_released,
- ip_block_disturbing_blocker_dies,
- ip_block_non_disturbing_blocker_dies
+ %%ip_restart_no_block,
+ %%ip_restart_disturbing_block,
+ %%ip_restart_non_disturbing_block,
+ %% Tested in inets_SUITE
+ %%ip_block_disturbing_idle,
+ %%ip_block_non_disturbing_idle,
+ ip_block_503
+ %% Tested in new httpd_SUITE
+ %%ip_block_disturbing_active,
+ %%ip_block_non_disturbing_active,
+ %%ip_block_disturbing_blocker_dies,
+ %%ip_block_non_disturbing_blocker_dies
+ %% No longer relevant
+ %%ip_block_disturbing_active_timeout_not_released,
+ %%ip_block_disturbing_active_timeout_released,
+ %%ip_block_non_disturbing_active_timeout_not_released,
+ %%ip_block_non_disturbing_active_timeout_released,
]},
{ssl, [], [{group, essl}]},
{essl, [],
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index bbd86c3eb3..79081f371c 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.10.1
+INETS_VSN = 5.10.2
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
index 9ba6a4a0ab..85d303689f 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
@@ -266,7 +266,7 @@ public abstract class AbstractConnection extends Thread {
*
* @param dest
* the Erlang PID of the remote process.
- * @param msg
+ * @param payload
* the encoded message to send.
*
* @exception java.io.IOException
@@ -959,7 +959,9 @@ public abstract class AbstractConnection extends Thread {
} catch (final Exception e) {
final String nn = peer.node();
close();
- throw new IOException("Error accepting connection from " + nn);
+ IOException ioe = new IOException("Error accepting connection from " + nn);
+ ioe.initCause(e);
+ throw ioe;
}
if (traceLevel >= handshakeThreshold) {
System.out.println("<- MD5 ACCEPTED " + peer.host());
@@ -990,7 +992,9 @@ public abstract class AbstractConnection extends Thread {
throw ae;
} catch (final Exception e) {
close();
- throw new IOException("Cannot connect to peer node");
+ IOException ioe = new IOException("Cannot connect to peer node");
+ ioe.initCause(e);
+ throw ioe;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
index 8e8bd473c8..e7a9d1092c 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
@@ -404,7 +404,7 @@ public class OtpConnection extends AbstractConnection {
*
* @param dest
* the Erlang PID of the remote process.
- * @param msg
+ * @param payload
* the encoded message to send.
*
* @exception java.io.IOException
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
index 7e3e2a7296..84b1355c54 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
@@ -51,8 +51,8 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
/**
* Create an Erlang integer from the given value.
*
- * @param val
- * the long value to use.
+ * @param v
+ * the big integer value to use.
*/
public OtpErlangLong(final BigInteger v) {
if (v == null) {
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
index 03c18e55a2..0254edd5da 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
@@ -58,15 +58,23 @@ public class OtpErlangMap extends OtpErlangObject implements Serializable,
/**
* Create a map from an array of terms.
*
- * @param elems
+ * @param keys
* the array of terms to create the map from.
- * @param start
- * the offset of the first term to insert.
+ * @param kstart
+ * the offset of the first key to insert.
+ * @param kcount
+ * the number of keys to insert.
+ * @param values
+ * the array of values to create the map from.
+ * @param vstart
+ * the offset of the first value to insert.
* @param vcount
- * the number of terms to insert.
+ * the number of values to insert.
*
* @exception java.lang.IllegalArgumentException
* if any array is empty (null) or contains null elements.
+ * @exception java.lang.IllegalArgumentException
+ * if kcount and vcount differ.
*/
public OtpErlangMap(final OtpErlangObject[] keys, final int kstart,
final int kcount, final OtpErlangObject[] values, final int vstart,
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
index fe81ce302d..f75e4353d0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
@@ -162,7 +162,7 @@ public class OtpErlangPid extends OtpErlangObject implements Serializable,
* Determine if two PIDs are equal. PIDs are equal if their components are
* equal.
*
- * @param port
+ * @param o
* the other PID to compare to.
*
* @return true if the PIDs are equal, false otherwise.
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
index 6766b52ce5..a5e202c473 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
@@ -41,8 +41,6 @@ public class OtpErlangString extends OtpErlangObject implements Serializable,
/**
* Create an Erlang string from a list of integers.
- *
- * @return an Erlang string with Unicode code units.
*
* @throws OtpErlangException
* for non-proper and non-integer lists.
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
index 0d1342d796..f813594541 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
@@ -21,6 +21,7 @@ package com.ericsson.otp.erlang;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
+import java.util.Arrays;
/**
* Provides a stream for decoding Erlang terms from external format.
@@ -819,7 +820,7 @@ public class OtpInputStream extends ByteArrayInputStream {
if (unsigned) {
if (c < 0) {
throw new OtpErlangDecodeException("Value not unsigned: "
- + b);
+ + Arrays.toString(b));
}
while (b[i] == 0) {
i++; // Skip leading zero sign bytes
@@ -844,7 +845,7 @@ public class OtpInputStream extends ByteArrayInputStream {
if (b.length - i > 8) {
// More than 64 bits of value
throw new OtpErlangDecodeException(
- "Value does not fit in long: " + b);
+ "Value does not fit in long: " + Arrays.toString(b));
}
// Convert the necessary bytes
for (v = c < 0 ? -1 : 0; i < b.length; i++) {
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
index 0fd93b09f4..4a4a1e7f8f 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
@@ -69,6 +69,7 @@ package com.ericsson.otp.erlang;
* notify other parties in a timely manner.
* </p>
*
+ * <p>
* When retrieving messages from a mailbox that has received an exit signal, an
* {@link OtpErlangExit OtpErlangExit} exception will be raised. Note that the
* exception is queued in the mailbox along with other messages, and will not be
@@ -420,7 +421,6 @@ public class OtpMbox {
/**
* Equivalent to <code>exit(new OtpErlangAtom(reason))</code>.
- * </p>
*
* @see #exit(OtpErlangObject)
*/
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
index 6f507bf4bb..31a5d0fb8f 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
@@ -30,14 +30,14 @@ package com.ericsson.otp.erlang;
* </p>
*
* <p>
- * The header information that is available is as follows: <lu>
+ * The header information that is available is as follows: <ul>
* <li> a tag indicating the type of message
* <li> the intended recipient of the message, either as a
* {@link OtpErlangPid pid} or as a String, but never both.
* <li> (sometimes) the sender of the message. Due to some eccentric
* characteristics of the Erlang distribution protocol, not all messages have
* information about the sending process. In particular, only messages whose tag
- * is {@link OtpMsg#regSendTag regSendTag} contain sender information. </lu>
+ * is {@link OtpMsg#regSendTag regSendTag} contain sender information. </ul>
*
* <p>
* Message are sent using the Erlang external format (see separate
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 a78423db44..c98790bbd4 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -202,7 +202,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
/**
* Write an array of bytes to the stream.
*
- * @param buf
+ * @param bytes
* the array of bytes to write.
*
*/
@@ -637,7 +637,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* Write a positive short to the stream. The short is interpreted as a two's
* complement unsigned short even if it is negative.
*
- * @param s
+ * @param us
* the short to use.
*/
public void write_ushort(final short us) {
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 8dae34431b..1c03efe7fd 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -428,14 +428,6 @@
</desc>
</func>
<func>
- <name name="file_info" arity="1"/>
- <fsummary>Get information about a file (deprecated)</fsummary>
- <desc>
- <p>This function is obsolete. Use <c>read_file_info/1,2</c>
- instead.</p>
- </desc>
- </func>
- <func>
<name name="format_error" arity="1"/>
<fsummary>Return a descriptive string for an error reason</fsummary>
<desc>
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index dbd0d3c815..820ecd1e30 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -112,7 +112,12 @@ do_recv(Sock, Bs) ->
<item>
<p>If a socket has somehow been connected without using
<c>gen_tcp</c>, use this option to pass the file
- descriptor for it.</p>
+ descriptor for it. If <c>{ip, ip_address()}</c>
+ and/or <c>{port, port_number()}</c> is combined with
+ this option the fd will be bound to the given interface
+ and port before connecting. If these options are not given
+ it is assumed that the fd is already bound appropriately.
+ </p>
</item>
<tag><c>inet</c></tag>
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 503725fe18..291d1b0da7 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -84,7 +84,12 @@
<item>
<p>If a socket has somehow been opened without using
<c>gen_udp</c>, use this option to pass the file
- descriptor for it.</p>
+ descriptor for it. If <c><anno>Port</anno></c> is not set to 0
+ and/or <c>{ip, ip_address()}</c> is combined with this option
+ the fd will be bound to the given interface and port after being
+ opened. If these options are not given it is assumed that the fd
+ is already bound appropriately.
+ </p>
</item>
<tag><c>inet6</c></tag>
<item>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index c6538b7d05..f92770603a 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -30,6 +30,77 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 3.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ OTP-11850 fixed filelib:wildcard/1 to work with broken
+ symlinks. This correction, however, introduced problems
+ since symlinks were no longer followed for functions like
+ filelib:ensure_dir/1, filelib:is_dir/1,
+ filelib:file_size/1, etc. This is now corrected.</p>
+ <p>
+ Own Id: OTP-12054 Aux Id: seq12660 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 3.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If the Config given to
+ application_controller:change_application_data included
+ other config files, it was only expanded for already
+ existing (loaded) applications. If an upgrade added a new
+ application which had config data in an included config
+ file, the new application did not get correct config
+ data.</p>
+ <p>
+ This is now changed so config data will be expanded for
+ all applications.</p>
+ <p>
+ Own Id: OTP-11864</p>
+ </item>
+ <item>
+ <p>It was allowed to re-load pre-loaded modules such as
+ <c>erlang</c>, but that could cause strange and unwanted
+ things to happen, such as call <c>apply/3</c> to loop.
+ Pre-loaded modules are now sticky by default. (Thanks to
+ Loïc Hoguin for reporting this bug.)</p>
+ <p><c>code:add_path("/ending/in/slash/")</c> removes the
+ trailing slash, adding <c>/ending/in/slash</c> to the
+ code path. However,
+ <c>code:del_path("/ending/in/slash/")</c> would fail to
+ remove the path since it did not remove the trailing
+ slash. This has been fixed.</p>
+ <p>
+ Own Id: OTP-11913</p>
+ </item>
+ <item>
+ <p>
+ Fix erts_debug:size/1 to handle Map sizes</p>
+ <p>
+ Own Id: OTP-11923</p>
+ </item>
+ <item>
+ <p>The documentation for <c>file:file_info/1</c> has been
+ removed. The function itself was removed a long time
+ ago.</p>
+ <p>
+ Own Id: OTP-11982</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 3.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -80,7 +151,6 @@
</list>
</section>
-
<section><title>Improvements and New Features</title>
<list>
<item>
@@ -224,7 +294,26 @@
</item>
</list>
</section>
+</section>
+<section><title>Kernel 2.16.4.1</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ When using gen_tcp:connect and the <c>fd</c> option with
+ <c>port</c> and/or <c>ip</c>, the <c>port</c> and
+ <c>ip</c> options were ignored. This has been fixed so
+ that if <c>port</c> and/or <c>ip</c> is specified
+ together with <c>fd</c> a bind is requested for that
+ <c>fd</c>. If <c>port</c> and/or <c>ip</c> is not
+ specified bind will not be called.</p>
+ <p>
+ Own Id: OTP-12061</p>
+ </item>
+ </list>
+ </section>
</section>
<section><title>Kernel 2.16.4</title>
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index fc7ac08699..819554ce74 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -63,7 +63,10 @@ init(Ref, Parent, [Root,Mode0]) ->
process_flag(trap_exit, true),
Db = ets:new(code, [private]),
- foreach(fun (M) -> ets:insert(Db, {M,preloaded}) end, erlang:pre_loaded()),
+ foreach(fun (M) ->
+ %% Pre-loaded modules are always sticky.
+ ets:insert(Db, [{M,preloaded},{{sticky,M},true}])
+ end, erlang:pre_loaded()),
ets:insert(Db, init:fetch_loaded()),
Mode =
@@ -988,7 +991,7 @@ try_archive_subdirs(_Archive, Base, []) ->
%% the complete directory name.
%%
del_path(Name0,Path,NameDb) ->
- case catch to_list(Name0)of
+ case catch filename:join([to_list(Name0)]) of
{'EXIT',_} ->
{{error,bad_name},Path};
Name ->
diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl
index 9a49655a9f..ef09d86ca4 100644
--- a/lib/kernel/src/erl_boot_server.erl
+++ b/lib/kernel/src/erl_boot_server.erl
@@ -341,9 +341,13 @@ handle_command(S, PS, Msg) ->
send_file_result(S, list_dir, Res),
PS2;
{read_file_info,File} ->
- {Res, PS2} = erl_prim_loader:prim_read_file_info(PS, File),
+ {Res, PS2} = erl_prim_loader:prim_read_file_info(PS, File, true),
send_file_result(S, read_file_info, Res),
PS2;
+ {read_link_info,File} ->
+ {Res, PS2} = erl_prim_loader:prim_read_file_info(PS, File, false),
+ send_file_result(S, read_link_info, Res),
+ PS2;
get_cwd ->
{Res, PS2} = erl_prim_loader:prim_get_cwd(PS, []),
send_file_result(S, get_cwd, Res),
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 20b703e084..ee2fb85de2 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -117,15 +117,7 @@
| {'time', 'posix'}.
%%% BIFs
--export([file_info/1, native_name_encoding/0]).
-
--spec file_info(Filename) -> {ok, FileInfo} | {error, Reason} when
- Filename :: name_all(),
- FileInfo :: file_info(),
- Reason :: posix() | badarg.
-
-file_info(_) ->
- erlang:nif_error(undef).
+-export([native_name_encoding/0]).
-spec native_name_encoding() -> latin1 | utf8.
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 41d422d7d4..d17da2d329 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1257,9 +1257,9 @@ open(FdO, Addr, Port, Opts, Protocol, Family, Type, Module)
Error ->
Error
end;
-open(Fd, _Addr, _Port, Opts, Protocol, Family, Type, Module)
+open(Fd, Addr, Port, Opts, Protocol, Family, Type, Module)
when is_integer(Fd) ->
- fdopen(Fd, Opts, Protocol, Family, Type, Module).
+ fdopen(Fd, Addr, Port, Opts, Protocol, Family, Type, Module).
bindx(S, [Addr], Port0) ->
{IP, Port} = set_bindx_port(Addr, Port0),
@@ -1298,12 +1298,35 @@ change_bindx_0_port({_IP, _Port}=Addr, _AssignedPort) ->
{'ok', socket()} | {'error', posix()}.
fdopen(Fd, Opts, Protocol, Family, Type, Module) ->
- case prim_inet:fdopen(Protocol, Family, Type, Fd) of
+ fdopen(Fd, any, 0, Opts, Protocol, Family, Type, Module).
+
+fdopen(Fd, Addr, Port, Opts, Protocol, Family, Type, Module) ->
+ IsAnyAddr = (Addr == {0,0,0,0} orelse Addr == {0,0,0,0,0,0,0,0}
+ orelse Addr == any),
+ Bound = Port == 0 andalso IsAnyAddr,
+ case prim_inet:fdopen(Protocol, Family, Type, Fd, Bound) of
{ok, S} ->
case prim_inet:setopts(S, Opts) of
ok ->
- inet_db:register_socket(S, Module),
- {ok, S};
+ case if
+ Bound ->
+ %% We do not do any binding if default
+ %% port+addr options where given in order
+ %% to keep backwards compatability with
+ %% pre Erlang/TOP 17
+ {ok, ok};
+ is_list(Addr) ->
+ bindx(S, Addr, Port);
+ true ->
+ prim_inet:bind(S, Addr, Port)
+ end of
+ {ok, _} ->
+ inet_db:register_socket(S, Module),
+ {ok, S};
+ Error ->
+ prim_inet:close(S),
+ Error
+ end;
Error ->
prim_inet:close(S), Error
end;
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 5658c6b6cf..9f6c0f4624 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -115,6 +115,6 @@
{applications, []},
{env, [{error_logger, tty}]},
{mod, {kernel, []}},
- {runtime_dependencies, ["erts-6.0", "stdlib-2.0", "sasl-2.4"]}
+ {runtime_dependencies, ["erts-6.1.2", "stdlib-2.0", "sasl-2.4"]}
]
}.
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 036e238c85..4901206c8e 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -1076,10 +1076,13 @@ otp_1586(Conf) when is_list(Conf) ->
{ok, Fd} = file:open(filename:join(Dir, "app5.app"), [write]),
w_app5(Fd),
file:close(Fd),
- code:add_patha(Dir),
- ok = application:load(app4()),
- ok = application:unload(app4),
- ok.
+ try
+ true = code:add_patha(Dir),
+ ok = application:load(app4()),
+ ok = application:unload(app4)
+ after
+ _ = code:del_path(Dir)
+ end.
%%-----------------------------------------------------------------
%% Ticket: OTP-2078
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 42b81d16b3..afedc17e57 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -37,8 +37,7 @@
native_early_modules/1, get_mode/1]).
-export([init_per_testcase/2, end_per_testcase/2,
- init_per_suite/1, end_per_suite/1,
- sticky_compiler/1]).
+ init_per_suite/1, end_per_suite/1]).
%% error_logger
-export([init/1,
@@ -55,7 +54,7 @@ all() ->
delete, purge, purge_many_exits, soft_purge, is_loaded, all_loaded,
load_binary, dir_req, object_code, set_path_file,
upgrade,
- pa_pz_option, add_del_path, dir_disappeared,
+ sticky_dir, pa_pz_option, add_del_path, dir_disappeared,
ext_mod_dep, clash, load_cached, start_node_with_cache,
add_and_rehash, where_is_file_no_cache,
where_is_file_cached, purge_stacktrace, mult_lib_roots,
@@ -219,6 +218,13 @@ del_path(suite) -> [];
del_path(doc) -> [];
del_path(Config) when is_list(Config) ->
P = code:get_path(),
+ try
+ del_path_1(P)
+ after
+ code:set_path(P)
+ end.
+
+del_path_1(P) ->
test_server:format("Initial code:get_path()=~p~n",[P]),
{'EXIT',_} = (catch code:del_path(3)),
false = code:del_path(my_dummy_name),
@@ -226,19 +232,22 @@ del_path(Config) when is_list(Config) ->
Dir = filename:join([code:lib_dir(kernel),"ebin"]),
test_server:format("kernel dir: ~p~n",[Dir]),
-
true = code:del_path(kernel),
NewP = code:get_path(),
test_server:format("Path after removing 'kernel':~p~n",[NewP]),
ReferenceP = lists:delete(Dir,P),
test_server:format("Reference path:~p~n",[ReferenceP]),
NewP = ReferenceP, % check that dir is deleted
+ code:set_path(P),
+ %% An superfluous "/" should also work.
+ true = code:del_path("kernel/"),
+ NewP = ReferenceP, % check that dir is deleted
code:set_path(P),
+
true = code:del_path(Dir),
NewP1 = code:get_path(),
NewP1 = lists:delete(Dir,P), % check that dir is deleted
- code:set_path(P),
ok.
replace_path(suite) -> [];
@@ -577,35 +586,42 @@ sticky_dir(suite) -> [];
sticky_dir(doc) -> ["Test that a module with the same name as a module in ",
"a sticky directory cannot be loaded."];
sticky_dir(Config) when is_list(Config) ->
- MyDir=filename:dirname(code:which(?MODULE)),
- {ok, Node}=?t:start_node(sticky_dir, slave,[{args, "-pa \""++MyDir++"\""}]),
- File=filename:join([?config(data_dir, Config), "calendar"]),
- Ret=rpc:call(Node, ?MODULE, sticky_compiler, [File]),
+ Pa = filename:dirname(code:which(?MODULE)),
+ {ok,Node} = ?t:start_node(sticky_dir, slave, [{args,"-pa "++Pa}]),
+ Mods = [code,lists,erlang,init],
+ OutDir = filename:join(?config(priv_dir, Config), sticky_dir),
+ _ = file:make_dir(OutDir),
+ Ret = rpc:call(Node, erlang, apply,
+ [fun sticky_compiler/2,[Mods,OutDir]]),
case Ret of
- fail ->
- ?t:fail("c:c allowed a sticky module to be compiled and loaded.");
- ok ->
+ [] ->
ok;
Other ->
- test_server:format("Other: ~p",[Other])
+ io:format("~p\n", [Other]),
+ ?t:fail()
end,
- ?t:stop_node(Node).
+ ?t:stop_node(Node),
+ ok.
-sticky_compiler(File) ->
- Compiled=File++code:objfile_extension(),
- Dir=filename:dirname(File),
- code:add_patha(Dir),
- file:delete(Compiled),
- case c:c(File, [{outdir, Dir}]) of
- {ok, Module} ->
- case catch Module:test(apa) of
- {error, _} ->
- fail;
- {'EXIT', _} ->
- ok
- end;
- Other ->
- test_server:format("c:c(~p) returned: ~p",[File, Other]),
+sticky_compiler(Files, PrivDir) ->
+ code:add_patha(PrivDir),
+ Rets = [do_sticky_compile(F, PrivDir) || F <- Files],
+ [R || R <- Rets, R =/= ok].
+
+do_sticky_compile(Mod, Dir) ->
+ %% Make sure that the module is loaded. A module being sticky
+ %% only prevents it from begin reloaded, not from being loaded
+ %% from the wrong place to begin with.
+ Mod = Mod:module_info(module),
+ File = filename:append(Dir, atom_to_list(Mod)),
+ Src = io_lib:format("-module(~s).\n"
+ "-export([test/1]).\n"
+ "test(me) -> fail.\n", [Mod]),
+ ok = file:write_file(File++".erl", Src),
+ case c:c(File, [{outdir,Dir}]) of
+ {ok,Module} ->
+ Module:test(me);
+ {error,sticky_directory} ->
ok
end.
diff --git a/lib/kernel/test/code_SUITE_data/calendar.erl b/lib/kernel/test/code_SUITE_data/calendar.erl
deleted file mode 100644
index c1a4a1c12a..0000000000
--- a/lib/kernel/test/code_SUITE_data/calendar.erl
+++ /dev/null
@@ -1,23 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(calendar).
--export([test/1]).
-
-test(apa) ->
- {error, this_function_should_not_be_called}.
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index b2ca3bdbc2..658c31c14d 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -328,6 +328,30 @@ file_requests(Config) when is_list(Config) ->
{ok,Info} = file:read_file_info(code:which(test_server)),
?line {ok,Info} = rpc:call(Node, erl_prim_loader, read_file_info,
[code:which(test_server)]),
+
+ PrivDir = ?config(priv_dir,Config),
+ Dir = filename:join(PrivDir,?MODULE_STRING++"_file_requests"),
+ ok = file:make_dir(Dir),
+ Alias = filename:join(Dir,"symlink"),
+ case file:make_symlink(code:which(test_server), Alias) of
+ {error, enotsup} ->
+ %% Links not supported on this platform
+ ok;
+ {error, eperm} ->
+ {win32,_} = os:type(),
+ %% Windows user not privileged to create symlinks"
+ ok;
+ ok ->
+ %% Reading file info for link should return file info for
+ %% link target
+ {ok,Info} = rpc:call(Node, erl_prim_loader, read_file_info,
+ [Alias]),
+ #file_info{type=regular} = Info,
+ {ok,#file_info{type=symlink}} =
+ rpc:call(Node, erl_prim_loader, read_link_info,
+ [Alias])
+ end,
+
{ok,Cwd} = file:get_cwd(),
?line {ok,Cwd} = rpc:call(Node, erl_prim_loader, get_cwd, []),
case file:get_cwd("C:") of
diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl
index a7af00c12a..c27d265550 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_api_SUITE.erl
@@ -32,14 +32,16 @@
t_connect_bad/1,
t_recv_timeout/1, t_recv_eof/1,
t_shutdown_write/1, t_shutdown_both/1, t_shutdown_error/1,
- t_fdopen/1, t_implicit_inet6/1]).
+ t_fdopen/1, t_fdconnect/1, t_implicit_inet6/1]).
+
+-export([getsockfd/0,closesockfd/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[{group, t_accept}, {group, t_connect}, {group, t_recv},
t_shutdown_write, t_shutdown_both, t_shutdown_error,
- t_fdopen, t_implicit_inet6].
+ t_fdopen, t_fdconnect, t_implicit_inet6].
groups() ->
[{t_accept, [], [t_accept_timeout]},
@@ -185,6 +187,37 @@ t_fdopen(Config) when is_list(Config) ->
?line ok = gen_tcp:close(L),
ok.
+t_fdconnect(Config) when is_list(Config) ->
+ Question = "Aaaa... Long time ago in a small town in Germany,",
+ Question1 = list_to_binary(Question),
+ Question2 = [<<"Aaaa">>, "... ", $L, <<>>, $o, "ng time ago ",
+ ["in ", [], <<"a small town">>, [" in Germany,", <<>>]]],
+ Question1 = iolist_to_binary(Question2),
+ Answer = "there was a shoemaker, Schumacher was his name.",
+ Path = ?config(data_dir, Config),
+ Lib = "gen_tcp_api_SUITE",
+ ok = erlang:load_nif(filename:join(Path,Lib), []),
+ {ok, L} = gen_tcp:listen(0, [{active, false}]),
+ {ok, Port} = inet:port(L),
+ FD = gen_tcp_api_SUITE:getsockfd(),
+ {ok, Client} = gen_tcp:connect(localhost, Port, [{fd,FD},{port,20002},
+ {active,false}]),
+ {ok, Server} = gen_tcp:accept(L),
+ ok = gen_tcp:send(Client, Question),
+ {ok, Question} = gen_tcp:recv(Server, length(Question), 2000),
+ ok = gen_tcp:send(Client, Question1),
+ {ok, Question} = gen_tcp:recv(Server, length(Question), 2000),
+ ok = gen_tcp:send(Client, Question2),
+ {ok, Question} = gen_tcp:recv(Server, length(Question), 2000),
+ ok = gen_tcp:send(Server, Answer),
+ {ok, Answer} = gen_tcp:recv(Client, length(Answer), 2000),
+ ok = gen_tcp:close(Client),
+ FD = gen_tcp_api_SUITE:closesockfd(FD),
+ {error,closed} = gen_tcp:recv(Server, 1, 2000),
+ ok = gen_tcp:close(Server),
+ ok = gen_tcp:close(L),
+ ok.
+
%%% implicit inet6 option to api functions
@@ -300,3 +333,7 @@ unused_ip(A, B, C, D) ->
end.
ok({ok,V}) -> V.
+
+
+getsockfd() -> undefined.
+closesockfd(_FD) -> undefined.
diff --git a/lib/kernel/test/gen_tcp_api_SUITE_data/Makefile.src b/lib/kernel/test/gen_tcp_api_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..5477598160
--- /dev/null
+++ b/lib/kernel/test/gen_tcp_api_SUITE_data/Makefile.src
@@ -0,0 +1,9 @@
+
+NIF_LIBS = gen_tcp_api_SUITE@dll@
+SHLIB_EXTRA_LDLIBS = @LIBS@
+
+all: $(NIF_LIBS)
+
+@SHLIB_RULES@
+
+$(NIF_LIBS): gen_tcp_api_SUITE.c
diff --git a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
new file mode 100644
index 0000000000..73a6568b30
--- /dev/null
+++ b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
@@ -0,0 +1,60 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+#include "erl_nif.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/types.h>
+
+#ifdef __WIN32__
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif
+
+#define sock_open(af, type, proto) socket((af), (type), (proto))
+
+static ERL_NIF_TERM getsockfd(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int fd;
+
+ fd = sock_open(AF_INET, SOCK_STREAM, 0);
+ return enif_make_int(env, fd);
+}
+
+static ERL_NIF_TERM closesockfd(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int fd;
+
+ enif_get_int(env, argv[0], &fd);
+
+ close(fd);
+
+ return enif_make_int(env, fd);
+}
+
+static ErlNifFunc nif_funcs[] =
+{
+ {"getsockfd", 0, getsockfd},
+ {"closesockfd", 1, closesockfd}
+};
+
+ERL_NIF_INIT(gen_tcp_api_SUITE,nif_funcs,NULL,NULL,NULL,NULL)
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index 6bb41999c5..8177123332 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -447,8 +447,8 @@ open_fd(Config) when is_list(Config) ->
{ok,S1} = gen_udp:open(0),
{ok,P2} = inet:port(S1),
{ok,FD} = prim_inet:getfd(S1),
- {error,einval} = gen_udp:open(P2, [inet6, {fd,FD}]),
- {ok,S2} = gen_udp:open(P2, [{fd,FD}]),
+ {error,einval} = gen_udp:open(0, [inet6, {fd,FD}]),
+ {ok,S2} = gen_udp:open(0, [{fd,FD}]),
{ok,S3} = gen_udp:open(0),
{ok,P3} = inet:port(S3),
ok = gen_udp:send(S3, Addr, P2, Msg),
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index dd5316b825..1ecfde190e 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 3.0
+KERNEL_VSN = 3.0.2
diff --git a/lib/megaco/configure.in b/lib/megaco/configure.in
index 64daa959b5..e3c24a58b8 100644
--- a/lib/megaco/configure.in
+++ b/lib/megaco/configure.in
@@ -167,6 +167,26 @@ if test "x$GCC" = xyes; then
LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
fi
+dnl ----------------------------------------------------------------------
+dnl Enable -fsanitize= flags.
+dnl ----------------------------------------------------------------------
+
+m4_define(DEFAULT_SANITIZERS, [address,undefined])
+AC_ARG_ENABLE(
+ sanitizers,
+ AS_HELP_STRING(
+ [--enable-sanitizers@<:@=comma-separated list of sanitizers@:>@],
+ [Default=DEFAULT_SANITIZERS]),
+[
+case "$enableval" in
+ no) sanitizers= ;;
+ yes) sanitizers="-fsanitize=DEFAULT_SANITIZERS" ;;
+ *) sanitizers="-fsanitize=$enableval" ;;
+esac
+CFLAGS="$CFLAGS $sanitizers"
+LDFLAGS="$LDFLAGS $sanitizers"
+])
+
dnl
dnl If ${ERL_TOP}/make/otp_ded.mk.in exists and contains DED_MK_VSN > 0,
dnl every thing releted to compiling Dynamic Erlang Drivers can be found
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 213c2b6d21..08212dfede 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -38,7 +38,30 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.12</title>
+ <section><title>Mnesia 4.12.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Force load table could hang when a node went away during
+ start up.</p>
+ <p>
+ Own Id: OTP-11948 Aux Id: seq12585 </p>
+ </item>
+ <item>
+ <p>
+ The time for inserting locks for a transaction with large
+ number of locks is reduced significantly.</p>
+ <p>
+ Own Id: OTP-11981</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.12</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl
index c3846b00c0..e27396731f 100644
--- a/lib/mnesia/src/mnesia_locker.erl
+++ b/lib/mnesia/src/mnesia_locker.erl
@@ -84,7 +84,7 @@ init(Parent) ->
register(?MODULE, self()),
process_flag(trap_exit, true),
?ets_new_table(mnesia_held_locks, [ordered_set, private, named_table]),
- ?ets_new_table(mnesia_tid_locks, [bag, private, named_table]),
+ ?ets_new_table(mnesia_tid_locks, [ordered_set, private, named_table]),
?ets_new_table(mnesia_sticky_locks, [set, private, named_table]),
?ets_new_table(mnesia_lock_queue, [bag, private, named_table, {keypos, 2}]),
@@ -253,13 +253,13 @@ loop(State) ->
end.
set_lock(Tid, Oid, Op, []) ->
- ?ets_insert(mnesia_tid_locks, {Tid, Oid, Op}),
+ ?ets_insert(mnesia_tid_locks, {{Tid, Oid, Op}}),
?ets_insert(mnesia_held_locks, {Oid, Op, [{Op, Tid}]});
set_lock(Tid, Oid, read, [{Oid, Prev, Items}]) ->
- ?ets_insert(mnesia_tid_locks, {Tid, Oid, read}),
+ ?ets_insert(mnesia_tid_locks, {{Tid, Oid, read}}),
?ets_insert(mnesia_held_locks, {Oid, Prev, [{read, Tid}|Items]});
set_lock(Tid, Oid, write, [{Oid, _Prev, Items}]) ->
- ?ets_insert(mnesia_tid_locks, {Tid, Oid, write}),
+ ?ets_insert(mnesia_tid_locks, {{Tid, Oid, write}}),
?ets_insert(mnesia_held_locks, {Oid, write, [{write, Tid}|Items]});
set_lock(Tid, Oid, Op, undefined) ->
set_lock(Tid, Oid, Op, ?ets_lookup(mnesia_held_locks, Oid)).
@@ -299,7 +299,7 @@ try_lock(Tid, Op, SimpleOp, Lock, Pid, Oid) ->
?ets_insert(mnesia_lock_queue,
#queue{oid = Oid, tid = Tid, op = Op,
pid = Pid, lucky = Lucky}),
- ?ets_insert(mnesia_tid_locks, {Tid, Oid, {queued, Op}})
+ ?ets_insert(mnesia_tid_locks, {{Tid, Oid, {queued, Op}}})
end.
grant_lock(Tid, read, Lock, Oid = {Tab, Key}, Default)
@@ -498,7 +498,7 @@ set_read_lock_on_all_keys(Tid, From, Tab, IxKey, Pos) ->
?ets_insert(mnesia_lock_queue,
#queue{oid = Oid, tid = Tid, op = Op,
pid = From, lucky = Lucky}),
- ?ets_insert(mnesia_tid_locks, {Tid, Oid, {queued, Op}})
+ ?ets_insert(mnesia_tid_locks, {{Tid, Oid, {queued, Op}}})
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -514,7 +514,8 @@ release_remote_non_pending(Node, Pending) ->
%% running at the failed node and also simply remove all
%% queue'd requests back to the failed node
- AllTids = ?ets_match(mnesia_tid_locks, {'$1', '_', '_'}),
+ AllTids0 = ?ets_match(mnesia_tid_locks, {{'$1', '_', '_'}}),
+ AllTids = lists:usort(AllTids0),
Tids = [T || [T] <- AllTids, Node == node(T#tid.pid), not lists:member(T, Pending)],
do_release_tids(Tids).
@@ -525,9 +526,10 @@ do_release_tids([]) ->
ok.
do_release_tid(Tid) ->
- Locks = ?ets_lookup(mnesia_tid_locks, Tid),
+ Objects = ets:select(mnesia_tid_locks, [{{{Tid, '_', '_'}}, [], ['$_']}]),
+ Locks = lists:map(fun({L}) -> L end, Objects),
?dbg("Release ~p ~p ~n", [Tid, Locks]),
- ?ets_delete(mnesia_tid_locks, Tid),
+ [?ets_delete(mnesia_tid_locks, L) || L <- Locks],
release_locks(Locks),
%% Removed queued locks which has had locks
UniqueLocks = keyunique(lists:sort(Locks),[]),
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index c596f98c81..173c46898b 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.12
+MNESIA_VSN = 4.12.1
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index a2c5eda9d7..c135e29520 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -31,6 +31,29 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 2.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ crashdump_viewer would crash if the owner of a timer was
+ specified as the process' registered name. This has been
+ corrected.</p>
+ <p>
+ Own Id: OTP-11919</p>
+ </item>
+ <item>
+ <p>
+ Fix crash and minor updates.</p>
+ <p>
+ Own Id: OTP-11949</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Observer 2.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl
index 03ca1bf9c1..c86f5ea916 100644
--- a/lib/observer/src/observer_wx.erl
+++ b/lib/observer/src/observer_wx.erl
@@ -112,10 +112,6 @@ setup(#state{frame = Frame} = State) ->
observer_lib:create_menus(DefMenus, MenuBar, default),
wxFrame:setMenuBar(Frame, MenuBar),
- StatusBar = wxStatusBar:new(Frame),
- wxFrame:setStatusBar(Frame, StatusBar),
- wxFrame:setTitle(Frame, atom_to_list(node())),
- wxStatusBar:setStatusText(StatusBar, atom_to_list(node())),
%% Setup panels
Panel = wxPanel:new(Frame, []),
@@ -131,6 +127,11 @@ setup(#state{frame = Frame} = State) ->
wxSizer:add(MainSizer, Notebook, [{proportion, 1}, {flag, ?wxEXPAND}]),
wxPanel:setSizer(Panel, MainSizer),
+ StatusBar = wxStatusBar:new(Frame),
+ wxFrame:setStatusBar(Frame, StatusBar),
+ wxFrame:setTitle(Frame, atom_to_list(node())),
+ wxStatusBar:setStatusText(StatusBar, atom_to_list(node())),
+
wxNotebook:connect(Notebook, command_notebook_page_changing),
wxFrame:connect(Frame, close_window, [{skip, true}]),
wxMenu:connect(Frame, command_menu_selected),
diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk
index a6300eeb18..b55cff7332 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 2.0
+OBSERVER_VSN = 2.0.1
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index f86146759c..ea5c51965f 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -228,4 +228,24 @@ if test "x$GCC" = xyes; then
LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
fi
+dnl ----------------------------------------------------------------------
+dnl Enable -fsanitize= flags.
+dnl ----------------------------------------------------------------------
+
+m4_define(DEFAULT_SANITIZERS, [address,undefined])
+AC_ARG_ENABLE(
+ sanitizers,
+ AS_HELP_STRING(
+ [--enable-sanitizers@<:@=comma-separated list of sanitizers@:>@],
+ [Default=DEFAULT_SANITIZERS]),
+[
+case "$enableval" in
+ no) sanitizers= ;;
+ yes) sanitizers="-fsanitize=DEFAULT_SANITIZERS" ;;
+ *) sanitizers="-fsanitize=$enableval" ;;
+esac
+CFLAGS="$CFLAGS $sanitizers"
+LDFLAGS="$LDFLAGS $sanitizers"
+])
+
AC_OUTPUT(c_src/$host/Makefile:c_src/Makefile.in)
diff --git a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
index 5ec0c084e3..c665e1fbc8 100644
--- a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
+++ b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
@@ -176,7 +176,6 @@ addresses({false, Adr, Rest}, Addresses) ->
{lists:reverse([Adr|Addresses]), Rest};
addresses({true, Adr, Rest}, Addresses) ->
addresses(address(protocol, Rest, [], []), [Adr|Addresses]).
-
%% Which protocol.
address(protocol, [$:|T], [], []) ->
address(version, T, [], [iiop]);
@@ -192,6 +191,7 @@ address(protocol, What, _, _) ->
[?LINE, What], ?DEBUG_LEVEL),
corba:raise(#'CosNaming_NamingContextExt_InvalidAddress'{});
+
%% Parsed one address, no version found or port found.
address(version, [$,|T], Acc, Previous) ->
{true, lists:reverse([?DEF_PORT, lists:reverse(Acc), ?DEF_VERS|Previous]), T};
@@ -208,15 +208,26 @@ address(version, [$@|T], Acc, Previous) ->
[?LINE, What], ?DEBUG_LEVEL),
corba:raise(#'CosNaming_NamingContextExt_InvalidAddress'{})
end;
+
+%% Found no iiop version, switch to ipv6.
+address(version, [$[|T], [], Previous) ->
+ address(ipv6, T, [], [?DEF_VERS|Previous]);
+
%% Found no iiop version, switch to port. In this case Acc contains the
%% Host.
address(version, [$:|T], Acc, Previous) ->
- case check_ip_version(T, [$:|Acc]) of
- false ->
- address(port, T, [], [lists:reverse(Acc), ?DEF_VERS|Previous]);
- {ok, NewAcc, NewT, Type} ->
- address(Type, NewT, [], [lists:reverse(NewAcc), ?DEF_VERS|Previous])
- end;
+ address(port, T, [], [lists:reverse(Acc), ?DEF_VERS|Previous]);
+
+%% Found IPv6
+address(address, [$[|T], [], Previous) ->
+ address(ipv6, T, [], Previous);
+
+%% Found port
+address(address, [$:|T], Acc, Previous) ->
+ address(port, T, [], [lists:reverse(Acc)|Previous]);
+
+address(ipv6, [$]|T], Acc, Previous) ->
+ address(address, T, Acc, Previous);
%% Parsed one address, port not found.
address(address, [$,|T], [], Previous) ->
@@ -267,68 +278,9 @@ address(address, [], [], Previous) ->
address(address, [], Acc, Previous) ->
{false, lists:reverse([?DEF_PORT, lists:reverse(Acc)|Previous]), []};
-%% Found port
-address(address, [$:|T], Acc, Previous) ->
- case check_ip_version(T, [$:|Acc]) of
- false ->
- address(port, T, [], [lists:reverse(Acc)|Previous]);
- {ok, NewAcc, NewT, Type} ->
- address(Type, NewT, [], [lists:reverse(NewAcc)|Previous])
- end;
-
address(Type, [H|T], Acc, Previous) ->
address(Type, T, [H|Acc], Previous).
-
-check_ip_version(T, Acc) ->
- case orber_env:ip_version() of
- inet ->
- false;
- inet6 ->
- case search_for_delimiter(1, T, Acc, $:) of
- {ok, NewAcc, NewT, Type} ->
- {ok, NewAcc, NewT, Type};
- _ ->
- false
- end
- end.
-
-%% An IPv6 address may look like (x == hex, d == dec):
-%% * "0:0:0:0:0:0:10.1.1.1" - x:x:x:x:x:x:d.d.d.d
-%% * "0:0:0:0:8:800:200C:417A" - x:x:x:x:x:x:x:x
-%% We cannot allow compressed addresses (::10.1.1.1) since we it is not
-%% possible to know if the last part is a port number or part of the address.
-search_for_delimiter(7, [], Acc, $:) ->
- {ok, Acc, [], address};
-search_for_delimiter(9, [], Acc, $.) ->
- {ok, Acc, [], address};
-search_for_delimiter(_, [], _, _) ->
- false;
-search_for_delimiter(7, [$/|T], Acc, $:) ->
- {ok, Acc, [$/|T], address};
-search_for_delimiter(9, [$/|T], Acc, $.) ->
- {ok, Acc, [$/|T], address};
-search_for_delimiter(_, [$/|_T], _Acc, _) ->
- false;
-search_for_delimiter(7, [$,|T], Acc, $:) ->
- {ok, Acc, [$,|T], address};
-search_for_delimiter(9, [$,|T], Acc, $.) ->
- {ok, Acc, [$,|T], address};
-search_for_delimiter(_, [$,|_T], _Acc, _) ->
- false;
-search_for_delimiter(7, [$:|T], Acc, $:) ->
- {ok, Acc, T, port};
-search_for_delimiter(9, [$:|T], Acc, $.) ->
- {ok, Acc, T, port};
-search_for_delimiter(N, [$:|T], Acc, $:) ->
- search_for_delimiter(N+1, T, [$:|Acc], $:);
-search_for_delimiter(N, [$.|T], Acc, $.) when N > 6, N < 9 ->
- search_for_delimiter(N+1, T, [$.|Acc], $.);
-search_for_delimiter(6, [$.|T], Acc, $:) ->
- search_for_delimiter(7, T, [$.|Acc], $.);
-search_for_delimiter(N, [H|T], Acc, LookingFor) ->
- search_for_delimiter(N, T, [H|Acc], LookingFor).
-
%%----------------------------------------------------------------------
%% Function : key
%% Arguments : A string which contain a Key we want to use and, if defined,
diff --git a/lib/orber/doc/src/ch_naming_service.xml b/lib/orber/doc/src/ch_naming_service.xml
index b735629a14..e355db2edb 100644
--- a/lib/orber/doc/src/ch_naming_service.xml
+++ b/lib/orber/doc/src/ch_naming_service.xml
@@ -273,25 +273,28 @@ lists:foreach(fun({{Id, Kind},BindingType}) -> case BindingType of
<p>The notation of this scheme is similar to the more well known URL <c>HTTP</c>, and
the full <c>corbaloc</c> BNF is:</p>
<code type="none"><![CDATA[
-<corbaloc> = "corbaloc:"<obj_addr_list>["/"<key_string>]
-<obj_addr_list> = [<obj_addr>","]*<obj_addr>
-<obj_addr> = <prot_addr> | <future_prot_addr>
-<prot_addr> = <rir_prot_addr> | <iiop_prot_addr>
-<rir_prot_addr> = <rir_prot_token>":"
-<rir_prot_token> = rir
-<future_prot_addr> = <future_prot_id><future_prot_addr>
-<future_prot_id> = <future_prot_token>":"
-<iiop_prot_addr> = <iiop_id><iiop_addr>
-<iiop_id> = <iiop_default> | <iiop_prot_token>":"
-<iiop_default> = ":"
-<iiop_prot_token> = "iiop"
-<iiop_addr> = <version><host>[":"<port>]
-<host> = DNS-style Host Name | ip_address
-<version> = <major>"."<minor>"@" | empty_string
-<port> = number
-<major> = number
-<minor> = number
-<key_string> = for example NameService
+<corbaloc> = "corbaloc:"<obj_addr_list>["/"<key_string>]
+<obj_addr_list> = [<obj_addr>","]*<obj_addr>
+<obj_addr> = <prot_addr> | <future_prot_addr>
+<prot_addr> = <rir_prot_addr> | <iiop_prot_addr>
+<rir_prot_addr> = <rir_prot_token>":"
+<rir_prot_token> = rir
+<future_prot_addr> = <future_prot_id><future_prot_addr>
+<future_prot_id> = <future_prot_token>":"
+<iiop_prot_addr> = <iiop_id><iiop_addr>
+<iiop_id> = <iiop_default> | <iiop_prot_token>":"
+<iiop_default> = ":"
+<iiop_prot_token> = "iiop"
+<iiop_addr> = <version><host>[":"<port>]
+<host> = <DNS-style Host Name> | <ip_v4_address> | "["<ip_v6_address>"]"
+<version> = <major>"."<minor>"@" | empty_string
+<port> = number
+<major> = number
+<minor> = number
+<DNS-style Host Name> = string
+<ip_v4_address> = string
+<ip_v6_address> = string
+<key_string> = for example NameService
]]></code>
<p>The <c>corbaloc</c> scheme consists of 3 parts:</p>
<list type="bulleted">
diff --git a/lib/orber/doc/src/corba.xml b/lib/orber/doc/src/corba.xml
index 004c7fb9b0..4a11b271b4 100644
--- a/lib/orber/doc/src/corba.xml
+++ b/lib/orber/doc/src/corba.xml
@@ -294,7 +294,9 @@ Example:
<p>This function returns the object reference for the object id asked
for.
The remote modifier string has the following format:
- <c>"iiop://host:port"</c>.</p>
+ <c>"iiop://"&lt;host&gt;":"&lt;port&gt;</c> where <c>&lt;host&gt; = &lt;DNS hostname&gt; |
+ &lt;IPv4 address&gt; | "["&lt;IPv6 address&gt;"]"</c>.
+ </p>
<p>The <em>configuration</em> context is used to override the global
SSL client side
<seealso marker="ch_install#config">configuration</seealso>.</p>
@@ -322,8 +324,11 @@ Example:
<v>ObjectId = string()</v>
</type>
<desc>
- <p>This function returns a list of allowed object id's. The remote modifier
- string has the following format: <c>"iiop://host:port"</c>.</p>
+ <p>This function returns a list of allowed object id's.
+ The remote modifier string has the following format:
+ <c>"iiop://"&lt;host&gt;":"&lt;port&gt;</c> where <c>&lt;host&gt; = &lt;DNS hostname&gt; |
+ &lt;IPv4 address&gt; | "["&lt;IPv6 address&gt;"]"</c>.
+ </p>
<p>The <em>configuration</em> context is used to override the global
SSL client side
<seealso marker="ch_install#config">configuration</seealso>.</p>
@@ -365,9 +370,11 @@ Example:
<p>This function takes a <c>corbaname</c>, <c>corbaloc</c> or an IOR on the
external string representation and returns the object reference.</p>
<p>To lookup the NameService reference, simply use
- <c>"corbaloc:iiop:[email protected]:4001/NameService"</c></p>
+ <c>"corbaloc:iiop:[email protected]:4001/NameService"</c></p>
<p>We can also resolve an object from the NameService by using
- <c>"corbaname:iiop:[email protected]:4001/NameService#org/Erlang/MyObj"</c></p>
+ <c>"corbaname:iiop:[email protected]:4001/NameService#org/Erlang/MyObj"</c></p>
+ <p>To lookup the NameService reference with an IPv6 address, simply use
+ <c>"corbaloc:iiop:1.2@[FEC1:0:3:0:0312:44AF:FAB1:3D01]:4001/NameService"</c></p>
<p>For more information about <c>corbaname</c> and <c>corbaloc</c>, see
the User's Guide (Interoperable Naming Service).</p>
<p>The <em>configuration</em> context is used to override the global
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 93dc403c47..141d306740 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,7 +33,46 @@
</header>
- <section><title>Orber 3.6.27</title>
+ <section><title>Orber 3.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The following functions have been corrected so they
+ work properly with IPv6 addresses. </p> <list>
+ <item><c>corba:resolve_initial_references_remote/2/3</c></item>
+ <item><c>corba:list_initial_references_remote/1/2</c></item>
+ <item><c>corba:string_to_object/1/2</c></item> </list>
+ <p>
+ Own Id: OTP-12016</p>
+ </item>
+ <item>
+ <p> A couple of macros were malformed, missing commas:
+ PROFILEBODY_1_1_TYPEDEF and PROFILEBODY_1_2_TYPEDEF.
+ Thanks to Vlad Dumitrescu. </p>
+ <p>
+ Own Id: OTP-12062</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> It is now possible to add listen interfaces for IPv6
+ when orber is default configured for IPv4 and the other
+ way around. For more information, consult the User's
+ Guide and the orber module Reference Manual. </p>
+ <p>
+ Own Id: OTP-12007</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Orber 3.6.27</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/orber/doc/src/orber.xml b/lib/orber/doc/src/orber.xml
index 16781059c7..a182a56972 100644
--- a/lib/orber/doc/src/orber.xml
+++ b/lib/orber/doc/src/orber.xml
@@ -356,8 +356,8 @@
<v>Type = normal | ssl</v>
<v>Port = integer() > 0</v>
<v>ConfigurationParameters = [{Key, Value}]</v>
- <v>Key = flags | iiop_in_connection_timeout | iiop_max_fragments | iiop_max_in_requests | interceptors | iiop_port | iiop_ssl_port | ssl_server_options</v>
- <v>Value = as described in the User's Guide</v>
+ <v>Key = flags | ip_family | iiop_in_connection_timeout | iiop_max_fragments | iiop_max_in_requests | interceptors | iiop_port | iiop_ssl_port | ssl_server_options</v>
+ <v>Value = as described in the User's Guide or below</v>
<v>Result = {ok, Ref} | {error, Reason} | {'EXCEPTION', #'BAD_PARAM'{}}</v>
<v>Ref = #Ref</v>
<v>Reason = string()</v>
@@ -383,6 +383,9 @@
<item><em>flags</em> - currently it is only possible to override the global
setting for the <c>Use Current Interface in IOR</c> and
<c>Exclude CodeSet Component</c> flags.</item>
+ <item><em>ip_family</em> - can be set to <c>inet</c> or <c>inet6</c> and is
+ used to get a listen interface that uses another IP version than the default
+ set with flags at startup.</item>
<item><em>iiop_port</em> - requires that <c>Use Current Interface in IOR</c>
is activated and the supplied <c>Type</c> is <c>normal</c>. If so,
exported IOR:s will contain the IIOP port defined by this configuration
@@ -390,7 +393,7 @@
<item><em>iiop_ssl_port</em> - almost equivalent to <c>iiop_port</c>.
The difference is that <c>Type</c> shall be <c>ssl</c> and that
exported IOR:s will contain the IIOP via SSL port defined by this configuration
- parameter.</item>
+ parameter.</item>
</list>
<p>If it is not possible to add a listener based on the supplied interface
and port, the error message is one of the ones described in <c>inet</c>
diff --git a/lib/orber/src/Makefile b/lib/orber/src/Makefile
index d96350f4d5..398e481138 100644
--- a/lib/orber/src/Makefile
+++ b/lib/orber/src/Makefile
@@ -194,8 +194,7 @@ ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin
ERL_COMPILE_FLAGS += $(ERL_IDL_FLAGS) \
-I$(ERL_TOP)/lib/orber/include \
+'{parse_transform,sys_pre_attributes}' \
- +'{attribute,insert,app_vsn,"orber_$(ORBER_VSN)"}' \
- -D'ORBVSN="$(ORBER_VSN)"'
+ +'{attribute,insert,app_vsn,"orber_$(ORBER_VSN)"}'
ASN_FLAGS = -bber +der +compact_bit_string +nowarn_unused_record
diff --git a/lib/orber/src/corba.erl b/lib/orber/src/corba.erl
index 989e84f581..586a02d540 100644
--- a/lib/orber/src/corba.erl
+++ b/lib/orber/src/corba.erl
@@ -311,19 +311,18 @@ resolve_initial_references_remote(_ObjectId, [], _Ctx) ->
raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO});
resolve_initial_references_remote(ObjectId, [RemoteModifier| Rest], Ctx)
when is_list(RemoteModifier) ->
- case lists:prefix("iiop://", RemoteModifier) of
- true ->
- [_, Host, Port] = string:tokens(RemoteModifier, ":/"),
+ case parse_remote_modifier(RemoteModifier) of
+ {error, _} ->
+ resolve_initial_references_remote(ObjectId, Rest, Ctx);
+ {ok, Host, Port} ->
IOR = iop_ior:create_external(orber:giop_version(), "",
- Host, list_to_integer(Port), "INIT"),
+ Host, list_to_integer(Port), "INIT"),
%% We know it's an external referens. Hence, no need to check.
{_, Key} = iop_ior:get_key(IOR),
orber_iiop:request(Key, 'get', [ObjectId],
{{'tk_objref', 12, "object"},
[{'tk_string', 0}],
- []}, 'true', infinity, IOR, Ctx);
- false ->
- resolve_initial_references_remote(ObjectId, Rest, Ctx)
+ []}, 'true', infinity, IOR, Ctx)
end.
list_initial_services_remote(Address) ->
@@ -332,24 +331,44 @@ list_initial_services_remote(Address) ->
list_initial_services_remote([], _Ctx) ->
raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO});
list_initial_services_remote([RemoteModifier| Rest], Ctx) when is_list(RemoteModifier) ->
- case lists:prefix("iiop://", RemoteModifier) of
- true ->
- [_, Host, Port] = string:tokens(RemoteModifier, ":/"),
+ case parse_remote_modifier(RemoteModifier) of
+ {error, _} ->
+ resolve_initial_references_remote(Rest, Ctx);
+ {ok, Host, Port} ->
IOR = iop_ior:create_external(orber:giop_version(), "",
Host, list_to_integer(Port), "INIT"),
%% We know it's an external referens. Hence, no need to check.
{_, Key} = iop_ior:get_key(IOR),
orber_iiop:request(Key, 'list', [],
{{'tk_sequence', {'tk_string',0},0},
- [], []}, 'true', infinity, IOR, Ctx);
- false ->
- list_initial_services_remote(Rest, Ctx)
+ [], []}, 'true', infinity, IOR, Ctx)
end;
list_initial_services_remote(_, _) ->
raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+parse_remote_modifier("iiop://" ++ Rest) ->
+ parse_host_version(Rest);
+parse_remote_modifier(_RemoteModifier) ->
+ {error, not_supported}.
+
+parse_host_version("[" ++ Rest) ->
+ parse_ipv6(Rest, []);
+parse_host_version(Rest) ->
+ parse_ipv4_or_dnsname(Rest, []).
+
+
+parse_ipv4_or_dnsname([$: |Rest], Acc) ->
+ {ok, lists:reverse(Acc), Rest};
+parse_ipv4_or_dnsname([C |Rest], Acc) ->
+ parse_ipv4_or_dnsname(Rest, [C |Acc]).
+
+parse_ipv6("]:" ++ Rest, Acc) ->
+ {ok, lists:reverse(Acc), Rest};
+parse_ipv6([C |Rest], Acc) ->
+ parse_ipv6(Rest, [C |Acc]).
+
%%-----------------------------------------------------------------
%% Objectreference convertions
%%-----------------------------------------------------------------
diff --git a/lib/orber/src/corba_request.erl b/lib/orber/src/corba_request.erl
deleted file mode 100644
index c4226739a9..0000000000
--- a/lib/orber/src/corba_request.erl
+++ /dev/null
@@ -1,384 +0,0 @@
-%%--------------------------------------------------------------------
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%-----------------------------------------------------------------
-%% File: corba_request.erl
-%% Description:
-%% This file contains an corba request server for Orber
-%%
-%%-----------------------------------------------------------------
--module(corba_request).
-
--behaviour(gen_server).
-
--include_lib("orber/include/corba.hrl").
-
-%%-----------------------------------------------------------------
-%% External exports
-%%-----------------------------------------------------------------
--export([start/1, stop/0, stop_all/0, create/1,
- create_schema/1]).
-
-%%-----------------------------------------------------------------
-%% Internal exports
-%%-----------------------------------------------------------------
--export([init/1, terminate/2, install/2, handle_call/3, handle_info/2]).
--export([handle_cast/2, dump/0, get_key_from_pid/1]).
-
-%%-----------------------------------------------------------------
-%% Standard interface CORBA::Request
-%%-----------------------------------------------------------------
--export([add_arg/6,
- invoke/2,
- delete/1,
- send/2,
- get_response/2]).
-
-%%-----------------------------------------------------------------
-%% Mnesia table definition
-%%-----------------------------------------------------------------
--record('corba_request', {reqid, ctx, operation, arg_list, result, req_flags, pid}).
-
-
-%%-----------------------------------------------------------------
-%% Macros
-%%-----------------------------------------------------------------
--define(dirty_query_context, true).
-
-%% This macro returns a read fun suitable for evaluation in a transaction
--define(read_function(ReqId),
- fun() ->
- mnesia:dirty_read(ReqId)
- end).
-
-%% This macro returns a write fun suitable for evaluation in a transaction
--define(write_function(R),
- fun() ->
- mnesia:dirty_write(R)
- end).
-
-%% This macro returns a write fun suitable for evaluation in a transaction
--define(update(R),
- fun() ->
- mnesia:dirty_write(R)
- end).
-
-%% This macro returns a delete fun suitable for evaluation in a transaction
--define(delete_function(R),
- fun() ->
- mnesia:delete(R)
- end).
-
--ifdef(dirty_query_context).
--define(query_check(Q_res), Q_res).
--else.
--define(query_check(Q_res), {atomic, Q_res}).
--endif.
-
-
--define(CHECK_EXCEPTION(Res), case Res of
- {'EXCEPTION', E} ->
- corba:raise(E);
- R ->
- R
- end).
-
-%%-----------------------------------------------------------------
-%% Debugging function
-%%-----------------------------------------------------------------
-dump() ->
- case catch mnesia:dirty_first('orber_request') of
- {'EXIT', R} ->
- io:format("Exited with ~p\n",[R]);
- Key ->
- dump_print(Key),
- dump_loop(Key)
- end.
-
-dump_loop(PreviousKey) ->
- case catch mnesia:dirty_next('orber_request', PreviousKey) of
- {'EXIT', R} ->
- io:format("Exited with ~p\n",[R]);
- '$end_of_table' ->
- ok;
- Key ->
- dump_print(Key),
- dump_loop(Key)
- end.
-
-dump_print(Key) ->
- case catch mnesia:dirty_read({'orber_request', Key}) of
- {'EXIT', R} ->
- io:format("Exited with ~p\n",[R]);
- [X] ->
- io:format("Req Id: ~p, op: ~p\n",[binary_to_term(X#orber_request.object_key),
- X#orber_request.pid]);
- _ ->
- ok
- end.
-
-
-%%-----------------------------------------------------------------
-%% External interface functions
-%%-----------------------------------------------------------------
-start(Opts) ->
- gen_server:start_link({local, orber_requestserver}, orber_request, Opts, []).
-
-stop() ->
- gen_server:call(orber_requestserver, stop, infinity).
-
-
-stop_all() ->
- Fun = fun() ->
- mnesia:match_object({orber_request, '_', '_', '_', '_', '_', '_', '_'})
- end,
- case catch mnesia:transaction(Fun) of
- {atomic, Objects} ->
- lists:foreach(fun({orber_request, _, _, _, _, _, _, _ }) ->
- ok %gen_server:call(Pid, stop, infinity)
- end,
- Objects);
- R ->
- R
- end.
-
-create() ->
- ?CHECK_EXCEPTION(gen_server:call(orber_requestserver,
- create, infinity)).
-
-create(Ctx, OP, Args, Flags) ->
- ?CHECK_EXCEPTION(gen_server:call(orber_requestserver,
- {create, Ctx, OP, Args, Flags}, infinity)).
-
-delete(ReqId) ->
- ?CHECK_EXCEPTION(gen_server:call(orber_requestserver,
- {delete, ReqId}, infinity)).
-
-%%------------------------------------------------------------
-%% Implementation of standard interface
-%%------------------------------------------------------------
-add_arg(ReqId, ArgumentName, TC, Value, Len, ArgFlags) ->
- Request = ets:lookup_element(orber_request, ReqId),
- case Request of
- [] ->
- ok;
- R ->
- Args = Request#orber_request.arg_list,
- NewArgs = lists:append(Args, []),
- ets:insert(orber_request, NewArgs),
- ok
- end.
-
-invoke(ReqId, InvokeFlags) ->
- ok.
-
-
-
-send(ReqId, InvokeFlags) ->
- ok.
-
-get_response(ReqId, ResponseFlags) ->
- [{_, Val}] = ets:lookup_element(orber_request, ReqId),
- Val#'orber_request'.result.
-
-%%-----------------------------------------------------------------
-%% Server functions
-%%-----------------------------------------------------------------
-init(Env) ->
- case mnesia:wait_for_tables(['orber_request'], infinity) of
- ok ->
- process_flag(trap_exit, true),
- {ok, []};
- StopReason ->
- {stop, StopReason}
- end.
-
-terminate(From, Reason) ->
- ok.
-
-
-
-install(Timeout, Options) ->
- %% check if there already exists a database. If not, create one.
- %% DB_initialized = perhaps_create_schema(Nodelist),
- %% check if mnesia is running. If not, start mnesia.
- DB_started = perhaps_start_mnesia(),
-
- %% Do we have a complete set of IFR tables? If not, create them.
- AllTabs = mnesia:system_info(tables),
-
- DB_Result = case lists:member(orber_request, AllTabs) of
- true ->
- case lists:member({local_content, true},
- Options) of
- true->
- mnesia:add_table_copy(orber_request,
- node(),
- ram_copies);
- _ ->
- mnesia:create_table(orber_request,
- [{attributes,
- record_info(fields,
- orber_objkeys)}
- |Options])
- end;
- _ ->
- mnesia:create_table(orber_request,
- [{attributes,
- record_info(fields,
- orber_objkeys)}
- |Options])
- end,
-
- Wait = mnesia:wait_for_tables([orber_request], Timeout),
- %% Check if any error has occured yet. If there are errors, return them.
- if
- DB_Result == {atomic, ok},
- Wait == ok ->
- ok;
- true ->
- {error, {DB_Result, Wait}}
- end.
-
-%%-----------------------------------------------------------------
-%% Func: handle_call/3
-%%
-%% Comment:
-%% In objectkey gen_server all exceptions are tupples and corba:raise
-%% may not be used. It is too time consuming to add catches in every
-%% function before returning. On the client side there is a case which
-%% maps every tupple on the format {'exception', E} to corba:raise(E).
-%%-----------------------------------------------------------------
-handle_call(stop, From, State) ->
- {stop, normal, [], State};
-handle_call(create, From, State) ->
- ReqId = term_to_binary({node(), now()}),
- _F = ?write_function(#'corba_request'{reqid=ReqId}),
- R = write_result(mnesia:transaction(_F)),
-
- ReqId
-
- ?query_check(Qres) = mnesia:dirty_read({orber_request, Objkey}),
- case Qres of
- [] ->
- _F = ?write_function(#orber_requests{object_key=Objkey, pid=Pid}),
- R = write_result(mnesia:transaction(_F)),
- if
- R == ok, pid(Pid) ->
- link(Pid);
- true ->
- true
- end,
- {reply, R, State};
- X ->
- {reply, {'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}},
- State}
- end;
-handle_call({delete, ReqId}, From, State) ->
- ?query_check(Qres) = mnesia:dirty_read({orber_request, ReqId}),
- case Qres of
- [] ->
- true;
- [X] when pid(X#orber_request.pid) ->
- unlink(X#orber_request.pid);
- _ ->
- true
- end,
- _F = ?delete_function({orber_request, ReqId}),
- R = write_result(mnesia:transaction(_F)),
- {reply, R, State}.
-
-handle_info({'EXIT', Pid, Reason}, State) when pid(Pid) ->
- _MF = fun() ->
- mnesia:match_object({orber_request, '_', '_', '_', '_', '_', '_', Pid})
- end,
- ?query_check(Qres) = mnesia:ets(_MF),
- case Qres of
- [] ->
- true;
- X ->
- remove_requests(X),
- unlink(Pid);
- _ ->
- true
- end,
- {noreply, State}.
-
-%%-----------------------------------------------------------------
-%% Internal Functions
-%%-----------------------------------------------------------------
-get_reqids_from_pid(Pid) ->
- case mnesia:dirty_match_object({orber_request, '_', '_', '_', '_', '_', '_', Pid}) of
- Keys ->
- [Keys]
- _ ->
- corba:raise(#'OBJECT_NOT_EXIST'{completion_status=?COMPLETED_NO})
- end.
-
-remove_requests([]) ->
- ok;
-remove_requests([H|T]) ->
- _F = ?delete_function({orber_request, H#orber_request.reqid}),
- write_result(mnesia:transaction(_F)),
- remove_requests(T).
-
-%%-----------------------------------------------------------------
-%% Check a read transaction
-query_result(?query_check(Qres)) ->
- case Qres of
- [Hres] ->
- Hres#orber_request.pid;
- [] ->
- {'excpetion', #'OBJECT_NOT_EXIST'{completion_status=?COMPLETED_NO}};
- Other ->
- {'excpetion', #'INTERNAL'{completion_status=?COMPLETED_NO}}
- end.
-
-%%-----------------------------------------------------------------
-%% Check a write transaction
-write_result({atomic,ok}) -> ok;
-write_result(Foo) ->
- {'excpetion', #'INTERNAL'{completion_status=?COMPLETED_NO}}.
-
-
-create_schema(Nodes) ->
- case mnesia:system_info(use_dir) of
- false ->
- mnesia:create_schema(Nodes);
- _ ->
- ok
- end.
-
-perhaps_start_mnesia() ->
- case mnesia:system_info(is_running) of
- no ->
- mnesia:start();
- _ ->
- ok
- end.
-
-
-%%------------------------------------------------------------
-%% Standard gen_server cast handle
-%%
-handle_cast(_, State) ->
- {noreply, State}.
-
-
diff --git a/lib/orber/src/orber_env.erl b/lib/orber/src/orber_env.erl
index 1c8a90bc81..16dbb74253 100644
--- a/lib/orber/src/orber_env.erl
+++ b/lib/orber/src/orber_env.erl
@@ -204,9 +204,9 @@ info(IoDevice) ->
_ ->
lists:flatten(
io_lib:format("======= Orber Execution Environment ======~n"
- " *** Orber-~s is not running ***~n"
+ " *** Orber is not running ***~n"
"==========================================~n",
- [?ORBVSN]))
+ []))
end,
case IoDevice of
info_msg ->
@@ -223,6 +223,7 @@ info(IoDevice) ->
create_main_info() ->
{Major, Minor} = giop_version(),
+ {orber, _, OrberVsn} = lists:keyfind(orber, 1, application:loaded_applications()),
[io_lib:format("======= Orber Execution Environment ======~n"
"Orber version.................: ~s~n"
"Orber domain..................: ~s~n"
@@ -257,7 +258,7 @@ create_main_info() ->
"Debug Level...................: ~p~n"
"orbInitRef....................: ~p~n"
"orbDefaultInitRef.............: ~p~n",
- [?ORBVSN, domain(), iiop_port(), nat_iiop_port(), host(),
+ [OrberVsn, domain(), iiop_port(), nat_iiop_port(), host(),
nat_host(), ip_address_local(),
orber:orber_nodes(), Major, Minor,
iiop_timeout(), iiop_connection_timeout(),
diff --git a/lib/orber/src/orber_iiop.hrl b/lib/orber/src/orber_iiop.hrl
index 7a30af63e4..b2e970b30d 100644
--- a/lib/orber/src/orber_iiop.hrl
+++ b/lib/orber/src/orber_iiop.hrl
@@ -467,14 +467,14 @@
[{"iiop_version",?IIOP_VERSION },
{"host", {'tk_string', 0}},
{"port", 'tk_ushort'},
- {"object_key", {'tk_sequence', 'tk_octet', 0}}
+ {"object_key", {'tk_sequence', 'tk_octet', 0}},
{"components", ?IOP_TAGGEDCOMPONENT_SEQ}]}).
-define(PROFILEBODY_1_2_TYPEDEF, {'tk_struct', ?SYSTEM_TYPE, 'IIOP_ProfileBody_1_1',
[{"iiop_version",?IIOP_VERSION },
{"host", {'tk_string', 0}},
{"port", 'tk_ushort'},
- {"object_key", {'tk_sequence', 'tk_octet', 0}}
+ {"object_key", {'tk_sequence', 'tk_octet', 0}},
{"components", ?IOP_TAGGEDCOMPONENT_SEQ}]}).
-define(SSLIOP_SSL, {'tk_struct', ?SYSTEM_TYPE, 'SSLIOP_SSL',
diff --git a/lib/orber/src/orber_iiop_net.erl b/lib/orber/src/orber_iiop_net.erl
index 33e02e3c04..1bfc6b7d58 100644
--- a/lib/orber/src/orber_iiop_net.erl
+++ b/lib/orber/src/orber_iiop_net.erl
@@ -157,7 +157,7 @@ terminate(_Reason, _State) ->
ok.
%%-----------------------------------------------------------------
-%% Func: parse_options/2
+%% Func: get_options/2
%%-----------------------------------------------------------------
get_options(normal, _Options) ->
[];
@@ -212,14 +212,21 @@ get_options(ssl, Options) ->
%%-----------------------------------------------------------------
parse_options([{port, Type, Port} | Rest], State) ->
Options = get_options(Type, []),
- Options2 = case orber_env:ip_address_variable_defined() of
- false ->
- Options;
- Host ->
- IPVersion = orber:ip_version(),
- {ok, IP} = inet:getaddr(Host, IPVersion),
- [{ip, IP} | Options]
- end,
+ Family = orber_env:ip_version(),
+ IPFamilyOptions =
+ case Family of
+ inet -> [inet];
+ inet6 -> [inet6, {ipv6_v6only, true}]
+ end,
+ Options2 =
+ case orber_env:ip_address_variable_defined() of
+ false ->
+ IPFamilyOptions ++ Options;
+ Host ->
+ {ok, IP} = inet:getaddr(Host, Family),
+ IPFamilyOptions ++ [{ip, IP} |Options]
+ end,
+
{ok, Listen, NewPort} = orber_socket:listen(Type, Port, Options2, true),
{ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, 0),
link(Pid),
@@ -283,28 +290,33 @@ handle_call({remove, Ref}, _From, State) ->
{reply, ok, State}
end;
handle_call({add, IP, Type, Port, AllOptions}, _From, State) ->
- Family = orber_env:ip_version(),
+ Family = orber_tb:keysearch(ip_family, AllOptions, orber_env:ip_version()),
+ IPFamilyOptions =
+ case Family of
+ inet -> [inet];
+ inet6 -> [inet6, {ipv6_v6only, true}]
+ end,
case inet:getaddr(IP, Family) of
{ok, IPTuple} ->
- try [{ip, IPTuple} |get_options(Type, AllOptions)] of
- Options ->
- Ref = make_ref(),
- ProxyOptions = filter_options(AllOptions, []),
- case orber_socket:listen(Type, Port, Options, false) of
- {ok, Listen, NewPort} ->
- {ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, Ref,
- ProxyOptions),
- link(Pid),
- ets:insert(?CONNECTION_DB, #listen{pid = Pid,
- socket = Listen,
- port = NewPort,
- type = Type, ref = Ref,
- options = Options,
- proxy_options = ProxyOptions}),
- {reply, {ok, Ref}, State};
- Error ->
- {reply, Error, State}
- end
+ try
+ Options = IPFamilyOptions ++ [{ip, IPTuple} |get_options(Type, AllOptions)],
+ Ref = make_ref(),
+ ProxyOptions = filter_options(AllOptions, []),
+ case orber_socket:listen(Type, Port, Options, false) of
+ {ok, Listen, NewPort} ->
+ {ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, Ref,
+ ProxyOptions),
+ link(Pid),
+ ets:insert(?CONNECTION_DB, #listen{pid = Pid,
+ socket = Listen,
+ port = NewPort,
+ type = Type, ref = Ref,
+ options = Options,
+ proxy_options = ProxyOptions}),
+ {reply, {ok, Ref}, State};
+ Error ->
+ {reply, Error, State}
+ end
catch
error:Reason ->
{reply, {error, Reason}, State}
diff --git a/lib/orber/src/orber_iiop_outproxy.erl b/lib/orber/src/orber_iiop_outproxy.erl
index 8319d89088..4ba5b05995 100644
--- a/lib/orber/src/orber_iiop_outproxy.erl
+++ b/lib/orber/src/orber_iiop_outproxy.erl
@@ -112,7 +112,8 @@ stop(Pid) ->
%%-----------------------------------------------------------------
init({connect, Host, Port, SocketType, SocketOptions, Parent, Key, NewKey}) ->
process_flag(trap_exit, true),
- case catch orber_socket:connect(SocketType, Host, Port, SocketOptions) of
+ case catch orber_socket:connect(SocketType, Host, Port,
+ get_ip_family_opts(Host) ++ SocketOptions) of
{'EXCEPTION', _E} ->
ignore;
%% We used to reply the below but since this would generate a CRASH REPORT
@@ -507,3 +508,38 @@ clear_queue(Proxy, RequestId, MRef) ->
end
end.
+get_ip_family_opts(Host) ->
+ case inet:parse_address(Host) of
+ {ok, {_,_,_,_}} ->
+ [inet];
+ {ok, {_,_,_,_,_,_,_,_}} ->
+ [inet6];
+ {error, einval} ->
+ check_family_for_name(Host, orber_env:ip_version())
+ end.
+
+check_family_for_name(Host, inet) ->
+ case inet:getaddr(Host, inet) of
+ {ok, _Address} ->
+ [inet];
+ {error, _} ->
+ case inet:getaddrs(Host, inet6) of
+ {ok, _Address} ->
+ [inet6];
+ {error, _} ->
+ [inet]
+ end
+ end;
+check_family_for_name(Host, inet6) ->
+ case inet:getaddr(Host, inet6) of
+ {ok, _Address} ->
+ [inet6];
+ {error, _} ->
+ case inet:getaddr(Host, inet) of
+ {ok, _Address} ->
+ [inet];
+ {error, _} ->
+ [inet6]
+ end
+ end.
+
diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl
index 07a0e09ccc..c8d2f0636b 100644
--- a/lib/orber/src/orber_socket.erl
+++ b/lib/orber/src/orber_socket.erl
@@ -205,29 +205,27 @@ listen(normal, Port, Options, Exception) ->
MaxSize ->
[{packet_size, MaxSize}|Options2]
end,
- case catch gen_tcp:listen(Port, [binary, {packet,cdr}, {keepalive, Keepalive},
+ Options4 = [binary, {packet,cdr}, {keepalive, Keepalive},
{reuseaddr,true}, {backlog, Backlog} |
- Options3]) of
+ Options3],
+
+ case catch gen_tcp:listen(Port, Options4) of
{ok, ListenSocket} ->
{ok, ListenSocket, check_port(Port, normal, ListenSocket)};
{error, Reason} when Exception == false ->
{error, Reason};
{error, eaddrinuse} ->
- AllOpts = [binary, {packet,cdr},
- {reuseaddr,true} | Options3],
orber:dbg("[~p] orber_socket:listen(normal, ~p, ~p);~n"
"Looks like the listen port is already in use.~n"
"Check if another Orber is started~n"
"on the same node and uses the same listen port (iiop_port). But it may also~n"
"be used by any other application; confirm with 'netstat'.",
- [?LINE, Port, AllOpts], ?DEBUG_LEVEL),
+ [?LINE, Port, Options4], ?DEBUG_LEVEL),
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO});
Error ->
- AllOpts = [binary, {packet,cdr},
- {reuseaddr,true} | Options3],
orber:dbg("[~p] orber_socket:listen(normal, ~p, ~p);~n"
"Failed with reason: ~p",
- [?LINE, Port, AllOpts, Error], ?DEBUG_LEVEL),
+ [?LINE, Port, Options4, Error], ?DEBUG_LEVEL),
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
end;
listen(ssl, Port, Options, Exception) ->
@@ -252,26 +250,24 @@ listen(ssl, Port, Options, Exception) ->
true ->
Options3
end,
- case catch ssl:listen(Port, [binary, {packet,cdr},
- {backlog, Backlog} | Options4]) of
+ Options5 = [binary, {packet,cdr}, {backlog, Backlog} | Options4],
+ case catch ssl:listen(Port, Options5) of
{ok, ListenSocket} ->
{ok, ListenSocket, check_port(Port, ssl, ListenSocket)};
{error, Reason} when Exception == false ->
{error, Reason};
{error, eaddrinuse} ->
- AllOpts = [binary, {packet,cdr} | Options4],
orber:dbg("[~p] orber_socket:listen(ssl, ~p, ~p);~n"
"Looks like the listen port is already in use. Check if~n"
"another Orber is started on the same node and uses the~n"
"same listen port (iiop_port). But it may also~n"
"be used by any other application; confirm with 'netstat'.",
- [?LINE, Port, AllOpts], ?DEBUG_LEVEL),
+ [?LINE, Port, Options5], ?DEBUG_LEVEL),
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO});
Error ->
- AllOpts = [binary, {packet,cdr} | Options4],
orber:dbg("[~p] orber_socket:listen(ssl, ~p, ~p);~n"
"Failed with reason: ~p",
- [?LINE, Port, AllOpts, Error], ?DEBUG_LEVEL),
+ [?LINE, Port, Options5, Error], ?DEBUG_LEVEL),
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
end.
@@ -485,16 +481,14 @@ check_port(Port, _, _) ->
%%-----------------------------------------------------------------
%% Check Options.
check_options(normal, Options, _Generation) ->
- [orber:ip_version()|Options];
+ Options;
check_options(ssl, Options, Generation) ->
- case orber:ip_version() of
- inet when Generation > 2 ->
+ if
+ Generation > 2 ->
[{ssl_imp, new}|Options];
- inet ->
- [{ssl_imp, old}|Options];
- inet6 when Generation > 2 ->
- [{ssl_imp, new}, inet6|Options];
- inet6 ->
- [{ssl_imp, old}, inet6|Options]
+ true ->
+ [{ssl_imp, old}|Options]
end.
+
+
diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile
index 2f8777c773..50be14c24a 100644
--- a/lib/orber/test/Makefile
+++ b/lib/orber/test/Makefile
@@ -73,7 +73,8 @@ MODULES = \
orber_firewall_ipv6_in_SUITE \
orber_firewall_ipv4_out_SUITE \
orber_firewall_ipv6_out_SUITE \
- orber_nat_SUITE
+ orber_nat_SUITE \
+ ip_v4v6_interop_SUITE
GEN_MOD_ORBER = \
oe_orber_test \
diff --git a/lib/orber/test/ip_v4v6_interop_SUITE.erl b/lib/orber/test/ip_v4v6_interop_SUITE.erl
new file mode 100644
index 0000000000..5eee5a29c2
--- /dev/null
+++ b/lib/orber/test/ip_v4v6_interop_SUITE.erl
@@ -0,0 +1,199 @@
+%%----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% File : ip_v4v6_interop_SUITE.erl
+%% Description :
+%%
+%%----------------------------------------------------------------------
+-module(ip_v4v6_interop_SUITE).
+
+-compile(export_all).
+%%----------------------------------------------------------------------
+%% External exports
+%%----------------------------------------------------------------------
+-export([
+ all/0,
+ init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ end_per_testcase/2,
+ groups/0,
+ init_per_group/2,
+ end_per_group/2
+ ]).
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+%%----------------------------------------------------------------------
+%% Macros
+%%----------------------------------------------------------------------
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+%%----------------------------------------------------------------------
+%% Records
+%%----------------------------------------------------------------------
+
+%%======================================================================
+%% Initialization functions.
+%%======================================================================
+
+init_per_testcase(_Case, Config) ->
+ %% Starting dual configured ORB
+ orber:jump_start([{iiop_port, 10001}, {flags, 16#1000}]),
+ orber:info(),
+ Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+end_per_testcase(_Case, Config) ->
+ orber:jump_stop(),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ Config.
+
+%%====================================================================
+%% SUITE specification
+%%====================================================================
+all() ->
+ [
+ dual_ipv4v6
+ ].
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+%%====================================================================
+%% Test Cases
+%%====================================================================
+dual_ipv4v6(doc) ->
+ ["ORB configured for supporting both IPv4 and IPv6"];
+dual_ipv4v6(_Config) ->
+
+ %% Starting slave node with ipv4 configured ORB
+ {ok, Ipv4Node, _Ipv4Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_port, 4001}])),
+ Ipv4NS = orber_test_lib:remote_apply(Ipv4Node, corba, resolve_initial_references, ["NameService"]),
+
+ %% Starting slave node with ipv6 configured ORB
+ {ok, Ipv6Node, _Ipv6Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_port, 6001}, {flags, 16#0100}])),
+ Ipv6NS = orber_test_lib:remote_apply(Ipv6Node, corba, resolve_initial_references, ["NameService"]),
+
+ %% Add the ipv6 interface in the dual configured ORB
+ ?match({ok, _}, orber:add_listen_interface("::1", normal,
+ [{ip_family, inet6}, {iiop_port, 10002}])),
+ DualNS = corba:resolve_initial_references("NameService"),
+
+ %% Bind IPv4 NameServer to a name in the dual stack orbs NameServer
+ NSDual4 = orber_test_lib:remote_apply(Ipv4Node, corba, resolve_initial_references_remote,
+ ["NameService", ["iiop://127.0.0.1:10001"]]),
+ ?match(ok, orber_test_lib:remote_apply(Ipv4Node, 'CosNaming_NamingContext', bind,
+ [NSDual4, lname:new(["ns4"]), Ipv4NS])),
+ 'CosNaming_NamingContext':resolve(DualNS, lname:new(["ns4"])),
+
+ %% Bind IPv6 NameServer to a name in the dual stack orbs NameServer
+ NSDual6 = orber_test_lib:remote_apply(Ipv6Node, corba, resolve_initial_references_remote,
+ ["NameService", ["iiop://[::1]:10002"]]),
+ ?match(ok, orber_test_lib:remote_apply(Ipv6Node, 'CosNaming_NamingContext', bind,
+ [NSDual6, lname:new(["ns6"]), Ipv6NS])),
+ 'CosNaming_NamingContext':resolve(DualNS, lname:new(["ns6"])),
+
+ %% IPv4: Fetch IPv6 NS reference from dual stack orber and register own NameServer in that
+ Ipv4NSO = orber_test_lib:remote_apply(Ipv4Node, 'CosNaming_NamingContext', resolve,
+ [NSDual4, lname:new(["ns6"])]),
+ ?match(ok, orber_test_lib:remote_apply(Ipv4Node, 'CosNaming_NamingContext', bind,
+ [Ipv4NSO, lname:new(["nso"]), Ipv4NS])),
+
+ %% IPv6: Fetch IPv4 NS reference from dual stack orber and register own NameServer in that
+ Ipv6NSO = orber_test_lib:remote_apply(Ipv6Node, 'CosNaming_NamingContext', resolve,
+ [NSDual6, lname:new(["ns4"])]),
+ ?match(ok, orber_test_lib:remote_apply(Ipv6Node, 'CosNaming_NamingContext', bind,
+ [Ipv6NSO, lname:new(["nso"]), Ipv6NS])),
+
+
+ %% IPv4: Fetch own NS reference from IPv6 NameServer and add a context then check that everything went well
+ Ipv4NSFromIpv6 = orber_test_lib:remote_apply(Ipv6Node, 'CosNaming_NamingContext', resolve,
+ [Ipv6NS, lname:new(["nso"])]),
+ _Ipv4NC = orber_test_lib:remote_apply(Ipv4Node, 'CosNaming_NamingContext', bind_new_context,
+ [Ipv4NSFromIpv6, lname:new(["test_context4"])]),
+
+ %% IPv6: Fetch own NS reference from IPv4 NameServer and add a context then check that everything went well
+ Ipv6NSFromIpv4 = orber_test_lib:remote_apply(Ipv4Node, 'CosNaming_NamingContext', resolve,
+ [Ipv4NS, lname:new(["nso"])]),
+ _Ipv6NC = orber_test_lib:remote_apply(Ipv6Node, 'CosNaming_NamingContext', bind_new_context,
+ [Ipv6NSFromIpv4, lname:new(["test_context6"])]),
+
+ %% Check that all the names are register correctly
+ {ok,DualNames,_} = 'CosNaming_NamingContext':list(DualNS, 100),
+ {ok,Ipv4Names,_} = orber_test_lib:remote_apply(Ipv4Node, 'CosNaming_NamingContext', list, [Ipv4NS, 100]),
+ {ok,Ipv6Names,_} = orber_test_lib:remote_apply(Ipv6Node, 'CosNaming_NamingContext', list, [Ipv6NS, 100]),
+
+ io:format("\nNames in Dual NS: ~p\n", [DualNames]),
+ ?match(2, length(DualNames)),
+ io:format("\nNames in IPv4 NS: ~p\n", [Ipv4Names]),
+ ?match(2, length(Ipv4Names)),
+ io:format("\nNames in IPv6 NS: ~p\n", [Ipv6Names]),
+ ?match(2, length(Ipv6Names)),
+
+ ok.
+
diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl
index 41a309ff16..40d8846e0f 100644
--- a/lib/orber/test/multi_ORB_SUITE.erl
+++ b/lib/orber/test/multi_ORB_SUITE.erl
@@ -582,12 +582,12 @@ proxy_interface_ipv6_api2() ->
IOR1 = ?match(#'IOP_IOR'{},
orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
- ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ["corbaloc::1.2@["++IP++"]:"++integer_to_list(ServerPort)++"/NameService"])),
?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR1])),
IOR2 = ?match(#'IOP_IOR'{},
orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
- ["corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ["corbaloc::1.2@["++Loopback++"]:"++integer_to_list(ServerPort)++"/NameService"])),
?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR2])),
ok.
diff --git a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
index 10827b6ef5..2853949a49 100644
--- a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
@@ -188,6 +188,7 @@ allow_port_range_api(_Config) ->
?ORB_ENV_USE_ACL_INCOMING)},
{iiop_acl, [{tcp_in, IP++"/128#5980/6000"}]}])),
ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ io:format("ServerNode: ~p\nServerHost: ~p\n", [ServerNode, ServerHost]),
IOR =
?match({'IOP_IOR',_,_},
corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
@@ -243,34 +244,34 @@ check_address_api(doc) -> ["Test corbaloc strings"];
check_address_api(suite) -> [];
check_address_api(_Config) ->
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],"NameService"},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:C02A:2A2A]/NameService")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],[]},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:C02A:2A2A]")),
?match({[[iiop,{1,2},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],"NameService"},
- orber_cosnaming_utils:addresses(":1.2@0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ orber_cosnaming_utils:addresses(":1.2@[0:0:0:0:0:FFFF:C02A:2A2A]/NameService")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],"NameService"},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:C02A:2A2A]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],"NameService"},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],[]},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],[]},
- orber_cosnaming_utils:addresses("iiop:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")),
+ orber_cosnaming_utils:addresses("iiop:1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809]],"NameService"},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11/NameService")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:10.11.11.11]/NameService")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809]],[]},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:10.11.11.11]")),
?match({[[iiop,{1,2},"0:0:0:0:0:FFFF:10.11.11.11",2809]],"NameService"},
- orber_cosnaming_utils:addresses(":1.2@0:0:0:0:0:FFFF:10.11.11.11/NameService")),
+ orber_cosnaming_utils:addresses(":1.2@[0:0:0:0:0:FFFF:10.11.11.11]/NameService")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",4001]],"NameService"},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11:4001/NameService")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:10.11.11.11]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],"NameService"},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/NameService")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],[]},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001/")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],[]},
- orber_cosnaming_utils:addresses("iiop:1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/")),
+ orber_cosnaming_utils:addresses("iiop:1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001/")),
?match({[[iiop,{1,1},"myhost",4001]],[]},
orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001")),
@@ -282,31 +283,31 @@ check_address_api(_Config) ->
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001,:1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], []},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001,:1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",4001],
[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:10.11.11.11]:4001,:1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001,:[0:0:0:0:0:FFFF:C02A:2A2A]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",2809],
[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11],:1.1@[0:0:0:0:0:FFFF:C02A:2A2A]:4001/NameService")),
?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], "NameService"},
- orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ orber_cosnaming_utils:addresses(":1.1@[0:0:0:0:0:FFFF:10.11.11.11]:4001,:1.1@[0:0:0:0:0:FFFF:C02A:2A2A]/NameService")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809],
[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], "NameService"},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:10.11.11.11],:[0:0:0:0:0:FFFF:C02A:2A2A]/NameService")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809],
[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], []},
- orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/")),
+ orber_cosnaming_utils:addresses(":[0:0:0:0:0:FFFF:10.11.11.11],:[0:0:0:0:0:FFFF:C02A:2A2A]/")),
?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809],
[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], []},
- orber_cosnaming_utils:addresses("iiop:0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/")),
+ orber_cosnaming_utils:addresses("iiop:[0:0:0:0:0:FFFF:10.11.11.11],:[0:0:0:0:0:FFFF:C02A:2A2A]/")),
[IP] = ?match([_], orber:host()),
{ok, ServerNode, _ServerHost} =
@@ -315,7 +316,7 @@ check_address_api(_Config) ->
{iiop_acl, [{tcp_in, IP++"/128"}]}])),
ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
?match({'IOP_IOR',_,_},
- corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ corba:string_to_object("corbaloc::1.2@["++IP++"]:"++integer_to_list(ServerPort)++"/NameService")),
% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
ok.
diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl
index 6824d25aef..46ed26f210 100644
--- a/lib/orber/test/orber_test_lib.erl
+++ b/lib/orber/test/orber_test_lib.erl
@@ -166,7 +166,7 @@ get_host(Family) ->
{6, _, _} when Family == inet ->
"127.0.0.1";
{6, _, _} ->
- "0:0:0:0:0:FFFF:7F00:0001";
+ "0:0:0:0:0:0:0:0001";
_ ->
[IP] = ?match([_], orber:host()),
IP
@@ -192,16 +192,16 @@ get_loopback_interface(Family) ->
{6, _, _} when Family == inet ->
"127.0.0.2";
{6, _, _} ->
- "0:0:0:0:0:FFFF:7F00:0002";
+ "0:0:0:0:0:0:0:0002";
_ when Family == inet ->
"127.0.0.1";
_ ->
- "0:0:0:0:0:FFFF:7F00:0001"
+ "0:0:0:0:0:0:0:0001"
end;
_ when Family == inet ->
"127.0.0.1";
_ ->
- "0:0:0:0:0:FFFF:7F00:0001"
+ "0:0:0:0:0:0:0:0001"
end.
%%------------------------------------------------------------
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 3ea64b1ff6..13bdf55c07 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1,2 +1,2 @@
-ORBER_VSN = 3.6.27
+ORBER_VSN = 3.7
diff --git a/lib/os_mon/doc/src/disksup.xml b/lib/os_mon/doc/src/disksup.xml
index dbcfd65095..0e76178edb 100644
--- a/lib/os_mon/doc/src/disksup.xml
+++ b/lib/os_mon/doc/src/disksup.xml
@@ -73,6 +73,17 @@
much disk can be utilized before the <c>disk_almost_full</c>
alarm is set. The default is 0.80 (80%).</p>
</item>
+ <tag><c>disksup_posix_only = bool()</c></tag>
+ <item>
+ <p>Specifies whether the <c>disksup</c> helper process should only
+ use POSIX conformant commands (<c>true</c>) or not. The default is
+ <c>false</c>. Setting this parameter to <c>true</c> can be
+ necessary on embedded systems with stripped-down versions
+ of Unix tools like <c>df</c>. The returned disk data and alarms
+ can be different when using this option.</p>
+ <p>The parameter is ignored on platforms that are known to not be
+ posix compatible (Windows and SunOS).</p>
+ </item>
</taglist>
<p>See <seealso marker="kernel:config">config(4)</seealso> for
information about how to change the value of configuration
diff --git a/lib/os_mon/src/disksup.erl b/lib/os_mon/src/disksup.erl
index 278da26a20..af5bcc6fe8 100644
--- a/lib/os_mon/src/disksup.erl
+++ b/lib/os_mon/src/disksup.erl
@@ -81,10 +81,12 @@ param_type(disk_space_check_interval, Val) when is_integer(Val),
param_type(disk_almost_full_threshold, Val) when is_number(Val),
0=<Val,
Val=<1 -> true;
+param_type(disksup_posix_only, Val) when Val==true; Val==false -> true;
param_type(_Param, _Val) -> false.
param_default(disk_space_check_interval) -> 30;
-param_default(disk_almost_full_threshold) -> 0.80.
+param_default(disk_almost_full_threshold) -> 0.80;
+param_default(disksup_posix_only) -> false.
%%----------------------------------------------------------------------
%% gen_server callbacks
@@ -94,7 +96,8 @@ init([]) ->
process_flag(trap_exit, true),
process_flag(priority, low),
- OS = get_os(),
+ PosixOnly = os_mon:get_env(disksup, disksup_posix_only),
+ OS = get_os(PosixOnly),
Port = case OS of
{unix, Flavor} when Flavor==sunos4;
Flavor==solaris;
@@ -102,6 +105,7 @@ init([]) ->
Flavor==dragonfly;
Flavor==darwin;
Flavor==linux;
+ Flavor==posix;
Flavor==openbsd;
Flavor==netbsd;
Flavor==irix64;
@@ -205,14 +209,16 @@ format_status(_Opt, [_PDict, #state{os = OS, threshold = Threshold,
%% Internal functions
%%----------------------------------------------------------------------
-get_os() ->
+get_os(PosixOnly) ->
case os:type() of
{unix, sunos} ->
- case os:version() of
+ case os:version() of
{5,_,_} -> {unix, solaris};
{4,_,_} -> {unix, sunos4};
V -> exit({unknown_os_version, V})
- end;
+ end;
+ {unix, _} when PosixOnly ->
+ {unix, posix};
{unix, irix64} -> {unix, irix};
OS ->
OS
@@ -259,6 +265,9 @@ check_disk_space({unix, irix}, Port, Threshold) ->
check_disk_space({unix, linux}, Port, Threshold) ->
Result = my_cmd("/bin/df -lk", Port),
check_disks_solaris(skip_to_eol(Result), Threshold);
+check_disk_space({unix, posix}, Port, Threshold) ->
+ Result = my_cmd("df -k -P", Port),
+ check_disks_solaris(skip_to_eol(Result), Threshold);
check_disk_space({unix, dragonfly}, Port, Threshold) ->
Result = my_cmd("/bin/df -k -t ufs,hammer", Port),
check_disks_solaris(skip_to_eol(Result), Threshold);
diff --git a/lib/os_mon/test/disksup_SUITE.erl b/lib/os_mon/test/disksup_SUITE.erl
index 94661cfa77..f9addd96cf 100644
--- a/lib/os_mon/test/disksup_SUITE.erl
+++ b/lib/os_mon/test/disksup_SUITE.erl
@@ -29,6 +29,7 @@
-export([port/1]).
-export([terminate/1, unavailable/1, restart/1]).
-export([otp_5910/1]).
+-export([posix_only/1]).
%% Default timetrap timeout (set in init_per_testcase)
-define(default_timeout, ?t:minutes(1)).
@@ -48,7 +49,8 @@ init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?default_timeout),
[{watchdog,Dog} | Config].
-end_per_testcase(unavailable, Config) ->
+end_per_testcase(TC, Config) when TC =:= unavailable;
+ TC =:= posix_only ->
restart(Config),
end_per_testcase(dummy, Config);
end_per_testcase(_Case, Config) ->
@@ -60,11 +62,10 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
Bugs = [otp_5910],
+ Always = [api, config, alarm, port, posix_only, unavailable] ++ Bugs,
case test_server:os_type() of
- {unix, sunos} ->
- [api, config, alarm, port, unavailable] ++ Bugs;
- {unix, _OSname} -> [api, alarm] ++ Bugs;
- {win32, _OSname} -> [api, alarm] ++ Bugs;
+ {unix, _OSname} -> Always;
+ {win32, _OSname} -> Always;
_OS -> [unavailable]
end.
@@ -83,12 +84,7 @@ api(doc) -> ["Test of API functions"];
api(Config) when is_list(Config) ->
%% get_disk_data()
- [{Id,KByte,Capacity}|_] = get_disk_data(),
- true = io_lib:printable_list(Id),
- true = is_integer(KByte),
- true = is_integer(Capacity),
- true = Capacity>0,
- true = KByte>0,
+ ok = check_get_disk_data(),
%% get_check_interval()
1800000 = disksup:get_check_interval(),
@@ -340,6 +336,7 @@ restart(suite) ->
[];
restart(Config) when is_list(Config) ->
ok = application:set_env(os_mon, start_disksup, true),
+ ok = application:set_env(os_mon, disksup_posix_only, false),
{ok, _Pid} = supervisor:restart_child(os_mon_sup, disksup),
ok.
@@ -405,9 +402,28 @@ otp_5910(Config) when is_list(Config) ->
ok = application:start(os_mon),
ok.
+posix_only(suite) -> [];
+posix_only(doc) -> ["Test disksup_posix_only option"];
+posix_only(Config) when is_list(Config) ->
+ %% Set option and restart disksup
+ ok = application:set_env(os_mon, disksup_posix_only, true),
+ ok = supervisor:terminate_child(os_mon_sup, disksup),
+ {ok, _Child1} = supervisor:restart_child(os_mon_sup, disksup),
+
+ ok = check_get_disk_data().
+
dump_info() ->
io:format("Status: ~p~n", [sys:get_status(disksup)]).
+check_get_disk_data() ->
+ [{Id,KByte,Capacity}|_] = get_disk_data(),
+ true = io_lib:printable_list(Id),
+ true = is_integer(KByte),
+ true = is_integer(Capacity),
+ true = Capacity>0,
+ true = KByte>0,
+ ok.
+
% filter get_disk_data and remove entriew with zero capacity
% "non-normal" filesystems report zero capacity
% - Perhaps errorneous 'df -k -l'?
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index 969af2d745..18b36ff953 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -37,7 +37,23 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.6.5</title>
+ <section><title>Reltool 0.6.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a minor typo in an error message from
+ reltool_server.</p>
+ <p>
+ Own Id: OTP-11977</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.6.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index 98eeed5c27..e7af4bd3f7 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -2030,7 +2030,7 @@ ensure_app_info(#app{name = Name,
[BadVsn | _] ->
reltool_utils:throw_error(
"~w: Application version clash. "
- "Multiple directories contains version ~tp.",
+ "Multiple directories contain version ~tp.",
[Name,BadVsn])
end,
FirstInfo = hd(AllInfo),
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index b3b7afd1a9..347e80ed7c 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -1205,9 +1205,14 @@ create_slim(Config) ->
RootDir = code:root_dir(),
Erl = filename:join([RootDir, "bin", "erl"]),
+ EscapedQuote =
+ case os:type() of
+ {win32,_} -> "\\\"";
+ _ -> "\""
+ end,
Args = ["-boot_var", "RELTOOL_EXT_LIB", TargetLibDir,
"-boot", filename:join(TargetRelVsnDir,RelName),
- "-sasl", "releases_dir", "\""++TargetRelDir++"\""],
+ "-sasl", "releases_dir", EscapedQuote++TargetRelDir++EscapedQuote],
{ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl, Args)),
?msym(RootDir, rpc:call(Node, code, root_dir, [])),
wait_for_app(Node,sasl,50),
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 163b77dfa0..4fc1534250 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.6.5
+RELTOOL_VSN = 0.6.6
diff --git a/lib/sasl/doc/src/alarm_handler.xml b/lib/sasl/doc/src/alarm_handler.xml
index ab3041137e..e4def7c7f5 100644
--- a/lib/sasl/doc/src/alarm_handler.xml
+++ b/lib/sasl/doc/src/alarm_handler.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1996</year>
- <year>2013</year>
+ <year>2014</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -87,7 +87,9 @@
<v>AlarmId = term()</v>
</type>
<desc>
- <p>Clears all alarms with id <c>AlarmId</c>.
+ <p>Sends the <c>clear_alarm</c> event to all event handlers.</p>
+ <p>When receiving this event, the default simple handler
+ clears the latest received alarm with id <c>AlarmId</c>.
</p>
</desc>
</func>
@@ -109,8 +111,10 @@
<v>AlarmDescription = term()</v>
</type>
<desc>
- <p>Sets an alarm with id <c>AlarmId</c>. This id is used at a
- later stage when the alarm is cleared.
+ <p>Sends the <c>set_alarm</c> event to all event handlers.</p>
+ <p>When receiving this event, the default simple handler
+ stores the alarm. The <c>AlarmId</c> identifies the alarm
+ and is used when the alarm is cleared.
</p>
</desc>
</func>
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 06674095f2..15efd47a1c 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,7 +33,29 @@
</header>
- <section><title>SNMP 4.25.1</title>
+ <section><title>SNMP 5.0</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ SNMP has been improved to handle IPv6. The agent can
+ handle dual stack IPv4 + IPv6, but not yet the manager.
+ The documentation also still lags behind... If you do
+ such advanced stuff like writing a custom net_if module,
+ the interface for it has changed, but other than that
+ SNMP is backwards compatible.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12020 Aux Id: OTP-11518 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 4.25.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index 7bdd500727..4546c343b7 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -31,6 +31,7 @@
-include("snmpa_internal.hrl").
-include("SNMP-COMMUNITY-MIB.hrl").
-include("SNMP-TARGET-MIB.hrl").
+-include("SNMPv2-TM.hrl").
-include("SNMPv2-TC.hrl").
-include("snmp_types.hrl").
@@ -129,10 +130,11 @@ read_community_config_files(Dir) ->
[FileName, D, Reason]),
ok
end,
- Filter = fun(Comms) -> Comms end,
- Check = fun(Entry) -> check_community(Entry) end,
+ Order = fun snmp_conf:no_order/2,
+ Filter = fun snmp_conf:no_filter/1,
+ Check = fun(Entry, State) -> {check_community(Entry), State} end,
[Comms] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, "community.conf"}]),
+ snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]),
Comms.
check_community({Index, CommunityName, SecName, CtxName, TransportTag}) ->
@@ -192,7 +194,7 @@ add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) ->
do_add_community(Community).
do_add_community(Community) ->
- case (catch check_community(Community)) of
+ try check_community(Community) of
{ok, Row} ->
Key = element(1, Row),
case table_cre_row(snmpCommunityTable, Key, Row) of
@@ -201,11 +203,12 @@ do_add_community(Community) ->
{ok, Key};
false ->
{error, create_failed}
- end;
+ end
+ catch
{error, Reason} ->
{error, Reason};
- Error ->
- {error, Error}
+ Class:Reason ->
+ {error, {Class, Reason, erlang:get_stacktrace()}}
end.
%% FIXME: does not work with mnesia
@@ -243,6 +246,10 @@ gc_tabs() ->
%%-----------------------------------------------------------------
community2vacm(Community, Addr) ->
Idxs = ets:lookup(snmp_community_cache, Community),
+ ?vtrace("community2vacm ->~n"
+ " Community: ~p~n"
+ " Addr: ~p~n"
+ " Idxs: ~p", [Community, Addr, Idxs]),
loop_c2v_rows(lists:keysort(2, Idxs), Addr).
loop_c2v_rows([{_, CommunityIndex} | T], Addr) ->
@@ -250,6 +257,9 @@ loop_c2v_rows([{_, CommunityIndex} | T], Addr) ->
"~n CommunityIndex: ~p", [CommunityIndex]),
case get_row(CommunityIndex) of
{_Community, VacmParams, Tag} ->
+ ?vtrace("loop_c2v_rows ->~n"
+ " VacmParams: ~p~n"
+ " Tag: ~p", [VacmParams, Tag]),
{TDomain, TAddr} = Addr,
case snmp_target_mib:is_valid_tag(Tag, TDomain, TAddr) of
true ->
@@ -506,7 +516,12 @@ snmpTargetAddrExtTable(get_next, RowIndex, Cols) ->
NCols = conv1(Cols),
conv2(next(snmpTargetAddrExtTable, RowIndex, NCols));
snmpTargetAddrExtTable(set, RowIndex, Cols0) ->
- case (catch verify_snmpTargetAddrExtTable_cols(Cols0, [])) of
+ case
+ (catch verify_snmpTargetAddrExtTable_cols(
+ Cols0,
+ get_snmpTargetAddrTDomain(RowIndex, Cols0),
+ []))
+ of
{ok, Cols} ->
NCols = conv3(Cols),
snmp_generic:table_func(set, RowIndex, NCols,
@@ -515,7 +530,11 @@ snmpTargetAddrExtTable(set, RowIndex, Cols0) ->
Error
end;
snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) ->
- case (catch verify_snmpTargetAddrExtTable_cols(Cols0, [])) of
+ case (catch verify_snmpTargetAddrExtTable_cols(
+ Cols0,
+ get_snmpTargetAddrTDomain(RowIndex, Cols0),
+ []))
+ of
{ok, Cols} ->
NCols = conv3(Cols),
snmp_generic:table_func(is_set_ok, RowIndex, NCols,
@@ -525,29 +544,49 @@ snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) ->
end.
-verify_snmpTargetAddrExtTable_cols([], Cols) ->
+
+get_snmpTargetAddrTDomain(RowIndex, Col) ->
+ case
+ get(
+ snmpTargetAddrTable, RowIndex,
+ [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain])
+ of
+ [{value,?snmpTargetAddrRowStatus_active},ValueTDomain] ->
+ case ValueTDomain of
+ {value,TDomain} ->
+ TDomain;
+ _ ->
+ ?snmpUDPDomain
+ end;
+ _ ->
+ wrongValue(Col)
+ end.
+
+
+
+verify_snmpTargetAddrExtTable_cols([], _TDomain, Cols) ->
{ok, lists:reverse(Cols)};
-verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], Acc) ->
- Val = verify_snmpTargetAddrExtTable_col(Col, Val0),
- verify_snmpTargetAddrExtTable_cols(Cols, [{Col, Val}|Acc]).
+verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], TDomain, Acc) ->
+ Val = verify_snmpTargetAddrExtTable_col(Col, TDomain, Val0),
+ verify_snmpTargetAddrExtTable_cols(Cols, TDomain, [{Col, Val}|Acc]).
-verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, []) ->
+verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, _TDomain, []) ->
[];
-verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, TMask) ->
- case (catch snmp_conf:check_taddress(TMask)) of
+verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, TDomain, TMask) ->
+ case (catch snmp_conf:check_taddress(TDomain, TMask)) of
ok ->
TMask;
_ ->
wrongValue(?snmpTargetAddrTMask)
end;
-verify_snmpTargetAddrExtTable_col(?snmpTargetAddrMMS, MMS) ->
+verify_snmpTargetAddrExtTable_col(?snmpTargetAddrMMS, _TDomain, MMS) ->
case (catch snmp_conf:check_packet_size(MMS)) of
ok ->
MMS;
_ ->
wrongValue(?snmpTargetAddrMMS)
end;
-verify_snmpTargetAddrExtTable_col(_, Val) ->
+verify_snmpTargetAddrExtTable_col(_, _TDomain, Val) ->
Val.
db(snmpTargetAddrExtTable) -> db(snmpTargetAddrTable);
@@ -583,6 +622,7 @@ conv3([{Idx, Val}|T]) -> [{Idx+10, Val} | conv3(T)];
conv3([]) -> [].
+
get(Name, RowIndex, Cols) ->
snmp_generic:handle_table_get(db(Name), RowIndex, Cols, foi(Name)).
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index cc191bd956..9d3f7ef5e7 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-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -41,6 +41,7 @@
-compile({no_auto_import,[error/1]}).
-export([init/0, configure/1]).
-export([intContextTable/1, intContextTable/3,
+ intAgentTransportDomain/1, intAgentTransports/1,
intAgentUDPPort/1, intAgentIpAddress/1,
snmpEngineID/1,
snmpEngineBoots/1,
@@ -51,7 +52,7 @@
set_engine_boots/1, set_engine_time/1,
table_next/2, check_status/3]).
-export([add_context/1, delete_context/1]).
--export([check_agent/1, check_context/1]).
+-export([check_agent/2, check_context/1, order_agent/2]).
%%-----------------------------------------------------------------
@@ -115,54 +116,46 @@ do_configure(Dir) ->
read_internal_config_files(Dir) ->
?vdebug("read context config file",[]),
- Gen = fun(D, Reason) ->
- convert_context(D, Reason)
- end,
- Filter = fun(Contexts) -> Contexts end,
- Check = fun(Entry) -> check_context(Entry) end,
- [Ctxs] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "context.conf"}]),
+ Gen = fun gen_context/2,
+ Order = fun snmp_conf:no_order/2,
+ Filter = fun snmp_conf:no_filter/1,
+ Check = fun(Entry, State) -> {check_context(Entry), State} end,
+ [Ctxs] =
+ snmp_conf:read_files
+ (Dir, [{"context.conf", Gen, Order, Check, Filter}]),
Ctxs.
-
read_agent(Dir) ->
?vdebug("read agent config file", []),
- FileName = "agent.conf",
- Check = fun(Entry) -> check_agent(Entry) end,
+ FileName = "agent.conf",
File = filename:join(Dir, FileName),
- Agent =
+ Conf0 =
try
- snmp_conf:read(File, Check)
+ snmp_conf:read(File, fun order_agent/2, fun check_agent/2)
catch
throw:{error, Reason} ->
error({failed_reading_config_file, Dir, FileName, Reason})
end,
- sort_agent(Agent).
-
-
-%%-----------------------------------------------------------------
-%% Make sure that each mandatory agent attribute is present, and
-%% provide default values for the other non-present attributes.
-%%-----------------------------------------------------------------
-sort_agent(L) ->
- Mand = [{intAgentIpAddress, mandatory},
- {intAgentUDPPort, mandatory},
- {snmpEngineMaxMessageSize, mandatory},
- {snmpEngineID, mandatory}],
- {ok, L2} = snmp_conf:check_mandatory(L, Mand),
- lists:keysort(1, L2).
+ Mand =
+ [{intAgentTransports, mandatory},
+ {snmpEngineMaxMessageSize, mandatory},
+ {snmpEngineID, mandatory}],
+ {ok, Conf} = snmp_conf:check_mandatory(Conf0, Mand),
+ Conf.
%%-----------------------------------------------------------------
%% Generate a context.conf file.
%%-----------------------------------------------------------------
-convert_context(Dir, _Reason) ->
+gen_context(Dir, _Reason) ->
config_err("missing context.conf file => generating a default file", []),
File = filename:join(Dir, "context.conf"),
case file:open(File, [write]) of
{ok, Fid} ->
ok = io:format(Fid, "~s\n", [context_header()]),
ok = io:format(Fid, "%% The default context\n\"\".\n", []),
- file:close(Fid);
+ file:close(Fid),
+ [];
{error, Reason} ->
file:delete(File),
error({failed_creating_file, File, Reason})
@@ -196,10 +189,44 @@ check_context(Context) ->
%% Agent
%% {Name, Value}.
%%-----------------------------------------------------------------
-check_agent({intAgentIpAddress, Value}) ->
- snmp_conf:check_ip(Value);
-check_agent({intAgentUDPPort, Value}) ->
- snmp_conf:check_integer(Value);
+check_agent(Entry, undefined) ->
+ check_agent(Entry, {snmp_target_mib:default_domain(), undefined});
+check_agent({intAgentTransportDomain, Domain}, {_, Port}) ->
+ {snmp_conf:check_domain(Domain), {Domain, Port}};
+check_agent({intAgentUDPPort, Port}, {Domain, _}) ->
+ ok = snmp_conf:check_port(Port),
+ {ok, {Domain, Port}};
+check_agent({intAgentIpAddress, _}, {_, undefined}) ->
+ error({missing_mandatory, intAgentUDPPort});
+check_agent({intAgentIpAddress = Tag, Ip} = Entry, {Domain, Port} = State) ->
+ {case snmp_conf:check_ip(Domain, Ip) of
+ ok ->
+ [Entry,
+ {intAgentTransports, [{Domain, {Ip, Port}}]}];
+ {ok, FixedIp} ->
+ [{Tag, FixedIp},
+ {intAgentTransports, [{Domain, {FixedIp, Port}}]}]
+ end, State};
+check_agent({intAgentTransports = Tag, Transports}, {_, Port} = State) ->
+ CheckedTransports =
+ [case
+ case Port of
+ undefined ->
+ snmp_conf:check_address(Domain, Address);
+ _ ->
+ snmp_conf:check_address(Domain, Address, Port)
+ end
+ of
+ ok ->
+ Transport;
+ {ok, FixedAddress} ->
+ {Domain, FixedAddress}
+ end
+ || {Domain, Address} = Transport <- Transports],
+ {{ok, {Tag, CheckedTransports}}, State};
+check_agent(Entry, State) ->
+ {check_agent(Entry), State}.
+
%% This one is kept for backwards compatibility
check_agent({intAgentMaxPacketSize, Value}) ->
snmp_conf:check_packet_size(Value);
@@ -210,6 +237,14 @@ check_agent({snmpEngineID, Value}) ->
check_agent(X) ->
error({invalid_agent_attribute, X}).
+%% Ordering function to sort intAgentTransportDomain first
+%% hence before intAgentIpAddress. Sort other entries on the key.
+order_agent(EntryA, EntryB) ->
+ snmp_conf:keyorder(
+ 1, EntryA, EntryB,
+ [intAgentTransportDomain, intAgentUDPPort | sort]).
+
+
maybe_create_table(Name) ->
case snmpa_local_db:table_exists(db(Name)) of
@@ -382,6 +417,14 @@ intAgentUDPPort(Op) ->
intAgentIpAddress(Op) ->
snmp_generic:variable_func(Op, db(intAgentIpAddress)).
+intAgentTransportDomain(Op) ->
+ snmp_generic:variable_func(Op, db(intAgentTransportDomain)).
+
+intAgentTransports(Op) ->
+ snmp_generic:variable_func(Op, db(intAgentTransports)).
+
+
+
snmpEngineID(print) ->
VarAndValue = [{snmpEngineID, snmpEngineID(get)}],
snmpa_mib_lib:print_variables(VarAndValue);
diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl
index 06afa68d96..3195ca2500 100644
--- a/lib/snmp/src/agent/snmp_generic.erl
+++ b/lib/snmp/src/agent/snmp_generic.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -414,7 +414,12 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndGo', RowIndex, Cols) ->
% side effect free and we only use the result temporary.
case catch snmpa_local_db:table_construct_row(
NameDb, RowIndex, ?'RowStatus_createAndGo', Cols) of
- {'EXIT', _} ->
+ {'EXIT', _Reason} ->
+ ?vtrace(
+ "failed construct row (createAndGo): "
+ " n Reason: ~p"
+ " n Stack: ~p",
+ [_Reason, erlang:get_stacktrace()]),
{noCreation, Col}; % Bad RowIndex
Row ->
case lists:member(noinit, tuple_to_list(Row)) of
@@ -431,7 +436,12 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndWait', RowIndex, Cols) ->
false ->
case catch snmpa_local_db:table_construct_row(
NameDb, RowIndex, ?'RowStatus_createAndGo', Cols) of
- {'EXIT', _} ->
+ {'EXIT', _Reason} ->
+ ?vtrace(
+ "failed construct row (createAndWait): "
+ " n Reason: ~p"
+ " n Stack: ~p",
+ [_Reason, erlang:get_stacktrace()]),
{noCreation, Col}; % Bad RowIndex
_Row ->
{noError, 0}
@@ -711,7 +721,19 @@ find_col(Col, [_H | T]) -> find_col(Col, T).
try_apply(nofunc, _) -> {noError, 0};
-try_apply(F, Args) -> apply(F, Args).
+try_apply(F, Args) -> maybe_verbose_apply(F, Args).
+
+maybe_verbose_apply(M, Args) ->
+ case get(verbosity) of
+ false ->
+ apply(M, Args);
+ _ ->
+ ?vlog("~n apply: ~w,~p~n", [M,Args]),
+ Res = apply(M,Args),
+ ?vlog("~n returned: ~p", [Res]),
+ Res
+ end.
+
table_info({Name, _Db}) ->
case snmpa_symbolic_store:table_info(Name) of
diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl
index 37e09f5d3e..31c7735226 100644
--- a/lib/snmp/src/agent/snmp_notification_mib.erl
+++ b/lib/snmp/src/agent/snmp_notification_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -106,17 +106,19 @@ do_reconfigure(Dir) ->
read_notify_config_files(Dir) ->
?vdebug("read notify config file",[]),
FileName = "notify.conf",
- Gen = fun(D, Reason) ->
- info_msg("failed reading config file ~s"
- "~n Config Dir: ~s"
- "~n Reason: ~p",
- [FileName, D, Reason]),
- ok
- end,
- Filter = fun(Notifs) -> Notifs end,
- Check = fun(Entry) -> check_notify(Entry) end,
+ Gen =
+ fun (D, Reason) ->
+ info_msg("failed reading config file ~s"
+ "~n Config Dir: ~s"
+ "~n Reason: ~p",
+ [FileName, D, Reason]),
+ ok
+ end,
+ Order = fun snmp_conf:no_order/2,
+ Filter = fun snmp_conf:no_filter/1,
+ Check = fun (Entry, State) -> {check_notify(Entry), State} end,
[Notifs] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, "notify.conf"}]),
+ snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]),
Notifs.
check_notify({Name, Tag, Type}) ->
diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl
index 766b75022b..aace3fd413 100644
--- a/lib/snmp/src/agent/snmp_standard_mib.erl
+++ b/lib/snmp/src/agent/snmp_standard_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -152,16 +152,19 @@ do_reconfigure(Dir) ->
%%-----------------------------------------------------------------
read_standard(Dir) ->
?vdebug("check standard config file",[]),
- FileName = "standard.conf",
- Gen = fun(D, Reason) ->
- throw({error, {failed_reading_config_file,
- D, FileName,
- list_dir(Dir), Reason}})
- end,
- Filter = fun(Standard) -> sort_standard(Standard) end,
- Check = fun(Entry) -> check_standard(Entry) end,
+ FileName = "standard.conf",
+ Gen =
+ fun (D, Reason) ->
+ throw(
+ {error,
+ {failed_reading_config_file,
+ D, FileName, list_dir(Dir), Reason}})
+ end,
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (Entry, State) -> {check_standard(Entry), State} end,
+ Filter = fun sort_standard/1,
[Standard] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, FileName}]),
+ snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]),
Standard.
list_dir(Dir) ->
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index b01d536caa..e916f17d6a 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -133,18 +133,22 @@ do_reconfigure(Dir) ->
read_target_config_files(Dir) ->
?vdebug("check target address and parameter config file(s)",[]),
- TAGen = fun(_D, _Reason) -> ok end,
- TAFilter = fun(Addr) -> Addr end,
- TACheck = fun(Entry) -> check_target_addr(Entry) end,
- TPGen = fun(_D, _Reason) -> ok end,
- TPFilter = fun(Params) -> Params end,
- TPCheck = fun(Entry) -> check_target_params(Entry) end,
+ TAName = "target_addr.conf",
+ TACheck = fun (Entry, State) -> {check_target_addr(Entry), State} end,
+
+ TPName = "target_params.conf",
+ TPCheck = fun (Entry, State) -> {check_target_params(Entry), State} end,
+
+ NoGen = fun snmp_conf:no_gen/2,
+ NoOrder = fun snmp_conf:no_order/2,
+ NoFilter = fun snmp_conf:no_filter/1,
[Addrs, Params] =
- snmp_conf:read_files(Dir,
- [{TAGen, TAFilter, TACheck, "target_addr.conf"},
- {TPGen, TPFilter, TPCheck, "target_params.conf"}]),
+ snmp_conf:read_files(
+ Dir,
+ [{TAName, NoGen, NoOrder, TACheck, NoFilter},
+ {TPName, NoGen, NoOrder, TPCheck, NoFilter}]),
{Addrs, Params}.
@@ -154,79 +158,154 @@ read_target_config_files(Dir) ->
%% TMask, MMS}
%%-----------------------------------------------------------------
-check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS}) ->
+check_target_addr(
+ {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS}) -> % Arity 11
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS);
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS}) % Arity 10
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS})
+ when is_integer(Udp) -> % Arity 10
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS);
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId}) % Arity 8
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ EngineId}) % Arity 8
+ when is_integer(Udp) ->
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId);
+%% Use dummy engine id if the old style is found
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params}) % Arity 7
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) % Arity 7
+ when is_integer(Udp) ->
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params);
+%% Use dummy engine id if the old style is found
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ TMask, MMS}) % Arity 9
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ TMask, MMS}) % Arity 9
+ when is_integer(Udp) ->
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
+check_target_addr(X) ->
+ error({invalid_target_addr, X}).
+
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params) -> % Arity 7
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ "dummy").
+%%
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId) -> % Arity 8
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, [], 2048).
+%%
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ TMask, MMS) -> % Arity 9
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ "dummy", TMask, MMS).
+%%
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, Mask, MMS) -> % Arity 10
?vtrace("check target address with:"
"~n Name: ~s"
"~n Domain: ~p"
- "~n Ip: ~p"
- "~n Udp: ~p"
+ "~n Address: ~p"
"~n Timeout: ~p"
"~n RetryCount: ~p"
"~n TagList: ~p"
"~n Params: ~p"
"~n EngineId: ~p"
- "~n TMask: ~p"
+ "~n Mask: ~p"
"~n MMS: ~p",
- [Name,
- Domain, Ip, Udp,
+ [Name, Domain, Address,
Timeout, RetryCount,
- TagList, Params, EngineId, TMask, MMS]),
+ TagList, Params, EngineId, Mask, MMS]),
snmp_conf:check_string(Name,{gt,0}),
snmp_conf:check_domain(Domain),
- snmp_conf:check_ip(Domain, Ip),
- snmp_conf:check_integer(Udp, {gt, 0}),
+ NAddress = check_address(Domain, Address),
snmp_conf:check_integer(Timeout, {gte, 0}),
snmp_conf:check_integer(RetryCount, {gte,0}),
snmp_conf:check_string(TagList),
snmp_conf:check_string(Params),
check_engine_id(EngineId),
- TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp),
+ NMask = check_mask(Domain, Mask),
TDomain = snmp_conf:mk_tdomain(Domain),
- check_tmask(TDomain, TMask, TAddress),
+ TAddress = snmp_conf:mk_taddress(Domain, NAddress),
+ TMask = snmp_conf:mk_taddress(Domain, NMask),
snmp_conf:check_packet_size(MMS),
?vtrace("check target address done",[]),
Addr = {Name, TDomain, TAddress, Timeout,
RetryCount, TagList, Params,
?'StorageType_nonVolatile', ?'RowStatus_active', EngineId,
TMask, MMS}, % Values for Augmenting table in SNMP-COMMUNITY-MIB
- {ok, Addr};
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS}) ->
- Domain = default_domain(),
- check_target_addr({Name,
- Domain, Ip, Udp,
- Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS});
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
- EngineId}) ->
- check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, [], 2048});
-%% Use dummy engine id if the old style is found
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) ->
- check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, "dummy", [], 2048});
-%% Use dummy engine id if the old style is found
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
- TMask, MMS}) ->
- check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, "dummy", TMask, MMS});
-check_target_addr(X) ->
- error({invalid_target_addr, X}).
-
+ {ok, Addr}.
check_engine_id(discovery) ->
ok;
check_engine_id(EngineId) ->
snmp_conf:check_string(EngineId).
+check_address(Domain, Address) ->
+ case snmp_conf:check_address(Domain, Address) of
+ ok ->
+ Address;
+ {ok, NAddress} ->
+ NAddress
+ end.
-check_tmask(_TDomain, [], _TAddress) ->
- ok;
-check_tmask(TDomain, TMask, TAddress) when length(TMask) =:= length(TAddress) ->
- snmp_conf:check_taddress(TDomain, TMask);
-check_tmask(_TDomain, TMask, _TAddr) ->
- throw({error, {invalid_tmask, TMask}}).
+check_mask(_Domain, [] = Mask) ->
+ Mask;
+check_mask(Domain, Mask) ->
+ try check_address(Domain, Mask)
+ catch
+ {error, {bad_address, Info}} ->
+ error({bad_mask, Info})
+ end.
%%-----------------------------------------------------------------
@@ -604,6 +683,20 @@ snmpTargetAddrTable(print) ->
FOI = foi(Table),
PrintRow =
fun(Prefix, Row) ->
+ TDomain = element(?snmpTargetAddrTDomain, Row),
+ Domain =
+ try snmp_conf:tdomain_to_domain(TDomain)
+ catch
+ {error, {bad_tdomain, _}} ->
+ undefined
+ end,
+ TAddress = element(?snmpTargetAddrTAddress, Row),
+ AddrString =
+ try snmp_conf:mk_addr_string({Domain, TAddress})
+ catch
+ {error, {bad_address, _}} ->
+ "-"
+ end,
lists:flatten(
io_lib:format("~sName: ~p"
"~n~sTDomain: ~p (~w)"
@@ -618,21 +711,8 @@ snmpTargetAddrTable(print) ->
"~n~s[Ext] TMask: ~p"
"~n~s[Ext] MMS: ~p",
[Prefix, element(?snmpTargetAddrName, Row),
- Prefix, element(?snmpTargetAddrTDomain, Row),
- case element(?snmpTargetAddrTDomain, Row) of
- ?snmpUDPDomain -> snmpUDPDomain;
- ?transportDomainUdpIpv4 -> transportDomainUdpIpv4;
- ?transportDomainUdpIpv6 -> transportDomainUdpIpv6;
- _ -> undefined
- end,
- Prefix, element(?snmpTargetAddrTAddress, Row),
- case element(?snmpTargetAddrTAddress, Row) of
- [A,B,C,D,U1,U2] ->
- lists:flatten(
- io_lib:format("~w.~w.~w.~w:~w",
- [A, B, C, D, U1 bsl 8 + U2]));
- _ -> "-"
- end,
+ Prefix, TDomain, Domain,
+ Prefix, TAddress, AddrString,
Prefix, element(?snmpTargetAddrTimeout, Row),
Prefix, element(?snmpTargetAddrRetryCount, Row),
Prefix, element(?snmpTargetAddrTagList, Row),
diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
index 223d3f7218..69dce337ba 100644
--- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
+++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -137,18 +137,20 @@ do_reconfigure(Dir) ->
read_usm_config_files(Dir) ->
?vdebug("read usm config file",[]),
- Gen = fun(D, Reason) -> generate_usm(D, Reason) end,
- Filter = fun(Usms) -> Usms end,
- Check = fun(Entry) -> check_usm(Entry) end,
+ Gen = fun (D, Reason) -> generate_usm(D, Reason) end,
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (Entry, State) -> {check_usm(Entry), State} end,
+ Filter = fun snmp_conf:no_filter/1,
[Usms] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, "usm.conf"}]),
+ snmp_conf:read_files(Dir, [{"usm.conf", Gen, Order, Check, Filter}]),
Usms.
generate_usm(Dir, _Reason) ->
info_msg("Incomplete configuration. Generating empty usm.conf.", []),
USMFile = filename:join(Dir, "usm.conf"),
- ok = file:write_file(USMFile, list_to_binary([])).
+ ok = file:write_file(USMFile, list_to_binary([])),
+ [].
check_usm({EngineID, Name, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC,
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 c0177b1cea..722bd7ac5b 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -123,15 +123,18 @@ do_reconfigure(Dir) ->
read_vacm_config_files(Dir) ->
?vdebug("read vacm config file",[]),
- Gen = fun(_D, _Reason) -> ok end,
- Filter = fun(Vacms) ->
- Sec2Group = [X || {vacmSecurityToGroup, X} <- Vacms],
- Access = [X || {vacmAccess, X} <- Vacms],
- View = [X || {vacmViewTreeFamily, X} <- Vacms],
- {Sec2Group, Access, View}
- end,
- Check = fun(Entry) -> check_vacm(Entry) end,
- [Vacms] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "vacm.conf"}]),
+ Gen = fun snmp_conf:no_gen/2,
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (Entry, State) -> {check_vacm(Entry), State} end,
+ Filter =
+ fun (Vacms) ->
+ Sec2Group = [X || {vacmSecurityToGroup, X} <- Vacms],
+ Access = [X || {vacmAccess, X} <- Vacms],
+ View = [X || {vacmViewTreeFamily, X} <- Vacms],
+ {Sec2Group, Access, View}
+ end,
+ [Vacms] =
+ snmp_conf:read_files(Dir, [{"vacm.conf", Gen, Order, Check, Filter}]),
Vacms.
%%-----------------------------------------------------------------
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index 9bed6e554e..6d3f1cca4a 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -2512,10 +2512,19 @@ handle_mib_of(MibServer, Oid) ->
%% Func: process_msg/7
%% Returns: RePdu
%%-----------------------------------------------------------------
-process_msg(MibView, Vsn, Pdu, PduMS, Community, {Ip, Udp}, ContextName,
- GbMaxVBs) ->
+process_msg(
+ MibView, Vsn, Pdu, PduMS, Community,
+ SourceAddress, ContextName, GbMaxVBs) ->
#pdu{request_id = ReqId} = Pdu,
- put(snmp_address, {tuple_to_list(Ip), Udp}),
+ put(
+ snmp_address,
+ case SourceAddress of
+ {Domain, _} when is_atom(Domain) ->
+ SourceAddress;
+ {Ip, Port} when is_integer(Port) ->
+ %% Legacy transport domain
+ {tuple_to_list(Ip), Port}
+ end),
put(snmp_request_id, ReqId),
put(snmp_community, Community),
put(snmp_context, ContextName),
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index c17a6abbd7..b4d32dc928 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-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -108,36 +108,25 @@ write_agent_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_agent_config(Dir, Hdr, Conf).
-write_agent_config(Dir, Hdr, Conf)
+write_agent_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_agent_conf(Conf) end,
- Write = fun(Fd) -> write_agent_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "agent.conf", Verify, Write).
-
+ Order = fun snmp_framework_mib:order_agent/2,
+ Check = fun snmp_framework_mib:check_agent/2,
+ Write = fun (Fd, Entries) -> write_agent_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "agent.conf", Order, Check, Write, Conf).
-append_agent_config(Dir, Conf)
+append_agent_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_agent_conf(Conf) end,
- Write = fun(Fd) -> write_agent_conf(Fd, Conf) end,
- append_config_file(Dir, "agent.conf", Verify, Write).
-
+ Order = fun snmp_framework_mib:order_agent/2,
+ Check = fun snmp_framework_mib:check_agent/2,
+ Write = fun write_agent_conf/2,
+ append_config_file(Dir, "agent.conf", Order, Check, Write, Conf).
read_agent_config(Dir) ->
- Verify = fun(Entry) -> verify_agent_conf_entry(Entry) end,
- read_config_file(Dir, "agent.conf", Verify).
+ Order = fun snmp_framework_mib:order_agent/2,
+ Check = fun snmp_framework_mib:check_agent/2,
+ read_config_file(Dir, "agent.conf", Order, Check).
-
-verify_agent_conf([]) ->
- ok;
-verify_agent_conf([H|T]) ->
- verify_agent_conf_entry(H),
- verify_agent_conf(T);
-verify_agent_conf(X) ->
- error({bad_agent_config, X}).
-
-verify_agent_conf_entry(Entry) ->
- ok = snmp_framework_mib:check_agent(Entry),
- ok.
write_agent_conf(Fd, "", Conf) ->
write_agent_conf(Fd, Conf);
@@ -151,6 +140,10 @@ write_agent_conf(Fd, [H|T]) ->
do_write_agent_conf(Fd, H),
write_agent_conf(Fd, T).
+do_write_agent_conf(Fd, {intAgentTransports = Tag, Val}) ->
+ io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
+do_write_agent_conf(Fd, {intAgentTransportDomain = Tag, Val}) ->
+ io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
do_write_agent_conf(Fd, {intAgentIpAddress = Tag, Val}) ->
io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
do_write_agent_conf(Fd, {intAgentUDPPort = Tag, Val} ) ->
@@ -191,34 +184,27 @@ write_context_config(Dir, Conf) ->
write_context_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_context_conf(Conf) end,
- Write = fun(Fd) -> write_context_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "context.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_context/2,
+ Write = fun (Fd, Entries) -> write_context_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "context.conf", Order, Check, Write, Conf).
-append_context_config(Dir, Conf)
+append_context_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_context_conf(Conf) end,
- Write = fun(Fd) -> write_context_conf(Fd, Conf) end,
- append_config_file(Dir, "context.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_context/2,
+ Write = fun write_context_conf/2,
+ append_config_file(Dir, "context.conf", Order, Check, Write, Conf).
read_context_config(Dir) ->
- Verify = fun(Entry) -> verify_context_conf_entry(Entry) end,
- read_config_file(Dir, "context.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_context/2,
+ read_config_file(Dir, "context.conf", Order, Check).
-
-verify_context_conf([]) ->
- ok;
-verify_context_conf([H|T]) ->
- verify_context_conf_entry(H),
- verify_context_conf(T);
-verify_context_conf(X) ->
- error({error_context_config, X}).
-
-verify_context_conf_entry(Context) ->
- {ok, _} = snmp_framework_mib:check_context(Context),
- ok.
+
+check_context(Entry, State) ->
+ {check_ok(snmp_framework_mib:check_context(Entry)),
+ State}.
write_context_conf(Fd, "", Conf) ->
write_context_conf(Fd, Conf);
@@ -271,36 +257,29 @@ write_community_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_community_config(Dir, Hdr, Conf).
-write_community_config(Dir, Hdr, Conf)
+write_community_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_community_conf(Conf) end,
- Write = fun(Fd) -> write_community_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "community.conf", Verify, Write).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_community/2,
+ Write = fun (Fd, Entries) -> write_community_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "community.conf", Order, Check, Write, Conf).
-
-append_community_config(Dir, Conf)
+append_community_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_community_conf(Conf) end,
- Write = fun(Fd) -> write_community_conf(Fd, Conf) end,
- append_config_file(Dir, "community.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_community/2,
+ Write = fun write_community_conf/2,
+ append_config_file(Dir, "community.conf", Order, Check, Write, Conf).
read_community_config(Dir) ->
- Verify = fun(Entry) -> verify_community_conf_entry(Entry) end,
- read_config_file(Dir, "community.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_community/2,
+ read_config_file(Dir, "community.conf", Order, Check).
-
-verify_community_conf([]) ->
- ok;
-verify_community_conf([H|T]) ->
- verify_community_conf_entry(H),
- verify_community_conf(T);
-verify_community_conf(X) ->
- error({invalid_community_config, X}).
-
-verify_community_conf_entry(Context) ->
- {ok, _} = snmp_community_mib:check_community(Context),
- ok.
+
+check_community(Entry, State) ->
+ {check_ok(snmp_community_mib:check_community(Entry)),
+ State}.
write_community_conf(Fd, "", Conf) ->
write_community_conf(Fd, Conf);
@@ -309,14 +288,17 @@ write_community_conf(Fd, Hdr, Conf) ->
write_community_conf(Fd, Conf).
write_community_conf(Fd, Conf) ->
- Fun = fun({Idx, Name, SecName, CtxName, TranspTag}) ->
- io:format(Fd, "{\"~s\", \"~s\", \"~s\", \"~s\", \"~s\"}.~n",
- [Idx, Name, SecName, CtxName, TranspTag]);
+ Fun =
+ fun({Idx, Name, SecName, CtxName, TranspTag}) ->
+ io:format(
+ Fd,
+ "{\"~s\", \"~s\", \"~s\", \"~s\", \"~s\"}.~n",
+ [Idx, Name, SecName, CtxName, TranspTag]);
(Crap) ->
- error({bad_community_config, Crap})
+ error({bad_community_config, Crap})
end,
lists:foreach(Fun, Conf).
-
+
%%
%% ------ standard.conf ------
@@ -343,40 +325,29 @@ write_standard_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_standard_config(Dir, Hdr, Conf).
-write_standard_config(Dir, Hdr, Conf)
+write_standard_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_standard_conf(Conf) end,
- Write = fun(Fd) -> write_standard_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "standard.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_standard/2,
+ Write = fun (Fd, Entries) -> write_standard_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "standard.conf", Order, Check, Write, Conf).
-append_standard_config(Dir, Conf)
+append_standard_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_standard_conf(Conf) end,
- Write = fun(Fd) -> write_standard_conf(Fd, Conf) end,
- append_config_file(Dir, "standard.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_standard/2,
+ Write = fun write_standard_conf/2,
+ append_config_file(Dir, "standard.conf", Order, Check, Write, Conf).
read_standard_config(Dir) ->
- Verify = fun(Entry) -> verify_standard_conf_entry(Entry) end,
- read_config_file(Dir, "standard.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_standard/2,
+ read_config_file(Dir, "standard.conf", Order, Check).
-
-verify_standard_conf([]) ->
- ok;
-verify_standard_conf([H|T]) ->
- verify_standard_conf_entry(H),
- verify_standard_conf(T);
-verify_standard_conf(X) ->
- error({bad_standard_config, X}).
-
-verify_standard_conf_entry(Std) ->
- case snmp_standard_mib:check_standard(Std) of
- ok ->
- ok;
- {ok, _} ->
- ok
- end.
+
+check_standard(Entry, State) ->
+ {check_ok(snmp_standard_mib:check_standard(Entry)),
+ State}.
write_standard_conf(Fd, "", Conf) ->
write_standard_conf(Fd, Conf);
@@ -410,72 +381,35 @@ do_write_standard_conf(_Fd, Tag, Val) ->
%% ------ target_addr.conf ------
%%
-target_addr_entry(Name,
- Ip,
- TagList,
- ParamsName,
- EngineId) ->
+target_addr_entry(
+ Name, Ip, TagList, ParamsName, EngineId) ->
target_addr_entry(Name, Ip, TagList, ParamsName, EngineId, []).
-target_addr_entry(Name,
- Ip,
- TagList,
- ParamsName,
- EngineId,
- TMask) ->
- target_addr_entry(Name, Ip, 162, TagList,
- ParamsName, EngineId,
- TMask, 2048).
-
-target_addr_entry(Name,
- Ip,
- Udp,
- TagList,
- ParamsName,
- EngineId,
- TMask,
- MaxMessageSize) ->
- target_addr_entry(Name, Ip, Udp, 1500, 3, TagList,
- ParamsName, EngineId,
- TMask, MaxMessageSize).
-
-target_addr_entry(Name,
- Ip,
- Udp,
- Timeout,
- RetryCount,
- TagList,
- ParamsName,
- EngineId,
- TMask,
- MaxMessageSize) ->
- target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp,
- Timeout, RetryCount, TagList,
- ParamsName, EngineId,
- TMask, MaxMessageSize).
-
-target_addr_entry(Name,
- Domain,
- Ip,
- Udp,
- Timeout,
- RetryCount,
- TagList,
- ParamsName,
- EngineId,
- TMask,
- MaxMessageSize) ->
- {Name,
- Domain,
- Ip,
- Udp,
- Timeout,
- RetryCount,
- TagList,
- ParamsName,
- EngineId,
- TMask,
- MaxMessageSize}.
+target_addr_entry(
+ Name, Ip, TagList, ParamsName,
+ EngineId, TMask) ->
+ target_addr_entry(
+ Name, Ip, 162, TagList, ParamsName,
+ EngineId, TMask, 2048).
+
+target_addr_entry(
+ Name, Domain_or_Ip, Addr_or_Port, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize) ->
+ target_addr_entry(
+ Name, Domain_or_Ip, Addr_or_Port, 1500, 3, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize).
+
+target_addr_entry(
+ Name, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize) ->
+ {Name, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize}.
+
+target_addr_entry(
+ Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
+ ParamsName, EngineId,TMask, MaxMessageSize) ->
+ {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize}.
write_target_addr_config(Dir, Conf) ->
@@ -504,37 +438,29 @@ write_target_addr_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_target_addr_config(Dir, Hdr, Conf).
-write_target_addr_config(Dir, Hdr, Conf)
+write_target_addr_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_target_addr_conf(Conf) end,
- Write = fun(Fd) -> write_target_addr_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "target_addr.conf", Verify, Write).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_target_addr/2,
+ Write = fun (Fd, Entries) -> write_target_addr_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "target_addr.conf", Order, Check, Write, Conf).
-
-
-append_target_addr_config(Dir, Conf)
+append_target_addr_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_target_addr_conf(Conf) end,
- Write = fun(Fd) -> write_target_addr_conf(Fd, Conf) end,
- append_config_file(Dir, "target_addr.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_target_addr/2,
+ Write = fun write_target_addr_conf/2,
+ append_config_file(Dir, "target_addr.conf", Order, Check, Write, Conf).
read_target_addr_config(Dir) ->
- Verify = fun(Entry) -> verify_target_addr_conf_entry(Entry) end,
- read_config_file(Dir, "target_addr.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_target_addr/2,
+ read_config_file(Dir, "target_addr.conf", Order, Check).
-
-verify_target_addr_conf([]) ->
- ok;
-verify_target_addr_conf([H|T]) ->
- verify_target_addr_conf_entry(H),
- verify_target_addr_conf(T);
-verify_target_addr_conf(X) ->
- error({bad_target_addr_config, X}).
-
-verify_target_addr_conf_entry(Entry) ->
- {ok, _} = snmp_target_mib:check_target_addr(Entry),
- ok.
+
+check_target_addr(Entry, State) ->
+ {check_ok(snmp_target_mib:check_target_addr(Entry)),
+ State}.
write_target_addr_conf(Fd, "", Conf) ->
write_target_addr_conf(Fd, Conf);
@@ -547,29 +473,36 @@ write_target_addr_conf(Fd, Conf) ->
lists:foreach(Fun, Conf),
ok.
-do_write_target_addr_conf(Fd,
- {Name,
- Ip, Udp,
- Timeout, RetryCount, TagList,
- ParamsName, EngineId,
- TMask, MaxMessageSize}) ->
- Domain = snmp_target_mib:default_domain(),
- do_write_target_addr_conf(Fd,
- {Name,
- Domain, Ip, Udp,
- Timeout, RetryCount, TagList,
- ParamsName, EngineId,
- TMask, MaxMessageSize});
-do_write_target_addr_conf(Fd,
- {Name,
- Domain, Ip, Udp,
- Timeout, RetryCount, TagList,
- ParamsName, EngineId,
- TMask, MaxMessageSize}) ->
- io:format(Fd,
- "{\"~s\", ~w, ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
- [Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
- ParamsName, EngineId, TMask, MaxMessageSize]);
+do_write_target_addr_conf(
+ Fd,
+ {Name, Ip, Udp, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize})
+ when is_integer(Udp) ->
+ Domain = snmp_target_mib:default_domain(),
+ Address = {Ip, Udp},
+ do_write_target_addr_conf(
+ Fd,
+ {Name, Domain, Address, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize});
+do_write_target_addr_conf(
+ Fd,
+ {Name, Domain, Address, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize})
+ when is_atom(Domain) ->
+ io:format(
+ Fd,
+ "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
+ [Name, Domain, Address, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize]);
+do_write_target_addr_conf(
+ Fd,
+ {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize}) ->
+ Address = {Ip, Udp},
+ do_write_target_addr_conf(
+ Fd,
+ {Name, Domain, Address, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize});
do_write_target_addr_conf(_Fd, Crap) ->
error({bad_target_addr_config, Crap}).
@@ -613,34 +546,27 @@ write_target_params_config(Dir, Conf) ->
write_target_params_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_target_params_conf(Conf) end,
- Write = fun(Fd) -> write_target_params_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "target_params.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_target_params/2,
+ Write = fun (Fd, Entries) -> write_target_params_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "target_params.conf", Order, Check, Write, Conf).
append_target_params_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_target_params_conf(Conf) end,
- Write = fun(Fd) -> write_target_params_conf(Fd, Conf) end,
- append_config_file(Dir, "target_params.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_target_params/2,
+ Write = fun write_target_params_conf/2,
+ append_config_file(Dir, "target_params.conf", Order, Check, Write, Conf).
read_target_params_config(Dir) ->
- Verify = fun(Entry) -> verify_target_params_conf_entry(Entry) end,
- read_config_file(Dir, "target_params.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_target_params/2,
+ read_config_file(Dir, "target_params.conf", Order, Check).
-verify_target_params_conf([]) ->
- ok;
-verify_target_params_conf([H|T]) ->
- verify_target_params_conf_entry(H),
- verify_target_params_conf(T);
-verify_target_params_conf(X) ->
- error({bad_target_params_config, X}).
-
-verify_target_params_conf_entry(Entry) ->
- {ok, _} = snmp_target_mib:check_target_params(Entry),
- ok.
+check_target_params(Entry, State) ->
+ {check_ok(snmp_target_mib:check_target_params(Entry)),
+ State}.
write_target_params_conf(Fd, "", Conf) ->
write_target_params_conf(Fd, Conf);
@@ -685,34 +611,27 @@ write_notify_config(Dir, Conf) ->
write_notify_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_notify_conf(Conf) end,
- Write = fun(Fd) -> write_notify_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "notify.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_notify/2,
+ Write = fun (Fd, Entries) -> write_notify_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "notify.conf", Order, Check, Write, Conf).
append_notify_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_notify_conf(Conf) end,
- Write = fun(Fd) -> write_notify_conf(Fd, Conf) end,
- append_config_file(Dir, "notify.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_notify/2,
+ Write = fun write_notify_conf/2,
+ append_config_file(Dir, "notify.conf", Order, Check, Write, Conf).
read_notify_config(Dir) ->
- Verify = fun(Entry) -> verify_notify_conf_entry(Entry) end,
- read_config_file(Dir, "notify.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_notify/2,
+ read_config_file(Dir, "notify.conf", Order, Check).
-verify_notify_conf([]) ->
- ok;
-verify_notify_conf([H|T]) ->
- verify_notify_conf_entry(H),
- verify_notify_conf(T);
-verify_notify_conf(X) ->
- error({bad_notify_config, X}).
-
-verify_notify_conf_entry(Entry) ->
- {ok, _} = snmp_notification_mib:check_notify(Entry),
- ok.
+check_notify(Entry, State) ->
+ {check_ok(snmp_notification_mib:check_notify(Entry)),
+ State}.
write_notify_conf(Fd, "", Conf) ->
write_notify_conf(Fd, Conf);
@@ -781,34 +700,27 @@ write_usm_config(Dir, Conf) ->
write_usm_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_usm_conf(Conf) end,
- Write = fun(Fd) -> write_usm_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "usm.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_usm/2,
+ Write = fun (Fd, Entries) -> write_usm_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "usm.conf", Order, Check, Write, Conf).
append_usm_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_usm_conf(Conf) end,
- Write = fun(Fd) -> write_usm_conf(Fd, Conf) end,
- append_config_file(Dir, "usm.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_usm/2,
+ Write = fun write_usm_conf/2,
+ append_config_file(Dir, "usm.conf", Order, Check, Write, Conf).
read_usm_config(Dir) ->
- Verify = fun(Entry) -> verify_usm_conf_entry(Entry) end,
- read_config_file(Dir, "usm.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_usm/2,
+ read_config_file(Dir, "usm.conf", Order, Check).
-verify_usm_conf([]) ->
- ok;
-verify_usm_conf([H|T]) ->
- verify_usm_conf_entry(H),
- verify_usm_conf(T);
-verify_usm_conf(X) ->
- error({bad_usm_conf, X}).
-
-verify_usm_conf_entry(Entry) ->
- {ok, _} = snmp_user_based_sm_mib:check_usm(Entry),
- ok.
+check_usm(Entry, State) ->
+ {check_ok(snmp_user_based_sm_mib:check_usm(Entry)),
+ State}.
write_usm_conf(Fd, "", Conf) ->
write_usm_conf(Fd, Conf);
@@ -820,11 +732,12 @@ write_usm_conf(Fd, Conf) ->
Fun = fun(Entry) -> do_write_usm_conf(Fd, Entry) end,
lists:foreach(Fun, Conf).
-do_write_usm_conf(Fd,
- {EngineID, UserName, SecName, Clone,
- AuthP, AuthKeyC, OwnAuthKeyC,
- PrivP, PrivKeyC, OwnPrivKeyC,
- Public, AuthKey, PrivKey}) ->
+do_write_usm_conf(
+ Fd,
+ {EngineID, UserName, SecName, Clone,
+ AuthP, AuthKeyC, OwnAuthKeyC,
+ PrivP, PrivKeyC, OwnPrivKeyC,
+ Public, AuthKey, PrivKey}) ->
io:format(Fd, "{", []),
io:format(Fd, "\"~s\", ", [EngineID]),
io:format(Fd, "\"~s\", ", [UserName]),
@@ -890,34 +803,27 @@ write_vacm_config(Dir, Conf) ->
write_vacm_config(Dir, Hdr, Conf)
when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
- Verify = fun() -> verify_vacm_conf(Conf) end,
- Write = fun(Fd) -> write_vacm_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, "vacm.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_vacm/2,
+ Write = fun (Fd, Entries) -> write_vacm_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, "vacm.conf", Order, Check, Write, Conf).
append_vacm_config(Dir, Conf)
when is_list(Dir) and is_list(Conf) ->
- Verify = fun() -> verify_vacm_conf(Conf) end,
- Write = fun(Fd) -> write_vacm_conf(Fd, Conf) end,
- append_config_file(Dir, "vacm.conf", Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_vacm/2,
+ Write = fun write_vacm_conf/2,
+ append_config_file(Dir, "vacm.conf", Order, Check, Write, Conf).
read_vacm_config(Dir) ->
- Verify = fun(Entry) -> verify_vacm_conf_entry(Entry) end,
- read_config_file(Dir, "vacm.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_vacm/2,
+ read_config_file(Dir, "vacm.conf", Order, Check).
-verify_vacm_conf([]) ->
- ok;
-verify_vacm_conf([H|T]) ->
- verify_vacm_conf_entry(H),
- verify_vacm_conf(T);
-verify_vacm_conf(X) ->
- error({bad_vacm_conf, X}).
-
-verify_vacm_conf_entry(Entry) ->
- {ok, _} = snmp_view_based_acm_mib:check_vacm(Entry),
- ok.
+check_vacm(Entry, State) ->
+ {check_ok(snmp_view_based_acm_mib:check_vacm(Entry)),
+ State}.
write_vacm_conf(Fd, "", Conf) ->
write_vacm_conf(Fd, Conf);
@@ -929,49 +835,60 @@ write_vacm_conf(Fd, Conf) ->
Fun = fun(Entry) -> do_write_vacm_conf(Fd, Entry) end,
lists:foreach(Fun, Conf).
-do_write_vacm_conf(Fd,
- {vacmSecurityToGroup,
- SecModel, SecName, GroupName}) ->
- io:format(Fd, "{vacmSecurityToGroup, ~w, \"~s\", \"~s\"}.~n",
- [SecModel, SecName, GroupName]);
-do_write_vacm_conf(Fd,
- {vacmAccess,
- GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}) ->
- io:format(Fd, "{vacmAccess, \"~s\", \"~s\", ~w, ~w, ~w, "
- "\"~s\", \"~s\", \"~s\"}.~n",
- [GroupName, Prefix, SecModel, SecLevel,
- Match, RV, WV, NV]);
-do_write_vacm_conf(Fd,
- {vacmViewTreeFamily,
- ViewIndex, ViewSubtree, ViewStatus, ViewMask}) ->
- io:format(Fd, "{vacmViewTreeFamily, \"~s\", ~w, ~w, ~w}.~n",
- [ViewIndex, ViewSubtree, ViewStatus, ViewMask]);
+do_write_vacm_conf(
+ Fd,
+ {vacmSecurityToGroup,
+ SecModel, SecName, GroupName}) ->
+ io:format(
+ Fd, "{vacmSecurityToGroup, ~w, \"~s\", \"~s\"}.~n",
+ [SecModel, SecName, GroupName]);
+do_write_vacm_conf(
+ Fd,
+ {vacmAccess,
+ GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}) ->
+ io:format(
+ Fd, "{vacmAccess, \"~s\", \"~s\", ~w, ~w, ~w, "
+ "\"~s\", \"~s\", \"~s\"}.~n",
+ [GroupName, Prefix, SecModel, SecLevel,
+ Match, RV, WV, NV]);
+do_write_vacm_conf(
+ Fd,
+ {vacmViewTreeFamily,
+ ViewIndex, ViewSubtree, ViewStatus, ViewMask}) ->
+ io:format(
+ Fd, "{vacmViewTreeFamily, \"~s\", ~w, ~w, ~w}.~n",
+ [ViewIndex, ViewSubtree, ViewStatus, ViewMask]);
do_write_vacm_conf(_Fd, Crap) ->
error({bad_vacm_config, Crap}).
%% ---- config file wrapper functions ----
-write_config_file(Dir, File, Verify, Write) ->
- snmp_config:write_config_file(Dir, File, Verify, Write).
+write_config_file(Dir, File, Order, Check, Write, Conf) ->
+ snmp_config:write_config_file(Dir, File, Order, Check, Write, Conf).
-append_config_file(Dir, File, Verify, Write) ->
- snmp_config:append_config_file(Dir, File, Verify, Write).
+append_config_file(Dir, File, Order, Check, Write, Conf) ->
+ snmp_config:append_config_file(Dir, File, Order, Check, Write, Conf).
-read_config_file(Dir, File, Verify) ->
- snmp_config:read_config_file(Dir, File, Verify).
+read_config_file(Dir, File, Order, Check) ->
+ snmp_config:read_config_file(Dir, File, Order, Check).
%% ---- config file utility functions ----
+check_ok(ok) ->
+ ok;
+check_ok({ok, _}) ->
+ ok.
+
header() ->
{Y,Mo,D} = date(),
{H,Mi,S} = time(),
- io_lib:format("%% This file was generated by "
- "~w (version-~s) ~w-~2.2.0w-~2.2.0w "
- "~2.2.0w:~2.2.0w:~2.2.0w\n",
- [?MODULE, ?version, Y, Mo, D, H, Mi, S]).
-
+ io_lib:format(
+ "%% This file was generated by "
+ "~w (version-~s) ~w-~2.2.0w-~2.2.0w "
+ "~2.2.0w:~2.2.0w:~2.2.0w\n",
+ [?MODULE, ?version, Y, Mo, D, H, Mi, S]).
error(R) ->
throw({error, R}).
diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl
index f991244287..292c370d51 100644
--- a/lib/snmp/src/agent/snmpa_local_db.erl
+++ b/lib/snmp/src/agent/snmpa_local_db.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1011,6 +1011,10 @@ table_construct_row(Name, RowIndex, Status, Cols) ->
defvals = Defs, status_col = StatusCol,
first_own_index = FirstOwnIndex, not_accessible = NoAccs} =
snmp_generic:table_info(Name),
+ ?vtrace(
+ "table_construct_row Indexes: ~p~n"
+ " RowIndex: ~p",
+ [Indexes, RowIndex]),
Keys = snmp_generic:split_index_to_keys(Indexes, RowIndex),
OwnKeys = snmp_generic:get_own_indexes(FirstOwnIndex, Keys),
Row = OwnKeys ++ snmp_generic:table_create_rest(length(OwnKeys) + 1,
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 11ae806866..642b1f7fc5 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-export([init/1, reset/0, inc/1, counters/0,
discarded_pdu/1,
- process_packet/6, process_packet/7,
+ process_packet/5, process_packet/6, process_packet/7,
generate_response_msg/5, generate_response_msg/6,
generate_msg/5, generate_msg/6,
generate_discovery_msg/4,
@@ -113,22 +113,30 @@ reset() ->
% length(snmp_pdus:enc_message(M)) + 4.
%%-----------------------------------------------------------------
-%% Func: process_packet(Packet, TDomain, TAddress, State, Log) ->
+%% Func: process_packet(Packet, Domain, Address, State, Log) ->
%% {ok, SnmpVsn, Pdu, PduMS, ACMData} | {discarded, Reason}
%% Types: Packet = binary()
-%% TDomain = snmpUDPDomain | transportDomain()
-%% TAddress = {Ip, Udp} (*but* depends on TDomain)
+%% Domain = snmpUDPDomain | transportDomain()
+%% Address = {Ip, Udp} (*but* depends on Domain)
%% State = #state
%% Purpose: This is the main Message Dispatching function. (see
%% section 4.2.1 in rfc2272)
%%-----------------------------------------------------------------
-process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) ->
+process_packet(Packet, From, State, NoteStore, Log) ->
LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
- process_packet(Packet, TDomain, TAddress, LocalEngineID,
- State, NoteStore, Log).
-
-process_packet(Packet, TDomain, TAddress, LocalEngineID,
- State, NoteStore, Log) ->
+ process_packet(Packet, From, LocalEngineID, State, NoteStore, Log).
+
+process_packet(
+ Packet, Domain, Address, LocalEngineID, State, NoteStore, Log) ->
+ From = {Domain, Address},
+ process_packet(Packet, From, LocalEngineID, State, NoteStore, Log).
+
+process_packet(Packet, Domain, Address, State, NoteStore, Log)
+ when is_atom(Domain) ->
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ From = {Domain, Address},
+ process_packet(Packet, From, LocalEngineID, State, NoteStore, Log);
+process_packet(Packet, From, LocalEngineID, State, NoteStore, Log) ->
inc(snmpInPkts),
case catch snmp_pdus:dec_message_only(binary_to_list(Packet)) of
@@ -136,17 +144,17 @@ process_packet(Packet, TDomain, TAddress, LocalEngineID,
when State#state.v1 =:= true ->
?vlog("v1, community: ~s", [Community]),
HS = ?empty_msg_size + length(Community),
- v1_v2c_proc('version-1', NoteStore, Community,
- TDomain, TAddress,
- LocalEngineID, Data, HS, Log, Packet);
+ v1_v2c_proc(
+ 'version-1', NoteStore, Community, From,
+ LocalEngineID, Data, HS, Log, Packet);
#message{version = 'version-2', vsn_hdr = Community, data = Data}
when State#state.v2c =:= true ->
?vlog("v2c, community: ~s", [Community]),
HS = ?empty_msg_size + length(Community),
- v1_v2c_proc('version-2', NoteStore, Community,
- TDomain, TAddress,
- LocalEngineID, Data, HS, Log, Packet);
+ v1_v2c_proc(
+ 'version-2', NoteStore, Community, From,
+ LocalEngineID, Data, HS, Log, Packet);
#message{version = 'version-3', vsn_hdr = V3Hdr, data = Data}
when State#state.v3 =:= true ->
@@ -154,9 +162,9 @@ process_packet(Packet, TDomain, TAddress, LocalEngineID,
[V3Hdr#v3_hdr.msgID,
V3Hdr#v3_hdr.msgFlags,
V3Hdr#v3_hdr.msgSecurityModel]),
- v3_proc(NoteStore, Packet,
- TDomain, TAddress,
- LocalEngineID, V3Hdr, Data, Log);
+ v3_proc(
+ NoteStore, Packet, From,
+ LocalEngineID, V3Hdr, Data, Log);
{'EXIT', {bad_version, Vsn}} ->
?vtrace("exit: bad version: ~p",[Vsn]),
@@ -183,11 +191,32 @@ discarded_pdu(Variable) -> inc(Variable).
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-v1_v2c_proc(Vsn, NoteStore, Community, Domain,
- {Ip, Udp}, LocalEngineID,
- Data, HS, Log, Packet) ->
- TDomain = snmp_conf:mk_tdomain(Domain),
- TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp),
+v1_v2c_proc(
+ Vsn, NoteStore, Community, From,
+ LocalEngineID, Data, HS, Log, Packet) ->
+ try
+ case From of
+ {D, A} when is_atom(D) ->
+ {snmp_conf:mk_tdomain(D),
+ snmp_conf:mk_taddress(D, A)};
+ {_, P} = A when is_integer(P) ->
+ {snmp_conf:mk_tdomain(),
+ snmp_conf:mk_taddress(A)}
+ end
+ of
+ {TDomain, TAddress} ->
+ v1_v2c_proc_dec(
+ Vsn, NoteStore, Community, TDomain, TAddress,
+ LocalEngineID, Data, HS, Log, Packet)
+ catch
+ _ ->
+ {discarded, {badarg, From}}
+ end.
+
+
+v1_v2c_proc_dec(
+ Vsn, NoteStore, Community, TDomain, TAddress,
+ LocalEngineID, Data, HS, Log, Packet) ->
AgentMS = get_engine_max_message_size(LocalEngineID),
MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress),
PduMS = case MgrMS of
@@ -214,7 +243,7 @@ v1_v2c_proc(Vsn, NoteStore, Community, Domain,
case Pdu#pdu.type of
'set-request' ->
%% Check if this message has already been processed
- Key = {agent, Ip, ReqId},
+ Key = {agent, {TDomain, TAddress}, ReqId},
case snmp_note_store:get_note(NoteStore, Key) of
undefined ->
%% Set the processed note _after_ pdu processing.
@@ -236,13 +265,7 @@ v1_v2c_proc(Vsn, NoteStore, Community, Domain,
{discarded, Reason};
_TrapPdu ->
{discarded, trap_pdu}
- end;
-v1_v2c_proc(_Vsn, _NoteStore, _Community, snmpUDPDomain, TAddress,
- _LocalEngineID, _Data, _HS, _Log, _Packet) ->
- {discarded, {badarg, TAddress}};
-v1_v2c_proc(_Vsn, _NoteStore, _Community, TDomain, _TAddress,
- _LocalEngineID, _Data, _HS, _Log, _Packet) ->
- {discarded, {badarg, TDomain}}.
+ end.
sec_model('version-1') -> ?SEC_V1;
sec_model('version-2') -> ?SEC_V2C.
@@ -252,8 +275,7 @@ sec_model('version-2') -> ?SEC_V2C.
%% Handles a SNMPv3 Message, following the procedures in rfc2272,
%% section 4.2 and 7.2
%%-----------------------------------------------------------------
-v3_proc(NoteStore, Packet, _TDomain, _TAddress, LocalEngineID,
- V3Hdr, Data, Log) ->
+v3_proc(NoteStore, Packet, _From, LocalEngineID, V3Hdr, Data, Log) ->
case (catch v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log)) of
{'EXIT', Reason} ->
exit(Reason);
@@ -999,7 +1021,7 @@ generate_discovery_msg(NoteStore, {TDomain, TAddress},
InitialUserName,
ContextName, Timeout) ->
- {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress),
+ {ok, {Domain, Address}} = transform_taddr(TDomain, TAddress),
%% 7.1.7
?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]),
@@ -1041,7 +1063,7 @@ generate_discovery_msg(NoteStore, {TDomain, TAddress},
%% Log(Packet),
inc_snmp_out_vars(Pdu),
?vdebug("generate_discovery_msg -> done", []),
- {Packet, Address};
+ {Domain, Address, Packet};
Error ->
throw(Error)
@@ -1081,8 +1103,22 @@ transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) ->
{ok, {Domain, Address}};
transform_taddr(?transportDomainUdpIpv4, BadAddr) ->
{error, {bad_transportDomainUdpIpv4_address, BadAddr}};
-transform_taddr(?transportDomainUdpIpv6,
- [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) ->
+transform_taddr(
+ ?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16,
+ P1, P2]) ->
+ Domain = transportDomainUdpIpv6,
+ Addr =
+ {(A1 bsl 8) bor A2, (A3 bsl 8) bor A4,
+ (A5 bsl 8) bor A6, (A7 bsl 8) bor A8,
+ (A9 bsl 8) bor A10, (A11 bsl 8) bor A12,
+ (A13 bsl 8) bor A14, (A15 bsl 8) bor A16},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(
+ ?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) ->
Domain = transportDomainUdpIpv6,
Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
Port = P1 bsl 8 + P2,
@@ -1171,6 +1207,9 @@ mk_v1_v2_packet_list([{Domain, Addr} | T],
%% Sending from default UDP port
inc_snmp_out_vars(Pdu),
Entry = {Domain, Addr, Packet},
+ %% It would be cleaner to return {To, Packet} to not
+ %% break the abstraction for an address on the
+ %% {Domain, Address} format.
mk_v1_v2_packet_list(T, Packet, Len, Pdu, [Entry | Acc]).
@@ -1277,6 +1316,9 @@ mk_v3_packet_entry(NoteStore, Domain, Addr,
req_id = Pdu#pdu.request_id},
snmp_note_store:set_note(NoteStore, 1500, CacheKey, CacheVal),
inc_snmp_out_vars(Pdu),
+ %% It would be cleaner to return {To, Packet} to not
+ %% break the abstraction for an address on the
+ %% {Domain, Address} format.
{ok, {Domain, Addr, Data}}
end.
diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl
index 79c85a6e4e..840d56d563 100644
--- a/lib/snmp/src/agent/snmpa_net_if.erl
+++ b/lib/snmp/src/agent/snmpa_net_if.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,18 +35,27 @@
-include("snmp_debug.hrl").
-include("snmp_verbosity.hrl").
--record(state, {parent,
- note_store,
- master_agent,
- usock,
- usock_opts,
- mpd_state,
- log,
- reqs = [],
- debug = false,
- limit = infinity,
- rcnt = [],
- filter}).
+-record(state,
+ {parent,
+ note_store,
+ master_agent,
+ transports = [],
+%% usock,
+%% usock_opts,
+ mpd_state,
+ log,
+ reqs = [],
+ debug = false,
+ limit = infinity,
+%% rcnt = [],
+ filter}).
+%% domain = snmpUDPDomain}).
+
+-record(transport,
+ {socket,
+ domain = snmpUDPDomain,
+ opts = [],
+ req_refs = []}).
-ifndef(default_verbosity).
-define(default_verbosity,silence).
@@ -104,13 +113,9 @@ get_request_limit(Pid) ->
set_request_limit(Pid, NewLimit) ->
call(Pid, {set_request_limit, NewLimit}).
-get_port() ->
- {value, UDPPort} = snmp_framework_mib:intAgentUDPPort(get),
- UDPPort.
-
-get_address() ->
- {value, IPAddress} = snmp_framework_mib:intAgentIpAddress(get),
- IPAddress.
+get_transports() ->
+ {value, Transports} = snmp_framework_mib:intAgentTransports(get),
+ Transports.
filter_reset(Pid) ->
Pid ! filter_reset.
@@ -129,7 +134,22 @@ init(Prio, NoteStore, MasterAgent, Parent, Opts) ->
case (catch do_init(Prio, NoteStore, MasterAgent, Parent, Opts)) of
{ok, State} ->
proc_lib:init_ack({ok, self()}),
- loop(State);
+ try loop(State)
+ catch
+ C:E when C =/= exit, E =/= shutdown ->
+ Fmt =
+ "loop/1 EXCEPTION ~w:~w~n"
+ " ~p",
+ S = erlang:get_stacktrace(),
+ case C of
+ exit ->
+ %% Externally killed, root cause is elsewhere
+ info_msg(Fmt, [C, E, S]);
+ _ ->
+ error_msg(Fmt, [C, E, S])
+ end,
+ erlang:raise(C, E, S)
+ end;
{error, Reason} ->
config_err("failed starting net-if: ~n~p", [Reason]),
proc_lib:init_ack({error, Reason});
@@ -147,12 +167,6 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) ->
put(verbosity,get_verbosity(Opts)),
?vlog("starting",[]),
- %% -- Port and address --
- UDPPort = get_port(),
- ?vdebug("port: ~w",[UDPPort]),
- IPAddress = get_address(),
- ?vdebug("addr: ~w",[IPAddress]),
-
%% -- Versions --
Vsns = get_vsns(Opts),
?vdebug("vsns: ~w",[Vsns]),
@@ -162,39 +176,45 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) ->
?vdebug("Limit: ~w", [Limit]),
FilterOpts = get_filter_opts(Opts),
FilterMod = create_filter(FilterOpts),
- ?vdebug("FilterMod: ~w", [FilterMod]),
+ ?vdebug("FilterMod: ~w FilterOpts: ~p", [FilterMod,FilterOpts]),
%% -- Audit trail log
Log = create_log(),
?vdebug("Log: ~w",[Log]),
-
- %% -- Socket --
- IPOpts1 = ip_opt_bind_to_ip_address(Opts, IPAddress),
- IPOpts2 = ip_opt_no_reuse_address(Opts),
- IPOpts3 = ip_opt_recbuf(Opts),
- IPOpts4 = ip_opt_sndbuf(Opts),
- IPOpts = [binary | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4],
- ?vdebug("open socket with options: ~w",[IPOpts]),
- case gen_udp_open(UDPPort, IPOpts) of
- {ok, Sock} ->
+ DomainAddresses = get_transports(),
+ ?vdebug("DomainAddresses: ~w",[DomainAddresses]),
+ try
+ [begin
+ SocketOpts = socket_opts(Domain, Address, Opts),
+ Socket = socket_open(Domain, SocketOpts),
+ active_once(Socket),
+ #transport{
+ socket = Socket,
+ domain = Domain,
+ opts = SocketOpts}
+ end || {Domain, Address} <- DomainAddresses]
+ of
+ [] ->
+ ?vinfo("No transports configured: ~p", [DomainAddresses]),
+ {error, {no_transports,DomainAddresses}};
+ Transports ->
MpdState = snmpa_mpd:init(Vsns),
- init_counters(),
- active_once(Sock),
+ init_counters(),
S = #state{parent = Parent,
note_store = NoteStore,
master_agent = MasterAgent,
mpd_state = MpdState,
- usock = Sock,
- usock_opts = IPOpts,
+ transports = Transports,
log = Log,
limit = Limit,
filter = FilterMod},
?vdebug("started with MpdState: ~p", [MpdState]),
- {ok, S};
- {error, Reason} ->
- ?vinfo("Failed to open UDP socket: ~p", [Reason]),
- {error, {udp_open, UDPPort, Reason}}
+ {ok, S}
+ catch
+ Error ->
+ ?vinfo("Failed to initialize socket(s): ~p", [Error]),
+ {error, Error}
end.
@@ -250,48 +270,84 @@ create_filter(BadOpts) ->
throw({error, {bad_filter_opts, BadOpts}}).
-log({_, []}, _, _, _, _) ->
+log({_, []}, _, _, _) ->
ok;
-log({Log, Types}, 'set-request', Packet, Addr, Port) ->
+log({Log, Types}, 'set-request', Packet, Address) ->
case lists:member(write, Types) of
true ->
- snmp_log:log(Log, Packet, Addr, Port);
+ snmp_log:log(Log, Packet, format_address(Address));
false ->
ok
end;
-log({Log, Types}, _, Packet, Addr, Port) ->
+log({Log, Types}, _, Packet, Address) ->
case lists:member(read, Types) of
true ->
- snmp_log:log(Log, Packet, Addr, Port);
+ snmp_log:log(Log, Packet, format_address(Address));
false ->
ok
- end;
-log(_, _, _, _, _) ->
- ok.
-
-
-gen_udp_open(Port, Opts) ->
+ end.
+
+format_address(Address) ->
+ iolist_to_binary(snmp_conf:mk_addr_string(Address)).
+
+
+socket_open(snmpUDPDomain = Domain, [IpPort | Opts]) ->
case init:get_argument(snmp_fd) of
{ok, [[FdStr]]} ->
Fd = list_to_integer(FdStr),
- gen_udp:open(0, [{fd, Fd}|Opts]);
+ ?vdebug("socket_open(~p, [~p | ~p]) Fd: ~p",
+ [Domain, IpPort, Opts, Fd]),
+ gen_udp_open(IpPort, [{fd, Fd} | Opts]);
error ->
case init:get_argument(snmpa_fd) of
{ok, [[FdStr]]} ->
Fd = list_to_integer(FdStr),
- gen_udp:open(0, [{fd, Fd}|Opts]);
+ ?vdebug("socket_open(~p, [~p | ~p]) Fd: ~p",
+ [Domain, IpPort, Opts, Fd]),
+ gen_udp_open(IpPort, [{fd, Fd} | Opts]);
error ->
- gen_udp:open(Port, Opts)
+ ?vdebug("socket_open(~p, [~p | ~p])",
+ [Domain, IpPort, Opts]),
+ gen_udp_open(IpPort, Opts)
end
+ end;
+socket_open(Domain, [IpPort | Opts])
+ when Domain =:= transportDomainUdpIpv4;
+ Domain =:= transportDomainUdpIpv6 ->
+ ?vdebug("socket_open(~p, [~p | ~p])", [Domain, IpPort, Opts]),
+ gen_udp_open(IpPort, Opts);
+socket_open(Domain, Opts) ->
+ throw({socket_open, Domain, Opts}).
+
+gen_udp_open(IpPort, Opts) ->
+ case gen_udp:open(IpPort, Opts) of
+ {ok, Socket} ->
+ Socket;
+ {error, Reason} ->
+ throw({udp_open, IpPort, Reason})
end.
-loop(S) ->
+
+loop(#state{transports = Transports, limit = Limit, parent = Parent} = S) ->
+ ?vdebug("loop(~p)", [S]),
receive
- {udp, _UdpId, Ip, Port, Packet} ->
- ?vlog("got paket from ~w:~w",[Ip,Port]),
- NewS = maybe_handle_recv(S, Ip, Port, Packet),
- loop(NewS);
+ {udp, Socket, IpAddr, IpPort, Packet} = Msg when is_port(Socket) ->
+ ?vlog("got paket from ~w:~w on ~w", [IpAddr, IpPort, Socket]),
+ case lists:keyfind(Socket, #transport.socket, Transports) of
+ #transport{socket = Socket, domain = Domain} = Transport ->
+ From =
+ case Domain of
+ snmpUDPDomain ->
+ {IpAddr, IpPort};
+ _ ->
+ {Domain, {IpAddr, IpPort}}
+ end,
+ loop(maybe_handle_recv(S, Transport, From, Packet));
+ false ->
+ error_msg("Packet on unknown port: ~p", [Msg]),
+ loop(S)
+ end;
{info, ReplyRef, Pid} ->
Info = get_info(S),
@@ -299,47 +355,78 @@ loop(S) ->
loop(S);
%% response (to get/get_next/get_bulk/set requests)
- {snmp_response, Vsn, RePdu, Type, ACMData, Dest, []} ->
+ {snmp_response, Vsn, RePdu, Type, ACMData, To, Extra} ->
?vlog("reply pdu: "
"~n ~s",
[?vapply(snmp_misc, format, [256, "~w", [RePdu]])]),
- NewS = maybe_handle_reply_pdu(S, Vsn, RePdu, Type, ACMData, Dest),
- loop(NewS);
+ {_, ReqRef} = lists:keyfind(request_ref, 1, Extra),
+ case
+ case
+ (Limit =/= infinity) andalso
+ select_transport_from_req_ref(ReqRef, Transports)
+ of
+ false ->
+ select_transport_from_domain(
+ address_to_domain(To),
+ Transports);
+ T ->
+ T
+ end
+ of
+ false ->
+ error_msg(
+ "Can not find transport for response PDU to: ~s",
+ [format_address(To)]),
+ loop(S);
+ Transport ->
+ NewS = update_req_counter_outgoing(S, Transport, ReqRef),
+ maybe_handle_reply_pdu(
+ NewS, Transport, Vsn, RePdu, Type, ACMData, To),
+ loop(NewS)
+ end;
%% Traps/notification
- {send_pdu, Vsn, Pdu, MsgData, To} ->
- ?vdebug("send pdu: "
- "~n Pdu: ~p"
- "~n To: ~p", [Pdu, To]),
- NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined),
+ {send_pdu, Vsn, Pdu, MsgData, TDomAddrs} ->
+ ?vdebug("send pdu:~n"
+ " Pdu: ~p~n"
+ " TDomAddrs: ~p", [Pdu, TDomAddrs]),
+ NewS =
+ maybe_handle_send_pdu(
+ S, Vsn, Pdu, MsgData, TDomAddrs, undefined),
loop(NewS);
%% We dont use the extra-info at this time, ...
- {send_pdu, Vsn, Pdu, MsgData, To, _ExtraInfo} ->
- ?vdebug("send pdu: "
- "~n Pdu: ~p"
- "~n To: ~p", [Pdu, To]),
- NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined),
+ {send_pdu, Vsn, Pdu, MsgData, TDomAddrs, _ExtraInfo} ->
+ ?vdebug("send pdu:~n"
+ " Pdu: ~p~n"
+ " TDomAddrs: ~p", [Pdu, TDomAddrs]),
+ NewS =
+ maybe_handle_send_pdu(
+ S, Vsn, Pdu, MsgData, TDomAddrs, undefined),
loop(NewS);
%% Informs
- {send_pdu_req, Vsn, Pdu, MsgData, To, From} ->
- ?vdebug("send pdu request: "
- "~n Pdu: ~p"
- "~n To: ~p"
- "~n From: ~p",
- [Pdu, To, toname(From)]),
- NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, From),
+ {send_pdu_req, Vsn, Pdu, MsgData, TDomAddrs, From} ->
+ ?vdebug("send pdu request:~n"
+ " Pdu: ~p~n"
+ " TDomAddrs: ~p~n"
+ " From: ~p",
+ [Pdu, TDomAddrs, toname(From)]),
+ NewS =
+ maybe_handle_send_pdu(
+ S, Vsn, Pdu, MsgData, TDomAddrs, From),
loop(NewS);
%% We dont use the extra-info at this time, ...
- {send_pdu_req, Vsn, Pdu, MsgData, To, From, _ExtraInfo} ->
- ?vdebug("send pdu request: "
- "~n Pdu: ~p"
- "~n To: ~p"
- "~n From: ~p",
- [Pdu, To, toname(From)]),
- NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, From),
+ {send_pdu_req, Vsn, Pdu, MsgData, TDomAddrs, From, _ExtraInfo} ->
+ ?vdebug("send pdu request:~n"
+ " Pdu: ~p~n"
+ " TDomAddrs: ~p~n"
+ " From: ~p",
+ [Pdu, TDomAddrs, toname(From)]),
+ NewS =
+ maybe_handle_send_pdu(
+ S, Vsn, Pdu, MsgData, TDomAddrs, From),
loop(NewS);
%% Discovery Inform
@@ -365,15 +452,34 @@ loop(S) ->
NewS = handle_send_discovery(S, Pdu, MsgData, To, From),
loop(NewS);
- {discarded_pdu, _Vsn, ReqId, _ACMData, Variable, _Extra} ->
- ?vdebug("discard PDU: ~p", [Variable]),
+ {discarded_pdu, _Vsn, ReqId, _ACMData, Variable, Extra} ->
+ ?vdebug("discard PDU: ~p - ~p - ~p",
+ [Variable, Extra, Transports]),
snmpa_mpd:discarded_pdu(Variable),
- NewS = update_req_counter_outgoing(S, ReqId),
- loop(NewS);
+ {_, ReqRef} = lists:keyfind(request_ref, 1, Extra),
+ if
+ Limit =:= infinity ->
+ %% The incoming PDU was not registered
+ loop(update_req_counter_outgoing(S, false, ReqRef));
+ true ->
+ case
+ select_transport_from_req_ref(ReqRef, Transports)
+ of
+ false ->
+ error_msg(
+ "Can not find transport for discarded PDU: ~p",
+ [ReqId]),
+ loop(S);
+ Transport ->
+ loop(
+ update_req_counter_outgoing(
+ S, Transport, ReqRef))
+ end
+ end;
{get_log_type, ReplyRef, Pid} ->
?vdebug("get log type: ~p", []),
- #state{log = {_, LogType}} = S,
+ {_, LogType} = S#state.log,
Pid ! {ReplyRef, {ok, LogType}, self()},
loop(S);
@@ -385,7 +491,6 @@ loop(S) ->
{get_request_limit, ReplyRef, Pid} ->
?vdebug("get request limit: ~p", []),
- #state{limit = Limit} = S,
Pid ! {ReplyRef, {ok, Limit}, self()},
loop(S);
@@ -409,36 +514,50 @@ loop(S) ->
reset_counters(),
loop(S);
- {'EXIT', Parent, Reason} when Parent == S#state.parent ->
+ {'EXIT', Parent, Reason} ->
?vlog("parent (~p) exited: "
"~n ~p", [Parent, Reason]),
exit(Reason);
- {'EXIT', Port, Reason} when Port == S#state.usock ->
- UDPPort = get_port(),
- NewS =
- case gen_udp_open(UDPPort, S#state.usock_opts) of
- {ok, Id} ->
- error_msg("Port ~p exited for reason"
- "~n ~p"
- "~n Re-opened (~p)", [Port, Reason, Id]),
- S#state{usock = Id};
- {error, ReopenReason} ->
- error_msg("Port ~p exited for reason"
- "~n ~p"
- "~n Re-open failed with reason"
- "~n ~p",
- [Port, Reason, ReopenReason]),
- ok
- end,
- loop(NewS);
-
- {'EXIT', Port, Reason} when is_port(Port) ->
- error_msg("Exit message from port ~p for reason ~p~n",
- [Port, Reason]),
- loop(S);
-
- {'EXIT', Pid, Reason} ->
+ {'EXIT', Socket, Reason} when is_port(Socket) ->
+ case lists:keyfind(Socket, #transport.socket, Transports) of
+ #transport{
+ socket = Socket,
+ domain = Domain,
+ opts = SocketOpts,
+ req_refs = ReqRefs} = Transport ->
+ try socket_open(Domain, SocketOpts) of
+ NewSocket ->
+ error_msg(
+ "Socket ~p exited for reason"
+ "~n ~p"
+ "~n Re-opened (~p)",
+ [Socket, Reason, NewSocket]),
+ (length(ReqRefs) < Limit) andalso
+ active_once(NewSocket),
+ S#state{
+ transports =
+ lists:keyreplace(
+ Socket, #transport.socket, Transports,
+ Transport#transport{socket = NewSocket})}
+ catch
+ ReopenReason ->
+ error_msg(
+ "Socket ~p exited for reason"
+ "~n ~p"
+ "~n Re-open failed with reason"
+ "~n ~p",
+ [Socket, Reason, ReopenReason]),
+ exit(ReopenReason)
+ end;
+ false ->
+ error_msg(
+ "Exit message from port ~p for reason ~p~n",
+ [Socket, Reason]),
+ loop(S)
+ end;
+
+ {'EXIT', Pid, Reason} when is_pid(Pid) ->
?vlog("~p exited: "
"~n ~p", [Pid, Reason]),
NewS = clear_reqs(Pid, S),
@@ -446,205 +565,321 @@ loop(S) ->
{system, From, Msg} ->
?vdebug("system event ~p from ~p", [Msg, From]),
- sys:handle_system_msg(Msg, From, S#state.parent, ?MODULE, [], S);
+ sys:handle_system_msg(Msg, From, Parent, ?MODULE, [], S);
_ ->
loop(S)
end.
-update_req_counter_incomming(#state{limit = infinity, usock = Sock} = S, _) ->
- active_once(Sock), %% No limit so activate directly
+update_req_counter_incoming(
+ #state{limit = infinity} = S,
+ #transport{socket = Socket},
+ _ReqRef) ->
+ active_once(Socket), %% No limit so activate directly
S;
-update_req_counter_incomming(#state{limit = Limit,
- rcnt = RCnt,
- usock = Sock} = S, Rid)
- when length(RCnt) + 1 == Limit ->
+update_req_counter_incoming(
+ #state{limit = Limit} = S,
+ #transport{socket = Socket, req_refs = ReqRefs} = T,
+ ReqRef) when length(ReqRefs) + 1 >= Limit ->
%% Ok, one more and we are at the limit.
%% Just make sure we are not already processing this one...
- case lists:member(Rid, RCnt) of
+ case lists:member(ReqRef, ReqRefs) of
false ->
%% We are at the limit, do _not_ activate socket
- S#state{rcnt = [Rid|RCnt]};
+ update_transport_req_refs(S, T, [ReqRef | ReqRefs]);
true ->
- active_once(Sock),
+ active_once(Socket),
S
end;
-update_req_counter_incomming(#state{rcnt = RCnt,
- usock = Sock} = S, Rid) ->
- active_once(Sock),
- case lists:member(Rid, RCnt) of
+update_req_counter_incoming(
+ #state{} = S,
+ #transport{socket = Socket, req_refs = ReqRefs} = T,
+ ReqRef) ->
+ active_once(Socket),
+ case lists:member(ReqRef, ReqRefs) of
false ->
- S#state{rcnt = [Rid|RCnt]};
+ update_transport_req_refs(S, T, [ReqRef | ReqRefs]);
true ->
S
end.
-
-update_req_counter_outgoing(#state{limit = infinity} = S, _Rid) ->
+update_req_counter_outgoing(
+ #state{limit = infinity} = S,
+ _Transport, _ReqRef) ->
%% Already activated (in the incoming function)
S;
-update_req_counter_outgoing(#state{limit = Limit,
- rcnt = RCnt,
- usock = Sock} = S, Rid)
- when length(RCnt) == Limit ->
- ?vtrace("handle_req_counter_outgoing(~w) -> entry with"
- "~n Rid: ~w"
- "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]),
- case lists:delete(Rid, RCnt) of
- NewRCnt when length(NewRCnt) < Limit ->
+update_req_counter_outgoing(
+ #state{limit = Limit} = S,
+ #transport{socket = Socket, req_refs = ReqRefs} = Transport,
+ ReqRef) ->
+ LengthReqRefs = length(ReqRefs),
+ ?vtrace("update_req_counter_outgoing() -> entry with~n"
+ " Limit: ~w~n"
+ " ReqRef: ~w~n"
+ " length(ReqRefs): ~w", [Limit, ReqRef, LengthReqRefs]),
+ NewReqRefs = lists:delete(ReqRef, ReqRefs),
+ (LengthReqRefs >= Limit) andalso (length(NewReqRefs) < Limit) andalso
+ begin
?vtrace("update_req_counter_outgoing -> "
- "passed below limit: activate", []),
- active_once(Sock),
- S#state{rcnt = NewRCnt};
- _ ->
- S
- end;
-update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S,
- Rid) ->
- ?vtrace("handle_req_counter_outgoing(~w) -> entry with"
- "~n Rid: ~w"
- "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]),
- NewRCnt = lists:delete(Rid, RCnt),
- S#state{rcnt = NewRCnt}.
-
-
-maybe_handle_recv(#state{usock = Sock, filter = FilterMod} = S,
- Ip, Port, Packet) ->
- case (catch FilterMod:accept_recv(Ip, Port)) of
+ "passed below limit: activate", []),
+ active_once(Socket)
+ end,
+ update_transport_req_refs(S, Transport, NewReqRefs).
+
+update_transport_req_refs(
+ #state{transports = Transports} = S,
+ #transport{socket = Socket} = T,
+ ReqRefs) ->
+ S#state{
+ transports =
+ lists:keyreplace(
+ Socket, #transport.socket, Transports,
+ T#transport{req_refs = ReqRefs})}.
+
+
+maybe_handle_recv(
+ #state{filter = FilterMod} = S,
+ #transport{socket = Socket} = Transport,
+ From, Packet) ->
+ {From_1, From_2} = From,
+ case
+ try FilterMod:accept_recv(From_1, From_2)
+ catch
+ Class:Exception ->
+ error_msg(
+ "FilterMod:accept_recv(~p, ~p) crashed: ~w:~w~n ~p",
+ [From_1,From_2,Class,Exception,erlang:get_stacktrace()]),
+ true
+ end
+ of
false ->
%% Drop the received packet
inc(netIfMsgInDrops),
- active_once(Sock),
+ active_once(Socket),
S;
- _ ->
- handle_recv(S, Ip, Port, Packet)
+ Other ->
+ case Other of
+ true ->
+ ok;
+ _ ->
+ error_msg(
+ "FilterMod:accept_recv(~p, ~p) returned: ~p",
+ [From_1,From_2,Other])
+ end,
+ handle_recv(S, Transport, From, Packet)
end.
-handle_discovery_response(_Ip, _Port, #pdu{request_id = ReqId} = Pdu,
- ManagerEngineId,
- #state{usock = Sock, reqs = Reqs} = S) ->
- case lists:keysearch(ReqId, 1, S#state.reqs) of
- {value, {_, Pid}} ->
- active_once(Sock),
- Pid ! {snmp_discovery_response_received, Pdu, ManagerEngineId},
- NReqs = lists:keydelete(ReqId, 1, Reqs),
- S#state{reqs = NReqs};
- _ ->
- %% Ouch, timeout? resend?
- S
- end.
-
-handle_recv(#state{usock = Sock,
- mpd_state = MpdState,
- note_store = NS,
- log = Log} = S, Ip, Port, Packet) ->
+handle_recv(
+ #state{mpd_state = MpdState, note_store = NS, log = Log} = S,
+ #transport{socket = Socket} = Transport,
+ From, Packet) ->
put(n1, erlang:now()),
- LogF = fun(Type, Data) ->
- log(Log, Type, Data, Ip, Port)
- end,
- Domain = snmp_conf:which_domain(Ip), % What the ****...
- case (catch snmpa_mpd:process_packet(Packet,
- Domain, {Ip, Port},
- MpdState, NS, LogF)) of
+ LogF =
+ fun(Type, Data) ->
+ log(Log, Type, Data, From)
+ end,
+ case (catch snmpa_mpd:process_packet(
+ Packet, From, MpdState, NS, LogF)) of
{ok, _Vsn, Pdu, _PduMS, {discovery, ManagerEngineId}} ->
- handle_discovery_response(Ip, Port, Pdu, ManagerEngineId, S);
+ handle_discovery_response(
+ S, Transport, From, Pdu, ManagerEngineId);
{ok, _Vsn, Pdu, _PduMS, discovery} ->
- handle_discovery_response(Ip, Port, Pdu, undefined, S);
+ handle_discovery_response(
+ S, Transport, From, Pdu, undefined);
{ok, Vsn, Pdu, PduMS, ACMData} ->
?vlog("got pdu ~s",
[?vapply(snmp_misc, format, [256, "~w", [Pdu]])]),
- %% handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S);
- maybe_handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S);
+ %% handle_recv_pdu(S, Transport, From, Vsn, Pdu, PduMS, ACMData);
+ maybe_handle_recv_pdu(
+ S, Transport, From, Vsn, Pdu, PduMS, ACMData);
{discarded, Reason} ->
?vlog("packet discarded for reason: ~s",
[?vapply(snmp_misc, format, [256, "~w", [Reason]])]),
- active_once(Sock),
+ active_once(Socket),
S;
{discarded, Reason, ReportPacket} ->
?vlog("sending report for reason: "
"~n ~s",
[?vapply(snmp_misc, format, [256, "~w", [Reason]])]),
- (catch udp_send(S#state.usock, Ip, Port, ReportPacket)),
- active_once(Sock),
+ (catch udp_send(Socket, From, ReportPacket)),
+ active_once(Socket),
S;
{discovery, ReportPacket} ->
?vlog("sending discovery report", []),
- (catch udp_send(S#state.usock, Ip, Port, ReportPacket)),
- active_once(Sock),
+ (catch udp_send(Socket, From, ReportPacket)),
+ active_once(Socket),
S;
Error ->
error_msg("processing of received message failed: "
"~n ~p", [Error]),
- active_once(Sock),
+ active_once(Socket),
S
end.
-
-maybe_handle_recv_pdu(Ip, Port, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData,
- #state{usock = Sock, filter = FilterMod} = S) ->
- case (catch FilterMod:accept_recv_pdu(Ip, Port, Type)) of
+
+handle_discovery_response(
+ #state{reqs = Reqs} = S,
+ #transport{socket = Socket},
+ _From,
+ #pdu{request_id = ReqId} = Pdu,
+ ManagerEngineId) ->
+ case lists:keyfind(ReqId, 1, S#state.reqs) of
+ {ReqId, Pid} ->
+ active_once(Socket),
+ Pid ! {snmp_discovery_response_received, Pdu, ManagerEngineId},
+ %% XXX Strange... Reqs from this Pid should be reaped
+ %% at process exit by clear_reqs/2 so the following
+ %% should be redundant.
+ NReqs = lists:keydelete(ReqId, 1, Reqs),
+ S#state{reqs = NReqs};
+ false ->
+ %% Ouch, timeout? resend?
+ S
+ end.
+
+maybe_handle_recv_pdu(
+ #state{filter = FilterMod} = S,
+ #transport{socket = Socket} = Transport,
+ From, Vsn,
+ #pdu{type = Type} = Pdu, PduMS, ACMData) ->
+ {From_1, From_2} = From,
+ case
+ try FilterMod:accept_recv_pdu(From_1, From_2, Type)
+ catch
+ Class:Exception ->
+ error_msg(
+ "FilterMod:accept_recv_pdu(~p, ~p, ~p) crashed: ~w:~w~n"
+ " ~p",
+ [From_1,From_2,Type,Class,Exception,
+ erlang:get_stacktrace()]),
+ true
+ end
+ of
false ->
inc(netIfPduInDrops),
- active_once(Sock),
- ok;
- _ ->
- handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S)
- end;
-maybe_handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S) ->
- handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S).
+ active_once(Socket),
+ S;
+ Other ->
+ case Other of
+ true ->
+ ok;
+ _ ->
+ error_msg(
+ "FilterMod:accept_recv_pdu(~p, ~p, ~p) returned: ~p",
+ [From_1,From_2,Type,Other])
+ end,
+ handle_recv_pdu(S, Transport, From, Vsn, Pdu, PduMS, ACMData)
+ end.
-handle_recv_pdu(Ip, Port, Vsn, #pdu{type = 'get-response'} = Pdu,
- _PduMS, _ACMData, #state{usock = Sock} = S) ->
- active_once(Sock),
- handle_response(Vsn, Pdu, {Ip, Port}, S),
+handle_recv_pdu(
+ #state{reqs = Reqs} = S,
+ #transport{socket = Socket},
+ From, Vsn,
+ #pdu{type = 'get-response', request_id = ReqId} = Pdu,
+ _PduMS, _ACMData) ->
+ active_once(Socket),
+ case lists:keyfind(ReqId, 1, Reqs) of
+ {ReqId, Pid} ->
+ ?vdebug("handle_recv_pdu -> "
+ "~n send response to receiver ~p", [Pid]),
+ Pid ! {snmp_response_received, Vsn, Pdu, From};
+ false ->
+ ?vdebug("handle_recv_pdu -> "
+ "~n No receiver available for response pdu", [])
+ end,
S;
-handle_recv_pdu(Ip, Port, Vsn, #pdu{request_id = Rid, type = Type} = Pdu,
- PduMS, ACMData, #state{master_agent = Pid} = S)
- when ((Type =:= 'get-request') orelse
- (Type =:= 'get-next-request') orelse
- (Type =:= 'get-bulk-request')) ->
- ?vtrace("handle_recv_pdu -> received get (~w)", [Type]),
- Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, {Ip, Port}, []},
- update_req_counter_incomming(S, Rid);
-handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData,
- #state{usock = Sock, master_agent = Pid} = S) ->
+handle_recv_pdu(
+ #state{master_agent = Pid} = S,
+ #transport{} = Transport,
+ From, Vsn,
+ #pdu{type = Type} = Pdu,
+ PduMS, ACMData)
+ when Type =:= 'set-request';
+ Type =:= 'get-request';
+ Type =:= 'get-next-request';
+ Type =:= 'get-bulk-request' ->
+ ?vtrace("handle_recv_pdu -> received request (~w)", [Type]),
+ ReqRef = make_ref(),
+ Extra = [{request_ref, ReqRef}],
+ Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, Extra},
+ NewS = update_req_counter_incoming(S, Transport, ReqRef),
+ ?vdebug("handle_recv_pdu -> ~p", [NewS]),
+ NewS;
+handle_recv_pdu(
+ #state{master_agent = Pid} = S,
+ #transport{socket = Socket},
+ From, Vsn, Pdu, PduMS, ACMData) ->
?vtrace("handle_recv_pdu -> received other request", []),
- active_once(Sock),
- Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, {Ip, Port}, []},
+ active_once(Socket),
+ Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, []},
S.
-maybe_handle_reply_pdu(#state{filter = FilterMod} = S, Vsn,
- #pdu{request_id = Rid} = Pdu,
- Type, ACMData, {Ip, Port} = Dest) ->
- S1 = update_req_counter_outgoing(S, Rid),
- case (catch FilterMod:accept_send_pdu([{Ip, Port}], Type)) of
+maybe_handle_reply_pdu(
+ #state{filter = FilterMod, transports = Transports} = S,
+ #transport{} = Transport,
+ Vsn,
+ #pdu{} = Pdu,
+ Type, ACMData, To) ->
+ %%
+ Addresses = [fix_filter_address(Transports, To)],
+ case
+ try
+ FilterMod:accept_send_pdu(Addresses, Type)
+ catch
+ Class:Exception ->
+ error_msg(
+ "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p",
+ [Addresses, Type, Class, Exception,
+ erlang:get_stacktrace()]),
+ true
+ end
+ of
false ->
inc(netIfPduOutDrops),
ok;
- _ ->
- handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, Dest)
- end,
- S1.
-
-handle_reply_pdu(#state{log = Log,
- usock = Sock,
- filter = FilterMod},
- Vsn, Pdu, Type, ACMData, {Ip, Port}) ->
- LogF = fun(Type2, Data) ->
- log(Log, Type2, Data, Ip, Port)
- end,
+ Other ->
+ case Other of
+ true ->
+ ok;
+ _ ->
+ error_msg(
+ "FilterMod:accept_send_pdu(~p, ~p) returned: ~p",
+ [Addresses,Type,Other])
+ end,
+ handle_reply_pdu(S, Transport, Vsn, Pdu, Type, ACMData, To)
+ end.
+
+handle_reply_pdu(
+ #state{log = Log} = S,
+ #transport{} = Transport,
+ Vsn,
+ #pdu{} = Pdu,
+ Type, ACMData, To) ->
+ %%
+ LogF =
+ fun(Type2, Data) ->
+ log(Log, Type2, Data, To)
+ end,
case (catch snmpa_mpd:generate_response_msg(Vsn, Pdu, Type,
ACMData, LogF)) of
{ok, Packet} ->
?vinfo("time in agent: ~w mysec", [time_in_agent()]),
- maybe_udp_send(FilterMod, Sock, Ip, Port, Packet);
+ try maybe_udp_send(S, Transport, To, Packet)
+ catch
+ {Reason, Sz} ->
+ error_msg("Cannot send message "
+ "~n size: ~p"
+ "~n reason: ~p"
+ "~n pdu: ~p",
+ [Sz, Reason, Pdu])
+ end;
{discarded, Reason} ->
?vlog("handle_reply_pdu -> "
"~n reply discarded for reason: ~s",
@@ -652,105 +887,116 @@ handle_reply_pdu(#state{log = Log,
ok;
{'EXIT', Reason} ->
user_err("failed generating response message: "
- "~nPDU: ~w~n~w", [Pdu, Reason])
+ "~nPDU: ~p~n~p", [Pdu, Reason])
end.
-
-process_taddrs(To) ->
- process_taddrs(To, []).
-process_taddrs([], Acc) ->
- lists:reverse(Acc);
-%% v3
-process_taddrs([{{_Domain, AddrAndPort}, _SecData}|T], Acc) ->
- process_taddrs(T, [AddrAndPort|Acc]);
-%% v1 & v2
-process_taddrs([{_Domain, AddrAndPort}|T], Acc) ->
- process_taddrs(T, [AddrAndPort|Acc]).
-merge_taddrs(To1, To2) ->
- merge_taddrs(To1, To2, []).
+maybe_handle_send_pdu(
+ #state{filter = FilterMod, transports = Transports} = S,
+ Vsn, Pdu, MsgData, TDomAddrSecs, From) ->
-merge_taddrs([], _To2, Acc) ->
- lists:reverse(Acc);
-%% v3
-merge_taddrs([{{_, AddrAndPort}, _} = H|To1], To2, Acc) ->
- case lists:member(AddrAndPort, To2) of
- true ->
- merge_taddrs(To1, To2, [H|Acc]);
- false ->
- merge_taddrs(To1, To2, Acc)
- end;
-%% v1 & v2
-merge_taddrs([{_, AddrAndPort} = H|To1], To2, Acc) ->
- case lists:member(AddrAndPort, To2) of
- true ->
- merge_taddrs(To1, To2, [H|Acc]);
- false ->
- merge_taddrs(To1, To2, Acc)
- end;
-merge_taddrs([_Crap|To1], To2, Acc) ->
- merge_taddrs(To1, To2, Acc).
-
-
-maybe_handle_send_pdu(#state{filter = FilterMod} = S,
- Vsn, Pdu, MsgData, To0, From) ->
+ ?vtrace("maybe_handle_send_pdu -> entry with~n"
+ " FilterMod: ~p~n"
+ " TDomAddrSecs: ~p", [FilterMod, TDomAddrSecs]),
- ?vtrace("maybe_handle_send_pdu -> entry with"
- "~n FilterMod: ~p"
- "~n To0: ~p", [FilterMod, To0]),
-
- To1 = snmpa_mpd:process_taddrs(To0),
- To2 = process_taddrs(To1),
+ DomAddrSecs = snmpa_mpd:process_taddrs(TDomAddrSecs),
+ AddressesToFilter =
+ case is_legacy_transports(Transports) of
+ true ->
+ [fix_filter_legacy_mpd_address(DAS)
+ || DAS <- DomAddrSecs];
+ false ->
+ [fix_filter_mpd_address(DAS)
+ || DAS <- DomAddrSecs]
+ end,
- case (catch FilterMod:accept_send_pdu(To2, pdu_type_of(Pdu))) of
+ Type = pdu_type_of(Pdu),
+
+ case
+ try FilterMod:accept_send_pdu(AddressesToFilter, Type)
+ catch
+ Class:Exception ->
+ error_msg(
+ "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p",
+ [AddressesToFilter,Type,
+ Class,Exception,erlang:get_stacktrace()]),
+ true
+ end
+ of
false ->
inc(netIfPduOutDrops),
ok;
true ->
- handle_send_pdu(S, Vsn, Pdu, MsgData, To1, From);
- To3 when is_list(To3) ->
- To4 = merge_taddrs(To1, To3),
- ?vtrace("maybe_handle_send_pdu -> To4: "
- "~n ~p", [To4]),
- handle_send_pdu(S, Vsn, Pdu, MsgData, To4, From);
- _ ->
- handle_send_pdu(S, Vsn, Pdu, MsgData, To1, From)
+ handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From);
+ FilteredAddresses when is_list(FilteredAddresses) ->
+ FilteredDomAddrSecs =
+ case is_legacy_transports(Transports) of
+ true ->
+ [DAS ||
+ DAS <- DomAddrSecs,
+ lists:member(
+ fix_filter_legacy_mpd_address(DAS),
+ FilteredAddresses)];
+ false ->
+ [DAS ||
+ DAS <- DomAddrSecs,
+ lists:member(
+ fix_filter_mpd_address(DAS),
+ FilteredAddresses)]
+ end,
+ ?vtrace("maybe_handle_send_pdu -> FilteredDomAddrSecs:~n"
+ " ~p", [FilteredDomAddrSecs]),
+ handle_send_pdu(S, Vsn, Pdu, MsgData, FilteredDomAddrSecs, From);
+ Other ->
+ error_msg(
+ "FilterMod:accept_send_pdu(~p, ~p) returned: ~p",
+ [AddressesToFilter,Type,Other]),
+ handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From)
end.
-handle_send_pdu(#state{note_store = NS} = S, Vsn, Pdu, MsgData, To, From) ->
-
- ?vtrace("handle_send_pdu -> entry with"
- "~n Pdu: ~p"
- "~n To: ~p", [Pdu, To]),
+handle_send_pdu(
+ #state{note_store = NS} = S,
+ Vsn, Pdu, MsgData, DomAddrSecs, From) ->
+ %%
+ ?vtrace("handle_send_pdu -> entry with~n"
+ " Pdu: ~p~n"
+ " DomAddrSecs: ~p", [Pdu, DomAddrSecs]),
- case (catch snmpa_mpd:generate_msg(Vsn, NS, Pdu, MsgData, To)) of
+ case (catch snmpa_mpd:generate_msg(
+ Vsn, NS, Pdu, MsgData, DomAddrSecs)) of
{ok, Addresses} ->
- handle_send_pdu(S, Pdu, Addresses);
+ do_handle_send_pdu(S, Pdu, Addresses);
{discarded, Reason} ->
?vlog("handle_send_pdu -> "
"~n PDU ~p not sent due to ~p", [Pdu, Reason]),
ok;
{'EXIT', Reason} ->
user_err("failed generating message: "
- "~nPDU: ~w~n~w", [Pdu, Reason]),
+ "~nPDU: ~p~n~p", [Pdu, Reason]),
ok
end,
case From of
undefined ->
S;
- Pid ->
+ Pid when is_pid(Pid) ->
?vtrace("link to ~p and add to request list", [Pid]),
link(Pid),
- NReqs = snmp_misc:keyreplaceadd(Pid, 2, S#state.reqs,
- {Pdu#pdu.request_id, From}),
+ NReqs =
+ snmp_misc:keyreplaceadd(
+ Pid, 2, S#state.reqs, {Pdu#pdu.request_id, From}),
S#state{reqs = NReqs}
end.
-handle_send_discovery(#state{note_store = NS} = S,
- Pdu, MsgData,
- To, From) ->
+handle_send_discovery(
+ #state{
+ note_store = NS,
+ log = Log,
+ reqs = Reqs,
+ transports = Transports} = S,
+ #pdu{type = Type, request_id = ReqId} = Pdu,
+ MsgData, To, From) when is_pid(From) ->
?vtrace("handle_send_discovery -> entry with"
"~n Pdu: ~p"
@@ -759,155 +1005,173 @@ handle_send_discovery(#state{note_store = NS} = S,
"~n From: ~p", [Pdu, MsgData, To, From]),
case (catch snmpa_mpd:generate_discovery_msg(NS, Pdu, MsgData, To)) of
- {ok, {Packet, {Ip, Port}}} ->
- handle_send_discovery(S, Pdu, Packet, Ip, Port, From);
+ {ok, {Domain, Address, Packet}} ->
+ case select_transport_from_domain(Domain, Transports) of
+ false ->
+ error_msg(
+ "Can not find transport to: ~s",
+ [format_address(To)]),
+ S;
+ #transport{socket = Socket} ->
+ log(Log, Type, Packet, {Domain, Address}),
+ udp_send(Socket, {Domain, Address}, Packet),
+ ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]),
+ NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}),
+ S#state{reqs = NReqs}
+ end;
{discarded, Reason} ->
?vlog("handle_send_discovery -> "
"~n Discovery PDU ~p not sent due to ~p", [Pdu, Reason]),
- ok;
+ S;
{'EXIT', Reason} ->
user_err("failed generating discovery message: "
- "~n PDU: ~w"
- "~n Reason: ~w", [Pdu, Reason]),
- ok
+ "~n PDU: ~p"
+ "~n Reason: ~p", [Pdu, Reason]),
+ S
end.
-handle_send_discovery(#state{log = Log,
- usock = Sock,
- reqs = Reqs} = S,
- #pdu{type = Type,
- request_id = ReqId},
- Packet, Ip, Port, From)
- when is_binary(Packet) ->
- log(Log, Type, Packet, Ip, Port),
- udp_send(Sock, Ip, Port, Packet),
- ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]),
- NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}),
- S#state{reqs = NReqs}.
+do_handle_send_pdu(S, #pdu{type = Type} = Pdu, Addresses) ->
+ do_handle_send_pdu(S, Type, Pdu, Addresses);
+do_handle_send_pdu(S, Trap, Addresses) ->
+ do_handle_send_pdu(S, trappdu, Trap, Addresses).
-handle_send_pdu(S, #pdu{type = Type} = Pdu, Addresses) ->
- handle_send_pdu(S, Type, Pdu, Addresses);
-handle_send_pdu(S, Trap, Addresses) ->
- handle_send_pdu(S, trappdu, Trap, Addresses).
-
-handle_send_pdu(S, Type, Pdu, Addresses) ->
- case (catch handle_send_pdu1(S, Type, Addresses)) of
+do_handle_send_pdu(S, Type, Pdu, Addresses) ->
+ try do_handle_send_pdu1(S, Type, Addresses)
+ catch
{Reason, Sz} ->
- error_msg("Cannot send message "
- "~n size: ~p"
- "~n reason: ~p"
- "~n pdu: ~p",
- [Sz, Reason, Pdu]);
- _ ->
- ok
- end.
-
-handle_send_pdu1(#state{log = Log,
- usock = Sock,
- filter = FilterMod}, Type, Addresses) ->
- SendFun =
- fun({snmpUDPDomain, {Ip, Port}, Packet})
- when is_binary(Packet) ->
- ?vdebug("[snmpUDPDomain] sending packet:"
- "~n size: ~p"
- "~n to: ~p:~p",
- [sz(Packet), Ip, Port]),
- maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
-
- ({snmpUDPDomain, {Ip, Port}, {Packet, _LogData}})
- when is_binary(Packet) ->
- ?vdebug("[snmpUDPDomain] sending encrypted packet:"
- "~n size: ~p"
- "~n to: ~p:~p",
- [sz(Packet), Ip, Port]),
- maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
-
- ({transportDomainUdpIpv4, {Ip, Port}, Packet})
- when is_binary(Packet) ->
- ?vdebug("[transportDomainUdpIpv4] sending packet:"
- "~n size: ~p"
- "~n to: ~p:~p",
- [sz(Packet), Ip, Port]),
- maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
-
- ({transportDomainUdpIpv4, {Ip, Port}, {Packet, _LogData}})
- when is_binary(Packet) ->
- ?vdebug("[transportDomainUdpIpv4] sending encrypted packet:"
- "~n size: ~p"
- "~n to: ~p:~p",
- [sz(Packet), Ip, Port]),
- maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
-
- ({transportDomainUdpIpv6, {Ip, Port}, Packet})
- when is_binary(Packet) ->
- ?vdebug("[transportDomainUdpIpv6] sending packet:"
- "~n size: ~p"
- "~n to: ~p:~p",
- [sz(Packet), Ip, Port]),
- maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
-
- ({transportDomainUdpIpv6, {Ip, Port}, {Packet, _LogData}})
- when is_binary(Packet) ->
- ?vdebug("[transportDomainUdpIpv6] sending encrypted packet:"
- "~n size: ~p"
- "~n to: ~p:~p",
- [sz(Packet), Ip, Port]),
- maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
-
- (_X) ->
- ?vlog("** bad res: ~p", [_X]),
- ok
- end,
- lists:foreach(SendFun, Addresses).
-
-
-handle_response(Vsn, Pdu, From, S) ->
- case lists:keysearch(Pdu#pdu.request_id, 1, S#state.reqs) of
- {value, {_, Pid}} ->
- ?vdebug("handle_response -> "
- "~n send response to receiver ~p", [Pid]),
- Pid ! {snmp_response_received, Vsn, Pdu, From};
- _ ->
- ?vdebug("handle_response -> "
- "~n No receiver available for response pdu", [])
+ error_msg(
+ "Can not send message~n"
+ " size: ~p~n"
+ " reason: ~p~n"
+ " pdu: ~p",
+ [Sz, Reason, Pdu])
end.
-maybe_udp_send(FilterMod, Sock, Ip, Port, Packet) ->
- case (catch FilterMod:accept_send(Ip, Port)) of
+do_handle_send_pdu1(
+ #state{transports = Transports} = S,
+ Type, Addresses) ->
+ lists:foreach(
+ fun ({Domain, Address, Packet}) when is_binary(Packet) ->
+ ?vdebug(
+ "[~w] sending packet:~n"
+ " size: ~p~n"
+ " to: ~p", [Domain, sz(Packet), Address]),
+ To = {Domain, Address},
+ case select_transport_from_domain(Domain, Transports) of
+ false ->
+ error_msg(
+ "Can not find transport~n"
+ " size: ~p~n"
+ " to: ~s",
+ [sz(Packet), format_address(To)]);
+ Transport ->
+ maybe_udp_send(S, Transport, To, Packet)
+ end;
+ ({Domain, Address, {Packet, LogData}}) when is_binary(Packet) ->
+ ?vdebug(
+ "[~w] sending encrypted packet:~n"
+ " size: ~p~n"
+ " to: ~p", [Domain, sz(Packet), Address]),
+ To = {Domain, Address},
+ case select_transport_from_domain(Domain, Transports) of
+ false ->
+ error_msg(
+ "Can not find transport~n"
+ " size: ~p~n"
+ " to: ~s",
+ [sz(Packet), format_address(To)]);
+ Transport ->
+ maybe_udp_send(S, Transport, To, Packet, Type, LogData)
+ end
+ end,
+ Addresses).
+
+maybe_udp_send(
+ #state{filter = FilterMod, transports = Transports},
+ #transport{socket = Socket},
+ To, Packet) ->
+ {To_1, To_2} = fix_filter_address(Transports, To),
+ case
+ try FilterMod:accept_send(To_1, To_2)
+ catch
+ Class:Exception ->
+ error_msg(
+ "FilterMod:accept_send(~p, ~p) crashed: ~w:~w~n ~p",
+ [To_1,To_2,Class,Exception,erlang:get_stacktrace()]),
+ true
+ end
+ of
false ->
inc(netIfMsgOutDrops),
ok;
- _ ->
- (catch udp_send(Sock, Ip, Port, Packet))
+ Other ->
+ case Other of
+ true ->
+ ok;
+ _ ->
+ error_msg(
+ "FilterMod:accept_send(~p, ~p) returned: ~p",
+ [To_1,To_2,Other])
+ end,
+ udp_send(Socket, To, Packet)
end.
-maybe_udp_send(FilterMod, AtLog, Type, Sock, Ip, Port, Packet) ->
- case (catch FilterMod:accept_send(Ip, Port)) of
+maybe_udp_send(
+ #state{log = Log, filter = FilterMod, transports = Transports},
+ #transport{socket = Socket},
+ To, Packet, Type, _LogData) ->
+ {To_1, To_2} = fix_filter_address(Transports, To),
+ case
+ try FilterMod:accept_send(To_1, To_2)
+ catch
+ Class:Exception ->
+ error_msg(
+ "FilterMod:accept_send(~p, ~p) crashed for: ~w:~w~n ~p",
+ [To_1, To_2, Class, Exception, erlang:get_stacktrace()]),
+ true
+ end
+ of
false ->
inc(netIfMsgOutDrops),
ok;
- _ ->
- log(AtLog, Type, Packet, Ip, Port),
- (catch udp_send(Sock, Ip, Port, Packet))
+ Other ->
+ case Other of
+ true ->
+ ok;
+ _ ->
+ error_msg(
+ "FilterMod:accept_send(~p, ~p) returned: ~p",
+ [To_1,To_2,Other])
+ end,
+ log(Log, Type, Packet, To),
+ udp_send(Socket, To, Packet)
end.
-
-udp_send(UdpId, AgentIp, UdpPort, B) ->
- case (catch gen_udp:send(UdpId, AgentIp, UdpPort, B)) of
+udp_send(Socket, To, B) ->
+ {IpAddr, IpPort} =
+ case To of
+ {Domain, Addr} when is_atom(Domain) ->
+ Addr;
+ {_, P} = Addr when is_integer(P) ->
+ Addr
+ end,
+ try gen_udp:send(Socket, IpAddr, IpPort, B) of
{error, emsgsize} ->
%% From this message we cannot recover, so exit sending loop
throw({emsgsize, sz(B)});
{error, ErrorReason} ->
error_msg("[error] cannot send message "
"(destination: ~p:~p, size: ~p, reason: ~p)",
- [AgentIp, UdpPort, sz(B), ErrorReason]);
- {'EXIT', ExitReason} ->
- error_msg("[exit] cannot send message "
- "(destination: ~p:~p, size: ~p, reason: ~p)",
- [AgentIp, UdpPort, sz(B), ExitReason]);
- _ ->
+ [IpAddr, IpPort, sz(B), ErrorReason]);
+ ok ->
ok
+ catch
+ error:ExitReason ->
+ error_msg("[exit] cannot send message "
+ "(destination: ~p:~p, size: ~p, reason: ~p, at: ~p)",
+ [IpAddr, IpPort, sz(B), ExitReason,
+ erlang:get_stacktrace()])
end.
sz(L) when is_list(L) -> length(L);
@@ -957,6 +1221,75 @@ active_once(Sock) ->
inet:setopts(Sock, [{active, once}]).
+select_transport_from_req_ref(_, []) ->
+ false;
+select_transport_from_req_ref(
+ ReqRef,
+ [#transport{req_refs = ReqRefs} = Transport | Transports]) ->
+ case lists:member(ReqRef, ReqRefs) of
+ true ->
+ Transport;
+ false ->
+ select_transport_from_req_ref(ReqRef, Transports)
+ end.
+
+select_transport_from_domain(Domain, Transports) when is_atom(Domain) ->
+ Pos = #transport.domain,
+ case lists:keyfind(Domain, Pos, Transports) of
+ #transport{domain = Domain} = Transport ->
+ Transport;
+ false when Domain == snmpUDPDomain ->
+ lists:keyfind(transportDomainUdpIpv4, Pos, Transports);
+ false when Domain == transportDomainUdpIpv4 ->
+ lists:keyfind(snmpUDPDomain, Pos, Transports);
+ false ->
+ false
+ end.
+
+address_to_domain({Domain, _Addr}) when is_atom(Domain) ->
+ Domain;
+address_to_domain({_Ip, Port}) when is_integer(Port) ->
+ snmpUDPDomain.
+
+%% If the agent uses legacy snmpUDPDomain e.g has not set
+%% intAgentTransportDomain, then make sure
+%% snmpa_network_interface_filter gets legacy arguments
+%% to not break backwards compatibility.
+%%
+fix_filter_address(Transports, Address) ->
+ case is_legacy_transports(Transports) of
+ true ->
+ case Address of
+ {Domain, Addr} when is_atom(Domain) ->
+ Addr;
+ {_, IpPort} = Addr when is_integer(IpPort) ->
+ Addr
+ end;
+ false ->
+ Address
+ end.
+
+is_legacy_transports([#transport{domain = snmpUDPDomain}]) ->
+ true;
+is_legacy_transports([#transport{} | _]) ->
+ false.
+
+fix_filter_legacy_mpd_address(Domain_Address_SecData) ->
+ case Domain_Address_SecData of
+ {{Domain, Addr}, _SecData} when is_atom(Domain) -> % v3
+ Addr;
+ {Domain, Addr} when is_atom(Domain) -> % v1 & v2
+ Addr
+ end.
+
+fix_filter_mpd_address(Domain_Address_SecData) ->
+ case Domain_Address_SecData of
+ {{Domain, _Addr} = Address, _SecData} when is_atom(Domain) -> % v3
+ Address;
+ {Domain, _Addr} = Address when is_atom(Domain) -> % v1 & v2
+ Address
+ end.
+
%%%-----------------------------------------------------------------
handle_set_log_type(#state{log = {Log, OldValue}} = State, NewType)
@@ -1113,37 +1446,39 @@ get_counters([Counter|Counters], Acc) ->
%% ----------------------------------------------------------------
-ip_opt_bind_to_ip_address(Opts, Ip) ->
- case get_bind_to_ip_address(Opts) of
- true ->
- [{ip, list_to_tuple(Ip)}];
- _ ->
- []
- end.
-
-ip_opt_no_reuse_address(Opts) ->
- case get_no_reuse_address(Opts) of
- false ->
- [{reuseaddr, true}];
- _ ->
- []
- end.
-
-ip_opt_recbuf(Opts) ->
- case get_recbuf(Opts) of
- use_default ->
- [];
- Sz ->
- [{recbuf, Sz}]
- end.
-
-ip_opt_sndbuf(Opts) ->
- case get_sndbuf(Opts) of
- use_default ->
- [];
- Sz ->
- [{sndbuf, Sz}]
- end.
+socket_opts(Domain, {IpAddr, IpPort}, Opts) ->
+ [IpPort, % Picked off at socket open, separate argument
+ binary
+ | case snmp_conf:tdomain_to_family(Domain) of
+ inet6 = Family ->
+ [Family, {ipv6_v6only, true}];
+ Family ->
+ [Family]
+ end ++
+ case get_bind_to_ip_address(Opts) of
+ true ->
+ [{ip, IpAddr}];
+ _ ->
+ []
+ end ++
+ case get_no_reuse_address(Opts) of
+ false ->
+ [{reuseaddr, true}];
+ _ ->
+ []
+ end ++
+ case get_recbuf(Opts) of
+ use_default ->
+ [];
+ Sz ->
+ [{recbuf, Sz}]
+ end ++
+ case get_sndbuf(Opts) of
+ use_default ->
+ [];
+ Sz ->
+ [{sndbuf, Sz}]
+ end].
%% ----------------------------------------------------------------
@@ -1203,6 +1538,9 @@ get_bind_to_ip_address(Opts) ->
error_msg(F,A) ->
?snmpa_error("NET-IF server: " ++ F, A).
+info_msg(F,A) ->
+ ?snmpa_info("NET-IF server: " ++ F, A).
+
%% ---
user_err(F, A) ->
@@ -1227,14 +1565,14 @@ call(Pid, Req) ->
%% ----------------------------------------------------------------
-get_info(#state{usock = Id, reqs = Reqs}) ->
+get_info(#state{transports = Transports, reqs = Reqs}) ->
ProcSize = proc_mem(self()),
- PortInfo = get_port_info(Id),
Counters = get_counters(),
- [{reqs, Reqs},
- {counters, Counters},
- {process_memory, ProcSize},
- {port_info, PortInfo}].
+ [{reqs, Reqs},
+ {counters, Counters},
+ {process_memory, ProcSize}
+ | [{port_info, get_port_info(Socket)}
+ || #transport{socket = Socket} <- Transports]].
proc_mem(P) when is_pid(P) ->
case (catch erlang:process_info(P, memory)) of
diff --git a/lib/snmp/src/agent/snmpa_net_if_filter.erl b/lib/snmp/src/agent/snmpa_net_if_filter.erl
index 989f7c95b3..dd77b143d0 100644
--- a/lib/snmp/src/agent/snmpa_net_if_filter.erl
+++ b/lib/snmp/src/agent/snmpa_net_if_filter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,35 +18,49 @@
%%
-module(snmpa_net_if_filter).
--export([accept_recv/2,
- accept_send/2,
- accept_recv_pdu/3,
- accept_send_pdu/2]).
+%% Behaviour
+-export([accept_recv/2, accept_send/2, accept_recv_pdu/3, accept_send_pdu/2]).
-include("snmp_debug.hrl").
-accept_recv(_Addr, _Port) ->
- ?d("accept_recv -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p", [_Addr, _Port]),
+accept_recv(Domain, _Address) when is_atom(Domain) ->
+ ?d("accept_recv -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p", [Domain, _Address]),
+ true;
+accept_recv(_Addr, Port) when is_integer(Port) ->
+ ?d("accept_recv -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p", [_Addr, Port]),
true.
-accept_send(_Addr, _Port) ->
- ?d("accept_send -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p", [_Addr, _Port]),
+accept_send(Domain, _Address) when is_atom(Domain) ->
+ ?d("accept_send -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p", [Domain, _Address]),
+ true;
+accept_send(_Addr, Port) when is_integer(Port) ->
+ ?d("accept_send -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p", [_Addr, Port]),
true.
-accept_recv_pdu(_Addr, _Port, _PduType) ->
- ?d("accept_recv_pdu -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n PduType: ~p", [_Addr, _Port, _PduType]),
+accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) ->
+ ?d("accept_recv -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p~n"
+ " PduType: ~p", [Domain, _Address, _PduType]),
+ true;
+accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) ->
+ ?d("accept_recv_pdu -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p~n"
+ " PduType: ~p", [_Addr, Port, _PduType]),
true.
accept_send_pdu(_Targets, _PduType) ->
- ?d("accept_send_pdu -> entry with"
- "~n Targets: ~p"
- "~n PduType: ~p", [_Targets, _PduType]),
+ ?d("accept_send_pdu -> entry with~n"
+ " Targets: ~p~n"
+ " PduType: ~p", [_Targets, _PduType]),
true.
diff --git a/lib/snmp/src/agent/snmpa_network_interface_filter.erl b/lib/snmp/src/agent/snmpa_network_interface_filter.erl
index 6fa131beee..90aa54a271 100644
--- a/lib/snmp/src/agent/snmpa_network_interface_filter.erl
+++ b/lib/snmp/src/agent/snmpa_network_interface_filter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,7 @@
behaviour_info(callbacks) ->
- [{accept_recv, 2},
+ [{accept_recv, 2},
{accept_send, 2},
{accept_recv_pdu, 3},
{accept_send_pdu, 2}];
@@ -31,20 +31,21 @@ behaviour_info(_) ->
undefined.
-%% accept_recv(address(), port()) -> boolean()
+%% accept_recv({domain(), address()}) -> boolean()
%% Called at the receiption of a message
%% (before *any* processing has been done).
%%
-%% accept_send(address(), port()) -> boolean()
+%% accept_send({domain(), address()}) -> boolean()
%% Called before the sending of a message
%% (after *all* processing has been done).
%%
-%% accept_recv_pdu(Addr, Port, pdu_type()) -> boolean()
+%% accept_recv_pdu({domain(), address()}, pdu_type()) -> boolean()
%% Called after the basic message processing (MPD) has been done,
%% but before the pdu is handed over to the master-agent for
%% primary processing.
%%
-%% accept_send_pdu(Targets, pdu_type()) -> boolean() | NewTargets
+%% accept_send_pdu([{domain(), address()}, ...] = Targets, pdu_type()) ->
+%% boolean() | NewTargets
%% Called before the basic message processing (MPD) is done,
%% when a pdu has been received from the master-agent.
%%
diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index b9a2496341..a79b150f57 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -270,12 +270,13 @@ localise_type({VariableOid, Value}, Mib) when is_list(VariableOid) ->
localise_type(X, _) -> X.
%%-----------------------------------------------------------------
-%% Func: make_v1_trap_pdu/4
+%% Func: make_v1_trap_pdu/5
%% Args: Enterprise = oid()
%% Specific = integer()
%% Varbinds is as returned from initiate_vars
%% (but only {Oid, Type[, Value} permitted)
%% SysUpTime = integer()
+%% AgentIp = {A, B, C, D}
%% Purpose: Make a #trappdu
%% Checks the Varbinds to see that no symbolic names are
%% present, and that each var has a type. Performs a get
@@ -284,7 +285,7 @@ localise_type(X, _) -> X.
%% Fails: yes
%% NOTE: Executed at the MA
%%-----------------------------------------------------------------
-make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) ->
+make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime, AgentIp) ->
{Enterp,Generic,Spec} =
case Enterprise of
?snmp ->
@@ -292,7 +293,6 @@ make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) ->
_ ->
{Enterprise,?enterpriseSpecific,Specific}
end,
- {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get),
#trappdu{enterprise = Enterp,
agent_addr = AgentIp,
generic_trap = Generic,
@@ -369,6 +369,7 @@ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID,
{tag, T},
{err, E},
{stacktrace, erlang:get_stacktrace()}],
+ ?vlog("snmpa_trap:send_trap exception: ~p", [Info]),
{error, {failed_sending_trap, Info}}
end.
@@ -789,23 +790,19 @@ send_trap_pdus([], ContextName, {TrapRec, Vbs},
send_v1_trap(_TrapRec, [], _Vbs, _ExtraInfo, _NetIf, _SysUpTime) ->
ok;
-send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec},
- V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) ->
+send_v1_trap(
+ #trap{enterpriseoid = Enter, specificcode = Spec},
+ V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) ->
?vdebug("prepare to send v1 trap "
"~n '~p'"
"~n with"
"~n ~p"
"~n to"
"~n ~p", [Enter, Spec, V1Res]),
- TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime),
- AddrCommunities = mk_addr_communities(V1Res),
- lists:foreach(fun({Community, Addrs}) ->
- ?vtrace("send v1 trap pdu to ~p",[Addrs]),
- NetIf ! {send_pdu, 'version-1', TrapPdu,
- {community, Community}, Addrs, ExtraInfo}
- end, AddrCommunities);
-send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf,
- SysUpTime) ->
+ do_send_v1_trap(Enter, Spec, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime);
+send_v1_trap(
+ #notification{oid = Oid},
+ V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) ->
%% Use alg. in rfc2089 to map a v2 trap to a v1 trap
% delete Counter64 objects from vbs
?vdebug("prepare to send v1 trap '~p'",[Oid]),
@@ -822,14 +819,38 @@ send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf,
{lists:reverse(First),Last}
end
end,
- TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime),
+ do_send_v1_trap(Enter, Spec, V1Res, NVbs, ExtraInfo, NetIf, SysUpTime).
+
+do_send_v1_trap(Enter, Spec, V1Res, NVbs, ExtraInfo, NetIf, SysUpTime) ->
+ {value, Transports} = snmp_framework_mib:intAgentTransports(get),
+ {_Domain, {AgentIp, _AgentPort}} =
+ case lists:keyfind(snmpUDPDomain, 1, Transports) of
+ false ->
+ case lists:keyfind(transportDomainUdpIpv4, 1, Transports) of
+ false ->
+ ?vtrace(
+ "snmpa_trap: can not send v1 trap "
+ "without IPv4 domain: ~p",
+ [Transports]),
+ user_err(
+ "snmpa_trap: can not send v1 trap "
+ "without IPv4 domain: ~p",
+ [Transports]);
+ DomainAddr ->
+ DomainAddr
+ end;
+ DomainAddr ->
+ DomainAddr
+ end,
+ TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp),
AddrCommunities = mk_addr_communities(V1Res),
- lists:foreach(fun({Community, Addrs}) ->
- ?vtrace("send v1 trap to ~p",[Addrs]),
- NetIf ! {send_pdu, 'version-1', TrapPdu,
- {community, Community}, Addrs, ExtraInfo}
- end, AddrCommunities).
-
+ lists:foreach(
+ fun ({Community, Addrs}) ->
+ ?vtrace("send v1 trap to ~p",[Addrs]),
+ NetIf ! {send_pdu, 'version-1', TrapPdu,
+ {community, Community}, Addrs, ExtraInfo}
+ end, AddrCommunities).
+
send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) ->
ok;
send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime) ->
@@ -1045,7 +1066,7 @@ deliver_recv(#snmpa_notification_delivery_info{tag = Tag,
"~n DeliveryResult: ~p"
"~n TAddr: ~p"
"", [Tag, Mod, Extra, DeliveryResult, TAddr]),
- Addr = transform_taddr(TAddr),
+ [Addr] = transform_taddrs([TAddr]),
(catch Mod:delivery_info(Tag, Addr, DeliveryResult, Extra));
deliver_recv({Tag, Receiver}, MsgId, Result) ->
?vtrace("deliver_recv -> entry with"
@@ -1072,35 +1093,90 @@ deliver_recv(Else, _MsgId, _Result) ->
[Else]),
user_err("snmpa: bad receiver, ~w\n", [Else]).
-transform_taddrs(Addrs) ->
- [transform_taddr(Addr) || Addr <- Addrs].
+transform_taddrs(TAddrs) ->
+ UseTDomain =
+ case snmp_framework_mib:intAgentTransportDomain(get) of
+ {value,snmpUDPDomain} ->
+ false;
+ {value,_} ->
+ true;
+ genErr ->
+ false
+ end,
+ DomAddrs = [transform_taddr(TAddr) || TAddr <- TAddrs],
+ case UseTDomain of
+ true ->
+ DomAddrs;
+ false ->
+ [Addr || {_Domain, Addr} <- DomAddrs]
+ end.
-transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2
- Addr = {A1, A2, A3, A4},
- Port = P1 bsl 8 + P2,
- {Addr, Port};
-transform_taddr({?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}) -> % v2
- Addr = {A1, A2, A3, A4},
+%% v2
+transform_taddr({?snmpUDPDomain, Addr}) ->
+ transform_taddr(transportDomainIdpIpv4, Addr);
+transform_taddr({?transportDomainUdpIpv4, Addr}) ->
+ transform_taddr(transportDomainUdpIpv4, Addr);
+transform_taddr({?transportDomainUdpIpv6, Addr}) ->
+ transform_taddr(transportDomainUdpIpv6, Addr);
+%% v3
+transform_taddr({{?snmpUDPDomain, Addr}, _MsgData}) ->
+ transform_taddr(transportDomainUdpIpv4, Addr);
+transform_taddr({{?transportDomainUdpIpv4, Addr}, _MsgData}) ->
+ transform_taddr(transportDomainUdpIpv4, Addr);
+transform_taddr({{?transportDomainUdpIpv6, Addr}, _MsgData}) ->
+ transform_taddr(transportDomainUdpIpv6, Addr).
+
+transform_taddr(
+ transportDomainUdpIpv4 = Domain,
+ [A1,A2,A3,A4,P1,P2]) ->
+ Ip = {A1, A2, A3, A4},
Port = P1 bsl 8 + P2,
- {Addr, Port};
-transform_taddr({?transportDomainUdpIpv6,
- [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}) -> % v2
- Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+ {Domain, {Ip, Port}};
+transform_taddr(
+ transportDomainUdpIpv6 = Domain,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) ->
+ Ip = {A1, A2, A3, A4, A5, A6, A7, A8},
Port = P1 bsl 8 + P2,
- {Addr, Port};
-transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3
- Addr = {A1, A2, A3, A4},
+ {Domain, {Ip, Port}};
+transform_taddr(
+ transportDomainUdpIpv6 = Domain,
+ [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16,
+ P1, P2]) ->
+ Ip =
+ {(A1 bsl 8) bor A2, (A3 bsl 8) bor A4,
+ (A5 bsl 8) bor A6, (A7 bsl 8) bor A8,
+ (A9 bsl 8) bor A10, (A11 bsl 8) bor A12,
+ (A13 bsl 8) bor A14, (A15 bsl 8) bor A16},
Port = P1 bsl 8 + P2,
- {Addr, Port};
-transform_taddr({{?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3
- Addr = {A1, A2, A3, A4},
- Port = P1 bsl 8 + P2,
- {Addr, Port};
-transform_taddr({{?transportDomainUdpIpv6,
- [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}, _MsgData}) -> % v3
- Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
- Port = P1 bsl 8 + P2,
- {Addr, Port}.
+ {Domain, {Ip, Port}}.
+
+%% transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2
+%% Addr = {A1, A2, A3, A4},
+%% Port = P1 bsl 8 + P2,
+%% {Addr, Port};
+%% transform_taddr({?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}) -> % v2
+%% Addr = {A1, A2, A3, A4},
+%% Port = P1 bsl 8 + P2,
+%% {Addr, Port};
+%% transform_taddr({?transportDomainUdpIpv6,
+%% [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}) -> % v2
+%% Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+%% Port = P1 bsl 8 + P2,
+%% {Addr, Port};
+%% transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3
+%% Addr = {A1, A2, A3, A4},
+%% Port = P1 bsl 8 + P2,
+%% {Addr, Port};
+%% transform_taddr({{?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3
+%% Addr = {A1, A2, A3, A4},
+%% Port = P1 bsl 8 + P2,
+%% {Addr, Port};
+%% transform_taddr({{?transportDomainUdpIpv6,
+%% [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}, _MsgData}) -> % v3
+%% Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+%% Port = P1 bsl 8 + P2,
+%% {Addr, Port}.
+
check_all_varbinds(#notification{oid = Oid}, Vbs, MibView) ->
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index babc33e6a5..ae79e3c1d1 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -28,6 +28,8 @@
%% {update, snmpa_local_db, soft, soft_purge, soft_purge, []}
%% {add_module, snmpm_net_if_mt}
[
+ {"4.25.1", [{restart_application, snmp}]},
+ {"4.25.0.1", [{restart_application, snmp}]},
{"4.25", [{restart_application, snmp}]},
{"4.24.2", [{restart_application, snmp}]},
{"4.24.1", [{restart_application, snmp}]},
@@ -40,6 +42,8 @@
%% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
[
+ {"4.25.1", [{restart_application, snmp}]},
+ {"4.25.0.1", [{restart_application, snmp}]},
{"4.25", [{restart_application, snmp}]},
{"4.24.2", [{restart_application, snmp}]},
{"4.24.1", [{restart_application, snmp}]},
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index c97b635fc6..8976322c4e 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -379,21 +379,33 @@ register_agent(UserId, Addr) ->
register_agent(UserId, Addr, ?DEFAULT_AGENT_PORT, []).
%% Backward compatibility
-register_agent(UserId, Addr, Port, Config0) ->
+register_agent(UserId, Domain, Addr, Config0) when is_atom(Domain) ->
case lists:keymember(target_name, 1, Config0) of
false ->
- TargetName = mk_target_name(Addr, Port, Config0),
- Config = [{reg_type, addr_port},
- {address, Addr}, {port, Port} | Config0],
+ TargetName = mk_target_name(Domain, Addr, Config0),
+ Config =
+ [{reg_type, addr_port},
+ {tdomain, Domain}, {taddress, Addr} | Config0],
do_register_agent(UserId, TargetName, ensure_engine_id(Config));
true ->
{value, {_, TargetName}} =
lists:keysearch(target_name, 1, Config0),
Config1 = lists:keydelete(target_name, 1, Config0),
- Config2 = [{reg_type, addr_port},
- {address, Addr}, {port, Port} | Config1],
+ Config2 =
+ [{reg_type, addr_port},
+ {tdomain, Domain}, {taddress, Addr} | Config1],
register_agent(UserId, TargetName, ensure_engine_id(Config2))
- end.
+ end;
+register_agent(UserId, Ip, Port, Config) when is_integer(Port) ->
+ Domain = snmpm_config:default_transport_domain(),
+ Addr =
+ case snmp_conf:check_address(Domain, {Ip, Port}) of
+ ok ->
+ {Ip, Port};
+ {ok, FixedAddr} ->
+ FixedAddr
+ end,
+ register_agent(UserId, Domain, Addr, Config).
unregister_agent(UserId, TargetName) when is_list(TargetName) ->
snmpm_config:unregister_agent(UserId, TargetName);
@@ -402,8 +414,8 @@ unregister_agent(UserId, TargetName) when is_list(TargetName) ->
unregister_agent(UserId, Addr) ->
unregister_agent(UserId, Addr, ?DEFAULT_AGENT_PORT).
-unregister_agent(UserId, Addr, Port) ->
- case target_name(Addr, Port) of
+unregister_agent(UserId, DomainIp, AddressPort) ->
+ case target_name(DomainIp, AddressPort) of
{ok, TargetName} ->
unregister_agent(UserId, TargetName);
Error ->
@@ -1264,14 +1276,17 @@ format_vb_value(Prefix, _Type, Val) ->
%% --- Internal utility functions ---
%%
-target_name(Addr) ->
- target_name(Addr, ?DEFAULT_AGENT_PORT).
+target_name(Ip) ->
+ target_name(Ip, ?DEFAULT_AGENT_PORT).
-target_name(Addr, Port) ->
- snmpm_config:agent_info(Addr, Port, target_name).
+target_name(DomainIp, AddressPort) ->
+ snmpm_config:agent_info(DomainIp, AddressPort, target_name).
mk_target_name(Addr, Port, Config) ->
- snmpm_config:mk_target_name(Addr, Port, Config).
+ R = snmpm_config:mk_target_name(Addr, Port, Config),
+ p(?MODULE_STRING":mk_target_name(~p, ~p, ~p) -> ~p.~n",
+ [Addr, Port, Config, R]),
+ R.
ensure_engine_id(Config) ->
case lists:keymember(engine_id, 1, Config) of
@@ -1287,5 +1302,5 @@ ensure_engine_id(Config) ->
%% p(F) ->
%% p(F, []).
-%% p(F, A) ->
-%% io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
+p(F, A) ->
+ io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl
index 5e2d9fdbf6..888f19aec6 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-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -78,43 +78,26 @@ write_manager_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_manager_config(Dir, Hdr, Conf).
-write_manager_config(Dir, Hdr, Conf)
- when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) ->
- Verify = fun() -> verify_manager_conf(Conf) end,
- Write = fun(Fid) -> write_manager_conf(Fid, Hdr, Conf) end,
- write_config_file(Dir, ?MANAGER_CONF_FILE, Verify, Write).
-
+write_manager_config(Dir, Hdr, Conf)
+ when is_list(Dir), is_list(Hdr), is_list(Conf) ->
+ Order = fun snmpm_config:order_manager_config/2,
+ Check = fun snmpm_config:check_manager_config/2,
+ Write = fun (Fd, Entries) -> write_manager_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, ?MANAGER_CONF_FILE, Order, Check, Write, Conf).
append_manager_config(Dir, Conf)
- when is_list(Dir) andalso is_list(Conf) ->
- Verify = fun() -> verify_manager_conf(Conf) end,
- Write = fun(Fid) -> write_manager_conf(Fid, Conf) end,
- append_config_file(Dir, ?MANAGER_CONF_FILE, Verify, Write).
-
+ when is_list(Dir), is_list(Conf) ->
+ Order = fun snmpm_config:order_manager_config/2,
+ Check = fun snmpm_config:check_manager_config/2,
+ Write = fun write_manager_conf/2,
+ append_config_file(Dir, ?MANAGER_CONF_FILE, Order, Check, Write, Conf).
-read_manager_config(Dir) ->
- Verify = fun(Entry) -> verify_manager_conf_entry(Entry) end,
- read_config_file(Dir, ?MANAGER_CONF_FILE, Verify).
+read_manager_config(Dir) when is_list(Dir) ->
+ Order = fun snmpm_config:order_manager_config/2,
+ Check = fun snmpm_config:check_manager_config/2,
+ read_config_file(Dir, ?MANAGER_CONF_FILE, Order, Check).
-verify_manager_conf([]) ->
- ok;
-verify_manager_conf([H|T]) ->
- verify_manager_conf_entry(H),
- verify_manager_conf(T);
-verify_manager_conf(X) ->
- error({bad_manager_config, X}).
-
-verify_manager_conf_entry(Entry) ->
- case snmpm_config:check_manager_config(Entry) of
- ok ->
- ok;
-%% {ok, _} ->
-%% ok;
- Error ->
- throw(Error)
- end.
-
write_manager_conf(Fd, "", Conf) ->
write_manager_conf(Fd, Conf);
write_manager_conf(Fd, Hdr, Conf) ->
@@ -127,14 +110,15 @@ write_manager_conf(Fd, [H|T]) ->
do_write_manager_conf(Fd, H),
write_manager_conf(Fd, T).
-do_write_manager_conf(Fd, {address = Tag, Val}) ->
- io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
-do_write_manager_conf(Fd, {port = Tag, Val} ) ->
+do_write_manager_conf(Fd, {Tag, Val})
+ when Tag =:= domain;
+ Tag =:= address;
+ Tag =:= port;
+ Tag =:= max_message_size ->
io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
-do_write_manager_conf(Fd, {engine_id = Tag, Val} ) ->
+do_write_manager_conf(Fd, {Tag, Val})
+ when Tag =:= engine_id ->
io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]);
-do_write_manager_conf(Fd, {max_message_size = Tag, Val} ) ->
- io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
do_write_manager_conf(_Fd, Crap) ->
error({bad_manager_config, Crap}).
@@ -167,36 +151,29 @@ write_users_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_users_config(Dir, Hdr, Conf).
-write_users_config(Dir, Hdr, Conf)
+write_users_config(Dir, Hdr, Conf)
when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) ->
- Verify = fun() -> verify_users_conf(Conf) end,
- Write = fun(Fd) -> write_users_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, ?USERS_CONF_FILE, Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_user_config/2,
+ Write = fun (Fd, Entries) -> write_users_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, ?USERS_CONF_FILE, Order, Check, Write, Conf).
-append_users_config(Dir, Conf)
+append_users_config(Dir, Conf)
when is_list(Dir) andalso is_list(Conf) ->
- Verify = fun() -> verify_users_conf(Conf) end,
- Write = fun(Fd) -> write_users_conf(Fd, Conf) end,
- append_config_file(Dir, ?USERS_CONF_FILE, Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_user_config/2,
+ Write = fun write_users_conf/2,
+ append_config_file(Dir, ?USERS_CONF_FILE, Order, Check, Write, Conf).
read_users_config(Dir) when is_list(Dir) ->
- Verify = fun(Entry) -> verify_users_conf_entry(Entry) end,
- read_config_file(Dir, ?USERS_CONF_FILE, Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_user_config/2,
+ read_config_file(Dir, ?USERS_CONF_FILE, Order, Check).
-
-verify_users_conf([]) ->
- ok;
-verify_users_conf([H|T]) ->
- verify_users_conf_entry(H),
- verify_users_conf(T);
-verify_users_conf(X) ->
- error({bad_users_conf, X}).
-
-verify_users_conf_entry(Entry) ->
- {ok, _} = snmpm_config:check_user_config(Entry),
- ok.
+
+check_user_config(Entry, State) ->
+ {check_ok(snmpm_config:check_user_config(Entry)),
+ State}.
write_users_conf(Fd, "", Conf) ->
write_users_conf(Fd, Conf);
@@ -239,36 +216,29 @@ write_agents_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_agents_config(Dir, Hdr, Conf).
-write_agents_config(Dir, Hdr, Conf)
+write_agents_config(Dir, Hdr, Conf)
when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) ->
- Verify = fun() -> verify_agents_conf(Conf) end,
- Write = fun(Fd) -> write_agents_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, ?AGENTS_CONF_FILE, Verify, Write).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_agent_config/2,
+ Write = fun (Fd, Entries) -> write_agents_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, ?AGENTS_CONF_FILE, Order, Check, Write, Conf).
-
-append_agents_config(Dir, Conf)
+append_agents_config(Dir, Conf)
when is_list(Dir) andalso is_list(Conf) ->
- Verify = fun() -> verify_agents_conf(Conf) end,
- Write = fun(Fd) -> write_agents_conf(Fd, Conf) end,
- append_config_file(Dir, ?AGENTS_CONF_FILE, Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_agent_config/2,
+ Write = fun write_agents_conf/2,
+ append_config_file(Dir, ?AGENTS_CONF_FILE, Order, Check, Write, Conf).
read_agents_config(Dir) ->
- Verify = fun(Entry) -> verify_agents_conf_entry(Entry) end,
- read_config_file(Dir, ?AGENTS_CONF_FILE, Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_agent_config/2,
+ read_config_file(Dir, ?AGENTS_CONF_FILE, Order, Check).
-verify_agents_conf([]) ->
- ok;
-verify_agents_conf([H|T]) ->
- verify_agents_conf_entry(H),
- verify_agents_conf(T);
-verify_agents_conf(X) ->
- error({bad_agents_config, X}).
-
-verify_agents_conf_entry(Entry) ->
- {ok, _} = snmpm_config:check_agent_config(Entry),
- ok.
+check_agent_config(Entry, State) ->
+ {check_ok(snmpm_config:check_agent_config(Entry)),
+ State}.
write_agents_conf(Fd, "", Conf) ->
write_agents_conf(Fd, Conf);
@@ -282,13 +252,15 @@ write_agents_conf(Fd, [H|T]) ->
do_write_agents_conf(Fd, H),
write_agents_conf(Fd, T).
-do_write_agents_conf(Fd,
- {UserId,
- TargetName, Comm, Ip, Port, EngineID,
- Timeout, MaxMessageSize, Version,
- SecModel, SecName, SecLevel} = _A) ->
- io:format(Fd,
- "{~w, \"~s\", \"~s\", ~w, ~w, \"~s\", ~w, ~w, ~w, ~w, \"~s\", ~w}.~n", [UserId, TargetName, Comm, Ip, Port, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel]);
+do_write_agents_conf(
+ Fd,
+ {UserId, TargetName, Comm, Ip, Port, EngineID,
+ Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel} = _A) ->
+ io:format(
+ Fd,
+ "{~w, \"~s\", \"~s\", ~w, ~w, \"~s\", ~w, ~w, ~w, ~w, \"~s\", ~w}.~n",
+ [UserId, TargetName, Comm, Ip, Port, EngineID,
+ Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel]);
do_write_agents_conf(_Fd, Crap) ->
error({bad_agents_config, Crap}).
@@ -314,37 +286,30 @@ write_usm_config(Dir, Conf) ->
Hdr = header() ++ Comment,
write_usm_config(Dir, Hdr, Conf).
-write_usm_config(Dir, Hdr, Conf)
+write_usm_config(Dir, Hdr, Conf)
when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) ->
- Verify = fun() -> verify_usm_conf(Conf) end,
- Write = fun(Fd) -> write_usm_conf(Fd, Hdr, Conf) end,
- write_config_file(Dir, ?USM_USERS_CONF_FILE, Verify, Write).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_usm_user_config/2,
+ Write = fun (Fd, Entries) -> write_usm_conf(Fd, Hdr, Entries) end,
+ write_config_file(Dir, ?USM_USERS_CONF_FILE, Order, Check, Write, Conf).
-
-append_usm_config(Dir, Conf)
+append_usm_config(Dir, Conf)
when is_list(Dir) andalso is_list(Conf) ->
- Verify = fun() -> verify_usm_conf(Conf) end,
- Write = fun(Fd) -> write_usm_conf(Fd, Conf) end,
- append_config_file(Dir, ?USM_USERS_CONF_FILE, Verify, Write).
-
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_usm_user_config/2,
+ Write = fun write_usm_conf/2,
+ append_config_file(Dir, ?USM_USERS_CONF_FILE, Order, Check, Write, Conf).
read_usm_config(Dir)
when is_list(Dir) ->
- Verify = fun(Entry) -> verify_usm_conf_entry(Entry) end,
- read_config_file(Dir, ?USM_USERS_CONF_FILE, Verify).
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_usm_user_config/2,
+ read_config_file(Dir, ?USM_USERS_CONF_FILE, Order, Check).
-verify_usm_conf([]) ->
- ok;
-verify_usm_conf([H|T]) ->
- verify_usm_conf_entry(H),
- verify_usm_conf(T);
-verify_usm_conf(X) ->
- error({bad_usm_conf, X}).
-
-verify_usm_conf_entry(Entry) ->
- {ok, _} = snmpm_config:check_usm_user_config(Entry),
- ok.
+check_usm_user_config(Entry, State) ->
+ {check_ok(snmpm_config:check_usm_user_config(Entry)),
+ State}.
write_usm_conf(Fd, "", Conf) ->
write_usm_conf(Fd, Conf);
@@ -358,41 +323,49 @@ write_usm_conf(Fd, [H|T]) ->
do_write_usm_conf(Fd, H),
write_usm_conf(Fd, T).
-do_write_usm_conf(Fd,
- {EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey}) ->
- io:format(Fd, "{\"~s\", \"~s\", ~w, ~w, ~w, ~w}.~n",
- [EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey]);
-do_write_usm_conf(Fd,
- {EngineID, UserName, SecName,
- AuthP, AuthKey, PrivP, PrivKey}) ->
- io:format(Fd, "{\"~s\", \"~s\", \"~s\", í~w, ~w, ~w, ~w}.~n",
- [EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey]);
+do_write_usm_conf(
+ Fd,
+ {EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey}) ->
+ io:format(
+ Fd, "{\"~s\", \"~s\", ~w, ~w, ~w, ~w}.~n",
+ [EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey]);
+do_write_usm_conf(
+ Fd,
+ {EngineID, UserName, SecName,
+ AuthP, AuthKey, PrivP, PrivKey}) ->
+ io:format(
+ Fd, "{\"~s\", \"~s\", \"~s\", í~w, ~w, ~w, ~w}.~n",
+ [EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey]);
do_write_usm_conf(_Fd, Crap) ->
error({bad_usm_conf, Crap}).
%% ---- config file wrapper functions ----
-write_config_file(Dir, File, Verify, Write) ->
- snmp_config:write_config_file(Dir, File, Verify, Write).
-
-append_config_file(Dir, File, Verify, Write) ->
- snmp_config:append_config_file(Dir, File, Verify, Write).
+write_config_file(Dir, File, Order, Check, Write, Conf) ->
+ snmp_config:write_config_file(Dir, File, Order, Check, Write, Conf).
-read_config_file(Dir, File, Verify) ->
- snmp_config:read_config_file(Dir, File, Verify).
+append_config_file(Dir, File, Order, Check, Write, Conf) ->
+ snmp_config:append_config_file(Dir, File, Order, Check, Write, Conf).
+read_config_file(Dir, File, Order, Check) ->
+ snmp_config:read_config_file(Dir, File, Order, Check).
%% ---- config file utility functions ----
+check_ok(ok) ->
+ ok;
+check_ok({ok, _}) ->
+ ok.
+
header() ->
{Y,Mo,D} = date(),
{H,Mi,S} = time(),
- io_lib:format("%% This file was generated by "
- "~w (version-~s) ~w-~2.2.0w-~2.2.0w "
- "~2.2.0w:~2.2.0w:~2.2.0w\n",
- [?MODULE, ?version, Y, Mo, D, H, Mi, S]).
-
+ io_lib:format(
+ "%% This file was generated by "
+ "~w (version-~s) ~w-~2.2.0w-~2.2.0w "
+ "~2.2.0w:~2.2.0w:~2.2.0w\n",
+ [?MODULE, ?version, Y, Mo, D, H, Mi, S]).
error(R) ->
throw({error, R}).
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index 2101ad46e1..013fefa4e2 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -103,8 +103,10 @@
get_agent_mp_model/2
]).
--export([check_manager_config/1,
- check_user_config/1,
+-export([
+ order_manager_config/2,
+ check_manager_config/2,
+ check_user_config/1,
check_agent_config/1,
check_usm_user_config/1]).
@@ -165,7 +167,7 @@
%%%-------------------------------------------------------------------
default_transport_domain() ->
- transportDomainUdpIpv4.
+ snmpUDPDomain.
start_link(Opts) ->
@@ -190,7 +192,11 @@ register_user(UserId, UserMod, UserData, DefaultAgentConfig)
when (UserId =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) ->
case (catch verify_user_behaviour(UserMod)) of
ok ->
- Config = default_agent_config(DefaultAgentConfig),
+ {ok, SystemDefaultAgentConfig} = agent_info(),
+ Config =
+ ensure_config(SystemDefaultAgentConfig,
+ DefaultAgentConfig),
+%% Config = default_agent_config(DefaultAgentConfig),
call({register_user, UserId, UserMod, UserData, Config});
Error ->
Error
@@ -201,19 +207,19 @@ register_user(UserId, _UserMod, _UserData, DefaultAgentConfig)
register_user(UserId, _, _, _) ->
{error, {bad_user_id, UserId}}.
-default_agent_config(DefaultAgentConfig) ->
- {ok, SystemDefaultAgentConfig} = agent_info(),
- default_agent_config(SystemDefaultAgentConfig, DefaultAgentConfig).
+%% default_agent_config(DefaultAgentConfig) ->
+%% {ok, SystemDefaultAgentConfig} = agent_info(),
+%% default_agent_config(SystemDefaultAgentConfig, DefaultAgentConfig).
-default_agent_config([], DefaultAgentConfig) ->
- DefaultAgentConfig;
-default_agent_config([{Key, _} = Entry|T], DefaultAgentConfig) ->
- case lists:keysearch(Key, 1, DefaultAgentConfig) of
- {value, _} ->
- default_agent_config(T, DefaultAgentConfig);
- false ->
- default_agent_config(T, [Entry|DefaultAgentConfig])
- end.
+%% default_agent_config([], DefaultAgentConfig) ->
+%% DefaultAgentConfig;
+%% default_agent_config([{Key, _} = Entry|T], DefaultAgentConfig) ->
+%% case lists:keymember(Key, 1, DefaultAgentConfig) of
+%% true ->
+%% default_agent_config(T, DefaultAgentConfig);
+%% false ->
+%% default_agent_config(T, [Entry|DefaultAgentConfig])
+%% end.
verify_user_behaviour(UserMod) ->
@@ -280,9 +286,10 @@ do_user_info(_UserId, BadItem) ->
%% A target-name constructed in this way is a string with the following:
%% <IP-address>:<Port>-<Version>
-%% This is intended for backward compatibility and therefor has
+%% This is intended for backward compatibility and therefore has
%% only support for IPv4 addresses and *no* other transport domain.
-mk_target_name(Addr0, Port, Config) when is_list(Config) ->
+mk_target_name(Domain, Addr, Config)
+ when is_atom(Domain), is_list(Config) ->
Version =
case lists:keysearch(version, 1, Config) of
{value, {_, V}} ->
@@ -290,18 +297,35 @@ mk_target_name(Addr0, Port, Config) when is_list(Config) ->
false ->
select_lowest_supported_version()
end,
- case normalize_address(Addr0) of
- {A, B, C, D} ->
- lists:flatten(
- io_lib:format("~w.~w.~w.~w:~w-~w", [A, B, C, D, Port, Version]));
- [A, B, C, D] ->
+ try
+ lists:flatten(
+ io_lib:format(
+ "~s-~w", [snmp_conf:mk_addr_string({Domain, Addr}), Version]))
+ catch
+ _ ->
lists:flatten(
- io_lib:format("~w.~w.~w.~w:~w-~w", [A, B, C, D, Port, Version]));
- _ ->
+ io_lib:format("~p-~w", [Addr, Version]))
+ end;
+mk_target_name(Ip, Port, Config)
+ when is_integer(Port), is_list(Config) ->
+ Domain = default_transport_domain(),
+ try fix_address(Domain, {Ip, Port}) of
+ Address ->
+ mk_target_name(Domain, Address, Config)
+ catch
+ _ ->
+ Version =
+ case lists:keysearch(version, 1, Config) of
+ {value, {_, V}} ->
+ V;
+ false ->
+ select_lowest_supported_version()
+ end,
lists:flatten(
- io_lib:format("~p:~w-~w", [Addr0, Port, Version]))
+ io_lib:format("~p:~w-~w", [Ip, Port, Version]))
end.
-
+
+
select_lowest_supported_version() ->
{ok, Versions} = system_info(versions),
select_lowest_supported_version([v1, v2, v3], Versions).
@@ -335,27 +359,17 @@ register_agent(UserId, TargetName, Config0)
%% is not present
%% 3) Check that there are no invalid or erroneous configs
%% 4) Check that the manager is capable of using the selected version
- case verify_agent_config(Config0) of
- {ok, Config} ->
- call({register_agent, UserId, TargetName, Config});
- Error ->
- Error
- end.
-
-
-verify_agent_config(Conf0) ->
try
- begin
- verify_mandatory(Conf0, [engine_id, address, reg_type]),
- verify_invalid(Conf0, [user_id]),
- Conf = verify_agent_config3(Conf0),
- Vsns = versions(),
- Vsn = which_version(Conf),
- verify_version(Vsn, Vsns),
- {ok, Conf}
- end
+ verify_mandatory(Config0, [engine_id, reg_type]),
+ verify_someof(Config0, [address, taddress]),
+ verify_illegal(Config0, [user_id]),
+ Config = verify_agent_config(Config0),
+ Vsns = versions(),
+ Vsn = which_version(Config),
+ verify_version(Vsn, Vsns),
+ call({register_agent, UserId, TargetName, Config})
catch
- throw:Error ->
+ Error ->
Error
end.
@@ -381,52 +395,43 @@ verify_version(Vsn, Vsns) ->
ok;
false ->
Reason = {version_not_supported_by_manager, Vsn, Vsns},
- throw({error, Reason})
- end.
-
-verify_agent_config3(Conf0) ->
- %% Fix (transport) address and domain
- {TDomain, Conf1} =
- case lists:keysearch(tdomain, 1, Conf0) of
- {value, {tdomain, Dom}} ->
- {Dom, Conf0};
- false ->
- Dom = default_transport_domain(),
- {Dom, [{tdomain, Dom} | Conf0]}
- end,
- Conf2 = case lists:keysearch(address, 1, Conf1) of
- {value, {address, Address}} ->
- lists:keyreplace(address, 1, Conf1,
- {address, {TDomain, Address}});
- false ->
- %% This is a mandatory config option,
- %% a later test will detect this
- Conf1
- end,
- case verify_agent2(Conf2) of
- {ok, Conf} ->
- Conf;
- {error, _} = ERROR ->
- throw(ERROR)
+ error(Reason)
end.
-verify_agent_config2(Conf) ->
- verify_agent2(Conf).
unregister_agent(UserId, TargetName) ->
call({unregister_agent, UserId, TargetName}).
%% This is the old style agent unregistration (using Addr and Port).
-unregister_agent(UserId, Addr0, Port) ->
- Addr = normalize_address(Addr0),
- case do_agent_info(Addr, Port, target_name) of
+unregister_agent(UserId, Domain, Address) when is_atom(Domain) ->
+ try fix_address(Domain, Address) of
+ NAddress ->
+ do_unregister_agent(UserId, Domain, NAddress)
+ catch
+ _ ->
+ {error, not_found}
+ end;
+unregister_agent(UserId, Ip, Port) when is_integer(Port) ->
+ Domain = default_transport_domain(),
+ try fix_address(Domain, {Ip, Port}) of
+ Address ->
+ do_unregister_agent(UserId, Domain, Address)
+ catch
+ _ ->
+ {error, not_found}
+ end.
+
+do_unregister_agent(UserId, Domain, Address) ->
+ case do_agent_info(Domain, Address, target_name) of
{ok, TargetName} ->
unregister_agent(UserId, TargetName);
Error ->
Error
end.
+
+
agent_info() ->
agent_info(?DEFAULT_TARGETNAME, all).
@@ -444,20 +449,46 @@ agent_info(TargetName, Item) ->
[] ->
{error, not_found}
end.
-
-agent_info(Addr0, Port, Item) ->
- Addr = normalize_address(Addr0),
- do_agent_info(Addr, Port, Item).
-do_agent_info(Addr, Port, target_name = Item) ->
- case ets:lookup(snmpm_agent_table, {Addr, Port, Item}) of
+agent_info(Domain, Address, Item) when is_atom(Domain) ->
+ try fix_address(Domain, Address) of
+ NAddress ->
+ do_agent_info(Domain, NAddress, Item)
+ catch
+ _Thrown ->
+ p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n"
+ " ~p",
+ [Domain, Address, Item, _Thrown, erlang:get_stacktrace()]),
+ {error, not_found}
+ end;
+agent_info(Ip, Port, Item) ->
+ p(?MODULE_STRING":agent_info(~p, ~p, ~p) entry~n",
+ [Ip, Port, Item]),
+ Domain = default_transport_domain(),
+ try fix_address(Domain, {Ip, Port}) of
+ Address ->
+ do_agent_info(Domain, Address, Item)
+ catch
+ _Thrown ->
+ p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n"
+ " ~p",
+ [Ip, Port, Item, _Thrown, erlang:get_stacktrace()]),
+ {error, not_found}
+ end.
+
+do_agent_info(Domain, Address, target_name = Item) ->
+ p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n",
+ [Domain, Address, Item]),
+ case ets:lookup(snmpm_agent_table, {Domain, Address, Item}) of
[{_, Val}] ->
{ok, Val};
[] ->
{error, not_found}
end;
-do_agent_info(Addr, Port, Item) ->
- case do_agent_info(Addr, Port, target_name) of
+do_agent_info(Domain, Address, Item) ->
+ p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n",
+ [Domain, Address, Item]),
+ case do_agent_info(Domain, Address, target_name) of
{ok, TargetName} ->
agent_info(TargetName, Item);
Error ->
@@ -465,6 +496,19 @@ do_agent_info(Addr, Port, Item) ->
end.
+ensure_agent_info(_, [], Info) ->
+ Info;
+ensure_agent_info(TargetName, [Item|Items], Info) ->
+ case lists:keymember(Item, 1, Info) of
+ true ->
+ ensure_agent_info(TargetName, Items, Info);
+ false ->
+ {ok, Value} = agent_info(TargetName, Item),
+ ensure_agent_info(TargetName, Items, [{Item, Value}|Info])
+ end.
+
+
+
which_agents() ->
which_agents('_').
@@ -474,38 +518,6 @@ which_agents(UserId) ->
[TargetName || [TargetName] <- Agents].
-verify_agent_info(TargetName, Info0) ->
- try
- begin
- verify_invalid(Info0, [user_id]),
- %% Check if address is part of the list and
- %% if so update it with the domain info.
- Info =
- case lists:keysearch(address, 1, Info0) of
- {value, {address, Addr}} ->
- %% If domain is part of the info, then use it.
- %% If not, lookup what is already stored for
- %% this agent and use that.
- Domain =
- case lists:keysearch(tdomain, 1, Info0) of
- {value, {tdomain, Dom}} ->
- Dom;
- false ->
- {ok, Dom} =
- agent_info(TargetName, tdomain),
- Dom
- end,
- Addr2 = {Domain, Addr},
- lists:keyreplace(address, 1, Info0, {address, Addr2});
- false ->
- Info0
- end,
- verify_agent2(Info)
- end
- catch
- throw:Error ->
- Error
- end.
update_agent_info(UserId, TargetName, Info) ->
call({update_agent_info, UserId, TargetName, Info}).
@@ -740,7 +752,7 @@ verify_usm_user_config(EngineID, Name, Config) ->
try
begin
verify_mandatory(Config, []),
- verify_invalid(Config, [engine_id, name]),
+ verify_illegal(Config, [engine_id, name]),
verify_usm_user_config2(EngineID, Name, Config)
end
catch
@@ -1073,7 +1085,11 @@ do_init(Opts) ->
%% -- Prio (optional) --
Prio = get_opt(priority, Opts, normal),
ets:insert(snmpm_config_table, {prio, Prio}),
- process_flag(priority, Prio),
+ try process_flag(priority, Prio)
+ catch
+ error:badarg ->
+ error({invalid_priority,Prio})
+ end,
%% -- Server (optional) --
ServerOpts = get_opt(server, Opts, []),
@@ -1506,7 +1522,9 @@ verify_versions([]) ->
ok;
verify_versions([Vsn|Vsns]) ->
verify_version(Vsn),
- verify_versions(Vsns).
+ verify_versions(Vsns);
+verify_versions(Vsns) ->
+ error({invalid_versions, Vsns}).
verify_version(v1) ->
ok;
@@ -1629,181 +1647,136 @@ init_agent_default() ->
%% The purpose of the default_agent is only to have a place
%% to store system wide default values related to agents.
%%
-
- %% Port
- init_agent_default(port, ?DEFAULT_AGENT_PORT),
-
- %% Timeout
- init_agent_default(timeout, 10000),
-
- %% Max message (packet) size
- init_agent_default(max_message_size, 484),
-
- %% MPModel
- init_agent_default(version, v2),
-
- %% SecModel
- init_agent_default(sec_model, v2c),
-
- %% SecName
- init_agent_default(sec_name, "initial"),
-
- %% SecLevel
- init_agent_default(sec_level, noAuthNoPriv),
-
- %% Community
- init_agent_default(community, "all-rights"),
- ok.
-
-
-init_agent_default(Item, Val) when Item =/= user_id ->
- case do_update_agent_info(default_agent, Item, Val) of
- ok ->
- ok;
- {error, Reason} ->
- error(Reason)
- end.
-
+ AgentDefaultConfig =
+ [{port, ?DEFAULT_AGENT_PORT}, % Port
+ {timeout, 10000}, % Timeout
+ {max_message_size, 484}, % Max message (packet) size
+ {version, v2}, % MPModel
+ {sec_model, v2c}, % SecModel
+ {sec_name, "initial"}, % SecName
+ {sec_level, noAuthPriv}, % SecLevel
+ {community, "all-rights"}], % Community
+ do_update_agent_info(default_agent, AgentDefaultConfig).
+
+%% %% Port
+%% init_agent_default(port, ?DEFAULT_AGENT_PORT),
+
+%% %% Timeout
+%% init_agent_default(timeout, 10000),
+
+%% %% Max message (packet) size
+%% init_agent_default(max_message_size, 484),
+
+%% %% MPModel
+%% init_agent_default(version, v2),
+
+%% %% SecModel
+%% init_agent_default(sec_model, v2c),
+
+%% %% SecName
+%% init_agent_default(sec_name, "initial"),
+
+%% %% SecLevel
+%% init_agent_default(sec_level, noAuthNoPriv),
+
+%% %% Community
+%% init_agent_default(community, "all-rights"),
+%% ok.
+
+
+%% init_agent_default(Item, Val) when Item =/= user_id ->
+%% case do_update_agent_info(default_agent, Item, Val) of
+%% ok ->
+%% ok;
+%% {error, Reason} ->
+%% error(Reason)
+%% end.
+
+%% read_agents_config_file(Dir) ->
+%% Verify = fun check_agent_config2/1,
+%% case read_file(Dir, "agents.conf", Verify, []) of
+%% {ok, Conf} ->
+%% Conf;
+%% Error ->
+%% ?vlog("agent config error: ~p", [Error]),
+%% throw(Error)
+%% end.
+
+%% check_agent_config2(Agent) ->
+%% case (catch check_agent_config(Agent)) of
+%% {ok, {UserId, TargetName, Conf, Version}} ->
+%% {ok, Vsns} = system_info(versions),
+%% case lists:member(Version, Vsns) of
+%% true ->
+%% {ok, {UserId, TargetName, Conf}};
+%% false ->
+%% error({version_not_supported_by_manager,
+%% Version, Vsns})
+%% end;
+%% Err ->
+%% throw(Err)
+%% end.
read_agents_config_file(Dir) ->
- Check = fun(C) -> check_agent_config2(C) end,
- case read_file(Dir, "agents.conf", Check, []) of
- {ok, Conf} ->
- Conf;
- Error ->
+ Order = fun snmp_conf:no_order/2,
+ Check = fun check_agent_config/2,
+ try read_file(Dir, "agents.conf", Order, Check, [])
+ catch
+ throw:Error ->
?vlog("agent config error: ~p", [Error]),
- throw(Error)
+ erlang:raise(throw, Error, erlang:get_stacktrace())
end.
-check_agent_config2(Agent) ->
- case (catch check_agent_config(Agent)) of
- {ok, {UserId, TargetName, Conf, Version}} ->
- {ok, Vsns} = system_info(versions),
- case lists:member(Version, Vsns) of
- true ->
- {ok, {UserId, TargetName, Conf}};
- false ->
- error({version_not_supported_by_manager,
- Version, Vsns})
- end;
- Err ->
- throw(Err)
+check_agent_config(Agent, State) ->
+ {ok, {UserId, TargetName, Conf, Version}} = check_agent_config(Agent),
+ {ok, Vsns} = system_info(versions),
+ case lists:member(Version, Vsns) of
+ true ->
+ {{ok, {UserId, TargetName, Conf}}, State};
+ false ->
+ error({version_not_supported_by_manager, Version, Vsns})
end.
%% For backward compatibility
-check_agent_config({UserId,
- TargetName,
- Community,
- Ip, Port,
- EngineId,
- Timeout, MaxMessageSize,
- Version, SecModel, SecName, SecLevel}) ->
- TDomain = default_transport_domain(),
- check_agent_config({UserId,
- TargetName,
- Community,
- TDomain, Ip, Port,
- EngineId,
- Timeout, MaxMessageSize,
- Version, SecModel, SecName, SecLevel});
-
-check_agent_config({UserId,
- TargetName,
- Community,
- TDomain, Ip, Port,
- EngineId,
- Timeout, MaxMessageSize,
- Version, SecModel, SecName, SecLevel}) ->
- ?vtrace("check_agent_config -> entry with"
- "~n UserId: ~p"
- "~n TargetName: ~p"
- "~n Community: ~p"
- "~n TDomain: ~p"
- "~n Ip: ~p"
- "~n Port: ~p"
- "~n EngineId: ~p"
- "~n Timeout: ~p"
- "~n MaxMessageSize: ~p"
- "~n Version: ~p"
- "~n SecModel: ~p"
- "~n SecName: ~p"
- "~n SecLevel: ~p",
- [UserId, TargetName, Community,
- TDomain, Ip, Port,
- EngineId, Timeout, MaxMessageSize,
- Version, SecModel, SecName, SecLevel]),
- Addr = normalize_address(TDomain, Ip),
- ?vtrace("check_agent_config -> Addr: ~p", [Addr]),
- Agent = {UserId,
- TargetName,
- Community,
- TDomain, Addr, Port,
- EngineId,
- Timeout, MaxMessageSize,
- Version, SecModel, SecName, SecLevel},
- {ok, verify_agent(Agent)};
+check_agent_config(
+ {UserId, TargetName, Community, Ip, Port,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) ->
+ Domain = default_transport_domain(),
+ Addr = fix_address(Domain, {Ip, Port}),
+ check_agent_config(
+ UserId, TargetName, Community, Domain, Addr,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel);
+check_agent_config(
+ {UserId, TargetName, Community, Domain, Ip, Port,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) ->
+ check_agent_config(
+ UserId, TargetName, Community, Domain, {Ip, Port},
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel);
check_agent_config(Agent) ->
error({bad_agent_config, Agent}).
-
-init_agents_config([]) ->
- ok;
-init_agents_config([Agent|Agents]) ->
- init_agent_config(Agent),
- init_agents_config(Agents).
-
-init_agent_config({_UserId, ?DEFAULT_TARGETNAME = TargetName, _Config}) ->
- throw({error, {invalid_target_name, TargetName}});
-init_agent_config({UserId, TargetName, Config}) ->
- case handle_register_agent(UserId, TargetName, Config) of
- ok ->
- ok;
- Error ->
- throw(Error)
- end.
-
-
-%% For backward compatibility
-verify_agent({UserId,
- TargetName,
- Comm,
- Ip, Port,
- EngineId,
- Timeout, MMS,
- Version, SecModel, SecName, SecLevel}) ->
- TDomain = default_transport_domain(),
- verify_agent({UserId,
- TargetName,
- Comm,
- TDomain, Ip, Port,
- EngineId,
- Timeout, MMS,
- Version, SecModel, SecName, SecLevel});
-
-verify_agent({UserId,
- TargetName,
- Comm,
- TDomain, Ip, Port,
- EngineId,
- Timeout, MMS,
- Version, SecModel, SecName, SecLevel}) ->
- ?vdebug("verify_agent -> entry with"
+check_agent_config(
+ UserId, TargetName, Comm, Domain, Addr,
+ EngineId, Timeout, MMS,
+ Version, SecModel, SecName, SecLevel) ->
+ ?vdebug("check_agent_config -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p", [UserId, TargetName]),
snmp_conf:check_string(TargetName, {gt, 0}),
- snmp_conf:check_integer(Port, {gt, 0}),
%% Note that the order of Conf *is* important.
%% Some properties may depend on others, so that
%% in order to verify one property, another must
%% be already verified (and present). An example
- %% of this is the property 'address', for which
+ %% of this is the property 'taddress', for which
%% the property tdomain is needed.
- Conf0 =
+ Conf =
[{reg_type, target_name},
- {tdomain, TDomain},
- %% This should be taddress, but what the*...
- {address, {TDomain, Ip}},
- {port, Port},
+ {tdomain, Domain},
+ {taddress, Addr},
{community, Comm},
{engine_id, EngineId},
{timeout, Timeout},
@@ -1813,40 +1786,186 @@ verify_agent({UserId,
{sec_name, SecName},
{sec_level, SecLevel}
],
- case verify_agent2(Conf0) of
- {ok, Conf} ->
- {UserId, TargetName, Conf, Version};
- Err ->
- throw(Err)
+ {ok, {UserId, TargetName, verify_agent_config(Conf), Version}}.
+
+
+
+init_agents_config([]) ->
+ ok;
+init_agents_config([Agent|Agents]) ->
+ init_agent_config(Agent),
+ init_agents_config(Agents).
+
+init_agent_config({_UserId, ?DEFAULT_TARGETNAME = TargetName, _Config}) ->
+ error({invalid_target_name, TargetName});
+init_agent_config({UserId, TargetName, Config}) ->
+ case handle_register_agent(UserId, TargetName, Config) of
+ ok ->
+ ok;
+ Error ->
+ throw(Error)
end.
-verify_agent2(Conf) ->
- verify_agent2(Conf, []).
-verify_agent2([], VerifiedConf) ->
- {ok, VerifiedConf};
-verify_agent2([{Item, Val0}|Items], VerifiedConf) ->
- case verify_val(Item, Val0) of
- {ok, Val} ->
- verify_agent2(Items, [{Item, Val} | VerifiedConf]);
- Err ->
- Err
+
+%% Sort 'tdomain' first then 'port' to ensure both
+%% sorts before 'taddress'. Keep the order of other items.
+order_agent(ItemA, ItemB) ->
+ snmp_conf:keyorder(1, ItemA, ItemB, [tdomain, port]).
+
+fix_agent_config(Conf) ->
+ ?vdebug("fix_agent_config -> entry with~n~n"
+ " Conf: ~p", [Conf]),
+ fix_agent_config(lists:sort(fun order_agent/2, Conf), []).
+
+fix_agent_config([], FixedConf) ->
+ Ret = lists:reverse(FixedConf),
+ ?vdebug("fix_agent_config -> returns:~n"
+ " ~p", [Ret]),
+ Ret;
+fix_agent_config([{taddress = Item, Address} = Entry|Conf], FixedConf) ->
+ {value, {tdomain, TDomain}} = lists:keysearch(tdomain, 1, FixedConf),
+ {value, {port, DefaultPort}} = lists:keysearch(port, 1, FixedConf),
+ case snmp_conf:check_address(TDomain, Address, DefaultPort) of
+ ok ->
+ fix_agent_config(Conf, [Entry|FixedConf]);
+ {ok, NAddress} ->
+ fix_agent_config(Conf, [{Item, NAddress}|FixedConf])
end;
-verify_agent2([Bad|_], _VerifiedConf) ->
- {error, {bad_agent_config, Bad}}.
+fix_agent_config([Entry|Conf], FixedConf) ->
+ fix_agent_config(Conf, [Entry|FixedConf]).
+
+
+
+verify_agent_config(Conf) ->
+ verify_agent_config(lists:sort(fun order_agent/2, Conf), []).
+
+verify_agent_config([], VerifiedConf) ->
+ Ret = lists:reverse(VerifiedConf),
+ ?vdebug("verify_agent_config -> returns:~n"
+ " ~p", [Ret]),
+ Ret;
+verify_agent_config([{Item, _} = Entry|Conf], VerifiedConf) ->
+ verify_illegal(VerifiedConf, [Item]), % Duplicates are hereby illegal
+ verify_agent_config(Conf, VerifiedConf, Entry);
+verify_agent_config([Bad|_], _VerifiedConf) ->
+ error({bad_agent_config, Bad}).
+
+verify_agent_config(
+ Conf, VerifiedConf, {taddress = Item, Address} = Entry) ->
+ verify_illegal(VerifiedConf, [address]),
+ {TDomain, VC} =
+ case lists:keysearch(tdomain, 1, VerifiedConf) of
+ {value, {tdomain,TD}} ->
+ {TD, VerifiedConf};
+ _ ->
+ %% Insert tdomain since it is missing
+ TD = default_transport_domain(),
+ {TD, [{tdomain, TD}|VerifiedConf]}
+ end,
+ case snmp_conf:check_address(TDomain, Address, 0) of
+ ok ->
+ verify_agent_config(Conf, [Entry|VC]);
+ {ok, NAddress} ->
+ verify_agent_config(Conf, [{Item, NAddress}|VC])
+ end;
+verify_agent_config(Conf, VerifiedConf, {address, Address}) ->
+ Item = taddress,
+ verify_illegal(VerifiedConf, [Item]),
+ {TDomain, VC} =
+ case lists:keysearch(tdomain, 1, VerifiedConf) of
+ {value, {tdomain, TD}} ->
+ {TD, VerifiedConf};
+ _ ->
+ %% Insert tdomain since it is missing
+ TD = default_transport_domain(),
+ {TD, [{tdomain, TD}|VerifiedConf]}
+ end,
+ case snmp_conf:check_address(TDomain, Address, 0) of
+ ok ->
+ verify_agent_config(Conf, [{Item, Address}|VC]);
+ {ok, NAddress} ->
+ verify_agent_config(Conf, [{Item, NAddress}|VC])
+ end;
+verify_agent_config(Conf, VerifiedConf, {Item, Val} = Entry) ->
+ case verify_agent_entry(Item, Val) of
+ ok ->
+ verify_agent_config(Conf, [Entry|VerifiedConf]);
+ {ok, NewVal} ->
+ verify_agent_config(Conf, [{Item, NewVal}|VerifiedConf])
+ end.
+
+verify_agent_entry(user_id, _UserId) ->
+ ok;
+verify_agent_entry(reg_type, RegType) ->
+ if
+ RegType =:= addr_port;
+ RegType =:= target_name ->
+ ok;
+ true ->
+ error({bad_reg_type, RegType})
+ end;
+verify_agent_entry(tdomain, TDomain) ->
+ snmp_conf:check_domain(TDomain);
+verify_agent_entry(port, Port) ->
+ snmp_conf:check_port(Port);
+verify_agent_entry(community, Comm) ->
+ snmp_conf:check_string(Comm);
+verify_agent_entry(engine_id, EngineId) ->
+ case EngineId of
+ discovery ->
+ ok;
+ _ ->
+ snmp_conf:check_string(EngineId)
+ end;
+verify_agent_entry(timeout, Timeout) ->
+ snmp_conf:check_timer(Timeout);
+verify_agent_entry(max_message_size, MMS) ->
+ snmp_conf:check_packet_size(MMS);
+verify_agent_entry(version, V) ->
+ if
+ V =:= v1;
+ V =:= v2;
+ V =:= v3 ->
+ ok;
+ true ->
+ error({bad_version, V})
+ end;
+verify_agent_entry(sec_model, Model) ->
+ snmp_conf:check_sec_model(Model);
+verify_agent_entry(sec_name, Name) ->
+ try snmp_conf:check_string(Name)
+ catch
+ _ ->
+ error({bad_sec_name, Name})
+ end;
+verify_agent_entry(sec_level, Level) ->
+ snmp_conf:check_sec_level(Level);
+verify_agent_entry(Item, _) ->
+ error({unknown_item, Item}).
+
+%% read_users_config_file(Dir) ->
+%% Verify = fun check_user_config/1,
+%% case read_file(Dir, "users.conf", Verify, []) of
+%% {ok, Conf} ->
+%% Conf;
+%% Error ->
+%% ?vlog("failure reading users config file: ~n ~p", [Error]),
+%% throw(Error)
+%% end.
+
read_users_config_file(Dir) ->
- Check = fun(C) -> check_user_config(C) end,
- case read_file(Dir, "users.conf", Check, []) of
- {ok, Conf} ->
- Conf;
- Error ->
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (User, State) -> {check_user_config(User), State} end,
+ try read_file(Dir, "users.conf", Order, Check, [])
+ catch
+ throw:Error ->
?vlog("failure reading users config file: ~n ~p", [Error]),
- throw(Error)
+ erlang:raise(throw, Error, erlang:get_stacktrace())
end.
-
check_user_config({Id, Mod, Data}) ->
?vtrace("check_user_config -> entry with"
"~n Id: ~p"
@@ -1864,21 +1983,18 @@ check_user_config({Id, Mod, Data, DefaultAgentConfig} = _User)
case (catch verify_user_behaviour(Mod)) of
ok ->
?vtrace("check_user_config -> user behaviour verified", []),
- case verify_user_agent_config(DefaultAgentConfig) of
- {ok, DefAgentConf} ->
- ?vtrace("check_user_config -> "
- "user agent (default) config verified", []),
- User2 = {Id, Mod, Data, DefAgentConf},
- {ok, User2};
- {error, Reason} ->
- error({bad_default_agent_config, Reason})
- end;
+ DefAgentConf =
+ verify_default_agent_config(DefaultAgentConfig),
+ ?vtrace("check_user_config -> "
+ "user agent (default) config verified", []),
+ User2 = {Id, Mod, Data, DefAgentConf},
+ {ok, User2};
Error ->
throw(Error)
end;
check_user_config({Id, _Mod, _Data, DefaultAgentConfig})
when (Id =/= ?DEFAULT_USER) ->
- {error, {bad_default_agent_config, DefaultAgentConfig}};
+ error({bad_default_agent_config, DefaultAgentConfig});
check_user_config({Id, _Mod, _Data, _DefaultAgentConfig}) ->
error({bad_user_id, Id});
check_user_config(User) ->
@@ -1904,7 +2020,7 @@ init_user_config(User) ->
error_msg("user config check failed: "
"~n~w~n~w", [User, Reason])
end.
-
+
verify_user({Id, UserMod, UserData}) ->
verify_user({Id, UserMod, UserData, []});
verify_user({Id, UserMod, UserData, DefaultAgentConfig})
@@ -1917,15 +2033,24 @@ verify_user({Id, UserMod, UserData, DefaultAgentConfig})
[Id, UserMod, UserData, DefaultAgentConfig]),
case (catch verify_user_behaviour(UserMod)) of
ok ->
- case verify_user_agent_config(DefaultAgentConfig) of
- {ok, DefAgentConf} ->
- Config = default_agent_config(DefAgentConf),
- {ok, #user{id = Id,
- mod = UserMod,
- data = UserData,
- default_agent_config = Config}};
- {error, Reason} ->
- error({bad_default_agent_config, Reason})
+ try
+ {ok, SystemDefaultAgentConfig} = agent_info(),
+ Config =
+ ensure_config(
+ SystemDefaultAgentConfig,
+ verify_default_agent_config(DefaultAgentConfig)),
+%% Config =
+%% default_agent_config(
+%% verify_default_agent_config(DefaultAgentConfig)),
+ {ok, #user{id = Id,
+ mod = UserMod,
+ data = UserData,
+ default_agent_config = Config}}
+ catch
+ Error ->
+ ?vdebug("verify_user default_agent_config -> throw"
+ "~n Error: ~p", [Error]),
+ error({bad_default_agent_config, Error})
end;
Error ->
throw(Error)
@@ -1936,27 +2061,32 @@ verify_user({Id, _UserMod, _UserData, DefaultAgentConfig})
verify_user({Id, _, _, _}) ->
{error, {bad_user_id, Id}}.
-verify_user_agent_config(Conf) ->
+verify_default_agent_config(Conf) ->
try
- begin
- verify_invalid(Conf, [user_id, engine_id, address]),
- verify_agent_config2(Conf)
- end
+ verify_illegal(
+ Conf,
+ [user_id, engine_id, address, tdomain, taddress]),
+ verify_agent_config(Conf)
catch
- throw:Error ->
- ?vdebug("verify_user_agent_config -> throw"
+ Error ->
+ ?vdebug("verify_default_agent_config -> throw"
"~n Error: ~p", [Error]),
- Error
+ error({bad_default_agent_config, Error})
end.
+%% read_usm_config_file(Dir) ->
+%% Verify = fun check_usm_user_config/1,
+%% case read_file(Dir, "usm.conf", Verify, []) of
+%% {ok, Conf} ->
+%% Conf;
+%% Error ->
+%% throw(Error)
+%% end.
+
read_usm_config_file(Dir) ->
- Check = fun(C) -> check_usm_user_config(C) end,
- case read_file(Dir, "usm.conf", Check, []) of
- {ok, Conf} ->
- Conf;
- Error ->
- throw(Error)
- end.
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (User, State) -> {check_usm_user_config(User), State} end,
+ read_file(Dir, "usm.conf", Order, Check, []).
%% Identity-function
check_usm_user_config({EngineId, Name,
@@ -2138,20 +2268,61 @@ is_crypto_supported(Func) ->
snmp_misc:is_crypto_supported(Func).
+%% read_manager_config_file(Dir) ->
+%% Verify = fun check_manager_config/1,
+%% case read_file(Dir, "manager.conf", Verify) of
+%% {ok, Conf} ->
+%% ?d("read_manager_config_file -> ok: "
+%% "~n Conf: ~p", [Conf]),
+%% %% If the address is not specified, then we assume
+%% %% it should be the local host.
+%% %% If the address is not possible to determine
+%% %% that way, then we give up...
+%% verify_mandatory(Conf, [port,engine_id,max_message_size]),
+%% ensure_config(default_manager_config(), Conf);
+%% %% check_mandatory_manager_config(Conf),
+%% %% ensure_manager_config(Conf);
+%% Error ->
+%% throw(Error)
+%% end.
+
read_manager_config_file(Dir) ->
- Check = fun(Conf) -> check_manager_config(Conf) end,
- case read_file(Dir, "manager.conf", Check) of
- {ok, Conf} ->
- ?d("read_manager_config_file -> ok: "
- "~n Conf: ~p", [Conf]),
- %% If the address is not specified, then we assume
- %% it should be the local host.
- %% If the address is not possible to determine
- %% that way, then we give up...
- check_mandatory_manager_config(Conf),
- ensure_manager_config(Conf);
- Error ->
- throw(Error)
+ Order = fun order_manager_config/2,
+ Check = fun check_manager_config/2,
+ Conf = read_file(Dir, "manager.conf", Order, Check),
+ ?d("read_manager_config_file -> ok: "
+ "~n Conf: ~p", [Conf]),
+ %% If the address is not specified, then we assume
+ %% it should be the local host.
+ %% If the address is not possible to determine
+ %% that way, then we give up...
+ verify_mandatory(Conf, [port,engine_id,max_message_size]),
+ default_manager_config(Conf).
+
+default_manager_config(Conf) ->
+ %% Ensure address of right family
+ case lists:keyfind(address, 1, Conf) of
+ false ->
+ Domain =
+ case lists:keyfind(domain, 1, Conf) of
+ false ->
+ default_transport_domain();
+ {_, D} ->
+ D
+ end,
+ Family = snmp_conf:tdomain_to_family(Domain),
+ {ok, HostName} = inet:gethostname(),
+ case inet:getaddr(HostName, Family) of
+ {ok, Address} ->
+ [{address, Address} | Conf];
+ {error, _Reason} ->
+ ?d("default_manager_config -> "
+ "failed getting ~w address for ~s:~n"
+ " _Reason: ~p", [Family, HostName, _Reason]),
+ Conf
+ end;
+ _ ->
+ Conf
end.
default_manager_config() ->
@@ -2164,46 +2335,66 @@ default_manager_config() ->
"~n _Reason: ~p", [_Reason]),
[]
end.
-
-check_manager_config({address, Addr}) ->
- snmp_conf:check_ip(Addr);
+
+order_manager_config(EntryA, EntryB) ->
+ snmp_conf:keyorder(1, EntryA, EntryB, [domain]).
+
+check_manager_config({domain, D}, _Domain) ->
+ {snmp_conf:check_domain(D), D};
+check_manager_config({address = Tag, Ip}, D) ->
+ Domain =
+ case D of
+ undefined ->
+ default_transport_domain();
+ _ ->
+ D
+ end,
+ {case snmp_conf:check_ip(Domain, Ip) of
+ ok ->
+ ok;
+ {ok, FixedIp} ->
+ {ok, {Tag, FixedIp}}
+ end, Domain};
+check_manager_config(Entry, Domain) ->
+ {check_manager_config(Entry), Domain}.
+
check_manager_config({port, Port}) ->
- snmp_conf:check_integer(Port, {gt, 0});
+ snmp_conf:check_port(Port);
check_manager_config({engine_id, EngineID}) ->
snmp_conf:check_string(EngineID);
check_manager_config({max_message_size, Max}) ->
snmp_conf:check_integer(Max, {gte, 484});
check_manager_config(Conf) ->
- {error, {unknown_config, Conf}}.
+ error({unknown_config, Conf}).
-check_mandatory_manager_config(Conf) ->
- Mand = [port, engine_id, max_message_size],
- check_mandatory_manager_config(Mand, Conf).
+%% check_mandatory_manager_config(Conf) ->
+%% Mand = [port, engine_id, max_message_size],
+%% check_mandatory_manager_config(Mand, Conf).
-check_mandatory_manager_config([], _Conf) ->
- ok;
-check_mandatory_manager_config([Item|Mand], Conf) ->
- case lists:keysearch(Item, 1, Conf) of
- false ->
- error({missing_mandatory_manager_config, Item});
- _ ->
- check_mandatory_manager_config(Mand, Conf)
- end.
+%% check_mandatory_manager_config([], _Conf) ->
+%% ok;
+%% check_mandatory_manager_config([Item|Mand], Conf) ->
+%% case lists:keysearch(Item, 1, Conf) of
+%% false ->
+%% error({missing_mandatory_manager_config, Item});
+%% _ ->
+%% check_mandatory_manager_config(Mand, Conf)
+%% end.
-ensure_manager_config(Confs) ->
- ensure_manager_config(Confs, default_manager_config()).
+%% ensure_manager_config(Confs) ->
+%% ensure_manager_config(Confs, default_manager_config()).
-ensure_manager_config(Confs, []) ->
- Confs;
-ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) ->
- case lists:keysearch(Key, 1, Confs) of
- false ->
- ensure_manager_config([DefKeyVal|Confs], Defs);
- {value, _Conf} ->
- ensure_manager_config(Confs, Defs)
- end.
+%% ensure_manager_config(Confs, []) ->
+%% Confs;
+%% ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) ->
+%% case lists:keysearch(Key, 1, Confs) of
+%% false ->
+%% ensure_manager_config([DefKeyVal|Confs], Defs);
+%% {value, _Conf} ->
+%% ensure_manager_config(Confs, Defs)
+%% end.
% ensure_manager_config([], Defs, Confs) ->
% Confs ++ Defs;
@@ -2216,46 +2407,102 @@ ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) ->
% ensure_manager_config(Confs, Defs, [Conf|Acc])
% end.
-
-
-read_file(Dir, FileName, Check, Default) ->
- File = filename:join(Dir, FileName),
- case file:read_file_info(File) of
- {ok, _} ->
- case (catch do_read(File, Check)) of
- {ok, Conf} ->
- {ok, Conf};
- Error ->
- ?vtrace("read_file -> read failed:"
- "~n Error: ~p", [Error]),
- Error
- end;
- {error, Reason} ->
+read_file(Dir, FileName, Order, Check, Default) ->
+ try snmp_conf:read(filename:join(Dir, FileName), Order, Check)
+ catch
+ {error, Reason} when element(1, Reason) =:= failed_open ->
?vlog("failed reading config from ~s: ~p", [FileName, Reason]),
- {ok, Default}
+ Default
end.
-read_file(Dir, FileName, Check) ->
- File = filename:join(Dir, FileName),
- case file:read_file_info(File) of
- {ok, _} ->
- case (catch do_read(File, Check)) of
- {ok, Conf} ->
- ?vtrace("read_file -> read ok"
- "~n Conf: ~p", [Conf]),
- {ok, Conf};
- Error ->
- ?vtrace("read_file -> read failed:"
- "~n Error: ~p", [Error]),
- Error
- end;
- {error, Reason} ->
+read_file(Dir, FileName, Order, Check) ->
+ try snmp_conf:read(filename:join(Dir, FileName), Order, Check)
+ catch
+ throw:{error, Reason} = Error
+ when element(1, Reason) =:= failed_open ->
error_msg("failed reading config from ~s: ~p", [FileName, Reason]),
- {error, {failed_reading, FileName, Reason}}
- end.
+ erlang:raise(throw, Error, erlang:get_stacktrace())
+ end.
+
+
+
+
+
+
+%% read_file(Dir, FileName, Verify, Default) ->
+%% File = filename:join(Dir, FileName),
+%% case file:read_file_info(File) of
+%% {ok, _} ->
+%% read_file(File, Verify);
+%% {error, Reason} ->
+%% ?vlog("failed reading config from ~s: ~p", [FileName, Reason]),
+%% {ok, Default}
+%% end.
+
+%% read_file(Dir, FileName, Verify) ->
+%% File = filename:join(Dir, FileName),
+%% case file:read_file_info(File) of
+%% {ok, _} ->
+%% read_file(File, Verify);
+%% {error, Reason} ->
+%% error_msg("failed reading config from ~s: ~p", [FileName, Reason]),
+%% {error, {failed_reading, FileName, Reason}}
+%% end.
+
+%% read_file(File, Verify) ->
+%% Check = fun (Config, State) -> {Verify(Config), State} end,
+%% try snmp_conf:read(File, Check) of
+%% Conf ->
+%% ?vtrace("read_file -> read ok"
+%% "~n Conf: ~p", [Conf]),
+%% {ok, Conf}
+%% catch
+%% Error ->
+%% ?vtrace("read_file -> read failed:"
+%% "~n Error: ~p", [Error]),
+%% Error
+%% end.
+
+%% XXX remove
+
+%% read_file(Dir, FileName, Check, Default) ->
+%% File = filename:join(Dir, FileName),
+%% case file:read_file_info(File) of
+%% {ok, _} ->
+%% case (catch do_read(File, Check)) of
+%% {ok, Conf} ->
+%% {ok, Conf};
+%% Error ->
+%% ?vtrace("read_file -> read failed:"
+%% "~n Error: ~p", [Error]),
+%% Error
+%% end;
+%% {error, Reason} ->
+%% ?vlog("failed reading config from ~s: ~p", [FileName, Reason]),
+%% {ok, Default}
+%% end.
+
+%% read_file(Dir, FileName, Check) ->
+%% File = filename:join(Dir, FileName),
+%% case file:read_file_info(File) of
+%% {ok, _} ->
+%% case (catch do_read(File, Check)) of
+%% {ok, Conf} ->
+%% ?vtrace("read_file -> read ok"
+%% "~n Conf: ~p", [Conf]),
+%% {ok, Conf};
+%% Error ->
+%% ?vtrace("read_file -> read failed:"
+%% "~n Error: ~p", [Error]),
+%% Error
+%% end;
+%% {error, Reason} ->
+%% error_msg("failed reading config from ~s: ~p", [FileName, Reason]),
+%% {error, {failed_reading, FileName, Reason}}
+%% end.
-do_read(File, Check) ->
- {ok, snmp_conf:read(File, Check)}.
+%% do_read(File, Check) ->
+%% {ok, snmp_conf:read(File, Check)}.
%%--------------------------------------------------------------------
@@ -2684,30 +2931,50 @@ handle_register_agent(UserId, TargetName, Config) ->
"~n Config: ~p", [UserId, TargetName, Config]),
case (catch agent_info(TargetName, user_id)) of
{error, _} ->
- ?vtrace("handle_register_agent -> user_id not found in config", []),
+ ?vtrace(
+ "handle_register_agent -> user_id not found in config", []),
case ets:lookup(snmpm_user_table, UserId) of
[#user{default_agent_config = DefConfig}] ->
- ?vtrace("handle_register_agent -> "
- "~n DefConfig: ~p", [DefConfig]),
- %% First, insert this users default config
- ?vtrace("handle_register_agent -> store default config", []),
- do_handle_register_agent(TargetName, DefConfig),
- %% Second, insert the config for this agent
- ?vtrace("handle_register_agent -> store config", []),
- do_handle_register_agent(TargetName,
- [{user_id, UserId}|Config]),
+ ?vtrace("handle_register_agent ->~n"
+ " DefConfig: ~p", [DefConfig]),
+ FixedConfig =
+ fix_agent_config(ensure_config(DefConfig, Config)),
+ ?vtrace("handle_register_agent ->~n"
+ " FixedConfig: ~p", [FixedConfig]),
+ do_handle_register_agent(
+ TargetName, [{user_id, UserId}|FixedConfig]),
%% <DIRTY-BACKWARD-COMPATIBILLITY>
- %% And now for some (backward compatibillity)
+ %% And now for some (backward compatibillity)
%% dirty crossref stuff
- ?vtrace("handle_register_agent -> lookup address", []),
- {ok, Addr} = agent_info(TargetName, address),
- ?vtrace("handle_register_agent -> Addr: ~p, lookup Port",
- [Addr]),
- {ok, Port} = agent_info(TargetName, port),
- ?vtrace("handle_register_agent -> register cross-ref fix", []),
- ets:insert(snmpm_agent_table,
- {{Addr, Port, target_name}, TargetName}),
+ {value, {_, Domain}} =
+ lists:keysearch(tdomain, 1, FixedConfig),
+ {value, {_, Address}} =
+ lists:keysearch(taddress, 1, FixedConfig),
+ ?vtrace(
+ "handle_register_agent -> register cross-ref fix", []),
+ ets:insert(snmpm_agent_table,
+ {{Domain, Address, target_name}, TargetName}),
%% </DIRTY-BACKWARD-COMPATIBILLITY>
+
+%% %% First, insert this users default config
+%% ?vtrace("handle_register_agent -> store default config", []),
+%% do_handle_register_agent(TargetName, DefConfig),
+%% %% Second, insert the config for this agent
+%% ?vtrace("handle_register_agent -> store config", []),
+%% do_handle_register_agent(TargetName,
+%% [{user_id, UserId}|Config]),
+%% %% <DIRTY-BACKWARD-COMPATIBILLITY>
+%% %% And now for some (backward compatibillity)
+%% %% dirty crossref stuff
+%% ?vtrace("handle_register_agent -> lookup taddress", []),
+%% {ok, {Addr, Port} = TAddress} =
+%% agent_info(TargetName, taddress),
+%% ?vtrace("handle_register_agent -> taddress: ~p",
+%% [TAddress]),
+%% ?vtrace("handle_register_agent -> register cross-ref fix", []),
+%% ets:insert(snmpm_agent_table,
+%% {{Addr, Port, target_name}, TargetName}),
+%% %% </DIRTY-BACKWARD-COMPATIBILLITY>
ok;
_ ->
{error, {not_found, UserId}}
@@ -2729,7 +2996,7 @@ handle_register_agent(UserId, TargetName, Config) ->
do_handle_register_agent(_TargetName, []) ->
ok;
do_handle_register_agent(TargetName, [{Item, Val}|Rest]) ->
- ?vtrace("handle_register_agent -> entry with"
+ ?vtrace("do_handle_register_agent -> entry with"
"~n TargetName: ~p"
"~n Item: ~p"
"~n Val: ~p"
@@ -2738,7 +3005,7 @@ do_handle_register_agent(TargetName, [{Item, Val}|Rest]) ->
ok ->
do_handle_register_agent(TargetName, Rest);
{error, Reason} ->
- ?vtrace("handle_register_agent -> failed updating ~p"
+ ?vtrace("do_handle_register_agent -> failed updating ~p"
"~n Item: ~p"
"~n Reason: ~p", [Item, Reason]),
ets:match_delete(snmpm_agent_table, {TargetName, '_'}),
@@ -2762,9 +3029,9 @@ handle_unregister_agent(UserId, TargetName) ->
%% <DIRTY-BACKWARD-COMPATIBILLITY>
%% And now for some (backward compatibillity)
%% dirty crossref stuff
- {ok, Addr} = agent_info(TargetName, address),
- {ok, Port} = agent_info(TargetName, port),
- ets:delete(snmpm_agent_table, {Addr, Port, target_name}),
+ {ok, Domain} = agent_info(TargetName, tdomain),
+ {ok, Address} = agent_info(TargetName, taddress),
+ ets:delete(snmpm_agent_table, {Domain, Address, target_name}),
%% </DIRTY-BACKWARD-COMPATIBILLITY>
ets:match_delete(snmpm_agent_table, {{TargetName, '_'}, '_'}),
ok;
@@ -2790,21 +3057,26 @@ handle_update_agent_info(UserId, TargetName, Info) ->
Error
end.
-handle_update_agent_info(TargetName, Info0) ->
+handle_update_agent_info(TargetName, Info) ->
?vtrace("handle_update_agent_info -> entry with"
"~n TargetName: ~p"
- "~n Info0: ~p", [TargetName, Info0]),
+ "~n Info: ~p", [TargetName, Info]),
%% Verify info
- try verify_agent_info(TargetName, Info0) of
- {ok, Info} ->
- do_update_agent_info(TargetName, Info);
+ try
+ verify_illegal(Info, [user_id]),
+ %% If port or domain is part of the info, then use it.
+ %% If not, lookup what is already stored for
+ %% this agent and use that.
+ do_update_agent_info(
+ TargetName,
+ fix_agent_config(
+ verify_agent_config(
+ ensure_agent_info(TargetName, [port,tdomain], Info))))
+ catch
Error ->
- Error
- catch
- throw:Error ->
Error;
T:E ->
- {error, {failed_info_verification, Info0, T, E}}
+ {error, {failed_info_verification, Info, T, E}}
end.
handle_update_agent_info(UserId, TargetName, Item, Val) ->
@@ -2816,6 +3088,9 @@ handle_update_agent_info(UserId, TargetName, Item, Val) ->
handle_update_agent_info(TargetName, [{Item, Val}]).
do_update_agent_info(TargetName, Info) ->
+ ?vtrace("do_update_agent_info -> entry with~n"
+ " TargetName: ~p~n"
+ " Info: ~p", [TargetName,Info]),
InsertItem =
fun({Item, Val}) ->
ets:insert(snmpm_agent_table, {{TargetName, Item}, Val})
@@ -2997,109 +3272,42 @@ verify_mandatory(Conf, [Mand|Mands]) ->
true ->
verify_mandatory(Conf, Mands);
false ->
- throw({error, {missing_mandatory_config, Mand}})
+ error({missing_mandatory_config, Mand})
end.
-verify_invalid(_, []) ->
+verify_illegal(_, []) ->
ok;
-verify_invalid(Conf, [Inv|Invs]) ->
+verify_illegal(Conf, [Inv|Invs]) ->
case lists:member(Inv, Conf) of
false ->
- verify_invalid(Conf, Invs);
+ verify_illegal(Conf, Invs);
true ->
- throw({error, {illegal_config, Inv}})
+ error({illegal_config, Inv})
end.
-
-verify_val(user_id, UserId) ->
- {ok, UserId};
-verify_val(reg_type, RegType)
- when (RegType =:= addr_port) orelse (RegType =:= target_name) ->
- {ok, RegType};
-verify_val(tdomain = Item, snmpUDPDomain = _Domain) ->
- verify_val(Item, transportDomainUdpIpv4);
-verify_val(tdomain, Domain) ->
- case lists:member(Domain, ?SUPPORTED_DOMAINS) of
+verify_someof(Conf, [Mand|Mands]) ->
+ case lists:keymember(Mand, 1, Conf) of
true ->
- {ok, Domain};
+ ok;
false ->
- case lists:member(Domain, snmp_conf:all_domains()) of
- true ->
- error({unsupported_domain, Domain});
- false ->
- error({unknown_domain, Domain})
+ case Mands of
+ [] ->
+ error({missing_mandatory_config, Mand});
+ _ ->
+ verify_someof(Conf, Mands)
end
- end;
-verify_val(address, {Domain, Addr0}) ->
- case normalize_address(Domain, Addr0) of
- {_A1, _A2, _A3, _A4} = Addr ->
- {ok, Addr};
- {_A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8} = Addr ->
- {ok, Addr};
- _ when is_list(Addr0) ->
- case (catch snmp_conf:check_ip(Addr0)) of
- ok ->
- {ok, list_to_tuple(Addr0)};
- Err ->
- Err
- end;
- _ ->
- error({bad_address, Addr0})
- end;
-verify_val(address, BadAddress) ->
- error({bad_address, BadAddress});
-verify_val(port, Port) ->
- case (catch snmp_conf:check_integer(Port, {gt, 0})) of
- ok ->
- {ok, Port};
- Err ->
- Err
- end;
-verify_val(community, Comm) ->
- case (catch snmp_conf:check_string(Comm)) of
- ok ->
- {ok, Comm};
- Err ->
- Err
- end;
-verify_val(engine_id, discovery = EngineId) ->
- {ok, EngineId};
-verify_val(engine_id, EngineId) ->
- case (catch snmp_conf:check_string(EngineId)) of
- ok ->
- {ok, EngineId};
- Err ->
- Err
- end;
-verify_val(timeout, Timeout) ->
- (catch snmp_conf:check_timer(Timeout));
-verify_val(max_message_size, MMS) ->
- case (catch snmp_conf:check_packet_size(MMS)) of
- ok ->
- {ok, MMS};
- Err ->
- Err
- end;
-verify_val(version, V)
- when (V =:= v1) orelse (V =:= v2) orelse (V =:= v3) ->
- {ok, V};
-verify_val(version, BadVersion) ->
- error({bad_version, BadVersion});
-verify_val(sec_model, Model) ->
- (catch snmp_conf:check_sec_model(Model));
-verify_val(sec_name, Name) when is_list(Name) ->
- case (catch snmp_conf:check_string(Name)) of
- ok ->
- {ok, Name};
- Err ->
- Err
- end;
-verify_val(sec_name, BadName) ->
- error({bad_sec_name, BadName});
-verify_val(sec_level, Level) ->
- (catch snmp_conf:check_sec_level(Level));
-verify_val(Item, _) ->
- {error, {unknown_item, Item}}.
+ end.
+
+ensure_config([], Config) ->
+ Config;
+ensure_config([Default|Defaults], Config) ->
+ case lists:keymember(element(1, Default), 1, Config) of
+ true ->
+ ensure_config(Defaults, Config);
+ false ->
+ ensure_config(Defaults, [Default|Config])
+ end.
+
%%%-------------------------------------------------------------------
@@ -3257,31 +3465,14 @@ init_mini_mib_elems(MibName, [_|T], Res) ->
%%----------------------------------------------------------------------
-normalize_address(Addr) ->
- normalize_address(snmpUDPDomain, Addr).
-
-normalize_address(snmpUDPDomain, Addr) ->
- normalize_address(transportDomainUdpIpv4, Addr);
-
-normalize_address(Domain, Addr) ->
- case inet:getaddr(Addr, td2fam(Domain)) of
- {ok, Addr2} ->
- Addr2;
- _ when is_list(Addr) ->
- case (catch snmp_conf:check_ip(Domain, Addr)) of
- ok ->
- list_to_tuple(Addr);
- _ ->
- Addr
- end;
- _ ->
- Addr
+fix_address(Domain, Address) ->
+ case snmp_conf:check_address(Domain, Address) of
+ ok ->
+ Address;
+ {ok, NAddress} ->
+ NAddress
end.
-td2fam(transportDomainUdpIpv4) -> inet;
-td2fam(transportDomainUdpIpv6) -> inet6.
-
-
%%----------------------------------------------------------------------
call(Req) ->
@@ -3389,6 +3580,6 @@ error_msg(F, A) ->
%% p(F) ->
%% p(F, []).
-%% p(F, A) ->
-%% io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
+p(F, A) ->
+ io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl
index 953c94ab54..f8a7441c0a 100644
--- a/lib/snmp/src/manager/snmpm_mpd.erl
+++ b/lib/snmp/src/manager/snmpm_mpd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,7 +21,7 @@
-export([init/1,
- process_msg/7,
+ process_msg/7, process_msg/6,
generate_msg/5, generate_response_msg/4,
next_msg_id/0,
@@ -92,8 +92,10 @@ reset(#state{v3 = V3}) ->
%% Purpose: This is the main Message Dispatching function. (see
%% section 4.2.1 in rfc2272)
%%-----------------------------------------------------------------
-process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) ->
+process_msg(Msg, Domain, Ip, Port, State, NoteStore, Logger) ->
+ process_msg(Msg, Domain, {Ip, Port}, State, NoteStore, Logger).
+process_msg(Msg, Domain, Addr, State, NoteStore, Logger) ->
inc(snmpInPkts),
case (catch snmp_pdus:dec_message_only(binary_to_list(Msg))) of
@@ -102,17 +104,17 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) ->
#message{version = 'version-1', vsn_hdr = Community, data = Data}
when State#state.v1 =:= true ->
HS = ?empty_msg_size + length(Community),
- process_v1_v2c_msg('version-1', NoteStore, Msg,
- Domain, Addr, Port,
- Community, Data, HS, Logger);
+ process_v1_v2c_msg(
+ 'version-1', NoteStore, Msg, Domain, Addr,
+ Community, Data, HS, Logger);
%% Version 2
#message{version = 'version-2', vsn_hdr = Community, data = Data}
when State#state.v2c =:= true ->
HS = ?empty_msg_size + length(Community),
- process_v1_v2c_msg('version-2', NoteStore, Msg,
- Domain, Addr, Port,
- Community, Data, HS, Logger);
+ process_v1_v2c_msg(
+ 'version-2', NoteStore, Msg, Domain, Addr,
+ Community, Data, HS, Logger);
%% Version 3
#message{version = 'version-3', vsn_hdr = H, data = Data}
@@ -122,7 +124,7 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) ->
"~n msgFlags: ~p"
"~n msgSecModel: ~p",
[H#v3_hdr.msgID,H#v3_hdr.msgFlags,H#v3_hdr.msgSecurityModel]),
- process_v3_msg(NoteStore, Msg, H, Data, Addr, Port, Logger);
+ process_v3_msg(NoteStore, Msg, H, Data, Addr, Logger);
%% Crap
{'EXIT', {bad_version, Vsn}} ->
@@ -148,32 +150,27 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) ->
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-process_v1_v2c_msg(Vsn, _NoteStore, Msg, Domain,
- Addr, Port,
- Community, Data, HS, Log) ->
+process_v1_v2c_msg(
+ Vsn, _NoteStore, Msg, Domain, Addr, Community, Data, HS, Log) ->
?vdebug("process_v1_v2c_msg -> entry with"
"~n Vsn: ~p"
"~n Domain: ~p"
"~n Addr: ~p"
- "~n Port: ~p"
"~n Community: ~p"
- "~n HS: ~p", [Vsn, Domain, Addr, Port, Community, HS]),
-
+ "~n HS: ~p", [Vsn, Domain, Addr, Community, HS]),
+
{TDomain, TAddress} =
try
- begin
- TD = snmp_conf:mk_tdomain(Domain),
- TA = snmp_conf:mk_taddress(Domain, Addr, Port),
- {TD, TA}
- end
+ {snmp_conf:mk_tdomain(Domain),
+ snmp_conf:mk_taddress(Domain, Addr)}
catch
throw:{error, TReason} ->
throw({discarded, {badarg, Domain, TReason}})
end,
Max = get_max_message_size(),
- AgentMax = get_agent_max_message_size(Addr, Port),
+ AgentMax = get_agent_max_message_size(Domain, Addr),
PduMS = pdu_ms(Max, AgentMax, HS),
?vtrace("process_v1_v2c_msg -> PduMS: ~p", [PduMS]),
@@ -213,13 +210,12 @@ sec_model('version-2') -> ?SEC_V2C.
%% Handles a SNMPv3 Message, following the procedures in rfc2272,
%% section 4.2 and 7.2
%%-----------------------------------------------------------------
-process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) ->
+process_v3_msg(NoteStore, Msg, Hdr, Data, Address, Log) ->
+ ?vdebug(
+ "process_v3_msg -> entry with~n"
+ " Hdr: ~p~n"
+ " Address: ~p", [Hdr, Address]),
- ?vdebug("process_v3_msg -> entry with"
- "~n Hdr: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Hdr, Addr, Port]),
-
%% 7.2.3
#v3_hdr{msgID = MsgID,
msgMaxSize = MMS,
@@ -352,8 +348,8 @@ process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) ->
%% 4.2.2.1.1 - we don't handle proxys yet => we only
%% handle CtxEngineID to ourselves
%% Check that we actually know of an agent with this
- %% CtxEngineID and Addr/Port
- case is_known_engine_id(CtxEngineID, Addr, Port) of
+ %% CtxEngineID and Address
+ case is_known_engine_id(CtxEngineID, Address) of
true ->
?vtrace("and the agent EngineID (~p) "
"is know to us", [CtxEngineID]),
@@ -866,14 +862,23 @@ get_max_message_size() ->
end.
%% The the MMS of the agent
-get_agent_max_message_size(Addr, Port) ->
- case snmpm_config:get_agent_engine_max_message_size(Addr, Port) of
+get_agent_max_message_size(Domain, Addr) ->
+ case snmpm_config:get_agent_engine_max_message_size(Domain, Addr) of
{ok, MMS} ->
MMS;
_Error ->
- ?vlog("unknown agent: ~w:~w", [Addr, Port]),
+ ?vlog("unknown agent: ~s",
+ [snmp_conf:mk_addr_string({Domain, Addr})]),
get_max_message_size()
end.
+%% get_agent_max_message_size(Addr, Port) ->
+%% case snmpm_config:get_agent_engine_max_message_size(Addr, Port) of
+%% {ok, MMS} ->
+%% MMS;
+%% _Error ->
+%% ?vlog("unknown agent: ~w:~w", [Addr, Port]),
+%% get_max_message_size()
+%% end.
%% Get "our" (manager) engine id
get_engine_id() ->
@@ -888,9 +893,12 @@ get_engine_id() ->
get_agent_engine_id(Name) ->
snmpm_config:get_agent_engine_id(Name).
-is_known_engine_id(EngineID, Addr, Port) ->
+is_known_engine_id(EngineID, {Addr, Port}) ->
snmpm_config:is_known_engine_id(EngineID, Addr, Port).
+%% is_known_engine_id(EngineID, Addr, Port) ->
+%% snmpm_config:is_known_engine_id(EngineID, Addr, Port).
+
% get_agent_engine_id(Addr, Port) ->
% case snmpm_config:get_agent_engine_id(Addr, Port) of
% {ok, Id} ->
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index 4d6bd9aa33..860b0b83dd 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,9 +27,9 @@
-export([
start_link/2,
stop/1,
- send_pdu/6, % Backward compatibillity
- send_pdu/7, % Backward compatibillity
- send_pdu/8,
+ send_pdu/6, % Backward compatibility
+ send_pdu/7, % Partly backward compatibility
+ send_pdu/8, % Backward compatibility
inform_response/4,
@@ -55,11 +55,12 @@
%% -define(VMODULE,"NET_IF").
-include("snmp_verbosity.hrl").
--record(state,
+-record(state,
{
server,
note_store,
- sock,
+ domain,
+ sock,
mpd_state,
log,
irb = auto, % auto | {user, integer()}
@@ -99,30 +100,32 @@ start_link(Server, NoteStore) ->
stop(Pid) ->
call(Pid, stop).
-send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) ->
- send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO).
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port) ->
+ send_pdu(
+ Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ?DEFAULT_EXTRA_INFO).
-send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) ->
- Domain = snmpm_config:default_transport_domain(),
- send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo).
-
-send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo)
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ExtraInfo)
when is_record(Pdu, pdu) ->
- ?d("send_pdu -> entry with"
- "~n Pid: ~p"
- "~n Pdu: ~p"
- "~n Vsn: ~p"
- "~n MsgData: ~p"
- "~n Domain: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]),
- cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}).
+ ?d("send_pdu -> entry with~n"
+ " Pid: ~p~n"
+ " Pdu: ~p~n"
+ " Vsn: ~p~n"
+ " MsgData: ~p~n"
+ " Domain/IP: ~p~n"
+ " Addr/Port: ~p",
+ [Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port]),
+ {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port),
+ cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}).
+
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) ->
+ send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo).
note_store(Pid, NoteStore) ->
call(Pid, {note_store, NoteStore}).
-inform_response(Pid, Ref, Addr, Port) ->
- cast(Pid, {inform_response, Ref, Addr, Port}).
+inform_response(Pid, Ref, Domain_or_Ip, Addr_or_Port) ->
+ {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port),
+ cast(Pid, {inform_response, Ref, Domain, Addr}).
info(Pid) ->
call(Pid, info).
@@ -199,7 +202,14 @@ do_init(Server, NoteStore) ->
BindTo = get_opt(Opts, bind_to, false),
NoReuse = get_opt(Opts, no_reuse, false),
{ok, Port} = snmpm_config:system_info(port),
- {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, BindTo, NoReuse),
+ Domain =
+ case snmpm_config:system_info(domain) of
+ {ok, D} ->
+ D;
+ _ ->
+ snmpm_config:default_transport_domain()
+ end,
+ {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, Domain, BindTo, NoReuse),
%% Flow control --
FilterOpts = get_opt(Opts, filter, []),
@@ -217,6 +227,7 @@ do_init(Server, NoteStore) ->
State = #state{server = Server,
note_store = NoteStore,
mpd_state = MpdState,
+ domain = Domain,
sock = Sock,
log = Log,
irb = IRB,
@@ -227,18 +238,23 @@ do_init(Server, NoteStore) ->
%% Open port
-do_open_port(Port, SendSz, RecvSz, BindTo, NoReuse) ->
- ?vtrace("do_open_port -> entry with"
- "~n Port: ~p"
- "~n SendSz: ~p"
- "~n RecvSz: ~p"
- "~n BindTo: ~p"
- "~n NoReuse: ~p", [Port, SendSz, RecvSz, BindTo, NoReuse]),
+do_open_port(Port, SendSz, RecvSz, Domain, BindTo, NoReuse) ->
+ ?vtrace("do_open_port -> entry with~n"
+ " Port: ~p~n"
+ " SendSz: ~p~n"
+ " RecvSz: ~p~n"
+ " Domain: ~p~n"
+ " BindTo: ~p~n"
+ " NoReuse: ~p",
+ [Port, SendSz, RecvSz, Domain, BindTo, NoReuse]),
IpOpts1 = bind_to(BindTo),
IpOpts2 = no_reuse(NoReuse),
IpOpts3 = recbuf(RecvSz),
IpOpts4 = sndbuf(SendSz),
- IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
+ IpOpts =
+ [binary,
+ snmp_conf:tdomain_to_family(Domain) |
+ IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
OpenRes =
case init:get_argument(snmpm_fd) of
{ok, [[FdStr]]} ->
@@ -386,25 +402,24 @@ handle_call(Req, From, State) ->
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
-handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo},
+handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo},
State) ->
- ?vlog("received send_pdu message with"
- "~n Pdu: ~p"
- "~n Vsn: ~p"
- "~n MsgData: ~p"
- "~n Domain: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]),
- maybe_process_extra_info(ExtraInfo),
- maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State),
+ ?vlog("received send_pdu message with~n"
+ " Pdu: ~p~n"
+ " Vsn: ~p~n"
+ " MsgData: ~p~n"
+ " Domain: ~p~n"
+ " Addr : ~p", [Pdu, Vsn, MsgData, Domain, Addr]),
+ maybe_process_extra_info(ExtraInfo),
+ maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State),
{noreply, State};
-handle_cast({inform_response, Ref, Addr, Port}, State) ->
- ?vlog("received inform_response message with"
- "~n Ref: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Ref, Addr, Port]),
- handle_inform_response(Ref, Addr, Port, State),
+handle_cast({inform_response, Ref, Domain, Addr}, State) ->
+ ?vlog("received inform_response message with~n"
+ " Ref: ~p~n"
+ " Domain: ~p~n"
+ " Addr: ~p", [Ref, Domain, Addr]),
+ handle_inform_response(Ref, Domain, Addr, State),
{noreply, State};
handle_cast(filter_reset, State) ->
@@ -423,9 +438,11 @@ handle_cast(Msg, State) ->
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
-handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) ->
+handle_info(
+ {udp, Sock, Ip, Port, Bytes},
+ #state{sock = Sock, domain = Domain} = State) ->
?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]),
- maybe_handle_recv_msg(Ip, Port, Bytes, State),
+ maybe_handle_recv_msg(Domain, {Ip, Port}, Bytes, State),
{noreply, State};
handle_info(inform_response_gc, State) ->
@@ -531,48 +548,50 @@ code_change(_Vsn, State, _Extra) ->
%%% Internal functions
%%%-------------------------------------------------------------------
-maybe_handle_recv_msg(Addr, Port, Bytes, #state{filter = FilterMod} = State) ->
- case (catch FilterMod:accept_recv(Addr, Port)) of
+maybe_handle_recv_msg(
+ Domain, Addr, Bytes,
+ #state{filter = FilterMod, domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_recv(Arg1, Arg2)) of
false ->
%% Drop the received packet
inc(netIfMsgInDrops),
ok;
_ ->
- handle_recv_msg(Addr, Port, Bytes, State)
+ handle_recv_msg(Domain, Addr, Bytes, State)
end.
-handle_recv_msg(Addr, Port, Bytes, #state{server = Pid})
+handle_recv_msg(Domain, Addr, Bytes, #state{server = Pid})
when is_binary(Bytes) andalso (size(Bytes) =:= 0) ->
- Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port},
+ Pid ! {snmp_error, {empty_message, Domain, Addr}, Domain, Addr},
ok;
-handle_recv_msg(Addr, Port, Bytes,
- #state{server = Pid,
- note_store = NoteStore,
- mpd_state = MpdState,
- sock = Sock,
- log = Log} = State) ->
- Domain = snmp_conf:which_domain(Addr), % What the ****...
- Logger = logger(Log, read, Addr, Port),
- case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port,
+handle_recv_msg(
+ Domain, Addr, Bytes,
+ #state{server = Pid,
+ note_store = NoteStore,
+ mpd_state = MpdState,
+ log = Log} = State) ->
+ Logger = logger(Log, read, Domain, Addr),
+ case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr,
MpdState, NoteStore, Logger)) of
{ok, Vsn, Pdu, MS, ACM} ->
- maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, MS, ACM,
+ maybe_handle_recv_pdu(Domain, Addr, Vsn, Pdu, MS, ACM,
Logger, State);
{discarded, Reason, Report} ->
?vdebug("discarded: ~p", [Reason]),
ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Addr, Port},
- maybe_udp_send(State#state.filter, Sock, Addr, Port, Report),
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr},
+ maybe_udp_send(Domain, Addr, Report, State),
ok;
{discarded, Reason} ->
?vdebug("discarded: ~p", [Reason]),
ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Addr, Port},
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr},
ok;
Error ->
@@ -582,88 +601,94 @@ handle_recv_msg(Addr, Port, Bytes,
end.
-maybe_handle_recv_pdu(Addr, Port,
- Vsn, #pdu{type = Type} = Pdu, PduMS, ACM,
- Logger,
- #state{filter = FilterMod} = State) ->
- case (catch FilterMod:accept_recv_pdu(Addr, Port, Type)) of
+maybe_handle_recv_pdu(
+ Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger,
+ #state{filter = FilterMod, domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of
false ->
inc(netIfPduInDrops),
ok;
_ ->
- handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State)
+ handle_recv_pdu(
+ Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State)
end;
-maybe_handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger,
- #state{filter = FilterMod} = State)
+maybe_handle_recv_pdu(
+ Domain, Addr, Vsn, Trap, PduMS, ACM, Logger,
+ #state{filter = FilterMod, domain = ManagerDomain} = State)
when is_record(Trap, trappdu) ->
- case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of
false ->
inc(netIfPduInDrops),
ok;
_ ->
- handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, State)
+ handle_recv_pdu(
+ Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, State)
end;
-maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) ->
- handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State).
-
-
-handle_recv_pdu(Addr, Port,
- Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM,
- Logger, #state{server = Pid, irb = IRB} = State) ->
- handle_inform_request(IRB, Pid, Vsn, Pdu, ACM,
- Addr, Port, Logger, State);
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = report} = Pdu, _PduMS, ok,
- _Logger,
- #state{server = Pid} = _State) ->
+maybe_handle_recv_pdu(
+ Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) ->
+ handle_recv_pdu(Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State).
+
+
+handle_recv_pdu(
+ Domain, Addr, Vsn,
+ #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger,
+ #state{server = Pid, irb = IRB} = State) ->
+ handle_inform_request(
+ IRB, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State);
+handle_recv_pdu(
+ Domain, Addr, _Vsn,
+ #pdu{type = report} = Pdu, _PduMS, ok, _Logger,
+ #state{server = Pid} = _State) ->
?vtrace("received report - ok", []),
- Pid ! {snmp_report, {ok, Pdu}, Addr, Port};
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = report} = Pdu, _PduMS,
- {error, ReqId, Reason},
- _Logger,
- #state{server = Pid} = _State) ->
+ Pid ! {snmp_report, {ok, Pdu}, Domain, Addr};
+handle_recv_pdu(
+ Domain, Addr, _Vsn,
+ #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger,
+ #state{server = Pid} = _State) ->
?vtrace("received report - error", []),
- Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Addr, Port};
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) ->
+ Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Addr};
+handle_recv_pdu(
+ Domain, Addr, _Vsn,
+ #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger,
+ #state{server = Pid} = _State) ->
?vtrace("received snmpv2-trap", []),
- Pid ! {snmp_trap, Pdu, Addr, Port};
-handle_recv_pdu(Addr, Port,
- _Vsn, Trap, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) when is_record(Trap, trappdu) ->
+ Pid ! {snmp_trap, Pdu, Domain, Addr};
+handle_recv_pdu(
+ Domain, Addr, _Vsn, Trap, _PduMS, _ACM, _Logger,
+ #state{server = Pid} = _State) when is_record(Trap, trappdu) ->
?vtrace("received trappdu", []),
- Pid ! {snmp_trap, Trap, Addr, Port};
-handle_recv_pdu(Addr, Port,
- _Vsn, Pdu, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) when is_record(Pdu, pdu) ->
+ Pid ! {snmp_trap, Trap, Domain, Addr};
+handle_recv_pdu(
+ Domain, Addr, _Vsn, Pdu, _PduMS, _ACM, _Logger,
+ #state{server = Pid} = _State) when is_record(Pdu, pdu) ->
?vtrace("received pdu", []),
- Pid ! {snmp_pdu, Pdu, Addr, Port};
-handle_recv_pdu(_Addr, _Port, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) ->
+ Pid ! {snmp_pdu, Pdu, Domain, Addr};
+handle_recv_pdu(
+ _Domain, _Addr, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) ->
?vlog("received unexpected pdu: "
- "~n Pdu: ~p"
- "~n ACM: ~p", [Pdu, ACM]).
+ "~n Pdu: ~p"
+ "~n ACM: ~p", [Pdu, ACM]).
-handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Addr, Port, Logger, State) ->
+handle_inform_request(
+ auto, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State) ->
?vtrace("received inform-request (true)", []),
- Pid ! {snmp_inform, ignore, Pdu, Addr, Port},
+ Pid ! {snmp_inform, ignore, Pdu, Domain, Addr},
RePdu = make_response_pdu(Pdu),
- maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, State);
-handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
- ACM, Addr, Port, _Logger, _State) ->
+ maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Addr, Logger, State);
+handle_inform_request(
+ {user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
+ ACM, Domain, Addr, _Logger, _State) ->
?vtrace("received inform-request (false)", []),
- Pid ! {snmp_inform, ReqId, Pdu, Addr, Port},
+ Pid ! {snmp_inform, ReqId, Pdu, Domain, Addr},
%% Before we go any further, we need to check that we have not
%% already received this message (possible resend).
- Key = {ReqId, Addr, Port},
+ Key = {ReqId, Domain, Addr},
case ets:lookup(snmpm_inform_request_table, Key) of
[_] ->
%% OK, we already know about this. We assume this
@@ -676,39 +701,43 @@ handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
Rec = {Key, Expire, {Vsn, ACM, RePdu}},
ets:insert(snmpm_inform_request_table, Rec)
end.
-
-handle_inform_response(Ref, Addr, Port, State) ->
- Key = {Ref, Addr, Port},
+
+handle_inform_response(Ref, Domain, Addr, State) ->
+ Key = {Ref, Domain, Addr},
case ets:lookup(snmpm_inform_request_table, Key) of
[{Key, _, {Vsn, ACM, RePdu}}] ->
- Logger = logger(State#state.log, read, Addr, Port),
+ Logger = logger(State#state.log, read, Domain, Addr),
ets:delete(snmpm_inform_request_table, Key),
- maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port,
- Logger, State);
+ maybe_send_inform_response(
+ RePdu, Vsn, ACM, Domain, Addr, Logger, State);
[] ->
%% Already acknowledged, or the user was to slow to reply...
ok
end,
ok.
-maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger,
- #state{server = Pid,
- sock = Sock,
- filter = FilterMod}) ->
- case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(RePdu))) of
+maybe_send_inform_response(
+ RePdu, Vsn, ACM, Domain, Addr, Logger,
+ #state{server = Pid,
+ filter = FilterMod,
+ domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_send_pdu(
+ Arg1, Arg2, pdu_type_of(RePdu)))
+ of
false ->
inc(netIfPduOutDrops),
ok;
_ ->
case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of
{ok, Msg} ->
- maybe_udp_send(FilterMod, Sock, Addr, Port, Msg);
+ maybe_udp_send(Domain, Addr, Msg, State);
{discarded, Reason} ->
?vlog("failed generating response message:"
"~n Reason: ~p", [Reason]),
ReqId = RePdu#pdu.request_id,
ErrorInfo = {failed_generating_response, {RePdu, Reason}},
- Pid ! {snmp_error, ReqId, ErrorInfo, Addr, Port},
+ Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr},
ok
end
end.
@@ -743,28 +772,29 @@ irgc_stop(Ref) ->
(catch erlang:cancel_timer(Ref)).
-maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port,
- #state{filter = FilterMod} = State) ->
- case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of
+maybe_handle_send_pdu(
+ Pdu, Vsn, MsgData, Domain, Addr,
+ #state{filter = FilterMod, domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of
false ->
inc(netIfPduOutDrops),
ok;
_ ->
- handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State)
+ handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State)
end.
-handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port,
- #state{server = Pid,
- note_store = NoteStore,
- sock = Sock,
- log = Log,
- filter = FilterMod}) ->
- Logger = logger(Log, write, Addr, Port),
- case (catch snmpm_mpd:generate_msg(Vsn, NoteStore,
- Pdu, MsgData, Logger)) of
+handle_send_pdu(
+ Pdu, Vsn, MsgData, Domain, Addr,
+ #state{server = Pid,
+ note_store = NoteStore,
+ log = Log} = State) ->
+ Logger = logger(Log, write, Domain, Addr),
+ case (catch snmpm_mpd:generate_msg(
+ Vsn, NoteStore, Pdu, MsgData, Logger)) of
{ok, Msg} ->
?vtrace("handle_send_pdu -> message generated", []),
- maybe_udp_send(FilterMod, Sock, Addr, Port, Msg);
+ maybe_udp_send(Domain, Addr, Msg, State);
{discarded, Reason} ->
?vlog("PDU not sent: "
"~n PDU: ~p"
@@ -774,28 +804,34 @@ handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port,
end.
-maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) ->
- case (catch FilterMod:accept_send(Addr, Port)) of
+maybe_udp_send(
+ Domain, Addr, Msg,
+ #state{sock = Sock, filter = FilterMod, domain = ManagerDomain}) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_send(Arg1, Arg2)) of
false ->
inc(netIfMsgOutDrops),
ok;
_ ->
- udp_send(Sock, Addr, Port, Msg)
+ %% XXX There should be some kind of lookup of socket
+ %% from transport domain here
+ {Ip, Port} = Addr,
+ udp_send(Sock, Ip, Port, Msg)
end.
-udp_send(Sock, Addr, Port, Msg) ->
- case (catch gen_udp:send(Sock, Addr, Port, Msg)) of
+udp_send(Sock, Ip, Port, Msg) ->
+ case (catch gen_udp:send(Sock, Ip, Port, Msg)) of
ok ->
?vdebug("sent ~w bytes to ~w:~w [~w]",
- [sz(Msg), Addr, Port, Sock]),
+ [sz(Msg), Ip, Port, Sock]),
ok;
{error, Reason} ->
error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Reason]);
+ "~n ~p",[Ip, Port, Reason]);
Error ->
error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Error])
+ "~n ~p",[Ip, Port, Error])
end.
sz(B) when is_binary(B) ->
@@ -989,6 +1025,26 @@ handle_set_log_type(State, _NewType) ->
{State, {error, not_enabled}}.
+%% If the manager uses legacy snmpUDPDomain e.g has not set
+%% {domain, _}, then make sure snmpm_network_interface_filter
+%% gets legacy arguments to not break backwards compatibility.
+%%
+fix_filter_address(snmpUDPDomain, {Domain, Addr})
+ when Domain =:= snmpUDPDomain;
+ Domain =:= transportDomainUdpIpv4 ->
+ Addr;
+fix_filter_address(_ManagerDomain, {Domain, _} = Address)
+ when is_atom(Domain) ->
+ Address;
+fix_filter_address(snmpUDPDomain, {_, Port} = Addr)
+ when is_integer(Port) ->
+ Addr.
+
+address(Domain, Addr) when is_atom(Domain) ->
+ {Domain, Addr};
+address(Ip, Port) when is_integer(Port) ->
+ {snmpm_config:default_transport_domain(), {Ip, Port}}.
+
%% -------------------------------------------------------------------
make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) ->
@@ -1029,15 +1085,17 @@ t() ->
%% -------------------------------------------------------------------
-logger(undefined, _Type, _Addr, _Port) ->
+logger(undefined, _Type, _Domain, _Addr) ->
fun(_) ->
ok
end;
-logger({Log, Types}, Type, Addr, Port) ->
+logger({Log, Types}, Type, Domain, Addr) ->
case lists:member(Type, Types) of
true ->
+ AddrString =
+ iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})),
fun(Msg) ->
- snmp_log:log(Log, Msg, Addr, Port)
+ snmp_log:log(Log, Msg, AddrString)
end;
false ->
fun(_) ->
diff --git a/lib/snmp/src/manager/snmpm_net_if_filter.erl b/lib/snmp/src/manager/snmpm_net_if_filter.erl
index eb0c6efb11..d96ae5c145 100644
--- a/lib/snmp/src/manager/snmpm_net_if_filter.erl
+++ b/lib/snmp/src/manager/snmpm_net_if_filter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,29 +25,51 @@
-include("snmp_debug.hrl").
-accept_recv(_Addr, _Port) ->
- ?d("accept_recv -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p", [_Addr, _Port]),
+accept_recv(Domain, _Address) when is_atom(Domain) ->
+ ?d("accept_recv -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p", [Domain, _Address]),
+ true;
+accept_recv(_Addr, Port) when is_integer(Port) ->
+ ?d("accept_recv -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p", [_Addr, Port]),
true.
-accept_send(_Addr, _Port) ->
- ?d("accept_send -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p", [_Addr, _Port]),
+accept_send(Domain, _Address) when is_atom(Domain) ->
+ ?d("accept_send -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p", [Domain, _Address]),
+ true;
+accept_send(_Addr, Port) when is_integer(Port) ->
+ ?d("accept_send -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p", [_Addr, Port]),
true.
-accept_recv_pdu(_Addr, _Port, _PduType) ->
- ?d("accept_recv_pdu -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n PduType: ~p", [_Addr, _Port, _PduType]),
+accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) ->
+ ?d("accept_recv_pdu -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p~n"
+ " PduType: ~p", [Domain, _Address, _PduType]),
+ true;
+accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) ->
+ ?d("accept_recv_pdu -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p~n"
+ " PduType: ~p", [_Addr, Port, _PduType]),
true.
-accept_send_pdu(_Addr, _Port, _PduType) ->
- ?d("accept_send_pdu -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n PduType: ~p", [_Addr, _Port, _PduType]),
+accept_send_pdu(Domain, _Address, _PduType) when is_atom(Domain) ->
+ ?d("accept_send_pdu -> entry with~n"
+ " Domain: ~p~n"
+ " Address: ~p~n"
+ " PduType: ~p", [Domain, _Address, _PduType]),
+ true;
+accept_send_pdu(_Addr, Port, _PduType) when is_integer(Port) ->
+ ?d("accept_send_pdu -> entry with~n"
+ " Addr: ~p~n"
+ " Port: ~p~n"
+ " PduType: ~p", [_Addr, Port, _PduType]),
true.
diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl
index 3e87f6a7fb..2937f5cc87 100644
--- a/lib/snmp/src/manager/snmpm_net_if_mt.erl
+++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,9 +27,9 @@
-export([
start_link/2,
stop/1,
- send_pdu/6, % Backward compatibillity
- send_pdu/7, % Backward compatibillity
- send_pdu/8,
+ send_pdu/6, % Backward compatibility
+ send_pdu/7, % Partly backward compatibility
+ send_pdu/8, % Backward compatibility
inform_response/4,
@@ -55,13 +55,14 @@
%% -define(VMODULE,"NET_IF").
-include("snmp_verbosity.hrl").
--record(state,
+-record(state,
{
server,
note_store,
- sock,
+ domain,
+ sock,
mpd_state,
- log,
+ log,
irb = auto, % auto | {user, integer()}
irgc,
filter
@@ -99,30 +100,32 @@ start_link(Server, NoteStore) ->
stop(Pid) ->
call(Pid, stop).
-send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) ->
- send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO).
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port) ->
+ send_pdu(
+ Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ?DEFAULT_EXTRA_INFO).
-send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) ->
- Domain = snmpm_config:default_transport_domain(),
- send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo).
-
-send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo)
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ExtraInfo)
when is_record(Pdu, pdu) ->
- ?d("send_pdu -> entry with"
- "~n Pid: ~p"
- "~n Pdu: ~p"
- "~n Vsn: ~p"
- "~n MsgData: ~p"
- "~n Domain: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]),
- cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}).
+ ?d("send_pdu -> entry with~n"
+ " Pid: ~p~n"
+ " Pdu: ~p~n"
+ " Vsn: ~p~n"
+ " MsgData: ~p~n"
+ " Domain/IP: ~p~n"
+ " Addr/Port : ~p",
+ [Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port]),
+ {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port),
+ cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}).
+
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) ->
+ send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo).
note_store(Pid, NoteStore) ->
call(Pid, {note_store, NoteStore}).
-inform_response(Pid, Ref, Addr, Port) ->
- cast(Pid, {inform_response, Ref, Addr, Port}).
+inform_response(Pid, Ref, Domain_or_Ip, Addr_or_Port) ->
+ {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port),
+ cast(Pid, {inform_response, Ref, Domain, Addr}).
info(Pid) ->
call(Pid, info).
@@ -202,7 +205,14 @@ do_init(Server, NoteStore) ->
BindTo = get_opt(Opts, bind_to, false),
NoReuse = get_opt(Opts, no_reuse, false),
{ok, Port} = snmpm_config:system_info(port),
- {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, BindTo, NoReuse),
+ Domain =
+ case snmpm_config:system_info(domain) of
+ {ok, D} ->
+ D;
+ _ ->
+ snmpm_config:default_transport_domain()
+ end,
+ {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, Domain, BindTo, NoReuse),
%% Flow control --
FilterOpts = get_opt(Opts, filter, []),
@@ -218,10 +228,11 @@ do_init(Server, NoteStore) ->
init_counters(),
%% -- We are done ---
- State = #state{server = Server,
- note_store = NoteStore,
+ State = #state{server = Server,
+ note_store = NoteStore,
mpd_state = MpdState,
- sock = Sock,
+ domain = Domain,
+ sock = Sock,
log = Log,
irb = IRB,
irgc = IrGcRef,
@@ -231,19 +242,24 @@ do_init(Server, NoteStore) ->
%% Open port
-do_open_port(Port, SendSz, RecvSz, BindTo, NoReuse) ->
- ?vtrace("do_open_port -> entry with"
- "~n Port: ~p"
- "~n SendSz: ~p"
- "~n RecvSz: ~p"
- "~n BindTo: ~p"
- "~n NoReuse: ~p", [Port, SendSz, RecvSz, BindTo, NoReuse]),
+do_open_port(Port, SendSz, RecvSz, Domain, BindTo, NoReuse) ->
+ ?vtrace("do_open_port -> entry with~n"
+ " Port: ~p~n"
+ " SendSz: ~p~n"
+ " RecvSz: ~p~n"
+ " Domain: ~p~n"
+ " BindTo: ~p~n"
+ " NoReuse: ~p",
+ [Port, SendSz, RecvSz, Domain, BindTo, NoReuse]),
IpOpts1 = bind_to(BindTo),
IpOpts2 = no_reuse(NoReuse),
IpOpts3 = recbuf(RecvSz),
IpOpts4 = sndbuf(SendSz),
- IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
- OpenRes =
+ IpOpts =
+ [binary,
+ snmp_conf:tdomain_to_family(Domain) |
+ IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
+ OpenRes =
case init:get_argument(snmpm_fd) of
{ok, [[FdStr]]} ->
Fd = list_to_integer(FdStr),
@@ -396,25 +412,24 @@ handle_call(Req, From, State) ->
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
-handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo},
+handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo},
State) ->
- ?vlog("received send_pdu message with"
- "~n Pdu: ~p"
- "~n Vsn: ~p"
- "~n MsgData: ~p"
- "~n Domain: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]),
- maybe_process_extra_info(ExtraInfo),
- handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State),
+ ?vlog("received send_pdu message with~n"
+ " Pdu: ~p~n"
+ " Vsn: ~p~n"
+ " MsgData: ~p~n"
+ " Domain: ~p~n"
+ " Addr: ~p", [Pdu, Vsn, MsgData, Domain, Addr]),
+ maybe_process_extra_info(ExtraInfo),
+ handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State),
{noreply, State};
-handle_cast({inform_response, Ref, Addr, Port}, State) ->
- ?vlog("received inform_response message with"
- "~n Ref: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Ref, Addr, Port]),
- handle_inform_response(Ref, Addr, Port, State),
+handle_cast({inform_response, Ref, Domain, Addr}, State) ->
+ ?vlog("received inform_response message with~n"
+ " Ref: ~p~n"
+ " Domain: ~p~n"
+ " Addr: ~p", [Ref, Domain, Addr]),
+ handle_inform_response(Ref, Domain, Addr, State),
{noreply, State};
handle_cast(filter_reset, State) ->
@@ -433,9 +448,11 @@ handle_cast(Msg, State) ->
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
-handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) ->
+handle_info(
+ {udp, Sock, Ip, Port, Bytes},
+ #state{sock = Sock, domain = Domain} = State) ->
?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]),
- handle_udp(Ip, Port, Bytes, State),
+ handle_udp(Domain, {Ip, Port}, Bytes, State),
{noreply, State};
handle_info(inform_response_gc, State) ->
@@ -500,60 +517,64 @@ code_change(_Vsn, State, _Extra) ->
%%% Internal functions
%%%-------------------------------------------------------------------
-handle_udp(Addr, Port, Bytes, State) ->
- Verbosity = get(verbosity),
- spawn_opt(fun() ->
- Log = worker_init(State, Verbosity),
- Res = (catch maybe_handle_recv_msg(
- Addr, Port, Bytes,
- State#state{log = Log})),
- worker_exit(udp, {Addr, Port}, Res)
- end,
- [monitor]).
-
-
-maybe_handle_recv_msg(Addr, Port, Bytes, #state{filter = FilterMod} = State) ->
- case (catch FilterMod:accept_recv(Addr, Port)) of
+handle_udp(Domain, Addr, Bytes, State) ->
+ Verbosity = get(verbosity),
+ spawn_opt(
+ fun() ->
+ Log = worker_init(State, Verbosity),
+ Res =
+ (catch maybe_handle_recv_msg(
+ Domain, Addr, Bytes,
+ State#state{log = Log})),
+ worker_exit(udp, {Domain, Addr}, Res)
+ end,
+ [monitor]).
+
+
+maybe_handle_recv_msg(
+ Domain, Addr, Bytes,
+ #state{filter = FilterMod, domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_recv(Arg1, Arg2)) of
false ->
- %% Drop the received packet
+ %% Drop the received packet
inc(netIfMsgInDrops),
ok;
_ ->
- handle_recv_msg(Addr, Port, Bytes, State)
+ handle_recv_msg(Domain, Addr, Bytes, State)
end.
-handle_recv_msg(Addr, Port, Bytes, #state{server = Pid})
+handle_recv_msg(Domain, Addr, Bytes, #state{server = Pid})
when is_binary(Bytes) andalso (size(Bytes) =:= 0) ->
- Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port},
+ Pid ! {snmp_error, {empty_message, Domain, Addr}, Domain, Addr},
ok;
-handle_recv_msg(Addr, Port, Bytes,
- #state{server = Pid,
- note_store = NoteStore,
- mpd_state = MpdState,
- sock = Sock,
- log = Log} = State) ->
- Domain = snmp_conf:which_domain(Addr), % What the ****...
- Logger = logger(Log, read, Addr, Port),
- case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port,
+handle_recv_msg(
+ Domain, Addr, Bytes,
+ #state{server = Pid,
+ note_store = NoteStore,
+ mpd_state = MpdState,
+ log = Log} = State) ->
+ Logger = logger(Log, read, Domain, Addr),
+ case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr,
MpdState, NoteStore, Logger)) of
{ok, Vsn, Pdu, MS, ACM} ->
- maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, MS, ACM,
+ maybe_handle_recv_pdu(Domain, Addr, Vsn, Pdu, MS, ACM,
Logger, State);
{discarded, Reason, Report} ->
?vdebug("discarded: ~p", [Reason]),
ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Addr, Port},
- maybe_udp_send(State#state.filter, Sock, Addr, Port, Report),
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr},
+ maybe_udp_send(Domain, Addr, Report, State),
ok;
{discarded, Reason} ->
?vdebug("discarded: ~p", [Reason]),
ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Addr, Port},
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr},
ok;
Error ->
@@ -563,94 +584,100 @@ handle_recv_msg(Addr, Port, Bytes,
end.
-maybe_handle_recv_pdu(Addr, Port,
- Vsn, #pdu{type = Type} = Pdu, PduMS, ACM,
- Logger,
- #state{filter = FilterMod} = State) ->
- case (catch FilterMod:accept_recv_pdu(Addr, Port, Type)) of
+maybe_handle_recv_pdu(
+ Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger,
+ #state{filter = FilterMod, domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of
false ->
inc(netIfPduInDrops),
ok;
_ ->
- handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State)
+ handle_recv_pdu(
+ Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State)
end;
-maybe_handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger,
- #state{filter = FilterMod} = State)
+maybe_handle_recv_pdu(
+ Domain, Addr, Vsn, Trap, PduMS, ACM, Logger,
+ #state{filter = FilterMod, domain = ManagerDomain} = State)
when is_record(Trap, trappdu) ->
- case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of
false ->
inc(netIfPduInDrops),
ok;
_ ->
- handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, State)
+ handle_recv_pdu(
+ Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, State)
end;
-maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) ->
- handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State).
-
-
-handle_recv_pdu(Addr, Port,
- Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM,
- Logger, #state{server = Pid, irb = IRB} = State) ->
- handle_inform_request(IRB, Pid, Vsn, Pdu, ACM,
- Addr, Port, Logger, State);
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = report} = Pdu, _PduMS, ok,
- _Logger,
- #state{server = Pid} = _State) ->
+maybe_handle_recv_pdu(
+ Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) ->
+ handle_recv_pdu(Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State).
+
+
+handle_recv_pdu(
+ Domain, Addr, Vsn,
+ #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger,
+ #state{server = Pid, irb = IRB} = State) ->
+ handle_inform_request(
+ IRB, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State);
+handle_recv_pdu(
+ Domain, Addr, _Vsn,
+ #pdu{type = report} = Pdu, _PduMS, ok, _Logger,
+ #state{server = Pid} = _State) ->
?vtrace("received report - ok", []),
- Pid ! {snmp_report, {ok, Pdu}, Addr, Port},
+ Pid ! {snmp_report, {ok, Pdu}, Domain, Addr},
ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = report} = Pdu, _PduMS,
- {error, ReqId, Reason},
- _Logger,
- #state{server = Pid} = _State) ->
+handle_recv_pdu(
+ Domain, Addr, _Vsn,
+ #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger,
+ #state{server = Pid} = _State) ->
?vtrace("received report - error", []),
- Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Addr, Port},
+ Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Addr},
ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) ->
+handle_recv_pdu(
+ Domain, Addr, _Vsn,
+ #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger,
+ #state{server = Pid} = _State) ->
?vtrace("received snmpv2-trap", []),
- Pid ! {snmp_trap, Pdu, Addr, Port},
+ Pid ! {snmp_trap, Pdu, Domain, Addr},
ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, Trap, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) when is_record(Trap, trappdu) ->
+handle_recv_pdu(
+ Domain, Addr, _Vsn, Trap, _PduMS, _ACM, _Logger,
+ #state{server = Pid} = _State) when is_record(Trap, trappdu) ->
?vtrace("received trappdu", []),
- Pid ! {snmp_trap, Trap, Addr, Port},
+ Pid ! {snmp_trap, Trap, Domain, Addr},
ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, Pdu, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) when is_record(Pdu, pdu) ->
+handle_recv_pdu(
+ Domain, Addr, _Vsn, Pdu, _PduMS, _ACM, _Logger,
+ #state{server = Pid} = _State) when is_record(Pdu, pdu) ->
?vtrace("received pdu", []),
- Pid ! {snmp_pdu, Pdu, Addr, Port},
+ Pid ! {snmp_pdu, Pdu, Domain, Addr},
ok;
-handle_recv_pdu(_Addr, _Port, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) ->
+handle_recv_pdu(
+ _Domain, _Addr, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) ->
?vlog("received unexpected pdu: "
"~n Pdu: ~p"
"~n ACM: ~p", [Pdu, ACM]),
ok.
-handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Addr, Port, Logger, State) ->
+handle_inform_request(
+ auto, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State) ->
?vtrace("received inform-request (true)", []),
- Pid ! {snmp_inform, ignore, Pdu, Addr, Port},
+ Pid ! {snmp_inform, ignore, Pdu, Domain, Addr},
RePdu = make_response_pdu(Pdu),
- maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, State);
-handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
- ACM, Addr, Port, _Logger, _State) ->
+ maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Addr, Logger, State);
+handle_inform_request(
+ {user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
+ ACM, Domain, Addr, _Logger, _State) ->
?vtrace("received inform-request (false)", []),
- Pid ! {snmp_inform, ReqId, Pdu, Addr, Port},
+ Pid ! {snmp_inform, ReqId, Pdu, Domain, Addr},
%% Before we go any further, we need to check that we have not
%% already received this message (possible resend).
- Key = {ReqId, Addr, Port},
+ Key = {ReqId, Domain, Addr},
case ets:lookup(snmpm_inform_request_table, Key) of
[_] ->
%% OK, we already know about this. We assume this
@@ -664,53 +691,58 @@ handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
ets:insert(snmpm_inform_request_table, Rec)
end,
ok.
-
-handle_inform_response(Ref, Addr, Port, State) ->
- Verbosity = get(verbosity),
- spawn_opt(fun() ->
- Log = worker_init(State, Verbosity),
- Res = (catch do_handle_inform_response(
- Ref,
- Addr, Port,
- State#state{log = Log})),
- worker_exit(inform_reponse, {Addr, Port}, Res)
- end,
- [monitor]).
-
+
+handle_inform_response(Ref, Domain, Addr, State) ->
+ Verbosity = get(verbosity),
+ spawn_opt(
+ fun() ->
+ Log = worker_init(State, Verbosity),
+ Res = (catch do_handle_inform_response(
+ Ref, Domain, Addr, State#state{log = Log})),
+ worker_exit(inform_response, {Domain, Addr}, Res)
+ end,
+ [monitor]).
+
-do_handle_inform_response(Ref, Addr, Port, State) ->
- Key = {Ref, Addr, Port},
+do_handle_inform_response(Ref, Domain, Addr, State) ->
+ Key = {Ref, Domain, Addr},
case ets:lookup(snmpm_inform_request_table, Key) of
[{Key, _, {Vsn, ACM, RePdu}}] ->
- Logger = logger(State#state.log, read, Addr, Port),
+ Logger = logger(State#state.log, read, Domain, Addr),
ets:delete(snmpm_inform_request_table, Key),
- maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port,
- Logger, State);
+ maybe_send_inform_response(
+ RePdu, Vsn, ACM, Domain, Addr, Logger, State);
[] ->
%% Already acknowledged, or the user was to slow to reply...
ok
end,
ok.
-maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger,
- #state{server = Pid,
- sock = Sock,
- filter = FilterMod}) ->
- case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(RePdu))) of
+maybe_send_inform_response(
+ RePdu, Vsn, ACM, Domain, Addr, Logger,
+ #state{server = Pid,
+ sock = Sock,
+ domain = ManagerDomain,
+ filter = FilterMod}) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_send_pdu(
+ Arg1, Arg2, pdu_type_of(RePdu)))
+ of
false ->
inc(netIfPduOutDrops),
ok;
_ ->
case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of
{ok, Msg} ->
- maybe_udp_send(FilterMod, Sock, Addr, Port, Msg);
+ maybe_udp_send(
+ Domain, Addr, Msg, Sock, FilterMod, ManagerDomain);
{discarded, Reason} ->
?vlog("failed generating response message:"
"~n Reason: ~p", [Reason]),
ReqId = RePdu#pdu.request_id,
ErrorInfo = {failed_generating_response, {RePdu, Reason}},
- Pid ! {snmp_error, ReqId, ErrorInfo, Addr, Port},
+ Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr},
ok
end
end.
@@ -745,40 +777,42 @@ irgc_stop(Ref) ->
(catch erlang:cancel_timer(Ref)).
-handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) ->
- Verbosity = get(verbosity),
- spawn_opt(fun() ->
- Log = worker_init(State, Verbosity),
- Res = (catch maybe_handle_send_pdu(
- Pdu, Vsn, MsgData,
- Domain, Addr, Port,
- State#state{log = Log})),
- worker_exit(send_pdu, {Domain, Addr, Port}, Res)
- end,
- [monitor]).
-
-maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port,
- #state{filter = FilterMod} = State) ->
- case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of
+handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State) ->
+ Verbosity = get(verbosity),
+ spawn_opt(
+ fun() ->
+ Log = worker_init(State, Verbosity),
+ Res = (catch maybe_handle_send_pdu(
+ Pdu, Vsn, MsgData,
+ Domain, Addr,
+ State#state{log = Log})),
+ worker_exit(send_pdu, {Domain, Addr}, Res)
+ end,
+ [monitor]).
+
+maybe_handle_send_pdu(
+ Pdu, Vsn, MsgData, Domain, Addr,
+ #state{filter = FilterMod, domain = ManagerDomain} = State) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of
false ->
inc(netIfPduOutDrops),
ok;
_ ->
- do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State)
+ do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State)
end.
-do_handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port,
- #state{server = Pid,
- note_store = NoteStore,
- sock = Sock,
- log = Log,
- filter = FilterMod}) ->
- Logger = logger(Log, write, Addr, Port),
- case (catch snmpm_mpd:generate_msg(Vsn, NoteStore,
- Pdu, MsgData, Logger)) of
+do_handle_send_pdu(
+ Pdu, Vsn, MsgData, Domain, Addr,
+ #state{server = Pid,
+ note_store = NoteStore,
+ log = Log} = State) ->
+ Logger = logger(Log, write, Domain, Addr),
+ case (catch snmpm_mpd:generate_msg(
+ Vsn, NoteStore, Pdu, MsgData, Logger)) of
{ok, Msg} ->
?vtrace("do_handle_send_pdu -> message generated", []),
- maybe_udp_send(FilterMod, Sock, Addr, Port, Msg);
+ maybe_udp_send(Domain, Addr, Msg, State);
{discarded, Reason} ->
?vlog("PDU not sent: "
"~n PDU: ~p"
@@ -787,30 +821,38 @@ do_handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port,
ok
end.
+maybe_udp_send(
+ Domain, Addr, Msg,
+ #state{sock = Sock, filter = FilterMod, domain = ManagerDomain}) ->
+ maybe_udp_send(Domain, Addr, Msg, Sock, FilterMod, ManagerDomain).
-maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) ->
- case (catch FilterMod:accept_send(Addr, Port)) of
+maybe_udp_send(Domain, Addr, Msg, Sock, FilterMod, ManagerDomain) ->
+ {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ case (catch FilterMod:accept_send(Arg1, Arg2)) of
false ->
inc(netIfMsgOutDrops),
ok;
_ ->
- udp_send(Sock, Addr, Port, Msg)
+ %% XXX There should be some kind of lookup of socket
+ %% from transport domain here
+ {Ip, Port} = Addr,
+ udp_send(Sock, Ip, Port, Msg)
end.
-udp_send(Sock, Addr, Port, Msg) ->
- case (catch gen_udp:send(Sock, Addr, Port, Msg)) of
+udp_send(Sock, Ip, Port, Msg) ->
+ case (catch gen_udp:send(Sock, Ip, Port, Msg)) of
ok ->
?vdebug("sent ~w bytes to ~w:~w [~w]",
- [sz(Msg), Addr, Port, Sock]),
+ [sz(Msg), Ip, Port, Sock]),
ok;
{error, Reason} ->
error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Reason]),
+ "~n ~p", [Ip, Port, Reason]),
ok;
Error ->
error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Error]),
+ "~n ~p", [Ip, Port, Error]),
ok
end.
@@ -1036,25 +1078,48 @@ worker_exit(Tag, Info, Result) ->
handle_worker_exit(_, {_, _, ok}) ->
ok;
-handle_worker_exit(Pid, {udp, {Addr, Port}, ExitStatus}) ->
- warning_msg("Worker process (~p) terminated "
- "while processing (incomming) message from ~w:~w: "
- "~n~p", [Pid, Addr, Port, ExitStatus]),
+handle_worker_exit(Pid, {udp, {Domain, Addr}, ExitStatus}) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (incomming) message from %s:~n"
+ "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]),
ok;
-handle_worker_exit(Pid, {send_pdu, {Domain, Addr, Port}, ExitStatus}) ->
- warning_msg("Worker process (~p) terminated "
- "while processing (outgoing) pdu for [~w] ~w:~w: "
- "~n~p", [Pid, Domain, Addr, Port, ExitStatus]),
+handle_worker_exit(Pid, {send_pdu, {Domain, Addr}, ExitStatus}) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (outgoing) pdu for %s:~n"
+ "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]),
ok;
-handle_worker_exit(Pid, {inform_response, {Addr, Port}, ExitStatus}) ->
- warning_msg("Worker process (~p) terminated "
- "while processing (outgoing) inform response for ~w:~w: "
- "~n~p", [Pid, Addr, Port, ExitStatus]),
+handle_worker_exit(Pid, {inform_response, {Domain, Addr}, ExitStatus}) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (outgoing) inform response for %s:~n"
+ "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]),
ok;
handle_worker_exit(_, _) ->
ok.
+%% If the manager uses legacy snmpUDPDomain e.g has not set
+%% {domain, _}, then make sure snmpm_network_interface_filter
+%% gets legacy arguments to not break backwards compatibility.
+%%
+fix_filter_address(snmpUDPDomain, {Domain, Addr})
+ when Domain =:= snmpUDPDomain;
+ Domain =:= transportDomainUdpIpv4 ->
+ Addr;
+fix_filter_address(_ManagerDomain, {Domain, _} = Address)
+ when is_atom(Domain) ->
+ Address;
+fix_filter_address(snmpUDPDomain, {_, Port} = Addr)
+ when is_integer(Port) ->
+ Addr.
+
+address(Domain, Addr) when is_atom(Domain) ->
+ {Domain, Addr};
+address(Ip, Port) when is_integer(Port) ->
+ {snmpm_config:default_transport_domain(), {Ip, Port}}.
+
%% -------------------------------------------------------------------
make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) ->
@@ -1095,15 +1160,17 @@ t() ->
%% -------------------------------------------------------------------
-logger(undefined, _Type, _Addr, _Port) ->
+logger(undefined, _Type, _Domain, _Addr) ->
fun(_) ->
ok
end;
-logger({_Name, Log, Types}, Type, Addr, Port) ->
+logger({_Name, Log, Types}, Type, Domain, Addr) ->
case lists:member(Type, Types) of
true ->
+ AddrString =
+ iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})),
fun(Msg) ->
- snmp_log:log(Log, Msg, Addr, Port)
+ snmp_log:log(Log, Msg, Domain, AddrString)
end;
false ->
fun(_) ->
@@ -1256,4 +1323,3 @@ call(Pid, Req, Timeout) ->
cast(Pid, Msg) ->
gen_server:cast(Pid, Msg).
-
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 9c79df2748..ece5dad082 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -163,8 +163,7 @@
reg_type,
target,
domain,
- addr,
- port,
+ address,
type,
data,
ref,
@@ -1033,14 +1032,14 @@ handle_info({snmp_error, Pdu, Reason}, State) ->
handle_snmp_error(Pdu, Reason, State),
{noreply, State};
-handle_info({snmp_error, Reason, Addr, Port}, State) ->
+handle_info({snmp_error, Reason, Domain, Addr}, State) ->
?vlog("received snmp_error message", []),
- handle_snmp_error(Addr, Port, -1, Reason, State),
+ handle_snmp_error(Domain, Addr, -1, Reason, State),
{noreply, State};
-handle_info({snmp_error, ReqId, Reason, Addr, Port}, State) ->
+handle_info({snmp_error, ReqId, Reason, Domain, Addr}, State) ->
?vlog("received snmp_error message", []),
- handle_snmp_error(Addr, Port, ReqId, Reason, State),
+ handle_snmp_error(Domain, Addr, ReqId, Reason, State),
{noreply, State};
%% handle_info({snmp_error, ReqId, Pdu, Reason, Addr, Port}, State) ->
@@ -1049,30 +1048,30 @@ handle_info({snmp_error, ReqId, Reason, Addr, Port}, State) ->
%% {noreply, State};
-handle_info({snmp_pdu, Pdu, Addr, Port}, State) ->
+handle_info({snmp_pdu, Pdu, Domain, Addr}, State) ->
?vlog("received snmp_pdu message", []),
- handle_snmp_pdu(Pdu, Addr, Port, State),
+ handle_snmp_pdu(Pdu, Domain, Addr, State),
{noreply, State};
-handle_info({snmp_trap, Trap, Addr, Port}, State) ->
+handle_info({snmp_trap, Trap, Domain, Addr}, State) ->
?vlog("received snmp_trap message", []),
- handle_snmp_trap(Trap, Addr, Port, State),
+ handle_snmp_trap(Trap, Domain, Addr, State),
{noreply, State};
-handle_info({snmp_inform, Ref, Pdu, Addr, Port}, State) ->
+handle_info({snmp_inform, Ref, Pdu, Domain, Addr}, State) ->
?vlog("received snmp_inform message", []),
- handle_snmp_inform(Ref, Pdu, Addr, Port, State),
+ handle_snmp_inform(Ref, Pdu, Domain, Addr, State),
{noreply, State};
-handle_info({snmp_report, {ok, Pdu}, Addr, Port}, State) ->
- handle_snmp_report(Pdu, Addr, Port, State),
+handle_info({snmp_report, {ok, Pdu}, Domain, Addr}, State) ->
+ handle_snmp_report(Pdu, Domain, Addr, State),
{noreply, State};
-handle_info({snmp_report, {error, ReqId, Info, Pdu}, Addr, Port}, State) ->
- handle_snmp_report(ReqId, Pdu, Info, Addr, Port, State),
+handle_info({snmp_report, {error, ReqId, Info, Pdu}, Domain, Addr}, State) ->
+ handle_snmp_report(ReqId, Pdu, Info, Domain, Addr, State),
{noreply, State};
@@ -1176,11 +1175,11 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) ->
"~n From: ~p",
[Pid, UserId, TargetName, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_sync_get -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_request(Oids, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
Extra, State),
?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
@@ -1193,8 +1192,7 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) ->
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = get,
data = MsgData,
ref = Ref,
@@ -1230,11 +1228,11 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts,
"~n From: ~p",
[Pid, UserId, TargetName, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
Extra, State),
?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
@@ -1247,12 +1245,11 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts,
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = get_next,
data = MsgData,
ref = Ref,
- mon = MonRef,
+ mon = MonRef,
from = From},
ets:insert(snmpm_request_table, Req),
ok;
@@ -1290,11 +1287,11 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts,
"~n From: ~p",
[Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_bulk_request(Oids, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
NonRep, MaxRep, Extra, State),
?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
@@ -1307,8 +1304,7 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts,
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = get_bulk,
data = MsgData,
ref = Ref,
@@ -1346,11 +1342,11 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) ->
"~n From: ~p",
[Pid, UserId, TargetName, VarsAndVals, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_sync_set -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
Extra, State),
?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
@@ -1363,8 +1359,7 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) ->
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = set,
data = MsgData,
ref = Ref,
@@ -1400,11 +1395,11 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_async_get -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_request(Oids, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
Extra, State),
?vdebug("handle_async_get -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_TIMEOUT(SendOpts),
@@ -1413,8 +1408,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = get,
data = MsgData,
expire = t() + Expire},
@@ -1450,11 +1444,11 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_async_get_next -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
Extra, State),
?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts),
@@ -1463,8 +1457,7 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) ->
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = get_next,
data = MsgData,
expire = t() + Expire},
@@ -1507,11 +1500,11 @@ handle_async_get_bulk(Pid,
"~n SendOpts: ~p",
[Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_bulk_request(Oids, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
NonRep, MaxRep, Extra, State),
?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts),
@@ -1520,8 +1513,7 @@ handle_async_get_bulk(Pid,
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = get_bulk,
data = MsgData,
expire = t() + Expire},
@@ -1556,11 +1548,11 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, VarsAndVals, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Vsn, MsgData} ->
?vtrace("handle_async_set -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
- Domain, Addr, Port,
+ Domain, Addr,
Extra, State),
?vdebug("handle_async_set -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_SET_TIMEOUT(SendOpts),
@@ -1569,8 +1561,7 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) ->
reg_type = RegType,
target = TargetName,
domain = Domain,
- addr = Addr,
- port = Port,
+ address = Addr,
type = set,
data = MsgData,
expire = t() + Expire},
@@ -1808,15 +1799,15 @@ handle_snmp_error(CrapError, Reason, _State) ->
"~n~p~n~p", [CrapError, Reason]),
ok.
-handle_snmp_error(Addr, Port, ReqId, Reason, State) ->
+handle_snmp_error(Domain, Addr, ReqId, Reason, State) ->
- ?vtrace("handle_snmp_error -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n ReqId: ~p"
- "~n Reason: ~p", [Addr, Port, ReqId, Reason]),
+ ?vtrace("handle_snmp_error -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " ReqId: ~p~n"
+ " Reason: ~p", [Domain, Addr, ReqId, Reason]),
- case snmpm_config:get_agent_user_id(Addr, Port) of
+ case snmpm_config:get_agent_user_id(Domain, Addr) of
{ok, UserId} ->
case snmpm_config:user_info(UserId) of
{ok, UserMod, UserData} ->
@@ -1831,7 +1822,7 @@ handle_snmp_error(Addr, Port, ReqId, Reason, State) ->
error_msg("failed retreiving the default user "
"info handling snmp error "
"<~p,~p>: ~n~w~n~w",
- [Addr, Port, ReqId, Reason])
+ [Domain, Addr, ReqId, Reason])
end
end;
_Error ->
@@ -1843,7 +1834,7 @@ handle_snmp_error(Addr, Port, ReqId, Reason, State) ->
error_msg("failed retreiving the default user "
"info handling snmp error "
"<~p,~p>: ~n~w~n~w",
- [Addr, Port, ReqId, Reason])
+ [Domain, Addr, ReqId, Reason])
end
end.
@@ -1867,12 +1858,12 @@ handle_error(_UserId, Mod, Reason, ReqId, Data, _State) ->
handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu,
- Addr, Port, State) ->
+ Domain, Addr, State) ->
- ?vtrace("handle_snmp_pdu(get-response) -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n Pdu: ~p", [Addr, Port, Pdu]),
+ ?vtrace("handle_snmp_pdu(get-response) -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " Pdu: ~p", [Domain, Addr, Pdu]),
case ets:lookup(snmpm_request_table, ReqId) of
@@ -1902,9 +1893,10 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu,
SnmpResponse = {EStatus, EIndex, Varbinds2},
case snmpm_config:user_info(UserId) of
{ok, UserMod, UserData} ->
- handle_pdu(UserId, UserMod,
- RegType, Target, Addr, Port,
- ReqId, SnmpResponse, UserData, State),
+ handle_pdu(
+ UserId, UserMod,
+ RegType, Target, Domain, Addr,
+ ReqId, SnmpResponse, UserData, State),
maybe_delete(Disco, ReqId);
_Error ->
%% reply to outstanding request, for which there is no
@@ -1912,15 +1904,16 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu,
%% Therefor send it to the default user
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
- handle_pdu(DefUserId, DefMod,
- RegType, Target, Addr, Port,
- ReqId, SnmpResponse, DefData, State),
+ handle_pdu(
+ DefUserId, DefMod,
+ RegType, Target, Domain, Addr,
+ ReqId, SnmpResponse, DefData, State),
maybe_delete(Disco, ReqId);
Error ->
error_msg("failed retreiving the default user "
"info handling pdu from "
"~p <~p,~p>: ~n~w~n~w",
- [Target, Addr, Port, Error, Pdu])
+ [Target, Domain, Addr, Error, Pdu])
end
end;
@@ -1974,7 +1967,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu,
varbinds = Varbinds} = Pdu,
Varbinds2 = fix_vbs_BITS(Varbinds),
SnmpInfo = {EStatus, EIndex, Varbinds2},
- case snmpm_config:get_agent_user_id(Addr, Port) of
+ case snmpm_config:get_agent_user_id(Domain, Addr) of
{ok, UserId} ->
%% A very late reply or a reply to a request
%% that has been cancelled.
@@ -1999,7 +1992,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu,
"user info handling (old) "
"pdu from "
"<~p,~p>: ~n~w~n~w",
- [Addr, Port, Error, Pdu])
+ [Domain, Addr, Error, Pdu])
end
end;
@@ -2016,28 +2009,30 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu,
"no agent info found", []),
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
- handle_agent(DefUserId, DefMod,
- Addr, Port,
- pdu, ignore,
- SnmpInfo, DefData, State);
+ handle_agent(
+ DefUserId, DefMod,
+ Domain, Addr,
+ pdu, ignore,
+ SnmpInfo, DefData, State);
Error ->
error_msg("failed retreiving the default user "
"info handling (old) pdu when no user "
"found from "
"<~p,~p>: ~n~w~n~w",
- [Addr, Port, Error, Pdu])
+ [Domain, Addr, Error, Pdu])
end
end
end;
-handle_snmp_pdu(CrapPdu, Addr, Port, _State) ->
+handle_snmp_pdu(CrapPdu, Domain, Addr, _State) ->
error_msg("received crap (snmp) Pdu from ~w:~w =>"
- "~p", [Addr, Port, CrapPdu]),
+ "~p", [Domain, Addr, CrapPdu]),
ok.
-handle_pdu(_UserId, Mod, target_name = _RegType, TargetName, _Addr, _Port,
- ReqId, SnmpResponse, Data, _State) ->
+handle_pdu(
+ _UserId, Mod, target_name = _RegType, TargetName, _Domain, _Addr,
+ ReqId, SnmpResponse, Data, _State) ->
?vtrace("handle_pdu(target_name) -> entry when"
"~n Mod: ~p", [Mod]),
F = fun() ->
@@ -2053,43 +2048,47 @@ handle_pdu(_UserId, Mod, target_name = _RegType, TargetName, _Addr, _Port,
end,
handle_callback(F),
ok;
-handle_pdu(_UserId, Mod, addr_port = _RegType, _TargetName, Addr, Port,
- ReqId, SnmpResponse, Data, _State) ->
+handle_pdu(
+ _UserId, Mod, addr_port = _RegType, _TargetName, _Domain, Addr,
+ ReqId, SnmpResponse, Data, _State) ->
?vtrace("handle_pdu(addr_port) -> entry when"
"~n Mod: ~p", [Mod]),
F = fun() ->
- (catch Mod:handle_pdu(Addr, Port, ReqId, SnmpResponse, Data))
+ {Ip, Port} = Addr,
+ (catch Mod:handle_pdu(Ip, Port, ReqId, SnmpResponse, Data))
end,
handle_callback(F),
ok.
-handle_agent(UserId, Mod, Addr, Port, Type, Ref, SnmpInfo, Data, State) ->
+handle_agent(UserId, Mod, Domain, Addr, Type, Ref, SnmpInfo, Data, State) ->
?vtrace("handle_agent -> entry when"
"~n UserId: ~p"
"~n Type: ~p"
"~n Mod: ~p", [UserId, Type, Mod]),
F = fun() ->
- do_handle_agent(UserId, Mod, Addr, Port,
+ do_handle_agent(UserId, Mod, Domain, Addr,
Type, Ref, SnmpInfo, Data, State)
end,
handle_callback(F),
ok.
do_handle_agent(DefUserId, DefMod,
- Addr, Port,
+ Domain, Addr,
Type, Ref,
SnmpInfo, DefData, State) ->
?vdebug("do_handle_agent -> entry when"
"~n DefUserId: ~p", [DefUserId]),
- try DefMod:handle_agent(Addr, Port, Type, SnmpInfo, DefData) of
+ try DefMod:handle_agent(Domain, Addr, Type, SnmpInfo, DefData) of
{register, UserId2, TargetName, Config} ->
?vtrace("do_handle_agent -> register: "
"~n UserId2: ~p"
"~n TargetName: ~p"
"~n Config: ~p",
[UserId2, TargetName, Config]),
- Config2 = ensure_present([{address, Addr}, {port, Port}], Config),
+ Config2 =
+ ensure_present(
+ [{tdomain, Domain}, {taddress, Addr}], Config),
Config3 = [{reg_type, target_name} | Config2],
case snmpm_config:register_agent(UserId2,
TargetName, Config3) of
@@ -2099,7 +2098,7 @@ do_handle_agent(DefUserId, DefMod,
error_msg("failed registering agent - "
"handling agent "
"~p <~p,~p>: ~n~w",
- [TargetName, Addr, Port, Reason]),
+ [TargetName, Domain, Addr, Reason]),
ok
end;
@@ -2108,31 +2107,33 @@ do_handle_agent(DefUserId, DefMod,
ok;
InvalidResult ->
- CallbackArgs = [Addr, Port, Type, SnmpInfo, DefData],
+ CallbackArgs = [Domain, Addr, Type, SnmpInfo, DefData],
handle_invalid_result(handle_agent, CallbackArgs, InvalidResult)
catch
error:{undef, _} when Type =:= pdu ->
%% Maybe, still on the old API
?vdebug("do_handle_agent -> maybe still on the old api", []),
- case (catch DefMod:handle_agent(Addr, Port, SnmpInfo, DefData)) of
+ {Ip, Port} = Addr,
+ case (catch DefMod:handle_agent(Ip, Port, SnmpInfo, DefData)) of
{register, UserId2, Config} ->
?vtrace("do_handle_agent -> register: "
"~n UserId2: ~p"
"~n Config: ~p", [UserId2, Config]),
- TargetName = mk_target_name(Addr, Port, Config),
- Config2 = [{reg_type, addr_port},
- {address, Addr},
- {port, Port} | Config],
- case snmpm_config:register_agent(UserId2,
- TargetName, Config2) of
+ TargetName = mk_target_name(Domain, Addr, Config),
+ Config2 =
+ ensure_present(
+ [{tdomain, Domain}, {taddress, Addr}], Config),
+ Config3 = [{reg_type, addr_port} | Config2],
+ case snmpm_config:register_agent(
+ UserId2, TargetName, Config3) of
ok ->
ok;
{error, Reason} ->
error_msg("failed registering agent - "
"handling agent "
"~p <~p,~p>: ~n~w",
- [TargetName, Addr, Port, Reason]),
+ [TargetName, Domain, Addr, Reason]),
ok
end;
{register, UserId2, TargetName, Config} ->
@@ -2141,18 +2142,19 @@ do_handle_agent(DefUserId, DefMod,
"~n TargetName: ~p"
"~n Config: ~p",
[UserId2, TargetName, Config]),
- Config2 = ensure_present([{address, Addr}, {port, Port}],
- Config),
+ Config2 =
+ ensure_present(
+ [{tdomain, Domain}, {taddress, Addr}], Config),
Config3 = [{reg_type, target_name} | Config2],
- case snmpm_config:register_agent(UserId2,
- TargetName, Config3) of
+ case snmpm_config:register_agent(
+ UserId2, TargetName, Config3) of
ok ->
ok;
{error, Reason} ->
error_msg("failed registering agent - "
"handling agent "
"~p <~p,~p>: ~n~w",
- [TargetName, Addr, Port, Reason]),
+ [TargetName, Domain, Addr, Reason]),
ok
end;
_Ignore ->
@@ -2170,34 +2172,38 @@ do_handle_agent(DefUserId, DefMod,
%% Backward compatibillity crap
RegType = target_name,
- Target = mk_target_name(Addr, Port, default_agent_config()),
+ Target = mk_target_name(Domain, Addr, default_agent_config()),
case Type of
report ->
SnmpInform = SnmpInfo,
- handle_report(DefUserId, DefMod,
- RegType, Target, Addr, Port,
- SnmpInform, DefData, State);
+ handle_report(
+ DefUserId, DefMod,
+ RegType, Target, Domain, Addr,
+ SnmpInform, DefData, State);
inform ->
SnmpInform = SnmpInfo,
- handle_inform(DefUserId, DefMod, Ref,
- RegType, Target, Addr, Port,
- SnmpInform, DefData, State);
+ handle_inform(
+ DefUserId, DefMod, Ref,
+ RegType, Target, Domain, Addr,
+ SnmpInform, DefData, State);
trap ->
SnmpTrapInfo = SnmpInfo,
- handle_trap(DefUserId, DefMod,
- RegType, Target, Addr, Port,
- SnmpTrapInfo, DefData, State);
+ handle_trap(
+ DefUserId, DefMod,
+ RegType, Target, Domain, Addr,
+ SnmpTrapInfo, DefData, State);
_ ->
- error_msg("failed delivering ~w info to default user - "
- "regarding agent "
- "<~p,~p>: ~n~w", [Type, Addr, Port, SnmpInfo])
+ error_msg(
+ "failed delivering ~w info to default user - "
+ "regarding agent "
+ "<~p,~p>: ~n~w", [Type, Domain, Addr, SnmpInfo])
end;
T:E ->
- CallbackArgs = [Addr, Port, Type, SnmpInfo, DefData],
+ CallbackArgs = [Domain, Addr, Type, SnmpInfo, DefData],
handle_invalid_result(handle_agent, CallbackArgs, T, E)
end.
@@ -2215,50 +2221,51 @@ ensure_present([{Key, _Val} = Elem|Ensure], Config) ->
%% Retrieve user info for this agent.
%% If this is an unknown agent, then use the default user
-handle_snmp_trap(#trappdu{enterprise = Enteprise,
- generic_trap = Generic,
- specific_trap = Spec,
- time_stamp = Timestamp,
- varbinds = Varbinds} = Trap,
- Addr, Port, State) ->
-
- ?vtrace("handle_snmp_trap [trappdu] -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n Trap: ~p", [Addr, Port, Trap]),
+handle_snmp_trap(
+ #trappdu{enterprise = Enteprise,
+ generic_trap = Generic,
+ specific_trap = Spec,
+ time_stamp = Timestamp,
+ varbinds = Varbinds} = Trap, Domain, Addr, State) ->
+
+ ?vtrace("handle_snmp_trap [trappdu] -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " Trap: ~p", [Domain, Addr, Trap]),
Varbinds2 = fix_vbs_BITS(Varbinds),
SnmpTrapInfo = {Enteprise, Generic, Spec, Timestamp, Varbinds2},
- do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State);
+ do_handle_snmp_trap(SnmpTrapInfo, Domain, Addr, State);
handle_snmp_trap(#pdu{error_status = EStatus,
error_index = EIndex,
varbinds = Varbinds} = Trap,
- Addr, Port, State) ->
+ Domain, Addr, State) ->
- ?vtrace("handle_snmp_trap [pdu] -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n Trap: ~p", [Addr, Port, Trap]),
+ ?vtrace("handle_snmp_trap [pdu] -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " Trap: ~p", [Domain, Addr, Trap]),
Varbinds2 = fix_vbs_BITS(Varbinds),
SnmpTrapInfo = {EStatus, EIndex, Varbinds2},
- do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State);
+ do_handle_snmp_trap(SnmpTrapInfo, Domain, Addr, State);
-handle_snmp_trap(CrapTrap, Addr, Port, _State) ->
+handle_snmp_trap(CrapTrap, Domain, Addr, _State) ->
error_msg("received crap (snmp) trap from ~w:~w =>"
- "~p", [Addr, Port, CrapTrap]),
+ "~p", [Domain, Addr, CrapTrap]),
ok.
-do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State) ->
- case snmpm_config:get_agent_user_info(Addr, Port) of
+do_handle_snmp_trap(SnmpTrapInfo, Domain, Addr, State) ->
+ case snmpm_config:get_agent_user_info(Domain, Addr) of
{ok, UserId, Target, RegType} ->
?vtrace("handle_snmp_trap -> found user: ~p", [UserId]),
case snmpm_config:user_info(UserId) of
{ok, Mod, Data} ->
- handle_trap(UserId, Mod,
- RegType, Target, Addr, Port,
- SnmpTrapInfo, Data, State);
+ handle_trap(
+ UserId, Mod,
+ RegType, Target, Domain, Addr,
+ SnmpTrapInfo, Data, State);
Error1 ->
%% User no longer exists, unregister agent
@@ -2270,66 +2277,72 @@ do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State) ->
%% Try use the default user
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
- handle_agent(DefUserId, DefMod,
- Addr, Port,
- trap, ignore,
- SnmpTrapInfo, DefData, State);
+ handle_agent(
+ DefUserId, DefMod,
+ Domain, Addr,
+ trap, ignore,
+ SnmpTrapInfo, DefData, State);
Error2 ->
- error_msg("failed retreiving the default "
- "user info handling report from "
- "~p <~p,~p>: ~n~w~n~w",
- [Target, Addr, Port,
- Error2, SnmpTrapInfo])
+ error_msg(
+ "failed retreiving the default "
+ "user info handling report from "
+ "~p <~p,~p>: ~n~w~n~w",
+ [Target, Domain, Addr,
+ Error2, SnmpTrapInfo])
end;
Error3 ->
%% Failed unregister agent,
%% now its getting messy...
- warning_msg("failed unregister agent ~p <~p,~p> "
- "belonging to non-existing "
- "user ~p, handling trap: "
- "~n Error: ~w"
- "~n Trap info: ~w",
- [Target, Addr, Port, UserId,
- Error3, SnmpTrapInfo])
+ warning_msg(
+ "failed unregister agent ~p <~p,~p> "
+ "belonging to non-existing "
+ "user ~p, handling trap: "
+ "~n Error: ~w"
+ "~n Trap info: ~w",
+ [Target, Domain, Addr, UserId,
+ Error3, SnmpTrapInfo])
end
end;
Error4 ->
%% Unknown agent, pass it on to the default user
?vlog("[trap] failed retreiving user id for agent <~p,~p>: "
- "~n ~p", [Addr, Port, Error4]),
+ "~n ~p", [Domain, Addr, Error4]),
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
- handle_agent(DefUserId, DefMod,
- Addr, Port,
- trap, ignore,
- SnmpTrapInfo, DefData, State);
+ handle_agent(
+ DefUserId, DefMod,
+ Domain, Addr,
+ trap, ignore,
+ SnmpTrapInfo, DefData, State);
Error5 ->
- error_msg("failed retreiving "
- "the default user info handling trap from "
- "<~p,~p>: ~n~w~n~w",
- [Addr, Port, Error5, SnmpTrapInfo])
+ error_msg(
+ "failed retreiving "
+ "the default user info handling trap from "
+ "<~p,~p>: ~n~w~n~w",
+ [Domain, Addr, Error5, SnmpTrapInfo])
end
end,
ok.
-handle_trap(UserId, Mod,
- RegType, Target, Addr, Port, SnmpTrapInfo, Data, State) ->
+handle_trap(
+ UserId, Mod, RegType, Target, Domain, Addr, SnmpTrapInfo, Data, State) ->
?vtrace("handle_trap -> entry with"
"~n UserId: ~p"
"~n Mod: ~p", [UserId, Mod]),
F = fun() ->
- do_handle_trap(UserId, Mod,
- RegType, Target, Addr, Port,
- SnmpTrapInfo, Data, State)
+ do_handle_trap(
+ UserId, Mod,
+ RegType, Target, Domain, Addr,
+ SnmpTrapInfo, Data, State)
end,
handle_callback(F),
ok.
-do_handle_trap(UserId, Mod,
- RegType, Target, Addr, Port, SnmpTrapInfo, Data, _State) ->
+do_handle_trap(
+ UserId, Mod, RegType, Target, Domain, Addr, SnmpTrapInfo, Data, _State) ->
?vdebug("do_handle_trap -> entry with"
"~n UserId: ~p", [UserId]),
{HandleTrap, CallbackArgs} =
@@ -2338,8 +2351,9 @@ do_handle_trap(UserId, Mod,
{fun() -> Mod:handle_trap(Target, SnmpTrapInfo, Data) end,
[Target, SnmpTrapInfo, Data]};
addr_port ->
- {fun() -> Mod:handle_trap(Addr, Port, SnmpTrapInfo, Data) end,
- [Addr, Port, SnmpTrapInfo, Data]}
+ {Ip, Port} = Addr,
+ {fun() -> Mod:handle_trap(Ip, Port, SnmpTrapInfo, Data) end,
+ [Ip, Port, SnmpTrapInfo, Data]}
end,
try HandleTrap() of
@@ -2347,9 +2361,10 @@ do_handle_trap(UserId, Mod,
?vtrace("do_handle_trap -> register: "
"~n UserId2: ~p"
"~n Config: ~p", [UserId2, Config]),
- Target2 = mk_target_name(Addr, Port, Config),
- Config2 = [{reg_type, target_name},
- {address, Addr}, {port, Port} | Config],
+ Target2 = mk_target_name(Domain, Addr, Config),
+ Config2 =
+ [{reg_type, target_name},
+ {tdomain, Domain}, {taddress, Addr} | Config],
case snmpm_config:register_agent(UserId2, Target2, Config2) of
ok ->
ok;
@@ -2357,7 +2372,7 @@ do_handle_trap(UserId, Mod,
error_msg("failed registering agent "
"handling trap "
"<~p,~p>: ~n~w",
- [Addr, Port, Reason]),
+ [Domain, Addr, Reason]),
ok
end;
{register, UserId2, Target2, Config} ->
@@ -2375,20 +2390,19 @@ do_handle_trap(UserId, Mod,
error_msg("failed registering agent "
"handling trap "
"~p <~p,~p>: ~n~w",
- [Target2, Addr, Port, Reason]),
+ [Target2, Domain, Addr, Reason]),
reply
end;
unregister ->
?vtrace("do_handle_trap -> unregister", []),
- case snmpm_config:unregister_agent(UserId,
- Addr, Port) of
+ case snmpm_config:unregister_agent(UserId, Domain, Addr) of
ok ->
ok;
{error, Reason} ->
error_msg("failed unregistering agent "
"handling trap "
"<~p,~p>: ~n~w",
- [Addr, Port, Reason]),
+ [Domain, Addr, Reason]),
ok
end;
ignore ->
@@ -2405,28 +2419,30 @@ do_handle_trap(UserId, Mod,
end.
-handle_snmp_inform(Ref,
- #pdu{error_status = EStatus,
- error_index = EIndex,
- varbinds = Varbinds} = Pdu, Addr, Port, State) ->
+handle_snmp_inform(
+ Ref,
+ #pdu{error_status = EStatus,
+ error_index = EIndex,
+ varbinds = Varbinds} = Pdu, Domain, Addr, State) ->
- ?vtrace("handle_snmp_inform -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n Pdu: ~p", [Addr, Port, Pdu]),
+ ?vtrace("handle_snmp_inform -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " Pdu: ~p", [Domain, Addr, Pdu]),
Varbinds2 = fix_vbs_BITS(Varbinds),
SnmpInform = {EStatus, EIndex, Varbinds2},
- case snmpm_config:get_agent_user_info(Addr, Port) of
+ case snmpm_config:get_agent_user_info(Domain, Addr) of
{ok, UserId, Target, RegType} ->
case snmpm_config:user_info(UserId) of
{ok, Mod, Data} ->
?vdebug("[inform] callback handle_inform with: "
"~n UserId: ~p"
"~n Mod: ~p", [UserId, Mod]),
- handle_inform(UserId, Mod, Ref,
- RegType, Target, Addr, Port,
- SnmpInform, Data, State);
+ handle_inform(
+ UserId, Mod, Ref,
+ RegType, Target, Domain, Addr,
+ SnmpInform, Data, State);
Error1 ->
%% User no longer exists, unregister agent
case snmpm_config:unregister_agent(UserId, Target) of
@@ -2437,15 +2453,16 @@ handle_snmp_inform(Ref,
"~n ~p", [UserId, Error1]),
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
- handle_agent(DefUserId, DefMod,
- Addr, Port,
- inform, Ref,
- SnmpInform, DefData, State);
+ handle_agent(
+ DefUserId, DefMod,
+ Domain, Addr,
+ inform, Ref,
+ SnmpInform, DefData, State);
Error2 ->
error_msg("failed retreiving the default "
"user info handling inform from "
"~p <~p,~p>: ~n~w~n~w",
- [Target, Addr, Port,
+ [Target, Domain, Addr,
Error2, Pdu])
end;
Error3 ->
@@ -2456,7 +2473,7 @@ handle_snmp_inform(Ref,
"user ~p, handling inform: "
"~n Error: ~w"
"~n Pdu: ~w",
- [Target, Addr, Port, UserId,
+ [Target, Domain, Addr, UserId,
Error3, Pdu])
end
end;
@@ -2464,42 +2481,46 @@ handle_snmp_inform(Ref,
Error4 ->
%% Unknown agent, pass it on to the default user
?vlog("[inform] failed retreiving user id for agent <~p,~p>: "
- "~n ~p", [Addr, Port, Error4]),
+ "~n ~p", [Domain, Addr, Error4]),
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
- handle_agent(DefUserId, DefMod,
- Addr, Port,
- inform, Ref,
- SnmpInform, DefData, State);
+ handle_agent(
+ DefUserId, DefMod,
+ Domain, Addr,
+ inform, Ref,
+ SnmpInform, DefData, State);
Error5 ->
error_msg("failed retreiving "
"the default user info handling inform from "
"<~p,~p>: ~n~w~n~w",
- [Addr, Port, Error5, Pdu])
+ [Domain, Addr, Error5, Pdu])
end
end,
ok;
-handle_snmp_inform(_Ref, CrapInform, Addr, Port, _State) ->
+handle_snmp_inform(_Ref, CrapInform, Domain, Addr, _State) ->
error_msg("received crap (snmp) inform from ~w:~w =>"
- "~p", [Addr, Port, CrapInform]),
+ "~p", [Domain, Addr, CrapInform]),
ok.
-handle_inform(UserId, Mod, Ref,
- RegType, Target, Addr, Port, SnmpInform, Data, State) ->
+handle_inform(
+ UserId, Mod, Ref,
+ RegType, Target, Domain, Addr, SnmpInform, Data, State) ->
?vtrace("handle_inform -> entry with"
"~n UserId: ~p"
"~n Mod: ~p", [UserId, Mod]),
F = fun() ->
- do_handle_inform(UserId, Mod, Ref,
- RegType, Target, Addr, Port, SnmpInform,
- Data, State)
+ do_handle_inform(
+ UserId, Mod, Ref,
+ RegType, Target, Domain, Addr, SnmpInform,
+ Data, State)
end,
handle_callback(F),
ok.
-do_handle_inform(UserId, Mod, Ref,
- RegType, Target, Addr, Port, SnmpInform, Data, State) ->
+do_handle_inform(
+ UserId, Mod, Ref,
+ RegType, Target, Domain, Addr, SnmpInform, Data, State) ->
?vdebug("do_handle_inform -> entry with"
"~n UserId: ~p", [UserId]),
{HandleInform, CallbackArgs} =
@@ -2508,8 +2529,9 @@ do_handle_inform(UserId, Mod, Ref,
{fun() -> Mod:handle_inform(Target, SnmpInform, Data) end,
[Target, SnmpInform, Data]};
addr_port ->
- {fun() -> Mod:handle_inform(Addr, Port, SnmpInform, Data) end,
- [Addr, Port, SnmpInform, Data]}
+ {Ip, Port} = Addr,
+ {fun() -> Mod:handle_inform(Ip, Port, SnmpInform, Data) end,
+ [Ip, Port, SnmpInform, Data]}
end,
Rep =
@@ -2520,9 +2542,11 @@ do_handle_inform(UserId, Mod, Ref,
"~n Config: ~p", [UserId2, Config]),
%% The only user which would do this is the
%% default user
- Target2 = mk_target_name(Addr, Port, Config),
- Config2 = [{reg_type, target_name},
- {address, Addr}, {port, Port} | Config],
+ Target2 = mk_target_name(Domain, Addr, Config),
+ Config2 =
+ [{reg_type, target_name} |
+ ensure_present(
+ [{tdomain, Domain}, {taddress, Addr}], Config)],
case snmpm_config:register_agent(UserId2, Target2, Config2) of
ok ->
reply;
@@ -2530,7 +2554,7 @@ do_handle_inform(UserId, Mod, Ref,
error_msg("failed registering agent "
"handling inform "
"~p <~p,~p>: ~n~w",
- [Target2, Addr, Port, Reason]),
+ [Target2, Domain, Addr, Reason]),
reply
end;
@@ -2549,21 +2573,21 @@ do_handle_inform(UserId, Mod, Ref,
error_msg("failed registering agent "
"handling inform "
"~p <~p,~p>: ~n~w",
- [Target2, Addr, Port, Reason]),
+ [Target2, Domain, Addr, Reason]),
reply
end;
unregister ->
?vtrace("do_handle_inform -> unregister", []),
- case snmpm_config:unregister_agent(UserId,
- Addr, Port) of
+ case snmpm_config:unregister_agent(
+ UserId, Domain, Addr) of
ok ->
reply;
{error, Reason} ->
error_msg("failed unregistering agent "
"handling inform "
"<~p,~p>: ~n~w",
- [Addr, Port, Reason]),
+ [Domain, Addr, Reason]),
reply
end;
@@ -2576,8 +2600,8 @@ do_handle_inform(UserId, Mod, Ref,
reply;
InvalidResult ->
- handle_invalid_result(handle_inform, CallbackArgs,
- InvalidResult),
+ handle_invalid_result(
+ handle_inform, CallbackArgs, InvalidResult),
reply
catch
@@ -2586,31 +2610,34 @@ do_handle_inform(UserId, Mod, Ref,
reply
end,
- handle_inform_response(Rep, Ref, Addr, Port, State),
+ handle_inform_response(Rep, Ref, Domain, Addr, State),
ok.
-handle_inform_response(_, ignore, _Addr, _Port, _State) ->
+handle_inform_response(_, ignore, _Domain, _Addr, _State) ->
ignore;
-handle_inform_response(no_reply, _Ref, _Addr, _Port, _State) ->
+handle_inform_response(no_reply, _Ref, _Domain, _Addr, _State) ->
no_reply;
-handle_inform_response(_, Ref, Addr, Port,
- #state{net_if = Pid, net_if_mod = Mod}) ->
+handle_inform_response(
+ _, Ref, Domain, Addr,
+ #state{net_if = Pid, net_if_mod = Mod}) ->
?vdebug("handle_inform -> response", []),
- (catch Mod:inform_response(Pid, Ref, Addr, Port)).
+ (catch Mod:inform_response(Pid, Ref, Domain, Addr)).
-handle_snmp_report(#pdu{error_status = EStatus,
- error_index = EIndex,
- varbinds = Varbinds} = Pdu, Addr, Port, State) ->
+handle_snmp_report(
+ #pdu{error_status = EStatus,
+ error_index = EIndex,
+ varbinds = Varbinds} = Pdu,
+ Domain, Addr, State) ->
- ?vtrace("handle_snmp_report -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n Pdu: ~p", [Addr, Port, Pdu]),
+ ?vtrace("handle_snmp_report -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " Pdu: ~p", [Domain, Addr, Pdu]),
Varbinds2 = fix_vbs_BITS(Varbinds),
SnmpReport = {EStatus, EIndex, Varbinds2},
- case snmpm_config:get_agent_user_info(Addr, Port) of
+ case snmpm_config:get_agent_user_info(Domain, Addr) of
{ok, UserId, Target, RegType} ->
case snmpm_config:user_info(UserId) of
{ok, Mod, Data} ->
@@ -2620,7 +2647,7 @@ handle_snmp_report(#pdu{error_status = EStatus,
"~n ~p"
"~n ~p", [UserId, Mod, Target, SnmpReport]),
handle_report(UserId, Mod,
- RegType, Target, Addr, Port,
+ RegType, Target, Domain, Addr,
SnmpReport, Data, State);
Error1 ->
%% User no longer exists, unregister agent
@@ -2633,7 +2660,7 @@ handle_snmp_report(#pdu{error_status = EStatus,
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
handle_agent(DefUserId, DefMod,
- Addr, Port,
+ Domain, Addr,
report, ignore,
SnmpReport, DefData, State);
@@ -2641,7 +2668,7 @@ handle_snmp_report(#pdu{error_status = EStatus,
error_msg("failed retreiving the default "
"user info handling report from "
"~p <~p,~p>: ~n~w~n~w",
- [Target, Addr, Port,
+ [Target, Domain, Addr,
Error2, Pdu])
end;
Error3 ->
@@ -2652,7 +2679,7 @@ handle_snmp_report(#pdu{error_status = EStatus,
"user ~p, handling report: "
"~n Error: ~w"
"~n Report: ~w",
- [Target, Addr, Port, UserId,
+ [Target, Domain, Addr, UserId,
Error3, Pdu])
end
end;
@@ -2660,25 +2687,25 @@ handle_snmp_report(#pdu{error_status = EStatus,
Error4 ->
%% Unknown agent, pass it on to the default user
?vlog("[report] failed retreiving user id for agent <~p,~p>: "
- "~n ~p", [Addr, Port, Error4]),
+ "~n ~p", [Domain, Addr, Error4]),
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
handle_agent(DefUserId, DefMod,
- Addr, Port,
+ Domain, Addr,
report, ignore,
SnmpReport, DefData, State);
Error5 ->
error_msg("failed retreiving "
"the default user info handling report from "
"<~p,~p>: ~n~w~n~w",
- [Addr, Port, Error5, Pdu])
+ [Domain, Addr, Error5, Pdu])
end
end,
ok;
-handle_snmp_report(CrapReport, Addr, Port, _State) ->
+handle_snmp_report(CrapReport, Domain, Addr, _State) ->
error_msg("received crap (snmp) report from ~w:~w =>"
- "~p", [Addr, Port, CrapReport]),
+ "~p", [Domain, Addr, CrapReport]),
ok.
%% This could be from a failed get-request, so we might have a user
@@ -2686,20 +2713,20 @@ handle_snmp_report(CrapReport, Addr, Port, _State) ->
%% get-response (except for tha data which is different). Otherwise,
%% we handle it as an error (reported via the handle_error callback
%% function).
-handle_snmp_report(ReqId,
- #pdu{error_status = EStatus,
- error_index = EIndex,
- varbinds = Varbinds} = Pdu,
- {ReportReason, Info} = Rep,
- Addr, Port, State)
- when is_integer(ReqId) ->
-
- ?vtrace("handle_snmp_report -> entry with"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n ReqId: ~p"
- "~n Rep: ~p"
- "~n Pdu: ~p", [Addr, Port, ReqId, Rep, Pdu]),
+handle_snmp_report(
+ ReqId,
+ #pdu{error_status = EStatus,
+ error_index = EIndex,
+ varbinds = Varbinds} = Pdu,
+ {ReportReason, Info} = Rep,
+ Domain, Addr, State) when is_integer(ReqId) ->
+
+ ?vtrace("handle_snmp_report -> entry with~n"
+ " Domain: ~p~n"
+ " Addr: ~p~n"
+ " ReqId: ~p~n"
+ " Rep: ~p~n"
+ " Pdu: ~p", [Domain, Addr, ReqId, Rep, Pdu]),
Varbinds2 = fix_vbs_BITS(Varbinds),
SnmpReport = {EStatus, EIndex, Varbinds2},
@@ -2744,7 +2771,7 @@ handle_snmp_report(ReqId,
%% Either not a sync request or no such request. Either
%% way, this is error info, so handle it as such.
- case snmpm_config:get_agent_user_id(Addr, Port) of
+ case snmpm_config:get_agent_user_id(Domain, Addr) of
{ok, UserId} ->
case snmpm_config:user_info(UserId) of
{ok, Mod, Data} ->
@@ -2768,7 +2795,7 @@ handle_snmp_report(ReqId,
"default user "
"info handling report from "
"<~p,~p>: ~n~w~n~w~n~w",
- [Addr, Port, Error,
+ [Domain, Addr, Error,
ReqId, Reason])
end
end;
@@ -2776,7 +2803,7 @@ handle_snmp_report(ReqId,
%% Unknown agent, pass it on to the default user
?vlog("[report] failed retreiving user id for "
"agent <~p,~p>: "
- "~n ~p", [Addr, Port, Error]),
+ "~n ~p", [Domain, Addr, Error]),
case snmpm_config:user_info() of
{ok, DefUserId, DefMod, DefData} ->
handle_error(DefUserId, DefMod, Reason, ReqId,
@@ -2786,32 +2813,36 @@ handle_snmp_report(ReqId,
"the default user info handling "
"report from "
"<~p,~p>: ~n~w~n~w~n~w",
- [Addr, Port, Error, ReqId, Reason])
+ [Domain, Addr, Error, ReqId, Reason])
end
end
end,
ok;
-handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Addr, Port, _State) ->
- error_msg("received crap (snmp) report from ~w:~w =>"
- "~n~p~n~p~n~p", [Addr, Port, CrapReqId, CrapReport, CrapInfo]),
+handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Domain, Addr, _State) ->
+ error_msg(
+ "received crap (snmp) report from ~w:~w =>"
+ "~n~p~n~p~n~p",
+ [Domain, Addr, CrapReqId, CrapReport, CrapInfo]),
ok.
-handle_report(UserId, Mod, RegType, Target, Addr, Port,
+handle_report(UserId, Mod, RegType, Target, Domain, Addr,
SnmpReport, Data, State) ->
?vtrace("handle_report -> entry with"
"~n UserId: ~p"
"~n Mod: ~p", [UserId, Mod]),
F = fun() ->
- do_handle_report(UserId, Mod, RegType, Target, Addr, Port,
- SnmpReport, Data, State)
+ do_handle_report(
+ UserId, Mod, RegType, Target, Domain, Addr,
+ SnmpReport, Data, State)
end,
handle_callback(F),
ok.
-do_handle_report(UserId, Mod,
- RegType, Target, Addr, Port, SnmpReport, Data, _State) ->
+do_handle_report(
+ UserId, Mod, RegType, Target, Domain, Addr,
+ SnmpReport, Data, _State) ->
?vdebug("do_handle_report -> entry with"
"~n UserId: ~p", [UserId]),
{HandleReport, CallbackArgs} =
@@ -2820,8 +2851,9 @@ do_handle_report(UserId, Mod,
{fun() -> Mod:handle_report(Target, SnmpReport, Data) end,
[Target, SnmpReport, Data]};
addr_port ->
- {fun() -> Mod:handle_report(Addr, Port, SnmpReport, Data) end,
- [Addr, Port, SnmpReport, Data]}
+ {Ip, Port} = Addr,
+ {fun() -> Mod:handle_report(Ip, Port, SnmpReport, Data) end,
+ [Ip, Port, SnmpReport, Data]}
end,
try HandleReport() of
@@ -2831,17 +2863,18 @@ do_handle_report(UserId, Mod,
"~n Config: ~p", [UserId2, Config]),
%% The only user which would do this is the
%% default user
- Target2 = mk_target_name(Addr, Port, Config),
- Config2 = [{reg_type, target_name},
- {address, Addr}, {port, Port} | Config],
+ Target2 = mk_target_name(Domain, Addr, Config),
+ Config2 =
+ [{reg_type, target_name},
+ {tdomain, Domain}, {taddress, Addr} | Config],
case snmpm_config:register_agent(UserId2, Target2, Config2) of
ok ->
ok;
{error, Reason} ->
error_msg("failed registering agent "
"handling report "
- "<~p,~p>: ~n~w",
- [Addr, Port, Reason]),
+ "<~p,~p>: ~n~w",
+ [Domain, Addr, Reason]),
ok
end;
@@ -2860,21 +2893,20 @@ do_handle_report(UserId, Mod,
error_msg("failed registering agent "
"handling report "
"~p <~p,~p>: ~n~w",
- [Target2, Addr, Port, Reason]),
+ [Target2, Domain, Addr, Reason]),
reply
end;
unregister ->
?vtrace("do_handle_trap -> unregister", []),
- case snmpm_config:unregister_agent(UserId,
- Addr, Port) of
+ case snmpm_config:unregister_agent(UserId, Domain, Addr) of
ok ->
ok;
{error, Reason} ->
error_msg("failed unregistering agent "
"handling report "
"<~p,~p>: ~n~w",
- [Addr, Port, Reason]),
+ [Domain, Addr, Reason]),
ok
end;
@@ -3012,50 +3044,49 @@ do_gc(Key, Now) ->
%%
%%----------------------------------------------------------------------
-send_get_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
+send_get_request(Oids, Vsn, MsgData, Domain, Addr, ExtraInfo,
#state{net_if = NetIf,
net_if_mod = Mod,
mini_mib = MiniMIB}) ->
Pdu = make_pdu(get, Oids, MiniMIB),
- ?vtrace("send_get_request -> send get-request:"
- "~n Mod: ~p"
- "~n NetIf: ~p"
- "~n Pdu: ~p"
- "~n Vsn: ~p"
- "~n MsgData: ~p"
- "~n Domain: ~p"
- "~n Addr: ~p"
- "~n Port: ~p",
- [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port]),
+ ?vtrace("send_get_request -> send get-request:~n"
+ " Mod: ~p~n"
+ " NetIf: ~p~n"
+ " Pdu: ~p~n"
+ " Vsn: ~p~n"
+ " MsgData: ~p~n"
+ " Domain: ~p~n"
+ " Addr: ~p",
+ [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr]),
Res = (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData,
- Domain, Addr, Port, ExtraInfo)),
+ Domain, Addr, ExtraInfo)),
?vtrace("send_get_request -> send result:"
"~n ~p", [Res]),
Pdu#pdu.request_id.
-send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
+send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(get_next, Oids, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo),
Pdu#pdu.request_id.
-send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr, Port,
+send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr,
NonRep, MaxRep, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(bulk, {NonRep, MaxRep, Oids}, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo),
Pdu#pdu.request_id.
-send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
+send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(set, VarsAndVals, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo),
Pdu#pdu.request_id.
%% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo,
@@ -3291,10 +3322,9 @@ agent_data(TargetName, SendOpts) ->
{Comm, SecModel}
end,
Domain = agent_data_item(tdomain, TargetName),
- Addr = agent_data_item(address, TargetName),
- Port = agent_data_item(port, TargetName),
+ Addr = agent_data_item(taddress, TargetName),
RegType = agent_data_item(reg_type, TargetName),
- {ok, RegType, Domain, Addr, Port, version(Version), MsgData};
+ {ok, RegType, Domain, Addr, version(Version), MsgData};
Error ->
Error
end.
@@ -3440,9 +3470,9 @@ maybe_demonitor(MonRef) ->
t() ->
{A,B,C} = erlang:now(),
A*1000000000+B*1000+(C div 1000).
-
-mk_target_name(Addr, Port, Config) ->
- snmpm_config:mk_target_name(Addr, Port, Config).
+
+mk_target_name(Domain, Addr, Config) ->
+ snmpm_config:mk_target_name(Domain, Addr, Config).
default_agent_config() ->
case snmpm_config:agent_info() of
diff --git a/lib/snmp/src/manager/snmpm_user.erl b/lib/snmp/src/manager/snmpm_user.erl
index e6b0b6943e..8e5a874f77 100644
--- a/lib/snmp/src/manager/snmpm_user.erl
+++ b/lib/snmp/src/manager/snmpm_user.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -39,20 +39,25 @@
%% *** handle_error ***
%% An "asynchronous" error has been detected
--callback handle_error(ReqId :: integer(),
- Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} |
- {invalid_sec_info, SecInfo :: term(), SnmpInfo :: snmp_gen_info()} |
- {empty_message, Addr :: ip_address(), Port :: port_number()} |
- term(),
- UserData :: term()) ->
+-callback handle_error(
+ ReqId :: integer(),
+ Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} |
+ {invalid_sec_info,
+ SecInfo :: term(),
+ SnmpInfo :: snmp_gen_info()} |
+ {empty_message,
+ TransportDomain :: atom(),
+ {Addr :: ip_address(), Port :: port_number()}} |
+ term(),
+ UserData :: term()) ->
snmp:void().
%% *** handle_agent ***
%% A message was received from an unknown agent
--callback handle_agent(Addr :: term(),
- Port :: pos_integer(),
+-callback handle_agent(Domain :: atom(),
+ Address :: term(),
Type :: pdu | trap | inform | report,
SnmpInfo :: snmp_gen_info() | snmp_v1_trap_info(),
UserData :: term()) ->
diff --git a/lib/snmp/src/manager/snmpm_user_default.erl b/lib/snmp/src/manager/snmpm_user_default.erl
index 015198cb76..b827713f27 100644
--- a/lib/snmp/src/manager/snmpm_user_default.erl
+++ b/lib/snmp/src/manager/snmpm_user_default.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -36,13 +36,13 @@ handle_error(ReqId, Reason, UserData) ->
ignore.
-handle_agent(Addr, Port, Type, SnmpInfo, UserData) ->
- info("received handle_agent:"
- "~n Addr: ~p"
- "~n Port: ~p"
- "~n Type: ~p"
- "~n SnmpInfo: ~p"
- "~n UserData: ~p", [Addr, Port, Type, SnmpInfo, UserData]),
+handle_agent(Domain, Address, Type, SnmpInfo, UserData) ->
+ info("received handle_agent:~n"
+ " Domain: ~p~n"
+ " Address: ~p~n"
+ " Type: ~p~n"
+ " SnmpInfo: ~p~n"
+ " UserData: ~p", [Domain, Address, Type, SnmpInfo, UserData]),
ignore.
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index 46625989d5..f4483995cb 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,35 +25,42 @@
%% External exports
%% Avoid warning for local function error/1 clashing with autoimported BIF.
-compile({no_auto_import,[error/1]}).
--export([read_files/2, read/2]).
+-export([read_files/2, no_gen/2, no_order/2, no_filter/1, keyorder/4]).
+-export([read/2, read/3]).
%% Basic (type) check functions
-export([check_mandatory/2,
check_integer/1, check_integer/2,
-
+
check_string/1, check_string/2,
- check_atom/2,
+ check_atom/2,
check_timer/1,
- all_domains/0,
- check_domain/1,
- all_tdomains/0,
- check_tdomain/1,
- mk_tdomain/1,
- which_domain/1,
- check_ip/1, check_ip/2,
- check_taddress/1, check_taddress/2,
- mk_taddress/3,
-
- check_packet_size/1,
+ all_domains/0,
+ check_domain/1,
+ domain_to_name/1,
+ all_tdomains/0,
+ check_tdomain/1,
+ mk_tdomain/0, mk_tdomain/1,
+ tdomain_to_family/1, tdomain_to_domain/1,
+ which_domain/1,
+ mk_addr_string/1,
+ check_ip/1, check_ip/2,
+ check_port/1,
+%% ip_port_to_domaddr/2,
+ check_address/2, check_address/3,
+ check_taddress/2,
+ mk_taddress/1, mk_taddress/2,
+
+ check_packet_size/1,
check_oid/1,
- check_imask/1, check_emask/1,
-
- check_mp_model/1,
- check_sec_model/1, check_sec_model/2, check_sec_model/3,
+ check_imask/1, check_emask/1,
+
+ check_mp_model/1,
+ check_sec_model/1, check_sec_model/2, check_sec_model/3,
check_sec_level/1,
all_integer/1
@@ -70,17 +77,53 @@
-include("snmp_verbosity.hrl").
+-define(is_word(P), (((P) band (bnot 65535)) =:= 0)).
+-define(is_word(P0, P1), ((((P0) bor (P1)) band (bnot 255)) =:= 0)).
+
+mk_word(B0, B1) -> ((B0) bsl 8) bor (B1).
+mk_bytes(W) -> [(W) bsr 8,(W) band 255].
+
+-define(
+ is_ipv4_addr(A0, A1, A2, A3),
+ ((((A0) bor (A1) bor (A2) bor (A3)) band (bnot 255)) =:= 0)).
+
+-define(
+ is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ((((A0) bor (A1) bor (A2) bor (A3) bor (A4) bor (A5) bor (A6) bor (A7))
+ band (bnot 65535)) =:= 0)).
+-define(
+ is_ipv6_addr(
+ A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15),
+ ((((A0) bor (A1) bor (A2) bor (A3) bor
+ (A4) bor (A5) bor (A6) bor (A7) bor
+ (A8) bor (A9) bor (A10) bor (A11) bor
+ (A12) bor (A13) bor (A14) bor (A15))
+ band (bnot 65535)) =:= 0)).
+
+
%%-----------------------------------------------------------------
%% read_files(Dir, Files) -> Configs
%% Dir - string() - Full path to the config dir.
-%% Files - [{Gen, Filter, Check, FileName}]
+%% Files - [{FileName, Gen, Order, Check, Filter}]
+%% FileName - string() - Name of the config file.
%% Gen - function/2 - In case of failure when reading the config file,
%% this function is called to either generate a
%% default file or issue the error.
-%% Filter - function/1 - Filters all the config entries read from the file
-%% Check - function/1 - Check each entry as they are read from the file.
-%% FileName - string() - Name of the config file.
+%% Returns a generated config list corresponding
+%% to the written file.
+%% (Dir, Error) -> Configs.
+%% Order - function/2 - An ordering function that is used to process
+%% the read config entries using lists:sort/2.
+%% Returns true if arg 1 compares less than or
+%% equal to arg 2, false otherwise.
+%% Check - function/2 - Check each entry as they are read from the file.
+%% (Entry, State) ->
+%% {ok,NewState} | {{ok,NewEntry},NewState} |
+%% throw(Error)
+%% State =:= 'undefined' the first time.
+%% Filter - function/1 - Process all the config entries read from the file
+%% (Configs) -> [config_entry()].
%% Configs - [config_entry()]
%% config_entry() - term()
@@ -89,99 +132,143 @@ read_files(Dir, Files) when is_list(Dir) andalso is_list(Files) ->
read_files(_Dir, [], Res) ->
lists:reverse(Res);
-read_files(Dir, [{Gen, Filter, Check, FileName}|Files], Res)
- when is_function(Filter) andalso
- is_function(Check) andalso
- is_list(FileName) ->
- ?vdebug("read_files -> entry with"
- "~n FileName: ~p", [FileName]),
+read_files(Dir, [{FileName, Gen, Order, Check, Filter}|Files], Res)
+ when is_list(FileName),
+ is_function(Gen),
+ is_function(Order),
+ is_function(Check),
+ is_function(Filter) ->
+ ?vdebug("read_files -> entry with~n"
+ " FileName: ~p", [FileName]),
File = filename:join(Dir, FileName),
- case file:read_file_info(File) of
- {ok, _} ->
- Confs = read(File, Check),
- read_files(Dir, Files, [Filter(Confs)|Res]);
- {error, R} ->
- ?vlog("failed reading file info for ~s: "
- "~n ~p", [FileName, R]),
- Gen(Dir, R),
- read_files(Dir, Files, [Filter([])|Res])
- end.
-
+ Confs =
+ case file:read_file_info(File) of
+ {ok,_} ->
+ read(File, Order, Check);
+ {error, R} ->
+ ?vlog("failed reading file info for ~s: ~n"
+ " ~p", [FileName, R]),
+ Gen(Dir, R)
+ end,
+ read_files(Dir, Files, [Filter(Confs)|Res]).
+
+
+
+no_gen(_Dir, _R) -> [].
+no_order(_, _) -> true.
+no_filter(X) -> X.
+
+%% Order tuples on element N with Keys first in appearence order.
+%%
+%% 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.
+keyorder(N, A, B, _) when element(N, A) == element(N, B) ->
+ true;
+keyorder(N, A, B, [Key | _])
+ when tuple_size(A) >= 1, element(N, B) == Key ->
+ false;
+keyorder(N, A, B, [Key | _])
+ when element(N, A) == Key, tuple_size(B) >= 1 ->
+ true;
+keyorder(N, A, B, [_ | Keys]) ->
+ keyorder(N, A, B, Keys);
+keyorder(_, A, B, []) when tuple_size(A) >= 1, tuple_size(B) >= 1 ->
+ %% Do not order other keys
+ true;
+keyorder(N, A, B, sort) ->
+ %% Order other keys according to standard sort order
+ element(N, A) =< element(N, B).
+
+
+read(File, Verify) ->
+ Check = fun (Row, State) -> {Verify(Row), State} end,
+ read(File, fun no_order/2, Check).
%% Ret. Res | exit(Reason)
-read(File, Check) when is_function(Check) ->
- ?vdebug("read -> entry with"
- "~n File: ~p", [File]),
-
+read(File, Order, Check) when is_function(Order), is_function(Check) ->
+ ?vdebug("read -> entry with~n"
+ " File: ~p", [File]),
Fd = open_file(File),
+ read_fd(File, Order, Check, Fd, 1, []).
- case loop(Fd, [], Check, 1, File) of
- {error, Reason} ->
- file:close(Fd),
- error(Reason);
- {ok, Res} ->
- file:close(Fd),
- Res
+read_fd(File, Order, Check, Fd, StartLine, Res) ->
+ case do_read(Fd, "", StartLine) of
+ {ok, Row, EndLine} ->
+ ?vtrace("read_fd ->~n"
+ " Row: ~p~n"
+ " EndLine: ~p", [Row,EndLine]),
+ read_fd(
+ File, Order, Check, Fd, EndLine,
+ [{StartLine, Row, EndLine}|Res]);
+ {error, Error, EndLine} ->
+ ?vtrace("read_fd -> read failure:~n"
+ " Error: ~p~n"
+ " EndLine: ~p", [Error,EndLine]),
+ file:close(Fd),
+ error({failed_reading, File, StartLine, EndLine, Error});
+ {eof, _EndLine} ->
+ Lines =
+ lists:sort(
+ fun ({_, RowA, _}, {_, RowB, _}) ->
+ Order(RowA, RowB)
+ end,
+ lists:reverse(Res)),
+ ?vtrace("read_fd to read_check ->~n"
+ " Lines: ~p", [Lines]),
+ read_check(File, Check, Lines, undefined, [])
end.
-open_file(File) ->
- case file:open(File, [read]) of
- {ok, Fd} ->
- Fd;
- {error, Reason} ->
- error({failed_open, File, Reason})
+read_check(_, _, [], _, Res) ->
+ lists:reverse(Res);
+read_check(File, Check, [{StartLine, Row, EndLine}|Lines], State, Res) ->
+ try Check(Row, State) of
+ {Rows, NewState} when is_list(Rows) ->
+ ?vtrace("read_check -> ok:~n"
+ " Rows: ~p~n", [Rows]),
+ read_check(File, Check, Lines, NewState, Rows ++ Res);
+ {ok, NewState} ->
+ ?vtrace("read_check -> ok", []),
+ read_check(File, Check, Lines, NewState, [Row | Res]);
+ {{ok, NewRow}, NewState} ->
+ ?vtrace("read_check -> ok:~n"
+ " NewRow: ~p~n", [NewRow]),
+ read_check(File, Check, Lines, NewState, [NewRow | Res])
+ catch
+ {error, Reason} ->
+ ?vtrace("read_check -> error:~n"
+ " Reason: ~p", [Reason]),
+ error({failed_check, File, StartLine, EndLine, Reason});
+ Class:Reason ->
+ Error = {Class,Reason,erlang:get_stacktrace()},
+ ?vtrace("read_check -> failure:~n"
+ " Error: ~p", [Error]),
+ error({failed_check, File, StartLine, EndLine, Error})
end.
-loop(Fd, Res, Check, StartLine, File) ->
- case do_read(Fd, "", StartLine) of
- {ok, Row, EndLine} ->
- ?vtrace("loop -> "
- "~n Row: ~p"
- "~n EndLine: ~p", [Row, EndLine]),
- case (catch Check(Row)) of
- ok ->
- ?vtrace("loop -> ok", []),
- loop(Fd, [Row | Res], Check, EndLine, File);
- {ok, NewRow} ->
- ?vtrace("loop -> ok: "
- "~n NewRow: ~p", [NewRow]),
- loop(Fd, [NewRow | Res], Check, EndLine, File);
- {error, Reason} ->
- ?vtrace("loop -> check error: "
- "~n Reason: ~p", [Reason]),
- {error, {failed_check, File, StartLine, EndLine, Reason}};
- Error ->
- ?vtrace("loop -> check failure: "
- "~n Error: ~p", [Error]),
- {error, {failed_check, File, StartLine, EndLine, Error}}
- end;
- {error, EndLine, Error} ->
- ?vtrace("loop -> read failure: "
- "~n Error: ~p", [Error]),
- {error, {failed_reading, File, StartLine, EndLine, Error}};
- eof ->
- {ok, Res}
+open_file(File) ->
+ case file:open(File, [read]) of
+ {ok, Fd} ->
+ Fd;
+ {error, Reason} ->
+ error({failed_open, File, Reason})
end.
-
do_read(Io, Prompt, StartLine) ->
case io:request(Io, {get_until,Prompt,erl_scan,tokens,[StartLine]}) of
- {ok, Toks, EndLine} ->
- case erl_parse:parse_term(Toks) of
- {ok, Term} ->
- {ok, Term, EndLine};
- {error, {Line, erl_parse, Error}} ->
- {error, Line, {parse_error, Error}}
- end;
- {error,E,EndLine} ->
- {error, EndLine, E};
- {eof, _EndLine} ->
- eof;
- Other ->
- Other
+ {ok, Toks, EndLine} ->
+ case erl_parse:parse_term(Toks) of
+ {ok, Term} ->
+ {ok, Term, EndLine};
+ {error, {Line, erl_parse, Error}} ->
+ {error, {parse_error, Error}, Line}
+ end;
+ Other ->
+ Other
end.
+
%%-----------------------------------------------------------------
@@ -384,7 +471,7 @@ all_tdomains() ->
check_tdomain(TDomain) ->
SupportedTDomains =
[
- ?snmpUDPDomain,
+ ?snmpUDPDomain, % Legacy
?transportDomainUdpIpv4,
?transportDomainUdpIpv6
],
@@ -404,6 +491,9 @@ check_tdomain(TDomain) ->
%% ---------
+mk_tdomain() ->
+ mk_tdomain(snmpUDPDomain).
+
mk_tdomain(snmpUDPDomain) ->
mk_tdomain(transportDomainUdpIpv4);
mk_tdomain(transportDomainUdpIpv4) ->
@@ -416,40 +506,64 @@ mk_tdomain(BadDomain) ->
%% ---------
-check_taddress(X) ->
- check_taddress(snmpUDPDomain, X).
+tdomain_to_family(snmpUDPDomain) ->
+ inet;
+tdomain_to_family(transportDomainUdpIpv4) ->
+ inet;
+tdomain_to_family(transportDomainUdpIpv6) ->
+ inet6;
+tdomain_to_family(?snmpUDPDomain) ->
+ inet;
+tdomain_to_family(?transportDomainUdpIpv4) ->
+ inet;
+tdomain_to_family(?transportDomainUdpIpv6) ->
+ inet6;
+tdomain_to_family(BadDomain) ->
+ error({bad_domain, BadDomain}).
+
+
+%% ---------
+
+tdomain_to_domain(?snmpUDPDomain) ->
+ snmpUDPDomain;
+tdomain_to_domain(?transportDomainUdpIpv4) ->
+ transportDomainUdpIpv4;
+tdomain_to_domain(?transportDomainUdpIpv6) ->
+ transportDomainUdpIpv6;
+tdomain_to_domain(BadTDomain) ->
+ error({bad_tdomain, BadTDomain}).
+
+
+%% ---------
check_taddress(?snmpUDPDomain, X) ->
check_taddress(transportDomainUdpIpv4, X);
check_taddress(snmpUDPDomain, X) ->
check_taddress(transportDomainUdpIpv4, X);
-
+%%
check_taddress(?transportDomainUdpIpv4, X) ->
check_taddress(transportDomainUdpIpv4, X);
-check_taddress(transportDomainUdpIpv4, X)
- when is_list(X) andalso (length(X) =:= 6) ->
- case (catch all_integer(X)) of
- true ->
+check_taddress(transportDomainUdpIpv4, X) ->
+ case X of
+ [A0,A1,A2,A3,P0,P1]
+ when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) ->
ok;
- false ->
+ _ ->
error({invalid_taddress, X})
end;
-check_taddress(transportDomainUdpIpv4, X) ->
- error({invalid_taddress, X});
-
+%%
check_taddress(?transportDomainUdpIpv6, X) ->
check_taddress(transportDomainUdpIpv6, X);
-check_taddress(transportDomainUdpIpv6, X)
- when is_list(X) andalso (length(X) =:= 10) ->
- case (catch all_integer(X)) of
- true ->
+check_taddress(transportDomainUdpIpv6, X) ->
+ case X of
+ [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P0, P1) ->
ok;
- false ->
+ _ ->
error({invalid_taddress, X})
end;
-check_taddress(transportDomainUdpIpv6, X) ->
- error({invalid_taddress, X});
-
+%%
check_taddress(BadDomain, _X) ->
error({invalid_tdomain, BadDomain}).
@@ -512,96 +626,357 @@ all_domains() ->
transportDomainSctpDns
].
+check_domain(snmpUDPDomain) -> ok;
+check_domain(transportDomainUdpIpv4) -> ok;
+check_domain(transportDomainUdpIpv6) -> ok;
check_domain(Domain) ->
- SupportedDomains =
- [
- snmpUDPDomain,
- transportDomainUdpIpv4,
- transportDomainUdpIpv6
- ],
- AllDomains = all_domains(),
- case lists:member(Domain, SupportedDomains) of
+ case lists:member(Domain, all_domains()) of
true ->
- ok;
+ error({unsupported_domain, Domain});
false ->
- case lists:member(Domain, AllDomains) of
- true ->
- error({unsupported_domain, Domain});
- false ->
- error({unknown_domain, Domain})
- end
+ error({unknown_domain, Domain})
end.
-
+
+domain_to_name(snmpUDPDomain) ->
+ undefined;
+domain_to_name(transportDomainUdpIpv4) ->
+ udpIpv4;
+domain_to_name(transportDomainUdpIpv6) ->
+ udpIpv6;
+domain_to_name(transportDomainUdpIpv4z) ->
+ udpIpv4z;
+domain_to_name(transportDomainUdpIpv6z) ->
+ udpIpv6z;
+domain_to_name(transportDomainTcpIpv4) ->
+ tcpIpv4;
+domain_to_name(transportDomainTcpIpv6) ->
+ tcpIpv6;
+domain_to_name(transportDomainTcpIpv4z) ->
+ tcpIpv4z;
+domain_to_name(transportDomainTcpIpv6z) ->
+ tcpIpv6z;
+domain_to_name(transportDomainSctpIpv4) ->
+ sctpIpv4;
+domain_to_name(transportDomainSctpIpv6) ->
+ sctpIpv6;
+domain_to_name(transportDomainSctpIpv4z) ->
+ sctpIpv4z;
+domain_to_name(transportDomainSctpIpv6z) ->
+ sctpIpv6z;
+domain_to_name(transportDomainLocal) ->
+ local;
+domain_to_name(transportDomainUdpDns) ->
+ udpDns;
+domain_to_name(transportDomainTcpDns) ->
+ tcpDns;
+domain_to_name(transportDomainSctpDns) ->
+ sctpDns;
+domain_to_name(BadDomain) ->
+ error({bad_domain, BadDomain}).
%% ---------
-%% The values of Ip and Port has both been checked at this
-%% point, so we dont need to do that again.
-mk_taddress(snmpUDPDomain, Ip, Port) ->
- mk_taddress(transportDomainUdpIpv4, Ip, Port);
-mk_taddress(transportDomainUdpIpv4, Ip, Port) when is_list(Ip) ->
- Ip ++ [Port div 256, Port rem 256];
-mk_taddress(transportDomainUdpIpv4 = Domain, Ip, Port) when is_tuple(Ip) ->
- mk_taddress(Domain, tuple_to_list(Ip), Port);
-mk_taddress(transportDomainUdpIpv6, Ip, Port) when is_list(Ip) ->
- Ip ++ [Port div 256, Port rem 256];
-mk_taddress(transportDomainUdpIpv6 = Domain, Ip, Port) when is_tuple(Ip) ->
- mk_taddress(Domain, tuple_to_list(Ip), Port);
+mk_taddress(Address) ->
+ mk_taddress(snmpUDPDomain, Address).
+%% The values of Domain, Ip and Port has both been checked at this
+%% point, so we dont need to do that again, but this function is
+%% also used on incoming packets from net_if so a little
+%% check that net_if does not supply bad arguments is in order.
+%%
%% These are just for convenience
-mk_taddress(?snmpUDPDomain, Ip, Port) ->
- mk_taddress(snmpUDPDomain, Ip, Port);
-mk_taddress(?transportDomainUdpIpv4, Ip, Port) ->
- mk_taddress(transportDomainUdpIpv4, Ip, Port);
-mk_taddress(?transportDomainUdpIpv6, Ip, Port) ->
- mk_taddress(transportDomainUdpIpv6, Ip, Port);
-
+mk_taddress(?snmpUDPDomain, Address) ->
+ mk_taddress(snmpUDPDomain, Address);
+mk_taddress(?transportDomainUdpIpv4, Address) ->
+ mk_taddress(transportDomainUdpIpv4, Address);
+mk_taddress(?transportDomainUdpIpv6, Address) ->
+ mk_taddress(transportDomainUdpIpv6, Address);
+%%
+mk_taddress(snmpUDPDomain, Address) -> % Legacy
+ mk_taddress(transportDomainUdpIpv4, Address);
+mk_taddress(transportDomainUdpIpv4 = Domain, Address) ->
+ case Address of
+ [] -> % Empty mask
+ [];
+ {Ip, Port} when tuple_size(Ip) =:= 4, is_integer(Port) ->
+ tuple_to_list(Ip) ++ mk_bytes(Port);
+ _ ->
+ erlang:error(badarg, [Domain,Address])
+ end;
+mk_taddress(transportDomainUdpIpv6 = Domain, Address) ->
+ case Address of
+ [] -> % Empty mask
+ [];
+ {{A, B, C, D, E, F, G, H}, Port} ->
+ [A bsr 8, A band 255,
+ B bsr 8, B band 255,
+ C bsr 8, C band 255,
+ D bsr 8, D band 255,
+ E bsr 8, E band 255,
+ F bsr 8, F band 255,
+ G bsr 8, G band 255,
+ H bsr 8, H band 255,
+ Port bsr 8, Port band 255];
+ _ ->
+ erlang:error(badarg, [Domain,Address])
+ end;
%% Bad domain
-mk_taddress(BadDomain, _Ip, _Port) ->
+mk_taddress(BadDomain, _) ->
error({bad_domain, BadDomain}).
-
+
%% ---------
-which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 4) ->
+%% XXX remove, when net_if handles one socket per transport domain
+
+which_domain([A0,A1,A2,A3])
+ when ?is_ipv4_addr(A0, A1, A2, A3) ->
transportDomainUdpIpv4;
-which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 4) ->
+which_domain({A0, A1, A2, A3})
+ when ?is_ipv4_addr(A0, A1, A2, A3) ->
transportDomainUdpIpv4;
-which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 8) ->
+which_domain([A0,A1,A2,A3,A4,A5,A6,A7])
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) ->
+ transportDomainUdpIpv6;
+which_domain([A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15])
+ when ?is_ipv6_addr(
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ A8, A9, A10, A11, A12, A13, A14, A15) ->
transportDomainUdpIpv6;
-which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 8) ->
+which_domain({A0, A1, A2, A3, A4, A5, A6, A7})
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) ->
transportDomainUdpIpv6.
-
%% ---------
+mk_addr_string({_IP, Port} = Addr) when is_integer(Port) ->
+ mk_addr_string({snmpUDPDomain, Addr});
+mk_addr_string({Domain, Addr}) when is_atom(Domain) ->
+ %% XXX There is only code for IP domains here
+ case check_address_ip(Domain, Addr) of
+ false ->
+ case check_address_ip_port(Domain, Addr) of
+ false ->
+ error({bad_address, {Domain, Addr}});
+ true ->
+ {IP, Port} = Addr,
+ mk_addr_string_ntoa(Domain, IP, Port);
+ {IP, Port} ->
+ mk_addr_string_ntoa(Domain, IP, Port)
+ end;
+ true ->
+ mk_addr_string_ntoa(Domain, Addr);
+ IP ->
+ mk_addr_string_ntoa(Domain, IP)
+ end.
+
+
+mk_addr_string_ntoa({_, _, _, _} = IP) ->
+ inet:ntoa(IP);
+mk_addr_string_ntoa(IP) ->
+ lists:flatten(io_lib:format("[~s]", [inet:ntoa(IP)])).
+
+mk_addr_string_ntoa(Domain, IP) ->
+ case domain_to_name(Domain) of
+ undefined ->
+ mk_addr_string_ntoa(IP);
+ Name ->
+ lists:flatten(
+ io_lib:format("~w://~s", [Name, mk_addr_string_ntoa(IP)]))
+ end.
+
+mk_addr_string_ntoa(Domain, IP, Port) ->
+ lists:flatten(
+ io_lib:format(
+ "~s:~w", [mk_addr_string_ntoa(Domain, IP), Port])).
+
+%% ---------
+
check_ip(X) ->
check_ip(snmpUDPDomain, X).
-check_ip(snmpUDPDomain, X) ->
- check_ip(transportDomainUdpIpv4, X);
-check_ip(transportDomainUdpIpv4, X) when is_list(X) andalso (length(X) =:= 4) ->
- case (catch all_integer(X)) of
- true ->
+check_ip(Domain, IP) ->
+ %% XXX There is only code for IP domains here
+ case check_address_ip(Domain, IP) of
+ false ->
+ error({bad_address, {Domain, IP}});
+ true ->
ok;
- false ->
- error({invalid_ip_address, X})
- end;
-check_ip(transportDomainUdpIpv4, X) ->
- error({invalid_ip_address, X});
+ FixedIP ->
+ {ok, FixedIP}
+ end.
-check_ip(transportDomainUdpIpv6, X) when is_list(X) andalso (length(X) =:= 8) ->
- case (catch all_integer(X)) of
- true ->
+
+%% ---------
+
+check_port(Port) when ?is_word(Port) ->
+ ok;
+check_port(Port) ->
+ error({bad_port, Port}).
+
+%% ip_port_to_domaddr(IP, Port) when ?is_word(Port) ->
+%% %% XXX There is only code for IP domains here
+%% case check_address_ip(transportDomainUdpIpv4, IP) of
+%% false ->
+%% case check_address_ip(transportDomainUdpIpv6, IP) of
+%% false ->
+%% error({bad_address, {transportDomainUdpIpv4, {IP, Port}}});
+%% true ->
+%% {transportDomainUdpIpv6, {IP, Port}};
+%% FixedIP ->
+%% {transportDomainUdpIpv6, {FixedIP, Port}}
+%% end;
+%% true ->
+%% {transportDomainUdpIpv4, {IP, Port}};
+%% FixedIP ->
+%% {transportDomainUdpIpv4, {FixedIP, Port}}
+%% end;
+%% ip_port_to_domaddr(IP, Port) ->
+%% error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}).
+
+%% Check a configuration term field from a file to see if it
+%% can be fixed to be fed to mk_taddress/2.
+
+check_address(Domain, Address, DefaultPort) ->
+ %% If Address does not contain Port or contains Port =:= 0
+ %% create an address containing DefaultPort
+ %%
+ %% XXX There is only code for IP domains here
+ case check_address_ip(Domain, Address) of
+ false ->
+ case check_address_ip_port(Domain, Address) of
+ false ->
+ error({bad_address, {Domain, Address}});
+ true ->
+ case Address of
+ {IP, 0} ->
+ {ok, {IP, DefaultPort}};
+ _ ->
+ ok
+ end;
+ {FixedIP, 0} ->
+ {ok, {FixedIP, DefaultPort}};
+ FixedAddress ->
+ {ok, FixedAddress}
+ end;
+ true ->
+ {ok, {Address, DefaultPort}};
+ FixedIP ->
+ {ok, {FixedIP, DefaultPort}}
+ end.
+
+check_address(Domain, Address) ->
+ %% Address has to contain Port
+ %%
+ %% XXX There is only code for IP domains here
+ case check_address_ip_port(Domain, Address) of
+ false ->
+ error({bad_address, {Domain, Address}});
+ true ->
ok;
- false ->
- error({invalid_ip_address, X})
+ FixedAddress ->
+ {ok, FixedAddress}
+ end.
+
+%% -> IP
+check_address_ip(Domain, Address)
+ when Domain =:= snmpUDPDomain;
+ Domain =:= transportDomainUdpIpv4 ->
+ case Address of
+ %% Erlang native format
+ {A0, A1, A2, A3}
+ when ?is_ipv4_addr(A0, A1, A2, A3) ->
+ true;
+ %% Erlangish format
+ [A0,A1,A2,A3]
+ when ?is_ipv4_addr(A0, A1, A2, A3) ->
+ {A0, A1, A2, A3};
+ _ ->
+ false
+ end;
+check_address_ip(transportDomainUdpIpv6, Address) ->
+ case Address of
+ %% Erlang native format
+ {A0, A1, A2, A3, A4, A5, A6, A7}
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) ->
+ true;
+ %% Erlangish format
+ [A0,A1,A2,A3,A4,A5,A6,A7]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) ->
+ {A0, A1, A2, A3, A4, A5, A6, A7};
+ %% SNMP standards format
+ [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15]
+ when ?is_ipv6_addr(
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ A8, A9, A10, A11, A12, A13, A14, A15) ->
+ {mk_word(A0, A1), mk_word(A2, A3),
+ mk_word(A4, A5), mk_word(A6, A7),
+ mk_word(A8, A9), mk_word(A10, A11),
+ mk_word(A12, A13), mk_word(A14, A15)};
+ _ ->
+ false
end;
-check_ip(transportDomainUdpIpv6, X) ->
- error({invalid_ip_address, X});
+check_address_ip(BadDomain, _) ->
+ error({bad_domain, BadDomain}).
-check_ip(BadDomain, _X) ->
- error({invalid_domain, BadDomain}).
+%% -> {IP, Port}
+check_address_ip_port(Domain, Address)
+ when Domain =:= snmpUDPDomain;
+ Domain =:= transportDomainUdpIpv4 ->
+ case Address of
+ {IP, Port} when ?is_word(Port) ->
+ case check_address_ip(Domain, IP) of
+ false ->
+ false;
+ true ->
+ true;
+ FixedIP ->
+ {FixedIP, Port}
+ end;
+ %% SNMP standards format
+ [A0,A1,A2,A3,P0,P1]
+ when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) ->
+ {{A0, A1, A2, A3}, mk_word(P0, P1)};
+ _ ->
+ false
+ end;
+check_address_ip_port(transportDomainUdpIpv6 = Domain, Address) ->
+ case Address of
+ {IP, Port} when ?is_word(Port) ->
+ case check_address_ip(Domain, IP) of
+ false ->
+ false;
+ true ->
+ true;
+ FixedIP ->
+ {FixedIP, Port}
+ end;
+ %% Erlang friendly list format
+ [A0,A1,A2,A3,A4,A5,A6,A7,P]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P) ->
+ {{A0, A1, A2, A3, A4, A5, A6, A7}, P};
+ %% Strange hybrid format with port as bytes
+ [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P0, P1) ->
+ {{A0, A1, A2, A3, A4, A5, A6, A7}, mk_word(P0, P1)};
+ %% SNMP standards format
+ [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1]
+ when ?is_ipv6_addr(
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ A8, A9, A10, A11, A12, A13, A14, A15),
+ ?is_word(P0, P1) ->
+ {{mk_word(A0, A1), mk_word(A2, A3),
+ mk_word(A4, A5), mk_word(A6, A7),
+ mk_word(A8, A9), mk_word(A10, A11),
+ mk_word(A12, A13), mk_word(A14, A15)},
+ mk_word(P0, P1)};
+ _ ->
+ false
+ end;
+check_address_ip_port(BadDomain, _) ->
+ error({bad_domain, BadDomain}).
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index a222f842e5..9e9865f3b5 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,16 +26,21 @@
-compile({no_auto_import,[error/1]}).
-export([config/0]).
--export([write_config_file/4, append_config_file/4, read_config_file/3]).
+%%-export([write_config_file/4, append_config_file/4, read_config_file/4]).
+
+-export([write_config_file/6, append_config_file/6, read_config_file/4]).
-export([write_agent_snmp_files/7, write_agent_snmp_files/12,
+ write_agent_snmp_files/6, write_agent_snmp_files/11,
- write_agent_snmp_conf/5,
+ write_agent_snmp_conf/4, write_agent_snmp_conf/5,
write_agent_snmp_context_conf/1,
write_agent_snmp_community_conf/1,
write_agent_snmp_standard_conf/2,
- write_agent_snmp_target_addr_conf/4,
- write_agent_snmp_target_addr_conf/6,
+ write_agent_snmp_target_addr_conf/3,
+ write_agent_snmp_target_addr_conf/4,
+ write_agent_snmp_target_addr_conf/5,
+ write_agent_snmp_target_addr_conf/6,
write_agent_snmp_target_params_conf/2,
write_agent_snmp_notify_conf/2,
write_agent_snmp_usm_conf/5,
@@ -90,9 +95,9 @@
]).
--export_type([void/0,
- verify_config_entry_function/0,
- verify_config_function/0,
+-export_type([void/0,
+ order_config_entry_function/0,
+ check_config_entry_function/0,
write_config_function/0]).
@@ -567,11 +572,9 @@ config_agent_snmp(Dir, Vsns) ->
end,
NT
end,
- case (catch write_agent_snmp_files(Dir,
- Vsns, ManagerIP, TrapUdp,
- AgentIP, AgentUDP,
- SysName, NotifType, SecType,
- Passwd, EngineID, MMS)) of
+ case (catch write_agent_snmp_files(
+ Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP, SysName,
+ NotifType, SecType, Passwd, EngineID, MMS)) of
ok ->
i("~n- - - - - - - - - - - - -"),
i("Info: 1. SecurityName \"initial\" has noAuthNoPriv read access~n"
@@ -1580,35 +1583,63 @@ remove_newline(Str) ->
%% File generation
%%======================================================================
+write_agent_snmp_files(
+ Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName)
+ when is_list(Dir),
+ is_list(Vsns),
+ is_atom(Domain),
+ is_list(SysName) ->
+ write_agent_snmp_files(
+ Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName,
+ trap, none, "", "agentEngine", 484).
+
%%----------------------------------------------------------------------
%% Dir: string() (ex: "../conf/")
%% ManagerIP, AgentIP: [int(),int(),int(),int()]
%% TrapUdp, AgentUDP: integer()
%% SysName: string()
%%----------------------------------------------------------------------
-write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp,
- AgentIP, AgentUDP, SysName)
- when is_list(Dir) andalso
- is_list(Vsns) andalso
- is_list(ManagerIP) andalso
- is_integer(TrapUdp) andalso
- is_list(AgentIP) andalso
- is_integer(AgentUDP) andalso
+write_agent_snmp_files(
+ Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName)
+ when is_list(Dir) andalso
+ is_list(Vsns) andalso
+ is_list(ManagerIP) andalso
+ is_integer(TrapUDP) andalso
+ is_list(AgentIP) andalso
+ is_integer(AgentUDP) andalso
is_list(SysName) ->
- write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP,
- SysName, "trap", none, "", "agentEngine", 484).
+ write_agent_snmp_files(
+ Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName,
+ trap, none, "", "agentEngine", 484).
%%
%% ----- Agent config files generator functions -----
%%
-write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP,
- SysName, NotifType, SecType, Passwd, EngineID, MMS) ->
+write_agent_snmp_files(
+ Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName,
+ NotifType, SecType, Passwd, EngineID, MMS) ->
+ write_agent_snmp_conf(Dir, Domain, AgentAddr, EngineID, MMS),
+ write_agent_snmp_context_conf(Dir),
+ write_agent_snmp_community_conf(Dir),
+ write_agent_snmp_standard_conf(Dir, SysName),
+ write_agent_snmp_target_addr_conf(Dir, Domain, ManagerAddr, Vsns),
+ write_agent_snmp_target_params_conf(Dir, Vsns),
+ write_agent_snmp_notify_conf(Dir, NotifType),
+ write_agent_snmp_usm_conf(Dir, Vsns, EngineID, SecType, Passwd),
+ write_agent_snmp_vacm_conf(Dir, Vsns, SecType),
+ ok.
+
+write_agent_snmp_files(
+ Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName,
+ NotifType, SecType, Passwd, EngineID, MMS) ->
+ Domain = snmp_target_mib:default_domain(),
+ ManagerAddr = {ManagerIP, TrapUDP},
write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS),
write_agent_snmp_context_conf(Dir),
write_agent_snmp_community_conf(Dir),
write_agent_snmp_standard_conf(Dir, SysName),
- write_agent_snmp_target_addr_conf(Dir, ManagerIP, TrapUdp, Vsns),
+ write_agent_snmp_target_addr_conf(Dir, Domain, ManagerAddr, Vsns),
write_agent_snmp_target_params_conf(Dir, Vsns),
write_agent_snmp_notify_conf(Dir, NotifType),
write_agent_snmp_usm_conf(Dir, Vsns, EngineID, SecType, Passwd),
@@ -1616,11 +1647,38 @@ write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP,
ok.
+
%%
%% ------ [agent] agent.conf ------
%%
-write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS) ->
+write_agent_snmp_conf(Dir, Transports, EngineID, MMS) ->
+ Conf =
+ [{intAgentTransports, Transports},
+ {snmpEngineID, EngineID},
+ {snmpEngineMaxMessageSize, MMS}],
+ do_write_agent_snmp_conf(Dir, Conf).
+
+write_agent_snmp_conf(Dir, Domain, AgentAddr, EngineID, MMS)
+ when is_atom(Domain) ->
+ {AgentIP, AgentUDP} = AgentAddr,
+ Conf =
+ [{intAgentTransportDomain, Domain},
+ {intAgentUDPPort, AgentUDP},
+ {intAgentIpAddress, AgentIP},
+ {snmpEngineID, EngineID},
+ {snmpEngineMaxMessageSize, MMS}],
+ do_write_agent_snmp_conf(Dir, Conf);
+write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS)
+ when is_integer(AgentUDP) ->
+ Conf =
+ [{intAgentUDPPort, AgentUDP},
+ {intAgentIpAddress, AgentIP},
+ {snmpEngineID, EngineID},
+ {snmpEngineMaxMessageSize, MMS}],
+ do_write_agent_snmp_conf(Dir, Conf).
+
+do_write_agent_snmp_conf(Dir, Conf) ->
Comment =
"%% This file defines the Agent local configuration info\n"
"%% The data is inserted into the snmpEngine* variables defined\n"
@@ -1635,11 +1693,7 @@ write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS) ->
"%% {snmpEngineID, \"agentEngine\"}.\n"
"%% {snmpEngineMaxMessageSize, 484}.\n"
"%%\n\n",
- Hdr = header() ++ Comment,
- Conf = [{intAgentUDPPort, AgentUDP},
- {intAgentIpAddress, AgentIP},
- {snmpEngineID, EngineID},
- {snmpEngineMaxMessageSize, MMS}],
+ Hdr = header() ++ Comment,
write_agent_config(Dir, Hdr, Conf).
write_agent_config(Dir, Hdr, Conf) ->
@@ -1745,17 +1799,19 @@ update_agent_standard_config(Dir, Conf) ->
%% ------ target_addr.conf ------
%%
-write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Vsns) ->
- Timeout = 1500,
- RetryCount = 3,
- write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP,
- Timeout, RetryCount,
- Vsns).
+write_agent_snmp_target_addr_conf(Dir, Addresses, Vsns) ->
+ Timeout = 1500,
+ RetryCount = 3,
+ write_agent_snmp_target_addr_conf(
+ Dir, Addresses, Timeout, RetryCount, Vsns).
-write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP,
- Timeout, RetryCount,
- Vsns) ->
- Comment =
+write_agent_snmp_target_addr_conf(Dir, Domain_or_Ip, Addr_or_Port, Vsns) ->
+ Addresses = [{Domain_or_Ip, Addr_or_Port}],
+ write_agent_snmp_target_addr_conf(Dir, Addresses, Vsns).
+
+write_agent_snmp_target_addr_conf(
+ Dir, Addresses, Timeout, RetryCount, Vsns) ->
+ Comment =
"%% This file defines the target address parameters.\n"
"%% The data is inserted into the snmpTargetAddrTable defined\n"
"%% in SNMP-TARGET-MIB, and in the snmpTargetAddrExtTable defined\n"
@@ -1774,36 +1830,59 @@ write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP,
"%% [127,0,0,0], 2048}.\n"
"%%\n\n",
Hdr = header() ++ Comment,
- F = fun(v1 = Vsn, Acc) ->
- [{mk_ip(ManagerIp, Vsn),
- snmp_target_mib:default_domain(),
- ManagerIp, UDP, Timeout, RetryCount,
- "std_trap", mk_param(Vsn), "", [], 2048}| Acc];
- (v2 = Vsn, Acc) ->
- [{mk_ip(ManagerIp, Vsn),
- snmp_target_mib:default_domain(),
- ManagerIp, UDP, Timeout, RetryCount,
- "std_trap", mk_param(Vsn), "", [], 2048},
- {lists:flatten(io_lib:format("~s.2",[mk_ip(ManagerIp, Vsn)])),
- ManagerIp, UDP, Timeout, RetryCount,
- "std_inform", mk_param(Vsn), "", [], 2048}| Acc];
- (v3 = Vsn, Acc) ->
- [{mk_ip(ManagerIp, Vsn),
- snmp_target_mib:default_domain(),
- ManagerIp, UDP, Timeout, RetryCount,
- "std_trap", mk_param(Vsn), "", [], 2048},
- {lists:flatten(io_lib:format("~s.3",[mk_ip(ManagerIp, Vsn)])),
- ManagerIp, UDP, Timeout, RetryCount,
- "std_inform", mk_param(Vsn), "mgrEngine", [], 2048}| Acc]
- end,
- Conf = lists:foldl(F, [], Vsns),
+ Conf =
+ lists:foldl(
+ fun ({Domain_or_Ip, Addr_or_Port} = Address, OuterAcc) ->
+ lists:foldl(
+ fun(v1 = Vsn, Acc) ->
+ [{mk_name(Address, Vsn),
+ Domain_or_Ip, Addr_or_Port,
+ Timeout, RetryCount,
+ "std_trap", mk_param(Vsn), "",
+ [], 2048}| Acc];
+ (v2 = Vsn, Acc) ->
+ [{mk_name(Address, Vsn),
+ Domain_or_Ip, Addr_or_Port,
+ Timeout, RetryCount,
+ "std_trap", mk_param(Vsn), "",
+ [], 2048},
+ {lists:flatten(
+ io_lib:format(
+ "~s.2", [mk_name(Address, Vsn)])),
+ Domain_or_Ip, Addr_or_Port,
+ Timeout, RetryCount,
+ "std_inform", mk_param(Vsn), "",
+ [], 2048}| Acc];
+ (v3 = Vsn, Acc) ->
+ [{mk_name(Address, Vsn),
+ Domain_or_Ip, Addr_or_Port,
+ Timeout, RetryCount,
+ "std_trap", mk_param(Vsn), "",
+ [], 2048},
+ {lists:flatten(
+ io_lib:format(
+ "~s.3", [mk_name(Address, Vsn)])),
+ Domain_or_Ip, Addr_or_Port,
+ Timeout, RetryCount,
+ "std_inform", mk_param(Vsn), "mgrEngine",
+ [], 2048} | Acc]
+ end, OuterAcc, Vsns)
+ end, [], Addresses),
write_agent_target_addr_config(Dir, Hdr, Conf).
+write_agent_snmp_target_addr_conf(
+ Dir, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, Vsns) ->
+ Addresses = [{Domain_or_Ip, Addr_or_Port}],
+ write_agent_snmp_target_addr_conf(
+ Dir, Addresses, Timeout, RetryCount, Vsns).
+
mk_param(Vsn) ->
lists:flatten(io_lib:format("target_~w", [Vsn])).
-mk_ip([A,B,C,D], Vsn) ->
- lists:flatten(io_lib:format("~w.~w.~w.~w ~w", [A,B,C,D,Vsn])).
+mk_name(Address, Vsn) ->
+ lists:flatten(
+ io_lib:format(
+ "~s ~w", [snmp_conf:mk_addr_string(Address), Vsn])).
write_agent_target_addr_config(Dir, Hdr, Conf) ->
snmpa_conf:write_target_addr_config(Dir, Hdr, Conf).
@@ -2049,10 +2128,19 @@ write_manager_snmp_conf(Dir, IP, Port, MMS, EngineID) ->
"%% {max_message_size, 484}.\n"
"%%\n\n",
Hdr = header() ++ Comment,
- Conf = [{port, Port},
- {address, IP},
- {engine_id, EngineID},
- {max_message_size, MMS}],
+ Conf =
+ case Port of
+ {Addr, P} when is_integer(P), is_atom(IP) ->
+ Domain = IP,
+ [{domain, Domain},
+ {port, P},
+ {address, Addr}];
+ _ when is_integer(Port) ->
+ [{port, Port},
+ {address, IP}]
+ end ++
+ [{engine_id, EngineID},
+ {max_message_size, MMS}],
write_manager_config(Dir, Hdr, Conf).
write_manager_config(Dir, Hdr, Conf) ->
@@ -2410,83 +2498,92 @@ header() ->
[?MODULE, ?version, Y, Mo, D, H, Mi, S]).
-%% *If* these functions are successfull, they successfully return anything
-%% (which is ignored), but they fail with either a throw or an exit or
-%% something similar.
-
-%% Verification of one config entry read from a file
--type(verify_config_entry_function() ::
- fun((Entry :: term()) -> ok | {error, Reason :: term()})).
-
-%% Verification of config to be written
--type(verify_config_function() ::
- fun(() -> void())).
-
-%% Write config to file (as defined by Fd)
--type(write_config_function() ::
- fun((Fd :: file:io_device()) -> void())).
-
--spec write_config_file(Dir :: string(),
- FileName :: string(),
- Verify :: verify_config_function(),
- Write :: write_config_function()) ->
- ok | {error, Reason :: term()}.
-
-write_config_file(Dir, FileName, Verify, Write)
- when (is_list(Dir) andalso
- is_list(FileName) andalso
- is_function(Verify) andalso
- is_function(Write)) ->
+%% *If* these functions are successfull, they successfully return
+%% (value is ignored), but they fail preferably with
+%% throw({error, Reason}). Other exceptions are also handled.
+
+%% Sorting order for config entries (see lists:sort/2)
+-type(order_config_entry_function() ::
+ fun((term(), term()) -> boolean())).
+
+%% Check of config entries. Initial State is 'undefined'
+-type(check_config_entry_function() ::
+ fun((Entry :: term(), State :: undefined | term()) ->
+ {ok | {ok, NewEntry :: term()}, NewState :: term()})).
+
+%% Write configuration entries to file descriptor Fd
+-type(write_config_function() ::
+ fun((Fd :: file:io_device(), [Entry :: term()]) -> ok)).
+
+-spec write_config_file(
+ Dir :: string(),
+ FileName :: string(),
+ Order :: order_config_entry_function(),
+ Check :: check_config_entry_function(),
+ Write :: write_config_function(),
+ Entries :: [term()]) ->
+ ok | {error, term()}.
+
+write_config_file(Dir, FileName, Order, Check, Write, Entries)
+ when is_list(Dir), is_list(FileName),
+ is_function(Order), is_function(Check), is_function(Write),
+ is_list(Entries) ->
try
- begin
- do_write_config_file(Dir, FileName, Verify, Write)
- end
+ SortedEntries = lists:sort(Order, Entries),
+ _ =
+ lists:foldl(
+ fun (Entry, State) ->
+ case Check(Entry, State) of
+ {Ok, NewState} when is_list(Ok) ->
+ NewState;
+ {ok, NewState} ->
+ NewState;
+ {{ok, _}, NewState} ->
+ NewState
+ end
+ end, undefined, SortedEntries),
+ ok
+ of
+ _ ->
+ case file:open(filename:join(Dir, FileName), [write]) of
+ {ok, Fd} ->
+ write_config_file(Dir, FileName, Write, Entries, Fd);
+ Error ->
+ Error
+ end
catch
- throw:Error ->
- Error;
- T:E ->
- {error, {failed_write, Dir, FileName, T, E}}
- end.
-
-
-do_write_config_file(Dir, FileName, Verify, Write) ->
- Verify(),
- case file:open(filename:join(Dir, FileName), [write]) of
- {ok, Fd} ->
- file_write_and_close(Write, Fd, Dir, FileName);
Error ->
- Error
- end.
-
-append_config_file(Dir, FileName, Verify, Write)
- when (is_list(Dir) andalso
- is_list(FileName) andalso
- is_function(Verify) andalso
- is_function(Write)) ->
- try
- begin
- do_append_config_file(Dir, FileName, Verify, Write)
- end
- catch
- throw:Error ->
+ S = erlang:get_stacktrace(),
+ d("File write of ~s throwed: ~p~n ~p~n",
+ [FileName, Error, S]),
Error;
- T:E ->
- {error, {failed_append, Dir, FileName, T, E}}
+ C:E ->
+ S = erlang:get_stacktrace(),
+ d("File write of ~s exception: ~p:~p~n ~p~n",
+ [FileName,C,E,S]),
+ {error, {failed_write, Dir, FileName, {C, E, S}}}
end.
-do_append_config_file(Dir, FileName, Verify, Write) ->
- Verify(),
- case file:open(filename:join(Dir, FileName), [read, write]) of
- {ok, Fd} ->
- file:position(Fd, eof),
- file_write_and_close(Write, Fd, Dir, FileName);
+write_config_file(Dir, FileName, Write, Entries, Fd) ->
+ try Write(Fd, Entries) of
+ ok ->
+ close_config_file(Dir, FileName, Fd)
+ catch
Error ->
- Error
+ S = erlang:get_stacktrace(),
+ d("File write of ~s throwed: ~p~n ~p~n",
+ [FileName, Error, S]),
+ close_config_file(Dir, FileName, Fd),
+ Error;
+ C:E ->
+ S = erlang:get_stacktrace(),
+ d("File write of ~s exception: ~p:~p~n ~p~n",
+ [FileName,C,E,S]),
+ close_config_file(Dir, FileName, Fd),
+ {error, {failed_write, Dir, FileName, {C, E, S}}}
end.
-
-file_write_and_close(Write, Fd, Dir, FileName) ->
- ok = Write(Fd),
+close_config_file(Dir, FileName, Fd) ->
case file:sync(Fd) of
ok ->
case file:close(Fd) of
@@ -2496,63 +2593,159 @@ file_write_and_close(Write, Fd, Dir, FileName) ->
{error, {failed_closing, Dir, FileName, Reason}}
end;
{error, Reason} ->
+ _ = file:close(Fd),
{error, {failed_syncing, Dir, FileName, Reason}}
end.
--spec read_config_file(Dir :: string(),
- FileName :: string(),
- Verify :: verify_config_entry_function()) ->
- {ok, Config :: list()} | {error, Reason :: term()}.
-read_config_file(Dir, FileName, Verify)
- when is_list(Dir) andalso is_list(FileName) andalso is_function(Verify) ->
- (catch do_read_config_file(Dir, FileName, Verify)).
+-spec append_config_file(
+ Dir :: string(),
+ FileName :: string(),
+ Order :: order_config_entry_function(),
+ Check :: check_config_entry_function(),
+ Write :: write_config_function(),
+ Entries :: [term()]) ->
+ ok | {error, term()}.
+
+append_config_file(Dir, FileName, Order, Check, Write, Entries)
+ when is_list(Dir), is_list(FileName),
+ is_function(Order), is_function(Check), is_function(Write),
+ is_list(Entries) ->
+ case file:open(filename:join(Dir, FileName), [read, write]) of
+ {ok, Fd} ->
+ append_config_file(
+ Dir, FileName, Order, Check, Write, Entries, Fd);
+ Error ->
+ Error
+ end.
+
+append_config_file(Dir, FileName, Order, Check, Write, Entries, Fd) ->
+ try
+ %% Verify the entries together with the file content
+ LinesInFileR = read_lines(Fd, [], 1),
+ StartLine =
+ case LinesInFileR of
+ [] ->
+ 1;
+ [{_, _, EndLine} | _] ->
+ EndLine
+ end,
+ LinesR = prepend_lines(LinesInFileR, Entries, StartLine),
+ SortedLines = sort_lines(lists:reverse(LinesR), Order),
+ _ = verify_lines(SortedLines, Check, undefined, []),
+ %% Append to the file
+ Write(Fd, Entries)
+ of
+ ok ->
+ close_config_file(Dir, FileName, Fd)
+ catch
+ Error ->
+ S = erlang:get_stacktrace(),
+ d("File append of ~s throwed: ~p~n ~p~n",
+ [FileName, Error, S]),
+ close_config_file(Dir, FileName, Fd),
+ Error;
+ C:E ->
+ S = erlang:get_stacktrace(),
+ d("File append of ~s exception: ~p:~p~n ~p~n",
+ [FileName,C,E,S]),
+ close_config_file(Dir, FileName, Fd),
+ {error, {failed_append, Dir, FileName, {C, E, S}}}
+ end.
-do_read_config_file(Dir, FileName, Verify) ->
+%% Fake line numbers, one per entry
+prepend_lines(Lines, [], _) ->
+ Lines;
+prepend_lines(Lines, [Entry | Entries], StartLine) ->
+ EndLine = StartLine + 1,
+ prepend_lines([{StartLine, Entry, EndLine} | Lines], Entries, EndLine).
+
+
+
+-spec read_config_file(
+ Dir :: string(),
+ FileName :: string(),
+ Order :: order_config_entry_function(),
+ Check :: check_config_entry_function()) ->
+ {ok, Config :: [Entry :: term()]} |
+ {error, Reason :: term()}.
+
+read_config_file(Dir, FileName, Order, Check)
+ when is_list(Dir), is_list(FileName),
+ is_function(Order), is_function(Check) ->
case file:open(filename:join(Dir, FileName), [read]) of
{ok, Fd} ->
- Result = read_loop(Fd, [], Verify, 1),
- file:close(Fd),
- Result;
+ try
+ Lines = lists:reverse(read_lines(Fd, [], 1)),
+ SortedLines = sort_lines(Lines, Order),
+ {ok, verify_lines(SortedLines, Check, undefined, [])}
+ catch
+ Error ->
+ S = erlang:get_stacktrace(),
+ d("File read of ~s throwed: ~p~n ~p~n",
+ [FileName, Error, S]),
+ {error, Error};
+ T:E ->
+ S = erlang:get_stacktrace(),
+ d("File read of ~s exception: ~p:~p~n ~p~n",
+ [FileName,T,E,S]),
+ {error, {failed_read, Dir, FileName, {T, E, S}}}
+ after
+ file:close(Fd)
+ end;
{error, Reason} ->
{error, {Reason, FileName}}
end.
-read_loop(Fd, Acc, Check, StartLine) ->
- case read_term(Fd, StartLine) of
+read_lines(Fd, Acc, StartLine) ->
+ case read_and_parse_term(Fd, StartLine) of
{ok, Term, EndLine} ->
- case (catch Check(Term)) of
- ok ->
- read_loop(Fd, [Term | Acc], Check, EndLine);
- {error, Reason} ->
- {error, {failed_check, StartLine, EndLine, Reason}};
- Error ->
- {error, {failed_check, StartLine, EndLine, Error}}
- end;
- {error, EndLine, Error} ->
- {error, {failed_reading, StartLine, EndLine, Error}};
- eof ->
- {ok, lists:reverse(Acc)}
+ read_lines(Fd, [{StartLine, Term, EndLine}|Acc], EndLine);
+ {error, Error, EndLine} ->
+ throw({failed_reading, StartLine, EndLine, Error});
+ {eof, _EndLine} ->
+ Acc
end.
-
-read_term(Fd, StartLine) ->
+
+read_and_parse_term(Fd, StartLine) ->
case io:request(Fd, {get_until, "", erl_scan, tokens, [StartLine]}) of
{ok, Tokens, EndLine} ->
case erl_parse:parse_term(Tokens) of
{ok, Term} ->
{ok, Term, EndLine};
{error, {Line, erl_parse, Error}} ->
- {error, Line, {parse_error, Error}}
+ {error, {parse_error, Error}, Line}
end;
- {error, E, EndLine} ->
- {error, EndLine, E};
- {eof, _EndLine} ->
- eof;
Other ->
Other
end.
+sort_lines(Lines, Order) ->
+ lists:sort(
+ fun ({_, T1, _}, {_, T2, _}) ->
+ Order(T1, T2)
+ end, Lines).
+
+verify_lines([], _, _, Acc) ->
+ lists:reverse(Acc);
+verify_lines(
+ [{StartLine, Term, EndLine}|Lines], Check, State, Acc) ->
+ try Check(Term, State) of
+ {Terms, NewState} when is_list(Terms) ->
+ verify_lines(Lines, Check, NewState, Terms ++ Acc);
+ {ok, NewState} ->
+ verify_lines(Lines, Check, NewState, [Term|Acc]);
+ {{ok, NewTerm}, NewState} ->
+ verify_lines(Lines, Check, NewState, [NewTerm|Acc])
+ catch
+ {error, Reason} ->
+ throw({failed_check, StartLine, EndLine, Reason});
+ C:R ->
+ S = erlang:get_stacktrace(),
+ throw({failed_check, StartLine, EndLine, {C, R, S}})
+ end.
+
agent_snmp_mk_secret(Alg, Passwd, EngineID) ->
snmp_usm:passwd2localized_key(Alg, Passwd, EngineID).
@@ -2575,8 +2768,8 @@ ensure_started(App) ->
%% -------------------------------------------------------------------------
-% d(F, A) ->
-% i("DBG: " ++ F, A).
+d(F, A) ->
+ i("DBG: " ++ F, A).
i(F) ->
i(F, []).
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index ae28df37fa..4b22281b89 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-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,7 @@
-export([
create/4, create/5, create/6, open/1, open/2,
change_size/2, close/1, sync/1, info/1,
- log/4,
+ log/3, log/4,
log_to_txt/6, log_to_txt/7, log_to_txt/8,
log_to_io/5, log_to_io/6, log_to_io/7
]).
@@ -231,7 +231,20 @@ validate(Log, SeqNoReq)
validate_seqno(PrevSN, SeqNo),
{Timestamp, SeqNo};
- ({Timestamp, _Packet, _Addr, _Port}, {PrevTS, _PrevSN}) when SeqNoReq =:= true ->
+ ({Timestamp, SeqNo, _Packet, _AddrStr}, {PrevTS, PrevSN})
+ when is_integer(SeqNo) ->
+ ?vtrace("validating log entry when"
+ "~n Timestamp: ~p"
+ "~n SeqNo: ~p"
+ "~n PrevTS: ~p"
+ "~n PrevSN: ~p",
+ [Timestamp, SeqNo, PrevTS, PrevSN]),
+ validate_timestamp(PrevTS, Timestamp),
+ validate_seqno(PrevSN, SeqNo),
+ {Timestamp, SeqNo};
+
+ ({Timestamp, _Packet, _Addr, _Port}, {PrevTS, _PrevSN})
+ when SeqNoReq =:= true ->
?vtrace("validating log entry when"
"~n Timestamp: ~p"
"~n PrevTS: ~p",
@@ -344,12 +357,20 @@ validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) ->
%% log(Log, Packet, Addr, Port)
%%-----------------------------------------------------------------
-log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Addr, Port) ->
+log(#snmp_log{id = Log, seqno = SeqNo}, Packet, AddrStr) ->
+ ?vtrace(
+ "log -> entry with~n"
+ " Log: ~p~n"
+ " AddrStr: ~s", [Log, AddrStr]),
+ Entry = make_entry(SeqNo, Packet, AddrStr),
+ disk_log:alog(Log, Entry).
+
+log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Ip, Port) ->
?vtrace("log -> entry with"
"~n Log: ~p"
- "~n Addr: ~p"
- "~n Port: ~p", [Log, Addr, Port]),
- Entry = make_entry(SeqNo, Packet, Addr, Port),
+ "~n Ip: ~p"
+ "~n Port: ~p", [Log, Ip, Port]),
+ Entry = make_entry(SeqNo, Packet, Ip, Port),
%% io:format("log -> "
%% "~n Entry: ~p"
%% "~n Info: ~p"
@@ -361,18 +382,35 @@ log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Addr, Port) ->
%% "~n", [Res, disk_log:info(Log)]),
%% disk_log:sync(Log),
Res.
-
-make_entry(SeqNoGen, Packet, Addr, Port) ->
+
+make_entry(SeqNoGen, Packet, AddrStr)
+ when is_integer(Packet);
+ is_tuple(AddrStr) ->
+ erlang:error(badarg, [SeqNoGen, Packet, AddrStr]);
+make_entry(SeqNoGen, Packet, AddrStr) ->
try next_seqno(SeqNoGen) of
disabled ->
- {timestamp(), Packet, Addr, Port};
- {ok, NextSeqNo} ->
- {timestamp(), NextSeqNo, Packet, Addr, Port}
+ {timestamp(), Packet, AddrStr};
+ {ok, NextSeqNo} when is_integer(NextSeqNo) ->
+ {timestamp(), NextSeqNo, Packet, AddrStr}
catch
_:_ ->
- {timestamp(), Packet, Addr, Port}
+ {timestamp(), Packet, AddrStr}
+ end.
+
+make_entry(SeqNoGen, Packet, Ip, Port) when is_integer(Packet) ->
+ erlang:error(badarg, [SeqNoGen, Packet, Ip, Port]);
+make_entry(SeqNoGen, Packet, Ip, Port) ->
+ try next_seqno(SeqNoGen) of
+ disabled ->
+ {timestamp(), Packet, Ip, Port};
+ {ok, NextSeqNo} when is_integer(NextSeqNo) ->
+ {timestamp(), NextSeqNo, Packet, Ip, Port}
+ catch
+ _:_ ->
+ {timestamp(), Packet, Ip, Port}
end.
next_seqno({M, F, A}) ->
@@ -674,60 +712,68 @@ format_msg(Entry, Mib, Start, Stop) ->
end.
%% This is an old-style entry, that never had the sequence-number
-do_format_msg({Timestamp, Packet, {Addr, Port}}, Mib) ->
- do_format_msg(Timestamp, Packet, Addr, Port, Mib);
+do_format_msg({Timestamp, Packet, {Ip, Port}}, Mib) ->
+ do_format_msg(Timestamp, Packet, ipPort2Str(Ip, Port), Mib);
+%% This is the format without sequence-number
+do_format_msg({Timestamp, Packet, AddrStr}, Mib) ->
+ do_format_msg(Timestamp, Packet, AddrStr, Mib);
+%% This is the format with sequence-number
+do_format_msg({Timestamp, SeqNo, Packet, AddrStr}, Mib)
+ when is_integer(SeqNo) ->
+ do_format_msg(Timestamp, Packet, AddrStr, Mib);
%% This is the format without sequence-number
-do_format_msg({Timestamp, Packet, Addr, Port}, Mib) ->
- do_format_msg(Timestamp, Packet, Addr, Port, Mib);
+do_format_msg({Timestamp, Packet, Ip, Port}, Mib) ->
+ do_format_msg(Timestamp, Packet, ipPort2Str(Ip, Port), Mib);
%% This is the format with sequence-number
-do_format_msg({Timestamp, SeqNo, Packet, Addr, Port}, Mib) ->
- do_format_msg(Timestamp, SeqNo, Packet, Addr, Port, Mib);
+do_format_msg({Timestamp, SeqNo, Packet, Ip, Port}, Mib) ->
+ do_format_msg(Timestamp, SeqNo, Packet, ipPort2Str(Ip, Port), Mib);
%% This is crap...
do_format_msg(_, _) ->
format_tab("** unknown entry in log file\n\n", []).
-do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, AddrStr, Mib) ->
case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
Msg = #message{version = 'version-3',
vsn_hdr = V3Hdr,
data = ScopedPDU},
- f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+ f(ts2str(TimeStamp), "", Msg, AddrStr, Mib);
{'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
- [ts2str(TimeStamp), ip(Addr), Port, Reason])
+ format_tab(
+ "** error in log file at ~s from ~s ~p\n\n",
+ [ts2str(TimeStamp), AddrStr, Reason])
end;
-do_format_msg(TimeStamp, Packet, Addr, Port, Mib) ->
+do_format_msg(TimeStamp, Packet, AddrStr, Mib) ->
case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
Msg when is_record(Msg, message) ->
- f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+ f(ts2str(TimeStamp), "", Msg, AddrStr, Mib);
{'EXIT', Reason} ->
format_tab("** error in log file ~p\n\n", [Reason])
end.
-do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, AddrStr, Mib) ->
case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
Msg = #message{version = 'version-3',
vsn_hdr = V3Hdr,
data = ScopedPDU},
- f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+ f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib);
{'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
- [ts2str(TimeStamp), sn2str(SeqNo),
- ip(Addr), Port, Reason])
+ format_tab(
+ "** error in log file at ~s from ~s ~p\n\n",
+ [ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason])
end;
-do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) ->
+do_format_msg(TimeStamp, SeqNo, Packet, AddrStr, Mib) ->
case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
Msg when is_record(Msg, message) ->
- f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+ f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib);
{'EXIT', Reason} ->
- format_tab("** error in log file ~s from ~p:~w ~p\n\n",
- [ts2str(TimeStamp), sn2str(SeqNo),
- ip(Addr), Port, Reason])
+ format_tab(
+ "** error in log file ~s from ~s ~p\n\n",
+ [ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason])
end.
@@ -771,44 +817,71 @@ do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) ->
f(TimeStamp, SeqNo,
#message{version = Vsn, vsn_hdr = VsnHdr, data = Data},
- Addr, Port, Mib) ->
+ AddrStr, Mib) ->
Str = format_pdu(Data, Mib),
HdrStr = format_header(Vsn, VsnHdr),
- case get_type(Data) of
- trappdu ->
- f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'snmpv2-trap' ->
- f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'inform-request' ->
- f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'get-response' ->
- f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- report ->
- f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- _ ->
- f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
- end.
+ Class =
+ case get_type(Data) of
+ trappdu ->
+ trap;
+ 'snmpv2-trap' ->
+ trap;
+ 'inform-request' ->
+ inform;
+ 'get-response' ->
+ response;
+ report ->
+ report;
+ _ ->
+ request
+ end,
+ format_tab(
+ "~w ~s - ~s [~s]~s ~w\n~s",
+ [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+
+%% f(TimeStamp, SeqNo,
+%% #message{version = Vsn, vsn_hdr = VsnHdr, data = Data},
+%% Addr, Port, Mib) ->
+%% Str = format_pdu(Data, Mib),
+%% HdrStr = format_header(Vsn, VsnHdr),
+%% case get_type(Data) of
+%% trappdu ->
+%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+%% 'snmpv2-trap' ->
+%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+%% 'inform-request' ->
+%% f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+%% 'get-response' ->
+%% f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+%% report ->
+%% f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+%% _ ->
+%% f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
+%% end.
-f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("request ~s:~w - ~s [~s]~s ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+%% f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+%% format_tab("request ~s:~w - ~s [~s]~s ~w\n~s",
+%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("response ~s:~w - ~s [~s]~s ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+%% f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+%% format_tab("response ~s:~w - ~s [~s]~s ~w\n~s",
+%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("report ~s:~w - ~s [~s]~s ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+%% f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+%% format_tab("report ~s:~w - ~s [~s]~s ~w\n~s",
+%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("trap ~s:~w - ~s [~s]~s ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+%% format_tab("trap ~s:~w - ~s [~s]~s ~w\n~s",
+%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("inform ~s:~w - ~s [~s]~s ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+%% f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+%% format_tab("inform ~s:~w - ~s [~s]~s ~w\n~s",
+%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
+ipPort2Str(Ip, Port) ->
+ snmp_conf:mk_addr_string({Ip, Port}).
+ %% io_lib:format("~s:~w", [ip(Ip), Port]).
%% Convert a timestamp 2-tupple to a printable string
%%
@@ -909,8 +982,10 @@ get_type(#pdu{type = Type}) ->
Type.
-ip({A,B,C,D}) ->
- io_lib:format("~w.~w.~w.~w", [A,B,C,D]).
+%% ip(Domain, Addr) ->
+%% snmp_conf:mk_addr_string(Domain, Addr).
+%% ip({A,B,C,D}) ->
+%% io_lib:format("~w.~w.~w.~w", [A,B,C,D]).
diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl
index 15156f7467..90fa4c0dea 100644
--- a/lib/snmp/src/misc/snmp_pdus.erl
+++ b/lib/snmp/src/misc/snmp_pdus.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -174,7 +174,7 @@ dec_pdu_tag(168) ->
dec_pdu([164 | Bytes]) -> % It's a trap
Bytes2 = get_data_bytes(Bytes),
{Enterprise, Rest1} = dec_oid_tag(Bytes2),
- {{'IpAddress', AgentAddr}, Rest2} = dec_value(Rest1),
+ {{'IpAddress', [_, _, _, _] = AgentAddr}, Rest2} = dec_value(Rest1),
{GenericTrap, Rest3} = dec_int_tag(Rest2),
{SpecificTrap, Rest4} = dec_int_tag(Rest3),
{{'TimeTicks', TimeStamp}, VBBytes} = dec_value(Rest4),
@@ -664,7 +664,9 @@ enc_value('BITS', Val) ->
enc_oct_str_tag(bits_to_str(Val));
enc_value('OBJECT IDENTIFIER', Val) ->
enc_oid_tag(Val);
-enc_value('IpAddress', Val) ->
+enc_value('IpAddress', {A, B, C, D}) ->
+ enc_value('IpAddress', [A,B,C,D]);
+enc_value('IpAddress', Val) when is_list(Val) ->
Bytes2 = enc_oct_str_notag(Val),
Len2 = elength(length(Bytes2)),
lists:append([64 | Len2],Bytes2);
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile
index 7bc9dd07d4..a9bbe7fe62 100644
--- a/lib/snmp/test/Makefile
+++ b/lib/snmp/test/Makefile
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+# Copyright Ericsson AB 1997-2014. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -36,7 +36,7 @@ VSN = $(SNMP_VSN)
include modules.mk
SNMP_ROOT = ..
-SNMP_SUITE = snmp_SUITE
+SNMP_SUITE = snmp_SUITE
ERL_FILES = $(MODULES:%=%.erl)
@@ -239,6 +239,7 @@ release_tests_spec: opt
$(INSTALL_DATA) $(RELTEST_FILES) $(COVER_SPEC_FILE) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
tar cf - snmp_test_data | (cd "$(RELSYSDIR)"; tar xf -)
+ tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
release_docs_spec:
diff --git a/lib/snmp/test/klas3.erl b/lib/snmp/test/klas3.erl
index ec78d19dbb..4cbd852b2d 100644
--- a/lib/snmp/test/klas3.erl
+++ b/lib/snmp/test/klas3.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -67,11 +67,15 @@ fname(get) ->
end,
case snmpa:current_address() of
{value, {[_A,_B,_C,_D], E}} when is_integer(E) -> ok;
- {value, _} -> throw("bad_ip");
- _ -> throw("bad_adr")
+ {value, {D, _}} when is_atom(D) -> ok;
+ {value, Ip} ->
+ throw(format_string("bad_ip: ~p", [Ip]));
+ Other ->
+ throw(format_string("bad_adr: ~p", [Other]))
end,
case snmpa:current_net_if_data() of
{value, []} -> ok;
+ {value, [{request_ref, R}]} when is_reference(R) -> ok;
{value, _} -> throw("bad_nil");
_ -> throw("bad_nid")
end,
@@ -160,3 +164,6 @@ ftab2(get_next, [9], _Cols) ->
% bad return value
io:format("** Here comes Error Report get_next 3 bad return~n"),
[{[1,5],1},{[2,5],3},{[2,6],3}].
+
+format_string(Format, Args) ->
+ lists:flatten(io_lib:format(Format, Args)).
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index fd8315ec4d..1bf08a9729 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -19,6 +19,7 @@
SUITE_MODULES = \
snmp_SUITE \
+ snmp_to_snmpnet_SUITE \
snmp_app_test \
snmp_appup_test \
snmp_compiler_test \
diff --git a/lib/snmp/test/snmp_SUITE.erl b/lib/snmp/test/snmp_SUITE.erl
index 22b9c64588..6fabf6410f 100644
--- a/lib/snmp/test/snmp_SUITE.erl
+++ b/lib/snmp/test/snmp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -80,7 +80,8 @@ groups() ->
{group, note_store_test}]},
{agent, [], [{group, mibs_test},
{group, nfilter_test},
- {group, agent_test}]},
+ {group, agent_test},
+ {group, snmpnet_test}]},
{manager, [], [{group, manager_config_test},
{group, manager_user_test},
{group, manager_test}]},
@@ -95,6 +96,7 @@ groups() ->
{mibs_test, [], [{snmp_agent_mibs_test, all}]},
{nfilter_test, [], [{snmp_agent_nfilter_test, all}]},
{agent_test, [], [{snmp_agent_test, all}]},
+ {snmpnet_test, [], [{snmp_to_snmpnet_SUITE, all}]},
{manager_config_test, [], [{snmp_manager_config_test, all}]},
{manager_user_test, [], [{snmp_manager_user_test, all}]},
{manager_test, [], [{snmp_manager_test, all}]}
@@ -107,15 +109,18 @@ init_per_group(GroupName, Config0) ->
"~n GroupName: ~p"
"~n Config0: ~p", [GroupName, Config0]),
- %% Group name is not really the suite name
- %% (but it is a good enough approximation),
- %% but it does not matter since we only need
- %% it to be unique.
- snmp_test_lib:init_suite_top_dir(GroupName, Config0).
-
-
+ case GroupName of
+ snmpnet_test ->
+ Config0;
+ _ ->
+ %% Group name is not really the suite name
+ %% (but it is a good enough approximation),
+ %% but it does not matter since we only need
+ %% it to be unique.
+ snmp_test_lib:init_suite_top_dir(GroupName, Config0)
+ end.
+
+end_per_group(snmpnet_test, Config) ->
+ Config;
end_per_group(_GroupName, Config) ->
lists:keydelete(snmp_suite_top_dir, 1, Config).
-
-
-
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index 2a9f2e842d..9a9258aa91 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,7 +37,7 @@
v1_processing/1,
big/1,
big2/1,
- loop_mib_1/1,
+ loop_mib_1/1,
api/1,
subagent/1,
mnesia/1,
@@ -298,7 +298,6 @@
%% tickets2
otp8395/1,
otp9884/1
-
]).
%% Internal exports
@@ -390,9 +389,9 @@
usm_read/0,
usm_del_user/0,
usm_bad/0,
- loop_mib_1_test/0,
- loop_mib_2_test/0,
- loop_mib_3_test/0,
+ loop_mib_1_test/0,
+ loop_mib_2_test/0,
+ loop_mib_3_test/0,
otp_1129_i/1,
otp_1162_test/0,
otp_1131_test/0,
@@ -518,9 +517,13 @@ groups() ->
{mib_storage_varm_mnesia, [], varm_mib_storage_mnesia_cases()},
{misc, [], misc_cases()},
{test_v1, [], v1_cases()},
+ {test_v1_ipv6, [], v1_cases_ipv6()},
{test_v2, [], v2_cases()},
+ {test_v2_ipv6, [], v2_cases_ipv6()},
{test_v1_v2, [], v1_v2_cases()},
+ {test_v1_v2_ipv6, [], v1_v2_cases()},
{test_v3, [], v3_cases()},
+ {test_v3_ipv6, [], v3_cases_ipv6()},
{test_multi_threaded, [], mt_cases()},
{multiple_reqs, [], mul_cases()},
{multiple_reqs_2, [], mul_cases_2()},
@@ -611,6 +614,14 @@ init_per_group(test_v2 = GroupName, Config) ->
init_v2(snmp_test_lib:init_group_top_dir(GroupName, Config));
init_per_group(test_v1 = GroupName, Config) ->
init_v1(snmp_test_lib:init_group_top_dir(GroupName, Config));
+init_per_group(test_v1_ipv6 = GroupName, Config) ->
+ init_per_group_ipv6(GroupName, Config, fun init_v1/1);
+init_per_group(test_v2_ipv6 = GroupName, Config) ->
+ init_per_group_ipv6(GroupName, Config, fun init_v2/1);
+init_per_group(test_v1_v2_ipv6 = GroupName, Config) ->
+ init_per_group_ipv6(GroupName, Config, fun init_v1_v2/1);
+init_per_group(test_v3_ipv6 = GroupName, Config) ->
+ init_per_group_ipv6(GroupName, Config, fun init_v3/1);
init_per_group(misc = GroupName, Config) ->
init_misc(snmp_test_lib:init_group_top_dir(GroupName, Config));
init_per_group(mib_storage_varm_mnesia = GroupName, Config) ->
@@ -637,6 +648,18 @@ init_per_group(mib_storage_ets = GroupName, Config) ->
init_per_group(GroupName, Config) ->
snmp_test_lib:init_group_top_dir(GroupName, Config).
+init_per_group_ipv6(GroupName, Config, Init) ->
+ case ct:require(ipv6_hosts) of
+ ok ->
+ Init(
+ snmp_test_lib:init_group_top_dir(
+ GroupName,
+ [{ipfamily, inet6},
+ {ip, ?LOCALHOST(inet6)} | lists:keydelete(ip, 1, Config)]));
+ _ ->
+ {skip, "Host does not support IPV6"}
+ end.
+
end_per_group(all_tcs, Config) ->
finish_all(Config);
end_per_group(otp7157, Config) ->
@@ -655,31 +678,39 @@ end_per_group(multiple_reqs_3, Config) ->
finish_mul(Config);
end_per_group(test_multi_threaded, Config) ->
finish_mt(Config);
-end_per_group(test_v3, Config) ->
+end_per_group(test_v3_ipv6, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2_ipv6, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2_ipv6, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1_ipv6, Config) ->
+ finish_v1(Config);
+end_per_group(test_v3, Config) ->
finish_v3(Config);
-end_per_group(test_v1_v2, Config) ->
+end_per_group(test_v1_v2, Config) ->
finish_v1_v2(Config);
-end_per_group(test_v2, Config) ->
+end_per_group(test_v2, Config) ->
finish_v2(Config);
-end_per_group(test_v1, Config) ->
+end_per_group(test_v1, Config) ->
finish_v1(Config);
-end_per_group(misc, Config) ->
+end_per_group(misc, Config) ->
finish_misc(Config);
-end_per_group(mib_storage_varm_mnesia, Config) ->
+end_per_group(mib_storage_varm_mnesia, Config) ->
finish_varm_mib_storage_mnesia(Config);
-end_per_group(mib_storage_varm_dets, Config) ->
+end_per_group(mib_storage_varm_dets, Config) ->
finish_varm_mib_storage_dets(Config);
-end_per_group(mib_storage_size_check_mnesia, Config) ->
+end_per_group(mib_storage_size_check_mnesia, Config) ->
finish_size_check_msm(Config);
-end_per_group(mib_storage_size_check_dets, Config) ->
+end_per_group(mib_storage_size_check_dets, Config) ->
finish_size_check_msd(Config);
-end_per_group(mib_storage_size_check_ets, Config) ->
+end_per_group(mib_storage_size_check_ets, Config) ->
finish_size_check_mse(Config);
-end_per_group(mib_storage_mnesia, Config) ->
+end_per_group(mib_storage_mnesia, Config) ->
finish_mib_storage_mnesia(Config);
-end_per_group(mib_storage_dets, Config) ->
+end_per_group(mib_storage_dets, Config) ->
finish_mib_storage_dets(Config);
-end_per_group(mib_storage_ets, Config) ->
+end_per_group(mib_storage_ets, Config) ->
finish_mib_storage_ets(Config);
end_per_group(_GroupName, Config) ->
Config.
@@ -810,6 +841,10 @@ cases() ->
{group, test_v2},
{group, test_v1_v2},
{group, test_v3},
+ {group, test_v1_ipv6},
+ {group, test_v2_ipv6},
+ {group, test_v1_v2_ipv6},
+ {group, test_v3_ipv6},
{group, test_multi_threaded},
{group, mib_storage},
{group, tickets1}
@@ -865,8 +900,8 @@ start_v2_agent(Config) ->
start_v2_agent(Config, Opts) ->
snmp_agent_test_lib:start_v2_agent(Config, Opts).
-start_v3_agent(Config) ->
- snmp_agent_test_lib:start_v3_agent(Config).
+%% start_v3_agent(Config) ->
+%% snmp_agent_test_lib:start_v3_agent(Config).
start_v3_agent(Config, Opts) ->
snmp_agent_test_lib:start_v3_agent(Config, Opts).
@@ -1636,7 +1671,7 @@ del_dir(Dir, Depth) ->
ok
end.
-%v1_cases() -> [loop_mib];
+%v1_cases() -> [loop_mib_1];
v1_cases() ->
[
simple,
@@ -1644,7 +1679,7 @@ v1_cases() ->
v1_processing,
big,
big2,
- loop_mib_1,
+ loop_mib_1,
api,
subagent,
mnesia,
@@ -1662,14 +1697,40 @@ v1_cases() ->
change_target_addr_config
].
+v1_cases_ipv6() ->
+ [
+ simple,
+ v1_processing,
+ loop_mib_1,
+%% big,
+%% big2,
+ api,
+ subagent,
+%% mnesia,
+%% {group, multiple_reqs},
+ sa_register,
+%% v1_trap, % sends v1 trap
+%% sa_error,
+ next_across_sa,
+ undo,
+%% {group, reported_bugs},
+ {group, standard_mibs}, % snmp_standard_mib still failing, sends v1 trap
+ sparse_table,
+%% cnt_64, % sends v1 trap
+ opaque
+%% change_target_addr_config % sends v1 trap
+ ].
+
init_v1(Config) when is_list(Config) ->
?line SaNode = ?config(snmp_sa, Config),
?line create_tables(SaNode),
?line AgentConfDir = ?config(agent_conf_dir, Config),
?line MgrDir = ?config(mgr_dir, Config),
?line Ip = ?config(ip, Config),
- ?line config([v1], MgrDir, AgentConfDir,
- tuple_to_list(Ip), tuple_to_list(Ip)),
+ ?line IpFamily = config_ipfamily(Config),
+ ?line config(
+ [v1], MgrDir, AgentConfDir,
+ tuple_to_list(Ip), tuple_to_list(Ip), IpFamily),
[{vsn, v1} | start_v1_agent(Config)].
finish_v1(Config) when is_list(Config) ->
@@ -1706,14 +1767,43 @@ v2_cases() ->
v2_caps
].
+v2_cases_ipv6() ->
+ [
+ simple_2,
+ v2_processing,
+%% big_2,
+%% big2_2,
+ loop_mib_2,
+ api_2,
+ subagent_2,
+%% mnesia_2,
+%% {group, multiple_reqs_2},
+ sa_register_2,
+ v2_trap,
+ {group, v2_inform},
+%% sa_error_2,
+ next_across_sa_2,
+ undo_2,
+%% {group, reported_bugs_2},
+ {group, standard_mibs_2},
+ v2_types,
+ implied,
+ sparse_table_2,
+ cnt_64_2,
+ opaque_2,
+ v2_caps
+ ].
+
init_v2(Config) when is_list(Config) ->
SaNode = ?config(snmp_sa, Config),
create_tables(SaNode),
AgentConfDir = ?config(agent_conf_dir, Config),
MgrDir = ?config(mgr_dir, Config),
Ip = ?config(ip, Config),
- config([v2], MgrDir, AgentConfDir,
- tuple_to_list(Ip), tuple_to_list(Ip)),
+ IpFamily = config_ipfamily(Config),
+ config(
+ [v2], MgrDir, AgentConfDir,
+ tuple_to_list(Ip), tuple_to_list(Ip), IpFamily),
[{vsn, v2} | start_v2_agent(Config)].
finish_v2(Config) when is_list(Config) ->
@@ -1732,8 +1822,9 @@ init_v1_v2(Config) when is_list(Config) ->
AgentConfDir = ?config(agent_conf_dir, Config),
MgrDir = ?config(mgr_dir, Config),
Ip = ?config(ip, Config),
+ IpFamily = config_ipfamily(Config),
config([v1,v2], MgrDir, AgentConfDir,
- tuple_to_list(Ip), tuple_to_list(Ip)),
+ tuple_to_list(Ip), tuple_to_list(Ip), IpFamily),
[{vsn, bilingual} | start_bilingual_agent(Config)].
finish_v1_v2(Config) when is_list(Config) ->
@@ -1771,6 +1862,34 @@ v3_cases() ->
v2_caps_3
].
+v3_cases_ipv6() ->
+ [
+ simple_3,
+ v3_processing,
+%% big_3,
+%% big2_3,
+ api_3,
+ subagent_3,
+%% mnesia_3,
+ loop_mib_3,
+%% {group, multiple_reqs_3},
+ sa_register_3,
+ v3_trap,
+ {group, v3_inform},
+%% sa_error_3,
+ next_across_sa_3,
+ undo_3,
+%% {group, reported_bugs_3},
+ {group, standard_mibs_3},
+ {group, v3_security},
+ v2_types_3,
+ implied_3,
+ sparse_table_3,
+ cnt_64_3,
+ opaque_3,
+ v2_caps_3
+ ].
+
init_v3(Config) when is_list(Config) ->
%% Make sure crypto works, otherwise start_agent will fail
%% and we will be stuck with a bunch of mnesia tables for
@@ -1792,9 +1911,16 @@ init_v3(Config) when is_list(Config) ->
AgentConfDir = ?config(agent_conf_dir, Config),
MgrDir = ?config(mgr_dir, Config),
Ip = ?config(ip, Config),
- ?line ok = config([v3], MgrDir, AgentConfDir,
- tuple_to_list(Ip), tuple_to_list(Ip)),
- [{vsn, v3} | start_v3_agent(Config)].
+ IpFamily = config_ipfamily(Config),
+ ?line ok =
+ config(
+ [v3], MgrDir, AgentConfDir,
+ tuple_to_list(Ip), tuple_to_list(Ip), IpFamily),
+ Opts =
+ [{master_agent_verbosity, trace},
+ {agent_verbosity, trace},
+ {net_if_verbosity, trace}],
+ [{vsn, v3} | start_v3_agent(Config, Opts)].
finish_v3(Config) when is_list(Config) ->
delete_tables(),
@@ -5546,7 +5672,7 @@ usm_bad() ->
%%-----------------------------------------------------------------
loop_mib_1(suite) -> [];
loop_mib_1(Config) when is_list(Config) ->
- ?P(loop_mib_1),
+ ?P(loop_mib_1),
?LOG("loop_mib_1 -> initiate case",[]),
%% snmpa:verbosity(master_agent,debug),
%% snmpa:verbosity(mib_server,info),
@@ -5554,7 +5680,7 @@ loop_mib_1(Config) when is_list(Config) ->
?DBG("loop_mib_1 -> ~n"
"\tSaNode: ~p~n"
"\tMgrNode: ~p~n"
- "\tMibDir: ~p", [_SaNode, _MgrNode, _MibDir]),
+ "\tMibDir: ~p",[_SaNode, _MgrNode, _MibDir]),
?DBG("loop_mib_1 -> load mib SNMP-COMMUNITY-MIB",[]),
?line load_master_std("SNMP-COMMUNITY-MIB"),
?DBG("loop_mib_1 -> load mib SNMP-MPD-MIB",[]),
@@ -6378,8 +6504,6 @@ otp_4394_config(AgentConfDir, MgrDir, Ip0) ->
?line write_notify_conf(AgentConfDir),
ok.
-
-
otp_4394_finish(Config) when is_list(Config) ->
?DBG("finish_otp_4394 -> entry", []),
C1 = stop_agent(Config),
@@ -6532,6 +6656,7 @@ otp8395({init, Config}) when is_list(Config) ->
%% SubAgentHost = ?HPSTNAME(SubAgentNode),
ManagerHost = ?HOSTNAME(ManagerNode),
+ IpFamily = inet,
Host = snmp_test_lib:hostname(),
Ip = ?LOCALHOST(),
{ok, AgentIP0} = snmp_misc:ip(AgentHost),
@@ -6549,9 +6674,7 @@ otp8395({init, Config}) when is_list(Config) ->
Vsns = [v1],
AgentConfDir = ?config(agent_conf_dir, Config),
ManagerConfDir = ?config(manager_top_dir, Config),
- snmp_agent_test_lib:config(Vsns,
- ManagerConfDir, AgentConfDir,
- ManagerIP, AgentIP),
+ config(Vsns, ManagerConfDir, AgentConfDir, ManagerIP, AgentIP, IpFamily),
%% --
@@ -6560,6 +6683,7 @@ otp8395({init, Config}) when is_list(Config) ->
Config2 = start_agent([{host, Host},
{ip, Ip},
+ {ipfamily, IpFamily},
{agent_node, AgentNode},
{agent_host, AgentHost},
{agent_ip, AgentIP},
@@ -6639,6 +6763,7 @@ otp8395(Config) when is_list(Config) ->
put(mib_dir, ?config(mib_dir, Config)),
put(vsn, v1),
put(master_host, ?config(agent_host, Config)),
+ put(ipfamily, ?config(ipfamily, Config)),
try_test(simple_standard_test),
?SLEEP(1000),
@@ -6666,126 +6791,12 @@ otp8395(Config) when is_list(Config) ->
otp9884({init, Config}) when is_list(Config) ->
?DBG("otp9884(init) -> entry with"
"~n Config: ~p", [Config]),
-
- %% --
- %% Start nodes
- %%
-
- {ok, AgentNode} = start_node(agent),
-
- %% We don't use a manager in this test but the (common) config
- %% function takes an argument that is derived from this
- {ok, ManagerNode} = start_node(manager),
-
- %% --
- %% Mnesia init
- %%
-
- AgentDbDir = ?config(agent_db_dir, Config),
- AgentMnesiaDir = join([AgentDbDir, "mnesia"]),
- mnesia_init(AgentNode, AgentMnesiaDir),
-
- mnesia_create_schema(AgentNode, [AgentNode]),
-
- mnesia_start(AgentNode),
-
- %% --
- %% Host & IP
- %%
-
- AgentHost = ?HOSTNAME(AgentNode),
- ManagerHost = ?HOSTNAME(ManagerNode),
-
- Host = snmp_test_lib:hostname(),
- Ip = ?LOCALHOST(),
- {ok, AgentIP0} = snmp_misc:ip(AgentHost),
- AgentIP = tuple_to_list(AgentIP0),
- {ok, ManagerIP0} = snmp_misc:ip(ManagerHost),
- ManagerIP = tuple_to_list(ManagerIP0),
-
-
- %% --
- %% Write agent config
- %%
-
- Vsns = [v1],
- ManagerConfDir = ?config(manager_top_dir, Config),
- AgentConfDir = ?config(agent_conf_dir, Config),
- AgentTopDir = ?config(agent_top_dir, Config),
- AgentBkpDir1 = join([AgentTopDir, backup1]),
- AgentBkpDir2 = join([AgentTopDir, backup2]),
- ok = file:make_dir(AgentBkpDir1),
- ok = file:make_dir(AgentBkpDir2),
- AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2],
- snmp_agent_test_lib:config(Vsns,
- ManagerConfDir, AgentConfDir,
- ManagerIP, AgentIP),
-
-
- %% --
- %% Start the agent
- %%
-
- Config2 = start_agent([{host, Host},
- {ip, Ip},
- {agent_node, AgentNode},
- {agent_host, AgentHost},
- {agent_ip, AgentIP},
- {agent_backup_dirs, AgentBkpDirs}|Config]),
-
- %% --
- %% Create watchdog
- %%
-
- Dog = ?WD_START(?MINS(1)),
-
- [{watchdog, Dog} | Config2];
+ init_v1_agent([{ipfamily, inet} | Config]);
otp9884({fin, Config}) when is_list(Config) ->
?DBG("otp9884(fin) -> entry with"
"~n Config: ~p", [Config]),
-
- AgentNode = ?config(agent_node, Config),
- ManagerNode = ?config(manager_node, Config),
-
- %% -
- %% Stop agent (this is the nice way to do it,
- %% so logs and files can be closed in the proper way).
- %%
-
- AgentSup = ?config(agent_sup, Config),
- ?DBG("otp9884(fin) -> stop (stand-alone) agent: ~p", [AgentSup]),
- stop_stdalone_agent(AgentSup),
-
- %% -
- %% Stop mnesia
- %%
- ?DBG("otp9884(fin) -> stop mnesia", []),
- mnesia_stop(AgentNode),
-
-
- %% -
- %% Stop the agent node
- %%
-
- ?DBG("otp9884(fin) -> stop agent node", []),
- stop_node(AgentNode),
-
-
- %% SubAgentNode = ?config(sub_agent_node, Config),
- %% stop_node(SubAgentNode),
-
-
- %% -
- %% Stop the manager node
- %%
-
- ?DBG("otp9884(fin) -> stop manager node", []),
- stop_node(ManagerNode),
-
- Dog = ?config(watchdog, Config),
- ?WD_STOP(Dog),
- lists:keydelete(watchdog, 1, Config);
+ fin_v1_agent(Config);
otp9884(doc) ->
"OTP-9884 - Simlutaneous backup call should not work. ";
@@ -6845,8 +6856,6 @@ otp9884_await_backup_completion(First, Second)
end;
otp9884_await_backup_completion(First, Second) ->
throw({error, {bad_completion, First, Second}}).
-
-
%%-----------------------------------------------------------------
agent_log_validation(Node) ->
@@ -7143,6 +7152,9 @@ delete_files(Config) ->
config(Vsns, MgrDir, AgentDir, MIp, AIp) ->
snmp_agent_test_lib:config(Vsns, MgrDir, AgentDir, MIp, AIp).
+config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily) ->
+ snmp_agent_test_lib:config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily).
+
update_usm(Vsns, Dir) ->
snmp_agent_test_lib:update_usm(Vsns, Dir).
@@ -7387,3 +7399,124 @@ p(F, A) ->
formated_timestamp() ->
snmp_test_lib:formated_timestamp().
+
+init_v1_agent(Config) ->
+ %% --
+ %% Start nodes
+ %%
+
+ {ok, AgentNode} = start_node(agent),
+
+ %% We don't use a manager in this test but the (common) config
+ %% function takes an argument that is derived from this
+ {ok, ManagerNode} = start_node(manager),
+
+ %% --
+ %% Mnesia init
+ %%
+
+ AgentDbDir = ?config(agent_db_dir, Config),
+ AgentMnesiaDir = join([AgentDbDir, "mnesia"]),
+ mnesia_init(AgentNode, AgentMnesiaDir),
+
+ mnesia_create_schema(AgentNode, [AgentNode]),
+
+ mnesia_start(AgentNode),
+
+ %% --
+ %% Host & IP
+ %%
+
+ AgentHost = ?HOSTNAME(AgentNode),
+ ManagerHost = ?HOSTNAME(ManagerNode),
+
+ Host = snmp_test_lib:hostname(),
+ IpFamily = config_ipfamily(Config),
+ Ip = ?LOCALHOST(IpFamily),
+ {ok, AgentIP0} = snmp_misc:ip(AgentHost, IpFamily),
+ AgentIP = tuple_to_list(AgentIP0),
+ {ok, ManagerIP0} = snmp_misc:ip(ManagerHost, IpFamily),
+ ManagerIP = tuple_to_list(ManagerIP0),
+
+
+ %% --
+ %% Write agent config
+ %%
+
+ Vsns = [v1],
+ ManagerConfDir = ?config(manager_top_dir, Config),
+ AgentConfDir = ?config(agent_conf_dir, Config),
+ AgentTopDir = ?config(agent_top_dir, Config),
+ AgentBkpDir1 = join([AgentTopDir, backup1]),
+ AgentBkpDir2 = join([AgentTopDir, backup2]),
+ ok = file:make_dir(AgentBkpDir1),
+ ok = file:make_dir(AgentBkpDir2),
+ AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2],
+ config(Vsns, ManagerConfDir, AgentConfDir, ManagerIP, AgentIP, IpFamily),
+
+
+ %% --
+ %% Start the agent
+ %%
+
+ Config2 = start_agent([{host, Host},
+ {ip, Ip},
+ {agent_node, AgentNode},
+ {agent_host, AgentHost},
+ {agent_ip, AgentIP},
+ {agent_backup_dirs, AgentBkpDirs}|Config]),
+
+ %% --
+ %% Create watchdog
+ %%
+
+ Dog = ?WD_START(?MINS(1)),
+
+ [{watchdog, Dog} | Config2].
+
+fin_v1_agent(Config) ->
+ AgentNode = ?config(agent_node, Config),
+ ManagerNode = ?config(manager_node, Config),
+
+ %% -
+ %% Stop agent (this is the nice way to do it,
+ %% so logs and files can be closed in the proper way).
+ %%
+
+ AgentSup = ?config(agent_sup, Config),
+ stop_stdalone_agent(AgentSup),
+
+ %% -
+ %% Stop mnesia
+ %%
+ mnesia_stop(AgentNode),
+
+
+ %% -
+ %% Stop the agent node
+ %%
+ stop_node(AgentNode),
+
+
+ %% SubAgentNode = ?config(sub_agent_node, Config),
+ %% stop_node(SubAgentNode),
+
+
+ %% -
+ %% Stop the manager node
+ %%
+ stop_node(ManagerNode),
+
+ Dog = ?config(watchdog, Config),
+ ?WD_STOP(Dog),
+ lists:keydelete(watchdog, 1, Config).
+
+
+
+config_ipfamily(Config) ->
+ case ?config(ipfamily, Config) of
+ undefined ->
+ inet;
+ Value ->
+ Value
+ end.
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index d7109253f7..333fe6eb66 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -39,7 +39,7 @@
get_req/2, get_next_req/1,
- config/5,
+ config/5, config/6,
delete_files/1,
copy_file/2,
update_usm/2,
@@ -232,13 +232,14 @@ init_case(Config) when is_list(Config) ->
MgrNode = ?config(snmp_mgr, Config),
MasterNode = ?config(snmp_master, Config),
%% MasterNode = node(),
-
+ IpFamily = proplists:get_value(ipfamily, Config, inet),
+
SaHost = ?HOSTNAME(SaNode),
MgrHost = ?HOSTNAME(MgrNode),
MasterHost = ?HOSTNAME(MasterNode),
- {ok, MasterIP} = snmp_misc:ip(MasterHost),
- {ok, MIP} = snmp_misc:ip(MgrHost),
- {ok, SIP} = snmp_misc:ip(SaHost),
+ {ok, MasterIP} = snmp_misc:ip(MasterHost, IpFamily),
+ {ok, MIP} = snmp_misc:ip(MgrHost, IpFamily),
+ {ok, SIP} = snmp_misc:ip(SaHost, IpFamily),
put(mgr_node, MgrNode),
@@ -250,6 +251,7 @@ init_case(Config) when is_list(Config) ->
put(mip, tuple_to_list(MIP)),
put(masterip, tuple_to_list(MasterIP)),
put(sip, tuple_to_list(SIP)),
+ put(ipfamily, IpFamily),
MibDir = ?config(mib_dir, Config),
put(mib_dir, MibDir),
@@ -358,6 +360,7 @@ run(Mod, Func, Args, Opts) ->
{packet_server_debug,true},
{debug,true},
{agent, get(master_host)},
+ {ipfamily, get(ipfamily)},
{agent_udp, 4000},
{trap_udp, 5000},
{recbuf,65535},
@@ -1368,16 +1371,35 @@ stop_node(Node) ->
%%%-----------------------------------------------------------------
config(Vsns, MgrDir, AgentConfDir, MIp, AIp) ->
+ config(Vsns, MgrDir, AgentConfDir, MIp, AIp, inet).
+
+config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) ->
?LOG("config -> entry with"
- "~n Vsns: ~p"
- "~n MgrDir: ~p"
- "~n AgentConfDir: ~p"
- "~n MIp: ~p"
- "~n AIp: ~p",
- [Vsns, MgrDir, AgentConfDir, MIp, AIp]),
- ?line snmp_config:write_agent_snmp_files(AgentConfDir, Vsns,
- MIp, ?TRAP_UDP, AIp, 4000,
- "test"),
+ "~n Vsns: ~p"
+ "~n MgrDir: ~p"
+ "~n AgentConfDir: ~p"
+ "~n MIp: ~p"
+ "~n AIp: ~p"
+ "~n IpFamily: ~p",
+ [Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily]),
+ ?line {Domain, ManagerAddr} =
+ case IpFamily of
+ inet6 ->
+ Ipv6Domain = transportDomainUdpIpv6,
+ AgentIpv6Addr = {AIp, 4000},
+ ManagerIpv6Addr = {MIp, ?TRAP_UDP},
+ ?line ok =
+ snmp_config:write_agent_snmp_files(
+ AgentConfDir, Vsns,
+ Ipv6Domain, ManagerIpv6Addr, AgentIpv6Addr, "test"),
+ {Ipv6Domain, ManagerIpv6Addr};
+ _ ->
+ ?line ok =
+ snmp_config:write_agent_snmp_files(
+ AgentConfDir, Vsns, MIp, ?TRAP_UDP, AIp, 4000, "test"),
+ {snmpUDPDomain, {MIp, ?TRAP_UDP}}
+ end,
+
?line case update_usm(Vsns, AgentConfDir) of
true ->
?line copy_file(join(AgentConfDir, "usm.conf"),
@@ -1388,7 +1410,7 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp) ->
end,
?line update_community(Vsns, AgentConfDir),
?line update_vacm(Vsns, AgentConfDir),
- ?line write_target_addr_conf(AgentConfDir, MIp, ?TRAP_UDP, Vsns),
+ ?line write_target_addr_conf(AgentConfDir, Domain, ManagerAddr, Vsns),
?line write_target_params_conf(AgentConfDir, Vsns),
?line write_notify_conf(AgentConfDir),
ok.
@@ -1486,7 +1508,7 @@ rewrite_usm_mgr(Dir, ShaKey, DesKey) ->
{"mgrEngine", "newUser", "newUser", zeroDotZero,
usmHMACSHAAuthProtocol, "", "",
usmDESPrivProtocol, "", "", "", ShaKey, DesKey}],
- ok = snmp_config:write_agent_usm_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_usm_config(Dir, "", Conf).
reset_usm_mgr(Dir) ->
?line ok = file:rename(join(Dir,"usm.old"),
@@ -1512,13 +1534,15 @@ update_vacm(_Vsn, Dir) ->
write_community_conf(Dir, Conf) ->
- snmp_config:write_agent_community_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_community_config(Dir, "", Conf).
write_target_addr_conf(Dir, Conf) ->
- snmp_config:write_agent_target_addr_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_target_addr_config(Dir, "", Conf).
-write_target_addr_conf(Dir, ManagerIp, UDP, Vsns) ->
- snmp_config:write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Vsns).
+write_target_addr_conf(Dir, Ip_or_Domain, Port_or_Addr, Vsns) ->
+ ?line ok =
+ snmp_config:write_agent_snmp_target_addr_conf(
+ Dir, Ip_or_Domain, Port_or_Addr, Vsns).
rewrite_target_addr_conf(Dir, NewPort) ->
?DBG("rewrite_target_addr_conf -> entry with"
@@ -1534,8 +1558,7 @@ rewrite_target_addr_conf(Dir, NewPort) ->
end,
?line [TrapAddr|Addrs] =
- snmp_conf:read(TAFile,
- fun(R) -> rewrite_target_addr_conf_check(R) end),
+ snmp_conf:read(TAFile, fun rewrite_target_addr_conf_check/1),
?DBG("rewrite_target_addr_conf -> TrapAddr: ~p",[TrapAddr]),
@@ -1571,14 +1594,14 @@ write_target_params_conf(Dir, Vsns) ->
(v3) -> {"target_v3", v3, usm, "all-rights", noAuthNoPriv}
end,
Conf = [F(Vsn) || Vsn <- Vsns],
- snmp_config:write_agent_target_params_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_target_params_config(Dir, "", Conf).
rewrite_target_params_conf(Dir, SecName, SecLevel)
when is_list(SecName) andalso is_atom(SecLevel) ->
?line ok = file:rename(join(Dir,"target_params.conf"),
join(Dir,"target_params.old")),
Conf = [{"target_v3", v3, usm, SecName, SecLevel}],
- snmp_config:write_agent_target_params_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_target_params_config(Dir, "", Conf).
reset_target_params_conf(Dir) ->
?line ok = file:rename(join(Dir,"target_params.old"),
@@ -1587,12 +1610,12 @@ reset_target_params_conf(Dir) ->
write_notify_conf(Dir) ->
Conf = [{"standard trap", "std_trap", trap},
{"standard inform", "std_inform", inform}],
- snmp_config:write_agent_notify_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_notify_config(Dir, "", Conf).
write_view_conf(Dir) ->
Conf = [{2, [1,3,6], included, null},
{2, ?tDescr_instance, excluded, null}],
- snmp_config:write_agent_view_config(Dir, "", Conf).
+ ?line ok = snmp_config:write_agent_view_config(Dir, "", Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/snmp/test/snmp_conf_test.erl b/lib/snmp/test/snmp_conf_test.erl
index c4341d8d7e..7f5d11c0e7 100644
--- a/lib/snmp/test/snmp_conf_test.erl
+++ b/lib/snmp/test/snmp_conf_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -373,6 +373,8 @@ verify_ip(Val) ->
case (catch snmp_conf:check_ip(Val)) of
{error, Reason} ->
?FAIL({verify_ip, Val, Reason});
+ {ok, _} ->
+ ok;
ok ->
ok
end.
@@ -401,7 +403,7 @@ check_taddress(Config) when is_list(Config) ->
ok.
verify_taddress(Val) ->
- case (catch snmp_conf:check_taddress(Val)) of
+ case (catch snmp_conf:check_taddress(snmpUDPDomain, Val)) of
{error, Reason} ->
?FAIL({verify_taddress, Val, Reason});
ok ->
@@ -409,7 +411,7 @@ verify_taddress(Val) ->
end.
verify_not_taddress(Val) ->
- case (catch snmp_conf:check_taddress(Val)) of
+ case (catch snmp_conf:check_taddress(snmpUDPDomain, Val)) of
ok ->
?FAIL({verify_taddress, Val});
{error, _Reason} ->
diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl
index 7b9924b83c..2f5c68d14d 100644
--- a/lib/snmp/test/snmp_manager_config_test.erl
+++ b/lib/snmp/test/snmp_manager_config_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -693,7 +693,7 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) ->
"arne_anka", "4001", "500", "\"bmkEngine\""),
?line {error, Reason12} = config_start(Opts),
p("start failed (as expected): ~p", [Reason12]),
- ?line {failed_check, _, _, 2, {invalid_ip_address, _}} = Reason12,
+ ?line {failed_check, _, _, 2, {bad_address, _}} = Reason12,
await_config_not_running(),
%% --
@@ -702,7 +702,7 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) ->
"9999", "4001", "500", "\"bmkEngine\""),
?line {error, Reason13} = config_start(Opts),
p("start failed (as expected): ~p", [Reason13]),
- ?line {failed_check, _, _, 2, {invalid_ip_address, _}} = Reason13,
+ ?line {failed_check, _, _, 2, {bad_address, _}} = Reason13,
await_config_not_running(),
%% --
@@ -720,7 +720,8 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) ->
"[134,138,177,189]", "-1", "500", "\"bmkEngine\""),
?line {error, Reason22} = config_start(Opts),
p("start failed (as expected): ~p", [Reason22]),
- ?line {failed_check, _, _, 3, {invalid_integer, _}} = Reason22,
+ io:format("Reason22: ~p~n", [Reason22]),
+ ?line {failed_check, _, _, 3, {bad_port, _}} = Reason22,
await_config_not_running(),
%% --
@@ -729,7 +730,7 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) ->
"[134,138,177,189]", "\"kalle-anka\"", "500", "\"bmkEngine\""),
?line {error, Reason23} = config_start(Opts),
p("start failed (as expected): ~p", [Reason23]),
- ?line {failed_check, _, _, 3, {invalid_integer, _}} = Reason23,
+ ?line {failed_check, _, _, 3, {bad_port, _}} = Reason23,
await_config_not_running(),
%% --
@@ -1073,7 +1074,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
case config_start(Opts) of
{error, Reason53} ->
p("start failed (as expected): ~p", [Reason53]),
- ?line {failed_check, _, _, _, {invalid_ip_address, _}} = Reason53,
+ ?line {failed_check, _, _, _, {bad_address, _}} = Reason53,
await_config_not_running();
OK_53 ->
exit({error, {unexpected_success, "53", OK_53}})
@@ -1086,7 +1087,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
case config_start(Opts) of
{error, Reason54} ->
p("start failed (as expected): ~p", [Reason54]),
- ?line {failed_check, _, _, _, {invalid_ip_address, _}} = Reason54,
+ ?line {failed_check, _, _, _, {bad_address, _}} = Reason54,
await_config_not_running();
OK_54 ->
exit({error, {unexpected_success, "54", OK_54}})
@@ -1098,7 +1099,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
write_agents_conf(ConfDir, [Agent55]),
?line {error, Reason55} = config_start(Opts),
p("start failed (as expected): ~p", [Reason55]),
- ?line {failed_check, _, _, _, {invalid_ip_address, _}} = Reason55,
+ ?line {failed_check, _, _, _, {bad_address, _}} = Reason55,
await_config_not_running(),
%% --
@@ -1107,7 +1108,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
write_agents_conf(ConfDir, [Agent61]),
?line {error, Reason61} = config_start(Opts),
p("start failed (as expected): ~p", [Reason61]),
- ?line {failed_check, _, _, _, {invalid_integer, _}} = Reason61,
+ ?line {failed_check, _, _, _, {bad_address, _}} = Reason61,
await_config_not_running(),
%% --
@@ -1116,7 +1117,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
write_agents_conf(ConfDir, [Agent62]),
?line {error, Reason62} = config_start(Opts),
p("start failed (as expected): ~p", [Reason62]),
- ?line {failed_check, _, _, _, {invalid_integer, _}} = Reason62,
+ ?line {failed_check, _, _, _, {bad_address, _}} = Reason62,
await_config_not_running(),
%% --
@@ -1125,7 +1126,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
write_agents_conf(ConfDir, [Agent63]),
?line {error, Reason63} = config_start(Opts),
p("start failed (as expected): ~p", [Reason63]),
- ?line {failed_check, _, _, _, {invalid_integer, _}} = Reason63,
+ ?line {failed_check, _, _, _, {bad_address, _}} = Reason63,
await_config_not_running(),
%% --
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index 3a654a2805..78352e59cf 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -241,8 +241,11 @@ init_per_testcase2(Case, Config) ->
AgLogDir = filename:join(AgTopDir, "log/"),
?line ok = file:make_dir(AgLogDir),
+ Family = proplists:get_value(ipfamily, Config, inet),
+
Conf = [{watchdog, ?WD_START(?MINS(5))},
- {ip, ?LOCALHOST()},
+ {ipfamily, Family},
+ {ip, ?LOCALHOST(Family)},
{case_top_dir, CaseTopDir},
{agent_dir, AgTopDir},
{agent_conf_dir, AgConfDir},
@@ -410,7 +413,9 @@ all() ->
{group, event_tests},
{group, event_tests_mt},
discovery,
- {group, tickets}
+ {group, tickets},
+ {group, ipv6},
+ {group, ipv6_mt}
].
groups() ->
@@ -545,9 +550,29 @@ groups() ->
[
otp8395_1
]
- }
+ },
+ {ipv6, [], ipv6_tests()},
+ {ipv6_mt, [], ipv6_tests()}
+
+ ].
+
+ipv6_tests() ->
+ [
+ register_agent1,
+ simple_sync_get_next3,
+ simple_async_get2,
+ simple_sync_get3,
+ simple_async_get_next2,
+ simple_sync_set3,
+ simple_async_set2,
+ simple_sync_get_bulk2,
+ simple_async_get_bulk3,
+ misc_async2,
+ inform1,
+ inform_swarm
].
+
init_per_group(request_tests_mt = GroupName, Config) ->
snmp_test_lib:init_group_top_dir(
GroupName,
@@ -556,10 +581,26 @@ init_per_group(event_tests_mt = GroupName, Config) ->
snmp_test_lib:init_group_top_dir(
GroupName,
[{manager_net_if_module, snmpm_net_if_mt} | Config]);
+init_per_group(ipv6_mt = GroupName, Config) ->
+ case ct:require(ipv6_hosts) of
+ ok ->
+ ipv6_init(
+ snmp_test_lib:init_group_top_dir(
+ GroupName,
+ [{manager_net_if_module, snmpm_net_if_mt} | Config]));
+ _ ->
+ {skip, "Host does not support IPV6"}
+ end;
+init_per_group(ipv6 = GroupName, Config) ->
+ case ct:require(ipv6_hosts) of
+ ok ->
+ ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config));
+ _ ->
+ {skip, "Host does not support IPV6"}
+ end;
init_per_group(GroupName, Config) ->
snmp_test_lib:init_group_top_dir(GroupName, Config).
-
-
+
end_per_group(_GroupName, Config) ->
%% Do we really need to do this?
lists:keydelete(snmp_group_top_dir, 1, Config).
@@ -1508,7 +1549,7 @@ register_agent3(Config) when is_list(Config) ->
TargetName2 = "agent3",
?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName2,
[{tdomain, transportDomainUdpIpv6},
- {address, LocalHost},
+ {address, {0,0,0,0,0,0,0,1}},
{port, 5002},
{engine_id, "agentEngineId-2"}]),
TargetName3 = "agent4",
@@ -5074,7 +5115,7 @@ inform_swarm_collector(N) ->
inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, _)
when ((N == SentAckCnt) and
(N == RespCnt) and
- (N >= RecvCnt)) ->
+ (N =< RecvCnt)) ->
p("inform_swarm_collector -> done when"
"~n N: ~w"
"~n SentAckCnt: ~w"
@@ -5750,12 +5791,24 @@ fin_mgr_user(Conf) ->
init_mgr_user_data1(Conf) ->
Node = ?config(manager_node, Conf),
TargetName = ?config(manager_agent_target_name, Conf),
- Addr = ?config(ip, Conf),
+ IpFamily = ?config(ipfamily, Conf),
+ Ip = ?config(ip, Conf),
Port = ?AGENT_PORT,
- ?line ok = mgr_user_register_agent(Node, TargetName,
- [{address, Addr},
- {port, Port},
- {engine_id, "agentEngine"}]),
+ ?line ok =
+ case IpFamily of
+ inet ->
+ mgr_user_register_agent(
+ Node, TargetName,
+ [{address, Ip},
+ {port, Port},
+ {engine_id, "agentEngine"}]);
+ inet6 ->
+ mgr_user_register_agent(
+ Node, TargetName,
+ [{tdomain, transportDomainUdpIpv6},
+ {taddress, {Ip, Port}},
+ {engine_id, "agentEngine"}])
+ end,
_Agents = mgr_user_which_own_agents(Node),
?DBG("Own agents: ~p", [_Agents]),
@@ -5780,12 +5833,24 @@ init_mgr_user_data2(Conf) ->
"~n Conf: ~p", [Conf]),
Node = ?config(manager_node, Conf),
TargetName = ?config(manager_agent_target_name, Conf),
- Addr = ?config(ip, Conf),
+ IpFamily = ?config(ipfamily, Conf),
+ Ip = ?config(ip, Conf),
Port = ?AGENT_PORT,
- ?line ok = mgr_user_register_agent(Node, TargetName,
- [{address, Addr},
- {port, Port},
- {engine_id, "agentEngine"}]),
+ ?line ok =
+ case IpFamily of
+ inet ->
+ mgr_user_register_agent(
+ Node, TargetName,
+ [{address, Ip},
+ {port, Port},
+ {engine_id, "agentEngine"}]);
+ inet6 ->
+ mgr_user_register_agent(
+ Node, TargetName,
+ [{tdomain, transportDomainUdpIpv6},
+ {taddress, {Ip, Port}},
+ {engine_id, "agentEngine"}])
+ end,
_Agents = mgr_user_which_own_agents(Node),
?DBG("Own agents: ~p", [_Agents]),
@@ -6182,10 +6247,16 @@ await_stopped(Node, N) ->
write_manager_config(Config) ->
Dir = ?config(manager_conf_dir, Config),
- Ip = ?config(ip, Config),
- Addr = tuple_to_list(Ip),
- snmp_config:write_manager_snmp_files(Dir, Addr, ?MGR_PORT,
- ?MGR_MMS, ?MGR_ENGINE_ID, [], [], []).
+ Ip = tuple_to_list(?config(ip, Config)),
+ {Addr, Port} =
+ case ?config(ipfamily, Config) of
+ inet ->
+ {Ip, ?MGR_PORT};
+ inet6 ->
+ {transportDomainUdpIpv6, {Ip, ?MGR_PORT}}
+ end,
+ snmp_config:write_manager_snmp_files(
+ Dir, Addr, Port, ?MGR_MMS, ?MGR_ENGINE_ID, [], [], []).
write_manager_conf(Dir) ->
Port = "5000",
@@ -6214,25 +6285,27 @@ write_manager_conf(Dir, Str) ->
write_agent_config(Vsns, Conf) ->
Dir = ?config(agent_conf_dir, Conf),
- Ip = ?config(ip, Conf),
- ?line Addr = tuple_to_list(Ip),
- ?line ok = write_agent_config_files(Dir, Vsns, Addr),
+ ?line Ip = tuple_to_list(?config(ip, Conf)),
+ ?line Domain =
+ case ?config(ipfamily, Conf) of
+ inet ->
+ snmpUDPDomain;
+ inet6 ->
+ transportDomainUdpIpv6
+ end,
+ ?line ok = write_agent_config_files(Dir, Vsns, Domain, Ip),
?line ok = update_agent_usm(Vsns, Dir),
?line ok = update_agent_community(Vsns, Dir),
?line ok = update_agent_vacm(Vsns, Dir),
- ?line ok = write_agent_target_addr_conf(Dir, Addr, Vsns),
+ ?line ok = write_agent_target_addr_conf(Dir, Domain, Ip, Vsns),
?line ok = write_agent_target_params_conf(Dir, Vsns),
?line ok = write_agent_notify_conf(Dir),
ok.
-write_agent_config_files(Dir, Vsns, Addr) ->
- snmp_config:write_agent_snmp_files(Dir, Vsns,
- Addr, ?MGR_PORT,
- Addr, ?AGENT_PORT,
- "mgr-test", "trap",
- none, "",
- ?AGENT_ENGINE_ID,
- ?AGENT_MMS).
+write_agent_config_files(Dir, Vsns, Domain, Ip) ->
+ snmp_config:write_agent_snmp_files(
+ Dir, Vsns, Domain, {Ip, ?MGR_PORT}, {Ip, ?AGENT_PORT}, "mgr-test",
+ trap, none, "", ?AGENT_ENGINE_ID, ?AGENT_MMS).
update_agent_usm(Vsns, Dir) ->
case lists:member(v3, Vsns) of
@@ -6300,9 +6373,9 @@ update_agent_vacm(_Vsns, Dir) ->
excluded, null}],
snmp_config:update_agent_vacm_config(Dir, Conf).
-write_agent_target_addr_conf(Dir, Addr, Vsns) ->
- snmp_config:write_agent_snmp_target_addr_conf(Dir, Addr, ?MGR_PORT,
- 300, 3, Vsns).
+write_agent_target_addr_conf(Dir, Domain, Ip, Vsns) ->
+ snmp_config:write_agent_snmp_target_addr_conf(
+ Dir, Domain, {Ip, ?MGR_PORT}, 300, 3, Vsns).
write_agent_target_params_conf(Dir, Vsns) ->
F = fun(v1) -> {"target_v1", v1, v1, "all-rights", noAuthNoPriv};
@@ -6426,3 +6499,5 @@ formated_timestamp() ->
%% p(TName, F, A) ->
%% io:format("~w -> " ++ F ++ "~n", [TName|A]).
+ipv6_init(Config) when is_list(Config) ->
+ [{ipfamily, inet6} | Config].
diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl
index fbb891e40d..5e611340a3 100644
--- a/lib/snmp/test/snmp_test_lib.erl
+++ b/lib/snmp/test/snmp_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,7 +22,7 @@
-include_lib("kernel/include/file.hrl").
--export([hostname/0, hostname/1, localhost/0, os_type/0, sz/1,
+-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]).
-export([fix_data_dir/1,
@@ -60,6 +60,9 @@ from(_H, []) -> [].
localhost() ->
{ok, Ip} = snmp_misc:ip(net_adm:localhost()),
Ip.
+localhost(Family) ->
+ {ok, Ip} = snmp_misc:ip(net_adm:localhost(), Family),
+ Ip.
sz(L) when is_list(L) ->
length(L);
diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl
index 8cc3f75dc5..9b7609b831 100644
--- a/lib/snmp/test/snmp_test_lib.hrl
+++ b/lib/snmp/test/snmp_test_lib.hrl
@@ -1,5 +1,5 @@
%%<copyright>
-%% <year>2002-2008</year>
+%% <year>2002-2014</year>
%% <holder>Ericsson AB, All Rights Reserved</holder>
%%</copyright>
%%<legalnotice>
@@ -32,14 +32,15 @@
-define(APPLICATION, snmp).
-endif.
--define(SCONF(K,D,C), snmp_test_lib:set_config(K,D,C)).
--define(GCONF(K,C), snmp_test_lib:get_config(K,C)).
--define(RCONF(K,C,V), snmp_test_lib:replace_config(K,C,V)).
--define(HOSTNAME(N), snmp_test_lib:hostname(N)).
--define(LOCALHOST(), snmp_test_lib:localhost()).
--define(SZ(X), snmp_test_lib:sz(X)).
--define(OSTYPE(), snmp_test_lib:os_type()).
--define(DISPLAY_SUITE_INFO(), snmp_test_lib:display_suite_info(?MODULE)).
+-define(SCONF(K,D,C), snmp_test_lib:set_config(K,D,C)).
+-define(GCONF(K,C), snmp_test_lib:get_config(K,C)).
+-define(RCONF(K,C,V), snmp_test_lib:replace_config(K,C,V)).
+-define(HOSTNAME(N), snmp_test_lib:hostname(N)).
+-define(LOCALHOST(), snmp_test_lib:localhost()).
+-define(LOCALHOST(Family), snmp_test_lib:localhost(Family)).
+-define(SZ(X), snmp_test_lib:sz(X)).
+-define(OSTYPE(), snmp_test_lib:os_type()).
+-define(DISPLAY_SUITE_INFO(), snmp_test_lib:display_suite_info(?MODULE)).
%% - Test case macros -
diff --git a/lib/snmp/test/snmp_test_manager.erl b/lib/snmp/test/snmp_test_manager.erl
index 925ae77ab5..6d8673eecd 100644
--- a/lib/snmp/test/snmp_test_manager.erl
+++ b/lib/snmp/test/snmp_test_manager.erl
@@ -56,7 +56,7 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
code_change/3, terminate/2]).
--record(state, {mgr, parent, req, agent_target_name}).
+-record(state, {parent, req, agent_target_name}).
-define(SERVER, ?MODULE).
-define(USER, ?MODULE).
@@ -130,10 +130,10 @@ init([Parent, Opts]) ->
do_init(Opts) ->
{MgrDir, MgrConf, MgrOpts, AgentTargetName, AgentConf} = parse_opts(Opts),
ok = snmp_config:write_manager_config(MgrDir, "", MgrConf),
- {ok, Pid} = snmpm:start_link(MgrOpts),
+ ok = snmpm:start_link(MgrOpts),
ok = snmpm:register_user(?USER, ?MODULE, self()),
ok = snmpm:register_agent(?USER, AgentTargetName, AgentConf),
- {ok, #state{mgr = Pid, agent_target_name = AgentTargetName}}.
+ {ok, #state{agent_target_name = AgentTargetName}}.
parse_opts(Opts) ->
diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl
index d4eb00ff91..cf62edba1c 100644
--- a/lib/snmp/test/snmp_test_mgr.erl
+++ b/lib/snmp/test/snmp_test_mgr.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -235,21 +235,23 @@ init({Options, CallerPid}) ->
VsnHdrD =
{Com, User, EngineId, CtxEngineId, mk_seclevel(SecLevel)},
io:format("[~w] ~p -> VsnHdrD: ~p~n", [?MODULE, self(), VsnHdrD]),
+ IpFamily = get_value(ipfamily, Options, inet),
+ io:format("[~w] ~p -> IpFamily: ~p~n", [?MODULE, self(), IpFamily]),
AgIp = case snmp_misc:assq(agent, Options) of
{value, Tuple4} when is_tuple(Tuple4) andalso
(size(Tuple4) =:= 4) ->
Tuple4;
{value, Host} when is_list(Host) ->
- {ok, Ip} = snmp_misc:ip(Host),
+ {ok, Ip} = snmp_misc:ip(Host, IpFamily),
Ip
end,
io:format("[~w] ~p -> AgIp: ~p~n", [?MODULE, self(), AgIp]),
Quiet = lists:member(quiet, Options),
io:format("[~w] ~p -> Quiet: ~p~n", [?MODULE, self(), Quiet]),
- PackServ = start_packet_server(Quiet, Options, CallerPid,
- AgIp, Udp, TrapUdp,
- VsnHdrD, Version, Dir, RecBufSz,
- PacksDbg),
+ PackServ =
+ start_packet_server(
+ Quiet, Options, CallerPid, AgIp, Udp, TrapUdp,
+ VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily),
d("init -> packet server: ~p",[PackServ]),
State = #state{parent = CallerPid,
quiet = Quiet,
@@ -263,23 +265,21 @@ init({Options, CallerPid}) ->
end.
start_packet_server(false, _Options, _CallerPid, AgIp, Udp, TrapUdp,
- VsnHdrD, Version, Dir, RecBufSz, PacksDbg) ->
+ VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily) ->
d("start_packet_server -> entry", []),
- ?PACK_SERV:start_link_packet({msg, self()},
- AgIp, Udp, TrapUdp,
- VsnHdrD, Version, Dir, RecBufSz,
- PacksDbg);
+ ?PACK_SERV:start_link_packet(
+ {msg, self()}, AgIp, Udp, TrapUdp,
+ VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily);
start_packet_server(true, Options, CallerPid, AgIp, Udp, TrapUdp,
- VsnHdrD, Version, Dir, RecBufSz, PacksDbg) ->
+ VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily) ->
Type = get_value(receive_type, Options, pdu),
d("start_packet_server -> entry with"
"~n CallerPid: ~p"
"~n when"
"~n Type: ~p",[CallerPid, Type]),
- ?PACK_SERV:start_link_packet({Type, CallerPid},
- AgIp, Udp, TrapUdp,
- VsnHdrD, Version, Dir, RecBufSz,
- PacksDbg).
+ ?PACK_SERV:start_link_packet(
+ {Type, CallerPid}, AgIp, Udp, TrapUdp,
+ VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily).
is_options_ok([{mibs,List}|Opts]) when is_list(List) ->
is_options_ok(Opts);
@@ -287,6 +287,10 @@ is_options_ok([quiet|Opts]) ->
is_options_ok(Opts);
is_options_ok([{agent,_}|Opts]) ->
is_options_ok(Opts);
+is_options_ok([{ipfamily,IpFamily}|Opts])
+ when IpFamily =:= inet;
+ IpFamily =:= inet6 ->
+ is_options_ok(Opts);
is_options_ok([{agent_udp,Int}|Opts]) when is_integer(Int) ->
is_options_ok(Opts);
is_options_ok([{trap_udp,Int}|Opts]) when is_integer(Int) ->
diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl
index 5525c5c3ec..5274dcacd9 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,7 @@
-module(snmp_test_mgr_misc).
%% API
--export([start_link_packet/8, start_link_packet/9,
+-export([start_link_packet/8, start_link_packet/9, start_link_packet/10,
stop/1,
send_discovery_pdu/2,
send_pdu/2, send_msg/4, send_bytes/2,
@@ -31,7 +31,7 @@
get_pdu/1, set_pdu/2, format_hdr/1]).
%% internal exports
--export([init_packet/10]).
+-export([init_packet/11]).
-compile({no_auto_import, [error/2]}).
@@ -42,22 +42,26 @@
%%----------------------------------------------------------------------
%% The InHandler process will receive messages on the form {snmp_pdu, Pdu}.
%%----------------------------------------------------------------------
-start_link_packet(InHandler,
- AgentIp, UdpPort, TrapUdp,
- VsnHdr, Version, Dir, BufSz) ->
- start_link_packet(InHandler,
- AgentIp, UdpPort, TrapUdp,
- VsnHdr, Version, Dir, BufSz,
- false).
-
-start_link_packet(InHandler,
- AgentIp, UdpPort, TrapUdp,
- VsnHdr, Version, Dir, BufSz,
- Dbg) when is_integer(UdpPort) ->
- Args = [self(), InHandler,
- AgentIp, UdpPort, TrapUdp,
- VsnHdr, Version, Dir, BufSz,
- Dbg],
+start_link_packet(
+ InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz) ->
+ start_link_packet(
+ InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ false).
+
+start_link_packet(
+ InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ Dbg) ->
+ start_link_packet(
+ InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ Dbg, inet).
+
+start_link_packet(
+ InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ Dbg, IpFamily) when is_integer(UdpPort) ->
+ Args =
+ [self(),
+ InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ Dbg, IpFamily],
proc_lib:start_link(?MODULE, init_packet, Args).
stop(Pid) ->
@@ -90,12 +94,14 @@ send_bytes(Bytes, PacketPid) ->
%%--------------------------------------------------
%% The SNMP encode/decode process
%%--------------------------------------------------
-init_packet(Parent, SnmpMgr,
- AgentIp, UdpPort, TrapUdp,
- VsnHdr, Version, Dir, BufSz, DbgOptions) ->
+init_packet(
+ Parent,
+ SnmpMgr, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ DbgOptions, IpFamily) ->
put(sname, mgr_misc),
init_debug(DbgOptions),
- {ok, UdpId} = gen_udp:open(TrapUdp, [{recbuf,BufSz},{reuseaddr, true}]),
+ {ok, UdpId} =
+ gen_udp:open(TrapUdp, [{recbuf,BufSz}, {reuseaddr, true}, IpFamily]),
put(msg_id, 1),
proc_lib:init_ack(Parent, self()),
init_usm(Version, Dir),
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
new file mode 100644
index 0000000000..6e9c57bce9
--- /dev/null
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
@@ -0,0 +1,433 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test suite uses the following external programs:
+%% snmpget From packet 'snmp' (in Ubuntu 12.04)
+%% snmptrapd From packet 'snmpd' (in Ubuntu 12.04)
+%% They originate from the Net-SNMP applications, see:
+%% http://net-snmp.sourceforge.net/
+
+
+-module(snmp_to_snmpnet_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("snmp/include/STANDARD-MIB.hrl").
+
+-define(AGENT_ENGINE_ID, "ErlangSnmpAgent").
+-define(AGENT_PORT, 4000).
+-define(MANAGER_PORT, 8989).
+-define(DEFAULT_MAX_MESSAGE_SIZE, 484).
+
+expected(?sysDescr_instance = Oid, get) ->
+ OidStr = oid_str(Oid),
+ iolist_to_binary([OidStr | " = STRING: \"Erlang SNMP agent\""]).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [
+ {group, ipv4},
+ {group, ipv6},
+ {group, ipv4_ipv6}
+ ].
+
+groups() ->
+ [{ipv4, [],
+ [{group, get},
+ {group, inform}
+ ]},
+ {ipv6, [],
+ [{group, get},
+ {group, inform}
+ ]},
+ {ipv4_ipv6, [],
+ [{group, get},
+ {group, inform}
+ ]},
+ %%
+ {get, [],
+ [erlang_agent_netsnmp_get]},
+ {inform, [],
+ [erlang_agent_netsnmp_inform]}
+ ].
+
+init_per_suite(Config) ->
+ [{agent_port, ?AGENT_PORT}, {manager_port, ?MANAGER_PORT} | Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(ipv4, Config) ->
+ init_per_group_ip([inet], Config);
+init_per_group(ipv6, Config) ->
+ init_per_group_ipv6([inet6], Config);
+init_per_group(ipv4_ipv6, Config) ->
+ init_per_group_ipv6([inet, inet6], Config);
+%%
+init_per_group(get, Config) ->
+ %% From Ubuntu package snmp
+ find_executable(snmpget, Config);
+init_per_group(inform, Config) ->
+ %% From Ubuntu package snmpd
+ find_executable(snmptrapd, Config);
+%%
+init_per_group(_, Config) ->
+ Config.
+
+init_per_group_ipv6(Families, Config) ->
+ case ct:require(ipv6_hosts) of
+ ok ->
+ init_per_group_ip(Families, Config);
+ _ ->
+ {skip, "Host does not support IPV6"}
+ end.
+
+init_per_group_ip(Families, Config) ->
+ Dir = ?config(priv_dir, Config),
+ AgentPort = ?config(agent_port, Config),
+ ManagerPort = ?config(manager_port, Config),
+ Versions = [v2],
+ {ok, Host} = inet:gethostname(),
+ Transports =
+ [begin
+ {ok, Addr} = inet:getaddr(Host, Family),
+ {domain(Family), {Addr, AgentPort}}
+ end || Family <- Families],
+ Targets =
+ [begin
+ {ok, Addr} = inet:getaddr(Host, Family),
+ {domain(Family), {Addr, ManagerPort}}
+ end || Family <- Families],
+ agent_config(Dir, Transports, Targets, Versions),
+ [{port, ?AGENT_PORT}, {snmp_versions, Versions},
+ {transports, Transports}, {targets, Targets}
+ | Config].
+
+
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ct:timetrap(10000),
+ application:stop(snmp),
+ application:unload(snmp),
+ [{watchdog, Dog} | Config].
+
+end_per_testcase(_, Config) ->
+ case application:stop(snmp) of
+ ok ->
+ ok;
+ E1 ->
+ ct:pal("application:stop(snmp) -> ~p", [E1])
+ end,
+ case application:unload(snmp) of
+ ok ->
+ ok;
+ E2 ->
+ ct:pal("application:unload(snmp) -> ~p", [E2])
+ end,
+ Config.
+
+find_executable(Exec, Config) ->
+ ExecStr = atom_to_list(Exec),
+ case os:find_executable(ExecStr) of
+ false ->
+ %% The sbin dirs are not in the PATH on all platforms...
+ find_sys_executable(
+ Exec, ExecStr,
+ [["usr", "local", "sbin"],
+ ["usr", "sbin"],
+ ["sbin"]],
+ Config);
+ Path ->
+ [{Exec, Path} | Config]
+ end.
+
+find_sys_executable(_Exec, ExecStr, [], _Config) ->
+ {skip, ExecStr ++ " not found"};
+find_sys_executable(Exec, ExecStr, [Dir | Dirs], Config) ->
+ case os:find_executable(filename:join(["/" | Dir] ++ [ExecStr])) of
+ false ->
+ find_sys_executable(Exec, ExecStr, Dirs, Config);
+ Path ->
+ [{Exec, Path} | Config]
+ end.
+
+start_agent(Config) ->
+ ok = application:load(snmp),
+ ok = application:set_env(snmp, agent, app_env(Config)),
+ ok = application:start(snmp).
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+erlang_agent_netsnmp_get() ->
+ [{doc,"Test that we can access erlang snmp agent "
+ "from snmpnet manager"}].
+
+erlang_agent_netsnmp_get(Config) when is_list(Config) ->
+ Transports = ?config(transports, Config),
+ start_agent(Config),
+ Oid = ?sysDescr_instance,
+ Expected = expected(Oid, get),
+ [Expected = snmpget(Oid, Transport, Config)
+ || Transport <- Transports],
+ ok.
+
+%%--------------------------------------------------------------------
+erlang_agent_netsnmp_inform(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Mib = "TestTrapv2",
+
+ start_agent(Config),
+ ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)),
+
+ ProgHandle = start_snmptrapd(Mib, Config),
+
+ snmpa:send_notification(
+ snmp_master_agent, testTrapv22, {erlang_agent_test, self()}),
+
+ receive
+ {snmp_targets, erlang_agent_test, Addresses} ->
+ ct:pal("Notification sent to: ~p~n", [Addresses]),
+ erlang_agent_netsnmp_inform_responses(Addresses)
+ end,
+ stop_program(ProgHandle).
+
+erlang_agent_netsnmp_inform_responses([]) ->
+ receive
+ {snmp_notification, erlang_agent_test, _} = Unexpected ->
+ ct:pal("Unexpected response: ~p", [Unexpected]),
+ erlang_agent_netsnmp_inform_responses([])
+ after 0 ->
+ ok
+ end;
+erlang_agent_netsnmp_inform_responses([Address | Addresses]) ->
+ receive
+ {snmp_notification, erlang_agent_test,
+ {got_response, Address}} ->
+ ct:pal("Got response from: ~p~n", [Address]),
+ erlang_agent_netsnmp_inform_responses(Addresses);
+ {snmp_notification, erlang_agent_test,
+ {no_response, _} = NoResponse} ->
+ ct:fail(NoResponse)
+ end.
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+snmpget(Oid, Transport, Config) ->
+ Versions = ?config(snmp_versions, Config),
+
+ Args =
+ ["-c", "public", net_snmp_version(Versions),
+ "-m", "",
+ "-Cf",
+ net_snmp_addr_str(Transport),
+ oid_str(Oid)],
+ ProgHandle = start_program(snmpget, Args, none, Config),
+ {_, line, Line} = get_program_output(ProgHandle),
+ stop_program(ProgHandle),
+ Line.
+
+start_snmptrapd(Mibs, Config) ->
+ DataDir = ?config(data_dir, Config),
+ MibDir = filename:join(code:lib_dir(snmp), "mibs"),
+ Targets = ?config(targets, Config),
+ SnmptrapdArgs =
+ ["-f", "-Lo", "-C",
+ "-m", Mibs,
+ "-M", MibDir++":"++DataDir,
+ "--disableAuthorization=yes",
+ "--snmpTrapdAddr=" ++ net_snmp_addr_str(Targets)],
+ {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]),
+ start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config).
+
+start_program(Prog, Args, StartCheckMP, Config) ->
+ Path = ?config(Prog, Config),
+ DataDir = ?config(data_dir, Config),
+ StartWrapper = filename:join(DataDir, "start_stop_wrapper"),
+ Parent = self(),
+ Pid =
+ spawn_link(
+ fun () ->
+ run_program(Parent, StartWrapper, [Path | Args])
+ end),
+ start_check(Pid, erlang:monitor(process, Pid), StartCheckMP).
+
+start_check(Pid, Mon, none) ->
+ {Pid, Mon};
+start_check(Pid, Mon, StartCheckMP) ->
+ receive
+ {Pid, line, Line} ->
+ case re:run(Line, StartCheckMP, [{capture, none}]) of
+ match ->
+ {Pid, Mon};
+ nomatch ->
+ start_check(Pid, Mon, StartCheckMP)
+ end;
+ {'DOWN', Mon, _, _, Reason} ->
+ ct:fail("Prog ~p start failed: ~p", [Pid, Reason])
+ end.
+
+get_program_output({Pid, Mon}) ->
+ receive
+ {Pid, _, _} = Msg ->
+ Msg;
+ {'DOWN', Mon, _, _, Reason} ->
+ ct:fail("Prog ~p crashed: ~p", [Pid, Reason])
+ end.
+
+stop_program({Pid, _} = Handle) ->
+ Pid ! {self(), stop},
+ wait_program_stop(Handle).
+
+wait_program_stop({Pid, Mon}) ->
+ receive
+ {Pid, exit, ExitStatus} ->
+ receive
+ {'DOWN', Mon, _, _, _} ->
+ ExitStatus
+ end;
+ {'DOWN', Mon, _, _, Reason} ->
+ ct:fail("Prog stop: ~p", [Reason])
+ end.
+
+run_program(Parent, StartWrapper, ProgAndArgs) ->
+ Port =
+ open_port(
+ {spawn_executable, StartWrapper},
+ [{args, ProgAndArgs}, binary, stderr_to_stdout, {line, 80},
+ exit_status]),
+ ct:pal("Prog ~p started: ~p", [Port, ProgAndArgs]),
+ run_program_loop(Parent, Port, []).
+
+run_program_loop(Parent, Port, Buf) ->
+ receive
+ {Parent, stop} ->
+ true = port_command(Port, <<"stop\n">>),
+ ct:pal("Prog ~p stop", [Port]),
+ run_program_loop(Parent, Port, Buf);
+ {Port, {data, {Flag, Data}}} ->
+ case Flag of
+ eol ->
+ Line = iolist_to_binary(lists:reverse(Buf, Data)),
+ ct:pal("Prog ~p output: ~s", [Port, Line]),
+ Parent ! {self(), line, Line},
+ run_program_loop(Parent, Port, []);
+ noeol ->
+ run_program_loop(Parent, Port, [Data | Buf])
+ end;
+ {Port, {exit_status,ExitStatus}} ->
+ ct:pal("Prog ~p exit: ~p", [Port, ExitStatus]),
+ catch port_close(Port),
+ Parent ! {self(), exit, ExitStatus};
+ Unexpected ->
+ ct:pal("run_program_loop Unexpected: ~p", [Unexpected]),
+ run_program_loop(Parent, Port, Buf)
+ end.
+
+
+app_env(Config) ->
+ Dir = ?config(priv_dir, Config),
+ Vsns = ?config(snmp_versions, Config),
+ [{versions, Vsns},
+ {agent_type, master},
+ {agent_verbosity, trace},
+ {db_dir, Dir},
+ {audit_trail_log, [{type, read_write},
+ {dir, Dir},
+ {size, {10240, 10}}]},
+ {config, [{dir, Dir},
+ {force_load, true},
+ {verbosity, trace}]},
+ {local_db, [{repair, true},
+ {verbosity, silence}]},
+ {mib_server, [{verbosity, silence}]},
+ {symbolic_store, [{verbosity, silence}]},
+ {note_store, [{verbosity, silence}]},
+ {net_if, [{verbosity, trace}]}].
+
+oid_str([1 | Ints]) ->
+ "iso." ++ oid_str_tl(Ints);
+oid_str(Ints) ->
+ oid_str_tl(Ints).
+
+oid_str_tl([]) ->
+ "";
+oid_str_tl([Int]) ->
+ integer_to_list(Int);
+oid_str_tl([Int | Ints]) ->
+ integer_to_list(Int) ++ "." ++ oid_str_tl(Ints).
+
+agent_config(Dir, Transports, TargetDomain, TargetAddr, Versions) ->
+ agent_config(Dir, Transports, [{TargetDomain, TargetAddr}], Versions).
+%%
+agent_config(Dir, Transports, Targets, Versions) ->
+ EngineID = ?AGENT_ENGINE_ID,
+ MMS = ?DEFAULT_MAX_MESSAGE_SIZE,
+ ok = snmp_config:write_agent_snmp_conf(Dir, Transports, EngineID, MMS),
+ ok = snmp_config:write_agent_snmp_context_conf(Dir),
+ ok = snmp_config:write_agent_snmp_community_conf(Dir),
+ ok =
+ snmp_config:write_agent_snmp_standard_conf(
+ Dir, "snmp_to_snmpnet_SUITE"),
+ ok =
+ snmp_config:write_agent_snmp_target_addr_conf(
+ Dir, Targets, Versions),
+ ok = snmp_config:write_agent_snmp_target_params_conf(Dir, Versions),
+ ok = snmp_config:write_agent_snmp_notify_conf(Dir, inform),
+ ok = snmp_config:write_agent_snmp_vacm_conf(Dir, Versions, none).
+
+net_snmp_version([v3 | _]) ->
+ "-v3";
+net_snmp_version([v2 | _]) ->
+ "-v2c";
+net_snmp_version([v1 | _]) ->
+ "-v1".
+
+domain(inet) ->
+ transportDomainUdpIpv4;
+domain(inet6) ->
+ transportDomainUdpIpv6.
+
+net_snmp_addr_str([Target | Targets]) ->
+ net_snmp_addr_str(Target) ++
+ case Targets of
+ [] ->
+ [];
+ [_ | _] ->
+ "," ++ net_snmp_addr_str(Targets)
+ end;
+net_snmp_addr_str({transportDomainUdpIpv4, {Addr, Port}}) ->
+ "udp:" ++
+ inet_parse:ntoa(Addr) ++ ":" ++
+ integer_to_list(Port);
+net_snmp_addr_str({transportDomainUdpIpv6, {Addr, Port}}) ->
+ "udp6:[" ++
+ inet_parse:ntoa(Addr) ++ "]:" ++
+ integer_to_list(Port).
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin
new file mode 100644
index 0000000000..9d0790498d
--- /dev/null
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin
Binary files differ
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib
new file mode 100644
index 0000000000..679ddc14b0
--- /dev/null
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib
@@ -0,0 +1,71 @@
+TestTrapv2 DEFINITIONS ::= BEGIN
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
+ TimeTicks, Counter32, snmpModules, mib-2, enterprises, IpAddress,
+ Integer32
+ FROM SNMPv2-SMI
+ DisplayString, TestAndIncr, TimeStamp, RowStatus, TruthValue,
+ TEXTUAL-CONVENTION
+ FROM SNMPv2-TC
+ MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
+ FROM SNMPv2-CONF
+
+ system, snmp, ifIndex, ifAdminStatus, ifOperStatus
+ FROM RFC1213-MIB
+ snmpTraps
+ FROM SNMPv2-MIB;
+
+testTrapv2 MODULE-IDENTITY
+ LAST-UPDATED "9511090000Z"
+ ORGANIZATION "IETF SNMPv2 Working Group"
+ CONTACT-INFO
+ " Marshall T. Rose
+
+ Postal: Dover Beach Consulting, Inc.
+ 420 Whisman Court
+ Mountain View, CA 94043-2186
+ US
+
+ Tel: +1 415 968 1052
+
+ DESCRIPTION
+ "The MIB module for SNMPv2 entities."
+ REVISION "9304010000Z"
+ DESCRIPTION
+ "The initial revision of this MIB module was published as
+ RFC 1450."
+ ::= { system 100 }
+
+
+tst OBJECT IDENTIFIER ::= { system 0 }
+
+testTrapv21 NOTIFICATION-TYPE
+ STATUS current
+ DESCRIPTION
+ "This trap is exactly the v2 correspondance of testTrap1 in
+ TestTrap mib."
+ ::= { snmp 1 }
+
+testTrapv22 NOTIFICATION-TYPE
+ STATUS current
+ DESCRIPTION
+ "This trap is exactly the v2 correspondance of testTrap2 in
+ TestTrap mib."
+ ::= { system 0 1 }
+
+linkUp NOTIFICATION-TYPE
+ OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
+ STATUS current
+ DESCRIPTION
+ "A linkUp trap signifies that the SNMPv2 entity,
+ acting in an agent role, has detected that the
+ ifOperStatus object for one of its communication links
+ has transitioned out of the down state."
+ ::= { snmpTraps 4 }
+
+
+
+
+END
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper
new file mode 100755
index 0000000000..f806ab5c12
--- /dev/null
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper
@@ -0,0 +1,47 @@
+#! /bin/sh
+##
+## %CopyrightBegin%
+##
+## Copyright Ericsson AB 2014-2014. All Rights Reserved.
+##
+## The contents of this file are subject to the Erlang Public License,
+## Version 1.1, (the "License"); you may not use this file except in
+## compliance with the License. You should have received a copy of the
+## Erlang Public License along with this software. If not, it can be
+## retrieved online at http://www.erlang.org/.
+##
+## Software distributed under the License is distributed on an "AS IS"
+## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+## the License for the specific language governing rights and limitations
+## under the License.
+##
+## %CopyrightEnd%
+##
+#
+
+## Start the given executable, wait for stop command,
+## stop the running executable and wait for exit.
+
+die () {
+ r=$?
+ echo "$0:" "$*" 1>&2
+ exit $r
+}
+
+test -x "$1" || die "Not Executable: $1"
+
+# Redirect stdin to make sure the stop command is read by us below
+# and does not go to the executable
+"$@" 0< /dev/null &
+PID=$!
+
+# Wait for stop command
+while read LINE; do
+ case :"$LINE" in
+ :"stop")
+ break;;
+ esac
+done
+
+kill $PID
+wait $PID
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 04c3cc9392..fd10244386 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = snmp
-SNMP_VSN = 4.25.1
+SNMP_VSN = 5.0
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 84d5e5c86e..0dbec7527a 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -29,6 +29,48 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 3.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Removed mail address from error reports and corrected
+ spelling error (Stacktace -&gt; stacktrace)</p>
+ <p>
+ Own Id: OTP-11883 Aux Id: seq12586 </p>
+ </item>
+ <item>
+ <p>
+ Decode/encode fixes in SSH_MSG_IGNORE and
+ SSH_MSG_UNIMPLEMENTED.</p>
+ <p>
+ Own Id: OTP-11983</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Accepts that some older OpenSSH clients sends incorrect
+ disconnect messages.</p>
+ <p>
+ Own Id: OTP-11972</p>
+ </item>
+ <item>
+ <p>
+ Handle inet and inet6 option correctly</p>
+ <p>
+ Own Id: OTP-11976</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 3.0.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index 5a141ced3c..876eba598a 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -97,6 +97,8 @@
<seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/[2, 4]</seealso>.</p>
<p>Options are:</p>
<taglist>
+ <tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
+ <item> IP version to use.</item>
<tag><c><![CDATA[{user_dir, string()}]]></c></tag>
<item>
<p>Sets the user directory i.e. the directory containing
@@ -230,6 +232,8 @@
port.</p>
<p>Options are:</p>
<taglist>
+ <tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
+ <item> IP version to use when the host address is specified as <c>any</c>. </item>
<tag><c><![CDATA[{subsystems, [subsystem_spec()]]]></c></tag>
<item>
Provides specifications for handling of subsystems. The
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 42eb2167e0..8269f89e40 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,13 +19,25 @@
{"%VSN%",
[
+ {"3.0.2", [{load_module, ssh_message, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_io, soft_purge, soft_purge, []}]},
{"3.0.1", [{load_module, ssh, soft_purge, soft_purge, []},
- {load_module, ssh_acceptor, soft_purge, soft_purge, []}]},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
+ {load_module, ssh_message, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_io, soft_purge, soft_purge, []}]},
{<<".*">>, [{restart_application, ssh}]}
],
[
+ {"3.0.2", [{load_module, ssh_message, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_io, soft_purge, soft_purge, []}]},
{"3.0.1", [{load_module, ssh, soft_purge, soft_purge, []},
- {load_module, ssh_acceptor, soft_purge, soft_purge, []}]},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
+ {load_module, ssh_message, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_io, soft_purge, soft_purge, []}]},
{<<".*">>, [{restart_application, ssh}]}
]
}.
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 240de69eff..743c01a42c 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -74,8 +74,7 @@ connect(Host, Port, Options, Timeout) ->
{_, Transport, _} = TransportOpts =
proplists:get_value(transport, Options, {tcp, gen_tcp, tcp_closed}),
ConnectionTimeout = proplists:get_value(connect_timeout, Options, infinity),
- Inet = proplists:get_value(inet, SshOptions, inet),
- try Transport:connect(Host, Port, [ {active, false}, Inet | SocketOptions], ConnectionTimeout) of
+ try Transport:connect(Host, Port, [ {active, false} | SocketOptions], ConnectionTimeout) of
{ok, Socket} ->
Opts = [{user_pid, self()}, {host, Host} | fix_idle_time(SshOptions)],
ssh_connection_handler:start_connection(client, Socket, Opts, Timeout);
@@ -256,8 +255,8 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
handle_options(Opts) ->
try handle_option(proplists:unfold(Opts), [], []) of
- {_,_} = Options ->
- Options
+ {Inet, Ssh} ->
+ {handle_ip(Inet), Ssh}
catch
throw:Error ->
Error
@@ -433,13 +432,14 @@ handle_ssh_option(Opt) ->
throw({error, {eoptions, Opt}}).
handle_inet_option({active, _} = Opt) ->
- throw({error, {{eoptions, Opt}, "Ssh has built in flow control, "
- "and activ is handled internaly user is not allowd"
+ throw({error, {{eoptions, Opt}, "SSH has built in flow control, "
+ "and active is handled internally, user is not allowed"
"to specify this option"}});
-handle_inet_option({inet, Value} = Opt) when (Value == inet) or (Value == inet6) ->
- Opt;
+
+handle_inet_option({inet, Value}) when (Value == inet) or (Value == inet6) ->
+ Value;
handle_inet_option({reuseaddr, _} = Opt) ->
- throw({error, {{eoptions, Opt},"Is set internaly user is not allowd"
+ throw({error, {{eoptions, Opt},"Is set internally, user is not allowed"
"to specify this option"}});
%% Option verified by inet
handle_inet_option(Opt) ->
@@ -460,3 +460,17 @@ handle_pref_algs([H|T], Acc) ->
_ ->
false
end.
+
+handle_ip(Inet) -> %% Default to ipv4
+ case lists:member(inet, Inet) of
+ true ->
+ Inet;
+ false ->
+ case lists:member(inet6, Inet) of
+ true ->
+ Inet;
+ false ->
+ [inet | Inet]
+ end
+ end.
+
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 06866392da..86804c4436 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -104,21 +104,11 @@ start_connection(client = Role, Socket, Options, Timeout) ->
start_connection(server = Role, Socket, Options, Timeout) ->
try
- Sups = proplists:get_value(supervisors, Options),
- ConnectionSup = proplists:get_value(connection_sup, Sups),
- Opts = [{supervisors, Sups}, {user_pid, self()} | proplists:get_value(ssh_opts, Options, [])],
- {ok, Pid} = ssh_connection_sup:start_child(ConnectionSup, [Role, Socket, Opts]),
- {_, Callback, _} = proplists:get_value(transport, Options, {tcp, gen_tcp, tcp_closed}),
- socket_control(Socket, Pid, Callback),
- case proplists:get_value(parallel_login, Opts, false) of
+ case proplists:get_value(parallel_login, Options, false) of
true ->
- spawn(fun() ->
- Ref = erlang:monitor(process, Pid),
- handshake(Pid, Ref, Timeout)
- end);
+ spawn(fun() -> start_server_connection(Role, Socket, Options, Timeout) end);
false ->
- Ref = erlang:monitor(process, Pid),
- handshake(Pid, Ref, Timeout)
+ start_server_connection(Role, Socket, Options, Timeout)
end
catch
exit:{noproc, _} ->
@@ -127,6 +117,18 @@ start_connection(server = Role, Socket, Options, Timeout) ->
{error, Error}
end.
+
+start_server_connection(server = Role, Socket, Options, Timeout) ->
+ Sups = proplists:get_value(supervisors, Options),
+ ConnectionSup = proplists:get_value(connection_sup, Sups),
+ Opts = [{supervisors, Sups}, {user_pid, self()} | proplists:get_value(ssh_opts, Options, [])],
+ {ok, Pid} = ssh_connection_sup:start_child(ConnectionSup, [Role, Socket, Opts]),
+ {_, Callback, _} = proplists:get_value(transport, Options, {tcp, gen_tcp, tcp_closed}),
+ socket_control(Socket, Pid, Callback),
+ Ref = erlang:monitor(process, Pid),
+ handshake(Pid, Ref, Timeout).
+
+
start_link(Role, Socket, Options) ->
{ok, proc_lib:spawn_link(?MODULE, init, [[Role, Socket, Options]])}.
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 8d6c77c0ed..76b57cb995 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -255,7 +255,7 @@ encode(#ssh_msg_ignore{data = Data}) ->
ssh_bits:encode([?SSH_MSG_IGNORE, Data], [byte, string]);
encode(#ssh_msg_unimplemented{sequence = Seq}) ->
- ssh_bits:encode([?SSH_MSG_IGNORE, Seq], [byte, uint32]);
+ ssh_bits:encode([?SSH_MSG_UNIMPLEMENTED, Seq], [byte, uint32]);
encode(#ssh_msg_debug{always_display = Bool,
message = Msg,
@@ -391,13 +391,6 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
data = Data};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?UINT32(Len), Alg:Len/binary, KeyBlob/binary>>) ->
- #ssh_msg_userauth_pk_ok{
- algorithm_name = Alg,
- key_blob = KeyBlob
- };
-
-%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?UINT32(Len0), Prompt:Len0/binary,
?UINT32(Len1), Lang:Len1/binary>>) ->
#ssh_msg_userauth_passwd_changereq{
@@ -405,6 +398,13 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?UINT32(Len0), Prompt:Len0/b
languge = Lang
};
+%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?UINT32(Len), Alg:Len/binary, KeyBlob/binary>>) ->
+ #ssh_msg_userauth_pk_ok{
+ algorithm_name = Alg,
+ key_blob = KeyBlob
+ };
+
decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_RESPONSE), ?UINT32(Num), Data/binary>>) ->
#ssh_msg_userauth_info_response{
num_responses = Num,
@@ -461,10 +461,19 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
language = Lang
};
+%% Accept bad disconnects from ancient openssh clients that doesn't send language tag. Use english as a work-around.
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
+ ?UINT32(Len0), Desc:Len0/binary>>) ->
+ #ssh_msg_disconnect{
+ code = Code,
+ description = unicode:characters_to_list(Desc),
+ language = <<"en">>
+ };
+
decode(<<?SSH_MSG_NEWKEYS>>) ->
#ssh_msg_newkeys{};
-decode(<<?BYTE(?SSH_MSG_IGNORE), Data/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_IGNORE), ?UINT32(Len), Data:Len/binary>>) ->
#ssh_msg_ignore{data = Data};
decode(<<?BYTE(?SSH_MSG_UNIMPLEMENTED), ?UINT32(Seq)>>) ->
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index ba38c1da40..35fca21021 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -59,14 +59,19 @@ groups() ->
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
{internal_error, [], [internal_error]},
- {hardening_tests, [], [max_sessions]}
+ {hardening_tests, [], [ssh_connect_nonegtimeout_connected_parallel,
+ ssh_connect_nonegtimeout_connected_sequential,
+ ssh_connect_negtimeout_parallel,
+ ssh_connect_negtimeout_sequential,
+ max_sessions]}
].
basic_tests() ->
[send, close, peername_sockname,
exec, exec_compressed, shell, cli, known_hosts,
- idle_time, rekey, openssh_zlib_basic_test].
+ idle_time, rekey, openssh_zlib_basic_test,
+ misc_ssh_options, inet_option].
%%--------------------------------------------------------------------
@@ -175,16 +180,47 @@ misc_ssh_options(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
- CMiscOpt0 = [{connecect_timeout, 1000}, {ip_v6_disabled, false}, {user_dir, UserDir}],
- CMiscOpt1 = [{connecect_timeout, infinity}, {ip_v6_disabled, true}, {user_dir, UserDir}],
- SMiscOpt0 = [{ip_v6_disabled, false}, {user_dir, UserDir}, {system_dir, SystemDir}],
- SMiscOpt1 = [{ip_v6_disabled, true}, {user_dir, UserDir}, {system_dir, SystemDir}],
+ CMiscOpt0 = [{connect_timeout, 1000}, {user_dir, UserDir}],
+ CMiscOpt1 = [{connect_timeout, infinity}, {user_dir, UserDir}],
+ SMiscOpt0 = [{user_dir, UserDir}, {system_dir, SystemDir}],
+ SMiscOpt1 = [{user_dir, UserDir}, {system_dir, SystemDir}],
+
+ basic_test([{client_opts, CMiscOpt0}, {server_opts, SMiscOpt0}]),
+ basic_test([{client_opts, CMiscOpt1}, {server_opts, SMiscOpt1}]).
+
+%%--------------------------------------------------------------------
+inet_option() ->
+ [{doc, "Test configuring IPv4"}].
+inet_option(Config) when is_list(Config) ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
- ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ClientOpts = [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}],
+ ServerOpts = [{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}],
- basic_test([{client_opts, CMiscOpt0 ++ ClientOpts}, {server_opts, SMiscOpt0 ++ ServerOpts}]),
- basic_test([{client_opts, CMiscOpt1 ++ ClientOpts}, {server_opts, SMiscOpt1 ++ ServerOpts}]).
+ basic_test([{client_opts, [{inet, inet} | ClientOpts]},
+ {server_opts, [{inet, inet} | ServerOpts]}]).
+
+%%--------------------------------------------------------------------
+inet6_option() ->
+ [{doc, "Test configuring IPv6"}].
+inet6_option(Config) when is_list(Config) ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ ClientOpts = [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}],
+ ServerOpts = [{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}],
+
+ basic_test([{client_opts, [{inet, inet6} | ClientOpts]},
+ {server_opts, [{inet, inet6} | ServerOpts]}]).
%%--------------------------------------------------------------------
exec() ->
@@ -711,6 +747,98 @@ ms_passed(N1={_,_,M1}, N2={_,_,M2}) ->
1000 * (Min*60 + Sec + (M2-M1)/1000000).
%%--------------------------------------------------------------------
+ssh_connect_negtimeout_parallel(Config) -> ssh_connect_negtimeout(Config,true).
+ssh_connect_negtimeout_sequential(Config) -> ssh_connect_negtimeout(Config,false).
+
+ssh_connect_negtimeout(Config, Parallel) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NegTimeOut = 2000, % ms
+ ct:log("Parallel: ~p",[Parallel]),
+
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,Socket} = gen_tcp:connect(Host, Port, []),
+ ct:pal("And now sleeping 1.2*NegTimeOut (~p ms)...", [round(1.2 * NegTimeOut)]),
+ receive after round(1.2 * NegTimeOut) -> ok end,
+
+ case inet:sockname(Socket) of
+ {ok,_} -> ct:fail("Socket not closed");
+ {error,_} -> ok
+ end.
+
+%%--------------------------------------------------------------------
+ssh_connect_nonegtimeout_connected_parallel() ->
+ [{doc, "Test that ssh connection does not timeout if the connection is established (parallel)"}].
+ssh_connect_nonegtimeout_connected_parallel(Config) ->
+ ssh_connect_nonegtimeout_connected(Config, true).
+
+ssh_connect_nonegtimeout_connected_sequential() ->
+ [{doc, "Test that ssh connection does not timeout if the connection is established (non-parallel)"}].
+ssh_connect_nonegtimeout_connected_sequential(Config) ->
+ ssh_connect_nonegtimeout_connected(Config, false).
+
+
+ssh_connect_nonegtimeout_connected(Config, Parallel) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NegTimeOut = 20000, % ms
+ ct:log("Parallel: ~p",[Parallel]),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ receive
+ {'EXIT', _, _} ->
+ ct:fail(no_ssh_connection);
+ ErlShellStart ->
+ ct:pal("---Erlang shell start: ~p~n", [ErlShellStart]),
+ one_shell_op(IO, NegTimeOut),
+ one_shell_op(IO, NegTimeOut),
+ ct:pal("And now sleeping 1.2*NegTimeOut (~p ms)...", [round(1.2 * NegTimeOut)]),
+ receive after round(1.2 * NegTimeOut) -> ok end,
+ one_shell_op(IO, NegTimeOut)
+ end,
+ exit(Shell, kill).
+
+
+one_shell_op(IO, TimeOut) ->
+ ct:pal("One shell op: Waiting for prompter"),
+ receive
+ ErlPrompt0 -> ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
+ after TimeOut -> ct:fail("Timeout waiting for promter")
+ end,
+
+ IO ! {input, self(), "2*3*7.\r\n"},
+ receive
+ Echo0 -> ct:log("Echo: ~p ~n", [Echo0])
+ after TimeOut -> ct:fail("Timeout waiting for echo")
+ end,
+
+ receive
+ ?NEWLINE -> ct:log("NEWLINE received", [])
+ after TimeOut ->
+ receive Any1 -> ct:log("Bad NEWLINE: ~p",[Any1])
+ after 0 -> ct:fail("Timeout waiting for NEWLINE")
+ end
+ end,
+
+ receive
+ Result0 -> ct:log("Result: ~p~n", [Result0])
+ after TimeOut -> ct:fail("Timeout waiting for result")
+ end.
+
+%%--------------------------------------------------------------------
openssh_zlib_basic_test() ->
[{doc, "Test basic connection with openssh_zlib"}].
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 40ed27d8f5..9bef10a366 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 3.0.2
+SSH_VSN = 3.0.4
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index c61b2a9c2f..1b37a2baa2 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -25,7 +25,119 @@
<file>notes.xml</file>
</header>
<p>This document describes the changes made to the SSL application.</p>
- <section><title>SSL 5.3.4</title>
+ <section><title>SSL 5.3.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ ssl:recv now returns {error, einval} if applied to a non
+ passive socket, the same as gen_tcp:recv. </p>
+ <p>
+ Thanks to Danil Zagoskin for reporting this issue</p>
+ <p>
+ Own Id: OTP-11878</p>
+ </item>
+ <item>
+ <p>
+ Corrected handling of default values for
+ signature_algorithms extension in TLS-1.2 and
+ corresponding values used in previous versions that does
+ not support this extension. </p>
+ <p>
+ Thanks to Danil Zagoskin</p>
+ <p>
+ Own Id: OTP-11886</p>
+ </item>
+ <item>
+ <p>
+ Handle socket option inheritance when pooling of accept
+ sockets is used</p>
+ <p>
+ Own Id: OTP-11897</p>
+ </item>
+ <item>
+ <p>
+ Make sure that the list of versions, possibly supplied in
+ the versions option, is not order dependent.</p>
+ <p>
+ Thanks to Ransom Richardson for reporting this issue</p>
+ <p>
+ Own Id: OTP-11912</p>
+ </item>
+ <item>
+ <p>
+ Reject connection if the next_protocol message is sent
+ twice.</p>
+ <p>
+ Own Id: OTP-11926</p>
+ </item>
+ <item>
+ <p>
+ Correct options handling when ssl:ssl_accept/3 is called
+ with new ssl options after calling ssl:listen/2</p>
+ <p>
+ Own Id: OTP-11950</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Gracefully handle unknown alerts</p>
+ <p>
+ Thanks to Atul Atri for reporting this issue</p>
+ <p>
+ Own Id: OTP-11874</p>
+ </item>
+ <item>
+ <p>
+ Gracefully ignore cipher suites sent by client not
+ supported by the SSL/TLS version that the client has
+ negotiated.</p>
+ <p>
+ Thanks to Danil Zagoskin for reporting this issue</p>
+ <p>
+ Own Id: OTP-11875</p>
+ </item>
+ <item>
+ <p>
+ Gracefully handle structured garbage, i.e a client sends
+ some garbage in a ssl record instead of a valid fragment.</p>
+ <p>
+ Thanks to Danil Zagoskin</p>
+ <p>
+ Own Id: OTP-11880</p>
+ </item>
+ <item>
+ <p>
+ Gracefully handle invalid alerts</p>
+ <p>
+ Own Id: OTP-11890</p>
+ </item>
+ <item>
+ <p>
+ Generalize handling of default ciphers</p>
+ <p>
+ Thanks to Andreas Schultz</p>
+ <p>
+ Own Id: OTP-11966</p>
+ </item>
+ <item>
+ <p>
+ Make sure change cipher spec is correctly handled</p>
+ <p>
+ Own Id: OTP-11975</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 5.3.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index be1041ca13..d741fa63fb 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -339,14 +339,10 @@ negotiated_next_protocol(#sslsocket{pid = Pid}) ->
ssl_connection:negotiated_next_protocol(Pid).
%%--------------------------------------------------------------------
--spec cipher_suites() -> [ssl_cipher:erl_cipher_suite()].
--spec cipher_suites(erlang | openssl | all) -> [ssl_cipher:erl_cipher_suite()] | [string()].
-
+-spec cipher_suites(erlang | openssl | all) -> [ssl_cipher:erl_cipher_suite()] |
+ [string()].
%% Description: Returns all supported cipher suites.
%%--------------------------------------------------------------------
-cipher_suites() ->
- cipher_suites(erlang).
-
cipher_suites(erlang) ->
Version = tls_record:highest_protocol_version([]),
ssl_cipher:filter_suites([suite_definition(S)
@@ -358,11 +354,14 @@ cipher_suites(openssl) ->
cipher_suites(all) ->
Version = tls_record:highest_protocol_version([]),
Supported = ssl_cipher:all_suites(Version)
- ++ ssl_cipher:anonymous_suites(Version)
+ ++ ssl_cipher:anonymous_suites()
++ ssl_cipher:psk_suites(Version)
++ ssl_cipher:srp_suites(),
ssl_cipher:filter_suites([suite_definition(S) || S <- Supported]).
+cipher_suites() ->
+ cipher_suites(erlang).
+
%%--------------------------------------------------------------------
-spec getopts(#sslsocket{}, [gen_tcp:option_name()]) ->
{ok, [gen_tcp:option()]} | {error, reason()}.
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 34006612a2..4ac4e81d9e 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -58,7 +58,10 @@
%%====================================================================
%%--------------------------------------------------------------------
-spec connect(tls_connection | dtls_connection,
- host(), inet:port_number(), port(), {#ssl_options{}, #socket_options{}},
+ host(), inet:port_number(), port(),
+ {#ssl_options{}, #socket_options{},
+ %% Tracker only needed on server side
+ undefined},
pid(), tuple(), timeout()) ->
{ok, #sslsocket{}} | {error, reason()}.
%%
@@ -73,9 +76,10 @@ connect(Connection, Host, Port, Socket, Options, User, CbInfo, Timeout) ->
end.
%%--------------------------------------------------------------------
-spec ssl_accept(tls_connection | dtls_connection,
- inet:port_number(), port(), {#ssl_options{}, #socket_options{}},
- pid(), tuple(), timeout()) ->
- {ok, #sslsocket{}} | {error, reason()}.
+ inet:port_number(), port(),
+ {#ssl_options{}, #socket_options{}, undefined | pid()},
+ pid(), tuple(), timeout()) ->
+ {ok, #sslsocket{}} | {error, reason()}.
%%
%% Description: Performs accept on an ssl listen socket. e.i. performs
%% ssl handshake.
@@ -102,7 +106,8 @@ handshake(#sslsocket{pid = Pid}, Timeout) ->
end.
%%--------------------------------------------------------------------
--spec handshake(#sslsocket{}, #ssl_options{}, timeout()) -> ok | {error, reason()}.
+-spec handshake(#sslsocket{}, {#ssl_options{},#socket_options{}},
+ timeout()) -> ok | {error, reason()}.
%%
%% Description: Starts ssl handshake with some new options
%%--------------------------------------------------------------------
@@ -322,6 +327,7 @@ abbreviated(#hello_request{}, State0, Connection) ->
abbreviated(#finished{verify_data = Data} = Finished,
#state{role = server,
negotiated_version = Version,
+ expecting_finished = true,
tls_handshake_history = Handshake,
session = #session{master_secret = MasterSecret},
connection_states = ConnectionStates0} =
@@ -334,7 +340,8 @@ abbreviated(#finished{verify_data = Data} = Finished,
ssl_record:set_client_verify_data(current_both, Data, ConnectionStates0),
Connection:next_state_connection(abbreviated,
ack_connection(
- State#state{connection_states = ConnectionStates}));
+ State#state{connection_states = ConnectionStates,
+ expecting_finished = false}));
#alert{} = Alert ->
Connection:handle_own_alert(Alert, Version, abbreviated, State)
end;
@@ -354,7 +361,7 @@ abbreviated(#finished{verify_data = Data} = Finished,
finalize_handshake(State0#state{connection_states = ConnectionStates1},
abbreviated, Connection),
Connection:next_state_connection(abbreviated,
- ack_connection(State));
+ ack_connection(State#state{expecting_finished = false}));
#alert{} = Alert ->
Connection:handle_own_alert(Alert, Version, abbreviated, State0)
end;
@@ -365,7 +372,7 @@ abbreviated(#next_protocol{selected_protocol = SelectedProtocol},
#state{role = server, expecting_next_protocol_negotiation = true} = State0,
Connection) ->
{Record, State} = Connection:next_record(State0#state{next_protocol = SelectedProtocol}),
- Connection:next_state(abbreviated, abbreviated, Record, State);
+ Connection:next_state(abbreviated, abbreviated, Record, State#state{expecting_next_protocol_negotiation = false});
abbreviated(timeout, State, _) ->
{next_state, abbreviated, State, hibernate };
@@ -589,6 +596,7 @@ cipher(#finished{verify_data = Data} = Finished,
host = Host,
port = Port,
role = Role,
+ expecting_finished = true,
session = #session{master_secret = MasterSecret}
= Session0,
connection_states = ConnectionStates0,
@@ -599,7 +607,7 @@ cipher(#finished{verify_data = Data} = Finished,
MasterSecret, Handshake0) of
verified ->
Session = register_session(Role, Host, Port, Session0),
- cipher_role(Role, Data, Session, State, Connection);
+ cipher_role(Role, Data, Session, State#state{expecting_finished = false}, Connection);
#alert{} = Alert ->
Connection:handle_own_alert(Alert, Version, cipher, State)
end;
@@ -607,7 +615,8 @@ cipher(#finished{verify_data = Data} = Finished,
%% only allowed to send next_protocol message after change cipher spec
%% & before finished message and it is not allowed during renegotiation
cipher(#next_protocol{selected_protocol = SelectedProtocol},
- #state{role = server, expecting_next_protocol_negotiation = true} = State0, Connection) ->
+ #state{role = server, expecting_next_protocol_negotiation = true,
+ expecting_finished = true} = State0, Connection) ->
{Record, State} = Connection:next_record(State0#state{next_protocol = SelectedProtocol}),
Connection:next_state(cipher, cipher, Record, State#state{expecting_next_protocol_negotiation = false});
@@ -1034,9 +1043,6 @@ server_hello_done(State, Connection) ->
HelloDone = ssl_handshake:server_hello_done(),
Connection:send_handshake(HelloDone, State).
-
-
-
handle_peer_cert(Role, PeerCert, PublicKeyInfo,
#state{session = #session{cipher_suite = CipherSuite} = Session} = State0,
Connection) ->
diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl
index 592889b177..c544a0591f 100644
--- a/lib/ssl/src/ssl_connection.hrl
+++ b/lib/ssl/src/ssl_connection.hrl
@@ -77,6 +77,7 @@
terminated = false ::boolean(),
allow_renegotiate = true ::boolean(),
expecting_next_protocol_negotiation = false ::boolean(),
+ expecting_finished = false ::boolean(),
next_protocol = undefined :: undefined | binary(),
client_ecc, % {Curves, PointFmt}
tracker :: pid() %% Tracker process for listen socket
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index fc67d2c28d..b018332df1 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1719,6 +1719,11 @@ dec_hello_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len),
dec_hello_extensions(Rest, Acc#hello_extensions{ec_point_formats =
#ec_point_formats{ec_point_format_list =
ECPointFormats}});
+
+dec_hello_extensions(<<?UINT16(?SNI_EXT), ?UINT16(Len),
+ ExtData:Len/binary, Rest/binary>>, Acc) ->
+ <<?UINT16(_), NameList/binary>> = ExtData,
+ dec_hello_extensions(Rest, Acc#hello_extensions{sni = dec_sni(NameList)});
%% Ignore data following the ClientHello (i.e.,
%% extensions) if not understood.
@@ -1731,6 +1736,13 @@ dec_hello_extensions(_, Acc) ->
dec_hashsign(<<?BYTE(HashAlgo), ?BYTE(SignAlgo)>>) ->
{ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}.
+%% Ignore unknown names (only host_name is supported)
+dec_sni(<<?BYTE(?SNI_NAMETYPE_HOST_NAME), ?UINT16(Len),
+ HostName:Len/binary, _/binary>>) ->
+ #sni{hostname = binary_to_list(HostName)};
+dec_sni(<<?BYTE(_), ?UINT16(Len), _:Len, Rest/binary>>) -> dec_sni(Rest);
+dec_sni(_) -> undefined.
+
decode_next_protocols({next_protocol_negotiation, Protocols}) ->
decode_next_protocols(Protocols, []).
decode_next_protocols(<<>>, Acc) ->
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index fbc73e0e42..d6e5064c39 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -52,8 +52,8 @@
last_delay_timer = {undefined, undefined}%% Keep for testing purposes
}).
--define('24H_in_msec', 8640000).
--define('24H_in_sec', 8640).
+-define('24H_in_msec', 86400000).
+-define('24H_in_sec', 86400).
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
-define(SESSION_VALIDATION_INTERVAL, 60000).
-define(CLEAR_PEM_CACHE, 120000).
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 2ab085321a..26de51985a 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -444,12 +444,16 @@ next_state(_, StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, St
next_state(StateName, StateName, Record, State)
end;
next_state(Current, Next, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} =
- _ChangeCipher,
- #state{connection_states = ConnectionStates0} = State0) ->
+ _ChangeCipher,
+ #state{connection_states = ConnectionStates0} = State0)
+ when Next == cipher; Next == abbreviated ->
ConnectionStates1 =
ssl_record:activate_pending_connection_state(ConnectionStates0, read),
{Record, State} = next_record(State0#state{connection_states = ConnectionStates1}),
- next_state(Current, Next, Record, State);
+ next_state(Current, Next, Record, State#state{expecting_finished = true});
+next_state(Current, _Next, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} =
+ _ChangeCipher, #state{negotiated_version = Version} = State) ->
+ handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Version, Current, State);
next_state(Current, Next, #ssl_tls{type = _Unknown}, State0) ->
%% Ignore unknown type
{Record, State} = next_record(State0),
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 2f440f1f3c..1da4e88077 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -1371,6 +1371,7 @@ tcp_connect_big() ->
[{doc,"Test what happens when a tcp tries to connect, i,e. a bad big (ssl) packet is sent first"}].
tcp_connect_big(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
ServerOpts = ?config(server_opts, Config),
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
TcpOpts = [binary, {reuseaddr, true}],
@@ -1396,7 +1397,9 @@ tcp_connect_big(Config) when is_list(Config) ->
{Server, {error, timeout}} ->
ct:fail("hangs");
{Server, {error, Error}} ->
- ct:log("Error ~p", [Error])
+ ct:log("Error ~p", [Error]);
+ {'EXIT', Server, _} ->
+ ok
end
end.
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index 5f36842f9e..e5e942ce1b 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -38,6 +38,7 @@ all() -> [decode_hello_handshake,
decode_supported_elliptic_curves_hello_extension_correctly,
decode_unknown_hello_extension_correctly,
encode_single_hello_sni_extension_correctly,
+ decode_single_hello_sni_extension_correctly,
select_proper_tls_1_2_rsa_default_hashsign].
%%--------------------------------------------------------------------
@@ -98,6 +99,13 @@ encode_single_hello_sni_extension_correctly(_Config) ->
Encoded = ssl_handshake:encode_hello_extensions(Exts),
HelloExt = Encoded.
+decode_single_hello_sni_extension_correctly(_Config) ->
+ Exts = #hello_extensions{sni = #sni{hostname = "test.com"}},
+ SNI = <<16#00, 16#00, 16#00, 16#0d, 16#00, 16#0b, 16#00, 16#00, 16#08,
+ $t, $e, $s, $t, $., $c, $o, $m>>,
+ Decoded = ssl_handshake:decode_hello_extensions(SNI),
+ Exts = Decoded.
+
select_proper_tls_1_2_rsa_default_hashsign(_Config) ->
% RFC 5246 section 7.4.1.4.1 tells to use {sha1,rsa} as default signature_algorithm for RSA key exchanges
{sha, rsa} = ssl_handshake:select_hashsign_algs(undefined, ?rsaEncryption, {3,3}),
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index 1713367bd8..848d57f3e6 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -115,7 +115,7 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
If <c>FsmName={global,GlobalName}</c>, the gen_fsm is
registered globally as <c>GlobalName</c> using
<c>global:register_name/2</c>.
- If <c>EventMgrName={via,Module,ViaName}</c>, the event manager will
+ If <c>FsmName={via,Module,ViaName}</c>, the gen_fsm will
register with the registry represented by <c>Module</c>.
The <c>Module</c> callback should export the functions
<c>register_name/2</c>, <c>unregister_name/1</c>,
@@ -210,7 +210,7 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
registered at another node, or</item>
<item><c>{global,GlobalName}</c>, if the gen_fsm is globally
registered.</item>
- <item><c>{via,Module,ViaName}</c>, if the event manager is registered
+ <item><c>{via,Module,ViaName}</c>, if the gen_fsm is registered
through an alternative process registry.</item>
</list>
<p><c>Event</c> is an arbitrary term which is passed as one of
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index 4c83fde237..62c0394479 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.xml
@@ -113,7 +113,7 @@ gen_server:abcast -----> Module:handle_cast/2
registered globally as <c>GlobalName</c> using
<c>global:register_name/2</c>. If no name is provided,
the gen_server is not registered.
- If <c>EventMgrName={via,Module,ViaName}</c>, the event manager will
+ If <c>ServerName={via,Module,ViaName}</c>, the gen_server will
register with the registry represented by <c>Module</c>.
The <c>Module</c> callback should export the functions
<c>register_name/2</c>, <c>unregister_name/1</c>,
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index 15e6fdfa9f..5e74616099 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -30,6 +30,106 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 2.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ OTP-11850 fixed filelib:wildcard/1 to work with broken
+ symlinks. This correction, however, introduced problems
+ since symlinks were no longer followed for functions like
+ filelib:ensure_dir/1, filelib:is_dir/1,
+ filelib:file_size/1, etc. This is now corrected.</p>
+ <p>
+ Own Id: OTP-12054 Aux Id: seq12660 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p><c>filelib:wildcard("broken_symlink")</c> would return
+ an empty list if "broken_symlink" was a symlink that did
+ not point to an existing file.</p>
+ <p>
+ Own Id: OTP-11850 Aux Id: seq12571 </p>
+ </item>
+ <item>
+ <p><c>erl_tar</c> can now handle files names that contain
+ Unicode characters. See "UNICODE SUPPORT" in the
+ documentation for <c>erl_tar</c>.</p>
+ <p>When creating a tar file, <c>erl_tar</c> would
+ sometime write a too short end of tape marker. GNU tar
+ would correctly extract files from such tar file, but
+ would complain about "A lone zero block at...".</p>
+ <p>
+ Own Id: OTP-11854</p>
+ </item>
+ <item>
+ <p> When redefining and exporting the type <c>map()</c>
+ the Erlang Code Linter (<c>erl_lint</c>) erroneously
+ emitted an error. This bug has been fixed. </p>
+ <p>
+ Own Id: OTP-11872</p>
+ </item>
+ <item>
+ <p>
+ Fix evaluation of map updates in the debugger and
+ erl_eval</p>
+ <p>
+ Reported-by: José Valim</p>
+ <p>
+ Own Id: OTP-11922</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The following native functions now bump an appropriate
+ amount of reductions and yield when out of
+ reductions:</p> <list>
+ <item><c>erlang:binary_to_list/1</c></item>
+ <item><c>erlang:binary_to_list/3</c></item>
+ <item><c>erlang:bitstring_to_list/1</c></item>
+ <item><c>erlang:list_to_binary/1</c></item>
+ <item><c>erlang:iolist_to_binary/1</c></item>
+ <item><c>erlang:list_to_bitstring/1</c></item>
+ <item><c>binary:list_to_bin/1</c></item> </list>
+ <p>Characteristics impact:</p> <taglist>
+ <tag>Performance</tag> <item>The functions converting
+ from lists got a performance loss for very small lists,
+ and a performance gain for very large lists.</item>
+ <tag>Priority</tag> <item>Previously a process executing
+ one of these functions effectively got an unfair priority
+ boost. This priority boost depended on the input size.
+ The larger the input was, the larger the priority boost
+ got. This unfair priority boost is now lost. </item>
+ </taglist>
+ <p>
+ Own Id: OTP-11888</p>
+ </item>
+ <item>
+ <p>
+ Add <c>maps:get/3</c> to maps module. The function will
+ return the supplied default value if the key does not
+ exist in the map.</p>
+ <p>
+ Own Id: OTP-11951</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 2.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -343,10 +443,10 @@
"hello"}, % add new associations</c></item> <item><c>#{
"hi" := V1, a := V2, b := V3} = M2. % match keys with
values</c></item> </taglist></p>
- <p>
- For information on how to use Maps please see the
- <seealso marker="doc/reference_manual:maps">Reference
- Manual</seealso>.</p>
+ <p>
+ For information on how to use Maps please see Map Expressions in the
+ <seealso marker="doc/reference_manual:expressions#map_expressions">
+ Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
features: <taglist> <item>No variable keys</item>
@@ -2193,7 +2293,7 @@
platforms than before. If <c>configure</c> warns about no
atomic implementation available, try using the
<c>libatomic_ops</c> library. Use the <seealso
- marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--with-libatomic_ops=PATH</seealso>
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP">--with-libatomic_ops=PATH</seealso>
<c>configure</c> command line argument when specifying
where the <c>libatomic_ops</c> installation is located.
The <c>libatomic_ops</c> library can be downloaded from:
@@ -2211,7 +2311,7 @@
the pentium 4 processor. If you want the runtime system
to be compatible with older processors (back to 486) you
need to pass the <seealso
- marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--enable-ethread-pre-pentium4-compatibility</seealso>
+ marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP">--enable-ethread-pre-pentium4-compatibility</seealso>
<c>configure</c> command line argument when configuring
the system.</p>
<p>
diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml
index a46fa1289f..19605f325b 100644
--- a/lib/stdlib/doc/src/sys.xml
+++ b/lib/stdlib/doc/src/sys.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -115,6 +115,9 @@
<datatype>
<name name="dbg_fun"/>
</datatype>
+ <datatype>
+ <name name="format_fun"/>
+ </datatype>
</datatypes>
<funcs>
<func>
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index c32da1624f..76e03bbfaa 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -440,9 +440,10 @@ insert(Tab, Objs) when is_list(Objs) ->
insert(Tab, Obj) ->
badarg(treq(Tab, {insert, [Obj]}), [Tab, Obj]).
--spec insert_new(Name, Objects) -> boolean() when
+-spec insert_new(Name, Objects) -> boolean() | {'error', Reason} when
Name :: tab_name(),
- Objects :: object() | [object()].
+ Objects :: object() | [object()],
+ Reason :: term().
insert_new(Tab, Objs) when is_list(Objs) ->
badarg(treq(Tab, {insert_new, Objs}), [Tab, Objs]);
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 9b506b0a44..5f8637c118 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1121,8 +1121,20 @@ skip_toks(From, St, [I|Sis]) ->
skip_toks(From, St#epp{location=Cl}, Sis);
{ok,_Toks,Cl} ->
skip_toks(From, St#epp{location=Cl}, [I|Sis]);
- {error,_E,Cl} ->
- skip_toks(From, St#epp{location=Cl}, [I|Sis]);
+ {error,E,Cl} ->
+ case E of
+ {_,file_io_server,invalid_unicode} ->
+ %% The compiler needs to know that there was
+ %% invalid unicode characters in the file
+ %% (and there is no point in continuing anyway
+ %% since io server process has terminated).
+ epp_reply(From, {error,E}),
+ leave_file(wait_request(St), St);
+ _ ->
+ %% Some other invalid token, such as a bad floating
+ %% point number. Just ignore it.
+ skip_toks(From, St#epp{location=Cl}, [I|Sis])
+ end;
{eof,Cl} ->
leave_file(From, St#epp{location=Cl,istk=[I|Sis]});
{error,_E} ->
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 3cfedfee97..639ddfc214 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -77,7 +77,7 @@
%% Only exprs/2 checks the command by calling erl_lint. The reason is
%% that if there is a function handler present, then it is possible
%% that there are valid constructs in Expression to be taken care of
-%% by a function handler but considerad errors by erl_lint.
+%% by a function handler but considered errors by erl_lint.
-spec(exprs(Expressions, Bindings) -> {value, Value, NewBindings} when
Expressions :: expressions(),
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index 57e768ba9d..c74f68647f 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,6 +38,8 @@
checked_ra=[] % successfully accessed records
}).
+-define(REC_OFFSET, 100000000). % A hundred millions. Also in v3_core.
+
-spec(module(AbsForms, CompileOptions) -> AbsForms when
AbsForms :: [erl_parse:abstract_form()],
CompileOptions :: [compile:option()]).
@@ -144,10 +146,11 @@ pattern({map_field_exact,Line,K0,V0}, St0) ->
%% {{struct,Line,Tag,TPs},TPsvs,St1};
pattern({record_index,Line,Name,Field}, St) ->
{index_expr(Line, Field, Name, record_fields(Name, St)),St};
-pattern({record,Line,Name,Pfs}, St0) ->
+pattern({record,Line0,Name,Pfs}, St0) ->
Fs = record_fields(Name, St0),
{TMs,St1} = pattern_list(pattern_fields(Fs, Pfs), St0),
- {{tuple,Line,[{atom,Line,Name} | TMs]},St1};
+ Line = record_offset(Line0, St1),
+ {{tuple,Line,[{atom,Line0,Name} | TMs]},St1};
pattern({bin,Line,Es0}, St0) ->
{Es1,St1} = pattern_bin(Es0, St0),
{{bin,Line,Es1},St1};
@@ -329,8 +332,9 @@ expr({map_field_exact,Line,K0,V0}, St0) ->
expr({record_index,Line,Name,F}, St) ->
I = index_expr(Line, F, Name, record_fields(Name, St)),
expr(I, St);
-expr({record,Line,Name,Is}, St) ->
- expr({tuple,Line,[{atom,Line,Name} |
+expr({record,Line0,Name,Is}, St) ->
+ Line = record_offset(Line0, St),
+ expr({tuple,Line,[{atom,Line0,Name} |
record_inits(record_fields(Name, St), Is)]},
St);
expr({record_field,Line,R,Name,F}, St) ->
@@ -582,8 +586,9 @@ strict_get_record_field(Line, R, {atom,_,F}=Index, Name, St0) ->
I = index_expr(F, Fs, 2),
P = record_pattern(2, I, Var, length(Fs)+1, Line, [{atom,Line,Name}]),
NLine = neg_line(Line),
+ RLine = record_offset(NLine, St),
E = {'case',NLine,R,
- [{clause,NLine,[{tuple,NLine,P}],[],[Var]},
+ [{clause,NLine,[{tuple,RLine,P}],[],[Var]},
{clause,NLine,[{var,NLine,'_'}],[],
[{call,NLine,{remote,NLine,
{atom,NLine,erlang},
@@ -836,7 +841,7 @@ optimize_is_record(H0, G0, #exprec{compile=Opts}) ->
[] ->
{H0,G0};
Rs0 ->
- case lists:member(no_is_record_optimization, Opts) of
+ case lists:member(dialyzer, Opts) of % no_is_record_optimization
true ->
{H0,G0};
false ->
@@ -961,3 +966,10 @@ opt_remove_2(A, _) -> A.
neg_line(L) ->
erl_parse:set_line(L, fun(Line) -> -abs(Line) end).
+
+record_offset(L, St) ->
+ case lists:member(dialyzer, St#exprec.compile) of
+ true when L >= 0 -> L+?REC_OFFSET;
+ true when L < 0 -> L-?REC_OFFSET;
+ false -> L
+ end.
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index c0921e4cf1..9efbe8da20 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -265,7 +265,7 @@ do_wildcard(Pattern, Cwd, Mod) ->
lists:sort(Files).
do_wildcard_1({exists,File}, Mod) ->
- case eval_read_file_info(File, Mod) of
+ case eval_read_link_info(File, Mod) of
{ok,_} -> [File];
_ -> []
end;
@@ -488,7 +488,7 @@ badpattern(Reason) ->
error({badpattern,Reason}).
eval_read_file_info(File, file) ->
- file:read_link_info(File);
+ file:read_file_info(File);
eval_read_file_info(File, erl_prim_loader) ->
case erl_prim_loader:read_file_info(File) of
error -> {error, erl_prim_loader};
@@ -497,6 +497,16 @@ eval_read_file_info(File, erl_prim_loader) ->
eval_read_file_info(File, Mod) ->
Mod:read_file_info(File).
+eval_read_link_info(File, file) ->
+ file:read_link_info(File);
+eval_read_link_info(File, erl_prim_loader) ->
+ case erl_prim_loader:read_link_info(File) of
+ error -> {error, erl_prim_loader};
+ Res-> Res
+ end;
+eval_read_link_info(File, Mod) ->
+ Mod:read_link_info(File).
+
eval_list_dir(Dir, file) ->
file:list_dir(Dir);
eval_list_dir(Dir, erl_prim_loader) ->
diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl
index 56e15a17ec..89ae6fb187 100644
--- a/lib/stdlib/src/io_lib_format.erl
+++ b/lib/stdlib/src/io_lib_format.erl
@@ -255,7 +255,7 @@ term(T, none, _Adj, none, _Pad) -> T;
term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad);
term(T, F, Adj, P0, Pad) ->
L = lists:flatlength(T),
- P = case P0 of none -> erlang:min(L, F); _ -> P0 end,
+ P = erlang:min(L, case P0 of none -> F; _ -> min(P0, F) end),
if
L > P ->
adjust(chars($*, P), chars(Pad, F-P), Adj);
diff --git a/lib/stdlib/src/maps.erl b/lib/stdlib/src/maps.erl
index 4ef1638e6d..3f019aa35a 100644
--- a/lib/stdlib/src/maps.erl
+++ b/lib/stdlib/src/maps.erl
@@ -133,10 +133,10 @@ to_list(_) -> erlang:nif_error(undef).
update(_,_,_) -> erlang:nif_error(undef).
--spec values(Map) -> Keys when
+-spec values(Map) -> Values when
Map :: map(),
- Keys :: [Key],
- Key :: term().
+ Values :: [Value],
+ Value :: term().
values(_) -> erlang:nif_error(undef).
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index 3b90542452..679c13f0cf 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -371,6 +371,14 @@ expand_expr({bc,L,E,Qs}, C) ->
{bc,L,expand_expr(E, C),expand_quals(Qs, C)};
expand_expr({tuple,L,Elts}, C) ->
{tuple,L,expand_exprs(Elts, C)};
+expand_expr({map,L,Es}, C) ->
+ {map,L,expand_exprs(Es, C)};
+expand_expr({map,L,Arg,Es}, C) ->
+ {map,L,expand_expr(Arg, C),expand_exprs(Es, C)};
+expand_expr({map_field_assoc,L,K,V}, C) ->
+ {map_field_assoc,L,expand_expr(K, C),expand_expr(V, C)};
+expand_expr({map_field_exact,L,K,V}, C) ->
+ {map_field_exact,L,expand_expr(K, C),expand_expr(V, C)};
expand_expr({record_index,L,Name,F}, C) ->
{record_index,L,Name,expand_expr(F, C)};
expand_expr({record,L,Name,Is}, C) ->
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index d388410de0..3585eec342 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -103,7 +103,7 @@
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-2.4","kernel-3.0","erts-6.0","crypto-3.3",
+ {runtime_dependencies, ["sasl-2.4","kernel-3.0.2","erts-6.1.2","crypto-3.3",
"compiler-5.0"]}
]}.
diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src
index 22eefb2514..99d9b8b431 100644
--- a/lib/stdlib/src/stdlib.appup.src
+++ b/lib/stdlib/src/stdlib.appup.src
@@ -17,9 +17,11 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
+ [{<<"2\\.1(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1
+ {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0
{<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
%% Down to - max one major revision back
- [{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
+ [{<<"2\\.1(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1
+ {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0
{<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
}.
diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl
index e25cc25f57..d3ba09ce82 100644
--- a/lib/stdlib/src/sys.erl
+++ b/lib/stdlib/src/sys.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -46,7 +46,7 @@
{N :: non_neg_integer(),
[{Event :: system_event(),
FuncState :: _,
- FormFunc :: dbg_fun()}]}}
+ FormFunc :: format_fun()}]}}
| {'statistics', {file:date_time(),
{'reductions', non_neg_integer()},
MessagesIn :: non_neg_integer(),
@@ -57,6 +57,10 @@
Event :: system_event(),
ProcState :: _) -> 'done' | (NewFuncState :: _)).
+-type format_fun() :: fun((Device :: io:device() | file:io_device(),
+ Event :: system_event(),
+ Extra :: term()) -> any()).
+
%%-----------------------------------------------------------------
%% System messages
%%-----------------------------------------------------------------
@@ -346,7 +350,7 @@ handle_system_msg(SysState, Msg, From, Parent, Mod, Debug, Misc, Hib) ->
%%-----------------------------------------------------------------
-spec handle_debug(Debug, FormFunc, Extra, Event) -> [dbg_opt()] when
Debug :: [dbg_opt()],
- FormFunc :: dbg_fun(),
+ FormFunc :: format_fun(),
Extra :: term(),
Event :: system_event().
handle_debug([{trace, true} | T], FormFunc, State, Event) ->
diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl
index 6be37cbecf..119b4dc7cb 100644
--- a/lib/stdlib/test/dets_SUITE.erl
+++ b/lib/stdlib/test/dets_SUITE.erl
@@ -2032,6 +2032,12 @@ match(Config, Version) ->
CrashPos = if Version =:= 8 -> 5; Version =:= 9 -> 1 end,
crash(Fname, ObjPos2+CrashPos),
{ok, _} = dets:open_file(T, Args),
+ case dets:insert_new(T, Obj) of % OTP-12024
+ ok ->
+ bad_object(dets:sync(T), Fname);
+ Else3 ->
+ bad_object(Else3, Fname)
+ end,
io:format("Expect corrupt table:~n"),
case ins(T, N) of
ok ->
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index 8203a03a7a..040ae1effc 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,8 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
wildcard_one/1,wildcard_two/1,wildcard_errors/1,
- fold_files/1,otp_5960/1,ensure_dir_eexist/1,symlinks/1]).
+ fold_files/1,otp_5960/1,ensure_dir_eexist/1,ensure_dir_symlink/1,
+ wildcard_symlink/1, is_file_symlink/1, file_props_symlink/1]).
-import(lists, [foreach/2]).
@@ -43,7 +44,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[wildcard_one, wildcard_two, wildcard_errors,
- fold_files, otp_5960, ensure_dir_eexist, symlinks].
+ fold_files, otp_5960, ensure_dir_eexist, ensure_dir_symlink,
+ wildcard_symlink, is_file_symlink, file_props_symlink].
groups() ->
[].
@@ -367,9 +369,28 @@ ensure_dir_eexist(Config) when is_list(Config) ->
?line {error, eexist} = filelib:ensure_dir(NeedFileB),
ok.
-symlinks(Config) when is_list(Config) ->
+ensure_dir_symlink(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
- Dir = filename:join(PrivDir, ?MODULE_STRING++"_symlinks"),
+ Dir = filename:join(PrivDir, "ensure_dir_symlink"),
+ Name = filename:join(Dir, "same_name_as_file_and_dir"),
+ ok = filelib:ensure_dir(Name),
+ ok = file:write_file(Name, <<"some string\n">>),
+ %% With a symlink to the directory.
+ Symlink = filename:join(PrivDir, "ensure_dir_symlink_link"),
+ case file:make_symlink(Dir, Symlink) of
+ {error,enotsup} ->
+ {skip,"Symlinks not supported on this platform"};
+ {error,eperm} ->
+ {win32,_} = os:type(),
+ {skip,"Windows user not privileged to create symlinks"};
+ ok ->
+ SymlinkedName = filename:join(Symlink, "same_name_as_file_and_dir"),
+ ok = filelib:ensure_dir(SymlinkedName)
+ end.
+
+wildcard_symlink(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Dir = filename:join(PrivDir, ?MODULE_STRING++"_wildcard_symlink"),
SubDir = filename:join(Dir, "sub"),
AFile = filename:join(SubDir, "a_file"),
Alias = filename:join(Dir, "symlink"),
@@ -387,6 +408,18 @@ symlinks(Config) when is_list(Config) ->
basenames(Dir, filelib:wildcard(filename:join(Dir, "*"))),
["symlink"] =
basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"))),
+ ["sub","symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "*"),
+ erl_prim_loader)),
+ ["symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"),
+ erl_prim_loader)),
+ ["sub","symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "*"),
+ prim_file)),
+ ["symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"),
+ prim_file)),
ok = file:delete(AFile),
%% The symlink should still be visible even when its target
%% has been deleted.
@@ -394,6 +427,18 @@ symlinks(Config) when is_list(Config) ->
basenames(Dir, filelib:wildcard(filename:join(Dir, "*"))),
["symlink"] =
basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"))),
+ ["sub","symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "*"),
+ erl_prim_loader)),
+ ["symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"),
+ erl_prim_loader)),
+ ["sub","symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "*"),
+ prim_file)),
+ ["symlink"] =
+ basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"),
+ prim_file)),
ok
end.
@@ -402,3 +447,60 @@ basenames(Dir, Files) ->
Dir = filename:dirname(F),
filename:basename(F)
end || F <- Files].
+
+is_file_symlink(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Dir = filename:join(PrivDir, ?MODULE_STRING++"_is_file_symlink"),
+ SubDir = filename:join(Dir, "sub"),
+ AFile = filename:join(SubDir, "a_file"),
+ DirAlias = filename:join(Dir, "dir_symlink"),
+ FileAlias = filename:join(Dir, "file_symlink"),
+ ok = file:make_dir(Dir),
+ ok = file:make_dir(SubDir),
+ ok = file:write_file(AFile, "not that big\n"),
+ case file:make_symlink(SubDir, DirAlias) of
+ {error, enotsup} ->
+ {skip, "Links not supported on this platform"};
+ {error, eperm} ->
+ {win32,_} = os:type(),
+ {skip, "Windows user not privileged to create symlinks"};
+ ok ->
+ true = filelib:is_dir(DirAlias),
+ true = filelib:is_dir(DirAlias, erl_prim_loader),
+ true = filelib:is_dir(DirAlias, prim_file),
+ true = filelib:is_file(DirAlias),
+ true = filelib:is_file(DirAlias, erl_prim_loader),
+ true = filelib:is_file(DirAlias, prim_file),
+ ok = file:make_symlink(AFile,FileAlias),
+ true = filelib:is_file(FileAlias),
+ true = filelib:is_file(FileAlias, erl_prim_loader),
+ true = filelib:is_file(FileAlias, prim_file),
+ true = filelib:is_regular(FileAlias),
+ true = filelib:is_regular(FileAlias, erl_prim_loader),
+ true = filelib:is_regular(FileAlias, prim_file),
+ ok
+ end.
+
+file_props_symlink(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Dir = filename:join(PrivDir, ?MODULE_STRING++"_file_props_symlink"),
+ AFile = filename:join(Dir, "a_file"),
+ Alias = filename:join(Dir, "symlink"),
+ ok = file:make_dir(Dir),
+ ok = file:write_file(AFile, "not that big\n"),
+ case file:make_symlink(AFile, Alias) of
+ {error, enotsup} ->
+ {skip, "Links not supported on this platform"};
+ {error, eperm} ->
+ {win32,_} = os:type(),
+ {skip, "Windows user not privileged to create symlinks"};
+ ok ->
+ {_,_} = LastMod = filelib:last_modified(AFile),
+ LastMod = filelib:last_modified(Alias),
+ LastMod = filelib:last_modified(Alias, erl_prim_loader),
+ LastMod = filelib:last_modified(Alias, prim_file),
+ FileSize = filelib:file_size(AFile),
+ FileSize = filelib:file_size(Alias),
+ FileSize = filelib:file_size(Alias, erl_prim_loader),
+ FileSize = filelib:file_size(Alias, prim_file)
+ end.
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 5a8971c071..3a76275f31 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -30,7 +30,7 @@
io_fread_newlines/1, otp_8989/1, io_lib_fread_literal/1,
printable_range/1,
io_lib_print_binary_depth_one/1, otp_10302/1, otp_10755/1,
- otp_10836/1]).
+ otp_10836/1, io_lib_width_too_small/1]).
-export([pretty/2]).
@@ -69,7 +69,8 @@ all() ->
io_lib_collect_line_3_wb, cr_whitespace_in_string,
io_fread_newlines, otp_8989, io_lib_fread_literal,
printable_range,
- io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836].
+ io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836,
+ io_lib_width_too_small].
groups() ->
[].
@@ -2213,3 +2214,8 @@ compile_file(File, Text, Config) ->
try compile:file(Fname, [return])
after ok %file:delete(Fname)
end.
+
+io_lib_width_too_small(Config) ->
+ "**" = lists:flatten(io_lib:format("~2.3w", [3.14])),
+ "**" = lists:flatten(io_lib:format("~2.5w", [3.14])),
+ ok.
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index e016432f4d..f841e2c4a6 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -2532,6 +2532,11 @@ otp_6554(Config) when is_list(Config) ->
"\n end.\nok.\n" =
t(<<"begin F = fun() -> foo end, 1 end. B = F(). C = 17. b().">>),
+ ?line "3: command not found" = comm_err(<<"#{v(3) => v}.">>),
+ ?line "3: command not found" = comm_err(<<"#{k => v(3)}.">>),
+ ?line "3: command not found" = comm_err(<<"#{v(3) := v}.">>),
+ ?line "3: command not found" = comm_err(<<"#{k := v(3)}.">>),
+ ?line "3: command not found" = comm_err(<<"(v(3))#{}.">>),
%% Tests I'd like to do: (you should try them manually)
%% "catch spawn_link(fun() -> timer:sleep(1000), exit(foo) end)."
%% "** exception error: foo" should be output after 1 second
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index 37a6590b06..9881ab040e 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 2.0
+STDLIB_VSN = 2.1.1
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 4e1e6d8cb1..8384af53b0 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -31,6 +31,45 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 1.6.16</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The default encoding for Erlang source files is now
+ UTF-8. As a temporary measure to ease the transition from
+ the old default of Latin-1, if EDoc encounters byte
+ sequences that are not valid UTF-8 sequences, EDoc will
+ re-try in Latin-1 mode. This workaround will be removed
+ in a future release. </p>
+ <p>
+ Own Id: OTP-12008</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Syntax_Tools 1.6.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix reverting map in syntax_tools</p>
+ <p>
+ There was a bug in erl_syntax when running e.g.
+ erl_syntax:revert_forms, affecting maps. Instead of
+ getting Key/Value you got Key/Key in the resulting
+ abstract form.</p>
+ <p>
+ Own Id: OTP-11930</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Syntax_Tools 1.6.14</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 131be4e8e4..7e12eab1b5 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -184,9 +184,27 @@ quick_parse_file(File, Options) ->
parse_file(File, fun quick_parse/3, Options ++ [no_fail]).
parse_file(File, Parser, Options) ->
+ case do_parse_file(utf8, File, Parser, Options) of
+ {ok, Forms}=Ret ->
+ case find_invalid_unicode(Forms) of
+ none ->
+ Ret;
+ invalid_unicode ->
+ case epp:read_encoding(File) of
+ utf8 ->
+ Ret;
+ _ ->
+ do_parse_file(latin1, File, Parser, Options)
+ end
+ end;
+ Else ->
+ Else
+ end.
+
+do_parse_file(DefEncoding, File, Parser, Options) ->
case file:open(File, [read]) of
{ok, Dev} ->
- _ = epp:set_encoding(Dev),
+ _ = epp:set_encoding(Dev, DefEncoding),
try Parser(Dev, 1, Options)
after ok = file:close(Dev)
end;
@@ -194,6 +212,14 @@ parse_file(File, Parser, Options) ->
Error
end.
+find_invalid_unicode([H|T]) ->
+ case H of
+ {error, {_Line, file_io_server, invalid_unicode}} ->
+ invalid_unicode;
+ _Other ->
+ find_invalid_unicode(T)
+ end;
+find_invalid_unicode([]) -> none.
%% =====================================================================
%% @spec parse(IODevice) -> {ok, Forms} | {error, errorinfo()}
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index dae7530ce7..03429d4d42 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -72,13 +72,24 @@ file(Name) ->
{ok, V} ->
case V of
{ok, B} ->
- Enc = case epp:read_encoding(Name) of
+ Encoding = epp:read_encoding_from_binary(B),
+ Enc = case Encoding of
none -> epp:default_encoding();
Enc0 -> Enc0
end,
case catch unicode:characters_to_list(B, Enc) of
String when is_list(String) ->
string(String);
+ R when Encoding =:= none ->
+ case
+ catch unicode:characters_to_list(B, latin1)
+ of
+ String when is_list(String) ->
+ string(String);
+ _ ->
+ error_read_file(Name1),
+ exit(R)
+ end;
R ->
error_read_file(Name1),
exit(R)
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index cf396ce636..6a80734f83 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 1.6.14
+SYNTAX_TOOLS_VSN = 1.6.16
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index 556fe94a2a..a801a87725 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -32,6 +32,45 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The mechanism for running code cover analysis with
+ common_test has been improved. Earlier, if a test run
+ consisted of multiple tests, cover would be started and
+ stopped for each test. This would give "intermediate"
+ cover logs available from the "Coverage log" link on the
+ test suite result pages. To accumulate cover data over
+ all tests, the 'export' option had to be used in the
+ cover spec file. This was not well documented, and the
+ functionality was quite confusing.</p>
+ <p>
+ Using the 'nodes' option in the cover spec file would
+ fail when the test run consisted of multiple tests, since
+ the specified nodes would only be included in the cover
+ analysis of the first test.</p>
+ <p>
+ The repeated compilation and analysis of the same modules
+ was also very time consuming.</p>
+ <p>
+ To overcome these problems, ct will now only cover
+ compile and analyze modules once per test run, i.e. once
+ for each cover spec file. The log file is available via a
+ new button on the top level index page. The old "Coverage
+ log" links on the test suite result pages still exist,
+ but they all point to the same log containing the
+ accumulated result.</p>
+ <p>
+ Own Id: OTP-11971</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 70dc7a1441..9192a76a17 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -22,7 +22,7 @@
%%% TEST_SERVER_CTRL INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([run_test_case_apply/1,init_target_info/0,init_purify/0]).
--export([cover_compile/1,cover_analyse/3]).
+-export([cover_compile/1,cover_analyse/2]).
%%% TEST_SERVER_SUP INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([get_loc/1,set_tc_state/1]).
@@ -80,8 +80,8 @@ init_purify() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% cover_compile({App,Include,Exclude,Cross}) ->
-%% {ok,AnalyseModules} | {error,Reason}
+%% cover_compile(#cover{app=App,incl=Include,excl=Exclude,cross=Cross}) ->
+%% {ok,#cover{mods=AnalyseModules}} | {error,Reason}
%%
%% App = atom() , name of application to be compiled
%% Exclude = [atom()], list of modules to exclude
@@ -90,33 +90,35 @@ init_purify() ->
%% Cross = [atoms()], list of modules outside of App shat should be included
%% in the cover compilation, but that shall not be part of
%% the cover analysis for this application.
+%% AnalyseModules = [atom()], list of successfully compiled modules
%%
-%% Cover compile the given application. Return {ok,AnalyseMods} if application
-%% is found, else {error,application_not_found}.
+%% Cover compile the given application. Return {ok,CoverInfo} if
+%% compilation succeeds, else (if application is not found and there
+%% are no modules to compile) {error,application_not_found}.
-cover_compile({none,_Exclude,Include,Cross}) ->
+cover_compile(CoverInfo=#cover{app=none,incl=Include,cross=Cross}) ->
CrossMods = lists:flatmap(fun({_,M}) -> M end,Cross),
CompileMods = Include++CrossMods,
case length(CompileMods) of
0 ->
io:fwrite("WARNING: No modules to cover compile!\n\n",[]),
cover:start(), % start cover server anyway
- {ok,[]};
+ {ok,CoverInfo#cover{mods=[]}};
N ->
io:fwrite("Cover compiling ~w modules - "
"this may take some time... ",[N]),
do_cover_compile(CompileMods),
io:fwrite("done\n\n",[]),
- {ok,Include}
+ {ok,CoverInfo#cover{mods=Include}}
end;
-cover_compile({App,all,Include,Cross}) ->
+cover_compile(CoverInfo=#cover{app=App,excl=all,incl=Include,cross=Cross}) ->
CrossMods = lists:flatmap(fun({_,M}) -> M end,Cross),
CompileMods = Include++CrossMods,
case length(CompileMods) of
0 ->
io:fwrite("WARNING: No modules to cover compile!\n\n",[]),
cover:start(), % start cover server anyway
- {ok,[]};
+ {ok,CoverInfo#cover{mods=[]}};
N ->
io:fwrite("Cover compiling '~w' (~w files) - "
"this may take some time... ",[App,N]),
@@ -126,9 +128,9 @@ cover_compile({App,all,Include,Cross}) ->
"~tp\n", [App,CompileMods]),
do_cover_compile(CompileMods),
io:fwrite("done\n\n",[]),
- {ok,Include}
+ {ok,CoverInfo#cover{mods=Include}}
end;
-cover_compile({App,Exclude,Include,Cross}) ->
+cover_compile(CoverInfo=#cover{app=App,excl=Exclude,incl=Include,cross=Cross}) ->
CrossMods = lists:flatmap(fun({_,M}) -> M end,Cross),
case code:lib_dir(App) of
{error,bad_name} ->
@@ -146,7 +148,7 @@ cover_compile({App,Exclude,Include,Cross}) ->
"~tp\n", [App,Include]),
do_cover_compile(CompileMods),
io:fwrite("done\n\n",[]),
- {ok,Include}
+ {ok,CoverInfo#cover{mods=Include}}
end;
LibDir ->
EbinDir = filename:join([LibDir,"ebin"]),
@@ -158,13 +160,13 @@ cover_compile({App,Exclude,Include,Cross}) ->
0 ->
io:fwrite("WARNING: No modules to cover compile!\n\n",[]),
cover:start(), % start cover server anyway
- {ok,[]};
+ {ok,CoverInfo#cover{mods=[]}};
N ->
io:fwrite("Cover compiling '~w' (~w files) - "
"this may take some time... ",[App,N]),
do_cover_compile(CompileMods),
io:fwrite("done\n\n",[]),
- {ok,AnalyseMods}
+ {ok,CoverInfo#cover{mods=AnalyseMods}}
end
end.
@@ -174,9 +176,11 @@ module_names(Beams) ->
do_cover_compile(Modules) ->
- do_cover_compile1(lists:usort(Modules)). % remove duplicates
+ cover:start(),
+ pmap1(fun(M) -> do_cover_compile1(M) end,lists:usort(Modules)),
+ ok.
-do_cover_compile1([M|Rest]) ->
+do_cover_compile1(M) ->
case {code:is_sticky(M),code:is_loaded(M)} of
{true,_} ->
code:unstick_mod(M),
@@ -187,15 +191,13 @@ do_cover_compile1([M|Rest]) ->
io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n",
[M,Error])
end,
- code:stick_mod(M),
- do_cover_compile1(Rest);
+ code:stick_mod(M);
{false,false} ->
case code:load_file(M) of
{module,_} ->
- do_cover_compile1([M|Rest]);
+ do_cover_compile1(M);
Error ->
- io:fwrite("\nWARNING: Could not load ~w: ~p\n",[M,Error]),
- do_cover_compile1(Rest)
+ io:fwrite("\nWARNING: Could not load ~w: ~p\n",[M,Error])
end;
{false,_} ->
case cover:compile_beam(M) of
@@ -204,23 +206,52 @@ do_cover_compile1([M|Rest]) ->
Error ->
io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n",
[M,Error])
- end,
- do_cover_compile1(Rest)
- end;
-do_cover_compile1([]) ->
- ok.
+ end
+ end.
+
+pmap1(Fun,List) ->
+ NTot = length(List),
+ NProcs = erlang:system_info(schedulers) * 2,
+ NPerProc = (NTot div NProcs) + 1,
+
+ {[],Pids} =
+ lists:foldr(
+ fun(_,{L,Ps}) ->
+ {L1,L2} = if length(L)>=NPerProc -> lists:split(NPerProc,L);
+ true -> {L,[]} % last chunk
+ end,
+ {P,_Ref} =
+ spawn_monitor(fun() ->
+ exit(lists:map(Fun,L1))
+ end),
+ {L2,[P|Ps]}
+ end,
+ {List,[]},
+ lists:seq(1,NProcs)),
+ collect(Pids,[]).
+
+collect([],Acc) ->
+ lists:append(Acc);
+collect([Pid|Pids],Acc) ->
+ receive
+ {'DOWN', _Ref, process, Pid, Result} ->
+ %% collect(lists:delete(Pid,Pids),[Result|Acc])
+ collect(Pids,[Result|Acc])
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% cover_analyse(Analyse,Modules,Stop) -> [{M,{Cov,NotCov,Details}}]
+%% cover_analyse(Dir,#cover{level=Analyse,mods=Modules,stop=Stop) ->
+%% [{M,{Cov,NotCov,Details}}]
%%
-%% Analyse = {details,Dir} | details | {overview,void()} | overview
+%% Dir = string()
+%% Analyse = details | overview
%% Modules = [atom()], the modules to analyse
%%
-%% Cover analysis. If Analyse=={details,Dir} analyse_to_file is used.
+%% Cover analysis. If Analyse==details analyse_to_file is used.
%%
-%% If Analyse=={overview,Dir} analyse_to_file is not used, only an
-%% overview containing the number of covered/not covered lines in each
-%% module.
+%% If Analyse==overview analyse_to_file is not used, only an overview
+%% containing the number of covered/not covered lines in each module.
%%
%% Also, cover data will be exported to a file called all.coverdata in
%% the given directory.
@@ -235,11 +266,11 @@ do_cover_compile1([]) ->
%% which means that the modules will stay cover compiled. Note that
%% this is only recommended if the erlang node is being terminated
%% after the test is completed.
-cover_analyse(Analyse,Modules,Stop) ->
- print(stdout, "Cover analysing...\n", []),
+cover_analyse(Dir,#cover{level=Analyse,mods=Modules,stop=Stop}) ->
+ io:fwrite(user, "Cover analysing... ", []),
DetailsFun =
case Analyse of
- {details,Dir} ->
+ details ->
case cover:export(filename:join(Dir,"all.coverdata")) of
ok ->
fun(M) ->
@@ -256,7 +287,7 @@ cover_analyse(Analyse,Modules,Stop) ->
Error ->
fun(_) -> Error end
end;
- {overview,Dir} ->
+ overview ->
case cover:export(filename:join(Dir,"all.coverdata")) of
ok ->
fun(_) -> undefined end;
@@ -264,17 +295,19 @@ cover_analyse(Analyse,Modules,Stop) ->
fun(_) -> Error end
end
end,
- R = pmap(
+ R = pmap2(
fun(M) ->
case cover:analyse(M,module) of
{ok,{M,{Cov,NotCov}}} ->
{M,{Cov,NotCov,DetailsFun(M)}};
Err ->
- io:fwrite("WARNING: Analysis failed for ~w. Reason: ~p\n",
+ io:fwrite(user,
+ "\nWARNING: Analysis failed for ~w. Reason: ~p\n",
[M,Err]),
{M,Err}
end
end, Modules),
+ io:fwrite(user, "done\n\n", []),
case Stop of
true ->
@@ -286,12 +319,12 @@ cover_analyse(Analyse,Modules,Stop) ->
end,
R.
-pmap(Fun,List) ->
+pmap2(Fun,List) ->
Collector = self(),
Pids = lists:map(fun(E) ->
spawn(fun() ->
- Collector ! {res,self(),Fun(E)}
- end)
+ Collector ! {res,self(),Fun(E)}
+ end)
end, List),
lists:map(fun(Pid) ->
receive
@@ -300,7 +333,6 @@ pmap(Fun,List) ->
end
end, Pids).
-
do_cover_for_node(Node,CoverFunc) ->
do_cover_for_node(Node,CoverFunc,true).
do_cover_for_node(Node,CoverFunc,StickUnstick) ->
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 5fbc47a813..af8921fe75 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -52,7 +52,9 @@
-export([reject_io_reqs/1, get_levels/0, set_levels/3]).
-export([multiply_timetraps/1, scale_timetraps/1, get_timetrap_parameters/0]).
-export([create_priv_dir/1]).
--export([cover/2, cover/3, cover/8, cross_cover_analyse/2, trc/1, stop_trace/0]).
+-export([cover/1, cover/2, cover/3,
+ cover_compile/7, cover_analyse/2, cross_cover_analyse/2,
+ trc/1, stop_trace/0]).
-export([testcase_callback/1]).
-export([set_random_seed/1]).
-export([kill_slavenodes/0]).
@@ -409,11 +411,26 @@ cover(App, Analyse) when is_atom(App) ->
cover(CoverFile, Analyse) ->
cover(none, CoverFile, Analyse).
cover(App, CoverFile, Analyse) ->
- controller_call({cover,{App,CoverFile},Analyse,true}).
-cover(App, CoverFile, Exclude, Include, Cross, Export, Analyse, Stop) ->
- controller_call({cover,
- {App,{CoverFile,Exclude,Include,Cross,Export}},
- Analyse,Stop}).
+ {Excl,Incl,Cross} = read_cover_file(CoverFile),
+ CoverInfo = #cover{app=App,
+ file=CoverFile,
+ excl=Excl,
+ incl=Incl,
+ cross=Cross,
+ level=Analyse},
+ controller_call({cover,CoverInfo}).
+
+cover(CoverInfo) ->
+ controller_call({cover,CoverInfo}).
+
+cover_compile(App,File,Excl,Incl,Cross,Analyse,Stop) ->
+ cover_compile(#cover{app=App,
+ file=File,
+ excl=Excl,
+ incl=Incl,
+ cross=Cross,
+ level=Analyse,
+ stop=Stop}).
testcase_callback(ModFunc) ->
controller_call({testcase_callback,ModFunc}).
@@ -563,7 +580,7 @@ handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) ->
ExtraTools =
case State#state.cover of
false -> [];
- {App,Analyse,Stop} -> [{cover,App,Analyse,Stop}]
+ CoverInfo -> [{cover,CoverInfo}]
end,
ExtraTools1 =
case State#state.random_seed of
@@ -816,13 +833,13 @@ handle_call(stop_trace, _From, State) ->
{reply,R,State#state{trc=false}};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% handle_call({cover,App,Analyse,Stop}, _, State) -> ok | {error,Reason}
+%% handle_call({cover,CoverInfo}, _, State) -> ok | {error,Reason}
%%
-%% All modules inn application App are cover compiled
-%% Analyse indicates on which level the coverage should be analysed
+%% Set specification of cover analysis to be used when running tests
+%% (see start_extra_tools/1 and stop_extra_tools/1)
-handle_call({cover,App,Analyse,Stop}, _From, State) ->
- {reply,ok,State#state{cover={App,Analyse,Stop}}};
+handle_call({cover,CoverInfo}, _From, State) ->
+ {reply,ok,State#state{cover=CoverInfo}};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% handle_call({create_priv_dir,Value}, _, State) -> ok | {error,Reason}
@@ -1203,11 +1220,10 @@ elapsed_time(Before, After) ->
start_extra_tools(ExtraTools) ->
start_extra_tools(ExtraTools, []).
-start_extra_tools([{cover,App,Analyse,Stop} | ExtraTools], Started) ->
- case cover_compile(App) of
- {ok,AnalyseMods} ->
- start_extra_tools(ExtraTools,
- [{cover,App,Analyse,AnalyseMods,Stop}|Started]);
+start_extra_tools([{cover,CoverInfo} | ExtraTools], Started) ->
+ case start_cover(CoverInfo) of
+ {ok,NewCoverInfo} ->
+ start_extra_tools(ExtraTools,[{cover,NewCoverInfo}|Started]);
{error,_} ->
start_extra_tools(ExtraTools, Started)
end;
@@ -1226,8 +1242,8 @@ stop_extra_tools(ExtraTools) ->
end,
stop_extra_tools(ExtraTools, TestDir).
-stop_extra_tools([{cover,App,Analyse,AnalyseMods,Stop}|ExtraTools], TestDir) ->
- cover_analyse(App, Analyse, AnalyseMods, Stop, TestDir),
+stop_extra_tools([{cover,CoverInfo}|ExtraTools], TestDir) ->
+ stop_cover(CoverInfo,TestDir),
stop_extra_tools(ExtraTools, TestDir);
%%stop_extra_tools([_ | ExtraTools], TestDir) ->
%% stop_extra_tools(ExtraTools, TestDir);
@@ -1569,16 +1585,24 @@ do_test_cases(TopCases, SkipCases,
ok
end
end,
-
+ CoverLog =
+ case get(test_server_cover_log_dir) of
+ undefined ->
+ ?coverlog_name;
+ AbsLogDir ->
+ AbsLog = filename:join(AbsLogDir,?coverlog_name),
+ make_relative(AbsLog, TestDir)
+ end,
print(html,
"<p><ul>\n"
"<li><a href=\"~ts\">Full textual log</a></li>\n"
"<li><a href=\"~ts\">Coverage log</a></li>\n"
"<li><a href=\"~ts\">Unexpected I/O log</a></li>\n</ul></p>\n",
- [?suitelog_name,?coverlog_name,?unexpected_io_log]),
+ [?suitelog_name,CoverLog,?unexpected_io_log]),
print(html,
"<p>~ts</p>\n" ++
- xhtml("<table bgcolor=\"white\" border=\"3\" cellpadding=\"5\">",
+ xhtml(["<table bgcolor=\"white\" border=\"3\" cellpadding=\"5\">\n",
+ "<thead>\n"],
["<table id=\"",?sortable_table_name,"\">\n",
"<thead>\n"]) ++
"<tr><th>Num</th><th>Module</th><th>Group</th>" ++
@@ -5087,15 +5111,15 @@ pinfo(P) ->
%% Cover compilation
%% The compilation is executed on the target node
-cover_compile({App,{_File,Exclude,Include,Cross,_Export}}) ->
- cover_compile1({App,Exclude,Include,Cross});
+start_cover(#cover{}=CoverInfo) ->
+ cover_compile(CoverInfo);
+start_cover({log,CoverLogDir}=CoverInfo) ->
+ %% Cover is controlled by the framework - here's the log
+ put(test_server_cover_log_dir,CoverLogDir),
+ {ok,CoverInfo}.
-cover_compile({App,CoverFile}) ->
- {Exclude,Include,Cross} = read_cover_file(CoverFile),
- cover_compile1({App,Exclude,Include,Cross}).
-
-cover_compile1(What) ->
- test_server:cover_compile(What).
+cover_compile(CoverInfo) ->
+ test_server:cover_compile(CoverInfo).
%% Read the coverfile for an application and return a list of modules
%% that are members of the application but shall not be compiled
@@ -5163,25 +5187,45 @@ check_cross([]) ->
%%
%% This per application analysis writes the file cover.html in the
%% application's run.<timestamp> directory.
-cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
+stop_cover(#cover{}=CoverInfo, TestDir) ->
+ cover_analyse(CoverInfo, TestDir);
+stop_cover(_CoverInfo, _TestDir) ->
+ %% Cover is probably controlled by the framework
+ ok.
+
+make_relative(AbsDir, VsDir) ->
+ DirTokens = filename:split(AbsDir),
+ VsTokens = filename:split(VsDir),
+ filename:join(make_relative1(DirTokens, VsTokens)).
+
+make_relative1([T | DirTs], [T | VsTs]) ->
+ make_relative1(DirTs, VsTs);
+make_relative1(Last = [_File], []) ->
+ Last;
+make_relative1(Last = [_File], VsTs) ->
+ Ups = ["../" || _ <- VsTs],
+ Ups ++ Last;
+make_relative1(DirTs, []) ->
+ DirTs;
+make_relative1(DirTs, VsTs) ->
+ Ups = ["../" || _ <- VsTs],
+ Ups ++ DirTs.
+
+
+cover_analyse(CoverInfo, TestDir) ->
write_default_cross_coverlog(TestDir),
{ok,CoverLog} = open_html_file(filename:join(TestDir, ?coverlog_name)),
write_coverlog_header(CoverLog),
+ #cover{app=App,
+ file=CoverFile,
+ excl=Excluded,
+ cross=Cross} = CoverInfo,
io:fwrite(CoverLog, "<h1>Coverage for application '~w'</h1>\n", [App]),
io:fwrite(CoverLog,
"<p><a href=\"~ts\">Coverdata collected over all tests</a></p>",
[?cross_coverlog_name]),
- {CoverFile,_Included,Excluded,Cross} =
- case CoverInfo of
- {File,Excl,Incl,Cr,Export} ->
- cover:export(Export),
- {File,Incl,Excl,Cr};
- File ->
- {Excl,Incl,Cr} = read_cover_file(File),
- {File,Incl,Excl,Cr}
- end,
io:fwrite(CoverLog, "<p>CoverFile: <code>~tp</code>\n", [CoverFile]),
write_cross_cover_info(TestDir,Cross),
@@ -5196,7 +5240,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
io:fwrite(CoverLog, "<p>Excluded module(s): <code>~tp</code>\n", [Excluded]),
- Coverage = cover_analyse(Analyse, AnalyseMods, Stop),
+ Coverage = test_server:cover_analyse(TestDir, CoverInfo),
write_binary_file(filename:join(TestDir,?raw_coverlog_name),
term_to_binary(Coverage)),
@@ -5215,11 +5259,6 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
write_binary_file(filename:join(TestDir, ?cover_total),
term_to_binary(TotPercent)).
-cover_analyse(Analyse, AnalyseMods, Stop) ->
- TestDir = get(test_server_log_dir_base),
- test_server:cover_analyse({Analyse,TestDir}, AnalyseMods, Stop).
-
-
%% Cover analysis - accumulated over multiple tests
%% This can be executed on any node after all tests are finished.
%% Analyse = overview | details
diff --git a/lib/test_server/src/test_server_internal.hrl b/lib/test_server/src/test_server_internal.hrl
index 4e734a330b..bafeeaabfe 100644
--- a/lib/test_server/src/test_server_internal.hrl
+++ b/lib/test_server/src/test_server_internal.hrl
@@ -49,3 +49,12 @@
master,
cookie}).
+
+-record(cover, {app, % application; Name | none
+ file, % cover spec file
+ incl, % explicitly include modules
+ excl, % explicitly exclude modules
+ level, % analyse level; details | overview
+ mods, % actually cover compiled modules
+ stop=true, % stop cover after analyse; boolean()
+ cross}).% cross cover analyse info
diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl
index bc7d244c7c..d6d2e865e2 100644
--- a/lib/test_server/src/ts.erl
+++ b/lib/test_server/src/ts.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -641,16 +641,17 @@ get_last_app_tests([Dir|Dirs],RE,Acc) ->
NewAcc =
case re:run(Dir,RE,[{capture,all,list}]) of
{match,[Dir,AppStr]} ->
+ Dir1 = filename:dirname(Dir), % cover logs in ct_run.<t> dir
App = list_to_atom(AppStr),
case lists:keytake(App,1,Acc) of
{value,{App,LastDir},Rest} ->
- if Dir > LastDir ->
- [{App,Dir}|Rest];
+ if Dir1 > LastDir ->
+ [{App,Dir1}|Rest];
true ->
Acc
end;
false ->
- [{App,Dir} | Acc]
+ [{App,Dir1} | Acc]
end;
_ ->
Acc
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 4eb70aa2cd..9e1ac8fd12 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1 +1 @@
-TEST_SERVER_VSN = 3.7
+TEST_SERVER_VSN = 3.7.1
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 136e0a3127..1ba2514977 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -30,6 +30,24 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.6.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Removed <c>erlang:bitstr_to_list/1</c> and
+ <c>erlang:list_to_bitstr/1</c>. They were added by
+ mistake, and have always raised an <c>undefined</c>
+ exception when called.</p>
+ <p>
+ Own Id: OTP-11942</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.6.14</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index ec5a1f4bc5..4e3c49c717 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -853,7 +853,6 @@ resulting regexp is surrounded by \\_< and \\_>."
"append_element"
"await_proc_exit"
"await_sched_wall_time_modifications"
- "bitstr_to_list"
"bump_reductions"
"call_on_load_function"
"cancel_timer"
@@ -899,7 +898,6 @@ resulting regexp is surrounded by \\_< and \\_>."
"hibernate"
"insert_element"
"is_builtin"
- "list_to_bitstr"
"load_nif"
"loaded"
"localtime"
diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl
index 20ee32c861..f1251fddab 100644
--- a/lib/tools/src/lcnt.erl
+++ b/lib/tools/src/lcnt.erl
@@ -61,6 +61,8 @@
locations/1,
inspect/1,
inspect/2,
+ histogram/1,
+ histogram/2,
information/0,
swap_pid_keys/0,
% set options
@@ -89,14 +91,14 @@
duration = 0
}).
-
-record(stats, {
- file,
- line,
- tries,
- colls,
- time, % us
- nt % #timings collected
+ file :: atom(),
+ line :: non_neg_integer(),
+ tries :: non_neg_integer(),
+ colls :: non_neg_integer(),
+ time :: non_neg_integer(), % us
+ nt :: non_neg_integer(), % #timings collected
+ hist :: tuple() % histogram
}).
-record(lock, {
@@ -115,7 +117,9 @@
colls,
cr, % collision ratio
time,
- dtr % time duration ratio
+ dtr, % time duration ratio
+ %% new
+ hist % log2 histogram of lock wait_time
}).
@@ -127,7 +131,7 @@
%% -------------------------------------------------------------------- %%
start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []).
-stop() -> gen_server:cast(?MODULE, stop).
+stop() -> gen_server:call(?MODULE, stop, infinity).
init([]) -> {ok, #state{ locks = [], duration = 0 } }.
%% -------------------------------------------------------------------- %%
@@ -171,6 +175,8 @@ conflicts() -> call({conflicts, []}).
conflicts(Opts) -> call({conflicts, Opts}).
inspect(Lock) -> call({inspect, Lock, []}).
inspect(Lock, Opts) -> call({inspect, Lock, Opts}).
+histogram(Lock) -> call({histogram, Lock, []}).
+histogram(Lock, Opts)-> call({histogram, Lock, Opts}).
information() -> call(information).
swap_pid_keys() -> call(swap_pid_keys).
raw() -> call(raw).
@@ -283,14 +289,14 @@ handle_call({locations, InOpts}, _From, #state{ locks = Locks } = State) when is
{reply, ok, State};
-handle_call({inspect, Lockname, InOpts}, _From, #state{ duration = Duration, locks = Locks } = State) when is_list(InOpts) ->
+handle_call({inspect, Lockname, InOpts}, _From, #state{ duration=Duration, locks=Locks } = State) when is_list(InOpts) ->
Default = [
{sort, time},
{reverse, false},
- {print, [name,id,tries,colls,ratio,time,duration]},
+ {print, [name,id,tries,colls,ratio,time,duration,histogram]},
{max_locks, 20},
{combine, false},
- {thresholds, [] },
+ {thresholds, []},
{locations, false}],
Opts = options(InOpts, Default),
@@ -299,7 +305,7 @@ handle_call({inspect, Lockname, InOpts}, _From, #state{ duration = Duration, loc
{true, true} -> locks_ids(Filtered);
_ -> []
end,
- Combos = combine_classes(Filtered, proplists:get_value(combine, Opts)),
+ Combos = combine_classes(Filtered, proplists:get_value(combine, Opts)),
case proplists:get_value(locations, Opts) of
true ->
lists:foreach(fun
@@ -313,17 +319,14 @@ handle_call({inspect, Lockname, InOpts}, _From, #state{ duration = Duration, loc
[] ->
ok;
_ ->
- %io:format("Combined ~p~n", [Combined]),
print("lock: " ++ term2string(Name)),
print("id: " ++ IdString),
print("type: " ++ term2string(Type)),
Ps = stats2print(Combined, Duration),
- Opts1 = options([{print, [entry, tries,colls,ratio,time,duration]},
+ Opts1 = options([{print, [entry, tries,colls,ratio,time,duration,histogram]},
{thresholds, [{tries, -1}, {colls, -1}, {time, -1}]}], Opts),
print_lock_information(filter_print(Ps, Opts1), proplists:get_value(print, Opts1))
end
- % (#lock{ name = Name, id = Id}) ->
- % io:format("Empty lock ~p ~p~n", [Name, Id])
end, Combos);
_ ->
Print1 = locks2print(Combos, Duration),
@@ -332,6 +335,34 @@ handle_call({inspect, Lockname, InOpts}, _From, #state{ duration = Duration, loc
end,
{reply, ok, State};
+%% histogram
+
+handle_call({histogram, Lockname, InOpts}, _From, #state{ duration=Duration, locks=Locks} = State)->
+ Default = [
+ {sort, time},
+ {reverse, false},
+ {print, [name,id,tries,colls,ratio,time,duration,histogram]},
+ {max_locks, 20},
+ {combine, true},
+ {thresholds, []},
+ {locations, false}],
+
+ Opts = options(InOpts, Default),
+ Filtered = filter_locks(Locks, Lockname),
+ Combos = combine_classes(Filtered, proplists:get_value(combine, Opts)),
+ lists:foreach(fun
+ (#lock{ stats = Stats }=L) ->
+ SumStats = summate_stats(Stats),
+ Opts1 = options([{print, [name,id,tries,colls,ratio,time,duration]},
+ {thresholds, [{tries, -1}, {colls, -1}, {time, -1}]}], Opts),
+ Prints = locks2print([L], Duration),
+ print_lock_information(Prints, proplists:get_value(print, Opts1)),
+ print_full_histogram(SumStats#stats.hist),
+ io:format("~n")
+ end, Combos),
+
+ {reply, ok, State};
+
handle_call(raw, _From, #state{ locks = Locks} = State)->
{reply, Locks, State};
@@ -347,7 +378,6 @@ handle_call(swap_pid_keys, _From, #state{ locks = Locks } = State)->
(L) ->
L
end, Locks),
-
{reply, ok, State#state{ locks = SwappedLocks}};
% settings
@@ -380,6 +410,8 @@ handle_call({save, Filename}, _From, State) ->
{reply, {error, Error}, State}
end;
+handle_call(stop, _From, State) ->
+ {stop, normal, ok, State};
handle_call(Command, _From, State) ->
{reply, {error, {undefined, Command}}, State}.
@@ -390,8 +422,6 @@ handle_call(Command, _From, State) ->
%%
%% -------------------------------------------------------------------- %%
-handle_cast(stop, State) ->
- {stop, normal, State};
handle_cast(_, State) ->
{noreply, State}.
@@ -432,15 +462,32 @@ code_change(_OldVsn, State, _Extra) ->
summate_locks(Locks) -> summate_locks(Locks, #stats{ tries = 0, colls = 0, time = 0, nt = 0}).
summate_locks([], Stats) -> Stats;
-summate_locks([L|Ls], #stats{ tries = Tries, colls = Colls, time = Time, nt = Nt}) ->
+summate_locks([L|Ls], #stats{ tries = Tries, colls = Colls, time = Time, nt = Nt, hist = Hist}) ->
S = summate_stats(L#lock.stats),
- summate_locks(Ls, #stats{ tries = Tries + S#stats.tries, colls = Colls + S#stats.colls, time = Time + S#stats.time, nt = Nt + S#stats.nt}).
+ summate_locks(Ls, #stats{
+ tries = Tries + S#stats.tries,
+ colls = Colls + S#stats.colls,
+ time = Time + S#stats.time,
+ nt = Nt + S#stats.nt,
+ hist = summate_histogram(Hist, S#stats.hist)
+ }).
summate_stats(Stats) -> summate_stats(Stats, #stats{ tries = 0, colls = 0, time = 0, nt = 0}).
summate_stats([], Stats) -> Stats;
-summate_stats([S|Ss], #stats{ tries = Tries, colls = Colls, time = Time, nt = Nt}) ->
- summate_stats(Ss, #stats{ tries = Tries + S#stats.tries, colls = Colls + S#stats.colls, time = Time + S#stats.time, nt = Nt + S#stats.nt}).
-
+summate_stats([S|Ss], #stats{ tries = Tries, colls = Colls, time = Time, nt = Nt, hist = Hist}) ->
+ summate_stats(Ss, #stats{
+ tries = Tries + S#stats.tries,
+ colls = Colls + S#stats.colls,
+ time = Time + S#stats.time,
+ nt = Nt + S#stats.nt,
+ hist = summate_histogram(Hist, S#stats.hist)
+ }).
+
+%% first call is undefined
+summate_histogram(Tup,undefined) when is_tuple(Tup) -> Tup;
+summate_histogram(undefined,Tup) when is_tuple(Tup) -> Tup;
+summate_histogram(Hs1,Hs2) ->
+ list_to_tuple([ A + B || {A,B} <- lists:zip(tuple_to_list(Hs1),tuple_to_list(Hs2))]).
%% manipulators
filter_locks_type(Locks, undefined) -> Locks;
@@ -465,17 +512,16 @@ filter_print(PLs, Opts) ->
TLs = threshold_locks(PLs, proplists:get_value(thresholds, Opts, [])),
SLs = sort_locks(TLs, proplists:get_value(sort, Opts, time)),
CLs = cut_locks(SLs, proplists:get_value(max_locks, Opts, none)),
- reverse_locks(CLs, proplists:get_value(reverse, Opts, false)).
-
-sort_locks(Locks, Type) -> lists:reverse(sort_locks0(Locks, Type)).
-sort_locks0(Locks, name) -> lists:keysort(#print.name, Locks);
-sort_locks0(Locks, id) -> lists:keysort(#print.id, Locks);
-sort_locks0(Locks, type) -> lists:keysort(#print.type, Locks);
-sort_locks0(Locks, tries) -> lists:keysort(#print.tries, Locks);
-sort_locks0(Locks, colls) -> lists:keysort(#print.colls, Locks);
-sort_locks0(Locks, ratio) -> lists:keysort(#print.cr, Locks);
-sort_locks0(Locks, time) -> lists:keysort(#print.time, Locks);
-sort_locks0(Locks, _) -> sort_locks0(Locks, time).
+ reverse_locks(CLs, not proplists:get_value(reverse,Opts, false)).
+
+sort_locks(Locks, name) -> lists:keysort(#print.name, Locks);
+sort_locks(Locks, id) -> lists:keysort(#print.id, Locks);
+sort_locks(Locks, type) -> lists:keysort(#print.type, Locks);
+sort_locks(Locks, tries) -> lists:keysort(#print.tries, Locks);
+sort_locks(Locks, colls) -> lists:keysort(#print.colls, Locks);
+sort_locks(Locks, ratio) -> lists:keysort(#print.cr, Locks);
+sort_locks(Locks, time) -> lists:keysort(#print.time, Locks);
+sort_locks(Locks, _) -> sort_locks(Locks, time).
% cut locks not above certain thresholds
threshold_locks(Locks, Thresholds) ->
@@ -556,45 +602,61 @@ locks_ids(Locks) -> locks_ids(Locks, []).
locks_ids([], Out) -> Out;
locks_ids([#lock{ name = Key } = L|Ls], Out) ->
case proplists:get_value(Key, Out) of
- undefined ->
- locks_ids(Ls, [{Key, [L#lock.id] } | Out]);
- Ids ->
- locks_ids(Ls, [{Key, [L#lock.id | Ids] } | proplists:delete(Key,Out)])
+ undefined -> locks_ids(Ls, [{Key, [L#lock.id]}|Out]);
+ Ids -> locks_ids(Ls, [{Key, [L#lock.id|Ids]}|proplists:delete(Key,Out)])
end.
stats2print(Stats, Duration) ->
lists:map(fun
(S) ->
- #print{
- entry = term2string("~tp:~p", [S#stats.file, S#stats.line]),
- colls = S#stats.colls,
- tries = S#stats.tries,
- cr = percent(S#stats.colls, S#stats.tries),
- time = S#stats.time,
- dtr = percent(S#stats.time, Duration)
- }
+ #print{entry = term2string("~tp:~p", [S#stats.file, S#stats.line]),
+ colls = S#stats.colls,
+ tries = S#stats.tries,
+ cr = percent(S#stats.colls, S#stats.tries),
+ time = S#stats.time,
+ dtr = percent(S#stats.time, Duration),
+ hist = format_histogram(S#stats.hist)}
end, Stats).
locks2print(Locks, Duration) ->
lists:map( fun
(L) ->
- Tries = lists:sum([T || #stats{ tries = T} <- L#lock.stats]),
- Colls = lists:sum([C || #stats{ colls = C} <- L#lock.stats]),
- Time = lists:sum([T || #stats{ time = T} <- L#lock.stats]),
- Cr = percent(Colls, Tries),
- Dtr = percent(Time, Duration),
- #print{
- name = L#lock.name,
- id = L#lock.id,
- type = L#lock.type,
- tries = Tries,
- colls = Colls,
- cr = Cr,
- time = Time,
- dtr = Dtr
- }
+ #stats{tries = Tries,
+ colls = Colls,
+ time = Time,
+ hist = Hist} = summate_stats(L#lock.stats),
+ Cr = percent(Colls, Tries),
+ Dtr = percent(Time, Duration),
+ #print{name = L#lock.name,
+ id = L#lock.id,
+ type = L#lock.type,
+ tries = Tries,
+ colls = Colls,
+ hist = format_histogram(Hist),
+ cr = Cr,
+ time = Time,
+ dtr = Dtr}
end, Locks).
+
+format_histogram(Tup) when is_tuple(Tup) ->
+ Vs = tuple_to_list(Tup),
+ Max = lists:max(Vs),
+ case Max of
+ 0 -> string_histogram(Vs);
+ _ -> string_histogram([case V of 0 -> 0; _ -> V/Max end || V <- Vs])
+ end.
+
+string_histogram([0|Vs]) ->
+ [$\s|string_histogram(Vs)];
+string_histogram([V|Vs]) when V > 0.66 ->
+ [$X|string_histogram(Vs)];
+string_histogram([V|Vs]) when V > 0.33 ->
+ [$x|string_histogram(Vs)];
+string_histogram([_|Vs]) ->
+ [$.|string_histogram(Vs)];
+string_histogram([]) -> [].
+
%% state making
data2state(Data, State) ->
@@ -606,22 +668,32 @@ data2state(Data, State) ->
locks = Locks
}.
-locks2records(Locks) -> locks2records(Locks, []).
-locks2records([], Out) -> Out;
-locks2records([{Name, Id, Type, Stats}|Locks], Out) ->
- Lock = #lock{
- name = Name,
- id = clean_id_creation(Id),
- type = Type,
- stats = [ #stats{
- file = File,
- line = Line,
- tries = Tries,
- colls = Colls,
- time = time2us({S, Ns}),
- nt = N
- } || {{File, Line}, {Tries, Colls, {S, Ns, N}}} <- Stats] },
- locks2records(Locks, [Lock|Out]).
+locks2records([{Name, Id, Type, Stats}|Locks]) ->
+ [#lock{name = Name,
+ id = clean_id_creation(Id),
+ type = Type,
+ stats = stats2record(Stats)}|locks2records(Locks)];
+locks2records([]) -> [].
+
+%% new stats with histogram
+stats2record([{{File,Line},{Tries,Colls,{S,Ns,N}},Hist}|Stats]) ->
+ [#stats{file = File,
+ line = Line,
+ hist = Hist,
+ tries = Tries,
+ colls = Colls,
+ time = time2us({S, Ns}),
+ nt = N} | stats2record(Stats)];
+%% old stats without histogram
+stats2record([{{File,Line},{Tries,Colls,{S,Ns,N}}}|Stats]) ->
+ [#stats{file = File,
+ line = Line,
+ hist = {},
+ tries = Tries,
+ colls = Colls,
+ time = time2us({S, Ns}),
+ nt = N} | stats2record(Stats)];
+stats2record([]) -> [].
clean_id_creation(Id) when is_pid(Id) ->
Bin = term_to_binary(Id),
@@ -647,22 +719,45 @@ state2list(State) ->
(X, Y) -> {X,Y}
end, record_info(fields, state), Values).
-list2state(List) -> list2state(record_info(fields, state), List, [state]).
-list2state([], _, Out) -> list_to_tuple(lists:reverse(Out));
-list2state([locks|Fs], List, Out) ->
- Locks = [ list2lock(Lock) || Lock <- proplists:get_value(locks, List, [])],
- list2state(Fs, List, [Locks|Out]);
-list2state([F|Fs], List, Out) -> list2state(Fs, List, [proplists:get_value(F, List, state_default(F))|Out]).
-
lock_default(Field) -> proplists:get_value(Field, lock2list(#lock{})).
lock2list(Lock) ->
[_|Values] = tuple_to_list(Lock),
lists:zip(record_info(fields, lock), Values).
-list2lock(List) -> list2lock(record_info(fields, lock), List, [lock]).
-list2lock([], _, Out) -> list_to_tuple(lists:reverse(Out));
-list2lock([F|Fs], List, Out) -> list2lock(Fs, List, [proplists:get_value(F, List, lock_default(F))|Out]).
+
+list2state(List) ->
+ list_to_tuple([state|list2state(record_info(fields, state), List)]).
+list2state([], _) -> [];
+list2state([locks|Fs], List) ->
+ Locks = [list2lock(Lock) || Lock <- proplists:get_value(locks, List, [])],
+ [Locks|list2state(Fs,List)];
+list2state([F|Fs], List) ->
+ [proplists:get_value(F, List, state_default(F))|list2state(Fs, List)].
+
+list2lock(Ls) ->
+ list_to_tuple([lock|list2lock(record_info(fields, lock), Ls)]).
+
+list2lock([],_) -> [];
+list2lock([stats=F|Fs], Ls) ->
+ Stats = stats2stats(proplists:get_value(F, Ls, lock_default(F))),
+ [Stats|list2lock(Fs, Ls)];
+list2lock([F|Fs], Ls) ->
+ [proplists:get_value(F, Ls, lock_default(F))|list2lock(Fs, Ls)].
+
+%% process old stats (hack)
+%% old stats had no histograms
+%% in future versions stats should be serialized as a list, not a record
+
+stats2stats([]) -> [];
+stats2stats([Stat|Stats]) ->
+ Sz = tuple_size(#stats{}),
+ [stat2stat(Stat,Sz)|stats2stats(Stats)].
+
+stat2stat(Stat,Sz) when tuple_size(Stat) =:= Sz -> Stat;
+stat2stat(Stat,_) ->
+ %% assume no histogram at the end
+ list_to_tuple(tuple_to_list(Stat) ++ [{0}]).
%% printing
@@ -683,7 +778,7 @@ auto_print_width(Locks, Print) ->
({print,print}, Out) -> [print|Out];
({Str, Len}, Out) -> [erlang:min(erlang:max(length(s(Str))+1,Len),80)|Out]
end, [], lists:zip(tuple_to_list(L), tuple_to_list(Max)))))
- end, #print{ id = 4, type = 5, entry = 5, name = 6, tries = 8, colls = 13, cr = 16, time = 11, dtr = 14 },
+ end, #print{ id = 4, type = 5, entry = 5, name = 6, tries = 8, colls = 13, cr = 16, time = 11, dtr = 14, hist=20 },
Locks),
% Setup the offsets for later pruning
Offsets = [
@@ -695,7 +790,9 @@ auto_print_width(Locks, Print) ->
{colls, R#print.colls},
{ratio, R#print.cr},
{time, R#print.time},
- {duration, R#print.dtr}],
+ {duration, R#print.dtr},
+ {histogram, R#print.hist}
+ ],
% Prune offsets to only allow specified print options
lists:foldr(fun
({Type, W}, Out) -> [{Type, W}|Out];
@@ -705,9 +802,7 @@ auto_print_width(Locks, Print) ->
print_lock_information(Locks, Print) ->
% remake Print to autosize entries
AutoPrint = auto_print_width(Locks, Print),
-
print_header(AutoPrint),
-
lists:foreach(fun
(L) ->
print_lock(L, AutoPrint)
@@ -724,7 +819,8 @@ print_header(Opts) ->
colls = "#collisions",
cr = "collisions [%]",
time = "time [us]",
- dtr = "duration [%]"
+ dtr = "duration [%]",
+ hist = "histogram"
},
Divider = #print{
name = lists:duplicate(1 + length(Header#print.name), 45),
@@ -735,39 +831,44 @@ print_header(Opts) ->
colls = lists:duplicate(1 + length(Header#print.colls), 45),
cr = lists:duplicate(1 + length(Header#print.cr), 45),
time = lists:duplicate(1 + length(Header#print.time), 45),
- dtr = lists:duplicate(1 + length(Header#print.dtr), 45)
+ dtr = lists:duplicate(1 + length(Header#print.dtr), 45),
+ hist = lists:duplicate(1 + length(Header#print.hist), 45)
},
print_lock(Header, Opts),
print_lock(Divider, Opts),
ok.
-print_lock(L, Opts) -> print_lock(L, Opts, []).
-print_lock(_, [], Formats) -> print(strings(lists:reverse(Formats)));
-print_lock(L, [Opt|Opts], Formats) ->
+print_lock(L, Opts) ->
+ print(strings(format_lock(L, Opts))).
+
+format_lock(_, []) -> [];
+format_lock(L, [Opt|Opts]) ->
case Opt of
- id -> print_lock(L, Opts, [{space, 25, s(L#print.id) } | Formats]);
- {id, W} -> print_lock(L, Opts, [{space, W, s(L#print.id) } | Formats]);
- type -> print_lock(L, Opts, [{space, 18, s(L#print.type) } | Formats]);
- {type, W} -> print_lock(L, Opts, [{space, W, s(L#print.type) } | Formats]);
- entry -> print_lock(L, Opts, [{space, 30, s(L#print.entry)} | Formats]);
- {entry, W} -> print_lock(L, Opts, [{space, W, s(L#print.entry)} | Formats]);
- name -> print_lock(L, Opts, [{space, 22, s(L#print.name) } | Formats]);
- {name, W} -> print_lock(L, Opts, [{space, W, s(L#print.name) } | Formats]);
- tries -> print_lock(L, Opts, [{space, 12, s(L#print.tries)} | Formats]);
- {tries, W} -> print_lock(L, Opts, [{space, W, s(L#print.tries)} | Formats]);
- colls -> print_lock(L, Opts, [{space, 14, s(L#print.colls)} | Formats]);
- {colls, W} -> print_lock(L, Opts, [{space, W, s(L#print.colls)} | Formats]);
- ratio -> print_lock(L, Opts, [{space, 20, s(L#print.cr) } | Formats]);
- {ratio, W} -> print_lock(L, Opts, [{space, W, s(L#print.cr) } | Formats]);
- time -> print_lock(L, Opts, [{space, 15, s(L#print.time) } | Formats]);
- {time, W} -> print_lock(L, Opts, [{space, W, s(L#print.time) } | Formats]);
- duration -> print_lock(L, Opts, [{space, 20, s(L#print.dtr) } | Formats]);
- {duration, W} -> print_lock(L, Opts, [{space, W, s(L#print.dtr) } | Formats]);
- _ -> print_lock(L, Opts, Formats)
+ id -> [{space, 25, s(L#print.id) } | format_lock(L, Opts)];
+ {id, W} -> [{space, W, s(L#print.id) } | format_lock(L, Opts)];
+ type -> [{space, 18, s(L#print.type) } | format_lock(L, Opts)];
+ {type, W} -> [{space, W, s(L#print.type) } | format_lock(L, Opts)];
+ entry -> [{space, 30, s(L#print.entry)} | format_lock(L, Opts)];
+ {entry, W} -> [{space, W, s(L#print.entry)} | format_lock(L, Opts)];
+ name -> [{space, 22, s(L#print.name) } | format_lock(L, Opts)];
+ {name, W} -> [{space, W, s(L#print.name) } | format_lock(L, Opts)];
+ tries -> [{space, 12, s(L#print.tries)} | format_lock(L, Opts)];
+ {tries, W} -> [{space, W, s(L#print.tries)} | format_lock(L, Opts)];
+ colls -> [{space, 14, s(L#print.colls)} | format_lock(L, Opts)];
+ {colls, W} -> [{space, W, s(L#print.colls)} | format_lock(L, Opts)];
+ ratio -> [{space, 20, s(L#print.cr) } | format_lock(L, Opts)];
+ {ratio, W} -> [{space, W, s(L#print.cr) } | format_lock(L, Opts)];
+ time -> [{space, 15, s(L#print.time) } | format_lock(L, Opts)];
+ {time, W} -> [{space, W, s(L#print.time) } | format_lock(L, Opts)];
+ duration -> [{space, 20, s(L#print.dtr) } | format_lock(L, Opts)];
+ {duration, W} -> [{space, W, s(L#print.dtr) } | format_lock(L, Opts)];
+ histogram -> [{space, 0, s(L#print.hist) } | format_lock(L, Opts)];
+ {histogram, W} -> [{space, W, s(L#print.hist) } | format_lock(L, Opts)];
+ _ -> format_lock(L, Opts)
end.
-print_state_information(#state{ locks = Locks} = State) ->
+print_state_information(#state{locks = Locks} = State) ->
Stats = summate_locks(Locks),
print("information:"),
print(kv("#locks", s(length(Locks)))),
@@ -779,9 +880,25 @@ print_state_information(#state{ locks = Locks} = State) ->
print(kv("percent of duration", s(Stats#stats.time/State#state.duration*100) ++ " %")),
ok.
+
+print_full_histogram(T) when is_tuple(T) ->
+ Vs = tuple_to_list(T),
+ Max = lists:max(Vs),
+ W = 60,
+ print_full_histogram(0,Vs,Max,W).
+
+print_full_histogram(_,[],_,_) -> ok;
+print_full_histogram(Ix,[V|Vs],0,W) ->
+ io:format("~2w = log2 : ~8w |~n", [Ix,V]),
+ print_full_histogram(Ix+1,Vs,0,W);
+print_full_histogram(Ix,[V|Vs],Max,W) ->
+ io:format("~2w = log2 : ~8w | ~s~n", [Ix,V,lists:duplicate(trunc(W*(V/Max)), $#)]),
+ print_full_histogram(Ix+1,Vs,Max,W).
+
+
%% AUX
-time2us({S, Ns}) -> round(S*1000000 + Ns/1000).
+time2us({S, Ns}) -> S*1000000 + (Ns div 1000).
percent(_,0) -> 0.0;
percent(T,N) -> T/N*100.
@@ -808,7 +925,7 @@ s(T) -> term2string(T).
strings(Strings) -> strings(Strings, []).
strings([], Out) -> Out;
-strings([{space, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string("~~~ps", [N]), [S]));
+strings([{space, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string("~~~ws", [N]), [S]));
strings([{format, Format, S} | Ss], Out) -> strings(Ss, Out ++ term2string(Format, [S]));
strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~ts", [S])).
@@ -825,7 +942,7 @@ term2string(Term) when is_pid(Term) ->
term2string(Term) -> term2string("~w", [Term]).
term2string(Format, Terms) -> lists:flatten(io_lib:format(Format, Terms)).
-%%% AUD id binary
+%%% AUX id binary
bytes16(Value) ->
B0 = Value band 255,
diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl
index 1bee6021ab..010dffe138 100644
--- a/lib/tools/test/lcnt_SUITE.erl
+++ b/lib/tools/test/lcnt_SUITE.erl
@@ -27,11 +27,11 @@
%% Test cases
-export([
- load_v1/1,
- conflicts/1,
- locations/1,
- swap_keys/1
- ]).
+ t_load/1,
+ t_conflicts/1,
+ t_locations/1,
+ t_swap_keys/1
+ ]).
%% Default timetrap timeout (set in init_per_testcase)
-define(default_timeout, ?t:minutes(4)).
@@ -54,48 +54,52 @@ end_per_testcase(_Case, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
- [load_v1, conflicts, locations, swap_keys].
+all() -> [t_load, t_conflicts, t_locations, t_swap_keys].
-groups() ->
- [].
+groups() -> [].
-init_per_group(_GroupName, Config) ->
- Config.
+init_per_group(_GroupName, Config) -> Config.
-end_per_group(_GroupName, Config) ->
- Config.
+end_per_group(_GroupName, Config) -> Config.
%%----------------------------------------------------------------------
%% Tests
%%----------------------------------------------------------------------
-load_v1(suite) ->
- [];
-load_v1(doc) ->
- ["Load data from file."];
-load_v1(Config) when is_list(Config) ->
- ?line {ok, _} = lcnt:start(),
- ?line Path = ?config(data_dir, Config),
- ?line File = filename:join([Path,"big_bang_40.lcnt"]),
- ?line ok = lcnt:load(File),
- ?line ok = lcnt:stop(),
+t_load(suite) -> [];
+t_load(doc) -> ["Load data from file."];
+t_load(Config) when is_list(Config) ->
+ Path = ?config(data_dir, Config),
+ Files = [filename:join([Path,"big_bang_40.lcnt"]),
+ filename:join([Path,"ehb_3_3_hist.lcnt"])],
+ ok = t_load_file(Files),
ok.
-conflicts(suite) ->
- [];
-conflicts(doc) ->
- ["API: conflicts"];
-conflicts(Config) when is_list(Config) ->
- ?line {ok, _} = lcnt:start(),
- ?line Path = ?config(data_dir, Config),
- ?line File = filename:join([Path,"big_bang_40.lcnt"]),
- ?line ok = lcnt:load(File),
- ?line ok = lcnt:conflicts(),
- THs = [-1, 0, 100, 1000],
- Print = [name , id , type , entry , tries , colls , ratio , time , duration],
- Opts = [
+t_load_file([]) -> ok;
+t_load_file([File|Files]) ->
+ {ok, _} = lcnt:start(),
+ ok = lcnt:load(File),
+ ok = lcnt:stop(),
+ t_load_file(Files).
+
+t_conflicts(suite) -> [];
+t_conflicts(doc) -> ["API: conflicts"];
+t_conflicts(Config) when is_list(Config) ->
+ Path = ?config(data_dir, Config),
+ Files = [filename:join([Path,"big_bang_40.lcnt"]),
+ filename:join([Path,"ehb_3_3_hist.lcnt"])],
+ ok = t_conflicts_file(Files),
+ ok.
+
+t_conflicts_file([]) -> ok;
+t_conflicts_file([File|Files]) ->
+ {ok, _} = lcnt:start(),
+ ok = lcnt:load(File),
+ ok = lcnt:conflicts(),
+ THs = [-1, 0, 100, 1000],
+ Print = [name , id , type , entry , tries , colls , ratio , time , duration],
+ Opts = [
[{sort, Sort}, {reverse, Rev}, {max_locks, ML}, {combine, Combine}, {thresholds, [TH]}, {print, [Print]}] ||
Sort <- [name , id , type , tries , colls , ratio , time , entry],
ML <- [none, 1 , 32, 4096],
@@ -103,28 +107,33 @@ conflicts(Config) when is_list(Config) ->
TH <- [{tries, Tries} || Tries <- THs] ++ [{colls, Colls} || Colls <- THs] ++ [{time, Time} || Time <- THs],
Rev <- [true, false]
],
- ?line ok = test_conflicts_opts(Opts),
- ?line ok = lcnt:stop(),
- ok.
+ ok = test_conflicts_opts(Opts),
+ ok = lcnt:stop(),
+ t_conflicts_file(Files).
+
test_conflicts_opts([]) -> ok;
test_conflicts_opts([Opt|Opts]) ->
- ?line ok = lcnt:conflicts(Opt),
+ ok = lcnt:conflicts(Opt),
test_conflicts_opts(Opts).
-locations(suite) ->
- [];
-locations(doc) ->
- ["API: locations"];
-locations(Config) when is_list(Config) ->
- ?line {ok, _} = lcnt:start(),
- ?line Path = ?config(data_dir, Config),
- ?line File = filename:join([Path,"big_bang_40.lcnt"]),
- ?line ok = lcnt:load(File),
- ?line ok = lcnt:locations(),
- THs = [-1, 0, 100, 1000],
- Print = [name , id , type , entry , tries , colls , ratio , time , duration],
- Opts = [
+t_locations(suite) -> [];
+t_locations(doc) -> ["API: locations"];
+t_locations(Config) when is_list(Config) ->
+ Path = ?config(data_dir, Config),
+ Files = [filename:join([Path,"big_bang_40.lcnt"]),
+ filename:join([Path,"ehb_3_3_hist.lcnt"])],
+ ok = t_locations_file(Files),
+ ok.
+
+t_locations_file([]) -> ok;
+t_locations_file([File|Files]) ->
+ {ok, _} = lcnt:start(),
+ ok = lcnt:load(File),
+ ok = lcnt:locations(),
+ THs = [-1, 0, 100, 1000],
+ Print = [name , id , type , entry , tries , colls , ratio , time , duration],
+ Opts = [
[{full_id, Id}, {sort, Sort}, {max_locks, ML}, {combine, Combine}, {thresholds, [TH]}, {print, Print}] ||
Sort <- [name , id , type , tries , colls , ratio , time , entry],
ML <- [none, 1 , 64],
@@ -132,30 +141,34 @@ locations(Config) when is_list(Config) ->
TH <- [{tries, Tries} || Tries <- THs] ++ [{colls, Colls} || Colls <- THs] ++ [{time, Time} || Time <- THs],
Id <- [true, false]
],
- ?line ok = test_locations_opts(Opts),
- ?line ok = lcnt:stop(),
- ok.
+ ok = test_locations_opts(Opts),
+ ok = lcnt:stop(),
+ t_locations_file(Files).
test_locations_opts([]) -> ok;
test_locations_opts([Opt|Opts]) ->
- ?line ok = lcnt:locations(Opt),
+ ok = lcnt:locations(Opt),
test_locations_opts(Opts).
-swap_keys(suite) ->
- [];
-swap_keys(doc) ->
- ["Test interchanging port/process id with class"];
-swap_keys(Config) when is_list(Config) ->
- ?line {ok, _} = lcnt:start(),
- ?line Path = ?config(data_dir, Config),
- ?line File = filename:join([Path,"big_bang_40.lcnt"]),
- ?line ok = lcnt:load(File),
- ?line ok = lcnt:conflicts(),
- ?line ok = lcnt:swap_pid_keys(),
- ?line ok = lcnt:conflicts(),
- ?line ok = lcnt:stop(),
+t_swap_keys(suite) -> [];
+t_swap_keys(doc) -> ["Test interchanging port/process id with class"];
+t_swap_keys(Config) when is_list(Config) ->
+ Path = ?config(data_dir, Config),
+ Files = [filename:join([Path,"big_bang_40.lcnt"]),
+ filename:join([Path,"ehb_3_3_hist.lcnt"])],
+ ok = t_swap_keys_file(Files),
ok.
+t_swap_keys_file([]) -> ok;
+t_swap_keys_file([File|Files]) ->
+ {ok, _} = lcnt:start(),
+ ok = lcnt:load(File),
+ ok = lcnt:conflicts(),
+ ok = lcnt:swap_pid_keys(),
+ ok = lcnt:conflicts(),
+ ok = lcnt:stop(),
+ t_swap_keys_file(Files).
+
%%----------------------------------------------------------------------
%% Auxiliary tests
diff --git a/lib/tools/test/lcnt_SUITE_data/ehb_3_3_hist.lcnt b/lib/tools/test/lcnt_SUITE_data/ehb_3_3_hist.lcnt
new file mode 100644
index 0000000000..ff5bdcbdaa
--- /dev/null
+++ b/lib/tools/test/lcnt_SUITE_data/ehb_3_3_hist.lcnt
Binary files differ
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index 353275ae3b..6870aefe5c 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -1098,7 +1098,6 @@ read_expected(Version) ->
{POS1+1,{FF,{mod17,fun17,0}}},
{POS1+2,{FF,{erlang,spawn,1}}},
{POS1+2,{FF,{read,local,0}}},
- {POS1+3,{FF,{erlang,binary_to_term,1}}},
{POS1+3,{FF,{erlang,spawn,1}}},
{POS1+4,{FF,{dist,func,0}}},
{POS1+4,{FF,{erlang,spawn,1}}},
@@ -1207,6 +1206,7 @@ read_expected(Version) ->
OKB1 = [{POS13+1,{FF,{erts_debug,apply,4}}},
{POS13+2,{FF,{erts_debug,apply,4}}},
{POS13+3,{FF,{erts_debug,apply,4}}},
+ {POS1+3, {FF,{erlang,binary_to_term,1}}},
{POS3+1, {FF,{erlang,spawn,3}}},
{POS3+2, {FF,{erlang,spawn,3}}},
{POS3+3, {FF,{erlang,spawn_link,3}}},
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 2d2970de3a..54dc4ec91d 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.6.14
+TOOLS_VSN = 2.6.15
diff --git a/lib/typer/doc/src/notes.xml b/lib/typer/doc/src/notes.xml
index 53d554820d..23e22759d6 100644
--- a/lib/typer/doc/src/notes.xml
+++ b/lib/typer/doc/src/notes.xml
@@ -30,6 +30,21 @@
</header>
<p>This document describes the changes made to TypEr.</p>
+<section><title>TypEr 0.9.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The name of a compiler option has been fixed in the
+ Makefile. </p>
+ <p>
+ Own Id: OTP-11996</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>TypEr 0.9.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/typer/vsn.mk b/lib/typer/vsn.mk
index 9cc044c621..ce658e257b 100644
--- a/lib/typer/vsn.mk
+++ b/lib/typer/vsn.mk
@@ -1 +1 @@
-TYPER_VSN = 0.9.7
+TYPER_VSN = 0.9.8
diff --git a/lib/wx/api_gen/wx_doxygen.conf b/lib/wx/api_gen/wx_doxygen.conf
index a8516aa08e..f4d3c99ec0 100644
--- a/lib/wx/api_gen/wx_doxygen.conf
+++ b/lib/wx/api_gen/wx_doxygen.conf
@@ -249,6 +249,7 @@ PREDEFINED = \
wxUSE_DATAOBJ=1 \
wxUSE_SLIDER=1 \
wxUSE_CLIPBOARD=1 \
+ wxUSE_POPUPWIN=1 \
wxUSE_SYSTEM_OPTIONS=1 \
wxUSE_INTL=1 \
wxABI_VERSION=20809 \
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 31ed1374c2..107d064f4a 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -71,7 +71,8 @@ gen_derived_dest_2(C=#class{name=Class, options=Opts}) ->
if Derived andalso (TaylorMade =:= false) ->
case lists:keysearch(ifdef,1,Opts) of
- {value, {ifdef, What}} -> w("#if ~p~n",[What]);
+ {value, {ifdef, What}} when is_list(What)-> w("#if ~s~n",[What]);
+ {value, {ifdef, What}} when is_atom(What) -> w("#if ~p~n",[What]);
_ -> ok
end,
w("class E~s : public ~s {~n",[Class,Class]),
@@ -190,13 +191,14 @@ gen_funcs(Defs) ->
%% w(" case WXE_REMOVE_PORT:~n", []),
%% w(" { destroyMemEnv(Ecmd.port); } break;~n", []),
w(" case DESTROY_OBJECT: {~n"),
- w(" wxObject *This = (wxObject *) getPtr(bp,memenv);~n"),
- w(" if(This) {~n"),
- w(" if(recurse_level > 1) {~n"),
+ w(" void *This = getPtr(bp,memenv);~n"),
+ w(" wxeRefData *refd = getRefData(This);~n"),
+ w(" if(This && refd) {~n"),
+ w(" if(recurse_level > 1 && refd->type != 4) {~n"),
w(" delayed_delete->Append(Ecmd.Save());~n"),
w(" } else {~n"),
- w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n"),
- w(" delete This; }~n"),
+ w(" ((WxeApp *) wxTheApp)->clearPtr(This);~n"),
+ w(" delete_object(This, refd); }~n"),
w(" } } break;~n"),
w(" case WXE_REGISTER_OBJECT: {~n"
" registerPid(bp, Ecmd.caller, memenv);~n"
@@ -270,7 +272,8 @@ gen_class(C=#class{name=Name,methods=Ms,options=Opts}) ->
false ->
case lists:keysearch(ifdef,1,Opts) of
{value, {ifdef, What}} ->
- w("#if ~p~n",[What]),
+ is_atom(What) andalso w("#if ~p~n",[What]),
+ is_list(What) andalso w("#if ~s~n",[What]),
Methods = lists:flatten(Ms),
MsR = [gen_method(Name,M) ||
M <- lists:keysort(#method.id, Methods)],
@@ -735,9 +738,13 @@ call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) ->
false -> 0
end;
false ->
- case hd(reverse(wx_gen_erl:parents(RClass))) of
- root -> Id;
- _ -> 1
+ case is_dc(RClass) of
+ true -> 4;
+ false ->
+ case hd(reverse(wx_gen_erl:parents(RClass))) of
+ root -> Id;
+ _ -> 1
+ end
end
end,
case virtual_dest(ClassDef) orelse (CType =/= 0) of
@@ -899,6 +906,10 @@ is_window(Class) ->
is_dialog(Class) ->
lists:member("wxDialog", wx_gen_erl:parents(Class)).
+is_dc(Class) ->
+ Parents = wx_gen_erl:parents(Class),
+ lists:member("wxDC", Parents) orelse lists:member("wxGraphicsContext", Parents).
+
build_return_vals(Type,Ps) ->
HaveType = case Type of void -> 0; _ -> 1 end,
NoOut = lists:sum([1 || #param{in=In} <- Ps, In =/= true]) + HaveType,
@@ -1097,6 +1108,7 @@ gen_macros() ->
w("#include <wx/listbook.h>~n"),
w("#include <wx/treebook.h>~n"),
w("#include <wx/taskbar.h>~n"),
+ w("#include <wx/popupwin.h>~n"),
w("#include <wx/html/htmlwin.h>~n"),
w("#include <wx/html/htmlcell.h>~n"),
w("#include <wx/filename.h>~n"),
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index 3a1dcc7ba5..2e961cce98 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -31,7 +31,8 @@
%%
wxALWAYS_NATIVE_DOUBLE_BUFFER,
wxGAUGE_EMULATE_INDETERMINATE_MODE,
- wxTR_DEFAULT_STYLE
+ wxTR_DEFAULT_STYLE,
+ wxSL_LABELS
]}.
{gvars,
@@ -877,6 +878,7 @@
{class, wxTextCtrl, wxControl, [],
['wxTextCtrl','~wxTextCtrl','AppendText','CanCopy','CanCut','CanPaste',
'CanRedo','CanUndo','Clear','Copy','Create','Cut','DiscardEdits',
+ 'ChangeValue',
'EmulateKeyPress','GetDefaultStyle','GetInsertionPoint','GetLastPosition',
'GetLineLength','GetLineText','GetNumberOfLines','GetRange','GetSelection',
'GetStringSelection','GetStyle','GetValue',%'HitTest', %no Mac
@@ -1902,3 +1904,14 @@
'GetSystemEncoding','GetSystemEncodingName',
'GetSystemLanguage',
'IsLoaded','IsOk']}.
+
+{class, wxActivateEvent, wxEvent,
+ [{acc, [{m_active, "GetActive()"}]},
+ {event, [wxEVT_ACTIVATE, wxEVT_ACTIVATE_APP, wxEVT_HIBERNATE]}],
+ ['GetActive']}.
+
+{class, wxPopupWindow, wxWindow, [{ifdef, wxUSE_POPUPWIN}],
+ ['wxPopupWindow', '~wxPopupWindow', 'Create', 'Position']}.
+
+{class, wxPopupTransientWindow, wxPopupWindow, [{ifdef, wxUSE_POPUPWIN}],
+ ['wxPopupTransientWindow', '~wxPopupTransientWindow', 'Popup', 'Dismiss']}.
diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h
index 42925bff3a..0a3765a910 100644
--- a/lib/wx/c_src/gen/wxe_derived_dest.h
+++ b/lib/wx/c_src/gen/wxe_derived_dest.h
@@ -770,3 +770,19 @@ class EwxLocale : public wxLocale {
EwxLocale() : wxLocale() {};
};
+#if wxUSE_POPUPWIN
+class EwxPopupWindow : public wxPopupWindow {
+ public: ~EwxPopupWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+ EwxPopupWindow(wxWindow * parent,int flags) : wxPopupWindow(parent,flags) {};
+ EwxPopupWindow() : wxPopupWindow() {};
+};
+#endif // wxUSE_POPUPWIN
+
+#if wxUSE_POPUPWIN
+class EwxPopupTransientWindow : public wxPopupTransientWindow {
+ public: ~EwxPopupTransientWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+ EwxPopupTransientWindow(wxWindow * parent,int style) : wxPopupTransientWindow(parent,style) {};
+ EwxPopupTransientWindow() : wxPopupTransientWindow() {};
+};
+#endif // wxUSE_POPUPWIN
+
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index 0ca059ead4..255b36c2fa 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -298,6 +298,9 @@ void initEventTable()
{wxEVT_TASKBAR_LEFT_DCLICK, 228, "taskbar_left_dclick"},
{wxEVT_TASKBAR_RIGHT_DCLICK, 228, "taskbar_right_dclick"},
{wxEVT_INIT_DIALOG, 229, "init_dialog"},
+ {wxEVT_ACTIVATE, 231, "activate"},
+ {wxEVT_ACTIVATE_APP, 231, "activate_app"},
+ {wxEVT_HIBERNATE, 231, "hibernate"},
{-1, 0, }
};
for(int i=0; event_types[i].ev_type != -1; i++) {
@@ -812,6 +815,15 @@ case 229: {// wxInitDialogEvent
rt.addTupleCount(2);
break;
}
+case 231: {// wxActivateEvent
+ wxActivateEvent * ev = (wxActivateEvent *) event;
+ evClass = (char*)"wxActivateEvent";
+ rt.addAtom((char*)"wxActivate");
+ rt.addAtom(Etype->eName);
+ rt.addBool(ev->GetActive());
+ rt.addTupleCount(3);
+ break;
+}
}
rt.addTupleCount(5);
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index c1e9f3829a..91ce5d810c 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -45,13 +45,14 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd)
switch (Ecmd.op)
{
case DESTROY_OBJECT: {
- wxObject *This = (wxObject *) getPtr(bp,memenv);
- if(This) {
- if(recurse_level > 1) {
+ void *This = getPtr(bp,memenv);
+ wxeRefData *refd = getRefData(This);
+ if(This && refd) {
+ if(recurse_level > 1 && refd->type != 4) {
delayed_delete->Append(Ecmd.Save());
} else {
- ((WxeApp *) wxTheApp)->clearPtr((void *) This);
- delete This; }
+ ((WxeApp *) wxTheApp)->clearPtr(This);
+ delete_object(This, refd); }
} } break;
case WXE_REGISTER_OBJECT: {
registerPid(bp, Ecmd.caller, memenv);
@@ -5843,26 +5844,26 @@ case wxMirrorDC_new: { // wxMirrorDC::wxMirrorDC
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
bool * mirror = (bool *) bp; bp += 4;
wxMirrorDC * Result = new EwxMirrorDC(*dc,*mirror);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMirrorDC");
break;
}
case wxScreenDC_new: { // wxScreenDC::wxScreenDC
wxScreenDC * Result = new EwxScreenDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxScreenDC");
break;
}
case wxPostScriptDC_new_0: { // wxPostScriptDC::wxPostScriptDC
wxPostScriptDC * Result = new EwxPostScriptDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPostScriptDC");
break;
}
case wxPostScriptDC_new_1: { // wxPostScriptDC::wxPostScriptDC
wxPrintData *printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPostScriptDC * Result = new EwxPostScriptDC(*printData);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPostScriptDC");
break;
}
@@ -5883,7 +5884,7 @@ case wxPostScriptDC_GetResolution: { // wxPostScriptDC::GetResolution
#if !wxCHECK_VERSION(2,9,0)
case wxWindowDC_new_0: { // wxWindowDC::wxWindowDC
wxWindowDC * Result = new EwxWindowDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxWindowDC");
break;
}
@@ -5891,14 +5892,14 @@ case wxWindowDC_new_0: { // wxWindowDC::wxWindowDC
case wxWindowDC_new_1: { // wxWindowDC::wxWindowDC
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindowDC * Result = new EwxWindowDC(win);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxWindowDC");
break;
}
#if !wxCHECK_VERSION(2,9,0)
case wxClientDC_new_0: { // wxClientDC::wxClientDC
wxClientDC * Result = new EwxClientDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxClientDC");
break;
}
@@ -5906,14 +5907,14 @@ case wxClientDC_new_0: { // wxClientDC::wxClientDC
case wxClientDC_new_1: { // wxClientDC::wxClientDC
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxClientDC * Result = new EwxClientDC(win);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxClientDC");
break;
}
#if !wxCHECK_VERSION(2,9,0)
case wxPaintDC_new_0: { // wxPaintDC::wxPaintDC
wxPaintDC * Result = new EwxPaintDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPaintDC");
break;
}
@@ -5921,27 +5922,27 @@ case wxPaintDC_new_0: { // wxPaintDC::wxPaintDC
case wxPaintDC_new_1: { // wxPaintDC::wxPaintDC
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPaintDC * Result = new EwxPaintDC(win);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPaintDC");
break;
}
case wxMemoryDC_new_1_0: { // wxMemoryDC::wxMemoryDC
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxMemoryDC * Result = new EwxMemoryDC(*bitmap);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMemoryDC");
break;
}
case wxMemoryDC_new_1_1: { // wxMemoryDC::wxMemoryDC
wxDC * dc = (wxDC *) getPtr(bp,memenv); bp += 4;
wxMemoryDC * Result = new EwxMemoryDC(dc);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMemoryDC");
break;
}
case wxMemoryDC_new_0: { // wxMemoryDC::wxMemoryDC
wxMemoryDC * Result = new EwxMemoryDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMemoryDC");
break;
}
@@ -5961,7 +5962,7 @@ case wxMemoryDC_SelectObjectAsSource: { // wxMemoryDC::SelectObjectAsSource
}
case wxBufferedDC_new_0: { // wxBufferedDC::wxBufferedDC
wxBufferedDC * Result = new EwxBufferedDC();
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedDC");
break;
}
@@ -5979,7 +5980,7 @@ buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
}};
wxBufferedDC * Result = new EwxBufferedDC(dc,*buffer,style);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedDC");
break;
}
@@ -5996,7 +5997,7 @@ case wxBufferedDC_new_3: { // wxBufferedDC::wxBufferedDC
} break;
}};
wxBufferedDC * Result = new EwxBufferedDC(dc,area,style);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedDC");
break;
}
@@ -6043,7 +6044,7 @@ case wxBufferedPaintDC_new_3: { // wxBufferedPaintDC::wxBufferedPaintDC
} break;
}};
wxBufferedPaintDC * Result = new EwxBufferedPaintDC(window,*buffer,style);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedPaintDC");
break;
}
@@ -6057,7 +6058,7 @@ case wxBufferedPaintDC_new_2: { // wxBufferedPaintDC::wxBufferedPaintDC
} break;
}};
wxBufferedPaintDC * Result = new EwxBufferedPaintDC(window,style);
- newPtr((void *) Result, 1, memenv);
+ newPtr((void *) Result, 4, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedPaintDC");
break;
}
@@ -16774,6 +16775,15 @@ case wxTextCtrl_DiscardEdits: { // wxTextCtrl::DiscardEdits
This->DiscardEdits();
break;
}
+case wxTextCtrl_ChangeValue: { // wxTextCtrl::ChangeValue
+ wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
+ int * valueLen = (int *) bp; bp += 4;
+ wxString value = wxString(bp, wxConvUTF8);
+ bp += *valueLen+((8-((0+ *valueLen) & 7)) & 7);
+ if(!This) throw wxe_badarg(0);
+ This->ChangeValue(value);
+ break;
+}
case wxTextCtrl_EmulateKeyPress: { // wxTextCtrl::EmulateKeyPress
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
wxKeyEvent *event = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
@@ -31627,6 +31637,102 @@ case wxLocale_IsOk: { // wxLocale::IsOk
rt.addBool(Result);
break;
}
+case wxActivateEvent_GetActive: { // wxActivateEvent::GetActive
+ wxActivateEvent *This = (wxActivateEvent *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ bool Result = This->GetActive();
+ rt.addBool(Result);
+ break;
+}
+#if wxUSE_POPUPWIN
+case wxPopupWindow_new_2: { // wxPopupWindow::wxPopupWindow
+ int flags=wxBORDER_NONE;
+ wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ while( * (int*) bp) { switch (* (int*) bp) {
+ case 1: {bp += 4;
+ flags = (int)*(int *) bp; bp += 4;
+ } break;
+ }};
+ wxPopupWindow * Result = new EwxPopupWindow(parent,flags);
+ newPtr((void *) Result, 0, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxPopupWindow");
+ break;
+}
+case wxPopupWindow_new_0: { // wxPopupWindow::wxPopupWindow
+ wxPopupWindow * Result = new EwxPopupWindow();
+ newPtr((void *) Result, 0, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxPopupWindow");
+ break;
+}
+case wxPopupWindow_Create: { // wxPopupWindow::Create
+ int flags=wxBORDER_NONE;
+ wxPopupWindow *This = (wxPopupWindow *) getPtr(bp,memenv); bp += 4;
+ wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ while( * (int*) bp) { switch (* (int*) bp) {
+ case 1: {bp += 4;
+ flags = (int)*(int *) bp; bp += 4;
+ } break;
+ }};
+ if(!This) throw wxe_badarg(0);
+ bool Result = This->Create(parent,flags);
+ rt.addBool(Result);
+ break;
+}
+case wxPopupWindow_Position: { // wxPopupWindow::Position
+ wxPopupWindow *This = (wxPopupWindow *) getPtr(bp,memenv); bp += 4;
+ int * ptOriginX = (int *) bp; bp += 4;
+ int * ptOriginY = (int *) bp; bp += 4;
+ wxPoint ptOrigin = wxPoint(*ptOriginX,*ptOriginY);
+ int * sizeW = (int *) bp; bp += 4;
+ int * sizeH = (int *) bp; bp += 4;
+ wxSize size = wxSize(*sizeW,*sizeH);
+ if(!This) throw wxe_badarg(0);
+ This->Position(ptOrigin,size);
+ break;
+}
+#endif // wxUSE_POPUPWIN
+#if wxUSE_POPUPWIN
+case wxPopupTransientWindow_new_0: { // wxPopupTransientWindow::wxPopupTransientWindow
+ wxPopupTransientWindow * Result = new EwxPopupTransientWindow();
+ newPtr((void *) Result, 0, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxPopupTransientWindow");
+ break;
+}
+case wxPopupTransientWindow_new_2: { // wxPopupTransientWindow::wxPopupTransientWindow
+ int style=wxBORDER_NONE;
+ wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ while( * (int*) bp) { switch (* (int*) bp) {
+ case 1: {bp += 4;
+ style = (int)*(int *) bp; bp += 4;
+ } break;
+ }};
+ wxPopupTransientWindow * Result = new EwxPopupTransientWindow(parent,style);
+ newPtr((void *) Result, 0, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxPopupTransientWindow");
+ break;
+}
+case wxPopupTransientWindow_Popup: { // wxPopupTransientWindow::Popup
+ wxWindow * focus=NULL;
+ wxPopupTransientWindow *This = (wxPopupTransientWindow *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ while( * (int*) bp) { switch (* (int*) bp) {
+ case 1: {bp += 4;
+focus = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ } break;
+ }};
+ if(!This) throw wxe_badarg(0);
+ This->Popup(focus);
+ break;
+}
+case wxPopupTransientWindow_Dismiss: { // wxPopupTransientWindow::Dismiss
+ wxPopupTransientWindow *This = (wxPopupTransientWindow *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->Dismiss();
+ break;
+}
+#endif // wxUSE_POPUPWIN
default: {
wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_");
error.addInt((int) Ecmd.op);
diff --git a/lib/wx/c_src/gen/wxe_init.cpp b/lib/wx/c_src/gen/wxe_init.cpp
index a75298392b..3a4bced790 100644
--- a/lib/wx/c_src/gen/wxe_init.cpp
+++ b/lib/wx/c_src/gen/wxe_init.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2014. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -36,6 +36,8 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {
rt.addTupleCount(2);
rt.addAtom("wxGAUGE_EMULATE_INDETERMINATE_MODE"); rt.addInt(wxGAUGE_EMULATE_INDETERMINATE_MODE);
rt.addTupleCount(2);
+ rt.addAtom("wxSL_LABELS"); rt.addInt(wxSL_LABELS);
+ rt.addTupleCount(2);
rt.addAtom("wxTR_DEFAULT_STYLE"); rt.addInt(wxTR_DEFAULT_STYLE);
rt.addTupleCount(2);
rt.addAtom("wxBETA_NUMBER"); rt.addInt(wxBETA_NUMBER);
@@ -136,7 +138,7 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {
rt.addTupleCount(2);
rt.addAtom("wxWHITE_PEN"); rt.addRef(getRef((void *)wxWHITE_PEN,memenv),"wxPen");
rt.addTupleCount(2);
- rt.endList(56);
+ rt.endList(57);
rt.addTupleCount(2);
rt.send();
}
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index 2da24f5d5e..c8ca9bfe5b 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -58,6 +58,7 @@
#include <wx/listbook.h>
#include <wx/treebook.h>
#include <wx/taskbar.h>
+#include <wx/popupwin.h>
#include <wx/html/htmlwin.h>
#include <wx/html/htmlcell.h>
#include <wx/filename.h>
@@ -1716,1664 +1717,1676 @@
#define wxTextCtrl_Create 1824
#define wxTextCtrl_Cut 1825
#define wxTextCtrl_DiscardEdits 1826
-#define wxTextCtrl_EmulateKeyPress 1827
-#define wxTextCtrl_GetDefaultStyle 1828
-#define wxTextCtrl_GetInsertionPoint 1829
-#define wxTextCtrl_GetLastPosition 1830
-#define wxTextCtrl_GetLineLength 1831
-#define wxTextCtrl_GetLineText 1832
-#define wxTextCtrl_GetNumberOfLines 1833
-#define wxTextCtrl_GetRange 1834
-#define wxTextCtrl_GetSelection 1835
-#define wxTextCtrl_GetStringSelection 1836
-#define wxTextCtrl_GetStyle 1837
-#define wxTextCtrl_GetValue 1838
-#define wxTextCtrl_IsEditable 1839
-#define wxTextCtrl_IsModified 1840
-#define wxTextCtrl_IsMultiLine 1841
-#define wxTextCtrl_IsSingleLine 1842
-#define wxTextCtrl_LoadFile 1843
-#define wxTextCtrl_MarkDirty 1844
-#define wxTextCtrl_Paste 1845
-#define wxTextCtrl_PositionToXY 1846
-#define wxTextCtrl_Redo 1847
-#define wxTextCtrl_Remove 1848
-#define wxTextCtrl_Replace 1849
-#define wxTextCtrl_SaveFile 1850
-#define wxTextCtrl_SetDefaultStyle 1851
-#define wxTextCtrl_SetEditable 1852
-#define wxTextCtrl_SetInsertionPoint 1853
-#define wxTextCtrl_SetInsertionPointEnd 1854
-#define wxTextCtrl_SetMaxLength 1856
-#define wxTextCtrl_SetSelection 1857
-#define wxTextCtrl_SetStyle 1858
-#define wxTextCtrl_SetValue 1859
-#define wxTextCtrl_ShowPosition 1860
-#define wxTextCtrl_Undo 1861
-#define wxTextCtrl_WriteText 1862
-#define wxTextCtrl_XYToPosition 1863
-#define wxNotebook_new_0 1866
-#define wxNotebook_new_3 1867
-#define wxNotebook_destruct 1868
-#define wxNotebook_AddPage 1869
-#define wxNotebook_AdvanceSelection 1870
-#define wxNotebook_AssignImageList 1871
-#define wxNotebook_Create 1872
-#define wxNotebook_DeleteAllPages 1873
-#define wxNotebook_DeletePage 1874
-#define wxNotebook_RemovePage 1875
-#define wxNotebook_GetCurrentPage 1876
-#define wxNotebook_GetImageList 1877
-#define wxNotebook_GetPage 1879
-#define wxNotebook_GetPageCount 1880
-#define wxNotebook_GetPageImage 1881
-#define wxNotebook_GetPageText 1882
-#define wxNotebook_GetRowCount 1883
-#define wxNotebook_GetSelection 1884
-#define wxNotebook_GetThemeBackgroundColour 1885
-#define wxNotebook_HitTest 1887
-#define wxNotebook_InsertPage 1889
-#define wxNotebook_SetImageList 1890
-#define wxNotebook_SetPadding 1891
-#define wxNotebook_SetPageSize 1892
-#define wxNotebook_SetPageImage 1893
-#define wxNotebook_SetPageText 1894
-#define wxNotebook_SetSelection 1895
-#define wxNotebook_ChangeSelection 1896
-#define wxChoicebook_new_0 1897
-#define wxChoicebook_new_3 1898
-#define wxChoicebook_AddPage 1899
-#define wxChoicebook_AdvanceSelection 1900
-#define wxChoicebook_AssignImageList 1901
-#define wxChoicebook_Create 1902
-#define wxChoicebook_DeleteAllPages 1903
-#define wxChoicebook_DeletePage 1904
-#define wxChoicebook_RemovePage 1905
-#define wxChoicebook_GetCurrentPage 1906
-#define wxChoicebook_GetImageList 1907
-#define wxChoicebook_GetPage 1909
-#define wxChoicebook_GetPageCount 1910
-#define wxChoicebook_GetPageImage 1911
-#define wxChoicebook_GetPageText 1912
-#define wxChoicebook_GetSelection 1913
-#define wxChoicebook_HitTest 1914
-#define wxChoicebook_InsertPage 1915
-#define wxChoicebook_SetImageList 1916
-#define wxChoicebook_SetPageSize 1917
-#define wxChoicebook_SetPageImage 1918
-#define wxChoicebook_SetPageText 1919
-#define wxChoicebook_SetSelection 1920
-#define wxChoicebook_ChangeSelection 1921
-#define wxChoicebook_destroy 1922
-#define wxToolbook_new_0 1923
-#define wxToolbook_new_3 1924
-#define wxToolbook_AddPage 1925
-#define wxToolbook_AdvanceSelection 1926
-#define wxToolbook_AssignImageList 1927
-#define wxToolbook_Create 1928
-#define wxToolbook_DeleteAllPages 1929
-#define wxToolbook_DeletePage 1930
-#define wxToolbook_RemovePage 1931
-#define wxToolbook_GetCurrentPage 1932
-#define wxToolbook_GetImageList 1933
-#define wxToolbook_GetPage 1935
-#define wxToolbook_GetPageCount 1936
-#define wxToolbook_GetPageImage 1937
-#define wxToolbook_GetPageText 1938
-#define wxToolbook_GetSelection 1939
-#define wxToolbook_HitTest 1941
-#define wxToolbook_InsertPage 1942
-#define wxToolbook_SetImageList 1943
-#define wxToolbook_SetPageSize 1944
-#define wxToolbook_SetPageImage 1945
-#define wxToolbook_SetPageText 1946
-#define wxToolbook_SetSelection 1947
-#define wxToolbook_ChangeSelection 1948
-#define wxToolbook_destroy 1949
-#define wxListbook_new_0 1950
-#define wxListbook_new_3 1951
-#define wxListbook_AddPage 1952
-#define wxListbook_AdvanceSelection 1953
-#define wxListbook_AssignImageList 1954
-#define wxListbook_Create 1955
-#define wxListbook_DeleteAllPages 1956
-#define wxListbook_DeletePage 1957
-#define wxListbook_RemovePage 1958
-#define wxListbook_GetCurrentPage 1959
-#define wxListbook_GetImageList 1960
-#define wxListbook_GetPage 1962
-#define wxListbook_GetPageCount 1963
-#define wxListbook_GetPageImage 1964
-#define wxListbook_GetPageText 1965
-#define wxListbook_GetSelection 1966
-#define wxListbook_HitTest 1968
-#define wxListbook_InsertPage 1969
-#define wxListbook_SetImageList 1970
-#define wxListbook_SetPageSize 1971
-#define wxListbook_SetPageImage 1972
-#define wxListbook_SetPageText 1973
-#define wxListbook_SetSelection 1974
-#define wxListbook_ChangeSelection 1975
-#define wxListbook_destroy 1976
-#define wxTreebook_new_0 1977
-#define wxTreebook_new_3 1978
-#define wxTreebook_AddPage 1979
-#define wxTreebook_AdvanceSelection 1980
-#define wxTreebook_AssignImageList 1981
-#define wxTreebook_Create 1982
-#define wxTreebook_DeleteAllPages 1983
-#define wxTreebook_DeletePage 1984
-#define wxTreebook_RemovePage 1985
-#define wxTreebook_GetCurrentPage 1986
-#define wxTreebook_GetImageList 1987
-#define wxTreebook_GetPage 1989
-#define wxTreebook_GetPageCount 1990
-#define wxTreebook_GetPageImage 1991
-#define wxTreebook_GetPageText 1992
-#define wxTreebook_GetSelection 1993
-#define wxTreebook_ExpandNode 1994
-#define wxTreebook_IsNodeExpanded 1995
-#define wxTreebook_HitTest 1997
-#define wxTreebook_InsertPage 1998
-#define wxTreebook_InsertSubPage 1999
-#define wxTreebook_SetImageList 2000
-#define wxTreebook_SetPageSize 2001
-#define wxTreebook_SetPageImage 2002
-#define wxTreebook_SetPageText 2003
-#define wxTreebook_SetSelection 2004
-#define wxTreebook_ChangeSelection 2005
-#define wxTreebook_destroy 2006
-#define wxTreeCtrl_new_2 2009
-#define wxTreeCtrl_new_0 2010
-#define wxTreeCtrl_destruct 2012
-#define wxTreeCtrl_AddRoot 2013
-#define wxTreeCtrl_AppendItem 2014
-#define wxTreeCtrl_AssignImageList 2015
-#define wxTreeCtrl_AssignStateImageList 2016
-#define wxTreeCtrl_Collapse 2017
-#define wxTreeCtrl_CollapseAndReset 2018
-#define wxTreeCtrl_Create 2019
-#define wxTreeCtrl_Delete 2020
-#define wxTreeCtrl_DeleteAllItems 2021
-#define wxTreeCtrl_DeleteChildren 2022
-#define wxTreeCtrl_EditLabel 2023
-#define wxTreeCtrl_EnsureVisible 2024
-#define wxTreeCtrl_Expand 2025
-#define wxTreeCtrl_GetBoundingRect 2026
-#define wxTreeCtrl_GetChildrenCount 2028
-#define wxTreeCtrl_GetCount 2029
-#define wxTreeCtrl_GetEditControl 2030
-#define wxTreeCtrl_GetFirstChild 2031
-#define wxTreeCtrl_GetNextChild 2032
-#define wxTreeCtrl_GetFirstVisibleItem 2033
-#define wxTreeCtrl_GetImageList 2034
-#define wxTreeCtrl_GetIndent 2035
-#define wxTreeCtrl_GetItemBackgroundColour 2036
-#define wxTreeCtrl_GetItemData 2037
-#define wxTreeCtrl_GetItemFont 2038
-#define wxTreeCtrl_GetItemImage_1 2039
-#define wxTreeCtrl_GetItemImage_2 2040
-#define wxTreeCtrl_GetItemText 2041
-#define wxTreeCtrl_GetItemTextColour 2042
-#define wxTreeCtrl_GetLastChild 2043
-#define wxTreeCtrl_GetNextSibling 2044
-#define wxTreeCtrl_GetNextVisible 2045
-#define wxTreeCtrl_GetItemParent 2046
-#define wxTreeCtrl_GetPrevSibling 2047
-#define wxTreeCtrl_GetPrevVisible 2048
-#define wxTreeCtrl_GetRootItem 2049
-#define wxTreeCtrl_GetSelection 2050
-#define wxTreeCtrl_GetSelections 2051
-#define wxTreeCtrl_GetStateImageList 2052
-#define wxTreeCtrl_HitTest 2053
-#define wxTreeCtrl_InsertItem 2055
-#define wxTreeCtrl_IsBold 2056
-#define wxTreeCtrl_IsExpanded 2057
-#define wxTreeCtrl_IsSelected 2058
-#define wxTreeCtrl_IsVisible 2059
-#define wxTreeCtrl_ItemHasChildren 2060
-#define wxTreeCtrl_IsTreeItemIdOk 2061
-#define wxTreeCtrl_PrependItem 2062
-#define wxTreeCtrl_ScrollTo 2063
-#define wxTreeCtrl_SelectItem_1 2064
-#define wxTreeCtrl_SelectItem_2 2065
-#define wxTreeCtrl_SetIndent 2066
-#define wxTreeCtrl_SetImageList 2067
-#define wxTreeCtrl_SetItemBackgroundColour 2068
-#define wxTreeCtrl_SetItemBold 2069
-#define wxTreeCtrl_SetItemData 2070
-#define wxTreeCtrl_SetItemDropHighlight 2071
-#define wxTreeCtrl_SetItemFont 2072
-#define wxTreeCtrl_SetItemHasChildren 2073
-#define wxTreeCtrl_SetItemImage_2 2074
-#define wxTreeCtrl_SetItemImage_3 2075
-#define wxTreeCtrl_SetItemText 2076
-#define wxTreeCtrl_SetItemTextColour 2077
-#define wxTreeCtrl_SetStateImageList 2078
-#define wxTreeCtrl_SetWindowStyle 2079
-#define wxTreeCtrl_SortChildren 2080
-#define wxTreeCtrl_Toggle 2081
-#define wxTreeCtrl_ToggleItemSelection 2082
-#define wxTreeCtrl_Unselect 2083
-#define wxTreeCtrl_UnselectAll 2084
-#define wxTreeCtrl_UnselectItem 2085
-#define wxScrollBar_new_0 2086
-#define wxScrollBar_new_3 2087
-#define wxScrollBar_destruct 2088
-#define wxScrollBar_Create 2089
-#define wxScrollBar_GetRange 2090
-#define wxScrollBar_GetPageSize 2091
-#define wxScrollBar_GetThumbPosition 2092
-#define wxScrollBar_GetThumbSize 2093
-#define wxScrollBar_SetThumbPosition 2094
-#define wxScrollBar_SetScrollbar 2095
-#define wxSpinButton_new_2 2097
-#define wxSpinButton_new_0 2098
-#define wxSpinButton_Create 2099
-#define wxSpinButton_GetMax 2100
-#define wxSpinButton_GetMin 2101
-#define wxSpinButton_GetValue 2102
-#define wxSpinButton_SetRange 2103
-#define wxSpinButton_SetValue 2104
-#define wxSpinButton_destroy 2105
-#define wxSpinCtrl_new_0 2106
-#define wxSpinCtrl_new_2 2107
-#define wxSpinCtrl_Create 2109
-#define wxSpinCtrl_SetValue_1_1 2112
-#define wxSpinCtrl_SetValue_1_0 2113
-#define wxSpinCtrl_GetValue 2115
-#define wxSpinCtrl_SetRange 2117
-#define wxSpinCtrl_SetSelection 2118
-#define wxSpinCtrl_GetMin 2120
-#define wxSpinCtrl_GetMax 2122
-#define wxSpinCtrl_destroy 2123
-#define wxStaticText_new_0 2124
-#define wxStaticText_new_4 2125
-#define wxStaticText_Create 2126
-#define wxStaticText_GetLabel 2127
-#define wxStaticText_SetLabel 2128
-#define wxStaticText_Wrap 2129
-#define wxStaticText_destroy 2130
-#define wxStaticBitmap_new_0 2131
-#define wxStaticBitmap_new_4 2132
-#define wxStaticBitmap_Create 2133
-#define wxStaticBitmap_GetBitmap 2134
-#define wxStaticBitmap_SetBitmap 2135
-#define wxStaticBitmap_destroy 2136
-#define wxRadioBox_new 2137
-#define wxRadioBox_destruct 2139
-#define wxRadioBox_Create 2140
-#define wxRadioBox_Enable_2 2141
-#define wxRadioBox_Enable_1 2142
-#define wxRadioBox_GetSelection 2143
-#define wxRadioBox_GetString 2144
-#define wxRadioBox_SetSelection 2145
-#define wxRadioBox_Show_2 2146
-#define wxRadioBox_Show_1 2147
-#define wxRadioBox_GetColumnCount 2148
-#define wxRadioBox_GetItemHelpText 2149
-#define wxRadioBox_GetItemToolTip 2150
-#define wxRadioBox_GetItemFromPoint 2152
-#define wxRadioBox_GetRowCount 2153
-#define wxRadioBox_IsItemEnabled 2154
-#define wxRadioBox_IsItemShown 2155
-#define wxRadioBox_SetItemHelpText 2156
-#define wxRadioBox_SetItemToolTip 2157
-#define wxRadioButton_new_0 2158
-#define wxRadioButton_new_4 2159
-#define wxRadioButton_Create 2160
-#define wxRadioButton_GetValue 2161
-#define wxRadioButton_SetValue 2162
-#define wxRadioButton_destroy 2163
-#define wxSlider_new_6 2165
-#define wxSlider_new_0 2166
-#define wxSlider_Create 2167
-#define wxSlider_GetLineSize 2168
-#define wxSlider_GetMax 2169
-#define wxSlider_GetMin 2170
-#define wxSlider_GetPageSize 2171
-#define wxSlider_GetThumbLength 2172
-#define wxSlider_GetValue 2173
-#define wxSlider_SetLineSize 2174
-#define wxSlider_SetPageSize 2175
-#define wxSlider_SetRange 2176
-#define wxSlider_SetThumbLength 2177
-#define wxSlider_SetValue 2178
-#define wxSlider_destroy 2179
-#define wxDialog_new_4 2181
-#define wxDialog_new_0 2182
-#define wxDialog_destruct 2184
-#define wxDialog_Create 2185
-#define wxDialog_CreateButtonSizer 2186
-#define wxDialog_CreateStdDialogButtonSizer 2187
-#define wxDialog_EndModal 2188
-#define wxDialog_GetAffirmativeId 2189
-#define wxDialog_GetReturnCode 2190
-#define wxDialog_IsModal 2191
-#define wxDialog_SetAffirmativeId 2192
-#define wxDialog_SetReturnCode 2193
-#define wxDialog_Show 2194
-#define wxDialog_ShowModal 2195
-#define wxColourDialog_new_0 2196
-#define wxColourDialog_new_2 2197
-#define wxColourDialog_destruct 2198
-#define wxColourDialog_Create 2199
-#define wxColourDialog_GetColourData 2200
-#define wxColourData_new_0 2201
-#define wxColourData_new_1 2202
-#define wxColourData_destruct 2203
-#define wxColourData_GetChooseFull 2204
-#define wxColourData_GetColour 2205
-#define wxColourData_GetCustomColour 2207
-#define wxColourData_SetChooseFull 2208
-#define wxColourData_SetColour 2209
-#define wxColourData_SetCustomColour 2210
-#define wxPalette_new_0 2211
-#define wxPalette_new_4 2212
-#define wxPalette_destruct 2214
-#define wxPalette_Create 2215
-#define wxPalette_GetColoursCount 2216
-#define wxPalette_GetPixel 2217
-#define wxPalette_GetRGB 2218
-#define wxPalette_IsOk 2219
-#define wxDirDialog_new 2223
-#define wxDirDialog_destruct 2224
-#define wxDirDialog_GetPath 2225
-#define wxDirDialog_GetMessage 2226
-#define wxDirDialog_SetMessage 2227
-#define wxDirDialog_SetPath 2228
-#define wxFileDialog_new 2232
-#define wxFileDialog_destruct 2233
-#define wxFileDialog_GetDirectory 2234
-#define wxFileDialog_GetFilename 2235
-#define wxFileDialog_GetFilenames 2236
-#define wxFileDialog_GetFilterIndex 2237
-#define wxFileDialog_GetMessage 2238
-#define wxFileDialog_GetPath 2239
-#define wxFileDialog_GetPaths 2240
-#define wxFileDialog_GetWildcard 2241
-#define wxFileDialog_SetDirectory 2242
-#define wxFileDialog_SetFilename 2243
-#define wxFileDialog_SetFilterIndex 2244
-#define wxFileDialog_SetMessage 2245
-#define wxFileDialog_SetPath 2246
-#define wxFileDialog_SetWildcard 2247
-#define wxPickerBase_SetInternalMargin 2248
-#define wxPickerBase_GetInternalMargin 2249
-#define wxPickerBase_SetTextCtrlProportion 2250
-#define wxPickerBase_SetPickerCtrlProportion 2251
-#define wxPickerBase_GetTextCtrlProportion 2252
-#define wxPickerBase_GetPickerCtrlProportion 2253
-#define wxPickerBase_HasTextCtrl 2254
-#define wxPickerBase_GetTextCtrl 2255
-#define wxPickerBase_IsTextCtrlGrowable 2256
-#define wxPickerBase_SetPickerCtrlGrowable 2257
-#define wxPickerBase_SetTextCtrlGrowable 2258
-#define wxPickerBase_IsPickerCtrlGrowable 2259
-#define wxFilePickerCtrl_new_0 2260
-#define wxFilePickerCtrl_new_3 2261
-#define wxFilePickerCtrl_Create 2262
-#define wxFilePickerCtrl_GetPath 2263
-#define wxFilePickerCtrl_SetPath 2264
-#define wxFilePickerCtrl_destroy 2265
-#define wxDirPickerCtrl_new_0 2266
-#define wxDirPickerCtrl_new_3 2267
-#define wxDirPickerCtrl_Create 2268
-#define wxDirPickerCtrl_GetPath 2269
-#define wxDirPickerCtrl_SetPath 2270
-#define wxDirPickerCtrl_destroy 2271
-#define wxColourPickerCtrl_new_0 2272
-#define wxColourPickerCtrl_new_3 2273
-#define wxColourPickerCtrl_Create 2274
-#define wxColourPickerCtrl_GetColour 2275
-#define wxColourPickerCtrl_SetColour_1_1 2276
-#define wxColourPickerCtrl_SetColour_1_0 2277
-#define wxColourPickerCtrl_destroy 2278
-#define wxDatePickerCtrl_new_0 2279
-#define wxDatePickerCtrl_new_3 2280
-#define wxDatePickerCtrl_GetRange 2281
-#define wxDatePickerCtrl_GetValue 2282
-#define wxDatePickerCtrl_SetRange 2283
-#define wxDatePickerCtrl_SetValue 2284
-#define wxDatePickerCtrl_destroy 2285
-#define wxFontPickerCtrl_new_0 2286
-#define wxFontPickerCtrl_new_3 2287
-#define wxFontPickerCtrl_Create 2288
-#define wxFontPickerCtrl_GetSelectedFont 2289
-#define wxFontPickerCtrl_SetSelectedFont 2290
-#define wxFontPickerCtrl_GetMaxPointSize 2291
-#define wxFontPickerCtrl_SetMaxPointSize 2292
-#define wxFontPickerCtrl_destroy 2293
-#define wxFindReplaceDialog_new_0 2296
-#define wxFindReplaceDialog_new_4 2297
-#define wxFindReplaceDialog_destruct 2298
-#define wxFindReplaceDialog_Create 2299
-#define wxFindReplaceDialog_GetData 2300
-#define wxFindReplaceData_new_0 2301
-#define wxFindReplaceData_new_1 2302
-#define wxFindReplaceData_GetFindString 2303
-#define wxFindReplaceData_GetReplaceString 2304
-#define wxFindReplaceData_GetFlags 2305
-#define wxFindReplaceData_SetFlags 2306
-#define wxFindReplaceData_SetFindString 2307
-#define wxFindReplaceData_SetReplaceString 2308
-#define wxFindReplaceData_destroy 2309
-#define wxMultiChoiceDialog_new_0 2310
-#define wxMultiChoiceDialog_new_5 2312
-#define wxMultiChoiceDialog_GetSelections 2313
-#define wxMultiChoiceDialog_SetSelections 2314
-#define wxMultiChoiceDialog_destroy 2315
-#define wxSingleChoiceDialog_new_0 2316
-#define wxSingleChoiceDialog_new_5 2318
-#define wxSingleChoiceDialog_GetSelection 2319
-#define wxSingleChoiceDialog_GetStringSelection 2320
-#define wxSingleChoiceDialog_SetSelection 2321
-#define wxSingleChoiceDialog_destroy 2322
-#define wxTextEntryDialog_new 2323
-#define wxTextEntryDialog_GetValue 2324
-#define wxTextEntryDialog_SetValue 2325
-#define wxTextEntryDialog_destroy 2326
-#define wxPasswordEntryDialog_new 2327
-#define wxPasswordEntryDialog_destroy 2328
-#define wxFontData_new_0 2329
-#define wxFontData_new_1 2330
-#define wxFontData_destruct 2331
-#define wxFontData_EnableEffects 2332
-#define wxFontData_GetAllowSymbols 2333
-#define wxFontData_GetColour 2334
-#define wxFontData_GetChosenFont 2335
-#define wxFontData_GetEnableEffects 2336
-#define wxFontData_GetInitialFont 2337
-#define wxFontData_GetShowHelp 2338
-#define wxFontData_SetAllowSymbols 2339
-#define wxFontData_SetChosenFont 2340
-#define wxFontData_SetColour 2341
-#define wxFontData_SetInitialFont 2342
-#define wxFontData_SetRange 2343
-#define wxFontData_SetShowHelp 2344
-#define wxFontDialog_new_0 2348
-#define wxFontDialog_new_2 2350
-#define wxFontDialog_Create 2352
-#define wxFontDialog_GetFontData 2353
-#define wxFontDialog_destroy 2355
-#define wxProgressDialog_new 2356
-#define wxProgressDialog_destruct 2357
-#define wxProgressDialog_Resume 2358
-#define wxProgressDialog_Update_2 2359
-#define wxProgressDialog_Update_0 2360
-#define wxMessageDialog_new 2361
-#define wxMessageDialog_destruct 2362
-#define wxPageSetupDialog_new 2363
-#define wxPageSetupDialog_destruct 2364
-#define wxPageSetupDialog_GetPageSetupData 2365
-#define wxPageSetupDialog_ShowModal 2366
-#define wxPageSetupDialogData_new_0 2367
-#define wxPageSetupDialogData_new_1_0 2368
-#define wxPageSetupDialogData_new_1_1 2369
-#define wxPageSetupDialogData_destruct 2370
-#define wxPageSetupDialogData_EnableHelp 2371
-#define wxPageSetupDialogData_EnableMargins 2372
-#define wxPageSetupDialogData_EnableOrientation 2373
-#define wxPageSetupDialogData_EnablePaper 2374
-#define wxPageSetupDialogData_EnablePrinter 2375
-#define wxPageSetupDialogData_GetDefaultMinMargins 2376
-#define wxPageSetupDialogData_GetEnableMargins 2377
-#define wxPageSetupDialogData_GetEnableOrientation 2378
-#define wxPageSetupDialogData_GetEnablePaper 2379
-#define wxPageSetupDialogData_GetEnablePrinter 2380
-#define wxPageSetupDialogData_GetEnableHelp 2381
-#define wxPageSetupDialogData_GetDefaultInfo 2382
-#define wxPageSetupDialogData_GetMarginTopLeft 2383
-#define wxPageSetupDialogData_GetMarginBottomRight 2384
-#define wxPageSetupDialogData_GetMinMarginTopLeft 2385
-#define wxPageSetupDialogData_GetMinMarginBottomRight 2386
-#define wxPageSetupDialogData_GetPaperId 2387
-#define wxPageSetupDialogData_GetPaperSize 2388
-#define wxPageSetupDialogData_GetPrintData 2390
-#define wxPageSetupDialogData_IsOk 2391
-#define wxPageSetupDialogData_SetDefaultInfo 2392
-#define wxPageSetupDialogData_SetDefaultMinMargins 2393
-#define wxPageSetupDialogData_SetMarginTopLeft 2394
-#define wxPageSetupDialogData_SetMarginBottomRight 2395
-#define wxPageSetupDialogData_SetMinMarginTopLeft 2396
-#define wxPageSetupDialogData_SetMinMarginBottomRight 2397
-#define wxPageSetupDialogData_SetPaperId 2398
-#define wxPageSetupDialogData_SetPaperSize_1_1 2399
-#define wxPageSetupDialogData_SetPaperSize_1_0 2400
-#define wxPageSetupDialogData_SetPrintData 2401
-#define wxPrintDialog_new_2_0 2402
-#define wxPrintDialog_new_2_1 2403
-#define wxPrintDialog_destruct 2404
-#define wxPrintDialog_GetPrintDialogData 2405
-#define wxPrintDialog_GetPrintDC 2406
-#define wxPrintDialogData_new_0 2407
-#define wxPrintDialogData_new_1_1 2408
-#define wxPrintDialogData_new_1_0 2409
-#define wxPrintDialogData_destruct 2410
-#define wxPrintDialogData_EnableHelp 2411
-#define wxPrintDialogData_EnablePageNumbers 2412
-#define wxPrintDialogData_EnablePrintToFile 2413
-#define wxPrintDialogData_EnableSelection 2414
-#define wxPrintDialogData_GetAllPages 2415
-#define wxPrintDialogData_GetCollate 2416
-#define wxPrintDialogData_GetFromPage 2417
-#define wxPrintDialogData_GetMaxPage 2418
-#define wxPrintDialogData_GetMinPage 2419
-#define wxPrintDialogData_GetNoCopies 2420
-#define wxPrintDialogData_GetPrintData 2421
-#define wxPrintDialogData_GetPrintToFile 2422
-#define wxPrintDialogData_GetSelection 2423
-#define wxPrintDialogData_GetToPage 2424
-#define wxPrintDialogData_IsOk 2425
-#define wxPrintDialogData_SetCollate 2426
-#define wxPrintDialogData_SetFromPage 2427
-#define wxPrintDialogData_SetMaxPage 2428
-#define wxPrintDialogData_SetMinPage 2429
-#define wxPrintDialogData_SetNoCopies 2430
-#define wxPrintDialogData_SetPrintData 2431
-#define wxPrintDialogData_SetPrintToFile 2432
-#define wxPrintDialogData_SetSelection 2433
-#define wxPrintDialogData_SetToPage 2434
-#define wxPrintData_new_0 2435
-#define wxPrintData_new_1 2436
-#define wxPrintData_destruct 2437
-#define wxPrintData_GetCollate 2438
-#define wxPrintData_GetBin 2439
-#define wxPrintData_GetColour 2440
-#define wxPrintData_GetDuplex 2441
-#define wxPrintData_GetNoCopies 2442
-#define wxPrintData_GetOrientation 2443
-#define wxPrintData_GetPaperId 2444
-#define wxPrintData_GetPrinterName 2445
-#define wxPrintData_GetQuality 2446
-#define wxPrintData_IsOk 2447
-#define wxPrintData_SetBin 2448
-#define wxPrintData_SetCollate 2449
-#define wxPrintData_SetColour 2450
-#define wxPrintData_SetDuplex 2451
-#define wxPrintData_SetNoCopies 2452
-#define wxPrintData_SetOrientation 2453
-#define wxPrintData_SetPaperId 2454
-#define wxPrintData_SetPrinterName 2455
-#define wxPrintData_SetQuality 2456
-#define wxPrintPreview_new_2 2459
-#define wxPrintPreview_new_3 2460
-#define wxPrintPreview_destruct 2462
-#define wxPrintPreview_GetCanvas 2463
-#define wxPrintPreview_GetCurrentPage 2464
-#define wxPrintPreview_GetFrame 2465
-#define wxPrintPreview_GetMaxPage 2466
-#define wxPrintPreview_GetMinPage 2467
-#define wxPrintPreview_GetPrintout 2468
-#define wxPrintPreview_GetPrintoutForPrinting 2469
-#define wxPrintPreview_IsOk 2470
-#define wxPrintPreview_PaintPage 2471
-#define wxPrintPreview_Print 2472
-#define wxPrintPreview_RenderPage 2473
-#define wxPrintPreview_SetCanvas 2474
-#define wxPrintPreview_SetCurrentPage 2475
-#define wxPrintPreview_SetFrame 2476
-#define wxPrintPreview_SetPrintout 2477
-#define wxPrintPreview_SetZoom 2478
-#define wxPreviewFrame_new 2479
-#define wxPreviewFrame_destruct 2480
-#define wxPreviewFrame_CreateControlBar 2481
-#define wxPreviewFrame_CreateCanvas 2482
-#define wxPreviewFrame_Initialize 2483
-#define wxPreviewFrame_OnCloseWindow 2484
-#define wxPreviewControlBar_new 2485
-#define wxPreviewControlBar_destruct 2486
-#define wxPreviewControlBar_CreateButtons 2487
-#define wxPreviewControlBar_GetPrintPreview 2488
-#define wxPreviewControlBar_GetZoomControl 2489
-#define wxPreviewControlBar_SetZoomControl 2490
-#define wxPrinter_new 2492
-#define wxPrinter_CreateAbortWindow 2493
-#define wxPrinter_GetAbort 2494
-#define wxPrinter_GetLastError 2495
-#define wxPrinter_GetPrintDialogData 2496
-#define wxPrinter_Print 2497
-#define wxPrinter_PrintDialog 2498
-#define wxPrinter_ReportError 2499
-#define wxPrinter_Setup 2500
-#define wxPrinter_destroy 2501
-#define wxXmlResource_new_1 2502
-#define wxXmlResource_new_2 2503
-#define wxXmlResource_destruct 2504
-#define wxXmlResource_AttachUnknownControl 2505
-#define wxXmlResource_ClearHandlers 2506
-#define wxXmlResource_CompareVersion 2507
-#define wxXmlResource_Get 2508
-#define wxXmlResource_GetFlags 2509
-#define wxXmlResource_GetVersion 2510
-#define wxXmlResource_GetXRCID 2511
-#define wxXmlResource_InitAllHandlers 2512
-#define wxXmlResource_Load 2513
-#define wxXmlResource_LoadBitmap 2514
-#define wxXmlResource_LoadDialog_2 2515
-#define wxXmlResource_LoadDialog_3 2516
-#define wxXmlResource_LoadFrame_2 2517
-#define wxXmlResource_LoadFrame_3 2518
-#define wxXmlResource_LoadIcon 2519
-#define wxXmlResource_LoadMenu 2520
-#define wxXmlResource_LoadMenuBar_2 2521
-#define wxXmlResource_LoadMenuBar_1 2522
-#define wxXmlResource_LoadPanel_2 2523
-#define wxXmlResource_LoadPanel_3 2524
-#define wxXmlResource_LoadToolBar 2525
-#define wxXmlResource_Set 2526
-#define wxXmlResource_SetFlags 2527
-#define wxXmlResource_Unload 2528
-#define wxXmlResource_xrcctrl 2529
-#define wxHtmlEasyPrinting_new 2530
-#define wxHtmlEasyPrinting_destruct 2531
-#define wxHtmlEasyPrinting_GetPrintData 2532
-#define wxHtmlEasyPrinting_GetPageSetupData 2533
-#define wxHtmlEasyPrinting_PreviewFile 2534
-#define wxHtmlEasyPrinting_PreviewText 2535
-#define wxHtmlEasyPrinting_PrintFile 2536
-#define wxHtmlEasyPrinting_PrintText 2537
-#define wxHtmlEasyPrinting_PageSetup 2538
-#define wxHtmlEasyPrinting_SetFonts 2539
-#define wxHtmlEasyPrinting_SetHeader 2540
-#define wxHtmlEasyPrinting_SetFooter 2541
-#define wxGLCanvas_new_2 2543
-#define wxGLCanvas_new_3_1 2544
-#define wxGLCanvas_new_3_0 2545
-#define wxGLCanvas_GetContext 2546
-#define wxGLCanvas_SetCurrent 2548
-#define wxGLCanvas_SwapBuffers 2549
-#define wxGLCanvas_destroy 2550
-#define wxAuiManager_new 2551
-#define wxAuiManager_destruct 2552
-#define wxAuiManager_AddPane_2_1 2553
-#define wxAuiManager_AddPane_3 2554
-#define wxAuiManager_AddPane_2_0 2555
-#define wxAuiManager_DetachPane 2556
-#define wxAuiManager_GetAllPanes 2557
-#define wxAuiManager_GetArtProvider 2558
-#define wxAuiManager_GetDockSizeConstraint 2559
-#define wxAuiManager_GetFlags 2560
-#define wxAuiManager_GetManagedWindow 2561
-#define wxAuiManager_GetManager 2562
-#define wxAuiManager_GetPane_1_1 2563
-#define wxAuiManager_GetPane_1_0 2564
-#define wxAuiManager_HideHint 2565
-#define wxAuiManager_InsertPane 2566
-#define wxAuiManager_LoadPaneInfo 2567
-#define wxAuiManager_LoadPerspective 2568
-#define wxAuiManager_SavePaneInfo 2569
-#define wxAuiManager_SavePerspective 2570
-#define wxAuiManager_SetArtProvider 2571
-#define wxAuiManager_SetDockSizeConstraint 2572
-#define wxAuiManager_SetFlags 2573
-#define wxAuiManager_SetManagedWindow 2574
-#define wxAuiManager_ShowHint 2575
-#define wxAuiManager_UnInit 2576
-#define wxAuiManager_Update 2577
-#define wxAuiPaneInfo_new_0 2578
-#define wxAuiPaneInfo_new_1 2579
-#define wxAuiPaneInfo_destruct 2580
-#define wxAuiPaneInfo_BestSize_1 2581
-#define wxAuiPaneInfo_BestSize_2 2582
-#define wxAuiPaneInfo_Bottom 2583
-#define wxAuiPaneInfo_BottomDockable 2584
-#define wxAuiPaneInfo_Caption 2585
-#define wxAuiPaneInfo_CaptionVisible 2586
-#define wxAuiPaneInfo_Centre 2587
-#define wxAuiPaneInfo_CentrePane 2588
-#define wxAuiPaneInfo_CloseButton 2589
-#define wxAuiPaneInfo_DefaultPane 2590
-#define wxAuiPaneInfo_DestroyOnClose 2591
-#define wxAuiPaneInfo_Direction 2592
-#define wxAuiPaneInfo_Dock 2593
-#define wxAuiPaneInfo_Dockable 2594
-#define wxAuiPaneInfo_Fixed 2595
-#define wxAuiPaneInfo_Float 2596
-#define wxAuiPaneInfo_Floatable 2597
-#define wxAuiPaneInfo_FloatingPosition_1 2598
-#define wxAuiPaneInfo_FloatingPosition_2 2599
-#define wxAuiPaneInfo_FloatingSize_1 2600
-#define wxAuiPaneInfo_FloatingSize_2 2601
-#define wxAuiPaneInfo_Gripper 2602
-#define wxAuiPaneInfo_GripperTop 2603
-#define wxAuiPaneInfo_HasBorder 2604
-#define wxAuiPaneInfo_HasCaption 2605
-#define wxAuiPaneInfo_HasCloseButton 2606
-#define wxAuiPaneInfo_HasFlag 2607
-#define wxAuiPaneInfo_HasGripper 2608
-#define wxAuiPaneInfo_HasGripperTop 2609
-#define wxAuiPaneInfo_HasMaximizeButton 2610
-#define wxAuiPaneInfo_HasMinimizeButton 2611
-#define wxAuiPaneInfo_HasPinButton 2612
-#define wxAuiPaneInfo_Hide 2613
-#define wxAuiPaneInfo_IsBottomDockable 2614
-#define wxAuiPaneInfo_IsDocked 2615
-#define wxAuiPaneInfo_IsFixed 2616
-#define wxAuiPaneInfo_IsFloatable 2617
-#define wxAuiPaneInfo_IsFloating 2618
-#define wxAuiPaneInfo_IsLeftDockable 2619
-#define wxAuiPaneInfo_IsMovable 2620
-#define wxAuiPaneInfo_IsOk 2621
-#define wxAuiPaneInfo_IsResizable 2622
-#define wxAuiPaneInfo_IsRightDockable 2623
-#define wxAuiPaneInfo_IsShown 2624
-#define wxAuiPaneInfo_IsToolbar 2625
-#define wxAuiPaneInfo_IsTopDockable 2626
-#define wxAuiPaneInfo_Layer 2627
-#define wxAuiPaneInfo_Left 2628
-#define wxAuiPaneInfo_LeftDockable 2629
-#define wxAuiPaneInfo_MaxSize_1 2630
-#define wxAuiPaneInfo_MaxSize_2 2631
-#define wxAuiPaneInfo_MaximizeButton 2632
-#define wxAuiPaneInfo_MinSize_1 2633
-#define wxAuiPaneInfo_MinSize_2 2634
-#define wxAuiPaneInfo_MinimizeButton 2635
-#define wxAuiPaneInfo_Movable 2636
-#define wxAuiPaneInfo_Name 2637
-#define wxAuiPaneInfo_PaneBorder 2638
-#define wxAuiPaneInfo_PinButton 2639
-#define wxAuiPaneInfo_Position 2640
-#define wxAuiPaneInfo_Resizable 2641
-#define wxAuiPaneInfo_Right 2642
-#define wxAuiPaneInfo_RightDockable 2643
-#define wxAuiPaneInfo_Row 2644
-#define wxAuiPaneInfo_SafeSet 2645
-#define wxAuiPaneInfo_SetFlag 2646
-#define wxAuiPaneInfo_Show 2647
-#define wxAuiPaneInfo_ToolbarPane 2648
-#define wxAuiPaneInfo_Top 2649
-#define wxAuiPaneInfo_TopDockable 2650
-#define wxAuiPaneInfo_Window 2651
-#define wxAuiNotebook_new_0 2652
-#define wxAuiNotebook_new_2 2653
-#define wxAuiNotebook_AddPage 2654
-#define wxAuiNotebook_Create 2655
-#define wxAuiNotebook_DeletePage 2656
-#define wxAuiNotebook_GetArtProvider 2657
-#define wxAuiNotebook_GetPage 2658
-#define wxAuiNotebook_GetPageBitmap 2659
-#define wxAuiNotebook_GetPageCount 2660
-#define wxAuiNotebook_GetPageIndex 2661
-#define wxAuiNotebook_GetPageText 2662
-#define wxAuiNotebook_GetSelection 2663
-#define wxAuiNotebook_InsertPage 2664
-#define wxAuiNotebook_RemovePage 2665
-#define wxAuiNotebook_SetArtProvider 2666
-#define wxAuiNotebook_SetFont 2667
-#define wxAuiNotebook_SetPageBitmap 2668
-#define wxAuiNotebook_SetPageText 2669
-#define wxAuiNotebook_SetSelection 2670
-#define wxAuiNotebook_SetTabCtrlHeight 2671
-#define wxAuiNotebook_SetUniformBitmapSize 2672
-#define wxAuiNotebook_destroy 2673
-#define wxMDIParentFrame_new_0 2674
-#define wxMDIParentFrame_new_4 2675
-#define wxMDIParentFrame_destruct 2676
-#define wxMDIParentFrame_ActivateNext 2677
-#define wxMDIParentFrame_ActivatePrevious 2678
-#define wxMDIParentFrame_ArrangeIcons 2679
-#define wxMDIParentFrame_Cascade 2680
-#define wxMDIParentFrame_Create 2681
-#define wxMDIParentFrame_GetActiveChild 2682
-#define wxMDIParentFrame_GetClientWindow 2683
-#define wxMDIParentFrame_Tile 2684
-#define wxMDIChildFrame_new_0 2685
-#define wxMDIChildFrame_new_4 2686
-#define wxMDIChildFrame_destruct 2687
-#define wxMDIChildFrame_Activate 2688
-#define wxMDIChildFrame_Create 2689
-#define wxMDIChildFrame_Maximize 2690
-#define wxMDIChildFrame_Restore 2691
-#define wxMDIClientWindow_new_0 2692
-#define wxMDIClientWindow_new_2 2693
-#define wxMDIClientWindow_destruct 2694
-#define wxMDIClientWindow_CreateClient 2695
-#define wxLayoutAlgorithm_new 2696
-#define wxLayoutAlgorithm_LayoutFrame 2697
-#define wxLayoutAlgorithm_LayoutMDIFrame 2698
-#define wxLayoutAlgorithm_LayoutWindow 2699
-#define wxLayoutAlgorithm_destroy 2700
-#define wxEvent_GetId 2701
-#define wxEvent_GetSkipped 2702
-#define wxEvent_GetTimestamp 2703
-#define wxEvent_IsCommandEvent 2704
-#define wxEvent_ResumePropagation 2705
-#define wxEvent_ShouldPropagate 2706
-#define wxEvent_Skip 2707
-#define wxEvent_StopPropagation 2708
-#define wxCommandEvent_getClientData 2709
-#define wxCommandEvent_GetExtraLong 2710
-#define wxCommandEvent_GetInt 2711
-#define wxCommandEvent_GetSelection 2712
-#define wxCommandEvent_GetString 2713
-#define wxCommandEvent_IsChecked 2714
-#define wxCommandEvent_IsSelection 2715
-#define wxCommandEvent_SetInt 2716
-#define wxCommandEvent_SetString 2717
-#define wxScrollEvent_GetOrientation 2718
-#define wxScrollEvent_GetPosition 2719
-#define wxScrollWinEvent_GetOrientation 2720
-#define wxScrollWinEvent_GetPosition 2721
-#define wxMouseEvent_AltDown 2722
-#define wxMouseEvent_Button 2723
-#define wxMouseEvent_ButtonDClick 2724
-#define wxMouseEvent_ButtonDown 2725
-#define wxMouseEvent_ButtonUp 2726
-#define wxMouseEvent_CmdDown 2727
-#define wxMouseEvent_ControlDown 2728
-#define wxMouseEvent_Dragging 2729
-#define wxMouseEvent_Entering 2730
-#define wxMouseEvent_GetButton 2731
-#define wxMouseEvent_GetPosition 2734
-#define wxMouseEvent_GetLogicalPosition 2735
-#define wxMouseEvent_GetLinesPerAction 2736
-#define wxMouseEvent_GetWheelRotation 2737
-#define wxMouseEvent_GetWheelDelta 2738
-#define wxMouseEvent_GetX 2739
-#define wxMouseEvent_GetY 2740
-#define wxMouseEvent_IsButton 2741
-#define wxMouseEvent_IsPageScroll 2742
-#define wxMouseEvent_Leaving 2743
-#define wxMouseEvent_LeftDClick 2744
-#define wxMouseEvent_LeftDown 2745
-#define wxMouseEvent_LeftIsDown 2746
-#define wxMouseEvent_LeftUp 2747
-#define wxMouseEvent_MetaDown 2748
-#define wxMouseEvent_MiddleDClick 2749
-#define wxMouseEvent_MiddleDown 2750
-#define wxMouseEvent_MiddleIsDown 2751
-#define wxMouseEvent_MiddleUp 2752
-#define wxMouseEvent_Moving 2753
-#define wxMouseEvent_RightDClick 2754
-#define wxMouseEvent_RightDown 2755
-#define wxMouseEvent_RightIsDown 2756
-#define wxMouseEvent_RightUp 2757
-#define wxMouseEvent_ShiftDown 2758
-#define wxSetCursorEvent_GetCursor 2759
-#define wxSetCursorEvent_GetX 2760
-#define wxSetCursorEvent_GetY 2761
-#define wxSetCursorEvent_HasCursor 2762
-#define wxSetCursorEvent_SetCursor 2763
-#define wxKeyEvent_AltDown 2764
-#define wxKeyEvent_CmdDown 2765
-#define wxKeyEvent_ControlDown 2766
-#define wxKeyEvent_GetKeyCode 2767
-#define wxKeyEvent_GetModifiers 2768
-#define wxKeyEvent_GetPosition 2771
-#define wxKeyEvent_GetRawKeyCode 2772
-#define wxKeyEvent_GetRawKeyFlags 2773
-#define wxKeyEvent_GetUnicodeKey 2774
-#define wxKeyEvent_GetX 2775
-#define wxKeyEvent_GetY 2776
-#define wxKeyEvent_HasModifiers 2777
-#define wxKeyEvent_MetaDown 2778
-#define wxKeyEvent_ShiftDown 2779
-#define wxSizeEvent_GetSize 2780
-#define wxMoveEvent_GetPosition 2781
-#define wxEraseEvent_GetDC 2782
-#define wxFocusEvent_GetWindow 2783
-#define wxChildFocusEvent_GetWindow 2784
-#define wxMenuEvent_GetMenu 2785
-#define wxMenuEvent_GetMenuId 2786
-#define wxMenuEvent_IsPopup 2787
-#define wxCloseEvent_CanVeto 2788
-#define wxCloseEvent_GetLoggingOff 2789
-#define wxCloseEvent_SetCanVeto 2790
-#define wxCloseEvent_SetLoggingOff 2791
-#define wxCloseEvent_Veto 2792
-#define wxShowEvent_SetShow 2793
-#define wxShowEvent_GetShow 2794
-#define wxIconizeEvent_Iconized 2795
-#define wxJoystickEvent_ButtonDown 2796
-#define wxJoystickEvent_ButtonIsDown 2797
-#define wxJoystickEvent_ButtonUp 2798
-#define wxJoystickEvent_GetButtonChange 2799
-#define wxJoystickEvent_GetButtonState 2800
-#define wxJoystickEvent_GetJoystick 2801
-#define wxJoystickEvent_GetPosition 2802
-#define wxJoystickEvent_GetZPosition 2803
-#define wxJoystickEvent_IsButton 2804
-#define wxJoystickEvent_IsMove 2805
-#define wxJoystickEvent_IsZMove 2806
-#define wxUpdateUIEvent_CanUpdate 2807
-#define wxUpdateUIEvent_Check 2808
-#define wxUpdateUIEvent_Enable 2809
-#define wxUpdateUIEvent_Show 2810
-#define wxUpdateUIEvent_GetChecked 2811
-#define wxUpdateUIEvent_GetEnabled 2812
-#define wxUpdateUIEvent_GetShown 2813
-#define wxUpdateUIEvent_GetSetChecked 2814
-#define wxUpdateUIEvent_GetSetEnabled 2815
-#define wxUpdateUIEvent_GetSetShown 2816
-#define wxUpdateUIEvent_GetSetText 2817
-#define wxUpdateUIEvent_GetText 2818
-#define wxUpdateUIEvent_GetMode 2819
-#define wxUpdateUIEvent_GetUpdateInterval 2820
-#define wxUpdateUIEvent_ResetUpdateTime 2821
-#define wxUpdateUIEvent_SetMode 2822
-#define wxUpdateUIEvent_SetText 2823
-#define wxUpdateUIEvent_SetUpdateInterval 2824
-#define wxMouseCaptureChangedEvent_GetCapturedWindow 2825
-#define wxPaletteChangedEvent_SetChangedWindow 2826
-#define wxPaletteChangedEvent_GetChangedWindow 2827
-#define wxQueryNewPaletteEvent_SetPaletteRealized 2828
-#define wxQueryNewPaletteEvent_GetPaletteRealized 2829
-#define wxNavigationKeyEvent_GetDirection 2830
-#define wxNavigationKeyEvent_SetDirection 2831
-#define wxNavigationKeyEvent_IsWindowChange 2832
-#define wxNavigationKeyEvent_SetWindowChange 2833
-#define wxNavigationKeyEvent_IsFromTab 2834
-#define wxNavigationKeyEvent_SetFromTab 2835
-#define wxNavigationKeyEvent_GetCurrentFocus 2836
-#define wxNavigationKeyEvent_SetCurrentFocus 2837
-#define wxHelpEvent_GetOrigin 2838
-#define wxHelpEvent_GetPosition 2839
-#define wxHelpEvent_SetOrigin 2840
-#define wxHelpEvent_SetPosition 2841
-#define wxContextMenuEvent_GetPosition 2842
-#define wxContextMenuEvent_SetPosition 2843
-#define wxIdleEvent_CanSend 2844
-#define wxIdleEvent_GetMode 2845
-#define wxIdleEvent_RequestMore 2846
-#define wxIdleEvent_MoreRequested 2847
-#define wxIdleEvent_SetMode 2848
-#define wxGridEvent_AltDown 2849
-#define wxGridEvent_ControlDown 2850
-#define wxGridEvent_GetCol 2851
-#define wxGridEvent_GetPosition 2852
-#define wxGridEvent_GetRow 2853
-#define wxGridEvent_MetaDown 2854
-#define wxGridEvent_Selecting 2855
-#define wxGridEvent_ShiftDown 2856
-#define wxNotifyEvent_Allow 2857
-#define wxNotifyEvent_IsAllowed 2858
-#define wxNotifyEvent_Veto 2859
-#define wxSashEvent_GetEdge 2860
-#define wxSashEvent_GetDragRect 2861
-#define wxSashEvent_GetDragStatus 2862
-#define wxListEvent_GetCacheFrom 2863
-#define wxListEvent_GetCacheTo 2864
-#define wxListEvent_GetKeyCode 2865
-#define wxListEvent_GetIndex 2866
-#define wxListEvent_GetColumn 2867
-#define wxListEvent_GetPoint 2868
-#define wxListEvent_GetLabel 2869
-#define wxListEvent_GetText 2870
-#define wxListEvent_GetImage 2871
-#define wxListEvent_GetData 2872
-#define wxListEvent_GetMask 2873
-#define wxListEvent_GetItem 2874
-#define wxListEvent_IsEditCancelled 2875
-#define wxDateEvent_GetDate 2876
-#define wxCalendarEvent_GetWeekDay 2877
-#define wxFileDirPickerEvent_GetPath 2878
-#define wxColourPickerEvent_GetColour 2879
-#define wxFontPickerEvent_GetFont 2880
-#define wxStyledTextEvent_GetPosition 2881
-#define wxStyledTextEvent_GetKey 2882
-#define wxStyledTextEvent_GetModifiers 2883
-#define wxStyledTextEvent_GetModificationType 2884
-#define wxStyledTextEvent_GetText 2885
-#define wxStyledTextEvent_GetLength 2886
-#define wxStyledTextEvent_GetLinesAdded 2887
-#define wxStyledTextEvent_GetLine 2888
-#define wxStyledTextEvent_GetFoldLevelNow 2889
-#define wxStyledTextEvent_GetFoldLevelPrev 2890
-#define wxStyledTextEvent_GetMargin 2891
-#define wxStyledTextEvent_GetMessage 2892
-#define wxStyledTextEvent_GetWParam 2893
-#define wxStyledTextEvent_GetLParam 2894
-#define wxStyledTextEvent_GetListType 2895
-#define wxStyledTextEvent_GetX 2896
-#define wxStyledTextEvent_GetY 2897
-#define wxStyledTextEvent_GetDragText 2898
-#define wxStyledTextEvent_GetDragAllowMove 2899
-#define wxStyledTextEvent_GetDragResult 2900
-#define wxStyledTextEvent_GetShift 2901
-#define wxStyledTextEvent_GetControl 2902
-#define wxStyledTextEvent_GetAlt 2903
-#define utils_wxGetKeyState 2904
-#define utils_wxGetMousePosition 2905
-#define utils_wxGetMouseState 2906
-#define utils_wxSetDetectableAutoRepeat 2907
-#define utils_wxBell 2908
-#define utils_wxFindMenuItemId 2909
-#define utils_wxGenericFindWindowAtPoint 2910
-#define utils_wxFindWindowAtPoint 2911
-#define utils_wxBeginBusyCursor 2912
-#define utils_wxEndBusyCursor 2913
-#define utils_wxIsBusy 2914
-#define utils_wxShutdown 2915
-#define utils_wxShell 2916
-#define utils_wxLaunchDefaultBrowser 2917
-#define utils_wxGetEmailAddress 2918
-#define utils_wxGetUserId 2919
-#define utils_wxGetHomeDir 2920
-#define utils_wxNewId 2921
-#define utils_wxRegisterId 2922
-#define utils_wxGetCurrentId 2923
-#define utils_wxGetOsDescription 2924
-#define utils_wxIsPlatformLittleEndian 2925
-#define utils_wxIsPlatform64Bit 2926
-#define gdicmn_wxDisplaySize 2927
-#define gdicmn_wxSetCursor 2928
-#define wxPrintout_new 2929
-#define wxPrintout_destruct 2930
-#define wxPrintout_GetDC 2931
-#define wxPrintout_GetPageSizeMM 2932
-#define wxPrintout_GetPageSizePixels 2933
-#define wxPrintout_GetPaperRectPixels 2934
-#define wxPrintout_GetPPIPrinter 2935
-#define wxPrintout_GetPPIScreen 2936
-#define wxPrintout_GetTitle 2937
-#define wxPrintout_IsPreview 2938
-#define wxPrintout_FitThisSizeToPaper 2939
-#define wxPrintout_FitThisSizeToPage 2940
-#define wxPrintout_FitThisSizeToPageMargins 2941
-#define wxPrintout_MapScreenSizeToPaper 2942
-#define wxPrintout_MapScreenSizeToPage 2943
-#define wxPrintout_MapScreenSizeToPageMargins 2944
-#define wxPrintout_MapScreenSizeToDevice 2945
-#define wxPrintout_GetLogicalPaperRect 2946
-#define wxPrintout_GetLogicalPageRect 2947
-#define wxPrintout_GetLogicalPageMarginsRect 2948
-#define wxPrintout_SetLogicalOrigin 2949
-#define wxPrintout_OffsetLogicalOrigin 2950
-#define wxStyledTextCtrl_new_2 2951
-#define wxStyledTextCtrl_new_0 2952
-#define wxStyledTextCtrl_destruct 2953
-#define wxStyledTextCtrl_Create 2954
-#define wxStyledTextCtrl_AddText 2955
-#define wxStyledTextCtrl_AddStyledText 2956
-#define wxStyledTextCtrl_InsertText 2957
-#define wxStyledTextCtrl_ClearAll 2958
-#define wxStyledTextCtrl_ClearDocumentStyle 2959
-#define wxStyledTextCtrl_GetLength 2960
-#define wxStyledTextCtrl_GetCharAt 2961
-#define wxStyledTextCtrl_GetCurrentPos 2962
-#define wxStyledTextCtrl_GetAnchor 2963
-#define wxStyledTextCtrl_GetStyleAt 2964
-#define wxStyledTextCtrl_Redo 2965
-#define wxStyledTextCtrl_SetUndoCollection 2966
-#define wxStyledTextCtrl_SelectAll 2967
-#define wxStyledTextCtrl_SetSavePoint 2968
-#define wxStyledTextCtrl_GetStyledText 2969
-#define wxStyledTextCtrl_CanRedo 2970
-#define wxStyledTextCtrl_MarkerLineFromHandle 2971
-#define wxStyledTextCtrl_MarkerDeleteHandle 2972
-#define wxStyledTextCtrl_GetUndoCollection 2973
-#define wxStyledTextCtrl_GetViewWhiteSpace 2974
-#define wxStyledTextCtrl_SetViewWhiteSpace 2975
-#define wxStyledTextCtrl_PositionFromPoint 2976
-#define wxStyledTextCtrl_PositionFromPointClose 2977
-#define wxStyledTextCtrl_GotoLine 2978
-#define wxStyledTextCtrl_GotoPos 2979
-#define wxStyledTextCtrl_SetAnchor 2980
-#define wxStyledTextCtrl_GetCurLine 2981
-#define wxStyledTextCtrl_GetEndStyled 2982
-#define wxStyledTextCtrl_ConvertEOLs 2983
-#define wxStyledTextCtrl_GetEOLMode 2984
-#define wxStyledTextCtrl_SetEOLMode 2985
-#define wxStyledTextCtrl_StartStyling 2986
-#define wxStyledTextCtrl_SetStyling 2987
-#define wxStyledTextCtrl_GetBufferedDraw 2988
-#define wxStyledTextCtrl_SetBufferedDraw 2989
-#define wxStyledTextCtrl_SetTabWidth 2990
-#define wxStyledTextCtrl_GetTabWidth 2991
-#define wxStyledTextCtrl_SetCodePage 2992
-#define wxStyledTextCtrl_MarkerDefine 2993
-#define wxStyledTextCtrl_MarkerSetForeground 2994
-#define wxStyledTextCtrl_MarkerSetBackground 2995
-#define wxStyledTextCtrl_MarkerAdd 2996
-#define wxStyledTextCtrl_MarkerDelete 2997
-#define wxStyledTextCtrl_MarkerDeleteAll 2998
-#define wxStyledTextCtrl_MarkerGet 2999
-#define wxStyledTextCtrl_MarkerNext 3000
-#define wxStyledTextCtrl_MarkerPrevious 3001
-#define wxStyledTextCtrl_MarkerDefineBitmap 3002
-#define wxStyledTextCtrl_MarkerAddSet 3003
-#define wxStyledTextCtrl_MarkerSetAlpha 3004
-#define wxStyledTextCtrl_SetMarginType 3005
-#define wxStyledTextCtrl_GetMarginType 3006
-#define wxStyledTextCtrl_SetMarginWidth 3007
-#define wxStyledTextCtrl_GetMarginWidth 3008
-#define wxStyledTextCtrl_SetMarginMask 3009
-#define wxStyledTextCtrl_GetMarginMask 3010
-#define wxStyledTextCtrl_SetMarginSensitive 3011
-#define wxStyledTextCtrl_GetMarginSensitive 3012
-#define wxStyledTextCtrl_StyleClearAll 3013
-#define wxStyledTextCtrl_StyleSetForeground 3014
-#define wxStyledTextCtrl_StyleSetBackground 3015
-#define wxStyledTextCtrl_StyleSetBold 3016
-#define wxStyledTextCtrl_StyleSetItalic 3017
-#define wxStyledTextCtrl_StyleSetSize 3018
-#define wxStyledTextCtrl_StyleSetFaceName 3019
-#define wxStyledTextCtrl_StyleSetEOLFilled 3020
-#define wxStyledTextCtrl_StyleResetDefault 3021
-#define wxStyledTextCtrl_StyleSetUnderline 3022
-#define wxStyledTextCtrl_StyleSetCase 3023
-#define wxStyledTextCtrl_StyleSetHotSpot 3024
-#define wxStyledTextCtrl_SetSelForeground 3025
-#define wxStyledTextCtrl_SetSelBackground 3026
-#define wxStyledTextCtrl_GetSelAlpha 3027
-#define wxStyledTextCtrl_SetSelAlpha 3028
-#define wxStyledTextCtrl_SetCaretForeground 3029
-#define wxStyledTextCtrl_CmdKeyAssign 3030
-#define wxStyledTextCtrl_CmdKeyClear 3031
-#define wxStyledTextCtrl_CmdKeyClearAll 3032
-#define wxStyledTextCtrl_SetStyleBytes 3033
-#define wxStyledTextCtrl_StyleSetVisible 3034
-#define wxStyledTextCtrl_GetCaretPeriod 3035
-#define wxStyledTextCtrl_SetCaretPeriod 3036
-#define wxStyledTextCtrl_SetWordChars 3037
-#define wxStyledTextCtrl_BeginUndoAction 3038
-#define wxStyledTextCtrl_EndUndoAction 3039
-#define wxStyledTextCtrl_IndicatorSetStyle 3040
-#define wxStyledTextCtrl_IndicatorGetStyle 3041
-#define wxStyledTextCtrl_IndicatorSetForeground 3042
-#define wxStyledTextCtrl_IndicatorGetForeground 3043
-#define wxStyledTextCtrl_SetWhitespaceForeground 3044
-#define wxStyledTextCtrl_SetWhitespaceBackground 3045
-#define wxStyledTextCtrl_GetStyleBits 3046
-#define wxStyledTextCtrl_SetLineState 3047
-#define wxStyledTextCtrl_GetLineState 3048
-#define wxStyledTextCtrl_GetMaxLineState 3049
-#define wxStyledTextCtrl_GetCaretLineVisible 3050
-#define wxStyledTextCtrl_SetCaretLineVisible 3051
-#define wxStyledTextCtrl_GetCaretLineBackground 3052
-#define wxStyledTextCtrl_SetCaretLineBackground 3053
-#define wxStyledTextCtrl_AutoCompShow 3054
-#define wxStyledTextCtrl_AutoCompCancel 3055
-#define wxStyledTextCtrl_AutoCompActive 3056
-#define wxStyledTextCtrl_AutoCompPosStart 3057
-#define wxStyledTextCtrl_AutoCompComplete 3058
-#define wxStyledTextCtrl_AutoCompStops 3059
-#define wxStyledTextCtrl_AutoCompSetSeparator 3060
-#define wxStyledTextCtrl_AutoCompGetSeparator 3061
-#define wxStyledTextCtrl_AutoCompSelect 3062
-#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3063
-#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3064
-#define wxStyledTextCtrl_AutoCompSetFillUps 3065
-#define wxStyledTextCtrl_AutoCompSetChooseSingle 3066
-#define wxStyledTextCtrl_AutoCompGetChooseSingle 3067
-#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3068
-#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3069
-#define wxStyledTextCtrl_UserListShow 3070
-#define wxStyledTextCtrl_AutoCompSetAutoHide 3071
-#define wxStyledTextCtrl_AutoCompGetAutoHide 3072
-#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3073
-#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3074
-#define wxStyledTextCtrl_RegisterImage 3075
-#define wxStyledTextCtrl_ClearRegisteredImages 3076
-#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3077
-#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3078
-#define wxStyledTextCtrl_AutoCompSetMaxWidth 3079
-#define wxStyledTextCtrl_AutoCompGetMaxWidth 3080
-#define wxStyledTextCtrl_AutoCompSetMaxHeight 3081
-#define wxStyledTextCtrl_AutoCompGetMaxHeight 3082
-#define wxStyledTextCtrl_SetIndent 3083
-#define wxStyledTextCtrl_GetIndent 3084
-#define wxStyledTextCtrl_SetUseTabs 3085
-#define wxStyledTextCtrl_GetUseTabs 3086
-#define wxStyledTextCtrl_SetLineIndentation 3087
-#define wxStyledTextCtrl_GetLineIndentation 3088
-#define wxStyledTextCtrl_GetLineIndentPosition 3089
-#define wxStyledTextCtrl_GetColumn 3090
-#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3091
-#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3092
-#define wxStyledTextCtrl_SetIndentationGuides 3093
-#define wxStyledTextCtrl_GetIndentationGuides 3094
-#define wxStyledTextCtrl_SetHighlightGuide 3095
-#define wxStyledTextCtrl_GetHighlightGuide 3096
-#define wxStyledTextCtrl_GetLineEndPosition 3097
-#define wxStyledTextCtrl_GetCodePage 3098
-#define wxStyledTextCtrl_GetCaretForeground 3099
-#define wxStyledTextCtrl_GetReadOnly 3100
-#define wxStyledTextCtrl_SetCurrentPos 3101
-#define wxStyledTextCtrl_SetSelectionStart 3102
-#define wxStyledTextCtrl_GetSelectionStart 3103
-#define wxStyledTextCtrl_SetSelectionEnd 3104
-#define wxStyledTextCtrl_GetSelectionEnd 3105
-#define wxStyledTextCtrl_SetPrintMagnification 3106
-#define wxStyledTextCtrl_GetPrintMagnification 3107
-#define wxStyledTextCtrl_SetPrintColourMode 3108
-#define wxStyledTextCtrl_GetPrintColourMode 3109
-#define wxStyledTextCtrl_FindText 3110
-#define wxStyledTextCtrl_FormatRange 3111
-#define wxStyledTextCtrl_GetFirstVisibleLine 3112
-#define wxStyledTextCtrl_GetLine 3113
-#define wxStyledTextCtrl_GetLineCount 3114
-#define wxStyledTextCtrl_SetMarginLeft 3115
-#define wxStyledTextCtrl_GetMarginLeft 3116
-#define wxStyledTextCtrl_SetMarginRight 3117
-#define wxStyledTextCtrl_GetMarginRight 3118
-#define wxStyledTextCtrl_GetModify 3119
-#define wxStyledTextCtrl_SetSelection 3120
-#define wxStyledTextCtrl_GetSelectedText 3121
-#define wxStyledTextCtrl_GetTextRange 3122
-#define wxStyledTextCtrl_HideSelection 3123
-#define wxStyledTextCtrl_LineFromPosition 3124
-#define wxStyledTextCtrl_PositionFromLine 3125
-#define wxStyledTextCtrl_LineScroll 3126
-#define wxStyledTextCtrl_EnsureCaretVisible 3127
-#define wxStyledTextCtrl_ReplaceSelection 3128
-#define wxStyledTextCtrl_SetReadOnly 3129
-#define wxStyledTextCtrl_CanPaste 3130
-#define wxStyledTextCtrl_CanUndo 3131
-#define wxStyledTextCtrl_EmptyUndoBuffer 3132
-#define wxStyledTextCtrl_Undo 3133
-#define wxStyledTextCtrl_Cut 3134
-#define wxStyledTextCtrl_Copy 3135
-#define wxStyledTextCtrl_Paste 3136
-#define wxStyledTextCtrl_Clear 3137
-#define wxStyledTextCtrl_SetText 3138
-#define wxStyledTextCtrl_GetText 3139
-#define wxStyledTextCtrl_GetTextLength 3140
-#define wxStyledTextCtrl_GetOvertype 3141
-#define wxStyledTextCtrl_SetCaretWidth 3142
-#define wxStyledTextCtrl_GetCaretWidth 3143
-#define wxStyledTextCtrl_SetTargetStart 3144
-#define wxStyledTextCtrl_GetTargetStart 3145
-#define wxStyledTextCtrl_SetTargetEnd 3146
-#define wxStyledTextCtrl_GetTargetEnd 3147
-#define wxStyledTextCtrl_ReplaceTarget 3148
-#define wxStyledTextCtrl_SearchInTarget 3149
-#define wxStyledTextCtrl_SetSearchFlags 3150
-#define wxStyledTextCtrl_GetSearchFlags 3151
-#define wxStyledTextCtrl_CallTipShow 3152
-#define wxStyledTextCtrl_CallTipCancel 3153
-#define wxStyledTextCtrl_CallTipActive 3154
-#define wxStyledTextCtrl_CallTipPosAtStart 3155
-#define wxStyledTextCtrl_CallTipSetHighlight 3156
-#define wxStyledTextCtrl_CallTipSetBackground 3157
-#define wxStyledTextCtrl_CallTipSetForeground 3158
-#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3159
-#define wxStyledTextCtrl_CallTipUseStyle 3160
-#define wxStyledTextCtrl_VisibleFromDocLine 3161
-#define wxStyledTextCtrl_DocLineFromVisible 3162
-#define wxStyledTextCtrl_WrapCount 3163
-#define wxStyledTextCtrl_SetFoldLevel 3164
-#define wxStyledTextCtrl_GetFoldLevel 3165
-#define wxStyledTextCtrl_GetLastChild 3166
-#define wxStyledTextCtrl_GetFoldParent 3167
-#define wxStyledTextCtrl_ShowLines 3168
-#define wxStyledTextCtrl_HideLines 3169
-#define wxStyledTextCtrl_GetLineVisible 3170
-#define wxStyledTextCtrl_SetFoldExpanded 3171
-#define wxStyledTextCtrl_GetFoldExpanded 3172
-#define wxStyledTextCtrl_ToggleFold 3173
-#define wxStyledTextCtrl_EnsureVisible 3174
-#define wxStyledTextCtrl_SetFoldFlags 3175
-#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3176
-#define wxStyledTextCtrl_SetTabIndents 3177
-#define wxStyledTextCtrl_GetTabIndents 3178
-#define wxStyledTextCtrl_SetBackSpaceUnIndents 3179
-#define wxStyledTextCtrl_GetBackSpaceUnIndents 3180
-#define wxStyledTextCtrl_SetMouseDwellTime 3181
-#define wxStyledTextCtrl_GetMouseDwellTime 3182
-#define wxStyledTextCtrl_WordStartPosition 3183
-#define wxStyledTextCtrl_WordEndPosition 3184
-#define wxStyledTextCtrl_SetWrapMode 3185
-#define wxStyledTextCtrl_GetWrapMode 3186
-#define wxStyledTextCtrl_SetWrapVisualFlags 3187
-#define wxStyledTextCtrl_GetWrapVisualFlags 3188
-#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3189
-#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3190
-#define wxStyledTextCtrl_SetWrapStartIndent 3191
-#define wxStyledTextCtrl_GetWrapStartIndent 3192
-#define wxStyledTextCtrl_SetLayoutCache 3193
-#define wxStyledTextCtrl_GetLayoutCache 3194
-#define wxStyledTextCtrl_SetScrollWidth 3195
-#define wxStyledTextCtrl_GetScrollWidth 3196
-#define wxStyledTextCtrl_TextWidth 3197
-#define wxStyledTextCtrl_GetEndAtLastLine 3198
-#define wxStyledTextCtrl_TextHeight 3199
-#define wxStyledTextCtrl_SetUseVerticalScrollBar 3200
-#define wxStyledTextCtrl_GetUseVerticalScrollBar 3201
-#define wxStyledTextCtrl_AppendText 3202
-#define wxStyledTextCtrl_GetTwoPhaseDraw 3203
-#define wxStyledTextCtrl_SetTwoPhaseDraw 3204
-#define wxStyledTextCtrl_TargetFromSelection 3205
-#define wxStyledTextCtrl_LinesJoin 3206
-#define wxStyledTextCtrl_LinesSplit 3207
-#define wxStyledTextCtrl_SetFoldMarginColour 3208
-#define wxStyledTextCtrl_SetFoldMarginHiColour 3209
-#define wxStyledTextCtrl_LineDown 3210
-#define wxStyledTextCtrl_LineDownExtend 3211
-#define wxStyledTextCtrl_LineUp 3212
-#define wxStyledTextCtrl_LineUpExtend 3213
-#define wxStyledTextCtrl_CharLeft 3214
-#define wxStyledTextCtrl_CharLeftExtend 3215
-#define wxStyledTextCtrl_CharRight 3216
-#define wxStyledTextCtrl_CharRightExtend 3217
-#define wxStyledTextCtrl_WordLeft 3218
-#define wxStyledTextCtrl_WordLeftExtend 3219
-#define wxStyledTextCtrl_WordRight 3220
-#define wxStyledTextCtrl_WordRightExtend 3221
-#define wxStyledTextCtrl_Home 3222
-#define wxStyledTextCtrl_HomeExtend 3223
-#define wxStyledTextCtrl_LineEnd 3224
-#define wxStyledTextCtrl_LineEndExtend 3225
-#define wxStyledTextCtrl_DocumentStart 3226
-#define wxStyledTextCtrl_DocumentStartExtend 3227
-#define wxStyledTextCtrl_DocumentEnd 3228
-#define wxStyledTextCtrl_DocumentEndExtend 3229
-#define wxStyledTextCtrl_PageUp 3230
-#define wxStyledTextCtrl_PageUpExtend 3231
-#define wxStyledTextCtrl_PageDown 3232
-#define wxStyledTextCtrl_PageDownExtend 3233
-#define wxStyledTextCtrl_EditToggleOvertype 3234
-#define wxStyledTextCtrl_Cancel 3235
-#define wxStyledTextCtrl_DeleteBack 3236
-#define wxStyledTextCtrl_Tab 3237
-#define wxStyledTextCtrl_BackTab 3238
-#define wxStyledTextCtrl_NewLine 3239
-#define wxStyledTextCtrl_FormFeed 3240
-#define wxStyledTextCtrl_VCHome 3241
-#define wxStyledTextCtrl_VCHomeExtend 3242
-#define wxStyledTextCtrl_ZoomIn 3243
-#define wxStyledTextCtrl_ZoomOut 3244
-#define wxStyledTextCtrl_DelWordLeft 3245
-#define wxStyledTextCtrl_DelWordRight 3246
-#define wxStyledTextCtrl_LineCut 3247
-#define wxStyledTextCtrl_LineDelete 3248
-#define wxStyledTextCtrl_LineTranspose 3249
-#define wxStyledTextCtrl_LineDuplicate 3250
-#define wxStyledTextCtrl_LowerCase 3251
-#define wxStyledTextCtrl_UpperCase 3252
-#define wxStyledTextCtrl_LineScrollDown 3253
-#define wxStyledTextCtrl_LineScrollUp 3254
-#define wxStyledTextCtrl_DeleteBackNotLine 3255
-#define wxStyledTextCtrl_HomeDisplay 3256
-#define wxStyledTextCtrl_HomeDisplayExtend 3257
-#define wxStyledTextCtrl_LineEndDisplay 3258
-#define wxStyledTextCtrl_LineEndDisplayExtend 3259
-#define wxStyledTextCtrl_HomeWrapExtend 3260
-#define wxStyledTextCtrl_LineEndWrap 3261
-#define wxStyledTextCtrl_LineEndWrapExtend 3262
-#define wxStyledTextCtrl_VCHomeWrap 3263
-#define wxStyledTextCtrl_VCHomeWrapExtend 3264
-#define wxStyledTextCtrl_LineCopy 3265
-#define wxStyledTextCtrl_MoveCaretInsideView 3266
-#define wxStyledTextCtrl_LineLength 3267
-#define wxStyledTextCtrl_BraceHighlight 3268
-#define wxStyledTextCtrl_BraceBadLight 3269
-#define wxStyledTextCtrl_BraceMatch 3270
-#define wxStyledTextCtrl_GetViewEOL 3271
-#define wxStyledTextCtrl_SetViewEOL 3272
-#define wxStyledTextCtrl_SetModEventMask 3273
-#define wxStyledTextCtrl_GetEdgeColumn 3274
-#define wxStyledTextCtrl_SetEdgeColumn 3275
-#define wxStyledTextCtrl_SetEdgeMode 3276
-#define wxStyledTextCtrl_GetEdgeMode 3277
-#define wxStyledTextCtrl_GetEdgeColour 3278
-#define wxStyledTextCtrl_SetEdgeColour 3279
-#define wxStyledTextCtrl_SearchAnchor 3280
-#define wxStyledTextCtrl_SearchNext 3281
-#define wxStyledTextCtrl_SearchPrev 3282
-#define wxStyledTextCtrl_LinesOnScreen 3283
-#define wxStyledTextCtrl_UsePopUp 3284
-#define wxStyledTextCtrl_SelectionIsRectangle 3285
-#define wxStyledTextCtrl_SetZoom 3286
-#define wxStyledTextCtrl_GetZoom 3287
-#define wxStyledTextCtrl_GetModEventMask 3288
-#define wxStyledTextCtrl_SetSTCFocus 3289
-#define wxStyledTextCtrl_GetSTCFocus 3290
-#define wxStyledTextCtrl_SetStatus 3291
-#define wxStyledTextCtrl_GetStatus 3292
-#define wxStyledTextCtrl_SetMouseDownCaptures 3293
-#define wxStyledTextCtrl_GetMouseDownCaptures 3294
-#define wxStyledTextCtrl_SetSTCCursor 3295
-#define wxStyledTextCtrl_GetSTCCursor 3296
-#define wxStyledTextCtrl_SetControlCharSymbol 3297
-#define wxStyledTextCtrl_GetControlCharSymbol 3298
-#define wxStyledTextCtrl_WordPartLeft 3299
-#define wxStyledTextCtrl_WordPartLeftExtend 3300
-#define wxStyledTextCtrl_WordPartRight 3301
-#define wxStyledTextCtrl_WordPartRightExtend 3302
-#define wxStyledTextCtrl_SetVisiblePolicy 3303
-#define wxStyledTextCtrl_DelLineLeft 3304
-#define wxStyledTextCtrl_DelLineRight 3305
-#define wxStyledTextCtrl_GetXOffset 3306
-#define wxStyledTextCtrl_ChooseCaretX 3307
-#define wxStyledTextCtrl_SetXCaretPolicy 3308
-#define wxStyledTextCtrl_SetYCaretPolicy 3309
-#define wxStyledTextCtrl_GetPrintWrapMode 3310
-#define wxStyledTextCtrl_SetHotspotActiveForeground 3311
-#define wxStyledTextCtrl_SetHotspotActiveBackground 3312
-#define wxStyledTextCtrl_SetHotspotActiveUnderline 3313
-#define wxStyledTextCtrl_SetHotspotSingleLine 3314
-#define wxStyledTextCtrl_ParaDownExtend 3315
-#define wxStyledTextCtrl_ParaUp 3316
-#define wxStyledTextCtrl_ParaUpExtend 3317
-#define wxStyledTextCtrl_PositionBefore 3318
-#define wxStyledTextCtrl_PositionAfter 3319
-#define wxStyledTextCtrl_CopyRange 3320
-#define wxStyledTextCtrl_CopyText 3321
-#define wxStyledTextCtrl_SetSelectionMode 3322
-#define wxStyledTextCtrl_GetSelectionMode 3323
-#define wxStyledTextCtrl_LineDownRectExtend 3324
-#define wxStyledTextCtrl_LineUpRectExtend 3325
-#define wxStyledTextCtrl_CharLeftRectExtend 3326
-#define wxStyledTextCtrl_CharRightRectExtend 3327
-#define wxStyledTextCtrl_HomeRectExtend 3328
-#define wxStyledTextCtrl_VCHomeRectExtend 3329
-#define wxStyledTextCtrl_LineEndRectExtend 3330
-#define wxStyledTextCtrl_PageUpRectExtend 3331
-#define wxStyledTextCtrl_PageDownRectExtend 3332
-#define wxStyledTextCtrl_StutteredPageUp 3333
-#define wxStyledTextCtrl_StutteredPageUpExtend 3334
-#define wxStyledTextCtrl_StutteredPageDown 3335
-#define wxStyledTextCtrl_StutteredPageDownExtend 3336
-#define wxStyledTextCtrl_WordLeftEnd 3337
-#define wxStyledTextCtrl_WordLeftEndExtend 3338
-#define wxStyledTextCtrl_WordRightEnd 3339
-#define wxStyledTextCtrl_WordRightEndExtend 3340
-#define wxStyledTextCtrl_SetWhitespaceChars 3341
-#define wxStyledTextCtrl_SetCharsDefault 3342
-#define wxStyledTextCtrl_AutoCompGetCurrent 3343
-#define wxStyledTextCtrl_Allocate 3344
-#define wxStyledTextCtrl_FindColumn 3345
-#define wxStyledTextCtrl_GetCaretSticky 3346
-#define wxStyledTextCtrl_SetCaretSticky 3347
-#define wxStyledTextCtrl_ToggleCaretSticky 3348
-#define wxStyledTextCtrl_SetPasteConvertEndings 3349
-#define wxStyledTextCtrl_GetPasteConvertEndings 3350
-#define wxStyledTextCtrl_SelectionDuplicate 3351
-#define wxStyledTextCtrl_SetCaretLineBackAlpha 3352
-#define wxStyledTextCtrl_GetCaretLineBackAlpha 3353
-#define wxStyledTextCtrl_StartRecord 3354
-#define wxStyledTextCtrl_StopRecord 3355
-#define wxStyledTextCtrl_SetLexer 3356
-#define wxStyledTextCtrl_GetLexer 3357
-#define wxStyledTextCtrl_Colourise 3358
-#define wxStyledTextCtrl_SetProperty 3359
-#define wxStyledTextCtrl_SetKeyWords 3360
-#define wxStyledTextCtrl_SetLexerLanguage 3361
-#define wxStyledTextCtrl_GetProperty 3362
-#define wxStyledTextCtrl_GetStyleBitsNeeded 3363
-#define wxStyledTextCtrl_GetCurrentLine 3364
-#define wxStyledTextCtrl_StyleSetSpec 3365
-#define wxStyledTextCtrl_StyleSetFont 3366
-#define wxStyledTextCtrl_StyleSetFontAttr 3367
-#define wxStyledTextCtrl_StyleSetCharacterSet 3368
-#define wxStyledTextCtrl_StyleSetFontEncoding 3369
-#define wxStyledTextCtrl_CmdKeyExecute 3370
-#define wxStyledTextCtrl_SetMargins 3371
-#define wxStyledTextCtrl_GetSelection 3372
-#define wxStyledTextCtrl_PointFromPosition 3373
-#define wxStyledTextCtrl_ScrollToLine 3374
-#define wxStyledTextCtrl_ScrollToColumn 3375
-#define wxStyledTextCtrl_SetVScrollBar 3376
-#define wxStyledTextCtrl_SetHScrollBar 3377
-#define wxStyledTextCtrl_GetLastKeydownProcessed 3378
-#define wxStyledTextCtrl_SetLastKeydownProcessed 3379
-#define wxStyledTextCtrl_SaveFile 3380
-#define wxStyledTextCtrl_LoadFile 3381
-#define wxStyledTextCtrl_DoDragOver 3382
-#define wxStyledTextCtrl_DoDropText 3383
-#define wxStyledTextCtrl_GetUseAntiAliasing 3384
-#define wxStyledTextCtrl_AddTextRaw 3385
-#define wxStyledTextCtrl_InsertTextRaw 3386
-#define wxStyledTextCtrl_GetCurLineRaw 3387
-#define wxStyledTextCtrl_GetLineRaw 3388
-#define wxStyledTextCtrl_GetSelectedTextRaw 3389
-#define wxStyledTextCtrl_GetTextRangeRaw 3390
-#define wxStyledTextCtrl_SetTextRaw 3391
-#define wxStyledTextCtrl_GetTextRaw 3392
-#define wxStyledTextCtrl_AppendTextRaw 3393
-#define wxArtProvider_GetBitmap 3394
-#define wxArtProvider_GetIcon 3395
-#define wxTreeEvent_GetKeyCode 3396
-#define wxTreeEvent_GetItem 3397
-#define wxTreeEvent_GetKeyEvent 3398
-#define wxTreeEvent_GetLabel 3399
-#define wxTreeEvent_GetOldItem 3400
-#define wxTreeEvent_GetPoint 3401
-#define wxTreeEvent_IsEditCancelled 3402
-#define wxTreeEvent_SetToolTip 3403
-#define wxNotebookEvent_GetOldSelection 3404
-#define wxNotebookEvent_GetSelection 3405
-#define wxNotebookEvent_SetOldSelection 3406
-#define wxNotebookEvent_SetSelection 3407
-#define wxFileDataObject_new 3408
-#define wxFileDataObject_AddFile 3409
-#define wxFileDataObject_GetFilenames 3410
-#define wxFileDataObject_destroy 3411
-#define wxTextDataObject_new 3412
-#define wxTextDataObject_GetTextLength 3413
-#define wxTextDataObject_GetText 3414
-#define wxTextDataObject_SetText 3415
-#define wxTextDataObject_destroy 3416
-#define wxBitmapDataObject_new_1_1 3417
-#define wxBitmapDataObject_new_1_0 3418
-#define wxBitmapDataObject_GetBitmap 3419
-#define wxBitmapDataObject_SetBitmap 3420
-#define wxBitmapDataObject_destroy 3421
-#define wxClipboard_new 3423
-#define wxClipboard_destruct 3424
-#define wxClipboard_AddData 3425
-#define wxClipboard_Clear 3426
-#define wxClipboard_Close 3427
-#define wxClipboard_Flush 3428
-#define wxClipboard_GetData 3429
-#define wxClipboard_IsOpened 3430
-#define wxClipboard_Open 3431
-#define wxClipboard_SetData 3432
-#define wxClipboard_UsePrimarySelection 3434
-#define wxClipboard_IsSupported 3435
-#define wxClipboard_Get 3436
-#define wxSpinEvent_GetPosition 3437
-#define wxSpinEvent_SetPosition 3438
-#define wxSplitterWindow_new_0 3439
-#define wxSplitterWindow_new_2 3440
-#define wxSplitterWindow_destruct 3441
-#define wxSplitterWindow_Create 3442
-#define wxSplitterWindow_GetMinimumPaneSize 3443
-#define wxSplitterWindow_GetSashGravity 3444
-#define wxSplitterWindow_GetSashPosition 3445
-#define wxSplitterWindow_GetSplitMode 3446
-#define wxSplitterWindow_GetWindow1 3447
-#define wxSplitterWindow_GetWindow2 3448
-#define wxSplitterWindow_Initialize 3449
-#define wxSplitterWindow_IsSplit 3450
-#define wxSplitterWindow_ReplaceWindow 3451
-#define wxSplitterWindow_SetSashGravity 3452
-#define wxSplitterWindow_SetSashPosition 3453
-#define wxSplitterWindow_SetSashSize 3454
-#define wxSplitterWindow_SetMinimumPaneSize 3455
-#define wxSplitterWindow_SetSplitMode 3456
-#define wxSplitterWindow_SplitHorizontally 3457
-#define wxSplitterWindow_SplitVertically 3458
-#define wxSplitterWindow_Unsplit 3459
-#define wxSplitterWindow_UpdateSize 3460
-#define wxSplitterEvent_GetSashPosition 3461
-#define wxSplitterEvent_GetX 3462
-#define wxSplitterEvent_GetY 3463
-#define wxSplitterEvent_GetWindowBeingRemoved 3464
-#define wxSplitterEvent_SetSashPosition 3465
-#define wxHtmlWindow_new_0 3466
-#define wxHtmlWindow_new_2 3467
-#define wxHtmlWindow_AppendToPage 3468
-#define wxHtmlWindow_GetOpenedAnchor 3469
-#define wxHtmlWindow_GetOpenedPage 3470
-#define wxHtmlWindow_GetOpenedPageTitle 3471
-#define wxHtmlWindow_GetRelatedFrame 3472
-#define wxHtmlWindow_HistoryBack 3473
-#define wxHtmlWindow_HistoryCanBack 3474
-#define wxHtmlWindow_HistoryCanForward 3475
-#define wxHtmlWindow_HistoryClear 3476
-#define wxHtmlWindow_HistoryForward 3477
-#define wxHtmlWindow_LoadFile 3478
-#define wxHtmlWindow_LoadPage 3479
-#define wxHtmlWindow_SelectAll 3480
-#define wxHtmlWindow_SelectionToText 3481
-#define wxHtmlWindow_SelectLine 3482
-#define wxHtmlWindow_SelectWord 3483
-#define wxHtmlWindow_SetBorders 3484
-#define wxHtmlWindow_SetFonts 3485
-#define wxHtmlWindow_SetPage 3486
-#define wxHtmlWindow_SetRelatedFrame 3487
-#define wxHtmlWindow_SetRelatedStatusBar 3488
-#define wxHtmlWindow_ToText 3489
-#define wxHtmlWindow_destroy 3490
-#define wxHtmlLinkEvent_GetLinkInfo 3491
-#define wxSystemSettings_GetColour 3492
-#define wxSystemSettings_GetFont 3493
-#define wxSystemSettings_GetMetric 3494
-#define wxSystemSettings_GetScreenType 3495
-#define wxSystemOptions_GetOption 3496
-#define wxSystemOptions_GetOptionInt 3497
-#define wxSystemOptions_HasOption 3498
-#define wxSystemOptions_IsFalse 3499
-#define wxSystemOptions_SetOption_2_1 3500
-#define wxSystemOptions_SetOption_2_0 3501
-#define wxAuiNotebookEvent_SetSelection 3502
-#define wxAuiNotebookEvent_GetSelection 3503
-#define wxAuiNotebookEvent_SetOldSelection 3504
-#define wxAuiNotebookEvent_GetOldSelection 3505
-#define wxAuiNotebookEvent_SetDragSource 3506
-#define wxAuiNotebookEvent_GetDragSource 3507
-#define wxAuiManagerEvent_SetManager 3508
-#define wxAuiManagerEvent_GetManager 3509
-#define wxAuiManagerEvent_SetPane 3510
-#define wxAuiManagerEvent_GetPane 3511
-#define wxAuiManagerEvent_SetButton 3512
-#define wxAuiManagerEvent_GetButton 3513
-#define wxAuiManagerEvent_SetDC 3514
-#define wxAuiManagerEvent_GetDC 3515
-#define wxAuiManagerEvent_Veto 3516
-#define wxAuiManagerEvent_GetVeto 3517
-#define wxAuiManagerEvent_SetCanVeto 3518
-#define wxAuiManagerEvent_CanVeto 3519
-#define wxLogNull_new 3520
-#define wxLogNull_destroy 3521
-#define wxTaskBarIcon_new 3522
-#define wxTaskBarIcon_destruct 3523
-#define wxTaskBarIcon_PopupMenu 3524
-#define wxTaskBarIcon_RemoveIcon 3525
-#define wxTaskBarIcon_SetIcon 3526
-#define wxLocale_new_0 3527
-#define wxLocale_new_2 3529
-#define wxLocale_destruct 3530
-#define wxLocale_Init 3532
-#define wxLocale_AddCatalog_1 3533
-#define wxLocale_AddCatalog_3 3534
-#define wxLocale_AddCatalogLookupPathPrefix 3535
-#define wxLocale_GetCanonicalName 3536
-#define wxLocale_GetLanguage 3537
-#define wxLocale_GetLanguageName 3538
-#define wxLocale_GetLocale 3539
-#define wxLocale_GetName 3540
-#define wxLocale_GetString_2 3541
-#define wxLocale_GetString_4 3542
-#define wxLocale_GetHeaderValue 3543
-#define wxLocale_GetSysName 3544
-#define wxLocale_GetSystemEncoding 3545
-#define wxLocale_GetSystemEncodingName 3546
-#define wxLocale_GetSystemLanguage 3547
-#define wxLocale_IsLoaded 3548
-#define wxLocale_IsOk 3549
+#define wxTextCtrl_ChangeValue 1827
+#define wxTextCtrl_EmulateKeyPress 1828
+#define wxTextCtrl_GetDefaultStyle 1829
+#define wxTextCtrl_GetInsertionPoint 1830
+#define wxTextCtrl_GetLastPosition 1831
+#define wxTextCtrl_GetLineLength 1832
+#define wxTextCtrl_GetLineText 1833
+#define wxTextCtrl_GetNumberOfLines 1834
+#define wxTextCtrl_GetRange 1835
+#define wxTextCtrl_GetSelection 1836
+#define wxTextCtrl_GetStringSelection 1837
+#define wxTextCtrl_GetStyle 1838
+#define wxTextCtrl_GetValue 1839
+#define wxTextCtrl_IsEditable 1840
+#define wxTextCtrl_IsModified 1841
+#define wxTextCtrl_IsMultiLine 1842
+#define wxTextCtrl_IsSingleLine 1843
+#define wxTextCtrl_LoadFile 1844
+#define wxTextCtrl_MarkDirty 1845
+#define wxTextCtrl_Paste 1846
+#define wxTextCtrl_PositionToXY 1847
+#define wxTextCtrl_Redo 1848
+#define wxTextCtrl_Remove 1849
+#define wxTextCtrl_Replace 1850
+#define wxTextCtrl_SaveFile 1851
+#define wxTextCtrl_SetDefaultStyle 1852
+#define wxTextCtrl_SetEditable 1853
+#define wxTextCtrl_SetInsertionPoint 1854
+#define wxTextCtrl_SetInsertionPointEnd 1855
+#define wxTextCtrl_SetMaxLength 1857
+#define wxTextCtrl_SetSelection 1858
+#define wxTextCtrl_SetStyle 1859
+#define wxTextCtrl_SetValue 1860
+#define wxTextCtrl_ShowPosition 1861
+#define wxTextCtrl_Undo 1862
+#define wxTextCtrl_WriteText 1863
+#define wxTextCtrl_XYToPosition 1864
+#define wxNotebook_new_0 1867
+#define wxNotebook_new_3 1868
+#define wxNotebook_destruct 1869
+#define wxNotebook_AddPage 1870
+#define wxNotebook_AdvanceSelection 1871
+#define wxNotebook_AssignImageList 1872
+#define wxNotebook_Create 1873
+#define wxNotebook_DeleteAllPages 1874
+#define wxNotebook_DeletePage 1875
+#define wxNotebook_RemovePage 1876
+#define wxNotebook_GetCurrentPage 1877
+#define wxNotebook_GetImageList 1878
+#define wxNotebook_GetPage 1880
+#define wxNotebook_GetPageCount 1881
+#define wxNotebook_GetPageImage 1882
+#define wxNotebook_GetPageText 1883
+#define wxNotebook_GetRowCount 1884
+#define wxNotebook_GetSelection 1885
+#define wxNotebook_GetThemeBackgroundColour 1886
+#define wxNotebook_HitTest 1888
+#define wxNotebook_InsertPage 1890
+#define wxNotebook_SetImageList 1891
+#define wxNotebook_SetPadding 1892
+#define wxNotebook_SetPageSize 1893
+#define wxNotebook_SetPageImage 1894
+#define wxNotebook_SetPageText 1895
+#define wxNotebook_SetSelection 1896
+#define wxNotebook_ChangeSelection 1897
+#define wxChoicebook_new_0 1898
+#define wxChoicebook_new_3 1899
+#define wxChoicebook_AddPage 1900
+#define wxChoicebook_AdvanceSelection 1901
+#define wxChoicebook_AssignImageList 1902
+#define wxChoicebook_Create 1903
+#define wxChoicebook_DeleteAllPages 1904
+#define wxChoicebook_DeletePage 1905
+#define wxChoicebook_RemovePage 1906
+#define wxChoicebook_GetCurrentPage 1907
+#define wxChoicebook_GetImageList 1908
+#define wxChoicebook_GetPage 1910
+#define wxChoicebook_GetPageCount 1911
+#define wxChoicebook_GetPageImage 1912
+#define wxChoicebook_GetPageText 1913
+#define wxChoicebook_GetSelection 1914
+#define wxChoicebook_HitTest 1915
+#define wxChoicebook_InsertPage 1916
+#define wxChoicebook_SetImageList 1917
+#define wxChoicebook_SetPageSize 1918
+#define wxChoicebook_SetPageImage 1919
+#define wxChoicebook_SetPageText 1920
+#define wxChoicebook_SetSelection 1921
+#define wxChoicebook_ChangeSelection 1922
+#define wxChoicebook_destroy 1923
+#define wxToolbook_new_0 1924
+#define wxToolbook_new_3 1925
+#define wxToolbook_AddPage 1926
+#define wxToolbook_AdvanceSelection 1927
+#define wxToolbook_AssignImageList 1928
+#define wxToolbook_Create 1929
+#define wxToolbook_DeleteAllPages 1930
+#define wxToolbook_DeletePage 1931
+#define wxToolbook_RemovePage 1932
+#define wxToolbook_GetCurrentPage 1933
+#define wxToolbook_GetImageList 1934
+#define wxToolbook_GetPage 1936
+#define wxToolbook_GetPageCount 1937
+#define wxToolbook_GetPageImage 1938
+#define wxToolbook_GetPageText 1939
+#define wxToolbook_GetSelection 1940
+#define wxToolbook_HitTest 1942
+#define wxToolbook_InsertPage 1943
+#define wxToolbook_SetImageList 1944
+#define wxToolbook_SetPageSize 1945
+#define wxToolbook_SetPageImage 1946
+#define wxToolbook_SetPageText 1947
+#define wxToolbook_SetSelection 1948
+#define wxToolbook_ChangeSelection 1949
+#define wxToolbook_destroy 1950
+#define wxListbook_new_0 1951
+#define wxListbook_new_3 1952
+#define wxListbook_AddPage 1953
+#define wxListbook_AdvanceSelection 1954
+#define wxListbook_AssignImageList 1955
+#define wxListbook_Create 1956
+#define wxListbook_DeleteAllPages 1957
+#define wxListbook_DeletePage 1958
+#define wxListbook_RemovePage 1959
+#define wxListbook_GetCurrentPage 1960
+#define wxListbook_GetImageList 1961
+#define wxListbook_GetPage 1963
+#define wxListbook_GetPageCount 1964
+#define wxListbook_GetPageImage 1965
+#define wxListbook_GetPageText 1966
+#define wxListbook_GetSelection 1967
+#define wxListbook_HitTest 1969
+#define wxListbook_InsertPage 1970
+#define wxListbook_SetImageList 1971
+#define wxListbook_SetPageSize 1972
+#define wxListbook_SetPageImage 1973
+#define wxListbook_SetPageText 1974
+#define wxListbook_SetSelection 1975
+#define wxListbook_ChangeSelection 1976
+#define wxListbook_destroy 1977
+#define wxTreebook_new_0 1978
+#define wxTreebook_new_3 1979
+#define wxTreebook_AddPage 1980
+#define wxTreebook_AdvanceSelection 1981
+#define wxTreebook_AssignImageList 1982
+#define wxTreebook_Create 1983
+#define wxTreebook_DeleteAllPages 1984
+#define wxTreebook_DeletePage 1985
+#define wxTreebook_RemovePage 1986
+#define wxTreebook_GetCurrentPage 1987
+#define wxTreebook_GetImageList 1988
+#define wxTreebook_GetPage 1990
+#define wxTreebook_GetPageCount 1991
+#define wxTreebook_GetPageImage 1992
+#define wxTreebook_GetPageText 1993
+#define wxTreebook_GetSelection 1994
+#define wxTreebook_ExpandNode 1995
+#define wxTreebook_IsNodeExpanded 1996
+#define wxTreebook_HitTest 1998
+#define wxTreebook_InsertPage 1999
+#define wxTreebook_InsertSubPage 2000
+#define wxTreebook_SetImageList 2001
+#define wxTreebook_SetPageSize 2002
+#define wxTreebook_SetPageImage 2003
+#define wxTreebook_SetPageText 2004
+#define wxTreebook_SetSelection 2005
+#define wxTreebook_ChangeSelection 2006
+#define wxTreebook_destroy 2007
+#define wxTreeCtrl_new_2 2010
+#define wxTreeCtrl_new_0 2011
+#define wxTreeCtrl_destruct 2013
+#define wxTreeCtrl_AddRoot 2014
+#define wxTreeCtrl_AppendItem 2015
+#define wxTreeCtrl_AssignImageList 2016
+#define wxTreeCtrl_AssignStateImageList 2017
+#define wxTreeCtrl_Collapse 2018
+#define wxTreeCtrl_CollapseAndReset 2019
+#define wxTreeCtrl_Create 2020
+#define wxTreeCtrl_Delete 2021
+#define wxTreeCtrl_DeleteAllItems 2022
+#define wxTreeCtrl_DeleteChildren 2023
+#define wxTreeCtrl_EditLabel 2024
+#define wxTreeCtrl_EnsureVisible 2025
+#define wxTreeCtrl_Expand 2026
+#define wxTreeCtrl_GetBoundingRect 2027
+#define wxTreeCtrl_GetChildrenCount 2029
+#define wxTreeCtrl_GetCount 2030
+#define wxTreeCtrl_GetEditControl 2031
+#define wxTreeCtrl_GetFirstChild 2032
+#define wxTreeCtrl_GetNextChild 2033
+#define wxTreeCtrl_GetFirstVisibleItem 2034
+#define wxTreeCtrl_GetImageList 2035
+#define wxTreeCtrl_GetIndent 2036
+#define wxTreeCtrl_GetItemBackgroundColour 2037
+#define wxTreeCtrl_GetItemData 2038
+#define wxTreeCtrl_GetItemFont 2039
+#define wxTreeCtrl_GetItemImage_1 2040
+#define wxTreeCtrl_GetItemImage_2 2041
+#define wxTreeCtrl_GetItemText 2042
+#define wxTreeCtrl_GetItemTextColour 2043
+#define wxTreeCtrl_GetLastChild 2044
+#define wxTreeCtrl_GetNextSibling 2045
+#define wxTreeCtrl_GetNextVisible 2046
+#define wxTreeCtrl_GetItemParent 2047
+#define wxTreeCtrl_GetPrevSibling 2048
+#define wxTreeCtrl_GetPrevVisible 2049
+#define wxTreeCtrl_GetRootItem 2050
+#define wxTreeCtrl_GetSelection 2051
+#define wxTreeCtrl_GetSelections 2052
+#define wxTreeCtrl_GetStateImageList 2053
+#define wxTreeCtrl_HitTest 2054
+#define wxTreeCtrl_InsertItem 2056
+#define wxTreeCtrl_IsBold 2057
+#define wxTreeCtrl_IsExpanded 2058
+#define wxTreeCtrl_IsSelected 2059
+#define wxTreeCtrl_IsVisible 2060
+#define wxTreeCtrl_ItemHasChildren 2061
+#define wxTreeCtrl_IsTreeItemIdOk 2062
+#define wxTreeCtrl_PrependItem 2063
+#define wxTreeCtrl_ScrollTo 2064
+#define wxTreeCtrl_SelectItem_1 2065
+#define wxTreeCtrl_SelectItem_2 2066
+#define wxTreeCtrl_SetIndent 2067
+#define wxTreeCtrl_SetImageList 2068
+#define wxTreeCtrl_SetItemBackgroundColour 2069
+#define wxTreeCtrl_SetItemBold 2070
+#define wxTreeCtrl_SetItemData 2071
+#define wxTreeCtrl_SetItemDropHighlight 2072
+#define wxTreeCtrl_SetItemFont 2073
+#define wxTreeCtrl_SetItemHasChildren 2074
+#define wxTreeCtrl_SetItemImage_2 2075
+#define wxTreeCtrl_SetItemImage_3 2076
+#define wxTreeCtrl_SetItemText 2077
+#define wxTreeCtrl_SetItemTextColour 2078
+#define wxTreeCtrl_SetStateImageList 2079
+#define wxTreeCtrl_SetWindowStyle 2080
+#define wxTreeCtrl_SortChildren 2081
+#define wxTreeCtrl_Toggle 2082
+#define wxTreeCtrl_ToggleItemSelection 2083
+#define wxTreeCtrl_Unselect 2084
+#define wxTreeCtrl_UnselectAll 2085
+#define wxTreeCtrl_UnselectItem 2086
+#define wxScrollBar_new_0 2087
+#define wxScrollBar_new_3 2088
+#define wxScrollBar_destruct 2089
+#define wxScrollBar_Create 2090
+#define wxScrollBar_GetRange 2091
+#define wxScrollBar_GetPageSize 2092
+#define wxScrollBar_GetThumbPosition 2093
+#define wxScrollBar_GetThumbSize 2094
+#define wxScrollBar_SetThumbPosition 2095
+#define wxScrollBar_SetScrollbar 2096
+#define wxSpinButton_new_2 2098
+#define wxSpinButton_new_0 2099
+#define wxSpinButton_Create 2100
+#define wxSpinButton_GetMax 2101
+#define wxSpinButton_GetMin 2102
+#define wxSpinButton_GetValue 2103
+#define wxSpinButton_SetRange 2104
+#define wxSpinButton_SetValue 2105
+#define wxSpinButton_destroy 2106
+#define wxSpinCtrl_new_0 2107
+#define wxSpinCtrl_new_2 2108
+#define wxSpinCtrl_Create 2110
+#define wxSpinCtrl_SetValue_1_1 2113
+#define wxSpinCtrl_SetValue_1_0 2114
+#define wxSpinCtrl_GetValue 2116
+#define wxSpinCtrl_SetRange 2118
+#define wxSpinCtrl_SetSelection 2119
+#define wxSpinCtrl_GetMin 2121
+#define wxSpinCtrl_GetMax 2123
+#define wxSpinCtrl_destroy 2124
+#define wxStaticText_new_0 2125
+#define wxStaticText_new_4 2126
+#define wxStaticText_Create 2127
+#define wxStaticText_GetLabel 2128
+#define wxStaticText_SetLabel 2129
+#define wxStaticText_Wrap 2130
+#define wxStaticText_destroy 2131
+#define wxStaticBitmap_new_0 2132
+#define wxStaticBitmap_new_4 2133
+#define wxStaticBitmap_Create 2134
+#define wxStaticBitmap_GetBitmap 2135
+#define wxStaticBitmap_SetBitmap 2136
+#define wxStaticBitmap_destroy 2137
+#define wxRadioBox_new 2138
+#define wxRadioBox_destruct 2140
+#define wxRadioBox_Create 2141
+#define wxRadioBox_Enable_2 2142
+#define wxRadioBox_Enable_1 2143
+#define wxRadioBox_GetSelection 2144
+#define wxRadioBox_GetString 2145
+#define wxRadioBox_SetSelection 2146
+#define wxRadioBox_Show_2 2147
+#define wxRadioBox_Show_1 2148
+#define wxRadioBox_GetColumnCount 2149
+#define wxRadioBox_GetItemHelpText 2150
+#define wxRadioBox_GetItemToolTip 2151
+#define wxRadioBox_GetItemFromPoint 2153
+#define wxRadioBox_GetRowCount 2154
+#define wxRadioBox_IsItemEnabled 2155
+#define wxRadioBox_IsItemShown 2156
+#define wxRadioBox_SetItemHelpText 2157
+#define wxRadioBox_SetItemToolTip 2158
+#define wxRadioButton_new_0 2159
+#define wxRadioButton_new_4 2160
+#define wxRadioButton_Create 2161
+#define wxRadioButton_GetValue 2162
+#define wxRadioButton_SetValue 2163
+#define wxRadioButton_destroy 2164
+#define wxSlider_new_6 2166
+#define wxSlider_new_0 2167
+#define wxSlider_Create 2168
+#define wxSlider_GetLineSize 2169
+#define wxSlider_GetMax 2170
+#define wxSlider_GetMin 2171
+#define wxSlider_GetPageSize 2172
+#define wxSlider_GetThumbLength 2173
+#define wxSlider_GetValue 2174
+#define wxSlider_SetLineSize 2175
+#define wxSlider_SetPageSize 2176
+#define wxSlider_SetRange 2177
+#define wxSlider_SetThumbLength 2178
+#define wxSlider_SetValue 2179
+#define wxSlider_destroy 2180
+#define wxDialog_new_4 2182
+#define wxDialog_new_0 2183
+#define wxDialog_destruct 2185
+#define wxDialog_Create 2186
+#define wxDialog_CreateButtonSizer 2187
+#define wxDialog_CreateStdDialogButtonSizer 2188
+#define wxDialog_EndModal 2189
+#define wxDialog_GetAffirmativeId 2190
+#define wxDialog_GetReturnCode 2191
+#define wxDialog_IsModal 2192
+#define wxDialog_SetAffirmativeId 2193
+#define wxDialog_SetReturnCode 2194
+#define wxDialog_Show 2195
+#define wxDialog_ShowModal 2196
+#define wxColourDialog_new_0 2197
+#define wxColourDialog_new_2 2198
+#define wxColourDialog_destruct 2199
+#define wxColourDialog_Create 2200
+#define wxColourDialog_GetColourData 2201
+#define wxColourData_new_0 2202
+#define wxColourData_new_1 2203
+#define wxColourData_destruct 2204
+#define wxColourData_GetChooseFull 2205
+#define wxColourData_GetColour 2206
+#define wxColourData_GetCustomColour 2208
+#define wxColourData_SetChooseFull 2209
+#define wxColourData_SetColour 2210
+#define wxColourData_SetCustomColour 2211
+#define wxPalette_new_0 2212
+#define wxPalette_new_4 2213
+#define wxPalette_destruct 2215
+#define wxPalette_Create 2216
+#define wxPalette_GetColoursCount 2217
+#define wxPalette_GetPixel 2218
+#define wxPalette_GetRGB 2219
+#define wxPalette_IsOk 2220
+#define wxDirDialog_new 2224
+#define wxDirDialog_destruct 2225
+#define wxDirDialog_GetPath 2226
+#define wxDirDialog_GetMessage 2227
+#define wxDirDialog_SetMessage 2228
+#define wxDirDialog_SetPath 2229
+#define wxFileDialog_new 2233
+#define wxFileDialog_destruct 2234
+#define wxFileDialog_GetDirectory 2235
+#define wxFileDialog_GetFilename 2236
+#define wxFileDialog_GetFilenames 2237
+#define wxFileDialog_GetFilterIndex 2238
+#define wxFileDialog_GetMessage 2239
+#define wxFileDialog_GetPath 2240
+#define wxFileDialog_GetPaths 2241
+#define wxFileDialog_GetWildcard 2242
+#define wxFileDialog_SetDirectory 2243
+#define wxFileDialog_SetFilename 2244
+#define wxFileDialog_SetFilterIndex 2245
+#define wxFileDialog_SetMessage 2246
+#define wxFileDialog_SetPath 2247
+#define wxFileDialog_SetWildcard 2248
+#define wxPickerBase_SetInternalMargin 2249
+#define wxPickerBase_GetInternalMargin 2250
+#define wxPickerBase_SetTextCtrlProportion 2251
+#define wxPickerBase_SetPickerCtrlProportion 2252
+#define wxPickerBase_GetTextCtrlProportion 2253
+#define wxPickerBase_GetPickerCtrlProportion 2254
+#define wxPickerBase_HasTextCtrl 2255
+#define wxPickerBase_GetTextCtrl 2256
+#define wxPickerBase_IsTextCtrlGrowable 2257
+#define wxPickerBase_SetPickerCtrlGrowable 2258
+#define wxPickerBase_SetTextCtrlGrowable 2259
+#define wxPickerBase_IsPickerCtrlGrowable 2260
+#define wxFilePickerCtrl_new_0 2261
+#define wxFilePickerCtrl_new_3 2262
+#define wxFilePickerCtrl_Create 2263
+#define wxFilePickerCtrl_GetPath 2264
+#define wxFilePickerCtrl_SetPath 2265
+#define wxFilePickerCtrl_destroy 2266
+#define wxDirPickerCtrl_new_0 2267
+#define wxDirPickerCtrl_new_3 2268
+#define wxDirPickerCtrl_Create 2269
+#define wxDirPickerCtrl_GetPath 2270
+#define wxDirPickerCtrl_SetPath 2271
+#define wxDirPickerCtrl_destroy 2272
+#define wxColourPickerCtrl_new_0 2273
+#define wxColourPickerCtrl_new_3 2274
+#define wxColourPickerCtrl_Create 2275
+#define wxColourPickerCtrl_GetColour 2276
+#define wxColourPickerCtrl_SetColour_1_1 2277
+#define wxColourPickerCtrl_SetColour_1_0 2278
+#define wxColourPickerCtrl_destroy 2279
+#define wxDatePickerCtrl_new_0 2280
+#define wxDatePickerCtrl_new_3 2281
+#define wxDatePickerCtrl_GetRange 2282
+#define wxDatePickerCtrl_GetValue 2283
+#define wxDatePickerCtrl_SetRange 2284
+#define wxDatePickerCtrl_SetValue 2285
+#define wxDatePickerCtrl_destroy 2286
+#define wxFontPickerCtrl_new_0 2287
+#define wxFontPickerCtrl_new_3 2288
+#define wxFontPickerCtrl_Create 2289
+#define wxFontPickerCtrl_GetSelectedFont 2290
+#define wxFontPickerCtrl_SetSelectedFont 2291
+#define wxFontPickerCtrl_GetMaxPointSize 2292
+#define wxFontPickerCtrl_SetMaxPointSize 2293
+#define wxFontPickerCtrl_destroy 2294
+#define wxFindReplaceDialog_new_0 2297
+#define wxFindReplaceDialog_new_4 2298
+#define wxFindReplaceDialog_destruct 2299
+#define wxFindReplaceDialog_Create 2300
+#define wxFindReplaceDialog_GetData 2301
+#define wxFindReplaceData_new_0 2302
+#define wxFindReplaceData_new_1 2303
+#define wxFindReplaceData_GetFindString 2304
+#define wxFindReplaceData_GetReplaceString 2305
+#define wxFindReplaceData_GetFlags 2306
+#define wxFindReplaceData_SetFlags 2307
+#define wxFindReplaceData_SetFindString 2308
+#define wxFindReplaceData_SetReplaceString 2309
+#define wxFindReplaceData_destroy 2310
+#define wxMultiChoiceDialog_new_0 2311
+#define wxMultiChoiceDialog_new_5 2313
+#define wxMultiChoiceDialog_GetSelections 2314
+#define wxMultiChoiceDialog_SetSelections 2315
+#define wxMultiChoiceDialog_destroy 2316
+#define wxSingleChoiceDialog_new_0 2317
+#define wxSingleChoiceDialog_new_5 2319
+#define wxSingleChoiceDialog_GetSelection 2320
+#define wxSingleChoiceDialog_GetStringSelection 2321
+#define wxSingleChoiceDialog_SetSelection 2322
+#define wxSingleChoiceDialog_destroy 2323
+#define wxTextEntryDialog_new 2324
+#define wxTextEntryDialog_GetValue 2325
+#define wxTextEntryDialog_SetValue 2326
+#define wxTextEntryDialog_destroy 2327
+#define wxPasswordEntryDialog_new 2328
+#define wxPasswordEntryDialog_destroy 2329
+#define wxFontData_new_0 2330
+#define wxFontData_new_1 2331
+#define wxFontData_destruct 2332
+#define wxFontData_EnableEffects 2333
+#define wxFontData_GetAllowSymbols 2334
+#define wxFontData_GetColour 2335
+#define wxFontData_GetChosenFont 2336
+#define wxFontData_GetEnableEffects 2337
+#define wxFontData_GetInitialFont 2338
+#define wxFontData_GetShowHelp 2339
+#define wxFontData_SetAllowSymbols 2340
+#define wxFontData_SetChosenFont 2341
+#define wxFontData_SetColour 2342
+#define wxFontData_SetInitialFont 2343
+#define wxFontData_SetRange 2344
+#define wxFontData_SetShowHelp 2345
+#define wxFontDialog_new_0 2349
+#define wxFontDialog_new_2 2351
+#define wxFontDialog_Create 2353
+#define wxFontDialog_GetFontData 2354
+#define wxFontDialog_destroy 2356
+#define wxProgressDialog_new 2357
+#define wxProgressDialog_destruct 2358
+#define wxProgressDialog_Resume 2359
+#define wxProgressDialog_Update_2 2360
+#define wxProgressDialog_Update_0 2361
+#define wxMessageDialog_new 2362
+#define wxMessageDialog_destruct 2363
+#define wxPageSetupDialog_new 2364
+#define wxPageSetupDialog_destruct 2365
+#define wxPageSetupDialog_GetPageSetupData 2366
+#define wxPageSetupDialog_ShowModal 2367
+#define wxPageSetupDialogData_new_0 2368
+#define wxPageSetupDialogData_new_1_0 2369
+#define wxPageSetupDialogData_new_1_1 2370
+#define wxPageSetupDialogData_destruct 2371
+#define wxPageSetupDialogData_EnableHelp 2372
+#define wxPageSetupDialogData_EnableMargins 2373
+#define wxPageSetupDialogData_EnableOrientation 2374
+#define wxPageSetupDialogData_EnablePaper 2375
+#define wxPageSetupDialogData_EnablePrinter 2376
+#define wxPageSetupDialogData_GetDefaultMinMargins 2377
+#define wxPageSetupDialogData_GetEnableMargins 2378
+#define wxPageSetupDialogData_GetEnableOrientation 2379
+#define wxPageSetupDialogData_GetEnablePaper 2380
+#define wxPageSetupDialogData_GetEnablePrinter 2381
+#define wxPageSetupDialogData_GetEnableHelp 2382
+#define wxPageSetupDialogData_GetDefaultInfo 2383
+#define wxPageSetupDialogData_GetMarginTopLeft 2384
+#define wxPageSetupDialogData_GetMarginBottomRight 2385
+#define wxPageSetupDialogData_GetMinMarginTopLeft 2386
+#define wxPageSetupDialogData_GetMinMarginBottomRight 2387
+#define wxPageSetupDialogData_GetPaperId 2388
+#define wxPageSetupDialogData_GetPaperSize 2389
+#define wxPageSetupDialogData_GetPrintData 2391
+#define wxPageSetupDialogData_IsOk 2392
+#define wxPageSetupDialogData_SetDefaultInfo 2393
+#define wxPageSetupDialogData_SetDefaultMinMargins 2394
+#define wxPageSetupDialogData_SetMarginTopLeft 2395
+#define wxPageSetupDialogData_SetMarginBottomRight 2396
+#define wxPageSetupDialogData_SetMinMarginTopLeft 2397
+#define wxPageSetupDialogData_SetMinMarginBottomRight 2398
+#define wxPageSetupDialogData_SetPaperId 2399
+#define wxPageSetupDialogData_SetPaperSize_1_1 2400
+#define wxPageSetupDialogData_SetPaperSize_1_0 2401
+#define wxPageSetupDialogData_SetPrintData 2402
+#define wxPrintDialog_new_2_0 2403
+#define wxPrintDialog_new_2_1 2404
+#define wxPrintDialog_destruct 2405
+#define wxPrintDialog_GetPrintDialogData 2406
+#define wxPrintDialog_GetPrintDC 2407
+#define wxPrintDialogData_new_0 2408
+#define wxPrintDialogData_new_1_1 2409
+#define wxPrintDialogData_new_1_0 2410
+#define wxPrintDialogData_destruct 2411
+#define wxPrintDialogData_EnableHelp 2412
+#define wxPrintDialogData_EnablePageNumbers 2413
+#define wxPrintDialogData_EnablePrintToFile 2414
+#define wxPrintDialogData_EnableSelection 2415
+#define wxPrintDialogData_GetAllPages 2416
+#define wxPrintDialogData_GetCollate 2417
+#define wxPrintDialogData_GetFromPage 2418
+#define wxPrintDialogData_GetMaxPage 2419
+#define wxPrintDialogData_GetMinPage 2420
+#define wxPrintDialogData_GetNoCopies 2421
+#define wxPrintDialogData_GetPrintData 2422
+#define wxPrintDialogData_GetPrintToFile 2423
+#define wxPrintDialogData_GetSelection 2424
+#define wxPrintDialogData_GetToPage 2425
+#define wxPrintDialogData_IsOk 2426
+#define wxPrintDialogData_SetCollate 2427
+#define wxPrintDialogData_SetFromPage 2428
+#define wxPrintDialogData_SetMaxPage 2429
+#define wxPrintDialogData_SetMinPage 2430
+#define wxPrintDialogData_SetNoCopies 2431
+#define wxPrintDialogData_SetPrintData 2432
+#define wxPrintDialogData_SetPrintToFile 2433
+#define wxPrintDialogData_SetSelection 2434
+#define wxPrintDialogData_SetToPage 2435
+#define wxPrintData_new_0 2436
+#define wxPrintData_new_1 2437
+#define wxPrintData_destruct 2438
+#define wxPrintData_GetCollate 2439
+#define wxPrintData_GetBin 2440
+#define wxPrintData_GetColour 2441
+#define wxPrintData_GetDuplex 2442
+#define wxPrintData_GetNoCopies 2443
+#define wxPrintData_GetOrientation 2444
+#define wxPrintData_GetPaperId 2445
+#define wxPrintData_GetPrinterName 2446
+#define wxPrintData_GetQuality 2447
+#define wxPrintData_IsOk 2448
+#define wxPrintData_SetBin 2449
+#define wxPrintData_SetCollate 2450
+#define wxPrintData_SetColour 2451
+#define wxPrintData_SetDuplex 2452
+#define wxPrintData_SetNoCopies 2453
+#define wxPrintData_SetOrientation 2454
+#define wxPrintData_SetPaperId 2455
+#define wxPrintData_SetPrinterName 2456
+#define wxPrintData_SetQuality 2457
+#define wxPrintPreview_new_2 2460
+#define wxPrintPreview_new_3 2461
+#define wxPrintPreview_destruct 2463
+#define wxPrintPreview_GetCanvas 2464
+#define wxPrintPreview_GetCurrentPage 2465
+#define wxPrintPreview_GetFrame 2466
+#define wxPrintPreview_GetMaxPage 2467
+#define wxPrintPreview_GetMinPage 2468
+#define wxPrintPreview_GetPrintout 2469
+#define wxPrintPreview_GetPrintoutForPrinting 2470
+#define wxPrintPreview_IsOk 2471
+#define wxPrintPreview_PaintPage 2472
+#define wxPrintPreview_Print 2473
+#define wxPrintPreview_RenderPage 2474
+#define wxPrintPreview_SetCanvas 2475
+#define wxPrintPreview_SetCurrentPage 2476
+#define wxPrintPreview_SetFrame 2477
+#define wxPrintPreview_SetPrintout 2478
+#define wxPrintPreview_SetZoom 2479
+#define wxPreviewFrame_new 2480
+#define wxPreviewFrame_destruct 2481
+#define wxPreviewFrame_CreateControlBar 2482
+#define wxPreviewFrame_CreateCanvas 2483
+#define wxPreviewFrame_Initialize 2484
+#define wxPreviewFrame_OnCloseWindow 2485
+#define wxPreviewControlBar_new 2486
+#define wxPreviewControlBar_destruct 2487
+#define wxPreviewControlBar_CreateButtons 2488
+#define wxPreviewControlBar_GetPrintPreview 2489
+#define wxPreviewControlBar_GetZoomControl 2490
+#define wxPreviewControlBar_SetZoomControl 2491
+#define wxPrinter_new 2493
+#define wxPrinter_CreateAbortWindow 2494
+#define wxPrinter_GetAbort 2495
+#define wxPrinter_GetLastError 2496
+#define wxPrinter_GetPrintDialogData 2497
+#define wxPrinter_Print 2498
+#define wxPrinter_PrintDialog 2499
+#define wxPrinter_ReportError 2500
+#define wxPrinter_Setup 2501
+#define wxPrinter_destroy 2502
+#define wxXmlResource_new_1 2503
+#define wxXmlResource_new_2 2504
+#define wxXmlResource_destruct 2505
+#define wxXmlResource_AttachUnknownControl 2506
+#define wxXmlResource_ClearHandlers 2507
+#define wxXmlResource_CompareVersion 2508
+#define wxXmlResource_Get 2509
+#define wxXmlResource_GetFlags 2510
+#define wxXmlResource_GetVersion 2511
+#define wxXmlResource_GetXRCID 2512
+#define wxXmlResource_InitAllHandlers 2513
+#define wxXmlResource_Load 2514
+#define wxXmlResource_LoadBitmap 2515
+#define wxXmlResource_LoadDialog_2 2516
+#define wxXmlResource_LoadDialog_3 2517
+#define wxXmlResource_LoadFrame_2 2518
+#define wxXmlResource_LoadFrame_3 2519
+#define wxXmlResource_LoadIcon 2520
+#define wxXmlResource_LoadMenu 2521
+#define wxXmlResource_LoadMenuBar_2 2522
+#define wxXmlResource_LoadMenuBar_1 2523
+#define wxXmlResource_LoadPanel_2 2524
+#define wxXmlResource_LoadPanel_3 2525
+#define wxXmlResource_LoadToolBar 2526
+#define wxXmlResource_Set 2527
+#define wxXmlResource_SetFlags 2528
+#define wxXmlResource_Unload 2529
+#define wxXmlResource_xrcctrl 2530
+#define wxHtmlEasyPrinting_new 2531
+#define wxHtmlEasyPrinting_destruct 2532
+#define wxHtmlEasyPrinting_GetPrintData 2533
+#define wxHtmlEasyPrinting_GetPageSetupData 2534
+#define wxHtmlEasyPrinting_PreviewFile 2535
+#define wxHtmlEasyPrinting_PreviewText 2536
+#define wxHtmlEasyPrinting_PrintFile 2537
+#define wxHtmlEasyPrinting_PrintText 2538
+#define wxHtmlEasyPrinting_PageSetup 2539
+#define wxHtmlEasyPrinting_SetFonts 2540
+#define wxHtmlEasyPrinting_SetHeader 2541
+#define wxHtmlEasyPrinting_SetFooter 2542
+#define wxGLCanvas_new_2 2544
+#define wxGLCanvas_new_3_1 2545
+#define wxGLCanvas_new_3_0 2546
+#define wxGLCanvas_GetContext 2547
+#define wxGLCanvas_SetCurrent 2549
+#define wxGLCanvas_SwapBuffers 2550
+#define wxGLCanvas_destroy 2551
+#define wxAuiManager_new 2552
+#define wxAuiManager_destruct 2553
+#define wxAuiManager_AddPane_2_1 2554
+#define wxAuiManager_AddPane_3 2555
+#define wxAuiManager_AddPane_2_0 2556
+#define wxAuiManager_DetachPane 2557
+#define wxAuiManager_GetAllPanes 2558
+#define wxAuiManager_GetArtProvider 2559
+#define wxAuiManager_GetDockSizeConstraint 2560
+#define wxAuiManager_GetFlags 2561
+#define wxAuiManager_GetManagedWindow 2562
+#define wxAuiManager_GetManager 2563
+#define wxAuiManager_GetPane_1_1 2564
+#define wxAuiManager_GetPane_1_0 2565
+#define wxAuiManager_HideHint 2566
+#define wxAuiManager_InsertPane 2567
+#define wxAuiManager_LoadPaneInfo 2568
+#define wxAuiManager_LoadPerspective 2569
+#define wxAuiManager_SavePaneInfo 2570
+#define wxAuiManager_SavePerspective 2571
+#define wxAuiManager_SetArtProvider 2572
+#define wxAuiManager_SetDockSizeConstraint 2573
+#define wxAuiManager_SetFlags 2574
+#define wxAuiManager_SetManagedWindow 2575
+#define wxAuiManager_ShowHint 2576
+#define wxAuiManager_UnInit 2577
+#define wxAuiManager_Update 2578
+#define wxAuiPaneInfo_new_0 2579
+#define wxAuiPaneInfo_new_1 2580
+#define wxAuiPaneInfo_destruct 2581
+#define wxAuiPaneInfo_BestSize_1 2582
+#define wxAuiPaneInfo_BestSize_2 2583
+#define wxAuiPaneInfo_Bottom 2584
+#define wxAuiPaneInfo_BottomDockable 2585
+#define wxAuiPaneInfo_Caption 2586
+#define wxAuiPaneInfo_CaptionVisible 2587
+#define wxAuiPaneInfo_Centre 2588
+#define wxAuiPaneInfo_CentrePane 2589
+#define wxAuiPaneInfo_CloseButton 2590
+#define wxAuiPaneInfo_DefaultPane 2591
+#define wxAuiPaneInfo_DestroyOnClose 2592
+#define wxAuiPaneInfo_Direction 2593
+#define wxAuiPaneInfo_Dock 2594
+#define wxAuiPaneInfo_Dockable 2595
+#define wxAuiPaneInfo_Fixed 2596
+#define wxAuiPaneInfo_Float 2597
+#define wxAuiPaneInfo_Floatable 2598
+#define wxAuiPaneInfo_FloatingPosition_1 2599
+#define wxAuiPaneInfo_FloatingPosition_2 2600
+#define wxAuiPaneInfo_FloatingSize_1 2601
+#define wxAuiPaneInfo_FloatingSize_2 2602
+#define wxAuiPaneInfo_Gripper 2603
+#define wxAuiPaneInfo_GripperTop 2604
+#define wxAuiPaneInfo_HasBorder 2605
+#define wxAuiPaneInfo_HasCaption 2606
+#define wxAuiPaneInfo_HasCloseButton 2607
+#define wxAuiPaneInfo_HasFlag 2608
+#define wxAuiPaneInfo_HasGripper 2609
+#define wxAuiPaneInfo_HasGripperTop 2610
+#define wxAuiPaneInfo_HasMaximizeButton 2611
+#define wxAuiPaneInfo_HasMinimizeButton 2612
+#define wxAuiPaneInfo_HasPinButton 2613
+#define wxAuiPaneInfo_Hide 2614
+#define wxAuiPaneInfo_IsBottomDockable 2615
+#define wxAuiPaneInfo_IsDocked 2616
+#define wxAuiPaneInfo_IsFixed 2617
+#define wxAuiPaneInfo_IsFloatable 2618
+#define wxAuiPaneInfo_IsFloating 2619
+#define wxAuiPaneInfo_IsLeftDockable 2620
+#define wxAuiPaneInfo_IsMovable 2621
+#define wxAuiPaneInfo_IsOk 2622
+#define wxAuiPaneInfo_IsResizable 2623
+#define wxAuiPaneInfo_IsRightDockable 2624
+#define wxAuiPaneInfo_IsShown 2625
+#define wxAuiPaneInfo_IsToolbar 2626
+#define wxAuiPaneInfo_IsTopDockable 2627
+#define wxAuiPaneInfo_Layer 2628
+#define wxAuiPaneInfo_Left 2629
+#define wxAuiPaneInfo_LeftDockable 2630
+#define wxAuiPaneInfo_MaxSize_1 2631
+#define wxAuiPaneInfo_MaxSize_2 2632
+#define wxAuiPaneInfo_MaximizeButton 2633
+#define wxAuiPaneInfo_MinSize_1 2634
+#define wxAuiPaneInfo_MinSize_2 2635
+#define wxAuiPaneInfo_MinimizeButton 2636
+#define wxAuiPaneInfo_Movable 2637
+#define wxAuiPaneInfo_Name 2638
+#define wxAuiPaneInfo_PaneBorder 2639
+#define wxAuiPaneInfo_PinButton 2640
+#define wxAuiPaneInfo_Position 2641
+#define wxAuiPaneInfo_Resizable 2642
+#define wxAuiPaneInfo_Right 2643
+#define wxAuiPaneInfo_RightDockable 2644
+#define wxAuiPaneInfo_Row 2645
+#define wxAuiPaneInfo_SafeSet 2646
+#define wxAuiPaneInfo_SetFlag 2647
+#define wxAuiPaneInfo_Show 2648
+#define wxAuiPaneInfo_ToolbarPane 2649
+#define wxAuiPaneInfo_Top 2650
+#define wxAuiPaneInfo_TopDockable 2651
+#define wxAuiPaneInfo_Window 2652
+#define wxAuiNotebook_new_0 2653
+#define wxAuiNotebook_new_2 2654
+#define wxAuiNotebook_AddPage 2655
+#define wxAuiNotebook_Create 2656
+#define wxAuiNotebook_DeletePage 2657
+#define wxAuiNotebook_GetArtProvider 2658
+#define wxAuiNotebook_GetPage 2659
+#define wxAuiNotebook_GetPageBitmap 2660
+#define wxAuiNotebook_GetPageCount 2661
+#define wxAuiNotebook_GetPageIndex 2662
+#define wxAuiNotebook_GetPageText 2663
+#define wxAuiNotebook_GetSelection 2664
+#define wxAuiNotebook_InsertPage 2665
+#define wxAuiNotebook_RemovePage 2666
+#define wxAuiNotebook_SetArtProvider 2667
+#define wxAuiNotebook_SetFont 2668
+#define wxAuiNotebook_SetPageBitmap 2669
+#define wxAuiNotebook_SetPageText 2670
+#define wxAuiNotebook_SetSelection 2671
+#define wxAuiNotebook_SetTabCtrlHeight 2672
+#define wxAuiNotebook_SetUniformBitmapSize 2673
+#define wxAuiNotebook_destroy 2674
+#define wxMDIParentFrame_new_0 2675
+#define wxMDIParentFrame_new_4 2676
+#define wxMDIParentFrame_destruct 2677
+#define wxMDIParentFrame_ActivateNext 2678
+#define wxMDIParentFrame_ActivatePrevious 2679
+#define wxMDIParentFrame_ArrangeIcons 2680
+#define wxMDIParentFrame_Cascade 2681
+#define wxMDIParentFrame_Create 2682
+#define wxMDIParentFrame_GetActiveChild 2683
+#define wxMDIParentFrame_GetClientWindow 2684
+#define wxMDIParentFrame_Tile 2685
+#define wxMDIChildFrame_new_0 2686
+#define wxMDIChildFrame_new_4 2687
+#define wxMDIChildFrame_destruct 2688
+#define wxMDIChildFrame_Activate 2689
+#define wxMDIChildFrame_Create 2690
+#define wxMDIChildFrame_Maximize 2691
+#define wxMDIChildFrame_Restore 2692
+#define wxMDIClientWindow_new_0 2693
+#define wxMDIClientWindow_new_2 2694
+#define wxMDIClientWindow_destruct 2695
+#define wxMDIClientWindow_CreateClient 2696
+#define wxLayoutAlgorithm_new 2697
+#define wxLayoutAlgorithm_LayoutFrame 2698
+#define wxLayoutAlgorithm_LayoutMDIFrame 2699
+#define wxLayoutAlgorithm_LayoutWindow 2700
+#define wxLayoutAlgorithm_destroy 2701
+#define wxEvent_GetId 2702
+#define wxEvent_GetSkipped 2703
+#define wxEvent_GetTimestamp 2704
+#define wxEvent_IsCommandEvent 2705
+#define wxEvent_ResumePropagation 2706
+#define wxEvent_ShouldPropagate 2707
+#define wxEvent_Skip 2708
+#define wxEvent_StopPropagation 2709
+#define wxCommandEvent_getClientData 2710
+#define wxCommandEvent_GetExtraLong 2711
+#define wxCommandEvent_GetInt 2712
+#define wxCommandEvent_GetSelection 2713
+#define wxCommandEvent_GetString 2714
+#define wxCommandEvent_IsChecked 2715
+#define wxCommandEvent_IsSelection 2716
+#define wxCommandEvent_SetInt 2717
+#define wxCommandEvent_SetString 2718
+#define wxScrollEvent_GetOrientation 2719
+#define wxScrollEvent_GetPosition 2720
+#define wxScrollWinEvent_GetOrientation 2721
+#define wxScrollWinEvent_GetPosition 2722
+#define wxMouseEvent_AltDown 2723
+#define wxMouseEvent_Button 2724
+#define wxMouseEvent_ButtonDClick 2725
+#define wxMouseEvent_ButtonDown 2726
+#define wxMouseEvent_ButtonUp 2727
+#define wxMouseEvent_CmdDown 2728
+#define wxMouseEvent_ControlDown 2729
+#define wxMouseEvent_Dragging 2730
+#define wxMouseEvent_Entering 2731
+#define wxMouseEvent_GetButton 2732
+#define wxMouseEvent_GetPosition 2735
+#define wxMouseEvent_GetLogicalPosition 2736
+#define wxMouseEvent_GetLinesPerAction 2737
+#define wxMouseEvent_GetWheelRotation 2738
+#define wxMouseEvent_GetWheelDelta 2739
+#define wxMouseEvent_GetX 2740
+#define wxMouseEvent_GetY 2741
+#define wxMouseEvent_IsButton 2742
+#define wxMouseEvent_IsPageScroll 2743
+#define wxMouseEvent_Leaving 2744
+#define wxMouseEvent_LeftDClick 2745
+#define wxMouseEvent_LeftDown 2746
+#define wxMouseEvent_LeftIsDown 2747
+#define wxMouseEvent_LeftUp 2748
+#define wxMouseEvent_MetaDown 2749
+#define wxMouseEvent_MiddleDClick 2750
+#define wxMouseEvent_MiddleDown 2751
+#define wxMouseEvent_MiddleIsDown 2752
+#define wxMouseEvent_MiddleUp 2753
+#define wxMouseEvent_Moving 2754
+#define wxMouseEvent_RightDClick 2755
+#define wxMouseEvent_RightDown 2756
+#define wxMouseEvent_RightIsDown 2757
+#define wxMouseEvent_RightUp 2758
+#define wxMouseEvent_ShiftDown 2759
+#define wxSetCursorEvent_GetCursor 2760
+#define wxSetCursorEvent_GetX 2761
+#define wxSetCursorEvent_GetY 2762
+#define wxSetCursorEvent_HasCursor 2763
+#define wxSetCursorEvent_SetCursor 2764
+#define wxKeyEvent_AltDown 2765
+#define wxKeyEvent_CmdDown 2766
+#define wxKeyEvent_ControlDown 2767
+#define wxKeyEvent_GetKeyCode 2768
+#define wxKeyEvent_GetModifiers 2769
+#define wxKeyEvent_GetPosition 2772
+#define wxKeyEvent_GetRawKeyCode 2773
+#define wxKeyEvent_GetRawKeyFlags 2774
+#define wxKeyEvent_GetUnicodeKey 2775
+#define wxKeyEvent_GetX 2776
+#define wxKeyEvent_GetY 2777
+#define wxKeyEvent_HasModifiers 2778
+#define wxKeyEvent_MetaDown 2779
+#define wxKeyEvent_ShiftDown 2780
+#define wxSizeEvent_GetSize 2781
+#define wxMoveEvent_GetPosition 2782
+#define wxEraseEvent_GetDC 2783
+#define wxFocusEvent_GetWindow 2784
+#define wxChildFocusEvent_GetWindow 2785
+#define wxMenuEvent_GetMenu 2786
+#define wxMenuEvent_GetMenuId 2787
+#define wxMenuEvent_IsPopup 2788
+#define wxCloseEvent_CanVeto 2789
+#define wxCloseEvent_GetLoggingOff 2790
+#define wxCloseEvent_SetCanVeto 2791
+#define wxCloseEvent_SetLoggingOff 2792
+#define wxCloseEvent_Veto 2793
+#define wxShowEvent_SetShow 2794
+#define wxShowEvent_GetShow 2795
+#define wxIconizeEvent_Iconized 2796
+#define wxJoystickEvent_ButtonDown 2797
+#define wxJoystickEvent_ButtonIsDown 2798
+#define wxJoystickEvent_ButtonUp 2799
+#define wxJoystickEvent_GetButtonChange 2800
+#define wxJoystickEvent_GetButtonState 2801
+#define wxJoystickEvent_GetJoystick 2802
+#define wxJoystickEvent_GetPosition 2803
+#define wxJoystickEvent_GetZPosition 2804
+#define wxJoystickEvent_IsButton 2805
+#define wxJoystickEvent_IsMove 2806
+#define wxJoystickEvent_IsZMove 2807
+#define wxUpdateUIEvent_CanUpdate 2808
+#define wxUpdateUIEvent_Check 2809
+#define wxUpdateUIEvent_Enable 2810
+#define wxUpdateUIEvent_Show 2811
+#define wxUpdateUIEvent_GetChecked 2812
+#define wxUpdateUIEvent_GetEnabled 2813
+#define wxUpdateUIEvent_GetShown 2814
+#define wxUpdateUIEvent_GetSetChecked 2815
+#define wxUpdateUIEvent_GetSetEnabled 2816
+#define wxUpdateUIEvent_GetSetShown 2817
+#define wxUpdateUIEvent_GetSetText 2818
+#define wxUpdateUIEvent_GetText 2819
+#define wxUpdateUIEvent_GetMode 2820
+#define wxUpdateUIEvent_GetUpdateInterval 2821
+#define wxUpdateUIEvent_ResetUpdateTime 2822
+#define wxUpdateUIEvent_SetMode 2823
+#define wxUpdateUIEvent_SetText 2824
+#define wxUpdateUIEvent_SetUpdateInterval 2825
+#define wxMouseCaptureChangedEvent_GetCapturedWindow 2826
+#define wxPaletteChangedEvent_SetChangedWindow 2827
+#define wxPaletteChangedEvent_GetChangedWindow 2828
+#define wxQueryNewPaletteEvent_SetPaletteRealized 2829
+#define wxQueryNewPaletteEvent_GetPaletteRealized 2830
+#define wxNavigationKeyEvent_GetDirection 2831
+#define wxNavigationKeyEvent_SetDirection 2832
+#define wxNavigationKeyEvent_IsWindowChange 2833
+#define wxNavigationKeyEvent_SetWindowChange 2834
+#define wxNavigationKeyEvent_IsFromTab 2835
+#define wxNavigationKeyEvent_SetFromTab 2836
+#define wxNavigationKeyEvent_GetCurrentFocus 2837
+#define wxNavigationKeyEvent_SetCurrentFocus 2838
+#define wxHelpEvent_GetOrigin 2839
+#define wxHelpEvent_GetPosition 2840
+#define wxHelpEvent_SetOrigin 2841
+#define wxHelpEvent_SetPosition 2842
+#define wxContextMenuEvent_GetPosition 2843
+#define wxContextMenuEvent_SetPosition 2844
+#define wxIdleEvent_CanSend 2845
+#define wxIdleEvent_GetMode 2846
+#define wxIdleEvent_RequestMore 2847
+#define wxIdleEvent_MoreRequested 2848
+#define wxIdleEvent_SetMode 2849
+#define wxGridEvent_AltDown 2850
+#define wxGridEvent_ControlDown 2851
+#define wxGridEvent_GetCol 2852
+#define wxGridEvent_GetPosition 2853
+#define wxGridEvent_GetRow 2854
+#define wxGridEvent_MetaDown 2855
+#define wxGridEvent_Selecting 2856
+#define wxGridEvent_ShiftDown 2857
+#define wxNotifyEvent_Allow 2858
+#define wxNotifyEvent_IsAllowed 2859
+#define wxNotifyEvent_Veto 2860
+#define wxSashEvent_GetEdge 2861
+#define wxSashEvent_GetDragRect 2862
+#define wxSashEvent_GetDragStatus 2863
+#define wxListEvent_GetCacheFrom 2864
+#define wxListEvent_GetCacheTo 2865
+#define wxListEvent_GetKeyCode 2866
+#define wxListEvent_GetIndex 2867
+#define wxListEvent_GetColumn 2868
+#define wxListEvent_GetPoint 2869
+#define wxListEvent_GetLabel 2870
+#define wxListEvent_GetText 2871
+#define wxListEvent_GetImage 2872
+#define wxListEvent_GetData 2873
+#define wxListEvent_GetMask 2874
+#define wxListEvent_GetItem 2875
+#define wxListEvent_IsEditCancelled 2876
+#define wxDateEvent_GetDate 2877
+#define wxCalendarEvent_GetWeekDay 2878
+#define wxFileDirPickerEvent_GetPath 2879
+#define wxColourPickerEvent_GetColour 2880
+#define wxFontPickerEvent_GetFont 2881
+#define wxStyledTextEvent_GetPosition 2882
+#define wxStyledTextEvent_GetKey 2883
+#define wxStyledTextEvent_GetModifiers 2884
+#define wxStyledTextEvent_GetModificationType 2885
+#define wxStyledTextEvent_GetText 2886
+#define wxStyledTextEvent_GetLength 2887
+#define wxStyledTextEvent_GetLinesAdded 2888
+#define wxStyledTextEvent_GetLine 2889
+#define wxStyledTextEvent_GetFoldLevelNow 2890
+#define wxStyledTextEvent_GetFoldLevelPrev 2891
+#define wxStyledTextEvent_GetMargin 2892
+#define wxStyledTextEvent_GetMessage 2893
+#define wxStyledTextEvent_GetWParam 2894
+#define wxStyledTextEvent_GetLParam 2895
+#define wxStyledTextEvent_GetListType 2896
+#define wxStyledTextEvent_GetX 2897
+#define wxStyledTextEvent_GetY 2898
+#define wxStyledTextEvent_GetDragText 2899
+#define wxStyledTextEvent_GetDragAllowMove 2900
+#define wxStyledTextEvent_GetDragResult 2901
+#define wxStyledTextEvent_GetShift 2902
+#define wxStyledTextEvent_GetControl 2903
+#define wxStyledTextEvent_GetAlt 2904
+#define utils_wxGetKeyState 2905
+#define utils_wxGetMousePosition 2906
+#define utils_wxGetMouseState 2907
+#define utils_wxSetDetectableAutoRepeat 2908
+#define utils_wxBell 2909
+#define utils_wxFindMenuItemId 2910
+#define utils_wxGenericFindWindowAtPoint 2911
+#define utils_wxFindWindowAtPoint 2912
+#define utils_wxBeginBusyCursor 2913
+#define utils_wxEndBusyCursor 2914
+#define utils_wxIsBusy 2915
+#define utils_wxShutdown 2916
+#define utils_wxShell 2917
+#define utils_wxLaunchDefaultBrowser 2918
+#define utils_wxGetEmailAddress 2919
+#define utils_wxGetUserId 2920
+#define utils_wxGetHomeDir 2921
+#define utils_wxNewId 2922
+#define utils_wxRegisterId 2923
+#define utils_wxGetCurrentId 2924
+#define utils_wxGetOsDescription 2925
+#define utils_wxIsPlatformLittleEndian 2926
+#define utils_wxIsPlatform64Bit 2927
+#define gdicmn_wxDisplaySize 2928
+#define gdicmn_wxSetCursor 2929
+#define wxPrintout_new 2930
+#define wxPrintout_destruct 2931
+#define wxPrintout_GetDC 2932
+#define wxPrintout_GetPageSizeMM 2933
+#define wxPrintout_GetPageSizePixels 2934
+#define wxPrintout_GetPaperRectPixels 2935
+#define wxPrintout_GetPPIPrinter 2936
+#define wxPrintout_GetPPIScreen 2937
+#define wxPrintout_GetTitle 2938
+#define wxPrintout_IsPreview 2939
+#define wxPrintout_FitThisSizeToPaper 2940
+#define wxPrintout_FitThisSizeToPage 2941
+#define wxPrintout_FitThisSizeToPageMargins 2942
+#define wxPrintout_MapScreenSizeToPaper 2943
+#define wxPrintout_MapScreenSizeToPage 2944
+#define wxPrintout_MapScreenSizeToPageMargins 2945
+#define wxPrintout_MapScreenSizeToDevice 2946
+#define wxPrintout_GetLogicalPaperRect 2947
+#define wxPrintout_GetLogicalPageRect 2948
+#define wxPrintout_GetLogicalPageMarginsRect 2949
+#define wxPrintout_SetLogicalOrigin 2950
+#define wxPrintout_OffsetLogicalOrigin 2951
+#define wxStyledTextCtrl_new_2 2952
+#define wxStyledTextCtrl_new_0 2953
+#define wxStyledTextCtrl_destruct 2954
+#define wxStyledTextCtrl_Create 2955
+#define wxStyledTextCtrl_AddText 2956
+#define wxStyledTextCtrl_AddStyledText 2957
+#define wxStyledTextCtrl_InsertText 2958
+#define wxStyledTextCtrl_ClearAll 2959
+#define wxStyledTextCtrl_ClearDocumentStyle 2960
+#define wxStyledTextCtrl_GetLength 2961
+#define wxStyledTextCtrl_GetCharAt 2962
+#define wxStyledTextCtrl_GetCurrentPos 2963
+#define wxStyledTextCtrl_GetAnchor 2964
+#define wxStyledTextCtrl_GetStyleAt 2965
+#define wxStyledTextCtrl_Redo 2966
+#define wxStyledTextCtrl_SetUndoCollection 2967
+#define wxStyledTextCtrl_SelectAll 2968
+#define wxStyledTextCtrl_SetSavePoint 2969
+#define wxStyledTextCtrl_GetStyledText 2970
+#define wxStyledTextCtrl_CanRedo 2971
+#define wxStyledTextCtrl_MarkerLineFromHandle 2972
+#define wxStyledTextCtrl_MarkerDeleteHandle 2973
+#define wxStyledTextCtrl_GetUndoCollection 2974
+#define wxStyledTextCtrl_GetViewWhiteSpace 2975
+#define wxStyledTextCtrl_SetViewWhiteSpace 2976
+#define wxStyledTextCtrl_PositionFromPoint 2977
+#define wxStyledTextCtrl_PositionFromPointClose 2978
+#define wxStyledTextCtrl_GotoLine 2979
+#define wxStyledTextCtrl_GotoPos 2980
+#define wxStyledTextCtrl_SetAnchor 2981
+#define wxStyledTextCtrl_GetCurLine 2982
+#define wxStyledTextCtrl_GetEndStyled 2983
+#define wxStyledTextCtrl_ConvertEOLs 2984
+#define wxStyledTextCtrl_GetEOLMode 2985
+#define wxStyledTextCtrl_SetEOLMode 2986
+#define wxStyledTextCtrl_StartStyling 2987
+#define wxStyledTextCtrl_SetStyling 2988
+#define wxStyledTextCtrl_GetBufferedDraw 2989
+#define wxStyledTextCtrl_SetBufferedDraw 2990
+#define wxStyledTextCtrl_SetTabWidth 2991
+#define wxStyledTextCtrl_GetTabWidth 2992
+#define wxStyledTextCtrl_SetCodePage 2993
+#define wxStyledTextCtrl_MarkerDefine 2994
+#define wxStyledTextCtrl_MarkerSetForeground 2995
+#define wxStyledTextCtrl_MarkerSetBackground 2996
+#define wxStyledTextCtrl_MarkerAdd 2997
+#define wxStyledTextCtrl_MarkerDelete 2998
+#define wxStyledTextCtrl_MarkerDeleteAll 2999
+#define wxStyledTextCtrl_MarkerGet 3000
+#define wxStyledTextCtrl_MarkerNext 3001
+#define wxStyledTextCtrl_MarkerPrevious 3002
+#define wxStyledTextCtrl_MarkerDefineBitmap 3003
+#define wxStyledTextCtrl_MarkerAddSet 3004
+#define wxStyledTextCtrl_MarkerSetAlpha 3005
+#define wxStyledTextCtrl_SetMarginType 3006
+#define wxStyledTextCtrl_GetMarginType 3007
+#define wxStyledTextCtrl_SetMarginWidth 3008
+#define wxStyledTextCtrl_GetMarginWidth 3009
+#define wxStyledTextCtrl_SetMarginMask 3010
+#define wxStyledTextCtrl_GetMarginMask 3011
+#define wxStyledTextCtrl_SetMarginSensitive 3012
+#define wxStyledTextCtrl_GetMarginSensitive 3013
+#define wxStyledTextCtrl_StyleClearAll 3014
+#define wxStyledTextCtrl_StyleSetForeground 3015
+#define wxStyledTextCtrl_StyleSetBackground 3016
+#define wxStyledTextCtrl_StyleSetBold 3017
+#define wxStyledTextCtrl_StyleSetItalic 3018
+#define wxStyledTextCtrl_StyleSetSize 3019
+#define wxStyledTextCtrl_StyleSetFaceName 3020
+#define wxStyledTextCtrl_StyleSetEOLFilled 3021
+#define wxStyledTextCtrl_StyleResetDefault 3022
+#define wxStyledTextCtrl_StyleSetUnderline 3023
+#define wxStyledTextCtrl_StyleSetCase 3024
+#define wxStyledTextCtrl_StyleSetHotSpot 3025
+#define wxStyledTextCtrl_SetSelForeground 3026
+#define wxStyledTextCtrl_SetSelBackground 3027
+#define wxStyledTextCtrl_GetSelAlpha 3028
+#define wxStyledTextCtrl_SetSelAlpha 3029
+#define wxStyledTextCtrl_SetCaretForeground 3030
+#define wxStyledTextCtrl_CmdKeyAssign 3031
+#define wxStyledTextCtrl_CmdKeyClear 3032
+#define wxStyledTextCtrl_CmdKeyClearAll 3033
+#define wxStyledTextCtrl_SetStyleBytes 3034
+#define wxStyledTextCtrl_StyleSetVisible 3035
+#define wxStyledTextCtrl_GetCaretPeriod 3036
+#define wxStyledTextCtrl_SetCaretPeriod 3037
+#define wxStyledTextCtrl_SetWordChars 3038
+#define wxStyledTextCtrl_BeginUndoAction 3039
+#define wxStyledTextCtrl_EndUndoAction 3040
+#define wxStyledTextCtrl_IndicatorSetStyle 3041
+#define wxStyledTextCtrl_IndicatorGetStyle 3042
+#define wxStyledTextCtrl_IndicatorSetForeground 3043
+#define wxStyledTextCtrl_IndicatorGetForeground 3044
+#define wxStyledTextCtrl_SetWhitespaceForeground 3045
+#define wxStyledTextCtrl_SetWhitespaceBackground 3046
+#define wxStyledTextCtrl_GetStyleBits 3047
+#define wxStyledTextCtrl_SetLineState 3048
+#define wxStyledTextCtrl_GetLineState 3049
+#define wxStyledTextCtrl_GetMaxLineState 3050
+#define wxStyledTextCtrl_GetCaretLineVisible 3051
+#define wxStyledTextCtrl_SetCaretLineVisible 3052
+#define wxStyledTextCtrl_GetCaretLineBackground 3053
+#define wxStyledTextCtrl_SetCaretLineBackground 3054
+#define wxStyledTextCtrl_AutoCompShow 3055
+#define wxStyledTextCtrl_AutoCompCancel 3056
+#define wxStyledTextCtrl_AutoCompActive 3057
+#define wxStyledTextCtrl_AutoCompPosStart 3058
+#define wxStyledTextCtrl_AutoCompComplete 3059
+#define wxStyledTextCtrl_AutoCompStops 3060
+#define wxStyledTextCtrl_AutoCompSetSeparator 3061
+#define wxStyledTextCtrl_AutoCompGetSeparator 3062
+#define wxStyledTextCtrl_AutoCompSelect 3063
+#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3064
+#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3065
+#define wxStyledTextCtrl_AutoCompSetFillUps 3066
+#define wxStyledTextCtrl_AutoCompSetChooseSingle 3067
+#define wxStyledTextCtrl_AutoCompGetChooseSingle 3068
+#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3069
+#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3070
+#define wxStyledTextCtrl_UserListShow 3071
+#define wxStyledTextCtrl_AutoCompSetAutoHide 3072
+#define wxStyledTextCtrl_AutoCompGetAutoHide 3073
+#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3074
+#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3075
+#define wxStyledTextCtrl_RegisterImage 3076
+#define wxStyledTextCtrl_ClearRegisteredImages 3077
+#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3078
+#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3079
+#define wxStyledTextCtrl_AutoCompSetMaxWidth 3080
+#define wxStyledTextCtrl_AutoCompGetMaxWidth 3081
+#define wxStyledTextCtrl_AutoCompSetMaxHeight 3082
+#define wxStyledTextCtrl_AutoCompGetMaxHeight 3083
+#define wxStyledTextCtrl_SetIndent 3084
+#define wxStyledTextCtrl_GetIndent 3085
+#define wxStyledTextCtrl_SetUseTabs 3086
+#define wxStyledTextCtrl_GetUseTabs 3087
+#define wxStyledTextCtrl_SetLineIndentation 3088
+#define wxStyledTextCtrl_GetLineIndentation 3089
+#define wxStyledTextCtrl_GetLineIndentPosition 3090
+#define wxStyledTextCtrl_GetColumn 3091
+#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3092
+#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3093
+#define wxStyledTextCtrl_SetIndentationGuides 3094
+#define wxStyledTextCtrl_GetIndentationGuides 3095
+#define wxStyledTextCtrl_SetHighlightGuide 3096
+#define wxStyledTextCtrl_GetHighlightGuide 3097
+#define wxStyledTextCtrl_GetLineEndPosition 3098
+#define wxStyledTextCtrl_GetCodePage 3099
+#define wxStyledTextCtrl_GetCaretForeground 3100
+#define wxStyledTextCtrl_GetReadOnly 3101
+#define wxStyledTextCtrl_SetCurrentPos 3102
+#define wxStyledTextCtrl_SetSelectionStart 3103
+#define wxStyledTextCtrl_GetSelectionStart 3104
+#define wxStyledTextCtrl_SetSelectionEnd 3105
+#define wxStyledTextCtrl_GetSelectionEnd 3106
+#define wxStyledTextCtrl_SetPrintMagnification 3107
+#define wxStyledTextCtrl_GetPrintMagnification 3108
+#define wxStyledTextCtrl_SetPrintColourMode 3109
+#define wxStyledTextCtrl_GetPrintColourMode 3110
+#define wxStyledTextCtrl_FindText 3111
+#define wxStyledTextCtrl_FormatRange 3112
+#define wxStyledTextCtrl_GetFirstVisibleLine 3113
+#define wxStyledTextCtrl_GetLine 3114
+#define wxStyledTextCtrl_GetLineCount 3115
+#define wxStyledTextCtrl_SetMarginLeft 3116
+#define wxStyledTextCtrl_GetMarginLeft 3117
+#define wxStyledTextCtrl_SetMarginRight 3118
+#define wxStyledTextCtrl_GetMarginRight 3119
+#define wxStyledTextCtrl_GetModify 3120
+#define wxStyledTextCtrl_SetSelection 3121
+#define wxStyledTextCtrl_GetSelectedText 3122
+#define wxStyledTextCtrl_GetTextRange 3123
+#define wxStyledTextCtrl_HideSelection 3124
+#define wxStyledTextCtrl_LineFromPosition 3125
+#define wxStyledTextCtrl_PositionFromLine 3126
+#define wxStyledTextCtrl_LineScroll 3127
+#define wxStyledTextCtrl_EnsureCaretVisible 3128
+#define wxStyledTextCtrl_ReplaceSelection 3129
+#define wxStyledTextCtrl_SetReadOnly 3130
+#define wxStyledTextCtrl_CanPaste 3131
+#define wxStyledTextCtrl_CanUndo 3132
+#define wxStyledTextCtrl_EmptyUndoBuffer 3133
+#define wxStyledTextCtrl_Undo 3134
+#define wxStyledTextCtrl_Cut 3135
+#define wxStyledTextCtrl_Copy 3136
+#define wxStyledTextCtrl_Paste 3137
+#define wxStyledTextCtrl_Clear 3138
+#define wxStyledTextCtrl_SetText 3139
+#define wxStyledTextCtrl_GetText 3140
+#define wxStyledTextCtrl_GetTextLength 3141
+#define wxStyledTextCtrl_GetOvertype 3142
+#define wxStyledTextCtrl_SetCaretWidth 3143
+#define wxStyledTextCtrl_GetCaretWidth 3144
+#define wxStyledTextCtrl_SetTargetStart 3145
+#define wxStyledTextCtrl_GetTargetStart 3146
+#define wxStyledTextCtrl_SetTargetEnd 3147
+#define wxStyledTextCtrl_GetTargetEnd 3148
+#define wxStyledTextCtrl_ReplaceTarget 3149
+#define wxStyledTextCtrl_SearchInTarget 3150
+#define wxStyledTextCtrl_SetSearchFlags 3151
+#define wxStyledTextCtrl_GetSearchFlags 3152
+#define wxStyledTextCtrl_CallTipShow 3153
+#define wxStyledTextCtrl_CallTipCancel 3154
+#define wxStyledTextCtrl_CallTipActive 3155
+#define wxStyledTextCtrl_CallTipPosAtStart 3156
+#define wxStyledTextCtrl_CallTipSetHighlight 3157
+#define wxStyledTextCtrl_CallTipSetBackground 3158
+#define wxStyledTextCtrl_CallTipSetForeground 3159
+#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3160
+#define wxStyledTextCtrl_CallTipUseStyle 3161
+#define wxStyledTextCtrl_VisibleFromDocLine 3162
+#define wxStyledTextCtrl_DocLineFromVisible 3163
+#define wxStyledTextCtrl_WrapCount 3164
+#define wxStyledTextCtrl_SetFoldLevel 3165
+#define wxStyledTextCtrl_GetFoldLevel 3166
+#define wxStyledTextCtrl_GetLastChild 3167
+#define wxStyledTextCtrl_GetFoldParent 3168
+#define wxStyledTextCtrl_ShowLines 3169
+#define wxStyledTextCtrl_HideLines 3170
+#define wxStyledTextCtrl_GetLineVisible 3171
+#define wxStyledTextCtrl_SetFoldExpanded 3172
+#define wxStyledTextCtrl_GetFoldExpanded 3173
+#define wxStyledTextCtrl_ToggleFold 3174
+#define wxStyledTextCtrl_EnsureVisible 3175
+#define wxStyledTextCtrl_SetFoldFlags 3176
+#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3177
+#define wxStyledTextCtrl_SetTabIndents 3178
+#define wxStyledTextCtrl_GetTabIndents 3179
+#define wxStyledTextCtrl_SetBackSpaceUnIndents 3180
+#define wxStyledTextCtrl_GetBackSpaceUnIndents 3181
+#define wxStyledTextCtrl_SetMouseDwellTime 3182
+#define wxStyledTextCtrl_GetMouseDwellTime 3183
+#define wxStyledTextCtrl_WordStartPosition 3184
+#define wxStyledTextCtrl_WordEndPosition 3185
+#define wxStyledTextCtrl_SetWrapMode 3186
+#define wxStyledTextCtrl_GetWrapMode 3187
+#define wxStyledTextCtrl_SetWrapVisualFlags 3188
+#define wxStyledTextCtrl_GetWrapVisualFlags 3189
+#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3190
+#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3191
+#define wxStyledTextCtrl_SetWrapStartIndent 3192
+#define wxStyledTextCtrl_GetWrapStartIndent 3193
+#define wxStyledTextCtrl_SetLayoutCache 3194
+#define wxStyledTextCtrl_GetLayoutCache 3195
+#define wxStyledTextCtrl_SetScrollWidth 3196
+#define wxStyledTextCtrl_GetScrollWidth 3197
+#define wxStyledTextCtrl_TextWidth 3198
+#define wxStyledTextCtrl_GetEndAtLastLine 3199
+#define wxStyledTextCtrl_TextHeight 3200
+#define wxStyledTextCtrl_SetUseVerticalScrollBar 3201
+#define wxStyledTextCtrl_GetUseVerticalScrollBar 3202
+#define wxStyledTextCtrl_AppendText 3203
+#define wxStyledTextCtrl_GetTwoPhaseDraw 3204
+#define wxStyledTextCtrl_SetTwoPhaseDraw 3205
+#define wxStyledTextCtrl_TargetFromSelection 3206
+#define wxStyledTextCtrl_LinesJoin 3207
+#define wxStyledTextCtrl_LinesSplit 3208
+#define wxStyledTextCtrl_SetFoldMarginColour 3209
+#define wxStyledTextCtrl_SetFoldMarginHiColour 3210
+#define wxStyledTextCtrl_LineDown 3211
+#define wxStyledTextCtrl_LineDownExtend 3212
+#define wxStyledTextCtrl_LineUp 3213
+#define wxStyledTextCtrl_LineUpExtend 3214
+#define wxStyledTextCtrl_CharLeft 3215
+#define wxStyledTextCtrl_CharLeftExtend 3216
+#define wxStyledTextCtrl_CharRight 3217
+#define wxStyledTextCtrl_CharRightExtend 3218
+#define wxStyledTextCtrl_WordLeft 3219
+#define wxStyledTextCtrl_WordLeftExtend 3220
+#define wxStyledTextCtrl_WordRight 3221
+#define wxStyledTextCtrl_WordRightExtend 3222
+#define wxStyledTextCtrl_Home 3223
+#define wxStyledTextCtrl_HomeExtend 3224
+#define wxStyledTextCtrl_LineEnd 3225
+#define wxStyledTextCtrl_LineEndExtend 3226
+#define wxStyledTextCtrl_DocumentStart 3227
+#define wxStyledTextCtrl_DocumentStartExtend 3228
+#define wxStyledTextCtrl_DocumentEnd 3229
+#define wxStyledTextCtrl_DocumentEndExtend 3230
+#define wxStyledTextCtrl_PageUp 3231
+#define wxStyledTextCtrl_PageUpExtend 3232
+#define wxStyledTextCtrl_PageDown 3233
+#define wxStyledTextCtrl_PageDownExtend 3234
+#define wxStyledTextCtrl_EditToggleOvertype 3235
+#define wxStyledTextCtrl_Cancel 3236
+#define wxStyledTextCtrl_DeleteBack 3237
+#define wxStyledTextCtrl_Tab 3238
+#define wxStyledTextCtrl_BackTab 3239
+#define wxStyledTextCtrl_NewLine 3240
+#define wxStyledTextCtrl_FormFeed 3241
+#define wxStyledTextCtrl_VCHome 3242
+#define wxStyledTextCtrl_VCHomeExtend 3243
+#define wxStyledTextCtrl_ZoomIn 3244
+#define wxStyledTextCtrl_ZoomOut 3245
+#define wxStyledTextCtrl_DelWordLeft 3246
+#define wxStyledTextCtrl_DelWordRight 3247
+#define wxStyledTextCtrl_LineCut 3248
+#define wxStyledTextCtrl_LineDelete 3249
+#define wxStyledTextCtrl_LineTranspose 3250
+#define wxStyledTextCtrl_LineDuplicate 3251
+#define wxStyledTextCtrl_LowerCase 3252
+#define wxStyledTextCtrl_UpperCase 3253
+#define wxStyledTextCtrl_LineScrollDown 3254
+#define wxStyledTextCtrl_LineScrollUp 3255
+#define wxStyledTextCtrl_DeleteBackNotLine 3256
+#define wxStyledTextCtrl_HomeDisplay 3257
+#define wxStyledTextCtrl_HomeDisplayExtend 3258
+#define wxStyledTextCtrl_LineEndDisplay 3259
+#define wxStyledTextCtrl_LineEndDisplayExtend 3260
+#define wxStyledTextCtrl_HomeWrapExtend 3261
+#define wxStyledTextCtrl_LineEndWrap 3262
+#define wxStyledTextCtrl_LineEndWrapExtend 3263
+#define wxStyledTextCtrl_VCHomeWrap 3264
+#define wxStyledTextCtrl_VCHomeWrapExtend 3265
+#define wxStyledTextCtrl_LineCopy 3266
+#define wxStyledTextCtrl_MoveCaretInsideView 3267
+#define wxStyledTextCtrl_LineLength 3268
+#define wxStyledTextCtrl_BraceHighlight 3269
+#define wxStyledTextCtrl_BraceBadLight 3270
+#define wxStyledTextCtrl_BraceMatch 3271
+#define wxStyledTextCtrl_GetViewEOL 3272
+#define wxStyledTextCtrl_SetViewEOL 3273
+#define wxStyledTextCtrl_SetModEventMask 3274
+#define wxStyledTextCtrl_GetEdgeColumn 3275
+#define wxStyledTextCtrl_SetEdgeColumn 3276
+#define wxStyledTextCtrl_SetEdgeMode 3277
+#define wxStyledTextCtrl_GetEdgeMode 3278
+#define wxStyledTextCtrl_GetEdgeColour 3279
+#define wxStyledTextCtrl_SetEdgeColour 3280
+#define wxStyledTextCtrl_SearchAnchor 3281
+#define wxStyledTextCtrl_SearchNext 3282
+#define wxStyledTextCtrl_SearchPrev 3283
+#define wxStyledTextCtrl_LinesOnScreen 3284
+#define wxStyledTextCtrl_UsePopUp 3285
+#define wxStyledTextCtrl_SelectionIsRectangle 3286
+#define wxStyledTextCtrl_SetZoom 3287
+#define wxStyledTextCtrl_GetZoom 3288
+#define wxStyledTextCtrl_GetModEventMask 3289
+#define wxStyledTextCtrl_SetSTCFocus 3290
+#define wxStyledTextCtrl_GetSTCFocus 3291
+#define wxStyledTextCtrl_SetStatus 3292
+#define wxStyledTextCtrl_GetStatus 3293
+#define wxStyledTextCtrl_SetMouseDownCaptures 3294
+#define wxStyledTextCtrl_GetMouseDownCaptures 3295
+#define wxStyledTextCtrl_SetSTCCursor 3296
+#define wxStyledTextCtrl_GetSTCCursor 3297
+#define wxStyledTextCtrl_SetControlCharSymbol 3298
+#define wxStyledTextCtrl_GetControlCharSymbol 3299
+#define wxStyledTextCtrl_WordPartLeft 3300
+#define wxStyledTextCtrl_WordPartLeftExtend 3301
+#define wxStyledTextCtrl_WordPartRight 3302
+#define wxStyledTextCtrl_WordPartRightExtend 3303
+#define wxStyledTextCtrl_SetVisiblePolicy 3304
+#define wxStyledTextCtrl_DelLineLeft 3305
+#define wxStyledTextCtrl_DelLineRight 3306
+#define wxStyledTextCtrl_GetXOffset 3307
+#define wxStyledTextCtrl_ChooseCaretX 3308
+#define wxStyledTextCtrl_SetXCaretPolicy 3309
+#define wxStyledTextCtrl_SetYCaretPolicy 3310
+#define wxStyledTextCtrl_GetPrintWrapMode 3311
+#define wxStyledTextCtrl_SetHotspotActiveForeground 3312
+#define wxStyledTextCtrl_SetHotspotActiveBackground 3313
+#define wxStyledTextCtrl_SetHotspotActiveUnderline 3314
+#define wxStyledTextCtrl_SetHotspotSingleLine 3315
+#define wxStyledTextCtrl_ParaDownExtend 3316
+#define wxStyledTextCtrl_ParaUp 3317
+#define wxStyledTextCtrl_ParaUpExtend 3318
+#define wxStyledTextCtrl_PositionBefore 3319
+#define wxStyledTextCtrl_PositionAfter 3320
+#define wxStyledTextCtrl_CopyRange 3321
+#define wxStyledTextCtrl_CopyText 3322
+#define wxStyledTextCtrl_SetSelectionMode 3323
+#define wxStyledTextCtrl_GetSelectionMode 3324
+#define wxStyledTextCtrl_LineDownRectExtend 3325
+#define wxStyledTextCtrl_LineUpRectExtend 3326
+#define wxStyledTextCtrl_CharLeftRectExtend 3327
+#define wxStyledTextCtrl_CharRightRectExtend 3328
+#define wxStyledTextCtrl_HomeRectExtend 3329
+#define wxStyledTextCtrl_VCHomeRectExtend 3330
+#define wxStyledTextCtrl_LineEndRectExtend 3331
+#define wxStyledTextCtrl_PageUpRectExtend 3332
+#define wxStyledTextCtrl_PageDownRectExtend 3333
+#define wxStyledTextCtrl_StutteredPageUp 3334
+#define wxStyledTextCtrl_StutteredPageUpExtend 3335
+#define wxStyledTextCtrl_StutteredPageDown 3336
+#define wxStyledTextCtrl_StutteredPageDownExtend 3337
+#define wxStyledTextCtrl_WordLeftEnd 3338
+#define wxStyledTextCtrl_WordLeftEndExtend 3339
+#define wxStyledTextCtrl_WordRightEnd 3340
+#define wxStyledTextCtrl_WordRightEndExtend 3341
+#define wxStyledTextCtrl_SetWhitespaceChars 3342
+#define wxStyledTextCtrl_SetCharsDefault 3343
+#define wxStyledTextCtrl_AutoCompGetCurrent 3344
+#define wxStyledTextCtrl_Allocate 3345
+#define wxStyledTextCtrl_FindColumn 3346
+#define wxStyledTextCtrl_GetCaretSticky 3347
+#define wxStyledTextCtrl_SetCaretSticky 3348
+#define wxStyledTextCtrl_ToggleCaretSticky 3349
+#define wxStyledTextCtrl_SetPasteConvertEndings 3350
+#define wxStyledTextCtrl_GetPasteConvertEndings 3351
+#define wxStyledTextCtrl_SelectionDuplicate 3352
+#define wxStyledTextCtrl_SetCaretLineBackAlpha 3353
+#define wxStyledTextCtrl_GetCaretLineBackAlpha 3354
+#define wxStyledTextCtrl_StartRecord 3355
+#define wxStyledTextCtrl_StopRecord 3356
+#define wxStyledTextCtrl_SetLexer 3357
+#define wxStyledTextCtrl_GetLexer 3358
+#define wxStyledTextCtrl_Colourise 3359
+#define wxStyledTextCtrl_SetProperty 3360
+#define wxStyledTextCtrl_SetKeyWords 3361
+#define wxStyledTextCtrl_SetLexerLanguage 3362
+#define wxStyledTextCtrl_GetProperty 3363
+#define wxStyledTextCtrl_GetStyleBitsNeeded 3364
+#define wxStyledTextCtrl_GetCurrentLine 3365
+#define wxStyledTextCtrl_StyleSetSpec 3366
+#define wxStyledTextCtrl_StyleSetFont 3367
+#define wxStyledTextCtrl_StyleSetFontAttr 3368
+#define wxStyledTextCtrl_StyleSetCharacterSet 3369
+#define wxStyledTextCtrl_StyleSetFontEncoding 3370
+#define wxStyledTextCtrl_CmdKeyExecute 3371
+#define wxStyledTextCtrl_SetMargins 3372
+#define wxStyledTextCtrl_GetSelection 3373
+#define wxStyledTextCtrl_PointFromPosition 3374
+#define wxStyledTextCtrl_ScrollToLine 3375
+#define wxStyledTextCtrl_ScrollToColumn 3376
+#define wxStyledTextCtrl_SetVScrollBar 3377
+#define wxStyledTextCtrl_SetHScrollBar 3378
+#define wxStyledTextCtrl_GetLastKeydownProcessed 3379
+#define wxStyledTextCtrl_SetLastKeydownProcessed 3380
+#define wxStyledTextCtrl_SaveFile 3381
+#define wxStyledTextCtrl_LoadFile 3382
+#define wxStyledTextCtrl_DoDragOver 3383
+#define wxStyledTextCtrl_DoDropText 3384
+#define wxStyledTextCtrl_GetUseAntiAliasing 3385
+#define wxStyledTextCtrl_AddTextRaw 3386
+#define wxStyledTextCtrl_InsertTextRaw 3387
+#define wxStyledTextCtrl_GetCurLineRaw 3388
+#define wxStyledTextCtrl_GetLineRaw 3389
+#define wxStyledTextCtrl_GetSelectedTextRaw 3390
+#define wxStyledTextCtrl_GetTextRangeRaw 3391
+#define wxStyledTextCtrl_SetTextRaw 3392
+#define wxStyledTextCtrl_GetTextRaw 3393
+#define wxStyledTextCtrl_AppendTextRaw 3394
+#define wxArtProvider_GetBitmap 3395
+#define wxArtProvider_GetIcon 3396
+#define wxTreeEvent_GetKeyCode 3397
+#define wxTreeEvent_GetItem 3398
+#define wxTreeEvent_GetKeyEvent 3399
+#define wxTreeEvent_GetLabel 3400
+#define wxTreeEvent_GetOldItem 3401
+#define wxTreeEvent_GetPoint 3402
+#define wxTreeEvent_IsEditCancelled 3403
+#define wxTreeEvent_SetToolTip 3404
+#define wxNotebookEvent_GetOldSelection 3405
+#define wxNotebookEvent_GetSelection 3406
+#define wxNotebookEvent_SetOldSelection 3407
+#define wxNotebookEvent_SetSelection 3408
+#define wxFileDataObject_new 3409
+#define wxFileDataObject_AddFile 3410
+#define wxFileDataObject_GetFilenames 3411
+#define wxFileDataObject_destroy 3412
+#define wxTextDataObject_new 3413
+#define wxTextDataObject_GetTextLength 3414
+#define wxTextDataObject_GetText 3415
+#define wxTextDataObject_SetText 3416
+#define wxTextDataObject_destroy 3417
+#define wxBitmapDataObject_new_1_1 3418
+#define wxBitmapDataObject_new_1_0 3419
+#define wxBitmapDataObject_GetBitmap 3420
+#define wxBitmapDataObject_SetBitmap 3421
+#define wxBitmapDataObject_destroy 3422
+#define wxClipboard_new 3424
+#define wxClipboard_destruct 3425
+#define wxClipboard_AddData 3426
+#define wxClipboard_Clear 3427
+#define wxClipboard_Close 3428
+#define wxClipboard_Flush 3429
+#define wxClipboard_GetData 3430
+#define wxClipboard_IsOpened 3431
+#define wxClipboard_Open 3432
+#define wxClipboard_SetData 3433
+#define wxClipboard_UsePrimarySelection 3435
+#define wxClipboard_IsSupported 3436
+#define wxClipboard_Get 3437
+#define wxSpinEvent_GetPosition 3438
+#define wxSpinEvent_SetPosition 3439
+#define wxSplitterWindow_new_0 3440
+#define wxSplitterWindow_new_2 3441
+#define wxSplitterWindow_destruct 3442
+#define wxSplitterWindow_Create 3443
+#define wxSplitterWindow_GetMinimumPaneSize 3444
+#define wxSplitterWindow_GetSashGravity 3445
+#define wxSplitterWindow_GetSashPosition 3446
+#define wxSplitterWindow_GetSplitMode 3447
+#define wxSplitterWindow_GetWindow1 3448
+#define wxSplitterWindow_GetWindow2 3449
+#define wxSplitterWindow_Initialize 3450
+#define wxSplitterWindow_IsSplit 3451
+#define wxSplitterWindow_ReplaceWindow 3452
+#define wxSplitterWindow_SetSashGravity 3453
+#define wxSplitterWindow_SetSashPosition 3454
+#define wxSplitterWindow_SetSashSize 3455
+#define wxSplitterWindow_SetMinimumPaneSize 3456
+#define wxSplitterWindow_SetSplitMode 3457
+#define wxSplitterWindow_SplitHorizontally 3458
+#define wxSplitterWindow_SplitVertically 3459
+#define wxSplitterWindow_Unsplit 3460
+#define wxSplitterWindow_UpdateSize 3461
+#define wxSplitterEvent_GetSashPosition 3462
+#define wxSplitterEvent_GetX 3463
+#define wxSplitterEvent_GetY 3464
+#define wxSplitterEvent_GetWindowBeingRemoved 3465
+#define wxSplitterEvent_SetSashPosition 3466
+#define wxHtmlWindow_new_0 3467
+#define wxHtmlWindow_new_2 3468
+#define wxHtmlWindow_AppendToPage 3469
+#define wxHtmlWindow_GetOpenedAnchor 3470
+#define wxHtmlWindow_GetOpenedPage 3471
+#define wxHtmlWindow_GetOpenedPageTitle 3472
+#define wxHtmlWindow_GetRelatedFrame 3473
+#define wxHtmlWindow_HistoryBack 3474
+#define wxHtmlWindow_HistoryCanBack 3475
+#define wxHtmlWindow_HistoryCanForward 3476
+#define wxHtmlWindow_HistoryClear 3477
+#define wxHtmlWindow_HistoryForward 3478
+#define wxHtmlWindow_LoadFile 3479
+#define wxHtmlWindow_LoadPage 3480
+#define wxHtmlWindow_SelectAll 3481
+#define wxHtmlWindow_SelectionToText 3482
+#define wxHtmlWindow_SelectLine 3483
+#define wxHtmlWindow_SelectWord 3484
+#define wxHtmlWindow_SetBorders 3485
+#define wxHtmlWindow_SetFonts 3486
+#define wxHtmlWindow_SetPage 3487
+#define wxHtmlWindow_SetRelatedFrame 3488
+#define wxHtmlWindow_SetRelatedStatusBar 3489
+#define wxHtmlWindow_ToText 3490
+#define wxHtmlWindow_destroy 3491
+#define wxHtmlLinkEvent_GetLinkInfo 3492
+#define wxSystemSettings_GetColour 3493
+#define wxSystemSettings_GetFont 3494
+#define wxSystemSettings_GetMetric 3495
+#define wxSystemSettings_GetScreenType 3496
+#define wxSystemOptions_GetOption 3497
+#define wxSystemOptions_GetOptionInt 3498
+#define wxSystemOptions_HasOption 3499
+#define wxSystemOptions_IsFalse 3500
+#define wxSystemOptions_SetOption_2_1 3501
+#define wxSystemOptions_SetOption_2_0 3502
+#define wxAuiNotebookEvent_SetSelection 3503
+#define wxAuiNotebookEvent_GetSelection 3504
+#define wxAuiNotebookEvent_SetOldSelection 3505
+#define wxAuiNotebookEvent_GetOldSelection 3506
+#define wxAuiNotebookEvent_SetDragSource 3507
+#define wxAuiNotebookEvent_GetDragSource 3508
+#define wxAuiManagerEvent_SetManager 3509
+#define wxAuiManagerEvent_GetManager 3510
+#define wxAuiManagerEvent_SetPane 3511
+#define wxAuiManagerEvent_GetPane 3512
+#define wxAuiManagerEvent_SetButton 3513
+#define wxAuiManagerEvent_GetButton 3514
+#define wxAuiManagerEvent_SetDC 3515
+#define wxAuiManagerEvent_GetDC 3516
+#define wxAuiManagerEvent_Veto 3517
+#define wxAuiManagerEvent_GetVeto 3518
+#define wxAuiManagerEvent_SetCanVeto 3519
+#define wxAuiManagerEvent_CanVeto 3520
+#define wxLogNull_new 3521
+#define wxLogNull_destroy 3522
+#define wxTaskBarIcon_new 3523
+#define wxTaskBarIcon_destruct 3524
+#define wxTaskBarIcon_PopupMenu 3525
+#define wxTaskBarIcon_RemoveIcon 3526
+#define wxTaskBarIcon_SetIcon 3527
+#define wxLocale_new_0 3528
+#define wxLocale_new_2 3530
+#define wxLocale_destruct 3531
+#define wxLocale_Init 3533
+#define wxLocale_AddCatalog_1 3534
+#define wxLocale_AddCatalog_3 3535
+#define wxLocale_AddCatalogLookupPathPrefix 3536
+#define wxLocale_GetCanonicalName 3537
+#define wxLocale_GetLanguage 3538
+#define wxLocale_GetLanguageName 3539
+#define wxLocale_GetLocale 3540
+#define wxLocale_GetName 3541
+#define wxLocale_GetString_2 3542
+#define wxLocale_GetString_4 3543
+#define wxLocale_GetHeaderValue 3544
+#define wxLocale_GetSysName 3545
+#define wxLocale_GetSystemEncoding 3546
+#define wxLocale_GetSystemEncodingName 3547
+#define wxLocale_GetSystemLanguage 3548
+#define wxLocale_IsLoaded 3549
+#define wxLocale_IsOk 3550
+#define wxActivateEvent_GetActive 3551
+#define wxPopupWindow_new_2 3553
+#define wxPopupWindow_new_0 3554
+#define wxPopupWindow_destruct 3556
+#define wxPopupWindow_Create 3557
+#define wxPopupWindow_Position 3558
+#define wxPopupTransientWindow_new_0 3559
+#define wxPopupTransientWindow_new_2 3560
+#define wxPopupTransientWindow_destruct 3561
+#define wxPopupTransientWindow_Popup 3562
+#define wxPopupTransientWindow_Dismiss 3563
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index f617aaf349..0ee52e3af2 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -500,7 +500,7 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd)
if(it != ptr2ref.end()) {
wxeRefData *refd = it->second;
if(refd->alloc_in_erl) {
- if((refd->type == 1) && ((wxObject *)ptr)->IsKindOf(CLASSINFO(wxBufferedDC))) {
+ if((refd->type == 4) && ((wxObject *)ptr)->IsKindOf(CLASSINFO(wxBufferedDC))) {
((wxBufferedDC *)ptr)->m_dc = NULL; // Workaround
}
wxString msg;
@@ -539,6 +539,17 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd)
refmap.erase((ErlDrvTermData) Ecmd.port);
}
+
+wxeRefData * WxeApp::getRefData(void *ptr) {
+ ptrMap::iterator it = ptr2ref.find(ptr);
+ if(it != ptr2ref.end()) {
+ wxeRefData *refd = it->second;
+ return refd;
+ }
+ return NULL;
+}
+
+
wxeMemEnv * WxeApp::getMemEnv(ErlDrvTermData port) {
return refmap[port];
}
diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h
index 5b23e1cbbd..57bf2e2dba 100644
--- a/lib/wx/c_src/wxe_impl.h
+++ b/lib/wx/c_src/wxe_impl.h
@@ -80,6 +80,7 @@ public:
int getRef(void * ptr, wxeMemEnv *memenv);
void * getPtr(char * bp, wxeMemEnv *memenv);
void clearPtr(void *ptr);
+ wxeRefData * getRefData(void *ptr);
void registerPid(char *ptr, ErlDrvTermData pid, wxeMemEnv *memenv);
void init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller);
diff --git a/lib/wx/c_src/wxe_memory.h b/lib/wx/c_src/wxe_memory.h
index ec22183bfa..8a48c77154 100644
--- a/lib/wx/c_src/wxe_memory.h
+++ b/lib/wx/c_src/wxe_memory.h
@@ -47,7 +47,8 @@ class wxeRefData {
int type;
// 0 = wxWindow subclasses, 1 = wxObject subclasses
// 2 = wxDialog subclasses, 3 = allocated wxObjects but not returned from new
- // > 3 classes which lack virtual destr, or are supposed to be allocated on
+ // 4 = wxObjects that should always be deleted directly (wxDC derivates)
+ // > 4 classes which lack virtual destr, or are supposed to be allocated on
// the stack
bool alloc_in_erl;
wxeMemEnv *memenv;
diff --git a/lib/wx/configure.in b/lib/wx/configure.in
index a96f1f2632..4c4d4f41a8 100755..100644
--- a/lib/wx/configure.in
+++ b/lib/wx/configure.in
@@ -677,6 +677,27 @@ if test "x$GCC" = xyes; then
LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CXXFLAGS])
fi
+dnl ----------------------------------------------------------------------
+dnl Enable -fsanitize= flags.
+dnl ----------------------------------------------------------------------
+
+m4_define(DEFAULT_SANITIZERS, [address,undefined])
+AC_ARG_ENABLE(
+ sanitizers,
+ AS_HELP_STRING(
+ [--enable-sanitizers@<:@=comma-separated list of sanitizers@:>@],
+ [Default=DEFAULT_SANITIZERS]),
+[
+case "$enableval" in
+ no) sanitizers= ;;
+ yes) sanitizers="-fsanitize=DEFAULT_SANITIZERS" ;;
+ *) sanitizers="-fsanitize=$enableval" ;;
+esac
+CFLAGS="$CFLAGS $sanitizers"
+CXXFLAGS="$CXXFLAGS $sanitizers"
+LDFLAGS="$LDFLAGS $sanitizers"
+])
+
#############################################################################
dnl
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index daa61fda1e..63eb047caa 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -31,6 +31,36 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 1.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fix delayed destroy for wxPaintDC objects which could
+ cause an eternal loop for modal dialogs.</p> <p>Fix
+ wxSL_LABELS compatibility between wxWidgets-2.8 and
+ wxWidgets-3.0 versions</p>
+ <p>
+ Own Id: OTP-11985</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add missing classes wxPopup[Transient]Window,
+ wxActivateEvent and wxTextCtrl:cahngeValue/2 function.</p>
+ <p>
+ Own Id: OTP-11986</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 1.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl
index ac852ce054..348daf64ce 100644
--- a/lib/wx/include/wx.hrl
+++ b/lib/wx/include/wx.hrl
@@ -165,6 +165,11 @@
-type wxHelpEventType() :: help | detailed_help.
-type wxHelp() :: #wxHelp{}. %% Callback event: {@link wxHelpEvent}
+-record(wxActivate,{type :: wxActivateEventType(), %% Callback event: {@link wxActivateEvent}
+ active :: boolean()}).
+-type wxActivateEventType() :: activate | activate_app | hibernate.
+-type wxActivate() :: #wxActivate{}. %% Callback event: {@link wxActivateEvent}
+
-record(wxStyledText,{type :: wxStyledTextEventType(), %% Callback event: {@link wxStyledTextEvent}
position :: integer(),
key :: integer(),
@@ -316,8 +321,8 @@
-type wxTreeEventType() :: command_tree_begin_drag | command_tree_begin_rdrag | command_tree_begin_label_edit | command_tree_end_label_edit | command_tree_delete_item | command_tree_get_info | command_tree_set_info | command_tree_item_expanded | command_tree_item_expanding | command_tree_item_collapsed | command_tree_item_collapsing | command_tree_sel_changed | command_tree_sel_changing | command_tree_key_down | command_tree_item_activated | command_tree_item_right_click | command_tree_item_middle_click | command_tree_end_drag | command_tree_state_image_click | command_tree_item_gettooltip | command_tree_item_menu.
-type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent}
--type event() :: wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
--type wxEventType() :: wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
+-type event() :: wxActivate() | wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
+-type wxEventType() :: wxActivateEventType() | wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
%% Hardcoded Records
-record(wxMouseState, {x :: integer(), y :: integer(),
@@ -2515,7 +2520,7 @@
-define(wxSL_RIGHT, 256).
-define(wxSL_TOP, 128).
-define(wxSL_LEFT, 64).
--define(wxSL_LABELS, 32).
+-define(wxSL_LABELS, wxe_util:get_const(wxSL_LABELS)).
-define(wxSL_AUTOTICKS, ?wxSL_TICKS).
-define(wxSL_TICKS, 16).
-define(wxSL_VERTICAL, ?wxVERTICAL).
diff --git a/lib/wx/src/gen/wxActivateEvent.erl b/lib/wx/src/gen/wxActivateEvent.erl
new file mode 100644
index 0000000000..dc03866027
--- /dev/null
+++ b/lib/wx/src/gen/wxActivateEvent.erl
@@ -0,0 +1,72 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxactivateevent.html">wxActivateEvent</a>.
+%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt>
+%% <dd><em>activate</em>, <em>activate_app</em>, <em>hibernate</em></dd></dl>
+%% See also the message variant {@link wxEvtHandler:wxActivate(). #wxActivate{}} event record type.
+%%
+%% <p>This class is derived (and can use functions) from:
+%% <br />{@link wxEvent}
+%% </p>
+%% @type wxActivateEvent(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxActivateEvent).
+-include("wxe.hrl").
+-export([getActive/1]).
+
+%% inherited exports
+-export([getId/1,getSkipped/1,getTimestamp/1,isCommandEvent/1,parent_class/1,
+ resumePropagation/2,shouldPropagate/1,skip/1,skip/2,stopPropagation/1]).
+
+-export_type([wxActivateEvent/0]).
+%% @hidden
+parent_class(wxEvent) -> true;
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxActivateEvent() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxactivateevent.html#wxactivateeventgetactive">external documentation</a>.
+-spec getActive(This) -> boolean() when
+ This::wxActivateEvent().
+getActive(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxActivateEvent),
+ wxe_util:call(?wxActivateEvent_GetActive,
+ <<ThisRef:32/?UI>>).
+
+ %% From wxEvent
+%% @hidden
+stopPropagation(This) -> wxEvent:stopPropagation(This).
+%% @hidden
+skip(This, Options) -> wxEvent:skip(This, Options).
+%% @hidden
+skip(This) -> wxEvent:skip(This).
+%% @hidden
+shouldPropagate(This) -> wxEvent:shouldPropagate(This).
+%% @hidden
+resumePropagation(This,PropagationLevel) -> wxEvent:resumePropagation(This,PropagationLevel).
+%% @hidden
+isCommandEvent(This) -> wxEvent:isCommandEvent(This).
+%% @hidden
+getTimestamp(This) -> wxEvent:getTimestamp(This).
+%% @hidden
+getSkipped(This) -> wxEvent:getSkipped(This).
+%% @hidden
+getId(This) -> wxEvent:getId(This).
diff --git a/lib/wx/src/gen/wxPopupTransientWindow.erl b/lib/wx/src/gen/wxPopupTransientWindow.erl
new file mode 100644
index 0000000000..253d33e5ac
--- /dev/null
+++ b/lib/wx/src/gen/wxPopupTransientWindow.erl
@@ -0,0 +1,506 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopuptransientwindow.html">wxPopupTransientWindow</a>.
+%% <p>This class is derived (and can use functions) from:
+%% <br />{@link wxPopupWindow}
+%% <br />{@link wxWindow}
+%% <br />{@link wxEvtHandler}
+%% </p>
+%% @type wxPopupTransientWindow(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxPopupTransientWindow).
+-include("wxe.hrl").
+-export([destroy/1,dismiss/1,new/0,new/1,new/2,popup/1,popup/2]).
+
+%% inherited exports
+-export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
+ centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
+ clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
+ connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+ destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
+ enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,position/3,raise/1,refresh/1,refresh/2,
+ refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+
+-export_type([wxPopupTransientWindow/0]).
+%% @hidden
+parent_class(wxPopupWindow) -> true;
+parent_class(wxWindow) -> true;
+parent_class(wxEvtHandler) -> true;
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxPopupTransientWindow() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopuptransientwindow.html#wxpopuptransientwindowwxpopuptransientwindow">external documentation</a>.
+-spec new() -> wxPopupTransientWindow().
+new() ->
+ wxe_util:construct(?wxPopupTransientWindow_new_0,
+ <<>>).
+
+%% @equiv new(Parent, [])
+-spec new(Parent) -> wxPopupTransientWindow() when
+ Parent::wxWindow:wxWindow().
+
+new(Parent)
+ when is_record(Parent, wx_ref) ->
+ new(Parent, []).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopuptransientwindow.html#wxpopuptransientwindowwxpopuptransientwindow">external documentation</a>.
+-spec new(Parent, [Option]) -> wxPopupTransientWindow() when
+ Parent::wxWindow:wxWindow(),
+ Option :: {style, integer()}.
+new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
+ when is_list(Options) ->
+ ?CLASS(ParentT,wxWindow),
+ MOpts = fun({style, Style}, Acc) -> [<<1:32/?UI,Style:32/?UI>>|Acc];
+ (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
+ BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
+ wxe_util:construct(?wxPopupTransientWindow_new_2,
+ <<ParentRef:32/?UI, 0:32,BinOpt/binary>>).
+
+%% @equiv popup(This, [])
+-spec popup(This) -> ok when
+ This::wxPopupTransientWindow().
+
+popup(This)
+ when is_record(This, wx_ref) ->
+ popup(This, []).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopuptransientwindow.html#wxpopuptransientwindowpopup">external documentation</a>.
+-spec popup(This, [Option]) -> ok when
+ This::wxPopupTransientWindow(),
+ Option :: {focus, wxWindow:wxWindow()}.
+popup(#wx_ref{type=ThisT,ref=ThisRef}, Options)
+ when is_list(Options) ->
+ ?CLASS(ThisT,wxPopupTransientWindow),
+ MOpts = fun({focus, #wx_ref{type=FocusT,ref=FocusRef}}, Acc) -> ?CLASS(FocusT,wxWindow),[<<1:32/?UI,FocusRef:32/?UI>>|Acc];
+ (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
+ BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
+ wxe_util:cast(?wxPopupTransientWindow_Popup,
+ <<ThisRef:32/?UI, 0:32,BinOpt/binary>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopuptransientwindow.html#wxpopuptransientwindowdismiss">external documentation</a>.
+-spec dismiss(This) -> ok when
+ This::wxPopupTransientWindow().
+dismiss(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxPopupTransientWindow),
+ wxe_util:cast(?wxPopupTransientWindow_Dismiss,
+ <<ThisRef:32/?UI>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxPopupTransientWindow()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxPopupTransientWindow),
+ wxe_util:destroy(?DESTROY_OBJECT,Obj),
+ ok.
+ %% From wxPopupWindow
+%% @hidden
+position(This,PtOrigin,Size) -> wxPopupWindow:position(This,PtOrigin,Size).
+ %% From wxWindow
+%% @hidden
+warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
+%% @hidden
+validate(This) -> wxWindow:validate(This).
+%% @hidden
+updateWindowUI(This, Options) -> wxWindow:updateWindowUI(This, Options).
+%% @hidden
+updateWindowUI(This) -> wxWindow:updateWindowUI(This).
+%% @hidden
+update(This) -> wxWindow:update(This).
+%% @hidden
+transferDataToWindow(This) -> wxWindow:transferDataToWindow(This).
+%% @hidden
+transferDataFromWindow(This) -> wxWindow:transferDataFromWindow(This).
+%% @hidden
+thaw(This) -> wxWindow:thaw(This).
+%% @hidden
+show(This, Options) -> wxWindow:show(This, Options).
+%% @hidden
+show(This) -> wxWindow:show(This).
+%% @hidden
+shouldInheritColours(This) -> wxWindow:shouldInheritColours(This).
+%% @hidden
+setWindowVariant(This,Variant) -> wxWindow:setWindowVariant(This,Variant).
+%% @hidden
+setWindowStyleFlag(This,Style) -> wxWindow:setWindowStyleFlag(This,Style).
+%% @hidden
+setWindowStyle(This,Style) -> wxWindow:setWindowStyle(This,Style).
+%% @hidden
+setVirtualSizeHints(This,MinW,MinH, Options) -> wxWindow:setVirtualSizeHints(This,MinW,MinH, Options).
+%% @hidden
+setVirtualSizeHints(This,MinW,MinH) -> wxWindow:setVirtualSizeHints(This,MinW,MinH).
+%% @hidden
+setVirtualSizeHints(This,MinSize) -> wxWindow:setVirtualSizeHints(This,MinSize).
+%% @hidden
+setVirtualSize(This,X,Y) -> wxWindow:setVirtualSize(This,X,Y).
+%% @hidden
+setVirtualSize(This,Size) -> wxWindow:setVirtualSize(This,Size).
+%% @hidden
+setToolTip(This,Tip) -> wxWindow:setToolTip(This,Tip).
+%% @hidden
+setThemeEnabled(This,EnableTheme) -> wxWindow:setThemeEnabled(This,EnableTheme).
+%% @hidden
+setSizerAndFit(This,Sizer, Options) -> wxWindow:setSizerAndFit(This,Sizer, Options).
+%% @hidden
+setSizerAndFit(This,Sizer) -> wxWindow:setSizerAndFit(This,Sizer).
+%% @hidden
+setSizer(This,Sizer, Options) -> wxWindow:setSizer(This,Sizer, Options).
+%% @hidden
+setSizer(This,Sizer) -> wxWindow:setSizer(This,Sizer).
+%% @hidden
+setSizeHints(This,MinW,MinH, Options) -> wxWindow:setSizeHints(This,MinW,MinH, Options).
+%% @hidden
+setSizeHints(This,MinW,MinH) -> wxWindow:setSizeHints(This,MinW,MinH).
+%% @hidden
+setSizeHints(This,MinSize) -> wxWindow:setSizeHints(This,MinSize).
+%% @hidden
+setSize(This,X,Y,Width,Height, Options) -> wxWindow:setSize(This,X,Y,Width,Height, Options).
+%% @hidden
+setSize(This,X,Y,Width,Height) -> wxWindow:setSize(This,X,Y,Width,Height).
+%% @hidden
+setSize(This,Width,Height) -> wxWindow:setSize(This,Width,Height).
+%% @hidden
+setSize(This,Rect) -> wxWindow:setSize(This,Rect).
+%% @hidden
+setScrollPos(This,Orient,Pos, Options) -> wxWindow:setScrollPos(This,Orient,Pos, Options).
+%% @hidden
+setScrollPos(This,Orient,Pos) -> wxWindow:setScrollPos(This,Orient,Pos).
+%% @hidden
+setScrollbar(This,Orient,Pos,ThumbVisible,Range, Options) -> wxWindow:setScrollbar(This,Orient,Pos,ThumbVisible,Range, Options).
+%% @hidden
+setScrollbar(This,Orient,Pos,ThumbVisible,Range) -> wxWindow:setScrollbar(This,Orient,Pos,ThumbVisible,Range).
+%% @hidden
+setPalette(This,Pal) -> wxWindow:setPalette(This,Pal).
+%% @hidden
+setName(This,Name) -> wxWindow:setName(This,Name).
+%% @hidden
+setLabel(This,Label) -> wxWindow:setLabel(This,Label).
+%% @hidden
+setId(This,Winid) -> wxWindow:setId(This,Winid).
+%% @hidden
+setHelpText(This,Text) -> wxWindow:setHelpText(This,Text).
+%% @hidden
+setForegroundColour(This,Colour) -> wxWindow:setForegroundColour(This,Colour).
+%% @hidden
+setFont(This,Font) -> wxWindow:setFont(This,Font).
+%% @hidden
+setFocusFromKbd(This) -> wxWindow:setFocusFromKbd(This).
+%% @hidden
+setFocus(This) -> wxWindow:setFocus(This).
+%% @hidden
+setExtraStyle(This,ExStyle) -> wxWindow:setExtraStyle(This,ExStyle).
+%% @hidden
+setDropTarget(This,DropTarget) -> wxWindow:setDropTarget(This,DropTarget).
+%% @hidden
+setOwnForegroundColour(This,Colour) -> wxWindow:setOwnForegroundColour(This,Colour).
+%% @hidden
+setOwnFont(This,Font) -> wxWindow:setOwnFont(This,Font).
+%% @hidden
+setOwnBackgroundColour(This,Colour) -> wxWindow:setOwnBackgroundColour(This,Colour).
+%% @hidden
+setMinSize(This,MinSize) -> wxWindow:setMinSize(This,MinSize).
+%% @hidden
+setMaxSize(This,MaxSize) -> wxWindow:setMaxSize(This,MaxSize).
+%% @hidden
+setCursor(This,Cursor) -> wxWindow:setCursor(This,Cursor).
+%% @hidden
+setContainingSizer(This,Sizer) -> wxWindow:setContainingSizer(This,Sizer).
+%% @hidden
+setClientSize(This,Width,Height) -> wxWindow:setClientSize(This,Width,Height).
+%% @hidden
+setClientSize(This,Size) -> wxWindow:setClientSize(This,Size).
+%% @hidden
+setCaret(This,Caret) -> wxWindow:setCaret(This,Caret).
+%% @hidden
+setBackgroundStyle(This,Style) -> wxWindow:setBackgroundStyle(This,Style).
+%% @hidden
+setBackgroundColour(This,Colour) -> wxWindow:setBackgroundColour(This,Colour).
+%% @hidden
+setAutoLayout(This,AutoLayout) -> wxWindow:setAutoLayout(This,AutoLayout).
+%% @hidden
+setAcceleratorTable(This,Accel) -> wxWindow:setAcceleratorTable(This,Accel).
+%% @hidden
+scrollWindow(This,Dx,Dy, Options) -> wxWindow:scrollWindow(This,Dx,Dy, Options).
+%% @hidden
+scrollWindow(This,Dx,Dy) -> wxWindow:scrollWindow(This,Dx,Dy).
+%% @hidden
+scrollPages(This,Pages) -> wxWindow:scrollPages(This,Pages).
+%% @hidden
+scrollLines(This,Lines) -> wxWindow:scrollLines(This,Lines).
+%% @hidden
+screenToClient(This,Pt) -> wxWindow:screenToClient(This,Pt).
+%% @hidden
+screenToClient(This) -> wxWindow:screenToClient(This).
+%% @hidden
+reparent(This,NewParent) -> wxWindow:reparent(This,NewParent).
+%% @hidden
+removeChild(This,Child) -> wxWindow:removeChild(This,Child).
+%% @hidden
+releaseMouse(This) -> wxWindow:releaseMouse(This).
+%% @hidden
+refreshRect(This,Rect, Options) -> wxWindow:refreshRect(This,Rect, Options).
+%% @hidden
+refreshRect(This,Rect) -> wxWindow:refreshRect(This,Rect).
+%% @hidden
+refresh(This, Options) -> wxWindow:refresh(This, Options).
+%% @hidden
+refresh(This) -> wxWindow:refresh(This).
+%% @hidden
+raise(This) -> wxWindow:raise(This).
+%% @hidden
+popupMenu(This,Menu,X,Y) -> wxWindow:popupMenu(This,Menu,X,Y).
+%% @hidden
+popupMenu(This,Menu, Options) -> wxWindow:popupMenu(This,Menu, Options).
+%% @hidden
+popupMenu(This,Menu) -> wxWindow:popupMenu(This,Menu).
+%% @hidden
+popEventHandler(This, Options) -> wxWindow:popEventHandler(This, Options).
+%% @hidden
+popEventHandler(This) -> wxWindow:popEventHandler(This).
+%% @hidden
+pageUp(This) -> wxWindow:pageUp(This).
+%% @hidden
+pageDown(This) -> wxWindow:pageDown(This).
+%% @hidden
+navigate(This, Options) -> wxWindow:navigate(This, Options).
+%% @hidden
+navigate(This) -> wxWindow:navigate(This).
+%% @hidden
+moveBeforeInTabOrder(This,Win) -> wxWindow:moveBeforeInTabOrder(This,Win).
+%% @hidden
+moveAfterInTabOrder(This,Win) -> wxWindow:moveAfterInTabOrder(This,Win).
+%% @hidden
+move(This,X,Y, Options) -> wxWindow:move(This,X,Y, Options).
+%% @hidden
+move(This,X,Y) -> wxWindow:move(This,X,Y).
+%% @hidden
+move(This,Pt) -> wxWindow:move(This,Pt).
+%% @hidden
+makeModal(This, Options) -> wxWindow:makeModal(This, Options).
+%% @hidden
+makeModal(This) -> wxWindow:makeModal(This).
+%% @hidden
+lower(This) -> wxWindow:lower(This).
+%% @hidden
+lineUp(This) -> wxWindow:lineUp(This).
+%% @hidden
+lineDown(This) -> wxWindow:lineDown(This).
+%% @hidden
+layout(This) -> wxWindow:layout(This).
+%% @hidden
+isTopLevel(This) -> wxWindow:isTopLevel(This).
+%% @hidden
+isShown(This) -> wxWindow:isShown(This).
+%% @hidden
+isRetained(This) -> wxWindow:isRetained(This).
+%% @hidden
+isExposed(This,X,Y,W,H) -> wxWindow:isExposed(This,X,Y,W,H).
+%% @hidden
+isExposed(This,X,Y) -> wxWindow:isExposed(This,X,Y).
+%% @hidden
+isExposed(This,Pt) -> wxWindow:isExposed(This,Pt).
+%% @hidden
+isEnabled(This) -> wxWindow:isEnabled(This).
+%% @hidden
+invalidateBestSize(This) -> wxWindow:invalidateBestSize(This).
+%% @hidden
+initDialog(This) -> wxWindow:initDialog(This).
+%% @hidden
+inheritAttributes(This) -> wxWindow:inheritAttributes(This).
+%% @hidden
+hide(This) -> wxWindow:hide(This).
+%% @hidden
+hasTransparentBackground(This) -> wxWindow:hasTransparentBackground(This).
+%% @hidden
+hasScrollbar(This,Orient) -> wxWindow:hasScrollbar(This,Orient).
+%% @hidden
+hasCapture(This) -> wxWindow:hasCapture(This).
+%% @hidden
+getWindowVariant(This) -> wxWindow:getWindowVariant(This).
+%% @hidden
+getWindowStyleFlag(This) -> wxWindow:getWindowStyleFlag(This).
+%% @hidden
+getVirtualSize(This) -> wxWindow:getVirtualSize(This).
+%% @hidden
+getUpdateRegion(This) -> wxWindow:getUpdateRegion(This).
+%% @hidden
+getToolTip(This) -> wxWindow:getToolTip(This).
+%% @hidden
+getTextExtent(This,String, Options) -> wxWindow:getTextExtent(This,String, Options).
+%% @hidden
+getTextExtent(This,String) -> wxWindow:getTextExtent(This,String).
+%% @hidden
+getSizer(This) -> wxWindow:getSizer(This).
+%% @hidden
+getSize(This) -> wxWindow:getSize(This).
+%% @hidden
+getScrollThumb(This,Orient) -> wxWindow:getScrollThumb(This,Orient).
+%% @hidden
+getScrollRange(This,Orient) -> wxWindow:getScrollRange(This,Orient).
+%% @hidden
+getScrollPos(This,Orient) -> wxWindow:getScrollPos(This,Orient).
+%% @hidden
+getScreenRect(This) -> wxWindow:getScreenRect(This).
+%% @hidden
+getScreenPosition(This) -> wxWindow:getScreenPosition(This).
+%% @hidden
+getRect(This) -> wxWindow:getRect(This).
+%% @hidden
+getPosition(This) -> wxWindow:getPosition(This).
+%% @hidden
+getParent(This) -> wxWindow:getParent(This).
+%% @hidden
+getName(This) -> wxWindow:getName(This).
+%% @hidden
+getMinSize(This) -> wxWindow:getMinSize(This).
+%% @hidden
+getMaxSize(This) -> wxWindow:getMaxSize(This).
+%% @hidden
+getLabel(This) -> wxWindow:getLabel(This).
+%% @hidden
+getId(This) -> wxWindow:getId(This).
+%% @hidden
+getHelpText(This) -> wxWindow:getHelpText(This).
+%% @hidden
+getHandle(This) -> wxWindow:getHandle(This).
+%% @hidden
+getGrandParent(This) -> wxWindow:getGrandParent(This).
+%% @hidden
+getForegroundColour(This) -> wxWindow:getForegroundColour(This).
+%% @hidden
+getFont(This) -> wxWindow:getFont(This).
+%% @hidden
+getExtraStyle(This) -> wxWindow:getExtraStyle(This).
+%% @hidden
+getEventHandler(This) -> wxWindow:getEventHandler(This).
+%% @hidden
+getDropTarget(This) -> wxWindow:getDropTarget(This).
+%% @hidden
+getCursor(This) -> wxWindow:getCursor(This).
+%% @hidden
+getContainingSizer(This) -> wxWindow:getContainingSizer(This).
+%% @hidden
+getClientSize(This) -> wxWindow:getClientSize(This).
+%% @hidden
+getChildren(This) -> wxWindow:getChildren(This).
+%% @hidden
+getCharWidth(This) -> wxWindow:getCharWidth(This).
+%% @hidden
+getCharHeight(This) -> wxWindow:getCharHeight(This).
+%% @hidden
+getCaret(This) -> wxWindow:getCaret(This).
+%% @hidden
+getBestSize(This) -> wxWindow:getBestSize(This).
+%% @hidden
+getBackgroundStyle(This) -> wxWindow:getBackgroundStyle(This).
+%% @hidden
+getBackgroundColour(This) -> wxWindow:getBackgroundColour(This).
+%% @hidden
+getAcceleratorTable(This) -> wxWindow:getAcceleratorTable(This).
+%% @hidden
+freeze(This) -> wxWindow:freeze(This).
+%% @hidden
+fitInside(This) -> wxWindow:fitInside(This).
+%% @hidden
+fit(This) -> wxWindow:fit(This).
+%% @hidden
+findWindow(This,Winid) -> wxWindow:findWindow(This,Winid).
+%% @hidden
+enable(This, Options) -> wxWindow:enable(This, Options).
+%% @hidden
+enable(This) -> wxWindow:enable(This).
+%% @hidden
+disable(This) -> wxWindow:disable(This).
+%% @hidden
+destroyChildren(This) -> wxWindow:destroyChildren(This).
+%% @hidden
+convertPixelsToDialog(This,Sz) -> wxWindow:convertPixelsToDialog(This,Sz).
+%% @hidden
+convertDialogToPixels(This,Sz) -> wxWindow:convertDialogToPixels(This,Sz).
+%% @hidden
+close(This, Options) -> wxWindow:close(This, Options).
+%% @hidden
+close(This) -> wxWindow:close(This).
+%% @hidden
+clientToScreen(This,X,Y) -> wxWindow:clientToScreen(This,X,Y).
+%% @hidden
+clientToScreen(This,Pt) -> wxWindow:clientToScreen(This,Pt).
+%% @hidden
+clearBackground(This) -> wxWindow:clearBackground(This).
+%% @hidden
+centreOnParent(This, Options) -> wxWindow:centreOnParent(This, Options).
+%% @hidden
+centreOnParent(This) -> wxWindow:centreOnParent(This).
+%% @hidden
+centre(This, Options) -> wxWindow:centre(This, Options).
+%% @hidden
+centre(This) -> wxWindow:centre(This).
+%% @hidden
+centerOnParent(This, Options) -> wxWindow:centerOnParent(This, Options).
+%% @hidden
+centerOnParent(This) -> wxWindow:centerOnParent(This).
+%% @hidden
+center(This, Options) -> wxWindow:center(This, Options).
+%% @hidden
+center(This) -> wxWindow:center(This).
+%% @hidden
+captureMouse(This) -> wxWindow:captureMouse(This).
+%% @hidden
+cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
+ %% From wxEvtHandler
+%% @hidden
+disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
+%% @hidden
+disconnect(This,EventType) -> wxEvtHandler:disconnect(This,EventType).
+%% @hidden
+disconnect(This) -> wxEvtHandler:disconnect(This).
+%% @hidden
+connect(This,EventType, Options) -> wxEvtHandler:connect(This,EventType, Options).
+%% @hidden
+connect(This,EventType) -> wxEvtHandler:connect(This,EventType).
diff --git a/lib/wx/src/gen/wxPopupWindow.erl b/lib/wx/src/gen/wxPopupWindow.erl
new file mode 100644
index 0000000000..415185d574
--- /dev/null
+++ b/lib/wx/src/gen/wxPopupWindow.erl
@@ -0,0 +1,503 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopupwindow.html">wxPopupWindow</a>.
+%% <p>This class is derived (and can use functions) from:
+%% <br />{@link wxWindow}
+%% <br />{@link wxEvtHandler}
+%% </p>
+%% @type wxPopupWindow(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxPopupWindow).
+-include("wxe.hrl").
+-export([create/2,create/3,destroy/1,new/0,new/1,new/2,position/3]).
+
+%% inherited exports
+-export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
+ centerOnParent/2,centre/1,centre/2,centreOnParent/1,centreOnParent/2,
+ clearBackground/1,clientToScreen/2,clientToScreen/3,close/1,close/2,
+ connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
+ destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
+ enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setToolTip/2,setVirtualSize/2,setVirtualSize/3,
+ setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+
+-export_type([wxPopupWindow/0]).
+%% @hidden
+parent_class(wxWindow) -> true;
+parent_class(wxEvtHandler) -> true;
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxPopupWindow() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopupwindow.html#wxpopupwindowwxpopupwindow">external documentation</a>.
+-spec new() -> wxPopupWindow().
+new() ->
+ wxe_util:construct(?wxPopupWindow_new_0,
+ <<>>).
+
+%% @equiv new(Parent, [])
+-spec new(Parent) -> wxPopupWindow() when
+ Parent::wxWindow:wxWindow().
+
+new(Parent)
+ when is_record(Parent, wx_ref) ->
+ new(Parent, []).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopupwindow.html#wxpopupwindowwxpopupwindow">external documentation</a>.
+-spec new(Parent, [Option]) -> wxPopupWindow() when
+ Parent::wxWindow:wxWindow(),
+ Option :: {flags, integer()}.
+new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
+ when is_list(Options) ->
+ ?CLASS(ParentT,wxWindow),
+ MOpts = fun({flags, Flags}, Acc) -> [<<1:32/?UI,Flags:32/?UI>>|Acc];
+ (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
+ BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
+ wxe_util:construct(?wxPopupWindow_new_2,
+ <<ParentRef:32/?UI, 0:32,BinOpt/binary>>).
+
+%% @equiv create(This,Parent, [])
+-spec create(This, Parent) -> boolean() when
+ This::wxPopupWindow(), Parent::wxWindow:wxWindow().
+
+create(This,Parent)
+ when is_record(This, wx_ref),is_record(Parent, wx_ref) ->
+ create(This,Parent, []).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopupwindow.html#wxpopupwindowcreate">external documentation</a>.
+-spec create(This, Parent, [Option]) -> boolean() when
+ This::wxPopupWindow(), Parent::wxWindow:wxWindow(),
+ Option :: {flags, integer()}.
+create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options)
+ when is_list(Options) ->
+ ?CLASS(ThisT,wxPopupWindow),
+ ?CLASS(ParentT,wxWindow),
+ MOpts = fun({flags, Flags}, Acc) -> [<<1:32/?UI,Flags:32/?UI>>|Acc];
+ (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
+ BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
+ wxe_util:call(?wxPopupWindow_Create,
+ <<ThisRef:32/?UI,ParentRef:32/?UI, BinOpt/binary>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpopupwindow.html#wxpopupwindowposition">external documentation</a>.
+-spec position(This, PtOrigin, Size) -> ok when
+ This::wxPopupWindow(), PtOrigin::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}.
+position(#wx_ref{type=ThisT,ref=ThisRef},{PtOriginX,PtOriginY},{SizeW,SizeH})
+ when is_integer(PtOriginX),is_integer(PtOriginY),is_integer(SizeW),is_integer(SizeH) ->
+ ?CLASS(ThisT,wxPopupWindow),
+ wxe_util:cast(?wxPopupWindow_Position,
+ <<ThisRef:32/?UI,PtOriginX:32/?UI,PtOriginY:32/?UI,SizeW:32/?UI,SizeH:32/?UI>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxPopupWindow()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxPopupWindow),
+ wxe_util:destroy(?DESTROY_OBJECT,Obj),
+ ok.
+ %% From wxWindow
+%% @hidden
+warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
+%% @hidden
+validate(This) -> wxWindow:validate(This).
+%% @hidden
+updateWindowUI(This, Options) -> wxWindow:updateWindowUI(This, Options).
+%% @hidden
+updateWindowUI(This) -> wxWindow:updateWindowUI(This).
+%% @hidden
+update(This) -> wxWindow:update(This).
+%% @hidden
+transferDataToWindow(This) -> wxWindow:transferDataToWindow(This).
+%% @hidden
+transferDataFromWindow(This) -> wxWindow:transferDataFromWindow(This).
+%% @hidden
+thaw(This) -> wxWindow:thaw(This).
+%% @hidden
+show(This, Options) -> wxWindow:show(This, Options).
+%% @hidden
+show(This) -> wxWindow:show(This).
+%% @hidden
+shouldInheritColours(This) -> wxWindow:shouldInheritColours(This).
+%% @hidden
+setWindowVariant(This,Variant) -> wxWindow:setWindowVariant(This,Variant).
+%% @hidden
+setWindowStyleFlag(This,Style) -> wxWindow:setWindowStyleFlag(This,Style).
+%% @hidden
+setWindowStyle(This,Style) -> wxWindow:setWindowStyle(This,Style).
+%% @hidden
+setVirtualSizeHints(This,MinW,MinH, Options) -> wxWindow:setVirtualSizeHints(This,MinW,MinH, Options).
+%% @hidden
+setVirtualSizeHints(This,MinW,MinH) -> wxWindow:setVirtualSizeHints(This,MinW,MinH).
+%% @hidden
+setVirtualSizeHints(This,MinSize) -> wxWindow:setVirtualSizeHints(This,MinSize).
+%% @hidden
+setVirtualSize(This,X,Y) -> wxWindow:setVirtualSize(This,X,Y).
+%% @hidden
+setVirtualSize(This,Size) -> wxWindow:setVirtualSize(This,Size).
+%% @hidden
+setToolTip(This,Tip) -> wxWindow:setToolTip(This,Tip).
+%% @hidden
+setThemeEnabled(This,EnableTheme) -> wxWindow:setThemeEnabled(This,EnableTheme).
+%% @hidden
+setSizerAndFit(This,Sizer, Options) -> wxWindow:setSizerAndFit(This,Sizer, Options).
+%% @hidden
+setSizerAndFit(This,Sizer) -> wxWindow:setSizerAndFit(This,Sizer).
+%% @hidden
+setSizer(This,Sizer, Options) -> wxWindow:setSizer(This,Sizer, Options).
+%% @hidden
+setSizer(This,Sizer) -> wxWindow:setSizer(This,Sizer).
+%% @hidden
+setSizeHints(This,MinW,MinH, Options) -> wxWindow:setSizeHints(This,MinW,MinH, Options).
+%% @hidden
+setSizeHints(This,MinW,MinH) -> wxWindow:setSizeHints(This,MinW,MinH).
+%% @hidden
+setSizeHints(This,MinSize) -> wxWindow:setSizeHints(This,MinSize).
+%% @hidden
+setSize(This,X,Y,Width,Height, Options) -> wxWindow:setSize(This,X,Y,Width,Height, Options).
+%% @hidden
+setSize(This,X,Y,Width,Height) -> wxWindow:setSize(This,X,Y,Width,Height).
+%% @hidden
+setSize(This,Width,Height) -> wxWindow:setSize(This,Width,Height).
+%% @hidden
+setSize(This,Rect) -> wxWindow:setSize(This,Rect).
+%% @hidden
+setScrollPos(This,Orient,Pos, Options) -> wxWindow:setScrollPos(This,Orient,Pos, Options).
+%% @hidden
+setScrollPos(This,Orient,Pos) -> wxWindow:setScrollPos(This,Orient,Pos).
+%% @hidden
+setScrollbar(This,Orient,Pos,ThumbVisible,Range, Options) -> wxWindow:setScrollbar(This,Orient,Pos,ThumbVisible,Range, Options).
+%% @hidden
+setScrollbar(This,Orient,Pos,ThumbVisible,Range) -> wxWindow:setScrollbar(This,Orient,Pos,ThumbVisible,Range).
+%% @hidden
+setPalette(This,Pal) -> wxWindow:setPalette(This,Pal).
+%% @hidden
+setName(This,Name) -> wxWindow:setName(This,Name).
+%% @hidden
+setLabel(This,Label) -> wxWindow:setLabel(This,Label).
+%% @hidden
+setId(This,Winid) -> wxWindow:setId(This,Winid).
+%% @hidden
+setHelpText(This,Text) -> wxWindow:setHelpText(This,Text).
+%% @hidden
+setForegroundColour(This,Colour) -> wxWindow:setForegroundColour(This,Colour).
+%% @hidden
+setFont(This,Font) -> wxWindow:setFont(This,Font).
+%% @hidden
+setFocusFromKbd(This) -> wxWindow:setFocusFromKbd(This).
+%% @hidden
+setFocus(This) -> wxWindow:setFocus(This).
+%% @hidden
+setExtraStyle(This,ExStyle) -> wxWindow:setExtraStyle(This,ExStyle).
+%% @hidden
+setDropTarget(This,DropTarget) -> wxWindow:setDropTarget(This,DropTarget).
+%% @hidden
+setOwnForegroundColour(This,Colour) -> wxWindow:setOwnForegroundColour(This,Colour).
+%% @hidden
+setOwnFont(This,Font) -> wxWindow:setOwnFont(This,Font).
+%% @hidden
+setOwnBackgroundColour(This,Colour) -> wxWindow:setOwnBackgroundColour(This,Colour).
+%% @hidden
+setMinSize(This,MinSize) -> wxWindow:setMinSize(This,MinSize).
+%% @hidden
+setMaxSize(This,MaxSize) -> wxWindow:setMaxSize(This,MaxSize).
+%% @hidden
+setCursor(This,Cursor) -> wxWindow:setCursor(This,Cursor).
+%% @hidden
+setContainingSizer(This,Sizer) -> wxWindow:setContainingSizer(This,Sizer).
+%% @hidden
+setClientSize(This,Width,Height) -> wxWindow:setClientSize(This,Width,Height).
+%% @hidden
+setClientSize(This,Size) -> wxWindow:setClientSize(This,Size).
+%% @hidden
+setCaret(This,Caret) -> wxWindow:setCaret(This,Caret).
+%% @hidden
+setBackgroundStyle(This,Style) -> wxWindow:setBackgroundStyle(This,Style).
+%% @hidden
+setBackgroundColour(This,Colour) -> wxWindow:setBackgroundColour(This,Colour).
+%% @hidden
+setAutoLayout(This,AutoLayout) -> wxWindow:setAutoLayout(This,AutoLayout).
+%% @hidden
+setAcceleratorTable(This,Accel) -> wxWindow:setAcceleratorTable(This,Accel).
+%% @hidden
+scrollWindow(This,Dx,Dy, Options) -> wxWindow:scrollWindow(This,Dx,Dy, Options).
+%% @hidden
+scrollWindow(This,Dx,Dy) -> wxWindow:scrollWindow(This,Dx,Dy).
+%% @hidden
+scrollPages(This,Pages) -> wxWindow:scrollPages(This,Pages).
+%% @hidden
+scrollLines(This,Lines) -> wxWindow:scrollLines(This,Lines).
+%% @hidden
+screenToClient(This,Pt) -> wxWindow:screenToClient(This,Pt).
+%% @hidden
+screenToClient(This) -> wxWindow:screenToClient(This).
+%% @hidden
+reparent(This,NewParent) -> wxWindow:reparent(This,NewParent).
+%% @hidden
+removeChild(This,Child) -> wxWindow:removeChild(This,Child).
+%% @hidden
+releaseMouse(This) -> wxWindow:releaseMouse(This).
+%% @hidden
+refreshRect(This,Rect, Options) -> wxWindow:refreshRect(This,Rect, Options).
+%% @hidden
+refreshRect(This,Rect) -> wxWindow:refreshRect(This,Rect).
+%% @hidden
+refresh(This, Options) -> wxWindow:refresh(This, Options).
+%% @hidden
+refresh(This) -> wxWindow:refresh(This).
+%% @hidden
+raise(This) -> wxWindow:raise(This).
+%% @hidden
+popupMenu(This,Menu,X,Y) -> wxWindow:popupMenu(This,Menu,X,Y).
+%% @hidden
+popupMenu(This,Menu, Options) -> wxWindow:popupMenu(This,Menu, Options).
+%% @hidden
+popupMenu(This,Menu) -> wxWindow:popupMenu(This,Menu).
+%% @hidden
+popEventHandler(This, Options) -> wxWindow:popEventHandler(This, Options).
+%% @hidden
+popEventHandler(This) -> wxWindow:popEventHandler(This).
+%% @hidden
+pageUp(This) -> wxWindow:pageUp(This).
+%% @hidden
+pageDown(This) -> wxWindow:pageDown(This).
+%% @hidden
+navigate(This, Options) -> wxWindow:navigate(This, Options).
+%% @hidden
+navigate(This) -> wxWindow:navigate(This).
+%% @hidden
+moveBeforeInTabOrder(This,Win) -> wxWindow:moveBeforeInTabOrder(This,Win).
+%% @hidden
+moveAfterInTabOrder(This,Win) -> wxWindow:moveAfterInTabOrder(This,Win).
+%% @hidden
+move(This,X,Y, Options) -> wxWindow:move(This,X,Y, Options).
+%% @hidden
+move(This,X,Y) -> wxWindow:move(This,X,Y).
+%% @hidden
+move(This,Pt) -> wxWindow:move(This,Pt).
+%% @hidden
+makeModal(This, Options) -> wxWindow:makeModal(This, Options).
+%% @hidden
+makeModal(This) -> wxWindow:makeModal(This).
+%% @hidden
+lower(This) -> wxWindow:lower(This).
+%% @hidden
+lineUp(This) -> wxWindow:lineUp(This).
+%% @hidden
+lineDown(This) -> wxWindow:lineDown(This).
+%% @hidden
+layout(This) -> wxWindow:layout(This).
+%% @hidden
+isTopLevel(This) -> wxWindow:isTopLevel(This).
+%% @hidden
+isShown(This) -> wxWindow:isShown(This).
+%% @hidden
+isRetained(This) -> wxWindow:isRetained(This).
+%% @hidden
+isExposed(This,X,Y,W,H) -> wxWindow:isExposed(This,X,Y,W,H).
+%% @hidden
+isExposed(This,X,Y) -> wxWindow:isExposed(This,X,Y).
+%% @hidden
+isExposed(This,Pt) -> wxWindow:isExposed(This,Pt).
+%% @hidden
+isEnabled(This) -> wxWindow:isEnabled(This).
+%% @hidden
+invalidateBestSize(This) -> wxWindow:invalidateBestSize(This).
+%% @hidden
+initDialog(This) -> wxWindow:initDialog(This).
+%% @hidden
+inheritAttributes(This) -> wxWindow:inheritAttributes(This).
+%% @hidden
+hide(This) -> wxWindow:hide(This).
+%% @hidden
+hasTransparentBackground(This) -> wxWindow:hasTransparentBackground(This).
+%% @hidden
+hasScrollbar(This,Orient) -> wxWindow:hasScrollbar(This,Orient).
+%% @hidden
+hasCapture(This) -> wxWindow:hasCapture(This).
+%% @hidden
+getWindowVariant(This) -> wxWindow:getWindowVariant(This).
+%% @hidden
+getWindowStyleFlag(This) -> wxWindow:getWindowStyleFlag(This).
+%% @hidden
+getVirtualSize(This) -> wxWindow:getVirtualSize(This).
+%% @hidden
+getUpdateRegion(This) -> wxWindow:getUpdateRegion(This).
+%% @hidden
+getToolTip(This) -> wxWindow:getToolTip(This).
+%% @hidden
+getTextExtent(This,String, Options) -> wxWindow:getTextExtent(This,String, Options).
+%% @hidden
+getTextExtent(This,String) -> wxWindow:getTextExtent(This,String).
+%% @hidden
+getSizer(This) -> wxWindow:getSizer(This).
+%% @hidden
+getSize(This) -> wxWindow:getSize(This).
+%% @hidden
+getScrollThumb(This,Orient) -> wxWindow:getScrollThumb(This,Orient).
+%% @hidden
+getScrollRange(This,Orient) -> wxWindow:getScrollRange(This,Orient).
+%% @hidden
+getScrollPos(This,Orient) -> wxWindow:getScrollPos(This,Orient).
+%% @hidden
+getScreenRect(This) -> wxWindow:getScreenRect(This).
+%% @hidden
+getScreenPosition(This) -> wxWindow:getScreenPosition(This).
+%% @hidden
+getRect(This) -> wxWindow:getRect(This).
+%% @hidden
+getPosition(This) -> wxWindow:getPosition(This).
+%% @hidden
+getParent(This) -> wxWindow:getParent(This).
+%% @hidden
+getName(This) -> wxWindow:getName(This).
+%% @hidden
+getMinSize(This) -> wxWindow:getMinSize(This).
+%% @hidden
+getMaxSize(This) -> wxWindow:getMaxSize(This).
+%% @hidden
+getLabel(This) -> wxWindow:getLabel(This).
+%% @hidden
+getId(This) -> wxWindow:getId(This).
+%% @hidden
+getHelpText(This) -> wxWindow:getHelpText(This).
+%% @hidden
+getHandle(This) -> wxWindow:getHandle(This).
+%% @hidden
+getGrandParent(This) -> wxWindow:getGrandParent(This).
+%% @hidden
+getForegroundColour(This) -> wxWindow:getForegroundColour(This).
+%% @hidden
+getFont(This) -> wxWindow:getFont(This).
+%% @hidden
+getExtraStyle(This) -> wxWindow:getExtraStyle(This).
+%% @hidden
+getEventHandler(This) -> wxWindow:getEventHandler(This).
+%% @hidden
+getDropTarget(This) -> wxWindow:getDropTarget(This).
+%% @hidden
+getCursor(This) -> wxWindow:getCursor(This).
+%% @hidden
+getContainingSizer(This) -> wxWindow:getContainingSizer(This).
+%% @hidden
+getClientSize(This) -> wxWindow:getClientSize(This).
+%% @hidden
+getChildren(This) -> wxWindow:getChildren(This).
+%% @hidden
+getCharWidth(This) -> wxWindow:getCharWidth(This).
+%% @hidden
+getCharHeight(This) -> wxWindow:getCharHeight(This).
+%% @hidden
+getCaret(This) -> wxWindow:getCaret(This).
+%% @hidden
+getBestSize(This) -> wxWindow:getBestSize(This).
+%% @hidden
+getBackgroundStyle(This) -> wxWindow:getBackgroundStyle(This).
+%% @hidden
+getBackgroundColour(This) -> wxWindow:getBackgroundColour(This).
+%% @hidden
+getAcceleratorTable(This) -> wxWindow:getAcceleratorTable(This).
+%% @hidden
+freeze(This) -> wxWindow:freeze(This).
+%% @hidden
+fitInside(This) -> wxWindow:fitInside(This).
+%% @hidden
+fit(This) -> wxWindow:fit(This).
+%% @hidden
+findWindow(This,Winid) -> wxWindow:findWindow(This,Winid).
+%% @hidden
+enable(This, Options) -> wxWindow:enable(This, Options).
+%% @hidden
+enable(This) -> wxWindow:enable(This).
+%% @hidden
+disable(This) -> wxWindow:disable(This).
+%% @hidden
+destroyChildren(This) -> wxWindow:destroyChildren(This).
+%% @hidden
+convertPixelsToDialog(This,Sz) -> wxWindow:convertPixelsToDialog(This,Sz).
+%% @hidden
+convertDialogToPixels(This,Sz) -> wxWindow:convertDialogToPixels(This,Sz).
+%% @hidden
+close(This, Options) -> wxWindow:close(This, Options).
+%% @hidden
+close(This) -> wxWindow:close(This).
+%% @hidden
+clientToScreen(This,X,Y) -> wxWindow:clientToScreen(This,X,Y).
+%% @hidden
+clientToScreen(This,Pt) -> wxWindow:clientToScreen(This,Pt).
+%% @hidden
+clearBackground(This) -> wxWindow:clearBackground(This).
+%% @hidden
+centreOnParent(This, Options) -> wxWindow:centreOnParent(This, Options).
+%% @hidden
+centreOnParent(This) -> wxWindow:centreOnParent(This).
+%% @hidden
+centre(This, Options) -> wxWindow:centre(This, Options).
+%% @hidden
+centre(This) -> wxWindow:centre(This).
+%% @hidden
+centerOnParent(This, Options) -> wxWindow:centerOnParent(This, Options).
+%% @hidden
+centerOnParent(This) -> wxWindow:centerOnParent(This).
+%% @hidden
+center(This, Options) -> wxWindow:center(This, Options).
+%% @hidden
+center(This) -> wxWindow:center(This).
+%% @hidden
+captureMouse(This) -> wxWindow:captureMouse(This).
+%% @hidden
+cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
+ %% From wxEvtHandler
+%% @hidden
+disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
+%% @hidden
+disconnect(This,EventType) -> wxEvtHandler:disconnect(This,EventType).
+%% @hidden
+disconnect(This) -> wxEvtHandler:disconnect(This).
+%% @hidden
+connect(This,EventType, Options) -> wxEvtHandler:connect(This,EventType, Options).
+%% @hidden
+connect(This,EventType) -> wxEvtHandler:connect(This,EventType).
diff --git a/lib/wx/src/gen/wxTextCtrl.erl b/lib/wx/src/gen/wxTextCtrl.erl
index cb85652ceb..7e6852b9c8 100644
--- a/lib/wx/src/gen/wxTextCtrl.erl
+++ b/lib/wx/src/gen/wxTextCtrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,8 +29,8 @@
-module(wxTextCtrl).
-include("wxe.hrl").
--export([appendText/2,canCopy/1,canCut/1,canPaste/1,canRedo/1,canUndo/1,clear/1,
- copy/1,create/3,create/4,cut/1,destroy/1,discardEdits/1,emulateKeyPress/2,
+-export([appendText/2,canCopy/1,canCut/1,canPaste/1,canRedo/1,canUndo/1,changeValue/2,
+ clear/1,copy/1,create/3,create/4,cut/1,destroy/1,discardEdits/1,emulateKeyPress/2,
getDefaultStyle/1,getInsertionPoint/1,getLastPosition/1,getLineLength/2,
getLineText/2,getNumberOfLines/1,getRange/3,getSelection/1,getStringSelection/1,
getStyle/3,getValue/1,isEditable/1,isModified/1,isMultiLine/1,isSingleLine/1,
@@ -232,6 +232,16 @@ discardEdits(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:cast(?wxTextCtrl_DiscardEdits,
<<ThisRef:32/?UI>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtextctrl.html#wxtextctrlchangevalue">external documentation</a>.
+-spec changeValue(This, Value) -> ok when
+ This::wxTextCtrl(), Value::unicode:chardata().
+changeValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
+ when is_list(Value) ->
+ ?CLASS(ThisT,wxTextCtrl),
+ Value_UC = unicode:characters_to_binary([Value,0]),
+ wxe_util:cast(?wxTextCtrl_ChangeValue,
+ <<ThisRef:32/?UI,(byte_size(Value_UC)):32/?UI,(Value_UC)/binary, 0:(((8- ((0+byte_size(Value_UC)) band 16#7)) band 16#7))/unit:8>>).
+
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtextctrl.html#wxtextctrlemulatekeypress">external documentation</a>.
-spec emulateKeyPress(This, Event) -> boolean() when
This::wxTextCtrl(), Event::wxKeyEvent:wxKeyEvent().
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index e208b081e8..7d4db9ba97 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -1669,1665 +1669,1677 @@ wxdebug_table() ->
{1824, {wxTextCtrl, create, 3}},
{1825, {wxTextCtrl, cut, 0}},
{1826, {wxTextCtrl, discardEdits, 0}},
- {1827, {wxTextCtrl, emulateKeyPress, 1}},
- {1828, {wxTextCtrl, getDefaultStyle, 0}},
- {1829, {wxTextCtrl, getInsertionPoint, 0}},
- {1830, {wxTextCtrl, getLastPosition, 0}},
- {1831, {wxTextCtrl, getLineLength, 1}},
- {1832, {wxTextCtrl, getLineText, 1}},
- {1833, {wxTextCtrl, getNumberOfLines, 0}},
- {1834, {wxTextCtrl, getRange, 2}},
- {1835, {wxTextCtrl, getSelection, 2}},
- {1836, {wxTextCtrl, getStringSelection, 0}},
- {1837, {wxTextCtrl, getStyle, 2}},
- {1838, {wxTextCtrl, getValue, 0}},
- {1839, {wxTextCtrl, isEditable, 0}},
- {1840, {wxTextCtrl, isModified, 0}},
- {1841, {wxTextCtrl, isMultiLine, 0}},
- {1842, {wxTextCtrl, isSingleLine, 0}},
- {1843, {wxTextCtrl, loadFile, 2}},
- {1844, {wxTextCtrl, markDirty, 0}},
- {1845, {wxTextCtrl, paste, 0}},
- {1846, {wxTextCtrl, positionToXY, 3}},
- {1847, {wxTextCtrl, redo, 0}},
- {1848, {wxTextCtrl, remove, 2}},
- {1849, {wxTextCtrl, replace, 3}},
- {1850, {wxTextCtrl, saveFile, 1}},
- {1851, {wxTextCtrl, setDefaultStyle, 1}},
- {1852, {wxTextCtrl, setEditable, 1}},
- {1853, {wxTextCtrl, setInsertionPoint, 1}},
- {1854, {wxTextCtrl, setInsertionPointEnd, 0}},
- {1856, {wxTextCtrl, setMaxLength, 1}},
- {1857, {wxTextCtrl, setSelection, 2}},
- {1858, {wxTextCtrl, setStyle, 3}},
- {1859, {wxTextCtrl, setValue, 1}},
- {1860, {wxTextCtrl, showPosition, 1}},
- {1861, {wxTextCtrl, undo, 0}},
- {1862, {wxTextCtrl, writeText, 1}},
- {1863, {wxTextCtrl, xYToPosition, 2}},
- {1866, {wxNotebook, new_0, 0}},
- {1867, {wxNotebook, new_3, 3}},
- {1868, {wxNotebook, destruct, 0}},
- {1869, {wxNotebook, addPage, 3}},
- {1870, {wxNotebook, advanceSelection, 1}},
- {1871, {wxNotebook, assignImageList, 1}},
- {1872, {wxNotebook, create, 3}},
- {1873, {wxNotebook, deleteAllPages, 0}},
- {1874, {wxNotebook, deletePage, 1}},
- {1875, {wxNotebook, removePage, 1}},
- {1876, {wxNotebook, getCurrentPage, 0}},
- {1877, {wxNotebook, getImageList, 0}},
- {1879, {wxNotebook, getPage, 1}},
- {1880, {wxNotebook, getPageCount, 0}},
- {1881, {wxNotebook, getPageImage, 1}},
- {1882, {wxNotebook, getPageText, 1}},
- {1883, {wxNotebook, getRowCount, 0}},
- {1884, {wxNotebook, getSelection, 0}},
- {1885, {wxNotebook, getThemeBackgroundColour, 0}},
- {1887, {wxNotebook, hitTest, 2}},
- {1889, {wxNotebook, insertPage, 4}},
- {1890, {wxNotebook, setImageList, 1}},
- {1891, {wxNotebook, setPadding, 1}},
- {1892, {wxNotebook, setPageSize, 1}},
- {1893, {wxNotebook, setPageImage, 2}},
- {1894, {wxNotebook, setPageText, 2}},
- {1895, {wxNotebook, setSelection, 1}},
- {1896, {wxNotebook, changeSelection, 1}},
- {1897, {wxChoicebook, new_0, 0}},
- {1898, {wxChoicebook, new_3, 3}},
- {1899, {wxChoicebook, addPage, 3}},
- {1900, {wxChoicebook, advanceSelection, 1}},
- {1901, {wxChoicebook, assignImageList, 1}},
- {1902, {wxChoicebook, create, 3}},
- {1903, {wxChoicebook, deleteAllPages, 0}},
- {1904, {wxChoicebook, deletePage, 1}},
- {1905, {wxChoicebook, removePage, 1}},
- {1906, {wxChoicebook, getCurrentPage, 0}},
- {1907, {wxChoicebook, getImageList, 0}},
- {1909, {wxChoicebook, getPage, 1}},
- {1910, {wxChoicebook, getPageCount, 0}},
- {1911, {wxChoicebook, getPageImage, 1}},
- {1912, {wxChoicebook, getPageText, 1}},
- {1913, {wxChoicebook, getSelection, 0}},
- {1914, {wxChoicebook, hitTest, 2}},
- {1915, {wxChoicebook, insertPage, 4}},
- {1916, {wxChoicebook, setImageList, 1}},
- {1917, {wxChoicebook, setPageSize, 1}},
- {1918, {wxChoicebook, setPageImage, 2}},
- {1919, {wxChoicebook, setPageText, 2}},
- {1920, {wxChoicebook, setSelection, 1}},
- {1921, {wxChoicebook, changeSelection, 1}},
- {1922, {wxChoicebook, 'Destroy', undefined}},
- {1923, {wxToolbook, new_0, 0}},
- {1924, {wxToolbook, new_3, 3}},
- {1925, {wxToolbook, addPage, 3}},
- {1926, {wxToolbook, advanceSelection, 1}},
- {1927, {wxToolbook, assignImageList, 1}},
- {1928, {wxToolbook, create, 3}},
- {1929, {wxToolbook, deleteAllPages, 0}},
- {1930, {wxToolbook, deletePage, 1}},
- {1931, {wxToolbook, removePage, 1}},
- {1932, {wxToolbook, getCurrentPage, 0}},
- {1933, {wxToolbook, getImageList, 0}},
- {1935, {wxToolbook, getPage, 1}},
- {1936, {wxToolbook, getPageCount, 0}},
- {1937, {wxToolbook, getPageImage, 1}},
- {1938, {wxToolbook, getPageText, 1}},
- {1939, {wxToolbook, getSelection, 0}},
- {1941, {wxToolbook, hitTest, 2}},
- {1942, {wxToolbook, insertPage, 4}},
- {1943, {wxToolbook, setImageList, 1}},
- {1944, {wxToolbook, setPageSize, 1}},
- {1945, {wxToolbook, setPageImage, 2}},
- {1946, {wxToolbook, setPageText, 2}},
- {1947, {wxToolbook, setSelection, 1}},
- {1948, {wxToolbook, changeSelection, 1}},
- {1949, {wxToolbook, 'Destroy', undefined}},
- {1950, {wxListbook, new_0, 0}},
- {1951, {wxListbook, new_3, 3}},
- {1952, {wxListbook, addPage, 3}},
- {1953, {wxListbook, advanceSelection, 1}},
- {1954, {wxListbook, assignImageList, 1}},
- {1955, {wxListbook, create, 3}},
- {1956, {wxListbook, deleteAllPages, 0}},
- {1957, {wxListbook, deletePage, 1}},
- {1958, {wxListbook, removePage, 1}},
- {1959, {wxListbook, getCurrentPage, 0}},
- {1960, {wxListbook, getImageList, 0}},
- {1962, {wxListbook, getPage, 1}},
- {1963, {wxListbook, getPageCount, 0}},
- {1964, {wxListbook, getPageImage, 1}},
- {1965, {wxListbook, getPageText, 1}},
- {1966, {wxListbook, getSelection, 0}},
- {1968, {wxListbook, hitTest, 2}},
- {1969, {wxListbook, insertPage, 4}},
- {1970, {wxListbook, setImageList, 1}},
- {1971, {wxListbook, setPageSize, 1}},
- {1972, {wxListbook, setPageImage, 2}},
- {1973, {wxListbook, setPageText, 2}},
- {1974, {wxListbook, setSelection, 1}},
- {1975, {wxListbook, changeSelection, 1}},
- {1976, {wxListbook, 'Destroy', undefined}},
- {1977, {wxTreebook, new_0, 0}},
- {1978, {wxTreebook, new_3, 3}},
- {1979, {wxTreebook, addPage, 3}},
- {1980, {wxTreebook, advanceSelection, 1}},
- {1981, {wxTreebook, assignImageList, 1}},
- {1982, {wxTreebook, create, 3}},
- {1983, {wxTreebook, deleteAllPages, 0}},
- {1984, {wxTreebook, deletePage, 1}},
- {1985, {wxTreebook, removePage, 1}},
- {1986, {wxTreebook, getCurrentPage, 0}},
- {1987, {wxTreebook, getImageList, 0}},
- {1989, {wxTreebook, getPage, 1}},
- {1990, {wxTreebook, getPageCount, 0}},
- {1991, {wxTreebook, getPageImage, 1}},
- {1992, {wxTreebook, getPageText, 1}},
- {1993, {wxTreebook, getSelection, 0}},
- {1994, {wxTreebook, expandNode, 2}},
- {1995, {wxTreebook, isNodeExpanded, 1}},
- {1997, {wxTreebook, hitTest, 2}},
- {1998, {wxTreebook, insertPage, 4}},
- {1999, {wxTreebook, insertSubPage, 4}},
- {2000, {wxTreebook, setImageList, 1}},
- {2001, {wxTreebook, setPageSize, 1}},
- {2002, {wxTreebook, setPageImage, 2}},
- {2003, {wxTreebook, setPageText, 2}},
- {2004, {wxTreebook, setSelection, 1}},
- {2005, {wxTreebook, changeSelection, 1}},
- {2006, {wxTreebook, 'Destroy', undefined}},
- {2009, {wxTreeCtrl, new_2, 2}},
- {2010, {wxTreeCtrl, new_0, 0}},
- {2012, {wxTreeCtrl, destruct, 0}},
- {2013, {wxTreeCtrl, addRoot, 2}},
- {2014, {wxTreeCtrl, appendItem, 3}},
- {2015, {wxTreeCtrl, assignImageList, 1}},
- {2016, {wxTreeCtrl, assignStateImageList, 1}},
- {2017, {wxTreeCtrl, collapse, 1}},
- {2018, {wxTreeCtrl, collapseAndReset, 1}},
- {2019, {wxTreeCtrl, create, 2}},
- {2020, {wxTreeCtrl, delete, 1}},
- {2021, {wxTreeCtrl, deleteAllItems, 0}},
- {2022, {wxTreeCtrl, deleteChildren, 1}},
- {2023, {wxTreeCtrl, editLabel, 1}},
- {2024, {wxTreeCtrl, ensureVisible, 1}},
- {2025, {wxTreeCtrl, expand, 1}},
- {2026, {wxTreeCtrl, getBoundingRect, 3}},
- {2028, {wxTreeCtrl, getChildrenCount, 2}},
- {2029, {wxTreeCtrl, getCount, 0}},
- {2030, {wxTreeCtrl, getEditControl, 0}},
- {2031, {wxTreeCtrl, getFirstChild, 2}},
- {2032, {wxTreeCtrl, getNextChild, 2}},
- {2033, {wxTreeCtrl, getFirstVisibleItem, 0}},
- {2034, {wxTreeCtrl, getImageList, 0}},
- {2035, {wxTreeCtrl, getIndent, 0}},
- {2036, {wxTreeCtrl, getItemBackgroundColour, 1}},
- {2037, {wxTreeCtrl, getItemData, 1}},
- {2038, {wxTreeCtrl, getItemFont, 1}},
- {2039, {wxTreeCtrl, getItemImage_1, 1}},
- {2040, {wxTreeCtrl, getItemImage_2, 2}},
- {2041, {wxTreeCtrl, getItemText, 1}},
- {2042, {wxTreeCtrl, getItemTextColour, 1}},
- {2043, {wxTreeCtrl, getLastChild, 1}},
- {2044, {wxTreeCtrl, getNextSibling, 1}},
- {2045, {wxTreeCtrl, getNextVisible, 1}},
- {2046, {wxTreeCtrl, getItemParent, 1}},
- {2047, {wxTreeCtrl, getPrevSibling, 1}},
- {2048, {wxTreeCtrl, getPrevVisible, 1}},
- {2049, {wxTreeCtrl, getRootItem, 0}},
- {2050, {wxTreeCtrl, getSelection, 0}},
- {2051, {wxTreeCtrl, getSelections, 1}},
- {2052, {wxTreeCtrl, getStateImageList, 0}},
- {2053, {wxTreeCtrl, hitTest, 2}},
- {2055, {wxTreeCtrl, insertItem, 4}},
- {2056, {wxTreeCtrl, isBold, 1}},
- {2057, {wxTreeCtrl, isExpanded, 1}},
- {2058, {wxTreeCtrl, isSelected, 1}},
- {2059, {wxTreeCtrl, isVisible, 1}},
- {2060, {wxTreeCtrl, itemHasChildren, 1}},
- {2061, {wxTreeCtrl, isTreeItemIdOk, 1}},
- {2062, {wxTreeCtrl, prependItem, 3}},
- {2063, {wxTreeCtrl, scrollTo, 1}},
- {2064, {wxTreeCtrl, selectItem_1, 1}},
- {2065, {wxTreeCtrl, selectItem_2, 2}},
- {2066, {wxTreeCtrl, setIndent, 1}},
- {2067, {wxTreeCtrl, setImageList, 1}},
- {2068, {wxTreeCtrl, setItemBackgroundColour, 2}},
- {2069, {wxTreeCtrl, setItemBold, 2}},
- {2070, {wxTreeCtrl, setItemData, 2}},
- {2071, {wxTreeCtrl, setItemDropHighlight, 2}},
- {2072, {wxTreeCtrl, setItemFont, 2}},
- {2073, {wxTreeCtrl, setItemHasChildren, 2}},
- {2074, {wxTreeCtrl, setItemImage_2, 2}},
- {2075, {wxTreeCtrl, setItemImage_3, 3}},
- {2076, {wxTreeCtrl, setItemText, 2}},
- {2077, {wxTreeCtrl, setItemTextColour, 2}},
- {2078, {wxTreeCtrl, setStateImageList, 1}},
- {2079, {wxTreeCtrl, setWindowStyle, 1}},
- {2080, {wxTreeCtrl, sortChildren, 1}},
- {2081, {wxTreeCtrl, toggle, 1}},
- {2082, {wxTreeCtrl, toggleItemSelection, 1}},
- {2083, {wxTreeCtrl, unselect, 0}},
- {2084, {wxTreeCtrl, unselectAll, 0}},
- {2085, {wxTreeCtrl, unselectItem, 1}},
- {2086, {wxScrollBar, new_0, 0}},
- {2087, {wxScrollBar, new_3, 3}},
- {2088, {wxScrollBar, destruct, 0}},
- {2089, {wxScrollBar, create, 3}},
- {2090, {wxScrollBar, getRange, 0}},
- {2091, {wxScrollBar, getPageSize, 0}},
- {2092, {wxScrollBar, getThumbPosition, 0}},
- {2093, {wxScrollBar, getThumbSize, 0}},
- {2094, {wxScrollBar, setThumbPosition, 1}},
- {2095, {wxScrollBar, setScrollbar, 5}},
- {2097, {wxSpinButton, new_2, 2}},
- {2098, {wxSpinButton, new_0, 0}},
- {2099, {wxSpinButton, create, 2}},
- {2100, {wxSpinButton, getMax, 0}},
- {2101, {wxSpinButton, getMin, 0}},
- {2102, {wxSpinButton, getValue, 0}},
- {2103, {wxSpinButton, setRange, 2}},
- {2104, {wxSpinButton, setValue, 1}},
- {2105, {wxSpinButton, 'Destroy', undefined}},
- {2106, {wxSpinCtrl, new_0, 0}},
- {2107, {wxSpinCtrl, new_2, 2}},
- {2109, {wxSpinCtrl, create, 2}},
- {2112, {wxSpinCtrl, setValue_1_1, 1}},
- {2113, {wxSpinCtrl, setValue_1_0, 1}},
- {2115, {wxSpinCtrl, getValue, 0}},
- {2117, {wxSpinCtrl, setRange, 2}},
- {2118, {wxSpinCtrl, setSelection, 2}},
- {2120, {wxSpinCtrl, getMin, 0}},
- {2122, {wxSpinCtrl, getMax, 0}},
- {2123, {wxSpinCtrl, 'Destroy', undefined}},
- {2124, {wxStaticText, new_0, 0}},
- {2125, {wxStaticText, new_4, 4}},
- {2126, {wxStaticText, create, 4}},
- {2127, {wxStaticText, getLabel, 0}},
- {2128, {wxStaticText, setLabel, 1}},
- {2129, {wxStaticText, wrap, 1}},
- {2130, {wxStaticText, 'Destroy', undefined}},
- {2131, {wxStaticBitmap, new_0, 0}},
- {2132, {wxStaticBitmap, new_4, 4}},
- {2133, {wxStaticBitmap, create, 4}},
- {2134, {wxStaticBitmap, getBitmap, 0}},
- {2135, {wxStaticBitmap, setBitmap, 1}},
- {2136, {wxStaticBitmap, 'Destroy', undefined}},
- {2137, {wxRadioBox, new, 7}},
- {2139, {wxRadioBox, destruct, 0}},
- {2140, {wxRadioBox, create, 7}},
- {2141, {wxRadioBox, enable_2, 2}},
- {2142, {wxRadioBox, enable_1, 1}},
- {2143, {wxRadioBox, getSelection, 0}},
- {2144, {wxRadioBox, getString, 1}},
- {2145, {wxRadioBox, setSelection, 1}},
- {2146, {wxRadioBox, show_2, 2}},
- {2147, {wxRadioBox, show_1, 1}},
- {2148, {wxRadioBox, getColumnCount, 0}},
- {2149, {wxRadioBox, getItemHelpText, 1}},
- {2150, {wxRadioBox, getItemToolTip, 1}},
- {2152, {wxRadioBox, getItemFromPoint, 1}},
- {2153, {wxRadioBox, getRowCount, 0}},
- {2154, {wxRadioBox, isItemEnabled, 1}},
- {2155, {wxRadioBox, isItemShown, 1}},
- {2156, {wxRadioBox, setItemHelpText, 2}},
- {2157, {wxRadioBox, setItemToolTip, 2}},
- {2158, {wxRadioButton, new_0, 0}},
- {2159, {wxRadioButton, new_4, 4}},
- {2160, {wxRadioButton, create, 4}},
- {2161, {wxRadioButton, getValue, 0}},
- {2162, {wxRadioButton, setValue, 1}},
- {2163, {wxRadioButton, 'Destroy', undefined}},
- {2165, {wxSlider, new_6, 6}},
- {2166, {wxSlider, new_0, 0}},
- {2167, {wxSlider, create, 6}},
- {2168, {wxSlider, getLineSize, 0}},
- {2169, {wxSlider, getMax, 0}},
- {2170, {wxSlider, getMin, 0}},
- {2171, {wxSlider, getPageSize, 0}},
- {2172, {wxSlider, getThumbLength, 0}},
- {2173, {wxSlider, getValue, 0}},
- {2174, {wxSlider, setLineSize, 1}},
- {2175, {wxSlider, setPageSize, 1}},
- {2176, {wxSlider, setRange, 2}},
- {2177, {wxSlider, setThumbLength, 1}},
- {2178, {wxSlider, setValue, 1}},
- {2179, {wxSlider, 'Destroy', undefined}},
- {2181, {wxDialog, new_4, 4}},
- {2182, {wxDialog, new_0, 0}},
- {2184, {wxDialog, destruct, 0}},
- {2185, {wxDialog, create, 4}},
- {2186, {wxDialog, createButtonSizer, 1}},
- {2187, {wxDialog, createStdDialogButtonSizer, 1}},
- {2188, {wxDialog, endModal, 1}},
- {2189, {wxDialog, getAffirmativeId, 0}},
- {2190, {wxDialog, getReturnCode, 0}},
- {2191, {wxDialog, isModal, 0}},
- {2192, {wxDialog, setAffirmativeId, 1}},
- {2193, {wxDialog, setReturnCode, 1}},
- {2194, {wxDialog, show, 1}},
- {2195, {wxDialog, showModal, 0}},
- {2196, {wxColourDialog, new_0, 0}},
- {2197, {wxColourDialog, new_2, 2}},
- {2198, {wxColourDialog, destruct, 0}},
- {2199, {wxColourDialog, create, 2}},
- {2200, {wxColourDialog, getColourData, 0}},
- {2201, {wxColourData, new_0, 0}},
- {2202, {wxColourData, new_1, 1}},
- {2203, {wxColourData, destruct, 0}},
- {2204, {wxColourData, getChooseFull, 0}},
- {2205, {wxColourData, getColour, 0}},
- {2207, {wxColourData, getCustomColour, 1}},
- {2208, {wxColourData, setChooseFull, 1}},
- {2209, {wxColourData, setColour, 1}},
- {2210, {wxColourData, setCustomColour, 2}},
- {2211, {wxPalette, new_0, 0}},
- {2212, {wxPalette, new_4, 4}},
- {2214, {wxPalette, destruct, 0}},
- {2215, {wxPalette, create, 4}},
- {2216, {wxPalette, getColoursCount, 0}},
- {2217, {wxPalette, getPixel, 3}},
- {2218, {wxPalette, getRGB, 4}},
- {2219, {wxPalette, isOk, 0}},
- {2223, {wxDirDialog, new, 2}},
- {2224, {wxDirDialog, destruct, 0}},
- {2225, {wxDirDialog, getPath, 0}},
- {2226, {wxDirDialog, getMessage, 0}},
- {2227, {wxDirDialog, setMessage, 1}},
- {2228, {wxDirDialog, setPath, 1}},
- {2232, {wxFileDialog, new, 2}},
- {2233, {wxFileDialog, destruct, 0}},
- {2234, {wxFileDialog, getDirectory, 0}},
- {2235, {wxFileDialog, getFilename, 0}},
- {2236, {wxFileDialog, getFilenames, 1}},
- {2237, {wxFileDialog, getFilterIndex, 0}},
- {2238, {wxFileDialog, getMessage, 0}},
- {2239, {wxFileDialog, getPath, 0}},
- {2240, {wxFileDialog, getPaths, 1}},
- {2241, {wxFileDialog, getWildcard, 0}},
- {2242, {wxFileDialog, setDirectory, 1}},
- {2243, {wxFileDialog, setFilename, 1}},
- {2244, {wxFileDialog, setFilterIndex, 1}},
- {2245, {wxFileDialog, setMessage, 1}},
- {2246, {wxFileDialog, setPath, 1}},
- {2247, {wxFileDialog, setWildcard, 1}},
- {2248, {wxPickerBase, setInternalMargin, 1}},
- {2249, {wxPickerBase, getInternalMargin, 0}},
- {2250, {wxPickerBase, setTextCtrlProportion, 1}},
- {2251, {wxPickerBase, setPickerCtrlProportion, 1}},
- {2252, {wxPickerBase, getTextCtrlProportion, 0}},
- {2253, {wxPickerBase, getPickerCtrlProportion, 0}},
- {2254, {wxPickerBase, hasTextCtrl, 0}},
- {2255, {wxPickerBase, getTextCtrl, 0}},
- {2256, {wxPickerBase, isTextCtrlGrowable, 0}},
- {2257, {wxPickerBase, setPickerCtrlGrowable, 1}},
- {2258, {wxPickerBase, setTextCtrlGrowable, 1}},
- {2259, {wxPickerBase, isPickerCtrlGrowable, 0}},
- {2260, {wxFilePickerCtrl, new_0, 0}},
- {2261, {wxFilePickerCtrl, new_3, 3}},
- {2262, {wxFilePickerCtrl, create, 3}},
- {2263, {wxFilePickerCtrl, getPath, 0}},
- {2264, {wxFilePickerCtrl, setPath, 1}},
- {2265, {wxFilePickerCtrl, 'Destroy', undefined}},
- {2266, {wxDirPickerCtrl, new_0, 0}},
- {2267, {wxDirPickerCtrl, new_3, 3}},
- {2268, {wxDirPickerCtrl, create, 3}},
- {2269, {wxDirPickerCtrl, getPath, 0}},
- {2270, {wxDirPickerCtrl, setPath, 1}},
- {2271, {wxDirPickerCtrl, 'Destroy', undefined}},
- {2272, {wxColourPickerCtrl, new_0, 0}},
- {2273, {wxColourPickerCtrl, new_3, 3}},
- {2274, {wxColourPickerCtrl, create, 3}},
- {2275, {wxColourPickerCtrl, getColour, 0}},
- {2276, {wxColourPickerCtrl, setColour_1_1, 1}},
- {2277, {wxColourPickerCtrl, setColour_1_0, 1}},
- {2278, {wxColourPickerCtrl, 'Destroy', undefined}},
- {2279, {wxDatePickerCtrl, new_0, 0}},
- {2280, {wxDatePickerCtrl, new_3, 3}},
- {2281, {wxDatePickerCtrl, getRange, 2}},
- {2282, {wxDatePickerCtrl, getValue, 0}},
- {2283, {wxDatePickerCtrl, setRange, 2}},
- {2284, {wxDatePickerCtrl, setValue, 1}},
- {2285, {wxDatePickerCtrl, 'Destroy', undefined}},
- {2286, {wxFontPickerCtrl, new_0, 0}},
- {2287, {wxFontPickerCtrl, new_3, 3}},
- {2288, {wxFontPickerCtrl, create, 3}},
- {2289, {wxFontPickerCtrl, getSelectedFont, 0}},
- {2290, {wxFontPickerCtrl, setSelectedFont, 1}},
- {2291, {wxFontPickerCtrl, getMaxPointSize, 0}},
- {2292, {wxFontPickerCtrl, setMaxPointSize, 1}},
- {2293, {wxFontPickerCtrl, 'Destroy', undefined}},
- {2296, {wxFindReplaceDialog, new_0, 0}},
- {2297, {wxFindReplaceDialog, new_4, 4}},
- {2298, {wxFindReplaceDialog, destruct, 0}},
- {2299, {wxFindReplaceDialog, create, 4}},
- {2300, {wxFindReplaceDialog, getData, 0}},
- {2301, {wxFindReplaceData, new_0, 0}},
- {2302, {wxFindReplaceData, new_1, 1}},
- {2303, {wxFindReplaceData, getFindString, 0}},
- {2304, {wxFindReplaceData, getReplaceString, 0}},
- {2305, {wxFindReplaceData, getFlags, 0}},
- {2306, {wxFindReplaceData, setFlags, 1}},
- {2307, {wxFindReplaceData, setFindString, 1}},
- {2308, {wxFindReplaceData, setReplaceString, 1}},
- {2309, {wxFindReplaceData, 'Destroy', undefined}},
- {2310, {wxMultiChoiceDialog, new_0, 0}},
- {2312, {wxMultiChoiceDialog, new_5, 5}},
- {2313, {wxMultiChoiceDialog, getSelections, 0}},
- {2314, {wxMultiChoiceDialog, setSelections, 1}},
- {2315, {wxMultiChoiceDialog, 'Destroy', undefined}},
- {2316, {wxSingleChoiceDialog, new_0, 0}},
- {2318, {wxSingleChoiceDialog, new_5, 5}},
- {2319, {wxSingleChoiceDialog, getSelection, 0}},
- {2320, {wxSingleChoiceDialog, getStringSelection, 0}},
- {2321, {wxSingleChoiceDialog, setSelection, 1}},
- {2322, {wxSingleChoiceDialog, 'Destroy', undefined}},
- {2323, {wxTextEntryDialog, new, 3}},
- {2324, {wxTextEntryDialog, getValue, 0}},
- {2325, {wxTextEntryDialog, setValue, 1}},
- {2326, {wxTextEntryDialog, 'Destroy', undefined}},
- {2327, {wxPasswordEntryDialog, new, 3}},
- {2328, {wxPasswordEntryDialog, 'Destroy', undefined}},
- {2329, {wxFontData, new_0, 0}},
- {2330, {wxFontData, new_1, 1}},
- {2331, {wxFontData, destruct, 0}},
- {2332, {wxFontData, enableEffects, 1}},
- {2333, {wxFontData, getAllowSymbols, 0}},
- {2334, {wxFontData, getColour, 0}},
- {2335, {wxFontData, getChosenFont, 0}},
- {2336, {wxFontData, getEnableEffects, 0}},
- {2337, {wxFontData, getInitialFont, 0}},
- {2338, {wxFontData, getShowHelp, 0}},
- {2339, {wxFontData, setAllowSymbols, 1}},
- {2340, {wxFontData, setChosenFont, 1}},
- {2341, {wxFontData, setColour, 1}},
- {2342, {wxFontData, setInitialFont, 1}},
- {2343, {wxFontData, setRange, 2}},
- {2344, {wxFontData, setShowHelp, 1}},
- {2348, {wxFontDialog, new_0, 0}},
- {2350, {wxFontDialog, new_2, 2}},
- {2352, {wxFontDialog, create, 2}},
- {2353, {wxFontDialog, getFontData, 0}},
- {2355, {wxFontDialog, 'Destroy', undefined}},
- {2356, {wxProgressDialog, new, 3}},
- {2357, {wxProgressDialog, destruct, 0}},
- {2358, {wxProgressDialog, resume, 0}},
- {2359, {wxProgressDialog, update_2, 2}},
- {2360, {wxProgressDialog, update_0, 0}},
- {2361, {wxMessageDialog, new, 3}},
- {2362, {wxMessageDialog, destruct, 0}},
- {2363, {wxPageSetupDialog, new, 2}},
- {2364, {wxPageSetupDialog, destruct, 0}},
- {2365, {wxPageSetupDialog, getPageSetupData, 0}},
- {2366, {wxPageSetupDialog, showModal, 0}},
- {2367, {wxPageSetupDialogData, new_0, 0}},
- {2368, {wxPageSetupDialogData, new_1_0, 1}},
- {2369, {wxPageSetupDialogData, new_1_1, 1}},
- {2370, {wxPageSetupDialogData, destruct, 0}},
- {2371, {wxPageSetupDialogData, enableHelp, 1}},
- {2372, {wxPageSetupDialogData, enableMargins, 1}},
- {2373, {wxPageSetupDialogData, enableOrientation, 1}},
- {2374, {wxPageSetupDialogData, enablePaper, 1}},
- {2375, {wxPageSetupDialogData, enablePrinter, 1}},
- {2376, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
- {2377, {wxPageSetupDialogData, getEnableMargins, 0}},
- {2378, {wxPageSetupDialogData, getEnableOrientation, 0}},
- {2379, {wxPageSetupDialogData, getEnablePaper, 0}},
- {2380, {wxPageSetupDialogData, getEnablePrinter, 0}},
- {2381, {wxPageSetupDialogData, getEnableHelp, 0}},
- {2382, {wxPageSetupDialogData, getDefaultInfo, 0}},
- {2383, {wxPageSetupDialogData, getMarginTopLeft, 0}},
- {2384, {wxPageSetupDialogData, getMarginBottomRight, 0}},
- {2385, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
- {2386, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
- {2387, {wxPageSetupDialogData, getPaperId, 0}},
- {2388, {wxPageSetupDialogData, getPaperSize, 0}},
- {2390, {wxPageSetupDialogData, getPrintData, 0}},
- {2391, {wxPageSetupDialogData, isOk, 0}},
- {2392, {wxPageSetupDialogData, setDefaultInfo, 1}},
- {2393, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
- {2394, {wxPageSetupDialogData, setMarginTopLeft, 1}},
- {2395, {wxPageSetupDialogData, setMarginBottomRight, 1}},
- {2396, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
- {2397, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
- {2398, {wxPageSetupDialogData, setPaperId, 1}},
- {2399, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
- {2400, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
- {2401, {wxPageSetupDialogData, setPrintData, 1}},
- {2402, {wxPrintDialog, new_2_0, 2}},
- {2403, {wxPrintDialog, new_2_1, 2}},
- {2404, {wxPrintDialog, destruct, 0}},
- {2405, {wxPrintDialog, getPrintDialogData, 0}},
- {2406, {wxPrintDialog, getPrintDC, 0}},
- {2407, {wxPrintDialogData, new_0, 0}},
- {2408, {wxPrintDialogData, new_1_1, 1}},
- {2409, {wxPrintDialogData, new_1_0, 1}},
- {2410, {wxPrintDialogData, destruct, 0}},
- {2411, {wxPrintDialogData, enableHelp, 1}},
- {2412, {wxPrintDialogData, enablePageNumbers, 1}},
- {2413, {wxPrintDialogData, enablePrintToFile, 1}},
- {2414, {wxPrintDialogData, enableSelection, 1}},
- {2415, {wxPrintDialogData, getAllPages, 0}},
- {2416, {wxPrintDialogData, getCollate, 0}},
- {2417, {wxPrintDialogData, getFromPage, 0}},
- {2418, {wxPrintDialogData, getMaxPage, 0}},
- {2419, {wxPrintDialogData, getMinPage, 0}},
- {2420, {wxPrintDialogData, getNoCopies, 0}},
- {2421, {wxPrintDialogData, getPrintData, 0}},
- {2422, {wxPrintDialogData, getPrintToFile, 0}},
- {2423, {wxPrintDialogData, getSelection, 0}},
- {2424, {wxPrintDialogData, getToPage, 0}},
- {2425, {wxPrintDialogData, isOk, 0}},
- {2426, {wxPrintDialogData, setCollate, 1}},
- {2427, {wxPrintDialogData, setFromPage, 1}},
- {2428, {wxPrintDialogData, setMaxPage, 1}},
- {2429, {wxPrintDialogData, setMinPage, 1}},
- {2430, {wxPrintDialogData, setNoCopies, 1}},
- {2431, {wxPrintDialogData, setPrintData, 1}},
- {2432, {wxPrintDialogData, setPrintToFile, 1}},
- {2433, {wxPrintDialogData, setSelection, 1}},
- {2434, {wxPrintDialogData, setToPage, 1}},
- {2435, {wxPrintData, new_0, 0}},
- {2436, {wxPrintData, new_1, 1}},
- {2437, {wxPrintData, destruct, 0}},
- {2438, {wxPrintData, getCollate, 0}},
- {2439, {wxPrintData, getBin, 0}},
- {2440, {wxPrintData, getColour, 0}},
- {2441, {wxPrintData, getDuplex, 0}},
- {2442, {wxPrintData, getNoCopies, 0}},
- {2443, {wxPrintData, getOrientation, 0}},
- {2444, {wxPrintData, getPaperId, 0}},
- {2445, {wxPrintData, getPrinterName, 0}},
- {2446, {wxPrintData, getQuality, 0}},
- {2447, {wxPrintData, isOk, 0}},
- {2448, {wxPrintData, setBin, 1}},
- {2449, {wxPrintData, setCollate, 1}},
- {2450, {wxPrintData, setColour, 1}},
- {2451, {wxPrintData, setDuplex, 1}},
- {2452, {wxPrintData, setNoCopies, 1}},
- {2453, {wxPrintData, setOrientation, 1}},
- {2454, {wxPrintData, setPaperId, 1}},
- {2455, {wxPrintData, setPrinterName, 1}},
- {2456, {wxPrintData, setQuality, 1}},
- {2459, {wxPrintPreview, new_2, 2}},
- {2460, {wxPrintPreview, new_3, 3}},
- {2462, {wxPrintPreview, destruct, 0}},
- {2463, {wxPrintPreview, getCanvas, 0}},
- {2464, {wxPrintPreview, getCurrentPage, 0}},
- {2465, {wxPrintPreview, getFrame, 0}},
- {2466, {wxPrintPreview, getMaxPage, 0}},
- {2467, {wxPrintPreview, getMinPage, 0}},
- {2468, {wxPrintPreview, getPrintout, 0}},
- {2469, {wxPrintPreview, getPrintoutForPrinting, 0}},
- {2470, {wxPrintPreview, isOk, 0}},
- {2471, {wxPrintPreview, paintPage, 2}},
- {2472, {wxPrintPreview, print, 1}},
- {2473, {wxPrintPreview, renderPage, 1}},
- {2474, {wxPrintPreview, setCanvas, 1}},
- {2475, {wxPrintPreview, setCurrentPage, 1}},
- {2476, {wxPrintPreview, setFrame, 1}},
- {2477, {wxPrintPreview, setPrintout, 1}},
- {2478, {wxPrintPreview, setZoom, 1}},
- {2479, {wxPreviewFrame, new, 3}},
- {2480, {wxPreviewFrame, destruct, 0}},
- {2481, {wxPreviewFrame, createControlBar, 0}},
- {2482, {wxPreviewFrame, createCanvas, 0}},
- {2483, {wxPreviewFrame, initialize, 0}},
- {2484, {wxPreviewFrame, onCloseWindow, 1}},
- {2485, {wxPreviewControlBar, new, 4}},
- {2486, {wxPreviewControlBar, destruct, 0}},
- {2487, {wxPreviewControlBar, createButtons, 0}},
- {2488, {wxPreviewControlBar, getPrintPreview, 0}},
- {2489, {wxPreviewControlBar, getZoomControl, 0}},
- {2490, {wxPreviewControlBar, setZoomControl, 1}},
- {2492, {wxPrinter, new, 1}},
- {2493, {wxPrinter, createAbortWindow, 2}},
- {2494, {wxPrinter, getAbort, 0}},
- {2495, {wxPrinter, getLastError, 0}},
- {2496, {wxPrinter, getPrintDialogData, 0}},
- {2497, {wxPrinter, print, 3}},
- {2498, {wxPrinter, printDialog, 1}},
- {2499, {wxPrinter, reportError, 3}},
- {2500, {wxPrinter, setup, 1}},
- {2501, {wxPrinter, 'Destroy', undefined}},
- {2502, {wxXmlResource, new_1, 1}},
- {2503, {wxXmlResource, new_2, 2}},
- {2504, {wxXmlResource, destruct, 0}},
- {2505, {wxXmlResource, attachUnknownControl, 3}},
- {2506, {wxXmlResource, clearHandlers, 0}},
- {2507, {wxXmlResource, compareVersion, 4}},
- {2508, {wxXmlResource, get, 0}},
- {2509, {wxXmlResource, getFlags, 0}},
- {2510, {wxXmlResource, getVersion, 0}},
- {2511, {wxXmlResource, getXRCID, 2}},
- {2512, {wxXmlResource, initAllHandlers, 0}},
- {2513, {wxXmlResource, load, 1}},
- {2514, {wxXmlResource, loadBitmap, 1}},
- {2515, {wxXmlResource, loadDialog_2, 2}},
- {2516, {wxXmlResource, loadDialog_3, 3}},
- {2517, {wxXmlResource, loadFrame_2, 2}},
- {2518, {wxXmlResource, loadFrame_3, 3}},
- {2519, {wxXmlResource, loadIcon, 1}},
- {2520, {wxXmlResource, loadMenu, 1}},
- {2521, {wxXmlResource, loadMenuBar_2, 2}},
- {2522, {wxXmlResource, loadMenuBar_1, 1}},
- {2523, {wxXmlResource, loadPanel_2, 2}},
- {2524, {wxXmlResource, loadPanel_3, 3}},
- {2525, {wxXmlResource, loadToolBar, 2}},
- {2526, {wxXmlResource, set, 1}},
- {2527, {wxXmlResource, setFlags, 1}},
- {2528, {wxXmlResource, unload, 1}},
- {2529, {wxXmlResource, xrcctrl, 3}},
- {2530, {wxHtmlEasyPrinting, new, 1}},
- {2531, {wxHtmlEasyPrinting, destruct, 0}},
- {2532, {wxHtmlEasyPrinting, getPrintData, 0}},
- {2533, {wxHtmlEasyPrinting, getPageSetupData, 0}},
- {2534, {wxHtmlEasyPrinting, previewFile, 1}},
- {2535, {wxHtmlEasyPrinting, previewText, 2}},
- {2536, {wxHtmlEasyPrinting, printFile, 1}},
- {2537, {wxHtmlEasyPrinting, printText, 2}},
- {2538, {wxHtmlEasyPrinting, pageSetup, 0}},
- {2539, {wxHtmlEasyPrinting, setFonts, 3}},
- {2540, {wxHtmlEasyPrinting, setHeader, 2}},
- {2541, {wxHtmlEasyPrinting, setFooter, 2}},
- {2543, {wxGLCanvas, new_2, 2}},
- {2544, {wxGLCanvas, new_3_1, 3}},
- {2545, {wxGLCanvas, new_3_0, 3}},
- {2546, {wxGLCanvas, getContext, 0}},
- {2548, {wxGLCanvas, setCurrent, 0}},
- {2549, {wxGLCanvas, swapBuffers, 0}},
- {2550, {wxGLCanvas, 'Destroy', undefined}},
- {2551, {wxAuiManager, new, 1}},
- {2552, {wxAuiManager, destruct, 0}},
- {2553, {wxAuiManager, addPane_2_1, 2}},
- {2554, {wxAuiManager, addPane_3, 3}},
- {2555, {wxAuiManager, addPane_2_0, 2}},
- {2556, {wxAuiManager, detachPane, 1}},
- {2557, {wxAuiManager, getAllPanes, 0}},
- {2558, {wxAuiManager, getArtProvider, 0}},
- {2559, {wxAuiManager, getDockSizeConstraint, 2}},
- {2560, {wxAuiManager, getFlags, 0}},
- {2561, {wxAuiManager, getManagedWindow, 0}},
- {2562, {wxAuiManager, getManager, 1}},
- {2563, {wxAuiManager, getPane_1_1, 1}},
- {2564, {wxAuiManager, getPane_1_0, 1}},
- {2565, {wxAuiManager, hideHint, 0}},
- {2566, {wxAuiManager, insertPane, 3}},
- {2567, {wxAuiManager, loadPaneInfo, 2}},
- {2568, {wxAuiManager, loadPerspective, 2}},
- {2569, {wxAuiManager, savePaneInfo, 1}},
- {2570, {wxAuiManager, savePerspective, 0}},
- {2571, {wxAuiManager, setArtProvider, 1}},
- {2572, {wxAuiManager, setDockSizeConstraint, 2}},
- {2573, {wxAuiManager, setFlags, 1}},
- {2574, {wxAuiManager, setManagedWindow, 1}},
- {2575, {wxAuiManager, showHint, 1}},
- {2576, {wxAuiManager, unInit, 0}},
- {2577, {wxAuiManager, update, 0}},
- {2578, {wxAuiPaneInfo, new_0, 0}},
- {2579, {wxAuiPaneInfo, new_1, 1}},
- {2580, {wxAuiPaneInfo, destruct, 0}},
- {2581, {wxAuiPaneInfo, bestSize_1, 1}},
- {2582, {wxAuiPaneInfo, bestSize_2, 2}},
- {2583, {wxAuiPaneInfo, bottom, 0}},
- {2584, {wxAuiPaneInfo, bottomDockable, 1}},
- {2585, {wxAuiPaneInfo, caption, 1}},
- {2586, {wxAuiPaneInfo, captionVisible, 1}},
- {2587, {wxAuiPaneInfo, centre, 0}},
- {2588, {wxAuiPaneInfo, centrePane, 0}},
- {2589, {wxAuiPaneInfo, closeButton, 1}},
- {2590, {wxAuiPaneInfo, defaultPane, 0}},
- {2591, {wxAuiPaneInfo, destroyOnClose, 1}},
- {2592, {wxAuiPaneInfo, direction, 1}},
- {2593, {wxAuiPaneInfo, dock, 0}},
- {2594, {wxAuiPaneInfo, dockable, 1}},
- {2595, {wxAuiPaneInfo, fixed, 0}},
- {2596, {wxAuiPaneInfo, float, 0}},
- {2597, {wxAuiPaneInfo, floatable, 1}},
- {2598, {wxAuiPaneInfo, floatingPosition_1, 1}},
- {2599, {wxAuiPaneInfo, floatingPosition_2, 2}},
- {2600, {wxAuiPaneInfo, floatingSize_1, 1}},
- {2601, {wxAuiPaneInfo, floatingSize_2, 2}},
- {2602, {wxAuiPaneInfo, gripper, 1}},
- {2603, {wxAuiPaneInfo, gripperTop, 1}},
- {2604, {wxAuiPaneInfo, hasBorder, 0}},
- {2605, {wxAuiPaneInfo, hasCaption, 0}},
- {2606, {wxAuiPaneInfo, hasCloseButton, 0}},
- {2607, {wxAuiPaneInfo, hasFlag, 1}},
- {2608, {wxAuiPaneInfo, hasGripper, 0}},
- {2609, {wxAuiPaneInfo, hasGripperTop, 0}},
- {2610, {wxAuiPaneInfo, hasMaximizeButton, 0}},
- {2611, {wxAuiPaneInfo, hasMinimizeButton, 0}},
- {2612, {wxAuiPaneInfo, hasPinButton, 0}},
- {2613, {wxAuiPaneInfo, hide, 0}},
- {2614, {wxAuiPaneInfo, isBottomDockable, 0}},
- {2615, {wxAuiPaneInfo, isDocked, 0}},
- {2616, {wxAuiPaneInfo, isFixed, 0}},
- {2617, {wxAuiPaneInfo, isFloatable, 0}},
- {2618, {wxAuiPaneInfo, isFloating, 0}},
- {2619, {wxAuiPaneInfo, isLeftDockable, 0}},
- {2620, {wxAuiPaneInfo, isMovable, 0}},
- {2621, {wxAuiPaneInfo, isOk, 0}},
- {2622, {wxAuiPaneInfo, isResizable, 0}},
- {2623, {wxAuiPaneInfo, isRightDockable, 0}},
- {2624, {wxAuiPaneInfo, isShown, 0}},
- {2625, {wxAuiPaneInfo, isToolbar, 0}},
- {2626, {wxAuiPaneInfo, isTopDockable, 0}},
- {2627, {wxAuiPaneInfo, layer, 1}},
- {2628, {wxAuiPaneInfo, left, 0}},
- {2629, {wxAuiPaneInfo, leftDockable, 1}},
- {2630, {wxAuiPaneInfo, maxSize_1, 1}},
- {2631, {wxAuiPaneInfo, maxSize_2, 2}},
- {2632, {wxAuiPaneInfo, maximizeButton, 1}},
- {2633, {wxAuiPaneInfo, minSize_1, 1}},
- {2634, {wxAuiPaneInfo, minSize_2, 2}},
- {2635, {wxAuiPaneInfo, minimizeButton, 1}},
- {2636, {wxAuiPaneInfo, movable, 1}},
- {2637, {wxAuiPaneInfo, name, 1}},
- {2638, {wxAuiPaneInfo, paneBorder, 1}},
- {2639, {wxAuiPaneInfo, pinButton, 1}},
- {2640, {wxAuiPaneInfo, position, 1}},
- {2641, {wxAuiPaneInfo, resizable, 1}},
- {2642, {wxAuiPaneInfo, right, 0}},
- {2643, {wxAuiPaneInfo, rightDockable, 1}},
- {2644, {wxAuiPaneInfo, row, 1}},
- {2645, {wxAuiPaneInfo, safeSet, 1}},
- {2646, {wxAuiPaneInfo, setFlag, 2}},
- {2647, {wxAuiPaneInfo, show, 1}},
- {2648, {wxAuiPaneInfo, toolbarPane, 0}},
- {2649, {wxAuiPaneInfo, top, 0}},
- {2650, {wxAuiPaneInfo, topDockable, 1}},
- {2651, {wxAuiPaneInfo, window, 1}},
- {2652, {wxAuiNotebook, new_0, 0}},
- {2653, {wxAuiNotebook, new_2, 2}},
- {2654, {wxAuiNotebook, addPage, 3}},
- {2655, {wxAuiNotebook, create, 2}},
- {2656, {wxAuiNotebook, deletePage, 1}},
- {2657, {wxAuiNotebook, getArtProvider, 0}},
- {2658, {wxAuiNotebook, getPage, 1}},
- {2659, {wxAuiNotebook, getPageBitmap, 1}},
- {2660, {wxAuiNotebook, getPageCount, 0}},
- {2661, {wxAuiNotebook, getPageIndex, 1}},
- {2662, {wxAuiNotebook, getPageText, 1}},
- {2663, {wxAuiNotebook, getSelection, 0}},
- {2664, {wxAuiNotebook, insertPage, 4}},
- {2665, {wxAuiNotebook, removePage, 1}},
- {2666, {wxAuiNotebook, setArtProvider, 1}},
- {2667, {wxAuiNotebook, setFont, 1}},
- {2668, {wxAuiNotebook, setPageBitmap, 2}},
- {2669, {wxAuiNotebook, setPageText, 2}},
- {2670, {wxAuiNotebook, setSelection, 1}},
- {2671, {wxAuiNotebook, setTabCtrlHeight, 1}},
- {2672, {wxAuiNotebook, setUniformBitmapSize, 1}},
- {2673, {wxAuiNotebook, 'Destroy', undefined}},
- {2674, {wxMDIParentFrame, new_0, 0}},
- {2675, {wxMDIParentFrame, new_4, 4}},
- {2676, {wxMDIParentFrame, destruct, 0}},
- {2677, {wxMDIParentFrame, activateNext, 0}},
- {2678, {wxMDIParentFrame, activatePrevious, 0}},
- {2679, {wxMDIParentFrame, arrangeIcons, 0}},
- {2680, {wxMDIParentFrame, cascade, 0}},
- {2681, {wxMDIParentFrame, create, 4}},
- {2682, {wxMDIParentFrame, getActiveChild, 0}},
- {2683, {wxMDIParentFrame, getClientWindow, 0}},
- {2684, {wxMDIParentFrame, tile, 1}},
- {2685, {wxMDIChildFrame, new_0, 0}},
- {2686, {wxMDIChildFrame, new_4, 4}},
- {2687, {wxMDIChildFrame, destruct, 0}},
- {2688, {wxMDIChildFrame, activate, 0}},
- {2689, {wxMDIChildFrame, create, 4}},
- {2690, {wxMDIChildFrame, maximize, 1}},
- {2691, {wxMDIChildFrame, restore, 0}},
- {2692, {wxMDIClientWindow, new_0, 0}},
- {2693, {wxMDIClientWindow, new_2, 2}},
- {2694, {wxMDIClientWindow, destruct, 0}},
- {2695, {wxMDIClientWindow, createClient, 2}},
- {2696, {wxLayoutAlgorithm, new, 0}},
- {2697, {wxLayoutAlgorithm, layoutFrame, 2}},
- {2698, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
- {2699, {wxLayoutAlgorithm, layoutWindow, 2}},
- {2700, {wxLayoutAlgorithm, 'Destroy', undefined}},
- {2701, {wxEvent, getId, 0}},
- {2702, {wxEvent, getSkipped, 0}},
- {2703, {wxEvent, getTimestamp, 0}},
- {2704, {wxEvent, isCommandEvent, 0}},
- {2705, {wxEvent, resumePropagation, 1}},
- {2706, {wxEvent, shouldPropagate, 0}},
- {2707, {wxEvent, skip, 1}},
- {2708, {wxEvent, stopPropagation, 0}},
- {2709, {wxCommandEvent, getClientData, 0}},
- {2710, {wxCommandEvent, getExtraLong, 0}},
- {2711, {wxCommandEvent, getInt, 0}},
- {2712, {wxCommandEvent, getSelection, 0}},
- {2713, {wxCommandEvent, getString, 0}},
- {2714, {wxCommandEvent, isChecked, 0}},
- {2715, {wxCommandEvent, isSelection, 0}},
- {2716, {wxCommandEvent, setInt, 1}},
- {2717, {wxCommandEvent, setString, 1}},
- {2718, {wxScrollEvent, getOrientation, 0}},
- {2719, {wxScrollEvent, getPosition, 0}},
- {2720, {wxScrollWinEvent, getOrientation, 0}},
- {2721, {wxScrollWinEvent, getPosition, 0}},
- {2722, {wxMouseEvent, altDown, 0}},
- {2723, {wxMouseEvent, button, 1}},
- {2724, {wxMouseEvent, buttonDClick, 1}},
- {2725, {wxMouseEvent, buttonDown, 1}},
- {2726, {wxMouseEvent, buttonUp, 1}},
- {2727, {wxMouseEvent, cmdDown, 0}},
- {2728, {wxMouseEvent, controlDown, 0}},
- {2729, {wxMouseEvent, dragging, 0}},
- {2730, {wxMouseEvent, entering, 0}},
- {2731, {wxMouseEvent, getButton, 0}},
- {2734, {wxMouseEvent, getPosition, 0}},
- {2735, {wxMouseEvent, getLogicalPosition, 1}},
- {2736, {wxMouseEvent, getLinesPerAction, 0}},
- {2737, {wxMouseEvent, getWheelRotation, 0}},
- {2738, {wxMouseEvent, getWheelDelta, 0}},
- {2739, {wxMouseEvent, getX, 0}},
- {2740, {wxMouseEvent, getY, 0}},
- {2741, {wxMouseEvent, isButton, 0}},
- {2742, {wxMouseEvent, isPageScroll, 0}},
- {2743, {wxMouseEvent, leaving, 0}},
- {2744, {wxMouseEvent, leftDClick, 0}},
- {2745, {wxMouseEvent, leftDown, 0}},
- {2746, {wxMouseEvent, leftIsDown, 0}},
- {2747, {wxMouseEvent, leftUp, 0}},
- {2748, {wxMouseEvent, metaDown, 0}},
- {2749, {wxMouseEvent, middleDClick, 0}},
- {2750, {wxMouseEvent, middleDown, 0}},
- {2751, {wxMouseEvent, middleIsDown, 0}},
- {2752, {wxMouseEvent, middleUp, 0}},
- {2753, {wxMouseEvent, moving, 0}},
- {2754, {wxMouseEvent, rightDClick, 0}},
- {2755, {wxMouseEvent, rightDown, 0}},
- {2756, {wxMouseEvent, rightIsDown, 0}},
- {2757, {wxMouseEvent, rightUp, 0}},
- {2758, {wxMouseEvent, shiftDown, 0}},
- {2759, {wxSetCursorEvent, getCursor, 0}},
- {2760, {wxSetCursorEvent, getX, 0}},
- {2761, {wxSetCursorEvent, getY, 0}},
- {2762, {wxSetCursorEvent, hasCursor, 0}},
- {2763, {wxSetCursorEvent, setCursor, 1}},
- {2764, {wxKeyEvent, altDown, 0}},
- {2765, {wxKeyEvent, cmdDown, 0}},
- {2766, {wxKeyEvent, controlDown, 0}},
- {2767, {wxKeyEvent, getKeyCode, 0}},
- {2768, {wxKeyEvent, getModifiers, 0}},
- {2771, {wxKeyEvent, getPosition, 0}},
- {2772, {wxKeyEvent, getRawKeyCode, 0}},
- {2773, {wxKeyEvent, getRawKeyFlags, 0}},
- {2774, {wxKeyEvent, getUnicodeKey, 0}},
- {2775, {wxKeyEvent, getX, 0}},
- {2776, {wxKeyEvent, getY, 0}},
- {2777, {wxKeyEvent, hasModifiers, 0}},
- {2778, {wxKeyEvent, metaDown, 0}},
- {2779, {wxKeyEvent, shiftDown, 0}},
- {2780, {wxSizeEvent, getSize, 0}},
- {2781, {wxMoveEvent, getPosition, 0}},
- {2782, {wxEraseEvent, getDC, 0}},
- {2783, {wxFocusEvent, getWindow, 0}},
- {2784, {wxChildFocusEvent, getWindow, 0}},
- {2785, {wxMenuEvent, getMenu, 0}},
- {2786, {wxMenuEvent, getMenuId, 0}},
- {2787, {wxMenuEvent, isPopup, 0}},
- {2788, {wxCloseEvent, canVeto, 0}},
- {2789, {wxCloseEvent, getLoggingOff, 0}},
- {2790, {wxCloseEvent, setCanVeto, 1}},
- {2791, {wxCloseEvent, setLoggingOff, 1}},
- {2792, {wxCloseEvent, veto, 1}},
- {2793, {wxShowEvent, setShow, 1}},
- {2794, {wxShowEvent, getShow, 0}},
- {2795, {wxIconizeEvent, iconized, 0}},
- {2796, {wxJoystickEvent, buttonDown, 1}},
- {2797, {wxJoystickEvent, buttonIsDown, 1}},
- {2798, {wxJoystickEvent, buttonUp, 1}},
- {2799, {wxJoystickEvent, getButtonChange, 0}},
- {2800, {wxJoystickEvent, getButtonState, 0}},
- {2801, {wxJoystickEvent, getJoystick, 0}},
- {2802, {wxJoystickEvent, getPosition, 0}},
- {2803, {wxJoystickEvent, getZPosition, 0}},
- {2804, {wxJoystickEvent, isButton, 0}},
- {2805, {wxJoystickEvent, isMove, 0}},
- {2806, {wxJoystickEvent, isZMove, 0}},
- {2807, {wxUpdateUIEvent, canUpdate, 1}},
- {2808, {wxUpdateUIEvent, check, 1}},
- {2809, {wxUpdateUIEvent, enable, 1}},
- {2810, {wxUpdateUIEvent, show, 1}},
- {2811, {wxUpdateUIEvent, getChecked, 0}},
- {2812, {wxUpdateUIEvent, getEnabled, 0}},
- {2813, {wxUpdateUIEvent, getShown, 0}},
- {2814, {wxUpdateUIEvent, getSetChecked, 0}},
- {2815, {wxUpdateUIEvent, getSetEnabled, 0}},
- {2816, {wxUpdateUIEvent, getSetShown, 0}},
- {2817, {wxUpdateUIEvent, getSetText, 0}},
- {2818, {wxUpdateUIEvent, getText, 0}},
- {2819, {wxUpdateUIEvent, getMode, 0}},
- {2820, {wxUpdateUIEvent, getUpdateInterval, 0}},
- {2821, {wxUpdateUIEvent, resetUpdateTime, 0}},
- {2822, {wxUpdateUIEvent, setMode, 1}},
- {2823, {wxUpdateUIEvent, setText, 1}},
- {2824, {wxUpdateUIEvent, setUpdateInterval, 1}},
- {2825, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
- {2826, {wxPaletteChangedEvent, setChangedWindow, 1}},
- {2827, {wxPaletteChangedEvent, getChangedWindow, 0}},
- {2828, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
- {2829, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
- {2830, {wxNavigationKeyEvent, getDirection, 0}},
- {2831, {wxNavigationKeyEvent, setDirection, 1}},
- {2832, {wxNavigationKeyEvent, isWindowChange, 0}},
- {2833, {wxNavigationKeyEvent, setWindowChange, 1}},
- {2834, {wxNavigationKeyEvent, isFromTab, 0}},
- {2835, {wxNavigationKeyEvent, setFromTab, 1}},
- {2836, {wxNavigationKeyEvent, getCurrentFocus, 0}},
- {2837, {wxNavigationKeyEvent, setCurrentFocus, 1}},
- {2838, {wxHelpEvent, getOrigin, 0}},
- {2839, {wxHelpEvent, getPosition, 0}},
- {2840, {wxHelpEvent, setOrigin, 1}},
- {2841, {wxHelpEvent, setPosition, 1}},
- {2842, {wxContextMenuEvent, getPosition, 0}},
- {2843, {wxContextMenuEvent, setPosition, 1}},
- {2844, {wxIdleEvent, canSend, 1}},
- {2845, {wxIdleEvent, getMode, 0}},
- {2846, {wxIdleEvent, requestMore, 1}},
- {2847, {wxIdleEvent, moreRequested, 0}},
- {2848, {wxIdleEvent, setMode, 1}},
- {2849, {wxGridEvent, altDown, 0}},
- {2850, {wxGridEvent, controlDown, 0}},
- {2851, {wxGridEvent, getCol, 0}},
- {2852, {wxGridEvent, getPosition, 0}},
- {2853, {wxGridEvent, getRow, 0}},
- {2854, {wxGridEvent, metaDown, 0}},
- {2855, {wxGridEvent, selecting, 0}},
- {2856, {wxGridEvent, shiftDown, 0}},
- {2857, {wxNotifyEvent, allow, 0}},
- {2858, {wxNotifyEvent, isAllowed, 0}},
- {2859, {wxNotifyEvent, veto, 0}},
- {2860, {wxSashEvent, getEdge, 0}},
- {2861, {wxSashEvent, getDragRect, 0}},
- {2862, {wxSashEvent, getDragStatus, 0}},
- {2863, {wxListEvent, getCacheFrom, 0}},
- {2864, {wxListEvent, getCacheTo, 0}},
- {2865, {wxListEvent, getKeyCode, 0}},
- {2866, {wxListEvent, getIndex, 0}},
- {2867, {wxListEvent, getColumn, 0}},
- {2868, {wxListEvent, getPoint, 0}},
- {2869, {wxListEvent, getLabel, 0}},
- {2870, {wxListEvent, getText, 0}},
- {2871, {wxListEvent, getImage, 0}},
- {2872, {wxListEvent, getData, 0}},
- {2873, {wxListEvent, getMask, 0}},
- {2874, {wxListEvent, getItem, 0}},
- {2875, {wxListEvent, isEditCancelled, 0}},
- {2876, {wxDateEvent, getDate, 0}},
- {2877, {wxCalendarEvent, getWeekDay, 0}},
- {2878, {wxFileDirPickerEvent, getPath, 0}},
- {2879, {wxColourPickerEvent, getColour, 0}},
- {2880, {wxFontPickerEvent, getFont, 0}},
- {2881, {wxStyledTextEvent, getPosition, 0}},
- {2882, {wxStyledTextEvent, getKey, 0}},
- {2883, {wxStyledTextEvent, getModifiers, 0}},
- {2884, {wxStyledTextEvent, getModificationType, 0}},
- {2885, {wxStyledTextEvent, getText, 0}},
- {2886, {wxStyledTextEvent, getLength, 0}},
- {2887, {wxStyledTextEvent, getLinesAdded, 0}},
- {2888, {wxStyledTextEvent, getLine, 0}},
- {2889, {wxStyledTextEvent, getFoldLevelNow, 0}},
- {2890, {wxStyledTextEvent, getFoldLevelPrev, 0}},
- {2891, {wxStyledTextEvent, getMargin, 0}},
- {2892, {wxStyledTextEvent, getMessage, 0}},
- {2893, {wxStyledTextEvent, getWParam, 0}},
- {2894, {wxStyledTextEvent, getLParam, 0}},
- {2895, {wxStyledTextEvent, getListType, 0}},
- {2896, {wxStyledTextEvent, getX, 0}},
- {2897, {wxStyledTextEvent, getY, 0}},
- {2898, {wxStyledTextEvent, getDragText, 0}},
- {2899, {wxStyledTextEvent, getDragAllowMove, 0}},
- {2900, {wxStyledTextEvent, getDragResult, 0}},
- {2901, {wxStyledTextEvent, getShift, 0}},
- {2902, {wxStyledTextEvent, getControl, 0}},
- {2903, {wxStyledTextEvent, getAlt, 0}},
- {2904, {utils, getKeyState, 1}},
- {2905, {utils, getMousePosition, 2}},
- {2906, {utils, getMouseState, 0}},
- {2907, {utils, setDetectableAutoRepeat, 1}},
- {2908, {utils, bell, 0}},
- {2909, {utils, findMenuItemId, 3}},
- {2910, {utils, genericFindWindowAtPoint, 1}},
- {2911, {utils, findWindowAtPoint, 1}},
- {2912, {utils, beginBusyCursor, 1}},
- {2913, {utils, endBusyCursor, 0}},
- {2914, {utils, isBusy, 0}},
- {2915, {utils, shutdown, 1}},
- {2916, {utils, shell, 1}},
- {2917, {utils, launchDefaultBrowser, 2}},
- {2918, {utils, getEmailAddress, 0}},
- {2919, {utils, getUserId, 0}},
- {2920, {utils, getHomeDir, 0}},
- {2921, {utils, newId, 0}},
- {2922, {utils, registerId, 1}},
- {2923, {utils, getCurrentId, 0}},
- {2924, {utils, getOsDescription, 0}},
- {2925, {utils, isPlatformLittleEndian, 0}},
- {2926, {utils, isPlatform64Bit, 0}},
- {2927, {gdicmn, displaySize, 2}},
- {2928, {gdicmn, setCursor, 1}},
- {2929, {wxPrintout, new, 1}},
- {2930, {wxPrintout, destruct, 0}},
- {2931, {wxPrintout, getDC, 0}},
- {2932, {wxPrintout, getPageSizeMM, 2}},
- {2933, {wxPrintout, getPageSizePixels, 2}},
- {2934, {wxPrintout, getPaperRectPixels, 0}},
- {2935, {wxPrintout, getPPIPrinter, 2}},
- {2936, {wxPrintout, getPPIScreen, 2}},
- {2937, {wxPrintout, getTitle, 0}},
- {2938, {wxPrintout, isPreview, 0}},
- {2939, {wxPrintout, fitThisSizeToPaper, 1}},
- {2940, {wxPrintout, fitThisSizeToPage, 1}},
- {2941, {wxPrintout, fitThisSizeToPageMargins, 2}},
- {2942, {wxPrintout, mapScreenSizeToPaper, 0}},
- {2943, {wxPrintout, mapScreenSizeToPage, 0}},
- {2944, {wxPrintout, mapScreenSizeToPageMargins, 1}},
- {2945, {wxPrintout, mapScreenSizeToDevice, 0}},
- {2946, {wxPrintout, getLogicalPaperRect, 0}},
- {2947, {wxPrintout, getLogicalPageRect, 0}},
- {2948, {wxPrintout, getLogicalPageMarginsRect, 1}},
- {2949, {wxPrintout, setLogicalOrigin, 2}},
- {2950, {wxPrintout, offsetLogicalOrigin, 2}},
- {2951, {wxStyledTextCtrl, new_2, 2}},
- {2952, {wxStyledTextCtrl, new_0, 0}},
- {2953, {wxStyledTextCtrl, destruct, 0}},
- {2954, {wxStyledTextCtrl, create, 2}},
- {2955, {wxStyledTextCtrl, addText, 1}},
- {2956, {wxStyledTextCtrl, addStyledText, 1}},
- {2957, {wxStyledTextCtrl, insertText, 2}},
- {2958, {wxStyledTextCtrl, clearAll, 0}},
- {2959, {wxStyledTextCtrl, clearDocumentStyle, 0}},
- {2960, {wxStyledTextCtrl, getLength, 0}},
- {2961, {wxStyledTextCtrl, getCharAt, 1}},
- {2962, {wxStyledTextCtrl, getCurrentPos, 0}},
- {2963, {wxStyledTextCtrl, getAnchor, 0}},
- {2964, {wxStyledTextCtrl, getStyleAt, 1}},
- {2965, {wxStyledTextCtrl, redo, 0}},
- {2966, {wxStyledTextCtrl, setUndoCollection, 1}},
- {2967, {wxStyledTextCtrl, selectAll, 0}},
- {2968, {wxStyledTextCtrl, setSavePoint, 0}},
- {2969, {wxStyledTextCtrl, getStyledText, 2}},
- {2970, {wxStyledTextCtrl, canRedo, 0}},
- {2971, {wxStyledTextCtrl, markerLineFromHandle, 1}},
- {2972, {wxStyledTextCtrl, markerDeleteHandle, 1}},
- {2973, {wxStyledTextCtrl, getUndoCollection, 0}},
- {2974, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
- {2975, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
- {2976, {wxStyledTextCtrl, positionFromPoint, 1}},
- {2977, {wxStyledTextCtrl, positionFromPointClose, 2}},
- {2978, {wxStyledTextCtrl, gotoLine, 1}},
- {2979, {wxStyledTextCtrl, gotoPos, 1}},
- {2980, {wxStyledTextCtrl, setAnchor, 1}},
- {2981, {wxStyledTextCtrl, getCurLine, 1}},
- {2982, {wxStyledTextCtrl, getEndStyled, 0}},
- {2983, {wxStyledTextCtrl, convertEOLs, 1}},
- {2984, {wxStyledTextCtrl, getEOLMode, 0}},
- {2985, {wxStyledTextCtrl, setEOLMode, 1}},
- {2986, {wxStyledTextCtrl, startStyling, 2}},
- {2987, {wxStyledTextCtrl, setStyling, 2}},
- {2988, {wxStyledTextCtrl, getBufferedDraw, 0}},
- {2989, {wxStyledTextCtrl, setBufferedDraw, 1}},
- {2990, {wxStyledTextCtrl, setTabWidth, 1}},
- {2991, {wxStyledTextCtrl, getTabWidth, 0}},
- {2992, {wxStyledTextCtrl, setCodePage, 1}},
- {2993, {wxStyledTextCtrl, markerDefine, 3}},
- {2994, {wxStyledTextCtrl, markerSetForeground, 2}},
- {2995, {wxStyledTextCtrl, markerSetBackground, 2}},
- {2996, {wxStyledTextCtrl, markerAdd, 2}},
- {2997, {wxStyledTextCtrl, markerDelete, 2}},
- {2998, {wxStyledTextCtrl, markerDeleteAll, 1}},
- {2999, {wxStyledTextCtrl, markerGet, 1}},
- {3000, {wxStyledTextCtrl, markerNext, 2}},
- {3001, {wxStyledTextCtrl, markerPrevious, 2}},
- {3002, {wxStyledTextCtrl, markerDefineBitmap, 2}},
- {3003, {wxStyledTextCtrl, markerAddSet, 2}},
- {3004, {wxStyledTextCtrl, markerSetAlpha, 2}},
- {3005, {wxStyledTextCtrl, setMarginType, 2}},
- {3006, {wxStyledTextCtrl, getMarginType, 1}},
- {3007, {wxStyledTextCtrl, setMarginWidth, 2}},
- {3008, {wxStyledTextCtrl, getMarginWidth, 1}},
- {3009, {wxStyledTextCtrl, setMarginMask, 2}},
- {3010, {wxStyledTextCtrl, getMarginMask, 1}},
- {3011, {wxStyledTextCtrl, setMarginSensitive, 2}},
- {3012, {wxStyledTextCtrl, getMarginSensitive, 1}},
- {3013, {wxStyledTextCtrl, styleClearAll, 0}},
- {3014, {wxStyledTextCtrl, styleSetForeground, 2}},
- {3015, {wxStyledTextCtrl, styleSetBackground, 2}},
- {3016, {wxStyledTextCtrl, styleSetBold, 2}},
- {3017, {wxStyledTextCtrl, styleSetItalic, 2}},
- {3018, {wxStyledTextCtrl, styleSetSize, 2}},
- {3019, {wxStyledTextCtrl, styleSetFaceName, 2}},
- {3020, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
- {3021, {wxStyledTextCtrl, styleResetDefault, 0}},
- {3022, {wxStyledTextCtrl, styleSetUnderline, 2}},
- {3023, {wxStyledTextCtrl, styleSetCase, 2}},
- {3024, {wxStyledTextCtrl, styleSetHotSpot, 2}},
- {3025, {wxStyledTextCtrl, setSelForeground, 2}},
- {3026, {wxStyledTextCtrl, setSelBackground, 2}},
- {3027, {wxStyledTextCtrl, getSelAlpha, 0}},
- {3028, {wxStyledTextCtrl, setSelAlpha, 1}},
- {3029, {wxStyledTextCtrl, setCaretForeground, 1}},
- {3030, {wxStyledTextCtrl, cmdKeyAssign, 3}},
- {3031, {wxStyledTextCtrl, cmdKeyClear, 2}},
- {3032, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
- {3033, {wxStyledTextCtrl, setStyleBytes, 2}},
- {3034, {wxStyledTextCtrl, styleSetVisible, 2}},
- {3035, {wxStyledTextCtrl, getCaretPeriod, 0}},
- {3036, {wxStyledTextCtrl, setCaretPeriod, 1}},
- {3037, {wxStyledTextCtrl, setWordChars, 1}},
- {3038, {wxStyledTextCtrl, beginUndoAction, 0}},
- {3039, {wxStyledTextCtrl, endUndoAction, 0}},
- {3040, {wxStyledTextCtrl, indicatorSetStyle, 2}},
- {3041, {wxStyledTextCtrl, indicatorGetStyle, 1}},
- {3042, {wxStyledTextCtrl, indicatorSetForeground, 2}},
- {3043, {wxStyledTextCtrl, indicatorGetForeground, 1}},
- {3044, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
- {3045, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
- {3046, {wxStyledTextCtrl, getStyleBits, 0}},
- {3047, {wxStyledTextCtrl, setLineState, 2}},
- {3048, {wxStyledTextCtrl, getLineState, 1}},
- {3049, {wxStyledTextCtrl, getMaxLineState, 0}},
- {3050, {wxStyledTextCtrl, getCaretLineVisible, 0}},
- {3051, {wxStyledTextCtrl, setCaretLineVisible, 1}},
- {3052, {wxStyledTextCtrl, getCaretLineBackground, 0}},
- {3053, {wxStyledTextCtrl, setCaretLineBackground, 1}},
- {3054, {wxStyledTextCtrl, autoCompShow, 2}},
- {3055, {wxStyledTextCtrl, autoCompCancel, 0}},
- {3056, {wxStyledTextCtrl, autoCompActive, 0}},
- {3057, {wxStyledTextCtrl, autoCompPosStart, 0}},
- {3058, {wxStyledTextCtrl, autoCompComplete, 0}},
- {3059, {wxStyledTextCtrl, autoCompStops, 1}},
- {3060, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
- {3061, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
- {3062, {wxStyledTextCtrl, autoCompSelect, 1}},
- {3063, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
- {3064, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
- {3065, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
- {3066, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
- {3067, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
- {3068, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
- {3069, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
- {3070, {wxStyledTextCtrl, userListShow, 2}},
- {3071, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
- {3072, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
- {3073, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
- {3074, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
- {3075, {wxStyledTextCtrl, registerImage, 2}},
- {3076, {wxStyledTextCtrl, clearRegisteredImages, 0}},
- {3077, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
- {3078, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
- {3079, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
- {3080, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
- {3081, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
- {3082, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
- {3083, {wxStyledTextCtrl, setIndent, 1}},
- {3084, {wxStyledTextCtrl, getIndent, 0}},
- {3085, {wxStyledTextCtrl, setUseTabs, 1}},
- {3086, {wxStyledTextCtrl, getUseTabs, 0}},
- {3087, {wxStyledTextCtrl, setLineIndentation, 2}},
- {3088, {wxStyledTextCtrl, getLineIndentation, 1}},
- {3089, {wxStyledTextCtrl, getLineIndentPosition, 1}},
- {3090, {wxStyledTextCtrl, getColumn, 1}},
- {3091, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
- {3092, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
- {3093, {wxStyledTextCtrl, setIndentationGuides, 1}},
- {3094, {wxStyledTextCtrl, getIndentationGuides, 0}},
- {3095, {wxStyledTextCtrl, setHighlightGuide, 1}},
- {3096, {wxStyledTextCtrl, getHighlightGuide, 0}},
- {3097, {wxStyledTextCtrl, getLineEndPosition, 1}},
- {3098, {wxStyledTextCtrl, getCodePage, 0}},
- {3099, {wxStyledTextCtrl, getCaretForeground, 0}},
- {3100, {wxStyledTextCtrl, getReadOnly, 0}},
- {3101, {wxStyledTextCtrl, setCurrentPos, 1}},
- {3102, {wxStyledTextCtrl, setSelectionStart, 1}},
- {3103, {wxStyledTextCtrl, getSelectionStart, 0}},
- {3104, {wxStyledTextCtrl, setSelectionEnd, 1}},
- {3105, {wxStyledTextCtrl, getSelectionEnd, 0}},
- {3106, {wxStyledTextCtrl, setPrintMagnification, 1}},
- {3107, {wxStyledTextCtrl, getPrintMagnification, 0}},
- {3108, {wxStyledTextCtrl, setPrintColourMode, 1}},
- {3109, {wxStyledTextCtrl, getPrintColourMode, 0}},
- {3110, {wxStyledTextCtrl, findText, 4}},
- {3111, {wxStyledTextCtrl, formatRange, 7}},
- {3112, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
- {3113, {wxStyledTextCtrl, getLine, 1}},
- {3114, {wxStyledTextCtrl, getLineCount, 0}},
- {3115, {wxStyledTextCtrl, setMarginLeft, 1}},
- {3116, {wxStyledTextCtrl, getMarginLeft, 0}},
- {3117, {wxStyledTextCtrl, setMarginRight, 1}},
- {3118, {wxStyledTextCtrl, getMarginRight, 0}},
- {3119, {wxStyledTextCtrl, getModify, 0}},
- {3120, {wxStyledTextCtrl, setSelection, 2}},
- {3121, {wxStyledTextCtrl, getSelectedText, 0}},
- {3122, {wxStyledTextCtrl, getTextRange, 2}},
- {3123, {wxStyledTextCtrl, hideSelection, 1}},
- {3124, {wxStyledTextCtrl, lineFromPosition, 1}},
- {3125, {wxStyledTextCtrl, positionFromLine, 1}},
- {3126, {wxStyledTextCtrl, lineScroll, 2}},
- {3127, {wxStyledTextCtrl, ensureCaretVisible, 0}},
- {3128, {wxStyledTextCtrl, replaceSelection, 1}},
- {3129, {wxStyledTextCtrl, setReadOnly, 1}},
- {3130, {wxStyledTextCtrl, canPaste, 0}},
- {3131, {wxStyledTextCtrl, canUndo, 0}},
- {3132, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
- {3133, {wxStyledTextCtrl, undo, 0}},
- {3134, {wxStyledTextCtrl, cut, 0}},
- {3135, {wxStyledTextCtrl, copy, 0}},
- {3136, {wxStyledTextCtrl, paste, 0}},
- {3137, {wxStyledTextCtrl, clear, 0}},
- {3138, {wxStyledTextCtrl, setText, 1}},
- {3139, {wxStyledTextCtrl, getText, 0}},
- {3140, {wxStyledTextCtrl, getTextLength, 0}},
- {3141, {wxStyledTextCtrl, getOvertype, 0}},
- {3142, {wxStyledTextCtrl, setCaretWidth, 1}},
- {3143, {wxStyledTextCtrl, getCaretWidth, 0}},
- {3144, {wxStyledTextCtrl, setTargetStart, 1}},
- {3145, {wxStyledTextCtrl, getTargetStart, 0}},
- {3146, {wxStyledTextCtrl, setTargetEnd, 1}},
- {3147, {wxStyledTextCtrl, getTargetEnd, 0}},
- {3148, {wxStyledTextCtrl, replaceTarget, 1}},
- {3149, {wxStyledTextCtrl, searchInTarget, 1}},
- {3150, {wxStyledTextCtrl, setSearchFlags, 1}},
- {3151, {wxStyledTextCtrl, getSearchFlags, 0}},
- {3152, {wxStyledTextCtrl, callTipShow, 2}},
- {3153, {wxStyledTextCtrl, callTipCancel, 0}},
- {3154, {wxStyledTextCtrl, callTipActive, 0}},
- {3155, {wxStyledTextCtrl, callTipPosAtStart, 0}},
- {3156, {wxStyledTextCtrl, callTipSetHighlight, 2}},
- {3157, {wxStyledTextCtrl, callTipSetBackground, 1}},
- {3158, {wxStyledTextCtrl, callTipSetForeground, 1}},
- {3159, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
- {3160, {wxStyledTextCtrl, callTipUseStyle, 1}},
- {3161, {wxStyledTextCtrl, visibleFromDocLine, 1}},
- {3162, {wxStyledTextCtrl, docLineFromVisible, 1}},
- {3163, {wxStyledTextCtrl, wrapCount, 1}},
- {3164, {wxStyledTextCtrl, setFoldLevel, 2}},
- {3165, {wxStyledTextCtrl, getFoldLevel, 1}},
- {3166, {wxStyledTextCtrl, getLastChild, 2}},
- {3167, {wxStyledTextCtrl, getFoldParent, 1}},
- {3168, {wxStyledTextCtrl, showLines, 2}},
- {3169, {wxStyledTextCtrl, hideLines, 2}},
- {3170, {wxStyledTextCtrl, getLineVisible, 1}},
- {3171, {wxStyledTextCtrl, setFoldExpanded, 2}},
- {3172, {wxStyledTextCtrl, getFoldExpanded, 1}},
- {3173, {wxStyledTextCtrl, toggleFold, 1}},
- {3174, {wxStyledTextCtrl, ensureVisible, 1}},
- {3175, {wxStyledTextCtrl, setFoldFlags, 1}},
- {3176, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
- {3177, {wxStyledTextCtrl, setTabIndents, 1}},
- {3178, {wxStyledTextCtrl, getTabIndents, 0}},
- {3179, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
- {3180, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
- {3181, {wxStyledTextCtrl, setMouseDwellTime, 1}},
- {3182, {wxStyledTextCtrl, getMouseDwellTime, 0}},
- {3183, {wxStyledTextCtrl, wordStartPosition, 2}},
- {3184, {wxStyledTextCtrl, wordEndPosition, 2}},
- {3185, {wxStyledTextCtrl, setWrapMode, 1}},
- {3186, {wxStyledTextCtrl, getWrapMode, 0}},
- {3187, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
- {3188, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
- {3189, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
- {3190, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
- {3191, {wxStyledTextCtrl, setWrapStartIndent, 1}},
- {3192, {wxStyledTextCtrl, getWrapStartIndent, 0}},
- {3193, {wxStyledTextCtrl, setLayoutCache, 1}},
- {3194, {wxStyledTextCtrl, getLayoutCache, 0}},
- {3195, {wxStyledTextCtrl, setScrollWidth, 1}},
- {3196, {wxStyledTextCtrl, getScrollWidth, 0}},
- {3197, {wxStyledTextCtrl, textWidth, 2}},
- {3198, {wxStyledTextCtrl, getEndAtLastLine, 0}},
- {3199, {wxStyledTextCtrl, textHeight, 1}},
- {3200, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
- {3201, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
- {3202, {wxStyledTextCtrl, appendText, 1}},
- {3203, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
- {3204, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
- {3205, {wxStyledTextCtrl, targetFromSelection, 0}},
- {3206, {wxStyledTextCtrl, linesJoin, 0}},
- {3207, {wxStyledTextCtrl, linesSplit, 1}},
- {3208, {wxStyledTextCtrl, setFoldMarginColour, 2}},
- {3209, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
- {3210, {wxStyledTextCtrl, lineDown, 0}},
- {3211, {wxStyledTextCtrl, lineDownExtend, 0}},
- {3212, {wxStyledTextCtrl, lineUp, 0}},
- {3213, {wxStyledTextCtrl, lineUpExtend, 0}},
- {3214, {wxStyledTextCtrl, charLeft, 0}},
- {3215, {wxStyledTextCtrl, charLeftExtend, 0}},
- {3216, {wxStyledTextCtrl, charRight, 0}},
- {3217, {wxStyledTextCtrl, charRightExtend, 0}},
- {3218, {wxStyledTextCtrl, wordLeft, 0}},
- {3219, {wxStyledTextCtrl, wordLeftExtend, 0}},
- {3220, {wxStyledTextCtrl, wordRight, 0}},
- {3221, {wxStyledTextCtrl, wordRightExtend, 0}},
- {3222, {wxStyledTextCtrl, home, 0}},
- {3223, {wxStyledTextCtrl, homeExtend, 0}},
- {3224, {wxStyledTextCtrl, lineEnd, 0}},
- {3225, {wxStyledTextCtrl, lineEndExtend, 0}},
- {3226, {wxStyledTextCtrl, documentStart, 0}},
- {3227, {wxStyledTextCtrl, documentStartExtend, 0}},
- {3228, {wxStyledTextCtrl, documentEnd, 0}},
- {3229, {wxStyledTextCtrl, documentEndExtend, 0}},
- {3230, {wxStyledTextCtrl, pageUp, 0}},
- {3231, {wxStyledTextCtrl, pageUpExtend, 0}},
- {3232, {wxStyledTextCtrl, pageDown, 0}},
- {3233, {wxStyledTextCtrl, pageDownExtend, 0}},
- {3234, {wxStyledTextCtrl, editToggleOvertype, 0}},
- {3235, {wxStyledTextCtrl, cancel, 0}},
- {3236, {wxStyledTextCtrl, deleteBack, 0}},
- {3237, {wxStyledTextCtrl, tab, 0}},
- {3238, {wxStyledTextCtrl, backTab, 0}},
- {3239, {wxStyledTextCtrl, newLine, 0}},
- {3240, {wxStyledTextCtrl, formFeed, 0}},
- {3241, {wxStyledTextCtrl, vCHome, 0}},
- {3242, {wxStyledTextCtrl, vCHomeExtend, 0}},
- {3243, {wxStyledTextCtrl, zoomIn, 0}},
- {3244, {wxStyledTextCtrl, zoomOut, 0}},
- {3245, {wxStyledTextCtrl, delWordLeft, 0}},
- {3246, {wxStyledTextCtrl, delWordRight, 0}},
- {3247, {wxStyledTextCtrl, lineCut, 0}},
- {3248, {wxStyledTextCtrl, lineDelete, 0}},
- {3249, {wxStyledTextCtrl, lineTranspose, 0}},
- {3250, {wxStyledTextCtrl, lineDuplicate, 0}},
- {3251, {wxStyledTextCtrl, lowerCase, 0}},
- {3252, {wxStyledTextCtrl, upperCase, 0}},
- {3253, {wxStyledTextCtrl, lineScrollDown, 0}},
- {3254, {wxStyledTextCtrl, lineScrollUp, 0}},
- {3255, {wxStyledTextCtrl, deleteBackNotLine, 0}},
- {3256, {wxStyledTextCtrl, homeDisplay, 0}},
- {3257, {wxStyledTextCtrl, homeDisplayExtend, 0}},
- {3258, {wxStyledTextCtrl, lineEndDisplay, 0}},
- {3259, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
- {3260, {wxStyledTextCtrl, homeWrapExtend, 0}},
- {3261, {wxStyledTextCtrl, lineEndWrap, 0}},
- {3262, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
- {3263, {wxStyledTextCtrl, vCHomeWrap, 0}},
- {3264, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
- {3265, {wxStyledTextCtrl, lineCopy, 0}},
- {3266, {wxStyledTextCtrl, moveCaretInsideView, 0}},
- {3267, {wxStyledTextCtrl, lineLength, 1}},
- {3268, {wxStyledTextCtrl, braceHighlight, 2}},
- {3269, {wxStyledTextCtrl, braceBadLight, 1}},
- {3270, {wxStyledTextCtrl, braceMatch, 1}},
- {3271, {wxStyledTextCtrl, getViewEOL, 0}},
- {3272, {wxStyledTextCtrl, setViewEOL, 1}},
- {3273, {wxStyledTextCtrl, setModEventMask, 1}},
- {3274, {wxStyledTextCtrl, getEdgeColumn, 0}},
- {3275, {wxStyledTextCtrl, setEdgeColumn, 1}},
- {3276, {wxStyledTextCtrl, setEdgeMode, 1}},
- {3277, {wxStyledTextCtrl, getEdgeMode, 0}},
- {3278, {wxStyledTextCtrl, getEdgeColour, 0}},
- {3279, {wxStyledTextCtrl, setEdgeColour, 1}},
- {3280, {wxStyledTextCtrl, searchAnchor, 0}},
- {3281, {wxStyledTextCtrl, searchNext, 2}},
- {3282, {wxStyledTextCtrl, searchPrev, 2}},
- {3283, {wxStyledTextCtrl, linesOnScreen, 0}},
- {3284, {wxStyledTextCtrl, usePopUp, 1}},
- {3285, {wxStyledTextCtrl, selectionIsRectangle, 0}},
- {3286, {wxStyledTextCtrl, setZoom, 1}},
- {3287, {wxStyledTextCtrl, getZoom, 0}},
- {3288, {wxStyledTextCtrl, getModEventMask, 0}},
- {3289, {wxStyledTextCtrl, setSTCFocus, 1}},
- {3290, {wxStyledTextCtrl, getSTCFocus, 0}},
- {3291, {wxStyledTextCtrl, setStatus, 1}},
- {3292, {wxStyledTextCtrl, getStatus, 0}},
- {3293, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
- {3294, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
- {3295, {wxStyledTextCtrl, setSTCCursor, 1}},
- {3296, {wxStyledTextCtrl, getSTCCursor, 0}},
- {3297, {wxStyledTextCtrl, setControlCharSymbol, 1}},
- {3298, {wxStyledTextCtrl, getControlCharSymbol, 0}},
- {3299, {wxStyledTextCtrl, wordPartLeft, 0}},
- {3300, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
- {3301, {wxStyledTextCtrl, wordPartRight, 0}},
- {3302, {wxStyledTextCtrl, wordPartRightExtend, 0}},
- {3303, {wxStyledTextCtrl, setVisiblePolicy, 2}},
- {3304, {wxStyledTextCtrl, delLineLeft, 0}},
- {3305, {wxStyledTextCtrl, delLineRight, 0}},
- {3306, {wxStyledTextCtrl, getXOffset, 0}},
- {3307, {wxStyledTextCtrl, chooseCaretX, 0}},
- {3308, {wxStyledTextCtrl, setXCaretPolicy, 2}},
- {3309, {wxStyledTextCtrl, setYCaretPolicy, 2}},
- {3310, {wxStyledTextCtrl, getPrintWrapMode, 0}},
- {3311, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
- {3312, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
- {3313, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
- {3314, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
- {3315, {wxStyledTextCtrl, paraDownExtend, 0}},
- {3316, {wxStyledTextCtrl, paraUp, 0}},
- {3317, {wxStyledTextCtrl, paraUpExtend, 0}},
- {3318, {wxStyledTextCtrl, positionBefore, 1}},
- {3319, {wxStyledTextCtrl, positionAfter, 1}},
- {3320, {wxStyledTextCtrl, copyRange, 2}},
- {3321, {wxStyledTextCtrl, copyText, 2}},
- {3322, {wxStyledTextCtrl, setSelectionMode, 1}},
- {3323, {wxStyledTextCtrl, getSelectionMode, 0}},
- {3324, {wxStyledTextCtrl, lineDownRectExtend, 0}},
- {3325, {wxStyledTextCtrl, lineUpRectExtend, 0}},
- {3326, {wxStyledTextCtrl, charLeftRectExtend, 0}},
- {3327, {wxStyledTextCtrl, charRightRectExtend, 0}},
- {3328, {wxStyledTextCtrl, homeRectExtend, 0}},
- {3329, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
- {3330, {wxStyledTextCtrl, lineEndRectExtend, 0}},
- {3331, {wxStyledTextCtrl, pageUpRectExtend, 0}},
- {3332, {wxStyledTextCtrl, pageDownRectExtend, 0}},
- {3333, {wxStyledTextCtrl, stutteredPageUp, 0}},
- {3334, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
- {3335, {wxStyledTextCtrl, stutteredPageDown, 0}},
- {3336, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
- {3337, {wxStyledTextCtrl, wordLeftEnd, 0}},
- {3338, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
- {3339, {wxStyledTextCtrl, wordRightEnd, 0}},
- {3340, {wxStyledTextCtrl, wordRightEndExtend, 0}},
- {3341, {wxStyledTextCtrl, setWhitespaceChars, 1}},
- {3342, {wxStyledTextCtrl, setCharsDefault, 0}},
- {3343, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
- {3344, {wxStyledTextCtrl, allocate, 1}},
- {3345, {wxStyledTextCtrl, findColumn, 2}},
- {3346, {wxStyledTextCtrl, getCaretSticky, 0}},
- {3347, {wxStyledTextCtrl, setCaretSticky, 1}},
- {3348, {wxStyledTextCtrl, toggleCaretSticky, 0}},
- {3349, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
- {3350, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
- {3351, {wxStyledTextCtrl, selectionDuplicate, 0}},
- {3352, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
- {3353, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
- {3354, {wxStyledTextCtrl, startRecord, 0}},
- {3355, {wxStyledTextCtrl, stopRecord, 0}},
- {3356, {wxStyledTextCtrl, setLexer, 1}},
- {3357, {wxStyledTextCtrl, getLexer, 0}},
- {3358, {wxStyledTextCtrl, colourise, 2}},
- {3359, {wxStyledTextCtrl, setProperty, 2}},
- {3360, {wxStyledTextCtrl, setKeyWords, 2}},
- {3361, {wxStyledTextCtrl, setLexerLanguage, 1}},
- {3362, {wxStyledTextCtrl, getProperty, 1}},
- {3363, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
- {3364, {wxStyledTextCtrl, getCurrentLine, 0}},
- {3365, {wxStyledTextCtrl, styleSetSpec, 2}},
- {3366, {wxStyledTextCtrl, styleSetFont, 2}},
- {3367, {wxStyledTextCtrl, styleSetFontAttr, 7}},
- {3368, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
- {3369, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
- {3370, {wxStyledTextCtrl, cmdKeyExecute, 1}},
- {3371, {wxStyledTextCtrl, setMargins, 2}},
- {3372, {wxStyledTextCtrl, getSelection, 2}},
- {3373, {wxStyledTextCtrl, pointFromPosition, 1}},
- {3374, {wxStyledTextCtrl, scrollToLine, 1}},
- {3375, {wxStyledTextCtrl, scrollToColumn, 1}},
- {3376, {wxStyledTextCtrl, setVScrollBar, 1}},
- {3377, {wxStyledTextCtrl, setHScrollBar, 1}},
- {3378, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
- {3379, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
- {3380, {wxStyledTextCtrl, saveFile, 1}},
- {3381, {wxStyledTextCtrl, loadFile, 1}},
- {3382, {wxStyledTextCtrl, doDragOver, 3}},
- {3383, {wxStyledTextCtrl, doDropText, 3}},
- {3384, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
- {3385, {wxStyledTextCtrl, addTextRaw, 1}},
- {3386, {wxStyledTextCtrl, insertTextRaw, 2}},
- {3387, {wxStyledTextCtrl, getCurLineRaw, 1}},
- {3388, {wxStyledTextCtrl, getLineRaw, 1}},
- {3389, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
- {3390, {wxStyledTextCtrl, getTextRangeRaw, 2}},
- {3391, {wxStyledTextCtrl, setTextRaw, 1}},
- {3392, {wxStyledTextCtrl, getTextRaw, 0}},
- {3393, {wxStyledTextCtrl, appendTextRaw, 1}},
- {3394, {wxArtProvider, getBitmap, 2}},
- {3395, {wxArtProvider, getIcon, 2}},
- {3396, {wxTreeEvent, getKeyCode, 0}},
- {3397, {wxTreeEvent, getItem, 0}},
- {3398, {wxTreeEvent, getKeyEvent, 0}},
- {3399, {wxTreeEvent, getLabel, 0}},
- {3400, {wxTreeEvent, getOldItem, 0}},
- {3401, {wxTreeEvent, getPoint, 0}},
- {3402, {wxTreeEvent, isEditCancelled, 0}},
- {3403, {wxTreeEvent, setToolTip, 1}},
- {3404, {wxNotebookEvent, getOldSelection, 0}},
- {3405, {wxNotebookEvent, getSelection, 0}},
- {3406, {wxNotebookEvent, setOldSelection, 1}},
- {3407, {wxNotebookEvent, setSelection, 1}},
- {3408, {wxFileDataObject, new, 0}},
- {3409, {wxFileDataObject, addFile, 1}},
- {3410, {wxFileDataObject, getFilenames, 0}},
- {3411, {wxFileDataObject, 'Destroy', undefined}},
- {3412, {wxTextDataObject, new, 1}},
- {3413, {wxTextDataObject, getTextLength, 0}},
- {3414, {wxTextDataObject, getText, 0}},
- {3415, {wxTextDataObject, setText, 1}},
- {3416, {wxTextDataObject, 'Destroy', undefined}},
- {3417, {wxBitmapDataObject, new_1_1, 1}},
- {3418, {wxBitmapDataObject, new_1_0, 1}},
- {3419, {wxBitmapDataObject, getBitmap, 0}},
- {3420, {wxBitmapDataObject, setBitmap, 1}},
- {3421, {wxBitmapDataObject, 'Destroy', undefined}},
- {3423, {wxClipboard, new, 0}},
- {3424, {wxClipboard, destruct, 0}},
- {3425, {wxClipboard, addData, 1}},
- {3426, {wxClipboard, clear, 0}},
- {3427, {wxClipboard, close, 0}},
- {3428, {wxClipboard, flush, 0}},
- {3429, {wxClipboard, getData, 1}},
- {3430, {wxClipboard, isOpened, 0}},
- {3431, {wxClipboard, open, 0}},
- {3432, {wxClipboard, setData, 1}},
- {3434, {wxClipboard, usePrimarySelection, 1}},
- {3435, {wxClipboard, isSupported, 1}},
- {3436, {wxClipboard, get, 0}},
- {3437, {wxSpinEvent, getPosition, 0}},
- {3438, {wxSpinEvent, setPosition, 1}},
- {3439, {wxSplitterWindow, new_0, 0}},
- {3440, {wxSplitterWindow, new_2, 2}},
- {3441, {wxSplitterWindow, destruct, 0}},
- {3442, {wxSplitterWindow, create, 2}},
- {3443, {wxSplitterWindow, getMinimumPaneSize, 0}},
- {3444, {wxSplitterWindow, getSashGravity, 0}},
- {3445, {wxSplitterWindow, getSashPosition, 0}},
- {3446, {wxSplitterWindow, getSplitMode, 0}},
- {3447, {wxSplitterWindow, getWindow1, 0}},
- {3448, {wxSplitterWindow, getWindow2, 0}},
- {3449, {wxSplitterWindow, initialize, 1}},
- {3450, {wxSplitterWindow, isSplit, 0}},
- {3451, {wxSplitterWindow, replaceWindow, 2}},
- {3452, {wxSplitterWindow, setSashGravity, 1}},
- {3453, {wxSplitterWindow, setSashPosition, 2}},
- {3454, {wxSplitterWindow, setSashSize, 1}},
- {3455, {wxSplitterWindow, setMinimumPaneSize, 1}},
- {3456, {wxSplitterWindow, setSplitMode, 1}},
- {3457, {wxSplitterWindow, splitHorizontally, 3}},
- {3458, {wxSplitterWindow, splitVertically, 3}},
- {3459, {wxSplitterWindow, unsplit, 1}},
- {3460, {wxSplitterWindow, updateSize, 0}},
- {3461, {wxSplitterEvent, getSashPosition, 0}},
- {3462, {wxSplitterEvent, getX, 0}},
- {3463, {wxSplitterEvent, getY, 0}},
- {3464, {wxSplitterEvent, getWindowBeingRemoved, 0}},
- {3465, {wxSplitterEvent, setSashPosition, 1}},
- {3466, {wxHtmlWindow, new_0, 0}},
- {3467, {wxHtmlWindow, new_2, 2}},
- {3468, {wxHtmlWindow, appendToPage, 1}},
- {3469, {wxHtmlWindow, getOpenedAnchor, 0}},
- {3470, {wxHtmlWindow, getOpenedPage, 0}},
- {3471, {wxHtmlWindow, getOpenedPageTitle, 0}},
- {3472, {wxHtmlWindow, getRelatedFrame, 0}},
- {3473, {wxHtmlWindow, historyBack, 0}},
- {3474, {wxHtmlWindow, historyCanBack, 0}},
- {3475, {wxHtmlWindow, historyCanForward, 0}},
- {3476, {wxHtmlWindow, historyClear, 0}},
- {3477, {wxHtmlWindow, historyForward, 0}},
- {3478, {wxHtmlWindow, loadFile, 1}},
- {3479, {wxHtmlWindow, loadPage, 1}},
- {3480, {wxHtmlWindow, selectAll, 0}},
- {3481, {wxHtmlWindow, selectionToText, 0}},
- {3482, {wxHtmlWindow, selectLine, 1}},
- {3483, {wxHtmlWindow, selectWord, 1}},
- {3484, {wxHtmlWindow, setBorders, 1}},
- {3485, {wxHtmlWindow, setFonts, 3}},
- {3486, {wxHtmlWindow, setPage, 1}},
- {3487, {wxHtmlWindow, setRelatedFrame, 2}},
- {3488, {wxHtmlWindow, setRelatedStatusBar, 1}},
- {3489, {wxHtmlWindow, toText, 0}},
- {3490, {wxHtmlWindow, 'Destroy', undefined}},
- {3491, {wxHtmlLinkEvent, getLinkInfo, 0}},
- {3492, {wxSystemSettings, getColour, 1}},
- {3493, {wxSystemSettings, getFont, 1}},
- {3494, {wxSystemSettings, getMetric, 2}},
- {3495, {wxSystemSettings, getScreenType, 0}},
- {3496, {wxSystemOptions, getOption, 1}},
- {3497, {wxSystemOptions, getOptionInt, 1}},
- {3498, {wxSystemOptions, hasOption, 1}},
- {3499, {wxSystemOptions, isFalse, 1}},
- {3500, {wxSystemOptions, setOption_2_1, 2}},
- {3501, {wxSystemOptions, setOption_2_0, 2}},
- {3502, {wxAuiNotebookEvent, setSelection, 1}},
- {3503, {wxAuiNotebookEvent, getSelection, 0}},
- {3504, {wxAuiNotebookEvent, setOldSelection, 1}},
- {3505, {wxAuiNotebookEvent, getOldSelection, 0}},
- {3506, {wxAuiNotebookEvent, setDragSource, 1}},
- {3507, {wxAuiNotebookEvent, getDragSource, 0}},
- {3508, {wxAuiManagerEvent, setManager, 1}},
- {3509, {wxAuiManagerEvent, getManager, 0}},
- {3510, {wxAuiManagerEvent, setPane, 1}},
- {3511, {wxAuiManagerEvent, getPane, 0}},
- {3512, {wxAuiManagerEvent, setButton, 1}},
- {3513, {wxAuiManagerEvent, getButton, 0}},
- {3514, {wxAuiManagerEvent, setDC, 1}},
- {3515, {wxAuiManagerEvent, getDC, 0}},
- {3516, {wxAuiManagerEvent, veto, 1}},
- {3517, {wxAuiManagerEvent, getVeto, 0}},
- {3518, {wxAuiManagerEvent, setCanVeto, 1}},
- {3519, {wxAuiManagerEvent, canVeto, 0}},
- {3520, {wxLogNull, new, 0}},
- {3521, {wxLogNull, 'Destroy', undefined}},
- {3522, {wxTaskBarIcon, new, 0}},
- {3523, {wxTaskBarIcon, destruct, 0}},
- {3524, {wxTaskBarIcon, popupMenu, 1}},
- {3525, {wxTaskBarIcon, removeIcon, 0}},
- {3526, {wxTaskBarIcon, setIcon, 2}},
- {3527, {wxLocale, new_0, 0}},
- {3529, {wxLocale, new_2, 2}},
- {3530, {wxLocale, destruct, 0}},
- {3532, {wxLocale, init, 1}},
- {3533, {wxLocale, addCatalog_1, 1}},
- {3534, {wxLocale, addCatalog_3, 3}},
- {3535, {wxLocale, addCatalogLookupPathPrefix, 1}},
- {3536, {wxLocale, getCanonicalName, 0}},
- {3537, {wxLocale, getLanguage, 0}},
- {3538, {wxLocale, getLanguageName, 1}},
- {3539, {wxLocale, getLocale, 0}},
- {3540, {wxLocale, getName, 0}},
- {3541, {wxLocale, getString_2, 2}},
- {3542, {wxLocale, getString_4, 4}},
- {3543, {wxLocale, getHeaderValue, 2}},
- {3544, {wxLocale, getSysName, 0}},
- {3545, {wxLocale, getSystemEncoding, 0}},
- {3546, {wxLocale, getSystemEncodingName, 0}},
- {3547, {wxLocale, getSystemLanguage, 0}},
- {3548, {wxLocale, isLoaded, 1}},
- {3549, {wxLocale, isOk, 0}},
+ {1827, {wxTextCtrl, changeValue, 1}},
+ {1828, {wxTextCtrl, emulateKeyPress, 1}},
+ {1829, {wxTextCtrl, getDefaultStyle, 0}},
+ {1830, {wxTextCtrl, getInsertionPoint, 0}},
+ {1831, {wxTextCtrl, getLastPosition, 0}},
+ {1832, {wxTextCtrl, getLineLength, 1}},
+ {1833, {wxTextCtrl, getLineText, 1}},
+ {1834, {wxTextCtrl, getNumberOfLines, 0}},
+ {1835, {wxTextCtrl, getRange, 2}},
+ {1836, {wxTextCtrl, getSelection, 2}},
+ {1837, {wxTextCtrl, getStringSelection, 0}},
+ {1838, {wxTextCtrl, getStyle, 2}},
+ {1839, {wxTextCtrl, getValue, 0}},
+ {1840, {wxTextCtrl, isEditable, 0}},
+ {1841, {wxTextCtrl, isModified, 0}},
+ {1842, {wxTextCtrl, isMultiLine, 0}},
+ {1843, {wxTextCtrl, isSingleLine, 0}},
+ {1844, {wxTextCtrl, loadFile, 2}},
+ {1845, {wxTextCtrl, markDirty, 0}},
+ {1846, {wxTextCtrl, paste, 0}},
+ {1847, {wxTextCtrl, positionToXY, 3}},
+ {1848, {wxTextCtrl, redo, 0}},
+ {1849, {wxTextCtrl, remove, 2}},
+ {1850, {wxTextCtrl, replace, 3}},
+ {1851, {wxTextCtrl, saveFile, 1}},
+ {1852, {wxTextCtrl, setDefaultStyle, 1}},
+ {1853, {wxTextCtrl, setEditable, 1}},
+ {1854, {wxTextCtrl, setInsertionPoint, 1}},
+ {1855, {wxTextCtrl, setInsertionPointEnd, 0}},
+ {1857, {wxTextCtrl, setMaxLength, 1}},
+ {1858, {wxTextCtrl, setSelection, 2}},
+ {1859, {wxTextCtrl, setStyle, 3}},
+ {1860, {wxTextCtrl, setValue, 1}},
+ {1861, {wxTextCtrl, showPosition, 1}},
+ {1862, {wxTextCtrl, undo, 0}},
+ {1863, {wxTextCtrl, writeText, 1}},
+ {1864, {wxTextCtrl, xYToPosition, 2}},
+ {1867, {wxNotebook, new_0, 0}},
+ {1868, {wxNotebook, new_3, 3}},
+ {1869, {wxNotebook, destruct, 0}},
+ {1870, {wxNotebook, addPage, 3}},
+ {1871, {wxNotebook, advanceSelection, 1}},
+ {1872, {wxNotebook, assignImageList, 1}},
+ {1873, {wxNotebook, create, 3}},
+ {1874, {wxNotebook, deleteAllPages, 0}},
+ {1875, {wxNotebook, deletePage, 1}},
+ {1876, {wxNotebook, removePage, 1}},
+ {1877, {wxNotebook, getCurrentPage, 0}},
+ {1878, {wxNotebook, getImageList, 0}},
+ {1880, {wxNotebook, getPage, 1}},
+ {1881, {wxNotebook, getPageCount, 0}},
+ {1882, {wxNotebook, getPageImage, 1}},
+ {1883, {wxNotebook, getPageText, 1}},
+ {1884, {wxNotebook, getRowCount, 0}},
+ {1885, {wxNotebook, getSelection, 0}},
+ {1886, {wxNotebook, getThemeBackgroundColour, 0}},
+ {1888, {wxNotebook, hitTest, 2}},
+ {1890, {wxNotebook, insertPage, 4}},
+ {1891, {wxNotebook, setImageList, 1}},
+ {1892, {wxNotebook, setPadding, 1}},
+ {1893, {wxNotebook, setPageSize, 1}},
+ {1894, {wxNotebook, setPageImage, 2}},
+ {1895, {wxNotebook, setPageText, 2}},
+ {1896, {wxNotebook, setSelection, 1}},
+ {1897, {wxNotebook, changeSelection, 1}},
+ {1898, {wxChoicebook, new_0, 0}},
+ {1899, {wxChoicebook, new_3, 3}},
+ {1900, {wxChoicebook, addPage, 3}},
+ {1901, {wxChoicebook, advanceSelection, 1}},
+ {1902, {wxChoicebook, assignImageList, 1}},
+ {1903, {wxChoicebook, create, 3}},
+ {1904, {wxChoicebook, deleteAllPages, 0}},
+ {1905, {wxChoicebook, deletePage, 1}},
+ {1906, {wxChoicebook, removePage, 1}},
+ {1907, {wxChoicebook, getCurrentPage, 0}},
+ {1908, {wxChoicebook, getImageList, 0}},
+ {1910, {wxChoicebook, getPage, 1}},
+ {1911, {wxChoicebook, getPageCount, 0}},
+ {1912, {wxChoicebook, getPageImage, 1}},
+ {1913, {wxChoicebook, getPageText, 1}},
+ {1914, {wxChoicebook, getSelection, 0}},
+ {1915, {wxChoicebook, hitTest, 2}},
+ {1916, {wxChoicebook, insertPage, 4}},
+ {1917, {wxChoicebook, setImageList, 1}},
+ {1918, {wxChoicebook, setPageSize, 1}},
+ {1919, {wxChoicebook, setPageImage, 2}},
+ {1920, {wxChoicebook, setPageText, 2}},
+ {1921, {wxChoicebook, setSelection, 1}},
+ {1922, {wxChoicebook, changeSelection, 1}},
+ {1923, {wxChoicebook, 'Destroy', undefined}},
+ {1924, {wxToolbook, new_0, 0}},
+ {1925, {wxToolbook, new_3, 3}},
+ {1926, {wxToolbook, addPage, 3}},
+ {1927, {wxToolbook, advanceSelection, 1}},
+ {1928, {wxToolbook, assignImageList, 1}},
+ {1929, {wxToolbook, create, 3}},
+ {1930, {wxToolbook, deleteAllPages, 0}},
+ {1931, {wxToolbook, deletePage, 1}},
+ {1932, {wxToolbook, removePage, 1}},
+ {1933, {wxToolbook, getCurrentPage, 0}},
+ {1934, {wxToolbook, getImageList, 0}},
+ {1936, {wxToolbook, getPage, 1}},
+ {1937, {wxToolbook, getPageCount, 0}},
+ {1938, {wxToolbook, getPageImage, 1}},
+ {1939, {wxToolbook, getPageText, 1}},
+ {1940, {wxToolbook, getSelection, 0}},
+ {1942, {wxToolbook, hitTest, 2}},
+ {1943, {wxToolbook, insertPage, 4}},
+ {1944, {wxToolbook, setImageList, 1}},
+ {1945, {wxToolbook, setPageSize, 1}},
+ {1946, {wxToolbook, setPageImage, 2}},
+ {1947, {wxToolbook, setPageText, 2}},
+ {1948, {wxToolbook, setSelection, 1}},
+ {1949, {wxToolbook, changeSelection, 1}},
+ {1950, {wxToolbook, 'Destroy', undefined}},
+ {1951, {wxListbook, new_0, 0}},
+ {1952, {wxListbook, new_3, 3}},
+ {1953, {wxListbook, addPage, 3}},
+ {1954, {wxListbook, advanceSelection, 1}},
+ {1955, {wxListbook, assignImageList, 1}},
+ {1956, {wxListbook, create, 3}},
+ {1957, {wxListbook, deleteAllPages, 0}},
+ {1958, {wxListbook, deletePage, 1}},
+ {1959, {wxListbook, removePage, 1}},
+ {1960, {wxListbook, getCurrentPage, 0}},
+ {1961, {wxListbook, getImageList, 0}},
+ {1963, {wxListbook, getPage, 1}},
+ {1964, {wxListbook, getPageCount, 0}},
+ {1965, {wxListbook, getPageImage, 1}},
+ {1966, {wxListbook, getPageText, 1}},
+ {1967, {wxListbook, getSelection, 0}},
+ {1969, {wxListbook, hitTest, 2}},
+ {1970, {wxListbook, insertPage, 4}},
+ {1971, {wxListbook, setImageList, 1}},
+ {1972, {wxListbook, setPageSize, 1}},
+ {1973, {wxListbook, setPageImage, 2}},
+ {1974, {wxListbook, setPageText, 2}},
+ {1975, {wxListbook, setSelection, 1}},
+ {1976, {wxListbook, changeSelection, 1}},
+ {1977, {wxListbook, 'Destroy', undefined}},
+ {1978, {wxTreebook, new_0, 0}},
+ {1979, {wxTreebook, new_3, 3}},
+ {1980, {wxTreebook, addPage, 3}},
+ {1981, {wxTreebook, advanceSelection, 1}},
+ {1982, {wxTreebook, assignImageList, 1}},
+ {1983, {wxTreebook, create, 3}},
+ {1984, {wxTreebook, deleteAllPages, 0}},
+ {1985, {wxTreebook, deletePage, 1}},
+ {1986, {wxTreebook, removePage, 1}},
+ {1987, {wxTreebook, getCurrentPage, 0}},
+ {1988, {wxTreebook, getImageList, 0}},
+ {1990, {wxTreebook, getPage, 1}},
+ {1991, {wxTreebook, getPageCount, 0}},
+ {1992, {wxTreebook, getPageImage, 1}},
+ {1993, {wxTreebook, getPageText, 1}},
+ {1994, {wxTreebook, getSelection, 0}},
+ {1995, {wxTreebook, expandNode, 2}},
+ {1996, {wxTreebook, isNodeExpanded, 1}},
+ {1998, {wxTreebook, hitTest, 2}},
+ {1999, {wxTreebook, insertPage, 4}},
+ {2000, {wxTreebook, insertSubPage, 4}},
+ {2001, {wxTreebook, setImageList, 1}},
+ {2002, {wxTreebook, setPageSize, 1}},
+ {2003, {wxTreebook, setPageImage, 2}},
+ {2004, {wxTreebook, setPageText, 2}},
+ {2005, {wxTreebook, setSelection, 1}},
+ {2006, {wxTreebook, changeSelection, 1}},
+ {2007, {wxTreebook, 'Destroy', undefined}},
+ {2010, {wxTreeCtrl, new_2, 2}},
+ {2011, {wxTreeCtrl, new_0, 0}},
+ {2013, {wxTreeCtrl, destruct, 0}},
+ {2014, {wxTreeCtrl, addRoot, 2}},
+ {2015, {wxTreeCtrl, appendItem, 3}},
+ {2016, {wxTreeCtrl, assignImageList, 1}},
+ {2017, {wxTreeCtrl, assignStateImageList, 1}},
+ {2018, {wxTreeCtrl, collapse, 1}},
+ {2019, {wxTreeCtrl, collapseAndReset, 1}},
+ {2020, {wxTreeCtrl, create, 2}},
+ {2021, {wxTreeCtrl, delete, 1}},
+ {2022, {wxTreeCtrl, deleteAllItems, 0}},
+ {2023, {wxTreeCtrl, deleteChildren, 1}},
+ {2024, {wxTreeCtrl, editLabel, 1}},
+ {2025, {wxTreeCtrl, ensureVisible, 1}},
+ {2026, {wxTreeCtrl, expand, 1}},
+ {2027, {wxTreeCtrl, getBoundingRect, 3}},
+ {2029, {wxTreeCtrl, getChildrenCount, 2}},
+ {2030, {wxTreeCtrl, getCount, 0}},
+ {2031, {wxTreeCtrl, getEditControl, 0}},
+ {2032, {wxTreeCtrl, getFirstChild, 2}},
+ {2033, {wxTreeCtrl, getNextChild, 2}},
+ {2034, {wxTreeCtrl, getFirstVisibleItem, 0}},
+ {2035, {wxTreeCtrl, getImageList, 0}},
+ {2036, {wxTreeCtrl, getIndent, 0}},
+ {2037, {wxTreeCtrl, getItemBackgroundColour, 1}},
+ {2038, {wxTreeCtrl, getItemData, 1}},
+ {2039, {wxTreeCtrl, getItemFont, 1}},
+ {2040, {wxTreeCtrl, getItemImage_1, 1}},
+ {2041, {wxTreeCtrl, getItemImage_2, 2}},
+ {2042, {wxTreeCtrl, getItemText, 1}},
+ {2043, {wxTreeCtrl, getItemTextColour, 1}},
+ {2044, {wxTreeCtrl, getLastChild, 1}},
+ {2045, {wxTreeCtrl, getNextSibling, 1}},
+ {2046, {wxTreeCtrl, getNextVisible, 1}},
+ {2047, {wxTreeCtrl, getItemParent, 1}},
+ {2048, {wxTreeCtrl, getPrevSibling, 1}},
+ {2049, {wxTreeCtrl, getPrevVisible, 1}},
+ {2050, {wxTreeCtrl, getRootItem, 0}},
+ {2051, {wxTreeCtrl, getSelection, 0}},
+ {2052, {wxTreeCtrl, getSelections, 1}},
+ {2053, {wxTreeCtrl, getStateImageList, 0}},
+ {2054, {wxTreeCtrl, hitTest, 2}},
+ {2056, {wxTreeCtrl, insertItem, 4}},
+ {2057, {wxTreeCtrl, isBold, 1}},
+ {2058, {wxTreeCtrl, isExpanded, 1}},
+ {2059, {wxTreeCtrl, isSelected, 1}},
+ {2060, {wxTreeCtrl, isVisible, 1}},
+ {2061, {wxTreeCtrl, itemHasChildren, 1}},
+ {2062, {wxTreeCtrl, isTreeItemIdOk, 1}},
+ {2063, {wxTreeCtrl, prependItem, 3}},
+ {2064, {wxTreeCtrl, scrollTo, 1}},
+ {2065, {wxTreeCtrl, selectItem_1, 1}},
+ {2066, {wxTreeCtrl, selectItem_2, 2}},
+ {2067, {wxTreeCtrl, setIndent, 1}},
+ {2068, {wxTreeCtrl, setImageList, 1}},
+ {2069, {wxTreeCtrl, setItemBackgroundColour, 2}},
+ {2070, {wxTreeCtrl, setItemBold, 2}},
+ {2071, {wxTreeCtrl, setItemData, 2}},
+ {2072, {wxTreeCtrl, setItemDropHighlight, 2}},
+ {2073, {wxTreeCtrl, setItemFont, 2}},
+ {2074, {wxTreeCtrl, setItemHasChildren, 2}},
+ {2075, {wxTreeCtrl, setItemImage_2, 2}},
+ {2076, {wxTreeCtrl, setItemImage_3, 3}},
+ {2077, {wxTreeCtrl, setItemText, 2}},
+ {2078, {wxTreeCtrl, setItemTextColour, 2}},
+ {2079, {wxTreeCtrl, setStateImageList, 1}},
+ {2080, {wxTreeCtrl, setWindowStyle, 1}},
+ {2081, {wxTreeCtrl, sortChildren, 1}},
+ {2082, {wxTreeCtrl, toggle, 1}},
+ {2083, {wxTreeCtrl, toggleItemSelection, 1}},
+ {2084, {wxTreeCtrl, unselect, 0}},
+ {2085, {wxTreeCtrl, unselectAll, 0}},
+ {2086, {wxTreeCtrl, unselectItem, 1}},
+ {2087, {wxScrollBar, new_0, 0}},
+ {2088, {wxScrollBar, new_3, 3}},
+ {2089, {wxScrollBar, destruct, 0}},
+ {2090, {wxScrollBar, create, 3}},
+ {2091, {wxScrollBar, getRange, 0}},
+ {2092, {wxScrollBar, getPageSize, 0}},
+ {2093, {wxScrollBar, getThumbPosition, 0}},
+ {2094, {wxScrollBar, getThumbSize, 0}},
+ {2095, {wxScrollBar, setThumbPosition, 1}},
+ {2096, {wxScrollBar, setScrollbar, 5}},
+ {2098, {wxSpinButton, new_2, 2}},
+ {2099, {wxSpinButton, new_0, 0}},
+ {2100, {wxSpinButton, create, 2}},
+ {2101, {wxSpinButton, getMax, 0}},
+ {2102, {wxSpinButton, getMin, 0}},
+ {2103, {wxSpinButton, getValue, 0}},
+ {2104, {wxSpinButton, setRange, 2}},
+ {2105, {wxSpinButton, setValue, 1}},
+ {2106, {wxSpinButton, 'Destroy', undefined}},
+ {2107, {wxSpinCtrl, new_0, 0}},
+ {2108, {wxSpinCtrl, new_2, 2}},
+ {2110, {wxSpinCtrl, create, 2}},
+ {2113, {wxSpinCtrl, setValue_1_1, 1}},
+ {2114, {wxSpinCtrl, setValue_1_0, 1}},
+ {2116, {wxSpinCtrl, getValue, 0}},
+ {2118, {wxSpinCtrl, setRange, 2}},
+ {2119, {wxSpinCtrl, setSelection, 2}},
+ {2121, {wxSpinCtrl, getMin, 0}},
+ {2123, {wxSpinCtrl, getMax, 0}},
+ {2124, {wxSpinCtrl, 'Destroy', undefined}},
+ {2125, {wxStaticText, new_0, 0}},
+ {2126, {wxStaticText, new_4, 4}},
+ {2127, {wxStaticText, create, 4}},
+ {2128, {wxStaticText, getLabel, 0}},
+ {2129, {wxStaticText, setLabel, 1}},
+ {2130, {wxStaticText, wrap, 1}},
+ {2131, {wxStaticText, 'Destroy', undefined}},
+ {2132, {wxStaticBitmap, new_0, 0}},
+ {2133, {wxStaticBitmap, new_4, 4}},
+ {2134, {wxStaticBitmap, create, 4}},
+ {2135, {wxStaticBitmap, getBitmap, 0}},
+ {2136, {wxStaticBitmap, setBitmap, 1}},
+ {2137, {wxStaticBitmap, 'Destroy', undefined}},
+ {2138, {wxRadioBox, new, 7}},
+ {2140, {wxRadioBox, destruct, 0}},
+ {2141, {wxRadioBox, create, 7}},
+ {2142, {wxRadioBox, enable_2, 2}},
+ {2143, {wxRadioBox, enable_1, 1}},
+ {2144, {wxRadioBox, getSelection, 0}},
+ {2145, {wxRadioBox, getString, 1}},
+ {2146, {wxRadioBox, setSelection, 1}},
+ {2147, {wxRadioBox, show_2, 2}},
+ {2148, {wxRadioBox, show_1, 1}},
+ {2149, {wxRadioBox, getColumnCount, 0}},
+ {2150, {wxRadioBox, getItemHelpText, 1}},
+ {2151, {wxRadioBox, getItemToolTip, 1}},
+ {2153, {wxRadioBox, getItemFromPoint, 1}},
+ {2154, {wxRadioBox, getRowCount, 0}},
+ {2155, {wxRadioBox, isItemEnabled, 1}},
+ {2156, {wxRadioBox, isItemShown, 1}},
+ {2157, {wxRadioBox, setItemHelpText, 2}},
+ {2158, {wxRadioBox, setItemToolTip, 2}},
+ {2159, {wxRadioButton, new_0, 0}},
+ {2160, {wxRadioButton, new_4, 4}},
+ {2161, {wxRadioButton, create, 4}},
+ {2162, {wxRadioButton, getValue, 0}},
+ {2163, {wxRadioButton, setValue, 1}},
+ {2164, {wxRadioButton, 'Destroy', undefined}},
+ {2166, {wxSlider, new_6, 6}},
+ {2167, {wxSlider, new_0, 0}},
+ {2168, {wxSlider, create, 6}},
+ {2169, {wxSlider, getLineSize, 0}},
+ {2170, {wxSlider, getMax, 0}},
+ {2171, {wxSlider, getMin, 0}},
+ {2172, {wxSlider, getPageSize, 0}},
+ {2173, {wxSlider, getThumbLength, 0}},
+ {2174, {wxSlider, getValue, 0}},
+ {2175, {wxSlider, setLineSize, 1}},
+ {2176, {wxSlider, setPageSize, 1}},
+ {2177, {wxSlider, setRange, 2}},
+ {2178, {wxSlider, setThumbLength, 1}},
+ {2179, {wxSlider, setValue, 1}},
+ {2180, {wxSlider, 'Destroy', undefined}},
+ {2182, {wxDialog, new_4, 4}},
+ {2183, {wxDialog, new_0, 0}},
+ {2185, {wxDialog, destruct, 0}},
+ {2186, {wxDialog, create, 4}},
+ {2187, {wxDialog, createButtonSizer, 1}},
+ {2188, {wxDialog, createStdDialogButtonSizer, 1}},
+ {2189, {wxDialog, endModal, 1}},
+ {2190, {wxDialog, getAffirmativeId, 0}},
+ {2191, {wxDialog, getReturnCode, 0}},
+ {2192, {wxDialog, isModal, 0}},
+ {2193, {wxDialog, setAffirmativeId, 1}},
+ {2194, {wxDialog, setReturnCode, 1}},
+ {2195, {wxDialog, show, 1}},
+ {2196, {wxDialog, showModal, 0}},
+ {2197, {wxColourDialog, new_0, 0}},
+ {2198, {wxColourDialog, new_2, 2}},
+ {2199, {wxColourDialog, destruct, 0}},
+ {2200, {wxColourDialog, create, 2}},
+ {2201, {wxColourDialog, getColourData, 0}},
+ {2202, {wxColourData, new_0, 0}},
+ {2203, {wxColourData, new_1, 1}},
+ {2204, {wxColourData, destruct, 0}},
+ {2205, {wxColourData, getChooseFull, 0}},
+ {2206, {wxColourData, getColour, 0}},
+ {2208, {wxColourData, getCustomColour, 1}},
+ {2209, {wxColourData, setChooseFull, 1}},
+ {2210, {wxColourData, setColour, 1}},
+ {2211, {wxColourData, setCustomColour, 2}},
+ {2212, {wxPalette, new_0, 0}},
+ {2213, {wxPalette, new_4, 4}},
+ {2215, {wxPalette, destruct, 0}},
+ {2216, {wxPalette, create, 4}},
+ {2217, {wxPalette, getColoursCount, 0}},
+ {2218, {wxPalette, getPixel, 3}},
+ {2219, {wxPalette, getRGB, 4}},
+ {2220, {wxPalette, isOk, 0}},
+ {2224, {wxDirDialog, new, 2}},
+ {2225, {wxDirDialog, destruct, 0}},
+ {2226, {wxDirDialog, getPath, 0}},
+ {2227, {wxDirDialog, getMessage, 0}},
+ {2228, {wxDirDialog, setMessage, 1}},
+ {2229, {wxDirDialog, setPath, 1}},
+ {2233, {wxFileDialog, new, 2}},
+ {2234, {wxFileDialog, destruct, 0}},
+ {2235, {wxFileDialog, getDirectory, 0}},
+ {2236, {wxFileDialog, getFilename, 0}},
+ {2237, {wxFileDialog, getFilenames, 1}},
+ {2238, {wxFileDialog, getFilterIndex, 0}},
+ {2239, {wxFileDialog, getMessage, 0}},
+ {2240, {wxFileDialog, getPath, 0}},
+ {2241, {wxFileDialog, getPaths, 1}},
+ {2242, {wxFileDialog, getWildcard, 0}},
+ {2243, {wxFileDialog, setDirectory, 1}},
+ {2244, {wxFileDialog, setFilename, 1}},
+ {2245, {wxFileDialog, setFilterIndex, 1}},
+ {2246, {wxFileDialog, setMessage, 1}},
+ {2247, {wxFileDialog, setPath, 1}},
+ {2248, {wxFileDialog, setWildcard, 1}},
+ {2249, {wxPickerBase, setInternalMargin, 1}},
+ {2250, {wxPickerBase, getInternalMargin, 0}},
+ {2251, {wxPickerBase, setTextCtrlProportion, 1}},
+ {2252, {wxPickerBase, setPickerCtrlProportion, 1}},
+ {2253, {wxPickerBase, getTextCtrlProportion, 0}},
+ {2254, {wxPickerBase, getPickerCtrlProportion, 0}},
+ {2255, {wxPickerBase, hasTextCtrl, 0}},
+ {2256, {wxPickerBase, getTextCtrl, 0}},
+ {2257, {wxPickerBase, isTextCtrlGrowable, 0}},
+ {2258, {wxPickerBase, setPickerCtrlGrowable, 1}},
+ {2259, {wxPickerBase, setTextCtrlGrowable, 1}},
+ {2260, {wxPickerBase, isPickerCtrlGrowable, 0}},
+ {2261, {wxFilePickerCtrl, new_0, 0}},
+ {2262, {wxFilePickerCtrl, new_3, 3}},
+ {2263, {wxFilePickerCtrl, create, 3}},
+ {2264, {wxFilePickerCtrl, getPath, 0}},
+ {2265, {wxFilePickerCtrl, setPath, 1}},
+ {2266, {wxFilePickerCtrl, 'Destroy', undefined}},
+ {2267, {wxDirPickerCtrl, new_0, 0}},
+ {2268, {wxDirPickerCtrl, new_3, 3}},
+ {2269, {wxDirPickerCtrl, create, 3}},
+ {2270, {wxDirPickerCtrl, getPath, 0}},
+ {2271, {wxDirPickerCtrl, setPath, 1}},
+ {2272, {wxDirPickerCtrl, 'Destroy', undefined}},
+ {2273, {wxColourPickerCtrl, new_0, 0}},
+ {2274, {wxColourPickerCtrl, new_3, 3}},
+ {2275, {wxColourPickerCtrl, create, 3}},
+ {2276, {wxColourPickerCtrl, getColour, 0}},
+ {2277, {wxColourPickerCtrl, setColour_1_1, 1}},
+ {2278, {wxColourPickerCtrl, setColour_1_0, 1}},
+ {2279, {wxColourPickerCtrl, 'Destroy', undefined}},
+ {2280, {wxDatePickerCtrl, new_0, 0}},
+ {2281, {wxDatePickerCtrl, new_3, 3}},
+ {2282, {wxDatePickerCtrl, getRange, 2}},
+ {2283, {wxDatePickerCtrl, getValue, 0}},
+ {2284, {wxDatePickerCtrl, setRange, 2}},
+ {2285, {wxDatePickerCtrl, setValue, 1}},
+ {2286, {wxDatePickerCtrl, 'Destroy', undefined}},
+ {2287, {wxFontPickerCtrl, new_0, 0}},
+ {2288, {wxFontPickerCtrl, new_3, 3}},
+ {2289, {wxFontPickerCtrl, create, 3}},
+ {2290, {wxFontPickerCtrl, getSelectedFont, 0}},
+ {2291, {wxFontPickerCtrl, setSelectedFont, 1}},
+ {2292, {wxFontPickerCtrl, getMaxPointSize, 0}},
+ {2293, {wxFontPickerCtrl, setMaxPointSize, 1}},
+ {2294, {wxFontPickerCtrl, 'Destroy', undefined}},
+ {2297, {wxFindReplaceDialog, new_0, 0}},
+ {2298, {wxFindReplaceDialog, new_4, 4}},
+ {2299, {wxFindReplaceDialog, destruct, 0}},
+ {2300, {wxFindReplaceDialog, create, 4}},
+ {2301, {wxFindReplaceDialog, getData, 0}},
+ {2302, {wxFindReplaceData, new_0, 0}},
+ {2303, {wxFindReplaceData, new_1, 1}},
+ {2304, {wxFindReplaceData, getFindString, 0}},
+ {2305, {wxFindReplaceData, getReplaceString, 0}},
+ {2306, {wxFindReplaceData, getFlags, 0}},
+ {2307, {wxFindReplaceData, setFlags, 1}},
+ {2308, {wxFindReplaceData, setFindString, 1}},
+ {2309, {wxFindReplaceData, setReplaceString, 1}},
+ {2310, {wxFindReplaceData, 'Destroy', undefined}},
+ {2311, {wxMultiChoiceDialog, new_0, 0}},
+ {2313, {wxMultiChoiceDialog, new_5, 5}},
+ {2314, {wxMultiChoiceDialog, getSelections, 0}},
+ {2315, {wxMultiChoiceDialog, setSelections, 1}},
+ {2316, {wxMultiChoiceDialog, 'Destroy', undefined}},
+ {2317, {wxSingleChoiceDialog, new_0, 0}},
+ {2319, {wxSingleChoiceDialog, new_5, 5}},
+ {2320, {wxSingleChoiceDialog, getSelection, 0}},
+ {2321, {wxSingleChoiceDialog, getStringSelection, 0}},
+ {2322, {wxSingleChoiceDialog, setSelection, 1}},
+ {2323, {wxSingleChoiceDialog, 'Destroy', undefined}},
+ {2324, {wxTextEntryDialog, new, 3}},
+ {2325, {wxTextEntryDialog, getValue, 0}},
+ {2326, {wxTextEntryDialog, setValue, 1}},
+ {2327, {wxTextEntryDialog, 'Destroy', undefined}},
+ {2328, {wxPasswordEntryDialog, new, 3}},
+ {2329, {wxPasswordEntryDialog, 'Destroy', undefined}},
+ {2330, {wxFontData, new_0, 0}},
+ {2331, {wxFontData, new_1, 1}},
+ {2332, {wxFontData, destruct, 0}},
+ {2333, {wxFontData, enableEffects, 1}},
+ {2334, {wxFontData, getAllowSymbols, 0}},
+ {2335, {wxFontData, getColour, 0}},
+ {2336, {wxFontData, getChosenFont, 0}},
+ {2337, {wxFontData, getEnableEffects, 0}},
+ {2338, {wxFontData, getInitialFont, 0}},
+ {2339, {wxFontData, getShowHelp, 0}},
+ {2340, {wxFontData, setAllowSymbols, 1}},
+ {2341, {wxFontData, setChosenFont, 1}},
+ {2342, {wxFontData, setColour, 1}},
+ {2343, {wxFontData, setInitialFont, 1}},
+ {2344, {wxFontData, setRange, 2}},
+ {2345, {wxFontData, setShowHelp, 1}},
+ {2349, {wxFontDialog, new_0, 0}},
+ {2351, {wxFontDialog, new_2, 2}},
+ {2353, {wxFontDialog, create, 2}},
+ {2354, {wxFontDialog, getFontData, 0}},
+ {2356, {wxFontDialog, 'Destroy', undefined}},
+ {2357, {wxProgressDialog, new, 3}},
+ {2358, {wxProgressDialog, destruct, 0}},
+ {2359, {wxProgressDialog, resume, 0}},
+ {2360, {wxProgressDialog, update_2, 2}},
+ {2361, {wxProgressDialog, update_0, 0}},
+ {2362, {wxMessageDialog, new, 3}},
+ {2363, {wxMessageDialog, destruct, 0}},
+ {2364, {wxPageSetupDialog, new, 2}},
+ {2365, {wxPageSetupDialog, destruct, 0}},
+ {2366, {wxPageSetupDialog, getPageSetupData, 0}},
+ {2367, {wxPageSetupDialog, showModal, 0}},
+ {2368, {wxPageSetupDialogData, new_0, 0}},
+ {2369, {wxPageSetupDialogData, new_1_0, 1}},
+ {2370, {wxPageSetupDialogData, new_1_1, 1}},
+ {2371, {wxPageSetupDialogData, destruct, 0}},
+ {2372, {wxPageSetupDialogData, enableHelp, 1}},
+ {2373, {wxPageSetupDialogData, enableMargins, 1}},
+ {2374, {wxPageSetupDialogData, enableOrientation, 1}},
+ {2375, {wxPageSetupDialogData, enablePaper, 1}},
+ {2376, {wxPageSetupDialogData, enablePrinter, 1}},
+ {2377, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
+ {2378, {wxPageSetupDialogData, getEnableMargins, 0}},
+ {2379, {wxPageSetupDialogData, getEnableOrientation, 0}},
+ {2380, {wxPageSetupDialogData, getEnablePaper, 0}},
+ {2381, {wxPageSetupDialogData, getEnablePrinter, 0}},
+ {2382, {wxPageSetupDialogData, getEnableHelp, 0}},
+ {2383, {wxPageSetupDialogData, getDefaultInfo, 0}},
+ {2384, {wxPageSetupDialogData, getMarginTopLeft, 0}},
+ {2385, {wxPageSetupDialogData, getMarginBottomRight, 0}},
+ {2386, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
+ {2387, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
+ {2388, {wxPageSetupDialogData, getPaperId, 0}},
+ {2389, {wxPageSetupDialogData, getPaperSize, 0}},
+ {2391, {wxPageSetupDialogData, getPrintData, 0}},
+ {2392, {wxPageSetupDialogData, isOk, 0}},
+ {2393, {wxPageSetupDialogData, setDefaultInfo, 1}},
+ {2394, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
+ {2395, {wxPageSetupDialogData, setMarginTopLeft, 1}},
+ {2396, {wxPageSetupDialogData, setMarginBottomRight, 1}},
+ {2397, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
+ {2398, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
+ {2399, {wxPageSetupDialogData, setPaperId, 1}},
+ {2400, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
+ {2401, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
+ {2402, {wxPageSetupDialogData, setPrintData, 1}},
+ {2403, {wxPrintDialog, new_2_0, 2}},
+ {2404, {wxPrintDialog, new_2_1, 2}},
+ {2405, {wxPrintDialog, destruct, 0}},
+ {2406, {wxPrintDialog, getPrintDialogData, 0}},
+ {2407, {wxPrintDialog, getPrintDC, 0}},
+ {2408, {wxPrintDialogData, new_0, 0}},
+ {2409, {wxPrintDialogData, new_1_1, 1}},
+ {2410, {wxPrintDialogData, new_1_0, 1}},
+ {2411, {wxPrintDialogData, destruct, 0}},
+ {2412, {wxPrintDialogData, enableHelp, 1}},
+ {2413, {wxPrintDialogData, enablePageNumbers, 1}},
+ {2414, {wxPrintDialogData, enablePrintToFile, 1}},
+ {2415, {wxPrintDialogData, enableSelection, 1}},
+ {2416, {wxPrintDialogData, getAllPages, 0}},
+ {2417, {wxPrintDialogData, getCollate, 0}},
+ {2418, {wxPrintDialogData, getFromPage, 0}},
+ {2419, {wxPrintDialogData, getMaxPage, 0}},
+ {2420, {wxPrintDialogData, getMinPage, 0}},
+ {2421, {wxPrintDialogData, getNoCopies, 0}},
+ {2422, {wxPrintDialogData, getPrintData, 0}},
+ {2423, {wxPrintDialogData, getPrintToFile, 0}},
+ {2424, {wxPrintDialogData, getSelection, 0}},
+ {2425, {wxPrintDialogData, getToPage, 0}},
+ {2426, {wxPrintDialogData, isOk, 0}},
+ {2427, {wxPrintDialogData, setCollate, 1}},
+ {2428, {wxPrintDialogData, setFromPage, 1}},
+ {2429, {wxPrintDialogData, setMaxPage, 1}},
+ {2430, {wxPrintDialogData, setMinPage, 1}},
+ {2431, {wxPrintDialogData, setNoCopies, 1}},
+ {2432, {wxPrintDialogData, setPrintData, 1}},
+ {2433, {wxPrintDialogData, setPrintToFile, 1}},
+ {2434, {wxPrintDialogData, setSelection, 1}},
+ {2435, {wxPrintDialogData, setToPage, 1}},
+ {2436, {wxPrintData, new_0, 0}},
+ {2437, {wxPrintData, new_1, 1}},
+ {2438, {wxPrintData, destruct, 0}},
+ {2439, {wxPrintData, getCollate, 0}},
+ {2440, {wxPrintData, getBin, 0}},
+ {2441, {wxPrintData, getColour, 0}},
+ {2442, {wxPrintData, getDuplex, 0}},
+ {2443, {wxPrintData, getNoCopies, 0}},
+ {2444, {wxPrintData, getOrientation, 0}},
+ {2445, {wxPrintData, getPaperId, 0}},
+ {2446, {wxPrintData, getPrinterName, 0}},
+ {2447, {wxPrintData, getQuality, 0}},
+ {2448, {wxPrintData, isOk, 0}},
+ {2449, {wxPrintData, setBin, 1}},
+ {2450, {wxPrintData, setCollate, 1}},
+ {2451, {wxPrintData, setColour, 1}},
+ {2452, {wxPrintData, setDuplex, 1}},
+ {2453, {wxPrintData, setNoCopies, 1}},
+ {2454, {wxPrintData, setOrientation, 1}},
+ {2455, {wxPrintData, setPaperId, 1}},
+ {2456, {wxPrintData, setPrinterName, 1}},
+ {2457, {wxPrintData, setQuality, 1}},
+ {2460, {wxPrintPreview, new_2, 2}},
+ {2461, {wxPrintPreview, new_3, 3}},
+ {2463, {wxPrintPreview, destruct, 0}},
+ {2464, {wxPrintPreview, getCanvas, 0}},
+ {2465, {wxPrintPreview, getCurrentPage, 0}},
+ {2466, {wxPrintPreview, getFrame, 0}},
+ {2467, {wxPrintPreview, getMaxPage, 0}},
+ {2468, {wxPrintPreview, getMinPage, 0}},
+ {2469, {wxPrintPreview, getPrintout, 0}},
+ {2470, {wxPrintPreview, getPrintoutForPrinting, 0}},
+ {2471, {wxPrintPreview, isOk, 0}},
+ {2472, {wxPrintPreview, paintPage, 2}},
+ {2473, {wxPrintPreview, print, 1}},
+ {2474, {wxPrintPreview, renderPage, 1}},
+ {2475, {wxPrintPreview, setCanvas, 1}},
+ {2476, {wxPrintPreview, setCurrentPage, 1}},
+ {2477, {wxPrintPreview, setFrame, 1}},
+ {2478, {wxPrintPreview, setPrintout, 1}},
+ {2479, {wxPrintPreview, setZoom, 1}},
+ {2480, {wxPreviewFrame, new, 3}},
+ {2481, {wxPreviewFrame, destruct, 0}},
+ {2482, {wxPreviewFrame, createControlBar, 0}},
+ {2483, {wxPreviewFrame, createCanvas, 0}},
+ {2484, {wxPreviewFrame, initialize, 0}},
+ {2485, {wxPreviewFrame, onCloseWindow, 1}},
+ {2486, {wxPreviewControlBar, new, 4}},
+ {2487, {wxPreviewControlBar, destruct, 0}},
+ {2488, {wxPreviewControlBar, createButtons, 0}},
+ {2489, {wxPreviewControlBar, getPrintPreview, 0}},
+ {2490, {wxPreviewControlBar, getZoomControl, 0}},
+ {2491, {wxPreviewControlBar, setZoomControl, 1}},
+ {2493, {wxPrinter, new, 1}},
+ {2494, {wxPrinter, createAbortWindow, 2}},
+ {2495, {wxPrinter, getAbort, 0}},
+ {2496, {wxPrinter, getLastError, 0}},
+ {2497, {wxPrinter, getPrintDialogData, 0}},
+ {2498, {wxPrinter, print, 3}},
+ {2499, {wxPrinter, printDialog, 1}},
+ {2500, {wxPrinter, reportError, 3}},
+ {2501, {wxPrinter, setup, 1}},
+ {2502, {wxPrinter, 'Destroy', undefined}},
+ {2503, {wxXmlResource, new_1, 1}},
+ {2504, {wxXmlResource, new_2, 2}},
+ {2505, {wxXmlResource, destruct, 0}},
+ {2506, {wxXmlResource, attachUnknownControl, 3}},
+ {2507, {wxXmlResource, clearHandlers, 0}},
+ {2508, {wxXmlResource, compareVersion, 4}},
+ {2509, {wxXmlResource, get, 0}},
+ {2510, {wxXmlResource, getFlags, 0}},
+ {2511, {wxXmlResource, getVersion, 0}},
+ {2512, {wxXmlResource, getXRCID, 2}},
+ {2513, {wxXmlResource, initAllHandlers, 0}},
+ {2514, {wxXmlResource, load, 1}},
+ {2515, {wxXmlResource, loadBitmap, 1}},
+ {2516, {wxXmlResource, loadDialog_2, 2}},
+ {2517, {wxXmlResource, loadDialog_3, 3}},
+ {2518, {wxXmlResource, loadFrame_2, 2}},
+ {2519, {wxXmlResource, loadFrame_3, 3}},
+ {2520, {wxXmlResource, loadIcon, 1}},
+ {2521, {wxXmlResource, loadMenu, 1}},
+ {2522, {wxXmlResource, loadMenuBar_2, 2}},
+ {2523, {wxXmlResource, loadMenuBar_1, 1}},
+ {2524, {wxXmlResource, loadPanel_2, 2}},
+ {2525, {wxXmlResource, loadPanel_3, 3}},
+ {2526, {wxXmlResource, loadToolBar, 2}},
+ {2527, {wxXmlResource, set, 1}},
+ {2528, {wxXmlResource, setFlags, 1}},
+ {2529, {wxXmlResource, unload, 1}},
+ {2530, {wxXmlResource, xrcctrl, 3}},
+ {2531, {wxHtmlEasyPrinting, new, 1}},
+ {2532, {wxHtmlEasyPrinting, destruct, 0}},
+ {2533, {wxHtmlEasyPrinting, getPrintData, 0}},
+ {2534, {wxHtmlEasyPrinting, getPageSetupData, 0}},
+ {2535, {wxHtmlEasyPrinting, previewFile, 1}},
+ {2536, {wxHtmlEasyPrinting, previewText, 2}},
+ {2537, {wxHtmlEasyPrinting, printFile, 1}},
+ {2538, {wxHtmlEasyPrinting, printText, 2}},
+ {2539, {wxHtmlEasyPrinting, pageSetup, 0}},
+ {2540, {wxHtmlEasyPrinting, setFonts, 3}},
+ {2541, {wxHtmlEasyPrinting, setHeader, 2}},
+ {2542, {wxHtmlEasyPrinting, setFooter, 2}},
+ {2544, {wxGLCanvas, new_2, 2}},
+ {2545, {wxGLCanvas, new_3_1, 3}},
+ {2546, {wxGLCanvas, new_3_0, 3}},
+ {2547, {wxGLCanvas, getContext, 0}},
+ {2549, {wxGLCanvas, setCurrent, 0}},
+ {2550, {wxGLCanvas, swapBuffers, 0}},
+ {2551, {wxGLCanvas, 'Destroy', undefined}},
+ {2552, {wxAuiManager, new, 1}},
+ {2553, {wxAuiManager, destruct, 0}},
+ {2554, {wxAuiManager, addPane_2_1, 2}},
+ {2555, {wxAuiManager, addPane_3, 3}},
+ {2556, {wxAuiManager, addPane_2_0, 2}},
+ {2557, {wxAuiManager, detachPane, 1}},
+ {2558, {wxAuiManager, getAllPanes, 0}},
+ {2559, {wxAuiManager, getArtProvider, 0}},
+ {2560, {wxAuiManager, getDockSizeConstraint, 2}},
+ {2561, {wxAuiManager, getFlags, 0}},
+ {2562, {wxAuiManager, getManagedWindow, 0}},
+ {2563, {wxAuiManager, getManager, 1}},
+ {2564, {wxAuiManager, getPane_1_1, 1}},
+ {2565, {wxAuiManager, getPane_1_0, 1}},
+ {2566, {wxAuiManager, hideHint, 0}},
+ {2567, {wxAuiManager, insertPane, 3}},
+ {2568, {wxAuiManager, loadPaneInfo, 2}},
+ {2569, {wxAuiManager, loadPerspective, 2}},
+ {2570, {wxAuiManager, savePaneInfo, 1}},
+ {2571, {wxAuiManager, savePerspective, 0}},
+ {2572, {wxAuiManager, setArtProvider, 1}},
+ {2573, {wxAuiManager, setDockSizeConstraint, 2}},
+ {2574, {wxAuiManager, setFlags, 1}},
+ {2575, {wxAuiManager, setManagedWindow, 1}},
+ {2576, {wxAuiManager, showHint, 1}},
+ {2577, {wxAuiManager, unInit, 0}},
+ {2578, {wxAuiManager, update, 0}},
+ {2579, {wxAuiPaneInfo, new_0, 0}},
+ {2580, {wxAuiPaneInfo, new_1, 1}},
+ {2581, {wxAuiPaneInfo, destruct, 0}},
+ {2582, {wxAuiPaneInfo, bestSize_1, 1}},
+ {2583, {wxAuiPaneInfo, bestSize_2, 2}},
+ {2584, {wxAuiPaneInfo, bottom, 0}},
+ {2585, {wxAuiPaneInfo, bottomDockable, 1}},
+ {2586, {wxAuiPaneInfo, caption, 1}},
+ {2587, {wxAuiPaneInfo, captionVisible, 1}},
+ {2588, {wxAuiPaneInfo, centre, 0}},
+ {2589, {wxAuiPaneInfo, centrePane, 0}},
+ {2590, {wxAuiPaneInfo, closeButton, 1}},
+ {2591, {wxAuiPaneInfo, defaultPane, 0}},
+ {2592, {wxAuiPaneInfo, destroyOnClose, 1}},
+ {2593, {wxAuiPaneInfo, direction, 1}},
+ {2594, {wxAuiPaneInfo, dock, 0}},
+ {2595, {wxAuiPaneInfo, dockable, 1}},
+ {2596, {wxAuiPaneInfo, fixed, 0}},
+ {2597, {wxAuiPaneInfo, float, 0}},
+ {2598, {wxAuiPaneInfo, floatable, 1}},
+ {2599, {wxAuiPaneInfo, floatingPosition_1, 1}},
+ {2600, {wxAuiPaneInfo, floatingPosition_2, 2}},
+ {2601, {wxAuiPaneInfo, floatingSize_1, 1}},
+ {2602, {wxAuiPaneInfo, floatingSize_2, 2}},
+ {2603, {wxAuiPaneInfo, gripper, 1}},
+ {2604, {wxAuiPaneInfo, gripperTop, 1}},
+ {2605, {wxAuiPaneInfo, hasBorder, 0}},
+ {2606, {wxAuiPaneInfo, hasCaption, 0}},
+ {2607, {wxAuiPaneInfo, hasCloseButton, 0}},
+ {2608, {wxAuiPaneInfo, hasFlag, 1}},
+ {2609, {wxAuiPaneInfo, hasGripper, 0}},
+ {2610, {wxAuiPaneInfo, hasGripperTop, 0}},
+ {2611, {wxAuiPaneInfo, hasMaximizeButton, 0}},
+ {2612, {wxAuiPaneInfo, hasMinimizeButton, 0}},
+ {2613, {wxAuiPaneInfo, hasPinButton, 0}},
+ {2614, {wxAuiPaneInfo, hide, 0}},
+ {2615, {wxAuiPaneInfo, isBottomDockable, 0}},
+ {2616, {wxAuiPaneInfo, isDocked, 0}},
+ {2617, {wxAuiPaneInfo, isFixed, 0}},
+ {2618, {wxAuiPaneInfo, isFloatable, 0}},
+ {2619, {wxAuiPaneInfo, isFloating, 0}},
+ {2620, {wxAuiPaneInfo, isLeftDockable, 0}},
+ {2621, {wxAuiPaneInfo, isMovable, 0}},
+ {2622, {wxAuiPaneInfo, isOk, 0}},
+ {2623, {wxAuiPaneInfo, isResizable, 0}},
+ {2624, {wxAuiPaneInfo, isRightDockable, 0}},
+ {2625, {wxAuiPaneInfo, isShown, 0}},
+ {2626, {wxAuiPaneInfo, isToolbar, 0}},
+ {2627, {wxAuiPaneInfo, isTopDockable, 0}},
+ {2628, {wxAuiPaneInfo, layer, 1}},
+ {2629, {wxAuiPaneInfo, left, 0}},
+ {2630, {wxAuiPaneInfo, leftDockable, 1}},
+ {2631, {wxAuiPaneInfo, maxSize_1, 1}},
+ {2632, {wxAuiPaneInfo, maxSize_2, 2}},
+ {2633, {wxAuiPaneInfo, maximizeButton, 1}},
+ {2634, {wxAuiPaneInfo, minSize_1, 1}},
+ {2635, {wxAuiPaneInfo, minSize_2, 2}},
+ {2636, {wxAuiPaneInfo, minimizeButton, 1}},
+ {2637, {wxAuiPaneInfo, movable, 1}},
+ {2638, {wxAuiPaneInfo, name, 1}},
+ {2639, {wxAuiPaneInfo, paneBorder, 1}},
+ {2640, {wxAuiPaneInfo, pinButton, 1}},
+ {2641, {wxAuiPaneInfo, position, 1}},
+ {2642, {wxAuiPaneInfo, resizable, 1}},
+ {2643, {wxAuiPaneInfo, right, 0}},
+ {2644, {wxAuiPaneInfo, rightDockable, 1}},
+ {2645, {wxAuiPaneInfo, row, 1}},
+ {2646, {wxAuiPaneInfo, safeSet, 1}},
+ {2647, {wxAuiPaneInfo, setFlag, 2}},
+ {2648, {wxAuiPaneInfo, show, 1}},
+ {2649, {wxAuiPaneInfo, toolbarPane, 0}},
+ {2650, {wxAuiPaneInfo, top, 0}},
+ {2651, {wxAuiPaneInfo, topDockable, 1}},
+ {2652, {wxAuiPaneInfo, window, 1}},
+ {2653, {wxAuiNotebook, new_0, 0}},
+ {2654, {wxAuiNotebook, new_2, 2}},
+ {2655, {wxAuiNotebook, addPage, 3}},
+ {2656, {wxAuiNotebook, create, 2}},
+ {2657, {wxAuiNotebook, deletePage, 1}},
+ {2658, {wxAuiNotebook, getArtProvider, 0}},
+ {2659, {wxAuiNotebook, getPage, 1}},
+ {2660, {wxAuiNotebook, getPageBitmap, 1}},
+ {2661, {wxAuiNotebook, getPageCount, 0}},
+ {2662, {wxAuiNotebook, getPageIndex, 1}},
+ {2663, {wxAuiNotebook, getPageText, 1}},
+ {2664, {wxAuiNotebook, getSelection, 0}},
+ {2665, {wxAuiNotebook, insertPage, 4}},
+ {2666, {wxAuiNotebook, removePage, 1}},
+ {2667, {wxAuiNotebook, setArtProvider, 1}},
+ {2668, {wxAuiNotebook, setFont, 1}},
+ {2669, {wxAuiNotebook, setPageBitmap, 2}},
+ {2670, {wxAuiNotebook, setPageText, 2}},
+ {2671, {wxAuiNotebook, setSelection, 1}},
+ {2672, {wxAuiNotebook, setTabCtrlHeight, 1}},
+ {2673, {wxAuiNotebook, setUniformBitmapSize, 1}},
+ {2674, {wxAuiNotebook, 'Destroy', undefined}},
+ {2675, {wxMDIParentFrame, new_0, 0}},
+ {2676, {wxMDIParentFrame, new_4, 4}},
+ {2677, {wxMDIParentFrame, destruct, 0}},
+ {2678, {wxMDIParentFrame, activateNext, 0}},
+ {2679, {wxMDIParentFrame, activatePrevious, 0}},
+ {2680, {wxMDIParentFrame, arrangeIcons, 0}},
+ {2681, {wxMDIParentFrame, cascade, 0}},
+ {2682, {wxMDIParentFrame, create, 4}},
+ {2683, {wxMDIParentFrame, getActiveChild, 0}},
+ {2684, {wxMDIParentFrame, getClientWindow, 0}},
+ {2685, {wxMDIParentFrame, tile, 1}},
+ {2686, {wxMDIChildFrame, new_0, 0}},
+ {2687, {wxMDIChildFrame, new_4, 4}},
+ {2688, {wxMDIChildFrame, destruct, 0}},
+ {2689, {wxMDIChildFrame, activate, 0}},
+ {2690, {wxMDIChildFrame, create, 4}},
+ {2691, {wxMDIChildFrame, maximize, 1}},
+ {2692, {wxMDIChildFrame, restore, 0}},
+ {2693, {wxMDIClientWindow, new_0, 0}},
+ {2694, {wxMDIClientWindow, new_2, 2}},
+ {2695, {wxMDIClientWindow, destruct, 0}},
+ {2696, {wxMDIClientWindow, createClient, 2}},
+ {2697, {wxLayoutAlgorithm, new, 0}},
+ {2698, {wxLayoutAlgorithm, layoutFrame, 2}},
+ {2699, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
+ {2700, {wxLayoutAlgorithm, layoutWindow, 2}},
+ {2701, {wxLayoutAlgorithm, 'Destroy', undefined}},
+ {2702, {wxEvent, getId, 0}},
+ {2703, {wxEvent, getSkipped, 0}},
+ {2704, {wxEvent, getTimestamp, 0}},
+ {2705, {wxEvent, isCommandEvent, 0}},
+ {2706, {wxEvent, resumePropagation, 1}},
+ {2707, {wxEvent, shouldPropagate, 0}},
+ {2708, {wxEvent, skip, 1}},
+ {2709, {wxEvent, stopPropagation, 0}},
+ {2710, {wxCommandEvent, getClientData, 0}},
+ {2711, {wxCommandEvent, getExtraLong, 0}},
+ {2712, {wxCommandEvent, getInt, 0}},
+ {2713, {wxCommandEvent, getSelection, 0}},
+ {2714, {wxCommandEvent, getString, 0}},
+ {2715, {wxCommandEvent, isChecked, 0}},
+ {2716, {wxCommandEvent, isSelection, 0}},
+ {2717, {wxCommandEvent, setInt, 1}},
+ {2718, {wxCommandEvent, setString, 1}},
+ {2719, {wxScrollEvent, getOrientation, 0}},
+ {2720, {wxScrollEvent, getPosition, 0}},
+ {2721, {wxScrollWinEvent, getOrientation, 0}},
+ {2722, {wxScrollWinEvent, getPosition, 0}},
+ {2723, {wxMouseEvent, altDown, 0}},
+ {2724, {wxMouseEvent, button, 1}},
+ {2725, {wxMouseEvent, buttonDClick, 1}},
+ {2726, {wxMouseEvent, buttonDown, 1}},
+ {2727, {wxMouseEvent, buttonUp, 1}},
+ {2728, {wxMouseEvent, cmdDown, 0}},
+ {2729, {wxMouseEvent, controlDown, 0}},
+ {2730, {wxMouseEvent, dragging, 0}},
+ {2731, {wxMouseEvent, entering, 0}},
+ {2732, {wxMouseEvent, getButton, 0}},
+ {2735, {wxMouseEvent, getPosition, 0}},
+ {2736, {wxMouseEvent, getLogicalPosition, 1}},
+ {2737, {wxMouseEvent, getLinesPerAction, 0}},
+ {2738, {wxMouseEvent, getWheelRotation, 0}},
+ {2739, {wxMouseEvent, getWheelDelta, 0}},
+ {2740, {wxMouseEvent, getX, 0}},
+ {2741, {wxMouseEvent, getY, 0}},
+ {2742, {wxMouseEvent, isButton, 0}},
+ {2743, {wxMouseEvent, isPageScroll, 0}},
+ {2744, {wxMouseEvent, leaving, 0}},
+ {2745, {wxMouseEvent, leftDClick, 0}},
+ {2746, {wxMouseEvent, leftDown, 0}},
+ {2747, {wxMouseEvent, leftIsDown, 0}},
+ {2748, {wxMouseEvent, leftUp, 0}},
+ {2749, {wxMouseEvent, metaDown, 0}},
+ {2750, {wxMouseEvent, middleDClick, 0}},
+ {2751, {wxMouseEvent, middleDown, 0}},
+ {2752, {wxMouseEvent, middleIsDown, 0}},
+ {2753, {wxMouseEvent, middleUp, 0}},
+ {2754, {wxMouseEvent, moving, 0}},
+ {2755, {wxMouseEvent, rightDClick, 0}},
+ {2756, {wxMouseEvent, rightDown, 0}},
+ {2757, {wxMouseEvent, rightIsDown, 0}},
+ {2758, {wxMouseEvent, rightUp, 0}},
+ {2759, {wxMouseEvent, shiftDown, 0}},
+ {2760, {wxSetCursorEvent, getCursor, 0}},
+ {2761, {wxSetCursorEvent, getX, 0}},
+ {2762, {wxSetCursorEvent, getY, 0}},
+ {2763, {wxSetCursorEvent, hasCursor, 0}},
+ {2764, {wxSetCursorEvent, setCursor, 1}},
+ {2765, {wxKeyEvent, altDown, 0}},
+ {2766, {wxKeyEvent, cmdDown, 0}},
+ {2767, {wxKeyEvent, controlDown, 0}},
+ {2768, {wxKeyEvent, getKeyCode, 0}},
+ {2769, {wxKeyEvent, getModifiers, 0}},
+ {2772, {wxKeyEvent, getPosition, 0}},
+ {2773, {wxKeyEvent, getRawKeyCode, 0}},
+ {2774, {wxKeyEvent, getRawKeyFlags, 0}},
+ {2775, {wxKeyEvent, getUnicodeKey, 0}},
+ {2776, {wxKeyEvent, getX, 0}},
+ {2777, {wxKeyEvent, getY, 0}},
+ {2778, {wxKeyEvent, hasModifiers, 0}},
+ {2779, {wxKeyEvent, metaDown, 0}},
+ {2780, {wxKeyEvent, shiftDown, 0}},
+ {2781, {wxSizeEvent, getSize, 0}},
+ {2782, {wxMoveEvent, getPosition, 0}},
+ {2783, {wxEraseEvent, getDC, 0}},
+ {2784, {wxFocusEvent, getWindow, 0}},
+ {2785, {wxChildFocusEvent, getWindow, 0}},
+ {2786, {wxMenuEvent, getMenu, 0}},
+ {2787, {wxMenuEvent, getMenuId, 0}},
+ {2788, {wxMenuEvent, isPopup, 0}},
+ {2789, {wxCloseEvent, canVeto, 0}},
+ {2790, {wxCloseEvent, getLoggingOff, 0}},
+ {2791, {wxCloseEvent, setCanVeto, 1}},
+ {2792, {wxCloseEvent, setLoggingOff, 1}},
+ {2793, {wxCloseEvent, veto, 1}},
+ {2794, {wxShowEvent, setShow, 1}},
+ {2795, {wxShowEvent, getShow, 0}},
+ {2796, {wxIconizeEvent, iconized, 0}},
+ {2797, {wxJoystickEvent, buttonDown, 1}},
+ {2798, {wxJoystickEvent, buttonIsDown, 1}},
+ {2799, {wxJoystickEvent, buttonUp, 1}},
+ {2800, {wxJoystickEvent, getButtonChange, 0}},
+ {2801, {wxJoystickEvent, getButtonState, 0}},
+ {2802, {wxJoystickEvent, getJoystick, 0}},
+ {2803, {wxJoystickEvent, getPosition, 0}},
+ {2804, {wxJoystickEvent, getZPosition, 0}},
+ {2805, {wxJoystickEvent, isButton, 0}},
+ {2806, {wxJoystickEvent, isMove, 0}},
+ {2807, {wxJoystickEvent, isZMove, 0}},
+ {2808, {wxUpdateUIEvent, canUpdate, 1}},
+ {2809, {wxUpdateUIEvent, check, 1}},
+ {2810, {wxUpdateUIEvent, enable, 1}},
+ {2811, {wxUpdateUIEvent, show, 1}},
+ {2812, {wxUpdateUIEvent, getChecked, 0}},
+ {2813, {wxUpdateUIEvent, getEnabled, 0}},
+ {2814, {wxUpdateUIEvent, getShown, 0}},
+ {2815, {wxUpdateUIEvent, getSetChecked, 0}},
+ {2816, {wxUpdateUIEvent, getSetEnabled, 0}},
+ {2817, {wxUpdateUIEvent, getSetShown, 0}},
+ {2818, {wxUpdateUIEvent, getSetText, 0}},
+ {2819, {wxUpdateUIEvent, getText, 0}},
+ {2820, {wxUpdateUIEvent, getMode, 0}},
+ {2821, {wxUpdateUIEvent, getUpdateInterval, 0}},
+ {2822, {wxUpdateUIEvent, resetUpdateTime, 0}},
+ {2823, {wxUpdateUIEvent, setMode, 1}},
+ {2824, {wxUpdateUIEvent, setText, 1}},
+ {2825, {wxUpdateUIEvent, setUpdateInterval, 1}},
+ {2826, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
+ {2827, {wxPaletteChangedEvent, setChangedWindow, 1}},
+ {2828, {wxPaletteChangedEvent, getChangedWindow, 0}},
+ {2829, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
+ {2830, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
+ {2831, {wxNavigationKeyEvent, getDirection, 0}},
+ {2832, {wxNavigationKeyEvent, setDirection, 1}},
+ {2833, {wxNavigationKeyEvent, isWindowChange, 0}},
+ {2834, {wxNavigationKeyEvent, setWindowChange, 1}},
+ {2835, {wxNavigationKeyEvent, isFromTab, 0}},
+ {2836, {wxNavigationKeyEvent, setFromTab, 1}},
+ {2837, {wxNavigationKeyEvent, getCurrentFocus, 0}},
+ {2838, {wxNavigationKeyEvent, setCurrentFocus, 1}},
+ {2839, {wxHelpEvent, getOrigin, 0}},
+ {2840, {wxHelpEvent, getPosition, 0}},
+ {2841, {wxHelpEvent, setOrigin, 1}},
+ {2842, {wxHelpEvent, setPosition, 1}},
+ {2843, {wxContextMenuEvent, getPosition, 0}},
+ {2844, {wxContextMenuEvent, setPosition, 1}},
+ {2845, {wxIdleEvent, canSend, 1}},
+ {2846, {wxIdleEvent, getMode, 0}},
+ {2847, {wxIdleEvent, requestMore, 1}},
+ {2848, {wxIdleEvent, moreRequested, 0}},
+ {2849, {wxIdleEvent, setMode, 1}},
+ {2850, {wxGridEvent, altDown, 0}},
+ {2851, {wxGridEvent, controlDown, 0}},
+ {2852, {wxGridEvent, getCol, 0}},
+ {2853, {wxGridEvent, getPosition, 0}},
+ {2854, {wxGridEvent, getRow, 0}},
+ {2855, {wxGridEvent, metaDown, 0}},
+ {2856, {wxGridEvent, selecting, 0}},
+ {2857, {wxGridEvent, shiftDown, 0}},
+ {2858, {wxNotifyEvent, allow, 0}},
+ {2859, {wxNotifyEvent, isAllowed, 0}},
+ {2860, {wxNotifyEvent, veto, 0}},
+ {2861, {wxSashEvent, getEdge, 0}},
+ {2862, {wxSashEvent, getDragRect, 0}},
+ {2863, {wxSashEvent, getDragStatus, 0}},
+ {2864, {wxListEvent, getCacheFrom, 0}},
+ {2865, {wxListEvent, getCacheTo, 0}},
+ {2866, {wxListEvent, getKeyCode, 0}},
+ {2867, {wxListEvent, getIndex, 0}},
+ {2868, {wxListEvent, getColumn, 0}},
+ {2869, {wxListEvent, getPoint, 0}},
+ {2870, {wxListEvent, getLabel, 0}},
+ {2871, {wxListEvent, getText, 0}},
+ {2872, {wxListEvent, getImage, 0}},
+ {2873, {wxListEvent, getData, 0}},
+ {2874, {wxListEvent, getMask, 0}},
+ {2875, {wxListEvent, getItem, 0}},
+ {2876, {wxListEvent, isEditCancelled, 0}},
+ {2877, {wxDateEvent, getDate, 0}},
+ {2878, {wxCalendarEvent, getWeekDay, 0}},
+ {2879, {wxFileDirPickerEvent, getPath, 0}},
+ {2880, {wxColourPickerEvent, getColour, 0}},
+ {2881, {wxFontPickerEvent, getFont, 0}},
+ {2882, {wxStyledTextEvent, getPosition, 0}},
+ {2883, {wxStyledTextEvent, getKey, 0}},
+ {2884, {wxStyledTextEvent, getModifiers, 0}},
+ {2885, {wxStyledTextEvent, getModificationType, 0}},
+ {2886, {wxStyledTextEvent, getText, 0}},
+ {2887, {wxStyledTextEvent, getLength, 0}},
+ {2888, {wxStyledTextEvent, getLinesAdded, 0}},
+ {2889, {wxStyledTextEvent, getLine, 0}},
+ {2890, {wxStyledTextEvent, getFoldLevelNow, 0}},
+ {2891, {wxStyledTextEvent, getFoldLevelPrev, 0}},
+ {2892, {wxStyledTextEvent, getMargin, 0}},
+ {2893, {wxStyledTextEvent, getMessage, 0}},
+ {2894, {wxStyledTextEvent, getWParam, 0}},
+ {2895, {wxStyledTextEvent, getLParam, 0}},
+ {2896, {wxStyledTextEvent, getListType, 0}},
+ {2897, {wxStyledTextEvent, getX, 0}},
+ {2898, {wxStyledTextEvent, getY, 0}},
+ {2899, {wxStyledTextEvent, getDragText, 0}},
+ {2900, {wxStyledTextEvent, getDragAllowMove, 0}},
+ {2901, {wxStyledTextEvent, getDragResult, 0}},
+ {2902, {wxStyledTextEvent, getShift, 0}},
+ {2903, {wxStyledTextEvent, getControl, 0}},
+ {2904, {wxStyledTextEvent, getAlt, 0}},
+ {2905, {utils, getKeyState, 1}},
+ {2906, {utils, getMousePosition, 2}},
+ {2907, {utils, getMouseState, 0}},
+ {2908, {utils, setDetectableAutoRepeat, 1}},
+ {2909, {utils, bell, 0}},
+ {2910, {utils, findMenuItemId, 3}},
+ {2911, {utils, genericFindWindowAtPoint, 1}},
+ {2912, {utils, findWindowAtPoint, 1}},
+ {2913, {utils, beginBusyCursor, 1}},
+ {2914, {utils, endBusyCursor, 0}},
+ {2915, {utils, isBusy, 0}},
+ {2916, {utils, shutdown, 1}},
+ {2917, {utils, shell, 1}},
+ {2918, {utils, launchDefaultBrowser, 2}},
+ {2919, {utils, getEmailAddress, 0}},
+ {2920, {utils, getUserId, 0}},
+ {2921, {utils, getHomeDir, 0}},
+ {2922, {utils, newId, 0}},
+ {2923, {utils, registerId, 1}},
+ {2924, {utils, getCurrentId, 0}},
+ {2925, {utils, getOsDescription, 0}},
+ {2926, {utils, isPlatformLittleEndian, 0}},
+ {2927, {utils, isPlatform64Bit, 0}},
+ {2928, {gdicmn, displaySize, 2}},
+ {2929, {gdicmn, setCursor, 1}},
+ {2930, {wxPrintout, new, 1}},
+ {2931, {wxPrintout, destruct, 0}},
+ {2932, {wxPrintout, getDC, 0}},
+ {2933, {wxPrintout, getPageSizeMM, 2}},
+ {2934, {wxPrintout, getPageSizePixels, 2}},
+ {2935, {wxPrintout, getPaperRectPixels, 0}},
+ {2936, {wxPrintout, getPPIPrinter, 2}},
+ {2937, {wxPrintout, getPPIScreen, 2}},
+ {2938, {wxPrintout, getTitle, 0}},
+ {2939, {wxPrintout, isPreview, 0}},
+ {2940, {wxPrintout, fitThisSizeToPaper, 1}},
+ {2941, {wxPrintout, fitThisSizeToPage, 1}},
+ {2942, {wxPrintout, fitThisSizeToPageMargins, 2}},
+ {2943, {wxPrintout, mapScreenSizeToPaper, 0}},
+ {2944, {wxPrintout, mapScreenSizeToPage, 0}},
+ {2945, {wxPrintout, mapScreenSizeToPageMargins, 1}},
+ {2946, {wxPrintout, mapScreenSizeToDevice, 0}},
+ {2947, {wxPrintout, getLogicalPaperRect, 0}},
+ {2948, {wxPrintout, getLogicalPageRect, 0}},
+ {2949, {wxPrintout, getLogicalPageMarginsRect, 1}},
+ {2950, {wxPrintout, setLogicalOrigin, 2}},
+ {2951, {wxPrintout, offsetLogicalOrigin, 2}},
+ {2952, {wxStyledTextCtrl, new_2, 2}},
+ {2953, {wxStyledTextCtrl, new_0, 0}},
+ {2954, {wxStyledTextCtrl, destruct, 0}},
+ {2955, {wxStyledTextCtrl, create, 2}},
+ {2956, {wxStyledTextCtrl, addText, 1}},
+ {2957, {wxStyledTextCtrl, addStyledText, 1}},
+ {2958, {wxStyledTextCtrl, insertText, 2}},
+ {2959, {wxStyledTextCtrl, clearAll, 0}},
+ {2960, {wxStyledTextCtrl, clearDocumentStyle, 0}},
+ {2961, {wxStyledTextCtrl, getLength, 0}},
+ {2962, {wxStyledTextCtrl, getCharAt, 1}},
+ {2963, {wxStyledTextCtrl, getCurrentPos, 0}},
+ {2964, {wxStyledTextCtrl, getAnchor, 0}},
+ {2965, {wxStyledTextCtrl, getStyleAt, 1}},
+ {2966, {wxStyledTextCtrl, redo, 0}},
+ {2967, {wxStyledTextCtrl, setUndoCollection, 1}},
+ {2968, {wxStyledTextCtrl, selectAll, 0}},
+ {2969, {wxStyledTextCtrl, setSavePoint, 0}},
+ {2970, {wxStyledTextCtrl, getStyledText, 2}},
+ {2971, {wxStyledTextCtrl, canRedo, 0}},
+ {2972, {wxStyledTextCtrl, markerLineFromHandle, 1}},
+ {2973, {wxStyledTextCtrl, markerDeleteHandle, 1}},
+ {2974, {wxStyledTextCtrl, getUndoCollection, 0}},
+ {2975, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
+ {2976, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
+ {2977, {wxStyledTextCtrl, positionFromPoint, 1}},
+ {2978, {wxStyledTextCtrl, positionFromPointClose, 2}},
+ {2979, {wxStyledTextCtrl, gotoLine, 1}},
+ {2980, {wxStyledTextCtrl, gotoPos, 1}},
+ {2981, {wxStyledTextCtrl, setAnchor, 1}},
+ {2982, {wxStyledTextCtrl, getCurLine, 1}},
+ {2983, {wxStyledTextCtrl, getEndStyled, 0}},
+ {2984, {wxStyledTextCtrl, convertEOLs, 1}},
+ {2985, {wxStyledTextCtrl, getEOLMode, 0}},
+ {2986, {wxStyledTextCtrl, setEOLMode, 1}},
+ {2987, {wxStyledTextCtrl, startStyling, 2}},
+ {2988, {wxStyledTextCtrl, setStyling, 2}},
+ {2989, {wxStyledTextCtrl, getBufferedDraw, 0}},
+ {2990, {wxStyledTextCtrl, setBufferedDraw, 1}},
+ {2991, {wxStyledTextCtrl, setTabWidth, 1}},
+ {2992, {wxStyledTextCtrl, getTabWidth, 0}},
+ {2993, {wxStyledTextCtrl, setCodePage, 1}},
+ {2994, {wxStyledTextCtrl, markerDefine, 3}},
+ {2995, {wxStyledTextCtrl, markerSetForeground, 2}},
+ {2996, {wxStyledTextCtrl, markerSetBackground, 2}},
+ {2997, {wxStyledTextCtrl, markerAdd, 2}},
+ {2998, {wxStyledTextCtrl, markerDelete, 2}},
+ {2999, {wxStyledTextCtrl, markerDeleteAll, 1}},
+ {3000, {wxStyledTextCtrl, markerGet, 1}},
+ {3001, {wxStyledTextCtrl, markerNext, 2}},
+ {3002, {wxStyledTextCtrl, markerPrevious, 2}},
+ {3003, {wxStyledTextCtrl, markerDefineBitmap, 2}},
+ {3004, {wxStyledTextCtrl, markerAddSet, 2}},
+ {3005, {wxStyledTextCtrl, markerSetAlpha, 2}},
+ {3006, {wxStyledTextCtrl, setMarginType, 2}},
+ {3007, {wxStyledTextCtrl, getMarginType, 1}},
+ {3008, {wxStyledTextCtrl, setMarginWidth, 2}},
+ {3009, {wxStyledTextCtrl, getMarginWidth, 1}},
+ {3010, {wxStyledTextCtrl, setMarginMask, 2}},
+ {3011, {wxStyledTextCtrl, getMarginMask, 1}},
+ {3012, {wxStyledTextCtrl, setMarginSensitive, 2}},
+ {3013, {wxStyledTextCtrl, getMarginSensitive, 1}},
+ {3014, {wxStyledTextCtrl, styleClearAll, 0}},
+ {3015, {wxStyledTextCtrl, styleSetForeground, 2}},
+ {3016, {wxStyledTextCtrl, styleSetBackground, 2}},
+ {3017, {wxStyledTextCtrl, styleSetBold, 2}},
+ {3018, {wxStyledTextCtrl, styleSetItalic, 2}},
+ {3019, {wxStyledTextCtrl, styleSetSize, 2}},
+ {3020, {wxStyledTextCtrl, styleSetFaceName, 2}},
+ {3021, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
+ {3022, {wxStyledTextCtrl, styleResetDefault, 0}},
+ {3023, {wxStyledTextCtrl, styleSetUnderline, 2}},
+ {3024, {wxStyledTextCtrl, styleSetCase, 2}},
+ {3025, {wxStyledTextCtrl, styleSetHotSpot, 2}},
+ {3026, {wxStyledTextCtrl, setSelForeground, 2}},
+ {3027, {wxStyledTextCtrl, setSelBackground, 2}},
+ {3028, {wxStyledTextCtrl, getSelAlpha, 0}},
+ {3029, {wxStyledTextCtrl, setSelAlpha, 1}},
+ {3030, {wxStyledTextCtrl, setCaretForeground, 1}},
+ {3031, {wxStyledTextCtrl, cmdKeyAssign, 3}},
+ {3032, {wxStyledTextCtrl, cmdKeyClear, 2}},
+ {3033, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
+ {3034, {wxStyledTextCtrl, setStyleBytes, 2}},
+ {3035, {wxStyledTextCtrl, styleSetVisible, 2}},
+ {3036, {wxStyledTextCtrl, getCaretPeriod, 0}},
+ {3037, {wxStyledTextCtrl, setCaretPeriod, 1}},
+ {3038, {wxStyledTextCtrl, setWordChars, 1}},
+ {3039, {wxStyledTextCtrl, beginUndoAction, 0}},
+ {3040, {wxStyledTextCtrl, endUndoAction, 0}},
+ {3041, {wxStyledTextCtrl, indicatorSetStyle, 2}},
+ {3042, {wxStyledTextCtrl, indicatorGetStyle, 1}},
+ {3043, {wxStyledTextCtrl, indicatorSetForeground, 2}},
+ {3044, {wxStyledTextCtrl, indicatorGetForeground, 1}},
+ {3045, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
+ {3046, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
+ {3047, {wxStyledTextCtrl, getStyleBits, 0}},
+ {3048, {wxStyledTextCtrl, setLineState, 2}},
+ {3049, {wxStyledTextCtrl, getLineState, 1}},
+ {3050, {wxStyledTextCtrl, getMaxLineState, 0}},
+ {3051, {wxStyledTextCtrl, getCaretLineVisible, 0}},
+ {3052, {wxStyledTextCtrl, setCaretLineVisible, 1}},
+ {3053, {wxStyledTextCtrl, getCaretLineBackground, 0}},
+ {3054, {wxStyledTextCtrl, setCaretLineBackground, 1}},
+ {3055, {wxStyledTextCtrl, autoCompShow, 2}},
+ {3056, {wxStyledTextCtrl, autoCompCancel, 0}},
+ {3057, {wxStyledTextCtrl, autoCompActive, 0}},
+ {3058, {wxStyledTextCtrl, autoCompPosStart, 0}},
+ {3059, {wxStyledTextCtrl, autoCompComplete, 0}},
+ {3060, {wxStyledTextCtrl, autoCompStops, 1}},
+ {3061, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
+ {3062, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
+ {3063, {wxStyledTextCtrl, autoCompSelect, 1}},
+ {3064, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
+ {3065, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
+ {3066, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
+ {3067, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
+ {3068, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
+ {3069, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
+ {3070, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
+ {3071, {wxStyledTextCtrl, userListShow, 2}},
+ {3072, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
+ {3073, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
+ {3074, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
+ {3075, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
+ {3076, {wxStyledTextCtrl, registerImage, 2}},
+ {3077, {wxStyledTextCtrl, clearRegisteredImages, 0}},
+ {3078, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
+ {3079, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
+ {3080, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
+ {3081, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
+ {3082, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
+ {3083, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
+ {3084, {wxStyledTextCtrl, setIndent, 1}},
+ {3085, {wxStyledTextCtrl, getIndent, 0}},
+ {3086, {wxStyledTextCtrl, setUseTabs, 1}},
+ {3087, {wxStyledTextCtrl, getUseTabs, 0}},
+ {3088, {wxStyledTextCtrl, setLineIndentation, 2}},
+ {3089, {wxStyledTextCtrl, getLineIndentation, 1}},
+ {3090, {wxStyledTextCtrl, getLineIndentPosition, 1}},
+ {3091, {wxStyledTextCtrl, getColumn, 1}},
+ {3092, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
+ {3093, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
+ {3094, {wxStyledTextCtrl, setIndentationGuides, 1}},
+ {3095, {wxStyledTextCtrl, getIndentationGuides, 0}},
+ {3096, {wxStyledTextCtrl, setHighlightGuide, 1}},
+ {3097, {wxStyledTextCtrl, getHighlightGuide, 0}},
+ {3098, {wxStyledTextCtrl, getLineEndPosition, 1}},
+ {3099, {wxStyledTextCtrl, getCodePage, 0}},
+ {3100, {wxStyledTextCtrl, getCaretForeground, 0}},
+ {3101, {wxStyledTextCtrl, getReadOnly, 0}},
+ {3102, {wxStyledTextCtrl, setCurrentPos, 1}},
+ {3103, {wxStyledTextCtrl, setSelectionStart, 1}},
+ {3104, {wxStyledTextCtrl, getSelectionStart, 0}},
+ {3105, {wxStyledTextCtrl, setSelectionEnd, 1}},
+ {3106, {wxStyledTextCtrl, getSelectionEnd, 0}},
+ {3107, {wxStyledTextCtrl, setPrintMagnification, 1}},
+ {3108, {wxStyledTextCtrl, getPrintMagnification, 0}},
+ {3109, {wxStyledTextCtrl, setPrintColourMode, 1}},
+ {3110, {wxStyledTextCtrl, getPrintColourMode, 0}},
+ {3111, {wxStyledTextCtrl, findText, 4}},
+ {3112, {wxStyledTextCtrl, formatRange, 7}},
+ {3113, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
+ {3114, {wxStyledTextCtrl, getLine, 1}},
+ {3115, {wxStyledTextCtrl, getLineCount, 0}},
+ {3116, {wxStyledTextCtrl, setMarginLeft, 1}},
+ {3117, {wxStyledTextCtrl, getMarginLeft, 0}},
+ {3118, {wxStyledTextCtrl, setMarginRight, 1}},
+ {3119, {wxStyledTextCtrl, getMarginRight, 0}},
+ {3120, {wxStyledTextCtrl, getModify, 0}},
+ {3121, {wxStyledTextCtrl, setSelection, 2}},
+ {3122, {wxStyledTextCtrl, getSelectedText, 0}},
+ {3123, {wxStyledTextCtrl, getTextRange, 2}},
+ {3124, {wxStyledTextCtrl, hideSelection, 1}},
+ {3125, {wxStyledTextCtrl, lineFromPosition, 1}},
+ {3126, {wxStyledTextCtrl, positionFromLine, 1}},
+ {3127, {wxStyledTextCtrl, lineScroll, 2}},
+ {3128, {wxStyledTextCtrl, ensureCaretVisible, 0}},
+ {3129, {wxStyledTextCtrl, replaceSelection, 1}},
+ {3130, {wxStyledTextCtrl, setReadOnly, 1}},
+ {3131, {wxStyledTextCtrl, canPaste, 0}},
+ {3132, {wxStyledTextCtrl, canUndo, 0}},
+ {3133, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
+ {3134, {wxStyledTextCtrl, undo, 0}},
+ {3135, {wxStyledTextCtrl, cut, 0}},
+ {3136, {wxStyledTextCtrl, copy, 0}},
+ {3137, {wxStyledTextCtrl, paste, 0}},
+ {3138, {wxStyledTextCtrl, clear, 0}},
+ {3139, {wxStyledTextCtrl, setText, 1}},
+ {3140, {wxStyledTextCtrl, getText, 0}},
+ {3141, {wxStyledTextCtrl, getTextLength, 0}},
+ {3142, {wxStyledTextCtrl, getOvertype, 0}},
+ {3143, {wxStyledTextCtrl, setCaretWidth, 1}},
+ {3144, {wxStyledTextCtrl, getCaretWidth, 0}},
+ {3145, {wxStyledTextCtrl, setTargetStart, 1}},
+ {3146, {wxStyledTextCtrl, getTargetStart, 0}},
+ {3147, {wxStyledTextCtrl, setTargetEnd, 1}},
+ {3148, {wxStyledTextCtrl, getTargetEnd, 0}},
+ {3149, {wxStyledTextCtrl, replaceTarget, 1}},
+ {3150, {wxStyledTextCtrl, searchInTarget, 1}},
+ {3151, {wxStyledTextCtrl, setSearchFlags, 1}},
+ {3152, {wxStyledTextCtrl, getSearchFlags, 0}},
+ {3153, {wxStyledTextCtrl, callTipShow, 2}},
+ {3154, {wxStyledTextCtrl, callTipCancel, 0}},
+ {3155, {wxStyledTextCtrl, callTipActive, 0}},
+ {3156, {wxStyledTextCtrl, callTipPosAtStart, 0}},
+ {3157, {wxStyledTextCtrl, callTipSetHighlight, 2}},
+ {3158, {wxStyledTextCtrl, callTipSetBackground, 1}},
+ {3159, {wxStyledTextCtrl, callTipSetForeground, 1}},
+ {3160, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
+ {3161, {wxStyledTextCtrl, callTipUseStyle, 1}},
+ {3162, {wxStyledTextCtrl, visibleFromDocLine, 1}},
+ {3163, {wxStyledTextCtrl, docLineFromVisible, 1}},
+ {3164, {wxStyledTextCtrl, wrapCount, 1}},
+ {3165, {wxStyledTextCtrl, setFoldLevel, 2}},
+ {3166, {wxStyledTextCtrl, getFoldLevel, 1}},
+ {3167, {wxStyledTextCtrl, getLastChild, 2}},
+ {3168, {wxStyledTextCtrl, getFoldParent, 1}},
+ {3169, {wxStyledTextCtrl, showLines, 2}},
+ {3170, {wxStyledTextCtrl, hideLines, 2}},
+ {3171, {wxStyledTextCtrl, getLineVisible, 1}},
+ {3172, {wxStyledTextCtrl, setFoldExpanded, 2}},
+ {3173, {wxStyledTextCtrl, getFoldExpanded, 1}},
+ {3174, {wxStyledTextCtrl, toggleFold, 1}},
+ {3175, {wxStyledTextCtrl, ensureVisible, 1}},
+ {3176, {wxStyledTextCtrl, setFoldFlags, 1}},
+ {3177, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
+ {3178, {wxStyledTextCtrl, setTabIndents, 1}},
+ {3179, {wxStyledTextCtrl, getTabIndents, 0}},
+ {3180, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
+ {3181, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
+ {3182, {wxStyledTextCtrl, setMouseDwellTime, 1}},
+ {3183, {wxStyledTextCtrl, getMouseDwellTime, 0}},
+ {3184, {wxStyledTextCtrl, wordStartPosition, 2}},
+ {3185, {wxStyledTextCtrl, wordEndPosition, 2}},
+ {3186, {wxStyledTextCtrl, setWrapMode, 1}},
+ {3187, {wxStyledTextCtrl, getWrapMode, 0}},
+ {3188, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
+ {3189, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
+ {3190, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
+ {3191, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
+ {3192, {wxStyledTextCtrl, setWrapStartIndent, 1}},
+ {3193, {wxStyledTextCtrl, getWrapStartIndent, 0}},
+ {3194, {wxStyledTextCtrl, setLayoutCache, 1}},
+ {3195, {wxStyledTextCtrl, getLayoutCache, 0}},
+ {3196, {wxStyledTextCtrl, setScrollWidth, 1}},
+ {3197, {wxStyledTextCtrl, getScrollWidth, 0}},
+ {3198, {wxStyledTextCtrl, textWidth, 2}},
+ {3199, {wxStyledTextCtrl, getEndAtLastLine, 0}},
+ {3200, {wxStyledTextCtrl, textHeight, 1}},
+ {3201, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
+ {3202, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
+ {3203, {wxStyledTextCtrl, appendText, 1}},
+ {3204, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
+ {3205, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
+ {3206, {wxStyledTextCtrl, targetFromSelection, 0}},
+ {3207, {wxStyledTextCtrl, linesJoin, 0}},
+ {3208, {wxStyledTextCtrl, linesSplit, 1}},
+ {3209, {wxStyledTextCtrl, setFoldMarginColour, 2}},
+ {3210, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
+ {3211, {wxStyledTextCtrl, lineDown, 0}},
+ {3212, {wxStyledTextCtrl, lineDownExtend, 0}},
+ {3213, {wxStyledTextCtrl, lineUp, 0}},
+ {3214, {wxStyledTextCtrl, lineUpExtend, 0}},
+ {3215, {wxStyledTextCtrl, charLeft, 0}},
+ {3216, {wxStyledTextCtrl, charLeftExtend, 0}},
+ {3217, {wxStyledTextCtrl, charRight, 0}},
+ {3218, {wxStyledTextCtrl, charRightExtend, 0}},
+ {3219, {wxStyledTextCtrl, wordLeft, 0}},
+ {3220, {wxStyledTextCtrl, wordLeftExtend, 0}},
+ {3221, {wxStyledTextCtrl, wordRight, 0}},
+ {3222, {wxStyledTextCtrl, wordRightExtend, 0}},
+ {3223, {wxStyledTextCtrl, home, 0}},
+ {3224, {wxStyledTextCtrl, homeExtend, 0}},
+ {3225, {wxStyledTextCtrl, lineEnd, 0}},
+ {3226, {wxStyledTextCtrl, lineEndExtend, 0}},
+ {3227, {wxStyledTextCtrl, documentStart, 0}},
+ {3228, {wxStyledTextCtrl, documentStartExtend, 0}},
+ {3229, {wxStyledTextCtrl, documentEnd, 0}},
+ {3230, {wxStyledTextCtrl, documentEndExtend, 0}},
+ {3231, {wxStyledTextCtrl, pageUp, 0}},
+ {3232, {wxStyledTextCtrl, pageUpExtend, 0}},
+ {3233, {wxStyledTextCtrl, pageDown, 0}},
+ {3234, {wxStyledTextCtrl, pageDownExtend, 0}},
+ {3235, {wxStyledTextCtrl, editToggleOvertype, 0}},
+ {3236, {wxStyledTextCtrl, cancel, 0}},
+ {3237, {wxStyledTextCtrl, deleteBack, 0}},
+ {3238, {wxStyledTextCtrl, tab, 0}},
+ {3239, {wxStyledTextCtrl, backTab, 0}},
+ {3240, {wxStyledTextCtrl, newLine, 0}},
+ {3241, {wxStyledTextCtrl, formFeed, 0}},
+ {3242, {wxStyledTextCtrl, vCHome, 0}},
+ {3243, {wxStyledTextCtrl, vCHomeExtend, 0}},
+ {3244, {wxStyledTextCtrl, zoomIn, 0}},
+ {3245, {wxStyledTextCtrl, zoomOut, 0}},
+ {3246, {wxStyledTextCtrl, delWordLeft, 0}},
+ {3247, {wxStyledTextCtrl, delWordRight, 0}},
+ {3248, {wxStyledTextCtrl, lineCut, 0}},
+ {3249, {wxStyledTextCtrl, lineDelete, 0}},
+ {3250, {wxStyledTextCtrl, lineTranspose, 0}},
+ {3251, {wxStyledTextCtrl, lineDuplicate, 0}},
+ {3252, {wxStyledTextCtrl, lowerCase, 0}},
+ {3253, {wxStyledTextCtrl, upperCase, 0}},
+ {3254, {wxStyledTextCtrl, lineScrollDown, 0}},
+ {3255, {wxStyledTextCtrl, lineScrollUp, 0}},
+ {3256, {wxStyledTextCtrl, deleteBackNotLine, 0}},
+ {3257, {wxStyledTextCtrl, homeDisplay, 0}},
+ {3258, {wxStyledTextCtrl, homeDisplayExtend, 0}},
+ {3259, {wxStyledTextCtrl, lineEndDisplay, 0}},
+ {3260, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
+ {3261, {wxStyledTextCtrl, homeWrapExtend, 0}},
+ {3262, {wxStyledTextCtrl, lineEndWrap, 0}},
+ {3263, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
+ {3264, {wxStyledTextCtrl, vCHomeWrap, 0}},
+ {3265, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
+ {3266, {wxStyledTextCtrl, lineCopy, 0}},
+ {3267, {wxStyledTextCtrl, moveCaretInsideView, 0}},
+ {3268, {wxStyledTextCtrl, lineLength, 1}},
+ {3269, {wxStyledTextCtrl, braceHighlight, 2}},
+ {3270, {wxStyledTextCtrl, braceBadLight, 1}},
+ {3271, {wxStyledTextCtrl, braceMatch, 1}},
+ {3272, {wxStyledTextCtrl, getViewEOL, 0}},
+ {3273, {wxStyledTextCtrl, setViewEOL, 1}},
+ {3274, {wxStyledTextCtrl, setModEventMask, 1}},
+ {3275, {wxStyledTextCtrl, getEdgeColumn, 0}},
+ {3276, {wxStyledTextCtrl, setEdgeColumn, 1}},
+ {3277, {wxStyledTextCtrl, setEdgeMode, 1}},
+ {3278, {wxStyledTextCtrl, getEdgeMode, 0}},
+ {3279, {wxStyledTextCtrl, getEdgeColour, 0}},
+ {3280, {wxStyledTextCtrl, setEdgeColour, 1}},
+ {3281, {wxStyledTextCtrl, searchAnchor, 0}},
+ {3282, {wxStyledTextCtrl, searchNext, 2}},
+ {3283, {wxStyledTextCtrl, searchPrev, 2}},
+ {3284, {wxStyledTextCtrl, linesOnScreen, 0}},
+ {3285, {wxStyledTextCtrl, usePopUp, 1}},
+ {3286, {wxStyledTextCtrl, selectionIsRectangle, 0}},
+ {3287, {wxStyledTextCtrl, setZoom, 1}},
+ {3288, {wxStyledTextCtrl, getZoom, 0}},
+ {3289, {wxStyledTextCtrl, getModEventMask, 0}},
+ {3290, {wxStyledTextCtrl, setSTCFocus, 1}},
+ {3291, {wxStyledTextCtrl, getSTCFocus, 0}},
+ {3292, {wxStyledTextCtrl, setStatus, 1}},
+ {3293, {wxStyledTextCtrl, getStatus, 0}},
+ {3294, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
+ {3295, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
+ {3296, {wxStyledTextCtrl, setSTCCursor, 1}},
+ {3297, {wxStyledTextCtrl, getSTCCursor, 0}},
+ {3298, {wxStyledTextCtrl, setControlCharSymbol, 1}},
+ {3299, {wxStyledTextCtrl, getControlCharSymbol, 0}},
+ {3300, {wxStyledTextCtrl, wordPartLeft, 0}},
+ {3301, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
+ {3302, {wxStyledTextCtrl, wordPartRight, 0}},
+ {3303, {wxStyledTextCtrl, wordPartRightExtend, 0}},
+ {3304, {wxStyledTextCtrl, setVisiblePolicy, 2}},
+ {3305, {wxStyledTextCtrl, delLineLeft, 0}},
+ {3306, {wxStyledTextCtrl, delLineRight, 0}},
+ {3307, {wxStyledTextCtrl, getXOffset, 0}},
+ {3308, {wxStyledTextCtrl, chooseCaretX, 0}},
+ {3309, {wxStyledTextCtrl, setXCaretPolicy, 2}},
+ {3310, {wxStyledTextCtrl, setYCaretPolicy, 2}},
+ {3311, {wxStyledTextCtrl, getPrintWrapMode, 0}},
+ {3312, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
+ {3313, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
+ {3314, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
+ {3315, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
+ {3316, {wxStyledTextCtrl, paraDownExtend, 0}},
+ {3317, {wxStyledTextCtrl, paraUp, 0}},
+ {3318, {wxStyledTextCtrl, paraUpExtend, 0}},
+ {3319, {wxStyledTextCtrl, positionBefore, 1}},
+ {3320, {wxStyledTextCtrl, positionAfter, 1}},
+ {3321, {wxStyledTextCtrl, copyRange, 2}},
+ {3322, {wxStyledTextCtrl, copyText, 2}},
+ {3323, {wxStyledTextCtrl, setSelectionMode, 1}},
+ {3324, {wxStyledTextCtrl, getSelectionMode, 0}},
+ {3325, {wxStyledTextCtrl, lineDownRectExtend, 0}},
+ {3326, {wxStyledTextCtrl, lineUpRectExtend, 0}},
+ {3327, {wxStyledTextCtrl, charLeftRectExtend, 0}},
+ {3328, {wxStyledTextCtrl, charRightRectExtend, 0}},
+ {3329, {wxStyledTextCtrl, homeRectExtend, 0}},
+ {3330, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
+ {3331, {wxStyledTextCtrl, lineEndRectExtend, 0}},
+ {3332, {wxStyledTextCtrl, pageUpRectExtend, 0}},
+ {3333, {wxStyledTextCtrl, pageDownRectExtend, 0}},
+ {3334, {wxStyledTextCtrl, stutteredPageUp, 0}},
+ {3335, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
+ {3336, {wxStyledTextCtrl, stutteredPageDown, 0}},
+ {3337, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
+ {3338, {wxStyledTextCtrl, wordLeftEnd, 0}},
+ {3339, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
+ {3340, {wxStyledTextCtrl, wordRightEnd, 0}},
+ {3341, {wxStyledTextCtrl, wordRightEndExtend, 0}},
+ {3342, {wxStyledTextCtrl, setWhitespaceChars, 1}},
+ {3343, {wxStyledTextCtrl, setCharsDefault, 0}},
+ {3344, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
+ {3345, {wxStyledTextCtrl, allocate, 1}},
+ {3346, {wxStyledTextCtrl, findColumn, 2}},
+ {3347, {wxStyledTextCtrl, getCaretSticky, 0}},
+ {3348, {wxStyledTextCtrl, setCaretSticky, 1}},
+ {3349, {wxStyledTextCtrl, toggleCaretSticky, 0}},
+ {3350, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
+ {3351, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
+ {3352, {wxStyledTextCtrl, selectionDuplicate, 0}},
+ {3353, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
+ {3354, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
+ {3355, {wxStyledTextCtrl, startRecord, 0}},
+ {3356, {wxStyledTextCtrl, stopRecord, 0}},
+ {3357, {wxStyledTextCtrl, setLexer, 1}},
+ {3358, {wxStyledTextCtrl, getLexer, 0}},
+ {3359, {wxStyledTextCtrl, colourise, 2}},
+ {3360, {wxStyledTextCtrl, setProperty, 2}},
+ {3361, {wxStyledTextCtrl, setKeyWords, 2}},
+ {3362, {wxStyledTextCtrl, setLexerLanguage, 1}},
+ {3363, {wxStyledTextCtrl, getProperty, 1}},
+ {3364, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
+ {3365, {wxStyledTextCtrl, getCurrentLine, 0}},
+ {3366, {wxStyledTextCtrl, styleSetSpec, 2}},
+ {3367, {wxStyledTextCtrl, styleSetFont, 2}},
+ {3368, {wxStyledTextCtrl, styleSetFontAttr, 7}},
+ {3369, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
+ {3370, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
+ {3371, {wxStyledTextCtrl, cmdKeyExecute, 1}},
+ {3372, {wxStyledTextCtrl, setMargins, 2}},
+ {3373, {wxStyledTextCtrl, getSelection, 2}},
+ {3374, {wxStyledTextCtrl, pointFromPosition, 1}},
+ {3375, {wxStyledTextCtrl, scrollToLine, 1}},
+ {3376, {wxStyledTextCtrl, scrollToColumn, 1}},
+ {3377, {wxStyledTextCtrl, setVScrollBar, 1}},
+ {3378, {wxStyledTextCtrl, setHScrollBar, 1}},
+ {3379, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
+ {3380, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
+ {3381, {wxStyledTextCtrl, saveFile, 1}},
+ {3382, {wxStyledTextCtrl, loadFile, 1}},
+ {3383, {wxStyledTextCtrl, doDragOver, 3}},
+ {3384, {wxStyledTextCtrl, doDropText, 3}},
+ {3385, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
+ {3386, {wxStyledTextCtrl, addTextRaw, 1}},
+ {3387, {wxStyledTextCtrl, insertTextRaw, 2}},
+ {3388, {wxStyledTextCtrl, getCurLineRaw, 1}},
+ {3389, {wxStyledTextCtrl, getLineRaw, 1}},
+ {3390, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
+ {3391, {wxStyledTextCtrl, getTextRangeRaw, 2}},
+ {3392, {wxStyledTextCtrl, setTextRaw, 1}},
+ {3393, {wxStyledTextCtrl, getTextRaw, 0}},
+ {3394, {wxStyledTextCtrl, appendTextRaw, 1}},
+ {3395, {wxArtProvider, getBitmap, 2}},
+ {3396, {wxArtProvider, getIcon, 2}},
+ {3397, {wxTreeEvent, getKeyCode, 0}},
+ {3398, {wxTreeEvent, getItem, 0}},
+ {3399, {wxTreeEvent, getKeyEvent, 0}},
+ {3400, {wxTreeEvent, getLabel, 0}},
+ {3401, {wxTreeEvent, getOldItem, 0}},
+ {3402, {wxTreeEvent, getPoint, 0}},
+ {3403, {wxTreeEvent, isEditCancelled, 0}},
+ {3404, {wxTreeEvent, setToolTip, 1}},
+ {3405, {wxNotebookEvent, getOldSelection, 0}},
+ {3406, {wxNotebookEvent, getSelection, 0}},
+ {3407, {wxNotebookEvent, setOldSelection, 1}},
+ {3408, {wxNotebookEvent, setSelection, 1}},
+ {3409, {wxFileDataObject, new, 0}},
+ {3410, {wxFileDataObject, addFile, 1}},
+ {3411, {wxFileDataObject, getFilenames, 0}},
+ {3412, {wxFileDataObject, 'Destroy', undefined}},
+ {3413, {wxTextDataObject, new, 1}},
+ {3414, {wxTextDataObject, getTextLength, 0}},
+ {3415, {wxTextDataObject, getText, 0}},
+ {3416, {wxTextDataObject, setText, 1}},
+ {3417, {wxTextDataObject, 'Destroy', undefined}},
+ {3418, {wxBitmapDataObject, new_1_1, 1}},
+ {3419, {wxBitmapDataObject, new_1_0, 1}},
+ {3420, {wxBitmapDataObject, getBitmap, 0}},
+ {3421, {wxBitmapDataObject, setBitmap, 1}},
+ {3422, {wxBitmapDataObject, 'Destroy', undefined}},
+ {3424, {wxClipboard, new, 0}},
+ {3425, {wxClipboard, destruct, 0}},
+ {3426, {wxClipboard, addData, 1}},
+ {3427, {wxClipboard, clear, 0}},
+ {3428, {wxClipboard, close, 0}},
+ {3429, {wxClipboard, flush, 0}},
+ {3430, {wxClipboard, getData, 1}},
+ {3431, {wxClipboard, isOpened, 0}},
+ {3432, {wxClipboard, open, 0}},
+ {3433, {wxClipboard, setData, 1}},
+ {3435, {wxClipboard, usePrimarySelection, 1}},
+ {3436, {wxClipboard, isSupported, 1}},
+ {3437, {wxClipboard, get, 0}},
+ {3438, {wxSpinEvent, getPosition, 0}},
+ {3439, {wxSpinEvent, setPosition, 1}},
+ {3440, {wxSplitterWindow, new_0, 0}},
+ {3441, {wxSplitterWindow, new_2, 2}},
+ {3442, {wxSplitterWindow, destruct, 0}},
+ {3443, {wxSplitterWindow, create, 2}},
+ {3444, {wxSplitterWindow, getMinimumPaneSize, 0}},
+ {3445, {wxSplitterWindow, getSashGravity, 0}},
+ {3446, {wxSplitterWindow, getSashPosition, 0}},
+ {3447, {wxSplitterWindow, getSplitMode, 0}},
+ {3448, {wxSplitterWindow, getWindow1, 0}},
+ {3449, {wxSplitterWindow, getWindow2, 0}},
+ {3450, {wxSplitterWindow, initialize, 1}},
+ {3451, {wxSplitterWindow, isSplit, 0}},
+ {3452, {wxSplitterWindow, replaceWindow, 2}},
+ {3453, {wxSplitterWindow, setSashGravity, 1}},
+ {3454, {wxSplitterWindow, setSashPosition, 2}},
+ {3455, {wxSplitterWindow, setSashSize, 1}},
+ {3456, {wxSplitterWindow, setMinimumPaneSize, 1}},
+ {3457, {wxSplitterWindow, setSplitMode, 1}},
+ {3458, {wxSplitterWindow, splitHorizontally, 3}},
+ {3459, {wxSplitterWindow, splitVertically, 3}},
+ {3460, {wxSplitterWindow, unsplit, 1}},
+ {3461, {wxSplitterWindow, updateSize, 0}},
+ {3462, {wxSplitterEvent, getSashPosition, 0}},
+ {3463, {wxSplitterEvent, getX, 0}},
+ {3464, {wxSplitterEvent, getY, 0}},
+ {3465, {wxSplitterEvent, getWindowBeingRemoved, 0}},
+ {3466, {wxSplitterEvent, setSashPosition, 1}},
+ {3467, {wxHtmlWindow, new_0, 0}},
+ {3468, {wxHtmlWindow, new_2, 2}},
+ {3469, {wxHtmlWindow, appendToPage, 1}},
+ {3470, {wxHtmlWindow, getOpenedAnchor, 0}},
+ {3471, {wxHtmlWindow, getOpenedPage, 0}},
+ {3472, {wxHtmlWindow, getOpenedPageTitle, 0}},
+ {3473, {wxHtmlWindow, getRelatedFrame, 0}},
+ {3474, {wxHtmlWindow, historyBack, 0}},
+ {3475, {wxHtmlWindow, historyCanBack, 0}},
+ {3476, {wxHtmlWindow, historyCanForward, 0}},
+ {3477, {wxHtmlWindow, historyClear, 0}},
+ {3478, {wxHtmlWindow, historyForward, 0}},
+ {3479, {wxHtmlWindow, loadFile, 1}},
+ {3480, {wxHtmlWindow, loadPage, 1}},
+ {3481, {wxHtmlWindow, selectAll, 0}},
+ {3482, {wxHtmlWindow, selectionToText, 0}},
+ {3483, {wxHtmlWindow, selectLine, 1}},
+ {3484, {wxHtmlWindow, selectWord, 1}},
+ {3485, {wxHtmlWindow, setBorders, 1}},
+ {3486, {wxHtmlWindow, setFonts, 3}},
+ {3487, {wxHtmlWindow, setPage, 1}},
+ {3488, {wxHtmlWindow, setRelatedFrame, 2}},
+ {3489, {wxHtmlWindow, setRelatedStatusBar, 1}},
+ {3490, {wxHtmlWindow, toText, 0}},
+ {3491, {wxHtmlWindow, 'Destroy', undefined}},
+ {3492, {wxHtmlLinkEvent, getLinkInfo, 0}},
+ {3493, {wxSystemSettings, getColour, 1}},
+ {3494, {wxSystemSettings, getFont, 1}},
+ {3495, {wxSystemSettings, getMetric, 2}},
+ {3496, {wxSystemSettings, getScreenType, 0}},
+ {3497, {wxSystemOptions, getOption, 1}},
+ {3498, {wxSystemOptions, getOptionInt, 1}},
+ {3499, {wxSystemOptions, hasOption, 1}},
+ {3500, {wxSystemOptions, isFalse, 1}},
+ {3501, {wxSystemOptions, setOption_2_1, 2}},
+ {3502, {wxSystemOptions, setOption_2_0, 2}},
+ {3503, {wxAuiNotebookEvent, setSelection, 1}},
+ {3504, {wxAuiNotebookEvent, getSelection, 0}},
+ {3505, {wxAuiNotebookEvent, setOldSelection, 1}},
+ {3506, {wxAuiNotebookEvent, getOldSelection, 0}},
+ {3507, {wxAuiNotebookEvent, setDragSource, 1}},
+ {3508, {wxAuiNotebookEvent, getDragSource, 0}},
+ {3509, {wxAuiManagerEvent, setManager, 1}},
+ {3510, {wxAuiManagerEvent, getManager, 0}},
+ {3511, {wxAuiManagerEvent, setPane, 1}},
+ {3512, {wxAuiManagerEvent, getPane, 0}},
+ {3513, {wxAuiManagerEvent, setButton, 1}},
+ {3514, {wxAuiManagerEvent, getButton, 0}},
+ {3515, {wxAuiManagerEvent, setDC, 1}},
+ {3516, {wxAuiManagerEvent, getDC, 0}},
+ {3517, {wxAuiManagerEvent, veto, 1}},
+ {3518, {wxAuiManagerEvent, getVeto, 0}},
+ {3519, {wxAuiManagerEvent, setCanVeto, 1}},
+ {3520, {wxAuiManagerEvent, canVeto, 0}},
+ {3521, {wxLogNull, new, 0}},
+ {3522, {wxLogNull, 'Destroy', undefined}},
+ {3523, {wxTaskBarIcon, new, 0}},
+ {3524, {wxTaskBarIcon, destruct, 0}},
+ {3525, {wxTaskBarIcon, popupMenu, 1}},
+ {3526, {wxTaskBarIcon, removeIcon, 0}},
+ {3527, {wxTaskBarIcon, setIcon, 2}},
+ {3528, {wxLocale, new_0, 0}},
+ {3530, {wxLocale, new_2, 2}},
+ {3531, {wxLocale, destruct, 0}},
+ {3533, {wxLocale, init, 1}},
+ {3534, {wxLocale, addCatalog_1, 1}},
+ {3535, {wxLocale, addCatalog_3, 3}},
+ {3536, {wxLocale, addCatalogLookupPathPrefix, 1}},
+ {3537, {wxLocale, getCanonicalName, 0}},
+ {3538, {wxLocale, getLanguage, 0}},
+ {3539, {wxLocale, getLanguageName, 1}},
+ {3540, {wxLocale, getLocale, 0}},
+ {3541, {wxLocale, getName, 0}},
+ {3542, {wxLocale, getString_2, 2}},
+ {3543, {wxLocale, getString_4, 4}},
+ {3544, {wxLocale, getHeaderValue, 2}},
+ {3545, {wxLocale, getSysName, 0}},
+ {3546, {wxLocale, getSystemEncoding, 0}},
+ {3547, {wxLocale, getSystemEncodingName, 0}},
+ {3548, {wxLocale, getSystemLanguage, 0}},
+ {3549, {wxLocale, isLoaded, 1}},
+ {3550, {wxLocale, isOk, 0}},
+ {3551, {wxActivateEvent, getActive, 0}},
+ {3553, {wxPopupWindow, new_2, 2}},
+ {3554, {wxPopupWindow, new_0, 0}},
+ {3556, {wxPopupWindow, destruct, 0}},
+ {3557, {wxPopupWindow, create, 2}},
+ {3558, {wxPopupWindow, position, 2}},
+ {3559, {wxPopupTransientWindow, new_0, 0}},
+ {3560, {wxPopupTransientWindow, new_2, 2}},
+ {3561, {wxPopupTransientWindow, destruct, 0}},
+ {3562, {wxPopupTransientWindow, popup, 1}},
+ {3563, {wxPopupTransientWindow, dismiss, 0}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index 97f9bd9695..82d0d265d7 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -1666,1662 +1666,1674 @@
-define(wxTextCtrl_Create, 1824).
-define(wxTextCtrl_Cut, 1825).
-define(wxTextCtrl_DiscardEdits, 1826).
--define(wxTextCtrl_EmulateKeyPress, 1827).
--define(wxTextCtrl_GetDefaultStyle, 1828).
--define(wxTextCtrl_GetInsertionPoint, 1829).
--define(wxTextCtrl_GetLastPosition, 1830).
--define(wxTextCtrl_GetLineLength, 1831).
--define(wxTextCtrl_GetLineText, 1832).
--define(wxTextCtrl_GetNumberOfLines, 1833).
--define(wxTextCtrl_GetRange, 1834).
--define(wxTextCtrl_GetSelection, 1835).
--define(wxTextCtrl_GetStringSelection, 1836).
--define(wxTextCtrl_GetStyle, 1837).
--define(wxTextCtrl_GetValue, 1838).
--define(wxTextCtrl_IsEditable, 1839).
--define(wxTextCtrl_IsModified, 1840).
--define(wxTextCtrl_IsMultiLine, 1841).
--define(wxTextCtrl_IsSingleLine, 1842).
--define(wxTextCtrl_LoadFile, 1843).
--define(wxTextCtrl_MarkDirty, 1844).
--define(wxTextCtrl_Paste, 1845).
--define(wxTextCtrl_PositionToXY, 1846).
--define(wxTextCtrl_Redo, 1847).
--define(wxTextCtrl_Remove, 1848).
--define(wxTextCtrl_Replace, 1849).
--define(wxTextCtrl_SaveFile, 1850).
--define(wxTextCtrl_SetDefaultStyle, 1851).
--define(wxTextCtrl_SetEditable, 1852).
--define(wxTextCtrl_SetInsertionPoint, 1853).
--define(wxTextCtrl_SetInsertionPointEnd, 1854).
--define(wxTextCtrl_SetMaxLength, 1856).
--define(wxTextCtrl_SetSelection, 1857).
--define(wxTextCtrl_SetStyle, 1858).
--define(wxTextCtrl_SetValue, 1859).
--define(wxTextCtrl_ShowPosition, 1860).
--define(wxTextCtrl_Undo, 1861).
--define(wxTextCtrl_WriteText, 1862).
--define(wxTextCtrl_XYToPosition, 1863).
--define(wxNotebook_new_0, 1866).
--define(wxNotebook_new_3, 1867).
--define(wxNotebook_destruct, 1868).
--define(wxNotebook_AddPage, 1869).
--define(wxNotebook_AdvanceSelection, 1870).
--define(wxNotebook_AssignImageList, 1871).
--define(wxNotebook_Create, 1872).
--define(wxNotebook_DeleteAllPages, 1873).
--define(wxNotebook_DeletePage, 1874).
--define(wxNotebook_RemovePage, 1875).
--define(wxNotebook_GetCurrentPage, 1876).
--define(wxNotebook_GetImageList, 1877).
--define(wxNotebook_GetPage, 1879).
--define(wxNotebook_GetPageCount, 1880).
--define(wxNotebook_GetPageImage, 1881).
--define(wxNotebook_GetPageText, 1882).
--define(wxNotebook_GetRowCount, 1883).
--define(wxNotebook_GetSelection, 1884).
--define(wxNotebook_GetThemeBackgroundColour, 1885).
--define(wxNotebook_HitTest, 1887).
--define(wxNotebook_InsertPage, 1889).
--define(wxNotebook_SetImageList, 1890).
--define(wxNotebook_SetPadding, 1891).
--define(wxNotebook_SetPageSize, 1892).
--define(wxNotebook_SetPageImage, 1893).
--define(wxNotebook_SetPageText, 1894).
--define(wxNotebook_SetSelection, 1895).
--define(wxNotebook_ChangeSelection, 1896).
--define(wxChoicebook_new_0, 1897).
--define(wxChoicebook_new_3, 1898).
--define(wxChoicebook_AddPage, 1899).
--define(wxChoicebook_AdvanceSelection, 1900).
--define(wxChoicebook_AssignImageList, 1901).
--define(wxChoicebook_Create, 1902).
--define(wxChoicebook_DeleteAllPages, 1903).
--define(wxChoicebook_DeletePage, 1904).
--define(wxChoicebook_RemovePage, 1905).
--define(wxChoicebook_GetCurrentPage, 1906).
--define(wxChoicebook_GetImageList, 1907).
--define(wxChoicebook_GetPage, 1909).
--define(wxChoicebook_GetPageCount, 1910).
--define(wxChoicebook_GetPageImage, 1911).
--define(wxChoicebook_GetPageText, 1912).
--define(wxChoicebook_GetSelection, 1913).
--define(wxChoicebook_HitTest, 1914).
--define(wxChoicebook_InsertPage, 1915).
--define(wxChoicebook_SetImageList, 1916).
--define(wxChoicebook_SetPageSize, 1917).
--define(wxChoicebook_SetPageImage, 1918).
--define(wxChoicebook_SetPageText, 1919).
--define(wxChoicebook_SetSelection, 1920).
--define(wxChoicebook_ChangeSelection, 1921).
--define(wxChoicebook_destroy, 1922).
--define(wxToolbook_new_0, 1923).
--define(wxToolbook_new_3, 1924).
--define(wxToolbook_AddPage, 1925).
--define(wxToolbook_AdvanceSelection, 1926).
--define(wxToolbook_AssignImageList, 1927).
--define(wxToolbook_Create, 1928).
--define(wxToolbook_DeleteAllPages, 1929).
--define(wxToolbook_DeletePage, 1930).
--define(wxToolbook_RemovePage, 1931).
--define(wxToolbook_GetCurrentPage, 1932).
--define(wxToolbook_GetImageList, 1933).
--define(wxToolbook_GetPage, 1935).
--define(wxToolbook_GetPageCount, 1936).
--define(wxToolbook_GetPageImage, 1937).
--define(wxToolbook_GetPageText, 1938).
--define(wxToolbook_GetSelection, 1939).
--define(wxToolbook_HitTest, 1941).
--define(wxToolbook_InsertPage, 1942).
--define(wxToolbook_SetImageList, 1943).
--define(wxToolbook_SetPageSize, 1944).
--define(wxToolbook_SetPageImage, 1945).
--define(wxToolbook_SetPageText, 1946).
--define(wxToolbook_SetSelection, 1947).
--define(wxToolbook_ChangeSelection, 1948).
--define(wxToolbook_destroy, 1949).
--define(wxListbook_new_0, 1950).
--define(wxListbook_new_3, 1951).
--define(wxListbook_AddPage, 1952).
--define(wxListbook_AdvanceSelection, 1953).
--define(wxListbook_AssignImageList, 1954).
--define(wxListbook_Create, 1955).
--define(wxListbook_DeleteAllPages, 1956).
--define(wxListbook_DeletePage, 1957).
--define(wxListbook_RemovePage, 1958).
--define(wxListbook_GetCurrentPage, 1959).
--define(wxListbook_GetImageList, 1960).
--define(wxListbook_GetPage, 1962).
--define(wxListbook_GetPageCount, 1963).
--define(wxListbook_GetPageImage, 1964).
--define(wxListbook_GetPageText, 1965).
--define(wxListbook_GetSelection, 1966).
--define(wxListbook_HitTest, 1968).
--define(wxListbook_InsertPage, 1969).
--define(wxListbook_SetImageList, 1970).
--define(wxListbook_SetPageSize, 1971).
--define(wxListbook_SetPageImage, 1972).
--define(wxListbook_SetPageText, 1973).
--define(wxListbook_SetSelection, 1974).
--define(wxListbook_ChangeSelection, 1975).
--define(wxListbook_destroy, 1976).
--define(wxTreebook_new_0, 1977).
--define(wxTreebook_new_3, 1978).
--define(wxTreebook_AddPage, 1979).
--define(wxTreebook_AdvanceSelection, 1980).
--define(wxTreebook_AssignImageList, 1981).
--define(wxTreebook_Create, 1982).
--define(wxTreebook_DeleteAllPages, 1983).
--define(wxTreebook_DeletePage, 1984).
--define(wxTreebook_RemovePage, 1985).
--define(wxTreebook_GetCurrentPage, 1986).
--define(wxTreebook_GetImageList, 1987).
--define(wxTreebook_GetPage, 1989).
--define(wxTreebook_GetPageCount, 1990).
--define(wxTreebook_GetPageImage, 1991).
--define(wxTreebook_GetPageText, 1992).
--define(wxTreebook_GetSelection, 1993).
--define(wxTreebook_ExpandNode, 1994).
--define(wxTreebook_IsNodeExpanded, 1995).
--define(wxTreebook_HitTest, 1997).
--define(wxTreebook_InsertPage, 1998).
--define(wxTreebook_InsertSubPage, 1999).
--define(wxTreebook_SetImageList, 2000).
--define(wxTreebook_SetPageSize, 2001).
--define(wxTreebook_SetPageImage, 2002).
--define(wxTreebook_SetPageText, 2003).
--define(wxTreebook_SetSelection, 2004).
--define(wxTreebook_ChangeSelection, 2005).
--define(wxTreebook_destroy, 2006).
--define(wxTreeCtrl_new_2, 2009).
--define(wxTreeCtrl_new_0, 2010).
--define(wxTreeCtrl_destruct, 2012).
--define(wxTreeCtrl_AddRoot, 2013).
--define(wxTreeCtrl_AppendItem, 2014).
--define(wxTreeCtrl_AssignImageList, 2015).
--define(wxTreeCtrl_AssignStateImageList, 2016).
--define(wxTreeCtrl_Collapse, 2017).
--define(wxTreeCtrl_CollapseAndReset, 2018).
--define(wxTreeCtrl_Create, 2019).
--define(wxTreeCtrl_Delete, 2020).
--define(wxTreeCtrl_DeleteAllItems, 2021).
--define(wxTreeCtrl_DeleteChildren, 2022).
--define(wxTreeCtrl_EditLabel, 2023).
--define(wxTreeCtrl_EnsureVisible, 2024).
--define(wxTreeCtrl_Expand, 2025).
--define(wxTreeCtrl_GetBoundingRect, 2026).
--define(wxTreeCtrl_GetChildrenCount, 2028).
--define(wxTreeCtrl_GetCount, 2029).
--define(wxTreeCtrl_GetEditControl, 2030).
--define(wxTreeCtrl_GetFirstChild, 2031).
--define(wxTreeCtrl_GetNextChild, 2032).
--define(wxTreeCtrl_GetFirstVisibleItem, 2033).
--define(wxTreeCtrl_GetImageList, 2034).
--define(wxTreeCtrl_GetIndent, 2035).
--define(wxTreeCtrl_GetItemBackgroundColour, 2036).
--define(wxTreeCtrl_GetItemData, 2037).
--define(wxTreeCtrl_GetItemFont, 2038).
--define(wxTreeCtrl_GetItemImage_1, 2039).
--define(wxTreeCtrl_GetItemImage_2, 2040).
--define(wxTreeCtrl_GetItemText, 2041).
--define(wxTreeCtrl_GetItemTextColour, 2042).
--define(wxTreeCtrl_GetLastChild, 2043).
--define(wxTreeCtrl_GetNextSibling, 2044).
--define(wxTreeCtrl_GetNextVisible, 2045).
--define(wxTreeCtrl_GetItemParent, 2046).
--define(wxTreeCtrl_GetPrevSibling, 2047).
--define(wxTreeCtrl_GetPrevVisible, 2048).
--define(wxTreeCtrl_GetRootItem, 2049).
--define(wxTreeCtrl_GetSelection, 2050).
--define(wxTreeCtrl_GetSelections, 2051).
--define(wxTreeCtrl_GetStateImageList, 2052).
--define(wxTreeCtrl_HitTest, 2053).
--define(wxTreeCtrl_InsertItem, 2055).
--define(wxTreeCtrl_IsBold, 2056).
--define(wxTreeCtrl_IsExpanded, 2057).
--define(wxTreeCtrl_IsSelected, 2058).
--define(wxTreeCtrl_IsVisible, 2059).
--define(wxTreeCtrl_ItemHasChildren, 2060).
--define(wxTreeCtrl_IsTreeItemIdOk, 2061).
--define(wxTreeCtrl_PrependItem, 2062).
--define(wxTreeCtrl_ScrollTo, 2063).
--define(wxTreeCtrl_SelectItem_1, 2064).
--define(wxTreeCtrl_SelectItem_2, 2065).
--define(wxTreeCtrl_SetIndent, 2066).
--define(wxTreeCtrl_SetImageList, 2067).
--define(wxTreeCtrl_SetItemBackgroundColour, 2068).
--define(wxTreeCtrl_SetItemBold, 2069).
--define(wxTreeCtrl_SetItemData, 2070).
--define(wxTreeCtrl_SetItemDropHighlight, 2071).
--define(wxTreeCtrl_SetItemFont, 2072).
--define(wxTreeCtrl_SetItemHasChildren, 2073).
--define(wxTreeCtrl_SetItemImage_2, 2074).
--define(wxTreeCtrl_SetItemImage_3, 2075).
--define(wxTreeCtrl_SetItemText, 2076).
--define(wxTreeCtrl_SetItemTextColour, 2077).
--define(wxTreeCtrl_SetStateImageList, 2078).
--define(wxTreeCtrl_SetWindowStyle, 2079).
--define(wxTreeCtrl_SortChildren, 2080).
--define(wxTreeCtrl_Toggle, 2081).
--define(wxTreeCtrl_ToggleItemSelection, 2082).
--define(wxTreeCtrl_Unselect, 2083).
--define(wxTreeCtrl_UnselectAll, 2084).
--define(wxTreeCtrl_UnselectItem, 2085).
--define(wxScrollBar_new_0, 2086).
--define(wxScrollBar_new_3, 2087).
--define(wxScrollBar_destruct, 2088).
--define(wxScrollBar_Create, 2089).
--define(wxScrollBar_GetRange, 2090).
--define(wxScrollBar_GetPageSize, 2091).
--define(wxScrollBar_GetThumbPosition, 2092).
--define(wxScrollBar_GetThumbSize, 2093).
--define(wxScrollBar_SetThumbPosition, 2094).
--define(wxScrollBar_SetScrollbar, 2095).
--define(wxSpinButton_new_2, 2097).
--define(wxSpinButton_new_0, 2098).
--define(wxSpinButton_Create, 2099).
--define(wxSpinButton_GetMax, 2100).
--define(wxSpinButton_GetMin, 2101).
--define(wxSpinButton_GetValue, 2102).
--define(wxSpinButton_SetRange, 2103).
--define(wxSpinButton_SetValue, 2104).
--define(wxSpinButton_destroy, 2105).
--define(wxSpinCtrl_new_0, 2106).
--define(wxSpinCtrl_new_2, 2107).
--define(wxSpinCtrl_Create, 2109).
--define(wxSpinCtrl_SetValue_1_1, 2112).
--define(wxSpinCtrl_SetValue_1_0, 2113).
--define(wxSpinCtrl_GetValue, 2115).
--define(wxSpinCtrl_SetRange, 2117).
--define(wxSpinCtrl_SetSelection, 2118).
--define(wxSpinCtrl_GetMin, 2120).
--define(wxSpinCtrl_GetMax, 2122).
--define(wxSpinCtrl_destroy, 2123).
--define(wxStaticText_new_0, 2124).
--define(wxStaticText_new_4, 2125).
--define(wxStaticText_Create, 2126).
--define(wxStaticText_GetLabel, 2127).
--define(wxStaticText_SetLabel, 2128).
--define(wxStaticText_Wrap, 2129).
--define(wxStaticText_destroy, 2130).
--define(wxStaticBitmap_new_0, 2131).
--define(wxStaticBitmap_new_4, 2132).
--define(wxStaticBitmap_Create, 2133).
--define(wxStaticBitmap_GetBitmap, 2134).
--define(wxStaticBitmap_SetBitmap, 2135).
--define(wxStaticBitmap_destroy, 2136).
--define(wxRadioBox_new, 2137).
--define(wxRadioBox_destruct, 2139).
--define(wxRadioBox_Create, 2140).
--define(wxRadioBox_Enable_2, 2141).
--define(wxRadioBox_Enable_1, 2142).
--define(wxRadioBox_GetSelection, 2143).
--define(wxRadioBox_GetString, 2144).
--define(wxRadioBox_SetSelection, 2145).
--define(wxRadioBox_Show_2, 2146).
--define(wxRadioBox_Show_1, 2147).
--define(wxRadioBox_GetColumnCount, 2148).
--define(wxRadioBox_GetItemHelpText, 2149).
--define(wxRadioBox_GetItemToolTip, 2150).
--define(wxRadioBox_GetItemFromPoint, 2152).
--define(wxRadioBox_GetRowCount, 2153).
--define(wxRadioBox_IsItemEnabled, 2154).
--define(wxRadioBox_IsItemShown, 2155).
--define(wxRadioBox_SetItemHelpText, 2156).
--define(wxRadioBox_SetItemToolTip, 2157).
--define(wxRadioButton_new_0, 2158).
--define(wxRadioButton_new_4, 2159).
--define(wxRadioButton_Create, 2160).
--define(wxRadioButton_GetValue, 2161).
--define(wxRadioButton_SetValue, 2162).
--define(wxRadioButton_destroy, 2163).
--define(wxSlider_new_6, 2165).
--define(wxSlider_new_0, 2166).
--define(wxSlider_Create, 2167).
--define(wxSlider_GetLineSize, 2168).
--define(wxSlider_GetMax, 2169).
--define(wxSlider_GetMin, 2170).
--define(wxSlider_GetPageSize, 2171).
--define(wxSlider_GetThumbLength, 2172).
--define(wxSlider_GetValue, 2173).
--define(wxSlider_SetLineSize, 2174).
--define(wxSlider_SetPageSize, 2175).
--define(wxSlider_SetRange, 2176).
--define(wxSlider_SetThumbLength, 2177).
--define(wxSlider_SetValue, 2178).
--define(wxSlider_destroy, 2179).
--define(wxDialog_new_4, 2181).
--define(wxDialog_new_0, 2182).
--define(wxDialog_destruct, 2184).
--define(wxDialog_Create, 2185).
--define(wxDialog_CreateButtonSizer, 2186).
--define(wxDialog_CreateStdDialogButtonSizer, 2187).
--define(wxDialog_EndModal, 2188).
--define(wxDialog_GetAffirmativeId, 2189).
--define(wxDialog_GetReturnCode, 2190).
--define(wxDialog_IsModal, 2191).
--define(wxDialog_SetAffirmativeId, 2192).
--define(wxDialog_SetReturnCode, 2193).
--define(wxDialog_Show, 2194).
--define(wxDialog_ShowModal, 2195).
--define(wxColourDialog_new_0, 2196).
--define(wxColourDialog_new_2, 2197).
--define(wxColourDialog_destruct, 2198).
--define(wxColourDialog_Create, 2199).
--define(wxColourDialog_GetColourData, 2200).
--define(wxColourData_new_0, 2201).
--define(wxColourData_new_1, 2202).
--define(wxColourData_destruct, 2203).
--define(wxColourData_GetChooseFull, 2204).
--define(wxColourData_GetColour, 2205).
--define(wxColourData_GetCustomColour, 2207).
--define(wxColourData_SetChooseFull, 2208).
--define(wxColourData_SetColour, 2209).
--define(wxColourData_SetCustomColour, 2210).
--define(wxPalette_new_0, 2211).
--define(wxPalette_new_4, 2212).
--define(wxPalette_destruct, 2214).
--define(wxPalette_Create, 2215).
--define(wxPalette_GetColoursCount, 2216).
--define(wxPalette_GetPixel, 2217).
--define(wxPalette_GetRGB, 2218).
--define(wxPalette_IsOk, 2219).
--define(wxDirDialog_new, 2223).
--define(wxDirDialog_destruct, 2224).
--define(wxDirDialog_GetPath, 2225).
--define(wxDirDialog_GetMessage, 2226).
--define(wxDirDialog_SetMessage, 2227).
--define(wxDirDialog_SetPath, 2228).
--define(wxFileDialog_new, 2232).
--define(wxFileDialog_destruct, 2233).
--define(wxFileDialog_GetDirectory, 2234).
--define(wxFileDialog_GetFilename, 2235).
--define(wxFileDialog_GetFilenames, 2236).
--define(wxFileDialog_GetFilterIndex, 2237).
--define(wxFileDialog_GetMessage, 2238).
--define(wxFileDialog_GetPath, 2239).
--define(wxFileDialog_GetPaths, 2240).
--define(wxFileDialog_GetWildcard, 2241).
--define(wxFileDialog_SetDirectory, 2242).
--define(wxFileDialog_SetFilename, 2243).
--define(wxFileDialog_SetFilterIndex, 2244).
--define(wxFileDialog_SetMessage, 2245).
--define(wxFileDialog_SetPath, 2246).
--define(wxFileDialog_SetWildcard, 2247).
--define(wxPickerBase_SetInternalMargin, 2248).
--define(wxPickerBase_GetInternalMargin, 2249).
--define(wxPickerBase_SetTextCtrlProportion, 2250).
--define(wxPickerBase_SetPickerCtrlProportion, 2251).
--define(wxPickerBase_GetTextCtrlProportion, 2252).
--define(wxPickerBase_GetPickerCtrlProportion, 2253).
--define(wxPickerBase_HasTextCtrl, 2254).
--define(wxPickerBase_GetTextCtrl, 2255).
--define(wxPickerBase_IsTextCtrlGrowable, 2256).
--define(wxPickerBase_SetPickerCtrlGrowable, 2257).
--define(wxPickerBase_SetTextCtrlGrowable, 2258).
--define(wxPickerBase_IsPickerCtrlGrowable, 2259).
--define(wxFilePickerCtrl_new_0, 2260).
--define(wxFilePickerCtrl_new_3, 2261).
--define(wxFilePickerCtrl_Create, 2262).
--define(wxFilePickerCtrl_GetPath, 2263).
--define(wxFilePickerCtrl_SetPath, 2264).
--define(wxFilePickerCtrl_destroy, 2265).
--define(wxDirPickerCtrl_new_0, 2266).
--define(wxDirPickerCtrl_new_3, 2267).
--define(wxDirPickerCtrl_Create, 2268).
--define(wxDirPickerCtrl_GetPath, 2269).
--define(wxDirPickerCtrl_SetPath, 2270).
--define(wxDirPickerCtrl_destroy, 2271).
--define(wxColourPickerCtrl_new_0, 2272).
--define(wxColourPickerCtrl_new_3, 2273).
--define(wxColourPickerCtrl_Create, 2274).
--define(wxColourPickerCtrl_GetColour, 2275).
--define(wxColourPickerCtrl_SetColour_1_1, 2276).
--define(wxColourPickerCtrl_SetColour_1_0, 2277).
--define(wxColourPickerCtrl_destroy, 2278).
--define(wxDatePickerCtrl_new_0, 2279).
--define(wxDatePickerCtrl_new_3, 2280).
--define(wxDatePickerCtrl_GetRange, 2281).
--define(wxDatePickerCtrl_GetValue, 2282).
--define(wxDatePickerCtrl_SetRange, 2283).
--define(wxDatePickerCtrl_SetValue, 2284).
--define(wxDatePickerCtrl_destroy, 2285).
--define(wxFontPickerCtrl_new_0, 2286).
--define(wxFontPickerCtrl_new_3, 2287).
--define(wxFontPickerCtrl_Create, 2288).
--define(wxFontPickerCtrl_GetSelectedFont, 2289).
--define(wxFontPickerCtrl_SetSelectedFont, 2290).
--define(wxFontPickerCtrl_GetMaxPointSize, 2291).
--define(wxFontPickerCtrl_SetMaxPointSize, 2292).
--define(wxFontPickerCtrl_destroy, 2293).
--define(wxFindReplaceDialog_new_0, 2296).
--define(wxFindReplaceDialog_new_4, 2297).
--define(wxFindReplaceDialog_destruct, 2298).
--define(wxFindReplaceDialog_Create, 2299).
--define(wxFindReplaceDialog_GetData, 2300).
--define(wxFindReplaceData_new_0, 2301).
--define(wxFindReplaceData_new_1, 2302).
--define(wxFindReplaceData_GetFindString, 2303).
--define(wxFindReplaceData_GetReplaceString, 2304).
--define(wxFindReplaceData_GetFlags, 2305).
--define(wxFindReplaceData_SetFlags, 2306).
--define(wxFindReplaceData_SetFindString, 2307).
--define(wxFindReplaceData_SetReplaceString, 2308).
--define(wxFindReplaceData_destroy, 2309).
--define(wxMultiChoiceDialog_new_0, 2310).
--define(wxMultiChoiceDialog_new_5, 2312).
--define(wxMultiChoiceDialog_GetSelections, 2313).
--define(wxMultiChoiceDialog_SetSelections, 2314).
--define(wxMultiChoiceDialog_destroy, 2315).
--define(wxSingleChoiceDialog_new_0, 2316).
--define(wxSingleChoiceDialog_new_5, 2318).
--define(wxSingleChoiceDialog_GetSelection, 2319).
--define(wxSingleChoiceDialog_GetStringSelection, 2320).
--define(wxSingleChoiceDialog_SetSelection, 2321).
--define(wxSingleChoiceDialog_destroy, 2322).
--define(wxTextEntryDialog_new, 2323).
--define(wxTextEntryDialog_GetValue, 2324).
--define(wxTextEntryDialog_SetValue, 2325).
--define(wxTextEntryDialog_destroy, 2326).
--define(wxPasswordEntryDialog_new, 2327).
--define(wxPasswordEntryDialog_destroy, 2328).
--define(wxFontData_new_0, 2329).
--define(wxFontData_new_1, 2330).
--define(wxFontData_destruct, 2331).
--define(wxFontData_EnableEffects, 2332).
--define(wxFontData_GetAllowSymbols, 2333).
--define(wxFontData_GetColour, 2334).
--define(wxFontData_GetChosenFont, 2335).
--define(wxFontData_GetEnableEffects, 2336).
--define(wxFontData_GetInitialFont, 2337).
--define(wxFontData_GetShowHelp, 2338).
--define(wxFontData_SetAllowSymbols, 2339).
--define(wxFontData_SetChosenFont, 2340).
--define(wxFontData_SetColour, 2341).
--define(wxFontData_SetInitialFont, 2342).
--define(wxFontData_SetRange, 2343).
--define(wxFontData_SetShowHelp, 2344).
--define(wxFontDialog_new_0, 2348).
--define(wxFontDialog_new_2, 2350).
--define(wxFontDialog_Create, 2352).
--define(wxFontDialog_GetFontData, 2353).
--define(wxFontDialog_destroy, 2355).
--define(wxProgressDialog_new, 2356).
--define(wxProgressDialog_destruct, 2357).
--define(wxProgressDialog_Resume, 2358).
--define(wxProgressDialog_Update_2, 2359).
--define(wxProgressDialog_Update_0, 2360).
--define(wxMessageDialog_new, 2361).
--define(wxMessageDialog_destruct, 2362).
--define(wxPageSetupDialog_new, 2363).
--define(wxPageSetupDialog_destruct, 2364).
--define(wxPageSetupDialog_GetPageSetupData, 2365).
--define(wxPageSetupDialog_ShowModal, 2366).
--define(wxPageSetupDialogData_new_0, 2367).
--define(wxPageSetupDialogData_new_1_0, 2368).
--define(wxPageSetupDialogData_new_1_1, 2369).
--define(wxPageSetupDialogData_destruct, 2370).
--define(wxPageSetupDialogData_EnableHelp, 2371).
--define(wxPageSetupDialogData_EnableMargins, 2372).
--define(wxPageSetupDialogData_EnableOrientation, 2373).
--define(wxPageSetupDialogData_EnablePaper, 2374).
--define(wxPageSetupDialogData_EnablePrinter, 2375).
--define(wxPageSetupDialogData_GetDefaultMinMargins, 2376).
--define(wxPageSetupDialogData_GetEnableMargins, 2377).
--define(wxPageSetupDialogData_GetEnableOrientation, 2378).
--define(wxPageSetupDialogData_GetEnablePaper, 2379).
--define(wxPageSetupDialogData_GetEnablePrinter, 2380).
--define(wxPageSetupDialogData_GetEnableHelp, 2381).
--define(wxPageSetupDialogData_GetDefaultInfo, 2382).
--define(wxPageSetupDialogData_GetMarginTopLeft, 2383).
--define(wxPageSetupDialogData_GetMarginBottomRight, 2384).
--define(wxPageSetupDialogData_GetMinMarginTopLeft, 2385).
--define(wxPageSetupDialogData_GetMinMarginBottomRight, 2386).
--define(wxPageSetupDialogData_GetPaperId, 2387).
--define(wxPageSetupDialogData_GetPaperSize, 2388).
--define(wxPageSetupDialogData_GetPrintData, 2390).
--define(wxPageSetupDialogData_IsOk, 2391).
--define(wxPageSetupDialogData_SetDefaultInfo, 2392).
--define(wxPageSetupDialogData_SetDefaultMinMargins, 2393).
--define(wxPageSetupDialogData_SetMarginTopLeft, 2394).
--define(wxPageSetupDialogData_SetMarginBottomRight, 2395).
--define(wxPageSetupDialogData_SetMinMarginTopLeft, 2396).
--define(wxPageSetupDialogData_SetMinMarginBottomRight, 2397).
--define(wxPageSetupDialogData_SetPaperId, 2398).
--define(wxPageSetupDialogData_SetPaperSize_1_1, 2399).
--define(wxPageSetupDialogData_SetPaperSize_1_0, 2400).
--define(wxPageSetupDialogData_SetPrintData, 2401).
--define(wxPrintDialog_new_2_0, 2402).
--define(wxPrintDialog_new_2_1, 2403).
--define(wxPrintDialog_destruct, 2404).
--define(wxPrintDialog_GetPrintDialogData, 2405).
--define(wxPrintDialog_GetPrintDC, 2406).
--define(wxPrintDialogData_new_0, 2407).
--define(wxPrintDialogData_new_1_1, 2408).
--define(wxPrintDialogData_new_1_0, 2409).
--define(wxPrintDialogData_destruct, 2410).
--define(wxPrintDialogData_EnableHelp, 2411).
--define(wxPrintDialogData_EnablePageNumbers, 2412).
--define(wxPrintDialogData_EnablePrintToFile, 2413).
--define(wxPrintDialogData_EnableSelection, 2414).
--define(wxPrintDialogData_GetAllPages, 2415).
--define(wxPrintDialogData_GetCollate, 2416).
--define(wxPrintDialogData_GetFromPage, 2417).
--define(wxPrintDialogData_GetMaxPage, 2418).
--define(wxPrintDialogData_GetMinPage, 2419).
--define(wxPrintDialogData_GetNoCopies, 2420).
--define(wxPrintDialogData_GetPrintData, 2421).
--define(wxPrintDialogData_GetPrintToFile, 2422).
--define(wxPrintDialogData_GetSelection, 2423).
--define(wxPrintDialogData_GetToPage, 2424).
--define(wxPrintDialogData_IsOk, 2425).
--define(wxPrintDialogData_SetCollate, 2426).
--define(wxPrintDialogData_SetFromPage, 2427).
--define(wxPrintDialogData_SetMaxPage, 2428).
--define(wxPrintDialogData_SetMinPage, 2429).
--define(wxPrintDialogData_SetNoCopies, 2430).
--define(wxPrintDialogData_SetPrintData, 2431).
--define(wxPrintDialogData_SetPrintToFile, 2432).
--define(wxPrintDialogData_SetSelection, 2433).
--define(wxPrintDialogData_SetToPage, 2434).
--define(wxPrintData_new_0, 2435).
--define(wxPrintData_new_1, 2436).
--define(wxPrintData_destruct, 2437).
--define(wxPrintData_GetCollate, 2438).
--define(wxPrintData_GetBin, 2439).
--define(wxPrintData_GetColour, 2440).
--define(wxPrintData_GetDuplex, 2441).
--define(wxPrintData_GetNoCopies, 2442).
--define(wxPrintData_GetOrientation, 2443).
--define(wxPrintData_GetPaperId, 2444).
--define(wxPrintData_GetPrinterName, 2445).
--define(wxPrintData_GetQuality, 2446).
--define(wxPrintData_IsOk, 2447).
--define(wxPrintData_SetBin, 2448).
--define(wxPrintData_SetCollate, 2449).
--define(wxPrintData_SetColour, 2450).
--define(wxPrintData_SetDuplex, 2451).
--define(wxPrintData_SetNoCopies, 2452).
--define(wxPrintData_SetOrientation, 2453).
--define(wxPrintData_SetPaperId, 2454).
--define(wxPrintData_SetPrinterName, 2455).
--define(wxPrintData_SetQuality, 2456).
--define(wxPrintPreview_new_2, 2459).
--define(wxPrintPreview_new_3, 2460).
--define(wxPrintPreview_destruct, 2462).
--define(wxPrintPreview_GetCanvas, 2463).
--define(wxPrintPreview_GetCurrentPage, 2464).
--define(wxPrintPreview_GetFrame, 2465).
--define(wxPrintPreview_GetMaxPage, 2466).
--define(wxPrintPreview_GetMinPage, 2467).
--define(wxPrintPreview_GetPrintout, 2468).
--define(wxPrintPreview_GetPrintoutForPrinting, 2469).
--define(wxPrintPreview_IsOk, 2470).
--define(wxPrintPreview_PaintPage, 2471).
--define(wxPrintPreview_Print, 2472).
--define(wxPrintPreview_RenderPage, 2473).
--define(wxPrintPreview_SetCanvas, 2474).
--define(wxPrintPreview_SetCurrentPage, 2475).
--define(wxPrintPreview_SetFrame, 2476).
--define(wxPrintPreview_SetPrintout, 2477).
--define(wxPrintPreview_SetZoom, 2478).
--define(wxPreviewFrame_new, 2479).
--define(wxPreviewFrame_destruct, 2480).
--define(wxPreviewFrame_CreateControlBar, 2481).
--define(wxPreviewFrame_CreateCanvas, 2482).
--define(wxPreviewFrame_Initialize, 2483).
--define(wxPreviewFrame_OnCloseWindow, 2484).
--define(wxPreviewControlBar_new, 2485).
--define(wxPreviewControlBar_destruct, 2486).
--define(wxPreviewControlBar_CreateButtons, 2487).
--define(wxPreviewControlBar_GetPrintPreview, 2488).
--define(wxPreviewControlBar_GetZoomControl, 2489).
--define(wxPreviewControlBar_SetZoomControl, 2490).
--define(wxPrinter_new, 2492).
--define(wxPrinter_CreateAbortWindow, 2493).
--define(wxPrinter_GetAbort, 2494).
--define(wxPrinter_GetLastError, 2495).
--define(wxPrinter_GetPrintDialogData, 2496).
--define(wxPrinter_Print, 2497).
--define(wxPrinter_PrintDialog, 2498).
--define(wxPrinter_ReportError, 2499).
--define(wxPrinter_Setup, 2500).
--define(wxPrinter_destroy, 2501).
--define(wxXmlResource_new_1, 2502).
--define(wxXmlResource_new_2, 2503).
--define(wxXmlResource_destruct, 2504).
--define(wxXmlResource_AttachUnknownControl, 2505).
--define(wxXmlResource_ClearHandlers, 2506).
--define(wxXmlResource_CompareVersion, 2507).
--define(wxXmlResource_Get, 2508).
--define(wxXmlResource_GetFlags, 2509).
--define(wxXmlResource_GetVersion, 2510).
--define(wxXmlResource_GetXRCID, 2511).
--define(wxXmlResource_InitAllHandlers, 2512).
--define(wxXmlResource_Load, 2513).
--define(wxXmlResource_LoadBitmap, 2514).
--define(wxXmlResource_LoadDialog_2, 2515).
--define(wxXmlResource_LoadDialog_3, 2516).
--define(wxXmlResource_LoadFrame_2, 2517).
--define(wxXmlResource_LoadFrame_3, 2518).
--define(wxXmlResource_LoadIcon, 2519).
--define(wxXmlResource_LoadMenu, 2520).
--define(wxXmlResource_LoadMenuBar_2, 2521).
--define(wxXmlResource_LoadMenuBar_1, 2522).
--define(wxXmlResource_LoadPanel_2, 2523).
--define(wxXmlResource_LoadPanel_3, 2524).
--define(wxXmlResource_LoadToolBar, 2525).
--define(wxXmlResource_Set, 2526).
--define(wxXmlResource_SetFlags, 2527).
--define(wxXmlResource_Unload, 2528).
--define(wxXmlResource_xrcctrl, 2529).
--define(wxHtmlEasyPrinting_new, 2530).
--define(wxHtmlEasyPrinting_destruct, 2531).
--define(wxHtmlEasyPrinting_GetPrintData, 2532).
--define(wxHtmlEasyPrinting_GetPageSetupData, 2533).
--define(wxHtmlEasyPrinting_PreviewFile, 2534).
--define(wxHtmlEasyPrinting_PreviewText, 2535).
--define(wxHtmlEasyPrinting_PrintFile, 2536).
--define(wxHtmlEasyPrinting_PrintText, 2537).
--define(wxHtmlEasyPrinting_PageSetup, 2538).
--define(wxHtmlEasyPrinting_SetFonts, 2539).
--define(wxHtmlEasyPrinting_SetHeader, 2540).
--define(wxHtmlEasyPrinting_SetFooter, 2541).
--define(wxGLCanvas_new_2, 2543).
--define(wxGLCanvas_new_3_1, 2544).
--define(wxGLCanvas_new_3_0, 2545).
--define(wxGLCanvas_GetContext, 2546).
--define(wxGLCanvas_SetCurrent, 2548).
--define(wxGLCanvas_SwapBuffers, 2549).
--define(wxGLCanvas_destroy, 2550).
--define(wxAuiManager_new, 2551).
--define(wxAuiManager_destruct, 2552).
--define(wxAuiManager_AddPane_2_1, 2553).
--define(wxAuiManager_AddPane_3, 2554).
--define(wxAuiManager_AddPane_2_0, 2555).
--define(wxAuiManager_DetachPane, 2556).
--define(wxAuiManager_GetAllPanes, 2557).
--define(wxAuiManager_GetArtProvider, 2558).
--define(wxAuiManager_GetDockSizeConstraint, 2559).
--define(wxAuiManager_GetFlags, 2560).
--define(wxAuiManager_GetManagedWindow, 2561).
--define(wxAuiManager_GetManager, 2562).
--define(wxAuiManager_GetPane_1_1, 2563).
--define(wxAuiManager_GetPane_1_0, 2564).
--define(wxAuiManager_HideHint, 2565).
--define(wxAuiManager_InsertPane, 2566).
--define(wxAuiManager_LoadPaneInfo, 2567).
--define(wxAuiManager_LoadPerspective, 2568).
--define(wxAuiManager_SavePaneInfo, 2569).
--define(wxAuiManager_SavePerspective, 2570).
--define(wxAuiManager_SetArtProvider, 2571).
--define(wxAuiManager_SetDockSizeConstraint, 2572).
--define(wxAuiManager_SetFlags, 2573).
--define(wxAuiManager_SetManagedWindow, 2574).
--define(wxAuiManager_ShowHint, 2575).
--define(wxAuiManager_UnInit, 2576).
--define(wxAuiManager_Update, 2577).
--define(wxAuiPaneInfo_new_0, 2578).
--define(wxAuiPaneInfo_new_1, 2579).
--define(wxAuiPaneInfo_destruct, 2580).
--define(wxAuiPaneInfo_BestSize_1, 2581).
--define(wxAuiPaneInfo_BestSize_2, 2582).
--define(wxAuiPaneInfo_Bottom, 2583).
--define(wxAuiPaneInfo_BottomDockable, 2584).
--define(wxAuiPaneInfo_Caption, 2585).
--define(wxAuiPaneInfo_CaptionVisible, 2586).
--define(wxAuiPaneInfo_Centre, 2587).
--define(wxAuiPaneInfo_CentrePane, 2588).
--define(wxAuiPaneInfo_CloseButton, 2589).
--define(wxAuiPaneInfo_DefaultPane, 2590).
--define(wxAuiPaneInfo_DestroyOnClose, 2591).
--define(wxAuiPaneInfo_Direction, 2592).
--define(wxAuiPaneInfo_Dock, 2593).
--define(wxAuiPaneInfo_Dockable, 2594).
--define(wxAuiPaneInfo_Fixed, 2595).
--define(wxAuiPaneInfo_Float, 2596).
--define(wxAuiPaneInfo_Floatable, 2597).
--define(wxAuiPaneInfo_FloatingPosition_1, 2598).
--define(wxAuiPaneInfo_FloatingPosition_2, 2599).
--define(wxAuiPaneInfo_FloatingSize_1, 2600).
--define(wxAuiPaneInfo_FloatingSize_2, 2601).
--define(wxAuiPaneInfo_Gripper, 2602).
--define(wxAuiPaneInfo_GripperTop, 2603).
--define(wxAuiPaneInfo_HasBorder, 2604).
--define(wxAuiPaneInfo_HasCaption, 2605).
--define(wxAuiPaneInfo_HasCloseButton, 2606).
--define(wxAuiPaneInfo_HasFlag, 2607).
--define(wxAuiPaneInfo_HasGripper, 2608).
--define(wxAuiPaneInfo_HasGripperTop, 2609).
--define(wxAuiPaneInfo_HasMaximizeButton, 2610).
--define(wxAuiPaneInfo_HasMinimizeButton, 2611).
--define(wxAuiPaneInfo_HasPinButton, 2612).
--define(wxAuiPaneInfo_Hide, 2613).
--define(wxAuiPaneInfo_IsBottomDockable, 2614).
--define(wxAuiPaneInfo_IsDocked, 2615).
--define(wxAuiPaneInfo_IsFixed, 2616).
--define(wxAuiPaneInfo_IsFloatable, 2617).
--define(wxAuiPaneInfo_IsFloating, 2618).
--define(wxAuiPaneInfo_IsLeftDockable, 2619).
--define(wxAuiPaneInfo_IsMovable, 2620).
--define(wxAuiPaneInfo_IsOk, 2621).
--define(wxAuiPaneInfo_IsResizable, 2622).
--define(wxAuiPaneInfo_IsRightDockable, 2623).
--define(wxAuiPaneInfo_IsShown, 2624).
--define(wxAuiPaneInfo_IsToolbar, 2625).
--define(wxAuiPaneInfo_IsTopDockable, 2626).
--define(wxAuiPaneInfo_Layer, 2627).
--define(wxAuiPaneInfo_Left, 2628).
--define(wxAuiPaneInfo_LeftDockable, 2629).
--define(wxAuiPaneInfo_MaxSize_1, 2630).
--define(wxAuiPaneInfo_MaxSize_2, 2631).
--define(wxAuiPaneInfo_MaximizeButton, 2632).
--define(wxAuiPaneInfo_MinSize_1, 2633).
--define(wxAuiPaneInfo_MinSize_2, 2634).
--define(wxAuiPaneInfo_MinimizeButton, 2635).
--define(wxAuiPaneInfo_Movable, 2636).
--define(wxAuiPaneInfo_Name, 2637).
--define(wxAuiPaneInfo_PaneBorder, 2638).
--define(wxAuiPaneInfo_PinButton, 2639).
--define(wxAuiPaneInfo_Position, 2640).
--define(wxAuiPaneInfo_Resizable, 2641).
--define(wxAuiPaneInfo_Right, 2642).
--define(wxAuiPaneInfo_RightDockable, 2643).
--define(wxAuiPaneInfo_Row, 2644).
--define(wxAuiPaneInfo_SafeSet, 2645).
--define(wxAuiPaneInfo_SetFlag, 2646).
--define(wxAuiPaneInfo_Show, 2647).
--define(wxAuiPaneInfo_ToolbarPane, 2648).
--define(wxAuiPaneInfo_Top, 2649).
--define(wxAuiPaneInfo_TopDockable, 2650).
--define(wxAuiPaneInfo_Window, 2651).
--define(wxAuiNotebook_new_0, 2652).
--define(wxAuiNotebook_new_2, 2653).
--define(wxAuiNotebook_AddPage, 2654).
--define(wxAuiNotebook_Create, 2655).
--define(wxAuiNotebook_DeletePage, 2656).
--define(wxAuiNotebook_GetArtProvider, 2657).
--define(wxAuiNotebook_GetPage, 2658).
--define(wxAuiNotebook_GetPageBitmap, 2659).
--define(wxAuiNotebook_GetPageCount, 2660).
--define(wxAuiNotebook_GetPageIndex, 2661).
--define(wxAuiNotebook_GetPageText, 2662).
--define(wxAuiNotebook_GetSelection, 2663).
--define(wxAuiNotebook_InsertPage, 2664).
--define(wxAuiNotebook_RemovePage, 2665).
--define(wxAuiNotebook_SetArtProvider, 2666).
--define(wxAuiNotebook_SetFont, 2667).
--define(wxAuiNotebook_SetPageBitmap, 2668).
--define(wxAuiNotebook_SetPageText, 2669).
--define(wxAuiNotebook_SetSelection, 2670).
--define(wxAuiNotebook_SetTabCtrlHeight, 2671).
--define(wxAuiNotebook_SetUniformBitmapSize, 2672).
--define(wxAuiNotebook_destroy, 2673).
--define(wxMDIParentFrame_new_0, 2674).
--define(wxMDIParentFrame_new_4, 2675).
--define(wxMDIParentFrame_destruct, 2676).
--define(wxMDIParentFrame_ActivateNext, 2677).
--define(wxMDIParentFrame_ActivatePrevious, 2678).
--define(wxMDIParentFrame_ArrangeIcons, 2679).
--define(wxMDIParentFrame_Cascade, 2680).
--define(wxMDIParentFrame_Create, 2681).
--define(wxMDIParentFrame_GetActiveChild, 2682).
--define(wxMDIParentFrame_GetClientWindow, 2683).
--define(wxMDIParentFrame_Tile, 2684).
--define(wxMDIChildFrame_new_0, 2685).
--define(wxMDIChildFrame_new_4, 2686).
--define(wxMDIChildFrame_destruct, 2687).
--define(wxMDIChildFrame_Activate, 2688).
--define(wxMDIChildFrame_Create, 2689).
--define(wxMDIChildFrame_Maximize, 2690).
--define(wxMDIChildFrame_Restore, 2691).
--define(wxMDIClientWindow_new_0, 2692).
--define(wxMDIClientWindow_new_2, 2693).
--define(wxMDIClientWindow_destruct, 2694).
--define(wxMDIClientWindow_CreateClient, 2695).
--define(wxLayoutAlgorithm_new, 2696).
--define(wxLayoutAlgorithm_LayoutFrame, 2697).
--define(wxLayoutAlgorithm_LayoutMDIFrame, 2698).
--define(wxLayoutAlgorithm_LayoutWindow, 2699).
--define(wxLayoutAlgorithm_destroy, 2700).
--define(wxEvent_GetId, 2701).
--define(wxEvent_GetSkipped, 2702).
--define(wxEvent_GetTimestamp, 2703).
--define(wxEvent_IsCommandEvent, 2704).
--define(wxEvent_ResumePropagation, 2705).
--define(wxEvent_ShouldPropagate, 2706).
--define(wxEvent_Skip, 2707).
--define(wxEvent_StopPropagation, 2708).
--define(wxCommandEvent_getClientData, 2709).
--define(wxCommandEvent_GetExtraLong, 2710).
--define(wxCommandEvent_GetInt, 2711).
--define(wxCommandEvent_GetSelection, 2712).
--define(wxCommandEvent_GetString, 2713).
--define(wxCommandEvent_IsChecked, 2714).
--define(wxCommandEvent_IsSelection, 2715).
--define(wxCommandEvent_SetInt, 2716).
--define(wxCommandEvent_SetString, 2717).
--define(wxScrollEvent_GetOrientation, 2718).
--define(wxScrollEvent_GetPosition, 2719).
--define(wxScrollWinEvent_GetOrientation, 2720).
--define(wxScrollWinEvent_GetPosition, 2721).
--define(wxMouseEvent_AltDown, 2722).
--define(wxMouseEvent_Button, 2723).
--define(wxMouseEvent_ButtonDClick, 2724).
--define(wxMouseEvent_ButtonDown, 2725).
--define(wxMouseEvent_ButtonUp, 2726).
--define(wxMouseEvent_CmdDown, 2727).
--define(wxMouseEvent_ControlDown, 2728).
--define(wxMouseEvent_Dragging, 2729).
--define(wxMouseEvent_Entering, 2730).
--define(wxMouseEvent_GetButton, 2731).
--define(wxMouseEvent_GetPosition, 2734).
--define(wxMouseEvent_GetLogicalPosition, 2735).
--define(wxMouseEvent_GetLinesPerAction, 2736).
--define(wxMouseEvent_GetWheelRotation, 2737).
--define(wxMouseEvent_GetWheelDelta, 2738).
--define(wxMouseEvent_GetX, 2739).
--define(wxMouseEvent_GetY, 2740).
--define(wxMouseEvent_IsButton, 2741).
--define(wxMouseEvent_IsPageScroll, 2742).
--define(wxMouseEvent_Leaving, 2743).
--define(wxMouseEvent_LeftDClick, 2744).
--define(wxMouseEvent_LeftDown, 2745).
--define(wxMouseEvent_LeftIsDown, 2746).
--define(wxMouseEvent_LeftUp, 2747).
--define(wxMouseEvent_MetaDown, 2748).
--define(wxMouseEvent_MiddleDClick, 2749).
--define(wxMouseEvent_MiddleDown, 2750).
--define(wxMouseEvent_MiddleIsDown, 2751).
--define(wxMouseEvent_MiddleUp, 2752).
--define(wxMouseEvent_Moving, 2753).
--define(wxMouseEvent_RightDClick, 2754).
--define(wxMouseEvent_RightDown, 2755).
--define(wxMouseEvent_RightIsDown, 2756).
--define(wxMouseEvent_RightUp, 2757).
--define(wxMouseEvent_ShiftDown, 2758).
--define(wxSetCursorEvent_GetCursor, 2759).
--define(wxSetCursorEvent_GetX, 2760).
--define(wxSetCursorEvent_GetY, 2761).
--define(wxSetCursorEvent_HasCursor, 2762).
--define(wxSetCursorEvent_SetCursor, 2763).
--define(wxKeyEvent_AltDown, 2764).
--define(wxKeyEvent_CmdDown, 2765).
--define(wxKeyEvent_ControlDown, 2766).
--define(wxKeyEvent_GetKeyCode, 2767).
--define(wxKeyEvent_GetModifiers, 2768).
--define(wxKeyEvent_GetPosition, 2771).
--define(wxKeyEvent_GetRawKeyCode, 2772).
--define(wxKeyEvent_GetRawKeyFlags, 2773).
--define(wxKeyEvent_GetUnicodeKey, 2774).
--define(wxKeyEvent_GetX, 2775).
--define(wxKeyEvent_GetY, 2776).
--define(wxKeyEvent_HasModifiers, 2777).
--define(wxKeyEvent_MetaDown, 2778).
--define(wxKeyEvent_ShiftDown, 2779).
--define(wxSizeEvent_GetSize, 2780).
--define(wxMoveEvent_GetPosition, 2781).
--define(wxEraseEvent_GetDC, 2782).
--define(wxFocusEvent_GetWindow, 2783).
--define(wxChildFocusEvent_GetWindow, 2784).
--define(wxMenuEvent_GetMenu, 2785).
--define(wxMenuEvent_GetMenuId, 2786).
--define(wxMenuEvent_IsPopup, 2787).
--define(wxCloseEvent_CanVeto, 2788).
--define(wxCloseEvent_GetLoggingOff, 2789).
--define(wxCloseEvent_SetCanVeto, 2790).
--define(wxCloseEvent_SetLoggingOff, 2791).
--define(wxCloseEvent_Veto, 2792).
--define(wxShowEvent_SetShow, 2793).
--define(wxShowEvent_GetShow, 2794).
--define(wxIconizeEvent_Iconized, 2795).
--define(wxJoystickEvent_ButtonDown, 2796).
--define(wxJoystickEvent_ButtonIsDown, 2797).
--define(wxJoystickEvent_ButtonUp, 2798).
--define(wxJoystickEvent_GetButtonChange, 2799).
--define(wxJoystickEvent_GetButtonState, 2800).
--define(wxJoystickEvent_GetJoystick, 2801).
--define(wxJoystickEvent_GetPosition, 2802).
--define(wxJoystickEvent_GetZPosition, 2803).
--define(wxJoystickEvent_IsButton, 2804).
--define(wxJoystickEvent_IsMove, 2805).
--define(wxJoystickEvent_IsZMove, 2806).
--define(wxUpdateUIEvent_CanUpdate, 2807).
--define(wxUpdateUIEvent_Check, 2808).
--define(wxUpdateUIEvent_Enable, 2809).
--define(wxUpdateUIEvent_Show, 2810).
--define(wxUpdateUIEvent_GetChecked, 2811).
--define(wxUpdateUIEvent_GetEnabled, 2812).
--define(wxUpdateUIEvent_GetShown, 2813).
--define(wxUpdateUIEvent_GetSetChecked, 2814).
--define(wxUpdateUIEvent_GetSetEnabled, 2815).
--define(wxUpdateUIEvent_GetSetShown, 2816).
--define(wxUpdateUIEvent_GetSetText, 2817).
--define(wxUpdateUIEvent_GetText, 2818).
--define(wxUpdateUIEvent_GetMode, 2819).
--define(wxUpdateUIEvent_GetUpdateInterval, 2820).
--define(wxUpdateUIEvent_ResetUpdateTime, 2821).
--define(wxUpdateUIEvent_SetMode, 2822).
--define(wxUpdateUIEvent_SetText, 2823).
--define(wxUpdateUIEvent_SetUpdateInterval, 2824).
--define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2825).
--define(wxPaletteChangedEvent_SetChangedWindow, 2826).
--define(wxPaletteChangedEvent_GetChangedWindow, 2827).
--define(wxQueryNewPaletteEvent_SetPaletteRealized, 2828).
--define(wxQueryNewPaletteEvent_GetPaletteRealized, 2829).
--define(wxNavigationKeyEvent_GetDirection, 2830).
--define(wxNavigationKeyEvent_SetDirection, 2831).
--define(wxNavigationKeyEvent_IsWindowChange, 2832).
--define(wxNavigationKeyEvent_SetWindowChange, 2833).
--define(wxNavigationKeyEvent_IsFromTab, 2834).
--define(wxNavigationKeyEvent_SetFromTab, 2835).
--define(wxNavigationKeyEvent_GetCurrentFocus, 2836).
--define(wxNavigationKeyEvent_SetCurrentFocus, 2837).
--define(wxHelpEvent_GetOrigin, 2838).
--define(wxHelpEvent_GetPosition, 2839).
--define(wxHelpEvent_SetOrigin, 2840).
--define(wxHelpEvent_SetPosition, 2841).
--define(wxContextMenuEvent_GetPosition, 2842).
--define(wxContextMenuEvent_SetPosition, 2843).
--define(wxIdleEvent_CanSend, 2844).
--define(wxIdleEvent_GetMode, 2845).
--define(wxIdleEvent_RequestMore, 2846).
--define(wxIdleEvent_MoreRequested, 2847).
--define(wxIdleEvent_SetMode, 2848).
--define(wxGridEvent_AltDown, 2849).
--define(wxGridEvent_ControlDown, 2850).
--define(wxGridEvent_GetCol, 2851).
--define(wxGridEvent_GetPosition, 2852).
--define(wxGridEvent_GetRow, 2853).
--define(wxGridEvent_MetaDown, 2854).
--define(wxGridEvent_Selecting, 2855).
--define(wxGridEvent_ShiftDown, 2856).
--define(wxNotifyEvent_Allow, 2857).
--define(wxNotifyEvent_IsAllowed, 2858).
--define(wxNotifyEvent_Veto, 2859).
--define(wxSashEvent_GetEdge, 2860).
--define(wxSashEvent_GetDragRect, 2861).
--define(wxSashEvent_GetDragStatus, 2862).
--define(wxListEvent_GetCacheFrom, 2863).
--define(wxListEvent_GetCacheTo, 2864).
--define(wxListEvent_GetKeyCode, 2865).
--define(wxListEvent_GetIndex, 2866).
--define(wxListEvent_GetColumn, 2867).
--define(wxListEvent_GetPoint, 2868).
--define(wxListEvent_GetLabel, 2869).
--define(wxListEvent_GetText, 2870).
--define(wxListEvent_GetImage, 2871).
--define(wxListEvent_GetData, 2872).
--define(wxListEvent_GetMask, 2873).
--define(wxListEvent_GetItem, 2874).
--define(wxListEvent_IsEditCancelled, 2875).
--define(wxDateEvent_GetDate, 2876).
--define(wxCalendarEvent_GetWeekDay, 2877).
--define(wxFileDirPickerEvent_GetPath, 2878).
--define(wxColourPickerEvent_GetColour, 2879).
--define(wxFontPickerEvent_GetFont, 2880).
--define(wxStyledTextEvent_GetPosition, 2881).
--define(wxStyledTextEvent_GetKey, 2882).
--define(wxStyledTextEvent_GetModifiers, 2883).
--define(wxStyledTextEvent_GetModificationType, 2884).
--define(wxStyledTextEvent_GetText, 2885).
--define(wxStyledTextEvent_GetLength, 2886).
--define(wxStyledTextEvent_GetLinesAdded, 2887).
--define(wxStyledTextEvent_GetLine, 2888).
--define(wxStyledTextEvent_GetFoldLevelNow, 2889).
--define(wxStyledTextEvent_GetFoldLevelPrev, 2890).
--define(wxStyledTextEvent_GetMargin, 2891).
--define(wxStyledTextEvent_GetMessage, 2892).
--define(wxStyledTextEvent_GetWParam, 2893).
--define(wxStyledTextEvent_GetLParam, 2894).
--define(wxStyledTextEvent_GetListType, 2895).
--define(wxStyledTextEvent_GetX, 2896).
--define(wxStyledTextEvent_GetY, 2897).
--define(wxStyledTextEvent_GetDragText, 2898).
--define(wxStyledTextEvent_GetDragAllowMove, 2899).
--define(wxStyledTextEvent_GetDragResult, 2900).
--define(wxStyledTextEvent_GetShift, 2901).
--define(wxStyledTextEvent_GetControl, 2902).
--define(wxStyledTextEvent_GetAlt, 2903).
--define(utils_wxGetKeyState, 2904).
--define(utils_wxGetMousePosition, 2905).
--define(utils_wxGetMouseState, 2906).
--define(utils_wxSetDetectableAutoRepeat, 2907).
--define(utils_wxBell, 2908).
--define(utils_wxFindMenuItemId, 2909).
--define(utils_wxGenericFindWindowAtPoint, 2910).
--define(utils_wxFindWindowAtPoint, 2911).
--define(utils_wxBeginBusyCursor, 2912).
--define(utils_wxEndBusyCursor, 2913).
--define(utils_wxIsBusy, 2914).
--define(utils_wxShutdown, 2915).
--define(utils_wxShell, 2916).
--define(utils_wxLaunchDefaultBrowser, 2917).
--define(utils_wxGetEmailAddress, 2918).
--define(utils_wxGetUserId, 2919).
--define(utils_wxGetHomeDir, 2920).
--define(utils_wxNewId, 2921).
--define(utils_wxRegisterId, 2922).
--define(utils_wxGetCurrentId, 2923).
--define(utils_wxGetOsDescription, 2924).
--define(utils_wxIsPlatformLittleEndian, 2925).
--define(utils_wxIsPlatform64Bit, 2926).
--define(gdicmn_wxDisplaySize, 2927).
--define(gdicmn_wxSetCursor, 2928).
--define(wxPrintout_new, 2929).
--define(wxPrintout_destruct, 2930).
--define(wxPrintout_GetDC, 2931).
--define(wxPrintout_GetPageSizeMM, 2932).
--define(wxPrintout_GetPageSizePixels, 2933).
--define(wxPrintout_GetPaperRectPixels, 2934).
--define(wxPrintout_GetPPIPrinter, 2935).
--define(wxPrintout_GetPPIScreen, 2936).
--define(wxPrintout_GetTitle, 2937).
--define(wxPrintout_IsPreview, 2938).
--define(wxPrintout_FitThisSizeToPaper, 2939).
--define(wxPrintout_FitThisSizeToPage, 2940).
--define(wxPrintout_FitThisSizeToPageMargins, 2941).
--define(wxPrintout_MapScreenSizeToPaper, 2942).
--define(wxPrintout_MapScreenSizeToPage, 2943).
--define(wxPrintout_MapScreenSizeToPageMargins, 2944).
--define(wxPrintout_MapScreenSizeToDevice, 2945).
--define(wxPrintout_GetLogicalPaperRect, 2946).
--define(wxPrintout_GetLogicalPageRect, 2947).
--define(wxPrintout_GetLogicalPageMarginsRect, 2948).
--define(wxPrintout_SetLogicalOrigin, 2949).
--define(wxPrintout_OffsetLogicalOrigin, 2950).
--define(wxStyledTextCtrl_new_2, 2951).
--define(wxStyledTextCtrl_new_0, 2952).
--define(wxStyledTextCtrl_destruct, 2953).
--define(wxStyledTextCtrl_Create, 2954).
--define(wxStyledTextCtrl_AddText, 2955).
--define(wxStyledTextCtrl_AddStyledText, 2956).
--define(wxStyledTextCtrl_InsertText, 2957).
--define(wxStyledTextCtrl_ClearAll, 2958).
--define(wxStyledTextCtrl_ClearDocumentStyle, 2959).
--define(wxStyledTextCtrl_GetLength, 2960).
--define(wxStyledTextCtrl_GetCharAt, 2961).
--define(wxStyledTextCtrl_GetCurrentPos, 2962).
--define(wxStyledTextCtrl_GetAnchor, 2963).
--define(wxStyledTextCtrl_GetStyleAt, 2964).
--define(wxStyledTextCtrl_Redo, 2965).
--define(wxStyledTextCtrl_SetUndoCollection, 2966).
--define(wxStyledTextCtrl_SelectAll, 2967).
--define(wxStyledTextCtrl_SetSavePoint, 2968).
--define(wxStyledTextCtrl_GetStyledText, 2969).
--define(wxStyledTextCtrl_CanRedo, 2970).
--define(wxStyledTextCtrl_MarkerLineFromHandle, 2971).
--define(wxStyledTextCtrl_MarkerDeleteHandle, 2972).
--define(wxStyledTextCtrl_GetUndoCollection, 2973).
--define(wxStyledTextCtrl_GetViewWhiteSpace, 2974).
--define(wxStyledTextCtrl_SetViewWhiteSpace, 2975).
--define(wxStyledTextCtrl_PositionFromPoint, 2976).
--define(wxStyledTextCtrl_PositionFromPointClose, 2977).
--define(wxStyledTextCtrl_GotoLine, 2978).
--define(wxStyledTextCtrl_GotoPos, 2979).
--define(wxStyledTextCtrl_SetAnchor, 2980).
--define(wxStyledTextCtrl_GetCurLine, 2981).
--define(wxStyledTextCtrl_GetEndStyled, 2982).
--define(wxStyledTextCtrl_ConvertEOLs, 2983).
--define(wxStyledTextCtrl_GetEOLMode, 2984).
--define(wxStyledTextCtrl_SetEOLMode, 2985).
--define(wxStyledTextCtrl_StartStyling, 2986).
--define(wxStyledTextCtrl_SetStyling, 2987).
--define(wxStyledTextCtrl_GetBufferedDraw, 2988).
--define(wxStyledTextCtrl_SetBufferedDraw, 2989).
--define(wxStyledTextCtrl_SetTabWidth, 2990).
--define(wxStyledTextCtrl_GetTabWidth, 2991).
--define(wxStyledTextCtrl_SetCodePage, 2992).
--define(wxStyledTextCtrl_MarkerDefine, 2993).
--define(wxStyledTextCtrl_MarkerSetForeground, 2994).
--define(wxStyledTextCtrl_MarkerSetBackground, 2995).
--define(wxStyledTextCtrl_MarkerAdd, 2996).
--define(wxStyledTextCtrl_MarkerDelete, 2997).
--define(wxStyledTextCtrl_MarkerDeleteAll, 2998).
--define(wxStyledTextCtrl_MarkerGet, 2999).
--define(wxStyledTextCtrl_MarkerNext, 3000).
--define(wxStyledTextCtrl_MarkerPrevious, 3001).
--define(wxStyledTextCtrl_MarkerDefineBitmap, 3002).
--define(wxStyledTextCtrl_MarkerAddSet, 3003).
--define(wxStyledTextCtrl_MarkerSetAlpha, 3004).
--define(wxStyledTextCtrl_SetMarginType, 3005).
--define(wxStyledTextCtrl_GetMarginType, 3006).
--define(wxStyledTextCtrl_SetMarginWidth, 3007).
--define(wxStyledTextCtrl_GetMarginWidth, 3008).
--define(wxStyledTextCtrl_SetMarginMask, 3009).
--define(wxStyledTextCtrl_GetMarginMask, 3010).
--define(wxStyledTextCtrl_SetMarginSensitive, 3011).
--define(wxStyledTextCtrl_GetMarginSensitive, 3012).
--define(wxStyledTextCtrl_StyleClearAll, 3013).
--define(wxStyledTextCtrl_StyleSetForeground, 3014).
--define(wxStyledTextCtrl_StyleSetBackground, 3015).
--define(wxStyledTextCtrl_StyleSetBold, 3016).
--define(wxStyledTextCtrl_StyleSetItalic, 3017).
--define(wxStyledTextCtrl_StyleSetSize, 3018).
--define(wxStyledTextCtrl_StyleSetFaceName, 3019).
--define(wxStyledTextCtrl_StyleSetEOLFilled, 3020).
--define(wxStyledTextCtrl_StyleResetDefault, 3021).
--define(wxStyledTextCtrl_StyleSetUnderline, 3022).
--define(wxStyledTextCtrl_StyleSetCase, 3023).
--define(wxStyledTextCtrl_StyleSetHotSpot, 3024).
--define(wxStyledTextCtrl_SetSelForeground, 3025).
--define(wxStyledTextCtrl_SetSelBackground, 3026).
--define(wxStyledTextCtrl_GetSelAlpha, 3027).
--define(wxStyledTextCtrl_SetSelAlpha, 3028).
--define(wxStyledTextCtrl_SetCaretForeground, 3029).
--define(wxStyledTextCtrl_CmdKeyAssign, 3030).
--define(wxStyledTextCtrl_CmdKeyClear, 3031).
--define(wxStyledTextCtrl_CmdKeyClearAll, 3032).
--define(wxStyledTextCtrl_SetStyleBytes, 3033).
--define(wxStyledTextCtrl_StyleSetVisible, 3034).
--define(wxStyledTextCtrl_GetCaretPeriod, 3035).
--define(wxStyledTextCtrl_SetCaretPeriod, 3036).
--define(wxStyledTextCtrl_SetWordChars, 3037).
--define(wxStyledTextCtrl_BeginUndoAction, 3038).
--define(wxStyledTextCtrl_EndUndoAction, 3039).
--define(wxStyledTextCtrl_IndicatorSetStyle, 3040).
--define(wxStyledTextCtrl_IndicatorGetStyle, 3041).
--define(wxStyledTextCtrl_IndicatorSetForeground, 3042).
--define(wxStyledTextCtrl_IndicatorGetForeground, 3043).
--define(wxStyledTextCtrl_SetWhitespaceForeground, 3044).
--define(wxStyledTextCtrl_SetWhitespaceBackground, 3045).
--define(wxStyledTextCtrl_GetStyleBits, 3046).
--define(wxStyledTextCtrl_SetLineState, 3047).
--define(wxStyledTextCtrl_GetLineState, 3048).
--define(wxStyledTextCtrl_GetMaxLineState, 3049).
--define(wxStyledTextCtrl_GetCaretLineVisible, 3050).
--define(wxStyledTextCtrl_SetCaretLineVisible, 3051).
--define(wxStyledTextCtrl_GetCaretLineBackground, 3052).
--define(wxStyledTextCtrl_SetCaretLineBackground, 3053).
--define(wxStyledTextCtrl_AutoCompShow, 3054).
--define(wxStyledTextCtrl_AutoCompCancel, 3055).
--define(wxStyledTextCtrl_AutoCompActive, 3056).
--define(wxStyledTextCtrl_AutoCompPosStart, 3057).
--define(wxStyledTextCtrl_AutoCompComplete, 3058).
--define(wxStyledTextCtrl_AutoCompStops, 3059).
--define(wxStyledTextCtrl_AutoCompSetSeparator, 3060).
--define(wxStyledTextCtrl_AutoCompGetSeparator, 3061).
--define(wxStyledTextCtrl_AutoCompSelect, 3062).
--define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3063).
--define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3064).
--define(wxStyledTextCtrl_AutoCompSetFillUps, 3065).
--define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3066).
--define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3067).
--define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3068).
--define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3069).
--define(wxStyledTextCtrl_UserListShow, 3070).
--define(wxStyledTextCtrl_AutoCompSetAutoHide, 3071).
--define(wxStyledTextCtrl_AutoCompGetAutoHide, 3072).
--define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3073).
--define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3074).
--define(wxStyledTextCtrl_RegisterImage, 3075).
--define(wxStyledTextCtrl_ClearRegisteredImages, 3076).
--define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3077).
--define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3078).
--define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3079).
--define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3080).
--define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3081).
--define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3082).
--define(wxStyledTextCtrl_SetIndent, 3083).
--define(wxStyledTextCtrl_GetIndent, 3084).
--define(wxStyledTextCtrl_SetUseTabs, 3085).
--define(wxStyledTextCtrl_GetUseTabs, 3086).
--define(wxStyledTextCtrl_SetLineIndentation, 3087).
--define(wxStyledTextCtrl_GetLineIndentation, 3088).
--define(wxStyledTextCtrl_GetLineIndentPosition, 3089).
--define(wxStyledTextCtrl_GetColumn, 3090).
--define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3091).
--define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3092).
--define(wxStyledTextCtrl_SetIndentationGuides, 3093).
--define(wxStyledTextCtrl_GetIndentationGuides, 3094).
--define(wxStyledTextCtrl_SetHighlightGuide, 3095).
--define(wxStyledTextCtrl_GetHighlightGuide, 3096).
--define(wxStyledTextCtrl_GetLineEndPosition, 3097).
--define(wxStyledTextCtrl_GetCodePage, 3098).
--define(wxStyledTextCtrl_GetCaretForeground, 3099).
--define(wxStyledTextCtrl_GetReadOnly, 3100).
--define(wxStyledTextCtrl_SetCurrentPos, 3101).
--define(wxStyledTextCtrl_SetSelectionStart, 3102).
--define(wxStyledTextCtrl_GetSelectionStart, 3103).
--define(wxStyledTextCtrl_SetSelectionEnd, 3104).
--define(wxStyledTextCtrl_GetSelectionEnd, 3105).
--define(wxStyledTextCtrl_SetPrintMagnification, 3106).
--define(wxStyledTextCtrl_GetPrintMagnification, 3107).
--define(wxStyledTextCtrl_SetPrintColourMode, 3108).
--define(wxStyledTextCtrl_GetPrintColourMode, 3109).
--define(wxStyledTextCtrl_FindText, 3110).
--define(wxStyledTextCtrl_FormatRange, 3111).
--define(wxStyledTextCtrl_GetFirstVisibleLine, 3112).
--define(wxStyledTextCtrl_GetLine, 3113).
--define(wxStyledTextCtrl_GetLineCount, 3114).
--define(wxStyledTextCtrl_SetMarginLeft, 3115).
--define(wxStyledTextCtrl_GetMarginLeft, 3116).
--define(wxStyledTextCtrl_SetMarginRight, 3117).
--define(wxStyledTextCtrl_GetMarginRight, 3118).
--define(wxStyledTextCtrl_GetModify, 3119).
--define(wxStyledTextCtrl_SetSelection, 3120).
--define(wxStyledTextCtrl_GetSelectedText, 3121).
--define(wxStyledTextCtrl_GetTextRange, 3122).
--define(wxStyledTextCtrl_HideSelection, 3123).
--define(wxStyledTextCtrl_LineFromPosition, 3124).
--define(wxStyledTextCtrl_PositionFromLine, 3125).
--define(wxStyledTextCtrl_LineScroll, 3126).
--define(wxStyledTextCtrl_EnsureCaretVisible, 3127).
--define(wxStyledTextCtrl_ReplaceSelection, 3128).
--define(wxStyledTextCtrl_SetReadOnly, 3129).
--define(wxStyledTextCtrl_CanPaste, 3130).
--define(wxStyledTextCtrl_CanUndo, 3131).
--define(wxStyledTextCtrl_EmptyUndoBuffer, 3132).
--define(wxStyledTextCtrl_Undo, 3133).
--define(wxStyledTextCtrl_Cut, 3134).
--define(wxStyledTextCtrl_Copy, 3135).
--define(wxStyledTextCtrl_Paste, 3136).
--define(wxStyledTextCtrl_Clear, 3137).
--define(wxStyledTextCtrl_SetText, 3138).
--define(wxStyledTextCtrl_GetText, 3139).
--define(wxStyledTextCtrl_GetTextLength, 3140).
--define(wxStyledTextCtrl_GetOvertype, 3141).
--define(wxStyledTextCtrl_SetCaretWidth, 3142).
--define(wxStyledTextCtrl_GetCaretWidth, 3143).
--define(wxStyledTextCtrl_SetTargetStart, 3144).
--define(wxStyledTextCtrl_GetTargetStart, 3145).
--define(wxStyledTextCtrl_SetTargetEnd, 3146).
--define(wxStyledTextCtrl_GetTargetEnd, 3147).
--define(wxStyledTextCtrl_ReplaceTarget, 3148).
--define(wxStyledTextCtrl_SearchInTarget, 3149).
--define(wxStyledTextCtrl_SetSearchFlags, 3150).
--define(wxStyledTextCtrl_GetSearchFlags, 3151).
--define(wxStyledTextCtrl_CallTipShow, 3152).
--define(wxStyledTextCtrl_CallTipCancel, 3153).
--define(wxStyledTextCtrl_CallTipActive, 3154).
--define(wxStyledTextCtrl_CallTipPosAtStart, 3155).
--define(wxStyledTextCtrl_CallTipSetHighlight, 3156).
--define(wxStyledTextCtrl_CallTipSetBackground, 3157).
--define(wxStyledTextCtrl_CallTipSetForeground, 3158).
--define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3159).
--define(wxStyledTextCtrl_CallTipUseStyle, 3160).
--define(wxStyledTextCtrl_VisibleFromDocLine, 3161).
--define(wxStyledTextCtrl_DocLineFromVisible, 3162).
--define(wxStyledTextCtrl_WrapCount, 3163).
--define(wxStyledTextCtrl_SetFoldLevel, 3164).
--define(wxStyledTextCtrl_GetFoldLevel, 3165).
--define(wxStyledTextCtrl_GetLastChild, 3166).
--define(wxStyledTextCtrl_GetFoldParent, 3167).
--define(wxStyledTextCtrl_ShowLines, 3168).
--define(wxStyledTextCtrl_HideLines, 3169).
--define(wxStyledTextCtrl_GetLineVisible, 3170).
--define(wxStyledTextCtrl_SetFoldExpanded, 3171).
--define(wxStyledTextCtrl_GetFoldExpanded, 3172).
--define(wxStyledTextCtrl_ToggleFold, 3173).
--define(wxStyledTextCtrl_EnsureVisible, 3174).
--define(wxStyledTextCtrl_SetFoldFlags, 3175).
--define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3176).
--define(wxStyledTextCtrl_SetTabIndents, 3177).
--define(wxStyledTextCtrl_GetTabIndents, 3178).
--define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3179).
--define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3180).
--define(wxStyledTextCtrl_SetMouseDwellTime, 3181).
--define(wxStyledTextCtrl_GetMouseDwellTime, 3182).
--define(wxStyledTextCtrl_WordStartPosition, 3183).
--define(wxStyledTextCtrl_WordEndPosition, 3184).
--define(wxStyledTextCtrl_SetWrapMode, 3185).
--define(wxStyledTextCtrl_GetWrapMode, 3186).
--define(wxStyledTextCtrl_SetWrapVisualFlags, 3187).
--define(wxStyledTextCtrl_GetWrapVisualFlags, 3188).
--define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3189).
--define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3190).
--define(wxStyledTextCtrl_SetWrapStartIndent, 3191).
--define(wxStyledTextCtrl_GetWrapStartIndent, 3192).
--define(wxStyledTextCtrl_SetLayoutCache, 3193).
--define(wxStyledTextCtrl_GetLayoutCache, 3194).
--define(wxStyledTextCtrl_SetScrollWidth, 3195).
--define(wxStyledTextCtrl_GetScrollWidth, 3196).
--define(wxStyledTextCtrl_TextWidth, 3197).
--define(wxStyledTextCtrl_GetEndAtLastLine, 3198).
--define(wxStyledTextCtrl_TextHeight, 3199).
--define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3200).
--define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3201).
--define(wxStyledTextCtrl_AppendText, 3202).
--define(wxStyledTextCtrl_GetTwoPhaseDraw, 3203).
--define(wxStyledTextCtrl_SetTwoPhaseDraw, 3204).
--define(wxStyledTextCtrl_TargetFromSelection, 3205).
--define(wxStyledTextCtrl_LinesJoin, 3206).
--define(wxStyledTextCtrl_LinesSplit, 3207).
--define(wxStyledTextCtrl_SetFoldMarginColour, 3208).
--define(wxStyledTextCtrl_SetFoldMarginHiColour, 3209).
--define(wxStyledTextCtrl_LineDown, 3210).
--define(wxStyledTextCtrl_LineDownExtend, 3211).
--define(wxStyledTextCtrl_LineUp, 3212).
--define(wxStyledTextCtrl_LineUpExtend, 3213).
--define(wxStyledTextCtrl_CharLeft, 3214).
--define(wxStyledTextCtrl_CharLeftExtend, 3215).
--define(wxStyledTextCtrl_CharRight, 3216).
--define(wxStyledTextCtrl_CharRightExtend, 3217).
--define(wxStyledTextCtrl_WordLeft, 3218).
--define(wxStyledTextCtrl_WordLeftExtend, 3219).
--define(wxStyledTextCtrl_WordRight, 3220).
--define(wxStyledTextCtrl_WordRightExtend, 3221).
--define(wxStyledTextCtrl_Home, 3222).
--define(wxStyledTextCtrl_HomeExtend, 3223).
--define(wxStyledTextCtrl_LineEnd, 3224).
--define(wxStyledTextCtrl_LineEndExtend, 3225).
--define(wxStyledTextCtrl_DocumentStart, 3226).
--define(wxStyledTextCtrl_DocumentStartExtend, 3227).
--define(wxStyledTextCtrl_DocumentEnd, 3228).
--define(wxStyledTextCtrl_DocumentEndExtend, 3229).
--define(wxStyledTextCtrl_PageUp, 3230).
--define(wxStyledTextCtrl_PageUpExtend, 3231).
--define(wxStyledTextCtrl_PageDown, 3232).
--define(wxStyledTextCtrl_PageDownExtend, 3233).
--define(wxStyledTextCtrl_EditToggleOvertype, 3234).
--define(wxStyledTextCtrl_Cancel, 3235).
--define(wxStyledTextCtrl_DeleteBack, 3236).
--define(wxStyledTextCtrl_Tab, 3237).
--define(wxStyledTextCtrl_BackTab, 3238).
--define(wxStyledTextCtrl_NewLine, 3239).
--define(wxStyledTextCtrl_FormFeed, 3240).
--define(wxStyledTextCtrl_VCHome, 3241).
--define(wxStyledTextCtrl_VCHomeExtend, 3242).
--define(wxStyledTextCtrl_ZoomIn, 3243).
--define(wxStyledTextCtrl_ZoomOut, 3244).
--define(wxStyledTextCtrl_DelWordLeft, 3245).
--define(wxStyledTextCtrl_DelWordRight, 3246).
--define(wxStyledTextCtrl_LineCut, 3247).
--define(wxStyledTextCtrl_LineDelete, 3248).
--define(wxStyledTextCtrl_LineTranspose, 3249).
--define(wxStyledTextCtrl_LineDuplicate, 3250).
--define(wxStyledTextCtrl_LowerCase, 3251).
--define(wxStyledTextCtrl_UpperCase, 3252).
--define(wxStyledTextCtrl_LineScrollDown, 3253).
--define(wxStyledTextCtrl_LineScrollUp, 3254).
--define(wxStyledTextCtrl_DeleteBackNotLine, 3255).
--define(wxStyledTextCtrl_HomeDisplay, 3256).
--define(wxStyledTextCtrl_HomeDisplayExtend, 3257).
--define(wxStyledTextCtrl_LineEndDisplay, 3258).
--define(wxStyledTextCtrl_LineEndDisplayExtend, 3259).
--define(wxStyledTextCtrl_HomeWrapExtend, 3260).
--define(wxStyledTextCtrl_LineEndWrap, 3261).
--define(wxStyledTextCtrl_LineEndWrapExtend, 3262).
--define(wxStyledTextCtrl_VCHomeWrap, 3263).
--define(wxStyledTextCtrl_VCHomeWrapExtend, 3264).
--define(wxStyledTextCtrl_LineCopy, 3265).
--define(wxStyledTextCtrl_MoveCaretInsideView, 3266).
--define(wxStyledTextCtrl_LineLength, 3267).
--define(wxStyledTextCtrl_BraceHighlight, 3268).
--define(wxStyledTextCtrl_BraceBadLight, 3269).
--define(wxStyledTextCtrl_BraceMatch, 3270).
--define(wxStyledTextCtrl_GetViewEOL, 3271).
--define(wxStyledTextCtrl_SetViewEOL, 3272).
--define(wxStyledTextCtrl_SetModEventMask, 3273).
--define(wxStyledTextCtrl_GetEdgeColumn, 3274).
--define(wxStyledTextCtrl_SetEdgeColumn, 3275).
--define(wxStyledTextCtrl_SetEdgeMode, 3276).
--define(wxStyledTextCtrl_GetEdgeMode, 3277).
--define(wxStyledTextCtrl_GetEdgeColour, 3278).
--define(wxStyledTextCtrl_SetEdgeColour, 3279).
--define(wxStyledTextCtrl_SearchAnchor, 3280).
--define(wxStyledTextCtrl_SearchNext, 3281).
--define(wxStyledTextCtrl_SearchPrev, 3282).
--define(wxStyledTextCtrl_LinesOnScreen, 3283).
--define(wxStyledTextCtrl_UsePopUp, 3284).
--define(wxStyledTextCtrl_SelectionIsRectangle, 3285).
--define(wxStyledTextCtrl_SetZoom, 3286).
--define(wxStyledTextCtrl_GetZoom, 3287).
--define(wxStyledTextCtrl_GetModEventMask, 3288).
--define(wxStyledTextCtrl_SetSTCFocus, 3289).
--define(wxStyledTextCtrl_GetSTCFocus, 3290).
--define(wxStyledTextCtrl_SetStatus, 3291).
--define(wxStyledTextCtrl_GetStatus, 3292).
--define(wxStyledTextCtrl_SetMouseDownCaptures, 3293).
--define(wxStyledTextCtrl_GetMouseDownCaptures, 3294).
--define(wxStyledTextCtrl_SetSTCCursor, 3295).
--define(wxStyledTextCtrl_GetSTCCursor, 3296).
--define(wxStyledTextCtrl_SetControlCharSymbol, 3297).
--define(wxStyledTextCtrl_GetControlCharSymbol, 3298).
--define(wxStyledTextCtrl_WordPartLeft, 3299).
--define(wxStyledTextCtrl_WordPartLeftExtend, 3300).
--define(wxStyledTextCtrl_WordPartRight, 3301).
--define(wxStyledTextCtrl_WordPartRightExtend, 3302).
--define(wxStyledTextCtrl_SetVisiblePolicy, 3303).
--define(wxStyledTextCtrl_DelLineLeft, 3304).
--define(wxStyledTextCtrl_DelLineRight, 3305).
--define(wxStyledTextCtrl_GetXOffset, 3306).
--define(wxStyledTextCtrl_ChooseCaretX, 3307).
--define(wxStyledTextCtrl_SetXCaretPolicy, 3308).
--define(wxStyledTextCtrl_SetYCaretPolicy, 3309).
--define(wxStyledTextCtrl_GetPrintWrapMode, 3310).
--define(wxStyledTextCtrl_SetHotspotActiveForeground, 3311).
--define(wxStyledTextCtrl_SetHotspotActiveBackground, 3312).
--define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3313).
--define(wxStyledTextCtrl_SetHotspotSingleLine, 3314).
--define(wxStyledTextCtrl_ParaDownExtend, 3315).
--define(wxStyledTextCtrl_ParaUp, 3316).
--define(wxStyledTextCtrl_ParaUpExtend, 3317).
--define(wxStyledTextCtrl_PositionBefore, 3318).
--define(wxStyledTextCtrl_PositionAfter, 3319).
--define(wxStyledTextCtrl_CopyRange, 3320).
--define(wxStyledTextCtrl_CopyText, 3321).
--define(wxStyledTextCtrl_SetSelectionMode, 3322).
--define(wxStyledTextCtrl_GetSelectionMode, 3323).
--define(wxStyledTextCtrl_LineDownRectExtend, 3324).
--define(wxStyledTextCtrl_LineUpRectExtend, 3325).
--define(wxStyledTextCtrl_CharLeftRectExtend, 3326).
--define(wxStyledTextCtrl_CharRightRectExtend, 3327).
--define(wxStyledTextCtrl_HomeRectExtend, 3328).
--define(wxStyledTextCtrl_VCHomeRectExtend, 3329).
--define(wxStyledTextCtrl_LineEndRectExtend, 3330).
--define(wxStyledTextCtrl_PageUpRectExtend, 3331).
--define(wxStyledTextCtrl_PageDownRectExtend, 3332).
--define(wxStyledTextCtrl_StutteredPageUp, 3333).
--define(wxStyledTextCtrl_StutteredPageUpExtend, 3334).
--define(wxStyledTextCtrl_StutteredPageDown, 3335).
--define(wxStyledTextCtrl_StutteredPageDownExtend, 3336).
--define(wxStyledTextCtrl_WordLeftEnd, 3337).
--define(wxStyledTextCtrl_WordLeftEndExtend, 3338).
--define(wxStyledTextCtrl_WordRightEnd, 3339).
--define(wxStyledTextCtrl_WordRightEndExtend, 3340).
--define(wxStyledTextCtrl_SetWhitespaceChars, 3341).
--define(wxStyledTextCtrl_SetCharsDefault, 3342).
--define(wxStyledTextCtrl_AutoCompGetCurrent, 3343).
--define(wxStyledTextCtrl_Allocate, 3344).
--define(wxStyledTextCtrl_FindColumn, 3345).
--define(wxStyledTextCtrl_GetCaretSticky, 3346).
--define(wxStyledTextCtrl_SetCaretSticky, 3347).
--define(wxStyledTextCtrl_ToggleCaretSticky, 3348).
--define(wxStyledTextCtrl_SetPasteConvertEndings, 3349).
--define(wxStyledTextCtrl_GetPasteConvertEndings, 3350).
--define(wxStyledTextCtrl_SelectionDuplicate, 3351).
--define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3352).
--define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3353).
--define(wxStyledTextCtrl_StartRecord, 3354).
--define(wxStyledTextCtrl_StopRecord, 3355).
--define(wxStyledTextCtrl_SetLexer, 3356).
--define(wxStyledTextCtrl_GetLexer, 3357).
--define(wxStyledTextCtrl_Colourise, 3358).
--define(wxStyledTextCtrl_SetProperty, 3359).
--define(wxStyledTextCtrl_SetKeyWords, 3360).
--define(wxStyledTextCtrl_SetLexerLanguage, 3361).
--define(wxStyledTextCtrl_GetProperty, 3362).
--define(wxStyledTextCtrl_GetStyleBitsNeeded, 3363).
--define(wxStyledTextCtrl_GetCurrentLine, 3364).
--define(wxStyledTextCtrl_StyleSetSpec, 3365).
--define(wxStyledTextCtrl_StyleSetFont, 3366).
--define(wxStyledTextCtrl_StyleSetFontAttr, 3367).
--define(wxStyledTextCtrl_StyleSetCharacterSet, 3368).
--define(wxStyledTextCtrl_StyleSetFontEncoding, 3369).
--define(wxStyledTextCtrl_CmdKeyExecute, 3370).
--define(wxStyledTextCtrl_SetMargins, 3371).
--define(wxStyledTextCtrl_GetSelection, 3372).
--define(wxStyledTextCtrl_PointFromPosition, 3373).
--define(wxStyledTextCtrl_ScrollToLine, 3374).
--define(wxStyledTextCtrl_ScrollToColumn, 3375).
--define(wxStyledTextCtrl_SetVScrollBar, 3376).
--define(wxStyledTextCtrl_SetHScrollBar, 3377).
--define(wxStyledTextCtrl_GetLastKeydownProcessed, 3378).
--define(wxStyledTextCtrl_SetLastKeydownProcessed, 3379).
--define(wxStyledTextCtrl_SaveFile, 3380).
--define(wxStyledTextCtrl_LoadFile, 3381).
--define(wxStyledTextCtrl_DoDragOver, 3382).
--define(wxStyledTextCtrl_DoDropText, 3383).
--define(wxStyledTextCtrl_GetUseAntiAliasing, 3384).
--define(wxStyledTextCtrl_AddTextRaw, 3385).
--define(wxStyledTextCtrl_InsertTextRaw, 3386).
--define(wxStyledTextCtrl_GetCurLineRaw, 3387).
--define(wxStyledTextCtrl_GetLineRaw, 3388).
--define(wxStyledTextCtrl_GetSelectedTextRaw, 3389).
--define(wxStyledTextCtrl_GetTextRangeRaw, 3390).
--define(wxStyledTextCtrl_SetTextRaw, 3391).
--define(wxStyledTextCtrl_GetTextRaw, 3392).
--define(wxStyledTextCtrl_AppendTextRaw, 3393).
--define(wxArtProvider_GetBitmap, 3394).
--define(wxArtProvider_GetIcon, 3395).
--define(wxTreeEvent_GetKeyCode, 3396).
--define(wxTreeEvent_GetItem, 3397).
--define(wxTreeEvent_GetKeyEvent, 3398).
--define(wxTreeEvent_GetLabel, 3399).
--define(wxTreeEvent_GetOldItem, 3400).
--define(wxTreeEvent_GetPoint, 3401).
--define(wxTreeEvent_IsEditCancelled, 3402).
--define(wxTreeEvent_SetToolTip, 3403).
--define(wxNotebookEvent_GetOldSelection, 3404).
--define(wxNotebookEvent_GetSelection, 3405).
--define(wxNotebookEvent_SetOldSelection, 3406).
--define(wxNotebookEvent_SetSelection, 3407).
--define(wxFileDataObject_new, 3408).
--define(wxFileDataObject_AddFile, 3409).
--define(wxFileDataObject_GetFilenames, 3410).
--define(wxFileDataObject_destroy, 3411).
--define(wxTextDataObject_new, 3412).
--define(wxTextDataObject_GetTextLength, 3413).
--define(wxTextDataObject_GetText, 3414).
--define(wxTextDataObject_SetText, 3415).
--define(wxTextDataObject_destroy, 3416).
--define(wxBitmapDataObject_new_1_1, 3417).
--define(wxBitmapDataObject_new_1_0, 3418).
--define(wxBitmapDataObject_GetBitmap, 3419).
--define(wxBitmapDataObject_SetBitmap, 3420).
--define(wxBitmapDataObject_destroy, 3421).
--define(wxClipboard_new, 3423).
--define(wxClipboard_destruct, 3424).
--define(wxClipboard_AddData, 3425).
--define(wxClipboard_Clear, 3426).
--define(wxClipboard_Close, 3427).
--define(wxClipboard_Flush, 3428).
--define(wxClipboard_GetData, 3429).
--define(wxClipboard_IsOpened, 3430).
--define(wxClipboard_Open, 3431).
--define(wxClipboard_SetData, 3432).
--define(wxClipboard_UsePrimarySelection, 3434).
--define(wxClipboard_IsSupported, 3435).
--define(wxClipboard_Get, 3436).
--define(wxSpinEvent_GetPosition, 3437).
--define(wxSpinEvent_SetPosition, 3438).
--define(wxSplitterWindow_new_0, 3439).
--define(wxSplitterWindow_new_2, 3440).
--define(wxSplitterWindow_destruct, 3441).
--define(wxSplitterWindow_Create, 3442).
--define(wxSplitterWindow_GetMinimumPaneSize, 3443).
--define(wxSplitterWindow_GetSashGravity, 3444).
--define(wxSplitterWindow_GetSashPosition, 3445).
--define(wxSplitterWindow_GetSplitMode, 3446).
--define(wxSplitterWindow_GetWindow1, 3447).
--define(wxSplitterWindow_GetWindow2, 3448).
--define(wxSplitterWindow_Initialize, 3449).
--define(wxSplitterWindow_IsSplit, 3450).
--define(wxSplitterWindow_ReplaceWindow, 3451).
--define(wxSplitterWindow_SetSashGravity, 3452).
--define(wxSplitterWindow_SetSashPosition, 3453).
--define(wxSplitterWindow_SetSashSize, 3454).
--define(wxSplitterWindow_SetMinimumPaneSize, 3455).
--define(wxSplitterWindow_SetSplitMode, 3456).
--define(wxSplitterWindow_SplitHorizontally, 3457).
--define(wxSplitterWindow_SplitVertically, 3458).
--define(wxSplitterWindow_Unsplit, 3459).
--define(wxSplitterWindow_UpdateSize, 3460).
--define(wxSplitterEvent_GetSashPosition, 3461).
--define(wxSplitterEvent_GetX, 3462).
--define(wxSplitterEvent_GetY, 3463).
--define(wxSplitterEvent_GetWindowBeingRemoved, 3464).
--define(wxSplitterEvent_SetSashPosition, 3465).
--define(wxHtmlWindow_new_0, 3466).
--define(wxHtmlWindow_new_2, 3467).
--define(wxHtmlWindow_AppendToPage, 3468).
--define(wxHtmlWindow_GetOpenedAnchor, 3469).
--define(wxHtmlWindow_GetOpenedPage, 3470).
--define(wxHtmlWindow_GetOpenedPageTitle, 3471).
--define(wxHtmlWindow_GetRelatedFrame, 3472).
--define(wxHtmlWindow_HistoryBack, 3473).
--define(wxHtmlWindow_HistoryCanBack, 3474).
--define(wxHtmlWindow_HistoryCanForward, 3475).
--define(wxHtmlWindow_HistoryClear, 3476).
--define(wxHtmlWindow_HistoryForward, 3477).
--define(wxHtmlWindow_LoadFile, 3478).
--define(wxHtmlWindow_LoadPage, 3479).
--define(wxHtmlWindow_SelectAll, 3480).
--define(wxHtmlWindow_SelectionToText, 3481).
--define(wxHtmlWindow_SelectLine, 3482).
--define(wxHtmlWindow_SelectWord, 3483).
--define(wxHtmlWindow_SetBorders, 3484).
--define(wxHtmlWindow_SetFonts, 3485).
--define(wxHtmlWindow_SetPage, 3486).
--define(wxHtmlWindow_SetRelatedFrame, 3487).
--define(wxHtmlWindow_SetRelatedStatusBar, 3488).
--define(wxHtmlWindow_ToText, 3489).
--define(wxHtmlWindow_destroy, 3490).
--define(wxHtmlLinkEvent_GetLinkInfo, 3491).
--define(wxSystemSettings_GetColour, 3492).
--define(wxSystemSettings_GetFont, 3493).
--define(wxSystemSettings_GetMetric, 3494).
--define(wxSystemSettings_GetScreenType, 3495).
--define(wxSystemOptions_GetOption, 3496).
--define(wxSystemOptions_GetOptionInt, 3497).
--define(wxSystemOptions_HasOption, 3498).
--define(wxSystemOptions_IsFalse, 3499).
--define(wxSystemOptions_SetOption_2_1, 3500).
--define(wxSystemOptions_SetOption_2_0, 3501).
--define(wxAuiNotebookEvent_SetSelection, 3502).
--define(wxAuiNotebookEvent_GetSelection, 3503).
--define(wxAuiNotebookEvent_SetOldSelection, 3504).
--define(wxAuiNotebookEvent_GetOldSelection, 3505).
--define(wxAuiNotebookEvent_SetDragSource, 3506).
--define(wxAuiNotebookEvent_GetDragSource, 3507).
--define(wxAuiManagerEvent_SetManager, 3508).
--define(wxAuiManagerEvent_GetManager, 3509).
--define(wxAuiManagerEvent_SetPane, 3510).
--define(wxAuiManagerEvent_GetPane, 3511).
--define(wxAuiManagerEvent_SetButton, 3512).
--define(wxAuiManagerEvent_GetButton, 3513).
--define(wxAuiManagerEvent_SetDC, 3514).
--define(wxAuiManagerEvent_GetDC, 3515).
--define(wxAuiManagerEvent_Veto, 3516).
--define(wxAuiManagerEvent_GetVeto, 3517).
--define(wxAuiManagerEvent_SetCanVeto, 3518).
--define(wxAuiManagerEvent_CanVeto, 3519).
--define(wxLogNull_new, 3520).
--define(wxLogNull_destroy, 3521).
--define(wxTaskBarIcon_new, 3522).
--define(wxTaskBarIcon_destruct, 3523).
--define(wxTaskBarIcon_PopupMenu, 3524).
--define(wxTaskBarIcon_RemoveIcon, 3525).
--define(wxTaskBarIcon_SetIcon, 3526).
--define(wxLocale_new_0, 3527).
--define(wxLocale_new_2, 3529).
--define(wxLocale_destruct, 3530).
--define(wxLocale_Init, 3532).
--define(wxLocale_AddCatalog_1, 3533).
--define(wxLocale_AddCatalog_3, 3534).
--define(wxLocale_AddCatalogLookupPathPrefix, 3535).
--define(wxLocale_GetCanonicalName, 3536).
--define(wxLocale_GetLanguage, 3537).
--define(wxLocale_GetLanguageName, 3538).
--define(wxLocale_GetLocale, 3539).
--define(wxLocale_GetName, 3540).
--define(wxLocale_GetString_2, 3541).
--define(wxLocale_GetString_4, 3542).
--define(wxLocale_GetHeaderValue, 3543).
--define(wxLocale_GetSysName, 3544).
--define(wxLocale_GetSystemEncoding, 3545).
--define(wxLocale_GetSystemEncodingName, 3546).
--define(wxLocale_GetSystemLanguage, 3547).
--define(wxLocale_IsLoaded, 3548).
--define(wxLocale_IsOk, 3549).
+-define(wxTextCtrl_ChangeValue, 1827).
+-define(wxTextCtrl_EmulateKeyPress, 1828).
+-define(wxTextCtrl_GetDefaultStyle, 1829).
+-define(wxTextCtrl_GetInsertionPoint, 1830).
+-define(wxTextCtrl_GetLastPosition, 1831).
+-define(wxTextCtrl_GetLineLength, 1832).
+-define(wxTextCtrl_GetLineText, 1833).
+-define(wxTextCtrl_GetNumberOfLines, 1834).
+-define(wxTextCtrl_GetRange, 1835).
+-define(wxTextCtrl_GetSelection, 1836).
+-define(wxTextCtrl_GetStringSelection, 1837).
+-define(wxTextCtrl_GetStyle, 1838).
+-define(wxTextCtrl_GetValue, 1839).
+-define(wxTextCtrl_IsEditable, 1840).
+-define(wxTextCtrl_IsModified, 1841).
+-define(wxTextCtrl_IsMultiLine, 1842).
+-define(wxTextCtrl_IsSingleLine, 1843).
+-define(wxTextCtrl_LoadFile, 1844).
+-define(wxTextCtrl_MarkDirty, 1845).
+-define(wxTextCtrl_Paste, 1846).
+-define(wxTextCtrl_PositionToXY, 1847).
+-define(wxTextCtrl_Redo, 1848).
+-define(wxTextCtrl_Remove, 1849).
+-define(wxTextCtrl_Replace, 1850).
+-define(wxTextCtrl_SaveFile, 1851).
+-define(wxTextCtrl_SetDefaultStyle, 1852).
+-define(wxTextCtrl_SetEditable, 1853).
+-define(wxTextCtrl_SetInsertionPoint, 1854).
+-define(wxTextCtrl_SetInsertionPointEnd, 1855).
+-define(wxTextCtrl_SetMaxLength, 1857).
+-define(wxTextCtrl_SetSelection, 1858).
+-define(wxTextCtrl_SetStyle, 1859).
+-define(wxTextCtrl_SetValue, 1860).
+-define(wxTextCtrl_ShowPosition, 1861).
+-define(wxTextCtrl_Undo, 1862).
+-define(wxTextCtrl_WriteText, 1863).
+-define(wxTextCtrl_XYToPosition, 1864).
+-define(wxNotebook_new_0, 1867).
+-define(wxNotebook_new_3, 1868).
+-define(wxNotebook_destruct, 1869).
+-define(wxNotebook_AddPage, 1870).
+-define(wxNotebook_AdvanceSelection, 1871).
+-define(wxNotebook_AssignImageList, 1872).
+-define(wxNotebook_Create, 1873).
+-define(wxNotebook_DeleteAllPages, 1874).
+-define(wxNotebook_DeletePage, 1875).
+-define(wxNotebook_RemovePage, 1876).
+-define(wxNotebook_GetCurrentPage, 1877).
+-define(wxNotebook_GetImageList, 1878).
+-define(wxNotebook_GetPage, 1880).
+-define(wxNotebook_GetPageCount, 1881).
+-define(wxNotebook_GetPageImage, 1882).
+-define(wxNotebook_GetPageText, 1883).
+-define(wxNotebook_GetRowCount, 1884).
+-define(wxNotebook_GetSelection, 1885).
+-define(wxNotebook_GetThemeBackgroundColour, 1886).
+-define(wxNotebook_HitTest, 1888).
+-define(wxNotebook_InsertPage, 1890).
+-define(wxNotebook_SetImageList, 1891).
+-define(wxNotebook_SetPadding, 1892).
+-define(wxNotebook_SetPageSize, 1893).
+-define(wxNotebook_SetPageImage, 1894).
+-define(wxNotebook_SetPageText, 1895).
+-define(wxNotebook_SetSelection, 1896).
+-define(wxNotebook_ChangeSelection, 1897).
+-define(wxChoicebook_new_0, 1898).
+-define(wxChoicebook_new_3, 1899).
+-define(wxChoicebook_AddPage, 1900).
+-define(wxChoicebook_AdvanceSelection, 1901).
+-define(wxChoicebook_AssignImageList, 1902).
+-define(wxChoicebook_Create, 1903).
+-define(wxChoicebook_DeleteAllPages, 1904).
+-define(wxChoicebook_DeletePage, 1905).
+-define(wxChoicebook_RemovePage, 1906).
+-define(wxChoicebook_GetCurrentPage, 1907).
+-define(wxChoicebook_GetImageList, 1908).
+-define(wxChoicebook_GetPage, 1910).
+-define(wxChoicebook_GetPageCount, 1911).
+-define(wxChoicebook_GetPageImage, 1912).
+-define(wxChoicebook_GetPageText, 1913).
+-define(wxChoicebook_GetSelection, 1914).
+-define(wxChoicebook_HitTest, 1915).
+-define(wxChoicebook_InsertPage, 1916).
+-define(wxChoicebook_SetImageList, 1917).
+-define(wxChoicebook_SetPageSize, 1918).
+-define(wxChoicebook_SetPageImage, 1919).
+-define(wxChoicebook_SetPageText, 1920).
+-define(wxChoicebook_SetSelection, 1921).
+-define(wxChoicebook_ChangeSelection, 1922).
+-define(wxChoicebook_destroy, 1923).
+-define(wxToolbook_new_0, 1924).
+-define(wxToolbook_new_3, 1925).
+-define(wxToolbook_AddPage, 1926).
+-define(wxToolbook_AdvanceSelection, 1927).
+-define(wxToolbook_AssignImageList, 1928).
+-define(wxToolbook_Create, 1929).
+-define(wxToolbook_DeleteAllPages, 1930).
+-define(wxToolbook_DeletePage, 1931).
+-define(wxToolbook_RemovePage, 1932).
+-define(wxToolbook_GetCurrentPage, 1933).
+-define(wxToolbook_GetImageList, 1934).
+-define(wxToolbook_GetPage, 1936).
+-define(wxToolbook_GetPageCount, 1937).
+-define(wxToolbook_GetPageImage, 1938).
+-define(wxToolbook_GetPageText, 1939).
+-define(wxToolbook_GetSelection, 1940).
+-define(wxToolbook_HitTest, 1942).
+-define(wxToolbook_InsertPage, 1943).
+-define(wxToolbook_SetImageList, 1944).
+-define(wxToolbook_SetPageSize, 1945).
+-define(wxToolbook_SetPageImage, 1946).
+-define(wxToolbook_SetPageText, 1947).
+-define(wxToolbook_SetSelection, 1948).
+-define(wxToolbook_ChangeSelection, 1949).
+-define(wxToolbook_destroy, 1950).
+-define(wxListbook_new_0, 1951).
+-define(wxListbook_new_3, 1952).
+-define(wxListbook_AddPage, 1953).
+-define(wxListbook_AdvanceSelection, 1954).
+-define(wxListbook_AssignImageList, 1955).
+-define(wxListbook_Create, 1956).
+-define(wxListbook_DeleteAllPages, 1957).
+-define(wxListbook_DeletePage, 1958).
+-define(wxListbook_RemovePage, 1959).
+-define(wxListbook_GetCurrentPage, 1960).
+-define(wxListbook_GetImageList, 1961).
+-define(wxListbook_GetPage, 1963).
+-define(wxListbook_GetPageCount, 1964).
+-define(wxListbook_GetPageImage, 1965).
+-define(wxListbook_GetPageText, 1966).
+-define(wxListbook_GetSelection, 1967).
+-define(wxListbook_HitTest, 1969).
+-define(wxListbook_InsertPage, 1970).
+-define(wxListbook_SetImageList, 1971).
+-define(wxListbook_SetPageSize, 1972).
+-define(wxListbook_SetPageImage, 1973).
+-define(wxListbook_SetPageText, 1974).
+-define(wxListbook_SetSelection, 1975).
+-define(wxListbook_ChangeSelection, 1976).
+-define(wxListbook_destroy, 1977).
+-define(wxTreebook_new_0, 1978).
+-define(wxTreebook_new_3, 1979).
+-define(wxTreebook_AddPage, 1980).
+-define(wxTreebook_AdvanceSelection, 1981).
+-define(wxTreebook_AssignImageList, 1982).
+-define(wxTreebook_Create, 1983).
+-define(wxTreebook_DeleteAllPages, 1984).
+-define(wxTreebook_DeletePage, 1985).
+-define(wxTreebook_RemovePage, 1986).
+-define(wxTreebook_GetCurrentPage, 1987).
+-define(wxTreebook_GetImageList, 1988).
+-define(wxTreebook_GetPage, 1990).
+-define(wxTreebook_GetPageCount, 1991).
+-define(wxTreebook_GetPageImage, 1992).
+-define(wxTreebook_GetPageText, 1993).
+-define(wxTreebook_GetSelection, 1994).
+-define(wxTreebook_ExpandNode, 1995).
+-define(wxTreebook_IsNodeExpanded, 1996).
+-define(wxTreebook_HitTest, 1998).
+-define(wxTreebook_InsertPage, 1999).
+-define(wxTreebook_InsertSubPage, 2000).
+-define(wxTreebook_SetImageList, 2001).
+-define(wxTreebook_SetPageSize, 2002).
+-define(wxTreebook_SetPageImage, 2003).
+-define(wxTreebook_SetPageText, 2004).
+-define(wxTreebook_SetSelection, 2005).
+-define(wxTreebook_ChangeSelection, 2006).
+-define(wxTreebook_destroy, 2007).
+-define(wxTreeCtrl_new_2, 2010).
+-define(wxTreeCtrl_new_0, 2011).
+-define(wxTreeCtrl_destruct, 2013).
+-define(wxTreeCtrl_AddRoot, 2014).
+-define(wxTreeCtrl_AppendItem, 2015).
+-define(wxTreeCtrl_AssignImageList, 2016).
+-define(wxTreeCtrl_AssignStateImageList, 2017).
+-define(wxTreeCtrl_Collapse, 2018).
+-define(wxTreeCtrl_CollapseAndReset, 2019).
+-define(wxTreeCtrl_Create, 2020).
+-define(wxTreeCtrl_Delete, 2021).
+-define(wxTreeCtrl_DeleteAllItems, 2022).
+-define(wxTreeCtrl_DeleteChildren, 2023).
+-define(wxTreeCtrl_EditLabel, 2024).
+-define(wxTreeCtrl_EnsureVisible, 2025).
+-define(wxTreeCtrl_Expand, 2026).
+-define(wxTreeCtrl_GetBoundingRect, 2027).
+-define(wxTreeCtrl_GetChildrenCount, 2029).
+-define(wxTreeCtrl_GetCount, 2030).
+-define(wxTreeCtrl_GetEditControl, 2031).
+-define(wxTreeCtrl_GetFirstChild, 2032).
+-define(wxTreeCtrl_GetNextChild, 2033).
+-define(wxTreeCtrl_GetFirstVisibleItem, 2034).
+-define(wxTreeCtrl_GetImageList, 2035).
+-define(wxTreeCtrl_GetIndent, 2036).
+-define(wxTreeCtrl_GetItemBackgroundColour, 2037).
+-define(wxTreeCtrl_GetItemData, 2038).
+-define(wxTreeCtrl_GetItemFont, 2039).
+-define(wxTreeCtrl_GetItemImage_1, 2040).
+-define(wxTreeCtrl_GetItemImage_2, 2041).
+-define(wxTreeCtrl_GetItemText, 2042).
+-define(wxTreeCtrl_GetItemTextColour, 2043).
+-define(wxTreeCtrl_GetLastChild, 2044).
+-define(wxTreeCtrl_GetNextSibling, 2045).
+-define(wxTreeCtrl_GetNextVisible, 2046).
+-define(wxTreeCtrl_GetItemParent, 2047).
+-define(wxTreeCtrl_GetPrevSibling, 2048).
+-define(wxTreeCtrl_GetPrevVisible, 2049).
+-define(wxTreeCtrl_GetRootItem, 2050).
+-define(wxTreeCtrl_GetSelection, 2051).
+-define(wxTreeCtrl_GetSelections, 2052).
+-define(wxTreeCtrl_GetStateImageList, 2053).
+-define(wxTreeCtrl_HitTest, 2054).
+-define(wxTreeCtrl_InsertItem, 2056).
+-define(wxTreeCtrl_IsBold, 2057).
+-define(wxTreeCtrl_IsExpanded, 2058).
+-define(wxTreeCtrl_IsSelected, 2059).
+-define(wxTreeCtrl_IsVisible, 2060).
+-define(wxTreeCtrl_ItemHasChildren, 2061).
+-define(wxTreeCtrl_IsTreeItemIdOk, 2062).
+-define(wxTreeCtrl_PrependItem, 2063).
+-define(wxTreeCtrl_ScrollTo, 2064).
+-define(wxTreeCtrl_SelectItem_1, 2065).
+-define(wxTreeCtrl_SelectItem_2, 2066).
+-define(wxTreeCtrl_SetIndent, 2067).
+-define(wxTreeCtrl_SetImageList, 2068).
+-define(wxTreeCtrl_SetItemBackgroundColour, 2069).
+-define(wxTreeCtrl_SetItemBold, 2070).
+-define(wxTreeCtrl_SetItemData, 2071).
+-define(wxTreeCtrl_SetItemDropHighlight, 2072).
+-define(wxTreeCtrl_SetItemFont, 2073).
+-define(wxTreeCtrl_SetItemHasChildren, 2074).
+-define(wxTreeCtrl_SetItemImage_2, 2075).
+-define(wxTreeCtrl_SetItemImage_3, 2076).
+-define(wxTreeCtrl_SetItemText, 2077).
+-define(wxTreeCtrl_SetItemTextColour, 2078).
+-define(wxTreeCtrl_SetStateImageList, 2079).
+-define(wxTreeCtrl_SetWindowStyle, 2080).
+-define(wxTreeCtrl_SortChildren, 2081).
+-define(wxTreeCtrl_Toggle, 2082).
+-define(wxTreeCtrl_ToggleItemSelection, 2083).
+-define(wxTreeCtrl_Unselect, 2084).
+-define(wxTreeCtrl_UnselectAll, 2085).
+-define(wxTreeCtrl_UnselectItem, 2086).
+-define(wxScrollBar_new_0, 2087).
+-define(wxScrollBar_new_3, 2088).
+-define(wxScrollBar_destruct, 2089).
+-define(wxScrollBar_Create, 2090).
+-define(wxScrollBar_GetRange, 2091).
+-define(wxScrollBar_GetPageSize, 2092).
+-define(wxScrollBar_GetThumbPosition, 2093).
+-define(wxScrollBar_GetThumbSize, 2094).
+-define(wxScrollBar_SetThumbPosition, 2095).
+-define(wxScrollBar_SetScrollbar, 2096).
+-define(wxSpinButton_new_2, 2098).
+-define(wxSpinButton_new_0, 2099).
+-define(wxSpinButton_Create, 2100).
+-define(wxSpinButton_GetMax, 2101).
+-define(wxSpinButton_GetMin, 2102).
+-define(wxSpinButton_GetValue, 2103).
+-define(wxSpinButton_SetRange, 2104).
+-define(wxSpinButton_SetValue, 2105).
+-define(wxSpinButton_destroy, 2106).
+-define(wxSpinCtrl_new_0, 2107).
+-define(wxSpinCtrl_new_2, 2108).
+-define(wxSpinCtrl_Create, 2110).
+-define(wxSpinCtrl_SetValue_1_1, 2113).
+-define(wxSpinCtrl_SetValue_1_0, 2114).
+-define(wxSpinCtrl_GetValue, 2116).
+-define(wxSpinCtrl_SetRange, 2118).
+-define(wxSpinCtrl_SetSelection, 2119).
+-define(wxSpinCtrl_GetMin, 2121).
+-define(wxSpinCtrl_GetMax, 2123).
+-define(wxSpinCtrl_destroy, 2124).
+-define(wxStaticText_new_0, 2125).
+-define(wxStaticText_new_4, 2126).
+-define(wxStaticText_Create, 2127).
+-define(wxStaticText_GetLabel, 2128).
+-define(wxStaticText_SetLabel, 2129).
+-define(wxStaticText_Wrap, 2130).
+-define(wxStaticText_destroy, 2131).
+-define(wxStaticBitmap_new_0, 2132).
+-define(wxStaticBitmap_new_4, 2133).
+-define(wxStaticBitmap_Create, 2134).
+-define(wxStaticBitmap_GetBitmap, 2135).
+-define(wxStaticBitmap_SetBitmap, 2136).
+-define(wxStaticBitmap_destroy, 2137).
+-define(wxRadioBox_new, 2138).
+-define(wxRadioBox_destruct, 2140).
+-define(wxRadioBox_Create, 2141).
+-define(wxRadioBox_Enable_2, 2142).
+-define(wxRadioBox_Enable_1, 2143).
+-define(wxRadioBox_GetSelection, 2144).
+-define(wxRadioBox_GetString, 2145).
+-define(wxRadioBox_SetSelection, 2146).
+-define(wxRadioBox_Show_2, 2147).
+-define(wxRadioBox_Show_1, 2148).
+-define(wxRadioBox_GetColumnCount, 2149).
+-define(wxRadioBox_GetItemHelpText, 2150).
+-define(wxRadioBox_GetItemToolTip, 2151).
+-define(wxRadioBox_GetItemFromPoint, 2153).
+-define(wxRadioBox_GetRowCount, 2154).
+-define(wxRadioBox_IsItemEnabled, 2155).
+-define(wxRadioBox_IsItemShown, 2156).
+-define(wxRadioBox_SetItemHelpText, 2157).
+-define(wxRadioBox_SetItemToolTip, 2158).
+-define(wxRadioButton_new_0, 2159).
+-define(wxRadioButton_new_4, 2160).
+-define(wxRadioButton_Create, 2161).
+-define(wxRadioButton_GetValue, 2162).
+-define(wxRadioButton_SetValue, 2163).
+-define(wxRadioButton_destroy, 2164).
+-define(wxSlider_new_6, 2166).
+-define(wxSlider_new_0, 2167).
+-define(wxSlider_Create, 2168).
+-define(wxSlider_GetLineSize, 2169).
+-define(wxSlider_GetMax, 2170).
+-define(wxSlider_GetMin, 2171).
+-define(wxSlider_GetPageSize, 2172).
+-define(wxSlider_GetThumbLength, 2173).
+-define(wxSlider_GetValue, 2174).
+-define(wxSlider_SetLineSize, 2175).
+-define(wxSlider_SetPageSize, 2176).
+-define(wxSlider_SetRange, 2177).
+-define(wxSlider_SetThumbLength, 2178).
+-define(wxSlider_SetValue, 2179).
+-define(wxSlider_destroy, 2180).
+-define(wxDialog_new_4, 2182).
+-define(wxDialog_new_0, 2183).
+-define(wxDialog_destruct, 2185).
+-define(wxDialog_Create, 2186).
+-define(wxDialog_CreateButtonSizer, 2187).
+-define(wxDialog_CreateStdDialogButtonSizer, 2188).
+-define(wxDialog_EndModal, 2189).
+-define(wxDialog_GetAffirmativeId, 2190).
+-define(wxDialog_GetReturnCode, 2191).
+-define(wxDialog_IsModal, 2192).
+-define(wxDialog_SetAffirmativeId, 2193).
+-define(wxDialog_SetReturnCode, 2194).
+-define(wxDialog_Show, 2195).
+-define(wxDialog_ShowModal, 2196).
+-define(wxColourDialog_new_0, 2197).
+-define(wxColourDialog_new_2, 2198).
+-define(wxColourDialog_destruct, 2199).
+-define(wxColourDialog_Create, 2200).
+-define(wxColourDialog_GetColourData, 2201).
+-define(wxColourData_new_0, 2202).
+-define(wxColourData_new_1, 2203).
+-define(wxColourData_destruct, 2204).
+-define(wxColourData_GetChooseFull, 2205).
+-define(wxColourData_GetColour, 2206).
+-define(wxColourData_GetCustomColour, 2208).
+-define(wxColourData_SetChooseFull, 2209).
+-define(wxColourData_SetColour, 2210).
+-define(wxColourData_SetCustomColour, 2211).
+-define(wxPalette_new_0, 2212).
+-define(wxPalette_new_4, 2213).
+-define(wxPalette_destruct, 2215).
+-define(wxPalette_Create, 2216).
+-define(wxPalette_GetColoursCount, 2217).
+-define(wxPalette_GetPixel, 2218).
+-define(wxPalette_GetRGB, 2219).
+-define(wxPalette_IsOk, 2220).
+-define(wxDirDialog_new, 2224).
+-define(wxDirDialog_destruct, 2225).
+-define(wxDirDialog_GetPath, 2226).
+-define(wxDirDialog_GetMessage, 2227).
+-define(wxDirDialog_SetMessage, 2228).
+-define(wxDirDialog_SetPath, 2229).
+-define(wxFileDialog_new, 2233).
+-define(wxFileDialog_destruct, 2234).
+-define(wxFileDialog_GetDirectory, 2235).
+-define(wxFileDialog_GetFilename, 2236).
+-define(wxFileDialog_GetFilenames, 2237).
+-define(wxFileDialog_GetFilterIndex, 2238).
+-define(wxFileDialog_GetMessage, 2239).
+-define(wxFileDialog_GetPath, 2240).
+-define(wxFileDialog_GetPaths, 2241).
+-define(wxFileDialog_GetWildcard, 2242).
+-define(wxFileDialog_SetDirectory, 2243).
+-define(wxFileDialog_SetFilename, 2244).
+-define(wxFileDialog_SetFilterIndex, 2245).
+-define(wxFileDialog_SetMessage, 2246).
+-define(wxFileDialog_SetPath, 2247).
+-define(wxFileDialog_SetWildcard, 2248).
+-define(wxPickerBase_SetInternalMargin, 2249).
+-define(wxPickerBase_GetInternalMargin, 2250).
+-define(wxPickerBase_SetTextCtrlProportion, 2251).
+-define(wxPickerBase_SetPickerCtrlProportion, 2252).
+-define(wxPickerBase_GetTextCtrlProportion, 2253).
+-define(wxPickerBase_GetPickerCtrlProportion, 2254).
+-define(wxPickerBase_HasTextCtrl, 2255).
+-define(wxPickerBase_GetTextCtrl, 2256).
+-define(wxPickerBase_IsTextCtrlGrowable, 2257).
+-define(wxPickerBase_SetPickerCtrlGrowable, 2258).
+-define(wxPickerBase_SetTextCtrlGrowable, 2259).
+-define(wxPickerBase_IsPickerCtrlGrowable, 2260).
+-define(wxFilePickerCtrl_new_0, 2261).
+-define(wxFilePickerCtrl_new_3, 2262).
+-define(wxFilePickerCtrl_Create, 2263).
+-define(wxFilePickerCtrl_GetPath, 2264).
+-define(wxFilePickerCtrl_SetPath, 2265).
+-define(wxFilePickerCtrl_destroy, 2266).
+-define(wxDirPickerCtrl_new_0, 2267).
+-define(wxDirPickerCtrl_new_3, 2268).
+-define(wxDirPickerCtrl_Create, 2269).
+-define(wxDirPickerCtrl_GetPath, 2270).
+-define(wxDirPickerCtrl_SetPath, 2271).
+-define(wxDirPickerCtrl_destroy, 2272).
+-define(wxColourPickerCtrl_new_0, 2273).
+-define(wxColourPickerCtrl_new_3, 2274).
+-define(wxColourPickerCtrl_Create, 2275).
+-define(wxColourPickerCtrl_GetColour, 2276).
+-define(wxColourPickerCtrl_SetColour_1_1, 2277).
+-define(wxColourPickerCtrl_SetColour_1_0, 2278).
+-define(wxColourPickerCtrl_destroy, 2279).
+-define(wxDatePickerCtrl_new_0, 2280).
+-define(wxDatePickerCtrl_new_3, 2281).
+-define(wxDatePickerCtrl_GetRange, 2282).
+-define(wxDatePickerCtrl_GetValue, 2283).
+-define(wxDatePickerCtrl_SetRange, 2284).
+-define(wxDatePickerCtrl_SetValue, 2285).
+-define(wxDatePickerCtrl_destroy, 2286).
+-define(wxFontPickerCtrl_new_0, 2287).
+-define(wxFontPickerCtrl_new_3, 2288).
+-define(wxFontPickerCtrl_Create, 2289).
+-define(wxFontPickerCtrl_GetSelectedFont, 2290).
+-define(wxFontPickerCtrl_SetSelectedFont, 2291).
+-define(wxFontPickerCtrl_GetMaxPointSize, 2292).
+-define(wxFontPickerCtrl_SetMaxPointSize, 2293).
+-define(wxFontPickerCtrl_destroy, 2294).
+-define(wxFindReplaceDialog_new_0, 2297).
+-define(wxFindReplaceDialog_new_4, 2298).
+-define(wxFindReplaceDialog_destruct, 2299).
+-define(wxFindReplaceDialog_Create, 2300).
+-define(wxFindReplaceDialog_GetData, 2301).
+-define(wxFindReplaceData_new_0, 2302).
+-define(wxFindReplaceData_new_1, 2303).
+-define(wxFindReplaceData_GetFindString, 2304).
+-define(wxFindReplaceData_GetReplaceString, 2305).
+-define(wxFindReplaceData_GetFlags, 2306).
+-define(wxFindReplaceData_SetFlags, 2307).
+-define(wxFindReplaceData_SetFindString, 2308).
+-define(wxFindReplaceData_SetReplaceString, 2309).
+-define(wxFindReplaceData_destroy, 2310).
+-define(wxMultiChoiceDialog_new_0, 2311).
+-define(wxMultiChoiceDialog_new_5, 2313).
+-define(wxMultiChoiceDialog_GetSelections, 2314).
+-define(wxMultiChoiceDialog_SetSelections, 2315).
+-define(wxMultiChoiceDialog_destroy, 2316).
+-define(wxSingleChoiceDialog_new_0, 2317).
+-define(wxSingleChoiceDialog_new_5, 2319).
+-define(wxSingleChoiceDialog_GetSelection, 2320).
+-define(wxSingleChoiceDialog_GetStringSelection, 2321).
+-define(wxSingleChoiceDialog_SetSelection, 2322).
+-define(wxSingleChoiceDialog_destroy, 2323).
+-define(wxTextEntryDialog_new, 2324).
+-define(wxTextEntryDialog_GetValue, 2325).
+-define(wxTextEntryDialog_SetValue, 2326).
+-define(wxTextEntryDialog_destroy, 2327).
+-define(wxPasswordEntryDialog_new, 2328).
+-define(wxPasswordEntryDialog_destroy, 2329).
+-define(wxFontData_new_0, 2330).
+-define(wxFontData_new_1, 2331).
+-define(wxFontData_destruct, 2332).
+-define(wxFontData_EnableEffects, 2333).
+-define(wxFontData_GetAllowSymbols, 2334).
+-define(wxFontData_GetColour, 2335).
+-define(wxFontData_GetChosenFont, 2336).
+-define(wxFontData_GetEnableEffects, 2337).
+-define(wxFontData_GetInitialFont, 2338).
+-define(wxFontData_GetShowHelp, 2339).
+-define(wxFontData_SetAllowSymbols, 2340).
+-define(wxFontData_SetChosenFont, 2341).
+-define(wxFontData_SetColour, 2342).
+-define(wxFontData_SetInitialFont, 2343).
+-define(wxFontData_SetRange, 2344).
+-define(wxFontData_SetShowHelp, 2345).
+-define(wxFontDialog_new_0, 2349).
+-define(wxFontDialog_new_2, 2351).
+-define(wxFontDialog_Create, 2353).
+-define(wxFontDialog_GetFontData, 2354).
+-define(wxFontDialog_destroy, 2356).
+-define(wxProgressDialog_new, 2357).
+-define(wxProgressDialog_destruct, 2358).
+-define(wxProgressDialog_Resume, 2359).
+-define(wxProgressDialog_Update_2, 2360).
+-define(wxProgressDialog_Update_0, 2361).
+-define(wxMessageDialog_new, 2362).
+-define(wxMessageDialog_destruct, 2363).
+-define(wxPageSetupDialog_new, 2364).
+-define(wxPageSetupDialog_destruct, 2365).
+-define(wxPageSetupDialog_GetPageSetupData, 2366).
+-define(wxPageSetupDialog_ShowModal, 2367).
+-define(wxPageSetupDialogData_new_0, 2368).
+-define(wxPageSetupDialogData_new_1_0, 2369).
+-define(wxPageSetupDialogData_new_1_1, 2370).
+-define(wxPageSetupDialogData_destruct, 2371).
+-define(wxPageSetupDialogData_EnableHelp, 2372).
+-define(wxPageSetupDialogData_EnableMargins, 2373).
+-define(wxPageSetupDialogData_EnableOrientation, 2374).
+-define(wxPageSetupDialogData_EnablePaper, 2375).
+-define(wxPageSetupDialogData_EnablePrinter, 2376).
+-define(wxPageSetupDialogData_GetDefaultMinMargins, 2377).
+-define(wxPageSetupDialogData_GetEnableMargins, 2378).
+-define(wxPageSetupDialogData_GetEnableOrientation, 2379).
+-define(wxPageSetupDialogData_GetEnablePaper, 2380).
+-define(wxPageSetupDialogData_GetEnablePrinter, 2381).
+-define(wxPageSetupDialogData_GetEnableHelp, 2382).
+-define(wxPageSetupDialogData_GetDefaultInfo, 2383).
+-define(wxPageSetupDialogData_GetMarginTopLeft, 2384).
+-define(wxPageSetupDialogData_GetMarginBottomRight, 2385).
+-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2386).
+-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2387).
+-define(wxPageSetupDialogData_GetPaperId, 2388).
+-define(wxPageSetupDialogData_GetPaperSize, 2389).
+-define(wxPageSetupDialogData_GetPrintData, 2391).
+-define(wxPageSetupDialogData_IsOk, 2392).
+-define(wxPageSetupDialogData_SetDefaultInfo, 2393).
+-define(wxPageSetupDialogData_SetDefaultMinMargins, 2394).
+-define(wxPageSetupDialogData_SetMarginTopLeft, 2395).
+-define(wxPageSetupDialogData_SetMarginBottomRight, 2396).
+-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2397).
+-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2398).
+-define(wxPageSetupDialogData_SetPaperId, 2399).
+-define(wxPageSetupDialogData_SetPaperSize_1_1, 2400).
+-define(wxPageSetupDialogData_SetPaperSize_1_0, 2401).
+-define(wxPageSetupDialogData_SetPrintData, 2402).
+-define(wxPrintDialog_new_2_0, 2403).
+-define(wxPrintDialog_new_2_1, 2404).
+-define(wxPrintDialog_destruct, 2405).
+-define(wxPrintDialog_GetPrintDialogData, 2406).
+-define(wxPrintDialog_GetPrintDC, 2407).
+-define(wxPrintDialogData_new_0, 2408).
+-define(wxPrintDialogData_new_1_1, 2409).
+-define(wxPrintDialogData_new_1_0, 2410).
+-define(wxPrintDialogData_destruct, 2411).
+-define(wxPrintDialogData_EnableHelp, 2412).
+-define(wxPrintDialogData_EnablePageNumbers, 2413).
+-define(wxPrintDialogData_EnablePrintToFile, 2414).
+-define(wxPrintDialogData_EnableSelection, 2415).
+-define(wxPrintDialogData_GetAllPages, 2416).
+-define(wxPrintDialogData_GetCollate, 2417).
+-define(wxPrintDialogData_GetFromPage, 2418).
+-define(wxPrintDialogData_GetMaxPage, 2419).
+-define(wxPrintDialogData_GetMinPage, 2420).
+-define(wxPrintDialogData_GetNoCopies, 2421).
+-define(wxPrintDialogData_GetPrintData, 2422).
+-define(wxPrintDialogData_GetPrintToFile, 2423).
+-define(wxPrintDialogData_GetSelection, 2424).
+-define(wxPrintDialogData_GetToPage, 2425).
+-define(wxPrintDialogData_IsOk, 2426).
+-define(wxPrintDialogData_SetCollate, 2427).
+-define(wxPrintDialogData_SetFromPage, 2428).
+-define(wxPrintDialogData_SetMaxPage, 2429).
+-define(wxPrintDialogData_SetMinPage, 2430).
+-define(wxPrintDialogData_SetNoCopies, 2431).
+-define(wxPrintDialogData_SetPrintData, 2432).
+-define(wxPrintDialogData_SetPrintToFile, 2433).
+-define(wxPrintDialogData_SetSelection, 2434).
+-define(wxPrintDialogData_SetToPage, 2435).
+-define(wxPrintData_new_0, 2436).
+-define(wxPrintData_new_1, 2437).
+-define(wxPrintData_destruct, 2438).
+-define(wxPrintData_GetCollate, 2439).
+-define(wxPrintData_GetBin, 2440).
+-define(wxPrintData_GetColour, 2441).
+-define(wxPrintData_GetDuplex, 2442).
+-define(wxPrintData_GetNoCopies, 2443).
+-define(wxPrintData_GetOrientation, 2444).
+-define(wxPrintData_GetPaperId, 2445).
+-define(wxPrintData_GetPrinterName, 2446).
+-define(wxPrintData_GetQuality, 2447).
+-define(wxPrintData_IsOk, 2448).
+-define(wxPrintData_SetBin, 2449).
+-define(wxPrintData_SetCollate, 2450).
+-define(wxPrintData_SetColour, 2451).
+-define(wxPrintData_SetDuplex, 2452).
+-define(wxPrintData_SetNoCopies, 2453).
+-define(wxPrintData_SetOrientation, 2454).
+-define(wxPrintData_SetPaperId, 2455).
+-define(wxPrintData_SetPrinterName, 2456).
+-define(wxPrintData_SetQuality, 2457).
+-define(wxPrintPreview_new_2, 2460).
+-define(wxPrintPreview_new_3, 2461).
+-define(wxPrintPreview_destruct, 2463).
+-define(wxPrintPreview_GetCanvas, 2464).
+-define(wxPrintPreview_GetCurrentPage, 2465).
+-define(wxPrintPreview_GetFrame, 2466).
+-define(wxPrintPreview_GetMaxPage, 2467).
+-define(wxPrintPreview_GetMinPage, 2468).
+-define(wxPrintPreview_GetPrintout, 2469).
+-define(wxPrintPreview_GetPrintoutForPrinting, 2470).
+-define(wxPrintPreview_IsOk, 2471).
+-define(wxPrintPreview_PaintPage, 2472).
+-define(wxPrintPreview_Print, 2473).
+-define(wxPrintPreview_RenderPage, 2474).
+-define(wxPrintPreview_SetCanvas, 2475).
+-define(wxPrintPreview_SetCurrentPage, 2476).
+-define(wxPrintPreview_SetFrame, 2477).
+-define(wxPrintPreview_SetPrintout, 2478).
+-define(wxPrintPreview_SetZoom, 2479).
+-define(wxPreviewFrame_new, 2480).
+-define(wxPreviewFrame_destruct, 2481).
+-define(wxPreviewFrame_CreateControlBar, 2482).
+-define(wxPreviewFrame_CreateCanvas, 2483).
+-define(wxPreviewFrame_Initialize, 2484).
+-define(wxPreviewFrame_OnCloseWindow, 2485).
+-define(wxPreviewControlBar_new, 2486).
+-define(wxPreviewControlBar_destruct, 2487).
+-define(wxPreviewControlBar_CreateButtons, 2488).
+-define(wxPreviewControlBar_GetPrintPreview, 2489).
+-define(wxPreviewControlBar_GetZoomControl, 2490).
+-define(wxPreviewControlBar_SetZoomControl, 2491).
+-define(wxPrinter_new, 2493).
+-define(wxPrinter_CreateAbortWindow, 2494).
+-define(wxPrinter_GetAbort, 2495).
+-define(wxPrinter_GetLastError, 2496).
+-define(wxPrinter_GetPrintDialogData, 2497).
+-define(wxPrinter_Print, 2498).
+-define(wxPrinter_PrintDialog, 2499).
+-define(wxPrinter_ReportError, 2500).
+-define(wxPrinter_Setup, 2501).
+-define(wxPrinter_destroy, 2502).
+-define(wxXmlResource_new_1, 2503).
+-define(wxXmlResource_new_2, 2504).
+-define(wxXmlResource_destruct, 2505).
+-define(wxXmlResource_AttachUnknownControl, 2506).
+-define(wxXmlResource_ClearHandlers, 2507).
+-define(wxXmlResource_CompareVersion, 2508).
+-define(wxXmlResource_Get, 2509).
+-define(wxXmlResource_GetFlags, 2510).
+-define(wxXmlResource_GetVersion, 2511).
+-define(wxXmlResource_GetXRCID, 2512).
+-define(wxXmlResource_InitAllHandlers, 2513).
+-define(wxXmlResource_Load, 2514).
+-define(wxXmlResource_LoadBitmap, 2515).
+-define(wxXmlResource_LoadDialog_2, 2516).
+-define(wxXmlResource_LoadDialog_3, 2517).
+-define(wxXmlResource_LoadFrame_2, 2518).
+-define(wxXmlResource_LoadFrame_3, 2519).
+-define(wxXmlResource_LoadIcon, 2520).
+-define(wxXmlResource_LoadMenu, 2521).
+-define(wxXmlResource_LoadMenuBar_2, 2522).
+-define(wxXmlResource_LoadMenuBar_1, 2523).
+-define(wxXmlResource_LoadPanel_2, 2524).
+-define(wxXmlResource_LoadPanel_3, 2525).
+-define(wxXmlResource_LoadToolBar, 2526).
+-define(wxXmlResource_Set, 2527).
+-define(wxXmlResource_SetFlags, 2528).
+-define(wxXmlResource_Unload, 2529).
+-define(wxXmlResource_xrcctrl, 2530).
+-define(wxHtmlEasyPrinting_new, 2531).
+-define(wxHtmlEasyPrinting_destruct, 2532).
+-define(wxHtmlEasyPrinting_GetPrintData, 2533).
+-define(wxHtmlEasyPrinting_GetPageSetupData, 2534).
+-define(wxHtmlEasyPrinting_PreviewFile, 2535).
+-define(wxHtmlEasyPrinting_PreviewText, 2536).
+-define(wxHtmlEasyPrinting_PrintFile, 2537).
+-define(wxHtmlEasyPrinting_PrintText, 2538).
+-define(wxHtmlEasyPrinting_PageSetup, 2539).
+-define(wxHtmlEasyPrinting_SetFonts, 2540).
+-define(wxHtmlEasyPrinting_SetHeader, 2541).
+-define(wxHtmlEasyPrinting_SetFooter, 2542).
+-define(wxGLCanvas_new_2, 2544).
+-define(wxGLCanvas_new_3_1, 2545).
+-define(wxGLCanvas_new_3_0, 2546).
+-define(wxGLCanvas_GetContext, 2547).
+-define(wxGLCanvas_SetCurrent, 2549).
+-define(wxGLCanvas_SwapBuffers, 2550).
+-define(wxGLCanvas_destroy, 2551).
+-define(wxAuiManager_new, 2552).
+-define(wxAuiManager_destruct, 2553).
+-define(wxAuiManager_AddPane_2_1, 2554).
+-define(wxAuiManager_AddPane_3, 2555).
+-define(wxAuiManager_AddPane_2_0, 2556).
+-define(wxAuiManager_DetachPane, 2557).
+-define(wxAuiManager_GetAllPanes, 2558).
+-define(wxAuiManager_GetArtProvider, 2559).
+-define(wxAuiManager_GetDockSizeConstraint, 2560).
+-define(wxAuiManager_GetFlags, 2561).
+-define(wxAuiManager_GetManagedWindow, 2562).
+-define(wxAuiManager_GetManager, 2563).
+-define(wxAuiManager_GetPane_1_1, 2564).
+-define(wxAuiManager_GetPane_1_0, 2565).
+-define(wxAuiManager_HideHint, 2566).
+-define(wxAuiManager_InsertPane, 2567).
+-define(wxAuiManager_LoadPaneInfo, 2568).
+-define(wxAuiManager_LoadPerspective, 2569).
+-define(wxAuiManager_SavePaneInfo, 2570).
+-define(wxAuiManager_SavePerspective, 2571).
+-define(wxAuiManager_SetArtProvider, 2572).
+-define(wxAuiManager_SetDockSizeConstraint, 2573).
+-define(wxAuiManager_SetFlags, 2574).
+-define(wxAuiManager_SetManagedWindow, 2575).
+-define(wxAuiManager_ShowHint, 2576).
+-define(wxAuiManager_UnInit, 2577).
+-define(wxAuiManager_Update, 2578).
+-define(wxAuiPaneInfo_new_0, 2579).
+-define(wxAuiPaneInfo_new_1, 2580).
+-define(wxAuiPaneInfo_destruct, 2581).
+-define(wxAuiPaneInfo_BestSize_1, 2582).
+-define(wxAuiPaneInfo_BestSize_2, 2583).
+-define(wxAuiPaneInfo_Bottom, 2584).
+-define(wxAuiPaneInfo_BottomDockable, 2585).
+-define(wxAuiPaneInfo_Caption, 2586).
+-define(wxAuiPaneInfo_CaptionVisible, 2587).
+-define(wxAuiPaneInfo_Centre, 2588).
+-define(wxAuiPaneInfo_CentrePane, 2589).
+-define(wxAuiPaneInfo_CloseButton, 2590).
+-define(wxAuiPaneInfo_DefaultPane, 2591).
+-define(wxAuiPaneInfo_DestroyOnClose, 2592).
+-define(wxAuiPaneInfo_Direction, 2593).
+-define(wxAuiPaneInfo_Dock, 2594).
+-define(wxAuiPaneInfo_Dockable, 2595).
+-define(wxAuiPaneInfo_Fixed, 2596).
+-define(wxAuiPaneInfo_Float, 2597).
+-define(wxAuiPaneInfo_Floatable, 2598).
+-define(wxAuiPaneInfo_FloatingPosition_1, 2599).
+-define(wxAuiPaneInfo_FloatingPosition_2, 2600).
+-define(wxAuiPaneInfo_FloatingSize_1, 2601).
+-define(wxAuiPaneInfo_FloatingSize_2, 2602).
+-define(wxAuiPaneInfo_Gripper, 2603).
+-define(wxAuiPaneInfo_GripperTop, 2604).
+-define(wxAuiPaneInfo_HasBorder, 2605).
+-define(wxAuiPaneInfo_HasCaption, 2606).
+-define(wxAuiPaneInfo_HasCloseButton, 2607).
+-define(wxAuiPaneInfo_HasFlag, 2608).
+-define(wxAuiPaneInfo_HasGripper, 2609).
+-define(wxAuiPaneInfo_HasGripperTop, 2610).
+-define(wxAuiPaneInfo_HasMaximizeButton, 2611).
+-define(wxAuiPaneInfo_HasMinimizeButton, 2612).
+-define(wxAuiPaneInfo_HasPinButton, 2613).
+-define(wxAuiPaneInfo_Hide, 2614).
+-define(wxAuiPaneInfo_IsBottomDockable, 2615).
+-define(wxAuiPaneInfo_IsDocked, 2616).
+-define(wxAuiPaneInfo_IsFixed, 2617).
+-define(wxAuiPaneInfo_IsFloatable, 2618).
+-define(wxAuiPaneInfo_IsFloating, 2619).
+-define(wxAuiPaneInfo_IsLeftDockable, 2620).
+-define(wxAuiPaneInfo_IsMovable, 2621).
+-define(wxAuiPaneInfo_IsOk, 2622).
+-define(wxAuiPaneInfo_IsResizable, 2623).
+-define(wxAuiPaneInfo_IsRightDockable, 2624).
+-define(wxAuiPaneInfo_IsShown, 2625).
+-define(wxAuiPaneInfo_IsToolbar, 2626).
+-define(wxAuiPaneInfo_IsTopDockable, 2627).
+-define(wxAuiPaneInfo_Layer, 2628).
+-define(wxAuiPaneInfo_Left, 2629).
+-define(wxAuiPaneInfo_LeftDockable, 2630).
+-define(wxAuiPaneInfo_MaxSize_1, 2631).
+-define(wxAuiPaneInfo_MaxSize_2, 2632).
+-define(wxAuiPaneInfo_MaximizeButton, 2633).
+-define(wxAuiPaneInfo_MinSize_1, 2634).
+-define(wxAuiPaneInfo_MinSize_2, 2635).
+-define(wxAuiPaneInfo_MinimizeButton, 2636).
+-define(wxAuiPaneInfo_Movable, 2637).
+-define(wxAuiPaneInfo_Name, 2638).
+-define(wxAuiPaneInfo_PaneBorder, 2639).
+-define(wxAuiPaneInfo_PinButton, 2640).
+-define(wxAuiPaneInfo_Position, 2641).
+-define(wxAuiPaneInfo_Resizable, 2642).
+-define(wxAuiPaneInfo_Right, 2643).
+-define(wxAuiPaneInfo_RightDockable, 2644).
+-define(wxAuiPaneInfo_Row, 2645).
+-define(wxAuiPaneInfo_SafeSet, 2646).
+-define(wxAuiPaneInfo_SetFlag, 2647).
+-define(wxAuiPaneInfo_Show, 2648).
+-define(wxAuiPaneInfo_ToolbarPane, 2649).
+-define(wxAuiPaneInfo_Top, 2650).
+-define(wxAuiPaneInfo_TopDockable, 2651).
+-define(wxAuiPaneInfo_Window, 2652).
+-define(wxAuiNotebook_new_0, 2653).
+-define(wxAuiNotebook_new_2, 2654).
+-define(wxAuiNotebook_AddPage, 2655).
+-define(wxAuiNotebook_Create, 2656).
+-define(wxAuiNotebook_DeletePage, 2657).
+-define(wxAuiNotebook_GetArtProvider, 2658).
+-define(wxAuiNotebook_GetPage, 2659).
+-define(wxAuiNotebook_GetPageBitmap, 2660).
+-define(wxAuiNotebook_GetPageCount, 2661).
+-define(wxAuiNotebook_GetPageIndex, 2662).
+-define(wxAuiNotebook_GetPageText, 2663).
+-define(wxAuiNotebook_GetSelection, 2664).
+-define(wxAuiNotebook_InsertPage, 2665).
+-define(wxAuiNotebook_RemovePage, 2666).
+-define(wxAuiNotebook_SetArtProvider, 2667).
+-define(wxAuiNotebook_SetFont, 2668).
+-define(wxAuiNotebook_SetPageBitmap, 2669).
+-define(wxAuiNotebook_SetPageText, 2670).
+-define(wxAuiNotebook_SetSelection, 2671).
+-define(wxAuiNotebook_SetTabCtrlHeight, 2672).
+-define(wxAuiNotebook_SetUniformBitmapSize, 2673).
+-define(wxAuiNotebook_destroy, 2674).
+-define(wxMDIParentFrame_new_0, 2675).
+-define(wxMDIParentFrame_new_4, 2676).
+-define(wxMDIParentFrame_destruct, 2677).
+-define(wxMDIParentFrame_ActivateNext, 2678).
+-define(wxMDIParentFrame_ActivatePrevious, 2679).
+-define(wxMDIParentFrame_ArrangeIcons, 2680).
+-define(wxMDIParentFrame_Cascade, 2681).
+-define(wxMDIParentFrame_Create, 2682).
+-define(wxMDIParentFrame_GetActiveChild, 2683).
+-define(wxMDIParentFrame_GetClientWindow, 2684).
+-define(wxMDIParentFrame_Tile, 2685).
+-define(wxMDIChildFrame_new_0, 2686).
+-define(wxMDIChildFrame_new_4, 2687).
+-define(wxMDIChildFrame_destruct, 2688).
+-define(wxMDIChildFrame_Activate, 2689).
+-define(wxMDIChildFrame_Create, 2690).
+-define(wxMDIChildFrame_Maximize, 2691).
+-define(wxMDIChildFrame_Restore, 2692).
+-define(wxMDIClientWindow_new_0, 2693).
+-define(wxMDIClientWindow_new_2, 2694).
+-define(wxMDIClientWindow_destruct, 2695).
+-define(wxMDIClientWindow_CreateClient, 2696).
+-define(wxLayoutAlgorithm_new, 2697).
+-define(wxLayoutAlgorithm_LayoutFrame, 2698).
+-define(wxLayoutAlgorithm_LayoutMDIFrame, 2699).
+-define(wxLayoutAlgorithm_LayoutWindow, 2700).
+-define(wxLayoutAlgorithm_destroy, 2701).
+-define(wxEvent_GetId, 2702).
+-define(wxEvent_GetSkipped, 2703).
+-define(wxEvent_GetTimestamp, 2704).
+-define(wxEvent_IsCommandEvent, 2705).
+-define(wxEvent_ResumePropagation, 2706).
+-define(wxEvent_ShouldPropagate, 2707).
+-define(wxEvent_Skip, 2708).
+-define(wxEvent_StopPropagation, 2709).
+-define(wxCommandEvent_getClientData, 2710).
+-define(wxCommandEvent_GetExtraLong, 2711).
+-define(wxCommandEvent_GetInt, 2712).
+-define(wxCommandEvent_GetSelection, 2713).
+-define(wxCommandEvent_GetString, 2714).
+-define(wxCommandEvent_IsChecked, 2715).
+-define(wxCommandEvent_IsSelection, 2716).
+-define(wxCommandEvent_SetInt, 2717).
+-define(wxCommandEvent_SetString, 2718).
+-define(wxScrollEvent_GetOrientation, 2719).
+-define(wxScrollEvent_GetPosition, 2720).
+-define(wxScrollWinEvent_GetOrientation, 2721).
+-define(wxScrollWinEvent_GetPosition, 2722).
+-define(wxMouseEvent_AltDown, 2723).
+-define(wxMouseEvent_Button, 2724).
+-define(wxMouseEvent_ButtonDClick, 2725).
+-define(wxMouseEvent_ButtonDown, 2726).
+-define(wxMouseEvent_ButtonUp, 2727).
+-define(wxMouseEvent_CmdDown, 2728).
+-define(wxMouseEvent_ControlDown, 2729).
+-define(wxMouseEvent_Dragging, 2730).
+-define(wxMouseEvent_Entering, 2731).
+-define(wxMouseEvent_GetButton, 2732).
+-define(wxMouseEvent_GetPosition, 2735).
+-define(wxMouseEvent_GetLogicalPosition, 2736).
+-define(wxMouseEvent_GetLinesPerAction, 2737).
+-define(wxMouseEvent_GetWheelRotation, 2738).
+-define(wxMouseEvent_GetWheelDelta, 2739).
+-define(wxMouseEvent_GetX, 2740).
+-define(wxMouseEvent_GetY, 2741).
+-define(wxMouseEvent_IsButton, 2742).
+-define(wxMouseEvent_IsPageScroll, 2743).
+-define(wxMouseEvent_Leaving, 2744).
+-define(wxMouseEvent_LeftDClick, 2745).
+-define(wxMouseEvent_LeftDown, 2746).
+-define(wxMouseEvent_LeftIsDown, 2747).
+-define(wxMouseEvent_LeftUp, 2748).
+-define(wxMouseEvent_MetaDown, 2749).
+-define(wxMouseEvent_MiddleDClick, 2750).
+-define(wxMouseEvent_MiddleDown, 2751).
+-define(wxMouseEvent_MiddleIsDown, 2752).
+-define(wxMouseEvent_MiddleUp, 2753).
+-define(wxMouseEvent_Moving, 2754).
+-define(wxMouseEvent_RightDClick, 2755).
+-define(wxMouseEvent_RightDown, 2756).
+-define(wxMouseEvent_RightIsDown, 2757).
+-define(wxMouseEvent_RightUp, 2758).
+-define(wxMouseEvent_ShiftDown, 2759).
+-define(wxSetCursorEvent_GetCursor, 2760).
+-define(wxSetCursorEvent_GetX, 2761).
+-define(wxSetCursorEvent_GetY, 2762).
+-define(wxSetCursorEvent_HasCursor, 2763).
+-define(wxSetCursorEvent_SetCursor, 2764).
+-define(wxKeyEvent_AltDown, 2765).
+-define(wxKeyEvent_CmdDown, 2766).
+-define(wxKeyEvent_ControlDown, 2767).
+-define(wxKeyEvent_GetKeyCode, 2768).
+-define(wxKeyEvent_GetModifiers, 2769).
+-define(wxKeyEvent_GetPosition, 2772).
+-define(wxKeyEvent_GetRawKeyCode, 2773).
+-define(wxKeyEvent_GetRawKeyFlags, 2774).
+-define(wxKeyEvent_GetUnicodeKey, 2775).
+-define(wxKeyEvent_GetX, 2776).
+-define(wxKeyEvent_GetY, 2777).
+-define(wxKeyEvent_HasModifiers, 2778).
+-define(wxKeyEvent_MetaDown, 2779).
+-define(wxKeyEvent_ShiftDown, 2780).
+-define(wxSizeEvent_GetSize, 2781).
+-define(wxMoveEvent_GetPosition, 2782).
+-define(wxEraseEvent_GetDC, 2783).
+-define(wxFocusEvent_GetWindow, 2784).
+-define(wxChildFocusEvent_GetWindow, 2785).
+-define(wxMenuEvent_GetMenu, 2786).
+-define(wxMenuEvent_GetMenuId, 2787).
+-define(wxMenuEvent_IsPopup, 2788).
+-define(wxCloseEvent_CanVeto, 2789).
+-define(wxCloseEvent_GetLoggingOff, 2790).
+-define(wxCloseEvent_SetCanVeto, 2791).
+-define(wxCloseEvent_SetLoggingOff, 2792).
+-define(wxCloseEvent_Veto, 2793).
+-define(wxShowEvent_SetShow, 2794).
+-define(wxShowEvent_GetShow, 2795).
+-define(wxIconizeEvent_Iconized, 2796).
+-define(wxJoystickEvent_ButtonDown, 2797).
+-define(wxJoystickEvent_ButtonIsDown, 2798).
+-define(wxJoystickEvent_ButtonUp, 2799).
+-define(wxJoystickEvent_GetButtonChange, 2800).
+-define(wxJoystickEvent_GetButtonState, 2801).
+-define(wxJoystickEvent_GetJoystick, 2802).
+-define(wxJoystickEvent_GetPosition, 2803).
+-define(wxJoystickEvent_GetZPosition, 2804).
+-define(wxJoystickEvent_IsButton, 2805).
+-define(wxJoystickEvent_IsMove, 2806).
+-define(wxJoystickEvent_IsZMove, 2807).
+-define(wxUpdateUIEvent_CanUpdate, 2808).
+-define(wxUpdateUIEvent_Check, 2809).
+-define(wxUpdateUIEvent_Enable, 2810).
+-define(wxUpdateUIEvent_Show, 2811).
+-define(wxUpdateUIEvent_GetChecked, 2812).
+-define(wxUpdateUIEvent_GetEnabled, 2813).
+-define(wxUpdateUIEvent_GetShown, 2814).
+-define(wxUpdateUIEvent_GetSetChecked, 2815).
+-define(wxUpdateUIEvent_GetSetEnabled, 2816).
+-define(wxUpdateUIEvent_GetSetShown, 2817).
+-define(wxUpdateUIEvent_GetSetText, 2818).
+-define(wxUpdateUIEvent_GetText, 2819).
+-define(wxUpdateUIEvent_GetMode, 2820).
+-define(wxUpdateUIEvent_GetUpdateInterval, 2821).
+-define(wxUpdateUIEvent_ResetUpdateTime, 2822).
+-define(wxUpdateUIEvent_SetMode, 2823).
+-define(wxUpdateUIEvent_SetText, 2824).
+-define(wxUpdateUIEvent_SetUpdateInterval, 2825).
+-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2826).
+-define(wxPaletteChangedEvent_SetChangedWindow, 2827).
+-define(wxPaletteChangedEvent_GetChangedWindow, 2828).
+-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2829).
+-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2830).
+-define(wxNavigationKeyEvent_GetDirection, 2831).
+-define(wxNavigationKeyEvent_SetDirection, 2832).
+-define(wxNavigationKeyEvent_IsWindowChange, 2833).
+-define(wxNavigationKeyEvent_SetWindowChange, 2834).
+-define(wxNavigationKeyEvent_IsFromTab, 2835).
+-define(wxNavigationKeyEvent_SetFromTab, 2836).
+-define(wxNavigationKeyEvent_GetCurrentFocus, 2837).
+-define(wxNavigationKeyEvent_SetCurrentFocus, 2838).
+-define(wxHelpEvent_GetOrigin, 2839).
+-define(wxHelpEvent_GetPosition, 2840).
+-define(wxHelpEvent_SetOrigin, 2841).
+-define(wxHelpEvent_SetPosition, 2842).
+-define(wxContextMenuEvent_GetPosition, 2843).
+-define(wxContextMenuEvent_SetPosition, 2844).
+-define(wxIdleEvent_CanSend, 2845).
+-define(wxIdleEvent_GetMode, 2846).
+-define(wxIdleEvent_RequestMore, 2847).
+-define(wxIdleEvent_MoreRequested, 2848).
+-define(wxIdleEvent_SetMode, 2849).
+-define(wxGridEvent_AltDown, 2850).
+-define(wxGridEvent_ControlDown, 2851).
+-define(wxGridEvent_GetCol, 2852).
+-define(wxGridEvent_GetPosition, 2853).
+-define(wxGridEvent_GetRow, 2854).
+-define(wxGridEvent_MetaDown, 2855).
+-define(wxGridEvent_Selecting, 2856).
+-define(wxGridEvent_ShiftDown, 2857).
+-define(wxNotifyEvent_Allow, 2858).
+-define(wxNotifyEvent_IsAllowed, 2859).
+-define(wxNotifyEvent_Veto, 2860).
+-define(wxSashEvent_GetEdge, 2861).
+-define(wxSashEvent_GetDragRect, 2862).
+-define(wxSashEvent_GetDragStatus, 2863).
+-define(wxListEvent_GetCacheFrom, 2864).
+-define(wxListEvent_GetCacheTo, 2865).
+-define(wxListEvent_GetKeyCode, 2866).
+-define(wxListEvent_GetIndex, 2867).
+-define(wxListEvent_GetColumn, 2868).
+-define(wxListEvent_GetPoint, 2869).
+-define(wxListEvent_GetLabel, 2870).
+-define(wxListEvent_GetText, 2871).
+-define(wxListEvent_GetImage, 2872).
+-define(wxListEvent_GetData, 2873).
+-define(wxListEvent_GetMask, 2874).
+-define(wxListEvent_GetItem, 2875).
+-define(wxListEvent_IsEditCancelled, 2876).
+-define(wxDateEvent_GetDate, 2877).
+-define(wxCalendarEvent_GetWeekDay, 2878).
+-define(wxFileDirPickerEvent_GetPath, 2879).
+-define(wxColourPickerEvent_GetColour, 2880).
+-define(wxFontPickerEvent_GetFont, 2881).
+-define(wxStyledTextEvent_GetPosition, 2882).
+-define(wxStyledTextEvent_GetKey, 2883).
+-define(wxStyledTextEvent_GetModifiers, 2884).
+-define(wxStyledTextEvent_GetModificationType, 2885).
+-define(wxStyledTextEvent_GetText, 2886).
+-define(wxStyledTextEvent_GetLength, 2887).
+-define(wxStyledTextEvent_GetLinesAdded, 2888).
+-define(wxStyledTextEvent_GetLine, 2889).
+-define(wxStyledTextEvent_GetFoldLevelNow, 2890).
+-define(wxStyledTextEvent_GetFoldLevelPrev, 2891).
+-define(wxStyledTextEvent_GetMargin, 2892).
+-define(wxStyledTextEvent_GetMessage, 2893).
+-define(wxStyledTextEvent_GetWParam, 2894).
+-define(wxStyledTextEvent_GetLParam, 2895).
+-define(wxStyledTextEvent_GetListType, 2896).
+-define(wxStyledTextEvent_GetX, 2897).
+-define(wxStyledTextEvent_GetY, 2898).
+-define(wxStyledTextEvent_GetDragText, 2899).
+-define(wxStyledTextEvent_GetDragAllowMove, 2900).
+-define(wxStyledTextEvent_GetDragResult, 2901).
+-define(wxStyledTextEvent_GetShift, 2902).
+-define(wxStyledTextEvent_GetControl, 2903).
+-define(wxStyledTextEvent_GetAlt, 2904).
+-define(utils_wxGetKeyState, 2905).
+-define(utils_wxGetMousePosition, 2906).
+-define(utils_wxGetMouseState, 2907).
+-define(utils_wxSetDetectableAutoRepeat, 2908).
+-define(utils_wxBell, 2909).
+-define(utils_wxFindMenuItemId, 2910).
+-define(utils_wxGenericFindWindowAtPoint, 2911).
+-define(utils_wxFindWindowAtPoint, 2912).
+-define(utils_wxBeginBusyCursor, 2913).
+-define(utils_wxEndBusyCursor, 2914).
+-define(utils_wxIsBusy, 2915).
+-define(utils_wxShutdown, 2916).
+-define(utils_wxShell, 2917).
+-define(utils_wxLaunchDefaultBrowser, 2918).
+-define(utils_wxGetEmailAddress, 2919).
+-define(utils_wxGetUserId, 2920).
+-define(utils_wxGetHomeDir, 2921).
+-define(utils_wxNewId, 2922).
+-define(utils_wxRegisterId, 2923).
+-define(utils_wxGetCurrentId, 2924).
+-define(utils_wxGetOsDescription, 2925).
+-define(utils_wxIsPlatformLittleEndian, 2926).
+-define(utils_wxIsPlatform64Bit, 2927).
+-define(gdicmn_wxDisplaySize, 2928).
+-define(gdicmn_wxSetCursor, 2929).
+-define(wxPrintout_new, 2930).
+-define(wxPrintout_destruct, 2931).
+-define(wxPrintout_GetDC, 2932).
+-define(wxPrintout_GetPageSizeMM, 2933).
+-define(wxPrintout_GetPageSizePixels, 2934).
+-define(wxPrintout_GetPaperRectPixels, 2935).
+-define(wxPrintout_GetPPIPrinter, 2936).
+-define(wxPrintout_GetPPIScreen, 2937).
+-define(wxPrintout_GetTitle, 2938).
+-define(wxPrintout_IsPreview, 2939).
+-define(wxPrintout_FitThisSizeToPaper, 2940).
+-define(wxPrintout_FitThisSizeToPage, 2941).
+-define(wxPrintout_FitThisSizeToPageMargins, 2942).
+-define(wxPrintout_MapScreenSizeToPaper, 2943).
+-define(wxPrintout_MapScreenSizeToPage, 2944).
+-define(wxPrintout_MapScreenSizeToPageMargins, 2945).
+-define(wxPrintout_MapScreenSizeToDevice, 2946).
+-define(wxPrintout_GetLogicalPaperRect, 2947).
+-define(wxPrintout_GetLogicalPageRect, 2948).
+-define(wxPrintout_GetLogicalPageMarginsRect, 2949).
+-define(wxPrintout_SetLogicalOrigin, 2950).
+-define(wxPrintout_OffsetLogicalOrigin, 2951).
+-define(wxStyledTextCtrl_new_2, 2952).
+-define(wxStyledTextCtrl_new_0, 2953).
+-define(wxStyledTextCtrl_destruct, 2954).
+-define(wxStyledTextCtrl_Create, 2955).
+-define(wxStyledTextCtrl_AddText, 2956).
+-define(wxStyledTextCtrl_AddStyledText, 2957).
+-define(wxStyledTextCtrl_InsertText, 2958).
+-define(wxStyledTextCtrl_ClearAll, 2959).
+-define(wxStyledTextCtrl_ClearDocumentStyle, 2960).
+-define(wxStyledTextCtrl_GetLength, 2961).
+-define(wxStyledTextCtrl_GetCharAt, 2962).
+-define(wxStyledTextCtrl_GetCurrentPos, 2963).
+-define(wxStyledTextCtrl_GetAnchor, 2964).
+-define(wxStyledTextCtrl_GetStyleAt, 2965).
+-define(wxStyledTextCtrl_Redo, 2966).
+-define(wxStyledTextCtrl_SetUndoCollection, 2967).
+-define(wxStyledTextCtrl_SelectAll, 2968).
+-define(wxStyledTextCtrl_SetSavePoint, 2969).
+-define(wxStyledTextCtrl_GetStyledText, 2970).
+-define(wxStyledTextCtrl_CanRedo, 2971).
+-define(wxStyledTextCtrl_MarkerLineFromHandle, 2972).
+-define(wxStyledTextCtrl_MarkerDeleteHandle, 2973).
+-define(wxStyledTextCtrl_GetUndoCollection, 2974).
+-define(wxStyledTextCtrl_GetViewWhiteSpace, 2975).
+-define(wxStyledTextCtrl_SetViewWhiteSpace, 2976).
+-define(wxStyledTextCtrl_PositionFromPoint, 2977).
+-define(wxStyledTextCtrl_PositionFromPointClose, 2978).
+-define(wxStyledTextCtrl_GotoLine, 2979).
+-define(wxStyledTextCtrl_GotoPos, 2980).
+-define(wxStyledTextCtrl_SetAnchor, 2981).
+-define(wxStyledTextCtrl_GetCurLine, 2982).
+-define(wxStyledTextCtrl_GetEndStyled, 2983).
+-define(wxStyledTextCtrl_ConvertEOLs, 2984).
+-define(wxStyledTextCtrl_GetEOLMode, 2985).
+-define(wxStyledTextCtrl_SetEOLMode, 2986).
+-define(wxStyledTextCtrl_StartStyling, 2987).
+-define(wxStyledTextCtrl_SetStyling, 2988).
+-define(wxStyledTextCtrl_GetBufferedDraw, 2989).
+-define(wxStyledTextCtrl_SetBufferedDraw, 2990).
+-define(wxStyledTextCtrl_SetTabWidth, 2991).
+-define(wxStyledTextCtrl_GetTabWidth, 2992).
+-define(wxStyledTextCtrl_SetCodePage, 2993).
+-define(wxStyledTextCtrl_MarkerDefine, 2994).
+-define(wxStyledTextCtrl_MarkerSetForeground, 2995).
+-define(wxStyledTextCtrl_MarkerSetBackground, 2996).
+-define(wxStyledTextCtrl_MarkerAdd, 2997).
+-define(wxStyledTextCtrl_MarkerDelete, 2998).
+-define(wxStyledTextCtrl_MarkerDeleteAll, 2999).
+-define(wxStyledTextCtrl_MarkerGet, 3000).
+-define(wxStyledTextCtrl_MarkerNext, 3001).
+-define(wxStyledTextCtrl_MarkerPrevious, 3002).
+-define(wxStyledTextCtrl_MarkerDefineBitmap, 3003).
+-define(wxStyledTextCtrl_MarkerAddSet, 3004).
+-define(wxStyledTextCtrl_MarkerSetAlpha, 3005).
+-define(wxStyledTextCtrl_SetMarginType, 3006).
+-define(wxStyledTextCtrl_GetMarginType, 3007).
+-define(wxStyledTextCtrl_SetMarginWidth, 3008).
+-define(wxStyledTextCtrl_GetMarginWidth, 3009).
+-define(wxStyledTextCtrl_SetMarginMask, 3010).
+-define(wxStyledTextCtrl_GetMarginMask, 3011).
+-define(wxStyledTextCtrl_SetMarginSensitive, 3012).
+-define(wxStyledTextCtrl_GetMarginSensitive, 3013).
+-define(wxStyledTextCtrl_StyleClearAll, 3014).
+-define(wxStyledTextCtrl_StyleSetForeground, 3015).
+-define(wxStyledTextCtrl_StyleSetBackground, 3016).
+-define(wxStyledTextCtrl_StyleSetBold, 3017).
+-define(wxStyledTextCtrl_StyleSetItalic, 3018).
+-define(wxStyledTextCtrl_StyleSetSize, 3019).
+-define(wxStyledTextCtrl_StyleSetFaceName, 3020).
+-define(wxStyledTextCtrl_StyleSetEOLFilled, 3021).
+-define(wxStyledTextCtrl_StyleResetDefault, 3022).
+-define(wxStyledTextCtrl_StyleSetUnderline, 3023).
+-define(wxStyledTextCtrl_StyleSetCase, 3024).
+-define(wxStyledTextCtrl_StyleSetHotSpot, 3025).
+-define(wxStyledTextCtrl_SetSelForeground, 3026).
+-define(wxStyledTextCtrl_SetSelBackground, 3027).
+-define(wxStyledTextCtrl_GetSelAlpha, 3028).
+-define(wxStyledTextCtrl_SetSelAlpha, 3029).
+-define(wxStyledTextCtrl_SetCaretForeground, 3030).
+-define(wxStyledTextCtrl_CmdKeyAssign, 3031).
+-define(wxStyledTextCtrl_CmdKeyClear, 3032).
+-define(wxStyledTextCtrl_CmdKeyClearAll, 3033).
+-define(wxStyledTextCtrl_SetStyleBytes, 3034).
+-define(wxStyledTextCtrl_StyleSetVisible, 3035).
+-define(wxStyledTextCtrl_GetCaretPeriod, 3036).
+-define(wxStyledTextCtrl_SetCaretPeriod, 3037).
+-define(wxStyledTextCtrl_SetWordChars, 3038).
+-define(wxStyledTextCtrl_BeginUndoAction, 3039).
+-define(wxStyledTextCtrl_EndUndoAction, 3040).
+-define(wxStyledTextCtrl_IndicatorSetStyle, 3041).
+-define(wxStyledTextCtrl_IndicatorGetStyle, 3042).
+-define(wxStyledTextCtrl_IndicatorSetForeground, 3043).
+-define(wxStyledTextCtrl_IndicatorGetForeground, 3044).
+-define(wxStyledTextCtrl_SetWhitespaceForeground, 3045).
+-define(wxStyledTextCtrl_SetWhitespaceBackground, 3046).
+-define(wxStyledTextCtrl_GetStyleBits, 3047).
+-define(wxStyledTextCtrl_SetLineState, 3048).
+-define(wxStyledTextCtrl_GetLineState, 3049).
+-define(wxStyledTextCtrl_GetMaxLineState, 3050).
+-define(wxStyledTextCtrl_GetCaretLineVisible, 3051).
+-define(wxStyledTextCtrl_SetCaretLineVisible, 3052).
+-define(wxStyledTextCtrl_GetCaretLineBackground, 3053).
+-define(wxStyledTextCtrl_SetCaretLineBackground, 3054).
+-define(wxStyledTextCtrl_AutoCompShow, 3055).
+-define(wxStyledTextCtrl_AutoCompCancel, 3056).
+-define(wxStyledTextCtrl_AutoCompActive, 3057).
+-define(wxStyledTextCtrl_AutoCompPosStart, 3058).
+-define(wxStyledTextCtrl_AutoCompComplete, 3059).
+-define(wxStyledTextCtrl_AutoCompStops, 3060).
+-define(wxStyledTextCtrl_AutoCompSetSeparator, 3061).
+-define(wxStyledTextCtrl_AutoCompGetSeparator, 3062).
+-define(wxStyledTextCtrl_AutoCompSelect, 3063).
+-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3064).
+-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3065).
+-define(wxStyledTextCtrl_AutoCompSetFillUps, 3066).
+-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3067).
+-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3068).
+-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3069).
+-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3070).
+-define(wxStyledTextCtrl_UserListShow, 3071).
+-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3072).
+-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3073).
+-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3074).
+-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3075).
+-define(wxStyledTextCtrl_RegisterImage, 3076).
+-define(wxStyledTextCtrl_ClearRegisteredImages, 3077).
+-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3078).
+-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3079).
+-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3080).
+-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3081).
+-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3082).
+-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3083).
+-define(wxStyledTextCtrl_SetIndent, 3084).
+-define(wxStyledTextCtrl_GetIndent, 3085).
+-define(wxStyledTextCtrl_SetUseTabs, 3086).
+-define(wxStyledTextCtrl_GetUseTabs, 3087).
+-define(wxStyledTextCtrl_SetLineIndentation, 3088).
+-define(wxStyledTextCtrl_GetLineIndentation, 3089).
+-define(wxStyledTextCtrl_GetLineIndentPosition, 3090).
+-define(wxStyledTextCtrl_GetColumn, 3091).
+-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3092).
+-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3093).
+-define(wxStyledTextCtrl_SetIndentationGuides, 3094).
+-define(wxStyledTextCtrl_GetIndentationGuides, 3095).
+-define(wxStyledTextCtrl_SetHighlightGuide, 3096).
+-define(wxStyledTextCtrl_GetHighlightGuide, 3097).
+-define(wxStyledTextCtrl_GetLineEndPosition, 3098).
+-define(wxStyledTextCtrl_GetCodePage, 3099).
+-define(wxStyledTextCtrl_GetCaretForeground, 3100).
+-define(wxStyledTextCtrl_GetReadOnly, 3101).
+-define(wxStyledTextCtrl_SetCurrentPos, 3102).
+-define(wxStyledTextCtrl_SetSelectionStart, 3103).
+-define(wxStyledTextCtrl_GetSelectionStart, 3104).
+-define(wxStyledTextCtrl_SetSelectionEnd, 3105).
+-define(wxStyledTextCtrl_GetSelectionEnd, 3106).
+-define(wxStyledTextCtrl_SetPrintMagnification, 3107).
+-define(wxStyledTextCtrl_GetPrintMagnification, 3108).
+-define(wxStyledTextCtrl_SetPrintColourMode, 3109).
+-define(wxStyledTextCtrl_GetPrintColourMode, 3110).
+-define(wxStyledTextCtrl_FindText, 3111).
+-define(wxStyledTextCtrl_FormatRange, 3112).
+-define(wxStyledTextCtrl_GetFirstVisibleLine, 3113).
+-define(wxStyledTextCtrl_GetLine, 3114).
+-define(wxStyledTextCtrl_GetLineCount, 3115).
+-define(wxStyledTextCtrl_SetMarginLeft, 3116).
+-define(wxStyledTextCtrl_GetMarginLeft, 3117).
+-define(wxStyledTextCtrl_SetMarginRight, 3118).
+-define(wxStyledTextCtrl_GetMarginRight, 3119).
+-define(wxStyledTextCtrl_GetModify, 3120).
+-define(wxStyledTextCtrl_SetSelection, 3121).
+-define(wxStyledTextCtrl_GetSelectedText, 3122).
+-define(wxStyledTextCtrl_GetTextRange, 3123).
+-define(wxStyledTextCtrl_HideSelection, 3124).
+-define(wxStyledTextCtrl_LineFromPosition, 3125).
+-define(wxStyledTextCtrl_PositionFromLine, 3126).
+-define(wxStyledTextCtrl_LineScroll, 3127).
+-define(wxStyledTextCtrl_EnsureCaretVisible, 3128).
+-define(wxStyledTextCtrl_ReplaceSelection, 3129).
+-define(wxStyledTextCtrl_SetReadOnly, 3130).
+-define(wxStyledTextCtrl_CanPaste, 3131).
+-define(wxStyledTextCtrl_CanUndo, 3132).
+-define(wxStyledTextCtrl_EmptyUndoBuffer, 3133).
+-define(wxStyledTextCtrl_Undo, 3134).
+-define(wxStyledTextCtrl_Cut, 3135).
+-define(wxStyledTextCtrl_Copy, 3136).
+-define(wxStyledTextCtrl_Paste, 3137).
+-define(wxStyledTextCtrl_Clear, 3138).
+-define(wxStyledTextCtrl_SetText, 3139).
+-define(wxStyledTextCtrl_GetText, 3140).
+-define(wxStyledTextCtrl_GetTextLength, 3141).
+-define(wxStyledTextCtrl_GetOvertype, 3142).
+-define(wxStyledTextCtrl_SetCaretWidth, 3143).
+-define(wxStyledTextCtrl_GetCaretWidth, 3144).
+-define(wxStyledTextCtrl_SetTargetStart, 3145).
+-define(wxStyledTextCtrl_GetTargetStart, 3146).
+-define(wxStyledTextCtrl_SetTargetEnd, 3147).
+-define(wxStyledTextCtrl_GetTargetEnd, 3148).
+-define(wxStyledTextCtrl_ReplaceTarget, 3149).
+-define(wxStyledTextCtrl_SearchInTarget, 3150).
+-define(wxStyledTextCtrl_SetSearchFlags, 3151).
+-define(wxStyledTextCtrl_GetSearchFlags, 3152).
+-define(wxStyledTextCtrl_CallTipShow, 3153).
+-define(wxStyledTextCtrl_CallTipCancel, 3154).
+-define(wxStyledTextCtrl_CallTipActive, 3155).
+-define(wxStyledTextCtrl_CallTipPosAtStart, 3156).
+-define(wxStyledTextCtrl_CallTipSetHighlight, 3157).
+-define(wxStyledTextCtrl_CallTipSetBackground, 3158).
+-define(wxStyledTextCtrl_CallTipSetForeground, 3159).
+-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3160).
+-define(wxStyledTextCtrl_CallTipUseStyle, 3161).
+-define(wxStyledTextCtrl_VisibleFromDocLine, 3162).
+-define(wxStyledTextCtrl_DocLineFromVisible, 3163).
+-define(wxStyledTextCtrl_WrapCount, 3164).
+-define(wxStyledTextCtrl_SetFoldLevel, 3165).
+-define(wxStyledTextCtrl_GetFoldLevel, 3166).
+-define(wxStyledTextCtrl_GetLastChild, 3167).
+-define(wxStyledTextCtrl_GetFoldParent, 3168).
+-define(wxStyledTextCtrl_ShowLines, 3169).
+-define(wxStyledTextCtrl_HideLines, 3170).
+-define(wxStyledTextCtrl_GetLineVisible, 3171).
+-define(wxStyledTextCtrl_SetFoldExpanded, 3172).
+-define(wxStyledTextCtrl_GetFoldExpanded, 3173).
+-define(wxStyledTextCtrl_ToggleFold, 3174).
+-define(wxStyledTextCtrl_EnsureVisible, 3175).
+-define(wxStyledTextCtrl_SetFoldFlags, 3176).
+-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3177).
+-define(wxStyledTextCtrl_SetTabIndents, 3178).
+-define(wxStyledTextCtrl_GetTabIndents, 3179).
+-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3180).
+-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3181).
+-define(wxStyledTextCtrl_SetMouseDwellTime, 3182).
+-define(wxStyledTextCtrl_GetMouseDwellTime, 3183).
+-define(wxStyledTextCtrl_WordStartPosition, 3184).
+-define(wxStyledTextCtrl_WordEndPosition, 3185).
+-define(wxStyledTextCtrl_SetWrapMode, 3186).
+-define(wxStyledTextCtrl_GetWrapMode, 3187).
+-define(wxStyledTextCtrl_SetWrapVisualFlags, 3188).
+-define(wxStyledTextCtrl_GetWrapVisualFlags, 3189).
+-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3190).
+-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3191).
+-define(wxStyledTextCtrl_SetWrapStartIndent, 3192).
+-define(wxStyledTextCtrl_GetWrapStartIndent, 3193).
+-define(wxStyledTextCtrl_SetLayoutCache, 3194).
+-define(wxStyledTextCtrl_GetLayoutCache, 3195).
+-define(wxStyledTextCtrl_SetScrollWidth, 3196).
+-define(wxStyledTextCtrl_GetScrollWidth, 3197).
+-define(wxStyledTextCtrl_TextWidth, 3198).
+-define(wxStyledTextCtrl_GetEndAtLastLine, 3199).
+-define(wxStyledTextCtrl_TextHeight, 3200).
+-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3201).
+-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3202).
+-define(wxStyledTextCtrl_AppendText, 3203).
+-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3204).
+-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3205).
+-define(wxStyledTextCtrl_TargetFromSelection, 3206).
+-define(wxStyledTextCtrl_LinesJoin, 3207).
+-define(wxStyledTextCtrl_LinesSplit, 3208).
+-define(wxStyledTextCtrl_SetFoldMarginColour, 3209).
+-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3210).
+-define(wxStyledTextCtrl_LineDown, 3211).
+-define(wxStyledTextCtrl_LineDownExtend, 3212).
+-define(wxStyledTextCtrl_LineUp, 3213).
+-define(wxStyledTextCtrl_LineUpExtend, 3214).
+-define(wxStyledTextCtrl_CharLeft, 3215).
+-define(wxStyledTextCtrl_CharLeftExtend, 3216).
+-define(wxStyledTextCtrl_CharRight, 3217).
+-define(wxStyledTextCtrl_CharRightExtend, 3218).
+-define(wxStyledTextCtrl_WordLeft, 3219).
+-define(wxStyledTextCtrl_WordLeftExtend, 3220).
+-define(wxStyledTextCtrl_WordRight, 3221).
+-define(wxStyledTextCtrl_WordRightExtend, 3222).
+-define(wxStyledTextCtrl_Home, 3223).
+-define(wxStyledTextCtrl_HomeExtend, 3224).
+-define(wxStyledTextCtrl_LineEnd, 3225).
+-define(wxStyledTextCtrl_LineEndExtend, 3226).
+-define(wxStyledTextCtrl_DocumentStart, 3227).
+-define(wxStyledTextCtrl_DocumentStartExtend, 3228).
+-define(wxStyledTextCtrl_DocumentEnd, 3229).
+-define(wxStyledTextCtrl_DocumentEndExtend, 3230).
+-define(wxStyledTextCtrl_PageUp, 3231).
+-define(wxStyledTextCtrl_PageUpExtend, 3232).
+-define(wxStyledTextCtrl_PageDown, 3233).
+-define(wxStyledTextCtrl_PageDownExtend, 3234).
+-define(wxStyledTextCtrl_EditToggleOvertype, 3235).
+-define(wxStyledTextCtrl_Cancel, 3236).
+-define(wxStyledTextCtrl_DeleteBack, 3237).
+-define(wxStyledTextCtrl_Tab, 3238).
+-define(wxStyledTextCtrl_BackTab, 3239).
+-define(wxStyledTextCtrl_NewLine, 3240).
+-define(wxStyledTextCtrl_FormFeed, 3241).
+-define(wxStyledTextCtrl_VCHome, 3242).
+-define(wxStyledTextCtrl_VCHomeExtend, 3243).
+-define(wxStyledTextCtrl_ZoomIn, 3244).
+-define(wxStyledTextCtrl_ZoomOut, 3245).
+-define(wxStyledTextCtrl_DelWordLeft, 3246).
+-define(wxStyledTextCtrl_DelWordRight, 3247).
+-define(wxStyledTextCtrl_LineCut, 3248).
+-define(wxStyledTextCtrl_LineDelete, 3249).
+-define(wxStyledTextCtrl_LineTranspose, 3250).
+-define(wxStyledTextCtrl_LineDuplicate, 3251).
+-define(wxStyledTextCtrl_LowerCase, 3252).
+-define(wxStyledTextCtrl_UpperCase, 3253).
+-define(wxStyledTextCtrl_LineScrollDown, 3254).
+-define(wxStyledTextCtrl_LineScrollUp, 3255).
+-define(wxStyledTextCtrl_DeleteBackNotLine, 3256).
+-define(wxStyledTextCtrl_HomeDisplay, 3257).
+-define(wxStyledTextCtrl_HomeDisplayExtend, 3258).
+-define(wxStyledTextCtrl_LineEndDisplay, 3259).
+-define(wxStyledTextCtrl_LineEndDisplayExtend, 3260).
+-define(wxStyledTextCtrl_HomeWrapExtend, 3261).
+-define(wxStyledTextCtrl_LineEndWrap, 3262).
+-define(wxStyledTextCtrl_LineEndWrapExtend, 3263).
+-define(wxStyledTextCtrl_VCHomeWrap, 3264).
+-define(wxStyledTextCtrl_VCHomeWrapExtend, 3265).
+-define(wxStyledTextCtrl_LineCopy, 3266).
+-define(wxStyledTextCtrl_MoveCaretInsideView, 3267).
+-define(wxStyledTextCtrl_LineLength, 3268).
+-define(wxStyledTextCtrl_BraceHighlight, 3269).
+-define(wxStyledTextCtrl_BraceBadLight, 3270).
+-define(wxStyledTextCtrl_BraceMatch, 3271).
+-define(wxStyledTextCtrl_GetViewEOL, 3272).
+-define(wxStyledTextCtrl_SetViewEOL, 3273).
+-define(wxStyledTextCtrl_SetModEventMask, 3274).
+-define(wxStyledTextCtrl_GetEdgeColumn, 3275).
+-define(wxStyledTextCtrl_SetEdgeColumn, 3276).
+-define(wxStyledTextCtrl_SetEdgeMode, 3277).
+-define(wxStyledTextCtrl_GetEdgeMode, 3278).
+-define(wxStyledTextCtrl_GetEdgeColour, 3279).
+-define(wxStyledTextCtrl_SetEdgeColour, 3280).
+-define(wxStyledTextCtrl_SearchAnchor, 3281).
+-define(wxStyledTextCtrl_SearchNext, 3282).
+-define(wxStyledTextCtrl_SearchPrev, 3283).
+-define(wxStyledTextCtrl_LinesOnScreen, 3284).
+-define(wxStyledTextCtrl_UsePopUp, 3285).
+-define(wxStyledTextCtrl_SelectionIsRectangle, 3286).
+-define(wxStyledTextCtrl_SetZoom, 3287).
+-define(wxStyledTextCtrl_GetZoom, 3288).
+-define(wxStyledTextCtrl_GetModEventMask, 3289).
+-define(wxStyledTextCtrl_SetSTCFocus, 3290).
+-define(wxStyledTextCtrl_GetSTCFocus, 3291).
+-define(wxStyledTextCtrl_SetStatus, 3292).
+-define(wxStyledTextCtrl_GetStatus, 3293).
+-define(wxStyledTextCtrl_SetMouseDownCaptures, 3294).
+-define(wxStyledTextCtrl_GetMouseDownCaptures, 3295).
+-define(wxStyledTextCtrl_SetSTCCursor, 3296).
+-define(wxStyledTextCtrl_GetSTCCursor, 3297).
+-define(wxStyledTextCtrl_SetControlCharSymbol, 3298).
+-define(wxStyledTextCtrl_GetControlCharSymbol, 3299).
+-define(wxStyledTextCtrl_WordPartLeft, 3300).
+-define(wxStyledTextCtrl_WordPartLeftExtend, 3301).
+-define(wxStyledTextCtrl_WordPartRight, 3302).
+-define(wxStyledTextCtrl_WordPartRightExtend, 3303).
+-define(wxStyledTextCtrl_SetVisiblePolicy, 3304).
+-define(wxStyledTextCtrl_DelLineLeft, 3305).
+-define(wxStyledTextCtrl_DelLineRight, 3306).
+-define(wxStyledTextCtrl_GetXOffset, 3307).
+-define(wxStyledTextCtrl_ChooseCaretX, 3308).
+-define(wxStyledTextCtrl_SetXCaretPolicy, 3309).
+-define(wxStyledTextCtrl_SetYCaretPolicy, 3310).
+-define(wxStyledTextCtrl_GetPrintWrapMode, 3311).
+-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3312).
+-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3313).
+-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3314).
+-define(wxStyledTextCtrl_SetHotspotSingleLine, 3315).
+-define(wxStyledTextCtrl_ParaDownExtend, 3316).
+-define(wxStyledTextCtrl_ParaUp, 3317).
+-define(wxStyledTextCtrl_ParaUpExtend, 3318).
+-define(wxStyledTextCtrl_PositionBefore, 3319).
+-define(wxStyledTextCtrl_PositionAfter, 3320).
+-define(wxStyledTextCtrl_CopyRange, 3321).
+-define(wxStyledTextCtrl_CopyText, 3322).
+-define(wxStyledTextCtrl_SetSelectionMode, 3323).
+-define(wxStyledTextCtrl_GetSelectionMode, 3324).
+-define(wxStyledTextCtrl_LineDownRectExtend, 3325).
+-define(wxStyledTextCtrl_LineUpRectExtend, 3326).
+-define(wxStyledTextCtrl_CharLeftRectExtend, 3327).
+-define(wxStyledTextCtrl_CharRightRectExtend, 3328).
+-define(wxStyledTextCtrl_HomeRectExtend, 3329).
+-define(wxStyledTextCtrl_VCHomeRectExtend, 3330).
+-define(wxStyledTextCtrl_LineEndRectExtend, 3331).
+-define(wxStyledTextCtrl_PageUpRectExtend, 3332).
+-define(wxStyledTextCtrl_PageDownRectExtend, 3333).
+-define(wxStyledTextCtrl_StutteredPageUp, 3334).
+-define(wxStyledTextCtrl_StutteredPageUpExtend, 3335).
+-define(wxStyledTextCtrl_StutteredPageDown, 3336).
+-define(wxStyledTextCtrl_StutteredPageDownExtend, 3337).
+-define(wxStyledTextCtrl_WordLeftEnd, 3338).
+-define(wxStyledTextCtrl_WordLeftEndExtend, 3339).
+-define(wxStyledTextCtrl_WordRightEnd, 3340).
+-define(wxStyledTextCtrl_WordRightEndExtend, 3341).
+-define(wxStyledTextCtrl_SetWhitespaceChars, 3342).
+-define(wxStyledTextCtrl_SetCharsDefault, 3343).
+-define(wxStyledTextCtrl_AutoCompGetCurrent, 3344).
+-define(wxStyledTextCtrl_Allocate, 3345).
+-define(wxStyledTextCtrl_FindColumn, 3346).
+-define(wxStyledTextCtrl_GetCaretSticky, 3347).
+-define(wxStyledTextCtrl_SetCaretSticky, 3348).
+-define(wxStyledTextCtrl_ToggleCaretSticky, 3349).
+-define(wxStyledTextCtrl_SetPasteConvertEndings, 3350).
+-define(wxStyledTextCtrl_GetPasteConvertEndings, 3351).
+-define(wxStyledTextCtrl_SelectionDuplicate, 3352).
+-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3353).
+-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3354).
+-define(wxStyledTextCtrl_StartRecord, 3355).
+-define(wxStyledTextCtrl_StopRecord, 3356).
+-define(wxStyledTextCtrl_SetLexer, 3357).
+-define(wxStyledTextCtrl_GetLexer, 3358).
+-define(wxStyledTextCtrl_Colourise, 3359).
+-define(wxStyledTextCtrl_SetProperty, 3360).
+-define(wxStyledTextCtrl_SetKeyWords, 3361).
+-define(wxStyledTextCtrl_SetLexerLanguage, 3362).
+-define(wxStyledTextCtrl_GetProperty, 3363).
+-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3364).
+-define(wxStyledTextCtrl_GetCurrentLine, 3365).
+-define(wxStyledTextCtrl_StyleSetSpec, 3366).
+-define(wxStyledTextCtrl_StyleSetFont, 3367).
+-define(wxStyledTextCtrl_StyleSetFontAttr, 3368).
+-define(wxStyledTextCtrl_StyleSetCharacterSet, 3369).
+-define(wxStyledTextCtrl_StyleSetFontEncoding, 3370).
+-define(wxStyledTextCtrl_CmdKeyExecute, 3371).
+-define(wxStyledTextCtrl_SetMargins, 3372).
+-define(wxStyledTextCtrl_GetSelection, 3373).
+-define(wxStyledTextCtrl_PointFromPosition, 3374).
+-define(wxStyledTextCtrl_ScrollToLine, 3375).
+-define(wxStyledTextCtrl_ScrollToColumn, 3376).
+-define(wxStyledTextCtrl_SetVScrollBar, 3377).
+-define(wxStyledTextCtrl_SetHScrollBar, 3378).
+-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3379).
+-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3380).
+-define(wxStyledTextCtrl_SaveFile, 3381).
+-define(wxStyledTextCtrl_LoadFile, 3382).
+-define(wxStyledTextCtrl_DoDragOver, 3383).
+-define(wxStyledTextCtrl_DoDropText, 3384).
+-define(wxStyledTextCtrl_GetUseAntiAliasing, 3385).
+-define(wxStyledTextCtrl_AddTextRaw, 3386).
+-define(wxStyledTextCtrl_InsertTextRaw, 3387).
+-define(wxStyledTextCtrl_GetCurLineRaw, 3388).
+-define(wxStyledTextCtrl_GetLineRaw, 3389).
+-define(wxStyledTextCtrl_GetSelectedTextRaw, 3390).
+-define(wxStyledTextCtrl_GetTextRangeRaw, 3391).
+-define(wxStyledTextCtrl_SetTextRaw, 3392).
+-define(wxStyledTextCtrl_GetTextRaw, 3393).
+-define(wxStyledTextCtrl_AppendTextRaw, 3394).
+-define(wxArtProvider_GetBitmap, 3395).
+-define(wxArtProvider_GetIcon, 3396).
+-define(wxTreeEvent_GetKeyCode, 3397).
+-define(wxTreeEvent_GetItem, 3398).
+-define(wxTreeEvent_GetKeyEvent, 3399).
+-define(wxTreeEvent_GetLabel, 3400).
+-define(wxTreeEvent_GetOldItem, 3401).
+-define(wxTreeEvent_GetPoint, 3402).
+-define(wxTreeEvent_IsEditCancelled, 3403).
+-define(wxTreeEvent_SetToolTip, 3404).
+-define(wxNotebookEvent_GetOldSelection, 3405).
+-define(wxNotebookEvent_GetSelection, 3406).
+-define(wxNotebookEvent_SetOldSelection, 3407).
+-define(wxNotebookEvent_SetSelection, 3408).
+-define(wxFileDataObject_new, 3409).
+-define(wxFileDataObject_AddFile, 3410).
+-define(wxFileDataObject_GetFilenames, 3411).
+-define(wxFileDataObject_destroy, 3412).
+-define(wxTextDataObject_new, 3413).
+-define(wxTextDataObject_GetTextLength, 3414).
+-define(wxTextDataObject_GetText, 3415).
+-define(wxTextDataObject_SetText, 3416).
+-define(wxTextDataObject_destroy, 3417).
+-define(wxBitmapDataObject_new_1_1, 3418).
+-define(wxBitmapDataObject_new_1_0, 3419).
+-define(wxBitmapDataObject_GetBitmap, 3420).
+-define(wxBitmapDataObject_SetBitmap, 3421).
+-define(wxBitmapDataObject_destroy, 3422).
+-define(wxClipboard_new, 3424).
+-define(wxClipboard_destruct, 3425).
+-define(wxClipboard_AddData, 3426).
+-define(wxClipboard_Clear, 3427).
+-define(wxClipboard_Close, 3428).
+-define(wxClipboard_Flush, 3429).
+-define(wxClipboard_GetData, 3430).
+-define(wxClipboard_IsOpened, 3431).
+-define(wxClipboard_Open, 3432).
+-define(wxClipboard_SetData, 3433).
+-define(wxClipboard_UsePrimarySelection, 3435).
+-define(wxClipboard_IsSupported, 3436).
+-define(wxClipboard_Get, 3437).
+-define(wxSpinEvent_GetPosition, 3438).
+-define(wxSpinEvent_SetPosition, 3439).
+-define(wxSplitterWindow_new_0, 3440).
+-define(wxSplitterWindow_new_2, 3441).
+-define(wxSplitterWindow_destruct, 3442).
+-define(wxSplitterWindow_Create, 3443).
+-define(wxSplitterWindow_GetMinimumPaneSize, 3444).
+-define(wxSplitterWindow_GetSashGravity, 3445).
+-define(wxSplitterWindow_GetSashPosition, 3446).
+-define(wxSplitterWindow_GetSplitMode, 3447).
+-define(wxSplitterWindow_GetWindow1, 3448).
+-define(wxSplitterWindow_GetWindow2, 3449).
+-define(wxSplitterWindow_Initialize, 3450).
+-define(wxSplitterWindow_IsSplit, 3451).
+-define(wxSplitterWindow_ReplaceWindow, 3452).
+-define(wxSplitterWindow_SetSashGravity, 3453).
+-define(wxSplitterWindow_SetSashPosition, 3454).
+-define(wxSplitterWindow_SetSashSize, 3455).
+-define(wxSplitterWindow_SetMinimumPaneSize, 3456).
+-define(wxSplitterWindow_SetSplitMode, 3457).
+-define(wxSplitterWindow_SplitHorizontally, 3458).
+-define(wxSplitterWindow_SplitVertically, 3459).
+-define(wxSplitterWindow_Unsplit, 3460).
+-define(wxSplitterWindow_UpdateSize, 3461).
+-define(wxSplitterEvent_GetSashPosition, 3462).
+-define(wxSplitterEvent_GetX, 3463).
+-define(wxSplitterEvent_GetY, 3464).
+-define(wxSplitterEvent_GetWindowBeingRemoved, 3465).
+-define(wxSplitterEvent_SetSashPosition, 3466).
+-define(wxHtmlWindow_new_0, 3467).
+-define(wxHtmlWindow_new_2, 3468).
+-define(wxHtmlWindow_AppendToPage, 3469).
+-define(wxHtmlWindow_GetOpenedAnchor, 3470).
+-define(wxHtmlWindow_GetOpenedPage, 3471).
+-define(wxHtmlWindow_GetOpenedPageTitle, 3472).
+-define(wxHtmlWindow_GetRelatedFrame, 3473).
+-define(wxHtmlWindow_HistoryBack, 3474).
+-define(wxHtmlWindow_HistoryCanBack, 3475).
+-define(wxHtmlWindow_HistoryCanForward, 3476).
+-define(wxHtmlWindow_HistoryClear, 3477).
+-define(wxHtmlWindow_HistoryForward, 3478).
+-define(wxHtmlWindow_LoadFile, 3479).
+-define(wxHtmlWindow_LoadPage, 3480).
+-define(wxHtmlWindow_SelectAll, 3481).
+-define(wxHtmlWindow_SelectionToText, 3482).
+-define(wxHtmlWindow_SelectLine, 3483).
+-define(wxHtmlWindow_SelectWord, 3484).
+-define(wxHtmlWindow_SetBorders, 3485).
+-define(wxHtmlWindow_SetFonts, 3486).
+-define(wxHtmlWindow_SetPage, 3487).
+-define(wxHtmlWindow_SetRelatedFrame, 3488).
+-define(wxHtmlWindow_SetRelatedStatusBar, 3489).
+-define(wxHtmlWindow_ToText, 3490).
+-define(wxHtmlWindow_destroy, 3491).
+-define(wxHtmlLinkEvent_GetLinkInfo, 3492).
+-define(wxSystemSettings_GetColour, 3493).
+-define(wxSystemSettings_GetFont, 3494).
+-define(wxSystemSettings_GetMetric, 3495).
+-define(wxSystemSettings_GetScreenType, 3496).
+-define(wxSystemOptions_GetOption, 3497).
+-define(wxSystemOptions_GetOptionInt, 3498).
+-define(wxSystemOptions_HasOption, 3499).
+-define(wxSystemOptions_IsFalse, 3500).
+-define(wxSystemOptions_SetOption_2_1, 3501).
+-define(wxSystemOptions_SetOption_2_0, 3502).
+-define(wxAuiNotebookEvent_SetSelection, 3503).
+-define(wxAuiNotebookEvent_GetSelection, 3504).
+-define(wxAuiNotebookEvent_SetOldSelection, 3505).
+-define(wxAuiNotebookEvent_GetOldSelection, 3506).
+-define(wxAuiNotebookEvent_SetDragSource, 3507).
+-define(wxAuiNotebookEvent_GetDragSource, 3508).
+-define(wxAuiManagerEvent_SetManager, 3509).
+-define(wxAuiManagerEvent_GetManager, 3510).
+-define(wxAuiManagerEvent_SetPane, 3511).
+-define(wxAuiManagerEvent_GetPane, 3512).
+-define(wxAuiManagerEvent_SetButton, 3513).
+-define(wxAuiManagerEvent_GetButton, 3514).
+-define(wxAuiManagerEvent_SetDC, 3515).
+-define(wxAuiManagerEvent_GetDC, 3516).
+-define(wxAuiManagerEvent_Veto, 3517).
+-define(wxAuiManagerEvent_GetVeto, 3518).
+-define(wxAuiManagerEvent_SetCanVeto, 3519).
+-define(wxAuiManagerEvent_CanVeto, 3520).
+-define(wxLogNull_new, 3521).
+-define(wxLogNull_destroy, 3522).
+-define(wxTaskBarIcon_new, 3523).
+-define(wxTaskBarIcon_destruct, 3524).
+-define(wxTaskBarIcon_PopupMenu, 3525).
+-define(wxTaskBarIcon_RemoveIcon, 3526).
+-define(wxTaskBarIcon_SetIcon, 3527).
+-define(wxLocale_new_0, 3528).
+-define(wxLocale_new_2, 3530).
+-define(wxLocale_destruct, 3531).
+-define(wxLocale_Init, 3533).
+-define(wxLocale_AddCatalog_1, 3534).
+-define(wxLocale_AddCatalog_3, 3535).
+-define(wxLocale_AddCatalogLookupPathPrefix, 3536).
+-define(wxLocale_GetCanonicalName, 3537).
+-define(wxLocale_GetLanguage, 3538).
+-define(wxLocale_GetLanguageName, 3539).
+-define(wxLocale_GetLocale, 3540).
+-define(wxLocale_GetName, 3541).
+-define(wxLocale_GetString_2, 3542).
+-define(wxLocale_GetString_4, 3543).
+-define(wxLocale_GetHeaderValue, 3544).
+-define(wxLocale_GetSysName, 3545).
+-define(wxLocale_GetSystemEncoding, 3546).
+-define(wxLocale_GetSystemEncodingName, 3547).
+-define(wxLocale_GetSystemLanguage, 3548).
+-define(wxLocale_IsLoaded, 3549).
+-define(wxLocale_IsOk, 3550).
+-define(wxActivateEvent_GetActive, 3551).
+-define(wxPopupWindow_new_2, 3553).
+-define(wxPopupWindow_new_0, 3554).
+-define(wxPopupWindow_destruct, 3556).
+-define(wxPopupWindow_Create, 3557).
+-define(wxPopupWindow_Position, 3558).
+-define(wxPopupTransientWindow_new_0, 3559).
+-define(wxPopupTransientWindow_new_2, 3560).
+-define(wxPopupTransientWindow_destruct, 3561).
+-define(wxPopupTransientWindow_Popup, 3562).
+-define(wxPopupTransientWindow_Dismiss, 3563).
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index b375c9d515..b127e6b71d 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -50,7 +50,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[calendarCtrl, treeCtrl, notebook, staticBoxSizer,
clipboard, helpFrame, htmlWindow, listCtrlSort, listCtrlVirtual,
- radioBox, systemSettings, taskBarIcon, toolbar].
+ radioBox, systemSettings, taskBarIcon, toolbar, popup].
groups() ->
[].
@@ -511,3 +511,50 @@ toolbar(Config) ->
wxFrame:connect(Frame, command_menu_selected, [{callback, Add}, {id, 747}]),
wxFrame:show(Frame),
wx_test_lib:wx_destroy(Frame,Config).
+
+
+popup(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+popup(Config) ->
+ Wx = wx:new(),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+ TB = wxFrame:createToolBar(Frame),
+ wxToolBar:addTool(TB, 747, "PressMe", wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}]),
+ [{shortHelp, "Press Me"}]),
+
+ Log = fun(#wx{id=Id, event=Ev}, Obj) ->
+ io:format("Got ~p from ~p~n", [Id, Ev]),
+ wxEvent:skip(Obj)
+ end,
+ CreatePopup = fun() ->
+ Pop = wxPopupTransientWindow:new(Frame),
+ Panel = wxPanel:new(Pop),
+ Sz = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sz, wxButton:new(Panel, 42, [{label, "A button"}])),
+ wxSizer:add(Sz, Txt = wxStaticText:new(Panel, 43, "Some static text")),
+ wxSizer:add(Sz, wxButton:new(Panel, 44, [{label, "B button"}])),
+ wxPanel:setSizerAndFit(Panel, Sz),
+ wxSizer:setSizeHints(Sz, Pop),
+ wxWindow:connect(Pop, command_button_clicked, [{callback, Log}]),
+ wxWindow:connect(Txt, left_up, [{callback, Log}]),
+ wxWindow:connect(Txt, middle_up, [{callback, Log}]),
+ wxWindow:connect(Txt, right_up, [{callback, Log}]),
+ wxWindow:connect(Pop, show, [{callback, Log}]),
+ Pos = wx_misc:getMousePosition(),
+ wxPopupTransientWindow:position(Pop, Pos, {-1, -1}),
+ wxPopupTransientWindow:popup(Pop),
+ Pop
+ end,
+ wxFrame:connect(Frame, command_menu_selected, [{id, 747}]),
+ wxFrame:show(Frame),
+
+ Pop = CreatePopup(),
+ Scale = case wx_test_lib:user_available(Config) of
+ true -> 25;
+ false -> 1
+ end,
+ receive
+ #wx{} -> CreatePopup()
+ after 200*Scale ->
+ wxPopupTransientWindow:dismiss(Pop)
+ end,
+ wx_test_lib:wx_destroy(Frame,Config).
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index 5523c20440..ee3d247553 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 1.2
+WX_VSN = 1.3
diff --git a/lib/xmerl/doc/src/motorcycles2html.erl b/lib/xmerl/doc/src/motorcycles2html.erl
index dfbd19e359..45c713e1ac 100644
--- a/lib/xmerl/doc/src/motorcycles2html.erl
+++ b/lib/xmerl/doc/src/motorcycles2html.erl
@@ -7,7 +7,7 @@
%%%-------------------------------------------------------------------
-module(motorcycles2html).
--include("xmerl.hrl").
+-include_lib("xmerl/include/xmerl.hrl").
-import(xmerl_xs,
[ xslapply/2, value_of/1, select/2, built_in_rules/2 ]).
@@ -57,12 +57,12 @@ template(E) -> built_in_rules(fun template/1, E).
%% sorts on the bike name element, unwraps the bike information and
%% inserts a line feed and indentation on each bike element.
sort_by_manufacturer(L) ->
- Tuples=[X1||X1={H,T} <- L],
+ Tuples=[X1||X1={_,_} <- L],
SortedTS = lists:keysort(1,Tuples),
InsertRefName_UnWrap=
fun([{[Name],V}|Rest],Name,F)->
[V|F(Rest,Name,F)];
- ([{[Name],V}|Rest],PreviousName,F) ->
+ ([{[Name],V}|Rest],_PreviousName,F) ->
[["<a name=\"",Name,"\"></>"],V|F(Rest,Name,F)];
([],_,_) -> []
end,
@@ -71,7 +71,7 @@ sort_by_manufacturer(L) ->
WS = "\n ",
Fun=fun([H|T],Acc,F)->
F(T,[H,WS|Acc],F);
- ([],Acc,F)->
+ ([],Acc,_F)->
lists:reverse([WS|Acc])
end,
if length(SortedRefed) > 0 ->
@@ -96,13 +96,12 @@ remove_duplicates([A|L],Acc) ->
end.
make_ref([]) -> [];
-make_ref([H]) when atom(H) ->
+make_ref([H]) when is_atom(H) ->
"<ul><a href=\"#"++atom_to_list(H)++"\">"++atom_to_list(H)++"</a></ul>";
-make_ref([H]) when list(H) ->
+make_ref([H]) when is_list(H) ->
"<ul><a href=\"#"++H++"\">\s"++H++"</a></ul>";
-make_ref([H|T]) when atom(H) ->
+make_ref([H|T]) when is_atom(H) ->
["<ul><a href=\"#"++atom_to_list(H)++"\">\s"++atom_to_list(H)++",\n</a></ul>"
|make_ref(T)];
-make_ref([H|T]) when list(H) ->
+make_ref([H|T]) when is_list(H) ->
["<ul><a href=\"#"++H++"\">\s"++H++",\n</a></ul>"|make_ref(T)].
-
diff --git a/otp_versions.table b/otp_versions.table
index 1120add531..3356f2951e 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,3 +1,7 @@
+OTP-17.2 : orber-3.7 snmp-5.0 # asn1-3.0.1 common_test-1.8.1 compiler-5.0.1 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4 debugger-4.0.1 dialyzer-2.7.1 diameter-1.7 edoc-0.7.14 eldap-1.0.3 erl_docgen-0.3.5 erl_interface-3.7.17 erts-6.1.2 et-1.5 eunit-2.2.7 gs-1.5.16 hipe-3.11 ic-4.3.5 inets-5.10.2 jinterface-1.5.9 kernel-3.0.2 megaco-3.17.1 mnesia-4.12.1 observer-2.0.1 odbc-2.10.20 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4 ssh-3.0.3 ssl-5.3.5 stdlib-2.1.1 syntax_tools-1.6.16 test_server-3.7.1 tools-2.6.15 typer-0.9.8 webtool-0.8.10 wx-1.3 xmerl-1.3.7 :
+OTP-17.1.2 : erts-6.1.2 kernel-3.0.2 stdlib-2.1.1 # asn1-3.0.1 common_test-1.8.1 compiler-5.0.1 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4 debugger-4.0.1 dialyzer-2.7.1 diameter-1.7 edoc-0.7.14 eldap-1.0.3 erl_docgen-0.3.5 erl_interface-3.7.17 et-1.5 eunit-2.2.7 gs-1.5.16 hipe-3.11 ic-4.3.5 inets-5.10.2 jinterface-1.5.9 megaco-3.17.1 mnesia-4.12.1 observer-2.0.1 odbc-2.10.20 orber-3.6.27 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4 snmp-4.25.1 ssh-3.0.3 ssl-5.3.5 syntax_tools-1.6.16 test_server-3.7.1 tools-2.6.15 typer-0.9.8 webtool-0.8.10 wx-1.3 xmerl-1.3.7 :
+OTP-17.1.1 : edoc-0.7.14 erts-6.1.1 syntax_tools-1.6.16 # asn1-3.0.1 common_test-1.8.1 compiler-5.0.1 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4 debugger-4.0.1 dialyzer-2.7.1 diameter-1.7 eldap-1.0.3 erl_docgen-0.3.5 erl_interface-3.7.17 et-1.5 eunit-2.2.7 gs-1.5.16 hipe-3.11 ic-4.3.5 inets-5.10.2 jinterface-1.5.9 kernel-3.0.1 megaco-3.17.1 mnesia-4.12.1 observer-2.0.1 odbc-2.10.20 orber-3.6.27 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4 snmp-4.25.1 ssh-3.0.3 ssl-5.3.5 stdlib-2.1 test_server-3.7.1 tools-2.6.15 typer-0.9.8 webtool-0.8.10 wx-1.3 xmerl-1.3.7 :
+OTP-17.1 : asn1-3.0.1 common_test-1.8.1 compiler-5.0.1 crypto-3.4 debugger-4.0.1 dialyzer-2.7.1 diameter-1.7 erl_interface-3.7.17 erts-6.1 hipe-3.11 inets-5.10.2 kernel-3.0.1 mnesia-4.12.1 observer-2.0.1 reltool-0.6.6 ssh-3.0.3 ssl-5.3.5 stdlib-2.1 syntax_tools-1.6.15 test_server-3.7.1 tools-2.6.15 typer-0.9.8 wx-1.3 # cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 edoc-0.7.13 eldap-1.0.3 erl_docgen-0.3.5 et-1.5 eunit-2.2.7 gs-1.5.16 ic-4.3.5 jinterface-1.5.9 megaco-3.17.1 odbc-2.10.20 orber-3.6.27 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 runtime_tools-1.8.14 sasl-2.4 snmp-4.25.1 webtool-0.8.10 xmerl-1.3.7 :
OTP-17.0.2 : inets-5.10.1 ssh-3.0.2 # asn1-3.0 common_test-1.8 compiler-5.0 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.3 debugger-4.0 dialyzer-2.7 diameter-1.6 edoc-0.7.13 eldap-1.0.3 erl_docgen-0.3.5 erl_interface-3.7.16 erts-6.0.1 et-1.5 eunit-2.2.7 gs-1.5.16 hipe-3.10.3 ic-4.3.5 jinterface-1.5.9 kernel-3.0 megaco-3.17.1 mnesia-4.12 observer-2.0 odbc-2.10.20 orber-3.6.27 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 reltool-0.6.5 runtime_tools-1.8.14 sasl-2.4 snmp-4.25.1 ssl-5.3.4 stdlib-2.0 syntax_tools-1.6.14 test_server-3.7 tools-2.6.14 typer-0.9.7 webtool-0.8.10 wx-1.2 xmerl-1.3.7 :
OTP-17.0.1 : erts-6.0.1 typer-0.9.7 # asn1-3.0 common_test-1.8 compiler-5.0 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.3 debugger-4.0 dialyzer-2.7 diameter-1.6 edoc-0.7.13 eldap-1.0.3 erl_docgen-0.3.5 erl_interface-3.7.16 et-1.5 eunit-2.2.7 gs-1.5.16 hipe-3.10.3 ic-4.3.5 inets-5.10 jinterface-1.5.9 kernel-3.0 megaco-3.17.1 mnesia-4.12 observer-2.0 odbc-2.10.20 orber-3.6.27 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 reltool-0.6.5 runtime_tools-1.8.14 sasl-2.4 snmp-4.25.1 ssh-3.0.1 ssl-5.3.4 stdlib-2.0 syntax_tools-1.6.14 test_server-3.7 tools-2.6.14 webtool-0.8.10 wx-1.2 xmerl-1.3.7 :
OTP-17.0 : asn1-3.0 common_test-1.8 compiler-5.0 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.3 debugger-4.0 dialyzer-2.7 diameter-1.6 edoc-0.7.13 eldap-1.0.3 erl_docgen-0.3.5 erl_interface-3.7.16 erts-6.0 et-1.5 eunit-2.2.7 gs-1.5.16 hipe-3.10.3 ic-4.3.5 inets-5.10 jinterface-1.5.9 kernel-3.0 megaco-3.17.1 mnesia-4.12 observer-2.0 odbc-2.10.20 orber-3.6.27 os_mon-2.2.15 ose-1.0 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22 reltool-0.6.5 runtime_tools-1.8.14 sasl-2.4 snmp-4.25.1 ssh-3.0.1 ssl-5.3.4 stdlib-2.0 syntax_tools-1.6.14 test_server-3.7 tools-2.6.14 typer-0.9.6 webtool-0.8.10 wx-1.2 xmerl-1.3.7 # :
diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml
index b5771a5929..51f1b2612c 100644
--- a/system/doc/efficiency_guide/advanced.xml
+++ b/system/doc/efficiency_guide/advanced.xml
@@ -183,7 +183,7 @@ On 64-bit architectures: 4 words for a reference from the current local node, an
<tag><em>Open ports</em></tag>
<item>
<marker id="ports"></marker>
- <p>The maximum number of simultaneously oper Erlang ports is
+ <p>The maximum number of simultaneously open Erlang ports is
often by default 16384. This limit can be configured at startup,
for more information see the
<seealso marker="erts:erl#max_ports"><c>+Q</c></seealso>
diff --git a/system/doc/reference_manual/data_types.xml b/system/doc/reference_manual/data_types.xml
index 0031664dfb..37c0db5ff7 100644
--- a/system/doc/reference_manual/data_types.xml
+++ b/system/doc/reference_manual/data_types.xml
@@ -215,7 +215,7 @@ adam
0</pre>
<p>A collection of maps processing functions can be found in
the STDLIB module <seealso marker="stdlib:maps"><c>maps</c></seealso>.</p>
- <p>Read more about <seealso marker="maps">Maps</seealso>.</p>
+ <p>Read more about <seealso marker="expressions#map_expressions">Maps</seealso>.</p>
<note>
<p>Maps are considered experimental during OTP 17.</p>
</note>
diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml
index 0ca425da86..fa8f9b2e8f 100644
--- a/system/doc/reference_manual/expressions.xml
+++ b/system/doc/reference_manual/expressions.xml
@@ -792,6 +792,7 @@ Expr1 -- Expr2</pre>
</section>
<section>
+ <marker id="map_expressions"></marker>
<title>Map Expressions</title>
<section>
<title>Creating Maps</title>
diff --git a/system/doc/reference_manual/processes.xml b/system/doc/reference_manual/processes.xml
index 20bab1eb48..95ae0672ec 100644
--- a/system/doc/reference_manual/processes.xml
+++ b/system/doc/reference_manual/processes.xml
@@ -114,8 +114,8 @@ spawn(Module, Name, Args) -> pid()
<p>Two processes can be <em>linked</em> to each other. A link
between two processes <c>Pid1</c> and <c>Pid2</c> is created
by <c>Pid1</c> calling the BIF <c>link(Pid2)</c> (or vice versa).
- There also exists a number a <c>spawn_link</c> BIFs, which spawns
- and links to a process in one operation.</p>
+ There also exist a number of <c>spawn_link</c> BIFs, which spawn
+ and link to a process in one operation.</p>
<p>Links are bidirectional and there can only be one link between
two processes. Repeated calls to <c>link(Pid)</c> have no effect.</p>
<p>A link can be removed by calling the BIF <c>unlink(Pid)</c>.</p>
diff --git a/system/doc/system_principles/versions.xml b/system/doc/system_principles/versions.xml
index c63913d867..ff042f4a3b 100644
--- a/system/doc/system_principles/versions.xml
+++ b/system/doc/system_principles/versions.xml
@@ -67,7 +67,7 @@
suffix corresponds to the OTP version of the base system that
has been patched. Note that if a development system is updated by
other means than <c>otp_patch_apply</c>, the <c>OTP_VERSION</c> file
- may identify wrong OTP version.</p>
+ may identify an incorrect OTP version.</p>
<p>No <c>OTP_VERSION</c> file will be placed in a
<seealso marker="create_target">target system</seealso> created