aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asn1/c_src/asn1_erl_nif.c43
-rw-r--r--lib/asn1/doc/src/asn1_ug.xml2
-rw-r--r--lib/asn1/doc/src/notes.xml73
-rw-r--r--lib/asn1/src/Makefile1
-rw-r--r--lib/asn1/src/asn1_records.hrl12
-rw-r--r--lib/asn1/src/asn1ct.erl19
-rw-r--r--lib/asn1/src/asn1ct_check.erl394
-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/asn1ct_parser2.erl23
-rw-r--r--lib/asn1/src/asn1ct_tok.erl2
-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.erl56
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constraints.py7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constructed.asn6
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn14
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Default.asn23
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfObj.asn45
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ParamBasic.asn122
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Set.py4
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TAGDEFAULT-AUTOMATIC.asn25
-rw-r--r--lib/asn1/test/asn1_app_test.erl4
-rw-r--r--lib/asn1/test/asn1_test_lib.erl106
-rw-r--r--lib/asn1/test/ber_decode_error.erl18
-rw-r--r--lib/asn1/test/error_SUITE.erl17
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl14
-rw-r--r--lib/asn1/test/testInfObj.erl36
-rw-r--r--lib/asn1/test/testNBAPsystem.erl15
-rw-r--r--lib/asn1/test/testParamBasic.erl3
-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/Makefile1
-rw-r--r--lib/common_test/doc/src/cover_chapter.xml25
-rw-r--r--lib/common_test/doc/src/notes.xml201
-rw-r--r--lib/common_test/doc/src/ref_man.xml1
-rwxr-xr-xlib/common_test/priv/auxdir/config.guess1534
-rwxr-xr-xlib/common_test/priv/auxdir/config.sub1789
-rwxr-xr-xlib/common_test/priv/auxdir/install-sh519
-rw-r--r--[-rwxr-xr-x]lib/common_test/priv/run_test.in0
-rw-r--r--lib/common_test/src/Makefile3
-rw-r--r--lib/common_test/src/common_test.app.src4
-rw-r--r--lib/common_test/src/ct_cover.erl175
-rw-r--r--lib/common_test/src/ct_framework.erl33
-rw-r--r--lib/common_test/src/ct_logs.erl116
-rw-r--r--lib/common_test/src/ct_netconfc.erl4
-rw-r--r--lib/common_test/src/ct_property_test.erl186
-rw-r--r--lib/common_test/src/ct_run.erl215
-rw-r--r--lib/common_test/src/ct_telnet.erl136
-rw-r--r--lib/common_test/src/ct_telnet_client.erl54
-rw-r--r--lib/common_test/src/unix_telnet.erl4
-rw-r--r--lib/common_test/test/Makefile3
-rw-r--r--lib/common_test/test/ct_cover_SUITE.erl107
-rw-r--r--lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl4
-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/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl12
-rw-r--r--lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl85
-rw-r--r--lib/common_test/test/ct_test_support.erl1
-rw-r--r--lib/common_test/test/telnet_server.erl48
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/notes.xml76
-rw-r--r--lib/compiler/src/beam_bool.erl75
-rw-r--r--lib/compiler/src/core_lib.erl9
-rw-r--r--lib/compiler/src/sys_core_fold.erl213
-rw-r--r--lib/compiler/src/v3_core.erl112
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl24
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl16
-rw-r--r--lib/compiler/test/fun_SUITE.erl19
-rw-r--r--lib/compiler/test/guard_SUITE.erl18
-rw-r--r--lib/compiler/test/match_SUITE.erl23
-rw-r--r--lib/compiler/test/warnings_SUITE.erl14
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/crypto/c_src/crypto.c43
-rw-r--r--lib/crypto/c_src/crypto_callback.c2
-rw-r--r--lib/crypto/doc/src/crypto.xml2
-rw-r--r--lib/crypto/doc/src/notes.xml78
-rw-r--r--lib/crypto/test/crypto_SUITE.erl28
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/i.xml2
-rw-r--r--lib/debugger/doc/src/int.xml2
-rw-r--r--lib/debugger/doc/src/notes.xml41
-rw-r--r--lib/debugger/src/Makefile2
-rw-r--r--lib/debugger/src/dbg_icmd.erl6
-rw-r--r--lib/debugger/src/dbg_ieval.erl12
-rw-r--r--lib/debugger/src/dbg_wx_mon.erl2
-rw-r--r--lib/debugger/src/dbg_wx_settings.erl10
-rw-r--r--lib/debugger/src/i.erl4
-rw-r--r--lib/debugger/src/int.erl5
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/doc/src/dialyzer.xml12
-rw-r--r--lib/dialyzer/doc/src/notes.xml112
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl11
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl268
-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.erl44
-rw-r--r--lib/dialyzer/test/dialyzer_SUITE.erl39
-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/opaque/opaque_bug5.erl10
-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/record_update2
-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/limit.erl20
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/literals.erl33
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/maps1.erl36
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl23
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/pretty_bitstring.erl8
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/record_update.erl10
-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/test/underspecs_SUITE_data/results/arr4
-rw-r--r--lib/dialyzer/test/underspecs_SUITE_data/src/arr.erl41
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/diameter/doc/src/diameter.xml12
-rw-r--r--lib/diameter/doc/src/notes.xml250
-rw-r--r--lib/diameter/examples/code/peer.erl2
-rw-r--r--lib/diameter/include/diameter_gen.hrl88
-rw-r--r--lib/diameter/src/base/diameter_codec.erl30
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl13
-rw-r--r--lib/diameter/src/base/diameter_service.erl130
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl118
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl36
-rw-r--r--lib/diameter/src/compiler/diameter_codegen.erl33
-rw-r--r--lib/diameter/src/diameter.appup.src34
-rw-r--r--lib/diameter/src/info/diameter_dbg.erl38
-rw-r--r--lib/diameter/test/diameter_config_SUITE.erl2
-rw-r--r--lib/diameter/test/diameter_event_SUITE.erl30
-rw-r--r--lib/diameter/test/diameter_transport_SUITE.erl2
-rw-r--r--lib/diameter/vsn.mk2
-rw-r--r--lib/edoc/doc/src/notes.xml51
-rw-r--r--lib/edoc/src/edoc.erl35
-rw-r--r--lib/edoc/src/edoc_layout.erl17
-rw-r--r--lib/edoc/src/edoc_types.erl2
-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/eldap/doc/src/eldap.xml36
-rw-r--r--lib/eldap/doc/src/notes.xml60
-rw-r--r--lib/eldap/src/eldap.erl96
-rw-r--r--lib/eldap/test/Makefile4
-rw-r--r--lib/eldap/test/README2
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl1122
-rw-r--r--lib/eldap/test/eldap_basic_SUITE_data/RANDbin0 -> 512 bytes
-rw-r--r--lib/eldap/test/eldap_misc_SUITE.erl51
-rw-r--r--lib/eldap/test/make_certs.erl357
-rw-r--r--lib/eldap/vsn.mk3
-rw-r--r--lib/erl_docgen/doc/src/notes.xml34
-rw-r--r--lib/erl_docgen/src/docgen_otp_specs.erl22
-rw-r--r--lib/erl_docgen/vsn.mk2
-rw-r--r--lib/erl_interface/aclocal.m41954
-rw-r--r--lib/erl_interface/configure.in20
-rw-r--r--lib/erl_interface/doc/src/notes.xml83
-rw-r--r--lib/erl_interface/ebin/.gitignore0
-rw-r--r--lib/erl_interface/src/Makefile.in38
-rwxr-xr-xlib/erl_interface/src/auxdir/config.guess1534
-rwxr-xr-xlib/erl_interface/src/auxdir/config.sub1789
-rwxr-xr-xlib/erl_interface/src/auxdir/install-sh519
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c2
-rw-r--r--lib/erl_interface/src/decode/decode_big.c22
-rw-r--r--lib/erl_interface/src/erl_interface.app.src32
-rw-r--r--lib/erl_interface/src/erl_interface.appup.src (renamed from lib/kernel/test/code_SUITE_data/calendar.erl)11
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c2
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/eunit/doc/src/notes.xml37
-rw-r--r--lib/eunit/src/Makefile5
-rw-r--r--lib/eunit/src/eunit_data.erl9
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/hipe/cerl/cerl_prettypr.erl17
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl20
-rw-r--r--lib/hipe/cerl/erl_types.erl99
-rw-r--r--lib/hipe/doc/src/notes.xml73
-rw-r--r--lib/hipe/llvm/elf_format.hrl2
-rw-r--r--lib/hipe/ppc/hipe_rtl_to_ppc.erl14
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl18
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_match.erl18
-rw-r--r--lib/hipe/sparc/hipe_rtl_to_sparc.erl10
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/hipe/x86/hipe_rtl_to_x86.erl15
-rw-r--r--lib/ic/c_src/oe_ei_encode_pid.c2
-rw-r--r--lib/ic/doc/src/notes.xml17
-rw-r--r--lib/ic/vsn.mk2
-rw-r--r--lib/inets/doc/src/http_uri.xml11
-rw-r--r--lib/inets/doc/src/httpc.xml4
-rw-r--r--lib/inets/doc/src/httpd.xml23
-rw-r--r--lib/inets/doc/src/httpd_conf.xml8
-rw-r--r--lib/inets/doc/src/notes.xml131
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_slave.erl2
-rw-r--r--lib/inets/src/ftp/ftp.erl77
-rw-r--r--lib/inets/src/http_client/httpc_cookie.erl20
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl6
-rw-r--r--lib/inets/src/http_lib/http_internal.hrl3
-rw-r--r--lib/inets/src/http_lib/http_request.erl26
-rw-r--r--lib/inets/src/http_lib/http_uri.erl35
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl28
-rw-r--r--lib/inets/src/http_server/httpd_request.erl102
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl39
-rw-r--r--lib/inets/src/http_server/mod_alias.erl14
-rw-r--r--lib/inets/src/inets_app/inets.appup.src11
-rw-r--r--lib/inets/test/ftp_property_test_SUITE.erl52
-rw-r--r--lib/inets/test/http_format_SUITE.erl16
-rw-r--r--lib/inets/test/httpc_SUITE.erl52
-rw-r--r--lib/inets/test/httpd_SUITE.erl226
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl2
-rw-r--r--lib/inets/test/httpd_test_lib.erl11
-rw-r--r--lib/inets/test/old_httpd_SUITE.erl31
-rw-r--r--lib/inets/test/property_test/README12
-rw-r--r--lib/inets/test/property_test/ftp_simple_client_server.erl306
-rw-r--r--lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf26
-rw-r--r--lib/inets/test/uri_SUITE.erl37
-rw-r--r--lib/inets/vsn.mk2
-rw-r--r--lib/jinterface/doc/src/notes.xml84
-rw-r--r--lib/jinterface/ebin/.gitignore0
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java144
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java10
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java7
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile25
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java13
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java13
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java6
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java16
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java10
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java7
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java13
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java28
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java20
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java6
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java13
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java7
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java6
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java6
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java10
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java10
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java47
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java34
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java28
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java11
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java67
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java35
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src32
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src18
-rw-r--r--lib/jinterface/test/jinterface_SUITE.erl18
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/FunEquals.java73
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/GetNames.java6
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Makefile.src3
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java18
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java9
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java17
-rw-r--r--lib/jinterface/test/nc_SUITE_data/echo_server.java3
-rw-r--r--lib/jinterface/vsn.mk2
-rw-r--r--lib/kernel/doc/src/error_logger.xml2
-rw-r--r--lib/kernel/doc/src/file.xml14
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml2
-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/inet.xml71
-rw-r--r--lib/kernel/doc/src/notes.xml159
-rw-r--r--lib/kernel/src/Makefile1
-rw-r--r--lib/kernel/src/application_master.erl6
-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/erl_epmd.erl15
-rw-r--r--lib/kernel/src/file.erl72
-rw-r--r--lib/kernel/src/gen_udp.erl2
-rw-r--r--lib/kernel/src/inet.erl67
-rw-r--r--lib/kernel/src/kernel.app.src2
-rw-r--r--lib/kernel/src/net_adm.erl9
-rw-r--r--lib/kernel/src/standard_error.erl155
-rw-r--r--lib/kernel/test/Makefile3
-rw-r--r--lib/kernel/test/application_SUITE.erl11
-rw-r--r--lib/kernel/test/code_SUITE.erl74
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl26
-rw-r--r--lib/kernel/test/file_SUITE.erl63
-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.c62
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl2
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl4
-rw-r--r--lib/kernel/test/inet_SUITE.erl49
-rw-r--r--lib/kernel/test/interactive_shell_SUITE.erl3
-rw-r--r--lib/kernel/test/kernel_SUITE.erl18
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl2
-rw-r--r--lib/kernel/test/standard_error_SUITE.erl38
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/aclocal.m41954
-rw-r--r--lib/megaco/configure.in20
-rw-r--r--lib/megaco/doc/src/notes.xml36
-rw-r--r--lib/megaco/src/app/megaco.appup.src15
-rw-r--r--lib/megaco/vsn.mk2
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap3.xml2
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap5.xmlsrc1
-rw-r--r--lib/mnesia/doc/src/mnesia.xml18
-rw-r--r--lib/mnesia/doc/src/notes.xml83
-rw-r--r--lib/mnesia/src/mnesia.erl6
-rw-r--r--lib/mnesia/src/mnesia_controller.erl15
-rw-r--r--lib/mnesia/src/mnesia_frag.erl2
-rw-r--r--lib/mnesia/src/mnesia_loader.erl3
-rw-r--r--lib/mnesia/src/mnesia_locker.erl20
-rw-r--r--lib/mnesia/src/mnesia_recover.erl31
-rw-r--r--lib/mnesia/src/mnesia_subscr.erl2
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl4
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/doc/src/notes.xml54
-rw-r--r--lib/observer/doc/src/observer_ug.xml5
-rw-r--r--lib/observer/src/observer_wx.erl9
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/odbc/aclocal.m41954
-rw-r--r--lib/odbc/c_src/odbcserver.c79
-rw-r--r--lib/odbc/c_src/odbcserver.h4
-rw-r--r--lib/odbc/configure.in22
-rw-r--r--lib/odbc/doc/src/error_handling.xml2
-rw-r--r--lib/odbc/doc/src/notes.xml64
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl37
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl15
-rw-r--r--lib/odbc/vsn.mk2
-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.xml56
-rw-r--r--lib/orber/doc/src/orber.xml9
-rw-r--r--lib/orber/src/Makefile3
-rw-r--r--lib/orber/src/cdr_decode.erl4
-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.erl3
-rw-r--r--lib/orber/src/orber_iiop_pm.erl34
-rw-r--r--lib/orber/src/orber_socket.erl79
-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.mk3
-rw-r--r--lib/os_mon/c_src/memsup.c2
-rw-r--r--lib/os_mon/doc/src/disksup.xml11
-rw-r--r--lib/os_mon/doc/src/notes.xml17
-rw-r--r--lib/os_mon/src/cpu_sup.erl12
-rw-r--r--lib/os_mon/src/disksup.erl19
-rw-r--r--lib/os_mon/test/disksup_SUITE.erl38
-rw-r--r--lib/os_mon/vsn.mk2
-rw-r--r--lib/ose/doc/src/notes.xml59
-rw-r--r--lib/ose/doc/src/ose_intro.xml4
-rw-r--r--lib/ose/vsn.mk2
-rw-r--r--lib/otp_mibs/doc/src/notes.xml16
-rw-r--r--lib/otp_mibs/src/Makefile2
-rw-r--r--lib/otp_mibs/vsn.mk2
-rw-r--r--lib/parsetools/doc/src/notes.xml18
-rw-r--r--lib/parsetools/include/leexinc.hrl12
-rw-r--r--lib/parsetools/test/leex_SUITE.erl51
-rw-r--r--lib/parsetools/vsn.mk2
-rw-r--r--lib/percept/doc/src/notes.xml15
-rw-r--r--lib/percept/src/Makefile3
-rw-r--r--lib/percept/vsn.mk2
-rw-r--r--lib/public_key/asn1/OTP-PKIX.asn110
-rw-r--r--lib/public_key/doc/src/cert_records.xml7
-rw-r--r--lib/public_key/doc/src/notes.xml16
-rw-r--r--lib/public_key/doc/src/public_key.xml57
-rw-r--r--lib/public_key/doc/src/public_key_records.xml68
-rw-r--r--lib/public_key/src/pubkey_pbe.erl76
-rw-r--r--lib/public_key/src/pubkey_pem.erl22
-rw-r--r--lib/public_key/src/public_key.erl43
-rw-r--r--lib/public_key/test/pbe_SUITE.erl70
-rw-r--r--lib/public_key/test/pbe_SUITE_data/old_aes_128_cbc_enc_key.pem (renamed from lib/public_key/test/pbe_SUITE_data/aes_128_cbc_enc_key)0
-rw-r--r--lib/public_key/test/pbe_SUITE_data/pbes1_des_cbc_md5_enc_key.pem17
-rw-r--r--lib/public_key/test/pbe_SUITE_data/pbes2_des_cbc_enc_key.pem (renamed from lib/public_key/test/pbe_SUITE_data/des_cbc_enc_key.pem)0
-rw-r--r--lib/public_key/test/pbe_SUITE_data/pbes2_des_ede3_cbc_enc_key.pem (renamed from lib/public_key/test/pbe_SUITE_data/des_ede3_cbc_enc_key.pem)0
-rw-r--r--lib/public_key/test/pbe_SUITE_data/pbes2_rc2_cbc_enc_key.pem (renamed from lib/public_key/test/pbe_SUITE_data/rc2_cbc_enc_key.pem)0
-rw-r--r--lib/public_key/vsn.mk2
-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/runtime_tools/doc/src/notes.xml17
-rw-r--r--lib/runtime_tools/src/system_information.erl1
-rw-r--r--lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat1
-rw-r--r--lib/runtime_tools/vsn.mk2
-rw-r--r--lib/sasl/doc/src/alarm_handler.xml12
-rw-r--r--lib/sasl/doc/src/notes.xml20
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl18
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app29
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup23
-rw-r--r--lib/sasl/test/sasl_SUITE.erl18
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/snmp/.gitignore3
-rw-r--r--lib/snmp/doc/src/notes.xml104
-rw-r--r--lib/snmp/doc/src/snmp_agent_config_files.xml56
-rw-r--r--lib/snmp/doc/src/snmp_agent_netif.xml34
-rw-r--r--lib/snmp/doc/src/snmp_manager_config_files.xml63
-rw-r--r--lib/snmp/doc/src/snmp_manager_netif.xml45
-rw-r--r--lib/snmp/doc/src/snmp_target_mib.xml22
-rw-r--r--lib/snmp/doc/src/snmpa_conf.xml66
-rw-r--r--lib/snmp/doc/src/snmpa_mpd.xml67
-rw-r--r--lib/snmp/doc/src/snmpa_network_interface_filter.xml40
-rw-r--r--lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml32
-rw-r--r--lib/snmp/doc/src/snmpm.xml14
-rw-r--r--lib/snmp/doc/src/snmpm_conf.xml8
-rw-r--r--lib/snmp/doc/src/snmpm_mpd.xml14
-rw-r--r--lib/snmp/doc/src/snmpm_network_interface.xml12
-rw-r--r--lib/snmp/doc/src/snmpm_network_interface_filter.xml34
-rw-r--r--lib/snmp/doc/src/snmpm_user.xml15
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl78
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl115
-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.erl258
-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.erl605
-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.src12
-rw-r--r--lib/snmp/src/compile/snmpc_lib.erl1
-rw-r--r--lib/snmp/src/manager/depend.mk5
-rw-r--r--lib/snmp/src/manager/snmpm.erl49
-rw-r--r--lib/snmp/src/manager/snmpm_conf.erl255
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl1283
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl76
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl904
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_filter.erl60
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_mt.erl1244
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl669
-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.erl739
-rw-r--r--lib/snmp/src/misc/snmp_config.erl565
-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.erl462
-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.erl25
-rw-r--r--lib/snmp/test/snmp_manager_test.erl160
-rw-r--r--lib/snmp/test/snmp_manager_user.erl15
-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.erl38
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl52
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE.erl559
-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
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE_data/snmpd.conf12
-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.xml304
-rw-r--r--lib/ssh/doc/src/ssh.xml14
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml71
-rw-r--r--lib/ssh/doc/src/ssh_sftp.xml125
-rw-r--r--lib/ssh/doc/src/using_ssh.xml2
-rw-r--r--lib/ssh/src/Makefile3
-rw-r--r--lib/ssh/src/ssh.app.src3
-rw-r--r--lib/ssh/src/ssh.appup.src56
-rw-r--r--lib/ssh/src/ssh.erl54
-rw-r--r--lib/ssh/src/ssh_acceptor.erl4
-rw-r--r--lib/ssh/src/ssh_acceptor_sup.erl13
-rw-r--r--lib/ssh/src/ssh_auth.erl110
-rw-r--r--lib/ssh/src/ssh_channel.erl14
-rw-r--r--lib/ssh/src/ssh_cli.erl12
-rw-r--r--lib/ssh/src/ssh_connect.hrl7
-rw-r--r--lib/ssh/src/ssh_connection.erl97
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl262
-rw-r--r--lib/ssh/src/ssh_info.erl193
-rw-r--r--lib/ssh/src/ssh_io.erl6
-rw-r--r--lib/ssh/src/ssh_message.erl45
-rw-r--r--lib/ssh/src/ssh_sftp.erl349
-rw-r--r--lib/ssh/src/ssh_sftpd.erl122
-rw-r--r--lib/ssh/src/ssh_system_sup.erl8
-rw-r--r--lib/ssh/src/ssh_transport.erl107
-rw-r--r--lib/ssh/src/ssh_xfer.erl17
-rw-r--r--lib/ssh/test/property_test/README12
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server.erl618
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa13
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa15
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_encode_decode.erl395
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_subsys.erl63
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl259
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl383
-rw-r--r--lib/ssh/test/ssh_property_test_SUITE.erl107
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl492
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt16384
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f11
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f21
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt1
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl48
-rw-r--r--lib/ssh/test/ssh_test_lib.erl3
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl197
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml199
-rw-r--r--lib/ssl/doc/src/ssl.xml64
-rw-r--r--lib/ssl/doc/src/ssl_app.xml13
-rw-r--r--lib/ssl/doc/src/ssl_protocol.xml2
-rw-r--r--lib/ssl/src/Makefile2
-rw-r--r--lib/ssl/src/dtls_record.erl4
-rw-r--r--lib/ssl/src/ssl.appup.src4
-rw-r--r--lib/ssl/src/ssl.erl59
-rw-r--r--lib/ssl/src/ssl_certificate.erl113
-rw-r--r--lib/ssl/src/ssl_cipher.erl48
-rw-r--r--lib/ssl/src/ssl_connection.erl74
-rw-r--r--lib/ssl/src/ssl_connection.hrl25
-rw-r--r--lib/ssl/src/ssl_handshake.erl59
-rw-r--r--lib/ssl/src/ssl_internal.hrl23
-rw-r--r--lib/ssl/src/ssl_manager.erl98
-rw-r--r--lib/ssl/src/ssl_pkix_db.erl33
-rw-r--r--lib/ssl/src/ssl_record.erl11
-rw-r--r--lib/ssl/src/tls_connection.erl33
-rw-r--r--lib/ssl/src/tls_record.erl22
-rw-r--r--lib/ssl/test/Makefile3
-rw-r--r--lib/ssl/test/erl_make_certs.erl6
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE.erl184
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/CA.pem14
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt11
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/ec1.key8
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt11
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/ec2.key8
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt20
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key51
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt20
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key51
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl12
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl201
-rw-r--r--lib/ssl/test/ssl_cipher_SUITE.erl188
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl16
-rw-r--r--lib/ssl/test/ssl_pem_cache_SUITE.erl127
-rw-r--r--lib/ssl/test/ssl_test_lib.erl37
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl75
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/doc/src/dict.xml2
-rw-r--r--lib/stdlib/doc/src/erl_tar.xml110
-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/io_protocol.xml9
-rw-r--r--lib/stdlib/doc/src/maps.xml17
-rw-r--r--lib/stdlib/doc/src/notes.xml288
-rw-r--r--lib/stdlib/doc/src/string.xml6
-rw-r--r--lib/stdlib/doc/src/sys.xml5
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml15
-rw-r--r--lib/stdlib/src/binary.erl8
-rw-r--r--lib/stdlib/src/c.erl17
-rw-r--r--lib/stdlib/src/dets.erl30
-rw-r--r--lib/stdlib/src/dets_server.erl18
-rw-r--r--lib/stdlib/src/edlin.erl2
-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.erl35
-rw-r--r--lib/stdlib/src/erl_parse.yrl14
-rw-r--r--lib/stdlib/src/erl_pp.erl10
-rw-r--r--lib/stdlib/src/erl_scan.erl4
-rw-r--r--lib/stdlib/src/erl_tar.erl126
-rw-r--r--lib/stdlib/src/filelib.erl16
-rw-r--r--lib/stdlib/src/gen_event.erl48
-rw-r--r--lib/stdlib/src/gen_fsm.erl49
-rw-r--r--lib/stdlib/src/gen_server.erl196
-rw-r--r--lib/stdlib/src/io.erl43
-rw-r--r--lib/stdlib/src/io_lib_format.erl2
-rw-r--r--lib/stdlib/src/maps.erl17
-rw-r--r--lib/stdlib/src/ms_transform.erl4
-rw-r--r--lib/stdlib/src/otp_internal.erl14
-rw-r--r--lib/stdlib/src/proc_lib.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.erl144
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl28
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl246
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl113
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl39
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl47
-rw-r--r--lib/stdlib/test/io_SUITE.erl52
-rw-r--r--lib/stdlib/test/maps_SUITE.erl33
-rw-r--r--lib/stdlib/test/ms_transform_SUITE.erl29
-rw-r--r--lib/stdlib/test/shell_SUITE.erl5
-rw-r--r--lib/stdlib/test/stdlib_SUITE.erl18
-rw-r--r--lib/stdlib/test/tar_SUITE.erl3
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/doc/src/notes.xml60
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl34
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl13
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl35
-rw-r--r--lib/syntax_tools/test/Makefile1
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl329
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl22
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl26
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl540
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl115
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/test_server/doc/src/notes.xml80
-rw-r--r--lib/test_server/src/Makefile2
-rwxr-xr-xlib/test_server/src/config.guess1534
-rwxr-xr-xlib/test_server/src/config.sub1789
-rw-r--r--lib/test_server/src/configure.in18
-rw-r--r--lib/test_server/src/erl2html2.erl83
-rwxr-xr-xlib/test_server/src/install-sh519
-rw-r--r--lib/test_server/src/test_server.app.src2
-rw-r--r--lib/test_server/src/test_server.erl118
-rw-r--r--lib/test_server/src/test_server_ctrl.erl142
-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/test/erl2html2_SUITE.erl2
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/doc/src/eprof.xml2
-rw-r--r--lib/tools/doc/src/fprof.xml2
-rw-r--r--lib/tools/doc/src/notes.xml68
-rw-r--r--lib/tools/emacs/erlang-skels.el150
-rw-r--r--lib/tools/emacs/erlang.el5
-rw-r--r--lib/tools/src/cover.erl2
-rw-r--r--lib/tools/src/lcnt.erl377
-rw-r--r--lib/tools/test/cover_SUITE_data/b.erl8
-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/aclocal.m41954
-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
-rwxr-xr-xlib/wx/autoconf/config.guess1534
-rwxr-xr-xlib/wx/autoconf/config.sub1789
-rwxr-xr-xlib/wx/autoconf/install-sh258
-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.xml76
-rw-r--r--lib/wx/examples/demo/ex_graphicsContext.erl2
-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/src/wxe_server.erl14
-rw-r--r--lib/wx/test/wx_class_SUITE.erl49
-rw-r--r--lib/wx/test/wx_event_SUITE.erl8
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/motorcycles2html.erl17
705 files changed, 49724 insertions, 39089 deletions
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c
index 8a0e4b1cf0..317a464060 100644
--- a/lib/asn1/c_src/asn1_erl_nif.c
+++ b/lib/asn1/c_src/asn1_erl_nif.c
@@ -941,16 +941,31 @@ static int ber_decode_value(ErlNifEnv* env, ERL_NIF_TERM *value, unsigned char *
int maybe_ret;
unsigned int len = 0;
unsigned int lenoflen = 0;
- int indef = 0;
unsigned char *tmp_out_buff;
ERL_NIF_TERM term = 0, curr_head = 0;
if (((in_buf[*ib_index]) & 0x80) == ASN1_SHORT_DEFINITE_LENGTH) {
len = in_buf[*ib_index];
- } else if (in_buf[*ib_index] == ASN1_INDEFINITE_LENGTH
- )
- indef = 1;
- else /* long definite length */{
+ } else if (in_buf[*ib_index] == ASN1_INDEFINITE_LENGTH) {
+ (*ib_index)++;
+ curr_head = enif_make_list(env, 0);
+ if (*ib_index+1 >= in_buf_len || form == ASN1_PRIMITIVE) {
+ return ASN1_INDEF_LEN_ERROR;
+ }
+ while (!(in_buf[*ib_index] == 0 && in_buf[*ib_index + 1] == 0)) {
+ maybe_ret = ber_decode(env, &term, in_buf, ib_index, in_buf_len);
+ if (maybe_ret <= ASN1_ERROR) {
+ return maybe_ret;
+ }
+ curr_head = enif_make_list_cell(env, term, curr_head);
+ if (*ib_index+1 >= in_buf_len) {
+ return ASN1_INDEF_LEN_ERROR;
+ }
+ }
+ enif_make_reverse_list(env, curr_head, value);
+ (*ib_index) += 2; /* skip the indefinite length end bytes */
+ return ASN1_OK;
+ } else /* long definite length */{
lenoflen = (in_buf[*ib_index] & 0x7f); /*length of length */
if (lenoflen > (in_buf_len - (*ib_index + 1)))
return ASN1_LEN_ERROR;
@@ -965,23 +980,7 @@ static int ber_decode_value(ErlNifEnv* env, ERL_NIF_TERM *value, unsigned char *
if (len > (in_buf_len - (*ib_index + 1)))
return ASN1_VALUE_ERROR;
(*ib_index)++;
- if (indef == 1) { /* in this case it is desireably to check that indefinite length
- end bytes exist in inbuffer */
- curr_head = enif_make_list(env, 0);
- while (!(in_buf[*ib_index] == 0 && in_buf[*ib_index + 1] == 0)) {
- if (*ib_index >= in_buf_len)
- return ASN1_INDEF_LEN_ERROR;
-
- if ((maybe_ret = ber_decode(env, &term, in_buf, ib_index, in_buf_len))
- <= ASN1_ERROR
- )
- return maybe_ret;
- curr_head = enif_make_list_cell(env, term, curr_head);
- }
- enif_make_reverse_list(env, curr_head, value);
- (*ib_index) += 2; /* skip the indefinite length end bytes */
- } else if (form == ASN1_CONSTRUCTED)
- {
+ if (form == ASN1_CONSTRUCTED) {
int end_index = *ib_index + len;
if (end_index > in_buf_len)
return ASN1_LEN_ERROR;
diff --git a/lib/asn1/doc/src/asn1_ug.xml b/lib/asn1/doc/src/asn1_ug.xml
index 020e58c615..8b33497dd3 100644
--- a/lib/asn1/doc/src/asn1_ug.xml
+++ b/lib/asn1/doc/src/asn1_ug.xml
@@ -1390,7 +1390,7 @@ GENERAL-PROCEDURES GENERAL-PROCEDURE ::= {
instance, if a Type is used in a definition with certain
purpose, one want the type-name to express the intention. This
can be done with parameterization.</p>
- <p>When many types (or an other ASN.1 entity) only differs in some
+ <p>When many types (or another ASN.1 entity) only differs in some
minor cases, but the structure of the types are similar, only
one general type can be defined and the differences may be supplied
through parameters. </p>
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index cb89bb298b..cf87c01658 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -31,6 +31,79 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 3.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When decoding BER, primitives with an indefinite length
+ will be immediately rejected. (Thanks to Simon Cornish
+ for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-12205</p>
+ </item>
+ <item>
+ <p>
+ BER: A bug with compliance to X.680 (200811) s31.2.7 has
+ been fixed. Basically, when TagDefault is AUTOMATIC then
+ tags are IMPLICIT unless EXPLICIT is given.</p>
+ <p>
+ Own Id: OTP-12318</p>
+ </item>
+ <item>
+ <p>
+ Usage of the <c>EXTERNAL</c> 1994 variant type was
+ broken.</p>
+ <p>
+ Own Id: OTP-12326</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Asn1 3.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Several problems where the ASN.1 compiler would crash
+ when attempting to compile correct specifications have
+ been corrected.</p>
+ <p>
+ Own Id: OTP-12125</p>
+ </item>
+ <item>
+ <p>
+ Robustness when decoding incorrect BER messages has been
+ improved.</p>
+ <p>
+ Own Id: OTP-12145</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl
index 396ba0fcfa..6c1cf1b12a 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -37,7 +37,7 @@
-record('ObjectClassFieldType',{classname,class,fieldname,type}).
-record(typedef,{checked=false,pos,name,typespec}).
--record(classdef,{checked=false,pos,name,typespec}).
+-record(classdef, {checked=false,pos,name,module,typespec}).
-record(valuedef,{checked=false,pos,name,type,value,module}).
-record(ptypedef,{checked=false,pos,name,args,typespec}).
-record(pvaluedef,{checked=false,pos,name,args,type,value}).
@@ -45,7 +45,6 @@
-record(pobjectdef,{checked=false,pos,name,args,class,def}).
-record(pobjectsetdef,{checked=false,pos,name,args,class,def}).
--record(identifier,{pos,val}).
-record('Constraint',{'SingleValue'=no,'SizeConstraint'=no,'ValueRange'=no,'PermittedAlphabet'=no,
'ContainedSubtype'=no, 'TypeConstraint'=no,'InnerSubtyping'=no,e=no,'Other'=no}).
-record(simpletableattributes,{objectsetname,c_name,c_index,usedclassfield,
@@ -73,6 +72,15 @@
% Externalvaluereference -> modulename '.' typename
-record('Externalvaluereference',{pos,module,value}).
+%% Used to hold a tag for a field in a SEQUENCE/SET. It can also
+%% be used for identifiers in OBJECT IDENTIFIER values, since the
+%% parser cannot always distinguish a SEQUENCE with one element from
+%% an OBJECT IDENTIFIER.
+-record(seqtag,
+ {pos :: integer(),
+ module :: atom(),
+ val :: atom()}).
+
-record(state,{module,mname,type,tname,value,vname,erule,parameters=[],
inputmodules,abscomppath=[],recordtopname=[],options,
sourcedir}).
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index 8470e5a1b4..df341e5aab 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -43,7 +43,7 @@
add_tobe_refed_func/1,add_generated_refed_func/1,
maybe_rename_function/3,current_sindex/0,
set_current_sindex/1,maybe_saved_sindex/2,
- parse_and_save/2,verbose/3,warning/3,warning/4,error/3]).
+ parse_and_save/2,verbose/3,warning/3,warning/4,error/3,format_error/1]).
-export([get_bit_string_format/0,use_legacy_types/0]).
-include("asn1_records.hrl").
@@ -143,7 +143,8 @@ parse_and_save_passes() ->
{pass,save,fun save_pass/1}].
common_passes() ->
- [{pass,check,fun check_pass/1},
+ [{iff,parse,{pass,parse_listing,fun parse_listing/1}},
+ {pass,check,fun check_pass/1},
{iff,abs,{pass,abs_listing,fun abs_listing/1}},
{pass,generate,fun generate_pass/1},
{unless,noobj,{pass,compile,fun compile_pass/1}}].
@@ -243,6 +244,16 @@ save_pass(#st{code=M,erule=Erule,dbfile=DbFile}=St) ->
asn1_db:dbsave(DbFile,M#module.name),
{ok,St}.
+parse_listing(#st{code=Code,outfile=OutFile0}=St) ->
+ OutFile = OutFile0 ++ ".parse",
+ case file:write_file(OutFile, io_lib:format("~p\n", [Code])) of
+ ok ->
+ done;
+ {error,Reason} ->
+ Error = {write_error,OutFile,Reason},
+ {error,St#st{error=[{structured_error,{OutFile0,none},?MODULE,Error}]}}
+ end.
+
abs_listing(#st{code={M,_},outfile=OutFile}) ->
pretty2(M#module.name, OutFile++".abs"),
done.
@@ -2430,6 +2441,10 @@ verbose(Format, Args, S) ->
ok
end.
+format_error({write_error,File,Reason}) ->
+ io_lib:format("writing output file ~s failed: ~s",
+ [File,file:format_error(Reason)]).
+
is_error(S) when is_record(S, state) ->
is_error(S#state.options);
is_error(O) ->
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index e788aa5c6c..240f1cbb16 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -91,7 +91,7 @@ check(S,{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets}) ->
save_asn1db_uptodate(S,S#state.erule,S#state.mname),
put(top_module,S#state.mname),
- _ = checkp(S, ParameterizedTypes), %must do this before the templates are used
+ ParamError = checkp(S, ParameterizedTypes), %must do this before the templates are used
%% table to save instances of parameterized objects,object sets
asn1ct_table:new(parameterized_objects),
@@ -160,8 +160,10 @@ check(S,{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets}) ->
Exporterror = check_exports(S,S#state.module),
ImportError = check_imports(S,S#state.module),
- case {Terror3,Verror5,Cerror,Oerror,Exporterror,ImportError} of
- {[],[],[],[],[],[]} ->
+ AllErrors = lists:flatten([ParamError,Terror3,Verror5,Cerror,
+ Oerror,Exporterror,ImportError]),
+ case AllErrors of
+ [] ->
ContextSwitchTs = context_switch_in_spec(),
InstanceOf = instance_of_in_spec(S#state.mname),
NewTypes = lists:subtract(Types,AddClasses) ++ ContextSwitchTs
@@ -175,8 +177,7 @@ check(S,{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets}) ->
lists:subtract(NewObjects,ExclO)++InlinedObjects,
lists:subtract(NewObjectSets,ExclOS)++ParObjectSetNames}};
_ ->
- {error,lists:flatten([Terror3,Verror5,Cerror,
- Oerror,Exporterror,ImportError])}
+ {error,AllErrors}
end.
context_switch_in_spec() ->
@@ -549,14 +550,10 @@ check_class(S = #state{mname=M,tname=T},ClassSpec)
#objectclass{fields=Def}; % in case of recursive definitions
Tref = #'Externaltypereference'{type=TName} ->
{MName,RefType} = get_referenced_type(S,Tref),
- case is_class(S,RefType) of
- true ->
- NewState = update_state(S#state{type=RefType,
- tname=TName},MName),
- check_class(NewState,get_class_def(S,RefType));
- _ ->
- error({class,{internal_error,RefType},S})
- end;
+ #classdef{} = CD = get_class_def(S, RefType),
+ NewState = update_state(S#state{type=RefType,
+ tname=TName}, MName),
+ check_class(NewState, CD);
{pt,ClassRef,Params} ->
%% parameterized class
{_,PClassDef} = get_referenced_type(S,ClassRef),
@@ -950,6 +947,8 @@ prepare_objset(ObjDef={object,definedsyntax,_ObjFields}) ->
{set,[ObjDef],false};
prepare_objset({ObjDef=#type{},Ext}) when is_list(Ext) ->
{set,[ObjDef|Ext],true};
+prepare_objset({#type{}=Type,#type{}=Ext}) ->
+ {set,[Type,Ext],true};
prepare_objset(Ret) ->
Ret.
@@ -1277,10 +1276,25 @@ get_fieldname_element(_S,Def,[{_RefType,_FieldName}|_RestFName])
check_fieldname_element(S,{value,{_,Def}}) ->
check_fieldname_element(S,Def);
-check_fieldname_element(S,TDef) when is_record(TDef,typedef) ->
- check_type(S,TDef,TDef#typedef.typespec);
-check_fieldname_element(S,VDef) when is_record(VDef,valuedef) ->
- check_value(S,VDef);
+check_fieldname_element(S, #typedef{typespec=Ts}=TDef) ->
+ case Ts of
+ #'Object'{} ->
+ check_object(S, TDef, Ts);
+ _ ->
+ check_type(S, TDef, Ts)
+ end;
+check_fieldname_element(S, #valuedef{}=VDef) ->
+ try
+ check_value(S, VDef)
+ catch
+ throw:{objectdef} ->
+ #valuedef{checked=C,pos=Pos,name=N,type=Type,
+ value=Def} = VDef,
+ ClassName = Type#type.def,
+ NewSpec = #'Object'{classname=ClassName,def=Def},
+ NewDef = #typedef{checked=C,pos=Pos,name=N,typespec=NewSpec},
+ check_fieldname_element(S, NewDef)
+ end;
check_fieldname_element(S,Eref)
when is_record(Eref,'Externaltypereference');
is_record(Eref,'Externalvaluereference') ->
@@ -1803,12 +1817,10 @@ convert_to_defaultfield(S,ObjFieldName,[OFS|RestOFS],CField)->
FieldName);
ValSetting = #valuedef{} ->
ValSetting;
- ValSetting = {'CHOICE',{Alt,_ChVal}} when is_atom(Alt) ->
- #valuedef{type=element(3,CField),
- value=ValSetting,
- module=S#state.mname};
ValSetting ->
- #identifier{val=ValSetting}
+ #valuedef{type=element(3,CField),
+ value=ValSetting,
+ module=S#state.mname}
end,
?dbg("fixedtypevaluefield ValRef: ~p~n",[ValRef]),
case ValRef of
@@ -2136,11 +2148,9 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
{'INTEGER',NamedNumberList} ->
ok = validate_integer(SVal, Value, NamedNumberList, Constr),
V#valuedef{value=normalize_value(SVal, Vtype, Value, [])};
- #'SEQUENCE'{components=Components} ->
- {ok,SeqVal} = validate_sequence(SVal, Value,
- Components, Constr),
- V#valuedef{value=normalize_value(SVal, Vtype,
- SeqVal, TopName)};
+ #'SEQUENCE'{} ->
+ {ok,SeqVal} = convert_external(SVal, Value),
+ V#valuedef{value=normalize_value(SVal, Vtype, SeqVal, TopName)};
{'SelectionType',SelName,SelT} ->
CheckedT = check_selectiontype(SVal, SelName, SelT),
NewV = V#valuedef{type=CheckedT},
@@ -2292,22 +2302,23 @@ validate_oid(_, S, OID, [Id|Vrest], Acc)
error({value, {"illegal "++to_string(OID),[Id,Vrest],Acc}, S})
end
end;
-validate_oid(_, S, OID, [{Atom,Value}],[])
+validate_oid(_, S, OID, [{#seqtag{module=Mod,val=Atom},Value}], [])
when is_atom(Atom),is_integer(Value) ->
%% this case when an OBJECT IDENTIFIER value has been parsed as a
%% SEQUENCE value
- Rec = #'Externalvaluereference'{module=S#state.mname,
+ Rec = #'Externalvaluereference'{module=Mod,
value=Atom},
validate_objectidentifier1(S, OID, [Rec,Value]);
-validate_oid(_, S, OID, [{Atom,EVRef}],[])
+validate_oid(_, S, OID, [{#seqtag{module=Mod,val=Atom},EVRef}], [])
when is_atom(Atom),is_record(EVRef,'Externalvaluereference') ->
%% this case when an OBJECT IDENTIFIER value has been parsed as a
%% SEQUENCE value OTP-4354
- Rec = #'Externalvaluereference'{module=EVRef#'Externalvaluereference'.module,
+ Rec = #'Externalvaluereference'{module=Mod,
value=Atom},
validate_objectidentifier1(S, OID, [Rec,EVRef]);
-validate_oid(_, S, OID, [Atom|Rest],Acc) when is_atom(Atom) ->
- Rec = #'Externalvaluereference'{module=S#state.mname,
+validate_oid(_, S, OID, [#seqtag{module=Mod,val=Atom}|Rest], Acc)
+ when is_atom(Atom) ->
+ Rec = #'Externalvaluereference'{module=Mod,
value=Atom},
validate_oid(true,S, OID, [Rec|Rest],Acc);
validate_oid(_, S, OID, V, Acc) ->
@@ -2399,13 +2410,13 @@ valid_objectid(o_id,_I,[1]) -> false;
valid_objectid(o_id,_I,[2]) -> true;
valid_objectid(_,_,_) -> true.
-validate_sequence(S=#state{type=Vtype},Value,_Components,_Constr) ->
+convert_external(S=#state{type=Vtype}, Value) ->
case Vtype of
#type{tag=[{tag,'UNIVERSAL',8,'IMPLICIT',32}]} ->
%% this is an 'EXTERNAL' (or INSTANCE OF)
case Value of
- [{identification,_}|_RestVal] ->
- {ok,to_EXTERNAL1990(S,Value)};
+ [{#seqtag{val=identification},_}|_] ->
+ {ok,to_EXTERNAL1990(S, Value)};
_ ->
{ok,Value}
end;
@@ -2413,21 +2424,25 @@ validate_sequence(S=#state{type=Vtype},Value,_Components,_Constr) ->
{ok,Value}
end.
-to_EXTERNAL1990(S,[{identification,{'CHOICE',{syntax,Stx}}}|Rest]) ->
- to_EXTERNAL1990(S,Rest,[{'direct-reference',Stx}]);
-to_EXTERNAL1990(S,[{identification,{'CHOICE',{'presentation-context-id',I}}}|Rest]) ->
- to_EXTERNAL1990(S,Rest,[{'indirect-reference',I}]);
-to_EXTERNAL1990(S,[{identification,{'CHOICE',{'context-negotiation',[{_,PCid},{_,TrStx}]}}}|Rest]) ->
- to_EXTERNAL1990(S,Rest,[{'indirect-reference',PCid},{'direct-reference',TrStx}]);
-to_EXTERNAL1990(S,_) ->
+to_EXTERNAL1990(S, [{#seqtag{val=identification}=T,
+ {'CHOICE',{syntax,Stx}}}|Rest]) ->
+ to_EXTERNAL1990(S, Rest, [{T#seqtag{val='direct-reference'},Stx}]);
+to_EXTERNAL1990(S, [{#seqtag{val=identification}=T,
+ {'CHOICE',{'presentation-context-id',I}}}|Rest]) ->
+ to_EXTERNAL1990(S, Rest, [{T#seqtag{val='indirect-reference'},I}]);
+to_EXTERNAL1990(S, [{#seqtag{val=identification}=T,
+ {'CHOICE',{'context-negotiation',[{_,PCid},{_,TrStx}]}}}|Rest]) ->
+ to_EXTERNAL1990(S, Rest, [{T#seqtag{val='indirect-reference'},PCid},
+ {T#seqtag{val='direct-reference'},TrStx}]);
+to_EXTERNAL1990(S, _) ->
error({value,"illegal value in EXTERNAL type",S}).
-to_EXTERNAL1990(S,[V={'data-value-descriptor',_}|Rest],Acc) ->
- to_EXTERNAL1990(S,Rest,[V|Acc]);
-to_EXTERNAL1990(_S,[{'data-value',Val}],Acc) ->
- Encoding = {encoding,{'CHOICE',{'octet-aligned',Val}}},
+to_EXTERNAL1990(S, [V={#seqtag{val='data-value-descriptor'},_}|Rest], Acc) ->
+ to_EXTERNAL1990(S, Rest, [V|Acc]);
+to_EXTERNAL1990(_S, [{#seqtag{val='data-value'}=T,Val}], Acc) ->
+ Encoding = {T#seqtag{val=encoding},{'CHOICE',{'octet-aligned',Val}}},
lists:reverse([Encoding|Acc]);
-to_EXTERNAL1990(S,_,_) ->
+to_EXTERNAL1990(S, _, _) ->
error({value,"illegal value in EXTERNAL type",S}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2689,20 +2704,20 @@ normalize_set(S,Value,Components,NameList) ->
normalized_record('SET',S,SortedVal,Components,NameList)
end.
-sort_value(Components,Value) ->
- ComponentNames = lists:map(fun(#'ComponentType'{name=Cname}) -> Cname end,
- Components),
- sort_value1(ComponentNames,Value,[]).
-sort_value1(_,V=#'Externalvaluereference'{},_) ->
- %% sort later, get the value in normalize_seq_or_set
- V;
-sort_value1([N|Ns],Value,Acc) ->
- case lists:keysearch(N,1,Value) of
- {value,V} ->sort_value1(Ns,Value,[V|Acc]);
- _ -> sort_value1(Ns,Value,Acc)
- end;
-sort_value1([],_,Acc) ->
- lists:reverse(Acc).
+sort_value(Components, Value0) when is_list(Value0) ->
+ {Keys0,_} = lists:mapfoldl(fun(#'ComponentType'{name=N}, I) ->
+ {{N,I},I+1}
+ end, 0, Components),
+ Keys = gb_trees:from_orddict(orddict:from_list(Keys0)),
+ Value1 = [{case gb_trees:lookup(N, Keys) of
+ {value,K} -> K;
+ none -> 'end'
+ end,Pair} || {#seqtag{val=N},_}=Pair <- Value0],
+ Value = lists:sort(Value1),
+ [Pair || {_,Pair} <- Value];
+sort_value(_Components, #'Externalvaluereference'{}=Value) ->
+ %% Sort later.
+ Value.
sort_val_if_set(['SET'|_],Val,Type) ->
sort_value(Type,Val);
@@ -2735,9 +2750,9 @@ is_record_normalized(_S,Name,Value,NumComps) when is_tuple(Value) ->
is_record_normalized(_,_,_,_) ->
false.
-normalize_seq_or_set(SorS,S,[{Cname,V}|Vs],
+normalize_seq_or_set(SorS, S, [{#seqtag{val=Cname},V}|Vs],
[#'ComponentType'{name=Cname,typespec=TS}|Cs],
- NameList,Acc) ->
+ NameList, Acc) ->
NewNameList =
case TS#type.def of
#'Externaltypereference'{type=TName} ->
@@ -2915,8 +2930,7 @@ get_canonic_type(S,Type,NameList) ->
check_ptype(S,Type,Ts) when is_record(Ts,type) ->
- %Tag = Ts#type.tag,
- %Constr = Ts#type.constraint,
+ check_formal_parameters(S, Type#ptypedef.args),
Def = Ts#type.def,
NewDef=
case Def of
@@ -2942,6 +2956,16 @@ check_ptype(S,Type,Ts) when is_record(Ts,type) ->
check_ptype(_S,_PTDef,Ts) when is_record(Ts,objectclass) ->
throw({asn1_param_class,Ts}).
+check_formal_parameters(S, Args) ->
+ _ = [check_formal_parameter(S, A) || A <- Args],
+ ok.
+
+check_formal_parameter(_, {_,_}) ->
+ ok;
+check_formal_parameter(_, #'Externaltypereference'{}) ->
+ ok;
+check_formal_parameter(S, #'Externalvaluereference'{value=Name}=Ref) ->
+ asn1_error(S, Ref, {illegal_typereference,Name}).
% check_type(S,Type,ObjSpec={{objectclassname,_},_}) ->
% check_class(S,ObjSpec);
@@ -2989,9 +3013,9 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
{TmpRefMod,TmpRefDef} ->
{TmpRefMod,TmpRefDef,false}
end,
- case is_class(S,RefTypeDef) of
- true -> throw({asn1_class,RefTypeDef});
- _ -> ok
+ case get_class_def(S, RefTypeDef) of
+ none -> ok;
+ #classdef{} -> throw({asn1_class,RefTypeDef})
end,
Ct = TestFun(Ext),
{RefType,ExtRef} =
@@ -3372,23 +3396,17 @@ get_type_from_object(S,Object,TypeField)
ObjSpec = check_object(S,ObjectDef,ObjectDef#typedef.typespec),
get_fieldname_element(S,ObjectDef#typedef{typespec=ObjSpec},TypeField).
-is_class(_S,#classdef{}) ->
- true;
-is_class(S,#typedef{typespec=#type{def=Eref}})
- when is_record(Eref,'Externaltypereference')->
- is_class(S,Eref);
-is_class(S,Eref) when is_record(Eref,'Externaltypereference')->
- {_,NextDef} = get_referenced_type(S,Eref),
- is_class(S,NextDef);
-is_class(_,_) ->
- false.
-
-get_class_def(_S,CD=#classdef{}) ->
+%% get_class_def(S, Type) -> #classdef{} | 'none'.
+get_class_def(S, #typedef{typespec=#type{def=#'Externaltypereference'{}=Eref}}) ->
+ {_,NextDef} = get_referenced_type(S, Eref),
+ get_class_def(S, NextDef);
+get_class_def(S, #'Externaltypereference'{}=Eref) ->
+ {_,NextDef} = get_referenced_type(S, Eref),
+ get_class_def(S, NextDef);
+get_class_def(_S, #classdef{}=CD) ->
CD;
-get_class_def(S,#typedef{typespec=#type{def=Eref}})
- when is_record(Eref,'Externaltypereference') ->
- {_,NextDef} = get_referenced_type(S,Eref),
- get_class_def(S,NextDef).
+get_class_def(_S, _) ->
+ none.
maybe_illicit_implicit_tag(Kind,Tag) ->
case Tag of
@@ -3595,109 +3613,54 @@ match_args(_,_, _, _) ->
%% categorize_arg(S,FormalArg,ActualArg) -> {FormalArg,CatgorizedActualArg}
%%
categorize_arg(S,{Governor,Param},ActArg) ->
- case {governor_category(S,Governor),parameter_name_style(Param,ActArg)} of
-%% {absent,beginning_uppercase} -> %% a type
-%% categorize(S,type,ActArg);
- {type,beginning_lowercase} -> %% a value
- categorize(S,value,Governor,ActArg);
- {type,beginning_uppercase} -> %% a value set
- categorize(S,value_set,ActArg);
-%% {absent,entirely_uppercase} -> %% a class
-%% categorize(S,class,ActArg);
+ case {governor_category(S, Governor),parameter_name_style(Param)} of
+ {type,beginning_lowercase} -> %a value
+ categorize(S, value, Governor, ActArg);
+ {type,beginning_uppercase} -> %a value set
+ categorize(ActArg);
{{class,ClassRef},beginning_lowercase} ->
- categorize(S,object,ActArg,ClassRef);
+ categorize(S, object, ActArg, ClassRef);
{{class,ClassRef},beginning_uppercase} ->
- categorize(S,object_set,ActArg,ClassRef);
- _ ->
- [ActArg]
+ categorize(S, object_set, ActArg, ClassRef)
end;
-categorize_arg(S,FormalArg,ActualArg) ->
- %% governor is absent => a type or a class
- case FormalArg of
- #'Externaltypereference'{type=Name} ->
- case is_class_name(Name) of
- true ->
- categorize(S,class,ActualArg);
- _ ->
- categorize(S,type,ActualArg)
- end;
- FA ->
- throw({error,{unexpected_formal_argument,FA}})
- end.
-
-governor_category(S,#type{def=Eref})
- when is_record(Eref,'Externaltypereference') ->
- governor_category(S,Eref);
-governor_category(_S,#type{}) ->
+categorize_arg(_S, _FormalArg, ActualArg) ->
+ %% Governor is absent -- must be a type or a class. We have already
+ %% checked that the FormalArg begins with an uppercase letter.
+ categorize(ActualArg).
+
+%% governor_category(S, Item) -> type | {class,#'Externaltypereference'{}}
+%% Determine whether Item is a type or a class.
+governor_category(S, #type{def=#'Externaltypereference'{}=Eref}) ->
+ governor_category(S, Eref);
+governor_category(_S, #type{}) ->
type;
-governor_category(S,Ref) when is_record(Ref,'Externaltypereference') ->
- case is_class(S,Ref) of
- true ->
- {class,Ref};
- _ ->
+governor_category(S, #'Externaltypereference'{}=Ref) ->
+ case get_class_def(S, Ref) of
+ #classdef{pos=Pos,module=Mod,name=Name} ->
+ {class,#'Externaltypereference'{pos=Pos,module=Mod,type=Name}};
+ none ->
type
- end;
-governor_category(_,Class)
- when Class == 'TYPE-IDENTIFIER'; Class == 'ABSTRACT-SYNTAX' ->
- class.
-%% governor_category(_,_) ->
-%% absent.
+ end.
%% parameter_name_style(Param,Data) -> Result
%% gets the Parameter and the name of the Data and if it exists tells
%% whether it begins with a lowercase letter or is partly or entirely
%% spelled with uppercase letters. Otherwise returns undefined
%%
-parameter_name_style(_,#'Externaltypereference'{type=Name}) ->
- name_category(Name);
-parameter_name_style(_,#'Externalvaluereference'{value=Name}) ->
- name_category(Name);
-parameter_name_style(_,{valueset,_}) ->
- %% It is a object set or value set
+parameter_name_style(#'Externaltypereference'{}) ->
beginning_uppercase;
-parameter_name_style(#'Externalvaluereference'{},_) ->
- beginning_lowercase;
-parameter_name_style(#'Externaltypereference'{type=Name},_) ->
- name_category(Name);
-parameter_name_style(_,_) ->
- undefined.
-
-name_category(Atom) when is_atom(Atom) ->
- name_category(atom_to_list(Atom));
-name_category([H|T]) ->
- case is_lowercase(H) of
- true ->
- beginning_lowercase;
- _ ->
- case is_class_name(T) of
- true ->
- entirely_uppercase;
- _ ->
- beginning_uppercase
- end
- end;
-name_category(_) ->
- undefined.
+parameter_name_style(#'Externalvaluereference'{}) ->
+ beginning_lowercase.
is_lowercase(X) when X >= $A,X =< $W ->
false;
is_lowercase(_) ->
true.
-
-is_class_name(Name) when is_atom(Name) ->
- is_class_name(atom_to_list(Name));
-is_class_name(Name) ->
- case [X||X <- Name, X >= $a,X =< $w] of
- [] ->
- true;
- _ ->
- false
- end.
-%% categorize(S,Category,Parameter) -> CategorizedParameter
+%% categorize(Parameter) -> CategorizedParameter
%% If Parameter has an abstract syntax of another category than
%% Category, transform it to a known syntax.
-categorize(_S,type,{object,_,Type}) ->
+categorize({object,_,Type}) ->
%% One example of this case is an object with a parameterized type
%% having a locally defined type as parameter.
Def = fun(D = #type{}) ->
@@ -3709,11 +3672,12 @@ categorize(_S,type,{object,_,Type}) ->
D
end,
[Def(X)||X<-Type];
-categorize(_S,type,Def) when is_record(Def,type) ->
+categorize(#type{}=Def) ->
[#typedef{name = new_reference_name("type_argument"),
typespec = Def#type{inlined=yes}}];
-categorize(_,_,Def) ->
+categorize(Def) ->
[Def].
+
categorize(S,object_set,Def,ClassRef) ->
NewObjSetSpec =
check_object(S,Def,#'ObjectSet'{class = ClassRef,
@@ -4546,55 +4510,43 @@ check_reference(S,#'Externaltypereference'{pos=Pos,module=Emod,type=Name}) ->
#'Externaltypereference'{pos=Pos,module=ModName,type=Name}
end.
+get_referenced_type(S, T) ->
+ case do_get_referenced_type(S, T) of
+ {_,#type{def=#'Externaltypereference'{}=ERef}} ->
+ get_referenced_type(S, ERef);
+ {_,#type{def=#'Externalvaluereference'{}=VRef}} ->
+ get_referenced_type(S, VRef);
+ {_,_}=Res ->
+ Res
+ end.
+
+do_get_referenced_type(#state{parameters=Ps}=S, T0) ->
+ case match_parameters(S, T0, Ps) of
+ T0 ->
+ do_get_ref_type_1(S, T0);
+ T ->
+ do_get_referenced_type(S, T)
+ end.
-get_referenced_type(S,Ext) when is_record(Ext,'Externaltypereference') ->
- case match_parameters(S,Ext, S#state.parameters) of
- Ext ->
- #'Externaltypereference'{pos=Pos,module=Emod,type=Etype} = Ext,
- case S#state.mname of
- Emod -> % a local reference in this module
- get_referenced1(S,Emod,Etype,Pos);
- _ ->% always when multi file compiling
- case lists:member(Emod,S#state.inputmodules) of
- true ->
- get_referenced1(S,Emod,Etype,Pos);
- false ->
- get_referenced(S,Emod,Etype,Pos)
- end
- end;
- ERef = #'Externaltypereference'{} ->
- get_referenced_type(S,ERef);
- Other ->
- {undefined,Other}
- end;
-get_referenced_type(S=#state{mname=Emod},
- ERef=#'Externalvaluereference'{pos=P,module=Emod,
- value=Eval}) ->
- case match_parameters(S,ERef,S#state.parameters) of
- ERef ->
- get_referenced1(S,Emod,Eval,P);
- OtherERef when is_record(OtherERef,'Externalvaluereference') ->
- get_referenced_type(S,OtherERef);
- Value ->
- {Emod,Value}
- end;
-get_referenced_type(S,ERef=#'Externalvaluereference'{pos=Pos,module=Emod,
- value=Eval}) ->
- case match_parameters(S,ERef,S#state.parameters) of
- ERef ->
- case lists:member(Emod,S#state.inputmodules) of
- true ->
- get_referenced1(S,Emod,Eval,Pos);
- false ->
- get_referenced(S,Emod,Eval,Pos)
- end;
- OtherERef ->
- get_referenced_type(S,OtherERef)
- end;
-get_referenced_type(S,#identifier{val=Name,pos=Pos}) ->
- get_referenced1(S,undefined,Name,Pos);
-get_referenced_type(_S,Type) ->
- {undefined,Type}.
+do_get_ref_type_1(S, #'Externaltypereference'{pos=P,
+ module=M,
+ type=T}) ->
+ do_get_ref_type_2(S, P, M, T);
+do_get_ref_type_1(S, #'Externalvaluereference'{pos=P,
+ module=M,
+ value=V}) ->
+ do_get_ref_type_2(S, P, M, V);
+do_get_ref_type_1(_, T) ->
+ {undefined,T}.
+
+do_get_ref_type_2(#state{mname=Current,inputmodules=Modules}=S,
+ Pos, M, T) ->
+ case M =:= Current orelse lists:member(M, Modules) of
+ true ->
+ get_referenced1(S, M, T, Pos);
+ false ->
+ get_referenced(S, M, T, Pos)
+ end.
%% get_referenced/3
%% The referenced entity Ename may in case of an imported parameterized
@@ -6631,6 +6583,8 @@ merge_tags2([T1= #tag{type='IMPLICIT'}, T2 |Rest], Acc) ->
merge_tags2([T1#tag{type=T2#tag.type, form=T2#tag.form}|Rest],Acc);
merge_tags2([T1= #tag{type={default,'IMPLICIT'}}, T2 |Rest], Acc) ->
merge_tags2([T1#tag{type=T2#tag.type, form=T2#tag.form}|Rest],Acc);
+merge_tags2([T1= #tag{type={default,'AUTOMATIC'}}, T2 |Rest], Acc) ->
+ merge_tags2([T1#tag{type=T2#tag.type, form=T2#tag.form}|Rest],Acc);
merge_tags2([H|T],Acc) ->
merge_tags2(T, [H|Acc]);
merge_tags2([], Acc) ->
@@ -6760,6 +6714,8 @@ format_error({illegal_instance_of,Class}) ->
[Class]);
format_error(illegal_octet_string_value) ->
"expecting a bstring or an hstring as value for an OCTET STRING";
+format_error({illegal_typereference,Name}) ->
+ io_lib:format("'~p' is used as a typereference, but does not start with an uppercase letter", [Name]);
format_error({invalid_fields,Fields,Obj}) ->
io_lib:format("invalid ~s in ~p", [format_fields(Fields),Obj]);
format_error({invalid_bit_number,Bit}) ->
@@ -7006,7 +6962,7 @@ include_default_class1(_,[]) ->
include_default_class1(Module,[{Name,TS}|Rest]) ->
case asn1_db:dbget(Module,Name) of
undefined ->
- C = #classdef{checked=true,name=Name,
+ C = #classdef{checked=true,module=Module,name=Name,
typespec=TS},
asn1_db:dbput(Module,Name,C);
_ -> ok
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/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl
index 283616b157..3891fce8d3 100644
--- a/lib/asn1/src/asn1ct_parser2.erl
+++ b/lib/asn1/src/asn1ct_parser2.erl
@@ -25,7 +25,8 @@
%% Only used internally within this module.
-record(typereference, {pos,val}).
--record(constraint,{c,e}).
+-record(constraint, {c,e}).
+-record(identifier, {pos,val}).
%% parse all types in module
parse(Tokens) ->
@@ -112,6 +113,9 @@ parse_ModuleDefinition(Tokens) ->
parse_Exports([{'EXPORTS',_L1},{';',_L2}|Rest]) ->
{{exports,[]},Rest};
+parse_Exports([{'EXPORTS',_},{'ALL',_},{';',_}|Rest]) ->
+ %% Same as no exports definition.
+ {{exports,all},Rest};
parse_Exports([{'EXPORTS',_L1}|Rest]) ->
{SymbolList,Rest2} = parse_SymbolList(Rest),
case Rest2 of
@@ -1037,10 +1041,6 @@ parse_DefinedObjectClass([{typereference,_,_ModName},{'.',_},Tr={typereference,_
parse_DefinedObjectClass([Tr={typereference,_,_ObjClName}|Rest]) ->
% {{objectclassname,tref2Exttref(Tr)},Rest};
{tref2Exttref(Tr),Rest};
-parse_DefinedObjectClass([{'TYPE-IDENTIFIER',_}|Rest]) ->
- {'TYPE-IDENTIFIER',Rest};
-parse_DefinedObjectClass([{'ABSTRACT-SYNTAX',_}|Rest]) ->
- {'ABSTRACT-SYNTAX',Rest};
parse_DefinedObjectClass(Tokens) ->
throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
[got,get_token(hd(Tokens)),expected,
@@ -1051,7 +1051,8 @@ parse_DefinedObjectClass(Tokens) ->
parse_ObjectClassAssignment([{typereference,L1,ObjClName},{'::=',_}|Rest]) ->
{Type,Rest2} = parse_ObjectClass(Rest),
- {#classdef{pos=L1,name=ObjClName,typespec=Type},Rest2};
+ {#classdef{pos=L1,name=ObjClName,module=resolve_module(Type),
+ typespec=Type},Rest2};
parse_ObjectClassAssignment(Tokens) ->
throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
[got,get_token(hd(Tokens)),expected,
@@ -2134,8 +2135,7 @@ parse_ParameterizedObjectSetAssignment(Tokens) ->
%% Parameter = {Governor,Reference} | Reference
%% Governor = Type | DefinedObjectClass
%% Type = #type{}
-%% DefinedObjectClass = #'Externaltypereference'{} |
-%% 'ABSTRACT-SYNTAX' | 'TYPE-IDENTIFIER'
+%% DefinedObjectClass = #'Externaltypereference'{}
%% Reference = #'Externaltypereference'{} | #'Externalvaluereference'{}
parse_ParameterList([{'{',_}|Rest]) ->
parse_ParameterList(Rest,[]);
@@ -2863,13 +2863,14 @@ parse_SequenceValue(Tokens) ->
throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
[got,get_token(hd(Tokens)),expected,'{']}}).
-parse_SequenceValue([{identifier,_,IdName}|Rest],Acc) ->
+parse_SequenceValue([{identifier,Pos,IdName}|Rest],Acc) ->
{Value,Rest2} = parse_Value(Rest),
+ SeqTag = #seqtag{pos=Pos,module=get(asn1_module),val=IdName},
case Rest2 of
[{',',_}|Rest3] ->
- parse_SequenceValue(Rest3,[{IdName,Value}|Acc]);
+ parse_SequenceValue(Rest3, [{SeqTag,Value}|Acc]);
[{'}',_}|Rest3] ->
- {lists:reverse([{IdName,Value}|Acc]),Rest3};
+ {lists:reverse(Acc, [{SeqTag,Value}]),Rest3};
_ ->
throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
[got,get_token(hd(Rest2)),expected,'}']}})
diff --git a/lib/asn1/src/asn1ct_tok.erl b/lib/asn1/src/asn1ct_tok.erl
index 33f4379173..8687ed955c 100644
--- a/lib/asn1/src/asn1ct_tok.erl
+++ b/lib/asn1/src/asn1ct_tok.erl
@@ -309,7 +309,6 @@ check_hex(_) ->
%% returns rstrtype if A is a reserved word in the group
%% RestrictedCharacterStringType
reserved_word('ABSENT') -> true;
-%reserved_word('ABSTRACT-SYNTAX') -> true; % impl as predef item
reserved_word('ALL') -> true;
reserved_word('ANY') -> true;
reserved_word('APPLICATION') -> true;
@@ -380,7 +379,6 @@ reserved_word('T61String') -> rstrtype;
reserved_word('TAGS') -> true;
reserved_word('TeletexString') -> rstrtype;
reserved_word('TRUE') -> true;
-%% reserved_word('TYPE-IDENTIFIER') -> true; % impl as predef item
reserved_word('UNION') -> true;
reserved_word('UNIQUE') -> true;
reserved_word('UNIVERSAL') -> true;
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..432197eec0 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -50,22 +50,24 @@ 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]},
+ ber_optional,
+ tagdefault_automatic]},
{app_test, [], [{asn1_app_test, all}]},
{appup_test, [], [{asn1_appup_test, all}]},
- {parallel, parallel([]),
+ {parallel, Parallel,
[cover,
xref,
{group, ber},
@@ -133,14 +135,13 @@ groups() ->
testChoiceIndefinite,
per_open_type,
testInfObjectClass,
- testParameterizedInfObj,
+ testParam,
testFragmented,
testMergeCompile,
testobj,
testDeepTConstr,
testExport,
testImport,
- testParamBasic,
testDER,
testDEFAULT,
testMvrasn6,
@@ -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),
@@ -528,12 +520,6 @@ testSetDefault(Config, Rule, Opts) ->
asn1_test_lib:compile("SetDefault", Config, [Rule|Opts]),
testSetDefault:main(Rule).
-testParamBasic(Config) ->
- test(Config, fun testParamBasic/3, [ber,{ber,[der]},per,uper]).
-testParamBasic(Config, Rule, Opts) ->
- asn1_test_lib:compile("ParamBasic", Config, [Rule|Opts]),
- testParamBasic:main(Rule).
-
testSetOptional(Config) -> test(Config, fun testSetOptional/3).
testSetOptional(Config, Rule, Opts) ->
asn1_test_lib:compile("SetOptional", Config, [Rule|Opts]),
@@ -674,6 +660,19 @@ ber_optional(Config, Rule, Opts) ->
{'C', asn1_NOVALUE, 111, asn1_NOVALUE}},
asn1_test_lib:roundtrip('SOpttest', 'S', V).
+tagdefault_automatic(Config) ->
+ test(Config, fun tagdefault_automatic/3, [ber]).
+tagdefault_automatic(Config, Rule, Opts) ->
+ asn1_test_lib:compile("TAGDEFAULT-AUTOMATIC", Config, [Rule|Opts]),
+ << 48,8,128,2,100,101,129,2,110,111 >> =
+ asn1_test_lib:roundtrip_enc('TAGDEFAULT-AUTOMATIC', 'Tagged', {'Tagged', << 100,101 >>, << 110,111 >>}),
+ << 48,8,128,2,100,101,129,2,110,111 >> =
+ asn1_test_lib:roundtrip_enc('TAGDEFAULT-AUTOMATIC', 'Untagged', {'Untagged', << 100,101 >>, << 110,111 >>}),
+ << 48,8,4,2,100,101,130,2,110,111 >> =
+ asn1_test_lib:roundtrip_enc('TAGDEFAULT-AUTOMATIC', 'Mixed', {'Mixed', << 100,101 >>, << 110,111 >>}),
+
+ ok.
+
%% records used by test-case default
-record('Def1', {bool0,
bool1 = asn1_DEFAULT,
@@ -766,11 +765,12 @@ testInfObjectClass(Config, Rule, Opts) ->
testInfObjectClass:main(Rule),
testInfObj:main(Rule).
-testParameterizedInfObj(Config) ->
- test(Config, fun testParameterizedInfObj/3).
-testParameterizedInfObj(Config, Rule, Opts) ->
- Files = ["Param","Param2"],
+testParam(Config) ->
+ test(Config, fun testParam/3, [ber,{ber,[der]},per,uper]).
+testParam(Config, Rule, Opts) ->
+ Files = ["ParamBasic","Param","Param2"],
asn1_test_lib:compile_all(Files, Config, [Rule|Opts]),
+ testParamBasic:main(Rule),
testParameterizedInfObj:main(Config, Rule),
asn1_test_lib:compile("Param", Config,
[legacy_erlang_types,Rule|Opts]),
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/Constructed.asn b/lib/asn1/test/asn1_SUITE_data/Constructed.asn
index 09a66d0c0d..bd49741726 100644
--- a/lib/asn1/test/asn1_SUITE_data/Constructed.asn
+++ b/lib/asn1/test/asn1_SUITE_data/Constructed.asn
@@ -1,6 +1,3 @@
-
-
-
Constructed DEFINITIONS ::=
BEGIN
@@ -20,4 +17,7 @@ C ::= CHOICE {
S3 ::= SEQUENCE {i INTEGER}
S3ext ::= SEQUENCE {i INTEGER, ...}
+
+OS ::= OCTET STRING
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1 b/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1
index c8145bad63..e279a180c1 100644
--- a/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1
@@ -21,6 +21,10 @@ val3-T T ::= {identification context-negotiation:{presentation-context-id 12,
transfer-syntax {1 2 3}},
data-value '123'H}
+val4-T T ::= {identification presentation-context-id:42,
+ data-value-descriptor "FooBar",
+ data-value '123'H}
+
-- EMBEDDED PDV type
EP ::= EMBEDDED PDV
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/InfObj.asn b/lib/asn1/test/asn1_SUITE_data/InfObj.asn
index 880e81c3b1..719119f418 100644
--- a/lib/asn1/test/asn1_SUITE_data/InfObj.asn
+++ b/lib/asn1/test/asn1_SUITE_data/InfObj.asn
@@ -255,6 +255,51 @@ Multiple-Optionals ::= SEQUENCE {
t3 [2] MULTIPLE-OPTIONALS.&T3 ({Multiple-Optionals-Set}{@id}) OPTIONAL
}
+-- Test different ways of constructing object sets.
+
+OBJECT-SET-TEST ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type
+} WITH SYNTAX {
+ &id IS &Type
+}
+
+ObjectSetTest{OBJECT-SET-TEST:ObjectSet} ::=
+ SEQUENCE {
+ id OBJECT-SET-TEST.&id ({ObjectSet}),
+ type OBJECT-SET-TEST.&Type ({ObjectSet}{@id})
+ }
+
+ost1 OBJECT-SET-TEST ::= { 1 IS BIT STRING }
+ost2 OBJECT-SET-TEST ::= { 2 IS OCTET STRING }
+ost3 OBJECT-SET-TEST ::= { 3 IS ENUMERATED {donald,scrooge} }
+ost4 OBJECT-SET-TEST ::= { 4 IS BOOLEAN }
+ost5 OBJECT-SET-TEST ::= { 5 IS INTEGER (0..15) }
+
+Ost12 OBJECT-SET-TEST ::= { ost1 | ost2 }
+Ost123 OBJECT-SET-TEST ::= { ost3 | Ost12 }
+Ost1234 OBJECT-SET-TEST ::= { Ost123 | ost4 }
+Ost45 OBJECT-SET-TEST ::= { ost4 | ost5 }
+Ost12345 OBJECT-SET-TEST ::= { Ost123 | Ost45 }
+
+OstSeq12 ::= ObjectSetTest{ {Ost12} }
+OstSeq123 ::= ObjectSetTest{ {Ost123} }
+OstSeq1234 ::= ObjectSetTest{ {Ost1234} }
+OstSeq45 ::= ObjectSetTest{ {Ost45} }
+OstSeq12345 ::= ObjectSetTest{ {Ost12345} }
+
+ExOst12 OBJECT-SET-TEST ::= { ost1, ..., ost2 }
+ExOst123 OBJECT-SET-TEST ::= { ost3, ..., ExOst12 }
+--ExOst1234 OBJECT-SET-TEST ::= { ExOst123, ..., ost4 }
+ExOst45 OBJECT-SET-TEST ::= { ost4, ..., ost5 }
+ExOst12345 OBJECT-SET-TEST ::= { ExOst123, ..., ExOst45 }
+
+ExOstSeq12 ::= ObjectSetTest{ {ExOst12} }
+ExOstSeq123 ::= ObjectSetTest{ {ExOst123} }
+--ExOstSeq1234 ::= ObjectSetTest{ {ExOst1234} }
+ExOstSeq45 ::= ObjectSetTest{ {ExOst45} }
+ExOstSeq12345 ::= ObjectSetTest{ {ExOst12345} }
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1 b/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
index 491bdf8956..68fc782f33 100644
--- a/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
@@ -20,4 +20,26 @@ T21 ::= General2{PrintableString}
T22 ::= General2{BIT STRING}
+
+--
+-- Test a class parameter that is the governor for another parameter.
+--
+
+AlgorithmIdentifier{ALGORITHM-TYPE, ALGORITHM-TYPE:AlgorithmSet} ::=
+ SEQUENCE {
+ algorithm ALGORITHM-TYPE.&id ({AlgorithmSet}),
+ type ALGORITHM-TYPE.&Type ({AlgorithmSet}{@algorithm})
+ }
+
+AnAlgorithm ::= AlgorithmIdentifier{ SIGNATURE-ALGORITHM,
+ { {KEY 1 CONTAINING INTEGER} |
+ {KEY 2 CONTAINING BOOLEAN} } }
+
+SIGNATURE-ALGORITHM ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type
+} WITH SYNTAX {
+ KEY &id CONTAINING &Type
+}
+
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_SUITE_data/TAGDEFAULT-AUTOMATIC.asn b/lib/asn1/test/asn1_SUITE_data/TAGDEFAULT-AUTOMATIC.asn
new file mode 100644
index 0000000000..2fcba1f71e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TAGDEFAULT-AUTOMATIC.asn
@@ -0,0 +1,25 @@
+TAGDEFAULT-AUTOMATIC DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+EXPORTS
+ Tagged,
+ Untagged,
+ Mixed
+;
+
+Tagged ::= SEQUENCE {
+ o0 [0] OCTET STRING,
+ o1 [1] OCTET STRING
+}
+
+Untagged ::= SEQUENCE {
+ o0 OCTET STRING,
+ o1 OCTET STRING
+}
+
+Mixed ::= SEQUENCE {
+ o0 OCTET STRING,
+ o2 [2] OCTET STRING
+}
+
+END
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..da07cd1118 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])
@@ -59,6 +112,7 @@ roundtrip(Mod, Type, Value) ->
roundtrip(Mod, Type, Value, ExpectedValue) ->
{ok,Encoded} = Mod:encode(Type, Value),
{ok,ExpectedValue} = Mod:decode(Type, Encoded),
+ test_ber_indefinite(Mod, Type, Encoded, ExpectedValue),
ok.
roundtrip_enc(Mod, Type, Value) ->
@@ -67,6 +121,7 @@ roundtrip_enc(Mod, Type, Value) ->
roundtrip_enc(Mod, Type, Value, ExpectedValue) ->
{ok,Encoded} = Mod:encode(Type, Value),
{ok,ExpectedValue} = Mod:decode(Type, Encoded),
+ test_ber_indefinite(Mod, Type, Encoded, ExpectedValue),
Encoded.
%%%
@@ -76,3 +131,52 @@ roundtrip_enc(Mod, Type, Value, ExpectedValue) ->
hex2num(C) when $0 =< C, C =< $9 -> C - $0;
hex2num(C) when $A =< C, C =< $F -> C - $A + 10;
hex2num(C) when $a =< C, C =< $f -> C - $a + 10.
+
+test_ber_indefinite(Mod, Type, Encoded, ExpectedValue) ->
+ case Mod:encoding_rule() of
+ ber ->
+ Indefinite = iolist_to_binary(ber_indefinite(Encoded)),
+ {ok,ExpectedValue} = Mod:decode(Type, Indefinite);
+ _ ->
+ ok
+ end.
+
+%% Rewrite all definite lengths for constructed values to an
+%% indefinite length.
+ber_indefinite(Bin0) ->
+ case ber_get_tag(Bin0) of
+ done ->
+ [];
+ primitive ->
+ Bin0;
+ {constructed,Tag,Bin1} ->
+ {Len,Bin2} = ber_get_len(Bin1),
+ <<Val0:Len/binary,Bin/binary>> = Bin2,
+ Val = iolist_to_binary(ber_indefinite(Val0)),
+ [<<Tag/binary,16#80,Val/binary,0,0>>|ber_indefinite(Bin)]
+ end.
+
+ber_get_tag(<<>>) ->
+ done;
+ber_get_tag(<<_:2,0:1,_:5,_/binary>>) ->
+ primitive;
+ber_get_tag(<<_:2,1:1,_:5,_/binary>>=Bin0) ->
+ TagLen = ber_tag_length(Bin0),
+ <<Tag:TagLen/binary,Bin/binary>> = Bin0,
+ {constructed,Tag,Bin}.
+
+ber_tag_length(<<_:3,2#11111:5,T/binary>>) ->
+ ber_tag_length_1(T, 1);
+ber_tag_length(_) ->
+ 1.
+
+ber_tag_length_1(<<1:1,_:7,T/binary>>, N) ->
+ ber_tag_length_1(T, N+1);
+ber_tag_length_1(<<0:1,_:7,_/binary>>, N) ->
+ N+1.
+
+ber_get_len(<<0:1,L:7,T/binary>>) ->
+ {L,T};
+ber_get_len(<<1:1,Octets:7,T0/binary>>) ->
+ <<L:Octets/unit:8,T/binary>> = T0,
+ {L,T}.
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
index 8be92292ee..ef11717c45 100644
--- a/lib/asn1/test/ber_decode_error.erl
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -51,4 +51,22 @@ run([]) ->
{error,{asn1,{invalid_value,_}}} =
(catch 'Constructed':decode('I', <<8,7>>)),
+ %% Short indefinite length. Make sure that the decoder doesn't look
+ %% beyond the end of binary when looking for a 0,0 terminator.
+ {error,{asn1,{invalid_length,_}}} =
+ (catch 'Constructed':decode('S', sub(<<8,16#80,0,0>>, 3))),
+ {error,{asn1,{invalid_length,_}}} =
+ (catch 'Constructed':decode('S', sub(<<8,16#80,0,0>>, 2))),
+ {error,{asn1,{invalid_length,_}}} =
+ (catch 'Constructed':decode('S', sub(<<40,16#80,1,1,255,0,0>>, 6))),
+ {error,{asn1,{invalid_length,_}}} =
+ (catch 'Constructed':decode('S', sub(<<40,16#80,1,1,255,0,0>>, 5))),
+
+ %% A primitive must not be encoded with an indefinite length.
+ {error,{asn1,{invalid_length,_}}} =
+ (catch 'Constructed':decode('OS', <<4,128,4,3,97,98,99,0,0>>)),
ok.
+
+sub(Bin, Bytes) ->
+ <<B:Bytes/binary,_/binary>> = Bin,
+ B.
diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl
index 8a0414708d..1edd60f7c8 100644
--- a/lib/asn1/test/error_SUITE.erl
+++ b/lib/asn1/test/error_SUITE.erl
@@ -20,7 +20,8 @@
-module(error_SUITE).
-export([suite/0,all/0,groups/0,
already_defined/1,bitstrings/1,enumerated/1,
- imports/1,instance_of/1,integers/1,objects/1,values/1]).
+ imports/1,instance_of/1,integers/1,objects/1,
+ parameterization/1,values/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -38,6 +39,7 @@ groups() ->
instance_of,
integers,
objects,
+ parameterization,
values]}].
parallel() ->
@@ -219,6 +221,19 @@ objects(Config) ->
} = run(P, Config),
ok.
+parameterization(Config) ->
+ M = 'Parameterization',
+ P = {M,
+ <<"Parameterization DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " NotUppercase{lowercase} ::= INTEGER (lowercase)\n"
+ "END\n">>},
+ {error,
+ [{structured_error,{'Parameterization',2},asn1ct_check,
+ {illegal_typereference,lowercase}}
+ ]
+ } = run(P, Config),
+ ok.
+
values(Config) ->
M = 'Values',
P = {M,
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
index bdd6883dac..61d1fbdd69 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -24,11 +24,21 @@
-include_lib("test_server/include/test_server.hrl").
test(Config) ->
- ValT = 'ContextSwitchingTypes':'val1-T'(),
- check_EXTERNAL(enc_dec('T', ValT)),
+ ValT_1 = 'ContextSwitchingTypes':'val1-T'(),
+ check_EXTERNAL(enc_dec('T', ValT_1)),
+
+ ValT_2 = 'ContextSwitchingTypes':'val2-T'(),
+ check_EXTERNAL(enc_dec('T', ValT_2)),
+
+ ValT_3 = 'ContextSwitchingTypes':'val3-T'(),
+ check_EXTERNAL(enc_dec('T', ValT_3)),
+
+ ValT_4 = 'ContextSwitchingTypes':'val4-T'(),
+ check_EXTERNAL(enc_dec('T', ValT_4)),
{ok,ValT2} = asn1ct:value('ContextSwitchingTypes', 'T',
[{i,?config(case_dir, Config)}]),
+ io:format("ValT2 ~p~n",[ValT2]),
check_EXTERNAL(enc_dec('T', ValT2)),
ValEP = 'ContextSwitchingTypes':'val1-EP'(),
diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl
index 311595cfda..37c134b1b9 100644
--- a/lib/asn1/test/testInfObj.erl
+++ b/lib/asn1/test/testInfObj.erl
@@ -118,7 +118,41 @@ main(_Erule) ->
roundtrip('InfObj', 'Multiple-Optionals',
{'Multiple-Optionals',1,42,true,asn1_NOVALUE}),
roundtrip('InfObj', 'Multiple-Optionals',
- {'Multiple-Optionals',1,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}).
+ {'Multiple-Optionals',1,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}),
+
+ test_objset('OstSeq12', [1,2]),
+ test_objset('OstSeq123', [1,2,3]),
+ test_objset('OstSeq1234', [1,2,3,4]),
+ test_objset('OstSeq45', [4,5]),
+ test_objset('OstSeq12345', [1,2,3,4,5]),
+
+ test_objset('ExOstSeq12', [1,2]),
+ test_objset('ExOstSeq123', [1,2,3]),
+ %%test_objset('ExOstSeq1234', [1,2,3,4]),
+ test_objset('ExOstSeq45', [4,5]),
+ test_objset('ExOstSeq12345', [1,2,3,4,5]),
+
+ ok.
+
+test_objset(Type, Keys) ->
+ _ = [test_object(Type, Key) || Key <- Keys],
+ _ = [(catch test_object(Type, Key)) ||
+ Key <- lists:seq(1, 5) -- Keys],
+ ok.
+
+test_object(T, 1) ->
+ roundtrip('InfObj', T, {T,1,<<42:7>>});
+test_object(T, 2) ->
+ roundtrip('InfObj', T, {T,2,<<"abc">>});
+test_object(T, 3) ->
+ roundtrip('InfObj', T, {T,3,donald}),
+ roundtrip('InfObj', T, {T,3,scrooge});
+test_object(T, 4) ->
+ roundtrip('InfObj', T, {T,4,true}),
+ roundtrip('InfObj', T, {T,4,false});
+test_object(T, 5) ->
+ roundtrip('InfObj', T, {T,5,0}),
+ roundtrip('InfObj', T, {T,5,15}).
roundtrip(M, T, V) ->
asn1_test_lib:roundtrip(M, T, V).
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/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl
index 3db89ca174..39f7947e8d 100644
--- a/lib/asn1/test/testParamBasic.erl
+++ b/lib/asn1/test/testParamBasic.erl
@@ -43,6 +43,9 @@ main(Rules) ->
#'T12'{number=11,string = <<10:4>>});
_ -> ok
end,
+ roundtrip('AnAlgorithm', {'AnAlgorithm',1,42}),
+ roundtrip('AnAlgorithm', {'AnAlgorithm',2,true}),
+ roundtrip('AnAlgorithm', {'AnAlgorithm',2,false}),
ok.
roundtrip(Type, Value) ->
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..daaf26a17f 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.3
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/Makefile b/lib/common_test/doc/src/Makefile
index 99161ce68a..57233a7f6c 100644
--- a/lib/common_test/doc/src/Makefile
+++ b/lib/common_test/doc/src/Makefile
@@ -47,6 +47,7 @@ CT_MODULES = \
ct_snmp \
unix_telnet \
ct_slave \
+ ct_property_test \
ct_netconfc
CT_XML_FILES = $(CT_MODULES:=.xml)
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..94738d2eff 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -32,6 +32,207 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The source code to html code generator in Test Server
+ (and Common Test) would fail to generate anchors in the
+ html code for functions with non-expandable macros,
+ resulting in bad html links to such functions. This
+ correction lets the code generator ignore macros that
+ can't be expanded (i.e. not pre-process them), so that
+ correct anchors will always be produced.</p>
+ <p>
+ Own Id: OTP-11766 Aux Id: seq12556 </p>
+ </item>
+ <item>
+ <p>
+ OTP-11971 erroneously changed the handling of relative
+ paths (import/export files) specified in the cover spec
+ file. This is now corrected so these are expected to be
+ relative to the directory where the cover spec file
+ itself is stored.</p>
+ <p>
+ Own Id: OTP-12031</p>
+ </item>
+ <item>
+ <p>
+ Common Test would sometimes crash while trying to print
+ large amounts of SASL reports to log on a computer with a
+ slow file system. This problem (due to an error in IO
+ message buffering in ct_logs) has been fixed.</p>
+ <p>
+ Own Id: OTP-12159</p>
+ </item>
+ <item>
+ <p>
+ The common_test telnet client, ct_telnet and friends, had
+ some unstable test cases. Some of these were caused by
+ the unix_telnet callback sending an extra newline after
+ sending the password. This caused the sever to send an
+ extra prompt back which confused the tests. The extra
+ newline is no longer sent.</p>
+ <p>
+ Also, debug printouts and logging from the telnet client
+ is improved, and some test cases are slightly modified in
+ order to stabilize the test.</p>
+ <p>
+ Own Id: OTP-12329</p>
+ </item>
+ <item>
+ <p>
+ ct_netconfc did not expect the return value
+ {error,timeout} from ssh_connection:subsystem/4. This has
+ been corrected.</p>
+ <p>
+ Own Id: OTP-12334</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A new option, <c>{newline,boolean()}</c> is added to all
+ functions in <c>ct_telnet</c> that send data (command
+ strings) to the telnet server. By default,
+ <c>ct_telnet</c> adds a newline to all command strings,
+ and by setting the new option to <c>false</c> this
+ behavior is turned off.</p>
+ <p>
+ Own Id: OTP-12252 Aux Id: seq12730 </p>
+ </item>
+ <item>
+ <p>
+ Distribute <c>autoconf</c> helpers to applications at
+ build time instead of having multiple identical copies
+ committed in the repository.</p>
+ <p>
+ Own Id: OTP-12348</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Ticket OTP-11971 introduced a runtime dependency towards
+ test_server-3.7.1, since the interface between
+ test_server and common_test was changed. Erroneously, the
+ common_test.app file was not updated according to this.
+ This has now been corrected.</p>
+ <p>
+ Own Id: OTP-12037</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Warning: this is experimental and may disappear or change
+ without previous warning.</p>
+ <p>
+ Experimental support for running Quickcheck and PropEr
+ tests from common_test suites is added to common_test.
+ See the reference manual for the new module
+ <c>ct_property_testing</c>.</p>
+ <p>
+ Experimental property tests are added under
+ <c>lib/{inet,ssh}/test/property_test</c>. They can be run
+ directly or from the commont_test suites
+ <c>inet/ftp_property_test_SUITE.erl</c> and
+ <c>ssh/test/ssh_property_test_SUITE.erl</c>.</p>
+ <p>
+ See the code in the <c>test</c> directories and the man
+ page for details.</p>
+ <p>
+ (Thanks to Tuncer Ayaz for a patch adding Triq)</p>
+ <p>
+ Own Id: OTP-12119</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml
index 2f5c892e60..c266b70d00 100644
--- a/lib/common_test/doc/src/ref_man.xml
+++ b/lib/common_test/doc/src/ref_man.xml
@@ -78,6 +78,7 @@
<xi:include href="unix_telnet.xml"/>
<xi:include href="ct_slave.xml"/>
<xi:include href="ct_hooks.xml"/>
+ <xi:include href="ct_property_test.xml"/>
</application>
diff --git a/lib/common_test/priv/auxdir/config.guess b/lib/common_test/priv/auxdir/config.guess
deleted file mode 100755
index f475ceb413..0000000000
--- a/lib/common_test/priv/auxdir/config.guess
+++ /dev/null
@@ -1,1534 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-#
-# Originally written by Per Bothner.
-#
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-#
-# Please send patches with a ChangeLog entry to [email protected].
-
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# ([email protected] 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:Bitrig:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # [email protected] (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH="x86_64"
- fi
- fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[4567])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep -q __LP64__
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- aarch64_be:Linux:*:*)
- UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_PCS_VFP
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
- fi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- or32:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
- # Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
- # this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- OS_REL='.3'
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <[email protected]>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
- x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
- exit ;;
-esac
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <[email protected]> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/lib/common_test/priv/auxdir/config.sub b/lib/common_test/priv/auxdir/config.sub
deleted file mode 100755
index bb6edbdb47..0000000000
--- a/lib/common_test/priv/auxdir/config.sub
+++ /dev/null
@@ -1,1789 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-
-
-# Please send patches with a ChangeLog entry to [email protected].
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | be32 | be64 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 \
- | or1k | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pyramid \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | we32k \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
- ;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- xscaleeb)
- basic_machine=armeb-unknown
- ;;
-
- xscaleel)
- basic_machine=armel-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pyramid-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i386-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
- ;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -dicos*)
- os=-dicos
- ;;
- -nacl*)
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- hexagon-*)
- os=-elf
- ;;
- tic54x-*)
- os=-coff
- ;;
- tic55x-*)
- os=-coff
- ;;
- tic6x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or1k-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -cnk*|-aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
-
diff --git a/lib/common_test/priv/auxdir/install-sh b/lib/common_test/priv/auxdir/install-sh
deleted file mode 100755
index a5897de6ea..0000000000
--- a/lib/common_test/priv/auxdir/install-sh
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
- --help display this help and exit.
- --version display version info and exit.
-
- -c (ignored)
- -C install only if different (preserve the last data modification time)
- -d create directories instead of installing files.
- -g GROUP $chgrpprog installed files to GROUP.
- -m MODE $chmodprog installed files to MODE.
- -o USER $chownprog installed files to USER.
- -s $stripprog installed files.
- -t DIRECTORY install into DIRECTORY.
- -T report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
- RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) ;;
-
- -C) copy_on_change=true;;
-
- -d) dir_arg=true;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
-
- -o) chowncmd="$chownprog $2"
- shift;;
-
- -s) stripcmd=$stripprog;;
-
- -t) dst_arg=$2
- shift;;
-
- -T) no_target_directory=true;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
- shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dst_arg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dst_arg"
- shift # fnord
- fi
- shift # arg
- dst_arg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dst_arg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix='/';;
- -*) prefix='./';;
- *) prefix='';;
- esac
-
- eval "$initialize_posix_glob"
-
- oIFS=$IFS
- IFS=/
- $posix_glob set -f
- set fnord $dstdir
- shift
- $posix_glob set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # If -C, don't bother to copy if it wouldn't change the file.
- if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
- set X $old && old=:$2:$4:$5:$6 &&
- set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
- test "$old" = "$new" &&
- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
- then
- rm -f "$dsttmp"
- else
- # Rename the file to the real destination.
- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
- {
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- fi || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
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/Makefile b/lib/common_test/src/Makefile
index 4600c0ad78..8d74546880 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -74,7 +74,8 @@ MODULES= \
ct_netconfc \
ct_conn_log_h \
cth_conn_log \
- ct_groups
+ ct_groups \
+ ct_property_test
TARGET_MODULES= $(MODULES:%=$(EBIN)/%)
BEAM_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src
index e28751fb59..580d5dbd7b 100644
--- a/lib/common_test/src/common_test.app.src
+++ b/lib/common_test/src/common_test.app.src
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. 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
@@ -64,7 +64,7 @@
{applications, [kernel,stdlib]},
{env, []},
{runtime_dependencies,["xmerl-1.3.7","webtool-0.8.10","tools-2.6.14",
- "test_server-3.7","stdlib-2.0","ssh-3.0.1",
+ "test_server-3.7.1","stdlib-2.0","ssh-3.0.1",
"snmp-4.25.1","sasl-2.4","runtime_tools-1.8.14",
"kernel-3.0","inets-5.10","erts-6.0",
"debugger-4.0","crypto-3.3","compiler-5.0"]}]}.
diff --git a/lib/common_test/src/ct_cover.erl b/lib/common_test/src/ct_cover.erl
index ae671c750a..b630a51835 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.
@@ -124,20 +128,20 @@ get_spec(File) ->
catch get_spec_test(File).
get_spec_test(File) ->
- FullName = filename:absname(File),
- case filelib:is_file(FullName) of
+ Dir = filename:dirname(File), % always abs path in here, set in ct_run
+ case filelib:is_file(File) of
true ->
- case file:consult(FullName) of
+ case file:consult(File) of
{ok,Terms} ->
Import =
case lists:keysearch(import, 1, Terms) of
{value,{_,Imps=[S|_]}} when is_list(S) ->
ImpsFN = lists:map(fun(F) ->
- filename:absname(F)
+ filename:absname(F,Dir)
end, Imps),
test_files(ImpsFN, ImpsFN);
{value,{_,Imp=[IC|_]}} when is_integer(IC) ->
- ImpFN = filename:absname(Imp),
+ ImpFN = filename:absname(Imp,Dir),
test_files([ImpFN], [ImpFN]);
_ ->
[]
@@ -145,11 +149,11 @@ get_spec_test(File) ->
Export =
case lists:keysearch(export, 1, Terms) of
{value,{_,Exp=[EC|_]}} when is_integer(EC) ->
- filename:absname(Exp);
+ filename:absname(Exp,Dir);
{value,{_,[Exp]}} ->
- filename:absname(Exp);
+ filename:absname(Exp,Dir);
_ ->
- []
+ undefined
end,
Nodes =
case lists:keysearch(nodes, 1, Terms) of
@@ -170,12 +174,12 @@ get_spec_test(File) ->
[] -> [#cover{app=none, level=details}];
_ -> Res
end,
- case get_cover_opts(Apps, Terms, []) of
+ case get_cover_opts(Apps, Terms, Dir, []) of
E = {error,_} ->
E;
[CoverSpec] ->
CoverSpec1 = remove_excludes_and_dups(CoverSpec),
- {FullName,Nodes,Import,Export,CoverSpec1};
+ {File,Nodes,Import,Export,CoverSpec1};
_ ->
{error,multiple_apps_in_cover_spec}
end;
@@ -186,7 +190,7 @@ get_spec_test(File) ->
{error,{invalid_cover_spec,Error}}
end;
false ->
- {error,{cant_read_cover_spec_file,FullName}}
+ {error,{cant_read_cover_spec_file,File}}
end.
collect_apps([{level,Level}|Ts], Apps) ->
@@ -201,124 +205,125 @@ collect_apps([], Apps) ->
%% get_cover_opts(Terms) -> AppCoverInfo
%% AppCoverInfo: [#cover{app=App,...}]
-get_cover_opts([App | Apps], Terms, CoverInfo) ->
- case get_app_info(App, Terms) of
+get_cover_opts([App | Apps], Terms, Dir, CoverInfo) ->
+ case get_app_info(App, Terms, Dir) of
E = {error,_} -> E;
AppInfo ->
AppInfo1 = files2mods(AppInfo),
- get_cover_opts(Apps, Terms, [AppInfo1|CoverInfo])
+ get_cover_opts(Apps, Terms, Dir, [AppInfo1|CoverInfo])
end;
-get_cover_opts([], _, CoverInfo) ->
+get_cover_opts([], _, _, CoverInfo) ->
lists:reverse(CoverInfo).
-%% get_app_info(App, Terms) -> App1
+%% get_app_info(App, Terms, Dir) -> App1
-get_app_info(App=#cover{app=none}, [{incl_dirs,Dirs}|Terms]) ->
- get_app_info(App, [{incl_dirs,none,Dirs}|Terms]);
-get_app_info(App=#cover{app=Name}, [{incl_dirs,Name,Dirs}|Terms]) ->
- case get_files(Dirs, ".beam", false, []) of
+get_app_info(App=#cover{app=none}, [{incl_dirs,Dirs}|Terms], Dir) ->
+ get_app_info(App, [{incl_dirs,none,Dirs}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{incl_dirs,Name,Dirs}|Terms], Dir) ->
+ case get_files(Dirs, Dir, ".beam", false, []) of
E = {error,_} -> E;
Mods1 ->
Mods = App#cover.incl_mods,
- get_app_info(App#cover{incl_mods=Mods++Mods1},Terms)
+ get_app_info(App#cover{incl_mods=Mods++Mods1},Terms,Dir)
end;
-get_app_info(App=#cover{app=none}, [{incl_dirs_r,Dirs}|Terms]) ->
- get_app_info(App, [{incl_dirs_r,none,Dirs}|Terms]);
-get_app_info(App=#cover{app=Name}, [{incl_dirs_r,Name,Dirs}|Terms]) ->
- case get_files(Dirs, ".beam", true, []) of
+get_app_info(App=#cover{app=none}, [{incl_dirs_r,Dirs}|Terms], Dir) ->
+ get_app_info(App, [{incl_dirs_r,none,Dirs}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{incl_dirs_r,Name,Dirs}|Terms], Dir) ->
+ case get_files(Dirs, Dir, ".beam", true, []) of
E = {error,_} -> E;
Mods1 ->
Mods = App#cover.incl_mods,
- get_app_info(App#cover{incl_mods=Mods++Mods1},Terms)
+ get_app_info(App#cover{incl_mods=Mods++Mods1},Terms,Dir)
end;
-get_app_info(App=#cover{app=none}, [{incl_mods,Mods1}|Terms]) ->
- get_app_info(App, [{incl_mods,none,Mods1}|Terms]);
-get_app_info(App=#cover{app=Name}, [{incl_mods,Name,Mods1}|Terms]) ->
+get_app_info(App=#cover{app=none}, [{incl_mods,Mods1}|Terms], Dir) ->
+ get_app_info(App, [{incl_mods,none,Mods1}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{incl_mods,Name,Mods1}|Terms], Dir) ->
Mods = App#cover.incl_mods,
- get_app_info(App#cover{incl_mods=Mods++Mods1},Terms);
+ get_app_info(App#cover{incl_mods=Mods++Mods1},Terms,Dir);
-get_app_info(App=#cover{app=none}, [{excl_dirs,Dirs}|Terms]) ->
- get_app_info(App, [{excl_dirs,none,Dirs}|Terms]);
-get_app_info(App=#cover{app=Name}, [{excl_dirs,Name,Dirs}|Terms]) ->
- case get_files(Dirs, ".beam", false, []) of
+get_app_info(App=#cover{app=none}, [{excl_dirs,Dirs}|Terms], Dir) ->
+ get_app_info(App, [{excl_dirs,none,Dirs}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{excl_dirs,Name,Dirs}|Terms], Dir) ->
+ case get_files(Dirs, Dir, ".beam", false, []) of
E = {error,_} -> E;
Mods1 ->
Mods = App#cover.excl_mods,
- get_app_info(App#cover{excl_mods=Mods++Mods1},Terms)
+ get_app_info(App#cover{excl_mods=Mods++Mods1},Terms,Dir)
end;
-get_app_info(App=#cover{app=none}, [{excl_dirs_r,Dirs}|Terms]) ->
- get_app_info(App, [{excl_dirs_r,none,Dirs}|Terms]);
-get_app_info(App=#cover{app=Name}, [{excl_dirs_r,Name,Dirs}|Terms]) ->
- case get_files(Dirs, ".beam", true, []) of
+get_app_info(App=#cover{app=none}, [{excl_dirs_r,Dirs}|Terms],Dir) ->
+ get_app_info(App, [{excl_dirs_r,none,Dirs}|Terms],Dir);
+get_app_info(App=#cover{app=Name}, [{excl_dirs_r,Name,Dirs}|Terms],Dir) ->
+ case get_files(Dirs, Dir, ".beam", true, []) of
E = {error,_} -> E;
Mods1 ->
Mods = App#cover.excl_mods,
- get_app_info(App#cover{excl_mods=Mods++Mods1},Terms)
+ get_app_info(App#cover{excl_mods=Mods++Mods1},Terms,Dir)
end;
-get_app_info(App=#cover{app=none}, [{excl_mods,Mods1}|Terms]) ->
- get_app_info(App, [{excl_mods,none,Mods1}|Terms]);
-get_app_info(App=#cover{app=Name}, [{excl_mods,Name,Mods1}|Terms]) ->
+get_app_info(App=#cover{app=none}, [{excl_mods,Mods1}|Terms], Dir) ->
+ get_app_info(App, [{excl_mods,none,Mods1}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{excl_mods,Name,Mods1}|Terms], Dir) ->
Mods = App#cover.excl_mods,
- get_app_info(App#cover{excl_mods=Mods++Mods1},Terms);
+ get_app_info(App#cover{excl_mods=Mods++Mods1},Terms,Dir);
-get_app_info(App=#cover{app=none}, [{cross,Cross}|Terms]) ->
- get_app_info(App, [{cross,none,Cross}|Terms]);
-get_app_info(App=#cover{app=Name}, [{cross,Name,Cross1}|Terms]) ->
+get_app_info(App=#cover{app=none}, [{cross,Cross}|Terms], Dir) ->
+ get_app_info(App, [{cross,none,Cross}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{cross,Name,Cross1}|Terms], Dir) ->
Cross = App#cover.cross,
- get_app_info(App#cover{cross=Cross++Cross1},Terms);
+ get_app_info(App#cover{cross=Cross++Cross1},Terms,Dir);
-get_app_info(App=#cover{app=none}, [{src_dirs,Dirs}|Terms]) ->
- get_app_info(App, [{src_dirs,none,Dirs}|Terms]);
-get_app_info(App=#cover{app=Name}, [{src_dirs,Name,Dirs}|Terms]) ->
- case get_files(Dirs, ".erl", false, []) of
+get_app_info(App=#cover{app=none}, [{src_dirs,Dirs}|Terms], Dir) ->
+ get_app_info(App, [{src_dirs,none,Dirs}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{src_dirs,Name,Dirs}|Terms], Dir) ->
+ case get_files(Dirs, Dir, ".erl", false, []) of
E = {error,_} -> E;
Src1 ->
Src = App#cover.src,
- get_app_info(App#cover{src=Src++Src1},Terms)
+ get_app_info(App#cover{src=Src++Src1},Terms,Dir)
end;
-get_app_info(App=#cover{app=none}, [{src_dirs_r,Dirs}|Terms]) ->
- get_app_info(App, [{src_dirs_r,none,Dirs}|Terms]);
-get_app_info(App=#cover{app=Name}, [{src_dirs_r,Name,Dirs}|Terms]) ->
- case get_files(Dirs, ".erl", true, []) of
+get_app_info(App=#cover{app=none}, [{src_dirs_r,Dirs}|Terms], Dir) ->
+ get_app_info(App, [{src_dirs_r,none,Dirs}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{src_dirs_r,Name,Dirs}|Terms], Dir) ->
+ case get_files(Dirs, Dir, ".erl", true, []) of
E = {error,_} -> E;
Src1 ->
Src = App#cover.src,
- get_app_info(App#cover{src=Src++Src1},Terms)
+ get_app_info(App#cover{src=Src++Src1},Terms,Dir)
end;
-get_app_info(App=#cover{app=none}, [{src_files,Src1}|Terms]) ->
- get_app_info(App, [{src_files,none,Src1}|Terms]);
-get_app_info(App=#cover{app=Name}, [{src_files,Name,Src1}|Terms]) ->
+get_app_info(App=#cover{app=none}, [{src_files,Src1}|Terms], Dir) ->
+ get_app_info(App, [{src_files,none,Src1}|Terms], Dir);
+get_app_info(App=#cover{app=Name}, [{src_files,Name,Src1}|Terms], Dir) ->
Src = App#cover.src,
- get_app_info(App#cover{src=Src++Src1},Terms);
+ get_app_info(App#cover{src=Src++Src1},Terms,Dir);
-get_app_info(App, [_|Terms]) ->
- get_app_info(App, Terms);
+get_app_info(App, [_|Terms], Dir) ->
+ get_app_info(App, Terms, Dir);
-get_app_info(App, []) ->
+get_app_info(App, [], _) ->
App.
%% get_files(...)
-get_files([Dir|Dirs], Ext, Recurse, Files) ->
- case file:list_dir(Dir) of
+get_files([Dir|Dirs], RootDir, Ext, Recurse, Files) ->
+ DirAbs = filename:absname(Dir, RootDir),
+ case file:list_dir(DirAbs) of
{ok,Entries} ->
- {SubDirs,Matches} = analyse_files(Entries, Dir, Ext, [], []),
+ {SubDirs,Matches} = analyse_files(Entries, DirAbs, Ext, [], []),
if Recurse == false ->
- get_files(Dirs, Ext, Recurse, Files++Matches);
+ get_files(Dirs, RootDir, Ext, Recurse, Files++Matches);
true ->
- Files1 = get_files(SubDirs, Ext, Recurse, Files++Matches),
- get_files(Dirs, Ext, Recurse, Files1)
+ Files1 = get_files(SubDirs, RootDir, Ext, Recurse, Files++Matches),
+ get_files(Dirs, RootDir, Ext, Recurse, Files1)
end;
{error,Reason} ->
- {error,{Reason,Dir}}
+ {error,{Reason,DirAbs}}
end;
-get_files([], _Ext, _R, Files) ->
+get_files([], _RootDir, _Ext, _R, Files) ->
Files.
%% analyse_files(...)
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..7037cdca73 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").
@@ -128,7 +129,13 @@ datestr_from_dirname([]) ->
close(Info, StartDir) ->
%% close executes on the ct_util process, not on the logger process
%% so we need to use a local copy of the log cache data
- LogCacheBin = make_last_run_index(),
+ LogCacheBin =
+ case make_last_run_index() of
+ {error,_} -> % log server not responding
+ undefined;
+ LCB ->
+ LCB
+ end,
put(ct_log_cache,LogCacheBin),
Cache2File = fun() ->
case get(ct_log_cache) of
@@ -709,6 +716,7 @@ logger_loop(State) ->
end
end,
if Importance >= (100-VLvl) ->
+ CtLogFd = State#logger_state.ct_log_fd,
case get_groupleader(Pid, GL, State) of
{tc_log,TCGL,TCGLs} ->
case erlang:is_process_alive(TCGL) of
@@ -722,14 +730,15 @@ logger_loop(State) ->
%% Group leader is dead, so write to the
%% CtLog or unexpected_io log instead
unexpected_io(Pid,Category,Importance,
- List,State),
+ List,CtLogFd),
+
logger_loop(State)
end;
{ct_log,_Fd,TCGLs} ->
%% If category is ct_internal then write
%% to ct_log, else write to unexpected_io
%% log
- unexpected_io(Pid,Category,Importance,List,State),
+ unexpected_io(Pid,Category,Importance,List,CtLogFd),
logger_loop(State#logger_state{
tc_groupleaders = TCGLs})
end;
@@ -802,16 +811,15 @@ logger_loop(State) ->
ok
end.
-create_io_fun(FromPid, State) ->
+create_io_fun(FromPid, CtLogFd) ->
%% we have to build one io-list of all strings
%% before printing, or other io printouts (made in
%% parallel) may get printed between this header
%% and footer
- Fd = State#logger_state.ct_log_fd,
fun({Str,Args}, IoList) ->
case catch io_lib:format(Str,Args) of
{'EXIT',_Reason} ->
- io:format(Fd, "Logging fails! Str: ~p, Args: ~p~n",
+ io:format(CtLogFd, "Logging fails! Str: ~p, Args: ~p~n",
[Str,Args]),
%% stop the testcase, we need to see the fault
exit(FromPid, {log_printout_error,Str,Args}),
@@ -826,28 +834,53 @@ create_io_fun(FromPid, State) ->
print_to_log(sync, FromPid, Category, TCGL, List, State) ->
%% in some situations (exceptions), the printout is made from the
%% test server IO process and there's no valid group leader to send to
+ CtLogFd = State#logger_state.ct_log_fd,
if FromPid /= TCGL ->
- IoFun = create_io_fun(FromPid, State),
+ IoFun = create_io_fun(FromPid, CtLogFd),
io:format(TCGL,"~ts", [lists:foldl(IoFun, [], List)]);
true ->
- unexpected_io(FromPid,Category,?MAX_IMPORTANCE,List,State)
+ unexpected_io(FromPid,Category,?MAX_IMPORTANCE,List,CtLogFd)
end,
State;
print_to_log(async, FromPid, Category, TCGL, List, State) ->
%% in some situations (exceptions), the printout is made from the
%% test server IO process and there's no valid group leader to send to
+ CtLogFd = State#logger_state.ct_log_fd,
Printer =
if FromPid /= TCGL ->
- IoFun = create_io_fun(FromPid, State),
+ IoFun = create_io_fun(FromPid, CtLogFd),
fun() ->
test_server:permit_io(TCGL, self()),
- io:format(TCGL, "~ts", [lists:foldl(IoFun, [], List)])
+
+ %% Since asynchronous io gets can get buffered if
+ %% the file system is slow, there is also a risk that
+ %% the group leader has terminated before we get to
+ %% the io:format(GL, ...) call. We check this and
+ %% print "expired" messages to the unexpected io
+ %% log instead (best we can do).
+
+ case erlang:is_process_alive(TCGL) of
+ true ->
+ try io:format(TCGL, "~ts",
+ [lists:foldl(IoFun,[],List)]) of
+ _ -> ok
+ catch
+ _:terminated ->
+ unexpected_io(FromPid, Category,
+ ?MAX_IMPORTANCE,
+ List, CtLogFd)
+ end;
+ false ->
+ unexpected_io(FromPid, Category,
+ ?MAX_IMPORTANCE,
+ List, CtLogFd)
+ end
end;
true ->
fun() ->
- unexpected_io(FromPid,Category,?MAX_IMPORTANCE,
- List,State)
+ unexpected_io(FromPid, Category, ?MAX_IMPORTANCE,
+ List, CtLogFd)
end
end,
case State#logger_state.async_print_jobs of
@@ -1304,7 +1337,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 +1402,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 +1422,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 +1566,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 +1724,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 +1740,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 +1890,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];
@@ -3120,12 +3181,11 @@ html_encoding(latin1) ->
html_encoding(utf8) ->
"utf-8".
-unexpected_io(Pid,ct_internal,_Importance,List,State) ->
- IoFun = create_io_fun(Pid,State),
- io:format(State#logger_state.ct_log_fd, "~ts",
- [lists:foldl(IoFun, [], List)]);
-unexpected_io(Pid,_Category,_Importance,List,State) ->
- IoFun = create_io_fun(Pid,State),
+unexpected_io(Pid,ct_internal,_Importance,List,CtLogFd) ->
+ IoFun = create_io_fun(Pid,CtLogFd),
+ io:format(CtLogFd, "~ts", [lists:foldl(IoFun, [], List)]);
+unexpected_io(Pid,_Category,_Importance,List,CtLogFd) ->
+ IoFun = create_io_fun(Pid,CtLogFd),
Data = io_lib:format("~ts", [lists:foldl(IoFun, [], List)]),
test_server_io:print_unexpected(Data),
ok.
diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl
index a3861dc745..bded5a15cb 100644
--- a/lib/common_test/src/ct_netconfc.erl
+++ b/lib/common_test/src/ct_netconfc.erl
@@ -1858,7 +1858,9 @@ ssh_open(#options{host=Host,timeout=Timeout,port=Port,ssh=SshOpts,name=Name}) ->
name = Name}};
failure ->
ssh:close(CM),
- {error,{ssh,could_not_execute_netconf_subsystem}}
+ {error,{ssh,could_not_execute_netconf_subsystem}};
+ {error,timeout} ->
+ {error,{ssh,could_not_execute_netconf_subsystem,timeout}}
end;
{error, Reason} ->
ssh:close(CM),
diff --git a/lib/common_test/src/ct_property_test.erl b/lib/common_test/src/ct_property_test.erl
new file mode 100644
index 0000000000..52acda5388
--- /dev/null
+++ b/lib/common_test/src/ct_property_test.erl
@@ -0,0 +1,186 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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%
+%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%% @doc EXPERIMENTAL support in common-test for calling property based tests.
+%%%
+%%% <p>This module is a first step towards running Property Based testing in the
+%%% Common Test framework. A property testing tool like QuickCheck or PropEr is
+%%% assumed to be installed.</p>
+%%%
+%%% <p>The idea is to have a common_test testsuite calling a property testing
+%%% tool with special property test suites as defined by that tool. In this manual
+%%% we assume the usual Erlang Application directory structure. The tests are
+%%% collected in the application's <c>test</c> directory. The test directory
+%%% has a sub-directory called <c>property_test</c> where everything needed for
+%%% the property tests are collected.</p>
+%%%
+%%% <p>A typical ct test suite using <c>ct_property_test</c> is organized as follows:
+%%% </p>
+%%% ```
+%%% -include_lib("common_test/include/ct.hrl").
+%%%
+%%% all() -> [prop_ftp_case].
+%%%
+%%% init_per_suite(Config) ->
+%%% ct_property_test:init_per_suite(Config).
+%%%
+%%% %%%---- test case
+%%% prop_ftp_case(Config) ->
+%%% ct_property_test:quickcheck(
+%%% ftp_simple_client_server:prop_ftp(Config),
+%%% Config
+%%% ).
+%%% '''
+%%%
+%%% <warning>
+%%% <p>
+%%% This is experimental code which may be changed or removed
+%%% anytime without any warning.
+%%% </p>
+%%% </warning>
+%%%
+%%% @end
+
+-module(ct_property_test).
+
+%% API
+-export([init_per_suite/1,
+ quickcheck/2]).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%%-----------------------------------------------------------------
+%%% @spec init_per_suite(Config) -> Config | {skip,Reason}
+%%%
+%%% @doc Initializes Config for property testing.
+%%%
+%%% <p>The function investigates if support is available for either Quickcheck, PropEr,
+%%% or Triq.
+%%% The options <c>{property_dir,AbsPath}</c> and
+%%% <c>{property_test_tool,Tool}</c> is set in the Config returned.</p>
+%%% <p>The function is intended to be called in the init_per_suite in the test suite.</p>
+%%% <p>The property tests are assumed to be in the subdirectory <c>property_test</c>.</p>
+%%% @end
+
+init_per_suite(Config) ->
+ case which_module_exists([eqc,proper,triq]) of
+ {ok,ToolModule} ->
+ ct:pal("Found property tester ~p",[ToolModule]),
+ Path = property_tests_path("property_test", Config),
+ case compile_tests(Path,ToolModule) of
+ error ->
+ {fail, "Property test compilation failed in "++Path};
+ up_to_date ->
+ add_code_pathz(Path),
+ [{property_dir,Path},
+ {property_test_tool,ToolModule} | Config]
+ end;
+
+ not_found ->
+ ct:pal("No property tester found",[]),
+ {skip, "No property testing tool found"}
+ end.
+
+%%%-----------------------------------------------------------------
+%%% @spec quickcheck(Property, Config) -> true | {fail,Reason}
+%%%
+%%% @doc Call quickcheck and return the result in a form suitable for common_test.
+%%%
+%%% <p>The function is intended to be called in the test cases in the test suite.</p>
+%%% @end
+
+quickcheck(Property, Config) ->
+ Tool = proplists:get_value(property_test_tool,Config),
+ F = function_name(quickcheck, Tool),
+ mk_ct_return( Tool:F(Property), Tool ).
+
+
+%%%================================================================
+%%%
+%%% Local functions
+%%%
+
+%%% Make return values back to the calling Common Test suite
+mk_ct_return(true, _Tool) ->
+ true;
+mk_ct_return(Other, Tool) ->
+ try lists:last(hd(Tool:counterexample()))
+ of
+ {set,{var,_},{call,M,F,Args}} ->
+ {fail, io_lib:format("~p:~p/~p returned bad result",[M,F,length(Args)])}
+ catch
+ _:_ ->
+ {fail, Other}
+ end.
+
+%%% Check if a property testing tool is found
+which_module_exists([Module|Modules]) ->
+ case module_exists(Module) of
+ true -> {ok,Module};
+ false -> which_module_exists(Modules)
+ end;
+which_module_exists(_) ->
+ not_found.
+
+module_exists(Module) ->
+ is_list(catch Module:module_info()).
+
+%%% The path to the property tests
+property_tests_path(Dir, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ filename:join(lists:droplast(filename:split(DataDir))++[Dir]).
+
+%%% Extend the code path with Dir if it not already present
+add_code_pathz(Dir) ->
+ case lists:member(Dir, code:get_path()) of
+ true -> ok;
+ false -> code:add_pathz(Dir)
+ end.
+
+compile_tests(Path, ToolModule) ->
+ MacroDefs = macro_def(ToolModule),
+ {ok,Cwd} = file:get_cwd(),
+ ok = file:set_cwd(Path),
+ {ok,FileNames} = file:list_dir("."),
+ BeamFiles = [F || F<-FileNames,
+ filename:extension(F) == ".beam"],
+ [file:delete(F) || F<-BeamFiles],
+ ct:pal("Compiling in ~p:~n Deleted ~p~n MacroDefs=~p",[Path,BeamFiles,MacroDefs]),
+ Result = make:all([load|MacroDefs]),
+ file:set_cwd(Cwd),
+ Result.
+
+
+macro_def(eqc) -> [{d, 'EQC'}];
+macro_def(proper) -> [{d, 'PROPER'}];
+macro_def(triq) -> [{d, 'TRIQ'}].
+
+function_name(quickcheck, triq) -> check;
+function_name(F, _) -> F.
+
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index 03cf06abed..4a12481214 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
@@ -293,10 +293,10 @@ script_start1(Parent, Args) ->
application:set_env(common_test, auto_compile, true),
InclDirs =
case proplists:get_value(include, Args) of
- Incl when is_list(hd(Incl)) ->
- Incl;
+ Incls when is_list(hd(Incls)) ->
+ [filename:absname(IDir) || IDir <- Incls];
Incl when is_list(Incl) ->
- [Incl];
+ [filename:absname(Incl)];
undefined ->
[]
end,
@@ -774,7 +774,8 @@ script_usage() ->
"\n\t[-basic_html]\n\n"),
io:format("Run tests from command line:\n\n"
"\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |"
- "\n\t[-suite Suite1 Suite2 .. SuiteN [-case Case1 Case2 .. CaseN]]"
+ "\n\t[[-dir TestDir] -suite Suite1 Suite2 .. SuiteN"
+ "\n\t [[-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]]]"
"\n\t[-step [config | keep_inactive]]"
"\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
"\n\t[-userconfig CallbackModule ConfigFile1 .. ConfigFileN]"
@@ -1023,10 +1024,10 @@ run_test2(StartOpts) ->
case proplists:get_value(include, StartOpts) of
undefined ->
[];
- Incl when is_list(hd(Incl)) ->
- Incl;
+ Incls when is_list(hd(Incls)) ->
+ [filename:absname(IDir) || IDir <- Incls];
Incl when is_list(Incl) ->
- [Incl]
+ [filename:absname(Incl)]
end,
case os:getenv("CT_INCLUDE_PATH") of
false ->
@@ -1393,6 +1394,7 @@ run_testspec2(TestSpec) ->
EnvInclude++Opts#opts.include
end,
application:set_env(common_test, include, AllInclude),
+
LogDir1 = which(logdir,Opts#opts.logdir),
case check_and_install_configfiles(
Opts#opts.config, LogDir1, Opts) of
@@ -1646,7 +1648,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 +1672,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 +1697,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 +2132,19 @@ 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,
+ %% test_server needs to know the include path too
+ InclPath = case application:get_env(common_test, include) of
+ {ok,Incls} -> Incls;
+ _ -> []
+ end,
+ application:set_env(test_server, include, InclPath),
+
+ test_server_ctrl:start_link(local),
%% let test_server expand the test tuples and count no of cases
{Suites,NoOfCases} = count_test_cases(Tests, Skip),
@@ -2231,24 +2169,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 +2226,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/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl
index 3b2652d06c..babe73e575 100644
--- a/lib/common_test/src/ct_telnet.erl
+++ b/lib/common_test/src/ct_telnet.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
@@ -141,7 +141,8 @@
-export([open/1, open/2, open/3, open/4, close/1]).
-export([cmd/2, cmd/3, cmdf/3, cmdf/4, get_data/1,
- send/2, sendf/3, expect/2, expect/3]).
+ send/2, send/3, sendf/3, sendf/4,
+ expect/2, expect/3]).
%% Callbacks
-export([init/3,handle_msg/2,reconnect/2,terminate/2]).
@@ -304,42 +305,74 @@ close(Connection) ->
%%% Test suite interface
%%%-----------------------------------------------------------------
%%% @spec cmd(Connection,Cmd) -> {ok,Data} | {error,Reason}
-%%% @equiv cmd(Connection,Cmd,DefaultTimeout)
+%%% @equiv cmd(Connection,Cmd,[])
cmd(Connection,Cmd) ->
- cmd(Connection,Cmd,default).
+ cmd(Connection,Cmd,[]).
%%%-----------------------------------------------------------------
-%%% @spec cmd(Connection,Cmd,Timeout) -> {ok,Data} | {error,Reason}
+%%% @spec cmd(Connection,Cmd,Opts) -> {ok,Data} | {error,Reason}
%%% Connection = ct_telnet:connection()
%%% Cmd = string()
-%%% Timeout = integer()
+%%% Opts = [Opt]
+%%% Opt = {timeout,timeout()} | {newline,boolean()}
%%% Data = [string()]
%%% Reason = term()
%%% @doc Send a command via telnet and wait for prompt.
-cmd(Connection,Cmd,Timeout) ->
- case get_handle(Connection) of
- {ok,Pid} ->
- call(Pid,{cmd,Cmd,Timeout});
+%%%
+%%% This function will by default add a newline to the end of the
+%%% given command. If this is not desired, the option
+%%% `{newline,false}' can be used. This is necessary, for example,
+%%% when sending telnet command sequences (prefixed with the
+%%% Interprete As Command, IAC, character).
+%%%
+%%% The option `timeout' specifies how long the client shall wait for
+%%% prompt. If the time expires, the function returns
+%%% `{error,timeout}'. See the module description for information
+%%% about the default value for the command timeout.
+cmd(Connection,Cmd,Opts) when is_list(Opts) ->
+ case check_cmd_opts(Opts) of
+ ok ->
+ case get_handle(Connection) of
+ {ok,Pid} ->
+ call(Pid,{cmd,Cmd,Opts});
+ Error ->
+ Error
+ end;
Error ->
Error
- end.
+ end;
+cmd(Connection,Cmd,Timeout) when is_integer(Timeout); Timeout==default ->
+ %% This clause is kept for backwards compatibility only
+ cmd(Connection,Cmd,[{timeout,Timeout}]).
+
+check_cmd_opts([{timeout,Timeout}|Opts]) when is_integer(Timeout);
+ Timeout==default ->
+ check_cmd_opts(Opts);
+check_cmd_opts([]) ->
+ ok;
+check_cmd_opts(Opts) ->
+ check_send_opts(Opts).
+
%%%-----------------------------------------------------------------
%%% @spec cmdf(Connection,CmdFormat,Args) -> {ok,Data} | {error,Reason}
-%%% @equiv cmdf(Connection,CmdFormat,Args,DefaultTimeout)
+%%% @equiv cmdf(Connection,CmdFormat,Args,[])
cmdf(Connection,CmdFormat,Args) ->
- cmdf(Connection,CmdFormat,Args,default).
+ cmdf(Connection,CmdFormat,Args,[]).
%%%-----------------------------------------------------------------
-%%% @spec cmdf(Connection,CmdFormat,Args,Timeout) -> {ok,Data} | {error,Reason}
+%%% @spec cmdf(Connection,CmdFormat,Args,Opts) -> {ok,Data} | {error,Reason}
%%% Connection = ct_telnet:connection()
%%% CmdFormat = string()
%%% Args = list()
-%%% Timeout = integer()
+%%% Opts = [Opt]
+%%% Opt = {timeout,timeout()} | {newline,boolean()}
%%% Data = [string()]
%%% Reason = term()
%%% @doc Send a telnet command and wait for prompt
%%% (uses a format string and list of arguments to build the command).
-cmdf(Connection,CmdFormat,Args,Timeout) when is_list(Args) ->
+%%%
+%%% See {@link cmd/3} further description.
+cmdf(Connection,CmdFormat,Args,Opts) when is_list(Args) ->
Cmd = lists:flatten(io_lib:format(CmdFormat,Args)),
- cmd(Connection,Cmd,Timeout).
+ cmd(Connection,Cmd,Opts).
%%%-----------------------------------------------------------------
%%% @spec get_data(Connection) -> {ok,Data} | {error,Reason}
@@ -358,32 +391,67 @@ get_data(Connection) ->
%%%-----------------------------------------------------------------
%%% @spec send(Connection,Cmd) -> ok | {error,Reason}
+%%% @equiv send(Connection,Cmd,[])
+send(Connection,Cmd) ->
+ send(Connection,Cmd,[]).
+
+%%%-----------------------------------------------------------------
+%%% @spec send(Connection,Cmd,Opts) -> ok | {error,Reason}
%%% Connection = ct_telnet:connection()
%%% Cmd = string()
+%%% Opts = [Opt]
+%%% Opt = {newline,boolean()}
%%% Reason = term()
%%% @doc Send a telnet command and return immediately.
%%%
+%%% This function will by default add a newline to the end of the
+%%% given command. If this is not desired, the option
+%%% `{newline,false}' can be used. This is necessary, for example,
+%%% when sending telnet command sequences (prefixed with the
+%%% Interprete As Command, IAC, character).
+%%%
%%% <p>The resulting output from the command can be read with
%%% <code>get_data/1</code> or <code>expect/2/3</code>.</p>
-send(Connection,Cmd) ->
- case get_handle(Connection) of
- {ok,Pid} ->
- call(Pid,{send,Cmd});
+send(Connection,Cmd,Opts) ->
+ case check_send_opts(Opts) of
+ ok ->
+ case get_handle(Connection) of
+ {ok,Pid} ->
+ call(Pid,{send,Cmd,Opts});
+ Error ->
+ Error
+ end;
Error ->
Error
end.
+check_send_opts([{newline,Bool}|Opts]) when is_boolean(Bool) ->
+ check_send_opts(Opts);
+check_send_opts([Invalid|_]) ->
+ {error,{invalid_option,Invalid}};
+check_send_opts([]) ->
+ ok.
+
+
%%%-----------------------------------------------------------------
%%% @spec sendf(Connection,CmdFormat,Args) -> ok | {error,Reason}
+%%% @equiv sendf(Connection,CmdFormat,Args,[])
+sendf(Connection,CmdFormat,Args) when is_list(Args) ->
+ sendf(Connection,CmdFormat,Args,[]).
+
+%%%-----------------------------------------------------------------
+%%% @spec sendf(Connection,CmdFormat,Args,Opts) -> ok | {error,Reason}
%%% Connection = ct_telnet:connection()
%%% CmdFormat = string()
%%% Args = list()
+%%% Opts = [Opt]
+%%% Opt = {newline,boolean()}
%%% Reason = term()
%%% @doc Send a telnet command and return immediately (uses a format
%%% string and a list of arguments to build the command).
-sendf(Connection,CmdFormat,Args) when is_list(Args) ->
+sendf(Connection,CmdFormat,Args,Opts) when is_list(Args) ->
Cmd = lists:flatten(io_lib:format(CmdFormat,Args)),
- send(Connection,Cmd).
+ send(Connection,Cmd,Opts).
%%%-----------------------------------------------------------------
%%% @spec expect(Connection,Patterns) -> term()
@@ -559,7 +627,7 @@ set_telnet_defaults([],S) ->
S.
%% @hidden
-handle_msg({cmd,Cmd,Timeout},State) ->
+handle_msg({cmd,Cmd,Opts},State) ->
start_gen_log(heading(cmd,State#state.name)),
log(State,cmd,"Cmd: ~p",[Cmd]),
@@ -584,11 +652,14 @@ handle_msg({cmd,Cmd,Timeout},State) ->
{ip,true} ->
ok
end,
- TO = if Timeout == default -> State#state.com_to;
- true -> Timeout
+ TO = case proplists:get_value(timeout,Opts,default) of
+ default -> State#state.com_to;
+ Timeout -> Timeout
end,
+ Newline = proplists:get_value(newline,Opts,true),
{Return,NewBuffer,Prompt} =
- case teln_cmd(State#state.teln_pid, Cmd, State#state.prx, TO) of
+ case teln_cmd(State#state.teln_pid, Cmd, State#state.prx,
+ Newline, TO) of
{ok,Data,_PromptType,Rest} ->
log(State,recv,"Return: ~p",[{ok,Data}]),
{{ok,Data},Rest,true};
@@ -597,13 +668,13 @@ handle_msg({cmd,Cmd,Timeout},State) ->
{State#state.name,
State#state.type},
State#state.teln_pid,
- {cmd,Cmd,TO}}},
+ {cmd,Cmd,Opts}}},
log(State,recv,"Return: ~p",[Error]),
{Retry,[],false}
end,
end_gen_log(),
{Return,State#state{buffer=NewBuffer,prompt=Prompt}};
-handle_msg({send,Cmd},State) ->
+handle_msg({send,Cmd,Opts},State) ->
start_gen_log(heading(send,State#state.name)),
log(State,send,"Sending: ~p",[Cmd]),
@@ -628,7 +699,8 @@ handle_msg({send,Cmd},State) ->
{ip,true} ->
ok
end,
- ct_telnet_client:send_data(State#state.teln_pid,Cmd),
+ Newline = proplists:get_value(newline,Opts,true),
+ ct_telnet_client:send_data(State#state.teln_pid,Cmd,Newline),
end_gen_log(),
{ok,State#state{buffer=[],prompt=false}};
handle_msg(get_data,State) ->
@@ -868,8 +940,8 @@ format_data(_How,{String,Args}) ->
%%%=================================================================
%%% Abstraction layer on top of ct_telnet_client.erl
-teln_cmd(Pid,Cmd,Prx,Timeout) ->
- ct_telnet_client:send_data(Pid,Cmd),
+teln_cmd(Pid,Cmd,Prx,Newline,Timeout) ->
+ ct_telnet_client:send_data(Pid,Cmd,Newline),
teln_receive_until_prompt(Pid,Prx,Timeout).
teln_get_all_data(Pid,Prx,Data,Acc,LastLine) ->
diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl
index ce30dcb74b..36d33522a3 100644
--- a/lib/common_test/src/ct_telnet_client.erl
+++ b/lib/common_test/src/ct_telnet_client.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
@@ -35,7 +35,7 @@
%% -define(debug, true).
-export([open/2, open/3, open/4, open/5, close/1]).
--export([send_data/2, get_data/1]).
+-export([send_data/2, send_data/3, get_data/1]).
-define(TELNET_PORT, 23).
-define(OPEN_TIMEOUT,10000).
@@ -97,7 +97,11 @@ close(Pid) ->
end.
send_data(Pid, Data) ->
- Pid ! {send_data, Data++"\n"},
+ send_data(Pid, Data, true).
+send_data(Pid, Data, true) ->
+ send_data(Pid, Data++"\n", false);
+send_data(Pid, Data, false) ->
+ Pid ! {send_data, Data},
ok.
get_data(Pid) ->
@@ -246,7 +250,13 @@ wait(false, _) -> infinity.
send(Data, Sock, ConnName) ->
case Data of
[?IAC|_] = Cmd ->
- cmd_dbg(Cmd);
+ cmd_dbg("Sending",Cmd),
+ try io_lib:format("[~w] ~w", [?MODULE,Data]) of
+ Str ->
+ ct_telnet:log(ConnName, general_io, Str, [])
+ catch
+ _:_ -> ok
+ end;
_ ->
dbg("Sending: ~tp\n", [Data]),
try io_lib:format("[~w] ~ts", [?MODULE,Data]) of
@@ -267,8 +277,7 @@ check_msg(Sock, [?IAC,?IAC | T], Acc) ->
check_msg(Sock, [?IAC | Cs], Acc) ->
case get_cmd(Cs) of
{Cmd,Cs1} ->
- dbg("Got ", []),
- cmd_dbg(Cmd),
+ cmd_dbg("Got",Cmd),
respond_cmd(Cmd, Sock),
check_msg(Sock, Cs1, Acc);
error ->
@@ -287,12 +296,12 @@ check_msg(_Sock, [], Acc) ->
respond_cmd([?WILL,?ECHO], Sock) ->
R = [?IAC,?DO,?ECHO],
- cmd_dbg(R),
+ cmd_dbg("Responding",R),
gen_tcp:send(Sock, R);
respond_cmd([?DO,?ECHO], Sock) ->
R = [?IAC,?WILL,?ECHO],
- cmd_dbg(R),
+ cmd_dbg("Responding",R),
gen_tcp:send(Sock, R);
%% Answers from server
@@ -312,12 +321,12 @@ respond_cmd([?WONT | _Opt], _Sock) -> % server ack?
respond_cmd([?WILL,Opt], Sock) ->
R = [?IAC,?DONT,Opt],
- cmd_dbg(R),
+ cmd_dbg("Responding",R),
gen_tcp:send(Sock, R);
respond_cmd([?DO | Opt], Sock) ->
R = [?IAC,?WONT | Opt],
- cmd_dbg(R),
+ cmd_dbg("Responding",R),
gen_tcp:send(Sock, R);
%% Commands without options (which we ignore)
@@ -353,13 +362,14 @@ get_subcmd([Opt | Rest], Acc) ->
get_subcmd(Rest, [Opt | Acc]).
-ifdef(debug).
-dbg(_Str,_Args) ->
- io:format(_Str,_Args).
+dbg(Str,Args) ->
+ TS = timestamp(),
+ io:format("[~p ct_telnet_client, ~s]\n" ++ Str,[self(),TS|Args]).
-cmd_dbg(_Cmd) ->
- case _Cmd of
+cmd_dbg(Prefix,Cmd) ->
+ case Cmd of
[?IAC|Cmd1] ->
- cmd_dbg(Cmd1);
+ cmd_dbg(Prefix,Cmd1);
[Ctrl|Opts] ->
CtrlStr =
case Ctrl of
@@ -375,15 +385,23 @@ cmd_dbg(_Cmd) ->
[Opt] -> Opt;
_ -> Opts
end,
- io:format("~ts(~w): ~w\n", [CtrlStr,Ctrl,Opts1]);
+ dbg("~ts: ~ts(~w): ~w\n", [Prefix,CtrlStr,Ctrl,Opts1]);
Any ->
- io:format("Unexpected in cmd_dbg:~n~w~n",[Any])
+ dbg("Unexpected in cmd_dbg:~n~w~n",[Any])
end.
+timestamp() ->
+ {MS,S,US} = now(),
+ {{Year,Month,Day}, {Hour,Min,Sec}} =
+ calendar:now_to_local_time({MS,S,US}),
+ MilliSec = trunc(US/1000),
+ lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B "
+ "~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B",
+ [Year,Month,Day,Hour,Min,Sec,MilliSec])).
-else.
dbg(_Str,_Args) ->
ok.
-cmd_dbg(_Cmd) ->
+cmd_dbg(_Prefix,_Cmd) ->
ok.
-endif.
diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl
index 10666b979d..09b6fd1510 100644
--- a/lib/common_test/src/unix_telnet.erl
+++ b/lib/common_test/src/unix_telnet.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
@@ -122,7 +122,7 @@ connect1(Name,Ip,Port,Timeout,KeepAlive,Username,Password) ->
ok = ct_telnet_client:send_data(Pid,Password),
Stars = lists:duplicate(length(Password),$*),
log(Name,send,"Password: ~s",[Stars]),
- ok = ct_telnet_client:send_data(Pid,""),
+% ok = ct_telnet_client:send_data(Pid,""),
case ct_telnet:silent_teln_expect(Name,Pid,[],
prompt,
?prx,[]) of
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..1dab425509 100644
--- a/lib/common_test/test/ct_cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE.erl
@@ -76,7 +76,12 @@ all() ->
cover_node_option,
ct_cover_add_remove_nodes,
otp_9956,
- cross
+ cross,
+ export_import,
+ relative_incl_dirs,
+ absolute_incl_dirs,
+ relative_excl_dirs,
+ absolute_excl_dirs
].
%%--------------------------------------------------------------------
@@ -172,8 +177,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}]),
@@ -199,6 +204,59 @@ cross(Config) ->
ok.
+export_import(Config) ->
+ DataDir = ?config(data_dir,Config),
+ false = check_cover(Config),
+ CoverSpec1 =
+ default_cover_file_content() ++ [{export,"export_import.coverdata"}],
+ CoverFile1 = create_cover_file(export_import1,CoverSpec1,Config),
+ {ok,Events1} = run_test(export_import1,default,[{cover,CoverFile1}],Config),
+ check_calls(Events1,1),
+ CoverSpec2 =
+ default_cover_file_content() ++ [{import,"export_import.coverdata"}],
+ CoverFile2 = create_cover_file(export_import2,CoverSpec2,Config),
+ {ok,Events2} = run_test(export_import2,default,[{cover,CoverFile2}],Config),
+ check_calls(Events2,2),
+ ok.
+
+relative_incl_dirs(Config) ->
+ false = check_cover(Config),
+ RelDir = rel_path(?config(priv_dir, Config), ?config(data_dir, Config)),
+ CoverSpec = [{incl_dirs, [RelDir]}],
+ CoverFile = create_cover_file(rel_incl_dirs, CoverSpec, Config),
+ Opts = [{cover, CoverFile}],
+ {ok, Events} = run_test(rel_incl_dirs, default, Opts, Config),
+ check_calls(Events, 1),
+ ok.
+
+absolute_incl_dirs(Config) ->
+ false = check_cover(Config),
+ CoverSpec = [{incl_dirs, [?config(data_dir, Config)]}],
+ CoverFile = create_cover_file(abs_incl_dirs, CoverSpec, Config),
+ Opts = [{cover, CoverFile}],
+ {ok, Events} = run_test(abs_incl_dirs, default, Opts, Config),
+ check_calls(Events, 1),
+ ok.
+
+relative_excl_dirs(Config) ->
+ false = check_cover(Config),
+ RelDir = rel_path(?config(priv_dir, Config), ?config(data_dir, Config)),
+ CoverSpec = default_cover_file_content() ++ [{excl_dirs, [RelDir]}],
+ CoverFile = create_cover_file(rel_excl_dirs, CoverSpec, Config),
+ Opts = [{cover, CoverFile}],
+ {ok, Events} = run_test(rel_excl_dirs, default_no_cover, Opts, Config),
+ check_no_cover_compiled(Events),
+ ok.
+
+absolute_excl_dirs(Config) ->
+ false = check_cover(Config),
+ AbsDir = ?config(data_dir, Config),
+ CoverSpec = default_cover_file_content() ++ [{excl_dirs, [AbsDir]}],
+ CoverFile = create_cover_file(abs_excl_dirs, CoverSpec, Config),
+ Opts = [{cover, CoverFile}],
+ {ok, Events} = run_test(abs_excl_dirs, default_no_cover, Opts, Config),
+ check_no_cover_compiled(Events),
+ ok.
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
@@ -267,30 +325,42 @@ 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 if a module was compiled without cover
+check_no_cover_compiled(Events) ->
+ check_no_cover_compiled(Events, ?mod).
+check_no_cover_compiled(Events, Mod) ->
+ [ {error, {not_cover_compiled, Mod}} = analyse_log(CoverLog, Mod)
+ || CoverLog <- cover_logs(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)],
- do_check_logs(CoverLogs,MFA,N).
+ do_check_logs(cover_logs(Events),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(),
+ {ok, Calls} = analyse_log(CoverLog, Mod),
{MFA,N} = lists:keyfind(MFA,1,Calls),
do_check_logs(CoverLogs,MFA,N);
do_check_logs([],_,_) ->
ok.
+cover_logs(Events) ->
+ [filename:join(D,"all.coverdata") || D <- get_log_dirs(Events)].
+
+analyse_log(CoverLog, Mod) ->
+ {ok, _} = cover:start(),
+ ok = cover:import(CoverLog),
+ Result = cover:analyse(Mod, calls, function),
+ ok = cover:stop(),
+ Result.
+
fullname(Name) ->
{ok,Host} = inet:gethostname(),
list_to_atom(atom_to_list(Name) ++ "@" ++ Host).
@@ -319,3 +389,12 @@ start_slave(Name,Args) ->
{boot_timeout,10}, % extending some timers for slow test hosts
{init_timeout,10},
{startup_timeout,10}]).
+
+rel_path(From, To) ->
+ Segments = do_rel_path(filename:split(From), filename:split(To)),
+ filename:join(Segments).
+
+do_rel_path([Seg|RestA], [Seg|RestB]) ->
+ do_rel_path(RestA, RestB);
+do_rel_path(PathA, PathB) ->
+ lists:duplicate(length(PathA), "..") ++ PathB.
diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
index 83d368c53d..789e48bd96 100644
--- a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
@@ -71,6 +71,10 @@ default(_Config) ->
cover_test_mod:foo(),
ok.
+default_no_cover(_Config) ->
+ cover_test_mod:foo(),
+ ok.
+
slave(_Config) ->
cover_compiled = code:which(cover_test_mod),
cover_test_mod:foo(),
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/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl
index 80616af064..3885c1991d 100644
--- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl
+++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl
@@ -20,7 +20,7 @@ suite() -> [
operations() ->
[start_stop, send_and_get, expect, already_closed,
- cmd, sendf, close_wrong_type].
+ cmd, sendf, no_newline, close_wrong_type].
mult_case(_Case, 0) ->
[];
@@ -129,6 +129,16 @@ sendf(Config) ->
ok = ct_telnet:close(Handle),
ok.
+no_newline(Config) ->
+ {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))),
+ IAC = 255, % interprete as command
+ AYT = 246, % are you there
+ ok = ct_telnet:send(Handle, [IAC,AYT], [{newline,false}]),
+ {ok,_} = ct_telnet:expect(Handle,"yes",[no_prompt_check]),
+ {ok,_} = ct_telnet:cmd(Handle, ""), % send newline only to get back prompt
+ ok = ct_telnet:close(Handle),
+ ok.
+
close_wrong_type(_) ->
{error, _} = ct_telnet:close(whatever),
ok.
diff --git a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl
index c0f79d0f10..0ddb4e9b00 100644
--- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl
+++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl
@@ -4,6 +4,26 @@
-include_lib("common_test/include/ct.hrl").
+%% telnet control characters
+-define(SE, 240).
+-define(NOP, 241).
+-define(DM, 242).
+-define(BRK, 243).
+-define(IP, 244).
+-define(AO, 245).
+-define(AYT, 246).
+-define(EC, 247).
+-define(EL, 248).
+-define(GA, 249).
+-define(SB, 250).
+-define(WILL, 251).
+-define(WONT, 252).
+-define(DO, 253).
+-define(DONT, 254).
+-define(IAC, 255).
+
+-define(SHORT_TIME,2000).
+
%%--------------------------------------------------------------------
%% TEST SERVER CALLBACK FUNCTIONS
%%--------------------------------------------------------------------
@@ -34,7 +54,9 @@ all() ->
ignore_prompt_timeout,
large_string,
server_speaks,
- server_disconnects
+ server_disconnects,
+ newline_ayt,
+ newline_break
].
groups() ->
@@ -95,7 +117,7 @@ expect_error_prompt(_) ->
expect_error_timeout1(_) ->
{ok, Handle} = ct_telnet:open(telnet_server_conn1),
ok = ct_telnet:send(Handle, "echo_no_prompt xxx"),
- {error,timeout} = ct_telnet:expect(Handle, ["xxx"], [{timeout,1000}]),
+ {error,timeout} = ct_telnet:expect(Handle, ["xxx"], [{timeout,?SHORT_TIME}]),
ok = ct_telnet:close(Handle),
ok.
@@ -158,16 +180,16 @@ ignore_prompt_timeout(_) ->
{ok, Handle} = ct_telnet:open(telnet_server_conn1),
ok = ct_telnet:send(Handle, "echo xxx"),
{error,timeout} = ct_telnet:expect(Handle, ["yyy"], [ignore_prompt,
- {timeout,1000}]),
+ {timeout,?SHORT_TIME}]),
ok = ct_telnet:send(Handle, "echo xxx"), % sends prompt and newline
{ok,["xxx"]} = ct_telnet:expect(Handle, ["xxx"], [ignore_prompt,
- {timeout,1000}]),
+ {timeout,?SHORT_TIME}]),
ok = ct_telnet:send(Handle, "echo_no_prompt xxx\n"), % no prompt, but newline
{ok,["xxx"]} = ct_telnet:expect(Handle, ["xxx"], [ignore_prompt,
- {timeout,1000}]),
+ {timeout,?SHORT_TIME}]),
ok = ct_telnet:send(Handle, "echo_no_prompt xxx"), % no prompt, no newline
{error,timeout} = ct_telnet:expect(Handle, ["xxx"], [ignore_prompt,
- {timeout,1000}]),
+ {timeout,?SHORT_TIME}]),
ok = ct_telnet:close(Handle),
ok.
@@ -213,7 +235,7 @@ no_prompt_check_timeout(_) ->
{ok, Handle} = ct_telnet:open(telnet_server_conn1),
ok = ct_telnet:send(Handle, "echo xxx"),
{error,timeout} = ct_telnet:expect(Handle, ["yyy"], [no_prompt_check,
- {timeout,1000}]),
+ {timeout,?SHORT_TIME}]),
ok = ct_telnet:close(Handle),
ok.
@@ -254,17 +276,31 @@ large_string(_) ->
%% The server says things. Manually check that it gets printed correctly
%% in the general IO log.
+%%
+%% In this test case we simulate data sent spontaneously from the
+%% server. We use ct_telnet_client:send_data instead of ct_telnet:send
+%% to avoid flushing of buffers in the client, and we use
+%% echo_no_prompt since the server would normally not send a prompt in
+%% this case.
server_speaks(_) ->
{ok, Handle} = ct_telnet:open(telnet_server_conn1),
- ok = ct_telnet:send(Handle, "echo_no_prompt This is the first message\r\n"),
- ok = ct_telnet:send(Handle, "echo_no_prompt This is the second message\r\n"),
- %% let ct_telnet_client get an idle timeout
+
+ Backdoor = ct_gen_conn:get_conn_pid(Handle),
+ ok = ct_telnet_client:send_data(Backdoor,
+ "echo_no_prompt This is the first message"),
+ ok = ct_telnet_client:send_data(Backdoor,
+ "echo_no_prompt This is the second message"),
+ %% Let ct_telnet_client get an idle timeout. This should print the
+ %% two messages to the log. Note that the buffers are not flushed here!
timer:sleep(15000),
- ok = ct_telnet:send(Handle, "echo_no_prompt This is the third message\r\n"),
- {ok,_} = ct_telnet:expect(Handle, ["the"], [no_prompt_check]),
+ ok = ct_telnet_client:send_data(Backdoor,
+ "echo_no_prompt This is the third message"),
+ {ok,_} = ct_telnet:expect(Handle, ["first.*second.*third"],
+ [no_prompt_check, sequence]),
{error,timeout} = ct_telnet:expect(Handle, ["the"], [no_prompt_check,
- {timeout,1000}]),
- ok = ct_telnet:send(Handle, "echo_no_prompt This is the fourth message\r\n"),
+ {timeout,?SHORT_TIME}]),
+ ok = ct_telnet_client:send_data(Backdoor,
+ "echo_no_prompt This is the fourth message"),
%% give the server time to respond
timer:sleep(2000),
%% closing the connection should print last message in log
@@ -279,9 +315,28 @@ server_disconnects(_) ->
%% wait until the get_data operation (triggered by send/2) times out
%% before sending the msg
timer:sleep(500),
- ok = ct_telnet:send(Handle, "echo_no_prompt This is the message\r\n"),
+ ok = ct_telnet:send(Handle, "echo_no_prompt This is the message"),
%% when the server closes the connection, the last message should be
%% printed in the log
timer:sleep(3000),
_ = ct_telnet:close(Handle),
ok.
+
+%% Test option {newline,false} to send telnet command sequence.
+newline_ayt(_) ->
+ {ok, Handle} = ct_telnet:open(telnet_server_conn1),
+ ok = ct_telnet:send(Handle, [?IAC,?AYT], [{newline,false}]),
+ {ok,["yes"]} = ct_telnet:expect(Handle, ["yes"]),
+ ok = ct_telnet:close(Handle),
+ ok.
+
+%% Test option {newline,false} to send telnet command sequence.
+newline_break(_) ->
+ {ok, Handle} = ct_telnet:open(telnet_server_conn1),
+ ok = ct_telnet:send(Handle, [?IAC,?BRK], [{newline,false}]),
+ %% '#' is the prompt in break mode
+ {ok,["# "]} = ct_telnet:expect(Handle, ["# "], [no_prompt_check]),
+ {ok,R} = ct_telnet:cmd(Handle, "q", [{newline,false}]),
+ "> " = lists:flatten(R),
+ ok = ct_telnet:close(Handle),
+ ok.
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index 2e2b45d59f..746469584d 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -481,6 +481,7 @@ er_loop(Evs) ->
From ! {event_receiver,lists:reverse(Evs)},
er_loop(Evs);
stop ->
+ unregister(event_receiver),
ok
end.
diff --git a/lib/common_test/test/telnet_server.erl b/lib/common_test/test/telnet_server.erl
index 1d341d6106..d25ee62d38 100644
--- a/lib/common_test/test/telnet_server.erl
+++ b/lib/common_test/test/telnet_server.erl
@@ -31,7 +31,8 @@
users,
authorized=false,
suppress_go_ahead=false,
- buffer=[]}).
+ buffer=[],
+ break=false}).
-type options() :: [{port,pos_integer()} | {users,users()}].
-type users() :: [{user(),password()}].
@@ -148,6 +149,9 @@ loop(State, N) ->
stopped
end.
+handle_data(Cmd,#state{break=true}=State) ->
+ dbg("Server got data when in break mode: ~p~n",[Cmd]),
+ handle_break_cmd(Cmd,State);
handle_data([?IAC|Cmd],State) ->
dbg("Server got cmd: ~p~n",[Cmd]),
handle_cmd(Cmd,State);
@@ -171,24 +175,38 @@ handle_data(Data,State) ->
{ok,State#state{buffer=[Data|State#state.buffer]}}
end.
-%% Add function clause below to handle new telnet commands (sent with
-%% ?IAC from client - this is not possible to do from ct_telnet API,
-%% but ct_telnet sends DONT SUPPRESS_GO_AHEAD)
+%% Add function clause below to handle new telnet commands sent with
+%% ?IAC from client. This can be done from ct_telnet:send or
+%% ct_telnet:cmd if using the option {newline,false}. Also, ct_telnet
+%% sends DONT SUPPRESS_GO_AHEAD.
handle_cmd([?DO,?SUPPRESS_GO_AHEAD|T],State) ->
send([?IAC,?WILL,?SUPPRESS_GO_AHEAD],State),
- handle_cmd(T,State#state{suppress_go_ahead=true});
+ handle_data(T,State#state{suppress_go_ahead=true});
handle_cmd([?DONT,?SUPPRESS_GO_AHEAD|T],State) ->
send([?IAC,?WONT,?SUPPRESS_GO_AHEAD],State),
- handle_cmd(T,State#state{suppress_go_ahead=false});
-handle_cmd([?IAC|T],State) ->
- %% Multiple commands in one packet
- handle_cmd(T,State);
+ handle_data(T,State#state{suppress_go_ahead=false});
+handle_cmd([?BRK|T],State) ->
+ %% Used when testing 'newline' option in ct_telnet:send and ct_telnet:cmd.
+ send("# ",State),
+ handle_data(T,State#state{break=true});
+handle_cmd([?AYT|T],State) ->
+ %% Used when testing 'newline' option in ct_telnet:send and ct_telnet:cmd.
+ send("yes\r\n> ",State),
+ handle_data(T,State);
handle_cmd([_H|T],State) ->
%% Not responding to this command
handle_cmd(T,State);
handle_cmd([],State) ->
{ok,State}.
+handle_break_cmd([$q|T],State) ->
+ %% Dummy cmd allowed in break mode - quit break mode
+ send("\r\n> ",State),
+ handle_data(T,State#state{break=false});
+handle_break_cmd([],State) ->
+ {ok,State}.
+
+
%% Add function clause below to handle new text command (text entered
%% from the telnet prompt)
do_handle_data(Data,#state{authorized=false}=State) ->
@@ -292,4 +310,14 @@ get_line([],_) ->
dbg(_F) ->
dbg(_F,[]).
dbg(_F,_A) ->
- io:format("[telnet_server] " ++ _F,_A).
+ TS = timestamp(),
+ io:format("[telnet_server, ~s]\n" ++ _F,[TS|_A]).
+
+timestamp() ->
+ {MS,S,US} = now(),
+ {{Year,Month,Day}, {Hour,Min,Sec}} =
+ calendar:now_to_local_time({MS,S,US}),
+ MilliSec = trunc(US/1000),
+ lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B "
+ "~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B",
+ [Year,Month,Day,Hour,Min,Sec,MilliSec])).
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index f8a5aab686..849edc15e1 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1 +1 @@
-COMMON_TEST_VSN = 1.8
+COMMON_TEST_VSN = 1.9
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index a0f2e617cb..84ebd2f210 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -31,6 +31,74 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 5.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Named funs with the same name and arity could get mixed
+ up with each other.</p>
+ <p>
+ Own Id: OTP-12262</p>
+ </item>
+ <item>
+ <p>
+ Coalesce map keys in dialyzer mode</p>
+ <p>
+ This fixes a regression introduced in commit
+ 805f9c89fc01220bc1bb0f27e1b68fd4eca688ba The problem
+ occurred with compounded map keys compiled with dialyzer
+ option turned on, '+dialyzer'.</p>
+ <p>
+ Reported by: Ivan Uemlianin</p>
+ <p>
+ Own Id: OTP-12347</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 5.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Corrected a bug with incorrect code generation when
+ inlining was turned on.</p>
+ <p>
+ Own Id: OTP-12132</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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 +279,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/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index 5a4621dc37..a452d30b61 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -126,44 +126,53 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
%% There was a reference to a boolean expression
%% from inside a protected block (try/catch), to
%% a boolean expression outside.
- throw:protected_barrier ->
+ throw:protected_barrier ->
failed;
- %% The 'xor' operator was used. We currently don't
- %% find it worthwile to translate 'xor' operators
- %% (the code would be clumsy).
- throw:'xor' ->
+ %% The 'xor' operator was used. We currently don't
+ %% find it worthwile to translate 'xor' operators
+ %% (the code would be clumsy).
+ throw:'xor' ->
failed;
- %% The block does not contain a boolean expression,
- %% but only a call to a guard BIF.
- %% For instance: ... when element(1, T) ->
- throw:not_boolean_expr ->
+ %% The block does not contain a boolean expression,
+ %% but only a call to a guard BIF.
+ %% For instance: ... when element(1, T) ->
+ throw:not_boolean_expr ->
failed;
- %% The block contains a 'move' instruction that could
- %% not be handled.
- throw:move ->
+ %% The block contains a 'move' instruction that could
+ %% not be handled.
+ throw:move ->
failed;
- %% The optimization is not safe. (A register
- %% used by the instructions following the
- %% optimized code is either not assigned a
- %% value at all or assigned a different value.)
- throw:all_registers_not_killed ->
+ %% The optimization is not safe. (A register
+ %% used by the instructions following the
+ %% optimized code is either not assigned a
+ %% value at all or assigned a different value.)
+ throw:all_registers_not_killed ->
failed;
- throw:registers_used ->
+ throw:registers_used ->
failed;
- %% A protected block refered to the value
- %% returned by another protected block,
- %% probably because the Core Erlang code
- %% used nested try/catches in the guard.
- %% (v3_core never produces nested try/catches
- %% in guards, so it must have been another
- %% Core Erlang translator.)
- throw:protected_violation ->
+ %% A protected block refered to the value
+ %% returned by another protected block,
+ %% probably because the Core Erlang code
+ %% used nested try/catches in the guard.
+ %% (v3_core never produces nested try/catches
+ %% in guards, so it must have been another
+ %% Core Erlang translator.)
+ throw:protected_violation ->
+ failed;
+
+ %% Failed to work out the live registers for a GC
+ %% BIF. For example, if the number of live registers
+ %% needed to be 4 because {x,3} was a source register,
+ %% but {x,2} was not known to be initialized, this
+ %% exception would be thrown.
+ throw:gc_bif_alloc_failure ->
failed
+
end
end.
@@ -665,10 +674,16 @@ put_reg_1(V, [], I) -> [{I,V}].
fetch_reg(V, [{I,V}|_]) -> {x,I};
fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs).
-live_regs(Regs) ->
- foldl(fun ({I,_}, _) ->
- I
- end, -1, Regs)+1.
+live_regs([{_,reserved}|_]) ->
+ %% We are not sure that this register is initialized, so we must
+ %% abort the optimization.
+ throw(gc_bif_alloc_failure);
+live_regs([{I,_}]) ->
+ I+1;
+live_regs([{_,_}|Regs]) ->
+ live_regs(Regs);
+live_regs([]) ->
+ 0.
%%%
diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl
index 2792fd8fa5..0d95971f91 100644
--- a/lib/compiler/src/core_lib.erl
+++ b/lib/compiler/src/core_lib.erl
@@ -212,6 +212,8 @@ vu_pattern(V, #c_tuple{es=Es}, St) ->
vu_pattern_list(V, Es, St);
vu_pattern(V, #c_binary{segments=Ss}, St) ->
vu_pat_seg_list(V, Ss, St);
+vu_pattern(V, #c_map{es=Es}, St) ->
+ vu_map_pairs(V, Es, St);
vu_pattern(V, #c_alias{var=Var,pat=P}, St0) ->
case vu_pattern(V, Var, St0) of
{true,_}=St1 -> St1;
@@ -234,6 +236,13 @@ vu_pat_seg_list(V, Ss, St) ->
end
end, St, Ss).
+vu_map_pairs(V, [#c_map_pair{val=Pat}|T], St0) ->
+ case vu_pattern(V, Pat, St0) of
+ {true,_}=St -> St;
+ St -> vu_map_pairs(V, T, St)
+ end;
+vu_map_pairs(_, [], St) -> St.
+
-spec vu_var_list(cerl:var_name(), [cerl:c_var()]) -> boolean().
vu_var_list(V, Vs) ->
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index ce40213bad..ed8f609082 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -1229,6 +1229,11 @@ is_non_numeric([H|T]) ->
is_non_numeric(H) andalso is_non_numeric(T);
is_non_numeric(Tuple) when is_tuple(Tuple) ->
is_non_numeric_tuple(Tuple, tuple_size(Tuple));
+is_non_numeric(Map) when is_map(Map) ->
+ %% Note that 17.x and 18.x compare keys in different ways.
+ %% Be very conservative -- require that both keys and values
+ %% are non-numeric.
+ is_non_numeric(maps:to_list(Map));
is_non_numeric(Num) when is_number(Num) ->
false;
is_non_numeric(_) -> true.
@@ -1338,9 +1343,12 @@ eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types)
{ok,#c_tuple{es=Elements}} ->
if
1 =< Pos, Pos =< length(Elements) ->
- case lists:nth(Pos, Elements) of
- #c_alias{var=Alias} -> Alias;
- Res -> Res
+ El = lists:nth(Pos, Elements),
+ try
+ pat_to_expr(El)
+ catch
+ throw:impossible ->
+ Call
end;
true ->
eval_failure(Call, badarg)
@@ -2040,17 +2048,18 @@ case_opt_args([], Cs, _Sub, _LitExpr, Acc) ->
%% Try to expand one argument to several arguments (if tuple/list)
%% or to remove a literal argument.
%%
-case_opt_arg(E0, Sub, Cs, LitExpr) ->
+case_opt_arg(E0, Sub, Cs0, LitExpr) ->
E = maybe_replace_var(E0, Sub),
case cerl:is_data(E) of
false ->
- {error,Cs};
+ {error,Cs0};
true ->
+ Cs = case_opt_nomatch(E, Cs0, LitExpr),
case cerl:data_type(E) of
{atomic,_} ->
- case_opt_lit(E, Cs, LitExpr);
+ case_opt_lit(E, Cs);
_ ->
- case_opt_data(E, Cs, LitExpr)
+ case_opt_data(E, Cs)
end
end.
@@ -2072,19 +2081,67 @@ maybe_replace_var_1(E, #sub{t=Tdb}) ->
false ->
E;
true ->
- cerl_trees:map(fun(C) ->
- case cerl:is_c_alias(C) of
- false -> C;
- true -> cerl:alias_pat(C)
- end
- end, T0)
+ %% The pattern was a tuple. Now we must make sure
+ %% that the elements of the tuple are suitable. In
+ %% particular, we don't want binary or map
+ %% construction here, since that means that the
+ %% binary or map will be constructed in the 'case'
+ %% argument. That is wasteful for binaries. Even
+ %% worse is that any map pattern that use the ':='
+ %% operator will fail when used in map
+ %% construction (only the '=>' operator is allowed
+ %% when constructing a map from scratch).
+ ToData = fun coerce_to_data/1,
+ try
+ cerl_trees:map(ToData, T0)
+ catch
+ throw:impossible ->
+ %% Something unsuitable was found (map or
+ %% or binary). Keep the variable.
+ E
+ end
end;
error ->
E
end.
-%% case_opt_lit(Literal, Clauses0, LitExpr) ->
-%% {ok,[],Clauses} | error
+%% coerce_to_data(Core) -> Core'
+%% Coerce an element originally from a pattern to an data item or or
+%% variable. Throw an 'impossible' exception if non-data Core Erlang
+%% terms such as binary construction or map construction are
+%% encountered.
+
+coerce_to_data(C) ->
+ case cerl:is_c_alias(C) of
+ false ->
+ case cerl:is_data(C) orelse cerl:is_c_var(C) of
+ true -> C;
+ false -> throw(impossible)
+ end;
+ true ->
+ coerce_to_data(cerl:alias_pat(C))
+ end.
+
+%% case_opt_nomatch(E, Clauses, LitExpr) -> Clauses'
+%% Remove all clauses that cannot possibly match.
+
+case_opt_nomatch(E, [{[P|_],C,_,_}=Current|Cs], LitExpr) ->
+ case cerl_clauses:match(P, E) of
+ none ->
+ %% The pattern will not match the case expression. Remove
+ %% the clause. Unless the entire case expression is a
+ %% literal, also emit a warning.
+ case LitExpr of
+ false -> add_warning(C, nomatch_clause_type);
+ true -> ok
+ end,
+ case_opt_nomatch(E, Cs, LitExpr);
+ _ ->
+ [Current|case_opt_nomatch(E, Cs, LitExpr)]
+ end;
+case_opt_nomatch(_, [], _) -> [].
+
+%% case_opt_lit(Literal, Clauses0) -> {ok,[],Clauses} | error
%% The current part of the case expression is a literal. That
%% means that we will know at compile-time whether a clause
%% will match, and we can remove the corresponding pattern from
@@ -2093,68 +2150,48 @@ maybe_replace_var_1(E, #sub{t=Tdb}) ->
%% The only complication is if the literal is a binary. Binary
%% pattern matching is tricky, so we will give up in that case.
-case_opt_lit(Lit, Cs0, LitExpr) ->
- Cs1 = case_opt_lit_1(Lit, Cs0, LitExpr),
- try case_opt_lit_2(Lit, Cs1) of
+case_opt_lit(Lit, Cs0) ->
+ try case_opt_lit_1(Lit, Cs0) of
Cs ->
{ok,[],Cs}
catch
throw:impossible ->
- {error,Cs1}
+ {error,Cs0}
end.
-case_opt_lit_1(E, [{[P|_],C,_,_}=Current|Cs], LitExpr) ->
- case cerl_clauses:match(P, E) of
- none ->
- %% The pattern will not match the literal. Remove the clause.
- %% Unless the entire case expression is a literal, also
- %% emit a warning.
- case LitExpr of
- false -> add_warning(C, nomatch_clause_type);
- true -> ok
- end,
- case_opt_lit_1(E, Cs, LitExpr);
- _ ->
- [Current|case_opt_lit_1(E, Cs, LitExpr)]
- end;
-case_opt_lit_1(_, [], _) -> [].
-
-case_opt_lit_2(E, [{[P|Ps],C,PsAcc,Bs0}|Cs]) ->
- %% Non-matching clauses have already been removed in case_opt_lit_1/3.
+case_opt_lit_1(E, [{[P|Ps],C,PsAcc,Bs0}|Cs]) ->
+ %% Non-matching clauses have already been removed
+ %% in case_opt_nomatch/3.
case cerl_clauses:match(P, E) of
{true,Bs} ->
%% The pattern matches the literal. Remove the pattern
%% and update the bindings.
- [{Ps,C,PsAcc,Bs++Bs0}|case_opt_lit_2(E, Cs)];
+ [{Ps,C,PsAcc,Bs++Bs0}|case_opt_lit_1(E, Cs)];
{false,_} ->
%% Binary literal and pattern. We are not sure whether
%% the pattern will match.
throw(impossible)
end;
-case_opt_lit_2(_, []) -> [].
+case_opt_lit_1(_, []) -> [].
%% case_opt_data(Expr, Clauses0, LitExpr) -> {ok,Exprs,Clauses}
-case_opt_data(E, Cs0, LitExpr) ->
+case_opt_data(E, Cs0) ->
Es = cerl:data_es(E),
- Cs = case_opt_data_1(Cs0, Es,
- {cerl:data_type(E),cerl:data_arity(E)},
- LitExpr),
- {ok,Es,Cs}.
-
-case_opt_data_1([{[P|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig, LitExpr) ->
- case case_data_pat(P, TypeSig) of
- {ok,Ps1,Bs1} ->
- [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}|
- case_opt_data_1(Cs, Es, TypeSig,LitExpr)];
- error ->
- case LitExpr of
- false -> add_warning(C, nomatch_clause_type);
- true -> ok
- end,
- case_opt_data_1(Cs, Es, TypeSig, LitExpr)
- end;
-case_opt_data_1([], _, _, _) -> [].
+ TypeSig = {cerl:data_type(E),cerl:data_arity(E)},
+ try case_opt_data_1(Cs0, Es, TypeSig) of
+ Cs ->
+ {ok,Es,Cs}
+ catch
+ throw:impossible ->
+ {error,Cs0}
+ end.
+
+case_opt_data_1([{[P|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig) ->
+ {ok,Ps1,Bs1} = case_data_pat(P, TypeSig),
+ [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}|
+ case_opt_data_1(Cs, Es, TypeSig)];
+case_opt_data_1([], _, _) -> [].
%% case_data_pat(Pattern, Type, Arity) -> {ok,[Pattern],[{AliasVar,Pat}]} | error.
@@ -2163,12 +2200,7 @@ case_data_pat(P, TypeSig) ->
false ->
case_data_pat_var(P, TypeSig);
true ->
- case {cerl:data_type(P),cerl:data_arity(P)} of
- TypeSig ->
- {ok,cerl:data_es(P),[]};
- {_,_} ->
- error
- end
+ {ok,cerl:data_es(P),[]}
end.
%% case_data_pat_var(Pattern, {DataType,ArityType}) ->
@@ -2188,35 +2220,38 @@ case_data_pat_var(P, {Type,Arity}=TypeSig) ->
alias ->
V = cerl:alias_var(P),
Apat = cerl:alias_pat(P),
- case case_data_pat(Apat, TypeSig) of
- {ok,Ps,Bs} ->
- {ok,Ps,[{V,cerl:ann_make_data(Ann, Type, unalias_pat_list(Ps))}|Bs]};
- error ->
- error
- end;
- _ ->
- error
+ {ok,Ps,Bs} = case_data_pat(Apat, TypeSig),
+ {ok,Ps,[{V,cerl:ann_make_data(Ann, Type,
+ pat_to_expr_list(Ps))}|Bs]}
end.
-%% unalias_pat(Pattern) -> Pattern.
-%% Remove all the aliases in a pattern but using the alias variables
-%% instead of the values. We KNOW they will be bound.
+%% pat_to_expr(Pattern) -> Expression.
+%% Convert a pattern to an expression if possible. We KNOW that
+%% all variables in the pattern will be bound.
+%%
+%% Throw an 'impossible' exception if a map or (non-literal)
+%% binary is encountered. Trying to use a map pattern as an
+%% expression is incorrect, while rebuilding a potentially
+%% huge binary in an expression would be wasteful.
-unalias_pat(P) ->
- case cerl:is_c_alias(P) of
- true ->
+pat_to_expr(P) ->
+ case cerl:type(P) of
+ alias ->
cerl:alias_var(P);
- false ->
+ var ->
+ P;
+ _ ->
case cerl:is_data(P) of
false ->
- P;
+ %% Map or binary.
+ throw(impossible);
true ->
- Es = unalias_pat_list(cerl:data_es(P)),
+ Es = pat_to_expr_list(cerl:data_es(P)),
cerl:update_data(P, cerl:data_type(P), Es)
end
end.
-unalias_pat_list(Ps) -> [unalias_pat(P) || P <- Ps].
+pat_to_expr_list(Ps) -> [pat_to_expr(P) || P <- Ps].
make_vars(A, Max) ->
make_vars(A, 1, Max).
@@ -2248,23 +2283,23 @@ letify(#c_var{name=Vname}=Var, Val, Body) ->
%% opt_case_in_let(LetExpr) -> LetExpr'
-opt_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let) ->
- opt_case_in_let_0(Vs, Arg, B, Let).
+opt_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let, Sub) ->
+ opt_case_in_let_0(Vs, Arg, B, Let, Sub).
opt_case_in_let_0([#c_var{name=V}], Arg,
- #c_case{arg=#c_var{name=V},clauses=Cs}=Case, Let) ->
+ #c_case{arg=#c_var{name=V},clauses=Cs}=Case, Let, Sub) ->
case opt_case_in_let_1(V, Arg, Cs) of
impossible ->
case is_simple_case_arg(Arg) andalso
not core_lib:is_var_used(V, Case#c_case{arg=#c_literal{val=nil}}) of
true ->
- expr(opt_bool_case(Case#c_case{arg=Arg,clauses=Cs}), sub_new());
+ expr(opt_bool_case(Case#c_case{arg=Arg,clauses=Cs}), sub_new(Sub));
false ->
Let
end;
Expr -> Expr
end;
-opt_case_in_let_0(_, _, _, Let) -> Let.
+opt_case_in_let_0(_, _, _, Let, _) -> Let.
opt_case_in_let_1(V, Arg, Cs) ->
try
@@ -2607,7 +2642,7 @@ opt_simple_let_2(Let0, Vs0, Arg0, Body0, effect, Sub) ->
expr(#c_seq{arg=Arg,body=Body}, effect, sub_new_preserve_types(Sub));
true ->
Let = Let0#c_let{vars=Vs,arg=Arg,body=Body},
- opt_case_in_let_arg(opt_case_in_let(Let), effect, Sub)
+ opt_case_in_let_arg(opt_case_in_let(Let, Sub), effect, Sub)
end
end;
opt_simple_let_2(Let, Vs0, Arg0, Body, value, Sub) ->
@@ -2630,7 +2665,7 @@ opt_simple_let_2(Let, Vs0, Arg0, Body, value, Sub) ->
expr(#c_seq{arg=Arg,body=Body}, value, sub_new_preserve_types(Sub));
{Vs,Arg,Body} ->
opt_case_in_let_arg(
- opt_case_in_let(Let#c_let{vars=Vs,arg=Arg,body=Body}),
+ opt_case_in_let(Let#c_let{vars=Vs,arg=Arg,body=Body}, Sub),
value, Sub)
end.
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 8c18f6a9f7..59ec0d4199 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.
@@ -645,8 +647,8 @@ expr({'fun',L,{clauses,Cs},Id}, St) ->
fun_tq(Id, Cs, L, St, unnamed);
expr({named_fun,L,'_',Cs,Id}, St) ->
fun_tq(Id, Cs, L, St, unnamed);
-expr({named_fun,L,Name,Cs,{Index,Uniq,_Fname}}, St) ->
- fun_tq({Index,Uniq,Name}, Cs, L, St, {named, Name});
+expr({named_fun,L,Name,Cs,Id}, St) ->
+ fun_tq(Id, Cs, L, St, {named,Name});
expr({call,L,{remote,_,M,F},As0}, #core{wanted=Wanted}=St0) ->
{[M1,F1|As1],Aps,St1} = safe_list([M,F|As0], St0),
Lanno = lineno_anno(L, St1),
@@ -784,23 +786,42 @@ is_valid_map_src(_) -> false.
map_pair_list(Es, St) ->
foldr(fun
({map_field_assoc,L,K0,V0}, {Ces,Esp,St0}) ->
- {K,Ep0,St1} = safe(K0, St0),
- ok = ensure_valid_map_key(K),
+ {K1,Ep0,St1} = safe(K0, St0),
+ K = ensure_valid_map_key(K1),
{V,Ep1,St2} = safe(V0, St1),
A = lineno_anno(L, St2),
Pair = #c_map_pair{op=#c_literal{val=assoc},anno=A,key=K,val=V},
{[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2};
({map_field_exact,L,K0,V0}, {Ces,Esp,St0}) ->
- {K,Ep0,St1} = safe(K0, St0),
- ok = ensure_valid_map_key(K),
+ {K1,Ep0,St1} = safe(K0, St0),
+ K = ensure_valid_map_key(K1),
{V,Ep1,St2} = safe(V0, St1),
A = lineno_anno(L, St2),
Pair = #c_map_pair{op=#c_literal{val=exact},anno=A,key=K,val=V},
{[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2}
end, {[],[],St}, Es).
-ensure_valid_map_key(#c_literal{}) -> ok;
-ensure_valid_map_key(_) -> throw({bad_map,bad_map_key}).
+ensure_valid_map_key(K0) ->
+ case coalesced_map_key(K0) of
+ {ok,K1} -> K1;
+ error -> throw({bad_map,bad_map_key})
+ end.
+
+coalesced_map_key(#c_literal{}=K) -> {ok,K};
+%% Dialyzer hack redux
+%% DO coalesce tuples and list in maps for dialyzer
+%% Dialyzer tries to break this apart, don't let it
+coalesced_map_key(#c_tuple{}=K) ->
+ case core_lib:is_literal(K) of
+ true -> {ok,cerl:fold_literal(K)};
+ false -> error
+ end;
+coalesced_map_key(#c_cons{}=K) ->
+ case core_lib:is_literal(K) of
+ true -> {ok,cerl:fold_literal(K)};
+ false -> error
+ end;
+coalesced_map_key(_) -> error.
%% try_exception([ExcpClause], St) -> {[ExcpVar],Handler,St}.
@@ -1557,9 +1578,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) ->
@@ -1604,17 +1625,23 @@ pattern_alias_map_pair_patterns([Cv]) -> Cv;
pattern_alias_map_pair_patterns([Cv1,Cv2|Cvs]) ->
pattern_alias_map_pair_patterns([pat_alias(Cv1,Cv2)|Cvs]).
-pattern_map_pair({map_field_exact,L,K,V}, St) ->
+pattern_map_pair({map_field_exact,L,K,V},St) ->
+ #c_map_pair{anno=lineno_anno(L, St),
+ op=#c_literal{val=exact},
+ key=pattern_map_key(K,St),
+ val=pattern(V, St)}.
+
+pattern_map_key(K,St) ->
+ %% Throws 'nomatch' if the key can't be a literal
+ %% this will be a cryptic error message but it is better than nothing
case expr(K,St) of
- {#c_literal{}=Key,_,_} ->
- #c_map_pair{anno=lineno_anno(L, St),
- op=#c_literal{val=exact},
- key=Key,
- val=pattern(V, St)};
- _ ->
- %% this will throw a cryptic error message
- %% but it is better than nothing
- throw(nomatch)
+ {Key0,[],_} ->
+ %% Dialyzer hack redux
+ case coalesced_map_key(Key0) of
+ {ok,Key1} -> Key1;
+ error -> throw(nomatch)
+ end;
+ _ -> throw(nomatch)
end.
%% pat_bin([BinElement], State) -> [BinSeg].
@@ -1721,6 +1748,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 +2285,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/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 149b9bbb8f..10e3451e8f 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -34,7 +34,7 @@
otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1,
match_string/1,zero_width/1,bad_size/1,haystack/1,
cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1,
- no_partition/1,calling_a_binary/1]).
+ no_partition/1,calling_a_binary/1,binary_in_map/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -59,7 +59,7 @@ groups() ->
matching_and_andalso,otp_7188,otp_7233,otp_7240,
otp_7498,match_string,zero_width,bad_size,haystack,
cover_beam_bool,matched_out_size,follow_fail_branch,
- no_partition,calling_a_binary]}].
+ no_partition,calling_a_binary,binary_in_map]}].
init_per_suite(Config) ->
@@ -1189,6 +1189,26 @@ call_binary(<<>>, Acc) ->
call_binary(<<H,T/bits>>, Acc) ->
T(<<Acc/binary,H>>).
+binary_in_map(Config) when is_list(Config) ->
+ ok = match_binary_in_map(#{key => <<42:8>>}),
+ {'EXIT',{{badmatch,#{key := 1}},_}} =
+ (catch match_binary_in_map(#{key => 1})),
+ {'EXIT',{{badmatch,#{key := <<1023:16>>}},_}} =
+ (catch match_binary_in_map(#{key => <<1023:16>>})),
+ {'EXIT',{{badmatch,#{key := <<1:8>>}},_}} =
+ (catch match_binary_in_map(#{key => <<1:8>>})),
+ {'EXIT',{{badmatch,not_a_map},_}} =
+ (catch match_binary_in_map(not_a_map)),
+ ok.
+
+match_binary_in_map(Map) ->
+ case 8 of
+ N ->
+ #{key := <<42:N>>} = Map,
+ ok
+ end.
+
+
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 6a7036d728..2de17e7653 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -60,6 +60,12 @@ t_element(Config) when is_list(Config) ->
X = make_ref(),
?line X = id(element(1, {X,y,z})),
?line b = id(element(2, {a,b,c,d})),
+ (fun() ->
+ case {a,#{k=>X}} of
+ {a,#{k:=X}}=Tuple ->
+ #{k:=X} = id(element(2, Tuple))
+ end
+ end)(),
%% No optimization, but should work.
Tuple = id({x,y,z}),
@@ -204,6 +210,16 @@ eq(Config) when is_list(Config) ->
?line ?CMP_DIFF(a, [a]),
?line ?CMP_DIFF(a, {1,2,3}),
+ ?CMP_SAME(#{a=>1.0,b=>2}, #{b=>2.0,a=>1}),
+ ?CMP_SAME(#{a=>[1.0],b=>[2]}, #{b=>[2.0],a=>[1]}),
+
+ %% The rule for comparing keys are different in 17.x and 18.x.
+ %% Just test that the results are consistent.
+ Bool = id(#{1=>a}) == id(#{1.0=>a}), %Unoptimizable.
+ Bool = id(#{1=>a}) == #{1.0=>a}, %Optimizable.
+ Bool = #{1=>a} == #{1.0=>a}, %Optimizable.
+ io:format("Bool = ~p\n", [Bool]),
+
ok.
%% OTP-7117.
diff --git a/lib/compiler/test/fun_SUITE.erl b/lib/compiler/test/fun_SUITE.erl
index 25b7f677b5..a3e9b7fe4e 100644
--- a/lib/compiler/test/fun_SUITE.erl
+++ b/lib/compiler/test/fun_SUITE.erl
@@ -21,10 +21,10 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
test1/1,overwritten_fun/1,otp_7202/1,bif_fun/1,
- external/1,eep37/1,badarity/1]).
+ external/1,eep37/1,eep37_dup/1,badarity/1]).
-%% Internal export.
--export([call_me/1]).
+%% Internal exports.
+-export([call_me/1,dup1/0,dup2/0]).
-include_lib("test_server/include/test_server.hrl").
@@ -32,7 +32,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [test1,overwritten_fun,otp_7202,bif_fun,external,eep37,badarity].
+ [test1,overwritten_fun,otp_7202,bif_fun,external,eep37,eep37_dup,badarity].
groups() ->
[].
@@ -206,6 +206,17 @@ eep37(Config) when is_list(Config) ->
50 = UnusedName(8),
ok.
+eep37_dup(Config) when is_list(Config) ->
+ dup1 = (dup1())(),
+ dup2 = (dup2())(),
+ ok.
+
+dup1() ->
+ fun _F() -> dup1 end.
+
+dup2() ->
+ fun _F() -> dup2 end.
+
badarity(Config) when is_list(Config) ->
{'EXIT',{{badarity,{_,[]}},_}} = (catch (fun badarity/1)()),
ok.
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index eb205d09a7..34bfdeb1e5 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -1556,6 +1556,24 @@ bad_constants(Config) when is_list(Config) ->
bad_guards(Config) when is_list(Config) ->
if erlang:float(self()); true -> ok end,
+
+ fc(catch bad_guards_1(1, [])),
+ fc(catch bad_guards_1(1, [2])),
+ fc(catch bad_guards_1(atom, [2])),
+
+ fc(catch bad_guards_2(#{a=>0,b=>0}, [])),
+ fc(catch bad_guards_2(#{a=>0,b=>0}, [x])),
+ fc(catch bad_guards_2(not_a_map, [x])),
+ fc(catch bad_guards_2(42, [x])),
+ ok.
+
+%% beam_bool used to produce GC BIF instructions whose
+%% Live operands included uninitialized registers.
+
+bad_guards_1(X, [_]) when {{X}}, -X ->
+ ok.
+
+bad_guards_2(M, [_]) when M#{a := 0, b => 0}, map_size(M) ->
ok.
%% Call this function to turn off constant propagation.
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index ae7d764535..1e778dca24 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -22,7 +22,7 @@
init_per_group/2,end_per_group/2,
pmatch/1,mixed/1,aliases/1,match_in_call/1,
untuplify/1,shortcut_boolean/1,letify_guard/1,
- selectify/1,underscore/1,coverage/1]).
+ selectify/1,underscore/1,match_map/1,coverage/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -35,7 +35,8 @@ all() ->
groups() ->
[{p,test_lib:parallel(),
[pmatch,mixed,aliases,match_in_call,untuplify,
- shortcut_boolean,letify_guard,selectify,underscore,coverage]}].
+ shortcut_boolean,letify_guard,selectify,
+ underscore,match_map,coverage]}].
init_per_suite(Config) ->
@@ -400,6 +401,24 @@ underscore(Config) when is_list(Config) ->
_ = is_list(Config),
ok.
+-record(s, {map,t}).
+
+match_map(Config) when is_list(Config) ->
+ Map = #{key=>{x,y},ignore=>anything},
+ #s{map=Map,t={x,y}} = do_match_map(#s{map=Map}),
+ {a,#{k:={a,b,c}}} = do_match_map_2(#{k=>{a,b,c}}),
+ ok.
+
+do_match_map(#s{map=#{key:=Val}}=S) ->
+ %% Would crash with a 'badarg' exception.
+ S#s{t=Val}.
+
+do_match_map_2(Map) ->
+ case {a,Map} of
+ {a,#{k:=_}}=Tuple ->
+ Tuple
+ end.
+
coverage(Config) when is_list(Config) ->
%% Cover beam_dead.
ok = coverage_1(x, a),
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..b1a6c15ac9 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 5.0
+COMPILER_VSN = 5.0.3
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 948093d69c..e7215eeb64 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -462,9 +462,11 @@ static void hmac_context_dtor(ErlNifEnv* env, struct hmac_context*);
/*
#define PRINTF_ERR0(FMT) enif_fprintf(stderr, FMT "\n")
#define PRINTF_ERR1(FMT, A1) enif_fprintf(stderr, FMT "\n", A1)
+#define PRINTF_ERR2(FMT, A1, A2) enif_fprintf(stderr, FMT "\n", A1, A2)
*/
#define PRINTF_ERR0(FMT)
#define PRINTF_ERR1(FMT,A1)
+#define PRINTF_ERR2(FMT,A1,A2)
#ifdef __OSE__
@@ -506,7 +508,33 @@ static int init_ose_crypto() {
#define CHECK_OSE_CRYPTO()
#endif
+
+static int verify_lib_version(void)
+{
+ const unsigned long libv = SSLeay();
+ const unsigned long hdrv = OPENSSL_VERSION_NUMBER;
+
+# define MAJOR_VER(V) ((unsigned long)(V) >> (7*4))
+
+ if (MAJOR_VER(libv) != MAJOR_VER(hdrv)) {
+ PRINTF_ERR2("CRYPTO: INCOMPATIBLE SSL VERSION"
+ " lib=%lx header=%lx\n", libv, hdrv);
+ return 0;
+ }
+ return 1;
+}
+
+
#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;
@@ -545,6 +573,9 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
if (!INIT_OSE_CRYPTO())
return 0;
+ if (!verify_lib_version())
+ return 0;
+
/* load_info: {301, <<"/full/path/of/this/library">>} */
if (!enif_get_tuple(env, load_info, &tpl_arity, &tpl_array)
|| tpl_arity != 2
@@ -613,7 +644,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 +2928,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 +3275,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 +3438,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/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 7712173ed8..98384978a5 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -693,7 +693,7 @@
<p>Decrypts <c>CipherText</c> according to the stream cipher <c>Type</c> specified in stream_init/3.
<c>PlainText</c> can be any number of bytes. The initial <c>State</c> is created using
<seealso marker="#stream_init-2">stream_init</seealso>.
- <c>NewState</c> must be passed into the next call to <c>stream_encrypt</c>.</p>
+ <c>NewState</c> must be passed into the next call to <c>stream_decrypt</c>.</p>
</desc>
</func>
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 34f2e3c469..605d61e8e4 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -30,6 +30,84 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 3.4.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add configure option --with-ssl-incl=PATH to support
+ OpenSSL installations with headers and libraries at
+ different places.</p>
+ <p>
+ Own Id: OTP-12215 Aux Id: seq12700 </p>
+ </item>
+ <item>
+ <p>
+ Add configure option --with-ssl-rpath to control which
+ runtime library path to use for dynamic linkage toward
+ OpenSSL.</p>
+ <p>
+ Own Id: OTP-12316 Aux Id: seq12753 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make <c>crypto</c> verify major version number of OpenSSL
+ header files and runtime library. Loading of
+ <c>crypto</c> will fail if there is a version mismatch.</p>
+ <p>
+ Own Id: OTP-12146 Aux Id: seq12700 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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..b87685cb3f 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 3.3
+CRYPTO_VSN = 3.4.2
diff --git a/lib/debugger/doc/src/i.xml b/lib/debugger/doc/src/i.xml
index fb7641c30e..7564da79b3 100644
--- a/lib/debugger/doc/src/i.xml
+++ b/lib/debugger/doc/src/i.xml
@@ -211,7 +211,7 @@
the result of calling the shell function <c>pid(X,Y,Z)</c>.
An attached process is expected to call the unofficial
<c>int:attached(Pid)</c> function and to be able to handle
- messages from the interpreter, see <c>dbg_ui_trace.erl</c> for
+ messages from the interpreter, see <c>dbg_wx_trace.erl</c> for
an example.</p>
</desc>
</func>
diff --git a/lib/debugger/doc/src/int.xml b/lib/debugger/doc/src/int.xml
index 3a5886ceb9..96d0d7f83d 100644
--- a/lib/debugger/doc/src/int.xml
+++ b/lib/debugger/doc/src/int.xml
@@ -49,7 +49,7 @@
execution. This is done by sending and receiving information
to/from the process via a third process, called the meta process.
It is possible to implement your own attached process. See
- <c>int.erl</c> for available functions and <c>dbg_ui_trace.erl</c>
+ <c>int.erl</c> for available functions and <c>dbg_wx_trace.erl</c>
for possible messages.</p>
<p>The interpreter depends on the Kernel, STDLIB and GS
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 8832f99fc3..b4baa2a1cd 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -32,6 +32,47 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 4.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure to install .hrl files when needed</p>
+ <p>
+ Own Id: OTP-12197</p>
+ </item>
+ <item>
+ <p>
+ Invoking debugger functions <c>ia/1</c> and <c>iaa/1</c>
+ crashed, when it tried to invoke the old and removed gs
+ based gui functions.</p>
+ <p>
+ Own Id: OTP-12357</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/src/Makefile b/lib/debugger/src/Makefile
index 90189dd297..d61519f1ad 100644
--- a/lib/debugger/src/Makefile
+++ b/lib/debugger/src/Makefile
@@ -63,7 +63,7 @@ MODULES= \
HRL_FILES=
-INTERNAL_HRL_FILES= dbg_ieval.hrl
+INTERNAL_HRL_FILES= dbg_ieval.hrl dbg_wx_filedialog_win.hrl
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl
index b1bf4ebecc..ce12c1beb3 100644
--- a/lib/debugger/src/dbg_icmd.erl
+++ b/lib/debugger/src/dbg_icmd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. 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
@@ -49,10 +49,6 @@
%% specifies if the process should break.
%%--------------------------------------------------------------------
-%% Common Test adaptation
-cmd({call_remote,0,ct_line,line,_As}, Bs, _Ieval) ->
- Bs;
-
cmd(Expr, Bs, Ieval) ->
cmd(Expr, Bs, get(next_break), Ieval).
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index 77297de0f3..96f9f91808 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. 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
@@ -457,11 +457,6 @@ do_eval_function(Mod, Fun, As0, Bs0, _, Ieval0) when is_function(Fun);
exception(error, Reason, Bs0, Ieval0)
end;
-%% Common Test adaptation
-do_eval_function(ct_line, line, As, Bs, extern, #ieval{level=Le}=Ieval) ->
- debugged_cmd({apply,ct_line,line,As}, Bs, Ieval#ieval{level=Le+1}),
- {value, ignore, Bs};
-
do_eval_function(Mod, Name, As0, Bs0, Called, Ieval0) ->
#ieval{level=Le,line=Li,top=Top} = Ieval0,
trace(call, {Called, {Le,Li,Mod,Name,As0}}),
@@ -896,11 +891,6 @@ expr({make_ext_fun,Line,MFA0}, Bs0, Ieval0) ->
exception(error, badarg, Bs, Ieval, true)
end;
-%% Common test adaptation
-expr({call_remote,0,ct_line,line,As0,Lc}, Bs0, Ieval0) ->
- {As,_Bs} = eval_list(As0, Bs0, Ieval0),
- eval_function(ct_line, line, As, Bs0, extern, Ieval0, Lc);
-
%% Local function call
expr({local_call,Line,F,As0,Lc}, Bs0, #ieval{module=M} = Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
diff --git a/lib/debugger/src/dbg_wx_mon.erl b/lib/debugger/src/dbg_wx_mon.erl
index 4ab03985d3..aed86f5232 100644
--- a/lib/debugger/src/dbg_wx_mon.erl
+++ b/lib/debugger/src/dbg_wx_mon.erl
@@ -414,7 +414,7 @@ gui_cmd({'Trace Window', TraceWin}, State) ->
State2 = State#state{tracewin=TraceWin},
case State#state.attach of
false -> ignore;
- {Flags, {dbg_ui_trace, start, StartFlags}} ->
+ {Flags, {dbg_wx_trace, start, StartFlags}} ->
case trace_function(State2) of
{_, _, StartFlags} -> ignore;
NewFunction -> % {_, _, NewStartFlags}
diff --git a/lib/debugger/src/dbg_wx_settings.erl b/lib/debugger/src/dbg_wx_settings.erl
index 20aac74c3d..2c332c0a54 100644
--- a/lib/debugger/src/dbg_wx_settings.erl
+++ b/lib/debugger/src/dbg_wx_settings.erl
@@ -65,14 +65,8 @@ open_win(Win, Pos, SFile, Str, What) ->
{style,What}]),
case wxFileDialog:showModal(FD) of
?wxID_OK ->
- case wxFileDialog:getPaths(FD) of
- [NewFile] ->
- wxFileDialog:destroy(FD),
- {ok, NewFile};
- _ ->
- wxFileDialog:destroy(FD),
- cancel
- end;
+ NewFile = wxFileDialog:getPath(FD),
+ {ok, NewFile};
_ ->
wxFileDialog:destroy(FD),
cancel
diff --git a/lib/debugger/src/i.erl b/lib/debugger/src/i.erl
index 5805501524..0afb998097 100644
--- a/lib/debugger/src/i.erl
+++ b/lib/debugger/src/i.erl
@@ -250,7 +250,7 @@ ist(Flag) ->
%% -------------------------------------------
iaa(Flag) ->
- iaa(Flag,{dbg_ui_trace,start,[]}).
+ iaa(Flag,{dbg_wx_trace,start,[]}).
%% -------------------------------------------
%% Set the automatic attachment flag.
@@ -271,7 +271,7 @@ iaa(Flag,Fnk) ->
%% -------------------------------------------
ia(Pid) ->
- ia(Pid,{dbg_ui_trace,start}).
+ ia(Pid,{dbg_wx_trace,start}).
%% -------------------------------------------
%% Attach to process.
diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl
index 2755db64b8..908390ce50 100644
--- a/lib/debugger/src/int.erl
+++ b/lib/debugger/src/int.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2013. 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
@@ -265,9 +265,6 @@ first_lines(Clauses) ->
first_line({clause,_L,_Vars,_,Exprs}) ->
first_line(Exprs);
-%% Common Test adaptation
-first_line([{call_remote,0,ct_line,line,_As}|Exprs]) ->
- first_line(Exprs);
first_line([Expr|_Exprs]) -> % Expr = {Op, Line, ..varying no of args..}
element(2, Expr).
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index cd107599e9..38c19be93e 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 4.0
+DEBUGGER_VSN = 4.0.2
diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml
index 3de60b2f7a..e482b1e6f8 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>
@@ -243,7 +238,10 @@
<item>Include warnings for functions that only return by means of an
exception.</item>
<tag><c><![CDATA[-Wrace_conditions]]></c>***</tag>
- <item>Include warnings for possible race conditions.</item>
+ <item>Include warnings for possible race conditions. Note that the
+ analysis that finds data races performs intra-procedural data flow analysis
+ and can sometimes explode in time. Enable it at your own risk.
+ </item>
<tag><c><![CDATA[-Wunderspecs]]></c>***</tag>
<item>Warn about underspecified functions
(the -spec is strictly more allowing than the success typing).</item>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 05baa93557..4020165697 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -31,6 +31,112 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> When compiling Erlang source, Dialyzer now ignores
+ the environment variable ERL_COMPILER_OPTIONS as well as
+ skips the Erlang Compiler option
+ <c>warnings_as_errors</c>. </p>
+ <p>
+ Own Id: OTP-12225</p>
+ </item>
+ <item>
+ <p> Dialyzer did not check the type of record elements
+ when updating them. The bug, introduced in Erlang/OTP
+ 17.1, has been corrected. (Thanks to Nicolas Dudebout for
+ pointing it out.) </p>
+ <p>
+ Own Id: OTP-12319</p>
+ </item>
+ <item>
+ <p>
+ Coalesce map keys in dialyzer mode</p>
+ <p>
+ This fixes a regression introduced in commit
+ 805f9c89fc01220bc1bb0f27e1b68fd4eca688ba The problem
+ occurred with compounded map keys compiled with dialyzer
+ option turned on, '+dialyzer'.</p>
+ <p>
+ Reported by: Ivan Uemlianin</p>
+ <p>
+ Own Id: OTP-12347</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 2.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> A bug concerning <c>is_record/2,3</c> has been fixed,
+ as well as some cases where Dialyzer could crash due to
+ reaching system limits. </p>
+ <p>
+ Own Id: OTP-12018</p>
+ </item>
+ <item>
+ <p> When given the <c>-Wunderspecs</c> flag Dialyzer
+ sometimes output bogus warnings for parametrized types.
+ This bug has been fixed. </p>
+ <p>
+ Own Id: OTP-12111</p>
+ </item>
+ <item>
+ <p>Dialyzer now fetch the compile options from beam
+ files, and use them when creating core from the abstract
+ code. Previously the options were ignored. </p>
+ <p>
+ Own Id: OTP-12150</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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 +273,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_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index 6a33a2acb3..af1c2b7e3a 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -373,7 +373,16 @@ compile_byte(File, Callgraph, CServer, UseContracts) ->
{error, " Could not get abstract code for: " ++ File ++ "\n" ++
" Recompile with +debug_info or analyze starting from source code"};
{ok, AbstrCode} ->
- compile_common(File, AbstrCode, [], Callgraph, CServer, UseContracts)
+ compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts)
+ end.
+
+compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts) ->
+ case dialyzer_utils:get_compile_options_from_beam(File) of
+ error ->
+ {error, " Could not get compile options for: " ++ File ++ "\n" ++
+ " Recompile or analyze starting from source code"};
+ {ok, CompOpts} ->
+ compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts)
end.
compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts) ->
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 1d2dfc7b2d..f27fc1a842 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -20,8 +20,6 @@
-module(dialyzer_contracts).
--compile(export_all).
-
-export([check_contract/2,
check_contracts/4,
contracts_without_fun/3,
@@ -686,7 +684,7 @@ picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) ->
true -> Acc;
false ->
case extra_contract_warning(MFA, FileLine, Contract,
- CSig, Sig, RecDict) of
+ CSig0, Sig0, RecDict) of
no_warning -> Acc;
{warning, Warning} -> [Warning|Acc]
end
@@ -752,7 +750,8 @@ is_remote_types_related(Contract, CSig, Sig, RecDict) ->
t_from_forms_without_remote([{FType, []}], RecDict) ->
Type0 = erl_types:t_from_form(FType, RecDict),
- {ok, erl_types:subst_all_remote(Type0, erl_types:t_none())};
+ Type1 = erl_types:subst_all_remote(Type0, erl_types:t_none()),
+ {ok, erl_types:subst_all_vars_to_any(Type1)};
t_from_forms_without_remote([{_FType, _Constrs}], _RecDict) ->
%% 'When' constraints
unsupported;
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index e0873b17f8..03005e689f 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,
@@ -93,6 +93,8 @@
-define(TYPE_LIMIT, 3).
+-define(BITS, 128).
+
-record(state, {callgraph :: dialyzer_callgraph:callgraph(),
envs :: env_tab(),
fun_tab :: fun_tab(),
@@ -136,11 +138,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 +278,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 +1106,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 +1236,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 +1289,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 +1441,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 +1457,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 +1470,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 +1481,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 +1497,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 +1546,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 ->
@@ -1615,10 +1612,18 @@ bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) ->
SizeVal = lists:max(List),
Flags = cerl:concrete(cerl:bitstr_flags(Seg)),
N = SizeVal * UnitVal,
- case lists:member(signed, Flags) of
- true -> t_from_range(-(1 bsl (N - 1)), 1 bsl (N - 1) - 1);
- false -> t_from_range(0, 1 bsl N - 1)
- end
+ case N >= ?BITS of
+ true ->
+ case lists:member(signed, Flags) of
+ true -> t_from_range(neg_inf, pos_inf);
+ false -> t_from_range(0, pos_inf)
+ end;
+ false ->
+ case lists:member(signed, Flags) of
+ true -> t_from_range(-(1 bsl (N - 1)), 1 bsl (N - 1) - 1);
+ false -> t_from_range(0, 1 bsl N - 1)
+ end
+ end
end
end,
{Map2, [_]} = bind_pat_vars([Val], [ValConstr], [], Map1, State, false),
@@ -1631,21 +1636,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 +1853,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 +1864,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 +1990,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 +2007,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 +2060,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 +2076,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 +3293,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 +3362,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 +3395,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 +3456,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 +3512,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..5297a3a7b4 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -31,6 +31,7 @@
format_sig/1,
format_sig/2,
get_abstract_code_from_beam/1,
+ get_compile_options_from_beam/1,
get_abstract_code_from_src/1,
get_abstract_code_from_src/2,
get_core_from_abstract_code/1,
@@ -97,7 +98,7 @@ get_abstract_code_from_src(File) ->
{'ok', abstract_code()} | {'error', [string()]}.
get_abstract_code_from_src(File, Opts) ->
- case compile:file(File, [to_pp, binary|Opts]) of
+ case compile:noenv_file(File, [to_pp, binary|Opts]) of
error -> {error, []};
{error, Errors, _} -> {error, format_errors(Errors)};
{ok, _, AbstrCode} -> {ok, AbstrCode}
@@ -136,6 +137,26 @@ get_abstract_code_from_beam(File) ->
error
end.
+-spec get_compile_options_from_beam(file:filename()) -> 'error' | {'ok', [compile:option()]}.
+
+get_compile_options_from_beam(File) ->
+ case beam_lib:chunks(File, [compile_info]) of
+ {ok, {_, List}} ->
+ case lists:keyfind(compile_info, 1, List) of
+ {compile_info, CompInfo} -> compile_info_to_options(CompInfo);
+ _ -> error
+ end;
+ _ ->
+ %% No or unsuitable compile info.
+ error
+ end.
+
+compile_info_to_options(CompInfo) ->
+ case lists:keyfind(options, 1, CompInfo) of
+ {options, CompOpts} -> {ok, CompOpts};
+ _ -> error
+ end.
+
-type get_core_from_abs_ret() :: {'ok', cerl:c_module()} | 'error'.
-spec get_core_from_abstract_code(abstract_code()) -> get_core_from_abs_ret().
@@ -150,7 +171,9 @@ get_core_from_abstract_code(AbstrCode, Opts) ->
%% performed them. In some cases we end up in trouble when
%% performing them again.
AbstrCode1 = cleanup_parse_transforms(AbstrCode),
- try compile:forms(AbstrCode1, Opts ++ src_compiler_opts()) of
+ %% Remove parse_transforms (and other options) from compile options.
+ Opts2 = cleanup_compile_options(Opts),
+ try compile:noenv_forms(AbstrCode1, Opts2 ++ src_compiler_opts()) of
{ok, _, Core} -> {ok, Core};
_What -> error
catch
@@ -402,7 +425,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().
@@ -419,6 +442,21 @@ cleanup_parse_transforms([Other|Left]) ->
cleanup_parse_transforms([]) ->
[].
+-spec cleanup_compile_options([compile:option()]) -> [compile:option()].
+
+cleanup_compile_options(Opts) ->
+ lists:filter(fun keep_compile_option/1, Opts).
+
+%% Using abstract, not asm or core.
+keep_compile_option(from_asm) -> false;
+keep_compile_option(asm) -> false;
+keep_compile_option(from_core) -> false;
+%% The parse transform will already have been applied, may cause
+%% problems if it is re-applied.
+keep_compile_option({parse_transform, _}) -> false;
+keep_compile_option(warnings_as_errors) -> false;
+keep_compile_option(_) -> true.
+
-spec format_errors([{module(), string()}]) -> [string()].
format_errors([{Mod, Errors}|Left]) ->
diff --git a/lib/dialyzer/test/dialyzer_SUITE.erl b/lib/dialyzer/test/dialyzer_SUITE.erl
index 1b62291a00..8507525597 100644
--- a/lib/dialyzer/test/dialyzer_SUITE.erl
+++ b/lib/dialyzer/test/dialyzer_SUITE.erl
@@ -30,12 +30,12 @@
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
--export([app_test/1, appup_test/1]).
+-export([app_test/1, appup_test/1, beam_tests/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test, appup_test].
+ [app_test, appup_test, beam_tests].
groups() ->
[].
@@ -75,3 +75,38 @@ app_test(Config) when is_list(Config) ->
%% Test that the .appup file does not contain any `basic' errors
appup_test(Config) when is_list(Config) ->
ok = ?t:appup_test(dialyzer).
+
+beam_tests(Config) when is_list(Config) ->
+ Prog = <<"
+ -module(no_auto_import).
+
+ %% Copied from erl_lint_SUITE.erl, clash6
+
+ -export([size/1]).
+
+ size([]) ->
+ 0;
+ size({N,_}) ->
+ N;
+ size([_|T]) ->
+ 1+size(T).
+ ">>,
+ Opts = [no_auto_import],
+ {ok, BeamFile} = compile(Config, Prog, no_auto_import, Opts),
+ [] = run_dialyzer([BeamFile]),
+ ok.
+
+compile(Config, Prog, Module, CompileOpts) ->
+ Source = lists:concat([Module, ".erl"]),
+ PrivDir = ?config(priv_dir,Config),
+ Filename = filename:join([PrivDir, Source]),
+ ok = file:write_file(Filename, Prog),
+ Opts = [{outdir, PrivDir}, debug_info | CompileOpts],
+ {ok, Module} = compile:file(Filename, Opts),
+ {ok, filename:join([PrivDir, lists:concat([Module, ".beam"])])}.
+
+run_dialyzer(Files) ->
+ dialyzer:run([{analysis_type, plt_build},
+ {files, Files},
+ {from, byte_code},
+ {check_plt, false}]).
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/opaque/opaque_bug5.erl b/lib/dialyzer/test/opaque_SUITE_data/src/opaque/opaque_bug5.erl
new file mode 100644
index 0000000000..28d739de8e
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/opaque/opaque_bug5.erl
@@ -0,0 +1,10 @@
+%% Second arg of is_record call wasn't checked properly
+
+-module(opaque_bug5).
+
+-export([b/0]).
+
+b() ->
+ is_record(id({a}), id(a)).
+
+id(I) -> I.
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/record_update b/lib/dialyzer/test/small_SUITE_data/results/record_update
new file mode 100644
index 0000000000..ea52057adf
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/record_update
@@ -0,0 +1,2 @@
+
+record_update.erl:7: Invalid type specification for function record_update:quux/2. The success typing is (#foo{bar::atom()},atom()) -> #foo{bar::atom()}
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/limit.erl b/lib/dialyzer/test/small_SUITE_data/src/limit.erl
new file mode 100644
index 0000000000..97ee585b77
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/limit.erl
@@ -0,0 +1,20 @@
+%% Misc cases where Dialyzer would fail with system_limit or crash
+
+-module(limit).
+
+-export([tu/0, big/1, b2/0]).
+
+tu() ->
+ erlang:make_tuple(1 bsl 24, def, [{5,e},{1,a},{3,c}]).
+
+big(<<Int:1152921504606846976/unit:128,0,_/binary>>) -> {5,Int}.
+
+b2() ->
+ Maxbig = maxbig(),
+ _ = bnot Maxbig,
+ ok.
+
+maxbig() ->
+ %% We assume that the maximum arity is (1 bsl 19) - 1.
+ Ws = erlang:system_info(wordsize),
+ (((1 bsl ((16777184 * (Ws div 4))-1)) - 1) bsl 1) + 1.
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/maps1.erl b/lib/dialyzer/test/small_SUITE_data/src/maps1.erl
index 06ced5b69e..228ffe2c22 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/maps1.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/maps1.erl
@@ -10,6 +10,7 @@
-export([recv/3, decode/1]).
+-export([get_my_map/0,is_my_map/1]).
%-record(can_pkt, {id, data :: binary(), timestamp}).
@@ -39,3 +40,38 @@ t2() -> ok.
update(#{ id := Id, val := Val } = M, X) when is_integer(Id) ->
M#{ val := [Val,X] }.
+
+%% key coalescing
+
+-spec get_my_map() -> map().
+
+get_my_map() ->
+ #{labels => [one, two],
+ number => 27,
+ [1,2,3] => wer,
+ {4,5,6} => sdf,
+ kvok => #{
+ <<"wat">> => v,
+ a => qwe,
+ 2 => asd,
+ [1,2,3] => wer,
+ {4,5,6} => sdf,
+ "abc" => zxc
+ }
+ }.
+
+-spec is_my_map(map()) -> 'ok'.
+
+is_my_map(#{labels := [one, two],
+ number := 27,
+ [1,2,3] := wer,
+ {4,5,6} := sdf,
+ kvok := #{
+ <<"wat">> := v,
+ a := qwe,
+ 2 := asd,
+ [1,2,3] := wer,
+ {4,5,6} := sdf,
+ "abc" := zxc
+ }
+ }) -> ok.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl b/lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl
new file mode 100644
index 0000000000..945b2a9144
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl
@@ -0,0 +1,23 @@
+%% In 17, the linter says that map(A) redefines 'type map', which is
+%% allowed until next release. However, Dialyzer used to replace
+%% map(A) with #{}, which resulted in warnings.
+
+-module(maps_redef2).
+
+-export([t/0]).
+
+-type map(_A) :: integer().
+
+t() ->
+ M = new(),
+ t1(M).
+
+-spec t1(map(_)) -> map(_).
+
+t1(A) ->
+ A + A.
+
+-spec new() -> map(_).
+
+new() ->
+ 3.
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/record_update.erl b/lib/dialyzer/test/small_SUITE_data/src/record_update.erl
new file mode 100644
index 0000000000..bad7a0a929
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/record_update.erl
@@ -0,0 +1,10 @@
+-module(record_update).
+
+-export([quux/2]).
+
+-record(foo, {bar :: atom()}).
+
+-spec quux(#foo{}, string()) -> #foo{}.
+
+quux(Foo, NotBar) ->
+ Foo#foo{ bar = NotBar }.
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/test/underspecs_SUITE_data/results/arr b/lib/dialyzer/test/underspecs_SUITE_data/results/arr
new file mode 100644
index 0000000000..9497d12eec
--- /dev/null
+++ b/lib/dialyzer/test/underspecs_SUITE_data/results/arr
@@ -0,0 +1,4 @@
+
+arr.erl:14: Type specification arr:test2(array:array(T),non_neg_integer(),T) -> array:array(T) is a supertype of the success typing: arr:test2(array:array(_),pos_integer(),_) -> array:array(_)
+arr.erl:24: Type specification arr:test4(array:array(T),non_neg_integer(),_) -> array:array(T) is a supertype of the success typing: arr:test4(array:array(_),pos_integer(),_) -> array:array(_)
+arr.erl:29: Type specification arr:test5(array:array(T),non_neg_integer(),T) -> array:array(T) is a supertype of the success typing: arr:test5(array:array(_),non_neg_integer(),integer()) -> array:array(_)
diff --git a/lib/dialyzer/test/underspecs_SUITE_data/src/arr.erl b/lib/dialyzer/test/underspecs_SUITE_data/src/arr.erl
new file mode 100644
index 0000000000..3b265ccec2
--- /dev/null
+++ b/lib/dialyzer/test/underspecs_SUITE_data/src/arr.erl
@@ -0,0 +1,41 @@
+-module(arr).
+
+%% http://erlang.org/pipermail/erlang-questions/2014-August/080445.html
+
+-define(A, array).
+
+-export([test/3, test2/3, test3/3, test4/3, test5/3, test6/3]).
+
+-spec test(?A:array(T), non_neg_integer(), T) -> ?A:array(T).
+
+test(Array, N, Value) ->
+ ?A:set(N, Value, Array).
+
+-spec test2(?A:array(T), non_neg_integer(), T) -> ?A:array(T).
+
+test2(Array, N, Value) when N > 0 ->
+ ?A:set(N, Value, Array).
+
+-spec test3(?A:array(T), non_neg_integer(), _) -> ?A:array(T).
+
+test3(Array, N, Value) ->
+ ?A:set(N, Value, Array).
+
+-spec test4(?A:array(T), non_neg_integer(), _) -> ?A:array(T).
+
+test4(Array, N, Value) when N > 0 ->
+ ?A:set(N, Value, Array).
+
+-spec test5(?A:array(T), non_neg_integer(), T) -> ?A:array(T).
+
+test5(Array, N, Value) when is_integer(Value) ->
+ ?A:set(N, Value, Array).
+
+%% One would ideally want a warning also for test6(), but the current
+%% analysis of parametrized opaque types is not strong enough to
+%% discover this.
+-spec test6(?A:array(integer()), non_neg_integer(), integer()) ->
+ ?A:array(any()).
+
+test6(Array, N, Value) ->
+ ?A:set(N, Value, Array).
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 95d2464e1d..e7c13f04ad 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 2.7
+DIALYZER_VSN = 2.7.3
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index ab9ad25a3a..00b54ffbc4 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -500,6 +500,18 @@ Matches only those peers matched by each filter in the specified list.</p>
<p>
Matches only those peers matched by at least one filter in the
specified list.</p>
+
+<p>
+The resulting peer list will be in match order, peers matching the
+first filter of the list sorting before those matched by the second,
+and so on.
+For example, the following filter causes peers matching both the host
+and realm filters to be presented before those matching only the realm
+filter.</p>
+
+<pre>
+{any, [{all, [host, realm]}, realm]}
+</pre>
</item>
</taglist>
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index 68e69dbfeb..e6ac332c10 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -42,6 +42,256 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>diameter 1.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix remote diameter_request table leak.</p>
+ <p>
+ An outgoing request whose pick_peer callback selected a
+ transport on another node resulted in an orphaned table
+ entry on that node.</p>
+ <p>
+ Own Id: OTP-12196</p>
+ </item>
+ <item>
+ <p>
+ Fix handling of 3xxx Result-Code without E-bit.</p>
+ <p>
+ OTP-12233 broke the population of the errors field of the
+ diameter_packet record when an incoming request with an
+ E-bit/Result-Code mismatch was detected, causing a
+ 4-tuple to be inserted as Result-Code in a diameter_avp
+ record.</p>
+ <p>
+ Own Id: OTP-12233</p>
+ </item>
+ <item>
+ <p>
+ Fix ignored connect timer.</p>
+ <p>
+ There are two timers governing the establishment of peer
+ connections: connect_timer and watchdog_timer. The former
+ is the RFC 6733 Tc timer, and is used at initial
+ connection establishment. The latter is RFC 3539 TwInit,
+ and is used for connection reestablishment. A connecting
+ transport erroneously used watchdog_timer in both cases.</p>
+ <p>
+ Own Id: OTP-12281 Aux Id: seq12728 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Order candidate peers in pick_peer callbacks.</p>
+ <p>
+ The order of candidate peers presented to a
+ diameter_app(3) pick_peer callback has previously not
+ been documented, but there are use cases that are
+ simplified by an ordering. The order is now determined by
+ the filter.</p>
+ <p>
+ Own Id: OTP-12308</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>diameter 1.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Don't leave extra bit in decoded AVP data.</p>
+ <p>
+ An extra bit could be communicated in the data field of a
+ diameter_avp record in the case of length errors. Of no
+ consequence for code using the record encoding of
+ Diameter messages, but code examining diameter_avp
+ records would see this bit.</p>
+ <p>
+ Dictionary files must be recompiled for the fix to have
+ effect.</p>
+ <p>
+ Own Id: OTP-12074</p>
+ </item>
+ <item>
+ <p>
+ Fix counting of outgoing requests and answers setting the
+ E-bit.</p>
+ <p>
+ OTP-11721 broke these counters for all outgoing requests
+ except DWR, and caused answers setting the E-bit to be
+ counted as unknown messages.</p>
+ <p>
+ Own Id: OTP-12080</p>
+ </item>
+ <item>
+ <p>
+ Fix Failed-AVP decode.</p>
+ <p>
+ The best-effort decode only worked for AVPs in the common
+ dictionary, not for those in the dictionary of the
+ application identified in the Diameter Header of the
+ answer message in question.</p>
+ <p>
+ Failed-AVP in an answer decoded with the RFC 3588 common
+ dictionary (diameter_gen_base_rfc3588) was regarded as an
+ error. The RFC 6733 dictionary was unaffected.</p>
+ <p>
+ Dictionary files must be recompiled for the fix to have
+ effect.</p>
+ <p>
+ Own Id: OTP-12094</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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>
+ Dictionary files must be recompiled for the fix to have
+ effect.</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>
+ Dictionary files must be recompiled for the fix to have
+ effect.</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/examples/code/peer.erl b/lib/diameter/examples/code/peer.erl
index b4ee17e4b7..7519abfb2c 100644
--- a/lib/diameter/examples/code/peer.erl
+++ b/lib/diameter/examples/code/peer.erl
@@ -74,7 +74,7 @@ start(Name, Opts)
| {error, term()}.
connect(Name, T) ->
- diameter:add_transport(Name, {connect, [{reconnect_timer, 5000}
+ diameter:add_transport(Name, {connect, [{connect_timer, 5000}
| client(T)]}).
%% listen/2
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index 7e91ce375f..bc25f7d472 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -311,19 +311,55 @@ d(Name, Avp, Acc) ->
Failed = relax(Name), %% Not AvpName or else a failed Failed-AVP
%% decode is packed into 'AVP'.
- try avp(decode, Data, AvpName) of
+ Mod = dict(Failed), %% Dictionary to decode in.
+
+ try Mod:avp(decode, Data, AvpName) of
V ->
{Avps, T} = Acc,
{H, A} = ungroup(V, Avp),
{[H | Avps], pack_avp(Name, A, T)}
catch
error: Reason ->
- d(undefined == Failed orelse is_failed(), Reason, Name, Avp, Acc)
+ d(undefined == Failed orelse is_failed(),
+ Reason,
+ Name,
+ trim(Avp),
+ Acc)
after
reset(?STRICT_KEY, Strict),
reset(?FAILED_KEY, Failed)
end.
+%% trim/1
+%%
+%% Remove any extra bit that was added in diameter_codec to induce a
+%% 5014 error.
+
+trim(#diameter_avp{data = <<0:1, Bin/binary>>} = Avp) ->
+ Avp#diameter_avp{data = Bin};
+
+trim(Avp) ->
+ Avp.
+
+%% dict/1
+%%
+%% Retrieve the dictionary for the best-effort decode of Failed-AVP,
+%% as put by diameter_codec:decode/2. See that function for the
+%% explanation.
+
+dict(true) ->
+ case get({diameter_codec, dictionary}) of
+ undefined ->
+ ?MODULE;
+ Mod ->
+ Mod
+ end;
+
+dict(_) ->
+ ?MODULE.
+
+%% d/5
+
%% Ignore a decode error within Failed-AVP ...
d(true, _, Name, Avp, Acc) ->
decode_AVP(Name, Avp, Acc);
@@ -341,6 +377,8 @@ d(false, Reason, Name, Avp, {Avps, Acc}) ->
{Rec, Failed} = Acc,
{[Avp|Avps], {Rec, [rc(Reason, Avp) | Failed]}}.
+%% relax/2
+
%% Set false in the process dictionary as soon as we see a Grouped AVP
%% that doesn't set the M-bit, so that is_strict() can say whether or
%% not to ignore the M-bit on an encapsulated AVP.
@@ -357,22 +395,23 @@ relax(_, _) ->
is_strict() ->
false /= getr(?STRICT_KEY).
+%% relax/1
+%%
%% Set true in the process dictionary as soon as we see Failed-AVP.
%% Matching on 'Failed-AVP' assumes that this is the RFC AVP.
%% Strictly, this doesn't need to be the case.
+
relax('Failed-AVP') ->
- case getr(?FAILED_KEY) of
- undefined ->
- putr(?FAILED_KEY, true);
- true = Yes ->
- Yes
- end;
+ is_failed() orelse putr(?FAILED_KEY, true);
+
relax(_) ->
is_failed().
is_failed() ->
true == getr(?FAILED_KEY).
+%% reset/2
+
reset(Key, undefined) ->
eraser(Key);
reset(_, _) ->
@@ -453,8 +492,8 @@ pack_AVP(_, #diameter_avp{data = <<0:1, Data/binary>>} = Avp, Acc) ->
{Rec, Failed} = Acc,
{Rec, [{5014, Avp#diameter_avp{data = Data}} | Failed]};
-pack_AVP(Name, #diameter_avp{is_mandatory = M} = Avp, Acc) ->
- case pack_arity(Name, M) of
+pack_AVP(Name, #diameter_avp{is_mandatory = M, name = AvpName} = Avp, Acc) ->
+ case pack_arity(Name, AvpName, M) of
0 ->
{Rec, Failed} = Acc,
{Rec, [{if M -> 5001; true -> 5008 end, Avp} | Failed]};
@@ -462,10 +501,13 @@ pack_AVP(Name, #diameter_avp{is_mandatory = M} = Avp, Acc) ->
pack(Arity, 'AVP', Avp, Acc)
end.
-%% Give Failed-AVP special treatment since it'll contain any
-%% unrecognized mandatory AVP's.
-pack_arity(Name, M) ->
- NF = Name /= 'Failed-AVP' andalso not is_failed(),
+%% Give Failed-AVP special treatment since (1) it'll contain any
+%% unrecognized mandatory AVP's and (2) the RFC 3588 grammar failed to
+%% allow for Failed-AVP in an answer-message.
+
+pack_arity(Name, AvpName, M) ->
+ IsFailed = Name == 'Failed-AVP' orelse is_failed(),
+
%% Not testing just Name /= 'Failed-AVP' means we're changing the
%% packing of AVPs nested within Failed-AVP, but the point of
%% ignoring errors within Failed-AVP is to decode as much as
@@ -473,12 +515,18 @@ pack_arity(Name, M) ->
%% packed into a dedicated field defeats that point. Note that we
%% can't just test not is_failed() since this will be 'true' when
%% packing an unknown AVP directly within Failed-AVP.
- case NF andalso M andalso is_strict() of
- true ->
- 0;
- false ->
- avp_arity(Name, 'AVP')
- end.
+
+ pack_arity(IsFailed
+ orelse {Name, AvpName} == {'answer-message', 'Failed-AVP'}
+ orelse not M
+ orelse not is_strict(),
+ Name).
+
+pack_arity(true, Name) ->
+ avp_arity(Name, 'AVP');
+
+pack_arity(false, _) ->
+ 0.
%% 3588:
%%
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index 06a4f5de64..a2b04bfd63 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -237,15 +237,35 @@ rec2msg(Mod, Rec) ->
%% Unsuccessfully decoded AVPs will be placed in #diameter_packet.errors.
--spec decode(module(), #diameter_packet{} | binary())
+-spec decode(module() | {module(), module()}, #diameter_packet{} | binary())
-> #diameter_packet{}.
+%% An Answer setting the E-bit. The application dictionary is needed
+%% for the best-effort decode of Failed-AVP, and the best way to make
+%% this available to the AVP decode in diameter_gen.hrl, without
+%% having to rewrite the entire codec generation, is to place it in
+%% the process dictionary. It's the code in diameter_gen.hrl (that's
+%% included by every generated codec module) that looks for the entry.
+%% Not ideal, but it solves the problem relatively simply.
+decode({Mod, Mod}, Pkt) ->
+ decode(Mod, Pkt);
+decode({Mod, AppMod}, Pkt) ->
+ Key = {?MODULE, dictionary},
+ put(Key, AppMod),
+ try
+ decode(Mod, Pkt)
+ after
+ erase(Key)
+ end;
+
+%% Or not: a request, or an answer not setting the E-bit.
decode(Mod, Pkt) ->
decode(Mod:id(), Mod, Pkt).
-%% If we're a relay application then just extract the avp's without
-%% any decoding of their data since we don't know the application in
-%% question.
+%% decode/3
+
+%% Relay application: just extract the avp's without any decoding of
+%% their data since we don't know the application in question.
decode(?APP_ID_RELAY, _, #diameter_packet{} = Pkt) ->
case collect_avps(Pkt) of
{E, As} ->
@@ -274,6 +294,8 @@ decode(Id, Mod, Bin)
when is_binary(Bin) ->
decode(Id, Mod, #diameter_packet{header = decode_header(Bin), bin = Bin}).
+%% decode_avps/4
+
decode_avps(MsgName, Mod, Pkt, {E, Avps}) ->
?LOG(invalid_avp_length, Pkt#diameter_packet.header),
#diameter_packet{errors = Failed}
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index 31e570ae20..ee6e7dd89e 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -225,8 +225,8 @@ start_transport(Addrs0, T) ->
erlang:monitor(process, TPid),
q_next(TPid, Addrs0, Tmo, Data),
{TPid, Addrs};
- No ->
- exit({shutdown, No})
+ {error, No} ->
+ exit({shutdown, {no_connection, No}})
end.
svc(#diameter_service{capabilities = LCaps0} = Svc, Addrs) ->
@@ -368,11 +368,8 @@ transition({diameter, {TPid, connected}},
%% message. This may be followed by an incoming message which arrived
%% before the transport was killed and this can't be distinguished
%% from one from the transport that's been started to replace it.
-transition({diameter, {_, connected}}, _) ->
- {stop, connection_timeout};
-transition({diameter, {_, connected, _}}, _) ->
- {stop, connection_timeout};
-transition({diameter, {_, connected, _, _}}, _) ->
+transition({diameter, T}, _)
+ when tuple_size(T) < 5, connected == element(2,T) ->
{stop, connection_timeout};
%% Connection has timed out: start an alternate.
@@ -477,6 +474,7 @@ send_CER(#state{state = {'Wait-Conn-Ack', Tmo},
hop_by_hop_id = Hid}}
= Pkt
= encode(CER, Dict),
+ incr(send, Pkt, Dict),
send(TPid, Pkt),
?LOG(send, 'CER'),
start_timer(Tmo, S#state{state = {'Wait-CEA', Hid, Eid}}).
@@ -1100,6 +1098,7 @@ send_dpr(Reason, Opts, #state{transport = TPid,
{'Origin-Realm', OR},
{'Disconnect-Cause', Cause}],
Dict),
+ incr(send, Pkt, Dict),
send(TPid, Pkt),
dpa_timer(Tmo),
?LOG(send, 'DPR'),
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index b7cd311e02..76b05a2ad4 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -1460,42 +1460,52 @@ pick_peer(Local,
peers(Alias, RH, Filter, Peers) ->
case ?Dict:find(Alias, Peers) of
{ok, L} ->
- ps(L, RH, Filter, {[],[]});
+ filter(L, RH, Filter);
error ->
[]
end.
-%% Place a peer whose Destination-Host/Realm matches those of the
-%% request at the front of the result list. Could add some sort of
-%% 'sort' option to allow more control.
-
-ps([], _, _, {Ys, Ns}) ->
- lists:reverse(Ys, Ns);
-ps([{_TPid, #diameter_caps{} = Caps} = TC | Rest], RH, Filter, Acc) ->
- ps(Rest, RH, Filter, pacc(caps_filter(Caps, RH, Filter),
- caps_filter(Caps, RH, {all, [host, realm]}),
- TC,
- Acc)).
-
-pacc(true, true, Peer, {Ts, Fs}) ->
- {[Peer|Ts], Fs};
-pacc(true, false, Peer, {Ts, Fs}) ->
- {Ts, [Peer|Fs]};
-pacc(_, _, _, Acc) ->
- Acc.
+%% filter/3
+%%
+%% Return peers in match order.
-%% caps_filter/3
+filter(Peers, RH, Filter) ->
+ {Ts, _} = fltr(Peers, RH, Filter),
+ Ts.
+
+%% fltr/4
+
+fltr(Peers, _, none) ->
+ {Peers, []};
-caps_filter(C, RH, {neg, F}) ->
- not caps_filter(C, RH, F);
+fltr(Peers, RH, {neg, F}) ->
+ {Ts, Fs} = fltr(Peers, RH, F),
+ {Fs, Ts};
-caps_filter(C, RH, {all, L})
+fltr(Peers, RH, {all, L})
when is_list(L) ->
- lists:all(fun(F) -> caps_filter(C, RH, F) end, L);
+ lists:foldl(fun(F,A) -> fltr_all(F, A, RH) end,
+ {Peers, []},
+ L);
-caps_filter(C, RH, {any, L})
+fltr(Peers, RH, {any, L})
when is_list(L) ->
- lists:any(fun(F) -> caps_filter(C, RH, F) end, L);
+ lists:foldl(fun(F,A) -> fltr_any(F, A, RH) end,
+ {[], Peers},
+ L);
+
+fltr(Peers, RH, F) ->
+ lists:partition(fun({_,C}) -> caps_filter(C, RH, F) end, Peers).
+
+fltr_all(F, {Ts0, Fs0}, RH) ->
+ {Ts1, Fs1} = fltr(Ts0, RH, F),
+ {Ts1, Fs0 ++ Fs1}.
+
+fltr_any(F, {Ts0, Fs0}, RH) ->
+ {Ts1, Fs1} = fltr(Fs0, RH, F),
+ {Ts0 ++ Ts1, Fs1}.
+
+%% caps_filter/3
caps_filter(#diameter_caps{origin_host = {_,OH}}, [_,DH], host) ->
eq(undefined, DH, OH);
@@ -1508,9 +1518,6 @@ caps_filter(C, _, Filter) ->
%% caps_filter/2
-caps_filter(_, none) ->
- true;
-
caps_filter(#diameter_caps{origin_host = {_,OH}}, {host, H}) ->
eq(any, H, OH);
@@ -1573,7 +1580,8 @@ transports(#state{watchdogT = WatchdogT}) ->
-define(OTHER_INFO, [connections,
name,
peers,
- statistics]).
+ statistics,
+ info]).
service_info(Item, S)
when is_atom(Item) ->
@@ -1663,6 +1671,7 @@ complete_info(Item, #state{service = Svc} = S) ->
keys -> ?ALL_INFO ++ ?CAP_INFO ++ ?OTHER_INFO;
all -> service_info(?ALL_INFO, S);
statistics -> info_stats(S);
+ info -> info_info(S);
connections -> info_connections(S);
peers -> info_peers(S)
end.
@@ -1745,12 +1754,11 @@ peer_acc(PeerT, Acc, #watchdog{pid = Pid,
state = WS,
started = At,
peer = TPid}) ->
- dict:append(Ref,
- [{type, Type},
- {options, Opts},
- {watchdog, {Pid, At, WS}}
- | info_peer(PeerT, TPid, WS)],
- Acc).
+ Info = [{type, Type},
+ {options, Opts},
+ {watchdog, {Pid, At, WS}}
+ | info_peer(PeerT, TPid, WS)],
+ dict:append(Ref, Info ++ [{info, info_process_info(Info)}], Acc).
info_peer(PeerT, TPid, WS)
when is_pid(TPid), WS /= ?WD_DOWN ->
@@ -1762,6 +1770,49 @@ info_peer(PeerT, TPid, WS)
info_peer(_, _, _) ->
[].
+info_process_info(Info) ->
+ lists:flatmap(fun ipi/1, Info).
+
+ipi({watchdog, {Pid, _, _}}) ->
+ info_pid(Pid);
+
+ipi({peer, {Pid, _}}) ->
+ info_pid(Pid);
+
+ipi({port, [{owner, Pid} | _]}) ->
+ info_pid(Pid);
+
+ipi(_) ->
+ [].
+
+info_pid(Pid) ->
+ case process_info(Pid, [message_queue_len, memory, binary]) of
+ undefined ->
+ [];
+ L ->
+ [{Pid, lists:map(fun({K,V}) -> {K, map_info(K,V)} end, L)}]
+ end.
+
+%% The binary list consists of 3-tuples {Ptr, Size, Count}, where Ptr
+%% is a C pointer value, Size is the size of a referenced binary in
+%% bytes, and Count is a global reference count. The same Ptr can
+%% occur multiple times, once for each reference on the process heap.
+%% In this case, the corresponding tuples will have Size in common but
+%% Count may differ just because no global lock is taken when the
+%% value is retrieved.
+%%
+%% The list can be quite large, and we aren't often interested in the
+%% pointers or counts, so whittle this down to the number of binaries
+%% referenced and their total byte count.
+map_info(binary, L) ->
+ SzD = lists:foldl(fun({P,S,_}, D) -> dict:store(P,S,D) end,
+ dict:new(),
+ L),
+ {dict:size(SzD), dict:fold(fun(_,S,N) -> S + N end, 0, SzD)};
+
+map_info(_, T) ->
+ T.
+
%% The point of extracting the config here is so that 'transport' info
%% has one entry for each transport ref, the peer table only
%% containing entries that have a living watchdog.
@@ -1819,6 +1870,13 @@ mk_app(#diameter_app{} = A) ->
info_pending(#state{} = S) ->
diameter_traffic:pending(transports(S)).
+%% info_info/1
+%%
+%% Extract process_info from connections info.
+
+info_info(S) ->
+ [I || L <- conn_list(S), {info, I} <- L].
+
%% info_connections/1
%%
%% One entry per transport connection. Statistics for each entry are
diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl
index 5fac61f416..3b62afca47 100644
--- a/lib/diameter/src/base/diameter_traffic.erl
+++ b/lib/diameter/src/base/diameter_traffic.erl
@@ -129,6 +129,11 @@ incr(Dir, #diameter_header{} = H, TPid, Dict) ->
%% incr_error/4
%% ---------------------------------------------------------------------------
+%% Identify messages using the application dictionary, not the encode
+%% dictionary, which may differ in the case of answer-message.
+incr_error(Dir, T, Pid, {_Dict, AppDict}) ->
+ incr_error(Dir, T, Pid, AppDict);
+
%% Decoded message without errors.
incr_error(recv, #diameter_packet{errors = []}, _, _) ->
ok;
@@ -169,7 +174,7 @@ incr_error(Dir, Id, TPid) ->
incr_rc(Dir, Pkt, TPid, Dict0) ->
try
- incr_rc(Dir, Pkt, Dict0, TPid, Dict0)
+ incr_result(Dir, Pkt, TPid, {Dict0, Dict0, Dict0})
catch
exit: {E,_} when E == no_result_code;
E == invalid_error_bit ->
@@ -471,7 +476,7 @@ send_A({Caps, Pkt}, TPid, Dict0, _RecvData) -> %% unsupported application
#diameter_packet{errors = [RC|_]} = Pkt,
send_A(answer_message(RC, Caps, Dict0, Pkt),
TPid,
- Dict0,
+ {Dict0, Dict0},
Pkt,
[],
[]);
@@ -479,7 +484,7 @@ send_A({Caps, Pkt}, TPid, Dict0, _RecvData) -> %% unsupported application
send_A({Caps, Pkt, App, {T, EvalPktFs, EvalFs}}, TPid, Dict0, RecvData) ->
send_A(answer(T, Caps, Pkt, App, Dict0, RecvData),
TPid,
- Dict0,
+ {App#diameter_app.dictionary, Dict0},
Pkt,
EvalPktFs,
EvalFs);
@@ -489,8 +494,8 @@ send_A(_, _, _, _) ->
%% send_A/6
-send_A(T, TPid, Dict0, ReqPkt, EvalPktFs, EvalFs) ->
- reply(T, TPid, Dict0, EvalPktFs, ReqPkt),
+send_A(T, TPid, DictT, ReqPkt, EvalPktFs, EvalFs) ->
+ reply(T, TPid, DictT, EvalPktFs, ReqPkt),
lists:foreach(fun diameter_lib:eval/1, EvalFs).
%% answer/6
@@ -648,32 +653,32 @@ is_loop(Code, Vid, OH, Dict0, Avps) ->
%% reply/5
%% Local answer ...
-reply({Dict, Ans}, TPid, Dict0, Fs, ReqPkt) ->
- reply(Ans, Dict, TPid, Dict0, Fs, ReqPkt);
+reply({Dict, Ans}, TPid, {AppDict, Dict0}, Fs, ReqPkt) ->
+ local(Ans, TPid, {Dict, AppDict, Dict0}, Fs, ReqPkt);
%% ... or relayed.
reply(#diameter_packet{} = Pkt, TPid, _Dict0, Fs, _ReqPkt) ->
eval_packet(Pkt, Fs),
send(TPid, Pkt).
-%% reply/6
+%% local/5
%%
%% Send a locally originating reply.
%% Skip the setting of Result-Code and Failed-AVP's below. This is
%% undocumented and shouldn't be relied on.
-reply([Msg], Dict, TPid, Dict0, Fs, ReqPkt)
+local([Msg], TPid, DictT, Fs, ReqPkt)
when is_list(Msg);
is_tuple(Msg) ->
- reply(Msg, Dict, TPid, Dict0, Fs, ReqPkt#diameter_packet{errors = []});
+ local(Msg, TPid, DictT, Fs, ReqPkt#diameter_packet{errors = []});
-reply(Msg, Dict, TPid, Dict0, Fs, ReqPkt) ->
- Pkt = encode(Dict,
+local(Msg, TPid, {Dict, AppDict, Dict0} = DictT, Fs, ReqPkt) ->
+ Pkt = encode({Dict, AppDict},
TPid,
reset(make_answer_packet(Msg, ReqPkt), Dict, Dict0),
Fs),
- incr(send, Pkt, TPid, Dict),
- incr_rc(send, Pkt, Dict, TPid, Dict0), %% count outgoing
+ incr(send, Pkt, TPid, AppDict),
+ incr_result(send, Pkt, TPid, DictT), %% count outgoing
send(TPid, Pkt).
%% reset/3
@@ -1038,29 +1043,29 @@ find(Pred, [H|T]) ->
%% code, the missing vendor id, and a zero filled payload of the minimum
%% required length for the omitted AVP will be added.
-%% incr_rc/5
+%% incr_result/5
%%
%% Increment a stats counter for result codes in incoming and outgoing
%% answers.
%% Outgoing message as binary: don't count. (Sending binaries is only
%% partially supported.)
-incr_rc(_, #diameter_packet{msg = undefined = No}, _, _, _) ->
+incr_result(_, #diameter_packet{msg = undefined = No}, _, _) ->
No;
%% Incoming or outgoing. Outgoing with encode errors never gets here
%% since encode fails.
-incr_rc(Dir, Pkt, Dict, TPid, Dict0) ->
+incr_result(Dir, Pkt, TPid, {Dict, AppDict, Dict0}) ->
#diameter_packet{header = #diameter_header{is_error = E}
= Hdr,
msg = Msg,
errors = Es}
= Pkt,
- Id = msg_id(Hdr, Dict),
+ Id = msg_id(Hdr, AppDict),
%% Count incoming decode errors.
- recv /= Dir orelse [] == Es orelse incr_error(Dir, Id, TPid, Dict),
+ recv /= Dir orelse [] == Es orelse incr_error(Dir, Id, TPid, AppDict),
%% Exit on a missing result code.
T = rc_counter(Dict, Msg),
@@ -1074,12 +1079,27 @@ incr_rc(Dir, Pkt, Dict, TPid, Dict0) ->
incr(TPid, {Id, Dir, Ctr}),
Ctr.
-%% Only count on known keeps so as not to be vulnerable to attack:
-%% there are 2^32 (application ids) * 2^24 (command codes) * 2 (R-bits)
-%% = 2^57 Ids for an attacker to choose from.
+%% msg_id/2
+
+msg_id(#diameter_packet{header = H}, Dict) ->
+ msg_id(H, Dict);
+
+%% Only count on known keys so as not to be vulnerable to attack:
+%% there are 2^32 (application ids) * 2^24 (command codes) = 2^56
+%% pairs for an attacker to choose from.
msg_id(Hdr, Dict) ->
{_ApplId, Code, R} = Id = diameter_codec:msg_id(Hdr),
- choose('' == Dict:msg_name(Code, 0 == R), unknown, Id).
+ case Dict:msg_name(Code, 0 == R) of
+ '' ->
+ unknown(Dict:id(), R);
+ _ ->
+ Id
+ end.
+
+unknown(?APP_ID_RELAY, R) ->
+ {relay, R};
+unknown(_, _) ->
+ unknown.
%% No E-bit: can't be 3xxx.
is_result(RC, false, _Dict0) ->
@@ -1396,6 +1416,7 @@ send_R(Pkt0,
packet = Pkt0},
try
+ incr(send, Pkt, TPid, Dict),
TRef = send_request(TPid, Pkt, Req, SvcName, Timeout),
Pid ! Ref, %% tell caller a send has been attempted
handle_answer(SvcName,
@@ -1431,14 +1452,14 @@ handle_answer(SvcName, App, {error, Req, Reason}) ->
handle_error(App, Req, Reason, SvcName);
handle_answer(SvcName,
- #diameter_app{dictionary = Dict,
+ #diameter_app{dictionary = AppDict,
id = Id}
= App,
{answer, Req, Dict0, Pkt}) ->
- Mod = dict(Dict, Dict0, Pkt),
- handle_A(errors(Id, diameter_codec:decode(Mod, Pkt)),
+ Dict = dict(AppDict, Dict0, Pkt),
+ handle_A(errors(Id, diameter_codec:decode({Dict, AppDict}, Pkt)),
SvcName,
- Mod,
+ Dict,
Dict0,
App,
Req).
@@ -1448,10 +1469,12 @@ handle_answer(SvcName,
%% want to examine the answer?
handle_A(Pkt, SvcName, Dict, Dict0, App, #request{transport = TPid} = Req) ->
- incr(recv, Pkt, TPid, Dict),
+ AppDict = App#diameter_app.dictionary,
+
+ incr(recv, Pkt, TPid, AppDict),
try
- incr_rc(recv, Pkt, Dict, TPid, Dict0) %% count incoming
+ incr_result(recv, Pkt, TPid, {Dict, AppDict, Dict0}) %% count incoming
of
_ -> answer(Pkt, SvcName, App, Req)
catch
@@ -1461,13 +1484,15 @@ handle_A(Pkt, SvcName, Dict, Dict0, App, #request{transport = TPid} = Req) ->
%% a missing AVP. If both are optional in the dictionary
%% then this isn't a decode error: just continue on.
answer(Pkt, SvcName, App, Req);
- exit: {invalid_error_bit, RC} ->
+ exit: {invalid_error_bit, {_, _, _, RC}} ->
#diameter_packet{errors = Es}
= Pkt,
E = {5004, #diameter_avp{name = 'Result-Code', value = RC}},
answer(Pkt#diameter_packet{errors = [E|Es]}, SvcName, App, Req)
end.
+%% answer/4
+
answer(Pkt,
SvcName,
#diameter_app{module = ModX,
@@ -1568,13 +1593,18 @@ encode(Dict, TPid, Pkt, Fs) ->
%% an encoded binary. This isn't the usual case and doesn't properly
%% support retransmission but is useful for test.
+encode(Dict, TPid, Pkt)
+ when is_atom(Dict) ->
+ encode({Dict, Dict}, TPid, Pkt);
+
%% A message to be encoded.
-encode(Dict, TPid, #diameter_packet{bin = undefined} = Pkt) ->
+encode(DictT, TPid, #diameter_packet{bin = undefined} = Pkt) ->
+ {Dict, AppDict} = DictT,
try
diameter_codec:encode(Dict, Pkt)
catch
exit: {diameter_codec, encode, T} = Reason ->
- incr_error(send, T, TPid, Dict),
+ incr_error(send, T, TPid, AppDict),
exit(Reason)
end;
@@ -1602,12 +1632,23 @@ send_request(TPid, #diameter_packet{} = Pkt, Req, SvcName, Timeout) ->
%% send/1
-send({TPid, Pkt, #request{handler = Pid} = Req, SvcName, Timeout, TRef}) ->
- Ref = send_request(TPid,
- Pkt,
- Req#request{handler = self()},
- SvcName,
- Timeout),
+send({TPid, Pkt, #request{handler = Pid} = Req0, SvcName, Timeout, TRef}) ->
+ Seqs = diameter_codec:sequence_numbers(Pkt),
+ Req = Req0#request{handler = self()},
+ Ref = send_request(TPid, Pkt, Req, SvcName, Timeout),
+
+ try
+ recv(TPid, Pid, TRef, Ref)
+ after
+ %% Remove only the entry for this specific send since a resend
+ %% from the originating node can pick another transport on
+ %% this one.
+ ets:delete_object(?REQUEST_TABLE, {Seqs, Req, Ref})
+ end.
+
+%% recv/4
+
+recv(TPid, Pid, TRef, Ref) ->
receive
{answer, _, _, _, _} = A ->
Pid ! A;
@@ -1683,6 +1724,7 @@ resend_request(Pkt0,
caps = Caps},
?LOG(retransmission, Pkt#diameter_packet.header),
+ incr(TPid, {msg_id(Pkt, Dict), send, retransmission}),
TRef = send_request(TPid, Pkt, Req, SvcName, Tmo),
{TRef, Req}.
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index eff5096745..b7f2d24941 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -255,11 +255,15 @@ close({'DOWN', _, process, TPid, {shutdown, Reason}},
close(_, _) ->
ok.
-event(_, #watchdog{status = T}, #watchdog{status = T}) ->
- ok;
-
-event(_, #watchdog{transport = undefined}, #watchdog{transport = undefined}) ->
+event(_,
+ #watchdog{status = From, transport = F},
+ #watchdog{status = To, transport = T})
+ when F == undefined, T == undefined; %% transport not started
+ From == initial, To == down; %% never really left INITIAL
+ From == To -> %% no state transition
ok;
+%% Note that there is no INITIAL -> DOWN transition in RFC 3539: ours
+%% is just a consequence of stop.
event(Msg,
#watchdog{status = From, transport = F, parent = Pid},
@@ -411,7 +415,7 @@ transition({'DOWN', _, process, TPid, _Reason},
stop;
%% ... or not.
-transition({'DOWN', _, process, TPid, _Reason},
+transition({'DOWN', _, process, TPid, _Reason} = D,
#watchdog{transport = TPid,
status = T,
restrict = {_,R}}
@@ -422,20 +426,14 @@ transition({'DOWN', _, process, TPid, _Reason},
%% Close an accepting watchdog immediately if there's no
%% restriction on the number of connections to the same peer: the
- %% state machine never enters state REOPEN in this case. The
- %% 'close' message (instead of stop) is so as not to bypass the
- %% sending of messages to the service process in handle_info/2.
-
- if T /= initial, M == accept, not R ->
- send(self(), close),
- S#watchdog{status = down};
- T /= initial ->
- set_watchdog(S#watchdog{status = down});
- M == connect ->
- set_watchdog(S);
- M == accept ->
- send(self(), close),
- S
+ %% state machine never enters state REOPEN in this case.
+
+ if T == initial;
+ M == accept, not R ->
+ close(D, S0),
+ stop;
+ true ->
+ set_watchdog(S#watchdog{status = down})
end;
%% Incoming message.
diff --git a/lib/diameter/src/compiler/diameter_codegen.erl b/lib/diameter/src/compiler/diameter_codegen.erl
index 5a068c1a25..d91a776321 100644
--- a/lib/diameter/src/compiler/diameter_codegen.erl
+++ b/lib/diameter/src/compiler/diameter_codegen.erl
@@ -132,7 +132,7 @@ gen(parse, ParseD, _Mod) ->
[?VERSION | ParseD];
gen(forms, ParseD, Mod) ->
- pp(erl_forms(Mod, ParseD));
+ preprocess(Mod, erl_forms(Mod, ParseD));
gen(hrl, ParseD, Mod) ->
gen_hrl(Mod, ParseD);
@@ -838,19 +838,19 @@ rec_name(Name, Prefix) ->
Prefix ++ Name.
%% ===========================================================================
-%% pp/1
+%% preprocess/2
%%
%% Preprocess forms as generated by 'forms' option. In particular,
%% replace the include_lib attributes in generated forms by the
%% corresponding forms, extracting the latter from an existing
%% dictionary (diameter_gen_relay). The resulting forms can be
%% compiled to beam using compile:forms/2 (which does no preprocessing
-%% or it's own; DiY currently appears to be the only way to preprocess
+%% of it's own; DiY currently appears to be the only way to preprocess
%% a forms list).
-pp(Forms) ->
+preprocess(Mod, Forms) ->
{_, Beam, _} = code:get_object_code(diameter_gen_relay),
- pp(Forms, abstract_code(Beam)).
+ pp(Forms, remod(Mod, abstract_code(Beam))).
pp(Forms, {ok, Code}) ->
Files = files(Code, []),
@@ -859,6 +859,25 @@ pp(Forms, {ok, Code}) ->
pp(Forms, {error, Reason}) ->
erlang:error({forms, Reason, Forms}).
+%% Replace literal diameter_gen_relay atoms in the extracted forms.
+%% ?MODULE for example.
+
+remod(Mod, L)
+ when is_list(L) ->
+ [remod(Mod, T) || T <- L];
+
+remod(Mod, {atom, _, diameter_gen_relay} = T) ->
+ setelement(3, T, Mod);
+
+remod(Mod, T)
+ when is_tuple(T) ->
+ list_to_tuple(remod(Mod, tuple_to_list(T)));
+
+remod(_, T) ->
+ T.
+
+%% Replace include_lib by the corresponding forms.
+
include({attribute, _, include_lib, Path}, Files) ->
Inc = filename:basename(Path),
[{Inc, Forms}] = [T || {F, _} = T <- Files, F == Inc], %% expect one
@@ -867,6 +886,8 @@ include({attribute, _, include_lib, Path}, Files) ->
include(T, _) ->
[T].
+%% Extract abstract code.
+
abstract_code(Beam) ->
case beam_lib:chunks(Beam, [abstract_code]) of
{ok, {_Mod, [{abstract_code, {_Vsn, Code}}]}} ->
@@ -877,6 +898,8 @@ abstract_code(Beam) ->
{E, Reason}
end.
+%% Extract filename/forms pairs for included forms.
+
files([{attribute, _, file, {Path, _}} | T], Acc) ->
{Body, Rest} = lists:splitwith(fun({attribute, _, file, _}) -> false;
(_) -> true
diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src
index b7b9662383..881d25b5fb 100644
--- a/lib/diameter/src/diameter.appup.src
+++ b/lib/diameter/src/diameter.appup.src
@@ -43,10 +43,23 @@
{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}]}
+ {load_module, diameter_sctp}]},
+ {"1.7", [{load_module, diameter_service}, %% 17.1
+ {load_module, diameter_codec},
+ {load_module, diameter_gen_base_rfc6733},
+ {load_module, diameter_gen_acct_rfc6733},
+ {load_module, diameter_gen_base_rfc3588},
+ {load_module, diameter_gen_base_accounting},
+ {load_module, diameter_gen_relay},
+ {load_module, diameter_traffic},
+ {load_module, diameter_peer_fsm}]},
+ {"1.7.1", [{load_module, diameter_traffic}, %% 17.3
+ {load_module, diameter_watchdog},
+ {load_module, diameter_peer_fsm},
+ {load_module, diameter_service}]}
],
[
{"0.9", [{restart_application, diameter}]},
@@ -67,7 +80,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},
@@ -75,6 +88,19 @@
{load_module, diameter_peer_fsm},
{load_module, diameter_watchdog},
{load_module, diameter_traffic},
- {load_module, diameter_lib}]}
+ {load_module, diameter_lib}]},
+ {"1.7", [{load_module, diameter_peer_fsm},
+ {load_module, diameter_traffic},
+ {load_module, diameter_gen_relay},
+ {load_module, diameter_gen_base_accounting},
+ {load_module, diameter_gen_base_rfc3588},
+ {load_module, diameter_gen_acct_rfc6733},
+ {load_module, diameter_gen_base_rfc6733},
+ {load_module, diameter_codec},
+ {load_module, diameter_service}]},
+ {"1.7.1", [{load_module, diameter_service},
+ {load_module, diameter_peer_fsm},
+ {load_module, diameter_watchdog},
+ {load_module, diameter_traffic}]}
]
}.
diff --git a/lib/diameter/src/info/diameter_dbg.erl b/lib/diameter/src/info/diameter_dbg.erl
index b5b3983afa..b536e5e80b 100644
--- a/lib/diameter/src/info/diameter_dbg.erl
+++ b/lib/diameter/src/info/diameter_dbg.erl
@@ -32,7 +32,8 @@
compiled/0,
procs/0,
latest/0,
- nl/0]).
+ nl/0,
+ sizes/0]).
-export([diameter_config/0,
diameter_peer/0,
@@ -69,7 +70,16 @@
-define(VALUES(Rec), tl(tuple_to_list(Rec))).
%% ----------------------------------------------------------
-%% # table(TableName)
+%% # sizes/0
+%%
+%% Return sizes of named tables.
+%% ----------------------------------------------------------
+
+sizes() ->
+ [{T, ets:info(T, size)} || T <- ?LOCAL, T /= diameter_peer].
+
+%% ----------------------------------------------------------
+%% # table/1
%%
%% Pretty-print a diameter table. Returns the number of records
%% printed, or undefined.
@@ -97,7 +107,7 @@ split([F|Fs], [V|Vs]) ->
{F, Fs, V, Vs}.
%% ----------------------------------------------------------
-%% # TableName()
+%% # TableName/0
%% ----------------------------------------------------------
-define(TABLE(Name), Name() -> table(Name)).
@@ -111,7 +121,7 @@ split([F|Fs], [V|Vs]) ->
?TABLE(diameter_stats).
%% ----------------------------------------------------------
-%% # tables()
+%% # tables/0
%%
%% Pretty-print diameter tables from all nodes. Returns the number of
%% records printed.
@@ -127,7 +137,7 @@ split(_, Fs, Vs) ->
split(Fs, Vs).
%% ----------------------------------------------------------
-%% # modules()
+%% # modules/0
%% ----------------------------------------------------------
modules() ->
@@ -140,49 +150,49 @@ appdir() ->
[_|_] = code:lib_dir(?APP, ebin).
%% ----------------------------------------------------------
-%% # versions()
+%% # versions/0
%% ----------------------------------------------------------
versions() ->
?I:versions(modules()).
%% ----------------------------------------------------------
-%% # versions()
+%% # version_info/0
%% ----------------------------------------------------------
version_info() ->
?I:version_info(modules()).
%% ----------------------------------------------------------
-%% # compiled()
+%% # compiled/0
%% ----------------------------------------------------------
compiled() ->
?I:compiled(modules()).
%% ----------------------------------------------------------
-%% procs()
+%% # procs/0
%% ----------------------------------------------------------
procs() ->
?I:procs(?APP).
%% ----------------------------------------------------------
-%% # latest()
+%% # latest/0
%% ----------------------------------------------------------
latest() ->
?I:latest(modules()).
%% ----------------------------------------------------------
-%% # nl()
+%% # nl/0
%% ----------------------------------------------------------
nl() ->
lists:foreach(fun(M) -> abcast = c:nl(M) end, modules()).
%% ----------------------------------------------------------
-%% # pp(Bin)
+%% # pp/1
%%
%% Description: Pretty-print a message binary.
%% ----------------------------------------------------------
@@ -317,7 +327,7 @@ ppp({Field, Value}) ->
io:format(": ~-22s : ~p~n", [Field, Value]).
%% ----------------------------------------------------------
-%% # subscriptions()
+%% # subscriptions/0
%%
%% Returns a list of {SvcName, Pid}.
%% ----------------------------------------------------------
@@ -326,7 +336,7 @@ subscriptions() ->
diameter_service:subscriptions().
%% ----------------------------------------------------------
-%% # children()
+%% # children/0
%% ----------------------------------------------------------
children() ->
diff --git a/lib/diameter/test/diameter_config_SUITE.erl b/lib/diameter/test/diameter_config_SUITE.erl
index d10ee83ba4..ad5b3f9420 100644
--- a/lib/diameter/test/diameter_config_SUITE.erl
+++ b/lib/diameter/test/diameter_config_SUITE.erl
@@ -157,7 +157,7 @@
{length_errors,
[[exit], [handle], [discard]],
[[x]]},
- {reconnect_timer,
+ {connect_timer,
[[3000]],
[[infinity]]},
{watchdog_timer,
diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl
index 94b4967921..f43f111d20 100644
--- a/lib/diameter/test/diameter_event_SUITE.erl
+++ b/lib/diameter/test/diameter_event_SUITE.erl
@@ -107,29 +107,38 @@ start_server(Config) ->
%% Connect with matching capabilities and expect the connection to
%% come up.
up(Config) ->
- {Svc, Ref} = connect(Config, []),
+ {Svc, Ref} = connect(Config, [{connect_timer, 5000},
+ {watchdog_timer, 15000}]),
start = event(Svc),
- {up, Ref, {_,_Caps}, _Config, #diameter_packet{}} = event(Svc),
- {watchdog, Ref, _, {initial, okay}, _} = event(Svc).
+ {up, Ref, {TPid, Caps}, Cfg, #diameter_packet{}} = event(Svc),
+ {watchdog, Ref, _, {initial, okay}, _} = event(Svc),
+ %% Kill the transport process and see that the connection is
+ %% reestablished after a watchdog timeout, not after connect_timer
+ %% expiry.
+ exit(TPid, kill),
+ {down, Ref, {TPid, Caps}, Cfg} = event(Svc),
+ {watchdog, Ref, _, {okay, down}, _} = event(Svc),
+ {reconnect, Ref, _} = event(Svc, 10000, 20000).
%% Connect with non-matching capabilities and expect CEA from the peer
%% to indicate as much and then for the transport to be restarted
-%% (after reconnect_timer).
+%% (after connect_timer).
down(Config) ->
{Svc, Ref} = connect(Config, [{capabilities, [{'Acct-Application-Id',
[?DICT_ACCT:id()]}]},
{applications, [?DICT_ACCT]},
- {reconnect_timer, 5000}]),
+ {connect_timer, 5000},
+ {watchdog_timer, 20000}]),
start = event(Svc),
{closed, Ref, {'CEA', ?NO_COMMON_APP, _, #diameter_packet{}}, _}
= event(Svc),
- {reconnect, Ref, _} = event(Svc).
+ {reconnect, Ref, _} = event(Svc, 4000, 10000).
%% Connect with matching capabilities but have the server delay its
%% CEA and cause the client to timeout.
cea_timeout(Config) ->
{Svc, Ref} = connect(Config, [{capx_timeout, ?SERVER_CAPX_TMO div 2},
- {reconnect_timer, 2*?SERVER_CAPX_TMO}]),
+ {connect_timer, 2*?SERVER_CAPX_TMO}]),
start = event(Svc),
{closed, Ref, {'CEA', timeout}, _} = event(Svc).
@@ -165,6 +174,13 @@ uniq() ->
event(Name) ->
receive #diameter_event{service = Name, info = T} -> T end.
+event(Name, TL, TH) ->
+ T0 = now(),
+ Event = event(Name),
+ DT = timer:now_diff(now(), T0) div 1000,
+ {true, true, DT, Event} = {TL < DT, DT < TH, DT, Event},
+ Event.
+
start_service(Name, Opts) ->
diameter:start_service(Name, [{monitor, self()} | Opts]).
diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl
index 9408fae62c..fcffa69c24 100644
--- a/lib/diameter/test/diameter_transport_SUITE.erl
+++ b/lib/diameter/test/diameter_transport_SUITE.erl
@@ -194,7 +194,7 @@ reconnect({connect, Ref}) ->
true = diameter:subscribe(SvcName),
ok = start_service(SvcName),
[{{_, _, LRef}, Pid}] = diameter_reg:wait({?MODULE, Ref, '_'}),
- CRef = ?util:connect(SvcName, tcp, LRef, [{reconnect_timer, 2000},
+ CRef = ?util:connect(SvcName, tcp, LRef, [{connect_timer, 2000},
{watchdog_timer, 6000}]),
%% Tell partner to kill transport after seeing that there are no
diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk
index 560c2aed50..587ae08b3d 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -18,5 +18,5 @@
# %CopyrightEnd%
APPLICATION = diameter
-DIAMETER_VSN = 1.7
+DIAMETER_VSN = 1.8
APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index d7cbfa1fdc..e350adb540 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -31,6 +31,57 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.16</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Maps: Properly align union typed assoc values in
+ documentation</p>
+ <p>
+ Own Id: OTP-12190</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Edoc 0.7.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix spec to doc generation from erl_docgen and edoc for
+ maps</p>
+ <p>
+ Own Id: OTP-12058</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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..a102d432bc 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -831,8 +831,6 @@ t_type([#xmlElement{name = nonempty_list, content = Es}]) ->
t_nonempty_list(Es);
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 = tuple, content = Es}]) ->
t_tuple(Es);
t_type([#xmlElement{name = 'fun', content = Es}]) ->
@@ -882,10 +880,11 @@ t_fun(Es) ->
[") -> "] ++ t_utype(get_elem(type, Es))).
t_map(Es) ->
- ["#{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
+ Fs = get_elem(map_field, Es),
+ ["#{"] ++ seq(fun t_map_field/1, Fs, ["}"]).
-t_map_field([K,V]) ->
- [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)].
+t_map_field(#xmlElement{content = [K,V]}) ->
+ t_utype_elem(K) ++ [" => "] ++ t_utype_elem(V).
t_record(E, Es) ->
Name = ["#"] ++ t_type(get_elem(atom, Es)),
@@ -1082,6 +1081,8 @@ 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 = 'fun', content = Es}]) ->
ot_fun(Es);
ot_type([#xmlElement{name = record, content = Es}]) ->
@@ -1138,6 +1139,12 @@ ot_nonempty_list(Es) ->
ot_tuple(Es) ->
{type,0,tuple,[ot_utype_elem(E) || E <- Es]}.
+ot_map(Es) ->
+ {type,0,map,[ot_map_field(E) || E <- get_elem(map_field,Es)]}.
+
+ot_map_field(#xmlElement{content=[K,V]}) ->
+ {type,0,map_field_assoc,ot_utype_elem(K), ot_utype_elem(V)}.
+
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/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index d4e00d3ecd..8a6c8eb33e 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -143,7 +143,7 @@ to_xml(#t_fun{args = As, range = T}, Env) ->
{'fun', [{argtypes, map(fun wrap_utype/2, As, Env)},
wrap_utype(T, Env)]};
to_xml(#t_map{ types = Ts}, Env) ->
- {map, map(fun wrap_utype/2, Ts, Env)};
+ {map, map(fun to_xml/2, Ts, Env)};
to_xml(#t_map_field{ k_type=K, v_type=V}, Env) ->
{map_field, [wrap_utype(K,Env), wrap_utype(V, Env)]};
to_xml(#t_tuple{types = Ts}, Env) ->
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..24cfbf16d5 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.13
+EDOC_VSN = 0.7.16
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index 8009a8d6a3..c4b1ac36ca 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -48,7 +48,7 @@ scope() See baseObject/0, singleLevel/0, wholeSubtree/0
dereference() See neverDerefAliases/0, derefInSearching/0, derefFindingBaseObj/0, derefAlways/0
filter() See present/1, substrings/2,
equalityMatch/2, greaterOrEqual/2, lessOrEqual/2,
- approxMatch/2,
+ approxMatch/2, extensibleMatch/2,
'and'/1, 'or'/1, 'not'/1.
</pre>
<p></p>
@@ -75,7 +75,9 @@ filter() See present/1, substrings/2,
<p>Setup a connection to an LDAP server, the <c>HOST</c>'s are tried in order.</p>
<p>The log function takes three arguments, <c>fun(Level, FormatString, [FormatArg]) end</c>.</p>
<p>Timeout set the maximum time in milliseconds that each server request may take.</p>
- <p>Currently, the only TCP socket option accepted is <c>inet6</c>. Default is <c>inet</c>.</p>
+ <p>All TCP socket options are accepted except
+ <c>active</c>, <c>binary</c>, <c>deliver</c>, <c>list</c>, <c>mode</c> and <c>packet</c>
+ </p>
</desc>
</func>
<func>
@@ -105,19 +107,23 @@ filter() See present/1, substrings/2,
</type>
<desc>
<p>Upgrade the connection associated with <c>Handle</c> to a tls connection if possible.</p>
- <p>The upgrade is done in two phases: first the server is asked for permission to upgrade. Second, if the request is acknowledged, the upgrade is performed.</p>
- <p>Error responese from phase one will not affect the current encryption state of the connection. Those responses are:</p>
+ <p>The upgrade is done in two phases: first the server is asked for permission to upgrade. Second, if the request is acknowledged, the upgrade to tls is performed.</p>
+ <p>Error responses from phase one will not affect the current encryption state of the connection. Those responses are:</p>
<taglist>
<tag><c>tls_already_started</c></tag>
<item>The connection is already encrypted. The connection is not affected.</item>
<tag><c>{response,ResponseFromServer}</c></tag>
<item>The upgrade was refused by the LDAP server. The <c>ResponseFromServer</c> is an atom delivered byt the LDAP server explained in section 2.3 of rfc 2830. The connection is not affected, so it is still un-encrypted.</item>
</taglist>
- <p>Errors in the seconde phase will however end the connection:</p>
+ <p>Errors in the second phase will however end the connection:</p>
<taglist>
<tag><c>Error</c></tag>
<item>Any error responded from ssl:connect/3</item>
</taglist>
+ <p>The <c>Timeout</c> parameter is for the actual tls upgrade (phase 2) while the timeout in
+ <seealso marker="#open/2">erl_tar:open/2</seealso> is used for the initial negotiation about
+ upgrade (phase 1).
+ </p>
</desc>
</func>
<func>
@@ -222,9 +228,9 @@ filter() See present/1, substrings/2,
</type>
<desc>
<p> Modify the DN of an entry. <c>DeleteOldRDN</c> indicates
- whether the current RDN should be removed after operation.
- <c>NewSupDN</c> should be "" if the RDN should not be moved or the new parent which
- the RDN will be moved to.</p>
+ whether the current RDN should be removed from the attribute list after the after operation.
+ <c>NewSupDN</c> is the new parent that the RDN shall be moved to. If the old parent should
+ remain as parent, <c>NewSupDN</c> shall be "".</p>
<pre>
modify_dn(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com ",
"cn=Bill Jr Valentine", true, "")
@@ -251,6 +257,10 @@ filter() See present/1, substrings/2,
Filter = eldap:substrings("cn", [{any,"V"}]),
search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]),
</pre>
+ <p>The <c>timeout</c> option in the <c>SearchOptions</c> is for the ldap server, while
+ the timeout in <seealso marker="#open/2">erl_tar:open/2</seealso> is used for each
+ individual request in the search operation.
+ </p>
</desc>
</func>
@@ -346,6 +356,16 @@ filter() See present/1, substrings/2,
<desc> <p>Create a approximation match filter.</p> </desc>
</func>
<func>
+ <name>extensibleMatch(MatchValue, OptionalAttrs) -> filter()</name>
+ <fsummary>Create search filter option.</fsummary>
+ <type>
+ <v>MatchValue = string()</v>
+ <v>OptionalAttrs = [Attr]</v>
+ <v>Attr = {matchingRule,string()} | {type,string()} | {dnAttributes,boolean()}</v>
+ </type>
+ <desc> <p>Creates an extensible match filter. For example, <c>eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}]))</c> creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc>
+ </func>
+ <func>
<name>'and'([Filter]) -> filter()</name>
<fsummary>Create search filter option.</fsummary>
<type>
diff --git a/lib/eldap/doc/src/notes.xml b/lib/eldap/doc/src/notes.xml
index 089bb731d4..e5cbcb26ff 100644
--- a/lib/eldap/doc/src/notes.xml
+++ b/lib/eldap/doc/src/notes.xml
@@ -30,7 +30,65 @@
</header>
<p>This document describes the changes made to the Eldap application.</p>
- <section><title>Eldap 1.0.3</title>
+<section><title>Eldap 1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed that eldap:open did not use the Timeout parameter
+ when calling ssl:connect. (Thanks Wiesław Bieniek for
+ reporting)</p>
+ <p>
+ Own Id: OTP-12311</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added the LDAP filter <c>extensibleMatch</c>.</p>
+ <p>
+ Own Id: OTP-12174</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+ <section><title>Eldap 1.0.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>eldap:open/2</c> and <c>eldap:open/3</c> gave wrong
+ return values for option errors.</p>
+ <p>
+ Own Id: OTP-12182</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Nearly all TCP options are possible to give in the
+ <c>eldap:open/2</c> call.</p>
+ <p>
+ Own Id: OTP-12171</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eldap 1.0.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index 1cd328cde3..80718bc106 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -12,8 +12,10 @@
-vc('$Id$ ').
-export([open/1,open/2,simple_bind/3,controlling_process/2,
start_tls/2, start_tls/3,
+ getopts/2,
baseObject/0,singleLevel/0,wholeSubtree/0,close/1,
equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
+ extensibleMatch/2,
approxMatch/2,search/2,substrings/2,present/1,
'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,
mod_replace/2, add/3, delete/2, modify_dn/5,parse_dn/1,
@@ -92,11 +94,21 @@ start_tls(Handle, TlsOptions, Timeout) ->
recv(Handle).
%%% --------------------------------------------------------------------
+%%% Ask for option values on the socket.
+%%% Warning: This is an undocumented function for testing purposes only.
+%%% Use at own risk...
+%%% --------------------------------------------------------------------
+getopts(Handle, OptNames) when is_pid(Handle), is_list(OptNames) ->
+ send(Handle, {getopts, OptNames}),
+ recv(Handle).
+
+%%% --------------------------------------------------------------------
%%% Shutdown connection (and process) asynchronous.
%%% --------------------------------------------------------------------
close(Handle) when is_pid(Handle) ->
- send(Handle, close).
+ send(Handle, close),
+ ok.
%%% --------------------------------------------------------------------
%%% Set who we should link ourselves to
@@ -340,6 +352,27 @@ substrings(Type, SubStr) when is_list(Type), is_list(SubStr) ->
{substrings,#'SubstringFilter'{type = Type,
substrings = Ss}}.
+%%%
+%%% Filter for extensibleMatch
+%%%
+extensibleMatch(MatchValue, OptArgs) ->
+ MatchingRuleAssertion =
+ mra(OptArgs, #'MatchingRuleAssertion'{matchValue = MatchValue}),
+ {extensibleMatch, MatchingRuleAssertion}.
+
+mra([{matchingRule,Val}|T], Ack) when is_list(Val) ->
+ mra(T, Ack#'MatchingRuleAssertion'{matchingRule=Val});
+mra([{type,Val}|T], Ack) when is_list(Val) ->
+ mra(T, Ack#'MatchingRuleAssertion'{type=Val});
+mra([{dnAttributes,true}|T], Ack) ->
+ mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="TRUE"});
+mra([{dnAttributes,false}|T], Ack) ->
+ mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="FALSE"});
+mra([H|_], _) ->
+ throw({error,{extensibleMatch_arg,H}});
+mra([], Ack) ->
+ Ack.
+
%%% --------------------------------------------------------------------
%%% Worker process. We keep track of a controlling process to
%%% be able to terminate together with it.
@@ -362,7 +395,7 @@ parse_args([{port, Port}|T], Cpid, Data) when is_integer(Port) ->
parse_args([{timeout, Timeout}|T], Cpid, Data) when is_integer(Timeout),Timeout>0 ->
parse_args(T, Cpid, Data#eldap{timeout = Timeout});
parse_args([{anon_auth, true}|T], Cpid, Data) ->
- parse_args(T, Cpid, Data#eldap{anon_auth = false});
+ parse_args(T, Cpid, Data#eldap{anon_auth = true});
parse_args([{anon_auth, _}|T], Cpid, Data) ->
parse_args(T, Cpid, Data);
parse_args([{ssl, true}|T], Cpid, Data) ->
@@ -374,24 +407,35 @@ parse_args([{sslopts, Opts}|T], Cpid, Data) when is_list(Opts) ->
parse_args([{sslopts, _}|T], Cpid, Data) ->
parse_args(T, Cpid, Data);
parse_args([{tcpopts, Opts}|T], Cpid, Data) when is_list(Opts) ->
- parse_args(T, Cpid, Data#eldap{tcp_opts = inet6_opt(Opts) ++ Data#eldap.tcp_opts});
+ parse_args(T, Cpid, Data#eldap{tcp_opts = tcp_opts(Opts,Cpid,Data#eldap.tcp_opts)});
parse_args([{log, F}|T], Cpid, Data) when is_function(F) ->
parse_args(T, Cpid, Data#eldap{log = F});
parse_args([{log, _}|T], Cpid, Data) ->
parse_args(T, Cpid, Data);
parse_args([H|_], Cpid, _) ->
send(Cpid, {error,{wrong_option,H}}),
+ unlink(Cpid),
exit(wrong_option);
parse_args([], _, Data) ->
Data.
-inet6_opt(Opts) ->
- case proplists:get_value(inet6, Opts) of
+tcp_opts([Opt|Opts], Cpid, Acc) ->
+ Key = if is_atom(Opt) -> Opt;
+ is_tuple(Opt) -> element(1,Opt)
+ end,
+ case lists:member(Key,[active,binary,deliver,list,mode,packet]) of
+ false ->
+ tcp_opts(Opts, Cpid, [Opt|Acc]);
true ->
- [inet6];
- _ ->
- []
- end.
+ tcp_opts_error(Opt, Cpid)
+ end;
+tcp_opts([], _Cpid, Acc) -> Acc.
+
+tcp_opts_error(Opt, Cpid) ->
+ send(Cpid, {error, {{forbidden_tcp_option,Opt},
+ "This option affects the eldap functionality and can't be set by user"}}),
+ unlink(Cpid),
+ exit(forbidden_tcp_option).
%%% Try to connect to the hosts in the listed order,
%%% and stop with the first one to which a successful
@@ -416,7 +460,8 @@ do_connect(Host, Data, Opts) when Data#eldap.ldaps == false ->
Data#eldap.timeout);
do_connect(Host, Data, Opts) when Data#eldap.ldaps == true ->
ssl:connect(Host, Data#eldap.port,
- Opts ++ Data#eldap.tls_opts ++ Data#eldap.tcp_opts).
+ Opts ++ Data#eldap.tls_opts ++ Data#eldap.tcp_opts,
+ Data#eldap.timeout).
loop(Cpid, Data) ->
receive
@@ -466,6 +511,36 @@ loop(Cpid, Data) ->
unlink(Cpid),
exit(closed);
+ {From, {getopts, OptNames}} ->
+ Result =
+ try
+ [case OptName of
+ port -> {port, Data#eldap.port};
+ log -> {log, Data#eldap.log};
+ timeout -> {timeout, Data#eldap.timeout};
+ ssl -> {ssl, Data#eldap.ldaps};
+ {sslopts, SslOptNames} when Data#eldap.using_tls==true ->
+ case ssl:getopts(Data#eldap.fd, SslOptNames) of
+ {ok,SslOptVals} -> {sslopts, SslOptVals};
+ {error,Reason} -> throw({error,Reason})
+ end;
+ {sslopts, _} ->
+ throw({error,no_tls});
+ {tcpopts, TcpOptNames} ->
+ case inet:getopts(Data#eldap.fd, TcpOptNames) of
+ {ok,TcpOptVals} -> {tcpopts, TcpOptVals};
+ {error,Posix} -> throw({error,Posix})
+ end
+ end || OptName <- OptNames]
+ of
+ OptsList -> {ok,OptsList}
+ catch
+ throw:Error -> Error;
+ Class:Error -> {error,{Class,Error}}
+ end,
+ send(From, Result),
+ ?MODULE:loop(Cpid, Data);
+
{Cpid, 'EXIT', Reason} ->
?PRINT("Got EXIT from Cpid, reason=~p~n",[Reason]),
exit(Reason);
@@ -811,6 +886,7 @@ v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV};
v_filter({approxMatch,AV}) -> {approxMatch,AV};
v_filter({present,A}) -> {present,A};
v_filter({substrings,S}) when is_record(S,'SubstringFilter') -> {substrings,S};
+v_filter({extensibleMatch,S}) when is_record(S,'MatchingRuleAssertion') -> {extensibleMatch,S};
v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}).
v_modifications(Mods) ->
diff --git a/lib/eldap/test/Makefile b/lib/eldap/test/Makefile
index 3c5810eece..28a7a107e1 100644
--- a/lib/eldap/test/Makefile
+++ b/lib/eldap/test/Makefile
@@ -28,7 +28,9 @@ INCLUDES= -I. -I ../include
# ----------------------------------------------------
MODULES= \
- eldap_basic_SUITE
+ eldap_basic_SUITE \
+ make_certs
+
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/eldap/test/README b/lib/eldap/test/README
index 8774db1504..ec774c1ae3 100644
--- a/lib/eldap/test/README
+++ b/lib/eldap/test/README
@@ -19,7 +19,7 @@ This will however not work, since slapd is guarded by apparmor that checks that
To make a local extension of alowed operations:
sudo emacs /etc/apparmor.d/local/usr.sbin.slapd
-and, after the change (yes, at least on Ubuntu it is right to edit ../local/.. but run with an other file) :
+and, after the change (yes, at least on Ubuntu it is right to edit ../local/.. but run with another file):
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.slapd
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index 6c3d303da0..137c61b2d9 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2013. 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
@@ -24,297 +24,919 @@
%%-include_lib("common_test/include/ct.hrl").
-include_lib("test_server/include/test_server.hrl").
-include_lib("eldap/include/eldap.hrl").
+-include_lib("eldap/ebin/ELDAPv3.hrl").
+
-define(TIMEOUT, 120000). % 2 min
+all() ->
+ [app,
+ appup,
+ {group, encode_decode},
+ {group, return_values},
+ {group, v4_connections},
+ {group, v6_connections},
+ {group, plain_api},
+ {group, ssl_api},
+ {group, start_tls_api}
+ ].
+
+groups() ->
+ [{encode_decode, [], [encode,
+ decode
+ ]},
+ {plain_api, [], [{group,api}]},
+ {ssl_api, [], [{group,api}, start_tls_on_ssl_should_fail]},
+ {start_tls_api, [], [{group,api}, start_tls_twice_should_fail]},
+
+ {api, [], [{group,api_not_bound},
+ {group,api_bound}]},
+
+ {api_not_bound, [], [elementary_search, search_non_existant,
+ add_when_not_bound,
+ bind]},
+ {api_bound, [], [add_when_bound,
+ add_already_exists,
+ more_add,
+ search_filter_equalityMatch,
+ search_filter_substring_any,
+ search_filter_initial,
+ search_filter_final,
+ search_filter_and,
+ search_filter_or,
+ search_filter_and_not,
+ search_two_hits,
+ modify,
+ delete,
+ modify_dn_delete_old,
+ modify_dn_keep_old]},
+ {v4_connections, [], connection_tests()},
+ {v6_connections, [], connection_tests()},
+ {return_values, [], [open_ret_val_success,
+ open_ret_val_error,
+ close_ret_val]}
+ ].
+
+connection_tests() ->
+ [tcp_connection,
+ tcp_connection_option,
+ ssl_connection,
+ client_side_start_tls_timeout,
+ client_side_bind_timeout,
+ client_side_add_timeout,
+ client_side_search_timeout
+ ].
+
+
+
init_per_suite(Config) ->
- StartSsl = try ssl:start()
- catch
- Error:Reason ->
- {skip, lists:flatten(io_lib:format("eldap init_per_suite failed to start ssl Error=~p Reason=~p", [Error, Reason]))}
- end,
- case StartSsl of
- ok ->
- chk_config(ldap_server, {"localhost",9876},
- chk_config(ldaps_server, {"localhost",9877},
- Config));
- _ ->
- StartSsl
- end.
+ SSL_available = init_ssl_certs_et_al(Config),
+ LDAP_server = find_first_server(false, [{config,eldap_server}, {config,ldap_server}, {"localhost",9876}]),
+ LDAPS_server =
+ case SSL_available of
+ true ->
+ find_first_server(true, [{config,ldaps_server}, {"localhost",9877}]);
+ false ->
+ undefined
+ end,
+ [{ssl_available, SSL_available},
+ {ldap_server, LDAP_server},
+ {ldaps_server, LDAPS_server} | Config].
end_per_suite(_Config) ->
- ok.
-
-init_per_testcase(_TestCase, Config0) ->
- {EldapHost,Port} = proplists:get_value(ldap_server,Config0),
- try
- {ok, Handle} = eldap:open([EldapHost], [{port,Port}]),
- ok = eldap:simple_bind(Handle, "cn=Manager,dc=ericsson,dc=se", "hejsan"),
- {ok, MyHost} = inet:gethostname(),
- Path = "dc="++MyHost++",dc=ericsson,dc=se",
- eldap:add(Handle,"dc=ericsson,dc=se",
- [{"objectclass", ["dcObject", "organization"]},
- {"dc", ["ericsson"]}, {"o", ["Testing"]}]),
- eldap:add(Handle,Path,
- [{"objectclass", ["dcObject", "organization"]},
- {"dc", [MyHost]}, {"o", ["Test machine"]}]),
- [{eldap_path,Path}|Config0]
- catch error:{badmatch,Error} ->
- io:format("Eldap init error ~p~n ~p~n",[Error, erlang:get_stacktrace()]),
- {skip, lists:flatten(io_lib:format("Ldap init failed with host ~p:~p. Error=~p", [EldapHost,Port,Error]))}
+ ssl:stop().
+
+
+init_per_group(return_values, Config) ->
+ case ?config(ldap_server,Config) of
+ undefined ->
+ {skip, "LDAP server not availble"};
+ {Host,Port} ->
+ ct:comment("ldap://~s:~p",[Host,Port]),
+ Config
+ end;
+init_per_group(plain_api, Config0) ->
+ case ?config(ldap_server,Config0) of
+ undefined ->
+ {skip, "LDAP server not availble"};
+ Server = {Host,Port} ->
+ ct:comment("ldap://~s:~p",[Host,Port]),
+ initialize_db([{server,Server}, {ssl_flag,false}, {start_tls,false} | Config0])
+ end;
+init_per_group(ssl_api, Config0) ->
+ case ?config(ldaps_server,Config0) of
+ undefined ->
+ {skip, "LDAPS server not availble"};
+ Server = {Host,Port} ->
+ ct:comment("ldaps://~s:~p",[Host,Port]),
+ initialize_db([{server,Server}, {ssl_flag,true}, {start_tls,false} | Config0])
+ end;
+init_per_group(start_tls_api, Config0) ->
+ case {?config(ldap_server,Config0), ?config(ssl_available,Config0)} of
+ {undefined,true} ->
+ {skip, "LDAP server not availble"};
+ {_,false} ->
+ {skip, "TLS not availble"};
+ {Server={Host,Port}, true} ->
+ ct:comment("ldap://~s:~p + start_tls",[Host,Port]),
+ Config = [{server,Server}, {ssl_flag,false} | Config0],
+ case supported_extension("1.3.6.1.4.1.1466.20037", Config) of
+ true -> initialize_db([{start_tls,true} | Config]);
+ false -> {skip, "start_tls not supported according to the server"}
+ end
+ end;
+init_per_group(v4_connections, Config) ->
+ [{tcp_listen_opts, [{reuseaddr, true}]},
+ {listen_host, "localhost"},
+ {tcp_connect_opts, []}
+ | Config];
+init_per_group(v6_connections, Config) ->
+ {ok, Hostname} = inet:gethostname(),
+ case lists:member(list_to_atom(Hostname), ct:get_config(ipv6_hosts,[])) of
+ true ->
+ [{tcp_listen_opts, [inet6,{reuseaddr, true}]},
+ {listen_host, "::"},
+ {tcp_connect_opts, [{tcpopts,[inet6]}]}
+ | Config];
+ false ->
+ {skip, io_lib:format("~p is not an ipv6_host",[Hostname])}
+ end;
+init_per_group(_, Config) ->
+ Config.
+
+end_per_group(plain_api, Config) -> clear_db(Config);
+end_per_group(ssl_api, Config) -> clear_db(Config);
+end_per_group(start_tls_api, Config) -> clear_db(Config);
+end_per_group(_Group, Config) -> Config.
+
+
+init_per_testcase(ssl_connection, Config) ->
+ case ?config(ssl_available,Config) of
+ true ->
+ SSL_Port = 9999,
+ CertFile = filename:join(?config(data_dir,Config), "certs/server/cert.pem"),
+ KeyFile = filename:join(?config(data_dir,Config), "certs/server/key.pem"),
+
+ Parent = self(),
+ Listener = spawn_link(
+ fun() ->
+ case ssl:listen(SSL_Port, [{certfile, CertFile},
+ {keyfile, KeyFile}
+ | ?config(tcp_listen_opts,Config)
+ ]) of
+ {ok,SSL_LSock} ->
+ Parent ! {ok,self()},
+ (fun L() ->
+ ct:log("ssl server waiting for connections...",[]),
+ {ok, S} = ssl:transport_accept(SSL_LSock),
+ ct:log("ssl:transport_accept/1 ok",[]),
+ ok = ssl:ssl_accept(S),
+ ct:log("ssl:ssl_accept/1 ok",[]),
+ L()
+ end)();
+ Other ->
+ Parent ! {not_ok,Other,self()}
+ end
+ end),
+ receive
+ {ok,Listener} ->
+ ct:log("SSL listening to port ~p (process ~p)",[SSL_Port, Listener]),
+ [{ssl_listener,Listener},
+ {ssl_listen_port,SSL_Port},
+ {ssl_connect_opts,[]}
+ | Config];
+ {no_ok,SSL_Other,Listener} ->
+ ct:log("ssl:listen on port ~p failed: ~p",[SSL_Port,SSL_Other]),
+ {fail, "ssl:listen/2 failed"}
+ after 5000 ->
+ {fail, "Waiting for ssl:listen timeout"}
+ end;
+ false ->
+ {skip, "ssl not available"}
+ end;
+
+init_per_testcase(TC, Config) ->
+ case lists:member(TC,connection_tests()) of
+ true ->
+ case gen_tcp:listen(0, proplists:get_value(tcp_listen_opts,Config)) of
+ {ok,LSock} ->
+ {ok,{_,Port}} = inet:sockname(LSock),
+ [{listen_socket,LSock},
+ {listen_port,Port}
+ | Config];
+ Other ->
+ {fail, Other}
+ end;
+
+ false ->
+ case proplists:get_value(name,?config(tc_group_properties, Config)) of
+ api_not_bound ->
+ {ok,H} = open(Config),
+ [{handle,H} | Config];
+ api_bound ->
+ {ok,H} = open(Config),
+ ok = eldap:simple_bind(H,
+ "cn=Manager,dc=ericsson,dc=se",
+ "hejsan"),
+ [{handle,H} | Config];
+ _Name ->
+ Config
+ end
end.
-end_per_testcase(_TestCase, Config) ->
- {EHost, Port} = proplists:get_value(ldap_server, Config),
- Path = proplists:get_value(eldap_path, Config),
- {ok, H} = eldap:open([EHost], [{port, Port}]),
- ok = eldap:simple_bind(H, "cn=Manager,dc=ericsson,dc=se", "hejsan"),
- case eldap:search(H, [{base, Path},
- {filter, eldap:present("objectclass")},
- {scope, eldap:wholeSubtree()}])
- of
- {ok, {eldap_search_result, Entries, _}} ->
- [ok = eldap:delete(H, Entry) || {eldap_entry, Entry, _} <- Entries];
- _ -> ignore
- end,
+end_per_testcase(_, Config) ->
+ catch gen_tcp:close( proplists:get_value(listen_socket, Config) ),
+ catch eldap:close( proplists:get_value(handle,Config) ).
- ok.
-%% suite() ->
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% Test cases
+%%%
-all() ->
- [app,
- appup,
- api,
- ssl_api,
- start_tls,
- tls_operations,
- start_tls_twice,
- start_tls_on_ssl
- ].
-
-app(doc) -> "Test that the eldap app file is ok";
-app(suite) -> [];
+%%%----------------------------------------------------------------
+%%% Test that the eldap app file is ok
app(Config) when is_list(Config) ->
ok = test_server:app_test(eldap).
-%% Test that the eldap appup file is ok
+%%%----------------------------------------------------------------
+%%% Test that the eldap appup file is ok
appup(Config) when is_list(Config) ->
ok = test_server:appup_test(eldap).
-api(doc) -> "Basic test that all api functions works as expected";
-api(suite) -> [];
-api(Config) ->
- {Host,Port} = proplists:get_value(ldap_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}]),
- %% {ok, H} = eldap:open([Host], [{port,Port+1}, {ssl, true}]),
- do_api_checks(H, Config),
- eldap:close(H),
- ok.
+%%%----------------------------------------------------------------
+open_ret_val_success(Config) ->
+ {Host,Port} = ?config(ldap_server,Config),
+ {ok,H} = eldap:open([Host], [{port,Port}]),
+ catch eldap:close(H).
+
+%%%----------------------------------------------------------------
+open_ret_val_error(_Config) ->
+ {error,_} = eldap:open(["nohost.example.com"], [{port,65535}]).
+
+%%%----------------------------------------------------------------
+close_ret_val(Config) ->
+ {Host,Port} = ?config(ldap_server,Config),
+ {ok,H} = eldap:open([Host], [{port,Port}]),
+ ok = eldap:close(H).
+
+%%%----------------------------------------------------------------
+tcp_connection(Config) ->
+ Host = proplists:get_value(listen_host, Config),
+ Port = proplists:get_value(listen_port, Config),
+ Opts = proplists:get_value(tcp_connect_opts, Config),
+ case eldap:open([Host], [{port,Port}|Opts]) of
+ {ok,_H} ->
+ Sl = proplists:get_value(listen_socket, Config),
+ case gen_tcp:accept(Sl,1000) of
+ {ok,_S} -> ok;
+ {error,timeout} -> ct:fail("server side accept timeout",[]);
+ Other -> ct:fail("gen_tdp:accept failed: ~p",[Other])
+ end;
+ Other -> ct:fail("eldap:open failed: ~p",[Other])
+ end.
+%%%----------------------------------------------------------------
+ssl_connection(Config) ->
+ Host = proplists:get_value(listen_host, Config),
+ Port = proplists:get_value(ssl_listen_port, Config),
+ Opts = proplists:get_value(tcp_connect_opts, Config),
+ SSLOpts = proplists:get_value(ssl_connect_opts, Config),
+ case eldap:open([Host], [{port,Port},
+ {ssl,true},
+ {timeout,5000},
+ {sslopts,SSLOpts}|Opts]) of
+ {ok,_H} -> ok;
+ Other -> ct:fail("eldap:open failed: ~p",[Other])
+ end.
-ssl_api(doc) -> "Basic test that all api functions works as expected";
-ssl_api(suite) -> [];
-ssl_api(Config) ->
- {Host,Port} = proplists:get_value(ldaps_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}, {ssl,true}]),
- do_api_checks(H, Config),
- eldap:close(H),
- ok.
+%%%----------------------------------------------------------------
+client_side_add_timeout(Config) ->
+ client_timeout(
+ fun(H) ->
+ eldap:add(H, "cn=Foo Bar,dc=host,dc=ericsson,dc=se",
+ [{"objectclass", ["person"]},
+ {"cn", ["Foo Bar"]},
+ {"sn", ["Bar"]},
+ {"telephoneNumber", ["555-1232", "555-5432"]}])
+ end, Config).
+
+%%%----------------------------------------------------------------
+client_side_bind_timeout(Config) ->
+ client_timeout(
+ fun(H) ->
+ eldap:simple_bind(H, anon, anon)
+ end, Config).
+
+%%%----------------------------------------------------------------
+client_side_search_timeout(Config) ->
+ client_timeout(
+ fun(H) ->
+ eldap:search(H, [{base,"dc=host,dc=ericsson,dc=se"},
+ {filter, eldap:present("objectclass")},
+ {scope, eldap:wholeSubtree()}])
+ end, Config).
+
+%%%----------------------------------------------------------------
+client_side_start_tls_timeout(Config) ->
+ client_timeout(
+ fun(H) ->
+ eldap:start_tls(H, [])
+ end, Config).
+
+%%%----------------------------------------------------------------
+tcp_connection_option(Config) ->
+ Host = proplists:get_value(listen_host, Config),
+ Port = proplists:get_value(listen_port, Config),
+ Opts = proplists:get_value(tcp_connect_opts, Config),
+ Sl = proplists:get_value(listen_socket, Config),
+
+ %% Make an option value to test. The option must be implemented on all
+ %% platforms that we test on. Must check what the default value is
+ %% so we don't happen to choose that particular value.
+ {ok,[{linger,DefaultLinger}]} = inet:getopts(Sl, [linger]),
+ TestLinger = case DefaultLinger of
+ {false,_} -> {true,5};
+ {true,_} -> {false,0}
+ end,
+
+ case catch eldap:open([Host],
+ [{port,Port},{tcpopts,[{linger,TestLinger}]}|Opts]) of
+ {ok,H} ->
+ case gen_tcp:accept(Sl,1000) of
+ {ok,_} ->
+ case eldap:getopts(H, [{tcpopts,[linger]}]) of
+ {ok,[{tcpopts,[{linger,ActualLinger}]}]} ->
+ case ActualLinger of
+ TestLinger ->
+ ok;
+ DefaultLinger ->
+ ct:fail("eldap:getopts: 'linger' didn't change,"
+ " got ~p (=default) expected ~p",
+ [ActualLinger,TestLinger]);
+ _ ->
+ ct:fail("eldap:getopts: bad 'linger', got ~p expected ~p",
+ [ActualLinger,TestLinger])
+ end;
+ Other ->
+ ct:fail("eldap:getopts: bad result ~p",[Other])
+ end;
+ {error,timeout} ->
+ ct:fail("server side accept timeout",[])
+ end;
+
+ Other ->
+ ct:fail("eldap:open failed: ~p",[Other])
+ end.
-start_tls(doc) -> "Test that an existing (tcp) connection can be upgraded to tls";
-start_tls(suite) -> [];
-start_tls(Config) ->
- {Host,Port} = proplists:get_value(ldap_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}]),
- ok = eldap:start_tls(H, [
- {keyfile, filename:join([proplists:get_value(data_dir,Config),
- "certs/client/key.pem"])}
- ]),
- eldap:close(H).
+%%%----------------------------------------------------------------
+%%% Basic test that all api functions works as expected
+
+%%%----------------------------------------------------------------
+elementary_search(Config) ->
+ {ok, #eldap_search_result{entries=[_]}} =
+ eldap:search(?config(handle,Config),
+ #eldap_search{base = ?config(eldap_path, Config),
+ filter= eldap:present("objectclass"),
+ scope = eldap:wholeSubtree()}).
+
+%%%----------------------------------------------------------------
+search_non_existant(Config) ->
+ {error, noSuchObject} =
+ eldap:search(?config(handle,Config),
+ #eldap_search{base = "cn=Bar," ++ ?config(eldap_path, Config),
+ filter= eldap:present("objectclass"),
+ scope = eldap:wholeSubtree()}).
+
+%%%----------------------------------------------------------------
+add_when_not_bound(Config) ->
+ {error, _} = eldap:add(?config(handle,Config),
+ "cn=Jonas Jonsson," ++ ?config(eldap_path, Config),
+ [{"objectclass", ["person"]},
+ {"cn", ["Jonas Jonsson"]},
+ {"sn", ["Jonsson"]}]).
+
+%%%----------------------------------------------------------------
+bind(Config) ->
+ ok = eldap:simple_bind(?config(handle,Config),
+ "cn=Manager,dc=ericsson,dc=se",
+ "hejsan").
+
+%%%----------------------------------------------------------------
+add_when_bound(Config) ->
+ ok = eldap:add(?config(handle, Config),
+ "cn=Jonas Jonsson," ++ ?config(eldap_path, Config),
+ [{"objectclass", ["person"]},
+ {"cn", ["Jonas Jonsson"]},
+ {"sn", ["Jonsson"]}]).
+
+%%%----------------------------------------------------------------
+add_already_exists(Config) ->
+ {error, entryAlreadyExists} =
+ eldap:add(?config(handle, Config),
+ "cn=Jonas Jonsson," ++ ?config(eldap_path, Config),
+ [{"objectclass", ["person"]},
+ {"cn", ["Jonas Jonsson"]},
+ {"sn", ["Jonsson"]}]).
+
+%%%----------------------------------------------------------------
+more_add(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ ok = eldap:add(H, "cn=Foo Bar," ++ BasePath,
+ [{"objectclass", ["person"]},
+ {"cn", ["Foo Bar"]},
+ {"sn", ["Bar"]},
+ {"telephoneNumber", ["555-1232", "555-5432"]}]),
+ ok = eldap:add(H, "ou=Team," ++ BasePath,
+ [{"objectclass", ["organizationalUnit"]},
+ {"ou", ["Team"]}]).
-tls_operations(doc) -> "Test that an upgraded connection is usable for ldap stuff";
-tls_operations(suite) -> [];
-tls_operations(Config) ->
- {Host,Port} = proplists:get_value(ldap_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}]),
- ok = eldap:start_tls(H, [
- {keyfile, filename:join([proplists:get_value(data_dir,Config),
- "certs/client/key.pem"])}
- ]),
- do_api_checks(H, Config),
+%%%----------------------------------------------------------------
+search_filter_equalityMatch(Config) ->
+ BasePath = ?config(eldap_path, Config),
+ ExpectedDN = "cn=Jonas Jonsson," ++ BasePath,
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} =
+ eldap:search(?config(handle, Config),
+ #eldap_search{base = BasePath,
+ filter = eldap:equalityMatch("sn", "Jonsson"),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+search_filter_substring_any(Config) ->
+ BasePath = ?config(eldap_path, Config),
+ ExpectedDN = "cn=Jonas Jonsson," ++ BasePath,
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} =
+ eldap:search(?config(handle, Config),
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{any, "ss"}]),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+search_filter_initial(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ ExpectedDN = "cn=Foo Bar," ++ BasePath,
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{initial, "B"}]),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+search_filter_final(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ ExpectedDN = "cn=Foo Bar," ++ BasePath,
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{final, "r"}]),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+search_filter_and(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ ExpectedDN = "cn=Foo Bar," ++ BasePath,
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:'and'([eldap:substrings("sn", [{any, "a"}]),
+ eldap:equalityMatch("cn","Foo Bar")]),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+search_filter_or(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ ExpectedDNs = lists:sort(["cn=Foo Bar," ++ BasePath,
+ "ou=Team," ++ BasePath]),
+ {ok, #eldap_search_result{entries=Es}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:'or'([eldap:substrings("sn", [{any, "a"}]),
+ eldap:equalityMatch("ou","Team")]),
+ scope=eldap:singleLevel()}),
+ ExpectedDNs = lists:sort([DN || #eldap_entry{object_name=DN} <- Es]).
+
+%%%----------------------------------------------------------------
+search_filter_and_not(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ {ok, #eldap_search_result{entries=[]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:'and'([eldap:substrings("sn", [{any, "a"}]),
+ eldap:'not'(
+ eldap:equalityMatch("cn","Foo Bar")
+ )]),
+ scope=eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+search_two_hits(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ DN1 = "cn=Santa Claus," ++ BasePath,
+ DN2 = "cn=Jultomten," ++ BasePath,
+ %% Add two objects:
+ ok = eldap:add(H, DN1,
+ [{"objectclass", ["person"]},
+ {"cn", ["Santa Claus"]},
+ {"sn", ["Santa"]},
+ {"description", ["USA"]}]),
+ ok = eldap:add(H, DN2,
+ [{"objectclass", ["person"]},
+ {"cn", ["Jultomten"]},
+ {"sn", ["Tomten"]},
+ {"description", ["Sweden"]}]),
+
+ %% Search for them:
+ {ok, #eldap_search_result{entries=Es}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:present("description"),
+ scope=eldap:singleLevel()}),
+
+ %% And check that they are the expected ones:
+ ExpectedDNs = lists:sort([DN1, DN2]),
+ ExpectedDNs = lists:sort([D || #eldap_entry{object_name=D} <- Es]),
+
+ %% Restore the database:
+ [ok=eldap:delete(H,DN) || DN <- ExpectedDNs].
+
+%%%----------------------------------------------------------------
+modify(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ %% The object to modify
+ DN = "cn=Foo Bar," ++ BasePath,
+
+ %% Save a copy to restore later:
+ {ok,OriginalAttrs} = attributes(H, DN),
+
+ %% Do a change
+ Mod = [eldap:mod_replace("telephoneNumber", ["555-12345"]),
+ eldap:mod_add("description", ["Nice guy"])],
+ ok = eldap:modify(H, DN, Mod),
+
+ %% Check that the object was changed
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:equalityMatch("telephoneNumber", "555-12345"),
+ scope=eldap:singleLevel()}),
+
+ %% Do another type of change
+ ok = eldap:modify(H, DN, [eldap:mod_delete("telephoneNumber", [])]),
+ %% and check that it worked by repeating the test above
+ {ok, #eldap_search_result{entries=[]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:equalityMatch("telephoneNumber", "555-12345"),
+ scope=eldap:singleLevel()}),
+ %% restore the orignal version:
+ restore_original_object(H, DN, OriginalAttrs).
+
+%%%----------------------------------------------------------------
+delete(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ %% The element to play with:
+ DN = "cn=Jonas Jonsson," ++ BasePath,
+
+ %% Prove that the element is present before deletion
+ {ok,OriginalAttrs} = attributes(H, DN),
+
+ %% Do what the test has to do:
+ ok = eldap:delete(H, DN),
+ %% check that it really was deleted:
+ {error, noSuchObject} = eldap:delete(H, DN),
+
+ %% And restore the object for subsequent tests
+ restore_original_object(H, DN, OriginalAttrs).
+
+%%%----------------------------------------------------------------
+modify_dn_delete_old(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ OrigCN = "Foo Bar",
+ OriginalRDN = "cn="++OrigCN,
+ DN = OriginalRDN ++ "," ++ BasePath,
+ NewCN = "Niclas Andre",
+ NewRDN = "cn="++NewCN,
+ NewDN = NewRDN ++ "," ++BasePath,
+
+ %% Check that the object to modify_dn of exists:
+ {ok,OriginalAttrs} = attributes(H, DN),
+ CN_orig = lists:sort(proplists:get_value("cn",OriginalAttrs)),
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{any, "a"}]),
+ scope = eldap:singleLevel()}),
+
+ %% Modify and delete the old one:
+ ok = eldap:modify_dn(H, DN, NewRDN, true, ""),
+
+ %% Check that DN was modified and the old one was deleted:
+ {ok,NewAttrs} = attributes(H, NewDN),
+ CN_new = lists:sort(proplists:get_value("cn",NewAttrs)),
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=NewDN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{any, "a"}]),
+ scope = eldap:singleLevel()}),
+ %% What we expect:
+ CN_new = lists:sort([NewCN | CN_orig -- [OrigCN]]),
+
+ %% Change back:
+ ok = eldap:modify_dn(H, NewDN, OriginalRDN, true, ""),
+
+ %% Check that DN was modified and the new one was deleted:
+ {ok,SameAsOriginalAttrs} = attributes(H, DN),
+ CN_orig = lists:sort(proplists:get_value("cn",SameAsOriginalAttrs)),
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{any, "a"}]),
+ scope = eldap:singleLevel()}).
+
+%%%----------------------------------------------------------------
+modify_dn_keep_old(Config) ->
+ H = ?config(handle, Config),
+ BasePath = ?config(eldap_path, Config),
+ OriginalRDN = "cn=Foo Bar",
+ DN = OriginalRDN ++ "," ++ BasePath,
+ NewCN = "Niclas Andre",
+ NewRDN = "cn="++NewCN,
+ NewDN = NewRDN ++ "," ++BasePath,
+
+ %% Check that the object to modify_dn of exists but the new one does not:
+ {ok,OriginalAttrs} = attributes(H, DN),
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} =
+ eldap:search(H,
+ #eldap_search{base = BasePath,
+ filter = eldap:substrings("sn", [{any, "a"}]),
+ scope = eldap:singleLevel()}),
+
+ %% Modify but keep the old "cn" attr:
+ ok = eldap:modify_dn(H, DN, NewRDN, false, ""),
+
+ %% Check that DN was modified and the old CN entry is not deleted:
+ {ok,NewAttrs} = attributes(H, NewDN),
+ CN_orig = proplists:get_value("cn",OriginalAttrs),
+ CN_new = proplists:get_value("cn",NewAttrs),
+ Expected = lists:sort([NewCN|CN_orig]),
+ Expected = lists:sort(CN_new),
+
+ %% Restore db:
+ ok = eldap:delete(H, NewDN),
+ restore_original_object(H, DN, OriginalAttrs).
+
+%%%----------------------------------------------------------------
+%%% Test that start_tls on an already upgraded connection makes no noise
+start_tls_twice_should_fail(Config) ->
+ {ok,H} = open_bind(Config),
+ {error,tls_already_started} = eldap:start_tls(H, []),
eldap:close(H).
-start_tls_twice(doc) -> "Test that start_tls on an already upgraded connection fails";
-start_tls_twice(suite) -> [];
-start_tls_twice(Config) ->
- {Host,Port} = proplists:get_value(ldap_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}]),
- ok = eldap:start_tls(H, []),
+%%%----------------------------------------------------------------
+%%% Test that start_tls on an ldaps connection fails
+start_tls_on_ssl_should_fail(Config) ->
+ {ok,H} = open_bind(Config),
{error,tls_already_started} = eldap:start_tls(H, []),
- do_api_checks(H, Config),
eldap:close(H).
+%%%----------------------------------------------------------------
+encode(_Config) ->
+ {ok,Bin} = 'ELDAPv3':encode('AddRequest', #'AddRequest'{entry="hejHopp" ,attributes=[]} ),
+ Expected = <<104,11,4,7,104,101,106,72,111,112,112,48,0>>,
+ case Bin of
+ Expected -> ok;
+ _ -> ct:log("Encoded erroneously to:~n~p~nExpected:~n~p",[Bin,Expected]),
+ {fail, "Bad encode"}
+ end.
+
+%%%----------------------------------------------------------------
+decode(_Config) ->
+ {ok,Res} = 'ELDAPv3':decode('AddRequest', <<104,11,4,7,104,101,106,72,111,112,112,48,0>>),
+ ct:log("Res = ~p", [Res]),
+ Expected = #'AddRequest'{entry = "hejHopp",attributes = []},
+ case Res of
+ Expected -> ok;
+ #'AddRequest'{entry= <<"hejHopp">>, attributes=[]} ->
+ {fail, "decoded to (correct) binary!!"};
+ _ ->
+ {fail, "Bad decode"}
+ end.
-start_tls_on_ssl(doc) -> "Test that start_tls on an ldaps connection fails";
-start_tls_on_ssl(suite) -> [];
-start_tls_on_ssl(Config) ->
- {Host,Port} = proplists:get_value(ldaps_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}, {ssl,true}]),
- {error,tls_already_started} = eldap:start_tls(H, []),
- do_api_checks(H, Config),
- eldap:close(H).
-%%%--------------------------------------------------------------------------------
-chk_config(Key, Default, Config) ->
- case catch ct:get_config(ldap_server, undefined) of
- undefined -> [{Key,Default} | Config ];
- {'EXIT',_} -> [{Key,Default} | Config ];
- Value -> [{Key,Value} | Config]
+%%%****************************************************************
+%%% Private
+
+attributes(H, DN) ->
+ case eldap:search(H,
+ #eldap_search{base = DN,
+ filter= eldap:present("objectclass"),
+ scope = eldap:wholeSubtree()}) of
+ {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN,
+ attributes=OriginalAttrs}]}} ->
+ {ok, OriginalAttrs};
+ Other ->
+ Other
end.
+restore_original_object(H, DN, Attrs) ->
+ eldap:delete(H, DN),
+ ok = eldap:add(H, DN, Attrs).
+
+
+find_first_server(UseSSL, [{config,Key}|Ss]) ->
+ case ct:get_config(Key) of
+ {Host,Port} ->
+ ct:log("find_first_server config ~p -> ~p",[Key,{Host,Port}]),
+ find_first_server(UseSSL, [{Host,Port}|Ss]);
+ undefined ->
+ ct:log("find_first_server config ~p is undefined",[Key]),
+ find_first_server(UseSSL, Ss)
+ end;
+find_first_server(UseSSL, [{Host,Port}|Ss]) ->
+ case eldap:open([Host],[{port,Port},{ssl,UseSSL}]) of
+ {ok,H} when UseSSL==false, Ss=/=[] ->
+ case eldap:start_tls(H,[]) of
+ ok ->
+ ct:log("find_first_server ~p UseSSL=~p -> ok",[{Host,Port},UseSSL]),
+ eldap:close(H),
+ {Host,Port};
+ Res ->
+ ct:log("find_first_server ~p UseSSL=~p failed with~n~p~nSave as spare host.",[{Host,Port},UseSSL,Res]),
+ eldap:close(H),
+ find_first_server(UseSSL, Ss++[{spare_host,Host,Port}])
+ end;
+ {ok,H} ->
+ ct:log("find_first_server ~p UseSSL=~p -> ok",[{Host,Port},UseSSL]),
+ eldap:close(H),
+ {Host,Port};
+ Res ->
+ ct:log("find_first_server ~p UseSSL=~p failed with~n~p",[{Host,Port},UseSSL,Res]),
+ find_first_server(UseSSL, Ss)
+ end;
+find_first_server(false, [{spare_host,Host,Port}|_]) ->
+ ct:log("find_first_server can't find start_tls host, use the spare non-start_tls host for plain ldap: ~p",[{Host,Port}]),
+ {Host,Port};
+find_first_server(_, []) ->
+ ct:log("find_first_server, nothing left to try",[]),
+ undefined.
+
+initialize_db(Config) ->
+ case {open_bind(Config), inet:gethostname()} of
+ {{ok,H}, {ok,MyHost}} ->
+ Path = "dc="++MyHost++",dc=ericsson,dc=se",
+ delete_old_contents(H, Path),
+ add_new_contents(H, Path, MyHost),
+ eldap:close(H),
+ [{eldap_path,Path}|Config];
+ Other ->
+ ct:fail("initialize_db failed: ~p",[Other])
+ end.
+clear_db(Config) ->
+ {ok,H} = open_bind(Config),
+ Path = ?config(eldap_path, Config),
+ delete_old_contents(H, Path),
+ eldap:close(H),
+ Config.
-do_api_checks(H, Config) ->
- BasePath = proplists:get_value(eldap_path, Config),
+delete_old_contents(H, Path) ->
+ case eldap:search(H, [{base, Path},
+ {filter, eldap:present("objectclass")},
+ {scope, eldap:wholeSubtree()}])
+ of
+ {ok, #eldap_search_result{entries=Entries}} ->
+ [ok = eldap:delete(H,DN) || #eldap_entry{object_name=DN} <- Entries];
+ _Res ->
+ ignore
+ end.
- All = fun(Where) ->
- eldap:search(H, #eldap_search{base=Where,
- filter=eldap:present("objectclass"),
- scope= eldap:wholeSubtree()})
- end,
- {ok, #eldap_search_result{entries=[_XYZ]}} = All(BasePath),
-%% ct:log("XYZ=~p",[_XYZ]),
- {error, noSuchObject} = All("cn=Bar,"++BasePath),
+add_new_contents(H, Path, MyHost) ->
+ ok(eldap:add(H,"dc=ericsson,dc=se",
+ [{"objectclass", ["dcObject", "organization"]},
+ {"dc", ["ericsson"]},
+ {"o", ["Testing"]}])),
+ ok(eldap:add(H,Path,
+ [{"objectclass", ["dcObject", "organization"]},
+ {"dc", [MyHost]},
+ {"o", ["Test machine"]}])).
- {error, _} = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath,
- [{"objectclass", ["person"]},
- {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]),
- eldap:simple_bind(H, "cn=Manager,dc=ericsson,dc=se", "hejsan"),
- chk_add(H, BasePath),
- {ok,FB} = chk_search(H, BasePath),
- chk_modify(H, FB),
- chk_delete(H, BasePath),
- chk_modify_dn(H, FB).
+ok({error,entryAlreadyExists}) -> ok;
+ok(X) -> ok=X.
-chk_add(H, BasePath) ->
- ok = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath,
- [{"objectclass", ["person"]},
- {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]),
- {error, entryAlreadyExists} = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath,
- [{"objectclass", ["person"]},
- {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]),
- ok = eldap:add(H, "cn=Foo Bar," ++ BasePath,
- [{"objectclass", ["person"]},
- {"cn", ["Foo Bar"]}, {"sn", ["Bar"]}, {"telephoneNumber", ["555-1232", "555-5432"]}]),
- ok = eldap:add(H, "ou=Team," ++ BasePath,
- [{"objectclass", ["organizationalUnit"]},
- {"ou", ["Team"]}]).
-chk_search(H, BasePath) ->
- Search = fun(Filter) ->
- eldap:search(H, #eldap_search{base=BasePath,
- filter=Filter,
- scope=eldap:singleLevel()})
- end,
- JJSR = {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:equalityMatch("sn", "Jonsson")),
- JJSR = Search(eldap:substrings("sn", [{any, "ss"}])),
- FBSR = {ok, #eldap_search_result{entries=[#eldap_entry{object_name=FB}]}} =
- Search(eldap:substrings("sn", [{any, "a"}])),
- FBSR = Search(eldap:substrings("sn", [{initial, "B"}])),
- FBSR = Search(eldap:substrings("sn", [{final, "r"}])),
- F_AND = eldap:'and'([eldap:present("objectclass"), eldap:present("ou")]),
- {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(F_AND),
- F_NOT = eldap:'and'([eldap:present("objectclass"), eldap:'not'(eldap:present("ou"))]),
- {ok, #eldap_search_result{entries=[#eldap_entry{}, #eldap_entry{}]}} = Search(F_NOT),
- {ok,FB}. %% FIXME
-
-chk_modify(H, FB) ->
- Mod = [eldap:mod_replace("telephoneNumber", ["555-12345"]),
- eldap:mod_add("description", ["Nice guy"])],
- %% io:format("MOD ~p ~p ~n",[FB, Mod]),
- ok = eldap:modify(H, FB, Mod),
- %% DELETE ATTR
- ok = eldap:modify(H, FB, [eldap:mod_delete("telephoneNumber", [])]).
-
-
-chk_delete(H, BasePath) ->
- {error, entryAlreadyExists} = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath,
- [{"objectclass", ["person"]},
- {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]),
- ok = eldap:delete(H, "cn=Jonas Jonsson," ++ BasePath),
- {error, noSuchObject} = eldap:delete(H, "cn=Jonas Jonsson," ++ BasePath).
-
-chk_modify_dn(H, FB) ->
- ok = eldap:modify_dn(H, FB, "cn=Niclas Andre", true, "").
- %%io:format("Res ~p~n ~p~n",[R, All(BasePath)]).
-
-
-%%%----------------
-add(H, Attr, Value, Path0, Attrs, Class) ->
- Path = case Path0 of
- [] -> Attr ++ "=" ++ Value;
- _ -> Attr ++ "=" ++ Value ++ "," ++ Path0
- end,
- case eldap:add(H, Path, [{"objectclass", Class}, {Attr, [Value]}] ++ Attrs)
- of
- ok -> {ok, Path};
- {error, E = entryAlreadyExists} -> {E, Path};
- R = {error, Reason} ->
- io:format("~p:~p: ~s,~s =>~n ~p~n",
- [?MODULE,?LINE, Attr, Value, R]),
- exit({ldap, add, Reason})
+cond_start_tls(H, Config) ->
+ case ?config(start_tls,Config) of
+ true -> start_tls(H,Config);
+ _ -> Config
end.
+start_tls(H, Config) ->
+ KeyFile = filename:join([?config(data_dir,Config),
+ "certs/client/key.pem"
+ ]),
+ case eldap:start_tls(H, [{keyfile, KeyFile}]) of
+ ok ->
+ [{start_tls_success,true} | Config];
+ Error ->
+ ct:log("Start_tls on ~p failed: ~p",[?config(url,Config) ,Error]),
+ ct:fail("start_tls failed")
+ end.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Develop
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-test() ->
- run().
-
-run() ->
- Cases = all(),
- run(Cases).
-
-run(Case) when is_atom(Case) ->
- run([Case]);
-run(Cases) when is_list(Cases) ->
- Run = fun(Test, Config0) ->
- Config = init_per_testcase(Test, Config0),
- try
- io:format("~nTest ~p ... ",[Test]),
- ?MODULE:Test(Config),
- end_per_testcase(Test, Config),
- io:format("ok~n",[])
- catch _:Reason ->
- io:format("~n FAIL (~p): ~p~n ~p~n",
- [Test, Reason, erlang:get_stacktrace()])
- end
- end,
- process_flag(trap_exit, true),
- Pid = spawn_link(fun() ->
- case init_per_suite([]) of
- {skip, Reason} -> io:format("Skip ~s~n",[Reason]);
- Config ->
- try
- [Run(Test, Config) || Test <- Cases]
- catch _:Err ->
- io:format("Error ~p in ~p~n",[Err, erlang:get_stacktrace()])
- end,
- end_per_suite(Config)
- end
- end),
- receive
- {'EXIT', Pid, normal} -> ok;
- Msg -> io:format("Received ~p (~p)~n",[Msg, Pid])
- after 100 -> ok end,
- process_flag(trap_exit, false),
- ok.
+%%%----------------------------------------------------------------
+open_bind(Config) ->
+ {ok,H} = open(Config),
+ ok = eldap:simple_bind(H, "cn=Manager,dc=ericsson,dc=se", "hejsan"),
+ {ok,H}.
+
+open(Config) ->
+ {Host,Port} = ?config(server,Config),
+ SSLflag = ?config(ssl_flag,Config),
+ {ok,H} = eldap:open([Host], [{port,Port},{ssl,SSLflag}]),
+ cond_start_tls(H, Config),
+ {ok,H}.
+
+%%%----------------------------------------------------------------
+supported_extension(OID, Config) ->
+ {ok,H} = open_bind(Config),
+ case eldap:search(H, [{scope, eldap:baseObject()},
+ {filter, eldap:present("objectclass")},
+ {deref, eldap:neverDerefAliases()},
+ {attributes, ["+"]}]) of
+ {ok,R=#eldap_search_result{}} ->
+ eldap:close(H),
+ lists:member(OID,
+ [SE || EE <- R#eldap_search_result.entries,
+ {"supportedExtension",SEs} <- EE#eldap_entry.attributes,
+ SE<-SEs]);
+ _ ->
+ eldap:close(H),
+ false
+ end.
+
+%%%----------------------------------------------------------------
+client_timeout(Fun, Config) ->
+ Host = proplists:get_value(listen_host, Config),
+ Port = proplists:get_value(listen_port, Config),
+ Opts = proplists:get_value(tcp_connect_opts, Config),
+ T = 1000,
+ case eldap:open([Host], [{timeout,T},{port,Port}|Opts]) of
+ {ok,H} ->
+ T0 = now(),
+ {error,{gen_tcp_error,timeout}} = Fun(H),
+ T_op = diff(T0,now()),
+ ct:log("Time = ~p, Timeout spec = ~p",[T_op,T]),
+ if
+ T_op < T ->
+ {fail, "Timeout too early"};
+ true ->
+ ok
+ end;
+
+ Other -> ct:fail("eldap:open failed: ~p",[Other])
+ end.
+
+diff({M1,S1,U1},{M2,S2,U2}) ->
+ ( ((M2-M1)*1000 + (S2-S1))*1000 + (U2-U1) ).
+
+%%%----------------------------------------------------------------
+init_ssl_certs_et_al(Config) ->
+ try ssl:start()
+ of
+ R when R==ok ; R=={error,{already_started,ssl}} ->
+ try make_certs:all("/dev/null",
+ filename:join(?config(data_dir,Config), "certs"))
+ of
+ {ok,_} -> true;
+ Other ->
+ ct:comment("make_certs failed"),
+ ct:log("make_certs failed ~p", [Other]),
+ false
+ catch
+ C:E ->
+ ct:comment("make_certs crashed"),
+ ct:log("make_certs failed ~p:~p", [C,E]),
+ false
+ end;
+ _ ->
+ false
+ catch
+ Error:Reason ->
+ ct:comment("ssl failed to start"),
+ ct:log("init_per_suite failed to start ssl Error=~p Reason=~p", [Error, Reason]),
+ false
+ end.
diff --git a/lib/eldap/test/eldap_basic_SUITE_data/RAND b/lib/eldap/test/eldap_basic_SUITE_data/RAND
new file mode 100644
index 0000000000..70997bd01f
--- /dev/null
+++ b/lib/eldap/test/eldap_basic_SUITE_data/RAND
Binary files differ
diff --git a/lib/eldap/test/eldap_misc_SUITE.erl b/lib/eldap/test/eldap_misc_SUITE.erl
deleted file mode 100644
index ca810ee33c..0000000000
--- a/lib/eldap/test/eldap_misc_SUITE.erl
+++ /dev/null
@@ -1,51 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% 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
-%% 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(eldap_misc_SUITE).
-
--compile(export_all). %% Use this only in test suites...
-
--include_lib("common_test/include/ct.hrl").
--include_lib("eldap/include/eldap.hrl").
--include_lib("eldap/ebin/ELDAPv3.hrl").
-
-all() ->
- [
- encode,
- decode
- ].
-
-
-encode(_Config) ->
- {ok,Bin} = 'ELDAPv3':encode('AddRequest', #'AddRequest'{entry="hejHopp" ,attributes=[]} ),
- Expected = <<104,11,4,7,104,101,106,72,111,112,112,48,0>>,
- Expected = Bin.
-
-decode(_Config) ->
- {ok,Res} = 'ELDAPv3':decode('AddRequest', <<104,11,4,7,104,101,106,72,111,112,112,48,0>>),
- ct:log("Res = ~p", [Res]),
- Expected = #'AddRequest'{entry = "hejHopp",attributes = []},
- case Res of
- Expected -> ok;
- #'AddRequest'{entry= <<"hejHopp">>, attributes=[]} ->
- {fail, "decoded to (correct) binary!!"};
- _ ->
- {fail, "Bad decode"}
- end.
-
diff --git a/lib/eldap/test/make_certs.erl b/lib/eldap/test/make_certs.erl
index f963af180d..15a7e118ff 100644
--- a/lib/eldap/test/make_certs.erl
+++ b/lib/eldap/test/make_certs.erl
@@ -1,41 +1,89 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2012. 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(make_certs).
+-compile([export_all]).
--export([all/2]).
+%-export([all/1, all/2, rootCA/2, intermediateCA/3, endusers/3, enduser/3, revoke/3, gencrl/2, verify/3]).
--record(dn, {commonName,
+-record(config, {commonName,
organizationalUnitName = "Erlang OTP",
organizationName = "Ericsson AB",
localityName = "Stockholm",
countryName = "SE",
- emailAddress = "[email protected]"}).
+ emailAddress = "[email protected]",
+ default_bits = 2048,
+ v2_crls = true,
+ ecc_certs = false,
+ issuing_distribution_point = false,
+ crl_port = 8000,
+ openssl_cmd = "openssl"}).
+
+
+default_config() ->
+ #config{}.
+
+make_config(Args) ->
+ make_config(Args, #config{}).
+
+make_config([], C) ->
+ C;
+make_config([{organizationalUnitName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{organizationalUnitName = Name});
+make_config([{organizationName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{organizationName = Name});
+make_config([{localityName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{localityName = Name});
+make_config([{countryName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{countryName = Name});
+make_config([{emailAddress, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{emailAddress = Name});
+make_config([{default_bits, Bits}|T], C) when is_integer(Bits) ->
+ make_config(T, C#config{default_bits = Bits});
+make_config([{v2_crls, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{v2_crls = Bool});
+make_config([{crl_port, Port}|T], C) when is_integer(Port) ->
+ make_config(T, C#config{crl_port = Port});
+make_config([{ecc_certs, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{ecc_certs = Bool});
+make_config([{issuing_distribution_point, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{issuing_distribution_point = Bool});
+make_config([{openssl_cmd, Cmd}|T], C) when is_list(Cmd) ->
+ make_config(T, C#config{openssl_cmd = Cmd}).
+
+
+all([DataDir, PrivDir]) ->
+ all(DataDir, PrivDir).
all(DataDir, PrivDir) ->
- OpenSSLCmd = "openssl",
+ all(DataDir, PrivDir, #config{}).
+
+all(DataDir, PrivDir, C) when is_list(C) ->
+ all(DataDir, PrivDir, make_config(C));
+all(DataDir, PrivDir, C = #config{}) ->
+ ok = filelib:ensure_dir(filename:join(PrivDir, "erlangCA")),
create_rnd(DataDir, PrivDir), % For all requests
- rootCA(PrivDir, OpenSSLCmd, "erlangCA"),
- intermediateCA(PrivDir, OpenSSLCmd, "otpCA", "erlangCA"),
- endusers(PrivDir, OpenSSLCmd, "otpCA", ["client", "server"]),
- collect_certs(PrivDir, ["erlangCA", "otpCA"], ["client", "server"]),
- %% Create keycert files
+ rootCA(PrivDir, "erlangCA", C),
+ intermediateCA(PrivDir, "otpCA", "erlangCA", C),
+ endusers(PrivDir, "otpCA", ["client", "server", "revoked"], C),
+ endusers(PrivDir, "erlangCA", ["localhost"], C),
+ %% Create keycert files
SDir = filename:join([PrivDir, "server"]),
SC = filename:join([SDir, "cert.pem"]),
SK = filename:join([SDir, "key.pem"]),
@@ -46,7 +94,14 @@ all(DataDir, PrivDir) ->
CK = filename:join([CDir, "key.pem"]),
CKC = filename:join([CDir, "keycert.pem"]),
append_files([CK, CC], CKC),
- remove_rnd(PrivDir).
+ RDir = filename:join([PrivDir, "revoked"]),
+ RC = filename:join([RDir, "cert.pem"]),
+ RK = filename:join([RDir, "key.pem"]),
+ RKC = filename:join([RDir, "keycert.pem"]),
+ revoke(PrivDir, "otpCA", "revoked", C),
+ append_files([RK, RC], RKC),
+ remove_rnd(PrivDir),
+ {ok, C}.
append_files(FileNames, ResultFileName) ->
{ok, ResultFile} = file:open(ResultFileName, [write]),
@@ -59,117 +114,182 @@ do_append_files([F|Fs], RF) ->
ok = file:write(RF, Data),
do_append_files(Fs, RF).
-rootCA(Root, OpenSSLCmd, Name) ->
- create_ca_dir(Root, Name, ca_cnf(Name)),
- DN = #dn{commonName = Name},
- create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)),
- ok.
+rootCA(Root, Name, C) ->
+ create_ca_dir(Root, Name, ca_cnf(C#config{commonName = Name})),
+ create_self_signed_cert(Root, Name, req_cnf(C#config{commonName = Name}), C),
+ file:copy(filename:join([Root, Name, "cert.pem"]), filename:join([Root, Name, "cacerts.pem"])),
+ gencrl(Root, Name, C).
-intermediateCA(Root, OpenSSLCmd, CA, ParentCA) ->
- CA = "otpCA",
- create_ca_dir(Root, CA, ca_cnf(CA)),
+intermediateCA(Root, CA, ParentCA, C) ->
+ create_ca_dir(Root, CA, ca_cnf(C#config{commonName = CA})),
CARoot = filename:join([Root, CA]),
- DN = #dn{commonName = CA},
CnfFile = filename:join([CARoot, "req.cnf"]),
- file:write_file(CnfFile, req_cnf(DN)),
- KeyFile = filename:join([CARoot, "private", "key.pem"]),
- ReqFile = filename:join([CARoot, "req.pem"]),
- create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ file:write_file(CnfFile, req_cnf(C#config{commonName = CA})),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ ReqFile = filename:join([CARoot, "req.pem"]),
+ create_req(Root, CnfFile, KeyFile, ReqFile, C),
CertFile = filename:join([CARoot, "cert.pem"]),
- sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile).
-
-endusers(Root, OpenSSLCmd, CA, Users) ->
- lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users).
-
-enduser(Root, OpenSSLCmd, CA, User) ->
+ sign_req(Root, ParentCA, "ca_cert", ReqFile, CertFile, C),
+ CACertsFile = filename:join(CARoot, "cacerts.pem"),
+ file:copy(filename:join([Root, ParentCA, "cacerts.pem"]), CACertsFile),
+ %% append this CA's cert to the cacerts file
+ {ok, Bin} = file:read_file(CertFile),
+ {ok, FD} = file:open(CACertsFile, [append]),
+ file:write(FD, ["\n", Bin]),
+ file:close(FD),
+ gencrl(Root, CA, C).
+
+endusers(Root, CA, Users, C) ->
+ [enduser(Root, CA, User, C) || User <- Users].
+
+enduser(Root, CA, User, C) ->
UsrRoot = filename:join([Root, User]),
file:make_dir(UsrRoot),
CnfFile = filename:join([UsrRoot, "req.cnf"]),
- DN = #dn{commonName = User},
- file:write_file(CnfFile, req_cnf(DN)),
- KeyFile = filename:join([UsrRoot, "key.pem"]),
- ReqFile = filename:join([UsrRoot, "req.pem"]),
- create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ file:write_file(CnfFile, req_cnf(C#config{commonName = User})),
+ KeyFile = filename:join([UsrRoot, "key.pem"]),
+ ReqFile = filename:join([UsrRoot, "req.pem"]),
+ create_req(Root, CnfFile, KeyFile, ReqFile, C),
+ %create_req(Root, CnfFile, KeyFile, ReqFile),
CertFileAllUsage = filename:join([UsrRoot, "cert.pem"]),
- sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFileAllUsage),
+ sign_req(Root, CA, "user_cert", ReqFile, CertFileAllUsage, C),
CertFileDigitalSigOnly = filename:join([UsrRoot, "digital_signature_only_cert.pem"]),
- sign_req(Root, OpenSSLCmd, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly).
-
-collect_certs(Root, CAs, Users) ->
- Bins = lists:foldr(
- fun(CA, Acc) ->
- File = filename:join([Root, CA, "cert.pem"]),
- {ok, Bin} = file:read_file(File),
- [Bin, "\n" | Acc]
- end, [], CAs),
- lists:foreach(
- fun(User) ->
- File = filename:join([Root, User, "cacerts.pem"]),
- file:write_file(File, Bins)
- end, Users).
+ sign_req(Root, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly, C),
+ CACertsFile = filename:join(UsrRoot, "cacerts.pem"),
+ file:copy(filename:join([Root, CA, "cacerts.pem"]), CACertsFile),
+ ok.
-create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) ->
+revoke(Root, CA, User, C) ->
+ UsrCert = filename:join([Root, User, "cert.pem"]),
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ Cmd = [C#config.openssl_cmd, " ca"
+ " -revoke ", UsrCert,
+ [" -crl_reason keyCompromise" || C#config.v2_crls ],
+ " -config ", CACnfFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env),
+ gencrl(Root, CA, C).
+
+gencrl(Root, CA, C) ->
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ CACRLFile = filename:join([Root, CA, "crl.pem"]),
+ Cmd = [C#config.openssl_cmd, " ca"
+ " -gencrl ",
+ " -crlhours 24",
+ " -out ", CACRLFile,
+ " -config ", CACnfFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+
+verify(Root, CA, User, C) ->
+ CAFile = filename:join([Root, User, "cacerts.pem"]),
+ CACRLFile = filename:join([Root, CA, "crl.pem"]),
+ CertFile = filename:join([Root, User, "cert.pem"]),
+ Cmd = [C#config.openssl_cmd, " verify"
+ " -CAfile ", CAFile,
+ " -CRLfile ", CACRLFile, %% this is undocumented, but seems to work
+ " -crl_check ",
+ CertFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ try cmd(Cmd, Env) catch
+ exit:{eval_cmd, _, _} ->
+ invalid
+ end.
+
+create_self_signed_cert(Root, CAName, Cnf, C = #config{ecc_certs = true}) ->
CARoot = filename:join([Root, CAName]),
CnfFile = filename:join([CARoot, "req.cnf"]),
file:write_file(CnfFile, Cnf),
- KeyFile = filename:join([CARoot, "private", "key.pem"]),
- CertFile = filename:join([CARoot, "cert.pem"]),
- Cmd = [OpenSSLCmd, " req"
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ Cmd = [C#config.openssl_cmd, " ecparam"
+ " -out ", KeyFile,
+ " -name secp521r1 ",
+ %" -name sect283k1 ",
+ " -genkey "],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env),
+
+ Cmd2 = [C#config.openssl_cmd, " req"
+ " -new"
+ " -x509"
+ " -config ", CnfFile,
+ " -key ", KeyFile,
+ " -outform PEM ",
+ " -out ", CertFile],
+ cmd(Cmd2, Env);
+create_self_signed_cert(Root, CAName, Cnf, C) ->
+ CARoot = filename:join([Root, CAName]),
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, Cnf),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ Cmd = [C#config.openssl_cmd, " req"
" -new"
" -x509"
" -config ", CnfFile,
" -keyout ", KeyFile,
- " -out ", CertFile],
- Env = [{"ROOTDIR", Root}],
- cmd(Cmd, Env),
- fix_key_file(OpenSSLCmd, KeyFile).
-
-% openssl 1.0 generates key files in pkcs8 format by default and we don't handle this format
-fix_key_file(OpenSSLCmd, KeyFile) ->
- KeyFileTmp = KeyFile ++ ".tmp",
- Cmd = [OpenSSLCmd, " rsa",
- " -in ",
- KeyFile,
- " -out ",
- KeyFileTmp],
- cmd(Cmd, []),
- ok = file:rename(KeyFileTmp, KeyFile).
+ " -outform PEM",
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+
create_ca_dir(Root, CAName, Cnf) ->
CARoot = filename:join([Root, CAName]),
+ ok = filelib:ensure_dir(CARoot),
file:make_dir(CARoot),
create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
create_rnd(Root, filename:join([CAName, "private"])),
create_files(CARoot, [{"serial", "01\n"},
+ {"crlnumber", "01"},
{"index.txt", ""},
{"ca.cnf", Cnf}]).
-create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) ->
- Cmd = [OpenSSLCmd, " req"
+create_req(Root, CnfFile, KeyFile, ReqFile, C = #config{ecc_certs = true}) ->
+ Cmd = [C#config.openssl_cmd, " ecparam"
+ " -out ", KeyFile,
+ " -name secp521r1 ",
+ %" -name sect283k1 ",
+ " -genkey "],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env),
+ Cmd2 = [C#config.openssl_cmd, " req"
+ " -new ",
+ " -key ", KeyFile,
+ " -outform PEM ",
+ " -out ", ReqFile,
+ " -config ", CnfFile],
+ cmd(Cmd2, Env);
+ %fix_key_file(KeyFile).
+create_req(Root, CnfFile, KeyFile, ReqFile, C) ->
+ Cmd = [C#config.openssl_cmd, " req"
" -new"
" -config ", CnfFile,
- " -keyout ", KeyFile,
- " -out ", ReqFile],
- Env = [{"ROOTDIR", Root}],
- cmd(Cmd, Env),
- fix_key_file(OpenSSLCmd, KeyFile).
+ " -outform PEM ",
+ " -keyout ", KeyFile,
+ " -out ", ReqFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+ %fix_key_file(KeyFile).
+
-sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
+sign_req(Root, CA, CertType, ReqFile, CertFile, C) ->
CACnfFile = filename:join([Root, CA, "ca.cnf"]),
- Cmd = [OpenSSLCmd, " ca"
+ Cmd = [C#config.openssl_cmd, " ca"
" -batch"
" -notext"
- " -config ", CACnfFile,
+ " -config ", CACnfFile,
" -extensions ", CertType,
- " -in ", ReqFile,
+ " -in ", ReqFile,
" -out ", CertFile],
- Env = [{"ROOTDIR", Root}],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
cmd(Cmd, Env).
-
+
%%
%% Misc
%%
-
+
create_dirs(Root, Dirs) ->
lists:foreach(fun(Dir) ->
file:make_dir(filename:join([Root, Dir])) end,
@@ -192,30 +312,30 @@ remove_rnd(Dir) ->
cmd(Cmd, Env) ->
FCmd = lists:flatten(Cmd),
- Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout,
+ Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout,
{env, Env}]),
- eval_cmd(Port).
+ eval_cmd(Port, FCmd).
-eval_cmd(Port) ->
- receive
+eval_cmd(Port, Cmd) ->
+ receive
{Port, {data, _}} ->
- eval_cmd(Port);
+ eval_cmd(Port, Cmd);
{Port, eof} ->
ok
end,
receive
{Port, {exit_status, Status}} when Status /= 0 ->
%% io:fwrite("exit status: ~w~n", [Status]),
- exit({eval_cmd, Status})
+ exit({eval_cmd, Cmd, Status})
after 0 ->
ok
end.
%%
-%% Contents of configuration files
+%% Contents of configuration files
%%
-req_cnf(DN) ->
+req_cnf(C) ->
["# Purpose: Configuration for requests (end users and CAs)."
"\n"
"ROOTDIR = $ENV::ROOTDIR\n"
@@ -224,10 +344,10 @@ req_cnf(DN) ->
"[req]\n"
"input_password = secret\n"
"output_password = secret\n"
- "default_bits = 1024\n"
+ "default_bits = ", integer_to_list(C#config.default_bits), "\n"
"RANDFILE = $ROOTDIR/RAND\n"
"encrypt_key = no\n"
- "default_md = sha1\n"
+ "default_md = md5\n"
"#string_mask = pkix\n"
"x509_extensions = ca_ext\n"
"prompt = no\n"
@@ -235,12 +355,12 @@ req_cnf(DN) ->
"\n"
"[name]\n"
- "commonName = ", DN#dn.commonName, "\n"
- "organizationalUnitName = ", DN#dn.organizationalUnitName, "\n"
- "organizationName = ", DN#dn.organizationName, "\n"
- "localityName = ", DN#dn.localityName, "\n"
- "countryName = ", DN#dn.countryName, "\n"
- "emailAddress = ", DN#dn.emailAddress, "\n"
+ "commonName = ", C#config.commonName, "\n"
+ "organizationalUnitName = ", C#config.organizationalUnitName, "\n"
+ "organizationName = ", C#config.organizationName, "\n"
+ "localityName = ", C#config.localityName, "\n"
+ "countryName = ", C#config.countryName, "\n"
+ "emailAddress = ", C#config.emailAddress, "\n"
"\n"
"[ca_ext]\n"
@@ -249,8 +369,7 @@ req_cnf(DN) ->
"subjectKeyIdentifier = hash\n"
"subjectAltName = email:copy\n"].
-
-ca_cnf(CA) ->
+ca_cnf(C) ->
["# Purpose: Configuration for CAs.\n"
"\n"
"ROOTDIR = $ENV::ROOTDIR\n"
@@ -258,21 +377,23 @@ ca_cnf(CA) ->
"\n"
"[ca]\n"
- "dir = $ROOTDIR/", CA, "\n"
+ "dir = $ROOTDIR/", C#config.commonName, "\n"
"certs = $dir/certs\n"
"crl_dir = $dir/crl\n"
"database = $dir/index.txt\n"
"new_certs_dir = $dir/newcerts\n"
"certificate = $dir/cert.pem\n"
"serial = $dir/serial\n"
- "crl = $dir/crl.pem\n"
+ "crl = $dir/crl.pem\n",
+ ["crlnumber = $dir/crlnumber\n" || C#config.v2_crls],
"private_key = $dir/private/key.pem\n"
"RANDFILE = $dir/private/RAND\n"
"\n"
- "x509_extensions = user_cert\n"
+ "x509_extensions = user_cert\n",
+ ["crl_extensions = crl_ext\n" || C#config.v2_crls],
"unique_subject = no\n"
"default_days = 3600\n"
- "default_md = sha1\n"
+ "default_md = md5\n"
"preserve = no\n"
"policy = policy_match\n"
"\n"
@@ -286,6 +407,13 @@ ca_cnf(CA) ->
"emailAddress = supplied\n"
"\n"
+ "[crl_ext]\n"
+ "authorityKeyIdentifier=keyid:always,issuer:always\n",
+ ["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point],
+
+ "[idpsec]\n"
+ "fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n"
+
"[user_cert]\n"
"basicConstraints = CA:false\n"
"keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
@@ -293,6 +421,12 @@ ca_cnf(CA) ->
"authorityKeyIdentifier = keyid,issuer:always\n"
"subjectAltName = email:copy\n"
"issuerAltName = issuer:copy\n"
+ "crlDistributionPoints=@crl_section\n"
+
+ "[crl_section]\n"
+ %% intentionally invalid
+ "URI.1=http://localhost/",C#config.commonName,"/crl.pem\n"
+ "URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n"
"\n"
"[user_cert_digital_signature_only]\n"
@@ -310,4 +444,7 @@ ca_cnf(CA) ->
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid:always,issuer:always\n"
"subjectAltName = email:copy\n"
- "issuerAltName = issuer:copy\n"].
+ "issuerAltName = issuer:copy\n"
+ "crlDistributionPoints=@crl_section\n"
+ ].
+
diff --git a/lib/eldap/vsn.mk b/lib/eldap/vsn.mk
index efdc30b476..432ba2e742 100644
--- a/lib/eldap/vsn.mk
+++ b/lib/eldap/vsn.mk
@@ -1,2 +1 @@
-ELDAP_VSN = 1.0.3
-
+ELDAP_VSN = 1.1
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index e546eb97fc..c2f81dfcc1 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -30,7 +30,39 @@
</header>
<p>This document describes the changes made to the <em>erl_docgen</em> application.</p>
- <section><title>Erl_Docgen 0.3.5</title>
+ <section><title>Erl_Docgen 0.3.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Maps: Properly align union typed assoc values in
+ documentation</p>
+ <p>
+ Own Id: OTP-12190</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix spec to doc generation from erl_docgen and edoc for
+ maps</p>
+ <p>
+ Own Id: OTP-12058</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.3.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/erl_docgen/src/docgen_otp_specs.erl b/lib/erl_docgen/src/docgen_otp_specs.erl
index 886194598f..1075c47801 100644
--- a/lib/erl_docgen/src/docgen_otp_specs.erl
+++ b/lib/erl_docgen/src/docgen_otp_specs.erl
@@ -388,8 +388,8 @@ 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 = 'fun', content = Es}]) ->
["fun("] ++ t_fun(Es) ++ [")"];
t_type([E = #xmlElement{name = record, content = Es}]) ->
@@ -432,8 +432,12 @@ t_nonempty_list(Es) ->
t_tuple(Es) ->
["{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
-t_map() ->
- ["map()"].
+t_map(Es) ->
+ Fs = get_elem(map_field, Es),
+ ["#{"] ++ seq(fun t_map_field/1, Fs, ["}"]).
+
+t_map_field(#xmlElement{content = [K,V]}) ->
+ [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)].
t_fun(Es) ->
["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es),
@@ -550,12 +554,14 @@ 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 = 'fun', content = Es}]) ->
ot_fun(Es);
ot_type([#xmlElement{name = record, content = Es}]) ->
ot_record(Es);
ot_type([#xmlElement{name = abstype, content = Es}]) ->
- ot_abstype(Es);
+ ot_abstype(Es);
ot_type([#xmlElement{name = union, content = Es}]) ->
ot_union(Es).
@@ -606,6 +612,12 @@ ot_nonempty_list(Es) ->
ot_tuple(Es) ->
{type,0,tuple,[ot_utype_elem(E) || E <- Es]}.
+ot_map(Es) ->
+ {type,0,map,[ot_map_field(E) || E <- get_elem(map_field,Es)]}.
+
+ot_map_field(#xmlElement{content=[K,V]}) ->
+ {type,0,map_field_assoc, ot_utype_elem(K), ot_utype_elem(V)}.
+
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_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 0f89922275..8957d6ac40 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1 +1 @@
-ERL_DOCGEN_VSN = 0.3.5
+ERL_DOCGEN_VSN = 0.3.7
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
deleted file mode 100644
index ed492d55ff..0000000000
--- a/lib/erl_interface/aclocal.m4
+++ /dev/null
@@ -1,1954 +0,0 @@
-dnl
-dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
-dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
-dnl
-dnl %CopyrightEnd%
-dnl
-
-dnl
-dnl aclocal.m4
-dnl
-dnl Local macros used in configure.in. The Local Macros which
-dnl could/should be part of autoconf are prefixed LM_, macros specific
-dnl to the Erlang system are prefixed ERL_.
-dnl
-
-AC_DEFUN(LM_PRECIOUS_VARS,
-[
-
-dnl ERL_TOP
-AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory])
-
-dnl Tools
-AC_ARG_VAR(CC, [C compiler])
-AC_ARG_VAR(CFLAGS, [C compiler flags])
-AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags])
-AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler])
-AC_ARG_VAR(CPP, [C/C++ preprocessor])
-AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags])
-AC_ARG_VAR(CXX, [C++ compiler])
-AC_ARG_VAR(CXXFLAGS, [C++ compiler flags])
-AC_ARG_VAR(LD, [linker (is often overridden by configure)])
-AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)])
-AC_ARG_VAR(LIBS, [libraries])
-AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)])
-AC_ARG_VAR(RANLIB, [ranlib])
-AC_ARG_VAR(AR, [ar])
-AC_ARG_VAR(GETCONF, [getconf])
-
-dnl Cross system root
-AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)])
-
-dnl Cross compilation variables
-AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-
-dnl Cross compilation variables for OSE
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file])
-AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
-
-])
-
-AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
-[
-erl_xcomp_without_sysroot=no
-if test "$cross_compiling" = "yes"; then
- test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes
- test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot"
-else
- erl_xcomp_sysroot=
- erl_xcomp_isysroot=
-fi
-])
-
-AC_DEFUN(LM_CHECK_GETCONF,
-[
-if test "$cross_compiling" != "yes"; then
- AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false])
-else
- dnl First check if we got a `<HOST>-getconf' in $PATH
- host_getconf="$host_alias-getconf"
- AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false])
- if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then
- dnl We should perhaps give up if we have'nt found it by now, but at
- dnl least in one Tilera MDE `getconf' under sysroot is a bourne
- dnl shell script which we can use. We try to find `<HOST>-getconf'
- dnl or `getconf' under sysconf, but only under sysconf since
- dnl `getconf' in $PATH is almost guaranteed to be for the build
- dnl machine.
- GETCONF=
- prfx="$erl_xcomp_sysroot"
- AC_PATH_TOOL([GETCONF], [getconf], [false],
- ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"])
- fi
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_WINDOWS_ENVIRONMENT
-dnl
-dnl
-dnl Tries to determine thw windows build environment, i.e.
-dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC
-dnl
-
-AC_DEFUN(LM_WINDOWS_ENVIRONMENT,
-[
-MIXED_CYGWIN=no
-MIXED_MSYS=no
-
-AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment)
-if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([Cygwin and VC])
- MIXED_CYGWIN_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
- elif test -x /usr/bin/msysinfo; then
- CFLAGS="-O2"
- MIXED_MSYS=yes
- AC_MSG_RESULT([MSYS and VC])
- MIXED_MSYS_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
-else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_VC=no
- MIXED_MSYS_VC=no
-fi
-AC_SUBST(MIXED_CYGWIN_VC)
-AC_SUBST(MIXED_MSYS_VC)
-
-MIXED_VC=no
-if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then
- MIXED_VC=yes
-fi
-
-AC_SUBST(MIXED_VC)
-
-if test "x$MIXED_MSYS" != "xyes"; then
- AC_MSG_CHECKING(for mixed cygwin and native MinGW environment)
- if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([yes])
- MIXED_CYGWIN_MINGW=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
- else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_MINGW=no
- fi
-else
- MIXED_CYGWIN_MINGW=no
-fi
-AC_SUBST(MIXED_CYGWIN_MINGW)
-
-AC_MSG_CHECKING(if we mix cygwin with any native compiler)
-if test "X$MIXED_CYGWIN" = "Xyes"; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_CYGWIN)
-
-AC_MSG_CHECKING(if we mix msys with another native compiler)
-if test "X$MIXED_MSYS" = "Xyes" ; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_MSYS)
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_FIND_EMU_CC
-dnl
-dnl
-dnl Tries fairly hard to find a C compiler that can handle jump tables.
-dnl Defines the @EMU_CC@ variable for the makefiles and
-dnl inserts NO_JUMP_TABLE in the header if one cannot be found...
-dnl
-
-AC_DEFUN(LM_FIND_EMU_CC,
- [AC_CACHE_CHECK(for a compiler that handles jumptables,
- ac_cv_prog_emu_cc,
- [
-AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
-lbl1:
- return 1;
-lbl2:
- return 2;
-],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
-
-if test $ac_cv_prog_emu_cc = no; then
- for ac_progname in emu_cc.sh gcc-4.2 gcc; do
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_progname; then
- ac_cv_prog_emu_cc=$ac_dir/$ac_progname
- break
- fi
- done
- IFS="$ac_save_ifs"
- if test $ac_cv_prog_emu_cc != no; then
- break
- fi
- done
-fi
-
-if test $ac_cv_prog_emu_cc != no; then
- save_CC=$CC
- save_CFLAGS=$CFLAGS
- save_CPPFLAGS=$CPPFLAGS
- CC=$ac_cv_prog_emu_cc
- CFLAGS=""
- CPPFLAGS=""
- AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
- lbl1:
- return 1;
- lbl2:
- return 2;
- ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
- CC=$save_CC
- CFLAGS=$save_CFLAGS
- CPPFLAGS=$save_CPPFLAGS
-fi
-])
-if test $ac_cv_prog_emu_cc = no; then
- AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables])
- EMU_CC=$CC
-else
- EMU_CC=$ac_cv_prog_emu_cc
-fi
-AC_SUBST(EMU_CC)
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_INSTALL_DIR
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl Figure out how to create directories with parents.
-dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better)
-dnl
-dnl We prefer 'install -d', but use 'mkdir -p' if it exists.
-dnl If none of these methods works, we give up.
-dnl
-
-
-AC_DEFUN(LM_PROG_INSTALL_DIR,
-[AC_CACHE_CHECK(how to create a directory including parents,
-ac_cv_prog_mkdir_p,
-[
-temp_name_base=config.$$
-temp_name=$temp_name_base/x/y/z
-$INSTALL -d $temp_name >/dev/null 2>&1
-ac_cv_prog_mkdir_p=none
-if test -d $temp_name; then
- ac_cv_prog_mkdir_p="$INSTALL -d"
-else
- mkdir -p $temp_name >/dev/null 2>&1
- if test -d $temp_name; then
- ac_cv_prog_mkdir_p="mkdir -p"
- fi
-fi
-rm -fr $temp_name_base
-])
-
-case "${ac_cv_prog_mkdir_p}" in
- none) AC_MSG_ERROR(don't know how create directories with parents) ;;
- *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_PERL5
-dnl
-dnl Try to find perl version 5. If found set PERL to the absolute path
-dnl of the program, if not found set PERL to false.
-dnl
-dnl On some systems /usr/bin/perl is perl 4 and e.g.
-dnl /usr/local/bin/perl is perl 5. We try to handle this case by
-dnl putting a couple of
-dnl Tries to handle the case that there are two programs called perl
-dnl in the path and one of them is perl 5 and the other isn't.
-dnl
-AC_DEFUN(LM_PROG_PERL5,
-[AC_PATH_PROGS(PERL, perl5 perl, false,
- /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH})
-changequote(, )dnl
-dnl[ That bracket is needed to balance the right bracket below
-if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then
-changequote([, ])dnl
- ac_cv_path_PERL=false
- PERL=false
-dnl AC_MSG_WARN(perl version 5 not found)
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SO_BSDCOMPAT
-dnl
-dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux)
-dnl
-AC_DEFUN(LM_DECL_SO_BSDCOMPAT,
-[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat,
-AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;],
- ac_cv_decl_so_bsdcompat=yes,
- ac_cv_decl_so_bsdcompat=no))
-
-case "${ac_cv_decl_so_bsdcompat}" in
- "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[],
- [Define if you have SO_BSDCOMPAT flag on sockets]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_INADDR_LOOPBACK
-dnl
-dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default
-dnl
-
-AC_DEFUN(LM_DECL_INADDR_LOOPBACK,
-[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h],
- ac_cv_decl_inaddr_loopback,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>], [int i = INADDR_LOOPBACK;],
-ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no)
-])
-
-if test ${ac_cv_decl_inaddr_loopback} = no; then
- AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h],
- ac_cv_decl_inaddr_loopback_rpc,
- AC_TRY_COMPILE([#include <rpc/types.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_rpc=yes,
- ac_cv_decl_inaddr_loopback_rpc=no))
-
- case "${ac_cv_decl_inaddr_loopback_rpc}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[],
- [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;;
- * )
- AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h],
- ac_cv_decl_inaddr_loopback_winsock2,
- AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_winsock2=yes,
- ac_cv_decl_inaddr_loopback_winsock2=no))
- case "${ac_cv_decl_inaddr_loopback_winsock2}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[],
- [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;;
- * )
- # couldn't find it anywhere
- AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[],
- [Define if you don't have a definition of INADDR_LOOPBACK]) ;;
- esac;;
- esac
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_SOCKADDR_SA_LEN
-dnl
-dnl Check if the sockaddr structure has the field sa_len
-dnl
-
-AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN,
-[AC_CACHE_CHECK([whether struct sockaddr has sa_len field],
- ac_cv_struct_sockaddr_sa_len,
-AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;],
- ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no))
-
-dnl FIXME convbreak
-case ${ac_cv_struct_sockaddr_sa_len} in
- "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;;
- *) ;;
-esac
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_EXCEPTION
-dnl
-dnl Check to see whether the system supports the matherr function
-dnl and its associated type "struct exception".
-dnl
-
-AC_DEFUN(LM_STRUCT_EXCEPTION,
-[AC_CACHE_CHECK([for struct exception (and matherr function)],
- ac_cv_struct_exception,
-AC_TRY_COMPILE([#include <math.h>],
- [struct exception x; x.type = DOMAIN; x.type = SING;],
- ac_cv_struct_exception=yes, ac_cv_struct_exception=no))
-
-case "${ac_cv_struct_exception}" in
- "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_IPV6
-dnl
-dnl Check for ipv6 support and what the in6_addr structure is called.
-dnl (early linux used in_addr6 insted of in6_addr)
-dnl
-
-AC_DEFUN(LM_SYS_IPV6,
-[AC_MSG_CHECKING(for IP version 6 support)
-AC_CACHE_VAL(ac_cv_sys_ipv6_support,
-[ok_so_far=yes
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no)
-
-if test $ok_so_far = yes; then
- ac_cv_sys_ipv6_support=yes
-else
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in_addr6 a6; struct sockaddr_in6 s6;],
- ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no)
-fi
-])dnl
-
-dnl
-dnl Have to use old style AC_DEFINE due to BC with old autoconf.
-dnl
-
-case ${ac_cv_sys_ipv6_support} in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- ;;
- in_addr6)
- AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)])
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this])
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_MULTICAST
-dnl
-dnl Check for multicast support. Only checks for multicast options in
-dnl setsockopt(), no check is performed that multicasting actually works.
-dnl If options are found defines HAVE_MULTICAST_SUPPORT
-dnl
-
-AC_DEFUN(LM_SYS_MULTICAST,
-[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support,
-[AC_EGREP_CPP(yes,
-[#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP)
-yes
-#endif
-], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)])
-if test $ac_cv_sys_multicast_support = yes; then
- AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1],
- [Define if setsockopt() accepts multicast options])
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SYS_ERRLIST
-dnl
-dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared
-dnl in a system header file, stdio.h or errno.h.
-dnl
-
-AC_DEFUN(LM_DECL_SYS_ERRLIST,
-[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h],
- ac_cv_decl_sys_errlist,
-[AC_TRY_COMPILE([#include <stdio.h>
-#include <errno.h>], [char *msg = *(sys_errlist + 1);],
- ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)])
-if test $ac_cv_decl_sys_errlist = yes; then
- AC_DEFINE(SYS_ERRLIST_DECLARED,[],
- [define if the variable sys_errlist is declared in a system header file])
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes
-dnl [, action-if-found [, action-if-not-found]]] )
-dnl
-dnl Checks if the declaration "declaration" of "funname" conflicts
-dnl with the header files idea of how the function should be
-dnl declared. It is useful on systems which lack prototypes and you
-dnl need to provide your own (e.g. when you want to take the address
-dnl of a function). The 4'th argument is expanded if conflicting,
-dnl the 5'th argument otherwise
-dnl
-dnl
-
-AC_DEFUN(LM_CHECK_FUNC_DECL,
-[AC_MSG_CHECKING([for conflicting declaration of $1])
-AC_CACHE_VAL(ac_cv_func_decl_$1,
-[AC_TRY_COMPILE([#include <stdio.h>
-$3],[$2
-char *c = (char *)$1;
-], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")])
-if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then
- AC_MSG_RESULT(yes)
- ifelse([$4], , :, [$4])
-else
- AC_MSG_RESULT(no)
-ifelse([$5], , , [$5
-])dnl
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl AC_DOUBLE_MIDDLE_ENDIAN
-dnl
-dnl Checks whether doubles are represented in "middle-endian" format.
-dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly,
-dnl as well as DOUBLE_MIDDLE_ENDIAN.
-dnl
-dnl
-
-AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN],
-[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian,
-[# It does not; compile a test program.
-AC_RUN_IFELSE(
-[AC_LANG_SOURCE([[#include <stdlib.h>
-
-int
-main(void)
-{
- int i = 0;
- int zero = 0;
- int bigendian;
- int zero_index = 0;
-
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
-
- /* we'll use the one with 32-bit words */
- union
- {
- double d;
- unsigned int c[2];
- } vint;
-
- union
- {
- double d;
- unsigned long c[2];
- } vlong;
-
- union
- {
- double d;
- unsigned short c[2];
- } vshort;
-
-
- /* Are we little or big endian? From Harbison&Steele. */
- u.l = 1;
- bigendian = (u.c[sizeof (long int) - 1] == 1);
-
- zero_index = bigendian ? 1 : 0;
-
- vint.d = 1.0;
- vlong.d = 1.0;
- vshort.d = 1.0;
-
- if (sizeof(unsigned int) == 4)
- {
- if (vint.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned long) == 4)
- {
- if (vlong.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned short) == 4)
- {
- if (vshort.c[zero_index] != 0)
- zero = 1;
- }
-
- exit (zero);
-}
-]])],
- [ac_cv_c_double_middle_endian=no],
- [ac_cv_c_double_middle_endian=yes],
- [ac_cv_c_double_middle=unknown])])
-case $ac_cv_c_double_middle_endian in
- yes)
- m4_default([$1],
- [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1,
- [Define to 1 if your processor stores the words in a double in
- middle-endian format (like some ARMs).])]) ;;
- no)
- $2 ;;
- *)
- m4_default([$3],
- [AC_MSG_WARN([unknown double endianness
-presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;;
-esac
-])# AC_C_DOUBLE_MIDDLE_ENDIAN
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_THR_LIB
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also
-dnl checks for some pthread headers which will appear in DEFS or config.h.
-dnl
-
-AC_DEFUN(LM_CHECK_THR_LIB,
-[
-
-NEED_NPTL_PTHREAD_H=no
-
-dnl win32?
-AC_MSG_CHECKING([for native win32 threads])
-if test "X$host_os" = "Xwin32"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DWIN32_THREADS"
- THR_LIBS=
- THR_LIB_NAME=win32_threads
- THR_LIB_TYPE=win32_threads
-elif test "X$host_os" = "Xose"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DOSE_THREADS"
- THR_LIBS=
- THR_LIB_NAME=ose_threads
- THR_LIB_TYPE=ose_threads
-else
- AC_MSG_RESULT(no)
- THR_DEFS=
- THR_LIBS=
- THR_LIB_NAME=
- THR_LIB_TYPE=posix_unknown
-
-dnl Try to find POSIX threads
-
-dnl The usual pthread lib...
- AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread")
-
-dnl Very old versions of FreeBSD have pthreads in special c library, c_r...
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r")
- fi
-
-dnl QNX has pthreads in standard C library
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed")
- fi
-
-dnl On ofs1 the '-pthread' switch should be used
- if test "x$THR_LIBS" = "x"; then
- AC_MSG_CHECKING([if the '-pthread' switch can be used])
- saved_cflags=$CFLAGS
- CFLAGS="$CFLAGS -pthread"
- AC_TRY_LINK([#include <pthread.h>],
- pthread_create((void*)0,(void*)0,(void*)0,(void*)0);,
- [THR_DEFS="-pthread"
- THR_LIBS="-pthread"])
- CFLAGS=$saved_cflags
- if test "x$THR_LIBS" != "x"; then
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- if test "x$THR_LIBS" != "x"; then
- THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS"
- THR_LIB_NAME=pthread
- if test "x$THR_LIBS" = "xnone_needed"; then
- THR_LIBS=
- fi
- case $host_os in
- solaris*)
- THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;;
- linux*)
- THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS"
-
- LM_CHECK_GETCONF
- AC_MSG_CHECKING(for Native POSIX Thread Library)
- libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null`
- if test $? -eq 0; then
- case "$libpthr_vsn" in
- *nptl*|*NPTL*) nptl=yes;;
- *) nptl=no;;
- esac
- elif test "$cross_compiling" = "yes"; then
- case "$erl_xcomp_linux_nptl" in
- "") nptl=cross;;
- yes|no) nptl=$erl_xcomp_linux_nptl;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);;
- esac
- else
- nptl=no
- fi
- AC_MSG_RESULT($nptl)
- if test $nptl = cross; then
- nptl=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $nptl = yes; then
- THR_LIB_TYPE=posix_nptl
- need_nptl_incldir=no
- AC_CHECK_HEADER(nptl/pthread.h,
- [need_nptl_incldir=yes
- NEED_NPTL_PTHREAD_H=yes])
- if test $need_nptl_incldir = yes; then
- # Ahh...
- nptl_path="$C_INCLUDE_PATH:$CPATH"
- if test X$cross_compiling != Xyes; then
- nptl_path="$nptl_path:/usr/local/include:/usr/include"
- else
- IROOT="$erl_xcomp_isysroot"
- test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot"
- test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot])
- nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include"
- fi
- nptl_ws_path=
- save_ifs="$IFS"; IFS=":"
- for dir in $nptl_path; do
- if test "x$dir" != "x"; then
- nptl_ws_path="$nptl_ws_path $dir"
- fi
- done
- IFS=$save_ifs
- nptl_incldir=
- for dir in $nptl_ws_path; do
- AC_CHECK_HEADER($dir/nptl/pthread.h,
- nptl_incldir=$dir/nptl)
- if test "x$nptl_incldir" != "x"; then
- THR_DEFS="$THR_DEFS -isystem $nptl_incldir"
- break
- fi
- done
- if test "x$nptl_incldir" = "x"; then
- AC_MSG_ERROR(Failed to locate nptl system include directory)
- fi
- fi
- fi
- ;;
- *) ;;
- esac
-
- dnl We sometimes need THR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS $THR_DEFS"
-
- dnl
- dnl Check for headers
- dnl
-
- AC_CHECK_HEADER(pthread.h,
- AC_DEFINE(HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- fi
-fi
-
-])
-
-AC_DEFUN(ERL_INTERNAL_LIBS,
-[
-
-ERTS_INTERNAL_X_LIBS=
-
-AC_CHECK_LIB(kstat, kstat_open,
-[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat])
-ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"])
-
-AC_SUBST(ERTS_INTERNAL_X_LIBS)
-
-])
-
-AC_DEFUN(ETHR_CHK_SYNC_OP,
-[
- AC_MSG_CHECKING([for $3-bit $1()])
- case "$2" in
- "1") sync_call="$1(&var);";;
- "2") sync_call="$1(&var, ($4) 0);";;
- "3") sync_call="$1(&var, ($4) 0, ($4) 0);";;
- esac
- have_sync_op=no
- AC_TRY_LINK([],
- [
- $4 res;
- volatile $4 var;
- res = $sync_call
- ],
- [have_sync_op=yes])
- test $have_sync_op = yes && $5
- AC_MSG_RESULT([$have_sync_op])
-])
-
-AC_DEFUN(ETHR_CHK_INTERLOCKED,
-[
- ilckd="$1"
- AC_MSG_CHECKING([for ${ilckd}()])
- case "$2" in
- "1") ilckd_call="${ilckd}(var);";;
- "2") ilckd_call="${ilckd}(var, ($3) 0);";;
- "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";;
- "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";;
- esac
- have_interlocked_op=no
- AC_TRY_LINK(
- [
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <intrin.h>
- ],
- [
- volatile $3 *var;
- volatile $3 arr[2];
-
- $ilckd_call
- return 0;
- ],
- [have_interlocked_op=yes])
- test $have_interlocked_op = yes && $4
- AC_MSG_RESULT([$have_interlocked_op])
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_FIND_ETHR_LIB
-dnl
-dnl NOTE! This macro may be changed at any time! Should *only* be used by
-dnl ERTS!
-dnl
-dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link
-dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS
-dnl except that the ethread lib itself is not included), ETHR_DEFS to
-dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the
-dnl thread library which the ethread library is based on, and ETHR_LIB_NAME
-dnl to the name of the library where the ethread implementation is located.
-dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and
-dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS,
-dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the
-dnl empty string.
-dnl
-
-AC_DEFUN(ERL_FIND_ETHR_LIB,
-[
-
-AC_ARG_ENABLE(native-ethr-impls,
- AS_HELP_STRING([--disable-native-ethr-impls],
- [disable native ethread implementations]),
-[ case "$enableval" in
- no) disable_native_ethr_impls=yes ;;
- *) disable_native_ethr_impls=no ;;
- esac ], disable_native_ethr_impls=no)
-
-test "X$disable_native_ethr_impls" = "Xyes" &&
- AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations])
-
-AC_ARG_ENABLE(x86-out-of-order,
- AS_HELP_STRING([--enable-x86-out-of-order],
- [enable x86/x84_64 out of order support (default disabled)]))
-
-AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
- AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls],
- [prefer gcc native ethread implementations]),
-[ case "$enableval" in
- yes) enable_prefer_gcc_native_ethr_impls=yes ;;
- *) enable_prefer_gcc_native_ethr_impls=no ;;
- esac ], enable_prefer_gcc_native_ethr_impls=no)
-
-test $enable_prefer_gcc_native_ethr_impls = yes &&
- AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations])
-
-AC_ARG_WITH(libatomic_ops,
- AS_HELP_STRING([--with-libatomic_ops=PATH],
- [specify and prefer usage of libatomic_ops in the ethread library]))
-
-AC_ARG_WITH(with_sparc_memory_order,
- AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO],
- [specify sparc memory order (defaults to RMO)]))
-
-LM_CHECK_THR_LIB
-ERL_INTERNAL_LIBS
-
-ethr_have_native_atomics=no
-ethr_have_native_spinlock=no
-ETHR_THR_LIB_BASE="$THR_LIB_NAME"
-ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE"
-ETHR_DEFS="$THR_DEFS"
-ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS"
-ETHR_LIBS=
-ETHR_LIB_NAME=
-
-ethr_modified_default_stack_size=
-
-dnl Name of lib where ethread implementation is located
-ethr_lib_name=ethread
-
-case "$THR_LIB_NAME" in
-
- win32_threads)
- ETHR_THR_LIB_BASE_DIR=win
- # * _WIN32_WINNT >= 0x0400 is needed for
- # TryEnterCriticalSection
- # * _WIN32_WINNT >= 0x0403 is needed for
- # InitializeCriticalSectionAndSpinCount
- # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403.
- #
- # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it
- # and save it in ETHR_DEFS.
- found_win32_winnt=no
- for cppflag in $CPPFLAGS; do
- case $cppflag in
- -DWINVER*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- ;;
- -D_WIN32_WINNT*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- found_win32_winnt=yes
- ;;
- *)
- ;;
- esac
- done
- if test $found_win32_winnt = no; then
- AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
- fi
-
- AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- have_interlocked_op=no
- ethr_have_native_atomics=no
- else
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()]))
- fi
- test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
- ;;
-
- pthread|ose_threads)
- case "$THR_LIB_NAME" in
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
- ;;
- ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1,
- [Define if you have OSE style threads])
- ETHR_THR_LIB_BASE_DIR=ose
- AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI_H, 1,
- [Define if you have the "ose_spi/ose_spi.h" header file.]))
- ;;
- esac
- if test "x$THR_LIB_NAME" = "xpthread"; then
- case $host_os in
- openbsd*)
- # The default stack size is insufficient for our needs
- # on OpenBSD. We increase it to 256 kilo words.
- ethr_modified_default_stack_size=256;;
- linux*)
- ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE"
-
- if test X$cross_compiling = Xyes; then
- case X$erl_xcomp_linux_usable_sigusrx in
- X) usable_sigusrx=cross;;
- Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);;
- esac
- case X$erl_xcomp_linux_usable_sigaltstack in
- X) usable_sigaltstack=cross;;
- Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);;
- esac
- else
- # FIXME: Test for actual problems instead of kernel versions
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
- usable_sigusrx=no
- usable_sigaltstack=no;;
- 2.[[2-3]]|2.[[2-3]].*)
- usable_sigusrx=yes
- usable_sigaltstack=no;;
- *)
- usable_sigusrx=yes
- usable_sigaltstack=yes;;
- esac
- fi
-
- AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
- AC_MSG_RESULT($usable_sigusrx)
- if test $usable_sigusrx = cross; then
- usable_sigusrx=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigusrx = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX"
- fi
-
- AC_MSG_CHECKING(if sigaltstack can be used)
- AC_MSG_RESULT($usable_sigaltstack)
- if test $usable_sigaltstack = cross; then
- usable_sigaltstack=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigaltstack = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
- fi
- ;;
- *) ;;
- esac
-
- fi
- dnl We sometimes need ETHR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $ETHR_DEFS"
-
- dnl We need the thread library in order to find some functions
- saved_libs="$LIBS"
- LIBS="$LIBS $ETHR_X_LIBS"
-
- dnl
- dnl Check for headers
- dnl
- AC_CHECK_HEADER(pthread.h, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- if test $NEED_NPTL_PTHREAD_H = yes; then
- AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \
-[Define if you need the <nptl/pthread.h> header file.])
- fi
-
- AC_CHECK_HEADER(sched.h, \
- AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \
-[Define if you have the <sched.h> header file.]))
-
- AC_CHECK_HEADER(sys/time.h, \
- AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \
-[Define if you have the <sys/time.h> header file.]))
-
- AC_TRY_COMPILE([#include <time.h>
- #include <sys/time.h>],
- [struct timeval *tv; return 0;],
- AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \
-[Define if you can safely include both <sys/time.h> and <time.h>.]))
-
-
- dnl
- dnl Check for functions
- dnl
- if test "x$THR_LIB_NAME" = "xpthread"; then
- AC_CHECK_FUNC(pthread_spin_lock, \
- [ethr_have_native_spinlock=yes \
- AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
-[Define if you have the pthread_spin_lock function.])])
-
- have_sched_yield=no
- have_librt_sched_yield=no
- AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes])
- if test $have_sched_yield = no; then
- AC_CHECK_LIB(rt, sched_yield,
- [have_librt_sched_yield=yes
- ETHR_X_LIBS="$ETHR_X_LIBS -lrt"])
- fi
- if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then
- AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.])
- AC_MSG_CHECKING([whether sched_yield() returns an int])
- sched_yield_ret_int=no
- AC_TRY_COMPILE([
- #ifdef ETHR_HAVE_SCHED_H
- #include <sched.h>
- #endif
- ],
- [int sched_yield();],
- [sched_yield_ret_int=yes])
- AC_MSG_RESULT([$sched_yield_ret_int])
- if test $sched_yield_ret_int = yes; then
- AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.])
- fi
- fi
-
- have_pthread_yield=no
- AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes])
- if test $have_pthread_yield = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.])
- AC_MSG_CHECKING([whether pthread_yield() returns an int])
- pthread_yield_ret_int=no
- AC_TRY_COMPILE([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [int pthread_yield();],
- [pthread_yield_ret_int=yes])
- AC_MSG_RESULT([$pthread_yield_ret_int])
- if test $pthread_yield_ret_int = yes; then
- AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.])
- fi
- fi
-
- have_pthread_rwlock_init=no
- AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes])
- if test $have_pthread_rwlock_init = yes; then
-
- ethr_have_pthread_rwlockattr_setkind_np=no
- AC_CHECK_FUNC(pthread_rwlockattr_setkind_np,
- [ethr_have_pthread_rwlockattr_setkind_np=yes])
-
- if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \
-[Define if you have the pthread_rwlockattr_setkind_np() function.])
-
- AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP])
- ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no
- AC_TRY_LINK([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [
- pthread_rwlockattr_t *attr;
- return pthread_rwlockattr_setkind_np(attr,
- PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
- ],
- [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes])
- AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np])
- if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \
-[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.])
- fi
- fi
- fi
-
- if test "$force_pthread_rwlocks" = "yes"; then
-
- AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \
-[Define if you want to force usage of pthread rwlocks])
-
- if test $have_pthread_rwlock_init = yes; then
- AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.])
- else
- AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found])
- fi
- fi
-
- AC_CHECK_FUNC(pthread_attr_setguardsize, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \
-[Define if you have the pthread_attr_setguardsize function.]))
-
- linux_futex=no
- AC_MSG_CHECKING([for Linux futexes])
- AC_TRY_LINK([
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/futex.h>
- #include <sys/time.h>
- ],
- [
- int i = 1;
- syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1,
- (void*)0,(void*)0, 0);
- syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0,
- (void*)0,(void*)0, 0);
- return 0;
- ],
- linux_futex=yes)
- AC_MSG_RESULT([$linux_futex])
- test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
-
- fi
-
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_CHECK_SIZEOF(long long)
- AC_CHECK_SIZEOF(__int128_t)
-
- if test "$ac_cv_sizeof_int" = "4"; then
- int32="int"
- elif test "$ac_cv_sizeof_long" = "4"; then
- int32="long"
- elif test "$ac_cv_sizeof_long_long" = "4"; then
- int32="long long"
- else
- AC_MSG_ERROR([No 32-bit type found])
- fi
-
- if test "$ac_cv_sizeof_int" = "8"; then
- int64="int"
- elif test "$ac_cv_sizeof_long" = "8"; then
- int64="long"
- elif test "$ac_cv_sizeof_long_long" = "8"; then
- int64="long long"
- else
- AC_MSG_ERROR([No 64-bit type found])
- fi
-
- int128=no
- if test "$ac_cv_sizeof___int128_t" = "16"; then
- int128="__int128_t"
- fi
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- ethr_have_native_atomics=no
- else
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers]))
-
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers]))
-
- if test $int128 != no; then
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers]))
- fi
-
- AC_MSG_CHECKING([for a usable libatomic_ops implementation])
- case "x$with_libatomic_ops" in
- xno | xyes | x)
- libatomic_ops_include=
- ;;
- *)
- if test -d "${with_libatomic_ops}/include"; then
- libatomic_ops_include="-I$with_libatomic_ops/include"
- CPPFLAGS="$CPPFLAGS $libatomic_ops_include"
- else
- AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found])
- fi;;
- esac
- ethr_have_libatomic_ops=no
- AC_TRY_LINK([#include "atomic_ops.h"],
- [
- volatile AO_t x;
- AO_t y;
- int z;
-
- AO_nop_full();
- AO_store(&x, (AO_t) 0);
- z = AO_load(&x);
- z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1);
- ],
- [ethr_have_native_atomics=yes
- ethr_have_libatomic_ops=yes])
- AC_MSG_RESULT([$ethr_have_libatomic_ops])
- if test $ethr_have_libatomic_ops = yes; then
- AC_CHECK_SIZEOF(AO_t, ,
- [
- #include <stdio.h>
- #include "atomic_ops.h"
- ])
- AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used])
-
- AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations])
- if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations])
- fi
- ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include"
- elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_MSG_ERROR([No usable libatomic_ops implementation found])
- fi
-
- case "$host_cpu" in
- sparc | sun4u | sparc64 | sun4v)
- case "$with_sparc_memory_order" in
- "TSO")
- AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);;
- "PSO")
- AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);;
- "RMO"|"")
- AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);;
- *)
- AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);;
- esac
- ethr_have_native_atomics=yes;;
- i86pc | i*86 | x86_64 | amd64)
- if test "$enable_x86_out_of_order" = "yes"; then
- AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized])
- fi
- ethr_have_native_atomics=yes;;
- macppc | ppc | powerpc | "Power Macintosh")
- ethr_have_native_atomics=yes;;
- tile)
- ethr_have_native_atomics=yes;;
- *)
- ;;
- esac
-
- fi
-
- test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes
-
- dnl Restore LIBS
- LIBS=$saved_libs
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- ;;
- *)
- ;;
-esac
-
-AC_MSG_CHECKING([whether default stack size should be modified])
-if test "x$ethr_modified_default_stack_size" != "x"; then
- AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size])
- AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words])
-else
- AC_MSG_RESULT([no])
-fi
-
-if test "x$ETHR_THR_LIB_BASE" != "x"; then
- ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS"
- ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS"
- ETHR_LIB_NAME=$ethr_lib_name
-fi
-
-AC_CHECK_SIZEOF(void *)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers])
-
-AC_CHECK_SIZEOF(int)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int])
-AC_CHECK_SIZEOF(long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long])
-AC_CHECK_SIZEOF(long long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long])
-AC_CHECK_SIZEOF(__int64)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64])
-AC_CHECK_SIZEOF(__int128_t)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t])
-
-
-case X$erl_xcomp_bigendian in
- X) ;;
- Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);;
-esac
-
-AC_C_BIGENDIAN
-
-if test "$ac_cv_c_bigendian" = "yes"; then
- AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian])
-fi
-
-case X$erl_xcomp_double_middle_endian in
- X) ;;
- Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);;
-esac
-
-AC_C_DOUBLE_MIDDLE_ENDIAN
-
-ETHR_X86_SSE2_ASM=no
-case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in
- yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64)
- AC_MSG_CHECKING([for gcc sse2 asm support])
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -msse2"
- gcc_sse2_asm=no
- AC_TRY_COMPILE([],
- [
- long long x, *y;
- __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory");
- ],
- [gcc_sse2_asm=yes])
- CFLAGS="$save_CFLAGS"
- AC_MSG_RESULT([$gcc_sse2_asm])
- if test "$gcc_sse2_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements])
- ETHR_X86_SSE2_ASM=yes
- fi
- ;;
- *)
- ;;
-esac
-
-case "$GCC-$host_cpu" in
- yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64)
- gcc_dw_cmpxchg_asm=no
- AC_MSG_CHECKING([for gcc double word cmpxchg asm support])
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
- __asm__ __volatile__(
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "pushl %%ebx\n\t"
- "movl %8, %%ebx\n\t"
-#endif
-#if ETHR_SIZEOF_PTR == 4
- "lock; cmpxchg8b %0\n\t"
-#else
- "lock; cmpxchg16b %0\n\t"
-#endif
- "setz %3\n\t"
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "popl %%ebx\n\t"
-#endif
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]),
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "r"(new[0])
-#else
- "b"(new[0])
-#endif
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
-#if !defined(__PIC__) || !__PIC__
-# error nope
-#endif
- __asm__ __volatile__(
- "pushl %%ebx\n\t"
- "movl (%7), %%ebx\n\t"
- "movl 4(%7), %%ecx\n\t"
- "lock; cmpxchg8b %0\n\t"
- "setz %3\n\t"
- "popl %%ebx\n\t"
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new)
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code])
- fi
- fi
- AC_MSG_RESULT([$gcc_dw_cmpxchg_asm])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction])
- fi;;
- *)
- ;;
-esac
-
-AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
-[Define if you have all ethread defines])
-
-AC_SUBST(ETHR_X_LIBS)
-AC_SUBST(ETHR_LIBS)
-AC_SUBST(ETHR_LIB_NAME)
-AC_SUBST(ETHR_DEFS)
-AC_SUBST(ETHR_THR_LIB_BASE)
-AC_SUBST(ETHR_THR_LIB_BASE_DIR)
-AC_SUBST(ETHR_X86_SSE2_ASM)
-
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_TIME_CORRECTION
-dnl
-dnl In the presence of a high resolution realtime timer Erlang can adapt
-dnl its view of time relative to this timer. On solaris such a timer is
-dnl available with the syscall gethrtime(). On other OS's a fallback
-dnl solution using times() is implemented. (However on e.g. FreeBSD times()
-dnl is implemented using gettimeofday so it doesn't make much sense to
-dnl use it there...) On second thought, it seems to be safer to do it the
-dnl other way around. I.e. only use times() on OS's where we know it will
-dnl work...
-dnl
-
-AC_DEFUN(ERL_TIME_CORRECTION,
-[if test x$ac_cv_func_gethrtime = x; then
- AC_CHECK_FUNC(gethrtime)
-fi
-if test x$clock_gettime_correction = xunknown; then
- AC_TRY_COMPILE([#include <time.h>],
- [struct timespec ts;
- long long result;
- clock_gettime(CLOCK_MONOTONIC,&ts);
- result = ((long long) ts.tv_sec) * 1000000000LL +
- ((long long) ts.tv_nsec);],
- clock_gettime_compiles=yes,
- clock_gettime_compiles=no)
-else
- clock_gettime_compiles=no
-fi
-
-
-AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction,
-[
-case $clock_gettime_correction in
- yes)
- erl_cv_time_correction=clock_gettime;;
- no|unknown)
- case $ac_cv_func_gethrtime in
- yes)
- erl_cv_time_correction=hrtime ;;
- no)
- case $host_os in
- linux*)
- case $clock_gettime_correction in
- unknown)
- if test x$clock_gettime_compiles = xyes; then
- if test X$cross_compiling != Xyes; then
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
- erl_cv_time_correction=times ;;
- *)
- erl_cv_time_correction=clock_gettime;;
- esac
- else
- case X$erl_xcomp_linux_clock_gettime_correction in
- X)
- erl_cv_time_correction=cross;;
- Xyes|Xno)
- if test $erl_xcomp_linux_clock_gettime_correction = yes; then
- erl_cv_time_correction=clock_gettime
- else
- erl_cv_time_correction=times
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);;
- esac
- fi
- else
- erl_cv_time_correction=times
- fi
- ;;
- *)
- erl_cv_time_correction=times ;;
- esac
- ;;
- *)
- erl_cv_time_correction=none ;;
- esac
- ;;
- esac
- ;;
-esac
-])
-
-xrtlib=""
-case $erl_cv_time_correction in
- times)
- AC_DEFINE(CORRECT_USING_TIMES,[],
- [Define if you do not have a high-res. timer & want to use times() instead])
- ;;
- clock_gettime|cross)
- if test $erl_cv_time_correction = cross; then
- erl_cv_time_correction=clock_gettime
- AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
- fi
- xrtlib="-lrt"
- AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
- [Define if you want to use clock_gettime to simulate gethrtime])
- ;;
-esac
-dnl
-dnl Check if gethrvtime is working, and if to use procfs ioctl
-dnl or (yet to be written) write to the procfs ctl file.
-dnl
-
-AC_MSG_CHECKING([if gethrvtime works and how to use it])
-AC_TRY_RUN([
-/* gethrvtime procfs ioctl test */
-/* These need to be undef:ed to not break activation of
- * micro level process accounting on /proc/self
- */
-#ifdef _LARGEFILE_SOURCE
-# undef _LARGEFILE_SOURCE
-#endif
-#ifdef _FILE_OFFSET_BITS
-# undef _FILE_OFFSET_BITS
-#endif
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/signal.h>
-#include <sys/fault.h>
-#include <sys/syscall.h>
-#include <sys/procfs.h>
-#include <fcntl.h>
-
-int main() {
- long msacct = PR_MSACCT;
- int fd;
- long long start, stop;
- int i;
- pid_t pid = getpid();
- char proc_self[30] = "/proc/";
-
- sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid);
- if ( (fd = open(proc_self, O_WRONLY)) == -1)
- exit(1);
- if (ioctl(fd, PIOCSET, &msacct) < 0)
- exit(2);
- if (close(fd) < 0)
- exit(3);
- start = gethrvtime();
- for (i = 0; i < 100; i++)
- stop = gethrvtime();
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
-}
-],
-erl_gethrvtime=procfs_ioctl,
-erl_gethrvtime=false,
-[
-case X$erl_xcomp_gethrvtime_procfs_ioctl in
- X)
- erl_gethrvtime=cross;;
- Xyes|Xno)
- if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then
- erl_gethrvtime=procfs_ioctl
- else
- erl_gethrvtime=false
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);;
-esac
-])
-
-case $erl_gethrvtime in
- procfs_ioctl)
- AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
- [define if gethrvtime() works and uses ioctl() to /proc/self])
- AC_MSG_RESULT(uses ioctl to procfs)
- ;;
- *)
- if test $erl_gethrvtime = cross; then
- erl_gethrvtime=false
- AC_MSG_RESULT(cross)
- AC_MSG_WARN([result 'not working' guessed because of cross compilation])
- else
- AC_MSG_RESULT(not working)
- fi
-
- dnl
- dnl Check if clock_gettime (linux) is working
- dnl
-
- AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time])
- save_libs=$LIBS
- LIBS="-lrt"
- AC_TRY_RUN([
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- int main() {
- long long start, stop;
- int i;
- struct timespec tp;
-
- if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0)
- exit(1);
- start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- for (i = 0; i < 100; i++)
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
- stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
- }
- ],
- erl_clock_gettime=yes,
- erl_clock_gettime=no,
- [
- case X$erl_xcomp_clock_gettime_cpu_time in
- X) erl_clock_gettime=cross;;
- Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;;
- *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);;
- esac
- ])
- LIBS=$save_libs
- case $host_os in
- linux*)
- AC_MSG_RESULT([no; not stable])
- LIBRT=$xrtlib
- ;;
- *)
- AC_MSG_RESULT($erl_clock_gettime)
- case $erl_clock_gettime in
- yes)
- AC_DEFINE(HAVE_CLOCK_GETTIME,[],
- [define if clock_gettime() works for getting process time])
- LIBRT=-lrt
- ;;
- cross)
- erl_clock_gettime=no
- AC_MSG_WARN([result no guessed because of cross compilation])
- LIBRT=$xrtlib
- ;;
- *)
- LIBRT=$xrtlib
- ;;
- esac
- ;;
- esac
- AC_SUBST(LIBRT)
- ;;
-esac
-])dnl
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_TRY_ENABLE_CFLAG
-dnl
-dnl
-dnl Tries a CFLAG and sees if it can be enabled without compiler errors
-dnl $1: textual cflag to add
-dnl $2: variable to store the modified CFLAG in
-dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
-dnl
-dnl
-AC_DEFUN([LM_TRY_ENABLE_CFLAG], [
- AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
- saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $$2";
- AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false)
- CFLAGS=$saved_CFLAGS;
- if test "X$can_enable_flag" = "Xtrue"; then
- AC_MSG_RESULT([yes])
- AS_VAR_SET($2, "$1 $$2")
- else
- AC_MSG_RESULT([no])
- fi
-])
-
-dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY
-dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]])
-dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a
-dnl AC_LANG_JAVA instead...)
-AC_DEFUN(ERL_TRY_LINK_JAVA,
-[java_link='$JAVAC conftest.java 1>&AC_FD_CC'
-changequote(, )dnl
-cat > conftest.java <<EOF
-$1
-class conftest { public static void main(String[] args) {
- $2
- ; return; }}
-EOF
-changequote([, ])dnl
-if AC_TRY_EVAL(java_link) && test -s conftest.class; then
- ifelse([$3], , :, [rm -rf conftest*
- $3])
-else
- echo "configure: failed program was:" 1>&AC_FD_CC
- cat conftest.java 1>&AC_FD_CC
- echo "configure: PATH was $PATH" 1>&AC_FD_CC
-ifelse([$4], , , [ rm -rf conftest*
- $4
-])dnl
-fi
-rm -f conftest*])
-#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */
-
-
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..29a9d71041 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -30,6 +30,89 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.7.20</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Use C99 function isfinite() instead of finite() when
+ available on non GCC compilers.</p>
+ <p>
+ Own Id: OTP-12268</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Distribute <c>autoconf</c> helpers to applications at
+ build time instead of having multiple identical copies
+ committed in the repository.</p>
+ <p>
+ Own Id: OTP-12348</p>
+ </item>
+ <item>
+ <p>
+ Added an .appup file for the application.</p>
+ <p>
+ Own Id: OTP-12358 Aux Id: OTP-12178 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.7.19</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Added a <c>.app</c> file for the application.</p>
+ <p>
+ Own Id: OTP-12178</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.7.18</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Implement --enable-sanitizers[=sanitizers]. Similar to
+ debugging with Valgrind, it's very useful to enable
+ -fsanitize= switches to catch bugs at runtime.</p>
+ <p>
+ Own Id: OTP-12153</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/ebin/.gitignore b/lib/erl_interface/ebin/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/erl_interface/ebin/.gitignore
diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in
index e36b39c1fb..7c09b605fa 100644
--- a/lib/erl_interface/src/Makefile.in
+++ b/lib/erl_interface/src/Makefile.in
@@ -40,6 +40,16 @@ include $(TARGET)/eidefs.mk
include $(ERL_TOP)/make/output.mk
+EBINDIR=../ebin
+
+APP_FILE= erl_interface.app
+APP_SRC= $(APP_FILE).src
+APP_TARGET= $(EBINDIR)/$(APP_FILE)
+
+APPUP_FILE= erl_interface.appup
+APPUP_SRC= $(APPUP_FILE).src
+APPUP_TARGET= $(EBINDIR)/$(APPUP_FILE)
+
USING_MINGW=@MIXED_CYGWIN_MINGW@
USING_MSYS_VC==@MIXED_MSYS_VC@
USING_CYGWIN_VC==@MIXED_MSYS_VC@
@@ -212,7 +222,9 @@ ifeq ($(USING_VC),yes)
TARGETS = \
$(OBJ_TARGETS) \
- $(EXE_TARGETS)
+ $(EXE_TARGETS) \
+ $(APP_TARGET) \
+ $(APPUP_TARGET)
OBJ_TARGETS = \
$(MT_EILIB) \
@@ -241,7 +253,9 @@ else
ifeq ($USING_MINGW,yes)
TARGETS = \
$(OBJ_TARGETS) \
- $(EXE_TARGETS)
+ $(EXE_TARGETS) \
+ $(APP_TARGET) \
+ $(APPUP_TARGET)
OBJ_TARGETS = \
$(MD_EILIB) \
@@ -259,7 +273,9 @@ ifdef THR_DEFS
TARGETS = \
$(OBJ_TARGETS) \
- $(EXE_TARGETS)
+ $(EXE_TARGETS) \
+ $(APP_TARGET) \
+ $(APPUP_TARGET)
OBJ_TARGETS = \
$(ST_EILIB) \
@@ -281,7 +297,9 @@ else
TARGETS = \
$(OBJ_TARGETS) \
- $(EXE_TARGETS)
+ $(EXE_TARGETS) \
+ $(APP_TARGET) \
+ $(APPUP_TARGET)
OBJ_TARGETS = \
$(ST_EILIB) \
@@ -547,6 +565,8 @@ clean:
rm -f $(MDD_EIOBJECTS) $(MDD_ERLOBJECTS) $(MDD_EILIB) $(MDD_ERLLIB)
rm -f $(ERL_CALL)
rm -f $(FAKE_TARGETS)
+ rm -f $(APP_TARGET)
+ rm -f $(APPUP_TARGET)
distclean: clean
rm -f config.h config.log config.status configure
@@ -597,12 +617,17 @@ $(MDD_OBJDIR)/%.o: %.c
# Create directories
###########################################################################
-_create_dirs := $(shell mkdir -p $(BINDIR) $(OBJDIR) $(ST_OBJDIR) $(MT_OBJDIR) $(MD_OBJDIR) $(MDD_OBJDIR))
+_create_dirs := $(shell mkdir -p $(EBINDIR) $(BINDIR) $(OBJDIR) $(ST_OBJDIR) $(MT_OBJDIR) $(MD_OBJDIR) $(MDD_OBJDIR))
###########################################################################
# Special rules
###########################################################################
+$(APP_TARGET): $(APP_SRC) ../vsn.mk
+ $(vsn_verbose)sed -e 's;%VSN%;$(ERL_INTERFACE_VSN);' $< > $@
+$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
+ $(vsn_verbose)sed -e 's;%VSN%;$(ERL_INTERFACE_VSN);' $< > $@
+
ifeq ($(TARGET),win32)
# Windows archive creation
@@ -857,6 +882,7 @@ release: opt
$(INSTALL_DIR) "$(RELSYSDIR)/include"
$(INSTALL_DIR) "$(RELSYSDIR)/lib"
$(INSTALL_DIR) "$(RELSYSDIR)/bin"
+ $(INSTALL_DIR) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/src/auxdir"
$(INSTALL_DIR) "$(RELSYSDIR)/src/connect"
$(INSTALL_DIR) "$(RELSYSDIR)/src/decode"
@@ -868,6 +894,8 @@ release: opt
$(INSTALL_DIR) "$(RELSYSDIR)/src/registry"
$(INSTALL_DIR) "$(RELEASE_PATH)/usr/include"
$(INSTALL_DIR) "$(RELEASE_PATH)/usr/lib"
+ $(INSTALL_DATA) $(APP_TARGET) "$(RELSYSDIR)/ebin/$(APP_FILE)"
+ $(INSTALL_DATA) $(APPUP_TARGET) "$(RELSYSDIR)/ebin/$(APPUP_FILE)"
$(INSTALL_DATA) $(HEADERS) "$(RELSYSDIR)/include"
$(INSTALL_DATA) $(HEADERS) "$(RELEASE_PATH)/usr/include"
$(INSTALL_DATA) $(OBJ_TARGETS) "$(RELSYSDIR)/lib"
diff --git a/lib/erl_interface/src/auxdir/config.guess b/lib/erl_interface/src/auxdir/config.guess
deleted file mode 100755
index f475ceb413..0000000000
--- a/lib/erl_interface/src/auxdir/config.guess
+++ /dev/null
@@ -1,1534 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-#
-# Originally written by Per Bothner.
-#
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-#
-# Please send patches with a ChangeLog entry to [email protected].
-
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# ([email protected] 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:Bitrig:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # [email protected] (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH="x86_64"
- fi
- fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[4567])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep -q __LP64__
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- aarch64_be:Linux:*:*)
- UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_PCS_VFP
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
- fi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- or32:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
- # Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
- # this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- OS_REL='.3'
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <[email protected]>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
- x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
- exit ;;
-esac
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <[email protected]> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/lib/erl_interface/src/auxdir/config.sub b/lib/erl_interface/src/auxdir/config.sub
deleted file mode 100755
index bb6edbdb47..0000000000
--- a/lib/erl_interface/src/auxdir/config.sub
+++ /dev/null
@@ -1,1789 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-
-
-# Please send patches with a ChangeLog entry to [email protected].
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | be32 | be64 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 \
- | or1k | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pyramid \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | we32k \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
- ;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- xscaleeb)
- basic_machine=armeb-unknown
- ;;
-
- xscaleel)
- basic_machine=armel-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pyramid-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i386-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
- ;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -dicos*)
- os=-dicos
- ;;
- -nacl*)
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- hexagon-*)
- os=-elf
- ;;
- tic54x-*)
- os=-coff
- ;;
- tic55x-*)
- os=-coff
- ;;
- tic6x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or1k-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -cnk*|-aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
-
diff --git a/lib/erl_interface/src/auxdir/install-sh b/lib/erl_interface/src/auxdir/install-sh
deleted file mode 100755
index a5897de6ea..0000000000
--- a/lib/erl_interface/src/auxdir/install-sh
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
- --help display this help and exit.
- --version display version info and exit.
-
- -c (ignored)
- -C install only if different (preserve the last data modification time)
- -d create directories instead of installing files.
- -g GROUP $chgrpprog installed files to GROUP.
- -m MODE $chmodprog installed files to MODE.
- -o USER $chownprog installed files to USER.
- -s $stripprog installed files.
- -t DIRECTORY install into DIRECTORY.
- -T report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
- RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) ;;
-
- -C) copy_on_change=true;;
-
- -d) dir_arg=true;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
-
- -o) chowncmd="$chownprog $2"
- shift;;
-
- -s) stripcmd=$stripprog;;
-
- -t) dst_arg=$2
- shift;;
-
- -T) no_target_directory=true;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
- shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dst_arg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dst_arg"
- shift # fnord
- fi
- shift # arg
- dst_arg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dst_arg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix='/';;
- -*) prefix='./';;
- *) prefix='';;
- esac
-
- eval "$initialize_posix_glob"
-
- oIFS=$IFS
- IFS=/
- $posix_glob set -f
- set fnord $dstdir
- shift
- $posix_glob set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # If -C, don't bother to copy if it wouldn't change the file.
- if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
- set X $old && old=:$2:$4:$5:$6 &&
- set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
- test "$old" = "$new" &&
- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
- then
- rm -f "$dsttmp"
- else
- # Rename the file to the real destination.
- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
- {
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- fi || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 2e8418d61e..45c000ef76 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -761,7 +761,7 @@ int ei_close_connection(int fd)
#endif
/*
- * Accept and initiate a connection from an other
+ * Accept and initiate a connection from another
* Erlang node. Return a file descriptor at success,
* otherwise -1;
*/
diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c
index b54ac85be2..477880b331 100644
--- a/lib/erl_interface/src/decode/decode_big.c
+++ b/lib/erl_interface/src/decode/decode_big.c
@@ -151,13 +151,29 @@ int ei_big_comp(erlang_big *x, erlang_big *y)
#endif
#ifdef USE_ISINF_ISNAN /* simulate finite() */
-# define finite(f) (!isinf(f) && !isnan(f))
-# define HAVE_FINITE
+# define isfinite(f) (!isinf(f) && !isnan(f))
+# define HAVE_ISFINITE
+#elif defined(__GNUC__) && defined(HAVE_FINITE)
+/* We use finite in gcc as it emits assembler instead of
+ the function call that isfinite emits. The assembler is
+ significantly faster. */
+# ifdef isfinite
+# undef isfinite
+# endif
+# define isfinite finite
+# ifndef HAVE_ISFINITE
+# define HAVE_ISFINITE
+# endif
+#elif defined(isfinite) && !defined(HAVE_ISFINITE)
+# define HAVE_ISFINITE
+#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE)
+# define isfinite finite
+# define HAVE_ISFINITE
#endif
#ifdef NO_FPE_SIGNALS
# define ERTS_FP_CHECK_INIT() do {} while (0)
-# define ERTS_FP_ERROR(f, Action) if (!finite(f)) { Action; } else {}
+# define ERTS_FP_ERROR(f, Action) if (!isfinite(f)) { Action; } else {}
# define ERTS_SAVE_FP_EXCEPTION()
# define ERTS_RESTORE_FP_EXCEPTION()
#else
diff --git a/lib/erl_interface/src/erl_interface.app.src b/lib/erl_interface/src/erl_interface.app.src
new file mode 100644
index 0000000000..11f884c36b
--- /dev/null
+++ b/lib/erl_interface/src/erl_interface.app.src
@@ -0,0 +1,32 @@
+%%
+%% %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%
+%%
+%% This is an -*- erlang -*- file.
+%%
+
+{application, erl_interface,
+ [
+ {description, "Erl Interface"},
+ {vsn, "%VSN%"},
+ {modules, []},
+ {registered, []},
+ {applications, []},
+ {env, []},
+ {runtime_dependencies, []}
+ ]
+}.
diff --git a/lib/kernel/test/code_SUITE_data/calendar.erl b/lib/erl_interface/src/erl_interface.appup.src
index c1a4a1c12a..d267e3d3d5 100644
--- a/lib/kernel/test/code_SUITE_data/calendar.erl
+++ b/lib/erl_interface/src/erl_interface.appup.src
@@ -1,7 +1,7 @@
-%%
+%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% 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
@@ -15,9 +15,4 @@
%% under the License.
%%
%% %CopyrightEnd%
-%%
--module(calendar).
--export([test/1]).
-
-test(apa) ->
- {error, this_function_should_not_be_called}.
+{"%VSN%", [], []}.
diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c
index ae0265a388..d70d914b79 100644
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ b/lib/erl_interface/src/legacy/erl_connect.c
@@ -190,7 +190,7 @@ int erl_close_connection(int fd)
}
/*
- * Accept and initiate a connection from an other
+ * Accept and initiate a connection from another
* Erlang node. Return a file descriptor at success,
* otherwise -1;
*/
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index 8731283265..c809d5421e 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.20
ERL_INTERFACE_VSN = $(EI_VSN)
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index 72ffda3cd5..6b76e097b6 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -32,6 +32,43 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
+<section><title>Eunit 2.2.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure to install .hrl files when needed</p>
+ <p>
+ Own Id: OTP-12197</p>
+ </item>
+ <item>
+ <p>
+ Make sure the clean rule for ssh, ssl, eunit and otp_mibs
+ actually removes generated files.</p>
+ <p>
+ Own Id: OTP-12200</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eunit 2.2.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Minor refactoring.</p>
+ <p>
+ Own Id: OTP-12051</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eunit 2.2.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/eunit/src/Makefile b/lib/eunit/src/Makefile
index e6dab67363..47aef104ff 100644
--- a/lib/eunit/src/Makefile
+++ b/lib/eunit/src/Makefile
@@ -46,6 +46,8 @@ SOURCES= \
INCLUDE_FILES = eunit.hrl
+INTERNAL_HRL_FILES= eunit_internal.hrl
+
PARSE_TRANSFORM_BIN = $(PARSE_TRANSFORM:%.erl=$(EBIN)/%.$(EMULATOR))
TARGET_FILES= $(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR))
@@ -78,7 +80,7 @@ all: $(OBJECTS)
clean:
- rm -f $(OBJECTS)
+ rm -f $(OBJECTS) $(PARSE_TRANSFORM_BIN)
rm -f core *~
distclean: clean
@@ -119,6 +121,7 @@ release_spec: opt
$(INSTALL_DATA) $(PARSE_TRANSFORM_BIN) $(OBJECTS) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/src"
$(INSTALL_DATA) $(PARSE_TRANSFORM) $(SOURCES) "$(RELSYSDIR)/src"
+ $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src"
$(INSTALL_DIR) "$(RELSYSDIR)/include"
$(INSTALL_DATA) $(INCLUDE_DELIVERABLES) "$(RELSYSDIR)/include"
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/eunit/vsn.mk b/lib/eunit/vsn.mk
index f04c0536fe..dca8b3ece0 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.2.7
+EUNIT_VSN = 2.2.9
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_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index a460f16272..74e93bf098 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -2,7 +2,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
@@ -1891,7 +1891,11 @@ infinity_add(neg_inf, _Number) -> neg_inf;
infinity_add(_Number, pos_inf) -> pos_inf;
infinity_add(_Number, neg_inf) -> neg_inf;
infinity_add(Number1, Number2) when is_integer(Number1), is_integer(Number2) ->
- Number1 + Number2.
+ try Number1 + Number2
+ catch
+ error:system_limit when Number1 < 0 -> neg_inf;
+ error:system_limit -> pos_inf
+ end.
infinity_mult(neg_inf, Number) ->
Greater = infinity_geq(Number, 0),
@@ -1902,7 +1906,13 @@ infinity_mult(pos_inf, Number) -> infinity_inv(infinity_mult(neg_inf, Number));
infinity_mult(Number, pos_inf) -> infinity_inv(infinity_mult(neg_inf, Number));
infinity_mult(Number, neg_inf) -> infinity_mult(neg_inf, Number);
infinity_mult(Number1, Number2) when is_integer(Number1), is_integer(Number2)->
- Number1 * Number2.
+ try Number1 * Number2
+ catch
+ error:system_limit ->
+ if (Number1 >= 0) =:= (Number2 >= 0) -> pos_inf;
+ true -> neg_inf
+ end
+ end.
width({Min, Max}) -> infinity_max([width(Min), width(Max)]);
width(pos_inf) -> pos_inf;
@@ -2633,7 +2643,9 @@ opaque_args(M, F, A, Xs, Opaques) ->
true ->
case t_tuple_subtypes(X, Opaques) of
unknown -> false;
- List when length(List) >= 1 -> opaque_recargs(List, Y, Opaques)
+ List when length(List) >= 1 ->
+ (t_is_atom(Y, Opaques) andalso
+ opaque_recargs(List, Y, Opaques))
end;
false -> t_has_opaque_subtype(X, Opaques)
end];
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 67661130a5..4215448c61 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2015. 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
@@ -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,
@@ -262,6 +262,8 @@
-define(TAG_IMMED1_SIZE, 4).
-define(BITS, (erlang:system_info(wordsize) * 8) - ?TAG_IMMED1_SIZE).
+-define(MAX_TUPLE_SIZE, (1 bsl 10)).
+
%%-----------------------------------------------------------------------------
%% Type tags and qualifiers
%%
@@ -530,39 +532,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 +1437,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;
@@ -1759,6 +1772,8 @@ t_tuple() ->
-spec t_tuple(non_neg_integer() | [erl_type()]) -> erl_type().
+t_tuple(N) when is_integer(N), N > ?MAX_TUPLE_SIZE ->
+ t_tuple();
t_tuple(N) when is_integer(N) ->
?tuple(lists:duplicate(N, ?any), N, ?any);
t_tuple(List) ->
@@ -4215,7 +4230,7 @@ t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) ->
t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) ->
{t_arity(), []};
t_from_form({type, _L, array, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(array, t_array(), TypeNames, RecDict, VarDict);
+ builtin_type(array, t_array(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) ->
{t_atom(), []};
t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) ->
@@ -4238,9 +4253,9 @@ t_from_form({type, _L, byte, []}, _TypeNames, _RecDict, _VarDict) ->
t_from_form({type, _L, char, []}, _TypeNames, _RecDict, _VarDict) ->
{t_char(), []};
t_from_form({type, _L, dict, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(dict, t_dict(), TypeNames, RecDict, VarDict);
+ builtin_type(dict, t_dict(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, digraph, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(digraph, t_digraph(), TypeNames, RecDict, VarDict);
+ builtin_type(digraph, t_digraph(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, float, []}, _TypeNames, _RecDict, _VarDict) ->
{t_float(), []};
t_from_form({type, _L, function, []}, _TypeNames, _RecDict, _VarDict) ->
@@ -4257,9 +4272,9 @@ t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
{T, R2} = t_from_form(Range, TypeNames, RecDict, VarDict),
{t_fun(L, T), R1 ++ R2};
t_from_form({type, _L, gb_set, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(gb_set, t_gb_set(), TypeNames, RecDict, VarDict);
+ builtin_type(gb_set, t_gb_set(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, gb_tree, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(gb_tree, t_gb_tree(), TypeNames, RecDict, VarDict);
+ builtin_type(gb_tree, t_gb_tree(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, identifier, []}, _TypeNames, _RecDict, _VarDict) ->
{t_identifier(), []};
t_from_form({type, _L, integer, []}, _TypeNames, _RecDict, _VarDict) ->
@@ -4273,8 +4288,12 @@ t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) ->
t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) ->
{T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
{t_list(T), R};
-t_from_form({type, _L, map, _}, TypeNames, RecDict, VarDict) ->
- builtin_type(map, t_map([]), TypeNames, RecDict, VarDict);
+t_from_form({type, _L, map, As0}, TypeNames, RecDict, VarDict) ->
+ As = case is_list(As0) of
+ true -> As0;
+ false -> []
+ end,
+ builtin_type(map, t_map([]), As, TypeNames, RecDict, VarDict);
t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) ->
{t_mfa(), []};
t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) ->
@@ -4333,7 +4352,7 @@ t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) ->
{L, R} = list_from_form(Elements, TypeNames, RecDict, VarDict),
{t_product(L), R};
t_from_form({type, _L, queue, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(queue, t_queue(), TypeNames, RecDict, VarDict);
+ builtin_type(queue, t_queue(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, range, [From, To]} = Type,
_TypeNames, _RecDict, _VarDict) ->
case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
@@ -4346,13 +4365,13 @@ t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) ->
t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) ->
{t_reference(), []};
t_from_form({type, _L, set, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(set, t_set(), TypeNames, RecDict, VarDict);
+ builtin_type(set, t_set(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, string, []}, _TypeNames, _RecDict, _VarDict) ->
{t_string(), []};
t_from_form({type, _L, term, []}, _TypeNames, _RecDict, _VarDict) ->
{t_any(), []};
t_from_form({type, _L, tid, []}, TypeNames, RecDict, VarDict) ->
- builtin_type(tid, t_tid(), TypeNames, RecDict, VarDict);
+ builtin_type(tid, t_tid(), [], TypeNames, RecDict, VarDict);
t_from_form({type, _L, timeout, []}, _TypeNames, _RecDict, _VarDict) ->
{t_timeout(), []};
t_from_form({type, _L, tuple, any}, _TypeNames, _RecDict, _VarDict) ->
@@ -4369,10 +4388,10 @@ t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames,
_RecDict, _VarDict) ->
{t_opaque(Mod, Name, Args, Rep), []}.
-builtin_type(Name, Type, TypeNames, RecDict, VarDict) ->
- case lookup_type(Name, 0, RecDict) of
+builtin_type(Name, Type, Args, TypeNames, RecDict, VarDict) ->
+ case lookup_type(Name, length(Args), RecDict) of
{_, {_M, _T, _A}} ->
- type_from_form(Name, [], TypeNames, RecDict, VarDict);
+ type_from_form(Name, Args, TypeNames, RecDict, VarDict);
error ->
{Type, []}
end.
@@ -4573,7 +4592,7 @@ t_form_to_string({type, _L, iodata, []}) -> "iodata()";
t_form_to_string({type, _L, iolist, []}) -> "iolist()";
t_form_to_string({type, _L, list, [Type]}) ->
"[" ++ t_form_to_string(Type) ++ "]";
-t_form_to_string({type, _L, map, _}) ->
+t_form_to_string({type, _L, map, Args}) when not is_list(Args) ->
"#{}";
t_form_to_string({type, _L, mfa, []}) -> "mfa()";
t_form_to_string({type, _L, module, []}) -> "module()";
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index c7faf733c7..2d6fd245f7 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -30,6 +30,73 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.11.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed internal elf_format hrl file to contain valid
+ erlang</p>
+ <p>
+ Own Id: OTP-12322</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.11.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The pretty-printing of bitstrings has been corrected.
+ </p>
+ <p>
+ Own Id: OTP-12015</p>
+ </item>
+ <item>
+ <p> A bug concerning <c>is_record/2,3</c> has been fixed,
+ as well as some cases where Dialyzer could crash due to
+ reaching system limits. </p>
+ <p>
+ Own Id: OTP-12018</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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 +185,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/llvm/elf_format.hrl b/lib/hipe/llvm/elf_format.hrl
index 78592e6e2a..7a3cdfead6 100644
--- a/lib/hipe/llvm/elf_format.hrl
+++ b/lib/hipe/llvm/elf_format.hrl
@@ -68,7 +68,7 @@
-define(E_IDENT, {?E_IDENT_OFFSET, ?E_IDENT_SIZE}).
-define(E_TYPE, {?E_TYPE_OFFSET, ?E_TYPE_SIZE}).
-define(E_MACHINE, {?E_MACHINE_OFFSET, ?E_MACHINE_SIZE}).
--define(E_VERSION, {?E_VERSION_OFFSET, ?E_VERSION_SIZE})
+-define(E_VERSION, {?E_VERSION_OFFSET, ?E_VERSION_SIZE}).
-define(E_ENTRY, {?E_ENTRY_OFFSET, ?E_ENTRY_SIZE}).
-define(E_PHOFF, {?E_PHOFF_OFFSET, ?E_PHOFF_SIZE}).
-define(E_SHOFF, {?E_SHOFF_OFFSET, ?E_SHOFF_SIZE}).
diff --git a/lib/hipe/ppc/hipe_rtl_to_ppc.erl b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
index 7dfa56df29..a55fc137c3 100644
--- a/lib/hipe/ppc/hipe_rtl_to_ppc.erl
+++ b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
@@ -102,10 +102,18 @@ conv_insn(I, Map, Data) ->
end.
conv_fconv(I, Map, Data) ->
- %% Dst := (double)Src, where Dst is FP reg and Src is int reg
+ %% Dst := (double)Src, where Dst is FP reg and Src is GP reg or imm
{Dst, Map0} = conv_fpreg(hipe_rtl:fconv_dst(I), Map),
- {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0), % exclude imm src
- I2 = mk_fconv(Dst, Src),
+ {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0),
+ I2 =
+ case hipe_ppc:is_temp(Src) of
+ true ->
+ mk_fconv(Dst, Src);
+ false ->
+ Tmp = new_untagged_temp(),
+ mk_li(Tmp, Src,
+ mk_fconv(Dst, Tmp))
+ end,
{I2, Map1, Data}.
mk_fconv(Dst, Src) ->
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index bc61bec0bd..2f62dd79ad 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -413,11 +413,11 @@ rtl_info_update(Rtl, Info) -> Rtl#rtl{info=Info}.
%% move
%%
-mk_move(Dst, Src) -> #move{dst=Dst, src=Src}.
+mk_move(Dst, Src) -> false = is_fpreg(Dst), false = is_fpreg(Src), #move{dst=Dst, src=Src}.
move_dst(#move{dst=Dst}) -> Dst.
-move_dst_update(M, NewDst) -> M#move{dst=NewDst}.
+move_dst_update(M, NewDst) -> false = is_fpreg(NewDst), M#move{dst=NewDst}.
move_src(#move{src=Src}) -> Src.
-move_src_update(M, NewSrc) -> M#move{src=NewSrc}.
+move_src_update(M, NewSrc) -> false = is_fpreg(NewSrc), M#move{src=NewSrc}.
%% is_move(#move{}) -> true;
%% is_move(_) -> false.
@@ -469,7 +469,11 @@ phi_remove_pred(Phi, Pred) ->
case NewArgList of
[Arg] -> %% the phi should be turned into a move instruction
{_Label,Var} = Arg,
- mk_move(phi_dst(Phi), Var);
+ Dst = phi_dst(Phi),
+ case {is_fpreg(Dst), is_fpreg(Var)} of
+ {true, true} -> mk_fmove(Dst, Var);
+ {false, false} -> mk_move(Dst, Var)
+ end;
%% io:format("~nPhi (~w) turned into move (~w) when removing pred ~w~n",[Phi,Move,Pred]),
[_|_] ->
Phi#phi{arglist=NewArgList}
@@ -836,11 +840,11 @@ fp_unop_op(#fp_unop{op=Op}) -> Op.
%% fmove
%%
-mk_fmove(X, Y) -> #fmove{dst=X, src=Y}.
+mk_fmove(X, Y) -> true = is_fpreg(X), true = is_fpreg(Y), #fmove{dst=X, src=Y}.
fmove_dst(#fmove{dst=Dst}) -> Dst.
-fmove_dst_update(M, NewDst) -> M#fmove{dst=NewDst}.
+fmove_dst_update(M, NewDst) -> true = is_fpreg(NewDst), M#fmove{dst=NewDst}.
fmove_src(#fmove{src=Src}) -> Src.
-fmove_src_update(M, NewSrc) -> M#fmove{src=NewSrc}.
+fmove_src_update(M, NewSrc) -> true = is_fpreg(NewSrc), M#fmove{src=NewSrc}.
%%
%% fconv
diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl
index 8831199244..af8903904b 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_match.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl
@@ -990,19 +990,19 @@ unsigned_bignum(Dst1, Src, TrueLblName) ->
hipe_tagscheme:unsafe_mk_big(Dst1, Src, unsigned),
hipe_rtl:mk_goto(TrueLblName)].
-load_bytes(Dst, Base, Offset, {Signedness, _Endianess},1) ->
+load_bytes(Dst, Base, Offset, {Signedness, _Endianness},1) ->
[hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness),
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1))];
-load_bytes(Dst, Base, Offset, {Signedness, Endianess},2) ->
- case Endianess of
+load_bytes(Dst, Base, Offset, {Signedness, Endianness},2) ->
+ case Endianness of
big ->
hipe_rtl_arch:load_big_2(Dst, Base, Offset, Signedness);
little ->
hipe_rtl_arch:load_little_2(Dst, Base, Offset, Signedness)
end;
-load_bytes(Dst, Base, Offset, {Signedness, Endianess},3) ->
+load_bytes(Dst, Base, Offset, {Signedness, Endianness},3) ->
Tmp1 = hipe_rtl:mk_new_reg(),
- case Endianess of
+ case Endianness of
big ->
[hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness),
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1)),
@@ -1026,18 +1026,18 @@ load_bytes(Dst, Base, Offset, {Signedness, Endianess},3) ->
hipe_rtl:mk_alu(Dst, Dst, 'or', Tmp1),
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1))]
end;
-load_bytes(Dst, Base, Offset, {Signedness, Endianess}, 4) ->
- case Endianess of
+load_bytes(Dst, Base, Offset, {Signedness, Endianness}, 4) ->
+ case Endianness of
big ->
hipe_rtl_arch:load_big_4(Dst, Base, Offset, Signedness);
little ->
hipe_rtl_arch:load_little_4(Dst, Base, Offset, Signedness)
end;
-load_bytes(Dst, Base, Offset, {Signedness, Endianess}, X) when X > 1 ->
+load_bytes(Dst, Base, Offset, {Signedness, Endianness}, X) when X > 1 ->
[LoopLbl, EndLbl] = create_lbls(2),
[Tmp1, Limit, TmpOffset] = create_regs(3),
- case Endianess of
+ case Endianness of
big ->
[hipe_rtl:mk_alu(Limit, Offset, add, hipe_rtl:mk_imm(X)),
hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness),
diff --git a/lib/hipe/sparc/hipe_rtl_to_sparc.erl b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
index dc001f865e..fd21be3ae7 100644
--- a/lib/hipe/sparc/hipe_rtl_to_sparc.erl
+++ b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
@@ -85,17 +85,17 @@ conv_insn(I, Map, Data) ->
end.
conv_fconv(I, Map, Data) ->
- %% Dst := (double)Src, where Dst is FP reg and Src is int reg
- {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map), % exclude imm src
+ %% Dst := (double)Src, where Dst is FP reg and Src is GP reg or imm
+ {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map),
{Dst, Map2} = conv_fpreg(hipe_rtl:fconv_dst(I), Map1),
I2 = mk_fconv(Src, Dst),
{I2, Map2, Data}.
mk_fconv(Src, Dst) ->
CSP = hipe_sparc:mk_temp(14, 'untagged'), % o6
- Disp = hipe_sparc:mk_simm13(100),
- [hipe_sparc:mk_store('stw', Src, CSP, Disp),
- hipe_sparc:mk_pseudo_fload(CSP, Disp, Dst, true),
+ Offset = 100,
+ mk_store('stw', Src, CSP, Offset) ++
+ [hipe_sparc:mk_pseudo_fload(CSP, hipe_sparc:mk_simm13(Offset), Dst, true),
hipe_sparc:mk_fp_unary('fitod', Dst, Dst)].
conv_fmove(I, Map, Data) ->
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index fb7e4b91a0..4cf09830cb 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.10.3
+HIPE_VSN = 3.11.2
diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl
index d77e4fed3b..36da2f4d44 100644
--- a/lib/hipe/x86/hipe_rtl_to_x86.erl
+++ b/lib/hipe/x86/hipe_rtl_to_x86.erl
@@ -236,7 +236,7 @@ conv_insn(I, Map, Data) ->
#fconv{} ->
{Dst, Map0} = conv_dst(hipe_rtl:fconv_dst(I), Map),
{[], Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0),
- I2 = [hipe_x86:mk_fmove(Src, Dst)],
+ I2 = conv_fconv(Dst, Src),
{I2, Map1, Data};
X ->
%% gctest??
@@ -712,6 +712,19 @@ vmap_lookup(Map, Key) ->
vmap_bind(Map, Key, Val) ->
gb_trees:insert(Key, Val, Map).
+%%% Finalise the conversion of an Integer-to-Float operation.
+
+conv_fconv(Dst, Src) ->
+ case hipe_x86:is_imm(Src) of
+ false ->
+ [hipe_x86:mk_fmove(Src, Dst)];
+ true ->
+ %% cvtsi2sd does not allow src to be an immediate
+ Tmp = new_untagged_temp(),
+ [hipe_x86:mk_move(Src, Tmp),
+ hipe_x86:mk_fmove(Tmp, Dst)]
+ end.
+
%%% Finalise the conversion of a 2-address FP operation.
conv_fp_unary(Dst, Src, FpUnOp) ->
diff --git a/lib/ic/c_src/oe_ei_encode_pid.c b/lib/ic/c_src/oe_ei_encode_pid.c
index b7083f84a0..609f441cf8 100644
--- a/lib/ic/c_src/oe_ei_encode_pid.c
+++ b/lib/ic/c_src/oe_ei_encode_pid.c
@@ -23,7 +23,7 @@
int oe_ei_encode_pid(CORBA_Environment *ev, const erlang_pid *p) {
int size = ev->_iout;
- (int) ei_encode_pid(NULL, &size, p);
+ ei_encode_pid(NULL, &size, p);
if (size >= ev->_outbufsz) {
char *buf = ev->_outbuf;
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index 03af316f75..bacac09f11 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -30,7 +30,22 @@
<file>notes.xml</file>
</header>
- <section><title>IC 4.3.5</title>
+ <section><title>IC 4.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix compiler warnings reported by LLVM</p>
+ <p>
+ Own Id: OTP-12138</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>IC 4.3.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index 2ffbbad444..bb273c7b57 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1 +1 @@
-IC_VSN = 4.3.5
+IC_VSN = 4.3.6
diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml
index e64c375bba..acbd79b201 100644
--- a/lib/inets/doc/src/http_uri.xml
+++ b/lib/inets/doc/src/http_uri.xml
@@ -63,6 +63,7 @@ host() = string()
port() = pos_integer()
path() = string() - Representing a file path or directory path
query() = string()
+fragment() = string()
]]></code>
<marker id="scheme_defaults"></marker>
@@ -92,13 +93,16 @@ query() = string()
<v>URI = uri() </v>
<v>Options = [Option] </v>
<v>Option = {ipv6_host_with_brackets, boolean()} |
- {scheme_defaults, scheme_defaults()}]</v>
- <v>Result = {Scheme, UserInfo, Host, Port, Path, Query}</v>
+ {scheme_defaults, scheme_defaults()} |
+ {fragment, boolean()}]</v>
+ <v>Result = {Scheme, UserInfo, Host, Port, Path, Query} |
+ {Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v>
<v>UserInfo = user_info()</v>
<v>Host = host()</v>
<v>Port = pos_integer()</v>
<v>Path = path()</v>
<v>Query = query()</v>
+ <v>Fragment = fragment()</v>
<v>Reason = term() </v>
</type>
<desc>
@@ -111,6 +115,9 @@ query() = string()
a scheme not found in the scheme defaults) a port number must be
provided or else the parsing will fail. </p>
+ <p>If the fragment option is true, the URI fragment will be returned as
+ part of the parsing result, otherwise it is completely ignored.</p>
+
<marker id="encode"></marker>
</desc>
</func>
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index 37eb7ba718..4178cb7d4c 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -302,7 +302,7 @@ filename() = string()
will be sent to that process: <c>{http, {RequestId,
stream_start, Headers}}, {http, {RequestId, stream,
BinBodyPart}}, {http, {RequestId, stream_end, Headers}}</c>. When
- streaming to to the calling processes using the option
+ streaming to the calling processes using the option
<c>{self, once}</c> the first message will have an additional
element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}}</c>,
this is the process id that should be used as an argument to
@@ -332,7 +332,7 @@ filename() = string()
<p>Defaults to <c>true</c>. </p>
</item>
- <tag><c><![CDATA[header_as_is]]></c></tag>
+ <tag><c><![CDATA[headers_as_is]]></c></tag>
<item>
<p>Shall the headers provided by the user be made
lower case or be regarded as case sensitive. </p>
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 3830b2e5ab..20c8a6b1b1 100644
--- a/lib/inets/doc/src/httpd.xml
+++ b/lib/inets/doc/src/httpd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -139,7 +139,7 @@
<marker id="prop_server_root"></marker>
<tag>{server_root, path()} </tag>
<item>
- <p>Defines the servers home directory where log files etc can
+ <p>Defines the server's home directory where log files etc can
be stored. Relative paths specified in other properties refer
to this directory. </p>
</item>
@@ -249,7 +249,16 @@
<p>Limits the size of the message header of HTTP request.
Defaults to 10240. </p>
</item>
-
+
+ <marker id="prop_max_content_length"></marker>
+ <tag>{max_content_length, integer()}</tag>
+ <item>
+ <p>Maximum Content-Length in an incoming request, in bytes. Requests
+ with content larger than this are answered with Status 413.
+ Defaults to 100000000 (100 MB).
+ </p>
+ </item>
+
<marker id="prop_max_uri"></marker>
<tag>{max_uri_size, integer()}</tag>
<item>
@@ -904,7 +913,7 @@ bytes
<p>Fetches information about the HTTP server. When called
with only the pid all properties are fetched, when called
with a list of specific properties they are fetched.
- Available properties are the same as the servers start options.
+ Available properties are the same as the server's start options.
</p>
<note><p>Pid is the pid returned from inets:start/[2,3].
@@ -930,7 +939,7 @@ bytes
<p>Fetches information about the HTTP server. When called with
only the Address and Port all properties are fetched, when
called with a list of specific properties they are fetched.
- Available properties are the same as the servers start
+ Available properties are the same as the server's start
options.
</p>
@@ -956,7 +965,7 @@ bytes
server. Incoming requests will be answered with a temporary
down message during the time the it takes to reload.</p>
- <note><p>Available properties are the same as the servers
+ <note><p>Available properties are the same as the server's
start options, although the properties bind_address and
port can not be changed.</p></note>
@@ -1068,7 +1077,7 @@ bytes
<type>
<v>OldData = list()</v>
<v>NewData = [{response,{StatusCode,Body}}] | [{response,{response,Head,Body}}] | [{response,{already_sent,Statuscode,Size}}] </v>
- <v>StausCode = integer()</v>
+ <v>StatusCode = integer()</v>
<v>Body = io_list() | nobody | {Fun, Arg}</v>
<v>Head = [HeaderOption]</v>
<v>HeaderOption = {Option, Value} | {code, StatusCode}</v>
diff --git a/lib/inets/doc/src/httpd_conf.xml b/lib/inets/doc/src/httpd_conf.xml
index 3ef03966a7..60fc2f135e 100644
--- a/lib/inets/doc/src/httpd_conf.xml
+++ b/lib/inets/doc/src/httpd_conf.xml
@@ -97,7 +97,7 @@
<v>FilePath = string()</v>
<v>Result = {ok,Directory} | {error,Reason}</v>
<v>Directory = string()</v>
- <v>Reason = string() | enoent | eaccess | enotdir | FileInfo</v>
+ <v>Reason = string() | enoent | eacces | enotdir | FileInfo</v>
<v>FileInfo = File info record</v>
</type>
<desc>
@@ -105,7 +105,7 @@
<p><c>is_directory/1</c> checks if <c>FilePath</c> is a
directory in which case it is returned. Please read
<c>file(3)</c> for a description of <c>enoent</c>,
- <c>eaccess</c> and <c>enotdir</c>. The definition of
+ <c>eacces</c> and <c>enotdir</c>. The definition of
the file info record can be found by including <c>file.hrl</c>
from the kernel application, see file(3).</p>
@@ -120,14 +120,14 @@
<v>FilePath = string()</v>
<v>Result = {ok,File} | {error,Reason}</v>
<v>File = string()</v>
- <v>Reason = string() | enoent | eaccess | enotdir | FileInfo</v>
+ <v>Reason = string() | enoent | eacces | enotdir | FileInfo</v>
<v>FileInfo = File info record</v>
</type>
<desc>
<marker id="is_file"></marker>
<p><c>is_file/1</c> checks if <c>FilePath</c> is a regular
file in which case it is returned. Read <c>file(3)</c> for a
- description of <c>enoent</c>, <c>eaccess</c> and
+ description of <c>enoent</c>, <c>eacces</c> and
<c>enotdir</c>. The definition of the file info record can be
found by including <c>file.hrl</c> from the kernel application,
see file(3).</p>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 596c0d77f4..7f73aa5e7b 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,7 +32,136 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 5.10.1</title>
+ <section><title>Inets 5.10.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ mod_alias now handles https-URIs properly</p>
+ <p>
+ Consistent view of configuration parameter
+ keep_alive_timeout, should be presented in the
+ httpd:info/[1,2] function in the same unit as it is
+ inputted.</p>
+ <p>
+ Own Id: OTP-12436 Aux Id: seq12786 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Gracefully handle invalid content-lenght headers instead
+ of crashing in list_to_integer.</p>
+ <p>
+ Own Id: OTP-12429</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 5.10.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a spelling mistake in httpc documentation.</p>
+ <p>
+ Own Id: OTP-12221</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add option {ftp_extension, boolean} to enable use of
+ extended commands EPSV and EPRT, as specified in RFC
+ 2428, for IPv4 instead of using the legacy commands. Ipv6
+ can not be supported without the extended commands.</p>
+ <p>
+ Own Id: OTP-12255</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 5.10.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix some spelling mistakes in documentation</p>
+ <p>
+ Own Id: OTP-12152</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ httpd: Seperate timeout for TLS/SSL handshake from
+ keepalive timeout</p>
+ <p>
+ Own Id: OTP-12013</p>
+ </item>
+ <item>
+ <p>
+ Warning: this is experimental and may disappear or change
+ without previous warning.</p>
+ <p>
+ Experimental support for running Quickcheck and PropEr
+ tests from common_test suites is added to common_test.
+ See the reference manual for the new module
+ <c>ct_property_testing</c>.</p>
+ <p>
+ Experimental property tests are added under
+ <c>lib/{inet,ssh}/test/property_test</c>. They can be run
+ directly or from the commont_test suites
+ <c>inet/ftp_property_test_SUITE.erl</c> and
+ <c>ssh/test/ssh_property_test_SUITE.erl</c>.</p>
+ <p>
+ See the code in the <c>test</c> directories and the man
+ page for details.</p>
+ <p>
+ (Thanks to Tuncer Ayaz for a patch adding Triq)</p>
+ <p>
+ Own Id: OTP-12119</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/examples/httpd_load_test/hdlt_slave.erl b/lib/inets/examples/httpd_load_test/hdlt_slave.erl
index 52af9b5b90..41361418bc 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_slave.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_slave.erl
@@ -180,7 +180,7 @@ ssh_slave_start(Host, ErlCmd) ->
?DEBUG("ssh_exec_erl -> done", []),
{ok, Connection, Channel};
Error3 ->
- ?LOG("failed exec comand: ~p", [Error3]),
+ ?LOG("failed exec command: ~p", [Error3]),
throw({error, {ssh_exec_failed, Error3}})
end.
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index 5674599ac5..8e51b1be5a 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -60,6 +60,7 @@
-define(DATA_ACCEPT_TIMEOUT, infinity).
-define(DEFAULT_MODE, passive).
-define(PROGRESS_DEFAULT, ignore).
+-define(FTP_EXT_DEFAULT, false).
%% Internal Constants
-define(FTP_PORT, 21).
@@ -94,7 +95,8 @@
ipfamily, % inet | inet6 | inet6fb4
progress = ignore, % ignore | pid()
dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity
- tls_upgrading_data_connection = false
+ tls_upgrading_data_connection = false,
+ ftp_extension = ?FTP_EXT_DEFAULT
}).
@@ -969,6 +971,8 @@ start_options(Options) ->
%% timeout
%% dtimeout
%% progress
+%% ftp_extension
+
open_options(Options) ->
?fcrt("open_options", [{options, Options}]),
ValidateMode =
@@ -1013,6 +1017,11 @@ open_options(Options) ->
(_) ->
false
end,
+ ValidateFtpExtension =
+ fun(true) -> true;
+ (false) -> true;
+ (_) -> false
+ end,
ValidOptions =
[{mode, ValidateMode, false, ?DEFAULT_MODE},
{host, ValidateHost, true, ehost},
@@ -1020,7 +1029,8 @@ open_options(Options) ->
{ipfamily, ValidateIpFamily, false, inet},
{timeout, ValidateTimeout, false, ?CONNECTION_TIMEOUT},
{dtimeout, ValidateDTimeout, false, ?DATA_ACCEPT_TIMEOUT},
- {progress, ValidateProgress, false, ?PROGRESS_DEFAULT}],
+ {progress, ValidateProgress, false, ?PROGRESS_DEFAULT},
+ {ftp_extension, ValidateFtpExtension, false, ?FTP_EXT_DEFAULT}],
validate_options(Options, ValidOptions, []).
tls_options(Options) ->
@@ -1174,12 +1184,14 @@ handle_call({_, {open, ip_comm, Opts}}, From, State) ->
DTimeout = key_search(dtimeout, Opts, ?DATA_ACCEPT_TIMEOUT),
Progress = key_search(progress, Opts, ignore),
IpFamily = key_search(ipfamily, Opts, inet),
+ FtpExt = key_search(ftp_extension, Opts, ?FTP_EXT_DEFAULT),
State2 = State#state{client = From,
mode = Mode,
progress = progress(Progress),
ipfamily = IpFamily,
- dtimeout = DTimeout},
+ dtimeout = DTimeout,
+ ftp_extension = FtpExt},
?fcrd("handle_call(open) -> setup ctrl connection with",
[{host, Host}, {port, Port}, {timeout, Timeout}]),
@@ -1202,11 +1214,13 @@ handle_call({_, {open, ip_comm, Host, Opts}}, From, State) ->
Timeout = key_search(timeout, Opts, ?CONNECTION_TIMEOUT),
DTimeout = key_search(dtimeout, Opts, ?DATA_ACCEPT_TIMEOUT),
Progress = key_search(progress, Opts, ignore),
+ FtpExt = key_search(ftp_extension, Opts, ?FTP_EXT_DEFAULT),
State2 = State#state{client = From,
mode = Mode,
progress = progress(Progress),
- dtimeout = DTimeout},
+ dtimeout = DTimeout,
+ ftp_extension = FtpExt},
case setup_ctrl_connection(Host, Port, Timeout, State2) of
{ok, State3, WaitTimeout} ->
@@ -1785,7 +1799,8 @@ handle_ctrl_result({pos_compl, Lines},
ipfamily = inet,
client = From,
caller = {setup_data_connection, Caller},
- timeout = Timeout} = State) ->
+ timeout = Timeout,
+ ftp_extension = false} = State) ->
{_, [?LEFT_PAREN | Rest]} =
lists:splitwith(fun(?LEFT_PAREN) -> false; (_) -> true end, Lines),
@@ -1806,6 +1821,28 @@ handle_ctrl_result({pos_compl, Lines},
{noreply,State#state{client = undefined, caller = undefined}}
end;
+handle_ctrl_result({pos_compl, Lines},
+ #state{mode = passive,
+ ipfamily = inet,
+ client = From,
+ caller = {setup_data_connection, Caller},
+ csock = CSock,
+ timeout = Timeout,
+ ftp_extension = true} = State) ->
+
+ [_, PortStr | _] = lists:reverse(string:tokens(Lines, "|")),
+ {ok, {IP, _}} = peername(CSock),
+
+ ?DBG('<--data tcp connect to ~p:~p, Caller=~p~n',[IP,PortStr,Caller]),
+ case connect(IP, list_to_integer(PortStr), Timeout, State) of
+ {ok, _, Socket} ->
+ handle_caller(State#state{caller = Caller, dsock = {tcp, Socket}});
+ {error, _Reason} = Error ->
+ gen_server:reply(From, Error),
+ {noreply, State#state{client = undefined, caller = undefined}}
+ end;
+
+
%% FTP server does not support passive mode: try to fallback on active mode
handle_ctrl_result(_,
#state{mode = passive,
@@ -2157,7 +2194,8 @@ setup_ctrl_connection(Host, Port, Timeout, State) ->
setup_data_connection(#state{mode = active,
caller = Caller,
- csock = CSock} = State) ->
+ csock = CSock,
+ ftp_extension = FtpExt} = State) ->
case (catch sockname(CSock)) of
{ok, {{_, _, _, _, _, _, _, _} = IP, _}} ->
{ok, LSock} =
@@ -2174,11 +2212,18 @@ setup_data_connection(#state{mode = active,
{ok, LSock} = gen_tcp:listen(0, [{ip, IP}, {active, false},
binary, {packet, 0}]),
{ok, Port} = inet:port(LSock),
- {IP1, IP2, IP3, IP4} = IP,
- {Port1, Port2} = {Port div 256, Port rem 256},
- send_ctrl_message(State,
- mk_cmd("PORT ~w,~w,~w,~w,~w,~w",
- [IP1, IP2, IP3, IP4, Port1, Port2])),
+ case FtpExt of
+ false ->
+ {IP1, IP2, IP3, IP4} = IP,
+ {Port1, Port2} = {Port div 256, Port rem 256},
+ send_ctrl_message(State,
+ mk_cmd("PORT ~w,~w,~w,~w,~w,~w",
+ [IP1, IP2, IP3, IP4, Port1, Port2]));
+ true ->
+ IpAddress = inet_parse:ntoa(IP),
+ Cmd = mk_cmd("EPRT |1|~s|~p|", [IpAddress, Port]),
+ send_ctrl_message(State, Cmd)
+ end,
activate_ctrl_connection(State),
{noreply, State#state{caller = {setup_data_connection,
{LSock, Caller}}}}
@@ -2191,9 +2236,17 @@ setup_data_connection(#state{mode = passive, ipfamily = inet6,
{noreply, State#state{caller = {setup_data_connection, Caller}}};
setup_data_connection(#state{mode = passive, ipfamily = inet,
- caller = Caller} = State) ->
+ caller = Caller,
+ ftp_extension = false} = State) ->
send_ctrl_message(State, mk_cmd("PASV", [])),
activate_ctrl_connection(State),
+ {noreply, State#state{caller = {setup_data_connection, Caller}}};
+
+setup_data_connection(#state{mode = passive, ipfamily = inet,
+ caller = Caller,
+ ftp_extension = true} = State) ->
+ send_ctrl_message(State, mk_cmd("EPSV", [])),
+ activate_ctrl_connection(State),
{noreply, State#state{caller = {setup_data_connection, Caller}}}.
connect(Host, Port, Timeout, #state{ipfamily = inet = IpFam}) ->
diff --git a/lib/inets/src/http_client/httpc_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl
index 134115bdfa..ed306a84f5 100644
--- a/lib/inets/src/http_client/httpc_cookie.erl
+++ b/lib/inets/src/http_client/httpc_cookie.erl
@@ -334,9 +334,23 @@ add_domain(Str, #http_cookie{domain_default = true}) ->
add_domain(Str, #http_cookie{domain = Domain}) ->
Str ++ "; $Domain=" ++ Domain.
+is_set_cookie_valid("") ->
+ %% an empty Set-Cookie header is not valid
+ false;
+is_set_cookie_valid([$=|_]) ->
+ %% a Set-Cookie header without name is not valid
+ false;
+is_set_cookie_valid(SetCookieHeader) ->
+ %% a Set-Cookie header without name/value is not valid
+ case string:chr(SetCookieHeader, $=) of
+ 0 -> false;
+ _ -> true
+ end.
+
parse_set_cookies(CookieHeaders, DefaultPathDomain) ->
- %% empty Set-Cookie header is invalid according to RFC but some sites violate it
- SetCookieHeaders = [Value || {"set-cookie", Value} <- CookieHeaders, Value /= ""],
+ %% filter invalid Set-Cookie headers
+ SetCookieHeaders = [Value || {"set-cookie", Value} <- CookieHeaders,
+ is_set_cookie_valid(Value)],
Cookies = [parse_set_cookie(SetCookieHeader, DefaultPathDomain) ||
SetCookieHeader <- SetCookieHeaders],
%% print_cookies("Parsed Cookies", Cookies),
@@ -348,6 +362,8 @@ parse_set_cookie(CookieHeader, {DefaultPath, DefaultDomain}) ->
Name = string:substr(CookieHeader, 1, Pos - 1),
{Value, Attrs} =
case string:substr(CookieHeader, Pos + 1) of
+ [] ->
+ {"", ""};
[$;|ValueAndAttrs] ->
{"", string:tokens(ValueAndAttrs, ";")};
ValueAndAttrs ->
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 5ae6760f08..0bbd40d656 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -350,7 +350,7 @@ handle_call(#request{address = Addr} = Request, _,
{reply, ok, State0#state{keep_alive = NewKeepAlive,
session = NewSession}};
undefined ->
- %% Note: tcp-message reciving has already been
+ %% Note: tcp-message receiving has already been
%% activated by handle_pipeline/2.
?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
@@ -632,7 +632,7 @@ handle_info({timeout, RequestId},
handle_info(timeout_queue, State = #state{request = undefined}) ->
{stop, normal, State};
-%% Timing was such as the pipeline_timout was not canceled!
+%% Timing was such as the queue_timeout was not canceled!
handle_info(timeout_queue, #state{timers = Timers} = State) ->
{noreply, State#state{timers =
Timers#timers{queue_timer = undefined}}};
@@ -1793,7 +1793,7 @@ tls_tunnel_request(#request{headers = Headers,
host_header(#http_request_h{host = Host}, _) ->
Host;
-%% Handles header_as_is
+%% Handles headers_as_is
host_header(_, URI) ->
{ok, {_, _, Host, _, _, _}} = http_uri:parse(URI),
Host.
diff --git a/lib/inets/src/http_lib/http_internal.hrl b/lib/inets/src/http_lib/http_internal.hrl
index 53b776c4e7..54425740b5 100644
--- a/lib/inets/src/http_lib/http_internal.hrl
+++ b/lib/inets/src/http_lib/http_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,6 +28,7 @@
-define(HTTP_MAX_URI_SIZE, nolimit).
-define(HTTP_MAX_VERSION_STRING, 8).
-define(HTTP_MAX_METHOD_STRING, 20).
+-define(HTTP_MAX_CONTENT_LENGTH, 100000000).
-ifndef(HTTP_DEFAULT_SSL_KIND).
-define(HTTP_DEFAULT_SSL_KIND, essl).
diff --git a/lib/inets/src/http_lib/http_request.erl b/lib/inets/src/http_lib/http_request.erl
index f295453bdd..a0833ddf01 100644
--- a/lib/inets/src/http_lib/http_request.erl
+++ b/lib/inets/src/http_lib/http_request.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. 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,8 +21,16 @@
-include("http_internal.hrl").
--export([headers/2, http_headers/1, is_absolut_uri/1]).
+-export([headers/2, http_headers/1, is_absolut_uri/1, key_value/1]).
+
+key_value(KeyValueStr) ->
+ case lists:splitwith(fun($:) -> false; (_) -> true end, KeyValueStr) of
+ {Key, [$: | Value]} ->
+ {http_util:to_lower(string:strip(Key)), string:strip(Value)};
+ {_, []} ->
+ undefined
+ end.
%%-------------------------------------------------------------------------
%% headers(HeaderList, #http_request_h{}) -> #http_request_h{}
%% HeaderList - ["HeaderField:Value"]
@@ -34,14 +42,12 @@
%%-------------------------------------------------------------------------
headers([], Headers) ->
Headers;
-headers([Header | Tail], Headers) ->
- case lists:splitwith(fun($:) -> false; (_) -> true end, Header) of
- {Key, [$: | Value]} ->
- headers(Tail, headers(http_util:to_lower(string:strip(Key)),
- string:strip(Value), Headers));
- {_, []} ->
- headers(Tail, Headers)
- end.
+headers([{Key, Value} | Tail], Headers) ->
+ headers(Tail, headers(Key, Value, Headers));
+headers([undefined], Headers) ->
+ Headers;
+headers(KeyValues, Headers) ->
+ headers([key_value(KeyValue) || KeyValue <- KeyValues], Headers).
%%-------------------------------------------------------------------------
%% headers(#http_request_h{}) -> HeaderList
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index 5962001c3a..350a4bc169 100644
--- a/lib/inets/src/http_lib/http_uri.erl
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -90,8 +90,8 @@ parse(AbsURI, Opts) ->
{error, Reason};
{Scheme, DefaultPort, Rest} ->
case (catch parse_uri_rest(Scheme, DefaultPort, Rest, Opts)) of
- {ok, {UserInfo, Host, Port, Path, Query}} ->
- {ok, {Scheme, UserInfo, Host, Port, Path, Query}};
+ {ok, Result} ->
+ {ok, Result};
{error, Reason} ->
{error, {Reason, Scheme, AbsURI}};
_ ->
@@ -148,27 +148,22 @@ parse_scheme(AbsURI, Opts) ->
end.
parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) ->
- {Authority, PathQuery} =
- case split_uri(URIPart, "/", URIPart, 1, 0) of
- Split = {_, _} ->
- Split;
- URIPart ->
- case split_uri(URIPart, "\\?", URIPart, 1, 0) of
- Split = {_, _} ->
- Split;
- URIPart ->
- {URIPart,""}
- end
- end,
+ {Authority, PathQueryFragment} =
+ split_uri(URIPart, "[/?#]", {URIPart, ""}, 1, 0),
+ {RawPath, QueryFragment} =
+ split_uri(PathQueryFragment, "[?#]", {PathQueryFragment, ""}, 1, 0),
+ {Query, Fragment} =
+ split_uri(QueryFragment, "#", {QueryFragment, ""}, 1, 0),
{UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1),
{Host, Port} = parse_host_port(Scheme, DefaultPort, HostPort, Opts),
- {Path, Query} = parse_path_query(PathQuery),
- {ok, {UserInfo, Host, Port, Path, Query}}.
-
+ Path = path(RawPath),
+ case lists:keyfind(fragment, 1, Opts) of
+ {fragment, true} ->
+ {ok, {Scheme, UserInfo, Host, Port, Path, Query, Fragment}};
+ _ ->
+ {ok, {Scheme, UserInfo, Host, Port, Path, Query}}
+ end.
-parse_path_query(PathQuery) ->
- {Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0),
- {path(Path), Query}.
%% In this version of the function, we no longer need
%% the Scheme argument, but just in case...
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 27446ca7fe..78dda794db 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -44,7 +44,7 @@
%% FilePath = string()
%% Result = {ok,Directory} | {error,Reason}
%% Directory = string()
-%% Reason = string() | enoent | eaccess | enotdir | FileInfo
+%% Reason = string() | enoent | eacces | enotdir | FileInfo
%% FileInfo = File info record
%%
%% Description: Checks if FilePath is a directory in which case it is
@@ -71,7 +71,7 @@ is_directory(_Type,_Access,FileInfo,_Directory) ->
%% FilePath = string()
%% Result = {ok,File} | {error,Reason}
%% File = string()
-%% Reason = string() | enoent | eaccess | enotdir | FileInfo
+%% Reason = string() | enoent | eacces | enotdir | FileInfo
%% FileInfo = File info record
%%
%% Description: Checks if FilePath is a regular file in which case it
@@ -205,13 +205,13 @@ load("MaxURISize " ++ MaxHeaderSize, []) ->
" is an invalid number of MaxHeaderSize")}
end;
-load("MaxBodySize " ++ MaxBodySize, []) ->
- case make_integer(MaxBodySize) of
+load("MaxContentLength " ++ Max, []) ->
+ case make_integer(Max) of
{ok, Integer} ->
- {ok, [], {max_body_size,Integer}};
+ {ok, [], {max_content_length, Integer}};
{error, _} ->
- {error, ?NICE(clean(MaxBodySize) ++
- " is an invalid number of MaxBodySize")}
+ {error, ?NICE(clean(Max) ++
+ " is an invalid number of MaxContentLength")}
end;
load("ServerName " ++ ServerName, []) ->
@@ -337,7 +337,7 @@ load("MaxKeepAliveRequest " ++ MaxRequests, []) ->
load("KeepAliveTimeout " ++ Timeout, []) ->
case make_integer(Timeout) of
{ok, Integer} ->
- {ok, [], {keep_alive_timeout, Integer*1000}};
+ {ok, [], {keep_alive_timeout, Integer}};
{error, _} ->
{error, ?NICE(clean(Timeout)++" is an invalid KeepAliveTimeout")}
end;
@@ -569,6 +569,12 @@ validate_config_params([{max_body_size, Value} | Rest])
validate_config_params([{max_body_size, Value} | _]) ->
throw({max_body_size, Value});
+validate_config_params([{max_content_length, Value} | Rest])
+ when is_integer(Value) andalso (Value > 0) ->
+ validate_config_params(Rest);
+validate_config_params([{max_content_length, Value} | _]) ->
+ throw({max_content_length, Value});
+
validate_config_params([{server_name, Value} | Rest])
when is_list(Value) ->
validate_config_params(Rest);
@@ -635,7 +641,7 @@ validate_config_params([{max_keep_alive_request, Value} | Rest])
when is_integer(Value) andalso (Value > 0) ->
validate_config_params(Rest);
validate_config_params([{max_keep_alive_request, Value} | _]) ->
- throw({max_header_size, Value});
+ throw({max_keep_alive_request, Value});
validate_config_params([{keep_alive_timeout, Value} | Rest])
when is_integer(Value) andalso (Value >= 0) ->
@@ -799,7 +805,7 @@ store({server_tokens, ServerTokens} = Entry, _ConfigList) ->
Server = server(ServerTokens),
{ok, [Entry, {server, Server}]};
store({keep_alive_timeout, KeepAliveTimeout}, _ConfigList) ->
- {ok, {keep_alive_timeout, KeepAliveTimeout * 1000}};
+ {ok, {keep_alive_timeout, KeepAliveTimeout}};
store(ConfigListEntry, _ConfigList) ->
{ok, ConfigListEntry}.
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index 712c73599f..6985065c3e 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. 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
@@ -118,18 +118,17 @@ validate(Method, Uri, Version) ->
%% create it.
%% ----------------------------------------------------------------------
update_mod_data(ModData, Method, RequestURI, HTTPVersion, Headers)->
- ParsedHeaders = tagup_header(Headers),
- PersistentConn = get_persistens(HTTPVersion, ParsedHeaders,
+ PersistentConn = get_persistens(HTTPVersion, Headers,
ModData#mod.config_db),
{ok, ModData#mod{data = [],
method = Method,
absolute_uri = format_absolute_uri(RequestURI,
- ParsedHeaders),
+ Headers),
request_uri = format_request_uri(RequestURI),
http_version = HTTPVersion,
request_line = Method ++ " " ++ RequestURI ++
" " ++ HTTPVersion,
- parsed_header = ParsedHeaders,
+ parsed_header = Headers,
connection = PersistentConn}}.
%%%========================================================================
@@ -146,14 +145,14 @@ parse_method(_, _, _, Max, _, _) ->
%% We do not know the version of the client as it comes after the
%% method send the lowest version in the response so that the client
%% will be able to handle it.
- {error, {too_long, Max, 413, "Method unreasonably long"}, lowest_version()}.
+ {error, {size_error, Max, 413, "Method unreasonably long"}, lowest_version()}.
parse_uri(_, _, Current, MaxURI, _, _)
when (Current > MaxURI) andalso (MaxURI =/= nolimit) ->
%% We do not know the version of the client as it comes after the
%% uri send the lowest version in the response so that the client
%% will be able to handle it.
- {error, {too_long, MaxURI, 414, "URI unreasonably long"},lowest_version()};
+ {error, {size_error, MaxURI, 414, "URI unreasonably long"},lowest_version()};
parse_uri(<<>>, URI, Current, Max, MaxSizes, Result) ->
{?MODULE, parse_uri, [URI, Current, Max, MaxSizes, Result]};
parse_uri(<<?SP, Rest/binary>>, URI, _, _, MaxSizes, Result) ->
@@ -179,12 +178,12 @@ parse_version(<<?CR>> = Data, Version, Current, Max, MaxSizes, Result) ->
parse_version(<<Octet, Rest/binary>>, Version, Current, Max, MaxSizes, Result) when Current =< Max ->
parse_version(Rest, [Octet | Version], Current + 1, Max, MaxSizes, Result);
parse_version(_, _, _, Max,_,_) ->
- {error, {too_long, Max, 413, "Version string unreasonably long"}, lowest_version()}.
+ {error, {size_error, Max, 413, "Version string unreasonably long"}, lowest_version()}.
parse_headers(_, _, _, Current, Max, _, Result)
when Max =/= nolimit andalso Current > Max ->
HttpVersion = lists:nth(3, lists:reverse(Result)),
- {error, {too_long, Max, 413, "Headers unreasonably long"}, HttpVersion};
+ {error, {size_error, Max, 413, "Headers unreasonably long"}, HttpVersion};
parse_headers(<<>>, Header, Headers, Current, Max, MaxSizes, Result) ->
{?MODULE, parse_headers, [<<>>, Header, Headers, Current, Max,
@@ -204,14 +203,22 @@ parse_headers(<<?CR,?LF,?CR,?LF,Body/binary>>, [], [], _, _, _, Result) ->
Result])),
{ok, NewResult};
parse_headers(<<?CR,?LF,?CR,?LF,Body/binary>>, Header, Headers, _, _,
- _, Result) ->
- HTTPHeaders = [lists:reverse(Header) | Headers],
- RequestHeaderRcord =
- http_request:headers(HTTPHeaders, #http_request_h{}),
- NewResult =
- list_to_tuple(lists:reverse([Body, {RequestHeaderRcord,
- HTTPHeaders} | Result])),
- {ok, NewResult};
+ MaxSizes, Result) ->
+ case http_request:key_value(lists:reverse(Header)) of
+ undefined -> %% Skip headers with missing :
+ {ok, list_to_tuple(lists:reverse([Body, {http_request:headers(Headers, #http_request_h{}), Headers} | Result]))};
+ NewHeader ->
+ case check_header(NewHeader, MaxSizes) of
+ ok ->
+ {ok, list_to_tuple(lists:reverse([Body, {http_request:headers([NewHeader | Headers],
+ #http_request_h{}),
+ [NewHeader | Headers]} | Result]))};
+
+ {error, Reason} ->
+ HttpVersion = lists:nth(3, lists:reverse(Result)),
+ {error, Reason, HttpVersion}
+ end
+ end;
parse_headers(<<?CR,?LF,?CR>> = Data, Header, Headers, Current, Max,
MaxSizes, Result) ->
@@ -243,8 +250,21 @@ parse_headers(<<?LF, Octet, Rest/binary>>, Header, Headers, Current, Max,
MaxSizes, Result);
parse_headers(<<?CR,?LF, Octet, Rest/binary>>, Header, Headers, _, Max,
MaxSizes, Result) ->
- parse_headers(Rest, [Octet], [lists:reverse(Header) | Headers],
- 0, Max, MaxSizes, Result);
+ case http_request:key_value(lists:reverse(Header)) of
+ undefined -> %% Skip headers with missing :
+ parse_headers(Rest, [Octet], Headers,
+ 0, Max, MaxSizes, Result);
+ NewHeader ->
+ case check_header(NewHeader, MaxSizes) of
+ ok ->
+ parse_headers(Rest, [Octet], [NewHeader | Headers],
+ 0, Max, MaxSizes, Result);
+ {error, Reason} ->
+ HttpVersion = lists:nth(3, lists:reverse(Result)),
+ {error, Reason, HttpVersion}
+ end
+ end;
+
parse_headers(<<?CR>> = Data, Header, Headers, Current, Max,
MaxSizes, Result) ->
{?MODULE, parse_headers, [Data, Header, Headers, Current, Max,
@@ -388,29 +408,25 @@ get_persistens(HTTPVersion,ParsedHeader,ConfigDB)->
false
end.
-
-%%----------------------------------------------------------------------
-%% tagup_header
-%%
-%% Parses the header of a HTTP request and returns a key,value tuple
-%% list containing Name and Value of each header directive as of:
-%%
-%% Content-Type: multipart/mixed -> {"Content-Type", "multipart/mixed"}
-%%
-%% But in http/1.1 the field-names are case insencitive so now it must be
-%% Content-Type: multipart/mixed -> {"content-type", "multipart/mixed"}
-%% The standard furthermore says that leading and traling white space
-%% is not a part of the fieldvalue and shall therefore be removed.
-%%----------------------------------------------------------------------
-tagup_header([]) -> [];
-tagup_header([Line|Rest]) -> [tag(Line, [])|tagup_header(Rest)].
-
-tag([], Tag) ->
- {http_util:to_lower(lists:reverse(Tag)), ""};
-tag([$:|Rest], Tag) ->
- {http_util:to_lower(lists:reverse(Tag)), string:strip(Rest)};
-tag([Chr|Rest], Tag) ->
- tag(Rest, [Chr|Tag]).
-
lowest_version()->
"HTTP/0.9".
+
+check_header({"content-length", Value}, Maxsizes) ->
+ Max = proplists:get_value(max_content_length, Maxsizes),
+ MaxLen = length(integer_to_list(Max)),
+ case length(Value) =< MaxLen of
+ true ->
+ try
+ _ = list_to_integer(Value),
+ ok
+ catch _:_ ->
+ {error, {size_error, Max, 411, "content-length not an integer"}}
+ end;
+ false ->
+ {error, {size_error, Max, 413, "content-length unreasonably long"}}
+ end;
+check_header(_, _) ->
+ ok.
+
+
+
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index b3c9cbc46a..f7a9fe5d49 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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,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
@@ -95,16 +96,15 @@ init([Manager, ConfigDB, AcceptTimeout]) ->
proc_lib:init_ack({ok, self()}),
{SocketType, Socket} = await_socket_ownership_transfer(AcceptTimeout),
-
- TimeOut = httpd_util:lookup(ConfigDB, keep_alive_timeout, 150000),
- Then = erlang:now(),
- case http_transport:negotiate(SocketType, Socket, TimeOut) of
+ %%Timeout value is in seconds we want it in milliseconds
+ KeepAliveTimeOut = 1000 * httpd_util:lookup(ConfigDB, keep_alive_timeout, 150),
+
+ 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) ->
@@ -120,11 +120,15 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) ->
MaxHeaderSize = max_header_size(ConfigDB),
MaxURISize = max_uri_size(ConfigDB),
NrOfRequest = max_keep_alive_request(ConfigDB),
-
+ MaxContentLen = max_content_length(ConfigDB),
+
{_, Status} = httpd_manager:new_connection(Manager),
MFA = {httpd_request, parse, [[{max_uri, MaxURISize}, {max_header, MaxHeaderSize},
- {max_version, ?HTTP_MAX_VERSION_STRING}, {max_method, ?HTTP_MAX_METHOD_STRING}]]},
+ {max_version, ?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, MaxContentLen}
+ ]]},
State = #state{mod = Mod,
manager = Manager,
@@ -208,7 +212,7 @@ handle_info({Proto, Socket, Data},
set_new_data_size(cancel_request_timeout(State), NewDataSize)
end,
handle_http_msg(Result, NewState);
- {error, {too_long, MaxSize, ErrCode, ErrStr}, Version} ->
+ {error, {size_error, MaxSize, ErrCode, ErrStr}, Version} ->
NewModData = ModData#mod{http_version = Version},
httpd_response:send_status(NewModData, ErrCode, ErrStr),
Reason = io_lib:format("~p: ~p max size is ~p~n",
@@ -445,8 +449,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
error_log(Reason, ModData),
{stop, normal, State#state{response_sent = true}};
_ ->
- Length =
- list_to_integer(Headers#http_request_h.'content-length'),
+ Length = list_to_integer(Headers#http_request_h.'content-length'),
case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of
true ->
case httpd_request:whole_body(Body, Length) of
@@ -455,7 +458,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
ModData#mod.socket,
[{active, once}]),
{noreply, State#state{mfa =
- {Module, Function, Args}}};
+ {Module, Function, Args}}};
{ok, NewBody} ->
handle_response(
@@ -472,7 +475,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
handle_expect(#state{headers = Headers, mod =
#mod{config_db = ConfigDB} = ModData} = State,
MaxBodySize) ->
- Length = Headers#http_request_h.'content-length',
+ Length = list_to_integer(Headers#http_request_h.'content-length'),
case expect(Headers, ModData#mod.http_version, ConfigDB) of
continue when (MaxBodySize > Length) orelse (MaxBodySize =:= nolimit) ->
httpd_response:send_status(ModData, 100, ""),
@@ -546,9 +549,13 @@ handle_next_request(#state{mod = #mod{connection = true} = ModData,
init_data = ModData#mod.init_data},
MaxHeaderSize = max_header_size(ModData#mod.config_db),
MaxURISize = max_uri_size(ModData#mod.config_db),
+ MaxContentLen = max_content_length(ModData#mod.config_db),
MFA = {httpd_request, parse, [[{max_uri, MaxURISize}, {max_header, MaxHeaderSize},
- {max_version, ?HTTP_MAX_VERSION_STRING}, {max_method, ?HTTP_MAX_METHOD_STRING}]]},
+ {max_version, ?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, MaxContentLen}
+ ]]},
TmpState = State#state{mod = NewModData,
mfa = MFA,
max_keep_alive_request = decrease(Max),
@@ -631,3 +638,5 @@ max_body_size(ConfigDB) ->
max_keep_alive_request(ConfigDB) ->
httpd_util:lookup(ConfigDB, max_keep_alive_request, infinity).
+max_content_length(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, max_content_length, ?HTTP_MAX_CONTENT_LENGTH).
diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl
index 0b9fe4cfe0..5039cd56b5 100644
--- a/lib/inets/src/http_server/mod_alias.erl
+++ b/lib/inets/src/http_server/mod_alias.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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
@@ -55,6 +55,7 @@ do(#mod{data = Data} = Info) ->
do_alias(#mod{config_db = ConfigDB,
request_uri = ReqURI,
+ socket_type = SocketType,
data = Data}) ->
{ShortPath, Path, AfterPath} =
real_name(ConfigDB, ReqURI, which_alias(ConfigDB)),
@@ -70,8 +71,9 @@ do_alias(#mod{config_db = ConfigDB,
(LastChar =/= $/)) ->
?hdrt("directory and last-char is a /", []),
ServerName = which_server_name(ConfigDB),
- Port = port_string( which_port(ConfigDB) ),
- URL = "http://" ++ ServerName ++ Port ++ ReqURI ++ "/",
+ Port = port_string(which_port(ConfigDB)),
+ Protocol = get_protocol(SocketType),
+ URL = Protocol ++ ServerName ++ Port ++ ReqURI ++ "/",
ReasonPhrase = httpd_util:reason_phrase(301),
Message = httpd_util:message(301, URL, ConfigDB),
{proceed,
@@ -94,6 +96,12 @@ port_string(80) ->
port_string(Port) ->
":" ++ integer_to_list(Port).
+get_protocol(ip_comm) ->
+ "http://";
+get_protocol(_) ->
+ %% Should clean up to have only one ssl type essl vs ssl is not relevant any more
+ "https://".
+
%% real_name
real_name(ConfigDB, RequestURI, []) ->
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 5499596bbd..90524ac367 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -17,20 +17,9 @@
%% %CopyrightEnd%
{"%VSN%",
[
- {"5.10",
- [{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\\..*">>,[{restart_application, inets}]}
],
[
- {"5.10",
- [{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\\..*">>,[{restart_application, inets}]}
]
}.
diff --git a/lib/inets/test/ftp_property_test_SUITE.erl b/lib/inets/test/ftp_property_test_SUITE.erl
new file mode 100644
index 0000000000..c7077421f4
--- /dev/null
+++ b/lib/inets/test/ftp_property_test_SUITE.erl
@@ -0,0 +1,52 @@
+%%
+%% %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%
+%%
+%%
+
+%%% Run like this:
+%%% ct:run_test([{suite,"ftp_property_test_SUITE"}, {logdir,"/ldisk/OTP/LOG"}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-module(ftp_property_test_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+all() -> [prop_ftp_case].
+
+
+init_per_suite(Config) ->
+ inets:start(),
+ ct_property_test:init_per_suite(Config).
+
+
+%%%---- test case
+prop_ftp_case(Config) ->
+ ct_property_test:quickcheck(
+ ftp_simple_client_server:prop_ftp(Config),
+ Config
+ ).
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index d4a3f28f38..5952e9fd6e 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. 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
@@ -355,10 +355,12 @@ http_request(Config) when is_list(Config) ->
"http://www.erlang.org",
"HTTP/1.1",
{#http_request_h{host = "www.erlang.org", te = []},
- ["te: ","host:www.erlang.org"]}, <<>>} =
+ [{"te", []}, {"host", "www.erlang.org"}]}, <<>>} =
parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE},
{max_version, ?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]],
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]],
HttpHead),
HttpHead1 = ["GET http://www.erlang.org HTTP/1.1" ++
@@ -369,7 +371,9 @@ http_request(Config) when is_list(Config) ->
{#http_request_h{}, []}, <<>>} =
parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE},
{max_version, ?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]], HttpHead1),
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]], HttpHead1),
HttpHead2 = ["GET http://www.erlang.org HTTP/1.1" ++
@@ -380,7 +384,9 @@ http_request(Config) when is_list(Config) ->
{#http_request_h{}, []}, <<>>} =
parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE},
{max_version, ?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]], HttpHead2),
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]], HttpHead2),
%% Note the following body is not related to the headers above
HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n",
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index c535d59b9f..21be7862cb 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. 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
@@ -91,6 +91,7 @@ only_simulated() ->
cookie,
cookie_profile,
empty_set_cookie,
+ invalid_set_cookie,
trace,
stream_once,
stream_single_chunk,
@@ -568,6 +569,18 @@ empty_set_cookie(Config) when is_list(Config) ->
ok = httpc:set_options([{cookies, disabled}]).
%%-------------------------------------------------------------------------
+invalid_set_cookie(doc) ->
+ ["Test ignoring invalid Set-Cookie header"];
+invalid_set_cookie(Config) when is_list(Config) ->
+ ok = httpc:set_options([{cookies, enabled}]),
+
+ URL = url(group_name(Config), "/invalid_set_cookie.html", Config),
+ {ok, {{_,200,_}, [_|_], [_|_]}} =
+ httpc:request(get, {URL, []}, [], []),
+
+ ok = httpc:set_options([{cookies, disabled}]).
+
+%%-------------------------------------------------------------------------
headers_as_is(doc) ->
["Test the option headers_as_is"];
headers_as_is(Config) when is_list(Config) ->
@@ -1246,8 +1259,9 @@ dummy_server_init(Caller, ip_comm, Inet, _) ->
dummy_ipcomm_server_loop({httpd_request, parse, [[{max_uri, ?HTTP_MAX_URI_SIZE},
{max_header, ?HTTP_MAX_HEADER_SIZE},
{max_version,?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]]},
- [], ListenSocket);
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}]]},
+ [], ListenSocket);
dummy_server_init(Caller, ssl, Inet, SSLOptions) ->
BaseOpts = [binary, {reuseaddr,true}, {active, false} |
@@ -1261,7 +1275,9 @@ dummy_ssl_server_init(Caller, BaseOpts, Inet) ->
dummy_ssl_server_loop({httpd_request, parse, [[{max_uri, ?HTTP_MAX_URI_SIZE},
{max_method, ?HTTP_MAX_METHOD_STRING},
{max_version,?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]]},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]]},
[], ListenSocket).
dummy_ipcomm_server_loop(MFA, Handlers, ListenSocket) ->
@@ -1338,16 +1354,20 @@ handle_request(Module, Function, Args, Socket) ->
stop ->
stop;
<<>> ->
- {httpd_request, parse, [[<<>>, [{max_uri, ?HTTP_MAX_URI_SIZE},
+ {httpd_request, parse, [[{max_uri,?HTTP_MAX_URI_SIZE},
{max_header, ?HTTP_MAX_HEADER_SIZE},
{max_version,?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]]]};
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]]};
Data ->
handle_request(httpd_request, parse,
[Data, [{max_uri, ?HTTP_MAX_URI_SIZE},
- {max_header, ?HTTP_MAX_HEADER_SIZE},
- {max_version,?HTTP_MAX_VERSION_STRING},
- {max_method, ?HTTP_MAX_METHOD_STRING}]], Socket)
+ {max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version,?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]], Socket)
end;
NewMFA ->
NewMFA
@@ -1437,7 +1457,7 @@ dummy_ssl_server_hang_loop(_) ->
ensure_host_header_with_port([]) ->
false;
-ensure_host_header_with_port(["host: " ++ Host| _]) ->
+ensure_host_header_with_port([{"host", Host}| _]) ->
case string:tokens(Host, [$:]) of
[_ActualHost, _Port] ->
true;
@@ -1449,7 +1469,7 @@ ensure_host_header_with_port([_|T]) ->
auth_header([]) ->
auth_header_not_found;
-auth_header(["authorization:" ++ Value | _]) ->
+auth_header([{"authorization", Value} | _]) ->
{ok, string:strip(Value)};
auth_header([_ | Tail]) ->
auth_header(Tail).
@@ -1466,7 +1486,7 @@ handle_auth("Basic " ++ UserInfo, Challange, DefaultResponse) ->
check_cookie([]) ->
ct:fail(no_cookie_header);
-check_cookie(["cookie:" ++ _Value | _]) ->
+check_cookie([{"cookie", _} | _]) ->
ok;
check_cookie([_Head | Tail]) ->
check_cookie(Tail).
@@ -1686,6 +1706,14 @@ handle_uri(_,"/empty_set_cookie.html",_,_,_,_) ->
"Content-Length:32\r\n\r\n"++
"<HTML><BODY>foobar</BODY></HTML>";
+handle_uri(_,"/invalid_set_cookie.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "set-cookie: =\r\n" ++
+ "set-cookie: name=\r\n" ++
+ "set-cookie: name-or-value\r\n" ++
+ "Content-Length:32\r\n\r\n"++
+ "<HTML><BODY>foobar</BODY></HTML>";
+
handle_uri(_,"/missing_crlf.html",_,_,_,_) ->
"HTTP/1.1 200 ok" ++
"Content-Length:32\r\n" ++
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 4be20d3a69..342004f19b 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2015. 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,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
]},
@@ -118,6 +132,7 @@ http_get() ->
bad_hex,
missing_CR,
max_header,
+ max_content_length,
ipv6
].
@@ -134,8 +149,24 @@ init_per_suite(Config) ->
inets_test_lib:del_dirs(ServerRoot),
DocRoot = filename:join(ServerRoot, "htdocs"),
setup_server_dirs(ServerRoot, DocRoot, DataDir),
+ {ok, Hostname0} = inet:gethostname(),
+ Inet =
+ case (catch ct:get_config(ipv6_hosts)) of
+ undefined ->
+ inet;
+ Hosts when is_list(Hosts) ->
+ case lists:member(list_to_atom(Hostname0), Hosts) of
+ true ->
+ inet6;
+ false ->
+ inet
+ end;
+ _ ->
+ inet
+ end,
[{server_root, ServerRoot},
{doc_root, DocRoot},
+ {ipfamily, Inet},
{node, node()},
{host, inets_test_lib:hostname()},
{address, getaddr()} | Config].
@@ -150,7 +181,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 +191,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 +235,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();
@@ -506,7 +541,7 @@ ipv6(Config) when is_list(Config) ->
true ->
Version = ?config(http_version, Config),
Host = ?config(host, Config),
- URI = http_request("GET /", Version, Host),
+ URI = http_request("GET / ", Version, Host),
httpd_test_lib:verify_request(?config(type, Config), Host,
?config(port, Config), [inet6],
?config(code, Config),
@@ -945,13 +980,22 @@ max_header(Config) when is_list(Config) ->
Host = ?config(host, Config),
case Version of
"HTTP/0.9" ->
- {skip, no_implemented};
+ {skip, not_implemented};
_ ->
dos_hostname(?config(type, Config), ?config(port, Config), Host,
?config(node, Config), Version, ?MAX_HEADER_SIZE)
end.
%%-------------------------------------------------------------------------
+max_content_length() ->
+ ["Denial Of Service (DOS) attack, prevented by max_content_length"].
+max_content_length(Config) when is_list(Config) ->
+ Version = ?config(http_version, Config),
+ Host = ?config(host, Config),
+ garbage_content_length(?config(type, Config), ?config(port, Config), Host,
+ ?config(node, Config), Version).
+
+%%-------------------------------------------------------------------------
security_1_1(Config) when is_list(Config) ->
security([{http_version, "HTTP/1.1"} | Config]).
@@ -1088,12 +1132,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 +1317,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 +1328,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,8 +1373,14 @@ 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);
+ [{max_clients, 1},
+ %% Make sure option checking code is run
+ {max_content_length, 100000002}] ++ server_config(http, Config);
server_config(https_limit, Config) ->
[{max_clients, 1}] ++ server_config(https, Config);
server_config(http_basic_auth, Config) ->
@@ -1270,7 +1425,7 @@ server_config(http, Config) ->
{server_root, ServerRoot},
{document_root, ?config(doc_root, Config)},
{bind_address, any},
- {ipfamily, inet},
+ {ipfamily, ?config(ipfamily, Config)},
{max_header_size, 256},
{max_header_action, close},
{directory_index, ["index.html", "welcome.html"]},
@@ -1539,9 +1694,10 @@ cleanup_mnesia() ->
transport_opts(ssl, Config) ->
PrivDir = ?config(priv_dir, Config),
- [{cacertfile, filename:join(PrivDir, "public_key_cacert.pem")}];
-transport_opts(_, _) ->
- [].
+ [?config(ipfamily, Config),
+ {cacertfile, filename:join(PrivDir, "public_key_cacert.pem")}];
+transport_opts(_, Config) ->
+ [?config(ipfamily, Config)].
%%% mod_range
@@ -1670,7 +1826,7 @@ dos_hostname(Type, Port, Host, Node, Version, Max) ->
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
dos_hostname_request(TooLongHeader, Version),
- [{statuscode, dos_code(Version)},
+ [{statuscode, request_entity_too_large_code(Version)},
{version, Version}]).
dos_hostname_request(Host, Version) ->
dos_http_request("GET / ", Version, Host).
@@ -1680,11 +1836,32 @@ dos_http_request(Request, "HTTP/1.1" = Version, Host) ->
dos_http_request(Request, Version, Host) ->
Request ++ Version ++ "\r\nhost:" ++ Host ++ "\r\n\r\n".
-dos_code("HTTP/1.0") ->
+request_entity_too_large_code("HTTP/1.0") ->
403; %% 413 not defined in HTTP/1.0
-dos_code(_) ->
+request_entity_too_large_code(_) ->
413.
+length_required_code("HTTP/1.0") ->
+ 403; %% 411 not defined in HTTP/1.0
+length_required_code(_) ->
+ 411.
+
+garbage_content_length(Type, Port, Host, Node, Version) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ garbage_content_length_request("GET / ", Version, Host, "aaaa"),
+ [{statuscode, length_required_code(Version)},
+ {version, Version}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ garbage_content_length_request("GET / ", Version, Host,
+ lists:duplicate($a, 100)),
+ [{statuscode, request_entity_too_large_code(Version)},
+ {version, Version}]).
+
+garbage_content_length_request(Request, Version, Host, Garbage) ->
+ http_request(Request, Version, Host,
+ {"content-length:" ++ Garbage, "Body with garbage content length indicator"}).
+
+
update_password(Node, ServerRoot, _Address, Port, AuthPrefix, Dir, Old, New)->
Directory = filename:join([ServerRoot, "htdocs", AuthPrefix ++ Dir]),
rpc:call(Node, mod_auth, update_password,
@@ -1792,3 +1969,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/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index 36a5bb9e71..647fa6f6c1 100644
--- a/lib/inets/test/httpd_test_lib.erl
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -91,16 +91,7 @@ verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut)
when (is_integer(TimeOut) orelse (TimeOut =:= infinity)) ->
verify_request(SocketType, Host, Port, [], Node, RequestStr, Options, TimeOut).
-verify_request(SocketType, Host, Port, TranspOpts0, Node, RequestStr, Options, TimeOut) ->
- %% For now, until we modernize the httpd tests
- TranspOpts =
- case lists:member(inet6, TranspOpts0) of
- true ->
- TranspOpts0;
- false ->
- [inet | TranspOpts0]
- end,
-
+verify_request(SocketType, Host, Port, TranspOpts, Node, RequestStr, Options, TimeOut) ->
try inets_test_lib:connect_bin(SocketType, Host, Port, TranspOpts) of
{ok, Socket} ->
ok = inets_test_lib:send(SocketType, Socket, RequestStr),
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/test/property_test/README b/lib/inets/test/property_test/README
new file mode 100644
index 0000000000..57602bf719
--- /dev/null
+++ b/lib/inets/test/property_test/README
@@ -0,0 +1,12 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The test in this directory are written assuming that the user has a QuickCheck license. They are to be run manually. Some may be possible to be run with other tools, e.g. PropEr.
+
diff --git a/lib/inets/test/property_test/ftp_simple_client_server.erl b/lib/inets/test/property_test/ftp_simple_client_server.erl
new file mode 100644
index 0000000000..40e630ee5c
--- /dev/null
+++ b/lib/inets/test/property_test/ftp_simple_client_server.erl
@@ -0,0 +1,306 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_simple_client_server).
+
+-compile(export_all).
+
+-ifndef(EQC).
+-ifndef(PROPER).
+-define(EQC,true).
+%%-define(PROPER,true).
+-endif.
+-endif.
+
+
+-ifdef(EQC).
+
+-include_lib("eqc/include/eqc.hrl").
+-include_lib("eqc/include/eqc_statem.hrl").
+-define(MOD_eqc, eqc).
+-define(MOD_eqc_gen, eqc_gen).
+-define(MOD_eqc_statem, eqc_statem).
+
+-else.
+-ifdef(PROPER).
+
+-include_lib("proper/include/proper.hrl").
+-define(MOD_eqc, proper).
+-define(MOD_eqc_gen, proper_gen).
+-define(MOD_eqc_statem, proper_statem).
+
+-endif.
+-endif.
+
+-record(state, {
+ initialized = false,
+ priv_dir,
+ data_dir,
+ servers = [], % [ {IP,Port,Userid,Pwd} ]
+ clients = [], % [ client_ref() ]
+ store = [] % [ {Name,Contents} ]
+ }).
+
+-define(fmt(F,A), io:format(F,A)).
+%%-define(fmt(F,A), ok).
+
+-define(v(K,L), proplists:get_value(K,L)).
+
+%%%================================================================
+%%%
+%%% Properties
+%%%
+
+%% This function is for normal eqc calls:
+prop_ftp() ->
+ {ok,PWD} = file:get_cwd(),
+ prop_ftp(filename:join([PWD,?MODULE_STRING++"_data"]),
+ filename:join([PWD,?MODULE_STRING,"_files"])).
+
+%% This function is for calls from common_test test cases:
+prop_ftp(Config) ->
+ prop_ftp(filename:join([?v(property_dir,Config), ?MODULE_STRING++"_data"]),
+ ?v(priv_dir,Config) ).
+
+
+prop_ftp(DataDir, PrivDir) ->
+ S0 = #state{data_dir = DataDir,
+ priv_dir = PrivDir},
+ ?FORALL(Cmds, more_commands(10,commands(?MODULE,S0)),
+ aggregate(command_names(Cmds),
+ begin {_H,S,Result} = run_commands(?MODULE,Cmds),
+ % io:format('**** Result=~p~n',[Result]),
+ % io:format('**** S=~p~n',[S]),
+ % io:format('**** _H=~p~n',[_H]),
+ % io:format('**** Cmds=~p~n',[Cmds]),
+ [cmnd_stop_server(X) || X <- S#state.servers],
+ [inets:stop(ftpc,X) || {ok,X} <- S#state.clients],
+ Result==ok
+ end)
+ ).
+
+%%%================================================================
+%%%
+%%% State model
+%%%
+
+%% @doc Returns the state in which each test case starts. (Unless a different
+%% initial state is supplied explicitly to, e.g. commands/2.)
+-spec initial_state() ->?MOD_eqc_statem:symbolic_state().
+initial_state() ->
+ ?fmt("Initial_state()~n",[]),
+ #state{}.
+
+%% @doc Command generator, S is the current state
+-spec command(S :: ?MOD_eqc_statem:symbolic_state()) -> ?MOD_eqc_gen:gen(eqc_statem:call()).
+
+command(#state{initialized=false,
+ priv_dir=PrivDir}) ->
+ {call,?MODULE,cmnd_init,[PrivDir]};
+
+command(#state{servers=[],
+ priv_dir=PrivDir,
+ data_dir=DataDir}) ->
+ {call,?MODULE,cmnd_start_server,[PrivDir,DataDir]};
+
+command(#state{servers=Ss=[_|_],
+ clients=[]}) ->
+ {call,?MODULE,cmnd_start_client,[oneof(Ss)]};
+
+command(#state{servers=Ss=[_|_],
+ clients=Cs=[_|_],
+ store=Store=[_|_]
+ }) ->
+ frequency([
+ { 5, {call,?MODULE,cmnd_start_client,[oneof(Ss)]}},
+ { 5, {call,?MODULE,cmnd_stop_client,[oneof(Cs)]}},
+ {10, {call,?MODULE,cmnd_put,[oneof(Cs),file_path(),file_contents()]}},
+ {20, {call,?MODULE,cmnd_get,[oneof(Cs),oneof(Store)]}},
+ {10, {call,?MODULE,cmnd_delete,[oneof(Cs),oneof(Store)]}}
+ ]);
+
+command(#state{servers=Ss=[_|_],
+ clients=Cs=[_|_],
+ store=[]
+ }) ->
+ frequency([
+ {5, {call,?MODULE,cmnd_start_client,[oneof(Ss)]}},
+ {5, {call,?MODULE,cmnd_stop_client,[oneof(Cs)]}},
+ {10, {call,?MODULE,cmnd_put,[oneof(Cs),file_path(),file_contents()]}}
+ ]).
+
+%% @doc Precondition, checked before command is added to the command sequence.
+-spec precondition(S :: ?MOD_eqc_statem:symbolic_state(), C :: ?MOD_eqc_statem:call()) -> boolean().
+
+precondition(#state{clients=Cs}, {call, _, cmnd_put, [C,_,_]}) -> lists:member(C,Cs);
+
+precondition(#state{clients=Cs, store=Store},
+ {call, _, cmnd_get, [C,X]}) -> lists:member(C,Cs) andalso lists:member(X,Store);
+
+precondition(#state{clients=Cs, store=Store},
+ {call, _, cmnd_delete, [C,X]}) -> lists:member(C,Cs) andalso lists:member(X,Store);
+
+precondition(#state{servers=Ss}, {call, _, cmnd_start_client, _}) -> Ss =/= [];
+
+precondition(#state{clients=Cs}, {call, _, cmnd_stop_client, [C]}) -> lists:member(C,Cs);
+
+precondition(#state{initialized=IsInit}, {call, _, cmnd_init, _}) -> IsInit==false;
+
+precondition(_S, {call, _, _, _}) -> true.
+
+
+%% @doc Postcondition, checked after command has been evaluated
+%% Note: S is the state before next_state(S,_,C)
+-spec postcondition(S :: ?MOD_eqc_statem:dynamic_state(), C :: ?MOD_eqc_statem:call(),
+ Res :: term()) -> boolean().
+
+postcondition(_S, {call, _, cmnd_get, [_,{_Name,Expected}]}, {ok,Value}) ->
+ Value == Expected;
+
+postcondition(S, {call, _, cmnd_delete, [_,{Name,_Expected}]}, ok) ->
+ ?fmt("file:read_file(..) = ~p~n",[file:read_file(filename:join(S#state.priv_dir,Name))]),
+ {error,enoent} == file:read_file(filename:join(S#state.priv_dir,Name));
+
+postcondition(S, {call, _, cmnd_put, [_,Name,Value]}, ok) ->
+ {ok,Bin} = file:read_file(filename:join(S#state.priv_dir,Name)),
+ Bin == unicode:characters_to_binary(Value);
+
+postcondition(_S, {call, _, cmnd_stop_client, _}, ok) -> true;
+
+postcondition(_S, {call, _, cmnd_start_client, _}, {ok,_}) -> true;
+
+postcondition(_S, {call, _, cmnd_init, _}, ok) -> true;
+
+postcondition(_S, {call, _, cmnd_start_server, _}, {ok,_}) -> true.
+
+
+%% @doc Next state transformation, S is the current state. Returns next state.
+-spec next_state(S :: ?MOD_eqc_statem:symbolic_state(),
+ V :: ?MOD_eqc_statem:var(),
+ C :: ?MOD_eqc_statem:call()) -> ?MOD_eqc_statem:symbolic_state().
+
+next_state(S, _V, {call, _, cmnd_put, [_,Name,Val]}) ->
+ S#state{store = [{Name,Val} | lists:keydelete(Name,1,S#state.store)]};
+
+next_state(S, _V, {call, _, cmnd_delete, [_,{Name,_Val}]}) ->
+ S#state{store = lists:keydelete(Name,1,S#state.store)};
+
+next_state(S, V, {call, _, cmnd_start_client, _}) ->
+ S#state{clients = [V | S#state.clients]};
+
+next_state(S, V, {call, _, cmnd_start_server, _}) ->
+ S#state{servers = [V | S#state.servers]};
+
+next_state(S, _V, {call, _, cmnd_stop_client, [C]}) ->
+ S#state{clients = S#state.clients -- [C]};
+
+next_state(S, _V, {call, _, cmnd_init, _}) ->
+ S#state{initialized=true};
+
+next_state(S, _V, {call, _, _, _}) ->
+ S.
+
+%%%================================================================
+%%%
+%%% Data model
+%%%
+
+file_path() -> non_empty(list(alphanum_char())).
+%%file_path() -> non_empty( list(oneof([alphanum_char(), utf8_char()])) ).
+
+%%file_contents() -> list(alphanum_char()).
+file_contents() -> list(oneof([alphanum_char(), utf8_char()])).
+
+alphanum_char() -> oneof(lists:seq($a,$z) ++ lists:seq($A,$Z) ++ lists:seq($0,$9)).
+
+utf8_char() -> oneof("åäöÅÄÖ話话カタカナひらがな").
+
+%%%================================================================
+%%%
+%%% Commands doing something with the System Under Test
+%%%
+
+cmnd_init(PrivDir) ->
+ ?fmt('Call cmnd_init(~p)~n',[PrivDir]),
+ os:cmd("killall vsftpd"),
+ clear_files(PrivDir),
+ ok.
+
+cmnd_start_server(PrivDir, DataDir) ->
+ ?fmt('Call cmnd_start_server(~p, ~p)~n',[PrivDir,DataDir]),
+ Cmnd = ["vsftpd ", filename:join(DataDir,"vsftpd.conf"),
+ " -oftpd_banner=erlang_otp_testing"
+ " -oanon_root=",PrivDir
+ ],
+ ?fmt("Cmnd=~s~n",[Cmnd]),
+ case os:cmd(Cmnd) of
+ [] ->
+ {ok,{"localhost",9999,"ftp","[email protected]"}};
+ Other ->
+ {error,Other}
+ end.
+
+cmnd_stop_server({ok,{_Host,Port,_Usr,_Pwd}}) ->
+ os:cmd("kill `netstat -tpln | grep "++integer_to_list(Port)++" | awk '{print $7}' | awk -F/ '{print $1}'`").
+
+cmnd_start_client({ok,{Host,Port,Usr,Pwd}}) ->
+ ?fmt('Call cmnd_start_client(~p)...',[{Host,Port,Usr,Pwd}]),
+ case inets:start(ftpc, [{host,Host},{port,Port}]) of
+ {ok,Client} ->
+ ?fmt("~p...",[{ok,Client}]),
+ case ftp:user(Client, Usr, Pwd) of
+ ok ->
+ ?fmt("OK!~n",[]),
+ {ok,Client};
+ Other ->
+ ?fmt("Other1=~p~n",[Other]),
+ inets:stop(ftpc,Client), Other
+ end;
+ Other ->
+ ?fmt("Other2=~p~n",[Other]),
+ Other
+ end.
+
+cmnd_stop_client({ok,Client}) ->
+ ?fmt('Call cmnd_stop_client(~p)~n',[Client]),
+ inets:stop(ftpc, Client). %% -> ok | Other
+
+cmnd_delete({ok,Client}, {Name,_ExpectedValue}) ->
+ ?fmt('Call cmnd_delete(~p, ~p)~n',[Client,Name]),
+ R=ftp:delete(Client, Name),
+ ?fmt("R=~p~n",[R]),
+ R.
+
+cmnd_put({ok,Client}, Name, Value) ->
+ ?fmt('Call cmnd_put(~p, ~p, ~p)...',[Client, Name, Value]),
+ R = ftp:send_bin(Client, unicode:characters_to_binary(Value), Name), % ok | {error,Error}
+ ?fmt('~p~n',[R]),
+ R.
+
+cmnd_get({ok,Client}, {Name,_ExpectedValue}) ->
+ ?fmt('Call cmnd_get(~p, ~p)~n',[Client,Name]),
+ case ftp:recv_bin(Client, Name) of
+ {ok,Bin} -> {ok, unicode:characters_to_list(Bin)};
+ Other -> Other
+ end.
+
+
+clear_files(Dir) ->
+ os:cmd(["rm -fr ",filename:join(Dir,"*")]).
diff --git a/lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf b/lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf
new file mode 100644
index 0000000000..fd48e2abf0
--- /dev/null
+++ b/lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf
@@ -0,0 +1,26 @@
+
+###
+### Some parameters are given in the vsftpd start command.
+###
+### Typical command-line paramters are such that has a file path
+### component like cert files.
+###
+
+
+listen=YES
+listen_port=9999
+run_as_launching_user=YES
+ssl_enable=NO
+#allow_anon_ssl=YES
+
+background=YES
+
+write_enable=YES
+anonymous_enable=YES
+anon_upload_enable=YES
+anon_mkdir_write_enable=YES
+anon_other_write_enable=YES
+anon_world_readable_only=NO
+
+### Shouldn't be necessary....
+require_ssl_reuse=NO
diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl
index 9ba09e1474..f75e347d0c 100644
--- a/lib/inets/test/uri_SUITE.erl
+++ b/lib/inets/test/uri_SUITE.erl
@@ -46,6 +46,7 @@ all() ->
userinfo,
scheme,
queries,
+ fragments,
escaped,
hexed_query
].
@@ -105,6 +106,42 @@ queries(Config) when is_list(Config) ->
{ok, {http,[],"localhost",8888,"/foobar.html","?foo=bar&foobar=42"}} =
http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42").
+fragments(Config) when is_list(Config) ->
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment"),
+ {ok, {http,[],"localhost",80,"/path",""}} =
+ http_uri:parse("http://localhost/path#fragment"),
+ {ok, {http,[],"localhost",80,"/","?query"}} =
+ http_uri:parse("http://localhost?query#fragment"),
+ {ok, {http,[],"localhost",80,"/path","?query"}} =
+ http_uri:parse("http://localhost/path?query#fragment"),
+ {ok, {http,[],"localhost",80,"/","","#fragment"}} =
+ http_uri:parse("http://localhost#fragment", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","","#fragment"}} =
+ http_uri:parse("http://localhost/path#fragment", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","?query","#fragment"}} =
+ http_uri:parse("http://localhost?query#fragment", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","?query","#fragment"}} =
+ http_uri:parse("http://localhost/path?query#fragment",
+ [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","",""}} =
+ http_uri:parse("http://localhost", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","",""}} =
+ http_uri:parse("http://localhost/path", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","?query",""}} =
+ http_uri:parse("http://localhost?query", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","?query",""}} =
+ http_uri:parse("http://localhost/path?query", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","","#"}} =
+ http_uri:parse("http://localhost#", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","","#"}} =
+ http_uri:parse("http://localhost/path#", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","?query","#"}} =
+ http_uri:parse("http://localhost?query#", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","?query","#"}} =
+ http_uri:parse("http://localhost/path?query#", [{fragment,true}]),
+ ok.
+
escaped(Config) when is_list(Config) ->
{ok, {http,[],"www.somedomain.com",80,"/%2Eabc",[]}} =
http_uri:parse("http://www.somedomain.com/%2Eabc"),
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index bbd86c3eb3..7d11916454 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.5
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index e81a9f82d2..fc5f8be53e 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -30,6 +30,90 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
+<section><title>Jinterface 1.5.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ handle empty .erlang.cookie without crashing and
+ OtpErlangList.clone must not return null</p>
+ <p>
+ Own Id: OTP-12210</p>
+ </item>
+ <item>
+ <p>
+ This fixes all the compilation warnings in the Java code</p>
+ <p>
+ Own Id: OTP-12211</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added an .appup file for the application.</p>
+ <p>
+ Own Id: OTP-12358 Aux Id: OTP-12178 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Jinterface 1.5.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Added a <c>.app</c> file for the application.</p>
+ <p>
+ Own Id: OTP-12178</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Jinterface 1.5.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Array now show meaningful values in exceptions.</p>
+ <p>
+ Own Id: OTP-12049</p>
+ </item>
+ <item>
+ <p>
+ Documentation improvements.</p>
+ <p>
+ Own Id: OTP-12050</p>
+ </item>
+ <item>
+ <p>
+ Include the cause when raising a new IOException, which
+ should make the reason for the exception clearer.</p>
+ <p>
+ Own Id: OTP-12075</p>
+ </item>
+ <item>
+ <p>
+ Arrays (here: md5 and freeVars) must not be compared with
+ equals, which is broken (compares identity).</p>
+ <p>
+ Own Id: OTP-12121</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Jinterface 1.5.9</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/jinterface/ebin/.gitignore b/lib/jinterface/ebin/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/jinterface/ebin/.gitignore
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..b8a973753a 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
@@ -20,7 +20,6 @@
package com.ericsson.otp.erlang;
import java.io.IOException;
-import java.io.InputStream;
import java.net.Socket;
import java.util.Random;
@@ -87,7 +86,7 @@ public abstract class AbstractConnection extends Thread {
protected boolean connected = false; // connection status
protected Socket socket; // communication channel
protected OtpPeer peer; // who are we connected to
- protected OtpLocalNode self; // this nodes id
+ protected OtpLocalNode localNode; // this nodes id
String name; // local name of this connection
protected boolean cookieOk = false; // already checked the cookie for this
@@ -137,7 +136,7 @@ public abstract class AbstractConnection extends Thread {
*/
protected AbstractConnection(final OtpLocalNode self, final Socket s)
throws IOException, OtpAuthException {
- this.self = self;
+ this.localNode = self;
peer = new OtpPeer();
socket = s;
@@ -181,7 +180,7 @@ public abstract class AbstractConnection extends Thread {
protected AbstractConnection(final OtpLocalNode self, final OtpPeer other)
throws IOException, OtpAuthException {
peer = other;
- this.self = self;
+ this.localNode = self;
socket = null;
int port;
@@ -234,6 +233,7 @@ public abstract class AbstractConnection extends Thread {
if (!connected) {
throw new IOException("Not connected");
}
+ @SuppressWarnings("resource")
final OtpOutputStream header = new OtpOutputStream(headerLen);
// preamble: 4 byte length + "passthrough" tag + version
@@ -246,7 +246,7 @@ public abstract class AbstractConnection extends Thread {
header.write_long(regSendTag);
header.write_any(from);
if (sendCookie) {
- header.write_atom(self.cookie());
+ header.write_atom(localNode.cookie());
} else {
header.write_atom("");
}
@@ -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
@@ -278,6 +278,7 @@ public abstract class AbstractConnection extends Thread {
if (!connected) {
throw new IOException("Not connected");
}
+ @SuppressWarnings("resource")
final OtpOutputStream header = new OtpOutputStream(headerLen);
// preamble: 4 byte length + "passthrough" tag + version
@@ -289,7 +290,7 @@ public abstract class AbstractConnection extends Thread {
header.write_tuple_head(3);
header.write_long(sendTag);
if (sendCookie) {
- header.write_atom(self.cookie());
+ header.write_atom(localNode.cookie());
} else {
header.write_atom("");
}
@@ -312,6 +313,7 @@ public abstract class AbstractConnection extends Thread {
private void cookieError(final OtpLocalNode local,
final OtpErlangAtom cookie) throws OtpAuthException {
try {
+ @SuppressWarnings("resource")
final OtpOutputStream header = new OtpOutputStream(headerLen);
// preamble: 4 byte length + "passthrough" tag + version
@@ -347,6 +349,7 @@ public abstract class AbstractConnection extends Thread {
msg[0] = new OtpErlangAtom("$gen_cast");
msg[1] = new OtpErlangTuple(msgbody);
+ @SuppressWarnings("resource")
final OtpOutputStream payload = new OtpOutputStream(
new OtpErlangTuple(msg));
@@ -384,6 +387,7 @@ public abstract class AbstractConnection extends Thread {
if (!connected) {
throw new IOException("Not connected");
}
+ @SuppressWarnings("resource")
final OtpOutputStream header = new OtpOutputStream(headerLen);
// preamble: 4 byte length + "passthrough" tag
@@ -420,6 +424,7 @@ public abstract class AbstractConnection extends Thread {
if (!connected) {
throw new IOException("Not connected");
}
+ @SuppressWarnings("resource")
final OtpOutputStream header = new OtpOutputStream(headerLen);
// preamble: 4 byte length + "passthrough" tag
@@ -468,6 +473,7 @@ public abstract class AbstractConnection extends Thread {
if (!connected) {
throw new IOException("Not connected");
}
+ @SuppressWarnings("resource")
final OtpOutputStream header = new OtpOutputStream(headerLen);
// preamble: 4 byte length + "passthrough" tag
@@ -488,6 +494,7 @@ public abstract class AbstractConnection extends Thread {
do_send(header);
}
+ @SuppressWarnings("resource")
@Override
public void run() {
if (!connected) {
@@ -506,7 +513,7 @@ public abstract class AbstractConnection extends Thread {
// don't return until we get a real message
// or a failure of some kind (e.g. EXIT)
// read length and read buffer must be atomic!
- tick_loop: do {
+ do {
// read 4 bytes - get length of incoming packet
// socket.getInputStream().read(lbuf);
readSock(socket, lbuf);
@@ -526,6 +533,7 @@ public abstract class AbstractConnection extends Thread {
final byte[] tmpbuf = new byte[len];
// i = socket.getInputStream().read(tmpbuf);
readSock(socket, tmpbuf);
+ ibuf.close();
ibuf = new OtpInputStream(tmpbuf, flags);
if (ibuf.read1() != passThrough) {
@@ -567,12 +575,12 @@ public abstract class AbstractConnection extends Thread {
}
cookie = (OtpErlangAtom) head.elementAt(1);
if (sendCookie) {
- if (!cookie.atomValue().equals(self.cookie())) {
- cookieError(self, cookie);
+ if (!cookie.atomValue().equals(localNode.cookie())) {
+ cookieError(localNode, cookie);
}
} else {
if (!cookie.atomValue().equals("")) {
- cookieError(self, cookie);
+ cookieError(localNode, cookie);
}
}
cookieOk = true;
@@ -610,12 +618,12 @@ public abstract class AbstractConnection extends Thread {
}
cookie = (OtpErlangAtom) head.elementAt(2);
if (sendCookie) {
- if (!cookie.atomValue().equals(self.cookie())) {
- cookieError(self, cookie);
+ if (!cookie.atomValue().equals(localNode.cookie())) {
+ cookieError(localNode, cookie);
}
} else {
if (!cookie.atomValue().equals("")) {
- cookieError(self, cookie);
+ cookieError(localNode, cookie);
}
}
cookieOk = true;
@@ -749,13 +757,14 @@ public abstract class AbstractConnection extends Thread {
final int oldLevel = traceLevel;
// pin the value
+ int theLevel = level;
if (level < 0) {
- level = 0;
+ theLevel = 0;
} else if (level > 4) {
- level = 4;
+ theLevel = 4;
}
- traceLevel = level;
+ traceLevel = theLevel;
return oldLevel;
}
@@ -908,18 +917,16 @@ public abstract class AbstractConnection extends Thread {
int got = 0;
final int len = b.length;
int i;
- InputStream is = null;
synchronized (this) {
if (s == null) {
throw new IOException("expected " + len
+ " bytes, socket was closed");
}
- is = s.getInputStream();
}
while (got < len) {
- i = is.read(b, got, len - got);
+ i = s.getInputStream().read(b, got, len - got);
if (i < 0) {
throw new IOException("expected " + len
@@ -943,9 +950,9 @@ public abstract class AbstractConnection extends Thread {
try {
sendStatus("ok");
final int our_challenge = genChallenge();
- sendChallenge(peer.distChoose, self.flags, our_challenge);
+ sendChallenge(peer.distChoose, localNode.flags, our_challenge);
final int her_challenge = recvChallengeReply(our_challenge);
- final byte[] our_digest = genDigest(her_challenge, self.cookie());
+ final byte[] our_digest = genDigest(her_challenge, localNode.cookie());
sendChallengeAck(our_digest);
connected = true;
cookieOk = true;
@@ -959,7 +966,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());
@@ -976,10 +985,10 @@ public abstract class AbstractConnection extends Thread {
System.out.println("-> MD5 CONNECT TO " + peer.host() + ":"
+ port);
}
- sendName(peer.distChoose, self.flags);
+ sendName(peer.distChoose, localNode.flags);
recvStatus();
final int her_challenge = recvChallenge();
- final byte[] our_digest = genDigest(her_challenge, self.cookie());
+ final byte[] our_digest = genDigest(her_challenge, localNode.cookie());
final int our_challenge = genChallenge();
sendChallengeReply(our_challenge, our_digest);
recvChallengeAck(our_challenge);
@@ -990,7 +999,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;
}
}
@@ -1050,33 +1061,35 @@ public abstract class AbstractConnection extends Thread {
return res;
}
- protected void sendName(final int dist, final int flags) throws IOException {
+ protected void sendName(final int dist, final int aflags) throws IOException {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
- final String str = self.node();
+ final String str = localNode.node();
obuf.write2BE(str.length() + 7); // 7 bytes + nodename
obuf.write1(AbstractNode.NTYPE_R6);
obuf.write2BE(dist);
- obuf.write4BE(flags);
+ obuf.write4BE(aflags);
obuf.write(str.getBytes());
obuf.writeTo(socket.getOutputStream());
if (traceLevel >= handshakeThreshold) {
- System.out.println("-> " + "HANDSHAKE sendName" + " flags=" + flags
- + " dist=" + dist + " local=" + self);
+ System.out.println("-> " + "HANDSHAKE sendName" + " flags=" + aflags
+ + " dist=" + dist + " local=" + localNode);
}
}
- protected void sendChallenge(final int dist, final int flags,
+ protected void sendChallenge(final int dist, final int aflags,
final int challenge) throws IOException {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
- final String str = self.node();
+ final String str = localNode.node();
obuf.write2BE(str.length() + 11); // 11 bytes + nodename
obuf.write1(AbstractNode.NTYPE_R6);
obuf.write2BE(dist);
- obuf.write4BE(flags);
+ obuf.write4BE(aflags);
obuf.write4BE(challenge);
obuf.write(str.getBytes());
@@ -1084,8 +1097,8 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("-> " + "HANDSHAKE sendChallenge" + " flags="
- + flags + " dist=" + dist + " challenge=" + challenge
- + " local=" + self);
+ + aflags + " dist=" + dist + " challenge=" + challenge
+ + " local=" + localNode);
}
}
@@ -1096,6 +1109,7 @@ public abstract class AbstractConnection extends Thread {
byte[] tmpbuf;
readSock(socket, lbuf);
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(lbuf, 0);
final int len = ibuf.read2BE();
tmpbuf = new byte[len];
@@ -1103,41 +1117,42 @@ public abstract class AbstractConnection extends Thread {
return tmpbuf;
}
- protected void recvName(final OtpPeer peer) throws IOException {
+ protected void recvName(final OtpPeer apeer) throws IOException {
String hisname = "";
try {
final byte[] tmpbuf = read2BytePackage();
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
byte[] tmpname;
final int len = tmpbuf.length;
- peer.ntype = ibuf.read1();
- if (peer.ntype != AbstractNode.NTYPE_R6) {
+ apeer.ntype = ibuf.read1();
+ if (apeer.ntype != AbstractNode.NTYPE_R6) {
throw new IOException("Unknown remote node type");
}
- peer.distLow = peer.distHigh = ibuf.read2BE();
- if (peer.distLow < 5) {
+ apeer.distLow = apeer.distHigh = ibuf.read2BE();
+ if (apeer.distLow < 5) {
throw new IOException("Unknown remote node type");
}
- peer.flags = ibuf.read4BE();
+ apeer.flags = ibuf.read4BE();
tmpname = new byte[len - 7];
ibuf.readN(tmpname);
hisname = OtpErlangString.newString(tmpname);
// Set the old nodetype parameter to indicate hidden/normal status
// When the old handshake is removed, the ntype should also be.
- if ((peer.flags & AbstractNode.dFlagPublished) != 0) {
- peer.ntype = AbstractNode.NTYPE_R4_ERLANG;
+ if ((apeer.flags & AbstractNode.dFlagPublished) != 0) {
+ apeer.ntype = AbstractNode.NTYPE_R4_ERLANG;
} else {
- peer.ntype = AbstractNode.NTYPE_R4_HIDDEN;
+ apeer.ntype = AbstractNode.NTYPE_R4_HIDDEN;
}
- if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) {
+ if ((apeer.flags & AbstractNode.dFlagExtendedReferences) == 0) {
throw new IOException(
"Handshake failed - peer cannot handle extended references");
}
- if ((peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) {
+ if ((apeer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) {
throw new IOException(
"Handshake failed - peer cannot handle extended pids and ports");
}
@@ -1147,13 +1162,13 @@ public abstract class AbstractConnection extends Thread {
}
final int i = hisname.indexOf('@', 0);
- peer.node = hisname;
- peer.alive = hisname.substring(0, i);
- peer.host = hisname.substring(i + 1, hisname.length());
+ apeer.node = hisname;
+ apeer.alive = hisname.substring(0, i);
+ apeer.host = hisname.substring(i + 1, hisname.length());
if (traceLevel >= handshakeThreshold) {
- System.out.println("<- " + "HANDSHAKE" + " ntype=" + peer.ntype
- + " dist=" + peer.distHigh + " remote=" + peer);
+ System.out.println("<- " + "HANDSHAKE" + " ntype=" + apeer.ntype
+ + " dist=" + apeer.distHigh + " remote=" + apeer);
}
}
@@ -1163,6 +1178,7 @@ public abstract class AbstractConnection extends Thread {
try {
final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(buf, 0);
peer.ntype = ibuf.read1();
if (peer.ntype != AbstractNode.NTYPE_R6) {
@@ -1195,7 +1211,7 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("<- " + "HANDSHAKE recvChallenge" + " from="
- + peer.node + " challenge=" + challenge + " local=" + self);
+ + peer.node + " challenge=" + challenge + " local=" + localNode);
}
return challenge;
@@ -1204,6 +1220,7 @@ public abstract class AbstractConnection extends Thread {
protected void sendChallengeReply(final int challenge, final byte[] digest)
throws IOException {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
obuf.write2BE(21);
obuf.write1(ChallengeReply);
@@ -1214,7 +1231,7 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("-> " + "HANDSHAKE sendChallengeReply"
+ " challenge=" + challenge + " digest=" + hex(digest)
- + " local=" + self);
+ + " local=" + localNode);
}
}
@@ -1237,6 +1254,7 @@ public abstract class AbstractConnection extends Thread {
try {
final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(buf, 0);
final int tag = ibuf.read1();
if (tag != ChallengeReply) {
@@ -1244,7 +1262,7 @@ public abstract class AbstractConnection extends Thread {
}
challenge = ibuf.read4BE();
ibuf.readN(her_digest);
- final byte[] our_digest = genDigest(our_challenge, self.cookie());
+ final byte[] our_digest = genDigest(our_challenge, localNode.cookie());
if (!digests_equals(her_digest, our_digest)) {
throw new OtpAuthException("Peer authentication error.");
}
@@ -1255,7 +1273,7 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("<- " + "HANDSHAKE recvChallengeReply"
+ " from=" + peer.node + " challenge=" + challenge
- + " digest=" + hex(her_digest) + " local=" + self);
+ + " digest=" + hex(her_digest) + " local=" + localNode);
}
return challenge;
@@ -1263,6 +1281,7 @@ public abstract class AbstractConnection extends Thread {
protected void sendChallengeAck(final byte[] digest) throws IOException {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
obuf.write2BE(17);
obuf.write1(ChallengeAck);
@@ -1272,7 +1291,7 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("-> " + "HANDSHAKE sendChallengeAck"
- + " digest=" + hex(digest) + " local=" + self);
+ + " digest=" + hex(digest) + " local=" + localNode);
}
}
@@ -1282,13 +1301,14 @@ public abstract class AbstractConnection extends Thread {
final byte[] her_digest = new byte[16];
try {
final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(buf, 0);
final int tag = ibuf.read1();
if (tag != ChallengeAck) {
throw new IOException("Handshake protocol error");
}
ibuf.readN(her_digest);
- final byte[] our_digest = genDigest(our_challenge, self.cookie());
+ final byte[] our_digest = genDigest(our_challenge, localNode.cookie());
if (!digests_equals(her_digest, our_digest)) {
throw new OtpAuthException("Peer authentication error.");
}
@@ -1301,12 +1321,13 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("<- " + "HANDSHAKE recvChallengeAck" + " from="
+ peer.node + " digest=" + hex(her_digest) + " local="
- + self);
+ + localNode);
}
}
protected void sendStatus(final String status) throws IOException {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
obuf.write2BE(status.length() + 1);
obuf.write1(ChallengeStatus);
@@ -1316,7 +1337,7 @@ public abstract class AbstractConnection extends Thread {
if (traceLevel >= handshakeThreshold) {
System.out.println("-> " + "HANDSHAKE sendStatus" + " status="
- + status + " local=" + self);
+ + status + " local=" + localNode);
}
}
@@ -1324,6 +1345,7 @@ public abstract class AbstractConnection extends Thread {
try {
final byte[] buf = read2BytePackage();
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(buf, 0);
final int tag = ibuf.read1();
if (tag != ChallengeStatus) {
@@ -1342,7 +1364,7 @@ public abstract class AbstractConnection extends Thread {
}
if (traceLevel >= handshakeThreshold) {
System.out.println("<- " + "HANDSHAKE recvStatus (ok)" + " local="
- + self);
+ + localNode);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
index 3ef44b8851..3bb1bbbd18 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
@@ -128,7 +128,12 @@ public class AbstractNode {
final File dotCookieFile = new File(dotCookieFilename);
br = new BufferedReader(new FileReader(dotCookieFile));
- defaultCookie = br.readLine().trim();
+ final String line = br.readLine();
+ if (line == null) {
+ defaultCookie = "";
+ } else {
+ defaultCookie = line.trim();
+ }
} catch (final IOException e) {
defaultCookie = "";
} finally {
@@ -260,8 +265,7 @@ public class AbstractNode {
final String drive = System.getenv("HOMEDRIVE");
final String path = System.getenv("HOMEPATH");
return (drive != null && path != null) ? drive + path : home;
- } else {
- return home;
}
+ return home;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java
index 2b085761e3..c8b4fcebde 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Link.java
@@ -41,11 +41,12 @@ class Link {
return local.equals(pid) || remote.equals(pid);
}
- public boolean equals(final OtpErlangPid local, final OtpErlangPid remote) {
- return this.local.equals(local) && this.remote.equals(remote)
- || this.local.equals(remote) && this.remote.equals(local);
+ public boolean equals(final OtpErlangPid alocal, final OtpErlangPid aremote) {
+ return local.equals(alocal) && remote.equals(aremote)
+ || local.equals(aremote) && remote.equals(alocal);
}
+ @Override
public int hashCode() {
if (hashCodeValue == 0) {
OtpErlangObject.Hash hash = new OtpErlangObject.Hash(5);
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
index f476d4594d..ea3ab770ce 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
@@ -32,6 +32,18 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
include $(ERL_TOP)/lib/jinterface/vsn.mk
VSN=$(JINTERFACE_VSN)
+#
+
+EBINDIR=$(ERL_TOP)/lib/jinterface/ebin
+
+APP_FILE= jinterface.app
+APP_SRC= $(APP_FILE).src
+APP_TARGET= $(EBINDIR)/$(APP_FILE)
+
+APPUP_FILE= jinterface.appup
+APPUP_SRC= $(APPUP_FILE).src
+APPUP_TARGET= $(EBINDIR)/$(APPUP_FILE)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
@@ -45,7 +57,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/jinterface-$(VSN)
# all java sourcefiles listed in common include file
include $(ERL_TOP)/lib/jinterface/java_src/$(JAVA_CLASS_SUBDIR)/java_files
-TARGET_FILES= $(JAVA_FILES:%=$(JAVA_DEST_ROOT)$(JAVA_CLASS_SUBDIR)%.class)
+TARGET_FILES= $(JAVA_FILES:%=$(JAVA_DEST_ROOT)$(JAVA_CLASS_SUBDIR)%.class) $(APP_TARGET) $(APPUP_TARGET)
JAVA_SRC= $(JAVA_FILES:%=%.java)
JARFILE= OtpErlang.jar
@@ -66,7 +78,7 @@ ifneq ($(V),0)
JARFLAGS=-cfv
endif
-JAVA_OPTIONS =
+JAVA_OPTIONS = -Xlint
ifeq ($(TESTROOT),)
RELEASE_PATH="$(ERL_TOP)/release/$(TARGET)"
@@ -79,6 +91,11 @@ endif
# Make Rules
# ----------------------------------------------------
+$(APP_TARGET): $(APP_SRC) $(ERL_TOP)/lib/jinterface/vsn.mk
+ $(vsn_verbose)sed -e 's;%VSN%;$(JINTERFACE_VSN);' $< > $@
+$(APPUP_TARGET): $(APPUP_SRC) $(ERL_TOP)/lib/jinterface/vsn.mk
+ $(vsn_verbose)sed -e 's;%VSN%;$(JINTERFACE_VSN);' $< > $@
+
debug opt: make_dirs $(JAVA_DEST_ROOT)$(JARFILE)
make_dirs:
@@ -106,6 +123,9 @@ release_spec: opt
$(V_at)$(INSTALL_DATA) $(JAVA_SRC) "$(RELSYSDIR)/java_src/com/ericsson/otp/erlang"
$(V_at)$(INSTALL_DIR) "$(RELSYSDIR)/priv"
$(V_at)$(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) "$(RELSYSDIR)/priv"
+ $(V_at)$(INSTALL_DIR) "$(RELSYSDIR)/ebin"
+ $(V_at)$(INSTALL_DATA) $(APP_TARGET) "$(RELSYSDIR)/ebin/$(APP_FILE)"
+ $(V_at)$(INSTALL_DATA) $(APPUP_TARGET) "$(RELSYSDIR)/ebin/$(APPUP_FILE)"
release_docs_spec:
@@ -113,4 +133,3 @@ release_docs_spec:
# ----------------------------------------------------
-
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..9ad02506fd 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpConnection.java
@@ -358,6 +358,7 @@ public class OtpConnection extends AbstractConnection {
* if the connection is not active or a communication
* error occurs.
*/
+ @SuppressWarnings("resource")
public void send(final OtpErlangPid dest, final OtpErlangObject msg)
throws IOException {
// encode and send the message
@@ -376,6 +377,7 @@ public class OtpConnection extends AbstractConnection {
* if the connection is not active or a communication
* error occurs.
*/
+ @SuppressWarnings("resource")
public void send(final String dest, final OtpErlangObject msg)
throws IOException {
// encode and send the message
@@ -404,7 +406,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/OtpCookedConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java
index 5abf6e33f7..43b0cad222 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpCookedConnection.java
@@ -149,6 +149,7 @@ public class OtpCookedConnection extends AbstractConnection {
/*
* send to pid
*/
+ @SuppressWarnings("resource")
void send(final OtpErlangPid from, final OtpErlangPid dest,
final OtpErlangObject msg) throws IOException {
// encode and send the message
@@ -159,6 +160,7 @@ public class OtpCookedConnection extends AbstractConnection {
* send to remote name dest is recipient's registered name, the nodename is
* implied by the choice of connection.
*/
+ @SuppressWarnings("resource")
void send(final OtpErlangPid from, final String dest,
final OtpErlangObject msg) throws IOException {
// encode and send the message
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
index 1868dc7740..8a8ba785d9 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
@@ -160,6 +160,7 @@ public class OtpEpmd {
try {
s = new Socket((String) null, EpmdPort.get());
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
obuf.write2BE(node.alive().length() + 1);
obuf.write1(stopReq);
@@ -189,6 +190,7 @@ public class OtpEpmd {
Socket s = null;
try {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
s = new Socket(node.host(), EpmdPort.get());
@@ -219,6 +221,7 @@ public class OtpEpmd {
+ node.host() + " when looking up " + node.alive());
}
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
final int response = ibuf.read1();
@@ -279,6 +282,7 @@ public class OtpEpmd {
Socket s = null;
try {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
s = new Socket((String) null, EpmdPort.get());
@@ -310,13 +314,12 @@ public class OtpEpmd {
final int n = s.getInputStream().read(tmpbuf);
if (n < 0) {
- if (s != null) {
s.close();
- }
throw new IOException("Nameserver not responding on "
+ node.host() + " when publishing " + node.alive());
}
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
final int response = ibuf.read1();
@@ -341,9 +344,7 @@ public class OtpEpmd {
throw new IOException("Nameserver not responding on " + node.host()
+ " when publishing " + node.alive());
} catch (final OtpErlangDecodeException e) {
- if (s != null) {
s.close();
- }
if (traceLevel >= traceThreshold) {
System.out.println("<- (invalid response)");
}
@@ -351,9 +352,7 @@ public class OtpEpmd {
+ " when publishing " + node.alive());
}
- if (s != null) {
s.close();
- }
return null;
}
@@ -366,6 +365,7 @@ public class OtpEpmd {
Socket s = null;
try {
+ @SuppressWarnings("resource")
final OtpOutputStream obuf = new OtpOutputStream();
try {
s = new Socket(address, EpmdPort.get());
@@ -390,6 +390,7 @@ public class OtpEpmd {
out.write(buffer, 0, bytesRead);
}
final byte[] tmpbuf = out.toByteArray();
+ @SuppressWarnings("resource")
final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
ibuf.read4BE(); // read port int
// final int port = ibuf.read4BE();
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
index 0371740b26..bff3e2c0e3 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
@@ -18,17 +18,15 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang atoms. Atoms can be created from
* strings whose length is not more than {@link #maxAtomLength maxAtomLength}
* characters.
*/
-public class OtpErlangAtom extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangAtom extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = -3204386396807876641L;
+ private static final long serialVersionUID = -3204386396807876641L;
/** The maximun allowed length of an atom, in characters */
public static final int maxAtomLength = 0xff; // one byte length
@@ -119,9 +117,8 @@ public class OtpErlangAtom extends OtpErlangObject implements Serializable,
public String toString() {
if (atomNeedsQuoting(atom)) {
return "'" + escapeSpecialChars(atom) + "'";
- } else {
- return atom;
}
+ return atom;
}
/**
@@ -139,8 +136,8 @@ public class OtpErlangAtom extends OtpErlangObject implements Serializable,
return false;
}
- final OtpErlangAtom atom = (OtpErlangAtom) o;
- return this.atom.compareTo(atom.atom) == 0;
+ final OtpErlangAtom other = (OtpErlangAtom) o;
+ return this.atom.compareTo(other.atom) == 0;
}
@Override
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java
index a9eaad540e..0891781f8d 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBinary.java
@@ -18,16 +18,14 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang binaries. Anything that can be
* represented as a sequence of bytes can be made into an Erlang binary.
*/
-public class OtpErlangBinary extends OtpErlangBitstr implements Serializable,
- Cloneable {
+public class OtpErlangBinary extends OtpErlangBitstr {
// don't change this!
- static final long serialVersionUID = -3781009633593609217L;
+ private static final long serialVersionUID = -3781009633593609217L;
/**
* Create a binary from a byte array
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
index 97897fe182..8cb4e0e685 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
@@ -20,17 +20,15 @@ package com.ericsson.otp.erlang;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang bitstrs. An Erlang bitstr is an
* Erlang binary with a length not an integral number of bytes (8-bit). Anything
* can be represented as a sequence of bytes can be made into an Erlang bitstr.
*/
-public class OtpErlangBitstr extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangBitstr extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = -3781009633593609217L;
+ private static final long serialVersionUID = -3781009633593609217L;
protected byte[] bin;
protected int pad_bits;
@@ -63,18 +61,18 @@ public class OtpErlangBitstr extends OtpErlangObject implements Serializable,
check_bitstr(this.bin, this.pad_bits);
}
- private void check_bitstr(final byte[] bin, final int pad_bits) {
- if (pad_bits < 0 || 7 < pad_bits) {
+ private void check_bitstr(final byte[] abin, final int a_pad_bits) {
+ if (a_pad_bits < 0 || 7 < a_pad_bits) {
throw new java.lang.IllegalArgumentException(
"Padding must be in range 0..7");
}
- if (pad_bits != 0 && bin.length == 0) {
+ if (a_pad_bits != 0 && abin.length == 0) {
throw new java.lang.IllegalArgumentException(
"Padding on zero length bitstr");
}
- if (bin.length != 0) {
+ if (abin.length != 0) {
// Make sure padding is zero
- bin[bin.length - 1] &= ~((1 << pad_bits) - 1);
+ abin[abin.length - 1] &= ~((1 << a_pad_bits) - 1);
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java
index b97b5b7d90..eecd2ea288 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBoolean.java
@@ -18,14 +18,12 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang booleans, which are special cases of
* atoms with values 'true' and 'false'.
*/
-public class OtpErlangBoolean extends OtpErlangAtom implements Serializable,
- Cloneable {
+public class OtpErlangBoolean extends OtpErlangAtom {
// don't change this!
static final long serialVersionUID = 1087178844844988393L;
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java
index 2d598c119e..eb6f3d8aba 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangByte.java
@@ -18,15 +18,13 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang integral types.
*/
-public class OtpErlangByte extends OtpErlangLong implements Serializable,
- Cloneable {
+public class OtpErlangByte extends OtpErlangLong {
// don't change this!
- static final long serialVersionUID = 5778019796466613446L;
+ private static final long serialVersionUID = 5778019796466613446L;
/**
* Create an Erlang integer from the given value.
@@ -56,6 +54,6 @@ public class OtpErlangByte extends OtpErlangLong implements Serializable,
throws OtpErlangRangeException, OtpErlangDecodeException {
super(buf);
- final byte i = byteValue();
+ byteValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java
index b442bbcec1..e7c6dd8ad4 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangChar.java
@@ -18,15 +18,13 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang integral types.
*/
-public class OtpErlangChar extends OtpErlangLong implements Serializable,
- Cloneable {
+public class OtpErlangChar extends OtpErlangLong {
// don't change this!
- static final long serialVersionUID = 3225337815669398204L;
+ private static final long serialVersionUID = 3225337815669398204L;
/**
* Create an Erlang integer from the given value.
@@ -56,6 +54,6 @@ public class OtpErlangChar extends OtpErlangLong implements Serializable,
throws OtpErlangRangeException, OtpErlangDecodeException {
super(buf);
- final char i = charValue();
+ charValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java
index db55deaedf..6986e26908 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDecodeException.java
@@ -26,6 +26,8 @@ package com.ericsson.otp.erlang;
* @see OtpInputStream
*/
public class OtpErlangDecodeException extends OtpErlangException {
+ private static final long serialVersionUID = 1L;
+
/**
* Provides a detailed message.
*/
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java
index 793940e858..e92ce11431 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangDouble.java
@@ -18,7 +18,6 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang floats and doubles. Erlang defines
@@ -26,10 +25,9 @@ import java.io.Serializable;
* {@link OtpErlangFloat} are used to provide representations corresponding to
* the Java types Double and Float.
*/
-public class OtpErlangDouble extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangDouble extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = 132947104811974021L;
+ private static final long serialVersionUID = 132947104811974021L;
private final double d;
@@ -120,8 +118,8 @@ public class OtpErlangDouble extends OtpErlangObject implements Serializable,
return false;
}
- final OtpErlangDouble d = (OtpErlangDouble) o;
- return this.d == d.d;
+ final OtpErlangDouble other = (OtpErlangDouble) o;
+ return this.d == other.d;
}
@Override
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java
index 8662b74c53..7d48f848f0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFloat.java
@@ -18,15 +18,13 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang floats and doubles.
*/
-public class OtpErlangFloat extends OtpErlangDouble implements Serializable,
- Cloneable {
+public class OtpErlangFloat extends OtpErlangDouble {
// don't change this!
- static final long serialVersionUID = -2231546377289456934L;
+ private static final long serialVersionUID = -2231546377289456934L;
/**
* Create an Erlang float from the given float value.
@@ -53,6 +51,6 @@ public class OtpErlangFloat extends OtpErlangDouble implements Serializable,
throws OtpErlangDecodeException, OtpErlangRangeException {
super(buf);
- final float f = floatValue();
+ floatValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java
index fc104e9564..05fa0cbb23 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangFun.java
@@ -18,10 +18,9 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
import java.util.Arrays;
-public class OtpErlangFun extends OtpErlangObject implements Serializable {
+public class OtpErlangFun extends OtpErlangObject {
// don't change this!
private static final long serialVersionUID = -3423031125356706472L;
@@ -94,7 +93,7 @@ public class OtpErlangFun extends OtpErlangObject implements Serializable {
return false;
}
} else {
- if (!md5.equals(f.md5)) {
+ if (!Arrays.equals(md5, f.md5)) {
return false;
}
}
@@ -104,7 +103,7 @@ public class OtpErlangFun extends OtpErlangObject implements Serializable {
if (freeVars == null) {
return f.freeVars == null;
}
- return freeVars.equals(f.freeVars);
+ return Arrays.equals(freeVars, f.freeVars);
}
@Override
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java
index d947421459..741fc29dd0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangInt.java
@@ -18,15 +18,13 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang integral types.
*/
-public class OtpErlangInt extends OtpErlangLong implements Serializable,
- Cloneable {
+public class OtpErlangInt extends OtpErlangLong {
// don't change this!
- static final long serialVersionUID = 1229430977614805556L;
+ private static final long serialVersionUID = 1229430977614805556L;
/**
* Create an Erlang integer from the given value.
@@ -56,6 +54,6 @@ public class OtpErlangInt extends OtpErlangLong implements Serializable,
throws OtpErlangRangeException, OtpErlangDecodeException {
super(buf);
- final int j = intValue();
+ intValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
index 3456fd7412..9f7c5f5499 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
@@ -18,7 +18,6 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -30,9 +29,9 @@ import java.util.NoSuchElementException;
* The arity of the list is the number of elements it contains.
*/
public class OtpErlangList extends OtpErlangObject implements
- Iterable<OtpErlangObject>, Serializable, Cloneable {
+ Iterable<OtpErlangObject> {
// don't change this!
- static final long serialVersionUID = 5999112769036676548L;
+ private static final long serialVersionUID = 5999112769036676548L;
private static final OtpErlangObject[] NO_ELEMENTS = new OtpErlangObject[0];
@@ -187,12 +186,11 @@ public class OtpErlangList extends OtpErlangObject implements
public OtpErlangObject[] elements() {
if (arity() == 0) {
return NO_ELEMENTS;
- } else {
+ }
final OtpErlangObject[] res = new OtpErlangObject[arity()];
System.arraycopy(elems, 0, res, 0, res.length);
return res;
}
- }
/**
* Get the string representation of the list.
@@ -326,7 +324,7 @@ public class OtpErlangList extends OtpErlangObject implements
try {
return new OtpErlangList(elements(), getLastTail());
} catch (final OtpErlangException e) {
- return null;
+ throw new AssertionError(this);
}
}
@@ -361,9 +359,8 @@ public class OtpErlangList extends OtpErlangObject implements
if (arity >= n) {
if (arity == n && lastTail != null) {
return lastTail;
- } else {
- return new SubList(this, n);
}
+ return new SubList(this, n);
}
return null;
}
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..c6021a6ae1 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangLong.java
@@ -18,7 +18,6 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
import java.math.BigInteger;
/**
@@ -30,10 +29,9 @@ import java.math.BigInteger;
* {@link OtpErlangUInt} and {@link OtpErlangUShort} are provided for Corba
* compatibility. See the documentation for IC for more information.
*/
-public class OtpErlangLong extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangLong extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = 1610466859236755096L;
+ private static final long serialVersionUID = 1610466859236755096L;
private long val;
private BigInteger bigVal = null;
@@ -51,8 +49,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) {
@@ -94,9 +92,8 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
public BigInteger bigIntegerValue() {
if (bigVal != null) {
return bigVal;
- } else {
- return BigInteger.valueOf(val);
}
+ return BigInteger.valueOf(val);
}
/**
@@ -109,9 +106,8 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
public long longValue() {
if (bigVal != null) {
return bigVal.longValue();
- } else {
- return val;
}
+ return val;
}
/**
@@ -159,7 +155,7 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
}
if (val == 0 || val == -1) {
return 0;
- } else {
+ }
// Binary search for bit length
int i = 32; // mask length
long m = (1L << i) - 1; // AND mask with ones in little end
@@ -193,7 +189,6 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
}
return i;
}
- }
/**
* Return the signum function of this object.
@@ -203,9 +198,8 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
public int signum() {
if (bigVal != null) {
return bigVal.signum();
- } else {
- return val > 0 ? 1 : val < 0 ? -1 : 0;
}
+ return val > 0 ? 1 : val < 0 ? -1 : 0;
}
/**
@@ -342,9 +336,8 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
public String toString() {
if (bigVal != null) {
return "" + bigVal;
- } else {
- return "" + val;
}
+ return "" + val;
}
/**
@@ -392,8 +385,7 @@ public class OtpErlangLong extends OtpErlangObject implements Serializable,
protected int doHashCode() {
if (bigVal != null) {
return bigVal.hashCode();
- } else {
- return BigInteger.valueOf(val).hashCode();
}
+ return BigInteger.valueOf(val).hashCode();
}
}
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..7f1a64b87d 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
@@ -18,7 +18,6 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang maps. Maps are created from one or
@@ -29,8 +28,7 @@ import java.io.Serializable;
* values can be retrieved as arrays and the value for a key can be queried.
*
*/
-public class OtpErlangMap extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangMap extends OtpErlangObject {
// don't change this!
private static final long serialVersionUID = -6410770117696198497L;
@@ -58,15 +56,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/OtpErlangObject.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
index 81220c5685..5215e5887b 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
@@ -171,14 +171,14 @@ public abstract class OtpErlangObject implements Serializable, Cloneable {
for (j = 0, k = 0;
j + 4 < b.length;
j += 4, k += 1, k %= 3) {
- abc[k] += ((int)b[j+0] & 0xFF) + ((int)b[j+1]<<8 & 0xFF00)
- + ((int)b[j+2]<<16 & 0xFF0000) + ((int)b[j+3]<<24);
+ abc[k] += (b[j+0] & 0xFF) + (b[j+1]<<8 & 0xFF00)
+ + (b[j+2]<<16 & 0xFF0000) + (b[j+3]<<24);
mix();
}
for (int n = 0, m = 0xFF;
j < b.length;
j++, n += 8, m <<= 8) {
- abc[k] += (int)b[j]<<n & m;
+ abc[k] += b[j]<<n & m;
}
mix();
}
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..4c9f5c78a3 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPid.java
@@ -18,16 +18,14 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang PIDs. PIDs represent Erlang
* processes and consist of a nodename and a number of integers.
*/
-public class OtpErlangPid extends OtpErlangObject implements Serializable,
- Cloneable, Comparable<Object> {
+public class OtpErlangPid extends OtpErlangObject implements Comparable<Object> {
// don't change this!
- static final long serialVersionUID = 1664394142301803659L;
+ private static final long serialVersionUID = 1664394142301803659L;
private final String node;
private final int id;
@@ -162,7 +160,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.
@@ -197,14 +195,11 @@ public class OtpErlangPid extends OtpErlangObject implements Serializable,
if (serial == pid.serial) {
if (id == pid.id) {
return node.compareTo(pid.node);
- } else {
+ }
return id - pid.id;
}
- } else {
return serial - pid.serial;
}
- } else {
return creation - pid.creation;
}
}
-}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java
index 2a0eab0a9c..8557e17325 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangPort.java
@@ -18,15 +18,13 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang ports.
*/
-public class OtpErlangPort extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangPort extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = 4037115468007644704L;
+ private static final long serialVersionUID = 4037115468007644704L;
private final String node;
private final int id;
@@ -40,6 +38,7 @@ public class OtpErlangPort extends OtpErlangObject implements Serializable,
*
* @deprecated use OtpLocalNode:createPort() instead
*/
+ @SuppressWarnings("unused")
private OtpErlangPort(final OtpSelf self) {
final OtpErlangPort p = self.createPort();
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java
index 8056439962..13a83333fa 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangRef.java
@@ -18,17 +18,15 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang refs. There are two styles of Erlang
* refs, old style (one id value) and new style (array of id values). This class
* manages both types.
*/
-public class OtpErlangRef extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangRef extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = -7022666480768586521L;
+ private static final long serialVersionUID = -7022666480768586521L;
private final String node;
private final int creation;
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java
index cd232570dd..6ef56defbd 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangShort.java
@@ -18,13 +18,11 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang integral types.
*/
-public class OtpErlangShort extends OtpErlangLong implements Serializable,
- Cloneable {
+public class OtpErlangShort extends OtpErlangLong {
// don't change this!
static final long serialVersionUID = 7162345156603088099L;
@@ -57,7 +55,7 @@ public class OtpErlangShort extends OtpErlangLong implements Serializable,
throws OtpErlangRangeException, OtpErlangDecodeException {
super(buf);
- final short j = shortValue();
+ shortValue();
}
}
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..1bccfcc567 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangString.java
@@ -18,17 +18,14 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
-import java.lang.Character;
import java.io.UnsupportedEncodingException;
/**
* Provides a Java representation of Erlang strings.
*/
-public class OtpErlangString extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangString extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = -7053595217604929233L;
+ private static final long serialVersionUID = -7053595217604929233L;
private final String str;
@@ -41,8 +38,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.
@@ -140,6 +135,7 @@ public class OtpErlangString extends OtpErlangObject implements Serializable,
return false;
}
+ @Override
protected int doHashCode() {
return str.hashCode();
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
index bffce7f14d..dffaa530cd 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
@@ -18,7 +18,6 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang tuples. Tuples are created from one
@@ -29,10 +28,9 @@ import java.io.Serializable;
* indexed from 0 to (arity-1) and can be retrieved individually by using the
* appropriate index.
*/
-public class OtpErlangTuple extends OtpErlangObject implements Serializable,
- Cloneable {
+public class OtpErlangTuple extends OtpErlangObject {
// don't change this!
- static final long serialVersionUID = 9163498658004915935L;
+ private static final long serialVersionUID = 9163498658004915935L;
private static final OtpErlangObject[] NO_ELEMENTS = new OtpErlangObject[0];
@@ -51,9 +49,8 @@ public class OtpErlangTuple extends OtpErlangObject implements Serializable,
if (elem == null) {
throw new java.lang.IllegalArgumentException(
"Tuple element cannot be null");
- } else {
- elems = new OtpErlangObject[] { elem };
}
+ elems = new OtpErlangObject[] { elem };
}
/**
@@ -242,6 +239,7 @@ public class OtpErlangTuple extends OtpErlangObject implements Serializable,
return true;
}
+ @Override
protected int doHashCode() {
OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
final int a = arity();
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java
index f01354d821..a02996e437 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUInt.java
@@ -18,13 +18,11 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang integral types.
*/
-public class OtpErlangUInt extends OtpErlangLong implements Serializable,
- Cloneable {
+public class OtpErlangUInt extends OtpErlangLong {
// don't change this!
static final long serialVersionUID = -1450956122937471885L;
@@ -40,7 +38,7 @@ public class OtpErlangUInt extends OtpErlangLong implements Serializable,
public OtpErlangUInt(final int i) throws OtpErlangRangeException {
super(i);
- final int j = uIntValue();
+ uIntValue();
}
/**
@@ -62,6 +60,6 @@ public class OtpErlangUInt extends OtpErlangLong implements Serializable,
throws OtpErlangRangeException, OtpErlangDecodeException {
super(buf);
- final int j = uIntValue();
+ uIntValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java
index 6b6bc7a56b..e9d251f815 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangUShort.java
@@ -18,13 +18,11 @@
*/
package com.ericsson.otp.erlang;
-import java.io.Serializable;
/**
* Provides a Java representation of Erlang integral types.
*/
-public class OtpErlangUShort extends OtpErlangLong implements Serializable,
- Cloneable {
+public class OtpErlangUShort extends OtpErlangLong {
// don't change this!
static final long serialVersionUID = 300370950578307246L;
@@ -40,7 +38,7 @@ public class OtpErlangUShort extends OtpErlangLong implements Serializable,
public OtpErlangUShort(final short s) throws OtpErlangRangeException {
super(s);
- final short j = uShortValue();
+ uShortValue();
}
/**
@@ -62,6 +60,6 @@ public class OtpErlangUShort extends OtpErlangLong implements Serializable,
throws OtpErlangRangeException, OtpErlangDecodeException {
super(buf);
- final short j = uShortValue();
+ uShortValue();
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java
index 33d25b6021..874c7da104 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpException.java
@@ -22,6 +22,8 @@ package com.ericsson.otp.erlang;
* Base class for the other OTP exception classes.
*/
public abstract class OtpException extends Exception {
+ private static final long serialVersionUID = 1L;
+
/**
* Provides no message.
*/
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..bab0629382 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.
@@ -84,16 +85,17 @@ public class OtpInputStream extends ByteArrayInputStream {
*
* @return the previous position in the stream.
*/
- public int setPos(int pos) {
+ public int setPos(final int pos) {
final int oldpos = super.pos;
+ int apos = pos;
if (pos > super.count) {
- pos = super.count;
+ apos = super.count;
} else if (pos < 0) {
- pos = 0;
+ apos = 0;
}
- super.pos = pos;
+ super.pos = apos;
return oldpos;
}
@@ -107,8 +109,8 @@ public class OtpInputStream extends ByteArrayInputStream {
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
- public int readN(final byte[] buf) throws OtpErlangDecodeException {
- return this.readN(buf, 0, buf.length);
+ public int readN(final byte[] abuf) throws OtpErlangDecodeException {
+ return this.readN(abuf, 0, abuf.length);
}
/**
@@ -120,12 +122,12 @@ public class OtpInputStream extends ByteArrayInputStream {
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
- public int readN(final byte[] buf, final int off, final int len)
+ public int readN(final byte[] abuf, final int off, final int len)
throws OtpErlangDecodeException {
if (len == 0 && available() == 0) {
return 0;
}
- final int i = super.read(buf, off, len);
+ final int i = super.read(abuf, off, len);
if (i < 0) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
@@ -213,7 +215,6 @@ public class OtpInputStream extends ByteArrayInputStream {
} catch (final IOException e) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- ;
return (b[0] << 8 & 0xff00) + (b[1] & 0xff);
}
@@ -232,7 +233,6 @@ public class OtpInputStream extends ByteArrayInputStream {
} catch (final IOException e) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- ;
return (b[0] << 24 & 0xff000000) + (b[1] << 16 & 0xff0000)
+ (b[2] << 8 & 0xff00) + (b[3] & 0xff);
}
@@ -252,7 +252,6 @@ public class OtpInputStream extends ByteArrayInputStream {
} catch (final IOException e) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- ;
return (b[1] << 8 & 0xff00) + (b[0] & 0xff);
}
@@ -271,7 +270,6 @@ public class OtpInputStream extends ByteArrayInputStream {
} catch (final IOException e) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- ;
return (b[3] << 24 & 0xff000000) + (b[2] << 16 & 0xff0000)
+ (b[1] << 8 & 0xff00) + (b[0] & 0xff);
}
@@ -287,17 +285,17 @@ public class OtpInputStream extends ByteArrayInputStream {
* @exception OtpErlangDecodeException
* if the next byte cannot be read.
*/
- public long readLE(int n) throws OtpErlangDecodeException {
+ public long readLE(final int n) throws OtpErlangDecodeException {
final byte[] b = new byte[n];
try {
super.read(b);
} catch (final IOException e) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- ;
long v = 0;
- while (n-- > 0) {
- v = v << 8 | (long) b[n] & 0xff;
+ int i = n;
+ while (i-- > 0) {
+ v = v << 8 | (long) b[i] & 0xff;
}
return v;
}
@@ -320,7 +318,6 @@ public class OtpInputStream extends ByteArrayInputStream {
} catch (final IOException e) {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- ;
long v = 0;
for (int i = 0; i < n; i++) {
v = v << 8 | (long) b[i] & 0xff;
@@ -349,6 +346,7 @@ public class OtpInputStream extends ByteArrayInputStream {
* @exception OtpErlangDecodeException
* if the next term in the stream is not an atom.
*/
+ @SuppressWarnings("fallthrough")
public String read_atom() throws OtpErlangDecodeException {
int tag;
int len = -1;
@@ -381,7 +379,7 @@ public class OtpInputStream extends ByteArrayInputStream {
case OtpExternal.smallAtomUtf8Tag:
len = read1();
- /* fall through */
+ // fall-through
case OtpExternal.atomUtf8Tag:
if (len < 0) {
len = read2BE();
@@ -819,7 +817,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 +842,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++) {
@@ -1054,7 +1052,7 @@ public class OtpInputStream extends ByteArrayInputStream {
}
return new OtpErlangFun(pid, module, index, uniq, freeVars);
} else if (tag == OtpExternal.newFunTag) {
- final int n = read4BE();
+ read4BE();
final int arity = read1();
final byte[] md5 = new byte[16];
readN(md5);
@@ -1148,13 +1146,13 @@ public class OtpInputStream extends ByteArrayInputStream {
}
final int size = read4BE();
- final byte[] buf = new byte[size];
+ final byte[] abuf = new byte[size];
final java.util.zip.InflaterInputStream is =
new java.util.zip.InflaterInputStream(this, new java.util.zip.Inflater(), size);
int curPos = 0;
try {
int curRead;
- while(curPos < size && (curRead = is.read(buf, curPos, size - curPos)) != -1) {
+ while(curPos < size && (curRead = is.read(abuf, curPos, size - curPos)) != -1) {
curPos += curRead;
}
if (curPos != size) {
@@ -1165,7 +1163,8 @@ public class OtpInputStream extends ByteArrayInputStream {
throw new OtpErlangDecodeException("Cannot read from input stream");
}
- final OtpInputStream ois = new OtpInputStream(buf, flags);
+ @SuppressWarnings("resource")
+ final OtpInputStream ois = new OtpInputStream(abuf, flags);
return ois.read_any();
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java
index 903a446258..a5a4d86602 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMD5.java
@@ -101,8 +101,11 @@ class OtpMD5 {
private void to_buffer(int to_start, final int[] from, int from_start,
int num) {
- while (num-- > 0) {
- buffer[to_start++] = from[from_start++];
+ int ix = num;
+ int to_ix = to_start;
+ int from_ix = from_start;
+ while (ix-- > 0) {
+ buffer[to_ix++] = from[from_ix++];
}
}
@@ -121,7 +124,7 @@ class OtpMD5 {
count[1] = plus(count[1], shr(inlen, 29));
- /* dumpstate(); */
+ // dumpstate();
if (inlen >= partlen) {
to_buffer(index, bytes, 0, (int) partlen);
@@ -144,6 +147,7 @@ class OtpMD5 {
}
+ @SuppressWarnings("unused")
private void dumpstate() {
System.out.println("state = {" + state[0] + ", " + state[1] + ", "
+ state[2] + ", " + state[3] + "}");
@@ -185,30 +189,30 @@ class OtpMD5 {
private long FF(long a, final long b, final long c, final long d,
final long x, final long s, final long ac) {
- a = plus(a, plus(plus(F(b, c, d), x), ac));
- a = ROTATE_LEFT(a, s);
- return plus(a, b);
+ long tmp = plus(a, plus(plus(F(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
private long GG(long a, final long b, final long c, final long d,
final long x, final long s, final long ac) {
- a = plus(a, plus(plus(G(b, c, d), x), ac));
- a = ROTATE_LEFT(a, s);
- return plus(a, b);
+ long tmp = plus(a, plus(plus(G(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
private long HH(long a, final long b, final long c, final long d,
final long x, final long s, final long ac) {
- a = plus(a, plus(plus(H(b, c, d), x), ac));
- a = ROTATE_LEFT(a, s);
- return plus(a, b);
+ long tmp = plus(a, plus(plus(H(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
private long II(long a, final long b, final long c, final long d,
final long x, final long s, final long ac) {
- a = plus(a, plus(plus(I(b, c, d), x), ac));
- a = ROTATE_LEFT(a, s);
- return plus(a, b);
+ long tmp = plus(a, plus(plus(I(b, c, d), x), ac));
+ tmp = ROTATE_LEFT(tmp, s);
+ return plus(tmp, b);
}
private void decode(final long output[], final int input[],
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..fc592c222c 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
@@ -127,14 +128,14 @@ public class OtpMbox {
* supercede that name.
* </p>
*
- * @param name
+ * @param aname
* the name to register for the mailbox. Specify null to
* unregister the existing name from this mailbox.
*
* @return true if the name was available, or false otherwise.
*/
- public synchronized boolean registerName(final String name) {
- return home.registerName(name, this);
+ public synchronized boolean registerName(final String aname) {
+ return home.registerName(aname, this);
}
/**
@@ -349,21 +350,21 @@ public class OtpMbox {
* Send a message to a named mailbox created from the same node as this
* mailbox.
*
- * @param name
+ * @param aname
* the registered name of recipient mailbox.
*
* @param msg
* the body of the message to send.
*
*/
- public void send(final String name, final OtpErlangObject msg) {
- home.deliver(new OtpMsg(self, name, (OtpErlangObject) msg.clone()));
+ public void send(final String aname, final OtpErlangObject msg) {
+ home.deliver(new OtpMsg(self, aname, (OtpErlangObject) msg.clone()));
}
/**
* Send a message to a named mailbox created from another node.
*
- * @param name
+ * @param aname
* the registered name of recipient mailbox.
*
* @param node
@@ -374,23 +375,23 @@ public class OtpMbox {
* the body of the message to send.
*
*/
- public void send(final String name, final String node,
+ public void send(final String aname, final String node,
final OtpErlangObject msg) {
try {
final String currentNode = home.node();
if (node.equals(currentNode)) {
- send(name, msg);
+ send(aname, msg);
} else if (node.indexOf('@', 0) < 0
&& node.equals(currentNode.substring(0, currentNode
.indexOf('@', 0)))) {
- send(name, msg);
+ send(aname, msg);
} else {
// other node
final OtpCookedConnection conn = home.getConnection(node);
if (conn == null) {
return;
}
- conn.send(self, name, msg);
+ conn.send(self, aname, msg);
}
} catch (final Exception e) {
}
@@ -420,7 +421,6 @@ public class OtpMbox {
/**
* Equivalent to <code>exit(new OtpErlangAtom(reason))</code>.
- * </p>
*
* @see #exit(OtpErlangObject)
*/
@@ -629,8 +629,8 @@ public class OtpMbox {
* @return the {@link OtpErlangPid pid} corresponding to the registered
* name, or null if the name is not known on this node.
*/
- public OtpErlangPid whereis(final String name) {
- return home.whereis(name);
+ public OtpErlangPid whereis(final String aname) {
+ return home.whereis(aname);
}
/**
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..7c5bc69361 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
@@ -129,13 +129,14 @@ public class OtpMsg {
}
// other message types (link, unlink)
- OtpMsg(int tag, final OtpErlangPid from, final OtpErlangPid to) {
+ OtpMsg(final int tag, final OtpErlangPid from, final OtpErlangPid to) {
// convert TT-tags to equiv non-TT versions
+ int atag = tag;
if (tag > 10) {
- tag -= 10;
+ atag -= 10;
}
- this.tag = tag;
+ this.tag = atag;
this.from = from;
this.to = to;
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java
index 7ead0b9c54..68addb9f2c 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpNode.java
@@ -74,7 +74,7 @@ public class OtpNode extends OtpLocalNode {
OtpNodeStatus handler;
// flags
- private int flags = 0;
+ private int connFlags = 0;
/**
* <p>
@@ -143,12 +143,12 @@ public class OtpNode extends OtpLocalNode {
init(port);
}
- private synchronized void init(final int port) throws IOException {
+ private synchronized void init(final int aport) throws IOException {
if (!initDone) {
connections = new Hashtable<String, OtpCookedConnection>(17,
(float) 0.95);
mboxes = new Mailboxes();
- acceptor = new Acceptor(port);
+ acceptor = new Acceptor(aport);
initDone = true;
}
}
@@ -314,13 +314,13 @@ public class OtpNode extends OtpLocalNode {
* OtpNodeStatus} handler object contains callback methods, that will be
* called when certain events occur.
*
- * @param handler
+ * @param ahandler
* the callback object to register. To clear the handler, specify
* null as the handler to use.
*
*/
- public synchronized void registerStatusHandler(final OtpNodeStatus handler) {
- this.handler = handler;
+ public synchronized void registerStatusHandler(final OtpNodeStatus ahandler) {
+ this.handler = ahandler;
}
/**
@@ -344,7 +344,7 @@ public class OtpNode extends OtpLocalNode {
* ;
* </pre>
*
- * @param node
+ * @param anode
* the name of the node to ping.
*
* @param timeout
@@ -362,11 +362,11 @@ public class OtpNode extends OtpLocalNode {
*
* the reply: <- SEND {2,'',#Pid<[email protected]>} {#Ref<[email protected]>,yes}
*/
- public boolean ping(final String node, final long timeout) {
- if (node.equals(this.node)) {
+ public boolean ping(final String anode, final long timeout) {
+ if (anode.equals(this.node)) {
return true;
- } else if (node.indexOf('@', 0) < 0
- && node.equals(this.node
+ } else if (anode.indexOf('@', 0) < 0
+ && anode.equals(this.node
.substring(0, this.node.indexOf('@', 0)))) {
return true;
}
@@ -375,7 +375,7 @@ public class OtpNode extends OtpLocalNode {
OtpMbox mbox = null;
try {
mbox = createMbox();
- mbox.send("net_kernel", node, getPingTuple(mbox));
+ mbox.send("net_kernel", anode, getPingTuple(mbox));
final OtpErlangObject reply = mbox.receive(timeout);
final OtpErlangTuple t = (OtpErlangTuple) reply;
@@ -392,17 +392,17 @@ public class OtpNode extends OtpLocalNode {
private OtpErlangTuple getPingTuple(final OtpMbox mbox) {
final OtpErlangObject[] ping = new OtpErlangObject[3];
final OtpErlangObject[] pid = new OtpErlangObject[2];
- final OtpErlangObject[] node = new OtpErlangObject[2];
+ final OtpErlangObject[] anode = new OtpErlangObject[2];
pid[0] = mbox.self();
pid[1] = createRef();
- node[0] = new OtpErlangAtom("is_auth");
- node[1] = new OtpErlangAtom(node());
+ anode[0] = new OtpErlangAtom("is_auth");
+ anode[1] = new OtpErlangAtom(node());
ping[0] = new OtpErlangAtom("$gen_call");
ping[1] = new OtpErlangTuple(pid);
- ping[2] = new OtpErlangTuple(node);
+ ping[2] = new OtpErlangTuple(anode);
return new OtpErlangTuple(ping);
}
@@ -450,9 +450,8 @@ public class OtpNode extends OtpLocalNode {
/* special case for netKernel requests */
if (name.equals("net_kernel")) {
return netKernel(m);
- } else {
- mbox = mboxes.get(name);
}
+ mbox = mboxes.get(name);
} else {
mbox = mboxes.get(m.getRecipientPid());
}
@@ -480,23 +479,23 @@ public class OtpNode extends OtpLocalNode {
/*
* find or create a connection to the given node
*/
- OtpCookedConnection getConnection(final String node) {
+ OtpCookedConnection getConnection(final String anode) {
OtpPeer peer = null;
OtpCookedConnection conn = null;
synchronized (connections) {
// first just try looking up the name as-is
- conn = connections.get(node);
+ conn = connections.get(anode);
if (conn == null) {
// in case node had no '@' add localhost info and try again
- peer = new OtpPeer(node);
+ peer = new OtpPeer(anode);
conn = connections.get(peer.node());
if (conn == null) {
try {
conn = new OtpCookedConnection(this, peer);
- conn.setFlags(flags);
+ conn.setFlags(connFlags);
addConnection(conn);
} catch (final Exception e) {
/* false = outgoing */
@@ -522,35 +521,35 @@ public class OtpNode extends OtpLocalNode {
}
/* use these wrappers to call handler functions */
- private synchronized void remoteStatus(final String node, final boolean up,
+ private synchronized void remoteStatus(final String anode, final boolean up,
final Object info) {
if (handler == null) {
return;
}
try {
- handler.remoteStatus(node, up, info);
+ handler.remoteStatus(anode, up, info);
} catch (final Exception e) {
}
}
- synchronized void localStatus(final String node, final boolean up,
+ synchronized void localStatus(final String anode, final boolean up,
final Object info) {
if (handler == null) {
return;
}
try {
- handler.localStatus(node, up, info);
+ handler.localStatus(anode, up, info);
} catch (final Exception e) {
}
}
- synchronized void connAttempt(final String node, final boolean incoming,
+ synchronized void connAttempt(final String anode, final boolean incoming,
final Object info) {
if (handler == null) {
return;
}
try {
- handler.connAttempt(node, incoming, info);
+ handler.connAttempt(anode, incoming, info);
} catch (final Exception e) {
}
}
@@ -684,13 +683,13 @@ public class OtpNode extends OtpLocalNode {
*/
public class Acceptor extends Thread {
private final ServerSocket sock;
- private final int port;
+ private final int acceptorPort;
private volatile boolean done = false;
Acceptor(final int port) throws IOException {
sock = new ServerSocket(port);
- this.port = sock.getLocalPort();
- OtpNode.this.port = this.port;
+ this.acceptorPort = sock.getLocalPort();
+ OtpNode.this.port = this.acceptorPort;
setDaemon(true);
setName("acceptor");
@@ -741,7 +740,7 @@ public class OtpNode extends OtpLocalNode {
}
public int port() {
- return port;
+ return acceptorPort;
}
@Override
@@ -771,7 +770,7 @@ public class OtpNode extends OtpLocalNode {
try {
synchronized (connections) {
conn = new OtpCookedConnection(OtpNode.this, newsock);
- conn.setFlags(flags);
+ conn.setFlags(connFlags);
addConnection(conn);
}
} catch (final OtpAuthException e) {
@@ -802,6 +801,6 @@ public class OtpNode extends OtpLocalNode {
}
public void setFlags(final int flags) {
- this.flags = flags;
+ this.connFlags = flags;
}
}
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..ef60a9f38a 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -25,7 +25,6 @@ import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
-import java.util.Arrays;
import java.util.zip.Deflater;
/**
@@ -45,8 +44,11 @@ public class OtpOutputStream extends ByteArrayOutputStream {
public static final int defaultIncrement = 2048;
// static formats, used to encode floats and doubles
+ @SuppressWarnings("unused")
private static final DecimalFormat eform = new DecimalFormat("e+00;e-00");
+ @SuppressWarnings("unused")
private static final BigDecimal ten = new BigDecimal(10.0);
+ @SuppressWarnings("unused")
private static final BigDecimal one = new BigDecimal(1.0);
private int fixedSize = Integer.MAX_VALUE;
@@ -159,9 +161,9 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* @see java.io.ByteArrayOutputStream#write(byte[])
*/
@Override
- public void write(final byte[] buf) {
+ public void write(final byte[] abuf) {
// don't assume that super.write(byte[]) calls write(buf, 0, buf.length)
- write(buf, 0, buf.length);
+ write(abuf, 0, abuf.length);
}
/* (non-Javadoc)
@@ -202,7 +204,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
/**
* Write an array of bytes to the stream.
*
- * @param buf
+ * @param bytes
* the array of bytes to write.
*
*/
@@ -285,10 +287,11 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* @param b
* the number of bytes to write from the little end.
*/
- public void writeLE(long n, final int b) {
+ public void writeLE(final long n, final int b) {
+ long v = n;
for (int i = 0; i < b; i++) {
- write((byte) (n & 0xff));
- n >>= 8;
+ write((byte) (v & 0xff));
+ v >>= 8;
}
}
@@ -518,16 +521,17 @@ public class OtpOutputStream extends ByteArrayOutputStream {
write_double(f);
}
- public void write_big_integer(BigInteger v) {
+ public void write_big_integer(final BigInteger v) {
if (v.bitLength() < 64) {
this.write_long(v.longValue(), true);
return;
}
final int signum = v.signum();
+ BigInteger val = v;
if (signum < 0) {
- v = v.negate();
+ val = val.negate();
}
- final byte[] magnitude = v.toByteArray();
+ final byte[] magnitude = val.toByteArray();
final int n = magnitude.length;
// Reverse the array to make it little endian.
for (int i = 0, j = n; i < j--; i++) {
@@ -568,7 +572,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
int n;
long mask;
for (mask = 0xFFFFffffL, n = 4; (abs & mask) != abs; n++, mask = mask << 8 | 0xffL) {
- ; // count nonzero bytes
+ // count nonzero bytes
}
write1(OtpExternal.smallBigTag);
write1(n); // length
@@ -637,7 +641,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) {
@@ -827,7 +831,6 @@ public class OtpOutputStream extends ByteArrayOutputStream {
write_nil(); // it should never ever get here...
}
} else { // unicode or longer, must code as list
- final char[] charbuf = s.toCharArray();
final int[] codePoints = OtpErlangString.stringToCodePoints(s);
write_list_head(codePoints.length);
for (final int codePoint : codePoints) {
@@ -867,6 +870,7 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* the compression level (<tt>0..9</tt>)
*/
public void write_compressed(final OtpErlangObject o, int level) {
+ @SuppressWarnings("resource")
final OtpOutputStream oos = new OtpOutputStream(o);
/*
* similar to erts_term_to_binary() in external.c:
@@ -920,6 +924,11 @@ public class OtpOutputStream extends ByteArrayOutputStream {
"Intermediate stream failed for Erlang object " + o);
} finally {
this.fixedSize = Integer.MAX_VALUE;
+ try {
+ dos.close();
+ } catch (IOException e) {
+ // ignore
+ }
}
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src
new file mode 100644
index 0000000000..d25d9bc142
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.app.src
@@ -0,0 +1,32 @@
+%%
+%% %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%
+%%
+%% This is an -*- erlang -*- file.
+%%
+
+{application, jinterface,
+ [
+ {description, "Jinterface"},
+ {vsn, "%VSN%"},
+ {modules, []},
+ {registered, []},
+ {applications, []},
+ {env, []},
+ {runtime_dependencies, []}
+ ]
+}.
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src
new file mode 100644
index 0000000000..d267e3d3d5
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src
@@ -0,0 +1,18 @@
+%% -*- erlang -*-
+%% %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%
+{"%VSN%", [], []}.
diff --git a/lib/jinterface/test/jinterface_SUITE.erl b/lib/jinterface/test/jinterface_SUITE.erl
index cb725164cd..00abc97ff5 100644
--- a/lib/jinterface/test/jinterface_SUITE.erl
+++ b/lib/jinterface/test/jinterface_SUITE.erl
@@ -38,7 +38,8 @@
java_exit_with_reason_any_term/1,
status_handler_localStatus/1, status_handler_remoteStatus/1,
status_handler_connAttempt/1,
- maps/1
+ maps/1,
+ fun_equals/1
]).
-include_lib("common_test/include/ct.hrl").
@@ -106,7 +107,8 @@ fundamental() ->
register_and_whereis, % RegisterAndWhereis.java
get_names, % GetNames.java
boolean_atom, % BooleanAtom.java
- maps % Maps.java
+ maps, % Maps.java
+ fun_equals % FunEquals.java
].
ping() ->
@@ -691,6 +693,18 @@ maps(Config) when is_list(Config) ->
[]).
%%%-----------------------------------------------------------------
+fun_equals(doc) ->
+ ["FunEquals.java: "
+ "Test OtpErlangFun.equals()"];
+fun_equals(suite) ->
+ [];
+fun_equals(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "FunEquals",
+ []).
+
+%%%-----------------------------------------------------------------
%%% INTERNAL FUNCTIONS
%%%-----------------------------------------------------------------
send_receive(TestCaseTag,Fun,Config) ->
diff --git a/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java b/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java
new file mode 100644
index 0000000000..961e462cb3
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/FunEquals.java
@@ -0,0 +1,73 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. 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%
+ */
+
+import com.ericsson.otp.erlang.OtpErlangAtom;
+import com.ericsson.otp.erlang.OtpErlangFun;
+import com.ericsson.otp.erlang.OtpErlangLong;
+import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangPid;
+
+public class FunEquals {
+
+ /*
+ Implements test case jinterface_SUITE:fun_equals/1
+
+ Test the function OtpErlangFun.equals()
+ */
+
+ public static void main(String argv[]) {
+
+ OtpErlangPid pid = new OtpErlangPid("here", 4, 5, 0);
+ String module = "mod";
+ int arity = 2;
+ byte[] md5 = new byte[]{3,5,7};
+ int index = 2;
+ long old_index = 1;
+ long uniq= 2;
+ OtpErlangObject[] freeVars = new OtpErlangObject[]{
+ new OtpErlangAtom("hej"), new OtpErlangLong(9)
+ };
+
+ OtpErlangFun f1 = new OtpErlangFun(pid, module, arity, md5,
+ index, old_index, uniq, freeVars);
+ OtpErlangFun f2 = new OtpErlangFun(pid, module, arity, copyArray(md5),
+ index, old_index, uniq, copyArray(freeVars));
+
+ if(!f1.equals(f2))
+ fail(1);
+
+ }
+
+ private static void fail(int reason) {
+ System.exit(reason);
+ }
+
+ private static byte[] copyArray(byte[] source) {
+ byte[] result = new byte[source.length];
+ System.arraycopy(source, 0, result, 0, source.length);
+ return result;
+ }
+
+ private static OtpErlangObject[] copyArray(OtpErlangObject[] source) {
+ OtpErlangObject[] result = new OtpErlangObject[source.length];
+ System.arraycopy(source, 0, result, 0, source.length);
+ return result;
+ }
+
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/GetNames.java b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
index 3d2bc4ac84..54efaad242 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
@@ -18,7 +18,9 @@
*/
import java.util.ArrayList;
-import com.ericsson.otp.erlang.*;
+
+import com.ericsson.otp.erlang.OtpMbox;
+import com.ericsson.otp.erlang.OtpNode;
class GetNames {
@@ -37,7 +39,7 @@ class GetNames {
OtpMbox mbox3 = node.createMbox();
node.registerName("mbox3",mbox3);
- ArrayList existing_names = new ArrayList();
+ ArrayList<String> existing_names = new ArrayList<String>();
existing_names.add("mbox3");
existing_names.add("mbox2");
existing_names.add("mbox1");
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Makefile.src b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
index a15ed1aa63..cd68f1ead5 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
+++ b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
@@ -47,7 +47,8 @@ JAVA_FILES = \
MboxSendReceive.java \
MboxLinkUnlink.java \
NodeStatusHandler.java \
- Maps.java
+ Maps.java \
+ FunEquals.java
CLASS_FILES = $(JAVA_FILES:.java=.class)
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
index 5d1d097cc8..470fdb4a14 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
@@ -17,7 +17,14 @@
* %CopyrightEnd%
*/
-import com.ericsson.otp.erlang.*;
+import com.ericsson.otp.erlang.OtpErlangAtom;
+import com.ericsson.otp.erlang.OtpErlangExit;
+import com.ericsson.otp.erlang.OtpErlangLong;
+import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangPid;
+import com.ericsson.otp.erlang.OtpErlangTuple;
+import com.ericsson.otp.erlang.OtpMbox;
+import com.ericsson.otp.erlang.OtpNode;
class MboxLinkUnlink {
@@ -66,7 +73,10 @@ class MboxLinkUnlink {
OtpErlangObject[] msg = {mainMbox.self(),mbox.self()};
mbox.send("erl_link_server", erlNode, new OtpErlangTuple(msg));
OtpErlangObject o = mbox.receive(1000);
- if (o == null) System.exit(1);
+ if (o == null) {
+ System.exit(1);
+ return;
+ }
OtpErlangTuple tuple = (OtpErlangTuple)o;
int tag = (int)((OtpErlangLong)tuple.elementAt(0)).longValue();
@@ -91,6 +101,7 @@ class MboxLinkUnlink {
expected = tuple.elementAt(2);
mbox.receive(1000);
System.exit(2);
+ break;
case erl_link_java_exit:
dbg("Java got \"erl_link_java_exit\"");
mbox.exit(tuple.elementAt(2));
@@ -104,6 +115,7 @@ class MboxLinkUnlink {
expected = tuple.elementAt(2);
mbox.receive(1000);
System.exit(3);
+ break;
case internal_link_linking_exits:
dbg("Java got \"internal_link_linking_exits\"");
mbox2 = node.createMbox();
@@ -113,6 +125,7 @@ class MboxLinkUnlink {
expected = tuple.elementAt(2);
mbox2.receive(1000); // hanging waiting for exit
System.exit(4); // got someting other than exit
+ break;
case internal_link_linked_exits:
dbg("Java got \"internal_link_linked_exits\"");
mbox2 = node.createMbox();
@@ -122,6 +135,7 @@ class MboxLinkUnlink {
expected = tuple.elementAt(2);
mbox.receive(1000); // hanging waiting for exit
System.exit(5); // got someting other than exit
+ break;
case internal_unlink_linking_exits:
dbg("Java got \"internal_unlink_linking_exits\"");
mbox2 = node.createMbox();
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
index 2db71bb5cd..44433aa619 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
@@ -17,7 +17,13 @@
* %CopyrightEnd%
*/
-import com.ericsson.otp.erlang.*;
+import com.ericsson.otp.erlang.OtpErlangAtom;
+import com.ericsson.otp.erlang.OtpErlangLong;
+import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangPid;
+import com.ericsson.otp.erlang.OtpErlangTuple;
+import com.ericsson.otp.erlang.OtpMbox;
+import com.ericsson.otp.erlang.OtpNode;
class MboxSendReceive {
@@ -35,6 +41,7 @@ class MboxSendReceive {
private static final int java_internal_send_receive_different_nodes = 3;
private static final int java_internal_send_receive_self = 4;
+ @SuppressWarnings("null")
public static void main(String argv[]) {
String cookie = argv[0];
diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
index 51ea15b5ef..06ddfa2d61 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
@@ -17,7 +17,14 @@
* %CopyrightEnd%
*/
-import com.ericsson.otp.erlang.*;
+import com.ericsson.otp.erlang.OtpErlangAtom;
+import com.ericsson.otp.erlang.OtpErlangBoolean;
+import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangString;
+import com.ericsson.otp.erlang.OtpErlangTuple;
+import com.ericsson.otp.erlang.OtpMbox;
+import com.ericsson.otp.erlang.OtpNode;
+import com.ericsson.otp.erlang.OtpNodeStatus;
public class NodeStatusHandler extends OtpNodeStatus {
/*
@@ -86,7 +93,10 @@ public class NodeStatusHandler extends OtpNodeStatus {
}
OtpErlangObject o = mbox.receive(recTime);
- if (o == null) System.exit(2);
+ if (o == null) {
+ System.exit(2);
+ return;
+ }
if (! ((OtpErlangAtom)o).atomValue().equals("done"))
System.exit(3);
@@ -100,6 +110,7 @@ public class NodeStatusHandler extends OtpNodeStatus {
+ @Override
public void remoteStatus(String node, boolean up, Object info) {
try {
dbg("Got remoteStatus: " + node + " " + up + " " + info);
@@ -120,6 +131,7 @@ public class NodeStatusHandler extends OtpNodeStatus {
}
+ @Override
public void localStatus(String node, boolean up, Object info) {
try {
dbg("Got localStatus: " + node + " " + up + " " + info);
@@ -141,6 +153,7 @@ public class NodeStatusHandler extends OtpNodeStatus {
+@Override
public void connAttempt(String node, boolean incoming, Object info) {
try {
dbg("Got connAttempt: " + node + " " + incoming + " " + info);
diff --git a/lib/jinterface/test/nc_SUITE_data/echo_server.java b/lib/jinterface/test/nc_SUITE_data/echo_server.java
index 2e18e908d4..0e43ea0680 100644
--- a/lib/jinterface/test/nc_SUITE_data/echo_server.java
+++ b/lib/jinterface/test/nc_SUITE_data/echo_server.java
@@ -148,11 +148,13 @@ public class echo_server {
final String atomValue = ((OtpErlangAtom) t).atomValue();
if (atomValue.equals("binary") && i instanceof OtpErlangBinary) {
final OtpErlangBinary b = (OtpErlangBinary) i;
+ @SuppressWarnings("resource")
final OtpInputStream bis = new OtpInputStream(b.binaryValue(),
0);
final OtpErlangObject o = bis.read_any();
return o;
} else if (atomValue.equals("compress")) {
+ @SuppressWarnings("resource")
final OtpOutputStream oos = new OtpOutputStream();
oos.write1(OtpExternal.versionTag);
oos.write_compressed(i);
@@ -206,6 +208,7 @@ public class echo_server {
&& i instanceof OtpErlangString) {
final OtpErlangString s = (OtpErlangString) i;
final String ss = s.stringValue().substring(3, 6);
+ @SuppressWarnings("unused")
final int[] cps = OtpErlangString.stringToCodePoints(ss);
return s;
} else if (atomValue.equals("utf8")) {
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index c50200fab6..72ad316333 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1 +1 @@
-JINTERFACE_VSN = 1.5.9
+JINTERFACE_VSN = 1.5.12
diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml
index 3815b0877c..df2f0b01ee 100644
--- a/lib/kernel/doc/src/error_logger.xml
+++ b/lib/kernel/doc/src/error_logger.xml
@@ -58,7 +58,7 @@
specific events. (<c>add_report_handler/1,2</c>). Also, there is
a useful event handler in STDLIB for multi-file logging of events,
see <c>log_mf_h(3)</c>.</p>
- <p>Warning events was introduced in Erlang/OTP R9C. To retain
+ <p>Warning events were introduced in Erlang/OTP R9C. To retain
backwards compatibility, these are by default tagged as errors,
thus showing up as error reports in the logs. By using
the command line flag <c><![CDATA[+W <w | i>]]></c>, they can instead
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 8dae34431b..dcb9640dcf 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>
@@ -1291,6 +1283,8 @@
or before unix time epoch which is 1970-01-01 00:00 UTC.
Default is <c>{time, local}</c>.
</p>
+ <p>If the <c>raw</c> option is set, the file server will not be called
+ and only informations about local files will be returned.</p>
<note>
<p>
Since file times is stored in posix time on most OS it is
@@ -1517,6 +1511,8 @@
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 the <c>raw</c> option is set, the file server will not be called
+ and only informations about local files will be returned.</p>
<p>If <c><anno>Name</anno></c> is not a symbolic link, this function returns
exactly the same result as <c>read_file_info/1</c>.
On platforms that do not support symbolic links, this function
@@ -1855,6 +1851,8 @@
interpret it as universal time and <c>posix</c> must be seconds since
or before unix time epoch which is 1970-01-01 00:00 UTC.
Default is <c>{time, local}</c>.
+ <p>If the <c>raw</c> option is set, the file server will not be called
+ and only informations about local files will be returned.</p>
</p>
<p>The following fields are used from the record, if they are
given.</p>
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml
index dc9e4766a9..ee8cd441d4 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -961,7 +961,7 @@
<pre> #sctp_paddrinfo{
assoc_id = assoc_id(),
address = {IP, Port},
- state = inactive | active,
+ state = inactive | active | unconfirmed,
cwnd = integer(),
srtt = integer(),
rto = integer(),
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/inet.xml b/lib/kernel/doc/src/inet.xml
index 50e1cc290c..77a8caaaf6 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -138,7 +138,7 @@ fe80::204:acff:fe17:bf38
<name name="get_rc" arity="0"/>
<fsummary>Return a list of IP configuration parameters</fsummary>
<desc>
- <p>Returns the state of the Inet configuration database in
+ <p>Returns the state of the Inet configuration database in
form of a list of recorded configuration parameters. (See the
ERTS User's Guide, Inet configuration, for more information).
Only parameters with other than default values are returned.</p>
@@ -258,8 +258,8 @@ fe80::204:acff:fe17:bf38
<type name="socket_getopt"/>
<type name="socket_setopt"/>
<desc>
- <p>Gets one or more options for a socket.
- See <seealso marker="#setopts/2">setopts/2</seealso>
+ <p>Gets one or more options for a socket.
+ See <seealso marker="#setopts/2">setopts/2</seealso>
for a list of available options.</p>
<p>The number of elements in the returned <c><anno>OptionValues</anno></c>
list does not necessarily correspond to the number of options
@@ -278,14 +278,14 @@ fe80::204:acff:fe17:bf38
by the protocol level, the option number and either a binary
or the size, in bytes, of the
buffer in which the option value is to be stored. A binary
- should be used when the underlying <c>getsockopt</c> requires
+ should be used when the underlying <c>getsockopt</c> requires
<em>input</em>
in the argument field, in which case the size of the binary
should correspond to the required buffer
size of the return value. The supplied values in a <c>RawOptReq</c>
correspond to the second, third and fourth/fifth parameters to the
<c>getsockopt</c> call in the C socket API. The value stored
- in the buffer is returned as a binary <c>ValueBin</c>
+ in the buffer is returned as a binary <c>ValueBin</c>
where all values are coded in the native endianess.</p>
<p>Asking for and inspecting raw socket options require low
level information about the current operating system and TCP
@@ -306,7 +306,7 @@ fe80::204:acff:fe17:bf38
value to be a 32 bit integer. We could use the following
code to retrieve the value:</p>
<code type="none"><![CDATA[
- get_tcpi_sacked(Sock) ->
+ get_tcpi_sacked(Sock) ->
{ok,[{raw,_,_,Info}]} = inet:getopts(Sock,[{raw,6,11,92}]),
<<_:28/binary,TcpiSacked:32/native,_/binary>> = Info,
TcpiSacked.]]></code>
@@ -332,23 +332,23 @@ fe80::204:acff:fe17:bf38
<taglist>
<tag><c>recv_avg</c></tag>
<item>
- <p>Average size of packets in bytes received to the socket.</p>
+ <p>Average size of packets in bytes received by the socket.</p>
</item>
<tag><c>recv_cnt</c></tag>
<item>
- <p>Number of packets received to the socket.</p>
+ <p>Number of packets received by the socket.</p>
</item>
<tag><c>recv_dvi</c></tag>
<item>
- <p>Average packet size deviation in bytes received to the socket.</p>
+ <p>Average packet size deviation in bytes received by the socket.</p>
</item>
<tag><c>recv_max</c></tag>
<item>
- <p>The size of the largest packet in bytes received to the socket.</p>
+ <p>The size of the largest packet in bytes received by the socket.</p>
</item>
<tag><c>recv_oct</c></tag>
<item>
- <p>Number of bytes received to the socket.</p>
+ <p>Number of bytes received by the socket.</p>
</item>
<tag><c>send_avg</c></tag>
@@ -408,7 +408,7 @@ fe80::204:acff:fe17:bf38
<name name="parse_ipv6strict_address" arity="1" />
<fsummary>Parse an IPv6 address strict.</fsummary>
<desc>
- <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
+ <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
Does <b>not</b> accept IPv4 adresses.</p>
</desc>
</func>
@@ -613,15 +613,20 @@ fe80::204:acff:fe17:bf38
<marker id="option-buffer"></marker>
</item>
- <tag><c>{buffer, Size}</c></tag>
+ <tag><c>{buffer, Size}</c></tag>
<item>
- <p>Determines the size of the user-level software buffer used by
- the driver. Not to be confused with <c>sndbuf</c>
- and <c>recbuf</c> options which correspond to
- the kernel socket buffers. It is recommended
- to have <c>val(buffer) &gt;= max(val(sndbuf),val(recbuf))</c>.
- In fact, the <c>val(buffer)</c> is automatically set to
- the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.</p>
+ <p>The size of the user-level software buffer used by
+ the driver. Not to be confused with <c>sndbuf</c>
+ and <c>recbuf</c> options which correspond to
+ the kernel socket buffers. It is recommended
+ to have <c>val(buffer) &gt;= max(val(sndbuf),val(recbuf))</c> to
+ avoid performance issues due to unnecessary copying.
+ In fact, the <c>val(buffer)</c> is automatically set to
+ the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.
+ However, since the actual sizes set for <c>sndbuf</c> and <c>recbuf</c>
+ usually becomes larger, you are encouraged to use
+ <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso>
+ to analyze the behavior of your operating system.</p>
</item>
<tag><c>{delay_send, Boolean}</c></tag>
@@ -998,8 +1003,12 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
</item>
<tag><c>{recbuf, Size}</c></tag>
<item>
- <p>Gives the size of the receive buffer to use for
- the socket.</p>
+ <p>The minimum size of the receive buffer to use for
+ the socket. You are encouraged to use
+ <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso>,
+ to retrieve the actual size set by your operating system.
+
+ </p>
</item>
<tag><c>{reuseaddr, Boolean}</c></tag>
<item>
@@ -1030,20 +1039,24 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
<tag><c>{sndbuf, Size}</c></tag>
<item>
- <p>Gives the size of the send buffer to use for the socket.</p>
+ <p>The minimum size of the send buffer to use for the socket.
+ You are encouraged to use
+ <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso>,
+ to retrieve the actual size set by your operating system.
+ </p>
</item>
<tag><c>{priority, Integer}</c></tag>
<item>
- <p>Sets the SO_PRIORITY socket level option on platforms where
- this is implemented. The behaviour and allowed range varies on
- different systems. The option is ignored on platforms where the
+ <p>Sets the SO_PRIORITY socket level option on platforms where
+ this is implemented. The behaviour and allowed range varies on
+ different systems. The option is ignored on platforms where the
option is not implemented. Use with caution.</p>
</item>
<tag><c>{tos, Integer}</c></tag>
<item>
- <p>Sets IP_TOS IP level options on platforms where this is
- implemented. The behaviour and allowed range varies on different
- systems. The option is ignored on platforms where the option is
+ <p>Sets IP_TOS IP level options on platforms where this is
+ implemented. The behaviour and allowed range varies on different
+ systems. The option is ignored on platforms where the option is
not implemented. Use with caution.</p>
</item>
</taglist>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index c6538b7d05..1ef106e17a 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -30,6 +30,145 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure to install .hrl files when needed</p>
+ <p>
+ Own Id: OTP-12197</p>
+ </item>
+ <item>
+ <p>
+ Removed the undocumented application environment variable
+ 'raw_files' from the kernel application. This variable
+ was checked (by call to application:get_env/2) each time
+ a raw file was to be opened in the file module.</p>
+ <p>
+ Own Id: OTP-12276</p>
+ </item>
+ <item>
+ <p>
+ A bug has been fixed when using the netns option to
+ gen_udp, which accidentally only worked if it was the
+ last option.</p>
+ <p>
+ Own Id: OTP-12314</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Updated documentation for inet buffer size options.</p>
+ <p>
+ Own Id: OTP-12296</p>
+ </item>
+ <item>
+ <p>
+ Introduce new option 'raw' in file_info and link_info
+ functions. This option allows the caller not to go
+ through the file server for information about files
+ guaranteed to be local.</p>
+ <p>
+ Own Id: OTP-12325</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 3.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Accept inet:ip_address() in net_adm:names/1</p>
+ <p>
+ Own Id: OTP-12154</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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 +219,6 @@
</list>
</section>
-
<section><title>Improvements and New Features</title>
<list>
<item>
@@ -224,7 +362,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/Makefile b/lib/kernel/src/Makefile
index cb3c0a49f4..c7c70ad257 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -122,6 +122,7 @@ HRL_FILES= ../include/file.hrl ../include/inet.hrl ../include/inet_sctp.hrl \
../include/net_address.hrl
INTERNAL_HRL_FILES= application_master.hrl disk_log.hrl \
+ erl_epmd.hrl hipe_ext_format.hrl \
inet_dns.hrl inet_res.hrl \
inet_boot.hrl inet_config.hrl inet_int.hrl \
inet_dns_record_adts.hrl
diff --git a/lib/kernel/src/application_master.erl b/lib/kernel/src/application_master.erl
index bc15b5a7de..7cdbe31ab2 100644
--- a/lib/kernel/src/application_master.erl
+++ b/lib/kernel/src/application_master.erl
@@ -103,9 +103,9 @@ call(AppMaster, Req) ->
%%% The reason for not using the logical structrure is that
%%% the application start function is synchronous, and
%%% that the AM is GL. This means that if AM executed the start
-%%% function, and this function uses spawn_request/1
-%%% or io, deadlock would occur. Therefore, this function is
-%%% executed by the process X. Also, AM needs three loops;
+%%% function, and this function uses io, deadlock would occur.
+%%% Therefore, this function is executed by the process X.
+%%% Also, AM needs three loops;
%%% init_loop (waiting for the start function to return)
%%% main_loop
%%% terminate_loop (waiting for the process to die)
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/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl
index b4fae24ef3..f6e2ca0954 100644
--- a/lib/kernel/src/erl_epmd.erl
+++ b/lib/kernel/src/erl_epmd.erl
@@ -85,24 +85,19 @@ port_please1(Node,HostName, Timeout) ->
Else
end.
-names() ->
+names() ->
{ok, H} = inet:gethostname(),
names(H).
-names(HostName) when is_atom(HostName) ->
- names1(atom_to_list(HostName));
-names(HostName) when is_list(HostName) ->
- names1(HostName);
-names(EpmdAddr) ->
- get_names(EpmdAddr).
-
-names1(HostName) ->
+names(HostName) when is_atom(HostName); is_list(HostName) ->
case inet:gethostbyname(HostName) of
{ok,{hostent, _Name, _ , _Af, _Size, [EpmdAddr | _]}} ->
get_names(EpmdAddr);
Else ->
Else
- end.
+ end;
+names(EpmdAddr) ->
+ get_names(EpmdAddr).
register_node(Name, PortNo) ->
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 20b703e084..3d6665a36a 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -114,18 +114,10 @@
-type sendfile_option() :: {chunk_size, non_neg_integer()}
| {use_threads, boolean()}.
-type file_info_option() :: {'time', 'local'} | {'time', 'universal'}
- | {'time', 'posix'}.
+ | {'time', 'posix'} | raw.
%%% 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.
@@ -250,7 +242,19 @@ read_file_info(Name) ->
Reason :: posix() | badarg.
read_file_info(Name, Opts) when is_list(Opts) ->
- check_and_call(read_file_info, [file_name(Name), Opts]).
+ Args = [file_name(Name), Opts],
+ case check_args(Args) of
+ ok ->
+ case lists:member(raw, Opts) of
+ true ->
+ [FileName|_] = Args,
+ ?PRIM_FILE:read_file_info(FileName, Opts);
+ false ->
+ call(read_file_info, Args)
+ end;
+ Error ->
+ Error
+ end.
-spec altname(Name :: name_all()) -> any().
@@ -272,7 +276,19 @@ read_link_info(Name) ->
Reason :: posix() | badarg.
read_link_info(Name, Opts) when is_list(Opts) ->
- check_and_call(read_link_info, [file_name(Name),Opts]).
+ Args = [file_name(Name), Opts],
+ case check_args(Args) of
+ ok ->
+ case lists:member(raw, Opts) of
+ true ->
+ [FileName|_] = Args,
+ ?PRIM_FILE:read_link_info(FileName, Opts);
+ false ->
+ call(read_link_info, Args)
+ end;
+ Error ->
+ Error
+ end.
-spec read_link(Name) -> {ok, Filename} | {error, Reason} when
@@ -306,7 +322,19 @@ write_file_info(Name, Info = #file_info{}) ->
Reason :: posix() | badarg.
write_file_info(Name, Info = #file_info{}, Opts) when is_list(Opts) ->
- check_and_call(write_file_info, [file_name(Name), Info, Opts]).
+ Args = [file_name(Name), Info, Opts],
+ case check_args(Args) of
+ ok ->
+ case lists:member(raw, Opts) of
+ true ->
+ [FileName|_] = Args,
+ ?PRIM_FILE:write_file_info(FileName, Info, Opts);
+ false ->
+ call(write_file_info, Args)
+ end;
+ Error ->
+ Error
+ end.
-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when
Dir :: name_all(),
@@ -392,26 +420,12 @@ write_file(Name, Bin, ModeList) when is_list(ModeList) ->
%% Obsolete, undocumented, local node only, don't use!.
%% XXX to be removed.
raw_read_file_info(Name) ->
- Args = [file_name(Name)],
- case check_args(Args) of
- ok ->
- [FileName] = Args,
- ?PRIM_FILE:read_file_info(FileName);
- Error ->
- Error
- end.
+ read_file_info(Name, [raw]).
%% Obsolete, undocumented, local node only, don't use!.
%% XXX to be removed.
raw_write_file_info(Name, #file_info{} = Info) ->
- Args = [file_name(Name)],
- case check_args(Args) of
- ok ->
- [FileName] = Args,
- ?PRIM_FILE:write_file_info(FileName, Info);
- Error ->
- Error
- end.
+ write_file_info(Name, Info, [raw]).
%%%-----------------------------------------------------------------
%%% File io server functions.
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index 70dceb3679..860eec10a0 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -78,7 +78,7 @@
ipv6_v6only.
-type socket() :: port().
--export_type([option/0, option_name/0]).
+-export_type([option/0, option_name/0, socket/0]).
-spec open(Port) -> {ok, Socket} | {error, Reason} when
Port :: inet:port_number(),
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 41d422d7d4..ec2c350931 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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
@@ -695,9 +695,9 @@ connect_options(Opts, Family) ->
Error -> Error
end.
-con_opt([{raw,A,B,C}|Opts],R,As) ->
+con_opt([{raw,A,B,C}|Opts],#connect_opts{} = R,As) ->
con_opt([{raw,{A,B,C}}|Opts],R,As);
-con_opt([Opt | Opts], R, As) ->
+con_opt([Opt | Opts], #connect_opts{} = R, As) ->
case Opt of
{ip,IP} -> con_opt(Opts, R#connect_opts { ifaddr = IP }, As);
{ifaddr,IP} -> con_opt(Opts, R#connect_opts { ifaddr = IP }, As);
@@ -722,10 +722,10 @@ con_opt([Opt | Opts], R, As) ->
{Name,Val} when is_atom(Name) -> con_add(Name, Val, R, Opts, As);
_ -> {error, badarg}
end;
-con_opt([], R, _) ->
+con_opt([], #connect_opts{} = R, _) ->
{ok, R}.
-con_add(Name, Val, R, Opts, AllOpts) ->
+con_add(Name, Val, #connect_opts{} = R, Opts, AllOpts) ->
case add_opt(Name, Val, R#connect_opts.opts, AllOpts) of
{ok, SOpts} ->
con_opt(Opts, R#connect_opts { opts = SOpts }, AllOpts);
@@ -763,9 +763,9 @@ listen_options(Opts, Family) ->
Error -> Error
end.
-list_opt([{raw,A,B,C}|Opts], R, As) ->
+list_opt([{raw,A,B,C}|Opts], #listen_opts{} = R, As) ->
list_opt([{raw,{A,B,C}}|Opts], R, As);
-list_opt([Opt | Opts], R, As) ->
+list_opt([Opt | Opts], #listen_opts{} = R, As) ->
case Opt of
{ip,IP} -> list_opt(Opts, R#listen_opts { ifaddr = IP }, As);
{ifaddr,IP} -> list_opt(Opts, R#listen_opts { ifaddr = IP }, As);
@@ -791,10 +791,10 @@ list_opt([Opt | Opts], R, As) ->
{Name,Val} when is_atom(Name) -> list_add(Name, Val, R, Opts, As);
_ -> {error, badarg}
end;
-list_opt([], R, _SockOpts) ->
+list_opt([], #listen_opts{} = R, _SockOpts) ->
{ok, R}.
-list_add(Name, Val, R, Opts, As) ->
+list_add(Name, Val, #listen_opts{} = R, Opts, As) ->
case add_opt(Name, Val, R#listen_opts.opts, As) of
{ok, SOpts} ->
list_opt(Opts, R#listen_opts { opts = SOpts }, As);
@@ -821,9 +821,9 @@ udp_options(Opts, Family) ->
Error -> Error
end.
-udp_opt([{raw,A,B,C}|Opts], R, As) ->
+udp_opt([{raw,A,B,C}|Opts], #udp_opts{} = R, As) ->
udp_opt([{raw,{A,B,C}}|Opts], R, As);
-udp_opt([Opt | Opts], R, As) ->
+udp_opt([Opt | Opts], #udp_opts{} = R, As) ->
case Opt of
{ip,IP} -> udp_opt(Opts, R#udp_opts { ifaddr = IP }, As);
{ifaddr,IP} -> udp_opt(Opts, R#udp_opts { ifaddr = IP }, As);
@@ -838,7 +838,7 @@ udp_opt([Opt | Opts], R, As) ->
BinNS = filename2binary(NS),
case prim_inet:is_sockopt_val(netns, BinNS) of
true ->
- list_opt(Opts, R#udp_opts { fd = [{netns,BinNS}] }, As);
+ udp_opt(Opts, R#udp_opts { fd = [{netns,BinNS}] }, As);
false ->
{error, badarg}
end;
@@ -848,10 +848,10 @@ udp_opt([Opt | Opts], R, As) ->
{Name,Val} when is_atom(Name) -> udp_add(Name, Val, R, Opts, As);
_ -> {error, badarg}
end;
-udp_opt([], R, _SockOpts) ->
+udp_opt([], #udp_opts{} = R, _SockOpts) ->
{ok, R}.
-udp_add(Name, Val, R, Opts, As) ->
+udp_add(Name, Val, #udp_opts{} = R, Opts, As) ->
case add_opt(Name, Val, R#udp_opts.opts, As) of
{ok, SOpts} ->
udp_opt(Opts, R#udp_opts { opts = SOpts }, As);
@@ -895,7 +895,7 @@ sctp_options(Opts, Mod) ->
Error -> Error
end.
-sctp_opt([Opt|Opts], Mod, R, As) ->
+sctp_opt([Opt|Opts], Mod, #sctp_opts{} = R, As) ->
case Opt of
{ip,IP} ->
sctp_opt_ifaddr(Opts, Mod, R, As, IP);
@@ -938,7 +938,7 @@ sctp_opt([], _Mod, #sctp_opts{ifaddr=IfAddr}=R, _SockOpts) ->
{ok, R}
end.
-sctp_opt(Opts, Mod, R, As, Name, Val) ->
+sctp_opt(Opts, Mod, #sctp_opts{} = R, As, Name, Val) ->
case add_opt(Name, Val, R#sctp_opts.opts, As) of
{ok,SocketOpts} ->
sctp_opt(Opts, Mod, R#sctp_opts{opts=SocketOpts}, As);
@@ -1070,7 +1070,7 @@ gethostbyname_tm(Name, Type, Timer, [wins|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
gethostbyname_tm(Name, Type, Timer, [native|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
-gethostbyname_tm(Name, Type, Timer, [_|_]=Opts) ->
+gethostbyname_tm(Name, Type, Timer, [_|Opts]) ->
gethostbyname_tm(Name, Type, Timer, Opts);
%% Make sure we always can look up our own hostname.
gethostbyname_tm(Name, Type, Timer, []) ->
@@ -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/src/net_adm.erl b/lib/kernel/src/net_adm.erl
index 3f5eac7822..2cdfb76417 100644
--- a/lib/kernel/src/net_adm.erl
+++ b/lib/kernel/src/net_adm.erl
@@ -89,18 +89,13 @@ names() ->
-spec names(Host) -> {ok, [{Name, Port}]} | {error, Reason} when
- Host :: atom() | string(),
+ Host :: atom() | string() | inet:ip_address(),
Name :: string(),
Port :: non_neg_integer(),
Reason :: address | file:posix().
names(Hostname) ->
- case inet:gethostbyname(Hostname) of
- {ok, {hostent, _Name, _ , _Af, _Size, [Addr | _]}} ->
- erl_epmd:names(Addr);
- Else ->
- Else
- end.
+ erl_epmd:names(Hostname).
-spec dns_hostname(Host) -> {ok, Name} | {error, Host} when
Host :: atom() | string(),
diff --git a/lib/kernel/src/standard_error.erl b/lib/kernel/src/standard_error.erl
index 10cf77e0d4..1c43063937 100644
--- a/lib/kernel/src/standard_error.erl
+++ b/lib/kernel/src/standard_error.erl
@@ -63,7 +63,7 @@ server(PortName,PortSettings) ->
run(Port).
run(P) ->
- put(unicode,false),
+ put(encoding, latin1),
server_loop(P).
server_loop(Port) ->
@@ -95,25 +95,47 @@ do_io_request(Req, From, ReplyAs, Port) ->
io_reply(From, ReplyAs, Reply).
%% New in R13B
-% Wide characters (Unicode)
-io_request({put_chars,Encoding,Chars}, Port) -> % Binary new in R9C
- put_chars(wrap_characters_to_binary(Chars,Encoding,
- case get(unicode) of
- true -> unicode;
- _ -> latin1
- end), Port);
-io_request({put_chars,Encoding,Mod,Func,Args}, Port) ->
- Result = case catch apply(Mod,Func,Args) of
- Data when is_list(Data); is_binary(Data) ->
- wrap_characters_to_binary(Data,Encoding,
- case get(unicode) of
- true -> unicode;
- _ -> latin1
- end);
- Undef ->
- Undef
- end,
- put_chars(Result, Port);
+%% Encoding option (unicode/latin1)
+io_request({put_chars,unicode,Chars}, Port) ->
+ case wrap_characters_to_binary(Chars, unicode, get(encoding)) of
+ error ->
+ {error,{error,put_chars}};
+ Bin ->
+ put_chars(Bin, Port)
+ end;
+io_request({put_chars,unicode,Mod,Func,Args}, Port) ->
+ case catch apply(Mod, Func, Args) of
+ Data when is_list(Data); is_binary(Data) ->
+ case wrap_characters_to_binary(Data, unicode, get(encoding)) of
+ Bin when is_binary(Bin) ->
+ put_chars(Bin, Port);
+ error ->
+ {error,{error,put_chars}}
+ end;
+ _ ->
+ {error,{error,put_chars}}
+ end;
+io_request({put_chars,latin1,Chars}, Port) ->
+ case catch unicode:characters_to_binary(Chars, latin1, get(encoding)) of
+ Data when is_binary(Data) ->
+ put_chars(Data, Port);
+ _ ->
+ {error,{error,put_chars}}
+ end;
+io_request({put_chars,latin1,Mod,Func,Args}, Port) ->
+ case catch apply(Mod, Func, Args) of
+ Data when is_list(Data); is_binary(Data) ->
+ case
+ catch unicode:characters_to_binary(Data, latin1, get(encoding))
+ of
+ Bin when is_binary(Bin) ->
+ put_chars(Bin, Port);
+ _ ->
+ {error,{error,put_chars}}
+ end;
+ _ ->
+ {error,{error,put_chars}}
+ end;
%% BC if called from pre-R13 node
io_request({put_chars,Chars}, Port) ->
io_request({put_chars,latin1,Chars}, Port);
@@ -134,10 +156,10 @@ io_request({get_geometry,rows},Port) ->
_ ->
{error,{error,enotsup}}
end;
-io_request({getopts,[]}, Port) ->
- getopts(Port);
-io_request({setopts,Opts}, Port) when is_list(Opts) ->
- setopts(Opts, Port);
+io_request(getopts, _Port) ->
+ getopts();
+io_request({setopts,Opts}, _Port) when is_list(Opts) ->
+ setopts(Opts);
io_request({requests,Reqs}, Port) ->
io_requests(Reqs, {ok,ok}, Port);
io_request(R, _Port) -> %Unknown request
@@ -176,47 +198,48 @@ io_reply(From, ReplyAs, Reply) ->
%% put_chars
put_chars(Chars, Port) when is_binary(Chars) ->
_ = put_port(Chars, Port),
- {ok,ok};
-put_chars(Chars, Port) ->
- case catch list_to_binary(Chars) of
- Binary when is_binary(Binary) ->
- put_chars(Binary, Port);
- _ ->
- {error,{error,put_chars}}
- end.
+ {ok,ok}.
%% setopts
-setopts(Opts0,Port) ->
- Opts = proplists:unfold(
- proplists:substitute_negations(
- [{latin1,unicode}],
- Opts0)),
+setopts(Opts0) ->
+ Opts = expand_encoding(Opts0),
case check_valid_opts(Opts) of
- true ->
- do_setopts(Opts,Port);
- false ->
- {error,{error,enotsup}}
+ true ->
+ do_setopts(Opts);
+ false ->
+ {error,{error,enotsup}}
end.
+
check_valid_opts([]) ->
true;
-check_valid_opts([{unicode,Valid}|T]) when Valid =:= true; Valid =:= utf8; Valid =:= false ->
+check_valid_opts([{encoding,Valid}|T]) when Valid =:= unicode;
+ Valid =:= utf8; Valid =:= latin1 ->
check_valid_opts(T);
check_valid_opts(_) ->
false.
-do_setopts(Opts, _Port) ->
- case proplists:get_value(unicode,Opts) of
- Valid when Valid =:= true; Valid =:= utf8 ->
- put(unicode,true);
- false ->
- put(unicode,false);
- undefined ->
- ok
+expand_encoding([]) ->
+ [];
+expand_encoding([latin1 | T]) ->
+ [{encoding,latin1} | expand_encoding(T)];
+expand_encoding([unicode | T]) ->
+ [{encoding,unicode} | expand_encoding(T)];
+expand_encoding([H|T]) ->
+ [H|expand_encoding(T)].
+
+do_setopts(Opts) ->
+ case proplists:get_value(encoding, Opts) of
+ Valid when Valid =:= unicode; Valid =:= utf8 ->
+ put(encoding, unicode);
+ latin1 ->
+ put(encoding, latin1);
+ undefined ->
+ ok
end,
{ok,ok}.
-getopts(_Port) ->
- Uni = {unicode, get(unicode) =:= true},
+getopts() ->
+ Uni = {encoding,get(encoding)},
{ok,[Uni]}.
wrap_characters_to_binary(Chars,From,To) ->
@@ -227,17 +250,17 @@ wrap_characters_to_binary(Chars,From,To) ->
_Else ->
16#10ffff
end,
- unicode:characters_to_binary(
- [ case X of
- $\n ->
- if
- TrNl ->
- "\r\n";
- true ->
- $\n
- end;
- High when High > Limit ->
- ["\\x{",erlang:integer_to_list(X, 16),$}];
- Ordinary ->
- Ordinary
- end || X <- unicode:characters_to_list(Chars,From) ],unicode,To).
+ case catch unicode:characters_to_list(Chars, From) of
+ L when is_list(L) ->
+ unicode:characters_to_binary(
+ [ case X of
+ $\n when TrNl ->
+ "\r\n";
+ High when High > Limit ->
+ ["\\x{",erlang:integer_to_list(X, 16),$}];
+ Low ->
+ Low
+ end || X <- L ], unicode, To);
+ _ ->
+ error
+ end.
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index f1b8a105ed..ef351a25fb 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -77,7 +77,8 @@ MODULES= \
ignore_cores \
zlib_SUITE \
loose_node \
- sendfile_SUITE
+ sendfile_SUITE \
+ standard_error_SUITE
APP_FILES = \
appinc.app \
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/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/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index f6d6cd94ab..2ce2303ba3 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -424,7 +424,7 @@ make_del_dir(Config) when is_list(Config) ->
?line ok = ?FILE_MODULE:del_dir(NewDir),
?line {error, enoent} = ?FILE_MODULE:del_dir(NewDir),
% Make sure we are not in a directory directly under test_server
- % as that would result in eacess errors when trying to delere '..',
+ % as that would result in eacces errors when trying to delete '..',
% because there are processes having that directory as current.
?line ok = ?FILE_MODULE:make_dir(NewDir),
?line {ok,CurrentDir} = file:get_cwd(),
@@ -1236,9 +1236,10 @@ file_info_basic_file(Config) when is_list(Config) ->
%% Test that the file has the expected attributes.
%% The times are tricky, so we will save them to a separate test case.
- ?line {ok,#file_info{size=Size,type=Type,access=Access,
- atime=AccessTime,mtime=ModifyTime}} =
- ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name, [raw]),
+ #file_info{size=Size,type=Type,access=Access,
+ atime=AccessTime,mtime=ModifyTime} = FileInfo,
?line io:format("Access ~p, Modify ~p", [AccessTime, ModifyTime]),
?line Size = 7,
?line Type = regular,
@@ -1280,9 +1281,10 @@ file_info_basic_directory(Config) when is_list(Config) ->
test_server:timetrap_cancel(Dog).
test_directory(Name, ExpectedAccess) ->
- ?line {ok,#file_info{size=Size,type=Type,access=Access,
- atime=AccessTime,mtime=ModifyTime}} =
- ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name, [raw]),
+ #file_info{size=Size,type=Type,access=Access,
+ atime=AccessTime,mtime=ModifyTime} = FileInfo,
?line io:format("Testing directory ~s", [Name]),
?line io:format("Directory size is ~p", [Size]),
?line io:format("Access ~p", [Access]),
@@ -1307,11 +1309,11 @@ file_info_bad(doc) -> [];
file_info_bad(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(5)),
?line RootDir = filename:join([?config(priv_dir, Config)]),
- ?line {error, enoent} =
- ?FILE_MODULE:read_file_info(
- filename:join(RootDir,
- atom_to_list(?MODULE)++ "_nonexistent")),
+ FileName = filename:join(RootDir, atom_to_list(?MODULE) ++ "_nonexistent"),
+ {error,enoent} = ?FILE_MODULE:read_file_info(FileName),
+ {error,enoent} = ?FILE_MODULE:read_file_info(FileName, [raw]),
?line {error, enoent} = ?FILE_MODULE:read_file_info(""),
+ {error, enoent} = ?FILE_MODULE:read_file_info("", [raw]),
?line [] = flush(),
?line test_server:timetrap_cancel(Dog),
ok.
@@ -1346,8 +1348,16 @@ file_info_int(Config) ->
?line io:put_chars(Fd1,"foo"),
%% check that the file got a modify date max a few seconds away from now
- ?line {ok,#file_info{type=regular,atime=AccTime1,mtime=ModTime1}} =
- ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo1} = ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo1Raw} = ?FILE_MODULE:read_file_info(Name, [raw]),
+
+ %% We assert that everything but the size is the same, on some OSs the
+ %% size may not have been flushed to disc and we do not want to do a
+ %% sync to force it.
+ FileInfo1Raw = FileInfo1#file_info{ size = FileInfo1Raw#file_info.size },
+
+ #file_info{type=regular,atime=AccTime1,mtime=ModTime1} = FileInfo1,
+
?line Now = erlang:localtime(), %???
?line io:format("Now ~p",[Now]),
?line io:format("Open file Acc ~p Mod ~p",[AccTime1,ModTime1]),
@@ -1363,9 +1373,10 @@ file_info_int(Config) ->
%% close the file, and watch the modify date change
?line ok = ?FILE_MODULE:close(Fd1),
- ?line {ok,#file_info{size=Size,type=regular,access=Access,
- atime=AccTime2,mtime=ModTime2}} =
- ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo2} = ?FILE_MODULE:read_file_info(Name),
+ {ok,FileInfo2} = ?FILE_MODULE:read_file_info(Name, [raw]),
+ #file_info{size=Size,type=regular,access=Access,
+ atime=AccTime2,mtime=ModTime2} = FileInfo2,
?line io:format("Closed file Acc ~p Mod ~p",[AccTime2,ModTime2]),
?line true = time_dist(ModTime1,ModTime2) >= 0,
@@ -1374,9 +1385,10 @@ file_info_int(Config) ->
?line Access = read_write,
%% Do some directory checking
- ?line {ok,#file_info{size=DSize,type=directory,access=DAccess,
- atime=AccTime3,mtime=ModTime3}} =
- ?FILE_MODULE:read_file_info(RootDir),
+ {ok,FileInfo3} = ?FILE_MODULE:read_file_info(RootDir),
+ {ok,FileInfo3} = ?FILE_MODULE:read_file_info(RootDir, [raw]),
+ #file_info{size=DSize,type=directory,access=DAccess,
+ atime=AccTime3,mtime=ModTime3} = FileInfo3,
%% this dir was modified only a few secs ago
?line io:format("Dir Acc ~p; Mod ~p; Now ~p", [AccTime3, ModTime3, Now]),
?line true = abs(time_dist(Now,ModTime3)) < 5,
@@ -1449,6 +1461,12 @@ file_write_file_info(Config) when is_list(Config) ->
?line ?FILE_MODULE:write_file_info(Name1, #file_info{mode=8#400}),
?line {error, eacces} = ?FILE_MODULE:write_file(Name1, "hello again"),
+ %% Same with raw.
+ ?FILE_MODULE:write_file_info(Name1, #file_info{mode=8#600}, [raw]),
+ ok = ?FILE_MODULE:write_file(Name1, "hello again"),
+ ?FILE_MODULE:write_file_info(Name1, #file_info{mode=8#400}, [raw]),
+ {error,eacces} = ?FILE_MODULE:write_file(Name1, "hello again"),
+
%% Write the times again.
%% Note: Seconds must be even; see note in file_info_times/1.
@@ -2650,7 +2668,9 @@ make_link(Config) when is_list(Config) ->
%% since they are not used on symbolic links.
?line {ok, Info} = ?FILE_MODULE:read_link_info(Name),
+ {ok,Info} = ?FILE_MODULE:read_link_info(Name, [raw]),
?line {ok, Info} = ?FILE_MODULE:read_link_info(Alias),
+ {ok,Info} = ?FILE_MODULE:read_link_info(Alias, [raw]),
?line #file_info{links = 2, type = regular} = Info,
?line {error, eexist} =
?FILE_MODULE:make_link(Name, Alias),
@@ -2670,6 +2690,7 @@ read_link_info_for_non_link(Config) when is_list(Config) ->
?line {ok, #file_info{type=directory}} =
?FILE_MODULE:read_link_info("."),
+ {ok, #file_info{type=directory}} = ?FILE_MODULE:read_link_info(".", [raw]),
?line [] = flush(),
?line test_server:timetrap_cancel(Dog),
@@ -2700,11 +2721,15 @@ symlinks(Config) when is_list(Config) ->
{skipped, "Windows user not privileged to create symlinks"};
ok ->
?line {ok, Info1} = ?FILE_MODULE:read_file_info(Name),
+ {ok,Info1} = ?FILE_MODULE:read_file_info(Name, [raw]),
?line {ok, Info1} = ?FILE_MODULE:read_file_info(Alias),
+ {ok,Info1} = ?FILE_MODULE:read_file_info(Alias, [raw]),
?line {ok, Info1} = ?FILE_MODULE:read_link_info(Name),
+ {ok,Info1} = ?FILE_MODULE:read_link_info(Name, [raw]),
?line #file_info{links = 1, type = regular} = Info1,
?line {ok, Info2} = ?FILE_MODULE:read_link_info(Alias),
+ {ok,Info2} = ?FILE_MODULE:read_link_info(Alias, [raw]),
?line #file_info{links=1, type=symlink} = Info2,
?line {ok, Name} = ?FILE_MODULE:read_link(Alias),
{ok, Name} = ?FILE_MODULE:read_link_all(Alias),
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..d774767624
--- /dev/null
+++ b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
@@ -0,0 +1,62 @@
+/*
+ * %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>
+#define sock_close(s) closesocket(s)
+#else
+#include <sys/socket.h>
+#define sock_close(s) close(s)
+#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);
+
+ sock_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_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 2df4bf7c95..4e4aeb67e2 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -882,7 +882,7 @@ passive_sockets_server_send(Socket, X) ->
accept_closed_by_other_process(doc) ->
["Tests the return value from gen_tcp:accept when ",
- "the socket is closed from an other process. (OTP-3817)"];
+ "the socket is closed from another process. (OTP-3817)"];
accept_closed_by_other_process(Config) when is_list(Config) ->
?line Parent = self(),
?line {ok, ListenSocket} = gen_tcp:listen(0, []),
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/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index ed43749cc0..849013ac79 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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,9 +36,10 @@
gethostnative_parallell/1, cname_loop/1,
gethostnative_soft_restart/0, gethostnative_soft_restart/1,
gethostnative_debug_level/0, gethostnative_debug_level/1,
+ lookup_bad_search_option/1,
getif/1,
getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1,
- parse_strict_address/1, simple_netns/1]).
+ parse_strict_address/1, simple_netns/1, simple_netns_open/1]).
-export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1,
kill_gethost/0, parallell_gethost/0, test_netns/0]).
@@ -52,8 +53,9 @@ all() ->
ipv4_to_ipv6, host_and_addr, {group, parse},
t_gethostnative, gethostnative_parallell, cname_loop,
gethostnative_debug_level, gethostnative_soft_restart,
+ lookup_bad_search_option,
getif, getif_ifr_name_overflow, getservbyname_overflow,
- getifaddrs, parse_strict_address, simple_netns].
+ getifaddrs, parse_strict_address, simple_netns, simple_netns_open].
groups() ->
[{parse, [], [parse_hosts, parse_address]}].
@@ -908,6 +910,21 @@ lookup_loop([H|Hs], Delay, Tag, Parent, Cnt, Hosts) ->
+lookup_bad_search_option(suite) ->
+ [];
+lookup_bad_search_option(doc) ->
+ ["Test lookup with erroneously configured lookup option (OTP-12133)"];
+lookup_bad_search_option(Config) when is_list(Config) ->
+ Db = inet_db,
+ %% The bad option can not enter through inet_db:set_lookup/1,
+ %% but through e.g .inetrc.
+ ets:insert(Db, {res_lookup,[lookup_bad_search_option]}),
+ {ok,Hostname} = inet:gethostname(),
+ {ok,_Hent} = inet:gethostbyname(Hostname), % Will hang loop for this bug
+ ok.
+
+
+
getif(suite) ->
[];
getif(doc) ->
@@ -1128,6 +1145,32 @@ jog_netns_opt(S) ->
ok.
+simple_netns_open(Config) when is_list(Config) ->
+ case gen_udp:open(0, [binary,{netns,"/"},inet]) of
+ {ok,U} ->
+ ok = gen_udp:close(U);
+ {error,E1} when E1 =:= einval; E1 =:= eperm ->
+ ok
+ end,
+ case gen_tcp:listen(0, [binary,{netns,"/"},inet]) of
+ {ok,T} ->
+ ok = gen_tcp:close(T);
+ {error,E2} when E2 =:= einval; E2 =:= eperm ->
+ ok
+ end,
+ try gen_sctp:open(0, [binary,{netns,"/"},inet]) of
+ {ok,S} ->
+ ok = gen_sctp:close(S);
+ {error,E3}
+ when E3 =:= einval; E3 =:= eperm; E3 =:= eprotonosupport ->
+ ok
+ catch
+ error:badarg ->
+ %% Some older platforms does not allow netns for sctp
+ ok
+ end.
+
+
%% Manual test to be run outside test_server in an emulator
%% started by root, in a machine with setns() support...
test_netns() ->
diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl
index a375adceea..7f6024f642 100644
--- a/lib/kernel/test/interactive_shell_SUITE.erl
+++ b/lib/kernel/test/interactive_shell_SUITE.erl
@@ -296,6 +296,7 @@ ctrl_keys(doc) -> ["Tests various control keys"];
ctrl_keys(_Conf) when is_list(_Conf) ->
Cu=[$\^u],
Cw=[$\^w],
+ Cy=[$\^y],
Home=[27,$O,$H],
End=[27,$O,$F],
rtnode([{putline,""},
@@ -308,6 +309,8 @@ ctrl_keys(_Conf) when is_list(_Conf) ->
{putline,"world\"."++Home++"\"hello "}, % test <HOME>
{getline,"\"hello world\""},
{putline,"world"++Home++"\"hello "++End++"\"."}, % test <END>
+ {getline,"\"hello world\""},
+ {putline,"\"hello world\""++Cu++Cy++"."},
{getline,"\"hello world\""}]
++wordLeft()++wordRight(),[]).
diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl
index 1884e8cf58..613efeeb2f 100644
--- a/lib/kernel/test/kernel_SUITE.erl
+++ b/lib/kernel/test/kernel_SUITE.erl
@@ -79,17 +79,29 @@ appup_test(_Config) ->
appup_tests(_App,{[],[]}) ->
{skip,"no previous releases available"};
-appup_tests(App,{OkVsns,NokVsns}) ->
+appup_tests(App,{OkVsns0,NokVsns}) ->
application:load(App),
{_,_,Vsn} = lists:keyfind(App,1,application:loaded_applications()),
AppupFileName = atom_to_list(App) ++ ".appup",
AppupFile = filename:join([code:lib_dir(App),ebin,AppupFileName]),
{ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile),
ct:log("~p~n",[AppupScript]),
- ct:log("Testing ok versions: ~p~n",[OkVsns]),
+ OkVsns =
+ case OkVsns0 -- [Vsn] of
+ OkVsns0 ->
+ OkVsns0;
+ Ok ->
+ ct:log("Current version, ~p, is same as in previous release.~n"
+ "Removing this from the list of ok versions.",
+ [Vsn]),
+ Ok
+ end,
+ ct:log("Testing that appup allows upgrade from these versions: ~p~n",
+ [OkVsns]),
check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}),
check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}),
- ct:log("Testing not ok versions: ~p~n",[NokVsns]),
+ ct:log("Testing that appup does not allow upgrade from these versions: ~p~n",
+ [NokVsns]),
check_appup(NokVsns,UpFrom,error),
check_appup(NokVsns,DownTo,error),
ok.
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 05bd5b3a3d..f55716cbec 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -262,7 +262,7 @@ make_del_dir(Config, Handle, Suffix) ->
?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, [NewDir]),
% Make sure we are not in a directory directly under test_server
- % as that would result in eacess errors when trying to delere '..',
+ % as that would result in eacces errors when trying to delete '..',
% because there are processes having that directory as current.
?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
?line {ok, CurrentDir} = ?PRIM_FILE_call(get_cwd, Handle, []),
diff --git a/lib/kernel/test/standard_error_SUITE.erl b/lib/kernel/test/standard_error_SUITE.erl
new file mode 100644
index 0000000000..b290454b40
--- /dev/null
+++ b/lib/kernel/test/standard_error_SUITE.erl
@@ -0,0 +1,38 @@
+%%
+%% %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(standard_error_SUITE).
+
+-export([all/0,suite/0]).
+-export([badarg/1,getopts/1]).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [badarg,getopts].
+
+badarg(Config) when is_list(Config) ->
+ {'EXIT',{badarg,_}} = (catch io:put_chars(standard_error, [oops])),
+ true = erlang:is_process_alive(whereis(standard_error)),
+ ok.
+
+getopts(Config) when is_list(Config) ->
+ [{encoding,latin1}] = io:getopts(standard_error),
+ ok.
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index dd5316b825..15820a0182 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 3.0
+KERNEL_VSN = 3.1
diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4
deleted file mode 100644
index ed492d55ff..0000000000
--- a/lib/megaco/aclocal.m4
+++ /dev/null
@@ -1,1954 +0,0 @@
-dnl
-dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
-dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
-dnl
-dnl %CopyrightEnd%
-dnl
-
-dnl
-dnl aclocal.m4
-dnl
-dnl Local macros used in configure.in. The Local Macros which
-dnl could/should be part of autoconf are prefixed LM_, macros specific
-dnl to the Erlang system are prefixed ERL_.
-dnl
-
-AC_DEFUN(LM_PRECIOUS_VARS,
-[
-
-dnl ERL_TOP
-AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory])
-
-dnl Tools
-AC_ARG_VAR(CC, [C compiler])
-AC_ARG_VAR(CFLAGS, [C compiler flags])
-AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags])
-AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler])
-AC_ARG_VAR(CPP, [C/C++ preprocessor])
-AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags])
-AC_ARG_VAR(CXX, [C++ compiler])
-AC_ARG_VAR(CXXFLAGS, [C++ compiler flags])
-AC_ARG_VAR(LD, [linker (is often overridden by configure)])
-AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)])
-AC_ARG_VAR(LIBS, [libraries])
-AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)])
-AC_ARG_VAR(RANLIB, [ranlib])
-AC_ARG_VAR(AR, [ar])
-AC_ARG_VAR(GETCONF, [getconf])
-
-dnl Cross system root
-AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)])
-
-dnl Cross compilation variables
-AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-
-dnl Cross compilation variables for OSE
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file])
-AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
-
-])
-
-AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
-[
-erl_xcomp_without_sysroot=no
-if test "$cross_compiling" = "yes"; then
- test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes
- test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot"
-else
- erl_xcomp_sysroot=
- erl_xcomp_isysroot=
-fi
-])
-
-AC_DEFUN(LM_CHECK_GETCONF,
-[
-if test "$cross_compiling" != "yes"; then
- AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false])
-else
- dnl First check if we got a `<HOST>-getconf' in $PATH
- host_getconf="$host_alias-getconf"
- AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false])
- if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then
- dnl We should perhaps give up if we have'nt found it by now, but at
- dnl least in one Tilera MDE `getconf' under sysroot is a bourne
- dnl shell script which we can use. We try to find `<HOST>-getconf'
- dnl or `getconf' under sysconf, but only under sysconf since
- dnl `getconf' in $PATH is almost guaranteed to be for the build
- dnl machine.
- GETCONF=
- prfx="$erl_xcomp_sysroot"
- AC_PATH_TOOL([GETCONF], [getconf], [false],
- ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"])
- fi
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_WINDOWS_ENVIRONMENT
-dnl
-dnl
-dnl Tries to determine thw windows build environment, i.e.
-dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC
-dnl
-
-AC_DEFUN(LM_WINDOWS_ENVIRONMENT,
-[
-MIXED_CYGWIN=no
-MIXED_MSYS=no
-
-AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment)
-if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([Cygwin and VC])
- MIXED_CYGWIN_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
- elif test -x /usr/bin/msysinfo; then
- CFLAGS="-O2"
- MIXED_MSYS=yes
- AC_MSG_RESULT([MSYS and VC])
- MIXED_MSYS_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
-else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_VC=no
- MIXED_MSYS_VC=no
-fi
-AC_SUBST(MIXED_CYGWIN_VC)
-AC_SUBST(MIXED_MSYS_VC)
-
-MIXED_VC=no
-if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then
- MIXED_VC=yes
-fi
-
-AC_SUBST(MIXED_VC)
-
-if test "x$MIXED_MSYS" != "xyes"; then
- AC_MSG_CHECKING(for mixed cygwin and native MinGW environment)
- if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([yes])
- MIXED_CYGWIN_MINGW=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
- else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_MINGW=no
- fi
-else
- MIXED_CYGWIN_MINGW=no
-fi
-AC_SUBST(MIXED_CYGWIN_MINGW)
-
-AC_MSG_CHECKING(if we mix cygwin with any native compiler)
-if test "X$MIXED_CYGWIN" = "Xyes"; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_CYGWIN)
-
-AC_MSG_CHECKING(if we mix msys with another native compiler)
-if test "X$MIXED_MSYS" = "Xyes" ; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_MSYS)
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_FIND_EMU_CC
-dnl
-dnl
-dnl Tries fairly hard to find a C compiler that can handle jump tables.
-dnl Defines the @EMU_CC@ variable for the makefiles and
-dnl inserts NO_JUMP_TABLE in the header if one cannot be found...
-dnl
-
-AC_DEFUN(LM_FIND_EMU_CC,
- [AC_CACHE_CHECK(for a compiler that handles jumptables,
- ac_cv_prog_emu_cc,
- [
-AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
-lbl1:
- return 1;
-lbl2:
- return 2;
-],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
-
-if test $ac_cv_prog_emu_cc = no; then
- for ac_progname in emu_cc.sh gcc-4.2 gcc; do
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_progname; then
- ac_cv_prog_emu_cc=$ac_dir/$ac_progname
- break
- fi
- done
- IFS="$ac_save_ifs"
- if test $ac_cv_prog_emu_cc != no; then
- break
- fi
- done
-fi
-
-if test $ac_cv_prog_emu_cc != no; then
- save_CC=$CC
- save_CFLAGS=$CFLAGS
- save_CPPFLAGS=$CPPFLAGS
- CC=$ac_cv_prog_emu_cc
- CFLAGS=""
- CPPFLAGS=""
- AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
- lbl1:
- return 1;
- lbl2:
- return 2;
- ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
- CC=$save_CC
- CFLAGS=$save_CFLAGS
- CPPFLAGS=$save_CPPFLAGS
-fi
-])
-if test $ac_cv_prog_emu_cc = no; then
- AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables])
- EMU_CC=$CC
-else
- EMU_CC=$ac_cv_prog_emu_cc
-fi
-AC_SUBST(EMU_CC)
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_INSTALL_DIR
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl Figure out how to create directories with parents.
-dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better)
-dnl
-dnl We prefer 'install -d', but use 'mkdir -p' if it exists.
-dnl If none of these methods works, we give up.
-dnl
-
-
-AC_DEFUN(LM_PROG_INSTALL_DIR,
-[AC_CACHE_CHECK(how to create a directory including parents,
-ac_cv_prog_mkdir_p,
-[
-temp_name_base=config.$$
-temp_name=$temp_name_base/x/y/z
-$INSTALL -d $temp_name >/dev/null 2>&1
-ac_cv_prog_mkdir_p=none
-if test -d $temp_name; then
- ac_cv_prog_mkdir_p="$INSTALL -d"
-else
- mkdir -p $temp_name >/dev/null 2>&1
- if test -d $temp_name; then
- ac_cv_prog_mkdir_p="mkdir -p"
- fi
-fi
-rm -fr $temp_name_base
-])
-
-case "${ac_cv_prog_mkdir_p}" in
- none) AC_MSG_ERROR(don't know how create directories with parents) ;;
- *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_PERL5
-dnl
-dnl Try to find perl version 5. If found set PERL to the absolute path
-dnl of the program, if not found set PERL to false.
-dnl
-dnl On some systems /usr/bin/perl is perl 4 and e.g.
-dnl /usr/local/bin/perl is perl 5. We try to handle this case by
-dnl putting a couple of
-dnl Tries to handle the case that there are two programs called perl
-dnl in the path and one of them is perl 5 and the other isn't.
-dnl
-AC_DEFUN(LM_PROG_PERL5,
-[AC_PATH_PROGS(PERL, perl5 perl, false,
- /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH})
-changequote(, )dnl
-dnl[ That bracket is needed to balance the right bracket below
-if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then
-changequote([, ])dnl
- ac_cv_path_PERL=false
- PERL=false
-dnl AC_MSG_WARN(perl version 5 not found)
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SO_BSDCOMPAT
-dnl
-dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux)
-dnl
-AC_DEFUN(LM_DECL_SO_BSDCOMPAT,
-[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat,
-AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;],
- ac_cv_decl_so_bsdcompat=yes,
- ac_cv_decl_so_bsdcompat=no))
-
-case "${ac_cv_decl_so_bsdcompat}" in
- "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[],
- [Define if you have SO_BSDCOMPAT flag on sockets]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_INADDR_LOOPBACK
-dnl
-dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default
-dnl
-
-AC_DEFUN(LM_DECL_INADDR_LOOPBACK,
-[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h],
- ac_cv_decl_inaddr_loopback,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>], [int i = INADDR_LOOPBACK;],
-ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no)
-])
-
-if test ${ac_cv_decl_inaddr_loopback} = no; then
- AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h],
- ac_cv_decl_inaddr_loopback_rpc,
- AC_TRY_COMPILE([#include <rpc/types.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_rpc=yes,
- ac_cv_decl_inaddr_loopback_rpc=no))
-
- case "${ac_cv_decl_inaddr_loopback_rpc}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[],
- [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;;
- * )
- AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h],
- ac_cv_decl_inaddr_loopback_winsock2,
- AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_winsock2=yes,
- ac_cv_decl_inaddr_loopback_winsock2=no))
- case "${ac_cv_decl_inaddr_loopback_winsock2}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[],
- [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;;
- * )
- # couldn't find it anywhere
- AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[],
- [Define if you don't have a definition of INADDR_LOOPBACK]) ;;
- esac;;
- esac
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_SOCKADDR_SA_LEN
-dnl
-dnl Check if the sockaddr structure has the field sa_len
-dnl
-
-AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN,
-[AC_CACHE_CHECK([whether struct sockaddr has sa_len field],
- ac_cv_struct_sockaddr_sa_len,
-AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;],
- ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no))
-
-dnl FIXME convbreak
-case ${ac_cv_struct_sockaddr_sa_len} in
- "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;;
- *) ;;
-esac
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_EXCEPTION
-dnl
-dnl Check to see whether the system supports the matherr function
-dnl and its associated type "struct exception".
-dnl
-
-AC_DEFUN(LM_STRUCT_EXCEPTION,
-[AC_CACHE_CHECK([for struct exception (and matherr function)],
- ac_cv_struct_exception,
-AC_TRY_COMPILE([#include <math.h>],
- [struct exception x; x.type = DOMAIN; x.type = SING;],
- ac_cv_struct_exception=yes, ac_cv_struct_exception=no))
-
-case "${ac_cv_struct_exception}" in
- "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_IPV6
-dnl
-dnl Check for ipv6 support and what the in6_addr structure is called.
-dnl (early linux used in_addr6 insted of in6_addr)
-dnl
-
-AC_DEFUN(LM_SYS_IPV6,
-[AC_MSG_CHECKING(for IP version 6 support)
-AC_CACHE_VAL(ac_cv_sys_ipv6_support,
-[ok_so_far=yes
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no)
-
-if test $ok_so_far = yes; then
- ac_cv_sys_ipv6_support=yes
-else
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in_addr6 a6; struct sockaddr_in6 s6;],
- ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no)
-fi
-])dnl
-
-dnl
-dnl Have to use old style AC_DEFINE due to BC with old autoconf.
-dnl
-
-case ${ac_cv_sys_ipv6_support} in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- ;;
- in_addr6)
- AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)])
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this])
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_MULTICAST
-dnl
-dnl Check for multicast support. Only checks for multicast options in
-dnl setsockopt(), no check is performed that multicasting actually works.
-dnl If options are found defines HAVE_MULTICAST_SUPPORT
-dnl
-
-AC_DEFUN(LM_SYS_MULTICAST,
-[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support,
-[AC_EGREP_CPP(yes,
-[#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP)
-yes
-#endif
-], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)])
-if test $ac_cv_sys_multicast_support = yes; then
- AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1],
- [Define if setsockopt() accepts multicast options])
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SYS_ERRLIST
-dnl
-dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared
-dnl in a system header file, stdio.h or errno.h.
-dnl
-
-AC_DEFUN(LM_DECL_SYS_ERRLIST,
-[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h],
- ac_cv_decl_sys_errlist,
-[AC_TRY_COMPILE([#include <stdio.h>
-#include <errno.h>], [char *msg = *(sys_errlist + 1);],
- ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)])
-if test $ac_cv_decl_sys_errlist = yes; then
- AC_DEFINE(SYS_ERRLIST_DECLARED,[],
- [define if the variable sys_errlist is declared in a system header file])
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes
-dnl [, action-if-found [, action-if-not-found]]] )
-dnl
-dnl Checks if the declaration "declaration" of "funname" conflicts
-dnl with the header files idea of how the function should be
-dnl declared. It is useful on systems which lack prototypes and you
-dnl need to provide your own (e.g. when you want to take the address
-dnl of a function). The 4'th argument is expanded if conflicting,
-dnl the 5'th argument otherwise
-dnl
-dnl
-
-AC_DEFUN(LM_CHECK_FUNC_DECL,
-[AC_MSG_CHECKING([for conflicting declaration of $1])
-AC_CACHE_VAL(ac_cv_func_decl_$1,
-[AC_TRY_COMPILE([#include <stdio.h>
-$3],[$2
-char *c = (char *)$1;
-], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")])
-if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then
- AC_MSG_RESULT(yes)
- ifelse([$4], , :, [$4])
-else
- AC_MSG_RESULT(no)
-ifelse([$5], , , [$5
-])dnl
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl AC_DOUBLE_MIDDLE_ENDIAN
-dnl
-dnl Checks whether doubles are represented in "middle-endian" format.
-dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly,
-dnl as well as DOUBLE_MIDDLE_ENDIAN.
-dnl
-dnl
-
-AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN],
-[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian,
-[# It does not; compile a test program.
-AC_RUN_IFELSE(
-[AC_LANG_SOURCE([[#include <stdlib.h>
-
-int
-main(void)
-{
- int i = 0;
- int zero = 0;
- int bigendian;
- int zero_index = 0;
-
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
-
- /* we'll use the one with 32-bit words */
- union
- {
- double d;
- unsigned int c[2];
- } vint;
-
- union
- {
- double d;
- unsigned long c[2];
- } vlong;
-
- union
- {
- double d;
- unsigned short c[2];
- } vshort;
-
-
- /* Are we little or big endian? From Harbison&Steele. */
- u.l = 1;
- bigendian = (u.c[sizeof (long int) - 1] == 1);
-
- zero_index = bigendian ? 1 : 0;
-
- vint.d = 1.0;
- vlong.d = 1.0;
- vshort.d = 1.0;
-
- if (sizeof(unsigned int) == 4)
- {
- if (vint.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned long) == 4)
- {
- if (vlong.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned short) == 4)
- {
- if (vshort.c[zero_index] != 0)
- zero = 1;
- }
-
- exit (zero);
-}
-]])],
- [ac_cv_c_double_middle_endian=no],
- [ac_cv_c_double_middle_endian=yes],
- [ac_cv_c_double_middle=unknown])])
-case $ac_cv_c_double_middle_endian in
- yes)
- m4_default([$1],
- [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1,
- [Define to 1 if your processor stores the words in a double in
- middle-endian format (like some ARMs).])]) ;;
- no)
- $2 ;;
- *)
- m4_default([$3],
- [AC_MSG_WARN([unknown double endianness
-presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;;
-esac
-])# AC_C_DOUBLE_MIDDLE_ENDIAN
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_THR_LIB
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also
-dnl checks for some pthread headers which will appear in DEFS or config.h.
-dnl
-
-AC_DEFUN(LM_CHECK_THR_LIB,
-[
-
-NEED_NPTL_PTHREAD_H=no
-
-dnl win32?
-AC_MSG_CHECKING([for native win32 threads])
-if test "X$host_os" = "Xwin32"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DWIN32_THREADS"
- THR_LIBS=
- THR_LIB_NAME=win32_threads
- THR_LIB_TYPE=win32_threads
-elif test "X$host_os" = "Xose"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DOSE_THREADS"
- THR_LIBS=
- THR_LIB_NAME=ose_threads
- THR_LIB_TYPE=ose_threads
-else
- AC_MSG_RESULT(no)
- THR_DEFS=
- THR_LIBS=
- THR_LIB_NAME=
- THR_LIB_TYPE=posix_unknown
-
-dnl Try to find POSIX threads
-
-dnl The usual pthread lib...
- AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread")
-
-dnl Very old versions of FreeBSD have pthreads in special c library, c_r...
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r")
- fi
-
-dnl QNX has pthreads in standard C library
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed")
- fi
-
-dnl On ofs1 the '-pthread' switch should be used
- if test "x$THR_LIBS" = "x"; then
- AC_MSG_CHECKING([if the '-pthread' switch can be used])
- saved_cflags=$CFLAGS
- CFLAGS="$CFLAGS -pthread"
- AC_TRY_LINK([#include <pthread.h>],
- pthread_create((void*)0,(void*)0,(void*)0,(void*)0);,
- [THR_DEFS="-pthread"
- THR_LIBS="-pthread"])
- CFLAGS=$saved_cflags
- if test "x$THR_LIBS" != "x"; then
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- if test "x$THR_LIBS" != "x"; then
- THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS"
- THR_LIB_NAME=pthread
- if test "x$THR_LIBS" = "xnone_needed"; then
- THR_LIBS=
- fi
- case $host_os in
- solaris*)
- THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;;
- linux*)
- THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS"
-
- LM_CHECK_GETCONF
- AC_MSG_CHECKING(for Native POSIX Thread Library)
- libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null`
- if test $? -eq 0; then
- case "$libpthr_vsn" in
- *nptl*|*NPTL*) nptl=yes;;
- *) nptl=no;;
- esac
- elif test "$cross_compiling" = "yes"; then
- case "$erl_xcomp_linux_nptl" in
- "") nptl=cross;;
- yes|no) nptl=$erl_xcomp_linux_nptl;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);;
- esac
- else
- nptl=no
- fi
- AC_MSG_RESULT($nptl)
- if test $nptl = cross; then
- nptl=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $nptl = yes; then
- THR_LIB_TYPE=posix_nptl
- need_nptl_incldir=no
- AC_CHECK_HEADER(nptl/pthread.h,
- [need_nptl_incldir=yes
- NEED_NPTL_PTHREAD_H=yes])
- if test $need_nptl_incldir = yes; then
- # Ahh...
- nptl_path="$C_INCLUDE_PATH:$CPATH"
- if test X$cross_compiling != Xyes; then
- nptl_path="$nptl_path:/usr/local/include:/usr/include"
- else
- IROOT="$erl_xcomp_isysroot"
- test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot"
- test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot])
- nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include"
- fi
- nptl_ws_path=
- save_ifs="$IFS"; IFS=":"
- for dir in $nptl_path; do
- if test "x$dir" != "x"; then
- nptl_ws_path="$nptl_ws_path $dir"
- fi
- done
- IFS=$save_ifs
- nptl_incldir=
- for dir in $nptl_ws_path; do
- AC_CHECK_HEADER($dir/nptl/pthread.h,
- nptl_incldir=$dir/nptl)
- if test "x$nptl_incldir" != "x"; then
- THR_DEFS="$THR_DEFS -isystem $nptl_incldir"
- break
- fi
- done
- if test "x$nptl_incldir" = "x"; then
- AC_MSG_ERROR(Failed to locate nptl system include directory)
- fi
- fi
- fi
- ;;
- *) ;;
- esac
-
- dnl We sometimes need THR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS $THR_DEFS"
-
- dnl
- dnl Check for headers
- dnl
-
- AC_CHECK_HEADER(pthread.h,
- AC_DEFINE(HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- fi
-fi
-
-])
-
-AC_DEFUN(ERL_INTERNAL_LIBS,
-[
-
-ERTS_INTERNAL_X_LIBS=
-
-AC_CHECK_LIB(kstat, kstat_open,
-[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat])
-ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"])
-
-AC_SUBST(ERTS_INTERNAL_X_LIBS)
-
-])
-
-AC_DEFUN(ETHR_CHK_SYNC_OP,
-[
- AC_MSG_CHECKING([for $3-bit $1()])
- case "$2" in
- "1") sync_call="$1(&var);";;
- "2") sync_call="$1(&var, ($4) 0);";;
- "3") sync_call="$1(&var, ($4) 0, ($4) 0);";;
- esac
- have_sync_op=no
- AC_TRY_LINK([],
- [
- $4 res;
- volatile $4 var;
- res = $sync_call
- ],
- [have_sync_op=yes])
- test $have_sync_op = yes && $5
- AC_MSG_RESULT([$have_sync_op])
-])
-
-AC_DEFUN(ETHR_CHK_INTERLOCKED,
-[
- ilckd="$1"
- AC_MSG_CHECKING([for ${ilckd}()])
- case "$2" in
- "1") ilckd_call="${ilckd}(var);";;
- "2") ilckd_call="${ilckd}(var, ($3) 0);";;
- "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";;
- "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";;
- esac
- have_interlocked_op=no
- AC_TRY_LINK(
- [
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <intrin.h>
- ],
- [
- volatile $3 *var;
- volatile $3 arr[2];
-
- $ilckd_call
- return 0;
- ],
- [have_interlocked_op=yes])
- test $have_interlocked_op = yes && $4
- AC_MSG_RESULT([$have_interlocked_op])
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_FIND_ETHR_LIB
-dnl
-dnl NOTE! This macro may be changed at any time! Should *only* be used by
-dnl ERTS!
-dnl
-dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link
-dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS
-dnl except that the ethread lib itself is not included), ETHR_DEFS to
-dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the
-dnl thread library which the ethread library is based on, and ETHR_LIB_NAME
-dnl to the name of the library where the ethread implementation is located.
-dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and
-dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS,
-dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the
-dnl empty string.
-dnl
-
-AC_DEFUN(ERL_FIND_ETHR_LIB,
-[
-
-AC_ARG_ENABLE(native-ethr-impls,
- AS_HELP_STRING([--disable-native-ethr-impls],
- [disable native ethread implementations]),
-[ case "$enableval" in
- no) disable_native_ethr_impls=yes ;;
- *) disable_native_ethr_impls=no ;;
- esac ], disable_native_ethr_impls=no)
-
-test "X$disable_native_ethr_impls" = "Xyes" &&
- AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations])
-
-AC_ARG_ENABLE(x86-out-of-order,
- AS_HELP_STRING([--enable-x86-out-of-order],
- [enable x86/x84_64 out of order support (default disabled)]))
-
-AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
- AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls],
- [prefer gcc native ethread implementations]),
-[ case "$enableval" in
- yes) enable_prefer_gcc_native_ethr_impls=yes ;;
- *) enable_prefer_gcc_native_ethr_impls=no ;;
- esac ], enable_prefer_gcc_native_ethr_impls=no)
-
-test $enable_prefer_gcc_native_ethr_impls = yes &&
- AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations])
-
-AC_ARG_WITH(libatomic_ops,
- AS_HELP_STRING([--with-libatomic_ops=PATH],
- [specify and prefer usage of libatomic_ops in the ethread library]))
-
-AC_ARG_WITH(with_sparc_memory_order,
- AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO],
- [specify sparc memory order (defaults to RMO)]))
-
-LM_CHECK_THR_LIB
-ERL_INTERNAL_LIBS
-
-ethr_have_native_atomics=no
-ethr_have_native_spinlock=no
-ETHR_THR_LIB_BASE="$THR_LIB_NAME"
-ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE"
-ETHR_DEFS="$THR_DEFS"
-ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS"
-ETHR_LIBS=
-ETHR_LIB_NAME=
-
-ethr_modified_default_stack_size=
-
-dnl Name of lib where ethread implementation is located
-ethr_lib_name=ethread
-
-case "$THR_LIB_NAME" in
-
- win32_threads)
- ETHR_THR_LIB_BASE_DIR=win
- # * _WIN32_WINNT >= 0x0400 is needed for
- # TryEnterCriticalSection
- # * _WIN32_WINNT >= 0x0403 is needed for
- # InitializeCriticalSectionAndSpinCount
- # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403.
- #
- # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it
- # and save it in ETHR_DEFS.
- found_win32_winnt=no
- for cppflag in $CPPFLAGS; do
- case $cppflag in
- -DWINVER*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- ;;
- -D_WIN32_WINNT*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- found_win32_winnt=yes
- ;;
- *)
- ;;
- esac
- done
- if test $found_win32_winnt = no; then
- AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
- fi
-
- AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- have_interlocked_op=no
- ethr_have_native_atomics=no
- else
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()]))
- fi
- test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
- ;;
-
- pthread|ose_threads)
- case "$THR_LIB_NAME" in
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
- ;;
- ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1,
- [Define if you have OSE style threads])
- ETHR_THR_LIB_BASE_DIR=ose
- AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI_H, 1,
- [Define if you have the "ose_spi/ose_spi.h" header file.]))
- ;;
- esac
- if test "x$THR_LIB_NAME" = "xpthread"; then
- case $host_os in
- openbsd*)
- # The default stack size is insufficient for our needs
- # on OpenBSD. We increase it to 256 kilo words.
- ethr_modified_default_stack_size=256;;
- linux*)
- ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE"
-
- if test X$cross_compiling = Xyes; then
- case X$erl_xcomp_linux_usable_sigusrx in
- X) usable_sigusrx=cross;;
- Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);;
- esac
- case X$erl_xcomp_linux_usable_sigaltstack in
- X) usable_sigaltstack=cross;;
- Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);;
- esac
- else
- # FIXME: Test for actual problems instead of kernel versions
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
- usable_sigusrx=no
- usable_sigaltstack=no;;
- 2.[[2-3]]|2.[[2-3]].*)
- usable_sigusrx=yes
- usable_sigaltstack=no;;
- *)
- usable_sigusrx=yes
- usable_sigaltstack=yes;;
- esac
- fi
-
- AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
- AC_MSG_RESULT($usable_sigusrx)
- if test $usable_sigusrx = cross; then
- usable_sigusrx=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigusrx = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX"
- fi
-
- AC_MSG_CHECKING(if sigaltstack can be used)
- AC_MSG_RESULT($usable_sigaltstack)
- if test $usable_sigaltstack = cross; then
- usable_sigaltstack=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigaltstack = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
- fi
- ;;
- *) ;;
- esac
-
- fi
- dnl We sometimes need ETHR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $ETHR_DEFS"
-
- dnl We need the thread library in order to find some functions
- saved_libs="$LIBS"
- LIBS="$LIBS $ETHR_X_LIBS"
-
- dnl
- dnl Check for headers
- dnl
- AC_CHECK_HEADER(pthread.h, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- if test $NEED_NPTL_PTHREAD_H = yes; then
- AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \
-[Define if you need the <nptl/pthread.h> header file.])
- fi
-
- AC_CHECK_HEADER(sched.h, \
- AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \
-[Define if you have the <sched.h> header file.]))
-
- AC_CHECK_HEADER(sys/time.h, \
- AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \
-[Define if you have the <sys/time.h> header file.]))
-
- AC_TRY_COMPILE([#include <time.h>
- #include <sys/time.h>],
- [struct timeval *tv; return 0;],
- AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \
-[Define if you can safely include both <sys/time.h> and <time.h>.]))
-
-
- dnl
- dnl Check for functions
- dnl
- if test "x$THR_LIB_NAME" = "xpthread"; then
- AC_CHECK_FUNC(pthread_spin_lock, \
- [ethr_have_native_spinlock=yes \
- AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
-[Define if you have the pthread_spin_lock function.])])
-
- have_sched_yield=no
- have_librt_sched_yield=no
- AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes])
- if test $have_sched_yield = no; then
- AC_CHECK_LIB(rt, sched_yield,
- [have_librt_sched_yield=yes
- ETHR_X_LIBS="$ETHR_X_LIBS -lrt"])
- fi
- if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then
- AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.])
- AC_MSG_CHECKING([whether sched_yield() returns an int])
- sched_yield_ret_int=no
- AC_TRY_COMPILE([
- #ifdef ETHR_HAVE_SCHED_H
- #include <sched.h>
- #endif
- ],
- [int sched_yield();],
- [sched_yield_ret_int=yes])
- AC_MSG_RESULT([$sched_yield_ret_int])
- if test $sched_yield_ret_int = yes; then
- AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.])
- fi
- fi
-
- have_pthread_yield=no
- AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes])
- if test $have_pthread_yield = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.])
- AC_MSG_CHECKING([whether pthread_yield() returns an int])
- pthread_yield_ret_int=no
- AC_TRY_COMPILE([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [int pthread_yield();],
- [pthread_yield_ret_int=yes])
- AC_MSG_RESULT([$pthread_yield_ret_int])
- if test $pthread_yield_ret_int = yes; then
- AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.])
- fi
- fi
-
- have_pthread_rwlock_init=no
- AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes])
- if test $have_pthread_rwlock_init = yes; then
-
- ethr_have_pthread_rwlockattr_setkind_np=no
- AC_CHECK_FUNC(pthread_rwlockattr_setkind_np,
- [ethr_have_pthread_rwlockattr_setkind_np=yes])
-
- if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \
-[Define if you have the pthread_rwlockattr_setkind_np() function.])
-
- AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP])
- ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no
- AC_TRY_LINK([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [
- pthread_rwlockattr_t *attr;
- return pthread_rwlockattr_setkind_np(attr,
- PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
- ],
- [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes])
- AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np])
- if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \
-[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.])
- fi
- fi
- fi
-
- if test "$force_pthread_rwlocks" = "yes"; then
-
- AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \
-[Define if you want to force usage of pthread rwlocks])
-
- if test $have_pthread_rwlock_init = yes; then
- AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.])
- else
- AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found])
- fi
- fi
-
- AC_CHECK_FUNC(pthread_attr_setguardsize, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \
-[Define if you have the pthread_attr_setguardsize function.]))
-
- linux_futex=no
- AC_MSG_CHECKING([for Linux futexes])
- AC_TRY_LINK([
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/futex.h>
- #include <sys/time.h>
- ],
- [
- int i = 1;
- syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1,
- (void*)0,(void*)0, 0);
- syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0,
- (void*)0,(void*)0, 0);
- return 0;
- ],
- linux_futex=yes)
- AC_MSG_RESULT([$linux_futex])
- test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
-
- fi
-
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_CHECK_SIZEOF(long long)
- AC_CHECK_SIZEOF(__int128_t)
-
- if test "$ac_cv_sizeof_int" = "4"; then
- int32="int"
- elif test "$ac_cv_sizeof_long" = "4"; then
- int32="long"
- elif test "$ac_cv_sizeof_long_long" = "4"; then
- int32="long long"
- else
- AC_MSG_ERROR([No 32-bit type found])
- fi
-
- if test "$ac_cv_sizeof_int" = "8"; then
- int64="int"
- elif test "$ac_cv_sizeof_long" = "8"; then
- int64="long"
- elif test "$ac_cv_sizeof_long_long" = "8"; then
- int64="long long"
- else
- AC_MSG_ERROR([No 64-bit type found])
- fi
-
- int128=no
- if test "$ac_cv_sizeof___int128_t" = "16"; then
- int128="__int128_t"
- fi
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- ethr_have_native_atomics=no
- else
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers]))
-
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers]))
-
- if test $int128 != no; then
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers]))
- fi
-
- AC_MSG_CHECKING([for a usable libatomic_ops implementation])
- case "x$with_libatomic_ops" in
- xno | xyes | x)
- libatomic_ops_include=
- ;;
- *)
- if test -d "${with_libatomic_ops}/include"; then
- libatomic_ops_include="-I$with_libatomic_ops/include"
- CPPFLAGS="$CPPFLAGS $libatomic_ops_include"
- else
- AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found])
- fi;;
- esac
- ethr_have_libatomic_ops=no
- AC_TRY_LINK([#include "atomic_ops.h"],
- [
- volatile AO_t x;
- AO_t y;
- int z;
-
- AO_nop_full();
- AO_store(&x, (AO_t) 0);
- z = AO_load(&x);
- z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1);
- ],
- [ethr_have_native_atomics=yes
- ethr_have_libatomic_ops=yes])
- AC_MSG_RESULT([$ethr_have_libatomic_ops])
- if test $ethr_have_libatomic_ops = yes; then
- AC_CHECK_SIZEOF(AO_t, ,
- [
- #include <stdio.h>
- #include "atomic_ops.h"
- ])
- AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used])
-
- AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations])
- if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations])
- fi
- ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include"
- elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_MSG_ERROR([No usable libatomic_ops implementation found])
- fi
-
- case "$host_cpu" in
- sparc | sun4u | sparc64 | sun4v)
- case "$with_sparc_memory_order" in
- "TSO")
- AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);;
- "PSO")
- AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);;
- "RMO"|"")
- AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);;
- *)
- AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);;
- esac
- ethr_have_native_atomics=yes;;
- i86pc | i*86 | x86_64 | amd64)
- if test "$enable_x86_out_of_order" = "yes"; then
- AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized])
- fi
- ethr_have_native_atomics=yes;;
- macppc | ppc | powerpc | "Power Macintosh")
- ethr_have_native_atomics=yes;;
- tile)
- ethr_have_native_atomics=yes;;
- *)
- ;;
- esac
-
- fi
-
- test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes
-
- dnl Restore LIBS
- LIBS=$saved_libs
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- ;;
- *)
- ;;
-esac
-
-AC_MSG_CHECKING([whether default stack size should be modified])
-if test "x$ethr_modified_default_stack_size" != "x"; then
- AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size])
- AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words])
-else
- AC_MSG_RESULT([no])
-fi
-
-if test "x$ETHR_THR_LIB_BASE" != "x"; then
- ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS"
- ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS"
- ETHR_LIB_NAME=$ethr_lib_name
-fi
-
-AC_CHECK_SIZEOF(void *)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers])
-
-AC_CHECK_SIZEOF(int)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int])
-AC_CHECK_SIZEOF(long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long])
-AC_CHECK_SIZEOF(long long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long])
-AC_CHECK_SIZEOF(__int64)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64])
-AC_CHECK_SIZEOF(__int128_t)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t])
-
-
-case X$erl_xcomp_bigendian in
- X) ;;
- Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);;
-esac
-
-AC_C_BIGENDIAN
-
-if test "$ac_cv_c_bigendian" = "yes"; then
- AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian])
-fi
-
-case X$erl_xcomp_double_middle_endian in
- X) ;;
- Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);;
-esac
-
-AC_C_DOUBLE_MIDDLE_ENDIAN
-
-ETHR_X86_SSE2_ASM=no
-case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in
- yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64)
- AC_MSG_CHECKING([for gcc sse2 asm support])
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -msse2"
- gcc_sse2_asm=no
- AC_TRY_COMPILE([],
- [
- long long x, *y;
- __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory");
- ],
- [gcc_sse2_asm=yes])
- CFLAGS="$save_CFLAGS"
- AC_MSG_RESULT([$gcc_sse2_asm])
- if test "$gcc_sse2_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements])
- ETHR_X86_SSE2_ASM=yes
- fi
- ;;
- *)
- ;;
-esac
-
-case "$GCC-$host_cpu" in
- yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64)
- gcc_dw_cmpxchg_asm=no
- AC_MSG_CHECKING([for gcc double word cmpxchg asm support])
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
- __asm__ __volatile__(
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "pushl %%ebx\n\t"
- "movl %8, %%ebx\n\t"
-#endif
-#if ETHR_SIZEOF_PTR == 4
- "lock; cmpxchg8b %0\n\t"
-#else
- "lock; cmpxchg16b %0\n\t"
-#endif
- "setz %3\n\t"
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "popl %%ebx\n\t"
-#endif
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]),
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "r"(new[0])
-#else
- "b"(new[0])
-#endif
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
-#if !defined(__PIC__) || !__PIC__
-# error nope
-#endif
- __asm__ __volatile__(
- "pushl %%ebx\n\t"
- "movl (%7), %%ebx\n\t"
- "movl 4(%7), %%ecx\n\t"
- "lock; cmpxchg8b %0\n\t"
- "setz %3\n\t"
- "popl %%ebx\n\t"
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new)
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code])
- fi
- fi
- AC_MSG_RESULT([$gcc_dw_cmpxchg_asm])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction])
- fi;;
- *)
- ;;
-esac
-
-AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
-[Define if you have all ethread defines])
-
-AC_SUBST(ETHR_X_LIBS)
-AC_SUBST(ETHR_LIBS)
-AC_SUBST(ETHR_LIB_NAME)
-AC_SUBST(ETHR_DEFS)
-AC_SUBST(ETHR_THR_LIB_BASE)
-AC_SUBST(ETHR_THR_LIB_BASE_DIR)
-AC_SUBST(ETHR_X86_SSE2_ASM)
-
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_TIME_CORRECTION
-dnl
-dnl In the presence of a high resolution realtime timer Erlang can adapt
-dnl its view of time relative to this timer. On solaris such a timer is
-dnl available with the syscall gethrtime(). On other OS's a fallback
-dnl solution using times() is implemented. (However on e.g. FreeBSD times()
-dnl is implemented using gettimeofday so it doesn't make much sense to
-dnl use it there...) On second thought, it seems to be safer to do it the
-dnl other way around. I.e. only use times() on OS's where we know it will
-dnl work...
-dnl
-
-AC_DEFUN(ERL_TIME_CORRECTION,
-[if test x$ac_cv_func_gethrtime = x; then
- AC_CHECK_FUNC(gethrtime)
-fi
-if test x$clock_gettime_correction = xunknown; then
- AC_TRY_COMPILE([#include <time.h>],
- [struct timespec ts;
- long long result;
- clock_gettime(CLOCK_MONOTONIC,&ts);
- result = ((long long) ts.tv_sec) * 1000000000LL +
- ((long long) ts.tv_nsec);],
- clock_gettime_compiles=yes,
- clock_gettime_compiles=no)
-else
- clock_gettime_compiles=no
-fi
-
-
-AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction,
-[
-case $clock_gettime_correction in
- yes)
- erl_cv_time_correction=clock_gettime;;
- no|unknown)
- case $ac_cv_func_gethrtime in
- yes)
- erl_cv_time_correction=hrtime ;;
- no)
- case $host_os in
- linux*)
- case $clock_gettime_correction in
- unknown)
- if test x$clock_gettime_compiles = xyes; then
- if test X$cross_compiling != Xyes; then
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
- erl_cv_time_correction=times ;;
- *)
- erl_cv_time_correction=clock_gettime;;
- esac
- else
- case X$erl_xcomp_linux_clock_gettime_correction in
- X)
- erl_cv_time_correction=cross;;
- Xyes|Xno)
- if test $erl_xcomp_linux_clock_gettime_correction = yes; then
- erl_cv_time_correction=clock_gettime
- else
- erl_cv_time_correction=times
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);;
- esac
- fi
- else
- erl_cv_time_correction=times
- fi
- ;;
- *)
- erl_cv_time_correction=times ;;
- esac
- ;;
- *)
- erl_cv_time_correction=none ;;
- esac
- ;;
- esac
- ;;
-esac
-])
-
-xrtlib=""
-case $erl_cv_time_correction in
- times)
- AC_DEFINE(CORRECT_USING_TIMES,[],
- [Define if you do not have a high-res. timer & want to use times() instead])
- ;;
- clock_gettime|cross)
- if test $erl_cv_time_correction = cross; then
- erl_cv_time_correction=clock_gettime
- AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
- fi
- xrtlib="-lrt"
- AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
- [Define if you want to use clock_gettime to simulate gethrtime])
- ;;
-esac
-dnl
-dnl Check if gethrvtime is working, and if to use procfs ioctl
-dnl or (yet to be written) write to the procfs ctl file.
-dnl
-
-AC_MSG_CHECKING([if gethrvtime works and how to use it])
-AC_TRY_RUN([
-/* gethrvtime procfs ioctl test */
-/* These need to be undef:ed to not break activation of
- * micro level process accounting on /proc/self
- */
-#ifdef _LARGEFILE_SOURCE
-# undef _LARGEFILE_SOURCE
-#endif
-#ifdef _FILE_OFFSET_BITS
-# undef _FILE_OFFSET_BITS
-#endif
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/signal.h>
-#include <sys/fault.h>
-#include <sys/syscall.h>
-#include <sys/procfs.h>
-#include <fcntl.h>
-
-int main() {
- long msacct = PR_MSACCT;
- int fd;
- long long start, stop;
- int i;
- pid_t pid = getpid();
- char proc_self[30] = "/proc/";
-
- sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid);
- if ( (fd = open(proc_self, O_WRONLY)) == -1)
- exit(1);
- if (ioctl(fd, PIOCSET, &msacct) < 0)
- exit(2);
- if (close(fd) < 0)
- exit(3);
- start = gethrvtime();
- for (i = 0; i < 100; i++)
- stop = gethrvtime();
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
-}
-],
-erl_gethrvtime=procfs_ioctl,
-erl_gethrvtime=false,
-[
-case X$erl_xcomp_gethrvtime_procfs_ioctl in
- X)
- erl_gethrvtime=cross;;
- Xyes|Xno)
- if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then
- erl_gethrvtime=procfs_ioctl
- else
- erl_gethrvtime=false
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);;
-esac
-])
-
-case $erl_gethrvtime in
- procfs_ioctl)
- AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
- [define if gethrvtime() works and uses ioctl() to /proc/self])
- AC_MSG_RESULT(uses ioctl to procfs)
- ;;
- *)
- if test $erl_gethrvtime = cross; then
- erl_gethrvtime=false
- AC_MSG_RESULT(cross)
- AC_MSG_WARN([result 'not working' guessed because of cross compilation])
- else
- AC_MSG_RESULT(not working)
- fi
-
- dnl
- dnl Check if clock_gettime (linux) is working
- dnl
-
- AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time])
- save_libs=$LIBS
- LIBS="-lrt"
- AC_TRY_RUN([
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- int main() {
- long long start, stop;
- int i;
- struct timespec tp;
-
- if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0)
- exit(1);
- start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- for (i = 0; i < 100; i++)
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
- stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
- }
- ],
- erl_clock_gettime=yes,
- erl_clock_gettime=no,
- [
- case X$erl_xcomp_clock_gettime_cpu_time in
- X) erl_clock_gettime=cross;;
- Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;;
- *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);;
- esac
- ])
- LIBS=$save_libs
- case $host_os in
- linux*)
- AC_MSG_RESULT([no; not stable])
- LIBRT=$xrtlib
- ;;
- *)
- AC_MSG_RESULT($erl_clock_gettime)
- case $erl_clock_gettime in
- yes)
- AC_DEFINE(HAVE_CLOCK_GETTIME,[],
- [define if clock_gettime() works for getting process time])
- LIBRT=-lrt
- ;;
- cross)
- erl_clock_gettime=no
- AC_MSG_WARN([result no guessed because of cross compilation])
- LIBRT=$xrtlib
- ;;
- *)
- LIBRT=$xrtlib
- ;;
- esac
- ;;
- esac
- AC_SUBST(LIBRT)
- ;;
-esac
-])dnl
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_TRY_ENABLE_CFLAG
-dnl
-dnl
-dnl Tries a CFLAG and sees if it can be enabled without compiler errors
-dnl $1: textual cflag to add
-dnl $2: variable to store the modified CFLAG in
-dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
-dnl
-dnl
-AC_DEFUN([LM_TRY_ENABLE_CFLAG], [
- AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
- saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $$2";
- AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false)
- CFLAGS=$saved_CFLAGS;
- if test "X$can_enable_flag" = "Xtrue"; then
- AC_MSG_RESULT([yes])
- AS_VAR_SET($2, "$1 $$2")
- else
- AC_MSG_RESULT([no])
- fi
-])
-
-dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY
-dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]])
-dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a
-dnl AC_LANG_JAVA instead...)
-AC_DEFUN(ERL_TRY_LINK_JAVA,
-[java_link='$JAVAC conftest.java 1>&AC_FD_CC'
-changequote(, )dnl
-cat > conftest.java <<EOF
-$1
-class conftest { public static void main(String[] args) {
- $2
- ; return; }}
-EOF
-changequote([, ])dnl
-if AC_TRY_EVAL(java_link) && test -s conftest.class; then
- ifelse([$3], , :, [rm -rf conftest*
- $3])
-else
- echo "configure: failed program was:" 1>&AC_FD_CC
- cat conftest.java 1>&AC_FD_CC
- echo "configure: PATH was $PATH" 1>&AC_FD_CC
-ifelse([$4], , , [ rm -rf conftest*
- $4
-])dnl
-fi
-rm -f conftest*])
-#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */
-
-
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/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index dff36fd51c..fd654af051 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -36,7 +36,41 @@
section is the version number of Megaco.</p>
- <section><title>Megaco 3.17.1</title>
+ <section><title>Megaco 3.17.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Distribute <c>autoconf</c> helpers to applications at
+ build time instead of having multiple identical copies
+ committed in the repository.</p>
+ <p>
+ Own Id: OTP-12348</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Megaco 3.17.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Implement --enable-sanitizers[=sanitizers]. Similar to
+ debugging with Valgrind, it's very useful to enable
+ -fsanitize= switches to catch bugs at runtime.</p>
+ <p>
+ Own Id: OTP-12153</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Megaco 3.17.1</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src
index db59f55b55..92504e8e87 100644
--- a/lib/megaco/src/app/megaco.appup.src
+++ b/lib/megaco/src/app/megaco.appup.src
@@ -174,11 +174,23 @@
%% |
%% v
%% 3.17.0.3
+%% |
+%% v
+%% 3.17.1
+%% |
+%% v
+%% 3.17.2
+%% |
+%% v
+%% 3.17.3
%%
%%
{"%VSN%",
[
+ {"3.17.2", []},
+ {"3.17.1", [{restart_application,megaco}]},
+ {"3.17.0.3", [{restart_application,megaco}]},
{"3.17.0.2", []},
{"3.17.0.1", []},
{"3.17", []},
@@ -190,6 +202,9 @@
}
],
[
+ {"3.17.2", []},
+ {"3.17.1", [{restart_application,megaco}]},
+ {"3.17.0.3", [{restart_application,megaco}]},
{"3.17.0.2", []},
{"3.17.0.1", []},
{"3.17", []},
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index 373f5199bf..8687d622e9 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = megaco
-MEGACO_VSN = 3.17.1
+MEGACO_VSN = 3.17.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xml b/lib/mnesia/doc/src/Mnesia_chap3.xml
index d6b4a1c6a1..ae704b4199 100644
--- a/lib/mnesia/doc/src/Mnesia_chap3.xml
+++ b/lib/mnesia/doc/src/Mnesia_chap3.xml
@@ -152,7 +152,7 @@ Transformer =
<c>ignore</c>, it indicates that only the meta data about the table will
be updated. Usage of <c>ignore</c> is not recommended (since it creates
inconsistencies between the meta data and the actual data) but included
- as a possibility for the user do to his own (off-line) transform.</p>
+ as a possibility for the user to do his own (off-line) transform.</p>
</item>
<item><c>change_table_copy_type(Tab, Node, ToType)</c>. This
function changes the storage type of a table. For example, a
diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
index 65b950bd46..127c23e0f7 100644
--- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
@@ -867,6 +867,7 @@ ok
</section>
<section>
+ <marker id="event_handling"></marker>
<title>Mnesia Event Handling</title>
<p>System events and table events are the two categories of events
that Mnesia will generate in various situations.
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 72e9bd7e8f..ed5b879f7f 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -151,9 +151,9 @@ If a new item is inserted with the same key as
</item>
<item>
<p><c>local_content</c> When an application requires
- tables whose contents is local to each node,
+ tables whose contents are local to each node,
<c>local_content</c> tables may be used. The name of the
- table is known to all Mnesia nodes, but its contents is
+ table is known to all Mnesia nodes, but its contents are
unique on each node. This means that access to such a table
must be done locally. Set the <c>local_content</c> field to
<c>true</c> if you want to enable the <c>local_content</c>
@@ -579,7 +579,7 @@ mnesia:add_table_index(person, age)
<desc>
<p>The tables are backed up to external media using the backup
module <c>BackupMod</c>. Tables with the local contents
- property is being backed up as they exist on the current
+ property are backed up as they exist on the current
node. <c>BackupMod</c> is the default backup callback
module obtained by
<c>mnesia:system_info(backup_module)</c>. See the User's
@@ -863,7 +863,7 @@ mnesia:create_table(person,
{attributes, record_info(fields,person)}]).
</code>
<p>The specification of <c>index</c> and <c>attributes</c> may be
- hard coded as <c>{index, [2]}</c> and
+ hard coded as <c>{index, [4]}</c> and
<c>{attributes, [name, age, address, salary, children]}</c>
respectively.
</p>
@@ -2188,12 +2188,13 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>subscribe(EventCategory)</name>
+ <name>subscribe(EventCategory) -> {ok, Node} | {error, Reason} </name>
<fsummary>Subscribe to events of type <c>EventCategory</c>.</fsummary>
<desc>
<p>Ensures that a copy of all events of type
<c>EventCategory</c> are sent to the caller. The event
- types available are described in the Mnesia User's Guide.</p>
+ types available are described in the Mnesia User's Guide at <seealso marker="Mnesia_chap5#event_handling">Mnesia Event Handling</seealso>.</p>
+ <p><c>Node</c> is the local node. For table events to be subscribed, mnesia must have a readable local copy of the table on the node.</p>
</desc>
</func>
<func>
@@ -2766,7 +2767,7 @@ raise(Name, Amount) ->
new type. The <c>Fun</c> argument can also be the atom
<c>ignore</c>, it indicates that only the meta data about the table will
be updated. Usage of <c>ignore</c> is not recommended but included
- as a possibility for the user do to his own transform.
+ as a possibility for the user to do his own transform.
<c>NewAttributeList</c> and <c>NewRecordName</c>
specifies the attributes and the new record type of converted
table. Table name will always remain unchanged, if the
@@ -2861,11 +2862,12 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>unsubscribe(EventCategory)</name>
+ <name>unsubscribe(EventCategory) -> {ok, Node} | {error, Reason} </name>
<fsummary>Subscribe to events of type <c>EventCategory</c>.</fsummary>
<desc>
<p>Stops sending events of type
<c>EventCategory</c> to the caller.</p>
+ <p><c>Node</c> is the local node.</p>
</desc>
</func>
<func>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 213c2b6d21..18f72f4faf 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -38,7 +38,88 @@
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.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a spelling mistake in mnesia documentation.</p>
+ <p>
+ Own Id: OTP-12278</p>
+ </item>
+ <item>
+ <p>
+ Matching data with <c>mnesia:match_object/1</c> did not
+ work as expected in some cases, when data was written in
+ the same transaction before the matching was invoked.</p>
+ <p>
+ Own Id: OTP-12304 Aux Id: Seq12745 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.12.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Various logging fixes, including: Add run queue index to
+ the process dump in crash dumps.<br/> Add thread index to
+ enomem slogan when crashing.<br/> Remove error logger
+ message for sending messages to old instances of the same
+ node.</p>
+ <p>
+ Own Id: OTP-12115</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.12.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a race which could make create_table fail if a node
+ was going down during the transaction.</p>
+ <p>
+ Own Id: OTP-12124 Aux Id: seq12694 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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.erl b/lib/mnesia/src/mnesia.erl
index b7d80c1370..8f14831ad3 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -1140,10 +1140,12 @@ match_object(_Tid, _Ts, Tab, Pat, _LockKind) ->
add_written_match(S, Pat, Tab, Objs) ->
Ops = find_ops(S, Tab, Pat),
- add_match(Ops, Objs, val({Tab, setorbag})).
+ FixedRes = add_match(Ops, Objs, val({Tab, setorbag})),
+ MS = ets:match_spec_compile([{Pat, [], ['$_']}]),
+ ets:match_spec_run(FixedRes, MS).
find_ops(S, Tab, Pat) ->
- GetWritten = [{{{Tab, '_'}, Pat, write}, [], ['$_']},
+ GetWritten = [{{{Tab, '_'}, '_', write}, [], ['$_']},
{{{Tab, '_'}, '_', delete}, [], ['$_']},
{{{Tab, '_'}, Pat, delete_object}, [], ['$_']}],
ets:select(S, GetWritten).
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index fe2fd67d71..5a9bae54da 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -300,8 +300,13 @@ mnesia_down(Node) ->
end.
wait_for_schema_commit_lock() ->
- link(whereis(?SERVER_NAME)),
- unsafe_call(wait_for_schema_commit_lock).
+ try
+ Pid = whereis(?SERVER_NAME),
+ link(Pid), %% Keep the link until release_schema_commit_lock
+ gen_server:call(Pid, wait_for_schema_commit_lock, infinity)
+ catch _:_ ->
+ mnesia:abort({node_not_running, node()})
+ end.
block_controller() ->
call(block_controller).
@@ -557,12 +562,6 @@ cast(Msg) ->
abcast(Nodes, Msg) ->
gen_server:abcast(Nodes, ?SERVER_NAME, Msg).
-unsafe_call(Msg) ->
- case whereis(?SERVER_NAME) of
- undefined -> {error, {node_not_running, node()}};
- Pid -> gen_server:call(Pid, Msg, infinity)
- end.
-
call(Msg) ->
case whereis(?SERVER_NAME) of
undefined ->
diff --git a/lib/mnesia/src/mnesia_frag.erl b/lib/mnesia/src/mnesia_frag.erl
index 4a1616e054..66fc20913c 100644
--- a/lib/mnesia/src/mnesia_frag.erl
+++ b/lib/mnesia/src/mnesia_frag.erl
@@ -939,7 +939,7 @@ do_split(_FH, _OldN, _FragNames, [], Ops) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Delete a fragment from a fragmented table
-%% and merge its records with an other fragment
+%% and merge its records with another fragment
make_multi_del_frag(Tab) ->
verify_multi(Tab),
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 4afbea1cc2..530317bcdd 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -208,7 +208,8 @@ do_get_network_copy(Tab, Reason, Ns, Storage, Cs) ->
set({Tab, load_node}, Node),
set({Tab, load_reason}, Reason),
mnesia_controller:i_have_tab(Tab),
- dbg_out("Table ~p copied from ~p to ~p~n", [Tab, Node, node()]),
+ dbg_out("Table ~p copied from ~p to ~p (~b entries)~n",
+ [Tab, Node, node(), mnesia:table_info(Tab, size)]),
{loaded, ok};
Err = {error, _} when element(1, Reason) == dumper ->
{not_loaded,Err};
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/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl
index b6492707e2..eeb4fa0ced 100644
--- a/lib/mnesia/src/mnesia_recover.erl
+++ b/lib/mnesia/src/mnesia_recover.erl
@@ -689,12 +689,29 @@ handle_call({connect_nodes, Ns}, From, State) ->
%% called from handle_info
gen_server:reply(From, {[], AlreadyConnected}),
{noreply, State};
- GoodNodes ->
+ ProbablyGoodNodes ->
%% Now we have agreed upon a protocol with some new nodes
- %% and we may use them when we recover transactions
+ %% and we may use them when we recover transactions.
+ %%
+ %% Just in case Mnesia was stopped on some of those nodes
+ %% between the protocol negotiation and now, we check one
+ %% more time the state of Mnesia.
+ %%
+ %% Of course, there is still a chance that mnesia_down
+ %% events occur during this check and we miss them. To
+ %% prevent it, handle_cast({mnesia_down, ...}, ...) removes
+ %% the down node again, in addition to mnesia_down/1.
+ %%
+ %% See a comment in handle_cast({mnesia_down, ...}, ...).
+ Verify = fun(N) ->
+ Run = mnesia_lib:is_running(N),
+ Run =:= yes orelse Run =:= starting
+ end,
+ GoodNodes = [N || N <- ProbablyGoodNodes, Verify(N)],
+
mnesia_lib:add_list(recover_nodes, GoodNodes),
cast({announce_all, GoodNodes}),
- case get_master_nodes(schema) of
+ case get_master_nodes(schema) of
[] ->
Context = starting_partitioned_network,
mnesia_monitor:detect_inconcistency(GoodNodes, Context);
@@ -842,6 +859,14 @@ handle_cast({what_decision, Node, OtherD}, State) ->
{noreply, State};
handle_cast({mnesia_down, Node}, State) ->
+ %% The node was already removed from recover_nodes in mnesia_down/1,
+ %% but we do it again here in the mnesia_recover process, in case
+ %% another event incorrectly added it back. This can happen during
+ %% Mnesia startup which takes time betweenthe connection, the
+ %% protocol negotiation and the merge of the schema.
+ %%
+ %% See a comment in handle_call({connect_nodes, ...), ...).
+ mnesia_lib:del(recover_nodes, Node),
case State#state.unclear_decision of
undefined ->
{noreply, State};
diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl
index 9272211ad2..866a57e370 100644
--- a/lib/mnesia/src/mnesia_subscr.erl
+++ b/lib/mnesia/src/mnesia_subscr.erl
@@ -225,7 +225,7 @@ call(Msg) ->
Res = gen_server:call(Pid, Msg, infinity),
%% We get an exit signal if server dies
receive
- {'EXIT', _Pid, _Reason} ->
+ {'EXIT', Pid, _Reason} ->
{error, {node_not_running, node()}}
after 0 ->
Res
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index d57f976d1f..8468472cf2 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -1584,7 +1584,8 @@ write_shadows(Config) when is_list(Config) ->
?match([RecA2], mnesia:read({Tab, a})),
?match([RecA2], mnesia:wread({Tab, a})),
- ?match([RecA2], mnesia:match_object(PatA2)), %% delete shadow old but not new write - is the new value visable
+ ?match([], mnesia:match_object(PatA1)), %% delete shadow old but not new write
+ ?match([RecA2], mnesia:match_object(PatA2)), %% is the new value visable
?match([a], mnesia:all_keys(Tab)),
?match([RecA2], mnesia:index_match_object(PatA2, ValPos)),
@@ -1643,6 +1644,7 @@ delete_shadows(Config) when is_list(Config) ->
?match([RecA2], mnesia:read({Tab, a})),
?match([RecA2], mnesia:wread({Tab, a})),
+ ?match([], mnesia:match_object(PatA1)),
?match([RecA2], mnesia:match_object(PatA2)),
?match([a], mnesia:all_keys(Tab)),
?match([RecA2], mnesia:index_match_object(PatA2, ValPos)),
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index c596f98c81..94eb360591 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.12
+MNESIA_VSN = 4.12.4
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index a2c5eda9d7..11729078c2 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -31,6 +31,60 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 2.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A note saying only R15B nodes can be observed is removed
+ from the user guide.</p>
+ <p>
+ Own Id: OTP-12078</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed statusbar on Windows</p>
+ <p>
+ Own Id: OTP-12162</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/doc/src/observer_ug.xml b/lib/observer/doc/src/observer_ug.xml
index 3aeaf1997a..62f99c5210 100644
--- a/lib/observer/doc/src/observer_ug.xml
+++ b/lib/observer/doc/src/observer_ug.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2011</year><year>2013</year>
+ <year>2011</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -54,9 +54,6 @@
impact only the active viewer is updated and the other
views will be updated when activated.
</p>
- <note>
- <p>Only R15B nodes can be observed.</p>
- </note>
<p> In general the mouse buttons behaves as expected, use left click
to select objects, right click to pop up a menu with most used
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..c8a6023b4f 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 2.0
+OBSERVER_VSN = 2.0.3
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
deleted file mode 100644
index ed492d55ff..0000000000
--- a/lib/odbc/aclocal.m4
+++ /dev/null
@@ -1,1954 +0,0 @@
-dnl
-dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
-dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
-dnl
-dnl %CopyrightEnd%
-dnl
-
-dnl
-dnl aclocal.m4
-dnl
-dnl Local macros used in configure.in. The Local Macros which
-dnl could/should be part of autoconf are prefixed LM_, macros specific
-dnl to the Erlang system are prefixed ERL_.
-dnl
-
-AC_DEFUN(LM_PRECIOUS_VARS,
-[
-
-dnl ERL_TOP
-AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory])
-
-dnl Tools
-AC_ARG_VAR(CC, [C compiler])
-AC_ARG_VAR(CFLAGS, [C compiler flags])
-AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags])
-AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler])
-AC_ARG_VAR(CPP, [C/C++ preprocessor])
-AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags])
-AC_ARG_VAR(CXX, [C++ compiler])
-AC_ARG_VAR(CXXFLAGS, [C++ compiler flags])
-AC_ARG_VAR(LD, [linker (is often overridden by configure)])
-AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)])
-AC_ARG_VAR(LIBS, [libraries])
-AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)])
-AC_ARG_VAR(RANLIB, [ranlib])
-AC_ARG_VAR(AR, [ar])
-AC_ARG_VAR(GETCONF, [getconf])
-
-dnl Cross system root
-AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)])
-
-dnl Cross compilation variables
-AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-
-dnl Cross compilation variables for OSE
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file])
-AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
-
-])
-
-AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
-[
-erl_xcomp_without_sysroot=no
-if test "$cross_compiling" = "yes"; then
- test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes
- test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot"
-else
- erl_xcomp_sysroot=
- erl_xcomp_isysroot=
-fi
-])
-
-AC_DEFUN(LM_CHECK_GETCONF,
-[
-if test "$cross_compiling" != "yes"; then
- AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false])
-else
- dnl First check if we got a `<HOST>-getconf' in $PATH
- host_getconf="$host_alias-getconf"
- AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false])
- if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then
- dnl We should perhaps give up if we have'nt found it by now, but at
- dnl least in one Tilera MDE `getconf' under sysroot is a bourne
- dnl shell script which we can use. We try to find `<HOST>-getconf'
- dnl or `getconf' under sysconf, but only under sysconf since
- dnl `getconf' in $PATH is almost guaranteed to be for the build
- dnl machine.
- GETCONF=
- prfx="$erl_xcomp_sysroot"
- AC_PATH_TOOL([GETCONF], [getconf], [false],
- ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"])
- fi
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_WINDOWS_ENVIRONMENT
-dnl
-dnl
-dnl Tries to determine thw windows build environment, i.e.
-dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC
-dnl
-
-AC_DEFUN(LM_WINDOWS_ENVIRONMENT,
-[
-MIXED_CYGWIN=no
-MIXED_MSYS=no
-
-AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment)
-if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([Cygwin and VC])
- MIXED_CYGWIN_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
- elif test -x /usr/bin/msysinfo; then
- CFLAGS="-O2"
- MIXED_MSYS=yes
- AC_MSG_RESULT([MSYS and VC])
- MIXED_MSYS_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
-else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_VC=no
- MIXED_MSYS_VC=no
-fi
-AC_SUBST(MIXED_CYGWIN_VC)
-AC_SUBST(MIXED_MSYS_VC)
-
-MIXED_VC=no
-if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then
- MIXED_VC=yes
-fi
-
-AC_SUBST(MIXED_VC)
-
-if test "x$MIXED_MSYS" != "xyes"; then
- AC_MSG_CHECKING(for mixed cygwin and native MinGW environment)
- if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([yes])
- MIXED_CYGWIN_MINGW=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
- else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_MINGW=no
- fi
-else
- MIXED_CYGWIN_MINGW=no
-fi
-AC_SUBST(MIXED_CYGWIN_MINGW)
-
-AC_MSG_CHECKING(if we mix cygwin with any native compiler)
-if test "X$MIXED_CYGWIN" = "Xyes"; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_CYGWIN)
-
-AC_MSG_CHECKING(if we mix msys with another native compiler)
-if test "X$MIXED_MSYS" = "Xyes" ; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_MSYS)
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_FIND_EMU_CC
-dnl
-dnl
-dnl Tries fairly hard to find a C compiler that can handle jump tables.
-dnl Defines the @EMU_CC@ variable for the makefiles and
-dnl inserts NO_JUMP_TABLE in the header if one cannot be found...
-dnl
-
-AC_DEFUN(LM_FIND_EMU_CC,
- [AC_CACHE_CHECK(for a compiler that handles jumptables,
- ac_cv_prog_emu_cc,
- [
-AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
-lbl1:
- return 1;
-lbl2:
- return 2;
-],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
-
-if test $ac_cv_prog_emu_cc = no; then
- for ac_progname in emu_cc.sh gcc-4.2 gcc; do
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_progname; then
- ac_cv_prog_emu_cc=$ac_dir/$ac_progname
- break
- fi
- done
- IFS="$ac_save_ifs"
- if test $ac_cv_prog_emu_cc != no; then
- break
- fi
- done
-fi
-
-if test $ac_cv_prog_emu_cc != no; then
- save_CC=$CC
- save_CFLAGS=$CFLAGS
- save_CPPFLAGS=$CPPFLAGS
- CC=$ac_cv_prog_emu_cc
- CFLAGS=""
- CPPFLAGS=""
- AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
- lbl1:
- return 1;
- lbl2:
- return 2;
- ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
- CC=$save_CC
- CFLAGS=$save_CFLAGS
- CPPFLAGS=$save_CPPFLAGS
-fi
-])
-if test $ac_cv_prog_emu_cc = no; then
- AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables])
- EMU_CC=$CC
-else
- EMU_CC=$ac_cv_prog_emu_cc
-fi
-AC_SUBST(EMU_CC)
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_INSTALL_DIR
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl Figure out how to create directories with parents.
-dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better)
-dnl
-dnl We prefer 'install -d', but use 'mkdir -p' if it exists.
-dnl If none of these methods works, we give up.
-dnl
-
-
-AC_DEFUN(LM_PROG_INSTALL_DIR,
-[AC_CACHE_CHECK(how to create a directory including parents,
-ac_cv_prog_mkdir_p,
-[
-temp_name_base=config.$$
-temp_name=$temp_name_base/x/y/z
-$INSTALL -d $temp_name >/dev/null 2>&1
-ac_cv_prog_mkdir_p=none
-if test -d $temp_name; then
- ac_cv_prog_mkdir_p="$INSTALL -d"
-else
- mkdir -p $temp_name >/dev/null 2>&1
- if test -d $temp_name; then
- ac_cv_prog_mkdir_p="mkdir -p"
- fi
-fi
-rm -fr $temp_name_base
-])
-
-case "${ac_cv_prog_mkdir_p}" in
- none) AC_MSG_ERROR(don't know how create directories with parents) ;;
- *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_PERL5
-dnl
-dnl Try to find perl version 5. If found set PERL to the absolute path
-dnl of the program, if not found set PERL to false.
-dnl
-dnl On some systems /usr/bin/perl is perl 4 and e.g.
-dnl /usr/local/bin/perl is perl 5. We try to handle this case by
-dnl putting a couple of
-dnl Tries to handle the case that there are two programs called perl
-dnl in the path and one of them is perl 5 and the other isn't.
-dnl
-AC_DEFUN(LM_PROG_PERL5,
-[AC_PATH_PROGS(PERL, perl5 perl, false,
- /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH})
-changequote(, )dnl
-dnl[ That bracket is needed to balance the right bracket below
-if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then
-changequote([, ])dnl
- ac_cv_path_PERL=false
- PERL=false
-dnl AC_MSG_WARN(perl version 5 not found)
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SO_BSDCOMPAT
-dnl
-dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux)
-dnl
-AC_DEFUN(LM_DECL_SO_BSDCOMPAT,
-[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat,
-AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;],
- ac_cv_decl_so_bsdcompat=yes,
- ac_cv_decl_so_bsdcompat=no))
-
-case "${ac_cv_decl_so_bsdcompat}" in
- "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[],
- [Define if you have SO_BSDCOMPAT flag on sockets]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_INADDR_LOOPBACK
-dnl
-dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default
-dnl
-
-AC_DEFUN(LM_DECL_INADDR_LOOPBACK,
-[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h],
- ac_cv_decl_inaddr_loopback,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>], [int i = INADDR_LOOPBACK;],
-ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no)
-])
-
-if test ${ac_cv_decl_inaddr_loopback} = no; then
- AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h],
- ac_cv_decl_inaddr_loopback_rpc,
- AC_TRY_COMPILE([#include <rpc/types.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_rpc=yes,
- ac_cv_decl_inaddr_loopback_rpc=no))
-
- case "${ac_cv_decl_inaddr_loopback_rpc}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[],
- [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;;
- * )
- AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h],
- ac_cv_decl_inaddr_loopback_winsock2,
- AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_winsock2=yes,
- ac_cv_decl_inaddr_loopback_winsock2=no))
- case "${ac_cv_decl_inaddr_loopback_winsock2}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[],
- [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;;
- * )
- # couldn't find it anywhere
- AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[],
- [Define if you don't have a definition of INADDR_LOOPBACK]) ;;
- esac;;
- esac
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_SOCKADDR_SA_LEN
-dnl
-dnl Check if the sockaddr structure has the field sa_len
-dnl
-
-AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN,
-[AC_CACHE_CHECK([whether struct sockaddr has sa_len field],
- ac_cv_struct_sockaddr_sa_len,
-AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;],
- ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no))
-
-dnl FIXME convbreak
-case ${ac_cv_struct_sockaddr_sa_len} in
- "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;;
- *) ;;
-esac
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_EXCEPTION
-dnl
-dnl Check to see whether the system supports the matherr function
-dnl and its associated type "struct exception".
-dnl
-
-AC_DEFUN(LM_STRUCT_EXCEPTION,
-[AC_CACHE_CHECK([for struct exception (and matherr function)],
- ac_cv_struct_exception,
-AC_TRY_COMPILE([#include <math.h>],
- [struct exception x; x.type = DOMAIN; x.type = SING;],
- ac_cv_struct_exception=yes, ac_cv_struct_exception=no))
-
-case "${ac_cv_struct_exception}" in
- "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_IPV6
-dnl
-dnl Check for ipv6 support and what the in6_addr structure is called.
-dnl (early linux used in_addr6 insted of in6_addr)
-dnl
-
-AC_DEFUN(LM_SYS_IPV6,
-[AC_MSG_CHECKING(for IP version 6 support)
-AC_CACHE_VAL(ac_cv_sys_ipv6_support,
-[ok_so_far=yes
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no)
-
-if test $ok_so_far = yes; then
- ac_cv_sys_ipv6_support=yes
-else
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in_addr6 a6; struct sockaddr_in6 s6;],
- ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no)
-fi
-])dnl
-
-dnl
-dnl Have to use old style AC_DEFINE due to BC with old autoconf.
-dnl
-
-case ${ac_cv_sys_ipv6_support} in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- ;;
- in_addr6)
- AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)])
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this])
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_MULTICAST
-dnl
-dnl Check for multicast support. Only checks for multicast options in
-dnl setsockopt(), no check is performed that multicasting actually works.
-dnl If options are found defines HAVE_MULTICAST_SUPPORT
-dnl
-
-AC_DEFUN(LM_SYS_MULTICAST,
-[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support,
-[AC_EGREP_CPP(yes,
-[#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP)
-yes
-#endif
-], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)])
-if test $ac_cv_sys_multicast_support = yes; then
- AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1],
- [Define if setsockopt() accepts multicast options])
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SYS_ERRLIST
-dnl
-dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared
-dnl in a system header file, stdio.h or errno.h.
-dnl
-
-AC_DEFUN(LM_DECL_SYS_ERRLIST,
-[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h],
- ac_cv_decl_sys_errlist,
-[AC_TRY_COMPILE([#include <stdio.h>
-#include <errno.h>], [char *msg = *(sys_errlist + 1);],
- ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)])
-if test $ac_cv_decl_sys_errlist = yes; then
- AC_DEFINE(SYS_ERRLIST_DECLARED,[],
- [define if the variable sys_errlist is declared in a system header file])
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes
-dnl [, action-if-found [, action-if-not-found]]] )
-dnl
-dnl Checks if the declaration "declaration" of "funname" conflicts
-dnl with the header files idea of how the function should be
-dnl declared. It is useful on systems which lack prototypes and you
-dnl need to provide your own (e.g. when you want to take the address
-dnl of a function). The 4'th argument is expanded if conflicting,
-dnl the 5'th argument otherwise
-dnl
-dnl
-
-AC_DEFUN(LM_CHECK_FUNC_DECL,
-[AC_MSG_CHECKING([for conflicting declaration of $1])
-AC_CACHE_VAL(ac_cv_func_decl_$1,
-[AC_TRY_COMPILE([#include <stdio.h>
-$3],[$2
-char *c = (char *)$1;
-], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")])
-if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then
- AC_MSG_RESULT(yes)
- ifelse([$4], , :, [$4])
-else
- AC_MSG_RESULT(no)
-ifelse([$5], , , [$5
-])dnl
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl AC_DOUBLE_MIDDLE_ENDIAN
-dnl
-dnl Checks whether doubles are represented in "middle-endian" format.
-dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly,
-dnl as well as DOUBLE_MIDDLE_ENDIAN.
-dnl
-dnl
-
-AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN],
-[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian,
-[# It does not; compile a test program.
-AC_RUN_IFELSE(
-[AC_LANG_SOURCE([[#include <stdlib.h>
-
-int
-main(void)
-{
- int i = 0;
- int zero = 0;
- int bigendian;
- int zero_index = 0;
-
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
-
- /* we'll use the one with 32-bit words */
- union
- {
- double d;
- unsigned int c[2];
- } vint;
-
- union
- {
- double d;
- unsigned long c[2];
- } vlong;
-
- union
- {
- double d;
- unsigned short c[2];
- } vshort;
-
-
- /* Are we little or big endian? From Harbison&Steele. */
- u.l = 1;
- bigendian = (u.c[sizeof (long int) - 1] == 1);
-
- zero_index = bigendian ? 1 : 0;
-
- vint.d = 1.0;
- vlong.d = 1.0;
- vshort.d = 1.0;
-
- if (sizeof(unsigned int) == 4)
- {
- if (vint.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned long) == 4)
- {
- if (vlong.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned short) == 4)
- {
- if (vshort.c[zero_index] != 0)
- zero = 1;
- }
-
- exit (zero);
-}
-]])],
- [ac_cv_c_double_middle_endian=no],
- [ac_cv_c_double_middle_endian=yes],
- [ac_cv_c_double_middle=unknown])])
-case $ac_cv_c_double_middle_endian in
- yes)
- m4_default([$1],
- [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1,
- [Define to 1 if your processor stores the words in a double in
- middle-endian format (like some ARMs).])]) ;;
- no)
- $2 ;;
- *)
- m4_default([$3],
- [AC_MSG_WARN([unknown double endianness
-presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;;
-esac
-])# AC_C_DOUBLE_MIDDLE_ENDIAN
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_THR_LIB
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also
-dnl checks for some pthread headers which will appear in DEFS or config.h.
-dnl
-
-AC_DEFUN(LM_CHECK_THR_LIB,
-[
-
-NEED_NPTL_PTHREAD_H=no
-
-dnl win32?
-AC_MSG_CHECKING([for native win32 threads])
-if test "X$host_os" = "Xwin32"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DWIN32_THREADS"
- THR_LIBS=
- THR_LIB_NAME=win32_threads
- THR_LIB_TYPE=win32_threads
-elif test "X$host_os" = "Xose"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DOSE_THREADS"
- THR_LIBS=
- THR_LIB_NAME=ose_threads
- THR_LIB_TYPE=ose_threads
-else
- AC_MSG_RESULT(no)
- THR_DEFS=
- THR_LIBS=
- THR_LIB_NAME=
- THR_LIB_TYPE=posix_unknown
-
-dnl Try to find POSIX threads
-
-dnl The usual pthread lib...
- AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread")
-
-dnl Very old versions of FreeBSD have pthreads in special c library, c_r...
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r")
- fi
-
-dnl QNX has pthreads in standard C library
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed")
- fi
-
-dnl On ofs1 the '-pthread' switch should be used
- if test "x$THR_LIBS" = "x"; then
- AC_MSG_CHECKING([if the '-pthread' switch can be used])
- saved_cflags=$CFLAGS
- CFLAGS="$CFLAGS -pthread"
- AC_TRY_LINK([#include <pthread.h>],
- pthread_create((void*)0,(void*)0,(void*)0,(void*)0);,
- [THR_DEFS="-pthread"
- THR_LIBS="-pthread"])
- CFLAGS=$saved_cflags
- if test "x$THR_LIBS" != "x"; then
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- if test "x$THR_LIBS" != "x"; then
- THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS"
- THR_LIB_NAME=pthread
- if test "x$THR_LIBS" = "xnone_needed"; then
- THR_LIBS=
- fi
- case $host_os in
- solaris*)
- THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;;
- linux*)
- THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS"
-
- LM_CHECK_GETCONF
- AC_MSG_CHECKING(for Native POSIX Thread Library)
- libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null`
- if test $? -eq 0; then
- case "$libpthr_vsn" in
- *nptl*|*NPTL*) nptl=yes;;
- *) nptl=no;;
- esac
- elif test "$cross_compiling" = "yes"; then
- case "$erl_xcomp_linux_nptl" in
- "") nptl=cross;;
- yes|no) nptl=$erl_xcomp_linux_nptl;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);;
- esac
- else
- nptl=no
- fi
- AC_MSG_RESULT($nptl)
- if test $nptl = cross; then
- nptl=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $nptl = yes; then
- THR_LIB_TYPE=posix_nptl
- need_nptl_incldir=no
- AC_CHECK_HEADER(nptl/pthread.h,
- [need_nptl_incldir=yes
- NEED_NPTL_PTHREAD_H=yes])
- if test $need_nptl_incldir = yes; then
- # Ahh...
- nptl_path="$C_INCLUDE_PATH:$CPATH"
- if test X$cross_compiling != Xyes; then
- nptl_path="$nptl_path:/usr/local/include:/usr/include"
- else
- IROOT="$erl_xcomp_isysroot"
- test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot"
- test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot])
- nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include"
- fi
- nptl_ws_path=
- save_ifs="$IFS"; IFS=":"
- for dir in $nptl_path; do
- if test "x$dir" != "x"; then
- nptl_ws_path="$nptl_ws_path $dir"
- fi
- done
- IFS=$save_ifs
- nptl_incldir=
- for dir in $nptl_ws_path; do
- AC_CHECK_HEADER($dir/nptl/pthread.h,
- nptl_incldir=$dir/nptl)
- if test "x$nptl_incldir" != "x"; then
- THR_DEFS="$THR_DEFS -isystem $nptl_incldir"
- break
- fi
- done
- if test "x$nptl_incldir" = "x"; then
- AC_MSG_ERROR(Failed to locate nptl system include directory)
- fi
- fi
- fi
- ;;
- *) ;;
- esac
-
- dnl We sometimes need THR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS $THR_DEFS"
-
- dnl
- dnl Check for headers
- dnl
-
- AC_CHECK_HEADER(pthread.h,
- AC_DEFINE(HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- fi
-fi
-
-])
-
-AC_DEFUN(ERL_INTERNAL_LIBS,
-[
-
-ERTS_INTERNAL_X_LIBS=
-
-AC_CHECK_LIB(kstat, kstat_open,
-[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat])
-ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"])
-
-AC_SUBST(ERTS_INTERNAL_X_LIBS)
-
-])
-
-AC_DEFUN(ETHR_CHK_SYNC_OP,
-[
- AC_MSG_CHECKING([for $3-bit $1()])
- case "$2" in
- "1") sync_call="$1(&var);";;
- "2") sync_call="$1(&var, ($4) 0);";;
- "3") sync_call="$1(&var, ($4) 0, ($4) 0);";;
- esac
- have_sync_op=no
- AC_TRY_LINK([],
- [
- $4 res;
- volatile $4 var;
- res = $sync_call
- ],
- [have_sync_op=yes])
- test $have_sync_op = yes && $5
- AC_MSG_RESULT([$have_sync_op])
-])
-
-AC_DEFUN(ETHR_CHK_INTERLOCKED,
-[
- ilckd="$1"
- AC_MSG_CHECKING([for ${ilckd}()])
- case "$2" in
- "1") ilckd_call="${ilckd}(var);";;
- "2") ilckd_call="${ilckd}(var, ($3) 0);";;
- "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";;
- "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";;
- esac
- have_interlocked_op=no
- AC_TRY_LINK(
- [
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <intrin.h>
- ],
- [
- volatile $3 *var;
- volatile $3 arr[2];
-
- $ilckd_call
- return 0;
- ],
- [have_interlocked_op=yes])
- test $have_interlocked_op = yes && $4
- AC_MSG_RESULT([$have_interlocked_op])
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_FIND_ETHR_LIB
-dnl
-dnl NOTE! This macro may be changed at any time! Should *only* be used by
-dnl ERTS!
-dnl
-dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link
-dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS
-dnl except that the ethread lib itself is not included), ETHR_DEFS to
-dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the
-dnl thread library which the ethread library is based on, and ETHR_LIB_NAME
-dnl to the name of the library where the ethread implementation is located.
-dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and
-dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS,
-dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the
-dnl empty string.
-dnl
-
-AC_DEFUN(ERL_FIND_ETHR_LIB,
-[
-
-AC_ARG_ENABLE(native-ethr-impls,
- AS_HELP_STRING([--disable-native-ethr-impls],
- [disable native ethread implementations]),
-[ case "$enableval" in
- no) disable_native_ethr_impls=yes ;;
- *) disable_native_ethr_impls=no ;;
- esac ], disable_native_ethr_impls=no)
-
-test "X$disable_native_ethr_impls" = "Xyes" &&
- AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations])
-
-AC_ARG_ENABLE(x86-out-of-order,
- AS_HELP_STRING([--enable-x86-out-of-order],
- [enable x86/x84_64 out of order support (default disabled)]))
-
-AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
- AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls],
- [prefer gcc native ethread implementations]),
-[ case "$enableval" in
- yes) enable_prefer_gcc_native_ethr_impls=yes ;;
- *) enable_prefer_gcc_native_ethr_impls=no ;;
- esac ], enable_prefer_gcc_native_ethr_impls=no)
-
-test $enable_prefer_gcc_native_ethr_impls = yes &&
- AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations])
-
-AC_ARG_WITH(libatomic_ops,
- AS_HELP_STRING([--with-libatomic_ops=PATH],
- [specify and prefer usage of libatomic_ops in the ethread library]))
-
-AC_ARG_WITH(with_sparc_memory_order,
- AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO],
- [specify sparc memory order (defaults to RMO)]))
-
-LM_CHECK_THR_LIB
-ERL_INTERNAL_LIBS
-
-ethr_have_native_atomics=no
-ethr_have_native_spinlock=no
-ETHR_THR_LIB_BASE="$THR_LIB_NAME"
-ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE"
-ETHR_DEFS="$THR_DEFS"
-ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS"
-ETHR_LIBS=
-ETHR_LIB_NAME=
-
-ethr_modified_default_stack_size=
-
-dnl Name of lib where ethread implementation is located
-ethr_lib_name=ethread
-
-case "$THR_LIB_NAME" in
-
- win32_threads)
- ETHR_THR_LIB_BASE_DIR=win
- # * _WIN32_WINNT >= 0x0400 is needed for
- # TryEnterCriticalSection
- # * _WIN32_WINNT >= 0x0403 is needed for
- # InitializeCriticalSectionAndSpinCount
- # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403.
- #
- # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it
- # and save it in ETHR_DEFS.
- found_win32_winnt=no
- for cppflag in $CPPFLAGS; do
- case $cppflag in
- -DWINVER*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- ;;
- -D_WIN32_WINNT*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- found_win32_winnt=yes
- ;;
- *)
- ;;
- esac
- done
- if test $found_win32_winnt = no; then
- AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
- fi
-
- AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- have_interlocked_op=no
- ethr_have_native_atomics=no
- else
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()]))
- fi
- test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
- ;;
-
- pthread|ose_threads)
- case "$THR_LIB_NAME" in
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
- ;;
- ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1,
- [Define if you have OSE style threads])
- ETHR_THR_LIB_BASE_DIR=ose
- AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI_H, 1,
- [Define if you have the "ose_spi/ose_spi.h" header file.]))
- ;;
- esac
- if test "x$THR_LIB_NAME" = "xpthread"; then
- case $host_os in
- openbsd*)
- # The default stack size is insufficient for our needs
- # on OpenBSD. We increase it to 256 kilo words.
- ethr_modified_default_stack_size=256;;
- linux*)
- ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE"
-
- if test X$cross_compiling = Xyes; then
- case X$erl_xcomp_linux_usable_sigusrx in
- X) usable_sigusrx=cross;;
- Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);;
- esac
- case X$erl_xcomp_linux_usable_sigaltstack in
- X) usable_sigaltstack=cross;;
- Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);;
- esac
- else
- # FIXME: Test for actual problems instead of kernel versions
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
- usable_sigusrx=no
- usable_sigaltstack=no;;
- 2.[[2-3]]|2.[[2-3]].*)
- usable_sigusrx=yes
- usable_sigaltstack=no;;
- *)
- usable_sigusrx=yes
- usable_sigaltstack=yes;;
- esac
- fi
-
- AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
- AC_MSG_RESULT($usable_sigusrx)
- if test $usable_sigusrx = cross; then
- usable_sigusrx=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigusrx = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX"
- fi
-
- AC_MSG_CHECKING(if sigaltstack can be used)
- AC_MSG_RESULT($usable_sigaltstack)
- if test $usable_sigaltstack = cross; then
- usable_sigaltstack=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigaltstack = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
- fi
- ;;
- *) ;;
- esac
-
- fi
- dnl We sometimes need ETHR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $ETHR_DEFS"
-
- dnl We need the thread library in order to find some functions
- saved_libs="$LIBS"
- LIBS="$LIBS $ETHR_X_LIBS"
-
- dnl
- dnl Check for headers
- dnl
- AC_CHECK_HEADER(pthread.h, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- if test $NEED_NPTL_PTHREAD_H = yes; then
- AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \
-[Define if you need the <nptl/pthread.h> header file.])
- fi
-
- AC_CHECK_HEADER(sched.h, \
- AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \
-[Define if you have the <sched.h> header file.]))
-
- AC_CHECK_HEADER(sys/time.h, \
- AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \
-[Define if you have the <sys/time.h> header file.]))
-
- AC_TRY_COMPILE([#include <time.h>
- #include <sys/time.h>],
- [struct timeval *tv; return 0;],
- AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \
-[Define if you can safely include both <sys/time.h> and <time.h>.]))
-
-
- dnl
- dnl Check for functions
- dnl
- if test "x$THR_LIB_NAME" = "xpthread"; then
- AC_CHECK_FUNC(pthread_spin_lock, \
- [ethr_have_native_spinlock=yes \
- AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
-[Define if you have the pthread_spin_lock function.])])
-
- have_sched_yield=no
- have_librt_sched_yield=no
- AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes])
- if test $have_sched_yield = no; then
- AC_CHECK_LIB(rt, sched_yield,
- [have_librt_sched_yield=yes
- ETHR_X_LIBS="$ETHR_X_LIBS -lrt"])
- fi
- if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then
- AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.])
- AC_MSG_CHECKING([whether sched_yield() returns an int])
- sched_yield_ret_int=no
- AC_TRY_COMPILE([
- #ifdef ETHR_HAVE_SCHED_H
- #include <sched.h>
- #endif
- ],
- [int sched_yield();],
- [sched_yield_ret_int=yes])
- AC_MSG_RESULT([$sched_yield_ret_int])
- if test $sched_yield_ret_int = yes; then
- AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.])
- fi
- fi
-
- have_pthread_yield=no
- AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes])
- if test $have_pthread_yield = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.])
- AC_MSG_CHECKING([whether pthread_yield() returns an int])
- pthread_yield_ret_int=no
- AC_TRY_COMPILE([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [int pthread_yield();],
- [pthread_yield_ret_int=yes])
- AC_MSG_RESULT([$pthread_yield_ret_int])
- if test $pthread_yield_ret_int = yes; then
- AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.])
- fi
- fi
-
- have_pthread_rwlock_init=no
- AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes])
- if test $have_pthread_rwlock_init = yes; then
-
- ethr_have_pthread_rwlockattr_setkind_np=no
- AC_CHECK_FUNC(pthread_rwlockattr_setkind_np,
- [ethr_have_pthread_rwlockattr_setkind_np=yes])
-
- if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \
-[Define if you have the pthread_rwlockattr_setkind_np() function.])
-
- AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP])
- ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no
- AC_TRY_LINK([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [
- pthread_rwlockattr_t *attr;
- return pthread_rwlockattr_setkind_np(attr,
- PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
- ],
- [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes])
- AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np])
- if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \
-[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.])
- fi
- fi
- fi
-
- if test "$force_pthread_rwlocks" = "yes"; then
-
- AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \
-[Define if you want to force usage of pthread rwlocks])
-
- if test $have_pthread_rwlock_init = yes; then
- AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.])
- else
- AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found])
- fi
- fi
-
- AC_CHECK_FUNC(pthread_attr_setguardsize, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \
-[Define if you have the pthread_attr_setguardsize function.]))
-
- linux_futex=no
- AC_MSG_CHECKING([for Linux futexes])
- AC_TRY_LINK([
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/futex.h>
- #include <sys/time.h>
- ],
- [
- int i = 1;
- syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1,
- (void*)0,(void*)0, 0);
- syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0,
- (void*)0,(void*)0, 0);
- return 0;
- ],
- linux_futex=yes)
- AC_MSG_RESULT([$linux_futex])
- test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
-
- fi
-
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_CHECK_SIZEOF(long long)
- AC_CHECK_SIZEOF(__int128_t)
-
- if test "$ac_cv_sizeof_int" = "4"; then
- int32="int"
- elif test "$ac_cv_sizeof_long" = "4"; then
- int32="long"
- elif test "$ac_cv_sizeof_long_long" = "4"; then
- int32="long long"
- else
- AC_MSG_ERROR([No 32-bit type found])
- fi
-
- if test "$ac_cv_sizeof_int" = "8"; then
- int64="int"
- elif test "$ac_cv_sizeof_long" = "8"; then
- int64="long"
- elif test "$ac_cv_sizeof_long_long" = "8"; then
- int64="long long"
- else
- AC_MSG_ERROR([No 64-bit type found])
- fi
-
- int128=no
- if test "$ac_cv_sizeof___int128_t" = "16"; then
- int128="__int128_t"
- fi
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- ethr_have_native_atomics=no
- else
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers]))
-
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers]))
-
- if test $int128 != no; then
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers]))
- fi
-
- AC_MSG_CHECKING([for a usable libatomic_ops implementation])
- case "x$with_libatomic_ops" in
- xno | xyes | x)
- libatomic_ops_include=
- ;;
- *)
- if test -d "${with_libatomic_ops}/include"; then
- libatomic_ops_include="-I$with_libatomic_ops/include"
- CPPFLAGS="$CPPFLAGS $libatomic_ops_include"
- else
- AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found])
- fi;;
- esac
- ethr_have_libatomic_ops=no
- AC_TRY_LINK([#include "atomic_ops.h"],
- [
- volatile AO_t x;
- AO_t y;
- int z;
-
- AO_nop_full();
- AO_store(&x, (AO_t) 0);
- z = AO_load(&x);
- z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1);
- ],
- [ethr_have_native_atomics=yes
- ethr_have_libatomic_ops=yes])
- AC_MSG_RESULT([$ethr_have_libatomic_ops])
- if test $ethr_have_libatomic_ops = yes; then
- AC_CHECK_SIZEOF(AO_t, ,
- [
- #include <stdio.h>
- #include "atomic_ops.h"
- ])
- AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used])
-
- AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations])
- if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations])
- fi
- ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include"
- elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_MSG_ERROR([No usable libatomic_ops implementation found])
- fi
-
- case "$host_cpu" in
- sparc | sun4u | sparc64 | sun4v)
- case "$with_sparc_memory_order" in
- "TSO")
- AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);;
- "PSO")
- AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);;
- "RMO"|"")
- AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);;
- *)
- AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);;
- esac
- ethr_have_native_atomics=yes;;
- i86pc | i*86 | x86_64 | amd64)
- if test "$enable_x86_out_of_order" = "yes"; then
- AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized])
- fi
- ethr_have_native_atomics=yes;;
- macppc | ppc | powerpc | "Power Macintosh")
- ethr_have_native_atomics=yes;;
- tile)
- ethr_have_native_atomics=yes;;
- *)
- ;;
- esac
-
- fi
-
- test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes
-
- dnl Restore LIBS
- LIBS=$saved_libs
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- ;;
- *)
- ;;
-esac
-
-AC_MSG_CHECKING([whether default stack size should be modified])
-if test "x$ethr_modified_default_stack_size" != "x"; then
- AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size])
- AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words])
-else
- AC_MSG_RESULT([no])
-fi
-
-if test "x$ETHR_THR_LIB_BASE" != "x"; then
- ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS"
- ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS"
- ETHR_LIB_NAME=$ethr_lib_name
-fi
-
-AC_CHECK_SIZEOF(void *)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers])
-
-AC_CHECK_SIZEOF(int)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int])
-AC_CHECK_SIZEOF(long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long])
-AC_CHECK_SIZEOF(long long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long])
-AC_CHECK_SIZEOF(__int64)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64])
-AC_CHECK_SIZEOF(__int128_t)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t])
-
-
-case X$erl_xcomp_bigendian in
- X) ;;
- Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);;
-esac
-
-AC_C_BIGENDIAN
-
-if test "$ac_cv_c_bigendian" = "yes"; then
- AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian])
-fi
-
-case X$erl_xcomp_double_middle_endian in
- X) ;;
- Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);;
-esac
-
-AC_C_DOUBLE_MIDDLE_ENDIAN
-
-ETHR_X86_SSE2_ASM=no
-case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in
- yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64)
- AC_MSG_CHECKING([for gcc sse2 asm support])
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -msse2"
- gcc_sse2_asm=no
- AC_TRY_COMPILE([],
- [
- long long x, *y;
- __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory");
- ],
- [gcc_sse2_asm=yes])
- CFLAGS="$save_CFLAGS"
- AC_MSG_RESULT([$gcc_sse2_asm])
- if test "$gcc_sse2_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements])
- ETHR_X86_SSE2_ASM=yes
- fi
- ;;
- *)
- ;;
-esac
-
-case "$GCC-$host_cpu" in
- yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64)
- gcc_dw_cmpxchg_asm=no
- AC_MSG_CHECKING([for gcc double word cmpxchg asm support])
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
- __asm__ __volatile__(
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "pushl %%ebx\n\t"
- "movl %8, %%ebx\n\t"
-#endif
-#if ETHR_SIZEOF_PTR == 4
- "lock; cmpxchg8b %0\n\t"
-#else
- "lock; cmpxchg16b %0\n\t"
-#endif
- "setz %3\n\t"
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "popl %%ebx\n\t"
-#endif
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]),
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "r"(new[0])
-#else
- "b"(new[0])
-#endif
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
-#if !defined(__PIC__) || !__PIC__
-# error nope
-#endif
- __asm__ __volatile__(
- "pushl %%ebx\n\t"
- "movl (%7), %%ebx\n\t"
- "movl 4(%7), %%ecx\n\t"
- "lock; cmpxchg8b %0\n\t"
- "setz %3\n\t"
- "popl %%ebx\n\t"
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new)
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code])
- fi
- fi
- AC_MSG_RESULT([$gcc_dw_cmpxchg_asm])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction])
- fi;;
- *)
- ;;
-esac
-
-AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
-[Define if you have all ethread defines])
-
-AC_SUBST(ETHR_X_LIBS)
-AC_SUBST(ETHR_LIBS)
-AC_SUBST(ETHR_LIB_NAME)
-AC_SUBST(ETHR_DEFS)
-AC_SUBST(ETHR_THR_LIB_BASE)
-AC_SUBST(ETHR_THR_LIB_BASE_DIR)
-AC_SUBST(ETHR_X86_SSE2_ASM)
-
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_TIME_CORRECTION
-dnl
-dnl In the presence of a high resolution realtime timer Erlang can adapt
-dnl its view of time relative to this timer. On solaris such a timer is
-dnl available with the syscall gethrtime(). On other OS's a fallback
-dnl solution using times() is implemented. (However on e.g. FreeBSD times()
-dnl is implemented using gettimeofday so it doesn't make much sense to
-dnl use it there...) On second thought, it seems to be safer to do it the
-dnl other way around. I.e. only use times() on OS's where we know it will
-dnl work...
-dnl
-
-AC_DEFUN(ERL_TIME_CORRECTION,
-[if test x$ac_cv_func_gethrtime = x; then
- AC_CHECK_FUNC(gethrtime)
-fi
-if test x$clock_gettime_correction = xunknown; then
- AC_TRY_COMPILE([#include <time.h>],
- [struct timespec ts;
- long long result;
- clock_gettime(CLOCK_MONOTONIC,&ts);
- result = ((long long) ts.tv_sec) * 1000000000LL +
- ((long long) ts.tv_nsec);],
- clock_gettime_compiles=yes,
- clock_gettime_compiles=no)
-else
- clock_gettime_compiles=no
-fi
-
-
-AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction,
-[
-case $clock_gettime_correction in
- yes)
- erl_cv_time_correction=clock_gettime;;
- no|unknown)
- case $ac_cv_func_gethrtime in
- yes)
- erl_cv_time_correction=hrtime ;;
- no)
- case $host_os in
- linux*)
- case $clock_gettime_correction in
- unknown)
- if test x$clock_gettime_compiles = xyes; then
- if test X$cross_compiling != Xyes; then
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
- erl_cv_time_correction=times ;;
- *)
- erl_cv_time_correction=clock_gettime;;
- esac
- else
- case X$erl_xcomp_linux_clock_gettime_correction in
- X)
- erl_cv_time_correction=cross;;
- Xyes|Xno)
- if test $erl_xcomp_linux_clock_gettime_correction = yes; then
- erl_cv_time_correction=clock_gettime
- else
- erl_cv_time_correction=times
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);;
- esac
- fi
- else
- erl_cv_time_correction=times
- fi
- ;;
- *)
- erl_cv_time_correction=times ;;
- esac
- ;;
- *)
- erl_cv_time_correction=none ;;
- esac
- ;;
- esac
- ;;
-esac
-])
-
-xrtlib=""
-case $erl_cv_time_correction in
- times)
- AC_DEFINE(CORRECT_USING_TIMES,[],
- [Define if you do not have a high-res. timer & want to use times() instead])
- ;;
- clock_gettime|cross)
- if test $erl_cv_time_correction = cross; then
- erl_cv_time_correction=clock_gettime
- AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
- fi
- xrtlib="-lrt"
- AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
- [Define if you want to use clock_gettime to simulate gethrtime])
- ;;
-esac
-dnl
-dnl Check if gethrvtime is working, and if to use procfs ioctl
-dnl or (yet to be written) write to the procfs ctl file.
-dnl
-
-AC_MSG_CHECKING([if gethrvtime works and how to use it])
-AC_TRY_RUN([
-/* gethrvtime procfs ioctl test */
-/* These need to be undef:ed to not break activation of
- * micro level process accounting on /proc/self
- */
-#ifdef _LARGEFILE_SOURCE
-# undef _LARGEFILE_SOURCE
-#endif
-#ifdef _FILE_OFFSET_BITS
-# undef _FILE_OFFSET_BITS
-#endif
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/signal.h>
-#include <sys/fault.h>
-#include <sys/syscall.h>
-#include <sys/procfs.h>
-#include <fcntl.h>
-
-int main() {
- long msacct = PR_MSACCT;
- int fd;
- long long start, stop;
- int i;
- pid_t pid = getpid();
- char proc_self[30] = "/proc/";
-
- sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid);
- if ( (fd = open(proc_self, O_WRONLY)) == -1)
- exit(1);
- if (ioctl(fd, PIOCSET, &msacct) < 0)
- exit(2);
- if (close(fd) < 0)
- exit(3);
- start = gethrvtime();
- for (i = 0; i < 100; i++)
- stop = gethrvtime();
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
-}
-],
-erl_gethrvtime=procfs_ioctl,
-erl_gethrvtime=false,
-[
-case X$erl_xcomp_gethrvtime_procfs_ioctl in
- X)
- erl_gethrvtime=cross;;
- Xyes|Xno)
- if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then
- erl_gethrvtime=procfs_ioctl
- else
- erl_gethrvtime=false
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);;
-esac
-])
-
-case $erl_gethrvtime in
- procfs_ioctl)
- AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
- [define if gethrvtime() works and uses ioctl() to /proc/self])
- AC_MSG_RESULT(uses ioctl to procfs)
- ;;
- *)
- if test $erl_gethrvtime = cross; then
- erl_gethrvtime=false
- AC_MSG_RESULT(cross)
- AC_MSG_WARN([result 'not working' guessed because of cross compilation])
- else
- AC_MSG_RESULT(not working)
- fi
-
- dnl
- dnl Check if clock_gettime (linux) is working
- dnl
-
- AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time])
- save_libs=$LIBS
- LIBS="-lrt"
- AC_TRY_RUN([
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- int main() {
- long long start, stop;
- int i;
- struct timespec tp;
-
- if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0)
- exit(1);
- start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- for (i = 0; i < 100; i++)
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
- stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
- }
- ],
- erl_clock_gettime=yes,
- erl_clock_gettime=no,
- [
- case X$erl_xcomp_clock_gettime_cpu_time in
- X) erl_clock_gettime=cross;;
- Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;;
- *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);;
- esac
- ])
- LIBS=$save_libs
- case $host_os in
- linux*)
- AC_MSG_RESULT([no; not stable])
- LIBRT=$xrtlib
- ;;
- *)
- AC_MSG_RESULT($erl_clock_gettime)
- case $erl_clock_gettime in
- yes)
- AC_DEFINE(HAVE_CLOCK_GETTIME,[],
- [define if clock_gettime() works for getting process time])
- LIBRT=-lrt
- ;;
- cross)
- erl_clock_gettime=no
- AC_MSG_WARN([result no guessed because of cross compilation])
- LIBRT=$xrtlib
- ;;
- *)
- LIBRT=$xrtlib
- ;;
- esac
- ;;
- esac
- AC_SUBST(LIBRT)
- ;;
-esac
-])dnl
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_TRY_ENABLE_CFLAG
-dnl
-dnl
-dnl Tries a CFLAG and sees if it can be enabled without compiler errors
-dnl $1: textual cflag to add
-dnl $2: variable to store the modified CFLAG in
-dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
-dnl
-dnl
-AC_DEFUN([LM_TRY_ENABLE_CFLAG], [
- AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
- saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $$2";
- AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false)
- CFLAGS=$saved_CFLAGS;
- if test "X$can_enable_flag" = "Xtrue"; then
- AC_MSG_RESULT([yes])
- AS_VAR_SET($2, "$1 $$2")
- else
- AC_MSG_RESULT([no])
- fi
-])
-
-dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY
-dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]])
-dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a
-dnl AC_LANG_JAVA instead...)
-AC_DEFUN(ERL_TRY_LINK_JAVA,
-[java_link='$JAVAC conftest.java 1>&AC_FD_CC'
-changequote(, )dnl
-cat > conftest.java <<EOF
-$1
-class conftest { public static void main(String[] args) {
- $2
- ; return; }}
-EOF
-changequote([, ])dnl
-if AC_TRY_EVAL(java_link) && test -s conftest.class; then
- ifelse([$3], , :, [rm -rf conftest*
- $3])
-else
- echo "configure: failed program was:" 1>&AC_FD_CC
- cat conftest.java 1>&AC_FD_CC
- echo "configure: PATH was $PATH" 1>&AC_FD_CC
-ifelse([$4], , , [ rm -rf conftest*
- $4
-])dnl
-fi
-rm -f conftest*])
-#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */
-
-
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index b4655ce373..f4b0a5d8d0 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -389,6 +389,9 @@ DWORD WINAPI database_handler(const char *port)
close_socket(socket);
clean_socket_lib();
/* Exit will be done by suervisor thread */
+#ifdef WIN32
+ return (DWORD)0;
+#endif
}
/* Description: Calls the appropriate function to handle the database
@@ -561,7 +564,6 @@ static db_result_msg db_connect(byte *args, db_state *state)
/* Close the connection to the database. Returns an ok or error message. */
static db_result_msg db_close_connection(db_state *state)
{
- int index;
SQLRETURN result;
diagnos diagnos;
@@ -610,11 +612,7 @@ static db_result_msg db_end_tran(byte compleationtype, db_state *state)
erlang term into the message buffer of the returned message-struct. */
static db_result_msg db_query(byte *sql, db_state *state)
{
- char *atom;
- int num_of_rows, elements, update;
- SQLSMALLINT num_of_columns;
SQLRETURN result;
- SQLINTEGER RowCountPtr;
db_result_msg msg;
diagnos diagnos;
byte is_error[6];
@@ -631,7 +629,7 @@ static db_result_msg db_query(byte *sql, db_state *state)
&statement_handle(state))))
DO_EXIT(EXIT_ALLOC);
- result = SQLExecDirect(statement_handle(state), sql, SQL_NTS);
+ result = SQLExecDirect(statement_handle(state), (SQLCHAR *)sql, SQL_NTS);
/* SQL_SUCCESS_WITH_INFO at this point may indicate an error in user input. */
if (result != SQL_SUCCESS && result != SQL_NO_DATA_FOUND) {
@@ -698,12 +696,9 @@ static db_result_msg db_query(byte *sql, db_state *state)
set. */
static db_result_msg db_select_count(byte *sql, db_state *state)
{
- SQLSMALLINT num_of_columns, intresult;
+ SQLSMALLINT num_of_columns;
SQLLEN num_of_rows;
- SQLRETURN result;
diagnos diagnos;
- db_result_msg msg;
- int index;
if (associated_result_set(state)) {
clean_state(state);
@@ -723,7 +718,7 @@ static db_result_msg db_select_count(byte *sql, db_state *state)
(SQLPOINTER)SQL_SCROLLABLE, (SQLINTEGER)0);
}
- if(!sql_success(SQLExecDirect(statement_handle(state), sql, SQL_NTS))) {
+ if(!sql_success(SQLExecDirect(statement_handle(state), (SQLCHAR *)sql, SQL_NTS))) {
diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state), extended_errors(state));
clean_state(state);
return encode_error_message(diagnos.error_msg, extended_error(state, diagnos.sqlState), diagnos.nativeError);
@@ -789,6 +784,9 @@ static db_result_msg db_select(byte *args, db_state *state)
orientation = SQL_FETCH_NEXT;
offset = atoi(strtok((char *)(args + sizeof(byte)), ";"));
n = atoi(strtok(NULL, ";"));
+ break;
+ default:
+ DO_EXIT(EXIT_PARAM_ARRAY);
}
msg = encode_empty_message();
@@ -864,7 +862,7 @@ static db_result_msg db_param_query(byte *buffer, db_state *state)
if(params != NULL) {
- result = SQLExecDirect(statement_handle(state), sql, SQL_NTS);
+ result = SQLExecDirect(statement_handle(state), (SQLCHAR *)sql, SQL_NTS);
if (!sql_success(result) || result == SQL_NO_DATA) {
diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state), extended_errors(state));
}
@@ -939,7 +937,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
SQLSMALLINT num_of_columns;
SQLCHAR name[MAX_NAME];
SQLSMALLINT name_len, sql_type, dec_digits, nullable;
- SQLLEN size;
+ SQLULEN size;
diagnos diagnos;
int i;
@@ -955,7 +953,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
&statement_handle(state))))
DO_EXIT(EXIT_ALLOC);
- if (!sql_success(SQLPrepare(statement_handle(state), sql, SQL_NTS))){
+ if (!sql_success(SQLPrepare(statement_handle(state), (SQLCHAR *)sql, SQL_NTS))){
diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state), extended_errors(state));
msg = encode_error_message(diagnos.error_msg, extended_error(state, diagnos.sqlState), diagnos.nativeError);
clean_state(state);
@@ -1291,8 +1289,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
db_result_msg msg;
SQLCHAR name[MAX_NAME];
SQLSMALLINT name_len, sql_type, dec_digits, nullable;
- SQLLEN size;
- SQLRETURN result;
+ SQLULEN size;
msg = encode_empty_message();
@@ -1324,7 +1321,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
if (columns(state)[i].type.c == SQL_C_BINARY) {
/* retrived later by retrive_binary_data */
- }else {
+ } else {
if(!sql_success(
SQLBindCol
(statement_handle(state),
@@ -1336,7 +1333,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
DO_EXIT(EXIT_BIND);
}
ei_x_encode_string_len(&dynamic_buffer(state),
- name, name_len);
+ (char *)name, name_len);
}
else {
columns(state)[i].type.len = 0;
@@ -1354,9 +1351,8 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
static db_result_msg encode_value_list(SQLSMALLINT num_of_columns,
db_state *state)
{
- int i, msg_len;
+ int i;
SQLRETURN result;
- db_result_msg list_result;
db_result_msg msg;
msg = encode_empty_message();
@@ -1399,9 +1395,8 @@ static db_result_msg encode_value_list_scroll(SQLSMALLINT num_of_columns,
SQLINTEGER OffSet, int N,
db_state *state)
{
- int i, j, msg_len;
+ int i, j;
SQLRETURN result;
- db_result_msg list_result;
db_result_msg msg;
msg = encode_empty_message();
@@ -1807,10 +1802,23 @@ static int read_exact(byte *buffer, int len) {
#endif
+static size_t length_buffer_to_size(byte length_buffer[LENGTH_INDICATOR_SIZE])
+{
+ size_t size = 0, i;
+
+ for (i = 0; i < LENGTH_INDICATOR_SIZE; ++i) {
+ size <<= 8;
+ size |= (unsigned char)length_buffer[i];
+ }
+
+ return size;
+}
+
+
/* Recieive (read) data from erlang on stdin */
static byte * receive_erlang_port_msg(void)
{
- int i, len = 0;
+ size_t len;
byte *buffer;
byte lengthstr[LENGTH_INDICATOR_SIZE];
@@ -1819,10 +1827,8 @@ static byte * receive_erlang_port_msg(void)
{
DO_EXIT(EXIT_STDIN_HEADER);
}
- for(i=0; i < LENGTH_INDICATOR_SIZE; i++) {
- len <<= 8;
- len |= lengthstr[i];
- }
+
+ len = length_buffer_to_size(lengthstr);
if (len <= 0 || len > 1024) {
DO_EXIT(EXIT_STDIN_HEADER);
@@ -1923,8 +1929,7 @@ static byte * receive_msg(int socket)
#endif
{
byte lengthstr[LENGTH_INDICATOR_SIZE];
- size_t msg_len = 0;
- int i;
+ size_t msg_len;
byte *buffer = NULL;
if(!receive_msg_part(socket, lengthstr, LENGTH_INDICATOR_SIZE)) {
@@ -1932,10 +1937,7 @@ static byte * receive_msg(int socket)
DO_EXIT(EXIT_SOCKET_RECV_HEADER);
}
- for(i = 0; i < LENGTH_INDICATOR_SIZE; i++) {
- msg_len <<= 8;
- msg_len |= lengthstr[i];
- }
+ msg_len = length_buffer_to_size(lengthstr);
buffer = (byte *)safe_malloc(msg_len);
@@ -2197,8 +2199,7 @@ static void init_driver(int erl_auto_commit_mode, int erl_trace_driver,
static void init_param_column(param_array *params, byte *buffer, int *index,
int num_param_values, db_state* state)
{
- int size, erl_type;
- long user_type, precision, scale, length, dummy;
+ long user_type, precision, scale, length;
long in_or_out;
ei_decode_long(buffer, index, &user_type);
@@ -2511,8 +2512,7 @@ static param_array * bind_parameter_arrays(byte *buffer, int *index,
int cols, int num_param_values,
db_state *state)
{
- int i, j, k, size, erl_type;
- db_result_msg msg;
+ int i, j, size, erl_type;
long dummy;
void *Values;
param_array *params;
@@ -2598,7 +2598,6 @@ static db_column retrive_binary_data(db_column column, int column_nr,
db_state *state)
{
char *outputptr;
- char *sqlState;
int blocklen, outputlen, result;
diagnos diagnos;
@@ -2739,8 +2738,8 @@ static diagnos get_diagnos(SQLSMALLINT handleType, SQLHANDLE handle, Boolean ext
the error message is obtained */
for(record_nr = 1; ;record_nr++) {
result = SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
- &nativeError, current_errmsg_pos,
- (SQLSMALLINT)errmsg_buffer_size, &errmsg_size);
+ &nativeError, (SQLCHAR *)current_errmsg_pos,
+ (SQLSMALLINT)errmsg_buffer_size, &errmsg_size);
if(result == SQL_SUCCESS) {
/* update the sqlstate in the diagnos record, because the SQLGetDiagRec
call succeeded */
diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index 916a7cb31d..7112fd2d47 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -119,7 +119,7 @@
/*------------------------ TYPDEFS ----------------------------------*/
-typedef unsigned char byte;
+typedef char byte;
typedef int Boolean;
typedef struct {
@@ -201,4 +201,4 @@ typedef enum {
#define param_query(db_state) (db_state -> param_query)
#define out_params(db_state) (db_state -> out_params)
#define extended_errors(db_state) (db_state -> extended_errors)
-#define extended_error(db_state, errorcode) ( extended_errors(state) ? errorcode : NULL )
+#define extended_error(db_state, errorcode) ( extended_errors(state) ? ((char *)errorcode) : NULL )
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index f86146759c..0cfcb9964b 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -136,7 +136,7 @@ AC_SUBST(THR_LIBS)
odbc_lib_link_success=no
AC_SUBST(TARGET_FLAGS)
case $host_os in
- darwin1[[0-2]].*|darwin[[0-9]].*)
+ darwin1[[0-4]].*|darwin[[0-9]].*)
TARGET_FLAGS="-DUNIX"
if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then
ODBC_LIB= -L"/usr/lib"
@@ -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/odbc/doc/src/error_handling.xml b/lib/odbc/doc/src/error_handling.xml
index b255865263..0b6179409d 100644
--- a/lib/odbc/doc/src/error_handling.xml
+++ b/lib/odbc/doc/src/error_handling.xml
@@ -88,7 +88,7 @@
<section>
<title>The whole picture </title>
<p>As the Erlang ODBC application relies on third party products
- and communicates with a database that probably runs on an other
+ and communicates with a database that probably runs on another
computer in the network there are plenty of things that might go
wrong. To fully understand the things that might happen it
facilitate to know the design of the Erlang ODBC application,
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index 0ba2b1ff3f..7a7658b092 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -31,7 +31,69 @@
<p>This document describes the changes made to the odbc application.
</p>
- <section><title>ODBC 2.10.20</title>
+ <section><title>ODBC 2.10.22</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ OS X Mavericks is based on Darwin version 13.x, and
+ Yosemite on 14.x. Change the ODBC configure.in script to
+ recognize these versions.</p>
+ <p>
+ Own Id: OTP-12260</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The commands longer than 127 chars sent to odbc server
+ crashed it, e.g. a connection string with driver path and
+ some additional parameters.</p>
+ <p>
+ Own Id: OTP-12346</p>
+ </item>
+ <item>
+ <p>
+ Distribute <c>autoconf</c> helpers to applications at
+ build time instead of having multiple identical copies
+ committed in the repository.</p>
+ <p>
+ Own Id: OTP-12348</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.10.21</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix compiler warnings reported by LLVM</p>
+ <p>
+ Own Id: OTP-12138</p>
+ </item>
+ <item>
+ <p>
+ Implement --enable-sanitizers[=sanitizers]. Similar to
+ debugging with Valgrind, it's very useful to enable
+ -fsanitize= switches to catch bugs at runtime.</p>
+ <p>
+ Own Id: OTP-12153</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.10.20</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 2a16388929..1907069726 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.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
@@ -47,7 +47,7 @@ all() ->
case odbc_test_lib:odbc_check() of
ok ->
[not_exist_db, commit, rollback, not_explicit_commit,
- no_c_node, port_dies, control_process_dies,
+ no_c_executable, port_dies, control_process_dies,
{group, client_dies}, connect_timeout, timeout,
many_timeouts, timeout_reset, disconnect_on_timeout,
connection_closed, disable_scrollable_cursors,
@@ -248,28 +248,31 @@ not_exist_db(_Config) ->
test_server:sleep(100).
%%-------------------------------------------------------------------------
-no_c_node(doc) ->
+no_c_executable(doc) ->
"Test what happens if the port-program can not be found";
-no_c_node(suite) -> [];
-no_c_node(_Config) ->
+no_c_executable(suite) -> [];
+no_c_executable(_Config) ->
process_flag(trap_exit, true),
Dir = filename:nativename(filename:join(code:priv_dir(odbc),
"bin")),
FileName1 = filename:nativename(os:find_executable("odbcserver",
Dir)),
FileName2 = filename:nativename(filename:join(Dir, "odbcsrv")),
- ok = file:rename(FileName1, FileName2),
- Result =
- case catch odbc:connect(?RDBMS:connection_string(),
- odbc_test_lib:platform_options()) of
- {error, port_program_executable_not_found} ->
- ok;
- Else ->
- Else
- end,
-
- ok = file:rename(FileName2, FileName1),
- ok = Result.
+ case file:rename(FileName1, FileName2) of
+ ok ->
+ Result =
+ case catch odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()) of
+ {error, port_program_executable_not_found} ->
+ ok;
+ Else ->
+ Else
+ end,
+ ok = file:rename(FileName2, FileName1),
+ ok = Result;
+ _ ->
+ {skip, "File permission issues"}
+ end.
%%------------------------------------------------------------------------
port_dies(doc) ->
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
index a7bb1d0ffe..d75e615ed4 100644
--- a/lib/odbc/test/odbc_start_SUITE.erl
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -109,8 +109,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
case odbc_test_lib:odbc_check() of
- ok -> [app, appup, start];
- Other -> [app, appup]
+ ok -> [app, appup, start, long_connection_line];
+ _Other -> [app, appup]
end.
groups() ->
@@ -168,3 +168,14 @@ start_odbc(Type) ->
{error, odbc_not_started} ->
test_server:fail(start_failed)
end.
+
+
+long_connection_line(doc)->
+ ["Test a connection line longer than 127 characters"];
+long_connection_line(suite) -> [];
+long_connection_line(_Config) ->
+ odbc:start(),
+ String133 = "unknown_odbc_parameter=01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
+ {error, Reason} = odbc:connect(String133, []),
+ odbc:stop(),
+ ct:pal("Driver error reason: ~p",[Reason]).
diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk
index 1af4751248..52c84429ec 100644
--- a/lib/odbc/vsn.mk
+++ b/lib/odbc/vsn.mk
@@ -1 +1 @@
-ODBC_VSN = 2.10.20
+ODBC_VSN = 2.10.22
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..2167a43eee 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,7 +33,61 @@
</header>
- <section><title>Orber 3.6.27</title>
+ <section><title>Orber 3.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fixed problem with IPv6 addresses in Service Context
+ when orber is default configured for IPv4. </p>
+ <p>
+ Own Id: OTP-12193</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/cdr_decode.erl b/lib/orber/src/cdr_decode.erl
index 36ef6ce02f..9aec64892e 100644
--- a/lib/orber/src/cdr_decode.erl
+++ b/lib/orber/src/cdr_decode.erl
@@ -193,7 +193,7 @@ dec_message_header(TypeCodes, Message, Bytes) ->
%% Args:
%% The message as a byte sequence.
%% Returns:
-%% A tuple {Endianess, Rest} where Endianess is big or little.
+%% A tuple {Endianness, Rest} where Endianness is big or little.
%% Rest is the remaining message byte sequence.
%%-----------------------------------------------------------------
dec_byte_order(<<0:8,T/binary>>) ->
@@ -206,7 +206,7 @@ dec_byte_order(<<1:8,T/binary>>) ->
%% Args:
%% The message as a byte sequence.
%% Returns:
-%% A tuple {Endianess, Rest} where Endianess is big or little.
+%% A tuple {Endianness, Rest} where Endianness is big or little.
%% Rest is the remaining message byte sequence.
%%-----------------------------------------------------------------
dec_byte_order_list([0|T]) ->
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..3adb40d01a 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,
+ orber_socket:get_ip_family_opts(Host) ++ SocketOptions) of
{'EXCEPTION', _E} ->
ignore;
%% We used to reply the below but since this would generate a CRASH REPORT
diff --git a/lib/orber/src/orber_iiop_pm.erl b/lib/orber/src/orber_iiop_pm.erl
index 927d12b3b2..fee2354f11 100644
--- a/lib/orber/src/orber_iiop_pm.erl
+++ b/lib/orber/src/orber_iiop_pm.erl
@@ -775,12 +775,11 @@ do_setup_connection(PMPid, Host, Port, SocketType, SocketOptions, Chars,
access_allowed(Host, Port, Type, {_,_,UserInterface}) ->
Flags = orber:get_flags(),
- Family = orber_env:ip_version(),
case ?ORB_FLAG_TEST(Flags, ?ORB_ENV_USE_ACL_OUTGOING) of
false when UserInterface == 0 ->
- get_local_interface(Type, Family);
+ get_local_interface(Type);
false ->
- inet:getaddr(UserInterface, Family);
+ inet:getaddr(UserInterface, get_ip_family(UserInterface));
true ->
SearchFor =
case Type of
@@ -789,43 +788,48 @@ access_allowed(Host, Port, Type, {_,_,UserInterface}) ->
ssl ->
ssl_out
end,
- {ok, Ip} = inet:getaddr(Host, Family),
+ {ok, Ip} = inet:getaddr(Host, get_ip_family(Host)),
case orber_acl:match(Ip, SearchFor, true) of
{true, [], 0} ->
- get_local_interface(Type, Family);
+ get_local_interface(Type);
{true, [], Port} ->
- get_local_interface(Type, Family);
+ get_local_interface(Type);
{true, [], {Min, Max}} when Port >= Min, Port =< Max ->
- get_local_interface(Type, Family);
- {true, [Interface], 0} ->
- {ok, NewIp} = inet:getaddr(Interface, Family),
+ get_local_interface(Type);
+ {true, [Interface], 0} ->
+ {ok, NewIp} = inet:getaddr(Interface, get_ip_family(Interface)),
{ok, NewIp, {Host, Port, 0}};
{true, [Interface], Port} ->
- {ok, NewIp} = inet:getaddr(Interface, Family),
+
+ {ok, NewIp} = inet:getaddr(Interface, get_ip_family(Interface)),
{ok, NewIp, {Host, Port, 0}};
{true, [Interface], {Min, Max}} when Port >= Min, Port =< Max ->
- {ok, NewIp} = inet:getaddr(Interface, Family),
+
+ {ok, NewIp} = inet:getaddr(Interface, get_ip_family(Interface)),
{ok, NewIp, {Host, Port, 0}};
_ ->
false
end
end.
-get_local_interface(normal, Family) ->
+get_local_interface(normal) ->
case orber_env:ip_address_local() of
[] ->
ok;
[Interface] ->
- inet:getaddr(Interface, Family)
+ inet:getaddr(Interface, get_ip_family(Interface))
end;
-get_local_interface(ssl, Family) ->
+get_local_interface(ssl) ->
case orber_env:iiop_ssl_ip_address_local() of
[] ->
ok;
[Interface] ->
- inet:getaddr(Interface, Family)
+ inet:getaddr(Interface, get_ip_family(Interface))
end.
+get_ip_family(Addr) ->
+ [Family] = orber_socket:get_ip_family_opts(Addr),
+ Family.
invoke_connection_closed(false) ->
ok;
diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl
index 07a0e09ccc..4507d90cce 100644
--- a/lib/orber/src/orber_socket.erl
+++ b/lib/orber/src/orber_socket.erl
@@ -37,7 +37,8 @@
-export([start/0, connect/4, listen/3, listen/4, accept/2, accept/3, write/3,
controlling_process/3, close/2, peername/2, sockname/2,
peerdata/2, peercert/2, sockdata/2, setopts/3,
- clear/2, shutdown/3, post_accept/2, post_accept/3]).
+ clear/2, shutdown/3, post_accept/2, post_accept/3,
+ get_ip_family_opts/1]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -205,29 +206,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 +251,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 +482,50 @@ 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.
+
+
+%%-----------------------------------------------------------------
+%% Check IP Family.
+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:getaddr(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/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..28fe9323fb 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1,2 +1 @@
-ORBER_VSN = 3.6.27
-
+ORBER_VSN = 3.7.1
diff --git a/lib/os_mon/c_src/memsup.c b/lib/os_mon/c_src/memsup.c
index 409db84aa7..5dcab07dd8 100644
--- a/lib/os_mon/c_src/memsup.c
+++ b/lib/os_mon/c_src/memsup.c
@@ -104,7 +104,7 @@
#if !defined (__OpenBSD__) && !defined (__NetBSD__)
#include <vm/vm_param.h>
#endif
-#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__NetBSD__)
+#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__NetBSD__) || defined(__OpenBSD__)
#include <sys/vmmeter.h>
#endif
#endif
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/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml
index 5ac04d4f42..6bc0cf7d43 100644
--- a/lib/os_mon/doc/src/notes.xml
+++ b/lib/os_mon/doc/src/notes.xml
@@ -30,6 +30,23 @@
</header>
<p>This document describes the changes made to the OS_Mon application.</p>
+<section><title>Os_Mon 2.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Adds a new application parameter 'disksup_posix_only', to
+ make diskup use only options defined in the POSIX
+ standard.</p>
+ <p>
+ Own Id: OTP-12053</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Os_Mon 2.2.15</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/os_mon/src/cpu_sup.erl b/lib/os_mon/src/cpu_sup.erl
index 34251178ee..1f088ecbde 100644
--- a/lib/os_mon/src/cpu_sup.erl
+++ b/lib/os_mon/src/cpu_sup.erl
@@ -543,7 +543,8 @@ measurement_server_init() ->
Server = case OS of
{unix, Flavor} when Flavor==sunos;
Flavor==linux ->
- port_server_start();
+ {ok, Pid} = port_server_start_link(),
+ Pid;
{unix, Flavor} when Flavor==darwin;
Flavor==freebsd;
Flavor==dragonfly;
@@ -588,8 +589,9 @@ measurement_server_loop(State) ->
Error -> Pid ! {error, Error}
end,
measurement_server_loop(State);
- {'EXIT', Pid, _n} when State#internal.port == Pid ->
- measurement_server_loop(State#internal{port = port_server_start()});
+ {'EXIT', OldPid, _n} when State#internal.port == OldPid ->
+ {ok, NewPid} = port_server_start_link(),
+ measurement_server_loop(State#internal{port = NewPid});
_Other ->
measurement_server_loop(State)
end.
@@ -605,12 +607,12 @@ port_server_call(Pid, Command) ->
{Pid, {error, Reason}} -> {error, Reason}
end.
-port_server_start() ->
+port_server_start_link() ->
Timeout = 6000,
Pid = spawn_link(fun() -> port_server_init(Timeout) end),
Pid ! {self(), ?ping},
receive
- {Pid, {data,4711}} -> Pid;
+ {Pid, {data,4711}} -> {ok, Pid};
{error,Reason} -> {error, Reason}
after Timeout ->
{error, timeout}
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/os_mon/vsn.mk b/lib/os_mon/vsn.mk
index 74397c2bc6..f90cc306f0 100644
--- a/lib/os_mon/vsn.mk
+++ b/lib/os_mon/vsn.mk
@@ -1 +1 @@
-OS_MON_VSN = 2.2.15
+OS_MON_VSN = 2.3
diff --git a/lib/ose/doc/src/notes.xml b/lib/ose/doc/src/notes.xml
index 760b92feed..7e86355f98 100644
--- a/lib/ose/doc/src/notes.xml
+++ b/lib/ose/doc/src/notes.xml
@@ -30,4 +30,63 @@
</header>
<p>This document describes the changes made to the OSE application.</p>
+<section><title>Ose 1.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add missing release notes for the OSE application.</p>
+ <p>
+ Own Id: OTP-12177</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ose 1.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix some spelling mistakes in documentation</p>
+ <p>
+ Own Id: OTP-12152</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ose 1.0</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Erlang/OTP has been ported to the realtime operating
+ system OSE. The port supports both smp and non-smp
+ emulator. For details around the port and how to started
+ see the User's Guide in the <seealso
+ marker="ose:ose_intro">ose</seealso> application. </p>
+ <p>
+ Note that not all parts of Erlang/OTP has been ported. </p>
+ <p>
+ Notable things that work are: non-smp and smp emulators,
+ OSE signal interaction, crypto, asn1, run_erl/to_erl,
+ tcp, epmd, distribution and most if not all non-os
+ specific functionality of Erlang.</p>
+ <p>
+ Notable things that does not work are: udp/sctp, os_mon,
+ erl_interface, binding of schedulers.</p>
+ <p>
+ Own Id: OTP-11334</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
</chapter>
diff --git a/lib/ose/doc/src/ose_intro.xml b/lib/ose/doc/src/ose_intro.xml
index b5e3ef8b33..0ed470890b 100644
--- a/lib/ose/doc/src/ose_intro.xml
+++ b/lib/ose/doc/src/ose_intro.xml
@@ -65,7 +65,7 @@ erl
/home/erlang
--</code>
<p>
- The arguments are printed on seperate lines to make it possible to know
+ The arguments are printed on separate lines to make it possible to know
what has to be quoted with &quot;. Each line is one quotable unit.
So taking the arguments above you can supply them to pm_create or
just execute directly on the command line. For example:</p>
@@ -75,7 +75,7 @@ pid: 0x110059
rtose@acp3400> pm_start 0x110059</code>
<p>
Also note that since we are running erl to figure out the arguments on a
- seperate machine the paths have to be updated. In the example above
+ separate machine the paths have to be updated. In the example above
<c>/usr/local/lib/erlang</c> was replaced by <c>/mst/erlang/</c>. The
goal is to in future releases not have to do the special argument handling
but for now (OTP 17.0) you have to do it.
diff --git a/lib/ose/vsn.mk b/lib/ose/vsn.mk
index 78ffa4d496..70db2ed69d 100644
--- a/lib/ose/vsn.mk
+++ b/lib/ose/vsn.mk
@@ -1 +1 @@
-OSE_VSN = 1.0
+OSE_VSN = 1.0.2
diff --git a/lib/otp_mibs/doc/src/notes.xml b/lib/otp_mibs/doc/src/notes.xml
index 391c82b1c5..c61978c99e 100644
--- a/lib/otp_mibs/doc/src/notes.xml
+++ b/lib/otp_mibs/doc/src/notes.xml
@@ -31,6 +31,22 @@
<p>This document describes the changes made to the OTP_Mibs
application.</p>
+<section><title>Otp_Mibs 1.0.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure the clean rule for ssh, ssl, eunit and otp_mibs
+ actually removes generated files.</p>
+ <p>
+ Own Id: OTP-12200</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Otp_Mibs 1.0.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/otp_mibs/src/Makefile b/lib/otp_mibs/src/Makefile
index 4f03d0228a..6096240bbd 100644
--- a/lib/otp_mibs/src/Makefile
+++ b/lib/otp_mibs/src/Makefile
@@ -72,7 +72,7 @@ ERL_COMPILE_FLAGS += -I$(INCLUDE) +warn_obsolete_guard
debug opt: $(TARGETS)
clean:
- rm -f $(TARGETS_FILES)
+ rm -f $(TARGET_FILES)
rm -f $(APP_TARGET)
rm -f $(APPUP_TARGET)
rm -f core
diff --git a/lib/otp_mibs/vsn.mk b/lib/otp_mibs/vsn.mk
index 98db21c132..2ff59431f4 100644
--- a/lib/otp_mibs/vsn.mk
+++ b/lib/otp_mibs/vsn.mk
@@ -1,4 +1,4 @@
-OTP_MIBS_VSN = 1.0.9
+OTP_MIBS_VSN = 1.0.10
# Note: The branch 'otp_mibs' is defunct as of otp_mibs-1.0.4 and
# should NOT be used again.
diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml
index a8368740da..c8cb70b6d2 100644
--- a/lib/parsetools/doc/src/notes.xml
+++ b/lib/parsetools/doc/src/notes.xml
@@ -30,6 +30,24 @@
</header>
<p>This document describes the changes made to the Parsetools application.</p>
+<section><title>Parsetools 2.0.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The line counter becomes invalid when rules with linewrap
+ are used. This issue appears because the parsing FSM does
+ not roll back the line counter after attempting such a
+ rule.</p>
+ <p>
+ Own Id: OTP-12238</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Parsetools 2.0.11</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/parsetools/include/leexinc.hrl b/lib/parsetools/include/leexinc.hrl
index dbbb688d2d..938aef58f9 100644
--- a/lib/parsetools/include/leexinc.hrl
+++ b/lib/parsetools/include/leexinc.hrl
@@ -36,8 +36,8 @@ string(Ics0, L0, Tcs, Ts) ->
string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts);
{reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state
{error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
- {A,Alen,_Tlen,_Ics1,L1,_S1} ->
- string_cont(yysuf(Tcs, Alen), L1, yyaction(A, Alen, Tcs, L0), Ts)
+ {A,Alen,_Tlen,_Ics1,_L1,_S1} ->
+ string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts)
end.
%% string_cont(RestChars, Line, Token, Tokens)
@@ -105,8 +105,8 @@ token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) ->
{reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match
Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
{done,{error,Error,L1},Ics1};
- {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> % Use last accept match
- token_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, Tline))
+ {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match
+ token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline))
end.
%% token_cont(RestChars, Line, Token)
@@ -177,9 +177,9 @@ tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) ->
%% Skip rest of tokens.
Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error);
- {A1,Alen1,_Tlen1,_Ics1,L1,_S1} ->
+ {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} ->
Token = yyaction(A1, Alen1, Tcs, Tline),
- tokens_cont(yysuf(Tcs, Alen1), L1, Token, Ts)
+ tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts)
end.
%% tokens_cont(RestChars, Line, Token, Tokens)
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index eb15bebf63..6d2afe061e 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -43,8 +43,8 @@
file/1, compile/1, syntax/1,
pt/1, man/1, ex/1, ex2/1, not_yet/1,
-
- otp_10302/1, otp_11286/1, unicode/1]).
+ line_wrap/1,
+ otp_10302/1, otp_11286/1, unicode/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -61,12 +61,13 @@ end_per_testcase(_Case, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [{group, checks}, {group, examples}].
+ [{group, checks}, {group, examples}, {group, bugs}].
groups() ->
[{checks, [], [file, compile, syntax]},
{examples, [], [pt, man, ex, ex2, not_yet, unicode]},
- {tickets, [], [otp_10302, otp_11286]}].
+ {tickets, [], [otp_10302, otp_11286]},
+ {bugs, [], [line_wrap]}].
init_per_suite(Config) ->
Config.
@@ -871,6 +872,48 @@ scan_token_1({more, Cont}, [C | Cs], Fun, Loc, Rs) ->
%% End of ex2
+line_wrap(doc) -> "Much more examples.";
+line_wrap(suite) -> [];
+line_wrap(Config) when is_list(Config) ->
+ Xrl =
+ <<"
+Definitions.
+Rules.
+[a]+[\\n]*= : {token, {first, TokenLine}}.
+[a]+ : {token, {second, TokenLine}}.
+[\\s\\r\\n\\t]+ : skip_token.
+Erlang code.
+ ">>,
+ Dir = ?privdir,
+ XrlFile = filename:join(Dir, "test_line_wrap.xrl"),
+ ?line ok = file:write_file(XrlFile, Xrl),
+ ErlFile = filename:join(Dir, "test_line_wrap.erl"),
+ {ok, _} = leex:file(XrlFile, []),
+ {ok, _} = compile:file(ErlFile, [{outdir,Dir}]),
+ code:purge(test_line_wrap),
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ code:load_abs(AbsFile, test_line_wrap),
+ fun() ->
+ S = "aaa\naaa",
+ {ok,[{second,1},{second,2}],2} = test_line_wrap:string(S)
+ end(),
+ fun() ->
+ S = "aaa\naaa",
+ {ok,[{second,3},{second,4}],4} = test_line_wrap:string(S, 3)
+ end(),
+ fun() ->
+ {done,{ok,{second,1},1},"\na"} = test_line_wrap:token([], "a\na"),
+ {more,Cont1} = test_line_wrap:token([], "\na"),
+ {done,{ok,{second,2},2},eof} = test_line_wrap:token(Cont1, eof)
+ end(),
+ fun() ->
+ {more,Cont1} = test_line_wrap:tokens([], "a\na"),
+ {done,{ok,[{second,1},{second,2}],2},eof} = test_line_wrap:tokens(Cont1, eof)
+ end(),
+ ok.
+
+%% End of line_wrap
+
not_yet(doc) ->
"Not yet implemented.";
not_yet(suite) -> [];
diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk
index 8fd7422c1c..dd9cc2991c 100644
--- a/lib/parsetools/vsn.mk
+++ b/lib/parsetools/vsn.mk
@@ -1 +1 @@
-PARSETOOLS_VSN = 2.0.11
+PARSETOOLS_VSN = 2.0.12
diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml
index bae999ed1a..b51c8fcb4d 100644
--- a/lib/percept/doc/src/notes.xml
+++ b/lib/percept/doc/src/notes.xml
@@ -32,6 +32,21 @@
</header>
<p>This document describes the changes made to the Percept application.</p>
+<section><title>Percept 0.8.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure to install .hrl files when needed</p>
+ <p>
+ Own Id: OTP-12197</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Percept 0.8.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/percept/src/Makefile b/lib/percept/src/Makefile
index 6bf0af9dc6..0282d6346a 100644
--- a/lib/percept/src/Makefile
+++ b/lib/percept/src/Makefile
@@ -50,6 +50,8 @@ MODULES= \
#HRL_FILES= ../include/
+INTERNAL_HRL_FILES= egd.hrl percept.hrl
+
ERL_FILES= $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
@@ -95,6 +97,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)/src"
$(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src"
+ $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src"
# $(INSTALL_DIR) "$(RELSYSDIR)/include"
# $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include"
$(INSTALL_DIR) "$(RELSYSDIR)/ebin"
diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk
index 935a9d1336..4451354e21 100644
--- a/lib/percept/vsn.mk
+++ b/lib/percept/vsn.mk
@@ -1 +1 @@
-PERCEPT_VSN = 0.8.9
+PERCEPT_VSN = 0.8.10
diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1
index 8d3c76adf5..37196bb9bf 100644
--- a/lib/public_key/asn1/OTP-PKIX.asn1
+++ b/lib/public_key/asn1/OTP-PKIX.asn1
@@ -452,23 +452,23 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= {
ecdsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= {
ID ecdsa-with-SHA1
- TYPE NULL } -- XXX Must be empty and not NULL
+ TYPE EcpkParameters } -- XXX Must be empty and not NULL
ecdsa-with-sha224 SIGNATURE-ALGORITHM-CLASS ::= {
ID ecdsa-with-SHA224
- TYPE NULL } -- XXX Must be empty and not NULL
+ TYPE EcpkParameters } -- XXX Must be empty and not NULL
ecdsa-with-sha256 SIGNATURE-ALGORITHM-CLASS ::= {
ID ecdsa-with-SHA256
- TYPE NULL } -- XXX Must be empty and not NULL
+ TYPE EcpkParameters } -- XXX Must be empty and not NULL
ecdsa-with-sha384 SIGNATURE-ALGORITHM-CLASS ::= {
ID ecdsa-with-SHA384
- TYPE NULL } -- XXX Must be empty and not NULL
+ TYPE EcpkParameters } -- XXX Must be empty and not NULL
ecdsa-with-sha512 SIGNATURE-ALGORITHM-CLASS ::= {
ID ecdsa-with-SHA512
- TYPE NULL } -- XXX Must be empty and not NULL
+ TYPE EcpkParameters } -- XXX Must be empty and not NULL
FIELD-ID-CLASS ::= CLASS {
&id OBJECT IDENTIFIER UNIQUE,
diff --git a/lib/public_key/doc/src/cert_records.xml b/lib/public_key/doc/src/cert_records.xml
index 397c13b463..b66c66bead 100644
--- a/lib/public_key/doc/src/cert_records.xml
+++ b/lib/public_key/doc/src/cert_records.xml
@@ -36,8 +36,9 @@
<p>This chapter briefly describes erlang records derived from ASN1
specifications used to handle <c> X509 certificates</c> and <c>CertificationRequest</c>.
- The intent is to describe the data types and not to specify the meaning of each
- component for this we refer you to <url
+ The intent is to describe the data types
+and not to specify the semantics of each component. For information on the
+semantics, please see <url
href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</url> and
<url href="http://www.ietf.org/rfc/rfc5967.txt">PKCS-10</url>.
</p>
@@ -79,7 +80,7 @@
<p><c>
special_string() =
{teletexString, string()} | {printableString, string()} |
- {universalString, string()} | {utf8String, string()} |
+ {universalString, string()} | {utf8String, binary()} |
{bmpString, string()}
</c></p>
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index 592d3c797d..fe4bf5ce2d 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -34,6 +34,22 @@
<file>notes.xml</file>
</header>
+<section><title>Public_Key 0.22.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Added missing encoding support for PBES2, and also
+ completed support for PBES1 that was incomplete.</p>
+ <p>
+ Own Id: OTP-11915</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Public_Key 0.22</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 8e93f562d4..e3473f80d7 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -75,7 +75,7 @@
<p><em>Data Types </em></p>
- <p><code>oid() - a tuple of integers as generated by the ASN1 compiler.</code></p>
+ <p><code>oid() - Object Identifier, a tuple of integers as generated by the ASN1 compiler.</code></p>
<p><code>boolean() = true | false</code></p>
@@ -92,7 +92,7 @@
not_encrypted | cipher_info()}</code></p>
<p><code>cipher_info() = {"RC2-CBC | "DES-CBC" | "DES-EDE3-CBC",
- crypto:rand_bytes(8)} | 'PBES2-params'}</code></p>
+ crypto:rand_bytes(8) | {#'PBEParameter{}, digest_type()} |#'PBES2-params'{}}</code></p>
<p><code>public_key() = rsa_public_key() | dsa_public_key() | ec_public_key()</code></p>
<p><code>private_key() = rsa_private_key() | dsa_private_key() | ec_private_key()</code></p>
@@ -113,6 +113,8 @@
<p><code>rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' |
'rsa_no_padding'</code></p>
+
+ <p><code>digest_type() - Union of below digest types</code></p>
<p><code>rsa_digest_type() = 'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' |
'sha512'</code></p>
@@ -429,10 +431,12 @@
<name>pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, {PublicKeyInfo, PolicyTree}} | {error, {bad_cert, Reason}} </name>
<fsummary> Performs a basic path validation according to RFC 5280.</fsummary>
<type>
- <v> TrustedCert = #'OTPCertificate'{} | der_encode() | unknown_ca | selfsigned_peer </v>
- <d>Normally a trusted certificate but it can also be one of the path validation
- errors <c>unknown_ca </c> or <c>selfsigned_peer </c> that can be discovered while
- constructing the input to this function and that should be run through the <c>verify_fun</c>.</d>
+ <v> TrustedCert = #'OTPCertificate'{} | der_encode() | atom() </v>
+ <d>Normally a trusted certificate but it can also be a path validation
+ error that can be discovered while
+ constructing the input to this function and that should be run through the <c>verify_fun</c>.
+ For example <c>unknown_ca </c> or <c>selfsigned_peer </c>
+ </d>
<v> CertChain = [der_encode()]</v>
<d>A list of DER encoded certificates in trust order ending with the peer certificate.</d>
<v> Options = proplists:proplist()</v>
@@ -440,8 +444,8 @@
rsa_public_key() | integer(), 'NULL' | 'Dss-Parms'{}}</v>
<v> PolicyTree = term() </v>
<d>At the moment this will always be an empty list as Policies are not currently supported</d>
- <v> Reason = cert_expired | invalid_issuer | invalid_signature | unknown_ca |
- selfsigned_peer | name_not_permitted | missing_basic_constraint | invalid_key_usage | crl_reason()
+ <v> Reason = cert_expired | invalid_issuer | invalid_signature | name_not_permitted |
+ missing_basic_constraint | invalid_key_usage | {revoked, crl_reason()} | atom()
</v>
</type>
<desc>
@@ -449,7 +453,7 @@
Performs a basic path validation according to
<url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280.</url>
However CRL validation is done separately by <seealso
- marker="public_key#pkix_crls_validate-3">pkix_crls_validate/3 </seealso> and should be called
+ marker="#pkix_crls_validate-3">pkix_crls_validate/3 </seealso> and should be called
from the supplied <c>verify_fun</c>
</p>
@@ -462,7 +466,7 @@
<code>
fun(OtpCert :: #'OTPCertificate'{},
- Event :: {bad_cert, Reason :: atom()} |
+ Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
{extension, #'Extension'{}},
InitialUserState :: term()) ->
{valid, UserState :: term()} |
@@ -491,6 +495,35 @@ fun(OtpCert :: #'OTPCertificate'{},
on.
</item>
</taglist>
+
+ <p> Possible reasons for a bad certificate are: </p>
+ <taglist>
+ <tag>cert_expired</tag>
+ <item>The certificate is no longer valid as its expiration date has passed.</item>
+
+ <tag>invalid_issuer</tag>
+ <item>The certificate issuer name does not match the name of the issuer certificate in the chain.</item>
+
+ <tag>invalid_signature</tag>
+ <item>The certificate was not signed by its issuer certificate in the chain.</item>
+
+ <tag>name_not_permitted</tag>
+ <item>Invalid Subject Alternative Name extension.</item>
+
+ <tag>missing_basic_constraint</tag>
+ <item>Certificate, required to have the basic constraints extension, does not have
+ a basic constraints extension.</item>
+
+ <tag>invalid_key_usage</tag>
+ <item>Certificate key is used in an invalid way according to the key usage extension.</item>
+
+ <tag>{revoked, crl_reason()}</tag>
+ <item>Certificate has been revoked.</item>
+
+ <tag>atom()</tag>
+ <item>Application specific error reason that should be checked by the verify_fun</item>
+ </taglist>
+
</desc>
</func>
@@ -499,14 +532,14 @@ fun(OtpCert :: #'OTPCertificate'{},
<fsummary> Performs CRL validation.</fsummary>
<type>
<v> OTPCertificate = #'OTPCertificate'{}</v>
- <v> DPAndCRLs = [{DP::#'DistributionPoint'{} ,CRL::#'CertificateList'{}}] </v>
+ <v> DPAndCRLs = [{DP::#'DistributionPoint'{}, {DerCRL::der_encoded(), CRL::#'CertificateList'{}}}] </v>
<v> Options = proplists:proplist()</v>
<v> CRLStatus() = valid | {bad_cert, revocation_status_undetermined} |
{bad_cert, {revoked, crl_reason()}}</v>
</type>
<desc>
<p> Performs CRL validation. It is intended to be called from
- the verify fun of <seealso marker="public_key#pkix_path_validation-3"> pkix_path_validation/3
+ the verify fun of <seealso marker="#pkix_path_validation-3"> pkix_path_validation/3
</seealso></p>
<taglist>
<p> Available options are: </p>
diff --git a/lib/public_key/doc/src/public_key_records.xml b/lib/public_key/doc/src/public_key_records.xml
index 13bb996f7f..d3534846fa 100644
--- a/lib/public_key/doc/src/public_key_records.xml
+++ b/lib/public_key/doc/src/public_key_records.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2013</year>
+ <year>2014</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -35,17 +35,27 @@
</header>
<p>This chapter briefly describes Erlang records derived from ASN1
- specifications used to handle public and private keys. The intent
- is to describe the data types and not to specify the meaning of
- each component for this we refer you to the relevant standards and RFCs.</p>
+ specifications used to handle public and private keys.
+ The intent is to describe the data types
+ and not to specify the semantics of each component. For information on the
+ semantics, please see the relevant standards and RFCs.</p>
<p>Use the following include directive to get access to the
- records and constant macros used in the following sections.</p>
+ records and constant macros described in the following sections.</p>
<code> -include_lib("public_key/include/public_key.hrl"). </code>
+ <section>
+ <title>Common Data Types</title>
+
+ <p>Common non-standard Erlang
+ data types used to described the record fields in the
+ below sections are defined in <seealso
+ marker="public_key">public key reference manual </seealso></p>
+ </section>
+
<section>
- <title>RSA as defined by the PKCS-1 standard and RFC 3447.</title>
+ <title>RSA as defined by the PKCS-1 standard and <url href="http://www.ietf.org/rfc/rfc3447.txt"> RFC 3447 </url></title>
<code>
#'RSAPublicKey'{
@@ -76,7 +86,8 @@
</section>
<section>
- <title>DSA as defined by Digital Signature Standard (NIST FIPS PUB 186-2)
+ <title>DSA as defined by
+ <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> Digital Signature Standard (NIST FIPS PUB 186-2) </url>
</title>
<code>
@@ -96,4 +107,47 @@
}.
</code>
</section>
+
+ <section>
+ <title>ECC (Elliptic Curve) <url href="http://www.ietf.org/rfc/rfc3447.txt"> RFC 5480 </url>
+ </title>
+
+ <code>
+#'ECPrivateKey'{
+ version, % integer()
+ privateKey, % octet_string()
+ parameters, % der_encoded() - {'EcpkParameters', #'ECParameters'{}} |
+ {'EcpkParameters', {namedCurve, oid()}} |
+ {'EcpkParameters', 'NULL'} % Inherited by CA
+ publicKey % bitstring()
+ }.
+
+#'ECParameters'{
+ version, % integer()
+ fieldID, % #'FieldID'{}
+ curve, % #'Curve'{}
+ base, % octet_string()
+ order, % integer()
+ cofactor % integer()
+ }.
+
+#'Curve'{
+ a, % octet_string()
+ b, % octet_string()
+ seed % bitstring() - optional
+
+ }.
+
+#'FieldID'{
+ fieldType, % oid()
+ parameters % Depending on fieldType
+ }.
+
+#'ECPoint'{
+ point % octet_string() - the public key
+ }.
+
+ </code>
+ </section>
+
</chapter>
diff --git a/lib/public_key/src/pubkey_pbe.erl b/lib/public_key/src/pubkey_pbe.erl
index 460624163b..521a32189d 100644
--- a/lib/public_key/src/pubkey_pbe.erl
+++ b/lib/public_key/src/pubkey_pbe.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2011-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("public_key.hrl").
--export([encode/4, decode/4, decrypt_parameters/1]).
+-export([encode/4, decode/4, decrypt_parameters/1, encrypt_parameters/1]).
-export([pbdkdf1/4, pbdkdf2/7]).
-define(DEFAULT_SHA_MAC_KEYLEN, 20).
@@ -40,16 +40,16 @@
%%--------------------------------------------------------------------
encode(Data, Password, "DES-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
- crypto:block_encrypt(des_cbc, Key, IV, Data);
+ crypto:block_encrypt(des_cbc, Key, IV, pbe_pad(Data, KeyDevParams));
encode(Data, Password, "DES-EDE3-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
<<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key,
- crypto:block_encrypt(des3_cbc, [Key1, Key2, Key3], IV, Data);
+ crypto:block_encrypt(des3_cbc, [Key1, Key2, Key3], IV, pbe_pad(Data));
encode(Data, Password, "RC2-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
- crypto:block_encrypt(rc2_cbc, Key, IV, Data).
+ crypto:block_encrypt(rc2_cbc, Key, IV, pbe_pad(Data, KeyDevParams)).
%%--------------------------------------------------------------------
-spec decode(binary(), string(), string(), term()) -> binary().
%%
@@ -108,6 +108,15 @@ decrypt_parameters(#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
algorithm = Oid, parameters = Param}) ->
decrypt_parameters(Oid, Param).
+
+%%--------------------------------------------------------------------
+-spec encrypt_parameters({Cipher::string(), Params::term()}) ->
+ #'EncryptedPrivateKeyInfo_encryptionAlgorithm'{}.
+%%
+%% Description: Performs ANS1-decoding of encryption parameters.
+%%--------------------------------------------------------------------
+encrypt_parameters({Cipher, Params}) ->
+ encrypt_parameters(Cipher, Params).
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -117,14 +126,18 @@ password_to_key_and_iv(Password, _, #'PBES2-params'{} = Params) ->
<<Key:KeyLen/binary, _/binary>> =
pbdkdf2(Password, Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoHash, PseudoOtputLen),
{Key, IV};
+password_to_key_and_iv(Password, _Cipher, {#'PBEParameter'{salt = Salt,
+ iterationCount = Count}, Hash}) ->
+ <<Key:8/binary, IV:8/binary, _/binary>>
+ = pbdkdf1(Password, erlang:iolist_to_binary(Salt), Count, Hash),
+ {Key, IV};
password_to_key_and_iv(Password, Cipher, Salt) ->
- KeyLen = derived_key_length(Cipher, undefined),
+ KeyLen = derived_key_length(Cipher, undefined),
<<Key:KeyLen/binary, _/binary>> =
pem_encrypt(<<>>, Password, Salt, ceiling(KeyLen div 16), <<>>, md5),
%% Old PEM encryption does not use standard encryption method
- %% pbdkdf1 and uses then salt as IV
+ %% pbdkdf1 and uses then salt as IV
{Key, Salt}.
-
pem_encrypt(_, _, _, 0, Acc, _) ->
Acc;
pem_encrypt(Prev, Password, Salt, Count, Acc, Hash) ->
@@ -169,7 +182,52 @@ do_xor_sum(Prf, PrfHash, PrfLen, Prev, Password, Count, Acc)->
decrypt_parameters(?'id-PBES2', DekParams) ->
{ok, Params} = 'PKCS-FRAME':decode('PBES2-params', DekParams),
- {cipher(Params#'PBES2-params'.encryptionScheme), Params}.
+ {cipher(Params#'PBES2-params'.encryptionScheme), Params};
+decrypt_parameters(?'pbeWithSHA1AndRC2-CBC', DekParams) ->
+ {ok, Params} = 'PKCS-FRAME':decode('PBEParameter', DekParams),
+ {"RC2-CBC", {Params, sha}};
+decrypt_parameters(?'pbeWithSHA1AndDES-CBC', DekParams) ->
+ {ok, Params} = 'PKCS-FRAME':decode('PBEParameter', DekParams),
+ {"DES-CBC", {Params, sha}};
+decrypt_parameters(?'pbeWithMD5AndRC2-CBC', DekParams) ->
+ {ok, Params} = 'PKCS-FRAME':decode('PBEParameter', DekParams),
+ {"RC2-CBC", {Params, md5}};
+decrypt_parameters(?'pbeWithMD5AndDES-CBC', DekParams) ->
+ {ok, Params} = 'PKCS-FRAME':decode('PBEParameter', DekParams),
+ {"DES-CBC", {Params, md5}}.
+
+encrypt_parameters(_Cipher, #'PBES2-params'{} = Params) ->
+ {ok, Der} ='PKCS-FRAME':encode('PBES2-params', Params),
+ #'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
+ algorithm = ?'id-PBES2',
+ parameters = Der};
+
+encrypt_parameters(Cipher, {#'PBEParameter'{} = Params, Hash}) ->
+ {ok, Der} ='PKCS-FRAME':encode('PBEParameter', Params),
+ #'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
+ algorithm = pbe1_oid(Cipher, Hash),
+ parameters = Der}.
+
+pbe1_oid("RC2-CBC", sha) ->
+ ?'pbeWithSHA1AndRC2-CBC';
+pbe1_oid("DES-CBC", sha) ->
+ ?'pbeWithSHA1AndDES-CBC';
+pbe1_oid("RC2-CBC", md5) ->
+ ?'pbeWithMD5AndRC2-CBC';
+pbe1_oid("DES-CBC", md5) ->
+ ?'pbeWithMD5AndDES-CBC'.
+
+pbe_pad(Data, {#'PBEParameter'{}, _}) ->
+ pbe_pad(Data);
+pbe_pad(Data, #'PBES2-params'{}) ->
+ pbe_pad(Data);
+pbe_pad(Data, _) ->
+ Data.
+
+pbe_pad(Data) ->
+ N = 8 - (erlang:byte_size(Data) rem 8),
+ Pad = list_to_binary(lists:duplicate(N, N)),
+ <<Data/binary, Pad/binary>>.
key_derivation_params(#'PBES2-params'{keyDerivationFunc = KeyDerivationFunc,
encryptionScheme = EncScheme}) ->
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index 3a1653d989..98881c4a6a 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.erl
@@ -68,7 +68,8 @@ encode(PemEntries) ->
%%--------------------------------------------------------------------
-spec decipher({public_key:pki_asn1_type(), DerEncrypted::binary(),
- {Cipher :: string(), Salt :: iodata() | #'PBES2-params'{}}},
+ {Cipher :: string(), Salt :: iodata() | #'PBES2-params'{}
+ | {#'PBEParameter'{}, atom()}}},
string()) -> Der::binary().
%%
%% Description: Deciphers a decrypted pem entry.
@@ -77,7 +78,8 @@ decipher({_, DecryptDer, {Cipher, KeyDevParams}}, Password) ->
pubkey_pbe:decode(DecryptDer, Password, Cipher, KeyDevParams).
%%--------------------------------------------------------------------
--spec cipher(Der::binary(), {Cipher :: string(), Salt :: iodata() | #'PBES2-params'{}} ,
+-spec cipher(Der::binary(), {Cipher :: string(), Salt :: iodata() | #'PBES2-params'{}
+ | {#'PBEParameter'{}, atom()}},
string()) -> binary().
%%
%% Description: Ciphers a PEM entry
@@ -94,6 +96,10 @@ encode_pem_entries(Entries) ->
encode_pem_entry({Type, Der, not_encrypted}) ->
StartStr = pem_start(Type),
[StartStr, "\n", b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"];
+encode_pem_entry({'PrivateKeyInfo', Der, EncParams}) ->
+ EncDer = encode_encrypted_private_keyinfo(Der, EncParams),
+ StartStr = pem_start('EncryptedPrivateKeyInfo'),
+ [StartStr, "\n", b64encode_and_split(EncDer), "\n", pem_end(StartStr) ,"\n\n"];
encode_pem_entry({Type, Der, {Cipher, Salt}}) ->
StartStr = pem_start(Type),
[StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n",
@@ -139,6 +145,12 @@ decode_encrypted_private_keyinfo(Der) ->
DecryptParams = pubkey_pbe:decrypt_parameters(AlgorithmInfo),
{'PrivateKeyInfo', iolist_to_binary(Data), DecryptParams}.
+
+encode_encrypted_private_keyinfo(EncData, EncryptParmams) ->
+ AlgorithmInfo = pubkey_pbe:encrypt_parameters(EncryptParmams),
+ public_key:der_encode('EncryptedPrivateKeyInfo',
+ #'EncryptedPrivateKeyInfo'{encryptionAlgorithm = AlgorithmInfo,
+ encryptedData = EncData}).
split_bin(Bin) ->
split_bin(0, Bin).
@@ -197,13 +209,15 @@ pem_start('DSAPrivateKey') ->
<<"-----BEGIN DSA PRIVATE KEY-----">>;
pem_start('DHParameter') ->
<<"-----BEGIN DH PARAMETERS-----">>;
+pem_start('EncryptedPrivateKeyInfo') ->
+ <<"-----BEGIN ENCRYPTED PRIVATE KEY-----">>;
pem_start('CertificationRequest') ->
<<"-----BEGIN CERTIFICATE REQUEST-----">>;
pem_start('ContentInfo') ->
<<"-----BEGIN PKCS7-----">>;
pem_start('CertificateList') ->
<<"-----BEGIN X509 CRL-----">>;
-pem_start('OTPEcpkParameters') ->
+pem_start('EcpkParameters') ->
<<"-----BEGIN EC PARAMETERS-----">>;
pem_start('ECPrivateKey') ->
<<"-----BEGIN EC PRIVATE KEY-----">>.
@@ -260,7 +274,7 @@ asn1_type(<<"-----BEGIN PKCS7-----">>) ->
asn1_type(<<"-----BEGIN X509 CRL-----">>) ->
'CertificateList';
asn1_type(<<"-----BEGIN EC PARAMETERS-----">>) ->
- 'OTPEcpkParameters';
+ 'EcpkParameters';
asn1_type(<<"-----BEGIN EC PRIVATE KEY-----">>) ->
'ECPrivateKey'.
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index a732455aa7..1bbf4ef416 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -64,9 +64,15 @@
-type der_encoded() :: binary().
-type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' | 'RSAPublicKey'
| 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter'
- | 'SubjectPublicKeyInfo' | 'CertificationRequest' | 'CertificateList'.
--type pem_entry() :: {pki_asn1_type(), binary(), %% DER or Encrypted DER
- not_encrypted | {Cipher :: string(), Salt :: binary()}}.
+ | 'SubjectPublicKeyInfo' | 'PrivateKeyInfo' |
+ 'CertificationRequest' | 'CertificateList' |
+ 'ECPrivateKey' | 'EcpkParameters'.
+-type pem_entry() :: {pki_asn1_type(),
+ binary(), %% DER or Encrypted DER
+ not_encrypted | {Cipher :: string(), Salt :: binary()} |
+ {Cipher :: string(), #'PBES2-params'{}} |
+ {Cipher :: string(), {#'PBEParameter'{}, atom()}} %% hash type
+ }.
-type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl
-type ssh_file() :: openssh_public_key | rfc4716_public_key | known_hosts |
auth_keys.
@@ -133,20 +139,19 @@ pem_entry_decode({Asn1Type, CryptDer, {Cipher, #'PBES2-params'{}}} = PemEntry,
is_binary(CryptDer) andalso
is_list(Cipher) ->
do_pem_entry_decode(PemEntry, Password);
+pem_entry_decode({Asn1Type, CryptDer, {Cipher, {#'PBEParameter'{},_}}} = PemEntry,
+ Password) when is_atom(Asn1Type) andalso
+ is_binary(CryptDer) andalso
+ is_list(Cipher) ->
+ do_pem_entry_decode(PemEntry, Password);
pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry,
Password) when is_atom(Asn1Type) andalso
is_binary(CryptDer) andalso
is_list(Cipher) andalso
is_binary(Salt) andalso
- erlang:byte_size(Salt) == 8 ->
- do_pem_entry_decode(PemEntry, Password);
-pem_entry_decode({Asn1Type, CryptDer, {"AES-128-CBC"=Cipher, IV}} = PemEntry,
- Password) when is_atom(Asn1Type) andalso
- is_binary(CryptDer) andalso
- is_list(Cipher) andalso
- is_binary(IV) andalso
- erlang:byte_size(IV) == 16 ->
- do_pem_entry_decode(PemEntry, Password).
+ ((erlang:byte_size(Salt) == 8) or (erlang:byte_size(Salt) == 16)) ->
+ do_pem_entry_decode(PemEntry, Password).
+
%%--------------------------------------------------------------------
-spec pem_entry_encode(pki_asn1_type(), term()) -> pem_entry().
@@ -174,13 +179,19 @@ pem_entry_encode(Asn1Type, Entity, {{Cipher, #'PBES2-params'{}} = CipherInfo,
is_list(Password) andalso
is_list(Cipher) ->
do_pem_entry_encode(Asn1Type, Entity, CipherInfo, Password);
-
+pem_entry_encode(Asn1Type, Entity, {{Cipher,
+ {#'PBEParameter'{}, _}} = CipherInfo,
+ Password}) when is_atom(Asn1Type) andalso
+ is_list(Password) andalso
+ is_list(Cipher) ->
+ do_pem_entry_encode(Asn1Type, Entity, CipherInfo, Password);
pem_entry_encode(Asn1Type, Entity, {{Cipher, Salt} = CipherInfo,
Password}) when is_atom(Asn1Type) andalso
is_list(Password) andalso
is_list(Cipher) andalso
is_binary(Salt) andalso
- erlang:byte_size(Salt) == 8 ->
+ ((erlang:byte_size(Salt) == 8) or
+ (erlang:byte_size(Salt) == 16)) ->
do_pem_entry_encode(Asn1Type, Entity, CipherInfo, Password).
%%--------------------------------------------------------------------
@@ -615,11 +626,11 @@ pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
%--------------------------------------------------------------------
-spec pkix_crls_validate(#'OTPCertificate'{},
- [{DP::#'DistributionPoint'{} ,CRL::#'CertificateList'{}}],
+ [{DP::#'DistributionPoint'{}, {DerCRL::binary(), CRL::#'CertificateList'{}}}],
Options :: proplists:proplist()) -> valid | {bad_cert, revocation_status_undetermined}
| {bad_cert, {revoked, crl_reason()}}.
-%% Description: Performs a basic path validation according to RFC 5280.
+%% Description: Performs a CRL validation according to RFC 5280.
%%--------------------------------------------------------------------
pkix_crls_validate(OtpCert, [{_,_,_} |_] = DPAndCRLs, Options) ->
pkix_crls_validate(OtpCert, DPAndCRLs, DPAndCRLs,
diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl
index b68ffbd5fd..aa2bbdd24b 100644
--- a/lib/public_key/test/pbe_SUITE.erl
+++ b/lib/public_key/test/pbe_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2011-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,7 +35,9 @@ all() ->
[
pbdkdf1,
pbdkdf2,
- encrypted_private_key_info].
+ old_enc,
+ pbes1,
+ pbes2].
groups() ->
[].
@@ -192,44 +194,48 @@ pbdkdf2(Config) when is_list(Config) ->
16#cc, 16#37, 16#d7, 16#f0, 16#34, 16#25, 16#e0, 16#c3>>
= pubkey_pbe:pbdkdf2("pass\0word",
"sa\0lt", 4096, 16, fun crypto:hmac/4, sha, 20).
-
-encrypted_private_key_info() ->
- [{doc,"Tests reading a EncryptedPrivateKeyInfo file encrypted with different ciphers"}].
-encrypted_private_key_info(Config) when is_list(Config) ->
+
+old_enc() ->
+ [{doc,"Tests encode/decode RSA key encrypted with different ciphers using old PEM encryption scheme"}].
+old_enc(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
- {ok, PemDes} = file:read_file(filename:join(Datadir, "des_cbc_enc_key.pem")),
+ %% key generated with ssh-keygen -N hello_aes -f old_aes_128_cbc_enc_key.pem
+ {ok, PemAesCbc} = file:read_file(filename:join(Datadir, "old_aes_128_cbc_enc_key.pem")),
- PemDesEntry = public_key:pem_decode(PemDes),
- ct:print("Pem entry: ~p" , [PemDesEntry]),
- [{'PrivateKeyInfo', _, {"DES-CBC",_}} = PubEntry0] = PemDesEntry,
- KeyInfo = public_key:pem_entry_decode(PubEntry0, "password"),
-
- {ok, Pem3Des} = file:read_file(filename:join(Datadir, "des_ede3_cbc_enc_key.pem")),
-
- Pem3DesEntry = public_key:pem_decode(Pem3Des),
- ct:print("Pem entry: ~p" , [Pem3DesEntry]),
- [{'PrivateKeyInfo', _, {"DES-EDE3-CBC",_}} = PubEntry1] = Pem3DesEntry,
- KeyInfo = public_key:pem_entry_decode(PubEntry1, "password"),
-
- {ok, PemRc2} = file:read_file(filename:join(Datadir, "rc2_cbc_enc_key.pem")),
-
- PemRc2Entry = public_key:pem_decode(PemRc2),
- ct:print("Pem entry: ~p" , [PemRc2Entry]),
- [{'PrivateKeyInfo', _, {"RC2-CBC",_}} = PubEntry2] = PemRc2Entry,
- KeyInfo = public_key:pem_entry_decode(PubEntry2, "password"),
-
- %% key generated with ssh-keygen -N hello_aes -f aes_128_cbc_enc_key
- {ok, PemAesCbc} = file:read_file(filename:join(Datadir, "aes_128_cbc_enc_key")),
-
PemAesCbcEntry = public_key:pem_decode(PemAesCbc),
ct:print("Pem entry: ~p" , [PemAesCbcEntry]),
[{'RSAPrivateKey', _, {"AES-128-CBC",_}} = PubAesCbcEntry] = PemAesCbcEntry,
- #'RSAPrivateKey'{} = public_key:pem_entry_decode(PubAesCbcEntry, "hello_aes"),
-
- check_key_info(KeyInfo).
+ #'RSAPrivateKey'{} = public_key:pem_entry_decode(PubAesCbcEntry, "hello_aes").
+pbes1() ->
+ [{doc,"Tests encode/decode EncryptedPrivateKeyInfo encrypted with different ciphers using PBES1"}].
+pbes1(Config) when is_list(Config) ->
+ decode_encode_key_file("pbes1_des_cbc_md5_enc_key.pem", "password", "DES-CBC", Config).
+
+pbes2() ->
+ [{doc,"Tests encode/decode EncryptedPrivateKeyInfo encrypted with different ciphers using PBES2"}].
+pbes2(Config) when is_list(Config) ->
+ decode_encode_key_file("pbes2_des_cbc_enc_key.pem", "password", "DES-CBC", Config),
+ decode_encode_key_file("pbes2_des_ede3_cbc_enc_key.pem", "password", "DES-EDE3-CBC", Config),
+ decode_encode_key_file("pbes2_rc2_cbc_enc_key.pem", "password", "RC2-CBC", Config).
check_key_info(#'PrivateKeyInfo'{privateKeyAlgorithm =
#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption},
privateKey = Key}) ->
#'RSAPrivateKey'{} = public_key:der_decode('RSAPrivateKey', iolist_to_binary(Key)).
+
+decode_encode_key_file(File, Password, Cipher, Config) ->
+ Datadir = ?config(data_dir, Config),
+ {ok, PemKey} = file:read_file(filename:join(Datadir, File)),
+
+ PemEntry = public_key:pem_decode(PemKey),
+ ct:print("Pem entry: ~p" , [PemEntry]),
+ [{Asn1Type, _, {Cipher,_} = CipherInfo} = PubEntry] = PemEntry,
+ KeyInfo = public_key:pem_entry_decode(PubEntry, Password),
+ PemKey1 = public_key:pem_encode([public_key:pem_entry_encode(Asn1Type, KeyInfo, {CipherInfo, Password})]),
+ Pem = strip_ending_newlines(PemKey),
+ Pem = strip_ending_newlines(PemKey1),
+ check_key_info(KeyInfo).
+
+strip_ending_newlines(Bin) ->
+ string:strip(binary_to_list(Bin), right, 10).
diff --git a/lib/public_key/test/pbe_SUITE_data/aes_128_cbc_enc_key b/lib/public_key/test/pbe_SUITE_data/old_aes_128_cbc_enc_key.pem
index 34c7543f30..34c7543f30 100644
--- a/lib/public_key/test/pbe_SUITE_data/aes_128_cbc_enc_key
+++ b/lib/public_key/test/pbe_SUITE_data/old_aes_128_cbc_enc_key.pem
diff --git a/lib/public_key/test/pbe_SUITE_data/pbes1_des_cbc_md5_enc_key.pem b/lib/public_key/test/pbe_SUITE_data/pbes1_des_cbc_md5_enc_key.pem
new file mode 100644
index 0000000000..12e860c7a7
--- /dev/null
+++ b/lib/public_key/test/pbe_SUITE_data/pbes1_des_cbc_md5_enc_key.pem
@@ -0,0 +1,17 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIICoTAbBgkqhkiG9w0BBQMwDgQIZmB6EGEnIOcCAggABIICgDaaKoCEUowjKt5M
+uwMAIf7uugy09OcqR8PcB9ioiuk5NQGXkIBxOOlOuFb6xrP+O2dSppr5k/ZU+NEX
+Lf18AdMld1nlE6lwjPytOIqt6Q3YMeny8un1/jopnkQZKthJ5moER5ohp/2osTDV
+4Ih8MtHTwE879SHAmj7Y3G7itKHQi17212DVmL+D+P7iRzTCKIyPj5KMXvXN+eor
+j0urZXVOeyRTABHQnf6xJn8K+dGowC/AJTQWOgFunlBKzecepqF22OQzIW2R60aM
+VgykSd8A5G8o1F+tO2Qrp6KM9Ak709dUX8qRb/C02w5rjg2g0frgFyEGX0pUJbno
+dJLKMOT1WvDnsXaS720beyzrOynWiAuaFZwb1/nPSQnzJ4t0mUvQQis5ph3eHSR/
+a9/PER81IDjPtjlTJjaOGuwhIRmGFsLUrQhOnVcI7Z5TCSj7EHdqK3xzjSVzu5DY
+BqE2rsigiIOszPdbK4tKCDheIwBhYdptDvG9c+j3Mj0YNOXJxsX0gVoMqtpwryNG
+OZy5fLujS4l+cPq64dOh/LE87mrM9St6M6gw2VRW7d0U18Muubp/MK8q9O2i80Nw
+ZFrHHE1N09x3aTnty4mwdCHl6w5aJMZg6WbUXJnf0zKa8ADv5wZmAvW3fO4G8434
+3FHj1hdyKPcoVjoFVawyRUflF/jYd1pLpV+iZwDDR4lacb4ay1Lut452ifZ8DqOq
+lWYL0uskCn1WI856vtlLV3gnV02xDjAilSY2hASOyoD1wypZefPn5S+U3vkLuzFZ
+ycbyIwGYTLWj71u8Vu3JceRI3OIPDuM7zcNHr71eQyiwLEA0iszQQA9xgqmeFtJO
+IkpUTAY=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/lib/public_key/test/pbe_SUITE_data/des_cbc_enc_key.pem b/lib/public_key/test/pbe_SUITE_data/pbes2_des_cbc_enc_key.pem
index eaa06145aa..eaa06145aa 100644
--- a/lib/public_key/test/pbe_SUITE_data/des_cbc_enc_key.pem
+++ b/lib/public_key/test/pbe_SUITE_data/pbes2_des_cbc_enc_key.pem
diff --git a/lib/public_key/test/pbe_SUITE_data/des_ede3_cbc_enc_key.pem b/lib/public_key/test/pbe_SUITE_data/pbes2_des_ede3_cbc_enc_key.pem
index 22ea46d56f..22ea46d56f 100644
--- a/lib/public_key/test/pbe_SUITE_data/des_ede3_cbc_enc_key.pem
+++ b/lib/public_key/test/pbe_SUITE_data/pbes2_des_ede3_cbc_enc_key.pem
diff --git a/lib/public_key/test/pbe_SUITE_data/rc2_cbc_enc_key.pem b/lib/public_key/test/pbe_SUITE_data/pbes2_rc2_cbc_enc_key.pem
index 618cddcfd7..618cddcfd7 100644
--- a/lib/public_key/test/pbe_SUITE_data/rc2_cbc_enc_key.pem
+++ b/lib/public_key/test/pbe_SUITE_data/pbes2_rc2_cbc_enc_key.pem
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index f0450918aa..2fa2d725c3 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 0.22
+PUBLIC_KEY_VSN = 0.22.1
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/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index 9b026aee11..2877355718 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -31,6 +31,23 @@
<p>This document describes the changes made to the Runtime_Tools
application.</p>
+<section><title>Runtime_Tools 1.8.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add <c>nif_version</c> to <c>erlang:system_info/1</c> in
+ order to get the NIF API version of the runtime system in
+ a way similar to <c>driver_version</c>.</p>
+ <p>
+ Own Id: OTP-12298</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Runtime_Tools 1.8.14</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/runtime_tools/src/system_information.erl b/lib/runtime_tools/src/system_information.erl
index f541d6e449..04cc33e1ad 100644
--- a/lib/runtime_tools/src/system_information.erl
+++ b/lib/runtime_tools/src/system_information.erl
@@ -371,6 +371,7 @@ erlang_system_info() ->
logical_processors_online,
logical_processors_available,
driver_version,
+ nif_version,
emu_args,
ethread_info,
beam_jump_table,
diff --git a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
index 18938372a3..bdc510e838 100644
--- a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
+++ b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
@@ -9720,6 +9720,7 @@
{logical_processors_online,4},
{logical_processors_available,4},
{driver_version,"2.1"},
+ {nif_version,"1.1"},
{taints,[]}]},
{erts_compile_info,
[{ldflags,[]},
diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk
index 32953dfc5a..c1df23d2a2 100644
--- a/lib/runtime_tools/vsn.mk
+++ b/lib/runtime_tools/vsn.mk
@@ -1 +1 @@
-RUNTIME_TOOLS_VSN = 1.8.14
+RUNTIME_TOOLS_VSN = 1.8.15
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/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index 2928a12d22..95d7c6fa50 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -30,6 +30,26 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
+<section><title>SASL 2.4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The documentation erroneously specified that
+ <c>alarm_handler:clear_alarm/1</c> would clear
+ <em>all</em> alarms with id <c>AlarmId</c>. This is now
+ corrected according to the implementation - only the
+ latest received alarm with the given <c>AlarmId</c> is
+ cleared by the simple default handler.</p>
+ <p>
+ Own Id: OTP-12025</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SASL 2.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index bd7414fbb4..b7c5f34f58 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2015. 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
@@ -1802,11 +1802,17 @@ upgrade_gg(cleanup,Config) ->
%%%-----------------------------------------------------------------
%%% OTP-10463, Bug - release_handler could not handle regexp in appup
%%% files.
-otp_10463_upgrade_script_regexp(_Config) ->
- %% Assuming that kernel always has a regexp in it's appup
- KernelVsn = vsn(kernel,current),
- {ok,KernelVsn,_} =
- release_handler:upgrade_script(kernel,code:lib_dir(kernel)),
+otp_10463_upgrade_script_regexp(Config) ->
+ DataDir = ?config(data_dir,Config),
+ code:add_path(filename:join([DataDir,regexp_appup,app1,ebin])),
+ application:start(app1),
+ {ok,"1.1",_} = release_handler:upgrade_script(app1,code:lib_dir(app1)),
+ ok.
+
+otp_10463_upgrade_script_regexp(cleanup,Config) ->
+ DataDir = ?config(data_dir,Config),
+ application:stop(app1),
+ code:del_path(filename:join([DataDir,regexp_appup,app1,ebin])),
ok.
no_dot_erlang(Conf) ->
diff --git a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app
new file mode 100644
index 0000000000..ba6d09cd42
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app
@@ -0,0 +1,29 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. 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 is an -*- erlang -*- file.
+%%
+{application, app1,
+ [
+ {description, "Test that release_handler can read appup with regexp"},
+ {vsn, "1.1"},
+ {modules, []},
+ {registered, []},
+ {applications, []}
+ ]
+}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup
new file mode 100644
index 0000000000..9c657232d0
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup
@@ -0,0 +1,23 @@
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. 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%
+{"1.1",
+ %% Up from
+ [{<<"1(\\.[0-9]+)*">>,[{restart_application,app1}]}],
+ %% Down to
+ [{<<"1(\\.[0-9]+)*">>,[{restart_application,app1}]}]
+}.
diff --git a/lib/sasl/test/sasl_SUITE.erl b/lib/sasl/test/sasl_SUITE.erl
index e91d220daf..d7b99d506e 100644
--- a/lib/sasl/test/sasl_SUITE.erl
+++ b/lib/sasl/test/sasl_SUITE.erl
@@ -57,17 +57,29 @@ appup_test(_Config) ->
appup_tests(_App,{[],[]}) ->
{skip,"no previous releases available"};
-appup_tests(App,{OkVsns,NokVsns}) ->
+appup_tests(App,{OkVsns0,NokVsns}) ->
application:load(App),
{_,_,Vsn} = lists:keyfind(App,1,application:loaded_applications()),
AppupFileName = atom_to_list(App) ++ ".appup",
AppupFile = filename:join([code:lib_dir(App),ebin,AppupFileName]),
{ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile),
ct:log("~p~n",[AppupScript]),
- ct:log("Testing ok versions: ~p~n",[OkVsns]),
+ OkVsns =
+ case OkVsns0 -- [Vsn] of
+ OkVsns0 ->
+ OkVsns0;
+ Ok ->
+ ct:log("Current version, ~p, is same as in previous release.~n"
+ "Removing this from the list of ok versions.",
+ [Vsn]),
+ Ok
+ end,
+ ct:log("Testing that appup allows upgrade from these versions: ~p~n",
+ [OkVsns]),
check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}),
check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}),
- ct:log("Testing not ok versions: ~p~n",[NokVsns]),
+ ct:log("Testing that appup does not allow upgrade from these versions: ~p~n",
+ [NokVsns]),
check_appup(NokVsns,UpFrom,error),
check_appup(NokVsns,DownTo,error),
ok.
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index da8cbc5130..4259a2d76c 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 2.4
+SASL_VSN = 2.4.1
diff --git a/lib/snmp/.gitignore b/lib/snmp/.gitignore
index 650c1d6865..aef73491a4 100644
--- a/lib/snmp/.gitignore
+++ b/lib/snmp/.gitignore
@@ -5,5 +5,4 @@
*.rej
doc/index.html
-
-
+mibs/.index
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 06674095f2..fd307ef824 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,7 +33,109 @@
</header>
- <section><title>SNMP 4.25.1</title>
+ <section>
+ <title>SNMP Development Toolkit 5.1.1</title>
+ <p>Version 5.1.1 supports code replacement in runtime from/to
+ version 5.1. </p>
+
+ <section>
+ <title>Improvements and new features</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>[compiler] Refinement of type Opaque was not allowed. </p>
+ <p>MIB constructs such as '<c>SYNTAX Opaque (SIZE(0..65535))</c>'
+ was previously not allowed,
+ see the standard <c>ALARM-MIB</c> for eaxmple. </p>
+ <p>Own Id: OTP-12066</p>
+ <p>Aux Id: Seq 12669</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+
+<!--
+ <list type="bulleted">
+ <item>
+ <p>[agent]
+ see <seealso marker="snmpa#load_mibs">load_mibs</seealso> and
+ <seealso marker="snmpa#unload_mibs">unload_mibs</seealso>. </p>
+ <p>Own Id: OTP-11216</p>
+ </item>
+
+ </list>
+-->
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+
+<!--
+ <list type="bulleted">
+ <item>
+ <p>[manager] The old Addr-and-Port based API functions, previously
+ long deprecated and marked for deletion in R16B, has now been
+ removed. </p>
+ <p>Own Id: OTP-10027</p>
+ </item>
+
+ </list>
+-->
+ </section>
+ </section> <!-- 5.1.1 -->
+
+
+
+ <section><title>SNMP 5.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The SNMP manager has been enhanced with dual stack
+ IPv4+IPv6, as the agent just was. The documentation is
+ also now updated for both the agent and the manager.</p>
+ <p>
+ Own Id: OTP-12108 Aux Id: OTP-12020 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/doc/src/snmp_agent_config_files.xml b/lib/snmp/doc/src/snmp_agent_config_files.xml
index 1e8e879814..1e938c0dc8 100644
--- a/lib/snmp/doc/src/snmp_agent_config_files.xml
+++ b/lib/snmp/doc/src/snmp_agent_config_files.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -102,20 +102,41 @@
<p><c>AgentVariable</c> is one of the variables is
SNMP-FRAMEWORK-MIB or one of the internal variables
<c>intAgentUDPPort</c>, which defines which UDP port the agent
- listens to, or <c>intAgentIpAddress</c>, which defines the IP
- address of the agent. </p>
+ listens to, or <c>intAgentTransports</c>, which defines the
+ transport domains and addresses of the agent. </p>
</item>
<item>
<p><c>Value</c> is the value for the variable.</p>
</item>
</list>
- <p>The following example shows a <c>agent.conf</c> file: </p>
+ <p>The following example shows an <c>agent.conf</c> file: </p>
<pre>
{intAgentUDPPort, 4000}.
-{intAgentIpAddress,[141,213,11,24]}.
+{intAgentTransports,
+ [{transportDomainUdpIpv4, {141,213,11,24}},
+ {transportDomainUdpIpv6, {0,0,0,0,0,0,0,1}}]}.
{snmpEngineID, "mbj's engine"}.
{snmpEngineMaxPacketSize, 484}.
</pre>
+ <p>The value of <c>intAgentTransports</c> is a list of
+ <c>{Domain, Addr}</c> tuples, where <c>Domain</c>
+ is either <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv6</c>,
+ and <c>Addr</c> is the address in the domain.
+ <c>Addr</c> can be specified either as an
+ <c>IpAddr</c> or as an <c>{IpAddr, IpPort}</c> tuple.
+ <c>IpAddr</c> is either a regular Erlang/OTP
+ <seealso marker="kernel:inet#type-ip_address"><c>ip_address()</c></seealso>
+ or a traditional SNMP integer list and <c>IpPort</c> is an integer.
+ </p>
+
+ <p>When the <c>Addr</c> value does not contain a port number,
+ the value of <c>intAgentUDPPort</c> is used.</p>
+
+ <p>The legacy and intermediate variables <c>intAgentIpAddress</c>
+ and <c>intAgentTransportDomain</c> are still supported so old
+ <c>agent.conf</c> files will work.
+ </p>
+
<p>The value of <c>snmpEngineID</c> is a string, which for a
deployed agent should have a very specific structure. See
RFC 2271/2571 for details.</p>
@@ -362,9 +383,9 @@
SNMP-TARGET-MIB and <c>snmpTargetAddrExtTable</c> in the
SNMP-COMMUNITY-MIB. </p>
<p>Each entry is a term: </p>
- <p><c>{TargetName, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId}.</c> <br></br> or <br></br>
-<c>{TargetName, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}.</c> <br></br> or <br></br>
-<c>{TargetName, Domain, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}.</c> </p>
+ <p><c>{TargetName, Domain, Addr, Timeout, RetryCount, TagList, ParamsName, EngineId}.</c>
+ <br></br> or <br></br>
+ <c>{TargetName, Domain, Addr, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}.</c> </p>
<list type="bulleted">
<item>
<p><c>TargetName</c> is a unique non-empty string. </p>
@@ -374,11 +395,14 @@
<c>transportDomainUdpIpv4</c> | <c>transportDomainUdpIpv6</c>. </p>
</item>
<item>
- <p><c>Ip</c> is a list of four or eight integers. </p>
- </item>
- <item>
- <p><c>Udp</c> is an integer. </p>
+ <p><c>Addr</c> is either an <c>IpAddr</c> or
+ an <c>{IpAddr, IpPort}</c> tuple. <c>IpAddr</c> is either
+ a regular Erlang/OTP
+ <seealso marker="kernel:inet#type-ip_address"><c>ip_address()</c></seealso>
+ or a traditional SNMP integer list, and <c>IpPort</c> is an integer.</p>
+ <p>If <c>IpPort</c> is omitted <c>162</c> is used.</p>
</item>
+
<item>
<p><c>Timeout</c> is an integer. </p>
</item>
@@ -395,13 +419,17 @@
<p><c>EngineId</c> is a string or the atom <c>discovery</c>. </p>
</item>
<item>
- <p><c>TMask</c> is a list of integer() of size 0,
- size 6 or size 10 (default: []). </p>
+ <p><c>TMask</c> is specified just as <c>Addr</c> or as <c>[]</c>.
+ Note in particular that using a list of 6 bytes for IPv4
+ or 8 words plus 2 bytes for IPv6 are still valid address formats
+ so old configurations will work.</p>
</item>
<item>
<p><c>MaxMessageSize</c> is an integer (default: 2048). </p>
</item>
</list>
+ <p>The old tuple formats with <c>Ip</c> address and <c>Udp</c>
+ port number found in old configurations still work.</p>
<p>Note that if <c>EngineId</c> has the value <c>discovery</c>,
the agent cannot send
<c>inform</c> messages to that manager until it has performed the
diff --git a/lib/snmp/doc/src/snmp_agent_netif.xml b/lib/snmp/doc/src/snmp_agent_netif.xml
index fccfc8857a..a9ce05e757 100644
--- a/lib/snmp/doc/src/snmp_agent_netif.xml
+++ b/lib/snmp/doc/src/snmp_agent_netif.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -51,7 +51,8 @@
</p>
<p>It is also possible to write your own Net if process. The default
Net if process is implemented in the module <c>snmpa_net_if</c> and
- it uses UDP as the transport protocol.
+ it uses UDP as the transport protocol i.e the transport domains
+ <c>transportDomainUdpIpv4</c> and/or <c>transportDomainUdpIpv6</c>.
</p>
<p>This section describes how to write a Net if process.
</p>
@@ -70,6 +71,12 @@
<p>The section <em>Messages</em> describes mandatory messages, which
Net if must send and be able to receive.
</p>
+ <p>In this section an <c>Address</c> field is a
+ <c>{Domain, Addr}</c> tuple where <c>Domain</c> is
+ <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv4</c>,
+ and <c>Addr</c> is an
+ <c>{<seealso marker="kernel:inet#type-ip_address">IpAddr</seealso>,
+ IpPort}</c> tuple.</p>
<section>
<marker id="outgoing_messages"></marker>
@@ -96,10 +103,7 @@ MasterAgent ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, Extra}
in use. Normally this is returned from
<c>snmpa_mpd:process_packet</c> (see Reference Manual).
</item>
- <item><c>From</c> is the source address. If UDP over IP is
- used, this should be a 2-tuple <c>{IP, UDPport}</c>, where
- <c>IP</c> is a 4-tuple with the IP address, and <c>UDPport</c>
- is an integer.
+ <item><c>From</c> is the source <c>Address</c>.
</item>
<item><c>Extra</c> is any term the Net if process wishes to
send to the agent. This term can be retrieved by the
@@ -127,10 +131,7 @@ Pid ! {snmp_response_received, Vsn, Pdu, From}
</item>
<item><c>Pdu</c> is the SNMP Pdu received
</item>
- <item><c>From</c> is the source address. If UDP over IP is
- used, this should be a 2-tuple <c>{IP, UDPport}</c>, where
- <c>IP</c> is a 4-tuple with the IP address, and <c>UDPport</c>
- is an integer.
+ <item><c>From</c> is the source <c>Address</c>.
</item>
</list>
</section>
@@ -168,10 +169,9 @@ Pid ! {snmp_response_received, Vsn, Pdu, From}
(see Reference Manual). </p>
</item>
<item>
- <p><c>To</c> is the destination address. If UDP over IP
- is used, this should be a 2-tuple <c>{IP, UDPport}</c>,
- where <c>IP</c> is a 4-tuple with the IP address, and
- <c>UDPport</c> is an integer. </p>
+ <p><c>To</c> is the destination <c>Address</c> that comes
+ from the <c>From</c> field in the corresponding <c>snmp_pdu</c>
+ message previously sent to the MasterAgent.</p>
</item>
<item>
<p><c>Extra</c> is the term that the Net if process
@@ -230,7 +230,8 @@ Pid ! {snmp_response_received, Vsn, Pdu, From}
SNMPv3, it is the context information. </p>
</item>
<item>
- <p><c>To</c> is a list of the destination addresses and
+ <p><c>To</c> is a list of <c>{Address, SecData}</c>
+ tuples i.e the destination addresses and
their corresponding security parameters. This value is
normally sent to <c>snmpa_mpd:generate_message/4</c>. </p>
</item>
@@ -268,7 +269,8 @@ Pid ! {snmp_response_received, Vsn, Pdu, From}
SNMPv3, it is the context information. </p>
</item>
<item>
- <p><c>To</c> is a list of the destination addresses and
+ <p><c>To</c> is a list of <c>{Address, SecData}</c>
+ tuples i.e the destination addresses and
their corresponding security parameters. This value is
normally sent to <c>snmpa_mpd:generate_message/4</c>. </p>
</item>
diff --git a/lib/snmp/doc/src/snmp_manager_config_files.xml b/lib/snmp/doc/src/snmp_manager_config_files.xml
index 486ef7c170..d8bd4b0f3a 100644
--- a/lib/snmp/doc/src/snmp_manager_config_files.xml
+++ b/lib/snmp/doc/src/snmp_manager_config_files.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -64,13 +64,42 @@
<item>
<p><c>Variable</c> is one of the following:</p>
<list type="bulleted">
- <item>
- <p><c>address</c> - which defines the IP address of the
- manager. Default is local host.</p>
- </item>
+ <item>
+ <p><c>transports</c> - which defines the transport domains
+ and their addresses for the manager. <em>Mandatory</em>
+ </p>
+ <p><c>Value</c> is a list of <c>{Domain, Addr}</c> tuples
+ or <c>Domain</c> atoms.
+ </p>
+ <list type="bulleted">
+ <item>
+ <p><c>Domain</c> is one of <c>transportDomainUdpIpv4</c>
+ or <c>transportDomainUdpIpv6</c>.</p>
+ </item>
+ <item>
+ <p><c>Addr</c> is for the currently supported domains
+ either an <c>IpAddr</c> or an <c>{IpAddr, IpPort}</c>
+ tuple.<c>IpAddr</c> is either a regular Erlang/OTP
+ <seealso marker="kernel:inet#type-ip_address">
+ <c>ip_address()</c></seealso> or a traditional SNMP integer list
+ and <c>IpPort</c> is an integer.
+ </p>
+ <p>When <c>Addr</c> does not contain a port number,
+ the value of <c>port</c> is used.
+ </p>
+ <p>When a <c>Addr</c> is not specified i.e by
+ using only a <c>Domain</c> atom, the host's name
+ is resolved to find the IP address, and the value of
+ <c>port</c> is used.
+ </p>
+ </item>
+ </list>
+ </item>
<item>
<p><c>port</c> - which defines which UDP port the manager uses
- for communicating with agents. <em>Mandatory</em>.</p>
+ for communicating with agents.
+ <em>Mandatory</em> if <c>transports</c> does not define
+ a port number for every transport.</p>
</item>
<item>
<p><c>engine_id</c> - The <c>SnmpEngineID</c> as defined in
@@ -87,11 +116,13 @@
</p>
</item>
</list>
+ <p>The legacy and intermediate variables <c>address</c> and <c>domain</c>
+ are still supported so old configurations will work.</p>
<p>The following example shows a <c>manager.conf</c> file:
</p>
<pre>
-{address, [141,213,11,24]}.
-{port, 5000}.
+{transports, [{transportDomainUdpIpv4, {{141,213,11,24}, 5000}},
+ {transportDomainUdpIpv6, {{0,0,0,0,0,0,0,1}, 5000}}]}.
{engine_id, "mgrEngine"}.
{max_message_size, 484}.
</pre>
@@ -146,7 +177,7 @@
</p>
<p>Each entry is a tuple:
</p>
- <p><c>{UserId, TargetName, Comm, Ip, Port, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}.</c></p>
+ <p><c>{UserId, TargetName, Comm, Domain, Addr, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}.</c></p>
<list type="bulleted">
<item>
<p><c>UserId</c> is the identity of the <em>manager user</em>
@@ -160,10 +191,17 @@
<p><c>Comm</c> is the community string (string).</p>
</item>
<item>
- <p><c>Ip</c> is the ip address of the agent (a list of four integers).</p>
+ <p><c>Domain</c> is the transport domain, either
+ <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv6</c>.</p>
</item>
<item>
- <p><c>Port</c> is the port number of the agent (integer).</p>
+ <p><c>Addr</c> is the address in the transport domain,
+ either an <c>{IpAddr, IpPort}</c> tuple or a traditional SNMP
+ integer list containing port number. <c>IpAddr</c> is either
+ a regular Erlang/OTP
+ <seealso marker="kernel:inet#type-ip_address"><c>ip_address()</c></seealso>
+ or a traditional SNMP integer list not containing port number,
+ and <c>IpPort</c> is an integer.</p>
</item>
<item>
<p><c>EngineID</c> is the engine-id of the agent (string).</p>
@@ -190,6 +228,9 @@
authPriv).</p>
</item>
</list>
+ <p>Legacy configurations using tuples without <c>Domain</c> element,
+ as well as with all <c>TDomain</c>, <c>Ip</c> and <c>Port</c> elements
+ still work.</p>
</section>
<section>
diff --git a/lib/snmp/doc/src/snmp_manager_netif.xml b/lib/snmp/doc/src/snmp_manager_netif.xml
index 757ed32880..97cedf00c0 100644
--- a/lib/snmp/doc/src/snmp_manager_netif.xml
+++ b/lib/snmp/doc/src/snmp_manager_netif.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -50,13 +50,14 @@
<p>The snmp application provides two different modules,
<c>snmpm_net_if</c> (the default) and <c>snmpm_net_if_mt</c>,
- both uses the UDP as the transport protocol. The difference
- between the two modules is that the latter is "multi-threaded",
- i.e. for each message/request a new process is created that
- process the message/request and then exits. </p>
+ both uses UDP as the transport protocol i.e the transport domains
+ <c>transportDomainUdpIpv4</c> and/or <c>transportDomainUdpIpv6</c>.
+ The difference between the two modules is that the latter is
+ "multi-threaded", i.e. for each message/request a new process
+ is created that processes the message/request and then exits. </p>
- <p>It is also possible to write your own Net if process,
- this section describes how to write a Net if processdo that.</p>
+ <p>It is also possible to write your own Net if process and
+ this section describes how to do that.</p>
<section>
<marker id="mandatory_functions"></marker>
@@ -70,11 +71,17 @@
<p>The section <em>Messages</em> describes mandatory messages, which
Net if must send to the manager server process.
</p>
+ <p>In this section a <c>Domain</c> field is the transport domain i.e
+ one of <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv6</c>,
+ and an <c>Addr</c> field is an
+ <c>{<seealso marker="kernel:inet#type-ip_address">IpAddr</seealso>,
+ IpPort}</c> tuple.</p>
+
<p>Net if must send the following message when it receives an
SNMP PDU from the network that is aimed for the MasterAgent:
</p>
<pre>
-Server ! {snmp_pdu, Pdu, Addr, Port}
+Server ! {snmp_pdu, Pdu, Domain, Addr}
</pre>
<list type="bulleted">
<item>
@@ -82,14 +89,14 @@ Server ! {snmp_pdu, Pdu, Addr, Port}
<c>snmp_types.hrl</c>, with the SNMP request.</p>
</item>
<item>
- <p><c>Addr</c> is the source address. </p>
+ <p><c>Domain</c> is the source transport domain. </p>
</item>
<item>
- <p><c>Port</c> is port number of the sender.</p>
+ <p><c>Addr</c> is the source address. </p>
</item>
</list>
<pre>
-Server ! {snmp_trap, Trap, Addr, Port}
+Server ! {snmp_trap, Trap, Domain, Addr}
</pre>
<list type="bulleted">
<item>
@@ -97,14 +104,14 @@ Server ! {snmp_trap, Trap, Addr, Port}
as defined in <c>snmp_types.hrl</c>, with the SNMP request.</p>
</item>
<item>
- <p><c>Addr</c> is the source address. </p>
+ <p><c>Domain</c> is the source transport domain. </p>
</item>
<item>
- <p><c>Port</c> is port number of the sender.</p>
+ <p><c>Addr</c> is the source address. </p>
</item>
</list>
<pre>
-Server ! {snmp_inform, Ref, Pdu, PduMS, Addr, Port}
+Server ! {snmp_inform, Ref, Pdu, PduMS, Domain, Addr}
</pre>
<list type="bulleted">
<item>
@@ -123,14 +130,14 @@ Server ! {snmp_inform, Ref, Pdu, PduMS, Addr, Port}
<c>snmp_types.hrl</c>, with the SNMP request.</p>
</item>
<item>
- <p><c>Addr</c> is the source address. </p>
+ <p><c>Domain</c> is the source transport domain. </p>
</item>
<item>
- <p><c>Port</c> is port number of the sender.</p>
+ <p><c>Addr</c> is the source address. </p>
</item>
</list>
<pre>
-Server ! {snmp_report, Data, Addr, Port}
+Server ! {snmp_report, Data, Domain, Addr}
</pre>
<list type="bulleted">
<item>
@@ -152,10 +159,10 @@ Server ! {snmp_report, Data, Addr, Port}
<p><c>ReasonInfo</c> is a term().</p>
</item>
<item>
- <p><c>Addr</c> is the source address. </p>
+ <p><c>Domain</c> is the source transport domain. </p>
</item>
<item>
- <p><c>Port</c> is port number of the sender.</p>
+ <p><c>Addr</c> is the source address. </p>
</item>
</list>
diff --git a/lib/snmp/doc/src/snmp_target_mib.xml b/lib/snmp/doc/src/snmp_target_mib.xml
index be6fa15c73..a076ff2d8e 100644
--- a/lib/snmp/doc/src/snmp_target_mib.xml
+++ b/lib/snmp/doc/src/snmp_target_mib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2013</year>
+ <year>1998</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -38,18 +38,18 @@
functions for the SNMP-TARGET-MIB,
and functions for configuring the database. </p>
<p>The configuration files are described in the SNMP User's Manual.</p>
+ <p>Legacy API functions <c>add_addr/10</c> that does not specify
+ transport domain, and <c>add_addr/11</c> that has got separate
+ <c>IpAddr</c> and <c>PortNumber</c> arguments still work as before
+ for backwards compatibility reasons.</p>
<marker id="types"></marker>
</description>
<section>
<title>DATA TYPES</title>
- <code type="none"><![CDATA[
-transportDomain() = transportDomainUdpIpv4 | transportDomainUdpIpv6
-transportAddressIPv4() = [integer()], length 4
-transportAddressIPv6() = [integer()], length 8
-transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6)
- ]]></code>
+ <p>See the <seealso marker="snmpa_conf#types">
+ data types in <c>snmpa_conf</c></seealso>.</p>
<marker id="configure"></marker>
</section>
@@ -129,20 +129,18 @@ transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6)
</func>
<func>
- <name>add_addr(Name, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name>
- <name>add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name>
+ <name>add_addr(Name, Domain, Addr, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name>
<fsummary>Add one target address definition</fsummary>
<type>
<v>Name = string()</v>
<v>Domain = transportDomain()</v>
- <v>Ip = transportAddressIPv4() | transportAddressIPv6() (depends on the value of Domain)</v>
- <v>Port = integer()</v>
+ <v>Addr = transportAddress() % Default port is 162</v>
<v>Timeout = integer()</v>
<v>Retry = integer()</v>
<v>TagList = string()</v>
<v>ParamsName = string()</v>
<v>EngineId = string()</v>
- <v>TMask = transportAddressMask() (depends on Domain)</v>
+ <v>TMask = transportAddressMask() % Depends on Domain</v>
<v>MMS = integer()</v>
<v>Ret = {ok, Key} | {error, Reason}</v>
<v>Key = term()</v>
diff --git a/lib/snmp/doc/src/snmpa_conf.xml b/lib/snmp/doc/src/snmpa_conf.xml
index 99a56cd601..2780cec156 100644
--- a/lib/snmp/doc/src/snmpa_conf.xml
+++ b/lib/snmp/doc/src/snmpa_conf.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2013</year>
+ <year>2006</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -45,20 +45,56 @@
<title>DATA TYPES</title>
<code type="none"><![CDATA[
transportDomain() = transportDomainUdpIpv4 | transportDomainUdpIpv6
-transportAddressIPv4() = [integer()], length 4
-transportAddressIPv6() = [integer()], length 8
-transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6)
+
+transportAddress() =
+ transportAddressIPv4() | transportAddressIPv6()
+
+transportAddressWithPort() =
+ transportAddressIPv4WithPort() | transportAddressIPv6WithPort()
+
+transportAddressWithoutPort() =
+ transportAddressIPv4WithoutPort() | transportAddressIPv6WithoutPort()
+
+transportAddressIPv4() =
+ transportAddressIPv4WithPort() | transportAddressIPv4WithoutPort()
+transportAddressIPv4WithPort =
+ {transportAddressIPv4WithoutPort(), inet:port_number()} |
+ [byte() x 4, byte() x 2]
+transportAddressIPv4WithoutPort =
+ inet:ip4_address() | [byte() x 4]
+
+transportAddressIPv6() =
+ transportAddressIPv6WithPort() | transportAddressIPv6WithoutPort()
+transportAddressIPv6WithPort =
+ {transportAddressIPv6WithoutPort(), inet:port_number()} |
+ [word() x 8, inet:port_number()] |
+ [word() x 8, byte() x 2] |
+ {byte() x 16, byte() x 2]
+transportAddressIPv6WithoutPort =
+ inet:ip6_address() | [word() x 8] | [byte() x 16]
+
+transportAddressMask() =
+ [] | transportAddressWithPort()
+
+byte() = 0..255
+word() = 0..65535
]]></code>
+ <p>For <c>inet:ip4_address()</c>, <c>inet:ip6_address()</c>
+ and <c>inet:port_number()</c>, see also
+ <seealso marker="kernel:inet#type-ip_address">
+ <c>inet:ip_address()</c></seealso></p>
<marker id="agent_entry"></marker>
</section>
+
+
<funcs>
<func>
<name>agent_entry(Tag, Val) -> agent_entry()</name>
<fsummary>Create an agent entry</fsummary>
<type>
- <v>Tag = intAgentIpAddress | intAgentUDPPort | intAgentMaxPacketSize | snmpEngineMaxMessageSize | snmpEngineID</v>
+ <v>Tag = intAgentTransports | intAgentUDPPort | intAgentMaxPacketSize | snmpEngineMaxMessageSize | snmpEngineID</v>
<v>Val = term()</v>
<v>agent_entry() = term()</v>
</type>
@@ -390,17 +426,15 @@ transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6)
</func>
<func>
- <name>target_addr_entry(Name, Ip, TagList, ParamsName, EngineId) -> target_addr_entry()</name>
- <name>target_addr_entry(Name, Ip, TagList, ParamsName, EngineId, TMask) -> target_addr_entry()</name>
- <name>target_addr_entry(Name, Ip, Udp, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
- <name>target_addr_entry(Name, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
- <name>target_addr_entry(Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
+ <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId) -> target_addr_entry()</name>
+ <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask) -> target_addr_entry()</name>
+ <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
+ <name>target_addr_entry(Name, Domain, Addr, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
<fsummary>Create an target_addr entry</fsummary>
<type>
<v>Name = string()</v>
<v>Domain = transportDomain()</v>
- <v>Ip = transportAddressIPv4() | transportAddressIPv6() (depends on Domain)</v>
- <v>Udp = integer()</v>
+ <v>Ip = transportAddress() (depends on Domain)</v>
<v>Timeout = integer()</v>
<v>RetryCount = integer()</v>
<v>TagList = string()</v>
@@ -414,12 +448,12 @@ transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6)
<p>Create an entry for the agent target_addr config file,
<c>target_addr.conf</c>. </p>
<p><c>Name</c> must be a <em>non-empty</em> string. </p>
- <p><c>target_addr_entry/5</c> translates to the following call:
- <c>target_addr_entry(Name, Ip, TagList, ParamsName, EngineId)</c>. </p>
<p><c>target_addr_entry/6</c> translates to the following call:
- <c>target_addr_entry(Name, Ip, 162, TagList, ParamsName, EngineId, TMask, 2048)</c>. </p>
+ <c>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, [])</c>. </p>
+ <p><c>target_addr_entry/7</c> translates to the following call:
+ <c>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask, 2048)</c>. </p>
<p><c>target_addr_entry/8</c> translates to the following call:
- <c>target_addr_entry(Name, Ip, Udp, 1500, 3, TagList, ParamsName, EngineId, TMask, MaxMessageSize)</c>. </p>
+ <c>target_addr_entry(Name, Domain, Addr, 1500, 3, TagList, ParamsName, EngineId, TMask, MaxMessageSize)</c>. </p>
<p>See
<seealso marker="snmp_agent_config_files#target_addr">Target Address Definitions</seealso>
for more info. </p>
diff --git a/lib/snmp/doc/src/snmpa_mpd.xml b/lib/snmp/doc/src/snmpa_mpd.xml
index c5ab0a0520..518100d30c 100644
--- a/lib/snmp/doc/src/snmpa_mpd.xml
+++ b/lib/snmp/doc/src/snmpa_mpd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2013</year>
+ <year>1999</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -43,6 +43,12 @@
<marker id="init"></marker>
</description>
+ <section>
+ <title>DATA TYPES</title>
+ <p>See the <seealso marker="snmpa_conf#types">
+ data types in <c>snmpa_conf</c></seealso>.</p>
+ </section>
+
<funcs>
<func>
<name>init(Vsns) -> mpd_state()</name>
@@ -63,16 +69,17 @@
</func>
<func>
- <name>process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
- <name>process_packet(Packet, TDomain, TAddress, LocalEngineID, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
+ <name>process_packet(Packet, From, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
+ <name>process_packet(Packet, From, LocalEngineID, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
<fsummary>Process a packet received from the network</fsummary>
<type>
<v>Packet = binary()</v>
- <v>TDomain = snmpUDPDomain</v>
- <v>TAddress = {Ip, Udp}</v>
+ <v>From = {TDomain, TAddr}</v>
+ <v>TDomain = transportDomainUdpIpv4 | transportDomainUdpIpv6</v>
+ <v>TAddr = {IpAddr, IpPort}</v>
<v>LocalEngineID = string()</v>
- <v>Ip = {integer(), integer(), integer(), integer()}</v>
- <v>Udp = integer()</v>
+ <v>IpAddr = <seealso marker="kernel:inet#type-ip_address">inet:ip_address()</seealso></v>
+ <v>IpPort = inet:port_number()</v>
<v>State = mpd_state()</v>
<v>NoteStore = pid()</v>
<v>Log = snmp_log()</v>
@@ -85,7 +92,7 @@
</type>
<desc>
<p>Processes an incoming packet. Performs authentication and
- decryption as necessary. The return values should be passed the
+ decryption as necessary. The return values should be passed to the
agent.</p>
<note>
@@ -150,14 +157,20 @@
network.
</p>
<p><c>MsgData</c> is the message specific data used in
- the SNMP message. This value is received in a <c>send_pdu</c>
- or <c>send_pdu_req</c> message from the agent. In SNMPv1 and
+ the SNMP message. This value is received in a
+ <seealso marker="snmp_agent_netif#im_send_pdu"><c>send_pdu</c></seealso>
+ or
+ <seealso marker="snmp_agent_netif#im_send_pdu_req">
+ <c>send_pdu_req</c></seealso>
+ message from the agent. In SNMPv1 and
SNMPv2c, this message data is the community string. In
- SNMPv3, it is the context information.
- <c>To</c> is a list of the destination addresses and
+ SNMPv3, it is the context information.</p>
+ <p>
+ <c>To</c> is a list of destination addresses and
their corresponding security parameters. This value is
- also received from the requests mentioned above.
- </p>
+ received in the same message from the agent and then transformed
+ trough <seealso marker="#process_taddrs"><c>process_taddrs</c></seealso>
+ before passed to this function.</p>
<note>
<p>Note that the use of the LocalEngineID argument is only intended
@@ -166,6 +179,32 @@
(see SNMP-FRAMEWORK-MIB). </p>
</note>
+ <marker id="process_taddrs"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>process_taddrs(TDests) -> Dests</name>
+ <fsummary>Transform addresses from internal MIB format to a less internal
+ </fsummary>
+ <type>
+ <v>TDests = [TDest]</v>
+ <v>TDest = {{TDomain, TAddr}, SecData} | {TDomain, TAddr}</v>
+ <v>TDomain = term() % Not at tuple</v>
+ <v>TAddr = term()</v>
+ <v>SecData = term()</v>
+ <v>Dests = [Dest]</v>
+ <v>Dest = {{Domain, Addr}, SecData} | {Domain, Addr}</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddress() % Depends on Domain</v>
+ </type>
+ <desc>
+ <p>Transforms addresses from internal MIB format to one
+ more useful to <seealso marker="snmp_agent_netif">Agent Net if</seealso>.
+ </p>
+ <p>See also <seealso marker="#generate_msg"><c>generate_msg</c>.</seealso>
+ </p>
+
<marker id="discarded_pdu"></marker>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpa_network_interface_filter.xml b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
index e08a26ed92..eb640e1bc3 100644
--- a/lib/snmp/doc/src/snmpa_network_interface_filter.xml
+++ b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2013</year>
+ <year>2007</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -58,10 +58,10 @@
on two levels: </p>
<list type="bulleted">
<item>
- <p>The first level is at the UDP entry / exit point, i.e.
- immediately after the receipt of the message, before any message
+ <p>The first level is at the transport entry / exit point, i.e.
+ immediately after the receipt of the message before any message
processing is done (accept_recv) and
- immediately before sending the message, after all message
+ immediately before sending the message after all message
processing is done (accept_send).</p>
</item>
<item>
@@ -78,6 +78,12 @@
<seealso marker="snmp_app#configuration_params">req_limit</seealso> and
the function
<seealso marker="snmpa#register_notification_filter">register_notification_filter</seealso>. </p>
+ <p>Legacy network interface filter modules used arguments on the form
+ <c>(IpAddr, PortNumber,...)</c> instead of
+ <c>(Domain, Addr, ...)</c>, and if the SNMP agent is run without
+ changing the configuration to use transport domains
+ the network interface filter will still get
+ the old arguments and work as before.</p>
</description>
<section>
@@ -88,15 +94,17 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
'set-request' | trap | 'get-bulk-request' | 'inform-request' |
report
</code>
+ <p>See also the <seealso marker="snmpa_conf#types">
+ data types in <c>snmpa_conf</c></seealso>.</p>
<marker id="accept_recv"></marker>
</section>
<funcs>
<func>
- <name>accept_recv(Ip, Port) -> boolean()</name>
+ <name>accept_recv(Domain, Addr) -> boolean()</name>
<fsummary>Shall the received message be accepted</fsummary>
<type>
- <v>Ip = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
</type>
<desc>
<p>Called at the reception of a message (before <em>any</em> processing
@@ -107,11 +115,11 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
</desc>
</func>
<func>
- <name>accept_send(Ip, Port) -> boolean()</name>
+ <name>accept_send(Domain, Addr) -> boolean()</name>
<fsummary>Shall the message be sent</fsummary>
<type>
- <v>Ip = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
</type>
<desc>
<p>Called before the sending of a message (after <em>all</em> processing
@@ -122,11 +130,11 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
</desc>
</func>
<func>
- <name>accept_recv_pdu(Ip, Port, PduType) -> boolean()</name>
+ <name>accept_recv_pdu(Domain, Addr, PduType) -> boolean()</name>
<fsummary>Shall the received pdu be accepted</fsummary>
<type>
- <v>Ip = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
<v>PduType = pdu_type()</v>
</type>
<desc>
@@ -144,7 +152,9 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
<type>
<v>Targets = targets()</v>
<v>targets() = [target()]</v>
- <v>target() = {ip_address(), port()}</v>
+ <v>target() = {Domain, Addr}</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
<v>PduType = pdu_type() > 0</v>
<v>Reply = boolean() | NewTargets</v>
<v>NewTargets = targets()</v>
@@ -155,7 +165,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
<p>For the message to be discarded all together, the function
<em>must</em> return <em>false</em>. </p>
<p>Note that it is possible for this function to filter out targets
- (but <em>not</em> add its own) by returning an updated
+ (but <em>not</em> to add its own) by returning an updated
<c>Targets</c> list (<c>NewTargets</c>). </p>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml b/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml
index aff71688b6..814f02a14c 100644
--- a/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml
+++ b/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2013</year>
+ <year>2014</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -45,22 +45,30 @@
must export the following functions: </p>
<list type="bulleted">
<item>
- <p><seealso marker="#delivery_targets">delivery_targets/3</seealso></p>
+ <p><seealso marker="#delivery_targets/3">delivery_targets/3</seealso></p>
</item>
<item>
- <p><seealso marker="#delivery_info">delivery_info/4</seealso></p>
+ <p><seealso marker="#delivery_info/4">delivery_info/4</seealso></p>
</item>
</list>
<p>The semantics of them and their exact signatures are explained
below. </p>
+ <p>Legacy notification delivery information receiver modules
+ used a target argument on the form
+ <c>{IpAddr, PortNumber}</c> instead of
+ <c>{Domain, Addr}</c>, and if the SNMP Agent is run without
+ changing the configuration to use transport domains
+ the notification delivery information receiver will still get
+ the old arguments and work as before.</p>
+
</description>
<section>
<title>DATA TYPES</title>
- <code type="none"><![CDATA[
-address() = A 4-tuple
- ]]></code>
+ <p>See the <seealso marker="snmpa_conf#types">
+ data types in <c>snmpa_conf</c></seealso>.</p>
+ <marker id="accept_recv"></marker>
<marker id="delivery_targets"></marker>
</section>
@@ -71,10 +79,8 @@ address() = A 4-tuple
<fsummary>Inform about target addresses</fsummary>
<type>
<v>Tag = term()</v>
- <v>Targets = [target()]</v>
- <v>target() = {Address, Port}</v>
- <v>Address = address()</v>
- <v>Port = integer()</v>
+ <v>Targets = [Target]</v>
+ <v>Target = {transportDomain(), transportAddressWithPort()</v>
<v>Extra = term()</v>
</type>
<desc>
@@ -94,10 +100,8 @@ address() = A 4-tuple
<fsummary>Inform about delivery result</fsummary>
<type>
<v>Tag = term()</v>
- <v>Target = target()</v>
- <v>target() = {Address, Port}</v>
- <v>Address = address()</v>
- <v>Port = integer()</v>
+ <v>Targets = [Target]</v>
+ <v>Target = {transportDomain(), transportAddressWithPort()</v>
<v>DeliveryResult = delivery_result()</v>
<v>delivery_result() = no_response | got_response</v>
<v>Extra = term()</v>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index dc8226bb87..ff90e49968 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.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>
@@ -69,6 +69,9 @@ sec_name() = string()
sec_level() = noAuthNoPriv | authNoPriv | authPriv
]]></code>
+ <p>See also the <seealso marker="snmpa_conf#types">
+ data types in <c>snmpa_conf</c></seealso>.</p>
+
<marker id="monitor"></marker>
</section>
<funcs>
@@ -300,9 +303,9 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
<p>The type of <c>Val</c> depends on <c>Item</c>: </p>
<code type="none"><![CDATA[
[mandatory] engine_id = string()
-[mandatory] address = ip_address()
-[optional] port = integer()
-[optional] tdomain = transportDomainUdpIpv4 | transportDomainUdpIpv6
+[mandatory] tadress = transportAddress() % Depends on tdomain
+[optional] port = inet:port_number()
+[optional] tdomain = transportDomain()
[optional] community = string()
[optional] timeout = integer() | snmp_timer()
[optional] max_message_size = integer()
@@ -313,7 +316,8 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
]]></code>
<p>Note that if no <c>tdomain</c> is given, the default value,
<c>transportDomainUdpIpv4</c>, is used.</p>
- <p>Note that if no <c>port</c> is given, the default value is used.</p>
+ <p>Note that if no <c>port</c> is given and if <c>taddress</c> does not
+ contain a port number, the default value is used.</p>
<marker id="unregister_agent"></marker>
</desc>
diff --git a/lib/snmp/doc/src/snmpm_conf.xml b/lib/snmp/doc/src/snmpm_conf.xml
index 0cc9ff3379..8635fb705b 100644
--- a/lib/snmp/doc/src/snmpm_conf.xml
+++ b/lib/snmp/doc/src/snmpm_conf.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2013</year>
+ <year>2006</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -195,14 +195,14 @@
</desc>
</func>
<func>
- <name>agents_entry(UserId, TargetName, Comm, Ip, Port, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel) -> agents_entry()</name>
+ <name>agents_entry(UserId, TargetName, Comm, Domain, Addr, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel) -> agents_entry()</name>
<fsummary>Create an agents entry</fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = string()</v>
<v>Comm = string()</v>
- <v>Ip = string()</v>
- <v>Port = integer()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddress()</v>
<v>EngineID = string()</v>
<v>Timeout = integer()</v>
<v>MaxMessageSize = integer()</v>
diff --git a/lib/snmp/doc/src/snmpm_mpd.xml b/lib/snmp/doc/src/snmpm_mpd.xml
index ad72fd7bc0..c23b2b6833 100644
--- a/lib/snmp/doc/src/snmpm_mpd.xml
+++ b/lib/snmp/doc/src/snmpm_mpd.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>
@@ -39,7 +39,12 @@
It is supposed to be used from a Network Interface process
(<seealso marker="snmp_manager_netif">Definition of Manager Net if</seealso>).
</p>
+
+ <p>Legacy API function <c>process_msg/7</c> that has got separate
+ <c>IpAddr</c> and <c>PortNumber</c> arguments still works as before
+ for backwards compatibility reasons.</p>
</description>
+
<funcs>
<func>
<name>init_mpd(Vsns) -> mpd_state()</name>
@@ -58,13 +63,12 @@
</desc>
</func>
<func>
- <name>process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) -> {ok, Vsn, Pdu, PduMS, MsgData} | {discarded, Reason}</name>
+ <name>process_msg(Msg, Domain, Addr, State, NoteStore, Logger) -> {ok, Vsn, Pdu, PduMS, MsgData} | {discarded, Reason}</name>
<fsummary>Process a message received from the network</fsummary>
<type>
<v>Msg = binary()</v>
- <v>TDomain = snmpUDPDomain</v>
- <v>Addr = {integer(), integer(), integer(), integer()}</v>
- <v>Port = integer()</v>
+ <v>Domain = transportDomainUdpIpv4 | transportDomainUdpIpv6</v>
+ <v>Addr = {<seealso marker="kernel:inet#type-ip_address">inet:ip_address(), inet:port_number()</seealso>} </v>
<v>State = mpd_state()</v>
<v>NoteStore = pid()</v>
<v>Logger = function()</v>
diff --git a/lib/snmp/doc/src/snmpm_network_interface.xml b/lib/snmp/doc/src/snmpm_network_interface.xml
index 6cf7bd6ed7..bea6b46dc7 100644
--- a/lib/snmp/doc/src/snmpm_network_interface.xml
+++ b/lib/snmp/doc/src/snmpm_network_interface.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>
@@ -69,6 +69,10 @@
<p>The semantics of them and their exact signatures are explained
below. </p>
+ <p>Legacy API function <c>send_pdu/7</c> that has got separate
+ <c>IpAddr</c> and <c>PortNumber</c> arguments still works as before
+ for backwards compatibility reasons.</p>
+
<marker id="start_link"></marker>
</description>
@@ -103,15 +107,15 @@
</func>
<func>
- <name>send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) -> void()</name>
+ <name>send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo) -> void()</name>
<fsummary>Request the network interface process to send this pdu</fsummary>
<type>
<v>Pid = pid()</v>
<v>Pdu = pdu()</v>
<v>Vsn = 'version-1' | 'version-2' | 'version-3'</v>
<v>MsgData = term()</v>
- <v>Addr = address()</v>
- <v>Port = integer()</v>
+ <v>Domain = transportDomainUdpIpv4 | transportDomainUdpIpv6</v>
+ <v>Addr = {<seealso marker="kernel:inet#type-ip_address">inet:ip_address(), inet:port_number()</seealso>} </v>
<v>ExtraInfo = term()</v>
</type>
<desc>
diff --git a/lib/snmp/doc/src/snmpm_network_interface_filter.xml b/lib/snmp/doc/src/snmpm_network_interface_filter.xml
index f0526269b3..1ef4f29c0f 100644
--- a/lib/snmp/doc/src/snmpm_network_interface_filter.xml
+++ b/lib/snmp/doc/src/snmpm_network_interface_filter.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2013</year>
+ <year>2007</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -76,6 +76,12 @@
The default filter accepts all messages.</p>
<p>A network interface filter can e.g. be used during testing or for load
regulation. </p>
+ <p>Legacy network interface filter modules used arguments on the form
+ <c>(IpAddr, PortNumber,...)</c> instead of
+ <c>(Domain, Addr, ...)</c>, and if the SNMP manager is run without
+ changing the configuration to use transport domains
+ the network interface filter will still get
+ the old arguments and work as before.</p>
</description>
<section>
@@ -86,16 +92,18 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
'set-request' | trap | 'get-bulk-request' | 'inform-request' |
report | trappdu
</code>
+ <p>See also the <seealso marker="snmpa_conf#types">
+ data types in <c>snmpa_conf</c></seealso>.</p>
<marker id="accept_recv"></marker>
</section>
<funcs>
<func>
- <name>accept_recv(Addr, Port) -> boolean()</name>
+ <name>accept_recv(Domain, Addr) -> boolean()</name>
<fsummary>Shall the received message be accepted</fsummary>
<type>
- <v>Addr = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
</type>
<desc>
<p>Called at the reception of a message (before <em>any</em> processing
@@ -107,11 +115,11 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
</func>
<func>
- <name>accept_send(Addr, Port) -> boolean()</name>
+ <name>accept_send(Domain, Addr) -> boolean()</name>
<fsummary>Shall the message be sent</fsummary>
<type>
- <v>Addr = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
</type>
<desc>
<p>Called before the sending of a message (after <em>all</em> processing
@@ -123,11 +131,11 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
</func>
<func>
- <name>accept_recv_pdu(Addr, Port, PduType) -> boolean()</name>
+ <name>accept_recv_pdu(Domain, Addr, PduType) -> boolean()</name>
<fsummary>Shall the received pdu be accepted</fsummary>
<type>
- <v>Addr = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
<v>PduType = pdu_type()</v>
</type>
<desc>
@@ -141,11 +149,11 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' |
</func>
<func>
- <name>accept_send_pdu(Addr, Port, PduType) -> boolean()</name>
+ <name>accept_send_pdu(Domain, Addr, PduType) -> boolean()</name>
<fsummary>Shall the pdu be sent</fsummary>
<type>
- <v>Addr = ip_address()</v>
- <v>Port = port()</v>
+ <v>Domain = transportDomain()</v>
+ <v>Addr = transportAddressWithPort()</v>
<v>PduType = pdu_type() > 0</v>
</type>
<desc>
diff --git a/lib/snmp/doc/src/snmpm_user.xml b/lib/snmp/doc/src/snmpm_user.xml
index 6f412d90f8..a4492839cd 100644
--- a/lib/snmp/doc/src/snmpm_user.xml
+++ b/lib/snmp/doc/src/snmpm_user.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>
@@ -63,10 +63,15 @@
<p>The semantics of them and their exact signatures are explained
below. </p>
<p>Some of the function has no defined return value (<c>void()</c>),
- they can ofcourse return anythyng. But the functions that do have
+ they can of course return anything. But the functions that do have
specified return value(s) <em>must</em> adhere to this. None of the
functions can use exit of throw to return. </p>
+ <p>If the manager is not configured to use any particular
+ transport domain, the behaviour <c>handle_agent/4</c>
+ will for backwards copmpatibility reasons be called with the old
+ <c>IpAddr</c> and <c>PortNumber</c> arguments</p>
+
<marker id="types"></marker>
</description>
@@ -116,11 +121,11 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(),
</func>
<func>
- <name>handle_agent(Addr, Port, Type, SnmpInfo, UserData) -> Reply</name>
+ <name>handle_agent(Domain, Addr, Type, SnmpInfo, UserData) -> Reply</name>
<fsummary>Handle agent</fsummary>
<type>
- <v>Addr = ip_address()</v>
- <v>Port = integer()</v>
+ <v>Domain = transportDomainUdpIpv4 | transportDomainUdpIpv6</v>
+ <v>Addr = {<seealso marker="kernel:inet#type-ip_address">inet:ip_address(), inet:port_number()</seealso>} </v>
<v>Type = pdu | trap | report | inform</v>
<v>SnmpInfo = SnmpPduInfo | SnmpTrapInfo | SnmpReportInfo | SnmpInformInfo</v>
<v>SnmpPduInfo = snmp_gen_info()</v>
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..6ff9224d34 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,50 @@ 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)
+ when is_list(Transports) ->
+ CheckedTransports =
+ [case Transport of
+ {Domain, Address} ->
+ 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;
+ _ ->
+ error({bad_transport, Transport})
+ end
+ || 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 +243,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 +423,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..ef9503cda8 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,173 @@ 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, _TMask, _MMS}) -> % Arity 10
+ error({bad_address, {Domain, Address}});
+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);
+check_target_addr(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params,
+ _EngineId}) ->% Arity 8
+ error({bad_address, {Domain, Address}});
+%% 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);
+check_target_addr(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params}) -> % Arity 7
+ error({bad_address, {Domain, Address}});
+%% 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(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params,
+ _TMask, _MMS}) -> % Arity 9
+ error({bad_address, {Domain, Address}});
+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, 162) 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 snmp_conf:check_address(Domain, Mask) of
+ ok ->
+ Mask;
+ {ok, NMask} ->
+ NMask
+ catch
+ {error, {bad_address, Info}} ->
+ error({bad_mask, Info})
+ end.
%%-----------------------------------------------------------------
@@ -286,16 +384,21 @@ table_del_row(Tab, Key) ->
snmpa_mib_lib:table_del_row(db(Tab), Key).
-add_addr(Name, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS) ->
- Domain = default_domain(),
- add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS).
-
-add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS) ->
- Addr = {Name, Domain, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS},
+add_addr(
+ Name, Domain_or_Ip, Addr_or_Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS) ->
+ add_addr(
+ {Name, Domain_or_Ip, Addr_or_Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS}).
+%%
+add_addr(
+ Name, Domain, Ip, Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS) ->
+ add_addr(
+ {Name, Domain, Ip, Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS}).
+%%
+add_addr(Addr) ->
case (catch check_target_addr(Addr)) of
{ok, Row} ->
Key = element(1, Row),
@@ -604,6 +707,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 +735,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..534d0e447b 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
@@ -47,7 +47,7 @@
read_standard_config/1,
%% target_addr.conf
- target_addr_entry/5, target_addr_entry/6,
+ target_addr_entry/5, target_addr_entry/6, target_addr_entry/7,
target_addr_entry/8, target_addr_entry/10, target_addr_entry/11,
write_target_addr_config/2, write_target_addr_config/3,
append_target_addr_config/2,
@@ -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,48 @@ 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, Domain, Addr, TagList,
+ ParamsName, EngineId) when is_atom(Domain) ->
+ target_addr_entry(
+ Name, Domain, Addr, 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, Domain_or_Ip, Addr_or_Port, TagList,
+ ParamsName, EngineId, TMask) ->
+ target_addr_entry(
+ Name, Domain_or_Ip, Addr_or_Port, 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 +451,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 +486,41 @@ 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, 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, 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}) ->
+ error({bad_address, {Domain, Address}});
+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 +564,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 +629,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 +718,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 +750,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 +821,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 +853,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..e7e54f5b7e 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -28,6 +28,12 @@
%% {update, snmpa_local_db, soft, soft_purge, soft_purge, []}
%% {add_module, snmpm_net_if_mt}
[
+ {"5.1", [ % Only compiler changes
+ ]},
+ {"5.0", [{restart_application, snmp}]},
+ {"4.25.1", [{restart_application, snmp}]},
+ {"4.25.0.1", [{restart_application, snmp}]},
+ {"4.25.0.0.1", [{restart_application, snmp}]},
{"4.25", [{restart_application, snmp}]},
{"4.24.2", [{restart_application, snmp}]},
{"4.24.1", [{restart_application, snmp}]},
@@ -40,6 +46,12 @@
%% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
[
+ {"5.1", [ % Only compiler changes
+ ]},
+ {"5.0", [{restart_application, snmp}]},
+ {"4.25.1", [{restart_application, snmp}]},
+ {"4.25.0.1", [{restart_application, snmp}]},
+ {"4.25.0.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/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl
index 5a661cf194..0f6393eeef 100644
--- a/lib/snmp/src/compile/snmpc_lib.erl
+++ b/lib/snmp/src/compile/snmpc_lib.erl
@@ -139,6 +139,7 @@ allow_size_rfc1902('Integer32') -> true;
allow_size_rfc1902('Unsigned32') -> true;
allow_size_rfc1902('OCTET STRING') -> true;
allow_size_rfc1902('Gauge32') -> true;
+allow_size_rfc1902('Opaque') -> true;
allow_size_rfc1902(_) -> false.
guess_integer_type() ->
diff --git a/lib/snmp/src/manager/depend.mk b/lib/snmp/src/manager/depend.mk
index 2e7783c8ed..60f61b0d3b 100644
--- a/lib/snmp/src/manager/depend.mk
+++ b/lib/snmp/src/manager/depend.mk
@@ -2,7 +2,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
@@ -50,10 +50,11 @@ $(EBIN)/snmpm_net_if.$(EMULATOR): \
snmpm_network_interface.erl
$(EBIN)/snmpm_net_if_mt.$(EMULATOR): \
+ snmpm_net_if_mt.erl \
../../include/snmp_types.hrl \
../misc/snmp_debug.hrl \
../misc/snmp_verbosity.hrl \
- snmpm_net_if_mt.erl \
+ snmpm_net_if.erl \
snmpm_network_interface.erl
$(EBIN)/snmpm_server.$(EMULATOR): \
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..087ef6c6ea 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,16 @@ 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 =:= transports;
+ 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 +152,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);
@@ -222,9 +200,10 @@ do_write_users_conf(_Fd, Crap) ->
%% ------ agents.conf ------
%%
-agents_entry(UserId, TargetName, Comm, Ip, Port, EngineID, Timeout,
- MaxMessageSize, Version, SecModel, SecName, SecLevel) ->
- {UserId, TargetName, Comm, Ip, Port, EngineID, Timeout,
+agents_entry(
+ UserId, TargetName, Comm, Domain_or_Ip, Addr_or_Port, EngineID, Timeout,
+ MaxMessageSize, Version, SecModel, SecName, SecLevel) ->
+ {UserId, TargetName, Comm, Domain_or_Ip, Addr_or_Port, EngineID, Timeout,
MaxMessageSize, Version, SecModel, SecName, SecLevel}.
@@ -239,36 +218,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 +254,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 +288,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 +325,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..5cab81baf6 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).
@@ -437,27 +442,76 @@ agent_info(TargetName, all) ->
All ->
{ok, [{Item, Val} || {{_, Item}, Val} <- All]}
end;
+%% Begin backwards compatibility
+agent_info(TargetName, address) ->
+ case agent_info({TargetName, taddress}) of
+ {ok, Val} ->
+ {Addr, _} = Val,
+ {ok, Addr};
+ _ ->
+ %% This should be redundant since 'taddress' should exist
+ agent_info({TargetName, address})
+ end;
+agent_info(TargetName, port) ->
+ case agent_info({TargetName, taddress}) of
+ {ok, Val} ->
+ {_, Port} = Val,
+ {ok, Port};
+ _ ->
+ %% This should be redundant since 'taddress' should exist
+ agent_info({TargetName, port})
+ end;
+%% End backwards compatibility
agent_info(TargetName, Item) ->
- case ets:lookup(snmpm_agent_table, {TargetName, Item}) of
+ agent_info({TargetName, Item}).
+
+agent_info(Key) ->
+ case ets:lookup(snmpm_agent_table, Key) of
[{_, Val}] ->
{ok, Val};
[] ->
{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) when is_integer(Port) ->
+ %% 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 +519,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 +541,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 +775,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 +1108,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, []),
@@ -1271,36 +1310,6 @@ verify_options(Opts, Mandatory) ->
verify_mandatory_options(Opts, Mandatory),
verify_options(Opts).
-%% mandatory() -> [mand()]
-%% mand() -> atom() | {atom, [atom()]}
-verify_mandatory_options(_Opts, []) ->
- ok;
-verify_mandatory_options(Opts, [Mand|Mands]) ->
- verify_mandatory_option(Opts, Mand),
- verify_mandatory_options(Opts, Mands).
-
-verify_mandatory_option(Opts, {Mand, MandSubOpts}) ->
- ?d("verify_mandatory_option -> entry with"
- "~n Mand: ~p"
- "~n MandSubObjs: ~p", [Mand, MandSubOpts]),
- case lists:keysearch(Mand, 1, Opts) of
- {value, {Mand, SubOpts}} ->
- verify_mandatory_options(SubOpts, MandSubOpts);
- false ->
- ?d("missing mandatory option: ~w [~p]", [Mand, MandSubOpts]),
- error({missing_mandatory, Mand, MandSubOpts})
- end;
-verify_mandatory_option(Opts, Mand) ->
- ?d("verify_mandatory_option -> entry with"
- "~n Mand: ~p", [Mand]),
- case lists:keymember(Mand, 1, Opts) of
- true ->
- ok;
- false ->
- ?d("missing mandatory option: ~w", [Mand]),
- error({missing_mandatory, Mand})
- end.
-
verify_options([]) ->
?d("verify_options -> done", []),
ok;
@@ -1506,7 +1515,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;
@@ -1614,7 +1625,38 @@ verify_verbosity(Verbosity) ->
_ ->
error({invalid_verbosity, Verbosity})
end.
+
+%% mandatory() -> [mand()]
+%% mand() -> atom() | {atom, [atom()]}
+verify_mandatory_options(_Opts, []) ->
+ ok;
+verify_mandatory_options(Opts, [Mand|Mands]) ->
+ verify_mandatory_option(Opts, Mand),
+ verify_mandatory_options(Opts, Mands).
+
+verify_mandatory_option(Opts, {Mand, MandSubOpts}) ->
+ ?d("verify_mandatory_option -> entry with"
+ "~n Mand: ~p"
+ "~n MandSubObjs: ~p", [Mand, MandSubOpts]),
+ case lists:keysearch(Mand, 1, Opts) of
+ {value, {Mand, SubOpts}} ->
+ verify_mandatory_options(SubOpts, MandSubOpts);
+ false ->
+ ?d("missing mandatory option: ~w [~p]", [Mand, MandSubOpts]),
+ error({missing_mandatory, Mand, MandSubOpts})
+ end;
+verify_mandatory_option(Opts, Mand) ->
+ ?d("verify_mandatory_option -> entry with"
+ "~n Mand: ~p", [Mand]),
+ case lists:keymember(Mand, 1, Opts) of
+ true ->
+ ok;
+ false ->
+ ?d("missing mandatory option: ~w", [Mand]),
+ error({missing_mandatory, Mand})
+ end.
+
%% ------------------------------------------------------------------------
init_manager_config([]) ->
@@ -1629,181 +1671,91 @@ 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, noAuthNoPriv}, % SecLevel
+ {community, "all-rights"}], % Community
+ do_update_agent_info(default_agent, AgentDefaultConfig).
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, Domain, Addr,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) when is_atom(Domain) ->
+ check_agent_config(
+ UserId, TargetName, Community, Domain, Addr,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel);
+check_agent_config(
+ {UserId, TargetName, Community, Ip, Port,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) when is_integer(Port) ->
+ Domain = default_transport_domain(),
+ Addr = {Ip, Port},
+ check_agent_config(
+ UserId, TargetName, Community, Domain, Addr,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel);
+check_agent_config(
+ {_UserId, _TargetName, _Community, Domain, Addr,
+ _EngineId, _Timeout, _MaxMessageSize,
+ _Version, _SecModel, _SecName, _SecLevel}) ->
+ error({bad_address, {Domain, Addr}});
+check_agent_config(
+ {UserId, TargetName, Community, Domain, Ip, Port,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) ->
+ Addr = {Ip, Port},
+ check_agent_config(
+ UserId, TargetName, Community, Domain, Addr,
+ 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, fix_address(Domain, Addr)},
{community, Comm},
{engine_id, EngineId},
{timeout, Timeout},
@@ -1813,40 +1765,180 @@ 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
+ %% Note: not default_transport_domain() since
+ %% taddress is the new format hence the application
+ %% should be tdomain aware and therefore addresses
+ %% on the Domain, Addr format should be used and understood.
+ TD = transportDomainUdpIpv4,
+ {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) ->
- 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 +1956,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 +1993,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 +2006,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 +2034,24 @@ 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) ->
- 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,
@@ -2139,125 +2234,128 @@ is_crypto_supported(Func) ->
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)
- end.
+ 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_someof(Conf, [port, transports]),
+ verify_mandatory(Conf, [engine_id, max_message_size]),
+ default_manager_config(Conf).
+
+default_manager_config(Conf) ->
+ %% Ensure valid transports entry
+ case lists:keyfind(transports, 1, Conf) of
+ false ->
+ {port, Port} = lists:keyfind(port, 1, Conf),
+ 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} ->
+ lists:sort(
+ fun order_manager_config/2,
+ [{transports, [{Domain, {Address, Port}}]} | Conf]);
+ {error, _Reason} ->
+ ?d("default_manager_config -> "
+ "failed getting ~w address for ~s:~n"
+ " _Reason: ~p", [Family, Hostname, _Reason]),
+ Conf
+ end;
+ _ ->
+ Conf
+ end.
+
+order_manager_config(EntryA, EntryB) ->
+ snmp_conf:keyorder(1, EntryA, EntryB, [domain, port]).
+
+check_manager_config(Entry, undefined) ->
+ check_manager_config(Entry, {default_transport_domain(), undefined});
+check_manager_config({domain, Domain}, {_, Port}) ->
+ {snmp_conf:check_domain(Domain), {Domain, Port}};
+check_manager_config({port, Port}, {Domain, _}) ->
+ {ok = snmp_conf:check_port(Port), {Domain, Port}};
+check_manager_config({address, _}, {_, undefined}) ->
+ error({missing_mandatory, port});
+check_manager_config({address = Tag, Ip} = Entry, {Domain, Port} = State) ->
+ {case snmp_conf:check_ip(Domain, Ip) of
+ ok ->
+ [Entry,
+ {transports, [{Domain, {Ip, Port}}]}];
+ {ok, FixedIp} ->
+ [{Tag, FixedIp},
+ {transports, [{Domain, {FixedIp, Port}}]}]
+ end, State};
+check_manager_config({transports = Tag, Transports}, {_, Port} = State)
+ when is_list(Transports) ->
+ CheckedTransports =
+ [case Transport of
+ {Domain, Address} ->
+ 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 when Port =:= undefined->
+ error({missing_mandatory, port});
+ Domain ->
+ Family = snmp_conf:tdomain_to_family(Domain),
+ {ok, Hostname} = inet:gethostname(),
+ case inet:getaddr(Hostname, Family) of
+ {ok, IpAddr} ->
+ {Domain, {IpAddr, Port}};
+ {error, _} ->
+ error({bad_address, {Domain, Hostname}})
+ end
+ end
+ || Transport <- Transports],
+ {{ok, {Tag, CheckedTransports}}, State};
+check_manager_config(Entry, State) ->
+ {check_manager_config(Entry), State}.
-default_manager_config() ->
- {ok, HostName} = inet:gethostname(),
- case inet:getaddr(HostName, inet) of
- {ok, A} ->
- [{address, tuple_to_list(A)}];
- {error, _Reason} ->
- ?d("default_manager_config -> failed getting address: "
- "~n _Reason: ~p", [_Reason]),
- []
- end.
-
-check_manager_config({address, Addr}) ->
- snmp_conf:check_ip(Addr);
-check_manager_config({port, Port}) ->
- snmp_conf:check_integer(Port, {gt, 0});
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}}.
-
-
-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.
-
-
-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([], Defs, Confs) ->
-% Confs ++ Defs;
-% ensure_manager_config(Confs0, [{Key, DefVal}|Defs], Acc) ->
-% case lists:keysearch(Key, 1, Confs0) of
-% false ->
-% ensure_manager_config(Confs0, Defs, [{Key, DefVal}|Acc]);
-% {value, Conf} ->
-% Confs = lists:keydelete(Key, 1, Confs0),
-% ensure_manager_config(Confs, Defs, [Conf|Acc])
-% end.
-
+ error({unknown_config, Conf}).
-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}}
+ erlang:raise(throw, Error, erlang:get_stacktrace())
end.
-do_read(File, Check) ->
- {ok, snmp_conf:read(File, Check)}.
-
-
%%--------------------------------------------------------------------
%% Func: handle_call/3
%% Returns: {reply, Reply, State} |
@@ -2684,30 +2782,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 +2847,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 +2856,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 +2880,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 +2908,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 +2939,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 +3123,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 +3316,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) ->
@@ -3391,4 +3433,3 @@ error_msg(F, 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..b4cc165d2e 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
@@ -17,7 +17,9 @@
%% %CopyrightEnd%
%%
+-ifndef(snmpm_net_if_mt).
-module(snmpm_net_if).
+-endif.
-behaviour(gen_server).
-behaviour(snmpm_network_interface).
@@ -27,9 +29,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 +57,11 @@
%% -define(VMODULE,"NET_IF").
-include("snmp_verbosity.hrl").
--record(state,
+-record(state,
{
server,
note_store,
- sock,
+ transports = [],
mpd_state,
log,
irb = auto, % auto | {user, integer()}
@@ -67,6 +69,9 @@
filter
}).
+-record(transport,
+ {socket,
+ domain = snmpUDPDomain}).
-define(DEFAULT_FILTER_MODULE, snmpm_net_if_filter).
-define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]).
@@ -99,30 +104,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, 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_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, 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).
@@ -144,6 +151,64 @@ filter_reset(Pid) ->
%%%-------------------------------------------------------------------
+%%% Multi-thread manager
+%%%-------------------------------------------------------------------
+
+-ifdef(snmpm_net_if_mt).
+
+%% This function is called through the macro below to
+%% (in the not multithreaded case) avoid creating the
+%% Failer/4 fun, and to avoid calling the Worker through a fun
+%% (now it shall not be a fun, just a code snippet).
+
+worker(Worker, Failer, #state{log = Log} = State) ->
+ Verbosity = get(verbosity),
+ spawn_opt(
+ fun () ->
+ try
+ put(sname, mnifw),
+ put(verbosity, Verbosity),
+ NewState =
+ case do_reopen_log(Log) of
+ Log ->
+ State;
+ NewLog ->
+ State#state{log = NewLog}
+ end,
+ Worker(NewState)
+ of
+ Result ->
+ %% Winds up in handle_info {'DOWN', ...}
+ erlang:exit({net_if_worker, Result})
+ catch
+ Class:Reason ->
+ %% Winds up in handle_info {'DOWN', ...}
+ erlang:exit(
+ {net_if_worker, Failer,
+ Class, Reason, erlang:get_stacktrace()})
+ end
+ end,
+ [monitor]).
+-define(
+ worker(S, Worker, Failer, State),
+ begin
+ worker(
+ fun (S) -> begin Worker end end,
+ begin Failer end,
+ (State))
+ end).
+
+-else.
+
+-define(
+ worker(S, Worker, _Failer, State),
+ begin (S) = (State), begin Worker end end).
+
+-endif.
+
+
+
+%%%-------------------------------------------------------------------
%%% Callback functions from gen_server
%%%-------------------------------------------------------------------
@@ -158,12 +223,19 @@ init([Server, NoteStore]) ->
?d("init -> entry with"
"~n Server: ~p"
"~n NoteStore: ~p", [Server, NoteStore]),
- case (catch do_init(Server, NoteStore)) of
+ try do_init(Server, NoteStore)
+ catch
{error, Reason} ->
- {stop, Reason};
- {ok, State} ->
- {ok, State}
+ {stop, Reason}
end.
+
+-ifdef(snmpm_net_if_mt).
+%% This should really be protected, but it also needs to
+%% be writable for the worker processes, so...
+-define(inform_table_opts, [set, public, named_table, {keypos, 1}]).
+-else.
+-define(inform_table_opts, [set, protected, named_table, {keypos, 1}]).
+-endif.
do_init(Server, NoteStore) ->
process_flag(trap_exit, true),
@@ -173,18 +245,18 @@ do_init(Server, NoteStore) ->
process_flag(priority, Prio),
%% -- Create inform request table --
- ets:new(snmpm_inform_request_table,
- [set, protected, named_table, {keypos, 1}]),
+ ets:new(snmpm_inform_request_table, ?inform_table_opts),
%% -- Verbosity --
{ok, Verbosity} = snmpm_config:system_info(net_if_verbosity),
- put(sname,mnif),
- put(verbosity,Verbosity),
+ put(sname, mnif),
+ put(verbosity, Verbosity),
?vlog("starting", []),
%% -- MPD --
{ok, Vsns} = snmpm_config:system_info(versions),
MpdState = snmpm_mpd:init(Vsns),
+ ?vdebug("MpdState: ~w", [MpdState]),
%% -- Module dependent options --
{ok, Opts} = snmpm_config:system_info(net_if_options),
@@ -193,14 +265,6 @@ do_init(Server, NoteStore) ->
{ok, IRB} = snmpm_config:system_info(net_if_irb),
IrGcRef = irgc_start(IRB),
- %% -- Socket --
- SndBuf = get_opt(Opts, sndbuf, default),
- RecBuf = get_opt(Opts, recbuf, default),
- 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),
-
%% Flow control --
FilterOpts = get_opt(Opts, filter, []),
FilterMod = create_filter(FilterOpts),
@@ -209,77 +273,107 @@ do_init(Server, NoteStore) ->
%% -- Audit trail log ---
{ok, ATL} = snmpm_config:system_info(audit_trail_log),
Log = do_init_log(ATL),
+ ?vdebug("Log: ~w", [Log]),
+
+ {ok, DomainAddresses} = snmpm_config:system_info(transports),
+ ?vdebug("DomainAddresses: ~w",[DomainAddresses]),
+ CommonSocketOpts = common_socket_opts(Opts),
+ BindTo = get_opt(Opts, bind_to, false),
+ case
+ [begin
+ {IpPort, SocketOpts} =
+ socket_params(Domain, Address, BindTo, CommonSocketOpts),
+ Socket = socket_open(IpPort, SocketOpts),
+ #transport{socket = Socket, domain = Domain}
+ end || {Domain, Address} <- DomainAddresses]
+ of
+ [] ->
+ ?vinfo("No transports configured: ~p", [DomainAddresses]),
+ throw({error, {no_transports,DomainAddresses}});
+ Transports ->
+ %% -- Initiate counters ---
+ init_counters(),
+
+ %% -- We are done ---
+ State = #state{
+ server = Server,
+ note_store = NoteStore,
+ mpd_state = MpdState,
+ transports = Transports,
+ log = Log,
+ irb = IRB,
+ irgc = IrGcRef,
+ filter = FilterMod},
+ ?vdebug("started", []),
+ {ok, State}
+ end.
- %% -- Initiate counters ---
- init_counters(),
-
- %% -- We are done ---
- State = #state{server = Server,
- note_store = NoteStore,
- mpd_state = MpdState,
- sock = Sock,
- log = Log,
- irb = IRB,
- irgc = IrGcRef,
- filter = FilterMod},
- ?vdebug("started", []),
- {ok, State}.
-
-
-%% 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]),
- IpOpts1 = bind_to(BindTo),
- IpOpts2 = no_reuse(NoReuse),
- IpOpts3 = recbuf(RecvSz),
- IpOpts4 = sndbuf(SendSz),
- IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
- OpenRes =
- case init:get_argument(snmpm_fd) of
- {ok, [[FdStr]]} ->
- Fd = list_to_integer(FdStr),
- gen_udp:open(0, [{fd, Fd}|IpOpts]);
- error ->
- gen_udp:open(Port, IpOpts)
- end,
- case OpenRes of
+socket_open(IpPort, SocketOpts) ->
+ ?vtrace("socket_open -> entry with~n"
+ " IpPort: ~p~n"
+ " SocketOpts: ~p", [IpPort, SocketOpts]),
+ case gen_udp:open(IpPort, SocketOpts) of
{error, _} = Error ->
throw(Error);
- OK ->
- OK
+ {ok, Socket} ->
+ Socket
end.
-bind_to(true) ->
- case snmpm_config:system_info(address) of
- {ok, Addr} when is_list(Addr) ->
- [{ip, list_to_tuple(Addr)}];
- {ok, Addr} ->
- [{ip, Addr}];
+socket_params(Domain, {IpAddr, IpPort} = Addr, BindTo, CommonSocketOpts) ->
+ Family = snmp_conf:tdomain_to_family(Domain),
+ SocketOpts =
+ case Family of
+ inet6 ->
+ [Family, {ipv6_v6only, true} | CommonSocketOpts];
+ Family ->
+ [Family | CommonSocketOpts]
+ end,
+ case Family of
+ inet ->
+ case init:get_argument(snmp_fd) of
+ {ok, [[FdStr]]} ->
+ Fd = list_to_integer(FdStr),
+ case BindTo of
+ true ->
+ {IpPort, [{ip, IpAddr}, {fd, Fd} | SocketOpts]};
+ _ ->
+ {0, [{fd, Fd} | SocketOpts]}
+ end;
+ error ->
+ socket_params(SocketOpts, Addr, BindTo)
+ end;
_ ->
- []
- end;
-bind_to(_) ->
- [].
-
-no_reuse(false) ->
- [{reuseaddr, true}];
-no_reuse(_) ->
- [].
-
-recbuf(default) ->
- [];
-recbuf(Sz) ->
- [{recbuf, Sz}].
+ socket_params(SocketOpts, Addr, BindTo)
+ end.
+%%
+socket_params(SocketOpts, {IpAddr, IpPort}, BindTo) ->
+ case BindTo of
+ true ->
+ {IpPort, [{ip, IpAddr} | SocketOpts]};
+ _ ->
+ {IpPort, SocketOpts}
+ end.
-sndbuf(default) ->
- [];
-sndbuf(Sz) ->
- [{sndbuf, Sz}].
+common_socket_opts(Opts) ->
+ [binary
+ | case get_opt(Opts, sndbuf, default) of
+ default ->
+ [];
+ Sz ->
+ [{sndbuf, Sz}]
+ end ++
+ case get_opt(Opts, recbuf, default) of
+ default ->
+ [];
+ Sz ->
+ [{sndbuf, Sz}]
+ end ++
+ case get_opt(Opts, no_reuse, false) of
+ false ->
+ [{reuseaddr, true}];
+ _ ->
+ []
+ end].
create_filter(Opts) when is_list(Opts) ->
@@ -294,6 +388,10 @@ create_filter(BadOpts) ->
throw({error, {bad_filter_opts, BadOpts}}).
+%% ----------------------------------------------------------------------
+%% Audit Trail Logger
+%% ----------------------------------------------------------------------
+
%% Open log
do_init_log(false) ->
?vtrace("do_init_log(false) -> entry", []),
@@ -314,24 +412,69 @@ do_init_log(true) ->
Function = increment_counter,
Args = [atl_seqno, Initial, Max],
SeqNoGen = {Module, Function, Args},
- case snmp_log:create(Name, File,
- SeqNoGen, Size, Repair, true) of
+ case snmp_log:create(
+ Name, File, SeqNoGen, Size, Repair, true) of
{ok, Log} ->
?vdebug("log created: ~w", [Log]),
- {Log, Type};
+ {Name, Log, Type};
{error, Reason} ->
throw({error, {failed_create_audit_log, Reason}})
end;
_ ->
case snmp_log:create(Name, File, Size, Repair, true) of
{ok, Log} ->
- {Log, Type};
+ ?vdebug("log created: ~w", [Log]),
+ {Name, Log, Type};
{error, Reason} ->
throw({error, {failed_create_audit_log, Reason}})
end
end.
-
+-ifdef(snmpm_net_if_mt).
+do_reopen_log(undefined) ->
+ undefined;
+do_reopen_log({Name, Log, Type}) ->
+ case snmp_log:open(Name, Log) of
+ {ok, NewLog} ->
+ {Name, NewLog, Type};
+ {error, Reason} ->
+ warning_msg(
+ "NetIf worker ~p failed to open ATL:~n"
+ " ~p", [self(), Reason]),
+ undefined
+ end.
+-endif.
+
+%% Close log
+do_close_log(undefined) ->
+ ok;
+do_close_log({_Name, Log, _Type}) ->
+ (catch snmp_log:sync(Log)),
+ (catch snmp_log:close(Log)),
+ ok;
+do_close_log(_) ->
+ ok.
+
+%% Log
+logger(undefined, _Type, _Domain, _Addr) ->
+ fun(_) ->
+ ok
+ end;
+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, AddrString)
+ end;
+ false ->
+ fun(_) ->
+ ok
+ end
+ end.
+
+
%%--------------------------------------------------------------------
%% Func: handle_call/3
%% Returns: {reply, Reply, State} |
@@ -386,25 +529,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,10 +565,21 @@ 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) ->
- ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]),
- maybe_handle_recv_msg(Ip, Port, Bytes, State),
- {noreply, State};
+handle_info(
+ {udp, Socket, IpAddr, IpPort, Bytes},
+ #state{transports = Transports} = State) ->
+ Size = byte_size(Bytes),
+ case lists:keyfind(Socket, #transport.socket, Transports) of
+ #transport{socket = Socket, domain = Domain} ->
+ ?vlog("received ~w bytes from ~p:~p [~w]",
+ [Size, IpAddr, IpPort, Socket]),
+ maybe_handle_recv_msg(Domain, {IpAddr, IpPort}, Bytes, State),
+ {noreply, State};
+ false ->
+ warning_msg("Received ~w bytes on unknown port: ~p from ~s",
+ [Size, Socket, format_address({IpAddr, IpPort})]),
+ {noreply, State}
+ end;
handle_info(inform_response_gc, State) ->
?vlog("received inform_response_gc message", []),
@@ -439,11 +592,42 @@ handle_info({disk_log, _Node, Log, Info}, State) ->
State2 = handle_disk_log(Log, Info, State),
{noreply, State2};
+handle_info({'DOWN', _, _, _, _} = Info, State) ->
+ handle_info_down(Info, State);
+
handle_info(Info, State) ->
+ handle_info_unknown(Info, State).
+
+
+handle_info_unknown(Info, State) ->
warning_msg("received unknown info: ~n~p", [Info]),
{noreply, State}.
+-ifdef(snmpm_net_if_mt).
+handle_info_down(
+ {'DOWN', _MRef, process, _Pid,
+ {net_if_worker, _Result}},
+ State) ->
+ ?vdebug("received DOWN message from net_if worker [~w]: "
+ "~n Result: ~p", [_Pid, _Result]),
+ {noreply, State};
+handle_info_down(
+ {'DOWN', _MRef, process, Pid,
+ {net_if_worker, Failer, Class, Reason, Stacktrace} = _ExitStatus},
+ State) ->
+ ?vdebug("received DOWN message from net_if worker [~w]: "
+ "~n ExitStatus: ~p", [Pid, _ExitStatus]),
+ Failer(Pid, Class, Reason, Stacktrace),
+ {noreply, State};
+handle_info_down(Info, State) ->
+ handle_info_unknown(Info, State).
+-else.
+handle_info_down(Info, State) ->
+ handle_info_unknown(Info, State).
+-endif.
+
+
%%--------------------------------------------------------------------
%% Func: terminate/2
%% Purpose: Shutdown the server
@@ -457,68 +641,12 @@ terminate(Reason, #state{log = Log, irgc = IrGcRef}) ->
ok.
-do_close_log({Log, _Type}) ->
- (catch snmp_log:sync(Log)),
- (catch snmp_log:close(Log)),
- ok;
-do_close_log(_) ->
- ok.
-
-
%%----------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState}
%%----------------------------------------------------------------------
-code_change({down, _Vsn}, OldState, downgrade_to_pre_4_14) ->
- ?d("code_change(down, downgrade_to_pre_4_14) -> entry with"
- "~n OldState: ~p", [OldState]),
- #state{server = Server,
- note_store = NoteStore,
- sock = Sock,
- mpd_state = MpdState,
- log = {OldLog, Type},
- irb = IRB,
- irgc = IRGC} = OldState,
- NewLog = snmp_log:downgrade(OldLog),
- State =
- {state, Server, NoteStore, Sock, MpdState, {NewLog, Type}, IRB, IRGC},
- {ok, State};
-
-code_change({down, _Vsn}, OldState, downgrade_to_pre_4_16) ->
- ?d("code_change(down, downgrade_to_pre_4_16) -> entry with"
- "~n OldState: ~p", [OldState]),
- {OldLog, Type} = OldState#state.log,
- NewLog = snmp_log:downgrade(OldLog),
- State = OldState#state{log = {NewLog, Type}},
- {ok, State};
-
-% upgrade
-code_change(_Vsn, OldState, upgrade_from_pre_4_14) ->
- ?d("code_change(up, upgrade_from_pre_4_14) -> entry with"
- "~n OldState: ~p", [OldState]),
- {state, Server, NoteStore, Sock, MpdState, {OldLog, Type}, IRB, IRGC} =
- OldState,
- NewLog = snmp_log:upgrade(OldLog),
- State = #state{server = Server,
- note_store = NoteStore,
- sock = Sock,
- mpd_state = MpdState,
- log = {NewLog, Type},
- irb = IRB,
- irgc = IRGC,
- filter = ?DEFAULT_FILTER_MODULE},
- {ok, State};
-
-code_change(_Vsn, OldState, upgrade_from_pre_4_16) ->
- ?d("code_change(up, upgrade_from_pre_4_16) -> entry with"
- "~n OldState: ~p", [OldState]),
- {OldLog, Type} = OldState#state.log,
- NewLog = snmp_log:upgrade(OldLog),
- State = OldState#state{log = {NewLog, Type}},
- {ok, State};
-
code_change(_Vsn, State, _Extra) ->
?d("code_change -> entry with"
"~n Vsn: ~p"
@@ -531,139 +659,155 @@ 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) ->
+ ?worker(
+ S, maybe_handle_recv_msg_mt(Domain, Addr, Bytes, S),
+ fun (Pid, Class, Reason, Stacktrace) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (incomming) message from %s:~n"
+ "~w:~w at ~p",
+ [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
+ Class, Reason, Stacktrace])
+ end,
+ State).
+
+maybe_handle_recv_msg_mt(
+ Domain, Addr, Bytes,
+ #state{filter = FilterMod, transports = Transports} = State) ->
+ {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
+ case (catch FilterMod:accept_recv(Arg1, Arg2)) of
false ->
%% Drop the received packet
- inc(netIfMsgInDrops),
- ok;
+ inc(netIfMsgInDrops);
_ ->
- handle_recv_msg(Addr, Port, Bytes, State)
- end.
+ handle_recv_msg(Domain, Addr, Bytes, State)
+ end,
+ ok.
-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},
- 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,
- MpdState, NoteStore, Logger)) of
+ Pid ! {snmp_error, {empty_message, Domain, Addr}, Domain, Addr};
+%%
+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,
- Logger, State);
+ 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),
- ok;
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr},
+ maybe_udp_send(Domain, Addr, Report, State);
{discarded, Reason} ->
?vdebug("discarded: ~p", [Reason]),
ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Addr, Port},
- ok;
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr};
Error ->
error_msg("processing of received message failed: "
- "~n ~p", [Error]),
- ok
+ "~n ~p", [Error])
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, transports = Transports} = State) ->
+ {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
+ case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of
false ->
- inc(netIfPduInDrops),
- ok;
+ inc(netIfPduInDrops);
_ ->
- 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, transports = Transports} = State)
when is_record(Trap, trappdu) ->
- case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of
+ {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
+ case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of
false ->
- inc(netIfPduInDrops),
- ok;
+ inc(netIfPduInDrops);
_ ->
- 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,40 +820,57 @@ 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) ->
+ ?worker(
+ S, handle_inform_response_mt(Ref, Domain, Addr, S),
+ fun (Pid, Class, Reason, Stacktrace) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (outgoing) inform response for %s:~n"
+ "~w:~w at ~p",
+ [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
+ Class, Reason, Stacktrace])
+ end,
+ State).
+
+handle_inform_response_mt(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,
+ transports = Transports} = State) ->
+ {Arg1, Arg2} = fix_filter_address(Transports, {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},
- ok
+ Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr}
end
end.
@@ -742,64 +903,99 @@ irgc_stop(undefined) ->
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) ->
+ ?worker(
+ S, maybe_handle_send_pdu_mt(Pdu, Vsn, MsgData, Domain, Addr, S),
+ fun (Pid, Class, Reason, Stacktrace) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (outgoing) pdu for %s:~n"
+ "~w:~w at ~p",
+ [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
+ Class, Reason, Stacktrace])
+ end,
+ State).
+
+maybe_handle_send_pdu_mt(
+ Pdu, Vsn, MsgData, Domain, Addr,
+ #state{filter = FilterMod, transports = Transports} = State) ->
+ {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
+ case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of
false ->
- inc(netIfPduOutDrops),
- ok;
+ inc(netIfPduOutDrops);
_ ->
- handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State)
- end.
+ handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State)
+ end,
+ ok.
-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"
"~n Reason: ~p", [Pdu, Reason]),
- Pid ! {snmp_error, Pdu, Reason},
- ok
+ Pid ! {snmp_error, Pdu, Reason}
end.
-maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) ->
- case (catch FilterMod:accept_send(Addr, Port)) of
+maybe_udp_send(
+ Domain, Addr, Msg,
+ #state{filter = FilterMod, transports = Transports}) ->
+ To = {Domain, Addr},
+ {Arg1, Arg2} = fix_filter_address(Transports, To),
+ case (catch FilterMod:accept_send(Arg1, Arg2)) of
false ->
inc(netIfMsgOutDrops),
ok;
_ ->
- udp_send(Sock, Addr, Port, Msg)
+ case select_transport_from_domain(Domain, Transports) of
+ false ->
+ error_msg(
+ "Can not find transport~n"
+ " size: ~p~n"
+ " to: ~s",
+ [sz(Msg), format_address(To)]);
+ #transport{socket = Socket} ->
+ udp_send(Socket, Addr, Msg)
+ end
end.
-
-
-udp_send(Sock, Addr, Port, Msg) ->
- case (catch gen_udp:send(Sock, Addr, Port, Msg)) of
+
+udp_send(Sock, To, Msg) ->
+ {IpAddr, IpPort} =
+ case To of
+ {Domain, Addr} when is_atom(Domain) ->
+ Addr;
+ {_, P} = Addr when is_integer(P) ->
+ Addr
+ end,
+ try gen_udp:send(Sock, IpAddr, IpPort, Msg) of
ok ->
?vdebug("sent ~w bytes to ~w:~w [~w]",
- [sz(Msg), Addr, Port, Sock]),
+ [sz(Msg), IpAddr, IpPort, Sock]),
ok;
{error, Reason} ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Reason]);
- Error ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Error])
+ error_msg("failed sending message to ~p:~p:~n"
+ " ~p",[IpAddr, IpPort, Reason])
+ catch
+ error:Error ->
+ error_msg("failed sending message to ~p:~p:~n"
+ " error:~p~n"
+ " ~p",
+ [IpAddr, IpPort, Error, erlang:get_stacktrace()])
end.
sz(B) when is_binary(B) ->
- size(B);
+ byte_size(B);
sz(L) when is_list(L) ->
length(L);
sz(_) ->
@@ -989,6 +1185,45 @@ handle_set_log_type(State, _NewType) ->
{State, {error, not_enabled}}.
+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.
+
+%% 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(Transports, Address) ->
+ DefaultDomain = snmpm_config:default_transport_domain(),
+ case Transports of
+ [#transport{domain = DefaultDomain}, DefaultDomain] ->
+ case Address of
+ {Domain, Addr} when is_atom(Domain) ->
+ Addr;
+ {_, IpPort} = Addr when is_integer(IpPort) ->
+ Addr
+ end;
+ _ ->
+ Address
+ end.
+
+address(Domain, Addr) when is_atom(Domain) ->
+ {Domain, Addr};
+address(Ip, Port) when is_integer(Port) ->
+ {snmpm_config:default_transport_domain(), {Ip, Port}}.
+
+format_address(Address) ->
+ iolist_to_binary(snmp_conf:mk_addr_string(Address)).
+
%% -------------------------------------------------------------------
make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) ->
@@ -1029,25 +1264,6 @@ t() ->
%% -------------------------------------------------------------------
-logger(undefined, _Type, _Addr, _Port) ->
- fun(_) ->
- ok
- end;
-logger({Log, Types}, Type, Addr, Port) ->
- case lists:member(Type, Types) of
- true ->
- fun(Msg) ->
- snmp_log:log(Log, Msg, Addr, Port)
- end;
- false ->
- fun(_) ->
- ok
- end
- end.
-
-
-%% -------------------------------------------------------------------
-
%% info_msg(F, A) ->
%% ?snmpm_info("NET-IF server: " ++ F, A).
@@ -1072,10 +1288,11 @@ get_opt(Opts, Key, Def) ->
%% -------------------------------------------------------------------
-get_info(#state{sock = Id}) ->
+get_info(#state{transports = Transports}) ->
ProcSize = proc_mem(self()),
- PortInfo = get_port_info(Id),
- [{process_memory, ProcSize}, {port_info, PortInfo}].
+ [{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
@@ -1190,4 +1407,3 @@ call(Pid, Req, Timeout) ->
cast(Pid, Msg) ->
gen_server:cast(Pid, Msg).
-
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..62f6023657 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
@@ -17,1243 +17,7 @@
%% %CopyrightEnd%
%%
--module(snmpm_net_if_mt).
-
--behaviour(gen_server).
--behaviour(snmpm_network_interface).
-
-
-%% Network Interface callback functions
--export([
- start_link/2,
- stop/1,
- send_pdu/6, % Backward compatibillity
- send_pdu/7, % Backward compatibillity
- send_pdu/8,
-
- inform_response/4,
-
- note_store/2,
-
- info/1,
- verbosity/2,
- %% system_info_updated/2,
- get_log_type/1, set_log_type/2,
- filter_reset/1
- ]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- code_change/3, terminate/2]).
-
--define(SNMP_USE_V3, true).
--include("snmp_types.hrl").
--include("snmpm_internal.hrl").
--include("snmpm_atl.hrl").
--include("snmp_debug.hrl").
-
-%% -define(VMODULE,"NET_IF").
--include("snmp_verbosity.hrl").
-
--record(state,
- {
- server,
- note_store,
- sock,
- mpd_state,
- log,
- irb = auto, % auto | {user, integer()}
- irgc,
- filter
- }).
-
-
--define(DEFAULT_FILTER_MODULE, snmpm_net_if_filter).
--define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]).
-
--ifdef(snmp_debug).
--define(GS_START_LINK(Args),
- gen_server:start_link(?MODULE, Args, [{debug,[trace]}])).
--else.
--define(GS_START_LINK(Args),
- gen_server:start_link(?MODULE, Args, [])).
--endif.
-
-
--define(IRGC_TIMEOUT, timer:minutes(5)).
-
--define(ATL_SEQNO_INITIAL, 1).
--define(ATL_SEQNO_MAX, 2147483647).
-
-
-%%%-------------------------------------------------------------------
-%%% API
-%%%-------------------------------------------------------------------
-start_link(Server, NoteStore) ->
- ?d("start_link -> entry with"
- "~n Server: ~p"
- "~n NoteStore: ~p", [Server, NoteStore]),
- Args = [Server, NoteStore],
- ?GS_START_LINK(Args).
-
-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, 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)
- 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}).
-
-note_store(Pid, NoteStore) ->
- call(Pid, {note_store, NoteStore}).
-
-inform_response(Pid, Ref, Addr, Port) ->
- cast(Pid, {inform_response, Ref, Addr, Port}).
-
-info(Pid) ->
- call(Pid, info).
-
-verbosity(Pid, V) ->
- call(Pid, {verbosity, V}).
-
-%% system_info_updated(Pid, What) ->
-%% call(Pid, {system_info_updated, What}).
-
-get_log_type(Pid) ->
- call(Pid, get_log_type).
-
-set_log_type(Pid, NewType) ->
- call(Pid, {set_log_type, NewType}).
-
-filter_reset(Pid) ->
- cast(Pid, filter_reset).
-
-
-%%%-------------------------------------------------------------------
-%%% Callback functions from gen_server
-%%%-------------------------------------------------------------------
-
-%%--------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%%--------------------------------------------------------------------
-init([Server, NoteStore]) ->
- ?d("init -> entry with"
- "~n Server: ~p"
- "~n NoteStore: ~p", [Server, NoteStore]),
- case (catch do_init(Server, NoteStore)) of
- {error, Reason} ->
- {stop, Reason};
- {ok, State} ->
- {ok, State}
- end.
-
-do_init(Server, NoteStore) ->
- process_flag(trap_exit, true),
-
- %% -- Prio --
- {ok, Prio} = snmpm_config:system_info(prio),
- process_flag(priority, Prio),
-
- %% -- Create inform request table --
- %% This should really be protected, but it also needs to
- %% be writable for the worker processes, so...
- ets:new(snmpm_inform_request_table,
- [set, public, named_table, {keypos, 1}]),
-
- %% -- Verbosity --
- {ok, Verbosity} = snmpm_config:system_info(net_if_verbosity),
- put(sname, mnif),
- put(verbosity, Verbosity),
- ?vlog("starting", []),
-
- %% -- MPD --
- {ok, Vsns} = snmpm_config:system_info(versions),
- MpdState = snmpm_mpd:init(Vsns),
- ?vdebug("MpdState: ~w", [MpdState]),
-
- %% -- Module dependent options --
- {ok, Opts} = snmpm_config:system_info(net_if_options),
-
- %% -- Inform response behaviour --
- {ok, IRB} = snmpm_config:system_info(net_if_irb),
- IrGcRef = irgc_start(IRB),
-
- %% -- Socket --
- SndBuf = get_opt(Opts, sndbuf, default),
- RecBuf = get_opt(Opts, recbuf, default),
- 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),
-
- %% Flow control --
- FilterOpts = get_opt(Opts, filter, []),
- FilterMod = create_filter(FilterOpts),
- ?vdebug("FilterMod: ~w", [FilterMod]),
-
- %% -- Audit trail log ---
- {ok, ATL} = snmpm_config:system_info(audit_trail_log),
- Log = do_init_log(ATL),
- ?vdebug("Log: ~w", [Log]),
-
- %% -- Initiate counters ---
- init_counters(),
-
- %% -- We are done ---
- State = #state{server = Server,
- note_store = NoteStore,
- mpd_state = MpdState,
- sock = Sock,
- log = Log,
- irb = IRB,
- irgc = IrGcRef,
- filter = FilterMod},
- ?vdebug("started", []),
- {ok, State}.
-
-
-%% 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]),
- IpOpts1 = bind_to(BindTo),
- IpOpts2 = no_reuse(NoReuse),
- IpOpts3 = recbuf(RecvSz),
- IpOpts4 = sndbuf(SendSz),
- IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
- OpenRes =
- case init:get_argument(snmpm_fd) of
- {ok, [[FdStr]]} ->
- Fd = list_to_integer(FdStr),
- gen_udp:open(0, [{fd, Fd}|IpOpts]);
- error ->
- gen_udp:open(Port, IpOpts)
- end,
- case OpenRes of
- {error, _} = Error ->
- throw(Error);
- OK ->
- OK
- end.
-
-bind_to(true) ->
- case snmpm_config:system_info(address) of
- {ok, Addr} when is_list(Addr) ->
- [{ip, list_to_tuple(Addr)}];
- {ok, Addr} ->
- [{ip, Addr}];
- _ ->
- []
- end;
-bind_to(_) ->
- [].
-
-no_reuse(false) ->
- [{reuseaddr, true}];
-no_reuse(_) ->
- [].
-
-recbuf(default) ->
- [];
-recbuf(Sz) ->
- [{recbuf, Sz}].
-
-sndbuf(default) ->
- [];
-sndbuf(Sz) ->
- [{sndbuf, Sz}].
-
-
-create_filter(Opts) when is_list(Opts) ->
- case get_opt(Opts, module, ?DEFAULT_FILTER_MODULE) of
- ?DEFAULT_FILTER_MODULE = Mod ->
- Mod;
- Module ->
- snmpm_network_interface_filter:verify(Module),
- Module
- end;
-create_filter(BadOpts) ->
- throw({error, {bad_filter_opts, BadOpts}}).
-
-
-%% ----------------------------------------------------------------------
-%% Audit Trail Logger
-%% ----------------------------------------------------------------------
-
-%% Open log
-do_init_log(false) ->
- ?vtrace("do_init_log(false) -> entry", []),
- undefined;
-do_init_log(true) ->
- ?vtrace("do_init_log(true) -> entry", []),
- {ok, Type} = snmpm_config:system_info(audit_trail_log_type),
- {ok, Dir} = snmpm_config:system_info(audit_trail_log_dir),
- {ok, Size} = snmpm_config:system_info(audit_trail_log_size),
- {ok, Repair} = snmpm_config:system_info(audit_trail_log_repair),
- Name = ?audit_trail_log_name,
- File = filename:absname(?audit_trail_log_file, Dir),
- case snmpm_config:system_info(audit_trail_log_seqno) of
- {ok, true} ->
- Initial = ?ATL_SEQNO_INITIAL,
- Max = ?ATL_SEQNO_MAX,
- Module = snmpm_config,
- Function = increment_counter,
- Args = [atl_seqno, Initial, Max],
- SeqNoGen = {Module, Function, Args},
- case snmp_log:create(Name, File, SeqNoGen, Size, Repair, true) of
- {ok, Log} ->
- ?vdebug("log created: ~w", [Log]),
- {Name, Log, Type};
- {error, Reason} ->
- throw({error, {failed_create_audit_log, Reason}})
- end;
- _ ->
- case snmp_log:create(Name, File, Size, Repair, true) of
- {ok, Log} ->
- ?vdebug("log created: ~w", [Log]),
- {Name, Log, Type};
- {error, Reason} ->
- throw({error, {failed_create_audit_log, Reason}})
- end
- end.
-
-
-%% ----------------------------------------------------------------------
-
-%%--------------------------------------------------------------------
-%% Func: handle_call/3
-%% Returns: {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} | (terminate/2 is called)
-%% {stop, Reason, State} (terminate/2 is called)
-%%--------------------------------------------------------------------
-handle_call({verbosity, Verbosity}, _From, State) ->
- ?vlog("received verbosity request", []),
- put(verbosity, Verbosity),
- {reply, ok, State};
-
-%% handle_call({system_info_updated, What}, _From, State) ->
-%% ?vlog("received system_info_updated request with What = ~p", [What]),
-%% {NewState, Reply} = handle_system_info_updated(State, What),
-%% {reply, Reply, NewState};
-
-handle_call(get_log_type, _From, State) ->
- ?vlog("received get-log-type request", []),
- Reply = (catch handle_get_log_type(State)),
- {reply, Reply, State};
-
-handle_call({set_log_type, NewType}, _From, State) ->
- ?vlog("received set-log-type request with NewType = ~p", [NewType]),
- {NewState, Reply} = (catch handle_set_log_type(State, NewType)),
- {reply, Reply, NewState};
-
-handle_call({note_store, Pid}, _From, State) ->
- ?vlog("received new note_store: ~w", [Pid]),
- {reply, ok, State#state{note_store = Pid}};
-
-handle_call(stop, _From, State) ->
- ?vlog("received stop request", []),
- Reply = ok,
- {stop, normal, Reply, State};
-
-handle_call(info, _From, State) ->
- ?vlog("received info request", []),
- Reply = get_info(State),
- {reply, Reply, State};
-
-handle_call(Req, From, State) ->
- warning_msg("received unknown request (from ~p): ~n~p", [Req, From]),
- {reply, {error, {invalid_request, Req}}, State}.
-
-
-%%--------------------------------------------------------------------
-%% Func: handle_cast/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%--------------------------------------------------------------------
-handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, 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),
- {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),
- {noreply, State};
-
-handle_cast(filter_reset, State) ->
- ?vlog("received filter_reset message", []),
- reset_counters(),
- {noreply, State};
-
-handle_cast(Msg, State) ->
- warning_msg("received unknown message: ~n~p", [Msg]),
- {noreply, State}.
-
-
-%%--------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%--------------------------------------------------------------------
-handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) ->
- ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]),
- handle_udp(Ip, Port, Bytes, State),
- {noreply, State};
-
-handle_info(inform_response_gc, State) ->
- ?vlog("received inform_response_gc message", []),
- State2 = handle_inform_response_gc(State),
- {noreply, State2};
-
-handle_info({disk_log, _Node, Log, Info}, State) ->
- ?vlog("received disk_log message: "
- "~n Info: ~p", [Info]),
- State2 = handle_disk_log(Log, Info, State),
- {noreply, State2};
-
-handle_info({'DOWN', _MRef, process, Pid, {net_if_worker, ExitStatus}},
- State) ->
- ?vdebug("received DOWN message from net_if-worker: "
- "~n ExitStatus: ~p", [ExitStatus]),
- handle_worker_exit(Pid, ExitStatus),
- {noreply, State};
-
-handle_info(Info, State) ->
- warning_msg("received unknown info: ~n~p", [Info]),
- {noreply, State}.
-
-
-%%--------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any (ignored by gen_server)
-%%--------------------------------------------------------------------
-terminate(Reason, #state{log = Log, irgc = IrGcRef}) ->
- ?vdebug("terminate: ~p", [Reason]),
- irgc_stop(IrGcRef),
- %% Close logs
- do_close_log(Log),
- ok.
-
-
-do_close_log({Log, _Type}) ->
- (catch snmp_log:sync(Log)),
- (catch snmp_log:close(Log)),
- ok;
-do_close_log(_) ->
- ok.
-
-
-%%----------------------------------------------------------------------
-%% Func: code_change/3
-%% Purpose: Convert process state when code is changed
-%% Returns: {ok, NewState}
-%%----------------------------------------------------------------------
-
-code_change(_Vsn, State, _Extra) ->
- ?d("code_change -> entry with"
- "~n Vsn: ~p"
- "~n State: ~p"
- "~n Extra: ~p", [_Vsn, State, _Extra]),
- {ok, State}.
-
-
-%%%-------------------------------------------------------------------
-%%% 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
- false ->
- %% Drop the received packet
- inc(netIfMsgInDrops),
- ok;
- _ ->
- handle_recv_msg(Addr, Port, Bytes, State)
- end.
-
-
-handle_recv_msg(Addr, Port, Bytes, #state{server = Pid})
- when is_binary(Bytes) andalso (size(Bytes) =:= 0) ->
- Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port},
- 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,
- MpdState, NoteStore, Logger)) of
-
- {ok, Vsn, Pdu, MS, ACM} ->
- maybe_handle_recv_pdu(Addr, Port, 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),
- ok;
-
- {discarded, Reason} ->
- ?vdebug("discarded: ~p", [Reason]),
- ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Addr, Port},
- ok;
-
- Error ->
- error_msg("processing of received message failed: "
- "~n ~p", [Error]),
- ok
- 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
- false ->
- inc(netIfPduInDrops),
- ok;
- _ ->
- handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State)
- end;
-maybe_handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger,
- #state{filter = FilterMod} = State)
- when is_record(Trap, trappdu) ->
- case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of
- false ->
- inc(netIfPduInDrops),
- ok;
- _ ->
- handle_recv_pdu(Addr, Port, 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) ->
- ?vtrace("received report - ok", []),
- Pid ! {snmp_report, {ok, Pdu}, Addr, Port},
- ok;
-handle_recv_pdu(Addr, Port,
- _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},
- ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) ->
- ?vtrace("received snmpv2-trap", []),
- Pid ! {snmp_trap, Pdu, Addr, Port},
- ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, Trap, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) when is_record(Trap, trappdu) ->
- ?vtrace("received trappdu", []),
- Pid ! {snmp_trap, Trap, Addr, Port},
- ok;
-handle_recv_pdu(Addr, Port,
- _Vsn, Pdu, _PduMS, _ACM,
- _Logger,
- #state{server = Pid} = _State) when is_record(Pdu, pdu) ->
- ?vtrace("received pdu", []),
- Pid ! {snmp_pdu, Pdu, Addr, Port},
- ok;
-handle_recv_pdu(_Addr, _Port, _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) ->
- ?vtrace("received inform-request (true)", []),
- Pid ! {snmp_inform, ignore, Pdu, Addr, Port},
- 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) ->
- ?vtrace("received inform-request (false)", []),
-
- Pid ! {snmp_inform, ReqId, Pdu, Addr, Port},
-
- %% Before we go any further, we need to check that we have not
- %% already received this message (possible resend).
-
- Key = {ReqId, Addr, Port},
- case ets:lookup(snmpm_inform_request_table, Key) of
- [_] ->
- %% OK, we already know about this. We assume this
- %% is a resend. Either the agent is really eager or
- %% the user has not answered yet. Bad user!
- ok;
- [] ->
- RePdu = make_response_pdu(Pdu),
- Expire = t() + To,
- Rec = {Key, Expire, {Vsn, ACM, RePdu}},
- 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]).
-
-
-
-do_handle_inform_response(Ref, Addr, Port, State) ->
- Key = {Ref, Addr, Port},
- case ets:lookup(snmpm_inform_request_table, Key) of
- [{Key, _, {Vsn, ACM, RePdu}}] ->
- Logger = logger(State#state.log, read, Addr, Port),
- ets:delete(snmpm_inform_request_table, Key),
- maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port,
- 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
- 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);
- {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},
- ok
- end
- end.
-
-handle_inform_response_gc(#state{irb = IRB} = State) ->
- ets:safe_fixtable(snmpm_inform_request_table, true),
- do_irgc(ets:first(snmpm_inform_request_table), t()),
- ets:safe_fixtable(snmpm_inform_request_table, false),
- State#state{irgc = irgc_start(IRB)}.
-
-%% We are deleting at the same time as we are traversing the table!!!
-do_irgc('$end_of_table', _) ->
- ok;
-do_irgc(Key, Now) ->
- Next = ets:next(snmpm_inform_request_table, Key),
- case ets:lookup(snmpm_inform_request_table, Key) of
- [{Key, BestBefore, _}] when BestBefore < Now ->
- ets:delete(snmpm_inform_request_table, Key);
- _ ->
- ok
- end,
- do_irgc(Next, Now).
-
-irgc_start(auto) ->
- undefined;
-irgc_start(_) ->
- erlang:send_after(?IRGC_TIMEOUT, self(), inform_response_gc).
-
-irgc_stop(undefined) ->
- ok;
-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
- false ->
- inc(netIfPduOutDrops),
- ok;
- _ ->
- do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, 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
- {ok, Msg} ->
- ?vtrace("do_handle_send_pdu -> message generated", []),
- maybe_udp_send(FilterMod, Sock, Addr, Port, Msg);
- {discarded, Reason} ->
- ?vlog("PDU not sent: "
- "~n PDU: ~p"
- "~n Reason: ~p", [Pdu, Reason]),
- Pid ! {snmp_error, Pdu, Reason},
- ok
- end.
-
-
-maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) ->
- case (catch FilterMod:accept_send(Addr, Port)) of
- false ->
- inc(netIfMsgOutDrops),
- ok;
- _ ->
- udp_send(Sock, Addr, Port, Msg)
- end.
-
-
-udp_send(Sock, Addr, Port, Msg) ->
- case (catch gen_udp:send(Sock, Addr, Port, Msg)) of
- ok ->
- ?vdebug("sent ~w bytes to ~w:~w [~w]",
- [sz(Msg), Addr, Port, Sock]),
- ok;
- {error, Reason} ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Reason]),
- ok;
- Error ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Addr, Port, Error]),
- ok
- end.
-
-sz(B) when is_binary(B) ->
- size(B);
-sz(L) when is_list(L) ->
- length(L);
-sz(_) ->
- undefined.
-
-
-handle_disk_log(_Log, {wrap, NoLostItems}, State) ->
- ?vlog("Audit Trail Log - wrapped: ~w previously logged items where lost",
- [NoLostItems]),
- State;
-handle_disk_log(_Log, {truncated, NoLostItems}, State) ->
- ?vlog("Audit Trail Log - truncated: ~w items where lost when truncating",
- [NoLostItems]),
- State;
-handle_disk_log(_Log, full, State) ->
- error_msg("Failed to write to Audit Trail Log (full)", []),
- State;
-handle_disk_log(_Log, {error_status, ok}, State) ->
- State;
-handle_disk_log(_Log, {error_status, {error, Reason}}, State) ->
- error_msg("Error status received from Audit Trail Log: "
- "~n~p", [Reason]),
- State;
-handle_disk_log(_Log, _Info, State) ->
- State.
-
-
-%% mk_discovery_msg('version-3', Pdu, _VsnHdr, UserName) ->
-%% ScopedPDU = #scopedPdu{contextEngineID = "",
-%% contextName = "",
-%% data = Pdu},
-%% Bytes = snmp_pdus:enc_scoped_pdu(ScopedPDU),
-%% MsgID = get(msg_id),
-%% put(msg_id,MsgID+1),
-%% UsmSecParams =
-%% #usmSecurityParameters{msgAuthoritativeEngineID = "",
-%% msgAuthoritativeEngineBoots = 0,
-%% msgAuthoritativeEngineTime = 0,
-%% msgUserName = UserName,
-%% msgPrivacyParameters = "",
-%% msgAuthenticationParameters = ""},
-%% SecBytes = snmp_pdus:enc_usm_security_parameters(UsmSecParams),
-%% PduType = Pdu#pdu.type,
-%% Hdr = #v3_hdr{msgID = MsgID,
-%% msgMaxSize = 1000,
-%% msgFlags = snmp_misc:mk_msg_flags(PduType, 0),
-%% msgSecurityModel = ?SEC_USM,
-%% msgSecurityParameters = SecBytes},
-%% Msg = #message{version = 'version-3', vsn_hdr = Hdr, data = Bytes},
-%% case (catch snmp_pdus:enc_message_only(Msg)) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% L when list(L) ->
-%% {Msg, L}
-%% end;
-%% mk_discovery_msg(Version, Pdu, {Com, _, _, _, _}, UserName) ->
-%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu},
-%% case catch snmp_pdus:enc_message(Msg) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% L when list(L) ->
-%% {Msg, L}
-%% end.
-
-
-%% mk_msg('version-3', Pdu, {Context, User, EngineID, CtxEngineId, SecLevel},
-%% MsgData) ->
-%% %% Code copied from snmp_mpd.erl
-%% {MsgId, SecName, SecData} =
-%% if
-%% tuple(MsgData), Pdu#pdu.type == 'get-response' ->
-%% MsgData;
-%% true ->
-%% Md = get(msg_id),
-%% put(msg_id, Md + 1),
-%% {Md, User, []}
-%% end,
-%% ScopedPDU = #scopedPdu{contextEngineID = CtxEngineId,
-%% contextName = Context,
-%% data = Pdu},
-%% ScopedPDUBytes = snmp_pdus:enc_scoped_pdu(ScopedPDU),
-
-%% PduType = Pdu#pdu.type,
-%% V3Hdr = #v3_hdr{msgID = MsgId,
-%% msgMaxSize = 1000,
-%% msgFlags = snmp_misc:mk_msg_flags(PduType, SecLevel),
-%% msgSecurityModel = ?SEC_USM},
-%% Message = #message{version = 'version-3', vsn_hdr = V3Hdr,
-%% data = ScopedPDUBytes},
-%% SecEngineID = case PduType of
-%% 'get-response' -> snmp_framework_mib:get_engine_id();
-%% _ -> EngineID
-%% end,
-%% case catch snmp_usm:generate_outgoing_msg(Message, SecEngineID,
-%% SecName, SecData, SecLevel) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% {error, Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% Packet ->
-%% Packet
-%% end;
-%% mk_msg(Version, Pdu, {Com, _User, _EngineID, _Ctx, _SecLevel}, _SecData) ->
-%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu},
-%% case catch snmp_pdus:enc_message(Msg) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% B when list(B) ->
-%% B
-%% end.
-
-
-%% handle_system_info_updated(#state{log = {Log, _OldType}} = State,
-%% audit_trail_log_type = _What) ->
-%% %% Just to make sure, check that ATL is actually enabled
-%% case snmpm_config:system_info(audit_trail_log) of
-%% {ok, true} ->
-%% {ok, Type} = snmpm_config:system_info(audit_trail_log_type),
-%% NewState = State#state{log = {Log, Type}},
-%% {NewState, ok};
-%% _ ->
-%% {State, {error, {adt_not_enabled}}}
-%% end;
-%% handle_system_info_updated(_State, _What) ->
-%% ok.
-
-handle_get_log_type(#state{log = {_Log, Value}} = State) ->
- %% Just to make sure, check that ATL is actually enabled
- case snmpm_config:system_info(audit_trail_log) of
- {ok, true} ->
- Type =
- case {lists:member(read, Value), lists:member(write, Value)} of
- {true, true} ->
- read_write;
- {true, false} ->
- read;
- {false, true} ->
- write;
- {false, false} ->
- throw({State, {error, {bad_atl_type, Value}}})
- end,
- {ok, Type};
- _ ->
- {error, not_enabled}
- end;
-handle_get_log_type(_State) ->
- {error, not_enabled}.
-
-handle_set_log_type(#state{log = {Log, OldValue}} = State, NewType) ->
- %% Just to make sure, check that ATL is actually enabled
- case snmpm_config:system_info(audit_trail_log) of
- {ok, true} ->
- NewValue =
- case NewType of
- read ->
- [read];
- write ->
- [write];
- read_write ->
- [read,write];
- _ ->
- throw({State, {error, {bad_atl_type, NewType}}})
- end,
- NewState = State#state{log = {Log, NewValue}},
- OldType =
- case {lists:member(read, OldValue),
- lists:member(write, OldValue)} of
- {true, true} ->
- read_write;
- {true, false} ->
- read;
- {false, true} ->
- write;
- {false, false} ->
- throw({State, {error, {bad_atl_type, OldValue}}})
- end,
- {NewState, {ok, OldType}};
- _ ->
- {State, {error, not_enabled}}
- end;
-handle_set_log_type(State, _NewType) ->
- {State, {error, not_enabled}}.
-
-
-%% -------------------------------------------------------------------
-
-worker_init(#state{log = undefined = Log}, Verbosity) ->
- worker_init2(Log, Verbosity);
-worker_init(#state{log = {Name, Log, Type}}, Verbosity) ->
- case snmp_log:open(Name, Log) of
- {ok, NewLog} ->
- worker_init2({Name, NewLog, Type}, Verbosity);
- {error, Reason} ->
- warning_msg("NetIf worker ~p failed opening ATL: "
- "~n ~p", [self(), Reason]),
- NewLog = undefined,
- worker_init2({Name, NewLog, Type}, Verbosity)
- end;
-worker_init(State, Verbosity) ->
- ?vinfo("worker_init -> entry with invalid data: "
- "~n State: ~p"
- "~n Verbosity: ~p", [State, Verbosity]),
- exit({worker_init, State, Verbosity}).
-
-worker_init2(Log, Verbosity) ->
- put(sname, mnifw),
- put(verbosity, Verbosity),
- Log.
-
-
-worker_exit(Tag, Info, Result) ->
- exit({net_if_worker, {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]),
- 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]),
- 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]),
- ok;
-handle_worker_exit(_, _) ->
- ok.
-
-
-%% -------------------------------------------------------------------
-
-make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) ->
- #pdu{type = 'get-response',
- request_id = ReqId,
- error_status = noError,
- error_index = 0,
- varbinds = Vbs}.
-
-
-%% ----------------------------------------------------------------
-
-pdu_type_of(#pdu{type = Type}) ->
- Type;
-pdu_type_of(TrapPdu) when is_record(TrapPdu, trappdu) ->
- trap.
-
-
-%% -------------------------------------------------------------------
-
-%% At this point this function is used during testing
-maybe_process_extra_info(?DEFAULT_EXTRA_INFO) ->
- ok;
-maybe_process_extra_info({?SNMPM_EXTRA_INFO_TAG, Fun})
- when is_function(Fun, 0) ->
- (catch Fun()),
- ok;
-maybe_process_extra_info(_ExtraInfo) ->
- ok.
-
-
-%% -------------------------------------------------------------------
-
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-
-%% -------------------------------------------------------------------
-
-logger(undefined, _Type, _Addr, _Port) ->
- fun(_) ->
- ok
- end;
-logger({_Name, Log, Types}, Type, Addr, Port) ->
- case lists:member(Type, Types) of
- true ->
- fun(Msg) ->
- snmp_log:log(Log, Msg, Addr, Port)
- end;
- false ->
- fun(_) ->
- ok
- end
- end.
-
-
-%% -------------------------------------------------------------------
-
-%% info_msg(F, A) ->
-%% ?snmpm_info("NET-IF server: " ++ F, A).
-
-warning_msg(F, A) ->
- ?snmpm_warning("NET-IF server: " ++ F, A).
-
-error_msg(F, A) ->
- ?snmpm_error("NET-IF server: " ++ F, A).
-
-
-
-%%%-------------------------------------------------------------------
-
-% get_opt(Key, Opts) ->
-% ?vtrace("get option ~w", [Key]),
-% snmp_misc:get_option(Key, Opts).
-
-get_opt(Opts, Key, Def) ->
- ?vtrace("get option ~w with default ~p", [Key, Def]),
- snmp_misc:get_option(Key, Opts, Def).
-
-
-%% -------------------------------------------------------------------
-
-get_info(#state{sock = Id}) ->
- ProcSize = proc_mem(self()),
- PortInfo = get_port_info(Id),
- [{process_memory, ProcSize}, {port_info, PortInfo}].
-
-proc_mem(P) when is_pid(P) ->
- case (catch erlang:process_info(P, memory)) of
- {memory, Sz} when is_integer(Sz) ->
- Sz;
- _ ->
- undefined
- end.
-%% proc_mem(_) ->
-%% undefined.
-
-
-get_port_info(Id) ->
- PortInfo =
- case (catch erlang:port_info(Id)) of
- PI when is_list(PI) ->
- [{port_info, PI}];
- _ ->
- []
- end,
- PortStatus =
- case (catch prim_inet:getstatus(Id)) of
- {ok, PS} ->
- [{port_status, PS}];
- _ ->
- []
- end,
- PortAct =
- case (catch inet:getopts(Id, [active])) of
- {ok, PA} ->
- [{port_act, PA}];
- _ ->
- []
- end,
- PortStats =
- case (catch inet:getstat(Id)) of
- {ok, Stat} ->
- [{port_stats, Stat}];
- _ ->
- []
- end,
- IfList =
- case (catch inet:getif(Id)) of
- {ok, IFs} ->
- [{interfaces, IFs}];
- _ ->
- []
- end,
- BufSz =
- case (catch inet:getopts(Id, [recbuf, sndbuf, buffer])) of
- {ok, Sz} ->
- [{buffer_size, Sz}];
- _ ->
- []
- end,
- [{socket, Id}] ++
- IfList ++
- PortStats ++
- PortInfo ++
- PortStatus ++
- PortAct ++
- BufSz.
-
-
-%%-----------------------------------------------------------------
-%% Counter functions
-%%-----------------------------------------------------------------
-init_counters() ->
- F = fun(Counter) -> maybe_create_counter(Counter) end,
- lists:map(F, counters()).
-
-reset_counters() ->
- F = fun(Counter) -> snmpm_config:reset_stats_counter(Counter) end,
- lists:map(F, counters()).
-
-maybe_create_counter(Counter) ->
- snmpm_config:maybe_cre_stats_counter(Counter, 0).
-
-counters() ->
- [
- netIfMsgOutDrops,
- netIfMsgInDrops,
- netIfPduOutDrops,
- netIfPduInDrops
- ].
-
-inc(Name) -> inc(Name, 1).
-inc(Name, N) -> snmpm_config:incr_stats_counter(Name, N).
-
-%% get_counters() ->
-%% Counters = counters(),
-%% get_counters(Counters, []).
-
-%% get_counters([], Acc) ->
-%% lists:reverse(Acc);
-%% get_counters([Counter|Counters], Acc) ->
-%% case snmpm_config:get_stats_counter(Counter) of
-%% {ok, CounterVal} ->
-%% get_counters(Counters, [{Counter, CounterVal}|Acc]);
-%% _ ->
-%% get_counters(Counters, Acc)
-%% end.
-
-
-%% ----------------------------------------------------------------
-
-call(Pid, Req) ->
- call(Pid, Req, infinity).
-
-call(Pid, Req, Timeout) ->
- gen_server:call(Pid, Req, Timeout).
-
-cast(Pid, Msg) ->
- gen_server:cast(Pid, Msg).
+-define(snmpm_net_if_mt, true).
+-module(snmpm_net_if_mt).
+-include("snmpm_net_if.erl").
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 9c79df2748..a75122d0bb 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,56 @@ 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
+ {Domain_or_Ip, Addr_or_Port} =
+ case Domain of
+ snmpUDPDomain ->
+ Addr;
+ _ ->
+ {Domain, Addr}
+ end,
+ try DefMod:handle_agent(
+ Domain_or_Ip, Addr_or_Port, 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 +2107,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 +2116,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 +2151,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 +2181,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 +2230,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 +2286,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 +2360,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 +2370,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 +2381,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 +2399,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 +2428,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 +2462,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 +2482,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 +2490,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 +2538,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 +2551,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 +2563,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 +2582,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 +2609,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 +2619,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 +2656,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 +2669,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 +2677,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 +2688,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 +2696,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 +2722,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 +2780,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 +2804,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 +2812,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 +2822,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 +2860,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 +2872,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 +2902,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 +3053,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 +3331,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 +3479,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..153c8070c2 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,359 @@ 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({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({_IP, Port} = Addr) when is_integer(Port) ->
+ mk_addr_string({snmpUDPDomain, Addr});
+mk_addr_string(Strange) ->
+ lists:flatten(io_lib:format("~w", [Strange])).
+
+
+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..17dfcd70b4 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,24 +26,29 @@
-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,
write_agent_snmp_vacm_conf/3,
write_manager_snmp_files/8,
- write_manager_snmp_conf/5,
- write_manager_snmp_users_conf/2,
+ write_manager_snmp_conf/4, write_manager_snmp_conf/5,
+ write_manager_snmp_users_conf/2,
write_manager_snmp_agents_conf/2,
write_manager_snmp_usm_conf/2
@@ -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,40 @@ 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);
+write_agent_snmp_conf(_Dir, Domain, AgentAddr, _EngineID, _MMS) ->
+ error({bad_address, {Domain, AgentAddr}}).
+
+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 +1695,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 +1801,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 +1832,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).
@@ -2037,7 +2118,24 @@ write_manager_snmp_files(Dir, IP, Port, MMS, EngineID,
%% ------ manager.conf ------
%%
-write_manager_snmp_conf(Dir, IP, Port, MMS, EngineID) ->
+write_manager_snmp_conf(Dir, Transports, MMS, EngineID) ->
+ Comment =
+"%% This file defines the Manager local configuration info\n"
+"%% Each row is a 2-tuple:\n"
+"%% {Variable, Value}.\n"
+"%% For example\n"
+"%% {transports, [{transportDomainUdpIpv4, {{127,42,17,5}, 5000}}]}.\n"
+"%% {engine_id, \"managerEngine\"}.\n"
+"%% {max_message_size, 484}.\n"
+"%%\n\n",
+ Hdr = header() ++ Comment,
+ Conf =
+ [{transports, Transports},
+ {engine_id, EngineID},
+ {max_message_size, MMS}],
+ write_manager_config(Dir, Hdr, Conf).
+
+write_manager_snmp_conf(Dir, Domain_or_IP, Addr_or_Port, MMS, EngineID) ->
Comment =
"%% This file defines the Manager local configuration info\n"
"%% Each row is a 2-tuple:\n"
@@ -2049,10 +2147,20 @@ 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 Addr_or_Port of
+ {IP, Port} when is_integer(Port), is_atom(Domain_or_IP) ->
+ [{domain, Domain_or_IP},
+ {port, Port},
+ {address, IP}];
+ _ when is_integer(Addr_or_Port) ->
+ [{port, Addr_or_Port},
+ {address, Domain_or_IP}];
+ _ ->
+ error({bad_address, {Domain_or_IP, Addr_or_Port}})
+ end ++
+ [{engine_id, EngineID},
+ {max_message_size, MMS}],
write_manager_config(Dir, Hdr, Conf).
write_manager_config(Dir, Hdr, Conf) ->
@@ -2410,83 +2518,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 +2613,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.
+
+%% 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).
+
+
-do_read_config_file(Dir, FileName, Verify) ->
+-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 +2788,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..b4770ad0a9 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()},
@@ -529,6 +532,7 @@ groups() ->
{v3_inform, [], v3_inform_cases()},
{v3_security, [], v3_security_cases()},
{standard_mibs, [], standard_mibs_cases()},
+ {standard_mibs_ipv6, [], standard_mibs_cases_ipv6()},
{standard_mibs_2, [], standard_mibs2_cases()},
{standard_mibs_3, [], standard_mibs3_cases()},
{reported_bugs, [], reported_bugs_cases()},
@@ -611,6 +615,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 +649,25 @@ 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 ->
+ case gen_udp:open(0, [inet6]) of
+ {ok, S} ->
+ ok = gen_udp:close(S),
+ Init(
+ snmp_test_lib:init_group_top_dir(
+ GroupName,
+ [{ipfamily, inet6},
+ {ip, ?LOCALHOST(inet6)}
+ | lists:keydelete(ip, 1, Config)]));
+ {error, _} ->
+ {skip, "Host seems to not support IPv6"}
+ end;
+ _ ->
+ {skip, "Host does not support IPV6"}
+ end.
+
end_per_group(all_tcs, Config) ->
finish_all(Config);
end_per_group(otp7157, Config) ->
@@ -655,31 +686,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, Config) ->
+end_per_group(test_v1_v2_ipv6, Config) ->
finish_v1_v2(Config);
-end_per_group(test_v2, Config) ->
+end_per_group(test_v2_ipv6, Config) ->
finish_v2(Config);
-end_per_group(test_v1, Config) ->
+end_per_group(test_v1_ipv6, Config) ->
finish_v1(Config);
-end_per_group(misc, Config) ->
+end_per_group(test_v3, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1, Config) ->
+ finish_v1(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 +849,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 +908,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 +1679,7 @@ del_dir(Dir, Depth) ->
ok
end.
-%v1_cases() -> [loop_mib];
+%v1_cases() -> [loop_mib_1];
v1_cases() ->
[
simple,
@@ -1644,7 +1687,7 @@ v1_cases() ->
v1_processing,
big,
big2,
- loop_mib_1,
+ loop_mib_1,
api,
subagent,
mnesia,
@@ -1662,14 +1705,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_ipv6},
+ 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 +1775,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 +1830,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 +1870,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 +1919,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(),
@@ -4710,6 +4844,15 @@ standard_mibs_cases() ->
snmp_view_based_acm_mib
].
+standard_mibs_cases_ipv6() ->
+ [
+ %% snmp_standard_mib, % Sending v1 traps does not work over IPv6
+ snmp_community_mib,
+ snmp_framework_mib,
+ snmp_target_mib,
+ snmp_notification_mib,
+ snmp_view_based_acm_mib
+ ].
%%-----------------------------------------------------------------
%% For this test, the agent is configured for v1.
@@ -5546,7 +5689,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 +5697,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 +6521,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 +6673,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 +6691,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 +6700,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 +6780,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 +6808,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 +6873,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 +7169,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 +7416,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..f37e957dae 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(),
%% --
@@ -1047,7 +1048,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
case config_start(Opts) of
{error, Reason51} ->
p("start failed (as expected): ~p", [Reason51]),
- ?line {failed_check, _, _, _, {bad_address, _}} = Reason51,
+ ?line {failed_check, _, _, _, {bad_domain, _}} = Reason51,
await_config_not_running();
OK_51 ->
exit({error, {unexpected_success, "51", OK_51}})
@@ -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..fa90872172 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,39 @@ 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 ->
+ case gen_udp:open(0, [inet6]) of
+ {ok, S} ->
+ ok = gen_udp:close(S),
+ ipv6_init(
+ snmp_test_lib:init_group_top_dir(
+ GroupName,
+ [{manager_net_if_module, snmpm_net_if_mt}
+ | Config]));
+ {error, _} ->
+ {skip, "Host seems to not support IPv6"}
+ end;
+ _ ->
+ {skip, "Host does not support IPV6"}
+ end;
+init_per_group(ipv6 = GroupName, Config) ->
+ case ct:require(ipv6_hosts) of
+ ok ->
+ case gen_udp:open(0, [inet6]) of
+ {ok, S} ->
+ ok = gen_udp:close(S),
+ ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config));
+ {error, _} ->
+ {skip, "Host seems to not support IPv6"}
+ end;
+ _ ->
+ {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 +1562,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 +5128,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 +5804,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 +5846,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 +6260,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 +6298,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 +6386,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 +6512,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_manager_user.erl b/lib/snmp/test/snmp_manager_user.erl
index ddbe156130..46c2b316be 100644
--- a/lib/snmp/test/snmp_manager_user.erl
+++ b/lib/snmp/test/snmp_manager_user.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
@@ -109,7 +109,18 @@ start_link(Parent, Id) ->
proc_lib:start_link(?MODULE, main, [true, Parent, self(), Id]).
stop() ->
- cast(stop).
+ MRef = erlang:monitor(process, ?SERVER),
+ cast(stop),
+ receive {'DOWN', MRef, _, _, Info} ->
+ case Info of
+ noproc ->
+ ok;
+ noconnection ->
+ ok;
+ normal ->
+ ok
+ end
+ end.
info() ->
call(info).
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..8cb6ec588e 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
@@ -161,7 +161,7 @@ get_timeout() ->
get_timeout(os:type())
end.
-get_timeout(_) -> 3500.
+get_timeout(_) -> 10000. % Trying to improve test results % 3500.
%%----------------------------------------------------------------------
%% Receives a trap from the agent.
@@ -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..2f96493ac5
--- /dev/null
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
@@ -0,0 +1,559 @@
+%%
+%% %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)
+%% snmpd From packet 'snmpd' (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(MANAGER_ENGINE_ID, "ErlangSnmpManager").
+-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, snmpget},
+ {group, snmptrapd},
+ {group, snmpd_mt},
+ {group, snmpd}
+ ]},
+ {ipv6, [],
+ [{group, snmpget},
+ {group, snmptrapd},
+ {group, snmpd_mt},
+ {group, snmpd}
+ ]},
+ {ipv4_ipv6, [],
+ [{group, snmpget},
+ {group, snmptrapd},
+ {group, snmpd_mt},
+ {group, snmpd}
+ ]},
+ %%
+ {snmpget, [],
+ [erlang_agent_netsnmp_get]},
+ {snmptrapd, [],
+ [erlang_agent_netsnmp_inform]},
+ {snmpd_mt, [],
+ [erlang_manager_netsnmp_get]},
+ {snmpd, [],
+ [erlang_manager_netsnmp_get]}
+ ].
+
+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(snmpget = Exec, Config) ->
+ %% From Ubuntu package snmp
+ init_per_group_agent(Exec, Config);
+init_per_group(snmptrapd = Exec, Config) ->
+ %% From Ubuntu package snmpd
+ init_per_group_agent(Exec, Config);
+init_per_group(snmpd_mt, Config) ->
+ %% From Ubuntu package snmp
+ init_per_group_manager(
+ snmpd,
+ [{manager_net_if_module, snmpm_net_if_mt} | Config]);
+init_per_group(snmpd = Exec, Config) ->
+ %% From Ubuntu package snmp
+ init_per_group_manager(
+ Exec,
+ [{manager_net_if_module, snmpm_net_if} | Config]);
+%%
+init_per_group(_, Config) ->
+ Config.
+
+init_per_group_ipv6(Families, Config) ->
+ case ct:require(ipv6_hosts) of
+ ok ->
+ case gen_udp:open(0, [inet6]) of
+ {ok, S} ->
+ ok = gen_udp:close(S),
+ init_per_group_ip(Families, Config);
+ {error, _} ->
+ {skip, "Host seems to not support IPv6"}
+ end;
+ _ ->
+ {skip, "Test config ipv6_hosts is missing"}
+ end.
+
+init_per_group_ip(Families, Config) ->
+ AgentPort = ?config(agent_port, Config),
+ ManagerPort = ?config(manager_port, Config),
+ {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],
+ [{transports, Transports}, {targets, Targets} | Config].
+
+init_per_group_agent(Exec, Config) ->
+ Versions = [v2],
+ Dir = ?config(priv_dir, Config),
+ Transports = ?config(transports, Config),
+ Targets = ?config(targets, Config),
+ agent_config(Dir, Transports, Targets, Versions),
+ find_executable(Exec, [{snmp_versions, Versions} | Config]).
+
+init_per_group_manager(Exec, Config) ->
+ Versions = [v2],
+ Dir = ?config(priv_dir, Config),
+ Targets = ?config(targets, Config),
+ manager_config(Dir, Targets),
+ find_executable(Exec, [{snmp_versions, Versions} | Config]).
+
+
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ct:timetrap(20000),
+ 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, agent_app_env(Config)),
+ ok = application:start(snmp).
+
+start_manager(Config) ->
+ ok = application:load(snmp),
+ ok = application:set_env(snmp, manager, manager_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_manager_netsnmp_get() ->
+ [{doc,"Test that the erlang snmp manager can access snmpnet agent"}].
+
+erlang_manager_netsnmp_get(Config) when is_list(Config) ->
+ Community = "happy-testing",
+ SysDescr = "Net-SNMP agent",
+ TargetName = "Target Net-SNMP agent",
+ Transports = ?config(transports, Config),
+ ProgHandle = start_snmpd(Community, SysDescr, Config),
+ start_manager(Config),
+ snmp_manager_user:start_link(self(), test_user),
+ [snmp_manager_user:register_agent(
+ TargetName++domain_suffix(Domain),
+ [{reg_type, target_name},
+ {tdomain, Domain}, {taddress, Addr},
+ {community, Community}, {engine_id, "EngineId"},
+ {version, v2}, {sec_model, v2c}, {sec_level, noAuthNoPriv}])
+ || {Domain, Addr} <- Transports],
+ Results =
+ [snmp_manager_user:sync_get(
+ TargetName++domain_suffix(Domain),
+ [?sysDescr_instance])
+ || {Domain, _} <- Transports],
+ ct:pal("sync_get -> ~p", [Results]),
+ snmp_manager_user:stop(),
+ stop_program(ProgHandle),
+ [{ok,
+ {noError, 0,
+ [{varbind, ?sysDescr_instance, 'OCTET STRING', SysDescr,1}] },
+ _} = R || R <- Results],
+ 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_snmpd(Community, SysDescr, Config) ->
+ DataDir = ?config(data_dir, Config),
+ Targets = ?config(targets, Config),
+ Transports = ?config(transports, Config),
+ Port = mk_port_number(),
+ CommunityArgs =
+ ["--rocommunity"++domain_suffix(Domain)++"="
+ ++Community++" "++inet_parse:ntoa(Ip)
+ || {Domain, {Ip, _}} <- Targets],
+ SnmpdArgs =
+ ["-f", "-r", %"-Dverbose",
+ "-c", filename:join(DataDir, "snmpd.conf"),
+ "-C", "-Lo",
+ "-m", "",
+ "--sysDescr="++SysDescr,
+ "--agentXSocket=tcp:localhost:"++integer_to_list(Port)]
+ ++ CommunityArgs
+ ++ [net_snmp_addr_str(Transports)],
+ {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]),
+ start_program(snmpd, SnmpdArgs, StartCheckMP, Config).
+
+start_program(Prog, Args, StartCheckMP, Config) ->
+ ct:pal("Starting program: ~w ~p", [Prog, Args]),
+ 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) ->
+ [Prog | _] = ProgAndArgs,
+ Port =
+ open_port(
+ {spawn_executable, StartWrapper},
+ [{args, ProgAndArgs}, binary, stderr_to_stdout, {line, 80},
+ exit_status]),
+ ct:pal("Prog ~p started: ~p", [Port, Prog]),
+ 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.
+
+
+agent_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}]}].
+
+manager_app_env(Config) ->
+ Dir = ?config(priv_dir, Config),
+ Vsns = ?config(snmp_versions, Config),
+ NetIfModule = ?config(manager_net_if_module, Config),
+ [{versions, Vsns},
+ {audit_trail_log, [{type, read_write},
+ {dir, Dir},
+ {size, {10240, 10}}]},
+ {net_if, [{module, NetIfModule}]},
+ {config, [{dir, Dir},
+ {db_dir, Dir},
+ {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, 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).
+
+manager_config(Dir, Targets) ->
+ EngineID = ?MANAGER_ENGINE_ID,
+ MMS = ?DEFAULT_MAX_MESSAGE_SIZE,
+ ok = snmp_config:write_manager_snmp_conf(Dir, Targets, MMS, EngineID).
+
+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).
+
+domain_suffix(transportDomainUdpIpv4) ->
+ "";
+domain_suffix(transportDomainUdpIpv6) ->
+ "6".
+
+mk_port_number() ->
+ {ok, Socket} = gen_udp:open(0, [{reuseaddr, true}]),
+ {ok, PortNum} = inet:port(Socket),
+ ok = gen_udp:close(Socket),
+ PortNum.
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/snmpd.conf b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/snmpd.conf
new file mode 100644
index 0000000000..2a5f31680f
--- /dev/null
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/snmpd.conf
@@ -0,0 +1,12 @@
+sysLocation On the lab network
+sysContact otptest <[email protected]>
+
+createUser myinternaluser SHA dropdead
+
+agentSecName myinternaluser
+
+master agentx
+
+[snmp]
+noPersistentLoad yes
+noPersistentSave yes
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..345cc790f2 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.1.1
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..3aa61aa9ec 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -29,6 +29,310 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure the clean rule for ssh, ssl, eunit and otp_mibs
+ actually removes generated files.</p>
+ <p>
+ Own Id: OTP-12200</p>
+ </item>
+ <item>
+ <p>
+ Improved Property Tests (Thanks to Thomas, John and
+ Tobias at QuviQ)</p>
+ <p>
+ Own Id: OTP-12256</p>
+ </item>
+ <item>
+ <p>
+ Correct typo of renegotiate that could cause rekeying to
+ fail</p>
+ <p>
+ Own Id: OTP-12277 Aux Id: seq12736 </p>
+ </item>
+ <item>
+ <p>
+ The {timeout, Timeout} option passed to
+ ssh_sftp:start_channel was not applied to the early
+ phases of the SSH protocol. This patch passes the Timeout
+ through to ssh:connect. In case the timeout occurs during
+ these phases, {error, timeout} is returned. (Thanks to
+ Simon Cornish)</p>
+ <p>
+ Own Id: OTP-12306</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added API functions ptty_alloc/3 and ptty_alloc/4, to
+ allocate a pseudo tty.</p>
+ <p>
+ Own Id: OTP-11542 Aux Id: seq12493, OTP-11631 </p>
+ </item>
+ <item>
+ <p>
+ Supports tar file creation on other media than file
+ systems mounted on the local machine.</p>
+ <p>
+ The <c>erl_tar</c> api is extended with
+ <c>erl_tar:init/3</c> that enables usage of user provided
+ media storage routines. A ssh-specific set of such
+ routines is hidden in the new function
+ <c>ssh_sftp:open_tar/3</c> to simplify creating a tar
+ archive on a remote ssh server.</p>
+ <p>
+ A chunked file reading option is added to
+ <c>erl_tar:add/3,4</c> to save memory on e.g small
+ embedded systems. The size of the slices read from a file
+ in that case can be specified.</p>
+ <p>
+ Own Id: OTP-12180 Aux Id: seq12715 </p>
+ </item>
+ <item>
+ <p>
+ Always send SSH_DISCONNECT protocol messages when peer
+ sends corrupt messages.</p>
+ <p>
+ Own Id: OTP-12185</p>
+ </item>
+ <item>
+ <p>
+ Hooks for funs that can change binaries sent to remote
+ sites from erl_tar for renote tar file creation are
+ added. See <c>ssh_sftp:open_tar/3,4</c> for details. The
+ hooks could also be used to read remote tar files that
+ need transformation before file extraction.</p>
+ <p>
+ Those hooks are intended for encryption and decryption of
+ tar files. Effort is put into memory, disk and network
+ resource economy.</p>
+ <p>
+ Own Id: OTP-12312 Aux Id: OTP-12180 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 3.0.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixes of login blocking after port scanning.</p>
+ <p>
+ Own Id: OTP-12247 Aux Id: seq12726 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 3.0.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add option sftp_vsn to SFTP</p>
+ <p>
+ Own Id: OTP-12227</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix option user_interaction to work as expected. When
+ password authentication is implemented with ssh
+ keyboard-interactive method and the password is already
+ supplied, so that we do not need to query user, then
+ connections should succeed even though user_interaction
+ option is set to false.</p>
+ <p>
+ Own Id: OTP-11329 Aux Id: seq12420, seq12335 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 3.0.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Gracefully handle bad data from the client when expecting
+ ssh version exchange.</p>
+ <p>
+ Own Id: OTP-12157 Aux Id: seq12706 </p>
+ </item>
+ <item>
+ <p>
+ When restarting an ssh daemon, that was stopped with
+ ssh:stop_listner/ [1,2] new options given shall replace
+ old ones.</p>
+ <p>
+ Own Id: OTP-12168 Aux Id: seq12711 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ ssh now has a format_status function to avoid printing
+ sensitive information in error loggs.</p>
+ <p>
+ Own Id: OTP-12030</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ The option <c>parallel_login</c> didn't work with the
+ value <c>true</c>. All logins were serial.</p>
+ <p>
+ Own Id: OTP-12194</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 3.0.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When starting an ssh-daemon giving the option
+ {parallel_login, true}, the timeout for authentication
+ negotiation ({negotiation_timeout, integer()}) was never
+ removed.</p>
+ <p>
+ This caused the session to always be terminated after the
+ timeout if parallel_login was set.</p>
+ <p>
+ Own Id: OTP-12057 Aux Id: seq12663 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Warning: this is experimental and may disappear or change
+ without previous warning.</p>
+ <p>
+ Experimental support for running Quickcheck and PropEr
+ tests from common_test suites is added to common_test.
+ See the reference manual for the new module
+ <c>ct_property_testing</c>.</p>
+ <p>
+ Experimental property tests are added under
+ <c>lib/{inet,ssh}/test/property_test</c>. They can be run
+ directly or from the commont_test suites
+ <c>inet/ftp_property_test_SUITE.erl</c> and
+ <c>ssh/test/ssh_property_test_SUITE.erl</c>.</p>
+ <p>
+ See the code in the <c>test</c> directories and the man
+ page for details.</p>
+ <p>
+ (Thanks to Tuncer Ayaz for a patch adding Triq)</p>
+ <p>
+ Own Id: OTP-12119</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 3.0.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When starting an ssh-daemon giving the option
+ {parallel_login, true}, the timeout for authentication
+ negotiation ({negotiation_timeout, integer()}) was never
+ removed.</p>
+ <p>
+ This caused the session to always be terminated after the
+ timeout if parallel_login was set.</p>
+ <p>
+ Own Id: OTP-12057 Aux Id: seq12663 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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..d481a75c9a 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>
@@ -36,8 +36,8 @@
<list type="bulleted">
<item>SSH requires the crypto and public_key applications.</item>
<item>Supported SSH version is 2.0 </item>
- <item>Supported MAC algorithms: hmac-sha1</item>
- <item>Supported encryption algorithms: aes128-cb and 3des-cbc</item>
+ <item>Supported MAC algorithms: hmac-sha2-256 and hmac-sha1</item>
+ <item>Supported encryption algorithms: aes128-ctr, aes128-cb and 3des-cbc</item>
<item>Supports unicode filenames if the emulator and the underlaying OS supports it. See the DESCRIPTION section in <seealso marker="kernel:file">file</seealso> for information about this subject</item>
<item>Supports unicode in shell and cli</item>
</list>
@@ -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,11 +232,13 @@
port.</p>
<p>Options are:</p>
<taglist>
- <tag><c><![CDATA[{subsystems, [subsystem_spec()]]]></c></tag>
+ <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
"sftp" subsystem spec can be retrieved by calling
- ssh_sftpd:subsystem_spec/1. If the subsystems option in
+ ssh_sftpd:subsystem_spec/1. If the subsystems option is
not present the value of
<c>[ssh_sftpd:subsystem_spec([])]</c> will be used. It is
of course possible to set the option to the empty list if
diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml
index 72e7252536..5e2926dfa6 100644
--- a/lib/ssh/doc/src/ssh_connection.xml
+++ b/lib/ssh/doc/src/ssh_connection.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2013</year>
+ <year>2014</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -62,6 +62,7 @@
<p><c>ssh_request_status() = success | failure</c></p>
<p><c>event() = {ssh_cm, ssh_connection_ref(), ssh_event_msg()} </c></p>
<p><c>ssh_event_msg() = data_events() | status_events() | terminal_events() </c></p>
+ <p><c>reason() = timeout | closed </c></p>
<taglist>
<tag><b>data_events()</b></tag>
@@ -137,7 +138,7 @@
<tag><c><![CDATA[{pty, ssh_channel_id(),
boolean() = WantReply, {string() = Terminal, integer() = CharWidth,
- integer() = RowHeight, integer() = PixelWidth, integer() = PixelHight,
+ integer() = RowHeight, integer() = PixelWidth, integer() = PixelHeight,
[{atom() | integer() = Opcode,
integer() = Value}] = TerminalModes}}]]></c></tag>
<item>A pseudo-terminal has been requested for the
@@ -148,11 +149,11 @@
drawable area of the window. The <c>Opcode</c> in the
<c>TerminalModes</c> list is the mnemonic name, represented
as an lowercase erlang atom, defined in
- <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 8,
- or the opcode if the mnemonic name is not listed in the
+ <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 8.
+ It may also be an opcode if the mnemonic name is not listed in the
RFC. Example <c>OP code: 53, mnemonic name ECHO erlang atom:
- echo</c>. There is currently no API function to generate this
- event.</item>
+ echo</c>.This event is sent as result of calling <seealso
+ marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso></item>
<tag><c><![CDATA[{shell, boolean() = WantReply}]]></c></tag>
<item> This message will request that the user's default shell
@@ -218,7 +219,7 @@
</func>
<func>
- <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() </name>
+ <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() | {error, reason()} </name>
<fsummary>Request that the server start the execution of the given command. </fsummary>
<type>
<v> ConnectionRef = ssh_connection_ref() </v>
@@ -273,7 +274,53 @@
</desc>
</func>
- <func>
+ <func>
+ <name>ptty_alloc(ConnectionRef, ChannelId, Options) -> </name>
+ <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() | {error, reason()} </name>
+ <fsummary>Send status replies to requests that want such replies. </fsummary>
+ <type>
+ <v> ConnectionRef = ssh_connection_ref() </v>
+ <v> ChannelId = ssh_channel_id()</v>
+ <v> Options = proplists:proplist()</v>
+ </type>
+ <desc>
+ <p> Sends a SSH Connection Protocol pty_req, to allocate a pseudo tty.
+ Should be called by a SSH client process.
+ Options are:
+ </p>
+
+ <taglist>
+ <tag>{term, string()}</tag>
+ <item>
+ Defaults to os:getenv("TERM") or "vt100" if it is undefined.
+ </item>
+ <tag>{width, integer()}</tag>
+ <item>
+ Defaults to 80 if pixel_width is not defined.
+ </item>
+ <tag>{height, integer()}</tag>
+ <item>
+ Defaults to 24 if pixel_height is not defined.
+ </item>
+ <tag>{pixel_width, integer()}</tag>
+ <item>
+ Is disregarded if width is defined.
+ </item>
+ <tag>{pixel_height, integer()}</tag>
+ <item>
+ Is disregarded if height is defined.
+ </item>
+ <tag>{pty_opts, [{posix_atom(), integer()}]}</tag>
+ <item>
+ Option may be an empty list, otherwise
+ see possible POSIX names in section 8 in <url href="http://www.ietf.org/rfc/rfc4254.txt"> RFC 4254</url>.
+ </item>
+ </taglist>
+
+ </desc>
+ </func>
+
+ <func>
<name>reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name>
<fsummary>Send status replies to requests that want such replies. </fsummary>
<type>
@@ -329,7 +376,7 @@
<func>
<name>session_channel(ConnectionRef, Timeout) -> </name>
<name>session_channel(ConnectionRef, InitialWindowSize,
- MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, Reason}</name>
+ MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, reason()}</name>
<fsummary>Opens a channel for a ssh session. </fsummary>
<type>
<v> ConnectionRef = ssh_connection_ref()</v>
@@ -346,7 +393,7 @@
</func>
<func>
- <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status()</name>
+ <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() | {error, reason()} </name>
<fsummary> Environment variables may be passed to the
shell/command to be started later.</fsummary>
<type>
@@ -364,7 +411,7 @@
</func>
<func>
- <name>shell(ConnectionRef, ChannelId) -> ssh_request_status()
+ <name>shell(ConnectionRef, ChannelId) -> ssh_request_status() | {error, closed}
</name>
<fsummary> Requests that the user's default shell (typically
defined in /etc/passwd in UNIX systems) shall be executed at the server
@@ -381,7 +428,7 @@
</func>
<func>
- <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status()</name>
+ <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() | {error, reason()} </name>
<fsummary> </fsummary>
<type>
<v> ConnectionRef = ssh_connection_ref() </v>
diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml
index e55d092fe2..ab111562f9 100644
--- a/lib/ssh/doc/src/ssh_sftp.xml
+++ b/lib/ssh/doc/src/ssh_sftp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2013</year>
+ <year>2005</year><year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -81,6 +81,17 @@
<p>The timeout is passed to the ssh_channel start function,
and defaults to infinity.</p>
</item>
+ <tag>
+ <p><c><![CDATA[{sftp_vsn, integer()}]]></c></p>
+ </tag>
+ <item>
+ <p>
+ Desired SFTP protocol version.
+ The actual version will be the minimum of
+ the desired version and the maximum supported
+ versions by the SFTP server.
+ </p>
+ </item>
</taglist>
<p>All other options are directly passed to
<seealso marker="ssh">ssh:connect/3</seealso> or ignored if a
@@ -183,6 +194,118 @@
can be used for reading directory contents.</p>
</desc>
</func>
+
+ <func>
+ <name>open_tar(ChannelPid, Path, Mode) -></name>
+ <name>open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, Reason}</name>
+ <fsummary>Opens a tar file on the server to which <v>ChannelPid</v> is connected and returns a handle</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Path = string()</v>
+ <v>Mode = [read] | [write] | [read,EncryptOpt] | [write,DecryptOpt] </v>
+ <v>EncryptOpt = {crypto,{InitFun,EncryptFun,CloseFun}}</v>
+ <v>DecryptOpt = {crypto,{InitFun,DecryptFun}}</v>
+ <v>InitFun = (fun() -> {ok,CryptoState}) | (fun() -> {ok,CryptoState,ChunkSize}) </v>
+ <v>CryptoState = any()</v>
+ <v>ChunkSize = undefined | pos_integer()</v>
+ <v>EncryptFun = (fun(PlainBin,CryptoState) -> EncryptResult)</v>
+ <v>EncryptResult = {ok,EncryptedBin,CryptoState} | {ok,EncryptedBin,CryptoState,ChunkSize}</v>
+ <v>PlainBin = binary()</v>
+ <v>EncryptedBin = binary()</v>
+ <v>DecryptFun = (fun(EncryptedBin,CryptoState) -> DecryptResult)</v>
+ <v>DecryptResult = {ok,PlainBin,CryptoState} | {ok,PlainBin,CryptoState,ChunkSize}</v>
+ <v>CloseFun = (fun(PlainBin,CryptoState) -> {ok,EncryptedBin})</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Opens a handle to a tar file on the server associated with <c>ChannelPid</c>. The handle
+ can be used for remote tar creation and extraction as defined by the
+ <seealso marker="stdlib:erl_tar#init/3">erl_tar:init/3</seealso> function.
+ </p>
+ <p>An example of writing and then reading a tar file:</p>
+ <code type="none">
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ...
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:close(HandleWrite),
+
+ %% And for reading
+ {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]),
+ {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
+ ok = erl_tar:close(HandleRead),
+ </code>
+
+ <p>The <c>crypto</c> mode option is applied to the generated stream of bytes just prior to sending
+ them to the sftp server. This is intended for encryption but could of course be used for other
+ purposes.
+ </p>
+ <p>The <c>InitFun</c> is applied once
+ prior to any other crypto operation. The returned <c>CryptoState</c> is then folded into
+ repeated applications of the <c>EncryptFun</c> or <c>DecryptFun</c>. The binary returned
+ from those Funs are sent further to the remote sftp server. Finally - if doing encryption
+ - the <c>CloseFun</c> is applied to the last piece of data. The <c>CloseFun</c> is
+ responsible for padding (if needed) and encryption of that last piece.
+ </p>
+ <p>The <c>ChunkSize</c> defines the size of the <c>PlainBin</c>s that <c>EncodeFun</c> is applied
+ to. If the <c>ChunkSize</c> is <c>undefined</c> the size of the <c>PlainBin</c>s varies because
+ this is inteded for stream crypto while a fixed <c>ChunkSize</c> is intended for block crypto. It
+ is possible to change the <c>ChunkSize</c>s in the return from the <c>EncryptFun</c> or
+ <c>DecryptFun</c>. It is in fact possible to change the value between <c>pos_integer()</c> and
+ <c>undefined</c>.
+ </p>
+ <p>The write and read example above can be extended with encryption and decryption:</p>
+ <code type="none">
+ %% First three parameters depending on which crypto type we select:
+ Key = &lt;&lt;"This is a 256 bit key. abcdefghi">>,
+ Ivec0 = crypto:rand_bytes(16),
+ DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc
+
+ %% Initialization of the CryptoState, in this case it is the Ivector.
+ InitFun = fun() -> {ok, Ivec0, DataSize} end,
+
+ %% How to encrypt:
+ EncryptFun =
+ fun(PlainBin,Ivec) ->
+ EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
+ {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
+ end,
+
+ %% What to do with the very last block:
+ CloseFun =
+ fun(PlainBin, Ivec) ->
+ EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
+ pad(16,PlainBin) %% Last chunk
+ ),
+ {ok, EncryptedBin}
+ end,
+
+ Cw = {InitFun,EncryptFun,CloseFun},
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ...
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:close(HandleWrite),
+
+ %% And for decryption (in this crypto example we could use the same InitFun
+ %% as for encryption):
+ DecryptFun =
+ fun(EncryptedBin,Ivec) ->
+ PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
+ {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
+ end,
+
+ Cr = {InitFun,DecryptFun},
+ {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]),
+ {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
+ ok = erl_tar:close(HandleRead),
+ </code>
+ </desc>
+ </func>
+
<func>
<name>close(ChannelPid, Handle) -> </name>
<name>close(ChannelPid, Handle, Timeout) -> ok | {error, Reason}</name>
diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml
index 9ab71260d3..46178d4018 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -79,7 +79,7 @@
<p> The option user_dir defaults to the users ~/.ssh directory</p>
<p>In the following example we generate new keys and host keys as
- to be able to run the example without having root privilages</p>
+ to be able to run the example without having root privileges</p>
<code>
$bash> ssh-keygen -t rsa -f /tmp/ssh_daemon/ssh_host_rsa_key
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 2ef2859fd7..90d71107ad 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -65,6 +65,7 @@ MODULES= \
ssh_cli \
ssh_file \
ssh_io \
+ ssh_info \
ssh_math \
ssh_message \
ssh_no_io \
@@ -115,7 +116,7 @@ $(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES)
debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
clean:
- rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
+ rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(BEHAVIOUR_TARGET_FILES)
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src
index e0a51b3574..bc01c539e0 100644
--- a/lib/ssh/src/ssh.app.src
+++ b/lib/ssh/src/ssh.app.src
@@ -23,6 +23,7 @@
sshd_sup,
ssh_file,
ssh_io,
+ ssh_info,
ssh_math,
ssh_no_io,
ssh_server_key_api,
@@ -39,7 +40,7 @@
{applications, [kernel, stdlib, crypto, public_key]},
{env, []},
{mod, {ssh_app, []}},
- {runtime_dependencies, ["stdlib-2.0","public_key-0.22","kernel-3.0",
+ {runtime_dependencies, ["stdlib-2.3","public_key-0.22","kernel-3.0",
"erts-6.0","crypto-3.3"]}]}.
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 42eb2167e0..b2b2994eed 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,13 +19,61 @@
{"%VSN%",
[
- {"3.0.1", [{load_module, ssh, soft_purge, soft_purge, []},
- {load_module, ssh_acceptor, soft_purge, soft_purge, []}]},
+ {"3.0.8", [{load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_xfer]},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_xfer, soft_purge, soft_purge, []}
+ ]},
+ {"3.0.7", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_info, soft_purge, soft_purge, []},
+ {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_xfer, soft_purge, soft_purge, [ssh_connection_handler]}]},
+ {"3.0.6", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_info, soft_purge, soft_purge, []},
+ {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_xfer, soft_purge, soft_purge, [ssh_connection_handler]}]},
{<<".*">>, [{restart_application, ssh}]}
],
[
- {"3.0.1", [{load_module, ssh, soft_purge, soft_purge, []},
- {load_module, ssh_acceptor, soft_purge, soft_purge, []}]},
+ {"3.0.8", [{load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_sftp, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_xfer, soft_purge, soft_purge, []}
+ ]},
+ {"3.0.7", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_info, soft_purge, soft_purge, []},
+ {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_xfer, soft_purge, soft_purge, [ssh_connection_handler]}]},
+ {"3.0.6", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_info, soft_purge, soft_purge, []},
+ {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]},
+ {load_module, ssh_xfer, soft_purge, soft_purge, [ssh_connection_handler]}]},
{<<".*">>, [{restart_application, ssh}]}
]
}.
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 240de69eff..eae33e3683 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);
@@ -195,6 +194,7 @@ shell(Host, Port, Options) ->
{ok, ConnectionRef} ->
case ssh_connection:session_channel(ConnectionRef, infinity) of
{ok,ChannelId} ->
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, []),
Args = [{channel_cb, ssh_shell},
{init_args,[ConnectionRef, ChannelId]},
{cm, ConnectionRef}, {channel_id, ChannelId}],
@@ -235,29 +235,33 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
{port, Port}, {role, server},
{socket_opts, SocketOptions},
{ssh_opts, Options}]) of
- {ok, SysSup} ->
- {ok, SysSup};
{error, {already_started, _}} ->
{error, eaddrinuse};
- {error, R} ->
- {error, R}
+ Result = {Code, _} when (Code == ok) or (Code == error) ->
+ Result
catch
exit:{noproc, _} ->
{error, ssh_not_started}
end;
Sup ->
- case ssh_system_sup:restart_acceptor(Host, Port) of
+ AccPid = ssh_system_sup:acceptor_supervisor(Sup),
+ case ssh_acceptor_sup:start_child(AccPid, [{address, Host},
+ {port, Port}, {role, server},
+ {socket_opts, SocketOptions},
+ {ssh_opts, Options}]) of
+ {error, {already_started, _}} ->
+ {error, eaddrinuse};
{ok, _} ->
{ok, Sup};
- _ ->
- {error, eaddrinuse}
+ Other ->
+ Other
end
end.
handle_options(Opts) ->
try handle_option(proplists:unfold(Opts), [], []) of
- {_,_} = Options ->
- Options
+ {Inet, Ssh} ->
+ {handle_ip(Inet), Ssh}
catch
throw:Error ->
Error
@@ -393,7 +397,8 @@ handle_ssh_option({compression, Value} = Opt) when is_atom(Value) ->
Opt;
handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module),
is_atom(Function) ->
-
+ Opt;
+handle_ssh_option({exec, Function} = Opt) when is_function(Function) ->
Opt;
handle_ssh_option({auth_methods, Value} = Opt) when is_list(Value) ->
Opt;
@@ -433,13 +438,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 +466,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_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 7302196674..6c443eeb9c 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -22,7 +22,8 @@
-module(ssh_acceptor).
%% Internal application API
--export([start_link/5]).
+-export([start_link/5,
+ number_of_connections/1]).
%% spawn export
-export([acceptor_init/6, acceptor_loop/6]).
@@ -140,5 +141,6 @@ handle_error(Reason) ->
number_of_connections(SystemSup) ->
length([X ||
{R,X,supervisor,[ssh_subsystem_sup]} <- supervisor:which_children(SystemSup),
+ is_pid(X),
is_reference(R)
]).
diff --git a/lib/ssh/src/ssh_acceptor_sup.erl b/lib/ssh/src/ssh_acceptor_sup.erl
index 2be729d305..46fdef07d0 100644
--- a/lib/ssh/src/ssh_acceptor_sup.erl
+++ b/lib/ssh/src/ssh_acceptor_sup.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
@@ -26,7 +26,7 @@
-module(ssh_acceptor_sup).
-behaviour(supervisor).
--export([start_link/1, start_child/2, stop_child/2]).
+-export([start_link/1, start_child/2, stop_child/3]).
%% Supervisor callback
-export([init/1]).
@@ -45,18 +45,17 @@ start_child(AccSup, ServerOpts) ->
{error, already_present} ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- Name = id(Address, Port),
- supervisor:delete_child(?MODULE, Name),
+ stop_child(AccSup, Address, Port),
supervisor:start_child(AccSup, Spec);
Reply ->
Reply
end.
-stop_child(Address, Port) ->
+stop_child(AccSup, Address, Port) ->
Name = id(Address, Port),
- case supervisor:terminate_child(?MODULE, Name) of
+ case supervisor:terminate_child(AccSup, Name) of
ok ->
- supervisor:delete_child(?MODULE, Name);
+ supervisor:delete_child(AccSup, Name);
Error ->
Error
end.
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 45fd907383..45c4d52d7e 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.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
@@ -119,8 +119,7 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
false ->
FirstAlg = proplists:get_value(public_key_alg, Opts, ?PREFERRED_PK_ALG),
SecondAlg = other_alg(FirstAlg),
- AllowUserInt = proplists:get_value(user_interaction, Opts, true),
- Prefs = method_preference(FirstAlg, SecondAlg, AllowUserInt),
+ Prefs = method_preference(FirstAlg, SecondAlg),
ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
userauth_preference = Prefs,
userauth_methods = none,
@@ -130,15 +129,13 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
case length(Algs) =:= 2 of
true ->
SecondAlg = other_alg(FirstAlg),
- AllowUserInt = proplists:get_value(user_interaction, Opts, true),
- Prefs = method_preference(FirstAlg, SecondAlg, AllowUserInt),
+ Prefs = method_preference(FirstAlg, SecondAlg),
ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
userauth_preference = Prefs,
userauth_methods = none,
service = "ssh-connection"});
_ ->
- AllowUserInt = proplists:get_value(user_interaction, Opts, true),
- Prefs = method_preference(FirstAlg, AllowUserInt),
+ Prefs = method_preference(FirstAlg),
ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
userauth_preference = Prefs,
userauth_methods = none,
@@ -187,9 +184,8 @@ handle_userauth_request(#ssh_msg_service_request{name =
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "password",
- data = Data}, _,
+ data = <<?FALSE, ?UINT32(Sz), BinPwd:Sz/binary>>}, _,
#ssh{opts = Opts} = Ssh) ->
- <<_:8, ?UINT32(Sz), BinPwd:Sz/binary>> = Data,
Password = unicode:characters_to_list(BinPwd),
case check_password(User, Password, Opts) of
true ->
@@ -204,6 +200,27 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
+ method = "password",
+ data = <<?TRUE,
+ _/binary
+ %% ?UINT32(Sz1), OldBinPwd:Sz1/binary,
+ %% ?UINT32(Sz2), NewBinPwd:Sz2/binary
+ >>
+ }, _,
+ Ssh) ->
+ %% Password change without us having sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ (because we never do)
+ %% RFC 4252 says:
+ %% SSH_MSG_USERAUTH_FAILURE without partial success - The password
+ %% has not been changed. Either password changing was not supported,
+ %% or the old password was bad.
+
+ {not_authorized, {User, {error,"Password change not supported"}},
+ ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
+ authentications = "",
+ partial_success = false}, Ssh)};
+
+handle_userauth_request(#ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
method = "none"}, _,
#ssh{userauth_supported_methods = Methods} = Ssh) ->
{not_authorized, {User, undefined},
@@ -256,15 +273,12 @@ handle_userauth_info_request(
data = Data}, IoCb,
#ssh{opts = Opts} = Ssh) ->
PromptInfos = decode_keyboard_interactive_prompts(NumPrompts,Data),
- Resps = keyboard_interact_get_responses(IoCb, Opts,
+ Responses = keyboard_interact_get_responses(IoCb, Opts,
Name, Instr, PromptInfos),
- RespBin = list_to_binary(
- lists:map(fun(S) -> <<?STRING(list_to_binary(S))>> end,
- Resps)),
{ok,
ssh_transport:ssh_packet(
#ssh_msg_userauth_info_response{num_responses = NumPrompts,
- data = RespBin}, Ssh)}.
+ data = Responses}, Ssh)}.
handle_userauth_info_response(#ssh_msg_userauth_info_response{},
_Auth) ->
@@ -276,25 +290,16 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{},
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-method_preference(Alg1, Alg2, true) ->
+method_preference(Alg1, Alg2) ->
[{"publickey", ?MODULE, publickey_msg, [Alg1]},
{"publickey", ?MODULE, publickey_msg,[Alg2]},
{"password", ?MODULE, password_msg, []},
{"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ];
-method_preference(Alg1, Alg2, false) ->
- [{"publickey", ?MODULE, publickey_msg, [Alg1]},
- {"publickey", ?MODULE, publickey_msg,[Alg2]},
- {"password", ?MODULE, password_msg, []}
].
-method_preference(Alg1, true) ->
+method_preference(Alg1) ->
[{"publickey", ?MODULE, publickey_msg, [Alg1]},
{"password", ?MODULE, password_msg, []},
{"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ];
-method_preference(Alg1, false) ->
- [{"publickey", ?MODULE, publickey_msg, [Alg1]},
- {"password", ?MODULE, password_msg, []}
].
user_name(Opts) ->
@@ -362,35 +367,29 @@ build_sig_data(SessionId, User, Service, KeyBlob, Alg) ->
algorithm_string('ssh-rsa') ->
"ssh-rsa";
algorithm_string('ssh-dss') ->
- "ssh-dss".
+ "ssh-dss".
decode_keyboard_interactive_prompts(_NumPrompts, Data) ->
ssh_message:decode_keyboard_interactive_prompts(Data, []).
keyboard_interact_get_responses(IoCb, Opts, Name, Instr, PromptInfos) ->
NumPrompts = length(PromptInfos),
- case proplists:get_value(keyboard_interact_fun, Opts) of
- undefined when NumPrompts == 1 ->
- %% Special case/fallback for just one prompt
- %% (assumed to be the password prompt)
- case proplists:get_value(password, Opts) of
- undefined -> keyboard_interact(IoCb, Name, Instr, PromptInfos, Opts);
- PW -> [PW]
- end;
- undefined ->
- keyboard_interact(IoCb, Name, Instr, PromptInfos, Opts);
- KbdInteractFun ->
- Prompts = lists:map(fun({Prompt, _Echo}) -> Prompt end,
- PromptInfos),
- case KbdInteractFun(Name, Instr, Prompts) of
- Rs when length(Rs) == NumPrompts ->
- Rs;
- Rs ->
- erlang:error({mismatching_number_of_responses,
- {got,Rs},
- {expected,NumPrompts}})
- end
- end.
+ keyboard_interact_get_responses(proplists:get_value(user_interaction, Opts, true),
+ proplists:get_value(keyboard_interact_fun, Opts),
+ proplists:get_value(password, Opts, undefined), IoCb, Name,
+ Instr, PromptInfos, Opts, NumPrompts).
+
+keyboard_interact_get_responses(_, undefined, Password, _, _, _, _, _,
+ 1) when Password =/= undefined ->
+ [Password]; %% Password auth implemented with keyboard-interaction and passwd is known
+keyboard_interact_get_responses(_, _, _, _, _, _, _, _, 0) ->
+ [""];
+keyboard_interact_get_responses(false, undefined, undefined, _, _, _, [Prompt|_], Opts, _) ->
+ ssh_no_io:read_line(Prompt, Opts); %% Throws error as keyboard interaction is not allowed
+keyboard_interact_get_responses(true, undefined, _,IoCb, Name, Instr, PromptInfos, Opts, _) ->
+ keyboard_interact(IoCb, Name, Instr, PromptInfos, Opts);
+keyboard_interact_get_responses(true, Fun, _, Name, Instr, PromptInfos, _, _, NumPrompts) ->
+ keyboard_interact_fun(Fun, Name, Instr, PromptInfos, NumPrompts).
keyboard_interact(IoCb, Name, Instr, Prompts, Opts) ->
if Name /= "" -> IoCb:format("~s", [Name]);
@@ -404,6 +403,21 @@ keyboard_interact(IoCb, Name, Instr, Prompts, Opts) ->
end,
Prompts).
+keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
+ Prompts = lists:map(fun({Prompt, _Echo}) -> Prompt end,
+ PromptInfos),
+ case KbdInteractFun(Name, Instr, Prompts) of
+ Rs when length(Rs) == NumPrompts ->
+ Rs;
+ Rs ->
+ throw({mismatching_number_of_responses,
+ {got,Rs},
+ {expected, NumPrompts},
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
+ description = "User interaction failed",
+ language = "en"}})
+ end.
+
other_alg('ssh-rsa') ->
'ssh-dss';
other_alg('ssh-dss') ->
diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl
index 508ae637cf..5c24f362b1 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.erl
@@ -67,7 +67,8 @@
%% Internal application API
-export([cache_create/0, cache_lookup/2, cache_update/2,
cache_delete/1, cache_delete/2, cache_foldl/3,
- cache_find/2]).
+ cache_find/2,
+ get_print_info/1]).
-record(state, {
cm,
@@ -190,6 +191,14 @@ init([Options]) ->
%% {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------
+handle_call(get_print_info, _From, State) ->
+ Reply =
+ {{State#state.cm,
+ State#state.channel_id},
+ io_lib:format('CB=~p',[State#state.channel_cb])
+ },
+ {reply, Reply, State};
+
handle_call(Request, From, #state{channel_cb = Module,
channel_state = ChannelState} = State) ->
try Module:handle_call(Request, From, ChannelState) of
@@ -333,6 +342,9 @@ cache_find(ChannelPid, Cache) ->
Channel
end.
+get_print_info(Pid) ->
+ call(Pid, get_print_info, 1000).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 77453e8fd7..18841e3d2d 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -457,17 +457,17 @@ bin_to_list(I) when is_integer(I) ->
start_shell(ConnectionHandler, State) ->
Shell = State#state.shell,
- ConnectionInfo = ssh_connection_handler:info(ConnectionHandler,
+ ConnectionInfo = ssh_connection_handler:connection_info(ConnectionHandler,
[peer, user]),
ShellFun = case is_function(Shell) of
true ->
- {ok, User} =
+ User =
proplists:get_value(user, ConnectionInfo),
case erlang:fun_info(Shell, arity) of
{arity, 1} ->
fun() -> Shell(User) end;
{arity, 2} ->
- [{_, PeerAddr}] =
+ {_, PeerAddr} =
proplists:get_value(peer, ConnectionInfo),
fun() -> Shell(User, PeerAddr) end;
_ ->
@@ -485,9 +485,9 @@ start_shell(_ConnectionHandler, Cmd, #state{exec={M, F, A}} = State) ->
State#state{group = Group, buf = empty_buf()};
start_shell(ConnectionHandler, Cmd, #state{exec=Shell} = State) when is_function(Shell) ->
- ConnectionInfo = ssh_connection_handler:info(ConnectionHandler,
+ ConnectionInfo = ssh_connection_handler:connection_info(ConnectionHandler,
[peer, user]),
- {ok, User} =
+ User =
proplists:get_value(user, ConnectionInfo),
ShellFun =
case erlang:fun_info(Shell, arity) of
@@ -496,7 +496,7 @@ start_shell(ConnectionHandler, Cmd, #state{exec=Shell} = State) when is_function
{arity, 2} ->
fun() -> Shell(Cmd, User) end;
{arity, 3} ->
- [{_, PeerAddr}] =
+ {_, PeerAddr} =
proplists:get_value(peer, ConnectionInfo),
fun() -> Shell(Cmd, User, PeerAddr) end;
_ ->
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index 8421b07167..d14f7ce27d 100644
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -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
@@ -26,6 +26,7 @@
-define(DEFAULT_PACKET_SIZE, 32768).
-define(DEFAULT_WINDOW_SIZE, 2*?DEFAULT_PACKET_SIZE).
-define(DEFAULT_TIMEOUT, 5000).
+-define(MAX_PROTO_VERSION, 255).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -164,6 +165,10 @@
recipient_channel
}).
+-define(TERMINAL_WIDTH, 80).
+-define(TERMINAL_HEIGHT, 24).
+-define(DEFAULT_TERMINAL, "vt100").
+
-define(TTY_OP_END,0). %% Indicates end of options.
-define(VINTR,1). %% Interrupt character; 255 if none. Similarly for the
%% other characters. Not all of these characters are
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index b377614949..c66f810948 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.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
@@ -32,11 +32,11 @@
%% API
-export([session_channel/2, session_channel/4,
exec/4, shell/2, subsystem/4, send/3, send/4, send/5,
- send_eof/2, adjust_window/3, setenv/5, close/2, reply_request/4]).
+ send_eof/2, adjust_window/3, setenv/5, close/2, reply_request/4,
+ ptty_alloc/3, ptty_alloc/4]).
%% Potential API currently unsupported and not tested
--export([open_pty/3, open_pty/7,
- open_pty/9, window_change/4, window_change/6,
+-export([window_change/4, window_change/6,
direct_tcpip/6, direct_tcpip/8, tcpip_forward/3,
cancel_tcpip_forward/3, signal/3, exit_status/3]).
@@ -56,8 +56,8 @@
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
--spec session_channel(pid(), timeout()) -> {ok, channel_id()} | {error, term()}.
--spec session_channel(pid(), integer(), integer(), timeout()) -> {ok, channel_id()} | {error, term()}.
+-spec session_channel(pid(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}.
+-spec session_channel(pid(), integer(), integer(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}.
%% Description: Opens a channel for a ssh session. A session is a
%% remote execution of a program. The program may be a shell, an
@@ -81,7 +81,8 @@ session_channel(ConnectionHandler, InitialWindowSize,
end.
%%--------------------------------------------------------------------
--spec exec(pid(), channel_id(), string(), timeout()) -> success | failure.
+-spec exec(pid(), channel_id(), string(), timeout()) ->
+ success | failure | {error, timeout | closed}.
%% Description: Will request that the server start the
%% execution of the given command.
@@ -101,8 +102,8 @@ shell(ConnectionHandler, ChannelId) ->
ssh_connection_handler:request(ConnectionHandler, self(), ChannelId,
"shell", false, <<>>, 0).
%%--------------------------------------------------------------------
--spec subsystem(pid(), channel_id(), string(), timeout()) ->
- success | failure | {error, timeout}.
+-spec subsystem(pid(), channel_id(), string(), timeout()) ->
+ success | failure | {error, timeout | closed}.
%%
%% Description: Executes a predefined subsystem.
%%--------------------------------------------------------------------
@@ -142,7 +143,7 @@ send_eof(ConnectionHandler, Channel) ->
ssh_connection_handler:send_eof(ConnectionHandler, Channel).
%%--------------------------------------------------------------------
--spec adjust_window(pid(), channel_id(), integer()) -> ok.
+-spec adjust_window(pid(), channel_id(), integer()) -> ok | {error, closed}.
%%
%%
%% Description: Adjusts the ssh flowcontrol window.
@@ -151,7 +152,8 @@ adjust_window(ConnectionHandler, Channel, Bytes) ->
ssh_connection_handler:adjust_window(ConnectionHandler, Channel, Bytes).
%%--------------------------------------------------------------------
--spec setenv(pid(), channel_id(), string(), string(), timeout()) -> success | failure.
+-spec setenv(pid(), channel_id(), string(), string(), timeout()) ->
+ success | failure | {error, timeout | closed}.
%%
%%
%% Description: Environment variables may be passed to the shell/command to be
@@ -183,6 +185,29 @@ reply_request(_,false, _, _) ->
ok.
%%--------------------------------------------------------------------
+-spec ptty_alloc(pid(), channel_id(), proplists:proplist()) ->
+ success | failiure | {error, closed}.
+-spec ptty_alloc(pid(), channel_id(), proplists:proplist(), timeout()) ->
+ success | failiure | {error, timeout} | {error, closed}.
+
+%%
+%%
+%% Description: Sends a ssh connection protocol pty_req.
+%%--------------------------------------------------------------------
+ptty_alloc(ConnectionHandler, Channel, Options) ->
+ ptty_alloc(ConnectionHandler, Channel, Options, infinity).
+ptty_alloc(ConnectionHandler, Channel, Options, TimeOut) ->
+ {Width, PixWidth} = pty_default_dimensions(width, Options),
+ {Hight, PixHight} = pty_default_dimensions(hight, Options),
+ pty_req(ConnectionHandler, Channel,
+ proplists:get_value(term, Options, default_term()),
+ proplists:get_value(width, Options, Width),
+ proplists:get_value(hight, Options, Hight),
+ proplists:get_value(pixel_widh, Options, PixWidth),
+ proplists:get_value(pixel_hight, Options, PixHight),
+ proplists:get_value(pty_opts, Options, []), TimeOut
+ ).
+%%--------------------------------------------------------------------
%% Not yet officialy supported! The following functions are part of the
%% initial contributed ssh application. They are untested. Do we want them?
%% Should they be documented and tested?
@@ -205,23 +230,6 @@ exit_status(ConnectionHandler, Channel, Status) ->
ssh_connection_handler:request(ConnectionHandler, Channel,
"exit-status", false, [?uint32(Status)], 0).
-open_pty(ConnectionHandler, Channel, TimeOut) ->
- open_pty(ConnectionHandler, Channel,
- os:getenv("TERM"), 80, 24, [], TimeOut).
-
-open_pty(ConnectionHandler, Channel, Term, Width, Height, PtyOpts, TimeOut) ->
- open_pty(ConnectionHandler, Channel, Term, Width,
- Height, 0, 0, PtyOpts, TimeOut).
-
-open_pty(ConnectionHandler, Channel, Term, Width, Height,
- PixWidth, PixHeight, PtyOpts, TimeOut) ->
- ssh_connection_handler:request(ConnectionHandler,
- Channel, "pty-req", true,
- [?string(Term),
- ?uint32(Width), ?uint32(Height),
- ?uint32(PixWidth),?uint32(PixHeight),
- encode_pty_opts(PtyOpts)], TimeOut).
-
direct_tcpip(ConnectionHandler, RemoteHost,
RemotePort, OrigIP, OrigPort, Timeout) ->
direct_tcpip(ConnectionHandler, RemoteHost, RemotePort, OrigIP, OrigPort,
@@ -782,9 +790,8 @@ handle_cli_msg(#connection{channel_cache = Cache} = Connection,
erlang:monitor(process, Pid),
Channel = Channel0#channel{user = Pid},
ssh_channel:cache_update(Cache, Channel),
- Reply = {connection_reply,
- channel_success_msg(RemoteId)},
- {{replies, [{channel_data, Pid, Reply0}, Reply]}, Connection};
+ {Reply, Connection1} = reply_msg(Channel, Connection, Reply0),
+ {{replies, [Reply]}, Connection1};
_Other ->
Reply = {connection_reply,
channel_failure_msg(RemoteId)},
@@ -1075,6 +1082,27 @@ flow_control([_|_], #channel{flow_control = From,
flow_control(_,_,_) ->
[].
+pty_req(ConnectionHandler, Channel, Term, Width, Height,
+ PixWidth, PixHeight, PtyOpts, TimeOut) ->
+ ssh_connection_handler:request(ConnectionHandler,
+ Channel, "pty-req", true,
+ [?string(Term),
+ ?uint32(Width), ?uint32(Height),
+ ?uint32(PixWidth),?uint32(PixHeight),
+ encode_pty_opts(PtyOpts)], TimeOut).
+
+pty_default_dimensions(Dimension, Options) ->
+ case proplists:get_value(Dimension, Options, 0) of
+ N when is_integer(N), N > 0 ->
+ {N, 0};
+ _ ->
+ case proplists:get_value(list_to_atom("pixel_" ++ atom_to_list(Dimension)), Options, 0) of
+ N when is_integer(N), N > 0 ->
+ {0, N};
+ _ ->
+ {?TERMINAL_WIDTH, 0}
+ end
+ end.
encode_pty_opts(Opts) ->
Bin = list_to_binary(encode_pty_opts2(Opts)),
@@ -1272,3 +1300,10 @@ decode_ip(Addr) when is_binary(Addr) ->
{ok,A} -> A
end.
+default_term() ->
+ case os:getenv("TERM") of
+ false ->
+ ?DEFAULT_TERMINAL;
+ Str when is_list(Str)->
+ Str
+ end.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 06866392da..68523aa72b 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.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
@@ -41,14 +41,16 @@
global_request/4, send/5, send_eof/2, info/1, info/2,
connection_info/2, channel_info/3,
adjust_window/3, close/2, stop/1, renegotiate/1, renegotiate_data/1,
- start_connection/4]).
+ start_connection/4,
+ get_print_info/1]).
%% gen_fsm callbacks
-export([hello/2, kexinit/2, key_exchange/2, new_keys/2,
- userauth/2, connected/2]).
+ userauth/2, connected/2,
+ error/2]).
-export([init/1, handle_event/3,
- handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).
+ handle_sync_event/4, handle_info/3, terminate/3, format_status/2, code_change/4]).
-record(state, {
role,
@@ -71,7 +73,8 @@
connection_queue,
address,
port,
- opts
+ opts,
+ recbuf
}).
-type state_name() :: hello | kexinit | key_exchange | new_keys | userauth | connection.
@@ -103,22 +106,22 @@ start_connection(client = Role, Socket, Options, Timeout) ->
end;
start_connection(server = Role, Socket, Options, Timeout) ->
+ SSH_Opts = proplists:get_value(ssh_opts, Options, []),
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, SSH_Opts, false) of
true ->
- spawn(fun() ->
- Ref = erlang:monitor(process, Pid),
- handshake(Pid, Ref, Timeout)
- end);
+ HandshakerPid =
+ spawn_link(fun() ->
+ receive
+ {do_handshake, Pid} ->
+ handshake(Pid, erlang:monitor(process,Pid), Timeout)
+ end
+ end),
+ ChildPid = start_the_connection_child(HandshakerPid, Role, Socket, Options),
+ HandshakerPid ! {do_handshake, ChildPid};
false ->
- Ref = erlang:monitor(process, Pid),
- handshake(Pid, Ref, Timeout)
+ ChildPid = start_the_connection_child(self(), Role, Socket, Options),
+ handshake(ChildPid, erlang:monitor(process,ChildPid), Timeout)
end
catch
exit:{noproc, _} ->
@@ -127,6 +130,16 @@ start_connection(server = Role, Socket, Options, Timeout) ->
{error, Error}
end.
+start_the_connection_child(UserPid, Role, Socket, Options) ->
+ Sups = proplists:get_value(supervisors, Options),
+ ConnectionSup = proplists:get_value(connection_sup, Sups),
+ Opts = [{supervisors, Sups}, {user_pid, UserPid} | 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),
+ Pid.
+
+
start_link(Role, Socket, Options) ->
{ok, proc_lib:spawn_link(?MODULE, init, [[Role, Socket, Options]])}.
@@ -160,9 +173,23 @@ init([Role, Socket, SshOpts]) ->
State#state{ssh_params = Ssh})
catch
_:Error ->
- gen_fsm:enter_loop(?MODULE, [], error, {Error, State0})
+ gen_fsm:enter_loop(?MODULE, [], error, {Error, State})
end.
+%% Temporary fix for the Nessus error. SYN-> <-SYNACK ACK-> RST-> ?
+error(_Event, {Error,State=#state{}}) ->
+ case Error of
+ {badmatch,{error,enotconn}} ->
+ %% {error,enotconn} probably from inet:peername in
+ %% init_ssh(server,..)/5 called from init/1
+ {stop, {shutdown,"TCP connenction to server was prematurely closed by the client"}, State};
+ _ ->
+ {stop, {shutdown,{init,Error}}, State}
+ end;
+error(Event, State) ->
+ %% State deliberately not checked beeing #state. This is a panic-clause...
+ {stop, {shutdown,{init,{spurious_error,Event}}}, State}.
+
%%--------------------------------------------------------------------
-spec open_channel(pid(), string(), iodata(), integer(), integer(),
timeout()) -> {open, channel_id()} | {error, term()}.
@@ -229,6 +256,9 @@ send_eof(ConnectionHandler, ChannelId) ->
%%--------------------------------------------------------------------
-spec connection_info(pid(), [atom()]) -> proplists:proplist().
%%--------------------------------------------------------------------
+get_print_info(ConnectionHandler) ->
+ sync_send_all_state_event(ConnectionHandler, get_print_info, 1000).
+
connection_info(ConnectionHandler, Options) ->
sync_send_all_state_event(ConnectionHandler, {connection_info, Options}).
@@ -259,8 +289,13 @@ renegotiate_data(ConnectionHandler) ->
-spec close(pid(), channel_id()) -> ok.
%%--------------------------------------------------------------------
close(ConnectionHandler, ChannelId) ->
- sync_send_all_state_event(ConnectionHandler, {close, ChannelId}).
-
+ case sync_send_all_state_event(ConnectionHandler, {close, ChannelId}) of
+ ok ->
+ ok;
+ {error, closed} ->
+ ok
+ end.
+
%%--------------------------------------------------------------------
-spec stop(pid()) -> ok | {error, term()}.
%%--------------------------------------------------------------------
@@ -291,28 +326,39 @@ info(ConnectionHandler, ChannelProcess) ->
hello(socket_control, #state{socket = Socket, ssh_params = Ssh} = State) ->
VsnMsg = ssh_transport:hello_version_msg(string_version(Ssh)),
send_msg(VsnMsg, State),
- inet:setopts(Socket, [{packet, line}, {active, once}]),
- {next_state, hello, State};
+ {ok, [{recbuf, Size}]} = inet:getopts(Socket, [recbuf]),
+ inet:setopts(Socket, [{packet, line}, {active, once}, {recbuf, ?MAX_PROTO_VERSION}]),
+ {next_state, hello, State#state{recbuf = Size}};
-hello({info_line, _Line},#state{socket = Socket} = State) ->
+hello({info_line, _Line},#state{role = client, socket = Socket} = State) ->
+ %% The server may send info lines before the version_exchange
inet:setopts(Socket, [{active, once}]),
{next_state, hello, State};
+hello({info_line, _Line},#state{role = server} = State) ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code =
+ ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Did not receive expected protocol version exchange",
+ language = "en"},
+ handle_disconnect(DisconnectMsg, State);
+
hello({version_exchange, Version}, #state{ssh_params = Ssh0,
- socket = Socket} = State) ->
+ socket = Socket,
+ recbuf = Size} = State) ->
{NumVsn, StrVsn} = ssh_transport:handle_hello_version(Version),
case handle_version(NumVsn, StrVsn, Ssh0) of
{ok, Ssh1} ->
- inet:setopts(Socket, [{packet,0}, {mode,binary}, {active, once}]),
+ inet:setopts(Socket, [{packet,0}, {mode,binary}, {active, once}, {recbuf, Size}]),
{KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh1),
send_msg(SshPacket, State),
{next_state, kexinit, next_packet(State#state{ssh_params = Ssh,
key_exchange_init_msg =
KeyInitMsg})};
not_supported ->
- DisconnectMsg =
+ DisconnectMsg =
#ssh_msg_disconnect{code =
- ?SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
+ ?SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
description = "Protocol version " ++ StrVsn
++ " not supported",
language = "en"},
@@ -528,7 +574,7 @@ connected({#ssh_msg_kexinit{}, _Payload} = Event, State) ->
%%--------------------------------------------------------------------
handle_event(#ssh_msg_disconnect{description = Desc} = DisconnectMsg, _StateName, #state{} = State) ->
- handle_disconnect(DisconnectMsg, State),
+ handle_disconnect(peer, DisconnectMsg, State),
{stop, {shutdown, Desc}, State};
handle_event(#ssh_msg_ignore{}, StateName, State) ->
@@ -583,7 +629,7 @@ handle_event(renegotiate, connected, #state{ssh_params = Ssh0}
renegotiate = true})};
handle_event(renegotiate, StateName, State) ->
- timer:apply_after(?REKEY_TIMOUT, gen_fsm, send_all_state_event, [self(), renegotiatie]),
+ timer:apply_after(?REKEY_TIMOUT, gen_fsm, send_all_state_event, [self(), renegotiate]),
%% Allready in keyexcahange so ignore
{next_state, StateName, State};
@@ -736,6 +782,20 @@ handle_sync_event({recv_window, ChannelId}, _From, StateName,
end,
{reply, Reply, StateName, next_packet(State)};
+handle_sync_event(get_print_info, _From, StateName, State) ->
+ Reply =
+ try
+ {inet:sockname(State#state.socket),
+ inet:peername(State#state.socket)
+ }
+ of
+ {{ok,Local}, {ok,Remote}} -> {{Local,Remote},io_lib:format("statename=~p",[StateName])};
+ _ -> {{"-",0},"-"}
+ catch
+ _:_ -> {{"?",0},"?"}
+ end,
+ {reply, Reply, StateName, State};
+
handle_sync_event({connection_info, Options}, _From, StateName, State) ->
Info = ssh_info(Options, State, []),
{reply, Info, StateName, State};
@@ -914,6 +974,10 @@ terminate(normal, _, #state{transport_cb = Transport,
(catch Transport:close(Socket)),
ok;
+terminate({shutdown,{init,Reason}}, StateName, State) ->
+ error_logger:info_report(io_lib:format("Erlang ssh in connection handler init: ~p~n",[Reason])),
+ terminate(normal, StateName, State);
+
%% Terminated by supervisor
terminate(shutdown, StateName, #state{ssh_params = Ssh0} = State) ->
DisconnectMsg =
@@ -929,8 +993,10 @@ terminate({shutdown, #ssh_msg_disconnect{} = Msg}, StateName,
{SshPacket, Ssh} = ssh_transport:ssh_packet(Msg, Ssh0),
send_msg(SshPacket, State),
terminate(normal, StateName, State#state{ssh_params = Ssh});
+
terminate({shutdown, _}, StateName, State) ->
terminate(normal, StateName, State);
+
terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
connection_state = Connection} = State) ->
terminate_subsytem(Connection),
@@ -943,12 +1009,43 @@ terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
send_msg(SshPacket, State),
terminate(normal, StateName, State#state{ssh_params = Ssh}).
+
terminate_subsytem(#connection{system_supervisor = SysSup,
sub_system_supervisor = SubSysSup}) when is_pid(SubSysSup) ->
ssh_system_sup:stop_subsystem(SysSup, SubSysSup);
terminate_subsytem(_) ->
ok.
+format_status(normal, [_, State]) ->
+ [{data, [{"StateData", State}]}];
+format_status(terminate, [_, State]) ->
+ SshParams0 = (State#state.ssh_params),
+ SshParams = SshParams0#ssh{c_keyinit = "***",
+ s_keyinit = "***",
+ send_mac_key = "***",
+ send_mac_size = "***",
+ recv_mac_key = "***",
+ recv_mac_size = "***",
+ encrypt_keys = "***",
+ encrypt_ctx = "***",
+ decrypt_keys = "***",
+ decrypt_ctx = "***",
+ compress_ctx = "***",
+ decompress_ctx = "***",
+ shared_secret = "***",
+ exchanged_hash = "***",
+ session_id = "***",
+ keyex_key = "***",
+ keyex_info = "***",
+ available_host_keys = "***"},
+ [{data, [{"StateData", State#state{decoded_data_buffer = "***",
+ encoded_data_buffer = "***",
+ key_exchange_init_msg = "***",
+ opts = "***",
+ recbuf = "***",
+ ssh_params = SshParams
+ }}]}].
+
%%--------------------------------------------------------------------
-spec code_change(OldVsn::term(), state_name(), Oldstate::term(), Extra::term()) ->
{ok, state_name(), #state{}}.
@@ -1109,7 +1206,14 @@ send_all_state_event(FsmPid, Event) ->
gen_fsm:send_all_state_event(FsmPid, Event).
sync_send_all_state_event(FsmPid, Event) ->
- try gen_fsm:sync_send_all_state_event(FsmPid, Event, infinity)
+ sync_send_all_state_event(FsmPid, Event, infinity).
+
+sync_send_all_state_event(FsmPid, Event, Timeout) ->
+ try gen_fsm:sync_send_all_state_event(FsmPid, Event, Timeout) of
+ {closed, _Channel} ->
+ {error, closed};
+ Result ->
+ Result
catch
exit:{noproc, _} ->
{error, closed};
@@ -1204,15 +1308,25 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
end;
generate_event(Msg, StateName, State0, EncData) ->
- Event = ssh_message:decode(Msg),
- State = generate_event_new_state(State0, EncData),
- case Event of
- #ssh_msg_kexinit{} ->
- %% We need payload for verification later.
- event({Event, Msg}, StateName, State);
- _ ->
- event(Event, StateName, State)
- end.
+ try
+ Event = ssh_message:decode(Msg),
+ State = generate_event_new_state(State0, EncData),
+ case Event of
+ #ssh_msg_kexinit{} ->
+ %% We need payload for verification later.
+ event({Event, Msg}, StateName, State);
+ _ ->
+ event(Event, StateName, State)
+ end
+ catch
+ _:_ ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Encountered unexpected input",
+ language = "en"},
+ handle_disconnect(DisconnectMsg, State0)
+ end.
+
handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From,
@@ -1370,37 +1484,57 @@ handle_ssh_packet(Length, StateName, #state{decoded_data_buffer = DecData0,
ssh_params = Ssh0,
transport_protocol = _Protocol,
socket = _Socket} = State0) ->
- {Ssh1, DecData, EncData, Mac} =
- ssh_transport:unpack(EncData0, Length, Ssh0),
- SshPacket = <<DecData0/binary, DecData/binary>>,
- case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of
- true ->
- PacketData = ssh_transport:msg_data(SshPacket),
- {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData),
- generate_event(Msg, StateName,
- State0#state{ssh_params = Ssh1,
- %% Important to be set for
- %% next_packet
- decoded_data_buffer = <<>>}, EncData);
- false ->
- DisconnectMsg =
+ try
+ {Ssh1, DecData, EncData, Mac} =
+ ssh_transport:unpack(EncData0, Length, Ssh0),
+ SshPacket = <<DecData0/binary, DecData/binary>>,
+ case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of
+ true ->
+ PacketData = ssh_transport:msg_data(SshPacket),
+ {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData),
+ generate_event(Msg, StateName,
+ State0#state{ssh_params = Ssh1,
+ %% Important to be set for
+ %% next_packet
+ decoded_data_buffer = <<>>},
+ EncData);
+ false ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad mac",
+ language = "en"},
+ handle_disconnect(DisconnectMsg, State0)
+ end
+ catch _:_ ->
+ Disconnect =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad mac",
+ description = "Bad input",
language = "en"},
- handle_disconnect(DisconnectMsg, State0)
- end.
+ handle_disconnect(Disconnect, State0)
+ end.
+
-handle_disconnect(#ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0,
- role = Role} = State0) ->
+handle_disconnect(DisconnectMsg, State) ->
+ handle_disconnect(own, DisconnectMsg, State).
+
+handle_disconnect(#ssh_msg_disconnect{} = DisconnectMsg, State, Error) ->
+ handle_disconnect(own, DisconnectMsg, State, Error);
+handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, role = Role} = State0) ->
{disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role),
- State = send_replies(Replies, State0),
+ State = send_replies(disconnect_replies(Type, Msg, Replies), State0),
{stop, {shutdown, Desc}, State#state{connection_state = Connection}}.
-handle_disconnect(#ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0,
- role = Role} = State0, ErrorMsg) ->
+
+handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0,
+ role = Role} = State0, ErrorMsg) ->
{disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role),
- State = send_replies(Replies, State0),
+ State = send_replies(disconnect_replies(Type, Msg, Replies), State0),
{stop, {shutdown, {Desc, ErrorMsg}}, State#state{connection_state = Connection}}.
+disconnect_replies(own, Msg, Replies) ->
+ [{connection_reply, Msg} | Replies];
+disconnect_replies(peer, _, Replies) ->
+ Replies.
+
counterpart_versions(NumVsn, StrVsn, #ssh{role = server} = Ssh) ->
Ssh#ssh{c_vsn = NumVsn , c_version = StrVsn};
counterpart_versions(NumVsn, StrVsn, #ssh{role = client} = Ssh) ->
@@ -1577,7 +1711,7 @@ handshake(Pid, Ref, Timeout) ->
{error, Reason}
after Timeout ->
stop(Pid),
- {error, Timeout}
+ {error, timeout}
end.
start_timeout(_,_, infinity) ->
diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl
new file mode 100644
index 0000000000..9ed598b3ab
--- /dev/null
+++ b/lib/ssh/src/ssh_info.erl
@@ -0,0 +1,193 @@
+%%
+%% %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%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Print some info of a running ssh aplication.
+%%----------------------------------------------------------------------
+
+-module(ssh_info).
+
+-compile(export_all).
+
+print() ->
+ try supervisor:which_children(ssh_sup)
+ of
+ _ ->
+ io:nl(),
+ print_general(),
+ io:nl(),
+ underline("Client part", $=),
+ print_clients(),
+ io:nl(),
+ underline("Server part", $=),
+ print_servers(),
+ io:nl(),
+ %% case os:type() of
+ %% {unix,_} ->
+ %% io:nl(),
+ %% underline("Linux part", $=),
+ %% underline("Listening"),
+ %% catch io:format(os:cmd("netstat -tpln")),
+ %% io:nl(),
+ %% underline("Other"),
+ %% catch io:format(os:cmd("netstat -tpn"));
+ %% _ -> ok
+ %% end,
+ underline("Supervisors", $=),
+ walk_sups(ssh_sup),
+ io:nl()
+ catch
+ _:_ ->
+ io:format("Ssh not found~n",[])
+ end.
+
+%%%================================================================
+print_general() ->
+ {_Name, Slogan, Ver} = lists:keyfind(ssh,1,application:which_applications()),
+ underline(io_lib:format("~s ~s", [Slogan, Ver]), $=),
+ io:format('This printout is generated ~s. ~n',[datetime()]).
+
+%%%================================================================
+print_clients() ->
+ try
+ lists:foreach(fun print_client/1, supervisor:which_children(sshc_sup))
+ catch
+ C:E ->
+ io:format('***FAILED: ~p:~p~n',[C,E])
+ end.
+
+print_client({undefined,Pid,supervisor,[ssh_connection_handler]}) ->
+ {{Local,Remote},_Str} = ssh_connection_handler:get_print_info(Pid),
+ io:format(" Local=~s Remote=~s~n",[fmt_host_port(Local),fmt_host_port(Remote)]);
+print_client(Other) ->
+ io:format(" [[Other 1: ~p]]~n",[Other]).
+
+
+%%%================================================================
+print_servers() ->
+ try
+ lists:foreach(fun print_server/1, supervisor:which_children(sshd_sup))
+ catch
+ C:E ->
+ io:format('***FAILED: ~p:~p~n',[C,E])
+ end.
+
+print_server({{server,ssh_system_sup,LocalHost,LocalPort},Pid,supervisor,[ssh_system_sup]}) when is_pid(Pid) ->
+ io:format('Local=~s (~p children)~n',[fmt_host_port({LocalHost,LocalPort}),
+ ssh_acceptor:number_of_connections(Pid)]),
+ lists:foreach(fun print_system_sup/1, supervisor:which_children(Pid));
+print_server(Other) ->
+ io:format(" [[Other 2: ~p]]~n",[Other]).
+
+print_system_sup({Ref,Pid,supervisor,[ssh_subsystem_sup]}) when is_reference(Ref),
+ is_pid(Pid) ->
+ lists:foreach(fun print_channels/1, supervisor:which_children(Pid));
+print_system_sup({{ssh_acceptor_sup,LocalHost,LocalPort}, Pid,supervisor, [ssh_acceptor_sup]}) when is_pid(Pid) ->
+ io:format(" [Acceptor for ~s]~n",[fmt_host_port({LocalHost,LocalPort})]);
+print_system_sup(Other) ->
+ io:format(" [[Other 3: ~p]]~n",[Other]).
+
+print_channels({{server,ssh_channel_sup,_,_},Pid,supervisor,[ssh_channel_sup]}) when is_pid(Pid) ->
+ lists:foreach(fun print_channel/1, supervisor:which_children(Pid));
+print_channels(Other) ->
+ io:format(" [[Other 4: ~p]]~n",[Other]).
+
+
+print_channel({Ref,Pid,worker,[ssh_channel]}) when is_reference(Ref),
+ is_pid(Pid) ->
+ {{ConnManager,ChannelID}, Str} = ssh_channel:get_print_info(Pid),
+ {{Local,Remote},StrM} = ssh_connection_handler:get_print_info(ConnManager),
+ io:format(' ch ~p: ~s ~s',[ChannelID, StrM, Str]),
+ io:format(" Local=~s Remote=~s~n",[fmt_host_port(Local),fmt_host_port(Remote)]);
+print_channel(Other) ->
+ io:format(" [[Other 5: ~p]]~n",[Other]).
+
+%%%================================================================
+-define(inc(N), (N+4)).
+
+walk_sups(StartPid) ->
+ io:format("Start at ~p, ~s.~n",[StartPid,dead_or_alive(StartPid)]),
+ walk_sups(children(StartPid), _Indent=?inc(0)).
+
+walk_sups([H={_,Pid,SupOrWorker,_}|T], Indent) ->
+ indent(Indent), io:format('~200p ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]),
+ case SupOrWorker of
+ supervisor -> walk_sups(children(Pid), ?inc(Indent));
+ _ -> ok
+ end,
+ walk_sups(T, Indent);
+walk_sups([], _) ->
+ ok.
+
+dead_or_alive(Name) when is_atom(Name) ->
+ case whereis(Name) of
+ undefined ->
+ "**UNDEFINED**";
+ Pid ->
+ dead_or_alive(Pid)
+ end;
+dead_or_alive(Pid) when is_pid(Pid) ->
+ case process_info(Pid) of
+ undefined -> "**DEAD**";
+ _ -> "alive"
+ end.
+
+indent(I) -> io:format('~*c',[I,$ ]).
+
+children(Pid) ->
+ Parent = self(),
+ Helper = spawn(fun() ->
+ Parent ! {self(),supervisor:which_children(Pid)}
+ end),
+ receive
+ {Helper,L} when is_list(L) ->
+ L
+ after
+ 2000 ->
+ catch exit(Helper, kill),
+ []
+ end.
+
+%%%================================================================
+underline(Str) ->
+ underline(Str, $-).
+
+underline(Str, LineChar) ->
+ Len = lists:flatlength(Str),
+ io:format('~s~n',[Str]),
+ line(Len,LineChar).
+
+line(Len, Char) ->
+ io:format('~*c~n', [Len,Char]).
+
+
+datetime() ->
+ {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(now()),
+ lists:flatten(io_lib:format('~4w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w UTC',[YYYY,MM,DD, H,M,S])).
+
+
+fmt_host_port({{A,B,C,D},Port}) -> io_lib:format('~p.~p.~p.~p:~p',[A,B,C,D,Port]);
+fmt_host_port({Host,Port}) -> io_lib:format('~s:~p',[Host,Port]).
+
+
+
+nyi() ->
+ io:format('Not yet implemented~n',[]),
+ nyi.
diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl
index 35336bce8b..97e2dee27a 100644
--- a/lib/ssh/src/ssh_io.erl
+++ b/lib/ssh/src/ssh_io.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
@@ -73,7 +73,9 @@ read_password(Prompt, Ssh) ->
listify(A) when is_atom(A) ->
atom_to_list(A);
listify(L) when is_list(L) ->
- L.
+ L;
+listify(B) when is_binary(B) ->
+ binary_to_list(B).
format(Fmt, Args) ->
io:format(Fmt, Args).
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 8d6c77c0ed..66e7717095 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2013-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
@@ -162,8 +162,15 @@ encode(#ssh_msg_userauth_info_request{
encode(#ssh_msg_userauth_info_response{
num_responses = Num,
data = Data}) ->
- ssh_bits:encode([?SSH_MSG_USERAUTH_INFO_RESPONSE, Num, Data],
- [byte, uint32, '...']);
+ Responses = lists:map(fun("") ->
+ <<>>;
+ (Response) ->
+ ssh_bits:encode([Response], [string])
+ end, Data),
+ Start = ssh_bits:encode([?SSH_MSG_USERAUTH_INFO_RESPONSE, Num],
+ [byte, uint32]),
+ iolist_to_binary([Start, Responses]);
+
encode(#ssh_msg_disconnect{
code = Code,
description = Desc,
@@ -255,7 +262,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 +398,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 +405,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 +468,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)>>) ->
@@ -489,6 +505,11 @@ erl_boolean(1) ->
decode_kex_init(<<?BYTE(Bool), ?UINT32(X)>>, Acc, 0) ->
list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
+decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) ->
+ %% The mandatory trailing UINT32 is missing. Assume the value it anyhow must have
+ %% See rfc 4253 7.1
+ X = 0,
+ list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
decode_kex_init(<<?UINT32(Len), Data:Len/binary, Rest/binary>>, Acc, N) ->
Names = string:tokens(unicode:characters_to_list(Data), ","),
decode_kex_init(Rest, [Names | Acc], N -1).
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index 0ea2366ac7..613f8f25b2 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.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
@@ -33,8 +33,8 @@
-export([start_channel/1, start_channel/2, start_channel/3, stop_channel/1]).
--export([open/3, opendir/2, close/2, readdir/2, pread/4, read/3,
- open/4, opendir/3, close/3, readdir/3, pread/5, read/4,
+-export([open/3, open_tar/3, opendir/2, close/2, readdir/2, pread/4, read/3,
+ open/4, open_tar/4, opendir/3, close/3, readdir/3, pread/5, read/4,
apread/4, aread/3, pwrite/4, write/3, apwrite/4, awrite/3,
pwrite/5, write/4,
position/3, real_path/2, read_file_info/2, get_file_info/2,
@@ -57,7 +57,8 @@
rep_buf = <<>>,
req_id,
req_list = [], %% {ReqId, Fun}
- inf %% list of fileinf
+ inf, %% list of fileinf,
+ opts
}).
-record(fileinf,
@@ -68,6 +69,18 @@
mode
}).
+-record(bufinf,
+ {
+ mode, % read | write (=from or to buffer by user)
+ crypto_state,
+ crypto_fun, % For encode or decode depending on the mode field
+ size = 0, % # bytes "before" the current buffer for the postion call
+
+ chunksize, % The size of the chunks to be sent or received
+ enc_text_buf = <<>>, % Encrypted text
+ plain_text_buf = <<>> % Decrypted text
+ }).
+
-define(FILEOP_TIMEOUT, infinity).
-define(NEXT_REQID(S),
@@ -85,10 +98,11 @@ start_channel(Host) when is_list(Host) ->
start_channel(Host, []).
start_channel(Cm, Opts) when is_pid(Cm) ->
Timeout = proplists:get_value(timeout, Opts, infinity),
+ {_, SftpOpts} = handle_options(Opts, [], []),
case ssh_xfer:attach(Cm, []) of
{ok, ChannelId, Cm} ->
case ssh_channel:start(Cm, ChannelId,
- ?MODULE, [Cm, ChannelId, Timeout]) of
+ ?MODULE, [Cm, ChannelId, SftpOpts]) of
{ok, Pid} ->
case wait_for_version_negotiation(Pid, Timeout) of
ok ->
@@ -108,11 +122,12 @@ start_channel(Cm, Opts) when is_pid(Cm) ->
start_channel(Host, Opts) ->
start_channel(Host, 22, Opts).
start_channel(Host, Port, Opts) ->
- Timeout = proplists:get_value(timeout, Opts, infinity),
- case ssh_xfer:connect(Host, Port, proplists:delete(timeout, Opts)) of
+ {SshOpts, SftpOpts} = handle_options(Opts, [], []),
+ Timeout = proplists:get_value(timeout, SftpOpts, infinity),
+ case ssh_xfer:connect(Host, Port, SshOpts, Timeout) of
{ok, ChannelId, Cm} ->
case ssh_channel:start(Cm, ChannelId, ?MODULE, [Cm,
- ChannelId, Timeout]) of
+ ChannelId, SftpOpts]) of
{ok, Pid} ->
case wait_for_version_negotiation(Pid, Timeout) of
ok ->
@@ -159,6 +174,77 @@ open(Pid, File, Mode) ->
open(Pid, File, Mode, FileOpTimeout) ->
call(Pid, {open, false, File, Mode}, FileOpTimeout).
+open_tar(Pid, File, Mode) ->
+ open_tar(Pid, File, Mode, ?FILEOP_TIMEOUT).
+open_tar(Pid, File, Mode, FileOpTimeout) ->
+ case {lists:member(write,Mode),
+ lists:member(read,Mode),
+ Mode -- [read,write]} of
+ {true,false,[]} ->
+ {ok,Handle} = open(Pid, File, [write], FileOpTimeout),
+ erl_tar:init(Pid, write,
+ fun(write, {_,Data}) ->
+ write_to_remote_tar(Pid, Handle, to_bin(Data), FileOpTimeout);
+ (position, {_,Pos}) ->
+ position(Pid, Handle, Pos, FileOpTimeout);
+ (close, _) ->
+ close(Pid, Handle, FileOpTimeout)
+ end);
+ {true,false,[{crypto,{CryptoInitFun,CryptoEncryptFun,CryptoEndFun}}]} ->
+ {ok,SftpHandle} = open(Pid, File, [write], FileOpTimeout),
+ BI = #bufinf{mode = write,
+ crypto_fun = CryptoEncryptFun},
+ {ok,BufHandle} = open_buf(Pid, CryptoInitFun, BI, FileOpTimeout),
+ erl_tar:init(Pid, write,
+ fun(write, {_,Data}) ->
+ write_buf(Pid, SftpHandle, BufHandle, to_bin(Data), FileOpTimeout);
+ (position, {_,Pos}) ->
+ position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout);
+ (close, _) ->
+ {ok,#bufinf{
+ plain_text_buf = PlainBuf0,
+ enc_text_buf = EncBuf0,
+ crypto_state = CState0
+ }} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout),
+ {ok,EncTextTail} = CryptoEndFun(PlainBuf0, CState0),
+ EncTextBuf = <<EncBuf0/binary, EncTextTail/binary>>,
+ case write(Pid, SftpHandle, EncTextBuf, FileOpTimeout) of
+ ok ->
+ call(Pid, {erase_bufinf,BufHandle}, FileOpTimeout),
+ close(Pid, SftpHandle, FileOpTimeout);
+ Other ->
+ Other
+ end
+ end);
+ {false,true,[]} ->
+ {ok,Handle} = open(Pid, File, [read,binary], FileOpTimeout),
+ erl_tar:init(Pid, read,
+ fun(read2, {_,Len}) ->
+ read_repeat(Pid, Handle, Len, FileOpTimeout);
+ (position, {_,Pos}) ->
+ position(Pid, Handle, Pos, FileOpTimeout);
+ (close, _) ->
+ close(Pid, Handle, FileOpTimeout)
+ end);
+ {false,true,[{crypto,{CryptoInitFun,CryptoDecryptFun}}]} ->
+ {ok,SftpHandle} = open(Pid, File, [read,binary], FileOpTimeout),
+ BI = #bufinf{mode = read,
+ crypto_fun = CryptoDecryptFun},
+ {ok,BufHandle} = open_buf(Pid, CryptoInitFun, BI, FileOpTimeout),
+ erl_tar:init(Pid, read,
+ fun(read2, {_,Len}) ->
+ read_buf(Pid, SftpHandle, BufHandle, Len, FileOpTimeout);
+ (position, {_,Pos}) ->
+ position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout);
+ (close, _) ->
+ call(Pid, {erase_bufinf,BufHandle}, FileOpTimeout),
+ close(Pid, SftpHandle, FileOpTimeout)
+ end);
+ _ ->
+ {error,{illegal_mode,Mode}}
+ end.
+
+
opendir(Pid, Path) ->
opendir(Pid, Path, ?FILEOP_TIMEOUT).
opendir(Pid, Path, FileOpTimeout) ->
@@ -392,7 +478,8 @@ write_file_loop(Pid, Handle, Pos, Bin, Remain, PacketSz, FileOpTimeout) ->
%%
%% Description:
%%--------------------------------------------------------------------
-init([Cm, ChannelId, Timeout]) ->
+init([Cm, ChannelId, Options]) ->
+ Timeout = proplists:get_value(timeout, Options, infinity),
erlang:monitor(process, Cm),
case ssh_connection:subsystem(Cm, ChannelId, "sftp", Timeout) of
success ->
@@ -401,7 +488,8 @@ init([Cm, ChannelId, Timeout]) ->
{ok, #state{xf = Xf,
req_id = 0,
rep_buf = <<>>,
- inf = new_inf()}};
+ inf = new_inf(),
+ opts = Options}};
failure ->
{stop, "server failed to start sftp subsystem"};
Error ->
@@ -442,6 +530,15 @@ handle_cast(_,State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+do_handle_call({get_bufinf,BufHandle}, _From, S=#state{inf=I0}) ->
+ {reply, dict:find(BufHandle,I0), S};
+
+do_handle_call({put_bufinf,BufHandle,B}, _From, S=#state{inf=I0}) ->
+ {reply, ok, S#state{inf=dict:store(BufHandle,B,I0)}};
+
+do_handle_call({erase_bufinf,BufHandle}, _From, S=#state{inf=I0}) ->
+ {reply, ok, S#state{inf=dict:erase(BufHandle,I0)}};
+
do_handle_call({open, Async,FileName,Mode}, From, #state{xf = XF} = State) ->
{Access,Flags,Attrs} = open_mode(XF#ssh_xfer.vsn, Mode),
ReqID = State#state.req_id,
@@ -546,12 +643,7 @@ do_handle_call({read,Async,Handle,Length}, From, State) ->
do_handle_call({pwrite,Async,Handle,At,Data0}, From, State) ->
case lseek_position(Handle, At, State) of
{ok,Offset} ->
- Data = if
- is_binary(Data0) ->
- Data0;
- is_list(Data0) ->
- list_to_binary(Data0)
- end,
+ Data = to_bin(Data0),
ReqID = State#state.req_id,
Size = size(Data),
ssh_xfer:write(?XF(State),ReqID,Handle,Offset,Data),
@@ -564,12 +656,7 @@ do_handle_call({pwrite,Async,Handle,At,Data0}, From, State) ->
do_handle_call({write,Async,Handle,Data0}, From, State) ->
case lseek_position(Handle, cur, State) of
{ok,Offset} ->
- Data = if
- is_binary(Data0) ->
- Data0;
- is_list(Data0) ->
- list_to_binary(Data0)
- end,
+ Data = to_bin(Data0),
ReqID = State#state.req_id,
Size = size(Data),
ssh_xfer:write(?XF(State),ReqID,Handle,Offset,Data),
@@ -707,8 +794,9 @@ handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State0) ->
%%
%% Description: Handles channel messages
%%--------------------------------------------------------------------
-handle_msg({ssh_channel_up, _, _}, #state{xf = Xf} = State) ->
- ssh_xfer:protocol_version_request(Xf),
+handle_msg({ssh_channel_up, _, _}, #state{opts = Options, xf = Xf} = State) ->
+ Version = proplists:get_value(sftp_vsn, Options, ?SSH_SFTP_PROTOCOL_VERSION),
+ ssh_xfer:protocol_version_request(Xf, Version),
{ok, State};
%% Version negotiation timed out
@@ -754,6 +842,15 @@ terminate(_Reason, State) ->
%%====================================================================
%% Internal functions
%%====================================================================
+handle_options([], Sftp, Ssh) ->
+ {Ssh, Sftp};
+handle_options([{timeout, _} = Opt | Rest], Sftp, Ssh) ->
+ handle_options(Rest, [Opt | Sftp], Ssh);
+handle_options([{sftp_vsn, _} = Opt| Rest], Sftp, Ssh) ->
+ handle_options(Rest, [Opt | Sftp], Ssh);
+handle_options([Opt | Rest], Sftp, Ssh) ->
+ handle_options(Rest, Sftp, [Opt | Ssh]).
+
call(Pid, Msg, TimeOut) ->
ssh_channel:call(Pid, {{timeout, TimeOut}, Msg}, infinity).
@@ -1111,5 +1208,207 @@ lseek_pos({eof, Offset}, _CurOffset, CurSize)
end;
lseek_pos(_, _, _) ->
{error, einval}.
-
+%%%================================================================
+%%%
+to_bin(Data) when is_list(Data) -> list_to_binary(Data);
+to_bin(Data) when is_binary(Data) -> Data.
+
+
+read_repeat(Pid, Handle, Len, FileOpTimeout) ->
+ {ok,{_WindowSz,PacketSz}} = recv_window(Pid, FileOpTimeout),
+ read_rpt(Pid, Handle, Len, PacketSz, FileOpTimeout, <<>>).
+
+read_rpt(Pid, Handle, WantedLen, PacketSz, FileOpTimeout, Acc) when WantedLen > 0 ->
+ case read(Pid, Handle, min(WantedLen,PacketSz), FileOpTimeout) of
+ {ok, Data} ->
+ read_rpt(Pid, Handle, WantedLen-size(Data), PacketSz, FileOpTimeout, <<Acc/binary, Data/binary>>);
+ eof ->
+ {ok, Acc};
+ Error ->
+ Error
+ end;
+read_rpt(_Pid, _Handle, WantedLen, _PacketSz, _FileOpTimeout, Acc) when WantedLen >= 0 ->
+ {ok,Acc}.
+
+
+write_to_remote_tar(_Pid, _SftpHandle, <<>>, _FileOpTimeout) ->
+ ok;
+write_to_remote_tar(Pid, SftpHandle, Bin, FileOpTimeout) ->
+ {ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout),
+ write_file_loop(Pid, SftpHandle, 0, Bin, size(Bin), Packet, FileOpTimeout).
+
+position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout) ->
+ {ok,#bufinf{mode = Mode,
+ plain_text_buf = Buf0,
+ size = Size}} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout),
+ case Pos of
+ {cur,0} when Mode==write ->
+ {ok,Size+size(Buf0)};
+
+ {cur,0} when Mode==read ->
+ {ok,Size};
+
+ _ when Mode==read, is_integer(Pos) ->
+ Skip = Pos-Size,
+ if
+ Skip < 0 ->
+ {error, cannot_rewind};
+ Skip == 0 ->
+ %% Optimization
+ {ok,Pos};
+ Skip > 0 ->
+ case read_buf(Pid, SftpHandle, BufHandle, Skip, FileOpTimeout) of
+ %% A bit innefficient to fetch the bufinf again, but there are lots of
+ %% other more important optimizations waiting....
+ {ok,_} ->
+ {ok,Pos};
+ Other ->
+ Other
+ end
+ end;
+
+ _ ->
+ {error,{not_yet_implemented,{pos,Pos}}}
+ end.
+
+read_buf(Pid, SftpHandle, BufHandle, WantedLen, FileOpTimeout) ->
+ {ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout),
+ {ok,B0} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout),
+ case do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, B0) of
+ {ok,ResultBin,B} ->
+ call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout),
+ {ok,ResultBin};
+ {error,Error} ->
+ {error,Error};
+ {eof,B} ->
+ call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout),
+ eof
+ end.
+
+do_the_read_buf(_Pid, _SftpHandle, WantedLen, _Packet, _FileOpTimeout,
+ B=#bufinf{plain_text_buf=PlainBuf0,
+ size = Size})
+ when size(PlainBuf0) >= WantedLen ->
+ %% We already have the wanted number of bytes decoded and ready!
+ <<ResultBin:WantedLen/binary, PlainBuf/binary>> = PlainBuf0,
+ {ok,ResultBin,B#bufinf{plain_text_buf=PlainBuf,
+ size = Size + WantedLen}};
+
+do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ B0=#bufinf{plain_text_buf = PlainBuf0,
+ enc_text_buf = EncBuf0,
+ chunksize = undefined
+ })
+ when size(EncBuf0) > 0 ->
+ %% We have (at least) one decodable byte waiting for decodeing.
+ {ok,DecodedBin,B} = apply_crypto(EncBuf0, B0),
+ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ B#bufinf{plain_text_buf = <<PlainBuf0/binary, DecodedBin/binary>>,
+ enc_text_buf = <<>>
+ });
+
+do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ B0=#bufinf{plain_text_buf = PlainBuf0,
+ enc_text_buf = EncBuf0,
+ chunksize = ChunkSize0
+ })
+ when size(EncBuf0) >= ChunkSize0 ->
+ %% We have (at least) one chunk of decodable bytes waiting for decodeing.
+ <<ToDecode:ChunkSize0/binary, EncBuf/binary>> = EncBuf0,
+ {ok,DecodedBin,B} = apply_crypto(ToDecode, B0),
+ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ B#bufinf{plain_text_buf = <<PlainBuf0/binary, DecodedBin/binary>>,
+ enc_text_buf = EncBuf
+ });
+
+do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, B=#bufinf{enc_text_buf = EncBuf0}) ->
+ %% We must read more bytes and append to the buffer of encoded bytes.
+ case read(Pid, SftpHandle, Packet, FileOpTimeout) of
+ {ok,EncryptedBin} ->
+ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ B#bufinf{enc_text_buf = <<EncBuf0/binary, EncryptedBin/binary>>});
+ eof ->
+ {eof,B};
+ Other ->
+ Other
+ end.
+
+
+write_buf(Pid, SftpHandle, BufHandle, PlainBin, FileOpTimeout) ->
+ {ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout),
+ {ok,B0=#bufinf{plain_text_buf=PTB}} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout),
+ case do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B0#bufinf{plain_text_buf = <<PTB/binary,PlainBin/binary>>}) of
+ {ok, B} ->
+ call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout),
+ ok;
+ {error,Error} ->
+ {error,Error}
+ end.
+
+do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B=#bufinf{enc_text_buf = EncBuf0,
+ size = Size})
+ when size(EncBuf0) >= Packet ->
+ <<BinToWrite:Packet/binary, EncBuf/binary>> = EncBuf0,
+ case write(Pid, SftpHandle, BinToWrite, FileOpTimeout) of
+ ok ->
+ do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B#bufinf{enc_text_buf = EncBuf,
+ size = Size + Packet});
+ Other ->
+ Other
+ end;
+
+do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B0=#bufinf{plain_text_buf = PlainBuf0,
+ enc_text_buf = EncBuf0,
+ chunksize = undefined})
+ when size(PlainBuf0) > 0 ->
+ {ok,EncodedBin,B} = apply_crypto(PlainBuf0, B0),
+ do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B#bufinf{plain_text_buf = <<>>,
+ enc_text_buf = <<EncBuf0/binary, EncodedBin/binary>>});
+
+do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B0=#bufinf{plain_text_buf = PlainBuf0,
+ enc_text_buf = EncBuf0,
+ chunksize = ChunkSize0
+ })
+ when size(PlainBuf0) >= ChunkSize0 ->
+ <<ToEncode:ChunkSize0/binary, PlainBuf/binary>> = PlainBuf0,
+ {ok,EncodedBin,B} = apply_crypto(ToEncode, B0),
+ do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ B#bufinf{plain_text_buf = PlainBuf,
+ enc_text_buf = <<EncBuf0/binary, EncodedBin/binary>>});
+
+do_the_write_buf(_Pid, _SftpHandle, _Packet, _FileOpTimeout, B) ->
+ {ok,B}.
+
+apply_crypto(In, B=#bufinf{crypto_state = CState0,
+ crypto_fun = F}) ->
+ case F(In,CState0) of
+ {ok,EncodedBin,CState} ->
+ {ok, EncodedBin, B#bufinf{crypto_state=CState}};
+ {ok,EncodedBin,CState,ChunkSize} ->
+ {ok, EncodedBin, B#bufinf{crypto_state=CState,
+ chunksize=ChunkSize}}
+ end.
+
+open_buf(Pid, CryptoInitFun, BufInfo0, FileOpTimeout) ->
+ case CryptoInitFun() of
+ {ok,CryptoState} ->
+ open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, undefined);
+ {ok,CryptoState,ChunkSize} ->
+ open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, ChunkSize);
+ Other ->
+ Other
+ end.
+
+open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, ChunkSize) ->
+ BufInfo = BufInfo0#bufinf{crypto_state = CryptoState,
+ chunksize = ChunkSize},
+ BufHandle = make_ref(),
+ call(Pid, {put_bufinf,BufHandle,BufInfo}, FileOpTimeout),
+ {ok,BufHandle}.
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 52665635f0..04ae6b11e2 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. 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
@@ -559,56 +559,73 @@ stat(ReqId, RelPath, State0=#state{file_handler=FileMod,
send_status({error, E}, ReqId, State1)
end.
-decode_4_open_flag(create_new) ->
- [write];
-decode_4_open_flag(create_truncate) ->
- [write];
-decode_4_open_flag(truncate_existing) ->
- [write];
-decode_4_open_flag(open_existing) ->
- [read].
-
-decode_4_flags([OpenFlag | Flags]) ->
- decode_4_flags(Flags, decode_4_open_flag(OpenFlag)).
-
-decode_4_flags([], Flags) ->
- Flags;
-decode_4_flags([append_data|R], _Flags) ->
- decode_4_flags(R, [append]);
-decode_4_flags([append_data_atomic|R], _Flags) ->
- decode_4_flags(R, [append]);
-decode_4_flags([_|R], Flags) ->
- decode_4_flags(R, Flags).
-
-decode_4_access_flag(read_data) ->
- [read];
-decode_4_access_flag(list_directory) ->
- [read];
-decode_4_access_flag(write_data) ->
- [write];
-decode_4_access_flag(add_file) ->
- [write];
-decode_4_access_flag(add_subdirectory) ->
- [read];
-decode_4_access_flag(append_data) ->
- [append];
-decode_4_access_flag(write_attributes) ->
- [write];
-decode_4_access_flag(_) ->
- [read].
-
-decode_4_acess([_ | _] = Flags) ->
+sftp_to_erlang_flag(read, Vsn) when Vsn == 3;
+ Vsn == 4 ->
+ read;
+sftp_to_erlang_flag(write, Vsn) when Vsn == 3;
+ Vsn == 4 ->
+ write;
+sftp_to_erlang_flag(append, Vsn) when Vsn == 3;
+ Vsn == 4 ->
+ append;
+sftp_to_erlang_flag(creat, Vsn) when Vsn == 3;
+ Vsn == 4 ->
+ write;
+sftp_to_erlang_flag(trunc, Vsn) when Vsn == 3;
+ Vsn == 4 ->
+ write;
+sftp_to_erlang_flag(excl, Vsn) when Vsn == 3;
+ Vsn == 4 ->
+ read;
+sftp_to_erlang_flag(create_new, Vsn) when Vsn > 4 ->
+ write;
+sftp_to_erlang_flag(create_truncate, Vsn) when Vsn > 4 ->
+ write;
+sftp_to_erlang_flag(open_existing, Vsn) when Vsn > 4 ->
+ read;
+sftp_to_erlang_flag(open_or_create, Vsn) when Vsn > 4 ->
+ write;
+sftp_to_erlang_flag(truncate_existing, Vsn) when Vsn > 4 ->
+ write;
+sftp_to_erlang_flag(append_data, Vsn) when Vsn > 4 ->
+ append;
+sftp_to_erlang_flag(append_data_atomic, Vsn) when Vsn > 4 ->
+ append;
+sftp_to_erlang_flag(_, _) ->
+ read.
+
+sftp_to_erlang_flags(Flags, Vsn) ->
lists:map(fun(Flag) ->
- [decode_4_access_flag(Flag)]
- end, Flags);
-decode_4_acess([]) ->
- [].
+ sftp_to_erlang_flag(Flag, Vsn)
+ end, Flags).
+
+sftp_to_erlang_access_flag(read_data, _) ->
+ read;
+sftp_to_erlang_access_flag(list_directory, _) ->
+ read;
+sftp_to_erlang_access_flag(write_data, _) ->
+ write;
+sftp_to_erlang_access_flag(append_data, _) ->
+ append;
+sftp_to_erlang_access_flag(add_subdirectory, _) ->
+ read;
+sftp_to_erlang_access_flag(add_file, _) ->
+ write;
+sftp_to_erlang_access_flag(write_attributes, _) ->
+ write;
+sftp_to_erlang_access_flag(_, _) ->
+ read.
+sftp_to_erlang_access_flags(Flags, Vsn) ->
+ lists:map(fun(Flag) ->
+ sftp_to_erlang_access_flag(Flag, Vsn)
+ end, Flags).
open(Vsn, ReqId, Data, State) when Vsn =< 3 ->
<<?UINT32(BLen), BPath:BLen/binary, ?UINT32(PFlags),
_Attrs/binary>> = Data,
Path = unicode:characters_to_list(BPath),
- Flags = ssh_xfer:decode_open_flags(Vsn, PFlags),
+ FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags),
+ Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn)),
do_open(ReqId, State, Path, Flags);
open(Vsn, ReqId, Data, State) when Vsn >= 4 ->
<<?UINT32(BLen), BPath:BLen/binary, ?UINT32(Access),
@@ -616,15 +633,12 @@ open(Vsn, ReqId, Data, State) when Vsn >= 4 ->
Path = unicode:characters_to_list(BPath),
FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags),
AcessBits = ssh_xfer:decode_ace_mask(Access),
- %% TODO: This is to make sure the Access flags are not ignored
- %% but this should be thought through better. This solution should
- %% be considered a hack in order to buy some time. At least
- %% it works better than when the Access flags where totally ignored.
- %% A better solution may need some code refactoring that we do
- %% not have time for right now.
- AcessFlags = decode_4_acess(AcessBits),
- Flags = lists:append(lists:umerge(
- [[decode_4_flags(FlagBits)] | AcessFlags])),
+ %% TODO: There are still flags that are not
+ %% fully handled as SSH_FXF_ACCESS_TEXT_MODE and
+ %% a lot a ACE flags, the later we may not need
+ %% to understand as they are NFS flags
+ AcessFlags = sftp_to_erlang_access_flags(AcessBits, Vsn),
+ Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn) ++ AcessFlags),
do_open(ReqId, State, Path, Flags).
do_open(ReqId, State0, Path, Flags) ->
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index 848133f838..660fe8bb65 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.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
@@ -173,8 +173,8 @@ ssh_acceptor_sup([_ | Rest]) ->
ssh_acceptor_sup(Rest).
stop_acceptor(Sup) ->
- [Name] =
- [SupName || {SupName, _, _, [ssh_acceptor_sup]} <-
+ [{Name, AcceptorSup}] =
+ [{SupName, ASup} || {SupName, ASup, _, [ssh_acceptor_sup]} <-
supervisor:which_children(Sup)],
- supervisor:terminate_child(Sup, Name).
+ supervisor:terminate_child(AcceptorSup, Name).
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 27723dc870..76fa776113 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.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
@@ -82,16 +82,21 @@ format_version({Major,Minor}) ->
integer_to_list(Minor) ++ "-Erlang".
handle_hello_version(Version) ->
- StrVersion = trim_tail(Version),
- case string:tokens(Version, "-") of
- [_, "2.0" | _] ->
- {{2,0}, StrVersion};
- [_, "1.99" | _] ->
- {{2,0}, StrVersion};
- [_, "1.3" | _] ->
- {{1,3}, StrVersion};
- [_, "1.5" | _] ->
- {{1,5}, StrVersion}
+ try
+ StrVersion = trim_tail(Version),
+ case string:tokens(Version, "-") of
+ [_, "2.0" | _] ->
+ {{2,0}, StrVersion};
+ [_, "1.99" | _] ->
+ {{2,0}, StrVersion};
+ [_, "1.3" | _] ->
+ {{1,3}, StrVersion};
+ [_, "1.5" | _] ->
+ {{1,5}, StrVersion}
+ end
+ catch
+ error:_ ->
+ {undefined, "unknown version"}
end.
key_exchange_init_msg(Ssh0) ->
@@ -113,15 +118,28 @@ key_init(client, Ssh, Value) ->
key_init(server, Ssh, Value) ->
Ssh#ssh{s_keyinit = Value}.
+available_ssh_algos() ->
+ Supports = crypto:supports(),
+ CipherAlgos = [{aes_ctr, "aes128-ctr"}, {aes_cbc128, "aes128-cbc"}, {des3_cbc, "3des-cbc"}],
+ Ciphers = [SshAlgo ||
+ {CryptoAlgo, SshAlgo} <- CipherAlgos,
+ lists:member(CryptoAlgo, proplists:get_value(ciphers, Supports, []))],
+ HashAlgos = [{sha256, "hmac-sha2-256"}, {sha, "hmac-sha1"}],
+ Hashs = [SshAlgo ||
+ {CryptoAlgo, SshAlgo} <- HashAlgos,
+ lists:member(CryptoAlgo, proplists:get_value(hashs, Supports, []))],
+ {Ciphers, Hashs}.
+
kexinit_messsage(client, Random, Compression, HostKeyAlgs) ->
+ {CipherAlgs, HashAlgs} = available_ssh_algos(),
#ssh_msg_kexinit{
cookie = Random,
kex_algorithms = ["diffie-hellman-group1-sha1"],
server_host_key_algorithms = HostKeyAlgs,
- encryption_algorithms_client_to_server = ["aes128-cbc","3des-cbc"],
- encryption_algorithms_server_to_client = ["aes128-cbc","3des-cbc"],
- mac_algorithms_client_to_server = ["hmac-sha1"],
- mac_algorithms_server_to_client = ["hmac-sha1"],
+ encryption_algorithms_client_to_server = CipherAlgs,
+ encryption_algorithms_server_to_client = CipherAlgs,
+ mac_algorithms_client_to_server = HashAlgs,
+ mac_algorithms_server_to_client = HashAlgs,
compression_algorithms_client_to_server = Compression,
compression_algorithms_server_to_client = Compression,
languages_client_to_server = [],
@@ -129,14 +147,15 @@ kexinit_messsage(client, Random, Compression, HostKeyAlgs) ->
};
kexinit_messsage(server, Random, Compression, HostKeyAlgs) ->
+ {CipherAlgs, HashAlgs} = available_ssh_algos(),
#ssh_msg_kexinit{
cookie = Random,
kex_algorithms = ["diffie-hellman-group1-sha1"],
server_host_key_algorithms = HostKeyAlgs,
- encryption_algorithms_client_to_server = ["aes128-cbc","3des-cbc"],
- encryption_algorithms_server_to_client = ["aes128-cbc","3des-cbc"],
- mac_algorithms_client_to_server = ["hmac-sha1"],
- mac_algorithms_server_to_client = ["hmac-sha1"],
+ encryption_algorithms_client_to_server = CipherAlgs,
+ encryption_algorithms_server_to_client = CipherAlgs,
+ mac_algorithms_client_to_server = HashAlgs,
+ mac_algorithms_server_to_client = HashAlgs,
compression_algorithms_client_to_server = Compression,
compression_algorithms_server_to_client = Compression,
languages_client_to_server = [],
@@ -636,7 +655,21 @@ encrypt_init(#ssh{encrypt = 'aes128-cbc', role = server} = Ssh) ->
<<K:16/binary>> = hash(Ssh, "D", 128),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
- encrypt_ctx = IV}}.
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'aes128-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes128-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}}.
encrypt_final(Ssh) ->
{ok, Ssh#ssh{encrypt = none,
@@ -658,7 +691,11 @@ encrypt(#ssh{encrypt = 'aes128-cbc',
encrypt_ctx = IV0} = Ssh, Data) ->
Enc = crypto:block_encrypt(aes_cbc128, K,IV0,Data),
IV = crypto:next_iv(aes_cbc, Enc),
- {Ssh#ssh{encrypt_ctx = IV}, Enc}.
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
+encrypt(#ssh{encrypt = 'aes128-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -690,7 +727,21 @@ decrypt_init(#ssh{decrypt = 'aes128-cbc', role = server} = Ssh) ->
hash(Ssh, "C", 128)},
<<K:16/binary>> = KD,
{ok, Ssh#ssh{decrypt_keys = K, decrypt_ctx = IV,
- decrypt_block_size = 16}}.
+ decrypt_block_size = 16}};
+decrypt_init(#ssh{decrypt = 'aes128-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes128-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}}.
decrypt_final(Ssh) ->
@@ -711,7 +762,11 @@ decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key,
decrypt_ctx = IV0} = Ssh, Data) ->
Dec = crypto:block_decrypt(aes_cbc128, Key,IV0,Data),
IV = crypto:next_iv(aes_cbc, Data),
- {Ssh#ssh{decrypt_ctx = IV}, Dec}.
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
+decrypt(#ssh{decrypt = 'aes128-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compression
@@ -846,7 +901,9 @@ mac('hmac-sha1-96', Key, SeqNum, Data) ->
mac('hmac-md5', Key, SeqNum, Data) ->
crypto:hmac(md5, Key, [<<?UINT32(SeqNum)>>, Data]);
mac('hmac-md5-96', Key, SeqNum, Data) ->
- crypto:hmac(md5, Key, [<<?UINT32(SeqNum)>>, Data], mac_digest_size('hmac-md5-96')).
+ crypto:hmac(md5, Key, [<<?UINT32(SeqNum)>>, Data], mac_digest_size('hmac-md5-96'));
+mac('hmac-sha2-256', Key, SeqNum, Data) ->
+ crypto:hmac(sha256, Key, [<<?UINT32(SeqNum)>>, Data]).
%% return N hash bytes (HASH)
hash(SSH, Char, Bits) ->
@@ -911,12 +968,14 @@ mac_key_size('hmac-sha1') -> 20*8;
mac_key_size('hmac-sha1-96') -> 20*8;
mac_key_size('hmac-md5') -> 16*8;
mac_key_size('hmac-md5-96') -> 16*8;
+mac_key_size('hmac-sha2-256')-> 32*8;
mac_key_size(none) -> 0.
mac_digest_size('hmac-sha1') -> 20;
mac_digest_size('hmac-sha1-96') -> 12;
mac_digest_size('hmac-md5') -> 20;
mac_digest_size('hmac-md5-96') -> 12;
+mac_digest_size('hmac-sha2-256') -> 32;
mac_digest_size(none) -> 0.
peer_name({Host, _}) ->
diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl
index 63d01fd9de..2743b704f1 100644
--- a/lib/ssh/src/ssh_xfer.erl
+++ b/lib/ssh/src/ssh_xfer.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,12 +23,12 @@
-module(ssh_xfer).
--export([attach/2, connect/3]).
+-export([attach/2, connect/3, connect/4]).
-export([open/6, opendir/3, readdir/3, close/3, read/5, write/5,
rename/5, remove/3, mkdir/4, rmdir/3, realpath/3, extended/4,
stat/4, fstat/4, lstat/4, setstat/4,
readlink/3, fsetstat/4, symlink/4,
- protocol_version_request/1,
+ protocol_version_request/2,
xf_reply/2,
xf_send_reply/3, xf_send_names/3, xf_send_name/4,
xf_send_status/3, xf_send_status/4, xf_send_status/5,
@@ -58,6 +58,13 @@ connect(Host, Port, Opts) ->
Error -> Error
end.
+connect(Host, Port, Opts, Timeout) ->
+ case ssh:connect(Host, Port, Opts, Timeout) of
+ {ok, CM} -> open_xfer(CM, [{timeout, Timeout}|Opts]);
+ {error, Timeout} -> {error, timeout};
+ Error -> Error
+ end.
+
open_xfer(CM, Opts) ->
TMO = proplists:get_value(timeout, Opts, infinity),
case ssh_connection:session_channel(CM, ?XFER_WINDOW_SIZE, ?XFER_PACKET_SIZE, TMO) of
@@ -67,8 +74,8 @@ open_xfer(CM, Opts) ->
Error
end.
-protocol_version_request(XF) ->
- xf_request(XF, ?SSH_FXP_INIT, <<?UINT32(?SSH_SFTP_PROTOCOL_VERSION)>>).
+protocol_version_request(XF, Version) ->
+ xf_request(XF, ?SSH_FXP_INIT, <<?UINT32(Version)>>).
open(XF, ReqID, FileName, Access, Flags, Attrs) ->
Vsn = XF#ssh_xfer.vsn,
diff --git a/lib/ssh/test/property_test/README b/lib/ssh/test/property_test/README
new file mode 100644
index 0000000000..57602bf719
--- /dev/null
+++ b/lib/ssh/test/property_test/README
@@ -0,0 +1,12 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The test in this directory are written assuming that the user has a QuickCheck license. They are to be run manually. Some may be possible to be run with other tools, e.g. PropEr.
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server.erl b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
new file mode 100644
index 0000000000..123b48412b
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
@@ -0,0 +1,618 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ssh_eqc_client_server).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-ifdef(PROPER).
+%% Proper is not supported.
+-else.
+-ifdef(TRIQ).
+%% Proper is not supported.
+-else.
+
+
+%% Limit the testing time on CI server... this needs to be improved in % from total budget.
+-define(TESTINGTIME(Prop), eqc:testing_time(30,Prop)).
+
+
+-include_lib("eqc/include/eqc.hrl").
+-include_lib("eqc/include/eqc_statem.hrl").
+-eqc_group_commands(true).
+
+-define(SSH_DIR,"ssh_eqc_client_server_dirs").
+
+-define(sec, *1000).
+-define(min, *60?sec).
+
+-record(srvr,{ref,
+ address,
+ port
+ }).
+
+-record(conn,{ref,
+ srvr_ref
+ }).
+
+-record(chan, {ref,
+ conn_ref,
+ subsystem,
+ client_pid
+ }).
+
+-record(state,{
+ initialized = false,
+ servers = [], % [#srvr{}]
+ clients = [],
+ connections = [], % [#conn{}]
+ channels = [], % [#chan{}]
+ data_dir
+ }).
+
+%%%===============================================================
+%%%
+%%% Specification of addresses, subsystems and such.
+%%%
+
+-define(MAX_NUM_SERVERS, 3).
+-define(MAX_NUM_CLIENTS, 3).
+
+-define(SUBSYSTEMS, ["echo1", "echo2", "echo3", "echo4"]).
+
+-define(SERVER_ADDRESS, { {127,1,0,choose(1,254)}, % IP
+ choose(1024,65535) % Port
+ }).
+
+-define(SERVER_EXTRA_OPTIONS, [{parallel_login,bool()}] ).
+
+
+%%%================================================================
+%%%
+%%% The properties - one sequantial and one parallel with the same model
+%%%
+%%% Run as
+%%%
+%%% $ (cd ..; make)
+%%% $ erl -pz ..
+%%%
+%%% eqc:quickcheck( ssh_eqc_client_server:prop_seq() ).
+%%% eqc:quickcheck( ssh_eqc_client_server:prop_parallel() ).
+%%% eqc:quickcheck( ssh_eqc_client_server:prop_parallel_multi() ).
+%%%
+
+
+%% To be called as eqc:quickcheck( ssh_eqc_client_server:prop_seq() ).
+prop_seq() ->
+ ?TESTINGTIME(do_prop_seq(?SSH_DIR)).
+
+%% To be called from a common_test test suite
+prop_seq(CT_Config) ->
+ do_prop_seq(full_path(?SSH_DIR, CT_Config)).
+
+
+do_prop_seq(DataDir) ->
+ setup_rsa(DataDir),
+ ?FORALL(Cmds,commands(?MODULE),
+ begin
+ {H,Sf,Result} = run_commands(?MODULE,Cmds,[{data_dir,DataDir}]),
+ present_result(?MODULE, Cmds, {H,Sf,Result}, Result==ok)
+ end).
+
+full_path(SSHdir, CT_Config) ->
+ filename:join(proplists:get_value(property_dir, CT_Config),
+ SSHdir).
+%%%----
+prop_parallel() ->
+ ?TESTINGTIME(do_prop_parallel(?SSH_DIR)).
+
+%% To be called from a common_test test suite
+prop_parallel(CT_Config) ->
+ do_prop_parallel(full_path(?SSH_DIR, CT_Config)).
+
+do_prop_parallel(DataDir) ->
+ setup_rsa(DataDir),
+ ?FORALL(Cmds,parallel_commands(?MODULE),
+ begin
+ {H,Sf,Result} = run_parallel_commands(?MODULE,Cmds,[{data_dir,DataDir}]),
+ present_result(?MODULE, Cmds, {H,Sf,Result}, Result==ok)
+ end).
+
+%%%----
+prop_parallel_multi() ->
+ ?TESTINGTIME(do_prop_parallel_multi(?SSH_DIR)).
+
+%% To be called from a common_test test suite
+prop_parallel_multi(CT_Config) ->
+ do_prop_parallel_multi(full_path(?SSH_DIR, CT_Config)).
+
+do_prop_parallel_multi(DataDir) ->
+ setup_rsa(DataDir),
+ ?FORALL(Repetitions,?SHRINK(1,[10]),
+ ?FORALL(Cmds,parallel_commands(?MODULE),
+ ?ALWAYS(Repetitions,
+ begin
+ {H,Sf,Result} = run_parallel_commands(?MODULE,Cmds,[{data_dir,DataDir}]),
+ present_result(?MODULE, Cmds, {H,Sf,Result}, Result==ok)
+ end))).
+
+%%%================================================================
+%%% State machine spec
+
+%%% called when using commands/1
+initial_state() ->
+ #state{}.
+
+%%% called when using commands/2
+initial_state(DataDir) ->
+ application:stop(ssh),
+ ssh:start().
+
+%%%----------------
+weight(S, ssh_send) -> 5*length([C || C<-S#state.channels, has_subsyst(C)]);
+weight(S, ssh_start_subsyst) -> 3*length([C || C<-S#state.channels, no_subsyst(C)]);
+weight(S, ssh_close_channel) -> 2*length([C || C<-S#state.channels, has_subsyst(C)]);
+weight(S, ssh_open_channel) -> length(S#state.connections);
+weight(_S, _) -> 1.
+
+%%%----------------
+%%% Initialize
+
+initial_state_pre(S) -> not S#state.initialized.
+
+initial_state_args(_) -> [{var,data_dir}].
+
+initial_state_next(S, _, _) -> S#state{initialized=true}.
+
+%%%----------------
+%%% Start a new daemon
+%%% Precondition: not more than ?MAX_NUM_SERVERS started
+
+%%% This is a bit funny because we need to pick an IP address and Port to
+%%% run the server on, but there is no way to atomically select a free Port!
+%%%
+%%% Therefore we just grab one IP-Port pair randomly and try to start the ssh server
+%%% on that pair. If it fails, we just forget about it and goes on. Yes, it
+%%% is a waste of cpu cycles, but at least it works!
+
+ssh_server_pre(S) -> S#state.initialized andalso
+ length(S#state.servers) < ?MAX_NUM_SERVERS.
+
+ssh_server_args(_) -> [?SERVER_ADDRESS, {var,data_dir}, ?SERVER_EXTRA_OPTIONS].
+
+ssh_server({IP,Port}, DataDir, ExtraOptions) ->
+ ok(ssh:daemon(IP, Port,
+ [
+ {system_dir, system_dir(DataDir)},
+ {user_dir, user_dir(DataDir)},
+ {subsystems, [{SS, {ssh_eqc_subsys, [SS]}} || SS <- ?SUBSYSTEMS]}
+ | ExtraOptions
+ ])).
+
+ssh_server_post(_S, _Args, {error,eaddrinuse}) -> true;
+ssh_server_post(_S, _Args, Result) -> is_ok(Result).
+
+ssh_server_next(S, {error,eaddrinuse}, _) -> S;
+ssh_server_next(S, Result, [{IP,Port},_,_]) ->
+ S#state{servers=[#srvr{ref = Result,
+ address = IP,
+ port = Port}
+ | S#state.servers]}.
+
+%%%----------------
+%%% Start a new client
+%%% Precondition: not more than ?MAX_NUM_CLIENTS started
+
+ssh_client_pre(S) -> S#state.initialized andalso
+ length(S#state.clients) < ?MAX_NUM_CLIENTS.
+
+ssh_client_args(_S) -> [].
+
+ssh_client() -> spawn(fun client_init/0).
+
+ssh_client_next(S, Pid, _) -> S#state{clients=[Pid|S#state.clients]}.
+
+
+client_init() -> client_loop().
+
+client_loop() ->
+ receive
+ {please_do,Fun,Ref,Pid} ->
+ Pid ! {my_pleasure, catch Fun(), Ref},
+ client_loop()
+ end.
+
+do(Pid, Fun) -> do(Pid, Fun, 30?sec).
+
+do(Pid, Fun, Timeout) when is_function(Fun,0) ->
+ Pid ! {please_do,Fun,Ref=make_ref(),self()},
+ receive
+ {my_pleasure, Result, Ref} -> Result
+ after
+ Timeout -> {error,do_timeout}
+ end.
+
+%%%----------------
+%%% Start a new connection
+%%% Precondition: deamon exists
+
+ssh_open_connection_pre(S) -> S#state.servers /= [].
+
+ssh_open_connection_args(S) -> [oneof(S#state.servers), {var,data_dir}].
+
+ssh_open_connection(#srvr{address=Ip, port=Port}, DataDir) ->
+ ok(ssh:connect(ensure_string(Ip), Port,
+ [
+ {silently_accept_hosts, true},
+ {user_dir, user_dir(DataDir)},
+ {user_interaction, false},
+ {connect_timeout, 2000}
+ ], 2000)).
+
+ssh_open_connection_post(_S, _Args, Result) -> is_ok(Result).
+
+ssh_open_connection_next(S, ConnRef, [#srvr{ref=SrvrRef},_]) ->
+ S#state{connections=[#conn{ref=ConnRef, srvr_ref=SrvrRef}|S#state.connections]}.
+
+%%%----------------
+%%% Stop a new connection
+%%% Precondition: connection exists
+
+ssh_close_connection_pre(S) -> S#state.connections /= [].
+
+ssh_close_connection_args(S) -> [oneof(S#state.connections)].
+
+ssh_close_connection(#conn{ref=ConnectionRef}) -> ssh:close(ConnectionRef).
+
+ssh_close_connection_next(S, _, [Conn=#conn{ref=ConnRef}]) ->
+ S#state{connections = S#state.connections--[Conn],
+ channels = [C || C <- S#state.channels,
+ C#chan.conn_ref /= ConnRef]
+ }.
+
+%%%----------------
+%%% Start a new channel without a sub system
+%%% Precondition: connection exists
+
+ssh_open_channel_pre(S) -> S#state.connections /= [].
+
+ssh_open_channel_args(S) -> [oneof(S#state.connections)].
+
+%%% For re-arrangement in parallel tests.
+ssh_open_channel_pre(S,[C]) -> lists:member(C,S#state.connections).
+
+ssh_open_channel(#conn{ref=ConnectionRef}) ->
+ ok(ssh_connection:session_channel(ConnectionRef, 20?sec)).
+
+ssh_open_channel_post(_S, _Args, Result) -> is_ok(Result).
+
+ssh_open_channel_next(S, ChannelRef, [#conn{ref=ConnRef}]) ->
+ S#state{channels=[#chan{ref=ChannelRef,
+ conn_ref=ConnRef}
+ | S#state.channels]}.
+
+%%%----------------
+%%% Stop a channel
+%%% Precondition: a channel exists, with or without a subsystem
+
+ssh_close_channel_pre(S) -> S#state.channels /= [].
+
+ssh_close_channel_args(S) -> [oneof(S#state.channels)].
+
+ssh_close_channel(#chan{ref=ChannelRef, conn_ref=ConnectionRef}) ->
+ ssh_connection:close(ConnectionRef, ChannelRef).
+
+ssh_close_channel_next(S, _, [C]) ->
+ S#state{channels = [Ci || Ci <- S#state.channels,
+ sig(C) /= sig(Ci)]}.
+
+
+sig(C) -> {C#chan.ref, C#chan.conn_ref}.
+
+
+%%%----------------
+%%% Start a sub system on a channel
+%%% Precondition: A channel without subsystem exists
+
+ssh_start_subsyst_pre(S) -> lists:any(fun no_subsyst/1, S#state.channels) andalso
+ S#state.clients /= [].
+
+ssh_start_subsyst_args(S) -> [oneof(lists:filter(fun no_subsyst/1, S#state.channels)),
+ oneof(?SUBSYSTEMS),
+ oneof(S#state.clients)
+ ].
+
+%% For re-arrangement in parallel tests.
+ssh_start_subsyst_pre(S, [C|_]) -> lists:member(C,S#state.channels)
+ andalso no_subsyst(C).
+
+ssh_start_subsyst(#chan{ref=ChannelRef, conn_ref=ConnectionRef}, SubSystem, Pid) ->
+ do(Pid, fun()->ssh_connection:subsystem(ConnectionRef, ChannelRef, SubSystem, 120?sec) end).
+
+ssh_start_subsyst_post(_S, _Args, Result) -> Result==success.
+
+ssh_start_subsyst_next(S, _Result, [C,SS,Pid|_]) ->
+ S#state{channels = [C#chan{subsystem=SS,
+ client_pid=Pid}|(S#state.channels--[C])] }.
+
+%%%----------------
+%%% Send a message on a channel
+%%% Precondition: a channel exists with a subsystem connected
+
+ssh_send_pre(S) -> lists:any(fun has_subsyst/1, S#state.channels).
+
+ssh_send_args(S) -> [oneof(lists:filter(fun has_subsyst/1, S#state.channels)),
+ choose(0,1),
+ message()].
+
+%% For re-arrangement in parallel tests.
+ssh_send_pre(S, [C|_]) -> lists:member(C, S#state.channels).
+
+ssh_send(C=#chan{conn_ref=ConnectionRef, ref=ChannelRef, client_pid=Pid}, Type, Msg) ->
+ do(Pid,
+ fun() ->
+ case ssh_connection:send(ConnectionRef, ChannelRef, Type, modify_msg(C,Msg), 10?sec) of
+ ok ->
+ receive
+ {ssh_cm,ConnectionRef,{data,ChannelRef,Type,Answer}} -> Answer
+ after 15?sec ->
+ %% receive
+ %% Other -> {error,{unexpected,Other}}
+ %% after 0 ->
+ {error,receive_timeout}
+ %% end
+ end;
+ Other ->
+ Other
+ end
+ end).
+
+ssh_send_blocking(_S, _Args) ->
+ true.
+
+ssh_send_post(_S, [C,_,Msg], Response) when is_binary(Response) ->
+ Expected = ssh_eqc_subsys:response(modify_msg(C,Msg), C#chan.subsystem),
+ case Response of
+ Expected -> true;
+ _ -> {send_failed, size(Response), size(Expected)}
+ end;
+
+ssh_send_post(_S, _Args, Response) ->
+ {error,Response}.
+
+
+modify_msg(_, <<>>) -> <<>>;
+modify_msg(#chan{subsystem=SS}, Msg) -> <<(list_to_binary(SS))/binary,Msg/binary>>.
+
+%%%================================================================
+%%% Misc functions
+
+message() ->
+ resize(500, binary()).
+
+ %% binary().
+
+ %% oneof([binary(),
+ %% ?LET(Size, choose(0,10000), binary(Size))
+ %% ]).
+
+has_subsyst(C) -> C#chan.subsystem /= undefined.
+
+no_subsyst(C) -> not has_subsyst(C).
+
+
+ok({ok,X}) -> X;
+ok({error,Err}) -> {error,Err}.
+
+is_ok({error,_}) -> false;
+is_ok(_) -> true.
+
+ensure_string({A,B,C,D}) -> lists:flatten(io_lib:format("~w.~w.~w.~w",[A,B,C,D]));
+ensure_string(X) -> X.
+
+%%%----------------------------------------------------------------
+present_result(_Module, Cmds, _Triple, true) ->
+ aggregate(with_title("Distribution sequential/parallel"), sequential_parallel(Cmds),
+ aggregate(with_title("Function calls"), cmnd_names(Cmds),
+ aggregate(with_title("Message sizes"), empty_msgs(Cmds),
+ aggregate(print_frequencies(), message_sizes(Cmds),
+ aggregate(title("Length of command sequences",print_frequencies()), num_calls(Cmds),
+ true)))));
+
+present_result(Module, Cmds, Triple, false) ->
+ pretty_commands(Module, Cmds, Triple, [{show_states,true}], false).
+
+
+
+cmnd_names(Cs) -> traverse_commands(fun cmnd_name/1, Cs).
+cmnd_name(L) -> [F || {set,_Var,{call,_Mod,F,_As}} <- L].
+
+empty_msgs(Cs) -> traverse_commands(fun empty_msg/1, Cs).
+empty_msg(L) -> [empty || {set,_,{call,_,ssh_send,[_,_,Msg]}} <- L,
+ size(Msg)==0].
+
+message_sizes(Cs) -> traverse_commands(fun message_size/1, Cs).
+message_size(L) -> [size(Msg) || {set,_,{call,_,ssh_send,[_,_,Msg]}} <- L].
+
+num_calls(Cs) -> traverse_commands(fun num_call/1, Cs).
+num_call(L) -> [length(L)].
+
+sequential_parallel(Cs) ->
+ traverse_commands(fun(L) -> dup_module(L, sequential) end,
+ fun(L) -> [dup_module(L1, mkmod("parallel",num(L1,L))) || L1<-L] end,
+ Cs).
+dup_module(L, ModName) -> lists:duplicate(length(L), ModName).
+mkmod(PfxStr,N) -> list_to_atom(PfxStr++"_"++integer_to_list(N)).
+
+%% Meta functions for the aggregate functions
+traverse_commands(Fun, L) when is_list(L) -> Fun(L);
+traverse_commands(Fun, {Seq, ParLs}) -> Fun(lists:append([Seq|ParLs])).
+
+traverse_commands(Fseq, _Fpar, L) when is_list(L) -> Fseq(L);
+traverse_commands(Fseq, Fpar, {Seq, ParLs}) -> lists:append([Fseq(Seq)|Fpar(ParLs)]).
+
+%%%----------------
+%% PrintMethod([{term(), int()}]) -> any().
+print_frequencies() -> print_frequencies(10).
+
+print_frequencies(Ngroups) -> fun([]) -> io:format('Empty list!~n',[]);
+ (L ) -> print_frequencies(L,Ngroups,0,element(1,lists:last(L)))
+ end.
+
+print_frequencies(Ngroups, MaxValue) -> fun(L) -> print_frequencies(L,Ngroups,0,MaxValue) end.
+
+print_frequencies(L, N, Min, Max) when N>Max -> print_frequencies(L++[{N,0}], N, Min, N);
+print_frequencies(L, N, Min, Max) ->
+%%io:format('L=~p~n',[L]),
+ try
+ IntervalUpperLimits =
+ lists:reverse(
+ [Max | tl(lists:reverse(lists:seq(Min,Max,round((Max-Min)/N))))]
+ ),
+ {Acc0,_} = lists:mapfoldl(fun(Upper,Lower) ->
+ {{{Lower,Upper},0}, Upper+1}
+ end, hd(IntervalUpperLimits), tl(IntervalUpperLimits)),
+ Fs0 = get_frequencies(L, Acc0),
+ SumVal = lists:sum([V||{_,V}<-Fs0]),
+ Fs = with_percentage(Fs0, SumVal),
+ Mean = mean(L),
+ Median = median(L),
+ Npos_value = num_digits(SumVal),
+ Npos_range = num_digits(Max),
+ io:format("Range~*s: ~s~n",[2*Npos_range-2,"", "Number in range"]),
+ io:format("~*c:~*c~n",[2*Npos_range+3,$-, max(16,Npos_value+10),$- ]),
+ [begin
+ io:format("~*w - ~*w: ~*w ~5.1f%",[Npos_range,Rlow,
+ Npos_range,Rhigh,
+ Npos_value,Val,
+ Percent]),
+ [io:format(" <-- mean=~.1f",[Mean]) || in_interval(Mean, Interval)],
+ [io:format(" <-- median=" ++
+ if
+ is_float(Median) -> "~.1f";
+ true -> "~p"
+ end, [Median]) || in_interval(Median, Interval)],
+ io:nl()
+ end
+ || {Interval={Rlow,Rhigh},Val,Percent} <- Fs],
+ io:format('~*c ~*c~n',[2*Npos_range,32,Npos_value+2,$-]),
+ io:format('~*c ~*w~n',[2*Npos_range,32,Npos_value,SumVal])
+ %%,io:format('L=~p~n',[L])
+ catch
+ C:E ->
+ io:format('*** Faild printing (~p:~p) for~n~p~n',[C,E,L])
+ end.
+
+get_frequencies([{I,Num}|T], [{{Lower,Upper},Cnt}|Acc]) when Lower=<I,I=<Upper ->
+ get_frequencies(T, [{{Lower,Upper},Cnt+Num}|Acc]);
+get_frequencies(L=[{I,_Num}|_], [Ah={{_Lower,Upper},_Cnt}|Acc]) when I>Upper ->
+ [Ah | get_frequencies(L,Acc)];
+get_frequencies([], Acc) ->
+ Acc.
+
+with_percentage(Fs, Sum) ->
+ [{Rng,Val,100*Val/Sum} || {Rng,Val} <- Fs].
+
+
+title(Str, Fun) ->
+ fun(L) ->
+ io:format('~s~n',[Str]),
+ Fun(L)
+ end.
+
+num_digits(I) -> 1+trunc(math:log(I)/math:log(10)).
+
+num(Elem, List) -> length(lists:takewhile(fun(E) -> E /= Elem end, List)) + 1.
+
+%%%---- Just for naming an operation for readability
+is_odd(I) -> (I rem 2) == 1.
+
+in_interval(Value, {Rlow,Rhigh}) ->
+ try
+ Rlow=<round(Value) andalso round(Value)=<Rhigh
+ catch
+ _:_ -> false
+ end.
+
+%%%================================================================
+%%% Statistical functions
+
+%%%---- Mean value
+mean(L = [X|_]) when is_number(X) ->
+ lists:sum(L) / length(L);
+mean(L = [{_Value,_Weight}|_]) ->
+ SumOfWeights = lists:sum([W||{_,W}<-L]),
+ WeightedSum = lists:sum([W*V||{V,W}<-L]),
+ WeightedSum / SumOfWeights;
+mean(_) ->
+ undefined.
+
+%%%---- Median
+median(L = [X|_]) when is_number(X) ->
+ case is_odd(length(L)) of
+ true ->
+ hd(lists:nthtail(length(L) div 2, L));
+ false ->
+ %% 1) L has at least on element (the when test).
+ %% 2) Length is even.
+ %% => Length >= 2
+ [M1,M2|_] = lists:nthtail((length(L) div 2)-1, L),
+ (M1+M2) / 2
+ end;
+%% integer Weights...
+median(L = [{_Value,_Weight}|_]) ->
+ median( lists:append([lists:duplicate(W,V) || {V,W} <- L]) );
+median(_) ->
+ undefined.
+
+%%%================================================================
+%%% The rest is taken and modified from ssh_test_lib.erl
+setup_rsa(Dir) ->
+ erase_dir(system_dir(Dir)),
+ erase_dir(user_dir(Dir)),
+ file:make_dir(system_dir(Dir)),
+ file:make_dir(user_dir(Dir)),
+
+ file:copy(data_dir(Dir,"id_rsa"), user_dir(Dir,"id_rsa")),
+ file:copy(data_dir(Dir,"ssh_host_rsa_key"), system_dir(Dir,"ssh_host_rsa_key")),
+ file:copy(data_dir(Dir,"ssh_host_rsa_key"), system_dir(Dir,"ssh_host_rsa_key.pub")),
+ ssh_test_lib:setup_rsa_known_host(data_dir(Dir), user_dir(Dir)),
+ ssh_test_lib:setup_rsa_auth_keys(data_dir(Dir), user_dir(Dir)).
+
+data_dir(Dir, File) -> filename:join(Dir, File).
+system_dir(Dir, File) -> filename:join([Dir, "system", File]).
+user_dir(Dir, File) -> filename:join([Dir, "user", File]).
+
+data_dir(Dir) -> Dir.
+system_dir(Dir) -> system_dir(Dir,"").
+user_dir(Dir) -> user_dir(Dir,"").
+
+erase_dir(Dir) ->
+ case file:list_dir(Dir) of
+ {ok,Files} -> lists:foreach(fun(F) -> file:delete(filename:join(Dir,F)) end,
+ Files);
+ _ -> ok
+ end,
+ file:del_dir(Dir).
+
+-endif.
+-endif.
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
new file mode 100644
index 0000000000..57ea2012c1
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
@@ -0,0 +1,395 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ssh_eqc_encode_decode).
+
+-compile(export_all).
+
+-proptest(eqc).
+-proptest([triq,proper]).
+
+-ifndef(EQC).
+-ifndef(PROPER).
+-ifndef(TRIQ).
+-define(EQC,true).
+%%-define(PROPER,true).
+%%-define(TRIQ,true).
+-endif.
+-endif.
+-endif.
+
+-ifdef(EQC).
+-include_lib("eqc/include/eqc.hrl").
+-define(MOD_eqc,eqc).
+
+-else.
+-ifdef(PROPER).
+-include_lib("proper/include/proper.hrl").
+-define(MOD_eqc,proper).
+
+-else.
+-ifdef(TRIQ).
+-define(MOD_eqc,triq).
+-include_lib("triq/include/triq.hrl").
+
+-endif.
+-endif.
+-endif.
+
+
+%%% Properties:
+
+prop_ssh_decode() ->
+ ?FORALL(Msg, ssh_msg(),
+ try ssh_message:decode(Msg)
+ of
+ _ -> true
+ catch
+ C:E -> io:format('~p:~p~n',[C,E]),
+ false
+ end
+ ).
+
+
+%%% This fails because ssh_message is not symmetric in encode and decode regarding data types
+prop_ssh_decode_encode() ->
+ ?FORALL(Msg, ssh_msg(),
+ Msg == ssh_message:encode(ssh_message:decode(Msg))
+ ).
+
+
+%%%================================================================
+%%%
+%%% Scripts to generate message generators
+%%%
+
+%% awk '/^( |\t)+byte( |\t)+SSH/,/^( |\t)*$/{print}' rfc425?.txt | sed 's/^\( \|\\t\)*//' > msgs.txt
+
+%% awk '/^byte( |\t)+SSH/{print $2","}' < msgs.txt
+
+%% awk 'BEGIN{print "%%%---- BEGIN GENERATED";prev=0} END{print " >>.\n%%%---- END GENERATED"} /^byte( |\t)+SSH/{if (prev==1) print " >>.\n"; prev=1; printf "%c%s%c",39,$2,39; print "()->\n <<?"$2;next} /^string( |\t)+\"/{print " ,"$2;next} /^string( |\t)+.*address/{print " ,(ssh_string_address())/binary %%",$2,$3,$4,$5,$6;next}/^string( |\t)+.*US-ASCII/{print " ,(ssh_string_US_ASCII())/binary %%",$2,$3,$4,$5,$6;next} /^string( |\t)+.*UTF-8/{print " ,(ssh_string_UTF_8())/binary %% ",$2,$3,$4,$5,$6;next} /^[a-z0-9]+( |\t)/{print " ,(ssh_"$1"())/binary %%",$2,$3,$4,$5,$6;next} /^byte\[16\]( |\t)+/{print" ,(ssh_byte_16())/binary %%",$2,$3,$4,$5,$6;next} /^name-list( |\t)+/{print" ,(ssh_name_list())/binary %%",$2,$3,$4,$5,$6;next} /./{print "?? %%",$0}' < msgs.txt > gen.txt
+
+%%%================================================================
+%%%
+%%% Generators
+%%%
+
+ssh_msg() -> ?LET(M,oneof(
+[[msg_code('SSH_MSG_CHANNEL_CLOSE'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_DATA'),gen_uint32(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_EOF'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_EXTENDED_DATA'),gen_uint32(),gen_uint32(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_FAILURE'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("direct-tcpip"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("forwarded-tcpip"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("session"),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("x11"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string( ),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN_CONFIRMATION'),gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN_FAILURE'),gen_uint32(),gen_uint32(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("env"),gen_boolean(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exec"),gen_boolean(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exit-signal"),0,gen_string( ),gen_boolean(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exit-status"),0,gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("pty-req"),gen_boolean(),gen_string( ),gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("shell"),gen_boolean()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("signal"),0,gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("subsystem"),gen_boolean(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("window-change"),0,gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("x11-req"),gen_boolean(),gen_boolean(),gen_string( ),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("xon-xoff"),0,gen_boolean()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string( ),gen_boolean()],
+ [msg_code('SSH_MSG_CHANNEL_SUCCESS'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_WINDOW_ADJUST'),gen_uint32(),gen_uint32()],
+%%Assym [msg_code('SSH_MSG_DEBUG'),gen_boolean(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_DISCONNECT'),gen_uint32(),gen_string( ),gen_string( )],
+%%Assym [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string("cancel-tcpip-forward"),gen_boolean(),gen_string( ),gen_uint32()],
+%%Assym [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string("tcpip-forward"),gen_boolean(),gen_string( ),gen_uint32()],
+%%Assym [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string( ),gen_boolean()],
+ [msg_code('SSH_MSG_IGNORE'),gen_string( )],
+ %% [msg_code('SSH_MSG_KEXDH_INIT'),gen_mpint()],
+ %% [msg_code('SSH_MSG_KEXDH_REPLY'),gen_string( ),gen_mpint(),gen_string( )],
+ %% [msg_code('SSH_MSG_KEXINIT'),gen_byte(16),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_boolean(),gen_uint32()],
+ [msg_code('SSH_MSG_KEX_DH_GEX_GROUP'),gen_mpint(),gen_mpint()],
+ [msg_code('SSH_MSG_NEWKEYS')],
+ [msg_code('SSH_MSG_REQUEST_FAILURE')],
+ [msg_code('SSH_MSG_REQUEST_SUCCESS')],
+ [msg_code('SSH_MSG_REQUEST_SUCCESS'),gen_uint32()],
+ [msg_code('SSH_MSG_SERVICE_ACCEPT'),gen_string( )],
+ [msg_code('SSH_MSG_SERVICE_REQUEST'),gen_string( )],
+ [msg_code('SSH_MSG_UNIMPLEMENTED'),gen_uint32()],
+ [msg_code('SSH_MSG_USERAUTH_BANNER'),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_USERAUTH_FAILURE'),gen_name_list(),gen_boolean()],
+ [msg_code('SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_USERAUTH_PK_OK'),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_USERAUTH_SUCCESS')]
+]
+
+), list_to_binary(M)).
+
+
+%%%================================================================
+%%%
+%%% Generator
+%%%
+
+do() ->
+ io_lib:format('[~s~n]',
+ [write_gen(
+ files(["rfc4254.txt",
+ "rfc4253.txt",
+ "rfc4419.txt",
+ "rfc4252.txt",
+ "rfc4256.txt"]))]).
+
+
+write_gen(L) when is_list(L) ->
+ string:join(lists:map(fun write_gen/1, L), ",\n ");
+write_gen({MsgName,Args}) ->
+ lists:flatten(["[",generate_args([MsgName|Args]),"]"]).
+
+generate_args(As) -> string:join([generate_arg(A) || A <- As], ",").
+
+generate_arg({<<"string">>, <<"\"",B/binary>>}) ->
+ S = get_string($",B),
+ ["gen_string(\"",S,"\")"];
+generate_arg({<<"string">>, _}) -> "gen_string( )";
+generate_arg({<<"byte[",B/binary>>, _}) ->
+ io_lib:format("gen_byte(~p)",[list_to_integer(get_string($],B))]);
+generate_arg({<<"byte">> ,_}) -> "gen_byte()";
+generate_arg({<<"uint16">>,_}) -> "gen_uint16()";
+generate_arg({<<"uint32">>,_}) -> "gen_uint32()";
+generate_arg({<<"uint64">>,_}) -> "gen_uint64()";
+generate_arg({<<"mpint">>,_}) -> "gen_mpint()";
+generate_arg({<<"name-list">>,_}) -> "gen_name_list()";
+generate_arg({<<"boolean">>,<<"FALSE">>}) -> "0";
+generate_arg({<<"boolean">>,<<"TRUE">>}) -> "1";
+generate_arg({<<"boolean">>,_}) -> "gen_boolean()";
+generate_arg({<<"....">>,_}) -> ""; %% FIXME
+generate_arg(Name) when is_binary(Name) ->
+ lists:flatten(["msg_code('",binary_to_list(Name),"')"]).
+
+
+gen_boolean() -> choose(0,1).
+
+gen_byte() -> choose(0,255).
+
+gen_uint16() -> gen_byte(2).
+
+gen_uint32() -> gen_byte(4).
+
+gen_uint64() -> gen_byte(8).
+
+gen_byte(N) when N>0 -> [gen_byte() || _ <- lists:seq(1,N)].
+
+gen_char() -> choose($a,$z).
+
+gen_mpint() -> ?LET(Size, choose(1,20),
+ ?LET(Str, vector(Size, gen_byte()),
+ gen_string( strip_0s(Str) )
+ )).
+
+strip_0s([0|T]) -> strip_0s(T);
+strip_0s(X) -> X.
+
+
+gen_string() ->
+ ?LET(Size, choose(0,10),
+ ?LET(Vector,vector(Size, gen_char()),
+ gen_string(Vector)
+ )).
+
+gen_string(S) when is_binary(S) -> gen_string(binary_to_list(S));
+gen_string(S) when is_list(S) -> uint32_to_list(length(S)) ++ S.
+
+gen_name_list() ->
+ ?LET(NumNames, choose(0,10),
+ ?LET(L, [gen_name() || _ <- lists:seq(1,NumNames)],
+ gen_string( string:join(L,"," ) )
+ )).
+
+gen_name() -> gen_string().
+
+uint32_to_list(I) -> binary_to_list(<<I:32/unsigned-big-integer>>).
+
+%%%----
+get_string(Delim, B) ->
+ binary_to_list( element(1, split_binary(B, count_string_chars(Delim,B,0))) ).
+
+count_string_chars(Delim, <<Delim,_/binary>>, Acc) -> Acc;
+count_string_chars(Delim, <<_,B/binary>>, Acc) -> count_string_chars(Delim, B, Acc+1).
+
+
+-define(MSG_CODE(Name,Num),
+msg_code(Name) -> Num;
+msg_code(Num) -> Name
+).
+
+?MSG_CODE('SSH_MSG_USERAUTH_REQUEST', 50);
+?MSG_CODE('SSH_MSG_USERAUTH_FAILURE', 51);
+?MSG_CODE('SSH_MSG_USERAUTH_SUCCESS', 52);
+?MSG_CODE('SSH_MSG_USERAUTH_BANNER', 53);
+?MSG_CODE('SSH_MSG_USERAUTH_PK_OK', 60);
+?MSG_CODE('SSH_MSG_USERAUTH_PASSWD_CHANGEREQ', 60);
+?MSG_CODE('SSH_MSG_DISCONNECT', 1);
+?MSG_CODE('SSH_MSG_IGNORE', 2);
+?MSG_CODE('SSH_MSG_UNIMPLEMENTED', 3);
+?MSG_CODE('SSH_MSG_DEBUG', 4);
+?MSG_CODE('SSH_MSG_SERVICE_REQUEST', 5);
+?MSG_CODE('SSH_MSG_SERVICE_ACCEPT', 6);
+?MSG_CODE('SSH_MSG_KEXINIT', 20);
+?MSG_CODE('SSH_MSG_NEWKEYS', 21);
+?MSG_CODE('SSH_MSG_GLOBAL_REQUEST', 80);
+?MSG_CODE('SSH_MSG_REQUEST_SUCCESS', 81);
+?MSG_CODE('SSH_MSG_REQUEST_FAILURE', 82);
+?MSG_CODE('SSH_MSG_CHANNEL_OPEN', 90);
+?MSG_CODE('SSH_MSG_CHANNEL_OPEN_CONFIRMATION', 91);
+?MSG_CODE('SSH_MSG_CHANNEL_OPEN_FAILURE', 92);
+?MSG_CODE('SSH_MSG_CHANNEL_WINDOW_ADJUST', 93);
+?MSG_CODE('SSH_MSG_CHANNEL_DATA', 94);
+?MSG_CODE('SSH_MSG_CHANNEL_EXTENDED_DATA', 95);
+?MSG_CODE('SSH_MSG_CHANNEL_EOF', 96);
+?MSG_CODE('SSH_MSG_CHANNEL_CLOSE', 97);
+?MSG_CODE('SSH_MSG_CHANNEL_REQUEST', 98);
+?MSG_CODE('SSH_MSG_CHANNEL_SUCCESS', 99);
+?MSG_CODE('SSH_MSG_CHANNEL_FAILURE', 100);
+?MSG_CODE('SSH_MSG_USERAUTH_INFO_REQUEST', 60);
+?MSG_CODE('SSH_MSG_USERAUTH_INFO_RESPONSE', 61);
+?MSG_CODE('SSH_MSG_KEX_DH_GEX_REQUEST_OLD', 30);
+?MSG_CODE('SSH_MSG_KEX_DH_GEX_REQUEST', 34);
+?MSG_CODE('SSH_MSG_KEX_DH_GEX_GROUP', 31);
+?MSG_CODE('SSH_MSG_KEX_DH_GEX_INIT', 32);
+?MSG_CODE('SSH_MSG_KEX_DH_GEX_REPLY', 33).
+
+%%%=============================================================================
+%%%=============================================================================
+%%%=============================================================================
+
+files(Fs) ->
+ Defs = lists:usort(lists:flatten(lists:map(fun file/1, Fs))),
+ DefinedIDs = lists:usort([binary_to_list(element(1,D)) || D <- Defs]),
+ WantedIDs = lists:usort(wanted_messages()),
+ Missing = WantedIDs -- DefinedIDs,
+ case Missing of
+ [] -> ok;
+ _ -> io:format('%% Warning: missing ~p~n', [Missing])
+ end,
+ Defs.
+
+
+file(F) ->
+ {ok,B} = file:read_file(F),
+ hunt_msg_def(B).
+
+
+hunt_msg_def(<<"\n",B/binary>>) -> some_hope(skip_blanks(B));
+hunt_msg_def(<<_, B/binary>>) -> hunt_msg_def(B);
+hunt_msg_def(<<>>) -> [].
+
+some_hope(<<"byte ", B/binary>>) -> try_message(skip_blanks(B));
+some_hope(B) -> hunt_msg_def(B).
+
+try_message(B = <<"SSH_MSG_",_/binary>>) ->
+ {ID,Rest} = get_id(B),
+ case lists:member(binary_to_list(ID), wanted_messages()) of
+ true ->
+ {Lines,More} = get_def_lines(skip_blanks(Rest), []),
+ [{ID,lists:reverse(Lines)} | hunt_msg_def(More)];
+ false ->
+ hunt_msg_def(Rest)
+ end;
+try_message(B) -> hunt_msg_def(B).
+
+
+skip_blanks(<<32, B/binary>>) -> skip_blanks(B);
+skip_blanks(<< 9, B/binary>>) -> skip_blanks(B);
+skip_blanks(B) -> B.
+
+get_def_lines(B0 = <<"\n",B/binary>>, Acc) ->
+ {ID,Rest} = get_id(skip_blanks(B)),
+ case {size(ID), skip_blanks(Rest)} of
+ {0,<<"....",More/binary>>} ->
+ {Text,LineEnd} = get_to_eol(skip_blanks(More)),
+ get_def_lines(LineEnd, [{<<"....">>,Text}|Acc]);
+ {0,_} ->
+ {Acc,B0};
+ {_,Rest1} ->
+ {Text,LineEnd} = get_to_eol(Rest1),
+ get_def_lines(LineEnd, [{ID,Text}|Acc])
+ end;
+get_def_lines(B, Acc) ->
+ {Acc,B}.
+
+
+get_to_eol(B) -> split_binary(B, count_to_eol(B,0)).
+
+count_to_eol(<<"\n",_/binary>>, Acc) -> Acc;
+count_to_eol(<<>>, Acc) -> Acc;
+count_to_eol(<<_,B/binary>>, Acc) -> count_to_eol(B,Acc+1).
+
+
+get_id(B) -> split_binary(B, count_id_chars(B,0)).
+
+count_id_chars(<<C,B/binary>>, Acc) when $A=<C,C=<$Z -> count_id_chars(B,Acc+1);
+count_id_chars(<<C,B/binary>>, Acc) when $a=<C,C=<$z -> count_id_chars(B,Acc+1);
+count_id_chars(<<C,B/binary>>, Acc) when $0=<C,C=<$9 -> count_id_chars(B,Acc+1);
+count_id_chars(<<"_",B/binary>>, Acc) -> count_id_chars(B,Acc+1);
+count_id_chars(<<"-",B/binary>>, Acc) -> count_id_chars(B,Acc+1); %% e.g name-list
+count_id_chars(<<"[",B/binary>>, Acc) -> count_id_chars(B,Acc+1); %% e.g byte[16]
+count_id_chars(<<"]",B/binary>>, Acc) -> count_id_chars(B,Acc+1); %% e.g byte[16]
+count_id_chars(_, Acc) -> Acc.
+
+wanted_messages() ->
+ ["SSH_MSG_CHANNEL_CLOSE",
+ "SSH_MSG_CHANNEL_DATA",
+ "SSH_MSG_CHANNEL_EOF",
+ "SSH_MSG_CHANNEL_EXTENDED_DATA",
+ "SSH_MSG_CHANNEL_FAILURE",
+ "SSH_MSG_CHANNEL_OPEN",
+ "SSH_MSG_CHANNEL_OPEN_CONFIRMATION",
+ "SSH_MSG_CHANNEL_OPEN_FAILURE",
+ "SSH_MSG_CHANNEL_REQUEST",
+ "SSH_MSG_CHANNEL_SUCCESS",
+ "SSH_MSG_CHANNEL_WINDOW_ADJUST",
+ "SSH_MSG_DEBUG",
+ "SSH_MSG_DISCONNECT",
+ "SSH_MSG_GLOBAL_REQUEST",
+ "SSH_MSG_IGNORE",
+ "SSH_MSG_KEXDH_INIT",
+ "SSH_MSG_KEXDH_REPLY",
+ "SSH_MSG_KEXINIT",
+ "SSH_MSG_KEX_DH_GEX_GROUP",
+ "SSH_MSG_KEX_DH_GEX_REQUEST",
+ "SSH_MSG_KEX_DH_GEX_REQUEST_OLD",
+ "SSH_MSG_NEWKEYS",
+ "SSH_MSG_REQUEST_FAILURE",
+ "SSH_MSG_REQUEST_SUCCESS",
+ "SSH_MSG_SERVICE_ACCEPT",
+ "SSH_MSG_SERVICE_REQUEST",
+ "SSH_MSG_UNIMPLEMENTED",
+ "SSH_MSG_USERAUTH_BANNER",
+ "SSH_MSG_USERAUTH_FAILURE",
+%% hard args "SSH_MSG_USERAUTH_INFO_REQUEST",
+%% "SSH_MSG_USERAUTH_INFO_RESPONSE",
+ "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ",
+ "SSH_MSG_USERAUTH_PK_OK",
+%%rfc4252 p12 error "SSH_MSG_USERAUTH_REQUEST",
+ "SSH_MSG_USERAUTH_SUCCESS"].
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_subsys.erl b/lib/ssh/test/property_test/ssh_eqc_subsys.erl
new file mode 100644
index 0000000000..e4b6af166f
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_subsys.erl
@@ -0,0 +1,63 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ssh_eqc_subsys).
+
+-behaviour(ssh_daemon_channel).
+
+-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]).
+
+-export([response/2]).
+
+-record(state, {id,
+ cm,
+ subsyst
+ }).
+
+init([SS]) ->
+ {ok, #state{subsyst=SS}}.
+
+handle_msg({ssh_channel_up, ChannelId, ConnectionManager}, State) ->
+ {ok, State#state{id = ChannelId,
+ cm = ConnectionManager}}.
+
+handle_ssh_msg({ssh_cm, CM, {data, ChannelId, Type, Data}}, S) ->
+ ssh_connection:send(CM, ChannelId, Type, response(Data,S)),
+ {ok, S};
+
+handle_ssh_msg({ssh_cm, _ConnectionManager, {eof, _ChannelId}}, State) ->
+ {ok, State};
+
+handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) ->
+ %% Ignore signals according to RFC 4254 section 6.9.
+ {ok, State};
+
+handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, _Error, _}}, State) ->
+ {stop, ChannelId, State};
+
+handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, _Status}}, State) ->
+ {stop, ChannelId, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+
+response(Msg, #state{subsyst=SS}) -> response(Msg, SS);
+response(Msg, SS) -> <<"Resp: ",Msg/binary,(list_to_binary(SS))/binary>>.
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index ba38c1da40..cb1b4ae945 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -53,20 +53,29 @@ all() ->
{group, hardening_tests}
].
-groups() ->
+groups() ->
[{dsa_key, [], basic_tests()},
{rsa_key, [], basic_tests()},
{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_ssh_connect_parallel,
+ max_sessions_ssh_connect_sequential,
+ max_sessions_sftp_start_channel_parallel,
+ max_sessions_sftp_start_channel_sequential
+ ]}
].
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 +184,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, [{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, CMiscOpt0 ++ ClientOpts}, {server_opts, SMiscOpt0 ++ ServerOpts}]),
- basic_test([{client_opts, CMiscOpt1 ++ ClientOpts}, {server_opts, SMiscOpt1 ++ ServerOpts}]).
+ basic_test([{client_opts, [{inet, inet6} | ClientOpts]},
+ {server_opts, [{inet, inet6} | ServerOpts]}]).
%%--------------------------------------------------------------------
exec() ->
@@ -683,7 +723,7 @@ ssh_connect_arg4_timeout(_Config) ->
%% Wait for client reaction on the connection try:
receive
- {done, Client, {error,_E}, T0} ->
+ {done, Client, {error,timeout}, T0} ->
Msp = ms_passed(T0, now()),
exit(Server,hasta_la_vista___baby),
Low = 0.9*Timeout,
@@ -693,6 +733,11 @@ ssh_connect_arg4_timeout(_Config) ->
Low<Msp, Msp<High -> ok;
true -> {fail, "timeout not within limits"}
end;
+
+ {done, Client, {error,Other}, _T0} ->
+ ct:log("Error message \"~p\" from the client is unexpected.",[{error,Other}]),
+ {fail, "Unexpected error message"};
+
{done, Client, {ok,_Ref}, _T0} ->
{fail,"ssh-connected ???"}
after
@@ -711,6 +756,100 @@ 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:pal("~p Listen ~p:~p",[_Pid,_Host,Port]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ receive
+ Error = {'EXIT', _, _} ->
+ ct:pal("~p",[Error]),
+ 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"}].
@@ -731,40 +870,92 @@ openssh_zlib_basic_test(Config) ->
%%--------------------------------------------------------------------
-max_sessions(Config) ->
+max_sessions_ssh_connect_parallel(Config) ->
+ max_sessions(Config, true, connect_fun(ssh__connect,Config)).
+max_sessions_ssh_connect_sequential(Config) ->
+ max_sessions(Config, false, connect_fun(ssh__connect,Config)).
+
+max_sessions_sftp_start_channel_parallel(Config) ->
+ max_sessions(Config, true, connect_fun(ssh_sftp__start_channel, Config)).
+max_sessions_sftp_start_channel_sequential(Config) ->
+ max_sessions(Config, false, connect_fun(ssh_sftp__start_channel, Config)).
+
+
+%%%---- helpers:
+connect_fun(ssh__connect, Config) ->
+ fun(Host,Port) ->
+ ssh_test_lib:connect(Host, Port,
+ [{silently_accept_hosts, true},
+ {user_dir, ?config(priv_dir,Config)},
+ {user_interaction, false},
+ {user, "carni"},
+ {password, "meat"}
+ ])
+ %% ssh_test_lib returns R when ssh:connect returns {ok,R}
+ end;
+connect_fun(ssh_sftp__start_channel, _Config) ->
+ fun(Host,Port) ->
+ {ok,_Pid,ConnRef} =
+ ssh_sftp:start_channel(Host, Port,
+ [{silently_accept_hosts, true},
+ {user, "carni"},
+ {password, "meat"}
+ ]),
+ ConnRef
+ end.
+
+
+max_sessions(Config, ParallelLogin, Connect0) when is_function(Connect0,2) ->
+ Connect = fun(Host,Port) ->
+ R = Connect0(Host,Port),
+ ct:pal("Connect(~p,~p) -> ~p",[Host,Port,R]),
+ R
+ end,
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
- MaxSessions = 2,
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ MaxSessions = 5,
+ {Pid, Host, Port} = ssh_test_lib:daemon([
+ {system_dir, SystemDir},
{user_dir, UserDir},
{user_passwords, [{"carni", "meat"}]},
- {parallel_login, true},
+ {parallel_login, ParallelLogin},
{max_sessions, MaxSessions}
]),
-
- Connect = fun() ->
- R=ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {user, "carni"},
- {password, "meat"}
- ]),
- ct:log("Connection ~p up",[R])
- end,
-
- try [Connect() || _ <- lists:seq(1,MaxSessions)]
+ ct:pal("~p Listen ~p:~p for max ~p sessions",[Pid,Host,Port,MaxSessions]),
+ try [Connect(Host,Port) || _ <- lists:seq(1,MaxSessions)]
of
- _ ->
- ct:pal("Expect Info Report:",[]),
- try Connect()
+ Connections ->
+ %% Step 1 ok: could set up max_sessions connections
+ ct:log("Connections up: ~p",[Connections]),
+ [_|_] = Connections,
+
+ %% Now try one more than alowed:
+ ct:pal("Info Report might come here...",[]),
+ try Connect(Host,Port)
of
- _ConnectionRef ->
+ _ConnectionRef1 ->
ssh:stop_daemon(Pid),
{fail,"Too many connections accepted"}
catch
error:{badmatch,{error,"Connection closed"}} ->
- ssh:stop_daemon(Pid),
- ok
+ %% Step 2 ok: could not set up max_sessions+1 connections
+ %% This is expected
+ %% Now stop one connection and try to open one more
+ ok = ssh:close(hd(Connections)),
+ try Connect(Host,Port)
+ of
+ _ConnectionRef1 ->
+ %% Step 3 ok: could set up one more connection after killing one
+ %% Thats good.
+ ssh:stop_daemon(Pid),
+ ok
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ %% Bad indeed. Could not set up one more connection even after killing
+ %% one existing. Very bad.
+ ssh:stop_daemon(Pid),
+ {fail,"Does not decrease # active sessions"}
+ end
end
catch
error:{badmatch,{error,"Connection closed"}} ->
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index f4f0682b40..e3871b3feb 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.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
@@ -31,20 +31,37 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
+%% suite() ->
+%% [{ct_hooks,[ts_install_cth]}].
all() ->
[
- {group, openssh_payload},
- interrupted_send
+ {group, openssh},
+ interrupted_send,
+ start_shell,
+ start_shell_exec,
+ start_shell_exec_fun,
+ gracefull_invalid_version,
+ gracefull_invalid_start,
+ gracefull_invalid_long_start,
+ gracefull_invalid_long_start_no_nl,
+ stop_listener,
+ start_subsystem_on_closed_channel
].
groups() ->
- [{openssh_payload, [], [simple_exec,
- small_cat,
- big_cat,
- send_after_exit
- ]}].
+ [{openssh, [], payload() ++ ptty()}].
+
+payload() ->
+ [simple_exec,
+ small_cat,
+ big_cat,
+ send_after_exit].
+
+ptty() ->
+ [ptty_alloc_default,
+ ptty_alloc,
+ ptty_alloc_pixel].
+
%%--------------------------------------------------------------------
init_per_suite(Config) ->
case catch crypto:start() of
@@ -58,13 +75,13 @@ end_per_suite(_Config) ->
crypto:stop().
%%--------------------------------------------------------------------
-init_per_group(openssh_payload, _Config) ->
+init_per_group(openssh, _Config) ->
case gen_tcp:connect("localhost", 22, []) of
{error,econnrefused} ->
{skip,"No openssh deamon"};
{ok, Socket} ->
gen_tcp:close(Socket)
- end;
+ end;
init_per_group(_, Config) ->
Config.
@@ -177,10 +194,10 @@ big_cat(Config) when is_list(Config) ->
case size(Data) =:= size(Other) of
true ->
ct:pal("received and sent data are same"
- "size but do not match~n",[]);
+ "size but do not match~n",[]);
false ->
ct:pal("sent ~p but only received ~p~n",
- [size(Data), size(Other)])
+ [size(Data), size(Other)])
end,
ct:fail(receive_data_mismatch);
Else ->
@@ -233,6 +250,43 @@ send_after_exit(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
+ptty_alloc_default() ->
+ [{doc, "Test sending PTTY alloc message with only defaults."}].
+
+ptty_alloc_default(Config) when is_list(Config) ->
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, []),
+ ssh:close(ConnectionRef).
+
+%%--------------------------------------------------------------------
+ptty_alloc() ->
+ [{doc, "Test sending PTTY alloc message with width,height options."}].
+
+ptty_alloc(Config) when is_list(Config) ->
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId,
+ [{term, default_term()}, {width, 70}, {high, 20}]),
+ ssh:close(ConnectionRef).
+
+
+%%--------------------------------------------------------------------
+ptty_alloc_pixel() ->
+ [{doc, "Test sending PTTY alloc message pixel options."}].
+
+ptty_alloc_pixel(Config) when is_list(Config) ->
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId,
+ [{term, default_term()}, {pixel_widh, 630}, {pixel_hight, 470}]),
+ ssh:close(ConnectionRef).
+
+%%--------------------------------------------------------------------
+
interrupted_send() ->
[{doc, "Use a subsystem that echos n char and then sends eof to cause a channel exit partway through a large send."}].
@@ -247,10 +301,10 @@ interrupted_send(Config) when is_list(Config) ->
{subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}]),
ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
@@ -276,6 +330,278 @@ interrupted_send(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+start_shell() ->
+ [{doc, "Start a shell"}].
+
+start_shell(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {shell, fun(U, H) -> start_our_shell(U, H) end} ]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ok = ssh_connection:shell(ConnectionRef,ChannelId0),
+
+ receive
+ {ssh_cm,ConnectionRef, {data, ChannelId0, 0, <<"Enter command\r\n">>}} ->
+ ok
+ after 5000 ->
+ ct:fail("CLI Timeout")
+ end,
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+%%--------------------------------------------------------------------
+start_shell_exec() ->
+ [{doc, "start shell to exec command"}].
+
+start_shell_exec(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {exec, {?MODULE,ssh_exec,[]}} ]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ success = ssh_connection:exec(ConnectionRef, ChannelId0,
+ "testing", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, _ChannelId, 0, <<"testing\r\n">>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec Timeout")
+ end,
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+start_shell_exec_fun() ->
+ [{doc, "start shell to exec command"}].
+
+start_shell_exec_fun(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {exec, fun ssh_exec/1}]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ success = ssh_connection:exec(ConnectionRef, ChannelId0,
+ "testing", infinity),
+
+ receive
+ {ssh_cm, ConnectionRef, {data, _ChannelId, 0, <<"testing\r\n">>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec Timeout")
+ end,
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+gracefull_invalid_version(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ {ok, S} = gen_tcp:connect(Host, Port, []),
+ ok = gen_tcp:send(S, ["SSH-8.-1","\r\n"]),
+ receive
+ Verstring ->
+ ct:pal("Server version: ~p~n", [Verstring]),
+ receive
+ {tcp_closed, S} ->
+ ok
+ end
+ end.
+
+gracefull_invalid_start(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ {ok, S} = gen_tcp:connect(Host, Port, []),
+ ok = gen_tcp:send(S, ["foobar","\r\n"]),
+ receive
+ Verstring ->
+ ct:pal("Server version: ~p~n", [Verstring]),
+ receive
+ {tcp_closed, S} ->
+ ok
+ end
+ end.
+
+gracefull_invalid_long_start(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ {ok, S} = gen_tcp:connect(Host, Port, []),
+ ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
+ receive
+ Verstring ->
+ ct:pal("Server version: ~p~n", [Verstring]),
+ receive
+ {tcp_closed, S} ->
+ ok
+ end
+ end.
+
+
+gracefull_invalid_long_start_no_nl(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ {ok, S} = gen_tcp:connect(Host, Port, []),
+ ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
+ receive
+ Verstring ->
+ ct:pal("Server version: ~p~n", [Verstring]),
+ receive
+ {tcp_closed, S} ->
+ ok
+ end
+ end.
+
+stop_listener() ->
+ [{doc, "start ssh daemon, setup connections, stop listener, restart listner"}].
+
+stop_listener(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ {Pid0, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {exec, fun ssh_exec/1}]),
+
+ ConnectionRef0 = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef0, infinity),
+
+ ssh:stop_listener(Host, Port),
+
+ {error, _} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+ success = ssh_connection:exec(ConnectionRef0, ChannelId0,
+ "testing", infinity),
+ receive
+ {ssh_cm, ConnectionRef0, {data, ChannelId0, 0, <<"testing\r\n">>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec Timeout")
+ end,
+
+ {ok, HostAddr} = inet:getaddr(Host, inet),
+ case ssh_test_lib:daemon(HostAddr, Port, [{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "potatis"},
+ {exec, fun ssh_exec/1}]) of
+ {Pid1, HostAddr, Port} ->
+ ConnectionRef1 = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "potatis"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+ {error, _} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef0),
+ ssh:close(ConnectionRef1),
+ ssh:stop_daemon(Pid0),
+ ssh:stop_daemon(Pid1);
+ Error ->
+ ct:fail({unexpected, Error})
+ end.
+
+start_subsystem_on_closed_channel(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ ok = ssh_connection:close(ConnectionRef, ChannelId),
+
+ {error, closed} = ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity),
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
big_cat_rx(ConnectionRef, ChannelId) ->
@@ -308,3 +634,24 @@ collect_data(ConnectionRef, ChannelId, Acc) ->
after 5000 ->
timeout
end.
+
+%%%-------------------------------------------------------------------
+%% This is taken from the ssh example code.
+start_our_shell(_User, _Peer) ->
+ spawn(fun() ->
+ io:format("Enter command\n")
+ %% Don't actually loop, just exit
+ end).
+
+ssh_exec(Cmd) ->
+ spawn(fun() ->
+ io:format(Cmd ++ "\n")
+ end).
+
+default_term() ->
+ case os:getenv("TERM") of
+ false ->
+ "vt100";
+ Str when is_list(Str)->
+ Str
+ end.
diff --git a/lib/ssh/test/ssh_property_test_SUITE.erl b/lib/ssh/test/ssh_property_test_SUITE.erl
new file mode 100644
index 0000000000..ffad8ebbb7
--- /dev/null
+++ b/lib/ssh/test/ssh_property_test_SUITE.erl
@@ -0,0 +1,107 @@
+%%
+%% %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%
+%%
+%%
+
+%%% Run like this:
+%%% ct:run_test([{suite,"ssh_property_test_SUITE"}, {logdir,"/ldisk/OTP/LOG"}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-module(ssh_property_test_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+all() -> [{group, messages},
+ {group, client_server}
+ ].
+
+groups() ->
+ [{messages, [], [decode,
+ decode_encode]},
+ {client_server, [], [client_server_sequential,
+ client_server_parallel,
+ client_server_parallel_multi]}
+ ].
+
+
+%%% First prepare Config and compile the property tests for the found tool:
+init_per_suite(Config) ->
+ ct_property_test:init_per_suite(Config).
+
+%%% One group in this suite happens to support only QuickCheck, so skip it
+%%% if we run proper.
+init_per_group(client_server, Config) ->
+ case ?config(property_test_tool,Config) of
+ eqc -> Config;
+ X -> {skip, lists:concat([X," is not supported"])}
+ end;
+init_per_group(_, Config) ->
+ Config.
+
+end_per_group(_, Config) ->
+ Config.
+
+%%% Always skip the testcase that is not quite in phase with the
+%%% ssh_message.erl code
+init_per_testcase(decode_encode, _) -> {skip, "Fails - testcase is not ok"};
+init_per_testcase(_TestCase, Config) -> Config.
+
+end_per_testcase(_TestCase, Config) -> Config.
+
+%%%================================================================
+%%% Test suites
+%%%
+decode(Config) ->
+ ct_property_test:quickcheck(
+ ssh_eqc_encode_decode:prop_ssh_decode(),
+ Config
+ ).
+
+decode_encode(Config) ->
+ ct_property_test:quickcheck(
+ ssh_eqc_encode_decode:prop_ssh_decode_encode(),
+ Config
+ ).
+
+client_server_sequential(Config) ->
+ ct_property_test:quickcheck(
+ ssh_eqc_client_server:prop_seq(Config),
+ Config
+ ).
+
+client_server_parallel(Config) ->
+ ct_property_test:quickcheck(
+ ssh_eqc_client_server:prop_parallel(Config),
+ Config
+ ).
+
+client_server_parallel_multi(Config) ->
+ ct_property_test:quickcheck(
+ ssh_eqc_client_server:prop_parallel_multi(Config),
+ Config
+ ).
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index 56b1363b7a..cb74a27638 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_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
@@ -32,6 +32,8 @@
-define(USER, "Alladin").
-define(PASSWD, "Sesame").
+-define(tar_file_name, "sftp_tar_test.tar").
+
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
@@ -63,23 +65,37 @@ end_per_suite(Config) ->
%%--------------------------------------------------------------------
groups() ->
[{erlang_server, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, rename_file, mk_rm_dir, remove_file, links,
+ write_file, write_big_file, sftp_read_big_file,
+ rename_file, mk_rm_dir, remove_file, links,
retrieve_attributes, set_attributes, async_read,
- async_write, position, pos_read, pos_write]},
+ async_write, position, pos_read, pos_write, version_option,
+ {group,remote_tar}]},
+
{openssh_server, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, rename_file, mk_rm_dir, remove_file, links,
+ write_file, write_big_file, sftp_read_big_file,
+ rename_file, mk_rm_dir, remove_file, links,
retrieve_attributes, set_attributes, async_read,
- async_write, position, pos_read, pos_write]}].
+ async_write, position, pos_read, pos_write,
+ {group,remote_tar}]},
+
+ {remote_tar, [], [create_empty_tar, files_to_tar, big_file_to_tar, files_chunked_to_tar,
+ directory_to_tar, binaries_to_tar, null_crypto_tar,
+ simple_crypto_tar_small, simple_crypto_tar_big,
+ read_tar, read_null_crypto_tar, read_crypto_tar,
+ aes_cbc256_crypto_tar, aes_ctr_stream_crypto_tar
+ ]}
+ ].
+
init_per_group(erlang_server, Config) ->
PrivDir = ?config(priv_dir, Config),
SysDir = ?config(data_dir, Config),
- Sftpd =
+ Sftpd = {_, HostX, PortX} =
ssh_test_lib:daemon([{system_dir, SysDir},
{user_dir, PrivDir},
{user_passwords,
[{?USER, ?PASSWD}]}]),
- [{group, erlang_server}, {sftpd, Sftpd} | Config];
+ [{peer, {fmt_host(HostX),PortX}}, {group, erlang_server}, {sftpd, Sftpd} | Config];
init_per_group(openssh_server, Config) ->
Host = ssh_test_lib:hostname(),
@@ -87,11 +103,31 @@ init_per_group(openssh_server, Config) ->
[{user_interaction, false},
{silently_accept_hosts, true}])) of
{ok, _ChannelPid, Connection} ->
+ [{peer, {_HostName,{IPx,Portx}}}] = ssh:connection_info(Connection,[peer]),
ssh:close(Connection),
- [{group, openssh_server} | Config];
+ [{peer, {fmt_host(IPx),Portx}}, {group, openssh_server} | Config];
_ ->
{skip, "No openssh server"}
- end.
+ end;
+
+init_per_group(remote_tar, Config) ->
+ {Host,Port} = ?config(peer, Config),
+ ct:log("Server (~p) at ~p:~p",[?config(group,Config),Host,Port]),
+ {ok, Connection} =
+ case ?config(group, Config) of
+ erlang_server ->
+ ssh:connect(Host, Port,
+ [{user, ?USER},
+ {password, ?PASSWD},
+ {user_interaction, false},
+ {silently_accept_hosts, true}]);
+ openssh_server ->
+ ssh:connect(Host, Port,
+ [{user_interaction, false},
+ {silently_accept_hosts, true}])
+ end,
+ [{remote_tar, true},
+ {connection, Connection} | Config].
end_per_group(erlang_server, Config) ->
Config;
@@ -111,33 +147,60 @@ init_per_testcase(sftp_nonexistent_subsystem, Config) ->
]),
[{sftpd, Sftpd} | Config];
-init_per_testcase(Case, Config) ->
+init_per_testcase(version_option, Config) ->
prep(Config),
TmpConfig0 = lists:keydelete(watchdog, 1, Config),
TmpConfig = lists:keydelete(sftp, 1, TmpConfig0),
Dog = ct:timetrap(?default_timeout),
+ {_,Host, Port} = ?config(sftpd, Config),
+ {ok, ChannelPid, Connection} =
+ ssh_sftp:start_channel(Host, Port,
+ [{sftp_vsn, 3},
+ {user, ?USER},
+ {password, ?PASSWD},
+ {user_interaction, false},
+ {silently_accept_hosts, true}]),
+ Sftp = {ChannelPid, Connection},
+ [{sftp,Sftp}, {watchdog, Dog} | TmpConfig];
+
+init_per_testcase(Case, Config0) ->
+ prep(Config0),
+ Config1 = lists:keydelete(watchdog, 1, Config0),
+ Config2 = lists:keydelete(sftp, 1, Config1),
+ Dog = ct:timetrap(?default_timeout),
- case ?config(group, Config) of
- erlang_server ->
- {_,Host, Port} = ?config(sftpd, Config),
- {ok, ChannelPid, Connection} =
- ssh_sftp:start_channel(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
- {user_interaction, false},
- {silently_accept_hosts, true}]),
- Sftp = {ChannelPid, Connection},
- [{sftp, Sftp}, {watchdog, Dog} | TmpConfig];
- openssh_server when Case == links ->
- {skip, "known bug in openssh"};
- openssh_server ->
- Host = ssh_test_lib:hostname(),
- {ok, ChannelPid, Connection} =
- ssh_sftp:start_channel(Host,
- [{user_interaction, false},
- {silently_accept_hosts, true}]),
- Sftp = {ChannelPid, Connection},
- [{sftp, Sftp}, {watchdog, Dog} | TmpConfig]
+ Config =
+ case ?config(group,Config2) of
+ erlang_server ->
+ {_,Host, Port} = ?config(sftpd, Config2),
+ {ok, ChannelPid, Connection} =
+ ssh_sftp:start_channel(Host, Port,
+ [{user, ?USER},
+ {password, ?PASSWD},
+ {user_interaction, false},
+ {silently_accept_hosts, true}]),
+ Sftp = {ChannelPid, Connection},
+ [{sftp, Sftp}, {watchdog, Dog} | Config2];
+ openssh_server when Case == links ->
+ {skip, "known bug in openssh"};
+ openssh_server ->
+ Host = ssh_test_lib:hostname(),
+ {ok, ChannelPid, Connection} =
+ ssh_sftp:start_channel(Host,
+ [{user_interaction, false},
+ {silently_accept_hosts, true}]),
+ Sftp = {ChannelPid, Connection},
+ [{sftp, Sftp}, {watchdog, Dog} | Config2]
+ end,
+
+ case catch ?config(remote_tar,Config) of
+ %% The 'catch' is for the case of Config={skip,...}
+ true ->
+ %% Provide a ChannelPid independent of the sftp-channel already opened.
+ {ok,ChPid2} = ssh_sftp:start_channel(?config(connection,Config)),
+ [{channel_pid2,ChPid2} | Config];
+ _ ->
+ Config
end.
end_per_testcase(sftp_nonexistent_subsystem, Config) ->
@@ -153,6 +216,7 @@ end_per_testcase(_, Config) ->
end_per_testcase(Config) ->
{Sftp, Connection} = ?config(sftp, Config),
ssh_sftp:stop_channel(Sftp),
+ catch ssh_sftp:stop_channel(?config(channel_pid2, Config)),
ssh:close(Connection).
%%--------------------------------------------------------------------
@@ -197,6 +261,7 @@ read_file(Config) when is_list(Config) ->
FileName = filename:join(PrivDir, "sftp.txt"),
{Sftp, _} = ?config(sftp, Config),
{ok, Data} = ssh_sftp:read_file(Sftp, FileName),
+ {ok, Data} = ssh_sftp:read_file(Sftp, FileName),
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
@@ -221,6 +286,31 @@ write_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
+write_big_file() ->
+ [{doc, "Test API function write_file/2 with big data"}].
+write_big_file(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ FileName = filename:join(PrivDir, "sftp.txt"),
+ {Sftp, _} = ?config(sftp, Config),
+
+ Data = list_to_binary(lists:duplicate(750000,"a")),
+ ssh_sftp:write_file(Sftp, FileName, [Data]),
+ {ok, Data} = file:read_file(FileName).
+
+%%--------------------------------------------------------------------
+sftp_read_big_file() ->
+ [{doc, "Test API function read_file/2 with big data"}].
+sftp_read_big_file(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ FileName = filename:join(PrivDir, "sftp.txt"),
+ {Sftp, _} = ?config(sftp, Config),
+
+ Data = list_to_binary(lists:duplicate(750000,"a")),
+ ct:log("Data size to write is ~p bytes",[size(Data)]),
+ ssh_sftp:write_file(Sftp, FileName, [Data]),
+ {ok, Data} = ssh_sftp:read_file(Sftp, FileName).
+
+%%--------------------------------------------------------------------
remove_file() ->
[{doc,"Test API function delete/2"}].
remove_file(Config) when is_list(Config) ->
@@ -447,6 +537,254 @@ sftp_nonexistent_subsystem(Config) when is_list(Config) ->
{silently_accept_hosts, true}]).
%%--------------------------------------------------------------------
+version_option() ->
+ [{doc, "Test API option sftp_vsn"}].
+version_option(Config) when is_list(Config) ->
+ open_close_dir(Config).
+
+%%--------------------------------------------------------------------
+create_empty_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ erl_tar:close(Handle),
+ {ChPid,_} = ?config(sftp,Config),
+ {ok, #file_info{type=regular}} =
+ ssh_sftp:read_file_info(ChPid,fnp(?tar_file_name,Config)).
+
+%%--------------------------------------------------------------------
+files_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose]),
+ ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar(["f1.txt", "f2.txt"], Config).
+
+%%--------------------------------------------------------------------
+big_file_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar(["big.txt"], Config).
+
+
+%%--------------------------------------------------------------------
+files_chunked_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:close(Handle),
+ chk_tar(["f1.txt"], Config).
+
+%%--------------------------------------------------------------------
+directory_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ ok = erl_tar:add(Handle, fn("d1",Config), "d1", [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar(["d1"], Config).
+
+%%--------------------------------------------------------------------
+binaries_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ Bin = <<"A binary">>,
+ ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar([{"b1",Bin}], Config).
+
+%%--------------------------------------------------------------------
+null_crypto_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ Cinit = fun() -> {ok, no_state, _SendSize=5} end,
+ Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=5} end,
+ Cend = fun(Bin,_CState) -> {ok,Bin} end,
+ C = {Cinit,Cenc,Cend},
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ Bin = <<"A binary">>,
+ ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
+ ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]),
+ ok = erl_tar:close(Handle),
+ chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config).
+
+%%--------------------------------------------------------------------
+simple_crypto_tar_small(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ Cinit = fun() -> {ok, no_state, _Size=6} end,
+ Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=5} end,
+ Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_Size=4} end,
+ Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
+ C = {Cinit,Cenc,Cend},
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ Bin = <<"A binary">>,
+ ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
+ ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:close(Handle),
+ chk_tar([{"b1",Bin}, "f1.txt"], Config, [{crypto,{Cinit,Cdec}}]).
+
+%%--------------------------------------------------------------------
+simple_crypto_tar_big(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ Cinit = fun() -> {ok, no_state, _SendSize=6} end,
+ Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=5} end,
+ Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_SendSize=4} end,
+ Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
+ C = {Cinit,Cenc,Cend},
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ Bin = <<"A binary">>,
+ ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
+ ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]),
+ ok = erl_tar:close(Handle),
+ chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config, [{crypto,{Cinit,Cdec}}]).
+
+stuff(Bin) -> << <<C,C>> || <<C>> <= Bin >>.
+
+unstuff(Bin) -> << <<C>> || <<C,C>> <= Bin >>.
+
+%%--------------------------------------------------------------------
+read_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ NameBins = lists:sort(
+ [{"b1",<<"A binary">>},
+ {"b2",list_to_binary(lists:duplicate(750000,"a"))}
+ ]),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
+ || {Name,Bin} <- NameBins],
+ ok = erl_tar:close(HandleWrite),
+
+ chk_tar(NameBins, Config).
+
+%%--------------------------------------------------------------------
+read_null_crypto_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ NameBins = lists:sort(
+ [{"b1",<<"A binary">>},
+ {"b2",list_to_binary(lists:duplicate(750000,"a"))}
+ ]),
+ Cinitw = fun() -> {ok, no_state, _SendSize=5} end,
+ Cinitr = fun() -> {ok, no_state, _FetchSize=42} end,
+ Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=42*42} end,
+ Cdec = fun(Bin,CState) -> {ok,Bin,CState,_FetchSize=19} end,
+ Cendw = fun(Bin,_CState) -> {ok,Bin} end,
+ Cw = {Cinitw,Cenc,Cendw},
+ Cr = {Cinitr,Cdec},
+
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
+ || {Name,Bin} <- NameBins],
+ ok = erl_tar:close(HandleWrite),
+
+ chk_tar(NameBins, Config, [{crypto,Cr}]).
+
+%%--------------------------------------------------------------------
+read_crypto_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ NameBins = lists:sort(
+ [{"b1",<<"A binary">>},
+ {"b2",list_to_binary(lists:duplicate(750000,"a"))}
+ ]),
+ Cinitw = fun() -> {ok, no_state, _SendSize=5} end,
+ Cinitr = fun() -> {ok, no_state, _FetchSize=42} end,
+
+ Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=42*42} end,
+ Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_FetchSize=120} end,
+ Cendw = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
+ Cw = {Cinitw,Cenc,Cendw},
+ Cr = {Cinitr,Cdec},
+
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
+ || {Name,Bin} <- NameBins],
+ ok = erl_tar:close(HandleWrite),
+
+ chk_tar(NameBins, Config, [{crypto,Cr}]).
+
+%%--------------------------------------------------------------------
+aes_cbc256_crypto_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ NameBins = lists:sort(
+ [{"b1",<<"A binary">>},
+ {"b2",list_to_binary(lists:duplicate(750000,"a"))},
+ {"d1",fn("d1",Config)} % Dir
+ ]),
+ Key = <<"This is a 256 bit key. Boring...">>,
+ Ivec0 = crypto:rand_bytes(16),
+ DataSize = 1024, % data_size rem 16 = 0 for aes_cbc
+
+ Cinitw = fun() -> {ok, Ivec0, DataSize} end,
+ Cinitr = fun() -> {ok, Ivec0, DataSize} end,
+
+ Cenc = fun(PlainBin,Ivec) ->
+ CipherBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
+ {ok, CipherBin, crypto:next_iv(aes_cbc,CipherBin), DataSize}
+ end,
+ Cdec = fun(CipherBin,Ivec) ->
+ PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, CipherBin),
+ {ok, PlainBin, crypto:next_iv(aes_cbc,CipherBin), DataSize}
+ end,
+
+ Cendw = fun(PlainBin, _) when PlainBin == <<>> -> {ok, <<>>};
+ (PlainBin, Ivec) ->
+ CipherBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
+ pad(16,PlainBin)), %% Last chunk
+ {ok, CipherBin}
+ end,
+
+ Cw = {Cinitw,Cenc,Cendw},
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins],
+ ok = erl_tar:close(HandleWrite),
+
+ Cr = {Cinitr,Cdec},
+ chk_tar(NameBins, Config, [{crypto,Cr}]).
+
+
+pad(BlockSize, Bin) ->
+ PadSize = (BlockSize - (size(Bin) rem BlockSize)) rem BlockSize,
+ list_to_binary( lists:duplicate(PadSize,0) ).
+
+%%--------------------------------------------------------------------
+aes_ctr_stream_crypto_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ NameBins = lists:sort(
+ [{"b1",<<"A binary">>},
+ {"b2",list_to_binary(lists:duplicate(750000,"a"))},
+ {"d1",fn("d1",Config)} % Dir
+ ]),
+ Key = <<"This is a 256 bit key. Boring...">>,
+ Ivec0 = crypto:rand_bytes(16),
+
+ Cinitw = Cinitr = fun() -> {ok, crypto:stream_init(aes_ctr,Key,Ivec0)} end,
+
+ Cenc = fun(PlainBin,State) ->
+ {NewState,CipherBin} = crypto:stream_encrypt(State, PlainBin),
+ {ok, CipherBin, NewState}
+ end,
+ Cdec = fun(CipherBin,State) ->
+ {NewState,PlainBin} = crypto:stream_decrypt(State, CipherBin),
+ {ok, PlainBin, NewState}
+ end,
+
+ Cendw = fun(PlainBin, _) when PlainBin == <<>> -> {ok, <<>>};
+ (PlainBin, Ivec) ->
+ CipherBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
+ pad(16,PlainBin)), %% Last chunk
+ {ok, CipherBin}
+ end,
+
+ Cw = {Cinitw,Cenc,Cendw},
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins],
+ ok = erl_tar:close(HandleWrite),
+
+ Cr = {Cinitr,Cdec},
+ chk_tar(NameBins, Config, [{crypto,Cr}]).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
prep(Config) ->
@@ -458,6 +796,7 @@ prep(Config) ->
file:delete(TestFile),
file:delete(TestFile1),
file:delete(TestLink),
+ file:delete(fnp(?tar_file_name,Config)),
%% Initial config
DataDir = ?config(data_dir, Config),
@@ -467,3 +806,94 @@ prep(Config) ->
{ok, FileInfo} = file:read_file_info(TestFile),
ok = file:write_file_info(TestFile,
FileInfo#file_info{mode = Mode}).
+
+
+
+chk_tar(Items, Config) ->
+ chk_tar(Items, Config, []).
+
+chk_tar(Items, Config, Opts) ->
+ chk_tar(Items, fnp(?tar_file_name,Config), Config, Opts).
+
+chk_tar(Items, TarFileName, Config, Opts) when is_list(Opts) ->
+ tar_size(TarFileName, Config),
+ {ChPid,_} = ?config(sftp,Config),
+ {ok,HandleRead} = ssh_sftp:open_tar(ChPid, TarFileName, [read|Opts]),
+ {ok,NameValueList} = erl_tar:extract(HandleRead,[memory,verbose]),
+ ok = erl_tar:close(HandleRead),
+ case {lists:sort(expand_items(Items,Config)), lists:sort(NameValueList)} of
+ {L,L} ->
+ true;
+ {Expect,Actual} ->
+ ct:log("Expect: ~p",[Expect]), ct:log("Actual: ~p",[Actual]),
+ case erl_tar:table(TarFileName) of
+ {ok,Names} -> ct:log("names: ~p",[Names]);
+ Other -> ct:log("~p",[Other])
+ end,
+ ct:log("~s",[analyze_report(Expect, Actual)]),
+ ct:fail(bad_tar_contents)
+ end.
+
+analyze_report([E={NameE,BinE}|Es], [A={NameA,BinA}|As]) ->
+ if
+ NameE == NameA,
+ BinE =/= BinA->
+ [["Component ",NameE," differs. \n Expected: ",BinE,"\n Actual: ",BinA,"\n\n"]
+ | analyze_report(Es,As)];
+
+ NameE < NameA ->
+ [["Component ",NameE," is missing.\n\n"]
+ | analyze_report(Es,[A|As])];
+
+ NameE > NameA ->
+ [["Component ",NameA," is not expected.\n\n"]
+ | analyze_report([E|Es],As)];
+ true ->
+ analyze_report(Es, As)
+ end;
+analyze_report([{NameE,_BinE}|Es], []) ->
+ [["Component ",NameE," missing.\n\n"] | analyze_report(Es,[])];
+analyze_report([], [{NameA,_BinA}|As]) ->
+ [["Component ",NameA," not expected.\n\n"] | analyze_report([],As)];
+analyze_report([], []) ->
+ "".
+
+tar_size(TarFileName, Config) ->
+ {ChPid,_} = ?config(sftp,Config),
+ {ok,Data} = ssh_sftp:read_file(ChPid, TarFileName),
+ io:format('Tar file ~p is~n ~p bytes.~n',[TarFileName, size(Data)]).
+
+expand_items(Items, Config) ->
+ lists:flatten(
+ [case Item of
+ {_Name,Bin} when is_binary(Bin) ->
+ Item;
+ {Name,FileName} when is_list(FileName) ->
+ read_item_contents(Name, fn(FileName,Config));
+ FileName when is_list(FileName) ->
+ read_item_contents(FileName, fn(FileName,Config))
+ end || Item <- Items]).
+
+read_item_contents(ItemName, FileName) ->
+ case file:read_file(FileName) of
+ {ok,Bin} ->
+ {ItemName, Bin};
+ {error,eisdir} ->
+ {ok,FileNames} = file:list_dir(FileName),
+ [read_item_contents(filename:join(ItemName,Name),
+ filename:join(FileName,Name))
+ || Name<-FileNames]
+ end.
+
+fn(Name, Config) ->
+ Dir = ?config(data_dir, Config),
+ filename:join([Dir,"sftp_tar_test_data",Name]).
+
+fnp(Name, Config) ->
+ Dir = ?config(priv_dir, Config),
+ filename:join([Dir,Name]).
+
+
+fmt_host({A,B,C,D}) -> lists:concat([A,".",B,".",C,".",D]);
+fmt_host(S) -> S.
+
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt
new file mode 100644
index 0000000000..f597b69d4c
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt
@@ -0,0 +1,16384 @@
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f1 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f1
new file mode 100644
index 0000000000..1bafa9761e
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f1
@@ -0,0 +1 @@
+And hi from the subdirectory too!
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f2 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f2
new file mode 100644
index 0000000000..8566adaeef
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f2
@@ -0,0 +1 @@
+one more file
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt
new file mode 100644
index 0000000000..137d409d7b
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt
@@ -0,0 +1 @@
+Hi there!
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt
new file mode 100644
index 0000000000..d18c6b11fc
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt
@@ -0,0 +1 @@
+How are you?
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 7b22e45d5e..0ce8eec906 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -56,7 +56,8 @@ all() ->
retrieve_attributes,
set_attributes,
links,
- ver3_rename,
+ ver3_rename,
+ ver3_open_flags,
relpath,
sshd_read_file,
ver6_basic].
@@ -193,6 +194,39 @@ open_close_file(Config) when is_list(Config) ->
?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
?SSH_FXF_OPEN_EXISTING).
+ver3_open_flags() ->
+ [{doc, "Test open flags"}].
+ver3_open_flags(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ FileName = filename:join(PrivDir, "not_exist.txt"),
+ {Cm, Channel} = ?config(sftp, Config),
+ ReqId = 0,
+
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), Handle/binary>>, _} =
+ open_file_v3(FileName, Cm, Channel, ReqId,
+ ?SSH_FXF_CREAT bor ?SSH_FXF_TRUNC),
+ {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId),
+ ?UINT32(?SSH_FX_OK), _/binary>>, _} = close(Handle, ReqId,
+ Cm, Channel),
+
+ NewFileName = filename:join(PrivDir, "not_exist2.txt"),
+ NewReqId = ReqId + 1,
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId), NewHandle/binary>>, _} =
+ open_file_v3(NewFileName, Cm, Channel, NewReqId,
+ ?SSH_FXF_CREAT bor ?SSH_FXF_EXCL),
+ {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId),
+ ?UINT32(?SSH_FX_OK), _/binary>>, _} = close(NewHandle, NewReqId,
+ Cm, Channel),
+
+ NewFileName1 = filename:join(PrivDir, "test.txt"),
+ NewReqId1 = NewReqId + 1,
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId1), NewHandle1/binary>>, _} =
+ open_file_v3(NewFileName1, Cm, Channel, NewReqId1,
+ ?SSH_FXF_READ bor ?SSH_FXF_WRITE bor ?SSH_FXF_APPEND),
+ {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId1),
+ ?UINT32(?SSH_FX_OK), _/binary>>, _} = close(NewHandle1, NewReqId1,
+ Cm, Channel).
+
%%--------------------------------------------------------------------
open_close_dir() ->
[{doc,"Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"}].
@@ -662,6 +696,16 @@ open_file(File, Cm, Channel, ReqId, Access, Flags) ->
?SSH_FXP_OPEN, Data/binary>>),
reply(Cm, Channel).
+open_file_v3(File, Cm, Channel, ReqId, Flags) ->
+
+ Data = list_to_binary([?uint32(ReqId),
+ ?binary(list_to_binary(File)),
+ ?uint32(Flags),
+ ?REG_ATTERS]),
+ Size = 1 + size(Data),
+ ssh_connection:send(Cm, Channel, <<?UINT32(Size),
+ ?SSH_FXP_OPEN, Data/binary>>),
+ reply(Cm, Channel).
close(Handle, ReqId, Cm , Channel) ->
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index 00c25bf394..b8abf5e80e 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -113,6 +113,9 @@ io_request({put_chars, Chars}, TestCase, _, _, Buff) ->
io_request({put_chars, unicode, Chars}, TestCase, _, _, Buff) when is_binary(Chars) ->
reply(TestCase, Chars),
{ok, ok, Buff};
+io_request({put_chars, unicode, io_lib, format, [Fmt,Args]}, TestCase, _, _, Buff) ->
+ reply(TestCase, io_lib:format(Fmt,Args)),
+ {ok, ok, Buff};
io_request({put_chars, Enc, Chars}, TestCase, _, _, Buff) ->
reply(TestCase, unicode:characters_to_binary(Chars,Enc,latin1)),
{ok, ok, Buff};
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index 8b5343cecc..af70eeb46c 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.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
@@ -54,7 +54,9 @@ groups() ->
]},
{erlang_server, [], [erlang_server_openssh_client_exec,
erlang_server_openssh_client_exec_compressed,
- erlang_server_openssh_client_pulic_key_dsa]}
+ erlang_server_openssh_client_pulic_key_dsa,
+ erlang_server_openssh_client_cipher_suites,
+ erlang_server_openssh_client_macs]}
].
init_per_suite(Config) ->
@@ -89,6 +91,12 @@ end_per_group(erlang_server, Config) ->
end_per_group(_, Config) ->
Config.
+init_per_testcase(erlang_server_openssh_client_cipher_suites, Config) ->
+ check_ssh_client_support(Config);
+
+init_per_testcase(erlang_server_openssh_client_macs, Config) ->
+ check_ssh_client_support(Config);
+
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -111,22 +119,9 @@ erlang_shell_client_openssh_server(Config) when is_list(Config) ->
IO ! {input, self(), "echo Hej\n"},
receive_hej(),
IO ! {input, self(), "exit\n"},
- receive
- <<"logout">> ->
- receive
- <<"Connection closed">> ->
- ok
- end;
- Other0 ->
- ct:fail({unexpected_msg, Other0})
- end,
- receive
- {'EXIT', Shell, normal} ->
- ok;
- Other1 ->
- ct:fail({unexpected_msg, Other1})
- end.
-
+ receive_logout(),
+ receive_normal_exit(Shell).
+
%--------------------------------------------------------------------
erlang_client_openssh_server_exec() ->
[{doc, "Test api function ssh_connection:exec"}].
@@ -221,6 +216,108 @@ erlang_server_openssh_client_exec(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+erlang_server_openssh_client_cipher_suites() ->
+ [{doc, "Test that we can connect with different cipher suites."}].
+
+erlang_server_openssh_client_cipher_suites(Config) when is_list(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+
+ ct:sleep(500),
+
+ Supports = crypto:supports(),
+ Ciphers = proplists:get_value(ciphers, Supports),
+ Tests = [
+ {"3des-cbc", lists:member(des3_cbc, Ciphers)},
+ {"aes128-cbc", lists:member(aes_cbc128, Ciphers)},
+ {"aes128-ctr", lists:member(aes_ctr, Ciphers)},
+ {"aes256-cbc", false}
+ ],
+ lists:foreach(fun({Cipher, Expect}) ->
+ Cmd = "ssh -p " ++ integer_to_list(Port) ++
+ " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " " ++
+ " -c " ++ Cipher ++ " 1+1.",
+
+ ct:pal("Cmd: ~p~n", [Cmd]),
+
+ SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
+
+ case Expect of
+ true ->
+ receive
+ {SshPort,{data, <<"2\n">>}} ->
+ ok
+ after ?TIMEOUT ->
+ ct:fail("Did not receive answer")
+ end;
+ false ->
+ receive
+ {SshPort,{data, <<"no matching cipher found", _/binary>>}} ->
+ ok
+ after ?TIMEOUT ->
+ ct:fail("Did not receive no matching cipher message")
+ end
+ end
+ end, Tests),
+
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+erlang_server_openssh_client_macs() ->
+ [{doc, "Test that we can connect with different MACs."}].
+
+erlang_server_openssh_client_macs(Config) when is_list(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+
+ ct:sleep(500),
+
+ Supports = crypto:supports(),
+ Hashs = proplists:get_value(hashs, Supports),
+ MACs = [{"hmac-sha1", lists:member(sha, Hashs)},
+ {"hmac-sha2-256", lists:member(sha256, Hashs)},
+ {"hmac-md5-96", false},
+ {"hmac-ripemd160", false}],
+ lists:foreach(fun({MAC, Expect}) ->
+ Cmd = "ssh -p " ++ integer_to_list(Port) ++
+ " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " " ++
+ " -o MACs=" ++ MAC ++ " 1+1.",
+
+ ct:pal("Cmd: ~p~n", [Cmd]),
+
+ SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
+
+ case Expect of
+ true ->
+ receive
+ {SshPort,{data, <<"2\n">>}} ->
+ ok
+ after ?TIMEOUT ->
+ ct:fail("Did not receive answer")
+ end;
+ false ->
+ receive
+ {SshPort,{data, <<"no matching mac found", _/binary>>}} ->
+ ok
+ after ?TIMEOUT ->
+ ct:fail("Did not receive no matching mac message")
+ end
+ end
+ end, MACs),
+
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
erlang_server_openssh_client_exec_compressed() ->
[{doc, "Test that exec command works."}].
@@ -427,9 +524,67 @@ erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config)
%%--------------------------------------------------------------------
receive_hej() ->
receive
- <<"Hej\n">> = Hej->
+ <<"Hej", _binary>> = Hej ->
+ ct:pal("Expected result: ~p~n", [Hej]);
+ <<"Hej\n", _binary>> = Hej ->
+ ct:pal("Expected result: ~p~n", [Hej]);
+ <<"Hej\r\n", _/binary>> = Hej ->
ct:pal("Expected result: ~p~n", [Hej]);
Info ->
- ct:pal("Extra info: ~p~n", [Info]),
- receive_hej()
+ Lines = binary:split(Info, [<<"\r\n">>], [global]),
+ case lists:member(<<"Hej">>, Lines) of
+ true ->
+ ct:pal("Expected result found in lines: ~p~n", [Lines]),
+ ok;
+ false ->
+ ct:pal("Extra info: ~p~n", [Info]),
+ receive_hej()
+ end
+ end.
+
+receive_logout() ->
+ receive
+ <<"logout">> ->
+ receive
+ <<"Connection closed">> ->
+ ok
+ end;
+ Info ->
+ ct:pal("Extra info when logging out: ~p~n", [Info]),
+ receive_logout()
+ end.
+
+receive_normal_exit(Shell) ->
+ receive
+ {'EXIT', Shell, normal} ->
+ ok;
+ <<"\r\n">> ->
+ receive_normal_exit(Shell);
+ Other ->
+ ct:fail({unexpected_msg, Other})
+ end.
+
+%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+%% Check if we have a "newer" ssh client that supports these test cases
+%%--------------------------------------------------------------------
+check_ssh_client_support(Config) ->
+ Port = open_port({spawn, "ssh -Q cipher"}, [exit_status, stderr_to_stdout]),
+ case check_ssh_client_support2(Port) of
+ 0 -> % exit status from command (0 == ok)
+ ssh:start(),
+ Config;
+ _ ->
+ {skip, "test case not supported by ssh client"}
+ end.
+
+check_ssh_client_support2(P) ->
+ receive
+ {P, {data, _A}} ->
+ check_ssh_client_support2(P);
+ {P, {exit_status, E}} ->
+ E
+ after 5000 ->
+ ct:pal("Openssh command timed out ~n"),
+ -1
end.
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 40ed27d8f5..c8cac3e852 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.1
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index c61b2a9c2f..4349e5a456 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -25,7 +25,204 @@
<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.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make sure the clean rule for ssh, ssl, eunit and otp_mibs
+ actually removes generated files.</p>
+ <p>
+ Own Id: OTP-12200</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change code to reflect that state data may be secret to
+ avoid breaking dialyzer contracts.</p>
+ <p>
+ Own Id: OTP-12341</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 5.3.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Handle the fact that servers may send an empty SNI
+ extension to the client.</p>
+ <p>
+ Own Id: OTP-12198</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 5.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Corrected handling of ECC certificates, there where
+ several small issues with the handling of such
+ certificates in the ssl and public_key application. Now
+ ECC signed ECC certificates shall work and not only RSA
+ signed ECC certificates.</p>
+ <p>
+ Own Id: OTP-12026</p>
+ </item>
+ <item>
+ <p>
+ Check that the certificate chain ends with a trusted ROOT
+ CA e.i. a self-signed certificate, but provide an option
+ partial_chain to enable the application to define an
+ intermediat CA as trusted.</p>
+ <p>
+ Own Id: OTP-12149</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add decode functions for SNI (Server Name Indication)</p>
+ <p>
+ Own Id: OTP-12048</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index ffee4bd1af..249fee5760 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2014</year>
+ <year>1999</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -163,7 +163,7 @@
is supplied it will override the certfile option.</item>
<tag>{certfile, path()}</tag>
- <item>Path to a file containing the user's certificate.</item>
+ <item>Path to a file containing the user's PEM encoded certificate.</item>
<tag>{key, {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey' |'PrivateKeyInfo', der_encoded()}}</tag>
<item> The DER encoded users private key. If this option
@@ -226,7 +226,7 @@
<p>The verification fun should be defined as:</p>
<code>
-fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
+fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
{extension, #'Extension'{}}, InitialUserState :: term()) ->
{valid, UserState :: term()} | {valid_peer, UserState :: term()} |
{fail, Reason :: term()} | {unknown, UserState :: term()}.
@@ -252,7 +252,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
always returns {valid, UserState}, the TLS/SSL handshake will
not be terminated with respect to verification failures and
the connection will be established. If called with an
- extension unknown to the user application the return value
+ extension unknown to the user application, the return value
{unknown, UserState} should be used.</p>
<p>The default verify_fun option in verify_peer mode:</p>
@@ -283,9 +283,29 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
end, []}
</code>
-<p>Possible path validation errors: </p>
+ <p>Possible path validation errors are given on the form {bad_cert, Reason} where Reason is:</p>
-<p> {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, {bad_cert, invalid_signature}, {bad_cert, unknown_ca},{bad_cert, selfsigned_peer}, {bad_cert, name_not_permitted}, {bad_cert, missing_basic_constraint}, {bad_cert, invalid_key_usage}</p>
+ <taglist>
+ <tag>unknown_ca</tag>
+ <item>No trusted CA was found in the trusted store. The trusted CA is
+ normally a so called ROOT CA that is a self-signed cert. Trust may
+ be claimed for an intermediat CA (trusted anchor does not have to be self signed
+ according to X-509) by using the option <c>partial_chain</c></item>
+
+ <tag>selfsigned_peer</tag>
+ <item>The chain consisted only of one self-signed certificate.</item>
+
+ <tag>PKIX X-509-path validation error</tag>
+ <item> Possible such reasons see <seealso
+ marker="public_key:public_key#pkix_path_validation-3"> public_key:pkix_path_validation/3 </seealso></item>
+ </taglist>
+
+ </item>
+
+ <tag>{partial_chain, fun(Chain::[DerCert]) -> {trusted_ca, DerCert} | unknown_ca </tag>
+ <item>
+ Claim an intermediat CA in the chain as trusted. TLS will then perform the public_key:pkix_path_validation/3
+ with the selected CA as trusted anchor and the rest of the chain.
</item>
<tag>{versions, [protocol()]}</tag>
@@ -328,11 +348,23 @@ fun(srp, Username :: string(), UserState :: term()) ->
</p>
</item>
+ <tag>{padding_check, boolean()}</tag>
+ <item>
+ <p> This option only affects TLS-1.0 connections.
+ If set to false it disables the block cipher padding check
+ to be able to interoperate with legacy software.
+ </p>
+
+ <warning><p> Using this option makes TLS vulnerable to
+ the Poodle attack</p></warning>
+
+ </item>
+
</taglist>
-
+
</section>
-
- <section>
+
+ <section>
<title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title>
<p>Options described here are client specific or has a slightly different
@@ -518,7 +550,19 @@ fun(srp, Username :: string(), UserState :: term()) ->
</p>
</desc>
</func>
-
+
+ <func>
+ <name>clear_pem_cache() -> ok </name>
+ <fsummary> Clears the pem cache</fsummary>
+
+ <desc><p>PEM files, used by ssl API-functions, are cached. The
+ cache is regularly checked to see if any cache entries should be
+ invalidated, however this function provides a way to
+ unconditionally clear the whole cache.
+ </p>
+ </desc>
+ </func>
+
<func>
<name>connect(Socket, SslOptions) -> </name>
<name>connect(Socket, SslOptions, Timeout) -> {ok, SslSocket}
diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml
index 43cb3934f7..f1377cabda 100644
--- a/lib/ssl/doc/src/ssl_app.xml
+++ b/lib/ssl/doc/src/ssl_app.xml
@@ -4,7 +4,7 @@
<appref>
<header>
<copyright>
- <year>1999</year><year>2013</year>
+ <year>1999</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -82,7 +82,16 @@
callback module, defaults to [].
</p>
</item>
-
+
+ <tag><c><![CDATA[ssl_pem_cache_clean = integer() <optional>]]></c></tag>
+ <item>
+ <p>
+ Number of milliseconds between PEM cache validations.
+ </p>
+ <seealso
+ marker="ssl#clear_pem_cache-0">ssl:clear_pem_cache/0</seealso>
+
+ </item>
</taglist>
</section>
diff --git a/lib/ssl/doc/src/ssl_protocol.xml b/lib/ssl/doc/src/ssl_protocol.xml
index cdfafe224b..80d9cc4ee8 100644
--- a/lib/ssl/doc/src/ssl_protocol.xml
+++ b/lib/ssl/doc/src/ssl_protocol.xml
@@ -83,7 +83,7 @@
<em>subject</em>. The certificate is signed
with the private key of the issuer of the certificate. A chain
of trust is build by having the issuer in its turn being
- certified by an other certificate and so on until you reach the
+ certified by another certificate and so on until you reach the
so called root certificate that is self signed i.e. issued
by itself.</p>
diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile
index 7c4c8ec2cc..0c00a650b9 100644
--- a/lib/ssl/src/Makefile
+++ b/lib/ssl/src/Makefile
@@ -118,7 +118,7 @@ $(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES)
debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
clean:
- rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
+ rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(BEHAVIOUR_TARGET_FILES)
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl
index a7bbb6bc40..ae35dd7ea4 100644
--- a/lib/ssl/src/dtls_record.erl
+++ b/lib/ssl/src/dtls_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2015. 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
@@ -146,7 +146,7 @@ decode_cipher_text(#ssl_tls{type = Type, version = Version,
= ConnnectionStates0) ->
CompressAlg = SecParams#security_parameters.compression_algorithm,
{PlainFragment, Mac, ReadState1} = ssl_record:decipher(dtls_v1:corresponding_tls_version(Version),
- CipherFragment, ReadState0),
+ CipherFragment, ReadState0, true),
MacHash = calc_mac_hash(ReadState1, Type, Version, Epoch, Seq, PlainFragment),
case ssl_record:is_correct_mac(Mac, MacHash) of
true ->
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index b713f86c1e..7986722094 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,13 +1,13 @@
%% -*- erlang -*-
{"%VSN%",
[
- {<<"5\\.3\\.[1-4]($|\\..*)">>, [{restart_application, ssl}]},
+ {<<"5\\.3\\.[1-7]($|\\..*)">>, [{restart_application, ssl}]},
{<<"5\\.[0-2]($|\\..*)">>, [{restart_application, ssl}]},
{<<"4\\..*">>, [{restart_application, ssl}]},
{<<"3\\..*">>, [{restart_application, ssl}]}
],
[
- {<<"5\\.3\\.[1-4]($|\\..*)">>, [{restart_application, ssl}]},
+ {<<"5\\.3\\.[1-7]($|\\..*)">>, [{restart_application, ssl}]},
{<<"5\\.[0-2]($|\\..*)">>, [{restart_application, ssl}]},
{<<"4\\..*">>, [{restart_application, ssl}]},
{<<"3\\..*">>, [{restart_application, ssl}]}
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index be1041ca13..4b7f49547b 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. 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
@@ -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()}.
@@ -570,21 +569,24 @@ handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
cacertfile = CaCertFile0} = InheritedSslOpts) ->
RecordCB = record_cb(Protocol),
CaCerts = handle_option(cacerts, Opts0, CaCerts0),
- {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun} = handle_verify_options(Opts0, CaCerts),
+ {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder} = handle_verify_options(Opts0, CaCerts),
CaCertFile = case proplists:get_value(cacertfile, Opts0, CaCertFile0) of
undefined ->
CaCertDefault;
CAFile ->
CAFile
end,
+
NewVerifyOpts = InheritedSslOpts#ssl_options{cacerts = CaCerts,
cacertfile = CaCertFile,
verify = Verify,
verify_fun = VerifyFun,
+ partial_chain = PartialChainHanlder,
fail_if_no_peer_cert = FailIfNoPeerCert},
SslOpts1 = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
- end, Opts0, [cacerts, cacertfile, verify, verify_fun, fail_if_no_peer_cert]),
+ end, Opts0, [cacerts, cacertfile, verify, verify_fun, partial_chain,
+ fail_if_no_peer_cert]),
case handle_option(versions, SslOpts1, []) of
[] ->
new_ssl_options(SslOpts1, NewVerifyOpts, RecordCB);
@@ -604,10 +606,10 @@ handle_options(Opts0) ->
ReuseSessionFun = fun(_, _, _, _) -> true end,
CaCerts = handle_option(cacerts, Opts, undefined),
- {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun} = handle_verify_options(Opts, CaCerts),
+ {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder} =
+ handle_verify_options(Opts, CaCerts),
CertFile = handle_option(certfile, Opts, <<>>),
-
RecordCb = record_cb(Opts),
Versions = case handle_option(versions, Opts, []) of
@@ -621,6 +623,7 @@ handle_options(Opts0) ->
versions = Versions,
verify = validate_option(verify, Verify),
verify_fun = VerifyFun,
+ partial_chain = PartialChainHanlder,
fail_if_no_peer_cert = FailIfNoPeerCert,
verify_client_once = handle_option(verify_client_once, Opts, false),
depth = handle_option(depth, Opts, 1),
@@ -653,11 +656,12 @@ handle_options(Opts0) ->
log_alert = handle_option(log_alert, Opts, true),
server_name_indication = handle_option(server_name_indication, Opts, undefined),
honor_cipher_order = handle_option(honor_cipher_order, Opts, false),
- protocol = proplists:get_value(protocol, Opts, tls)
+ protocol = proplists:get_value(protocol, Opts, tls),
+ padding_check = proplists:get_value(padding_check, Opts, true)
},
CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}),
- SslOptions = [protocol, versions, verify, verify_fun,
+ SslOptions = [protocol, versions, verify, verify_fun, partial_chain,
fail_if_no_peer_cert, verify_client_once,
depth, cert, certfile, key, keyfile,
password, cacerts, cacertfile, dh, dhfile,
@@ -666,7 +670,7 @@ handle_options(Opts0) ->
cb_info, renegotiate_at, secure_renegotiate, hibernate_after,
erl_dist, next_protocols_advertised,
client_preferred_next_protocols, log_alert,
- server_name_indication, honor_cipher_order],
+ server_name_indication, honor_cipher_order, padding_check],
SockOpts = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
@@ -709,6 +713,8 @@ validate_option(verify_fun, Fun) when is_function(Fun) ->
end, Fun};
validate_option(verify_fun, {Fun, _} = Value) when is_function(Fun) ->
Value;
+validate_option(partial_chain, Value) when is_function(Value) ->
+ Value;
validate_option(fail_if_no_peer_cert, Value) when is_boolean(Value) ->
Value;
validate_option(verify_client_once, Value) when is_boolean(Value) ->
@@ -842,6 +848,8 @@ validate_option(server_name_indication, undefined) ->
undefined;
validate_option(honor_cipher_order, Value) when is_boolean(Value) ->
Value;
+validate_option(padding_check, Value) when is_boolean(Value) ->
+ Value;
validate_option(Opt, Value) ->
throw({error, {options, {Opt, Value}}}).
@@ -1148,25 +1156,32 @@ handle_verify_options(Opts, CaCerts) ->
UserFailIfNoPeerCert = handle_option(fail_if_no_peer_cert, Opts, false),
UserVerifyFun = handle_option(verify_fun, Opts, undefined),
-
+ PartialChainHanlder = handle_option(partial_chain, Opts,
+ fun(_) -> unknown_ca end),
+
%% Handle 0, 1, 2 for backwards compatibility
case proplists:get_value(verify, Opts, verify_none) of
0 ->
{verify_none, false,
- ca_cert_default(verify_none, VerifyNoneFun, CaCerts), VerifyNoneFun};
+ ca_cert_default(verify_none, VerifyNoneFun, CaCerts),
+ VerifyNoneFun, PartialChainHanlder};
1 ->
{verify_peer, false,
- ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun};
+ ca_cert_default(verify_peer, UserVerifyFun, CaCerts),
+ UserVerifyFun, PartialChainHanlder};
2 ->
{verify_peer, true,
- ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun};
- verify_none ->
+ ca_cert_default(verify_peer, UserVerifyFun, CaCerts),
+ UserVerifyFun, PartialChainHanlder};
+ verify_none ->
{verify_none, false,
- ca_cert_default(verify_none, VerifyNoneFun, CaCerts), VerifyNoneFun};
+ ca_cert_default(verify_none, VerifyNoneFun, CaCerts),
+ VerifyNoneFun, PartialChainHanlder};
verify_peer ->
{verify_peer, UserFailIfNoPeerCert,
- ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun};
+ ca_cert_default(verify_peer, UserVerifyFun, CaCerts),
+ UserVerifyFun, PartialChainHanlder};
Value ->
throw({error, {options, {verify, Value}}})
end.
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index b186a1015a..30d224fee2 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. 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
@@ -30,7 +30,7 @@
-include("ssl_internal.hrl").
-include_lib("public_key/include/public_key.hrl").
--export([trusted_cert_and_path/3,
+-export([trusted_cert_and_path/4,
certificate_chain/3,
file_to_certificats/2,
validate_extension/3,
@@ -46,14 +46,14 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec trusted_cert_and_path([der_cert()], db_handle(), certdb_ref()) ->
+-spec trusted_cert_and_path([der_cert()], db_handle(), certdb_ref(), fun()) ->
{der_cert() | unknown_ca, [der_cert()]}.
%%
%% Description: Extracts the root cert (if not presents tries to
%% look it up, if not found {bad_cert, unknown_ca} will be added verification
%% errors. Returns {RootCert, Path, VerifyErrors}
%%--------------------------------------------------------------------
-trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef) ->
+trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef, PartialChainHandler) ->
Path = [Cert | _] = lists:reverse(CertChain),
OtpCert = public_key:pkix_decode_cert(Cert, otp),
SignedAndIssuerID =
@@ -62,32 +62,23 @@ trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef) ->
{ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self),
{self, IssuerId};
false ->
- case public_key:pkix_issuer_id(OtpCert, other) of
- {ok, IssuerId} ->
- {other, IssuerId};
- {error, issuer_not_found} ->
- case find_issuer(OtpCert, CertDbHandle) of
- {ok, IssuerId} ->
- {other, IssuerId};
- Other ->
- Other
- end
- end
+ other_issuer(OtpCert, CertDbHandle)
end,
case SignedAndIssuerID of
{error, issuer_not_found} ->
%% The root CA was not sent and can not be found.
- {unknown_ca, Path};
+ handle_incomplete_chain(Path, PartialChainHandler);
{self, _} when length(Path) == 1 ->
{selfsigned_peer, Path};
{_ ,{SerialNr, Issuer}} ->
case ssl_manager:lookup_trusted_cert(CertDbHandle, CertDbRef, SerialNr, Issuer) of
- {ok, {BinCert,_}} ->
- {BinCert, Path};
+ {ok, Trusted} ->
+ %% Trusted must be selfsigned or it is an incomplete chain
+ handle_path(Trusted, Path, PartialChainHandler);
_ ->
%% Root CA could not be verified
- {unknown_ca, Path}
+ handle_incomplete_chain(Path, PartialChainHandler)
end
end.
@@ -222,23 +213,27 @@ certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned
_ ->
%% The trusted cert may be obmitted from the chain as the
%% counter part needs to have it anyway to be able to
- %% verify it. This will be the normal case for servers
- %% that does not verify the clients and hence have not
- %% specified the cacertfile.
+ %% verify it.
{ok, lists:reverse(Chain)}
end.
find_issuer(OtpCert, CertDbHandle) ->
- IsIssuerFun = fun({_Key, {_Der, #'OTPCertificate'{} = ErlCertCandidate}}, Acc) ->
- case public_key:pkix_is_issuer(OtpCert, ErlCertCandidate) of
- true ->
- throw(public_key:pkix_issuer_id(ErlCertCandidate, self));
- false ->
- Acc
- end;
- (_, Acc) ->
- Acc
- end,
+ IsIssuerFun =
+ fun({_Key, {_Der, #'OTPCertificate'{} = ErlCertCandidate}}, Acc) ->
+ case public_key:pkix_is_issuer(OtpCert, ErlCertCandidate) of
+ true ->
+ case verify_cert_signer(OtpCert, ErlCertCandidate#'OTPCertificate'.tbsCertificate) of
+ true ->
+ throw(public_key:pkix_issuer_id(ErlCertCandidate, self));
+ false ->
+ Acc
+ end;
+ false ->
+ Acc
+ end;
+ (_, Acc) ->
+ Acc
+ end,
try ssl_pkix_db:foldl(IsIssuerFun, issuer_not_found, CertDbHandle) of
issuer_not_found ->
@@ -254,3 +249,57 @@ is_valid_extkey_usage(KeyUse, client) ->
is_valid_extkey_usage(KeyUse, server) ->
%% Server wants to verify client
is_valid_key_usage(KeyUse, ?'id-kp-clientAuth').
+
+verify_cert_signer(OtpCert, SignerTBSCert) ->
+ PublicKey = public_key(SignerTBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo),
+ public_key:pkix_verify(public_key:pkix_encode('OTPCertificate', OtpCert, otp), PublicKey).
+
+public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'id-ecPublicKey',
+ parameters = Params},
+ subjectPublicKey = Point}) ->
+ {Point, Params};
+public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'rsaEncryption'},
+ subjectPublicKey = Key}) ->
+ Key;
+public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'id-dsa',
+ parameters = {params, Params}},
+ subjectPublicKey = Key}) ->
+ {Key, Params}.
+
+other_issuer(OtpCert, CertDbHandle) ->
+ case public_key:pkix_issuer_id(OtpCert, other) of
+ {ok, IssuerId} ->
+ {other, IssuerId};
+ {error, issuer_not_found} ->
+ case find_issuer(OtpCert, CertDbHandle) of
+ {ok, IssuerId} ->
+ {other, IssuerId};
+ Other ->
+ Other
+ end
+ end.
+
+handle_path({BinCert, OTPCert}, Path, PartialChainHandler) ->
+ case public_key:pkix_is_self_signed(OTPCert) of
+ true ->
+ {BinCert, lists:delete(BinCert, Path)};
+ false ->
+ handle_incomplete_chain(Path, PartialChainHandler)
+ end.
+
+handle_incomplete_chain(Chain, Fun) ->
+ case catch Fun(Chain) of
+ {trusted_ca, DerCert} ->
+ new_trusteded_chain(DerCert, Chain);
+ unknown_ca = Error ->
+ {Error, Chain};
+ _ ->
+ {unknown_ca, Chain}
+ end.
+
+new_trusteded_chain(DerCert, [DerCert | Chain]) ->
+ {DerCert, Chain};
+new_trusteded_chain(DerCert, [_ | Rest]) ->
+ new_trusteded_chain(DerCert, Rest);
+new_trusteded_chain(_, []) ->
+ unknown_ca.
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 72467ea2a0..ff9c618a35 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,8 +33,7 @@
-include_lib("public_key/include/public_key.hrl").
-export([security_parameters/2, security_parameters/3, suite_definition/1,
- decipher/5, cipher/5,
- suite/1, suites/1, all_suites/1,
+ decipher/6, cipher/5, suite/1, suites/1, all_suites/1,
ec_keyed_suites/0, anonymous_suites/0, psk_suites/1, srp_suites/0,
openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1,
hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2]).
@@ -143,17 +142,18 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
{T, CS0#cipher_state{iv=NextIV}}.
%%--------------------------------------------------------------------
--spec decipher(cipher_enum(), integer(), #cipher_state{}, binary(), ssl_record:ssl_version()) ->
+-spec decipher(cipher_enum(), integer(), #cipher_state{}, binary(),
+ ssl_record:ssl_version(), boolean()) ->
{binary(), binary(), #cipher_state{}} | #alert{}.
%%
%% Description: Decrypts the data and the MAC using cipher described
%% by cipher_enum() and updating the cipher state.
%%-------------------------------------------------------------------
-decipher(?NULL, _HashSz, CipherState, Fragment, _) ->
+decipher(?NULL, _HashSz, CipherState, Fragment, _, _) ->
{Fragment, <<>>, CipherState};
-decipher(?RC4, HashSz, CipherState, Fragment, _) ->
+decipher(?RC4, HashSz, CipherState, Fragment, _, _) ->
State0 = case CipherState#cipher_state.state of
- undefined -> crypto:stream_init(rc4, CipherState#cipher_state.key);
+ undefined -> crypto:stream_init(rc4, CipherState#cipher_state.key);
S -> S
end,
try crypto:stream_decrypt(State0, Fragment) of
@@ -171,23 +171,23 @@ decipher(?RC4, HashSz, CipherState, Fragment, _) ->
?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
end;
-decipher(?DES, HashSz, CipherState, Fragment, Version) ->
+decipher(?DES, HashSz, CipherState, Fragment, Version, PaddingCheck) ->
block_decipher(fun(Key, IV, T) ->
crypto:block_decrypt(des_cbc, Key, IV, T)
- end, CipherState, HashSz, Fragment, Version);
-decipher(?'3DES', HashSz, CipherState, Fragment, Version) ->
+ end, CipherState, HashSz, Fragment, Version, PaddingCheck);
+decipher(?'3DES', HashSz, CipherState, Fragment, Version, PaddingCheck) ->
block_decipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) ->
crypto:block_decrypt(des3_cbc, [K1, K2, K3], IV, T)
- end, CipherState, HashSz, Fragment, Version);
-decipher(?AES, HashSz, CipherState, Fragment, Version) ->
+ end, CipherState, HashSz, Fragment, Version, PaddingCheck);
+decipher(?AES, HashSz, CipherState, Fragment, Version, PaddingCheck) ->
block_decipher(fun(Key, IV, T) when byte_size(Key) =:= 16 ->
crypto:block_decrypt(aes_cbc128, Key, IV, T);
(Key, IV, T) when byte_size(Key) =:= 32 ->
crypto:block_decrypt(aes_cbc256, Key, IV, T)
- end, CipherState, HashSz, Fragment, Version).
+ end, CipherState, HashSz, Fragment, Version, PaddingCheck).
block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
- HashSz, Fragment, Version) ->
+ HashSz, Fragment, Version, PaddingCheck) ->
try
Text = Fun(Key, IV, Fragment),
NextIV = next_iv(Fragment, IV),
@@ -195,7 +195,7 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
Content = GBC#generic_block_cipher.content,
Mac = GBC#generic_block_cipher.mac,
CipherState1 = CipherState0#cipher_state{iv=GBC#generic_block_cipher.next_iv},
- case is_correct_padding(GBC, Version) of
+ case is_correct_padding(GBC, Version, PaddingCheck) of
true ->
{Content, Mac, CipherState1};
false ->
@@ -1288,16 +1288,18 @@ generic_stream_cipher_from_bin(T, HashSz) ->
#generic_stream_cipher{content=Content,
mac=Mac}.
-%% For interoperability reasons we do not check the padding content in
-%% SSL 3.0 and TLS 1.0 as it is not strictly required and breaks
-%% interopability with for instance Google.
is_correct_padding(#generic_block_cipher{padding_length = Len,
- padding = Padding}, {3, N})
- when N == 0; N == 1 ->
- Len == byte_size(Padding);
-%% Padding must be check in TLS 1.1 and after
+ padding = Padding}, {3, 0}, _) ->
+ Len == byte_size(Padding); %% Only length check is done in SSL 3.0 spec
+%% For interoperability reasons it is possible to disable
+%% the padding check when using TLS 1.0, as it is not strictly required
+%% in the spec (only recommended), howerver this makes TLS 1.0 vunrable to the Poodle attack
+%% so by default this clause will not match
+is_correct_padding(GenBlockCipher, {3, 1}, false) ->
+ is_correct_padding(GenBlockCipher, {3, 0}, false);
+%% Padding must be checked in TLS 1.1 and after
is_correct_padding(#generic_block_cipher{padding_length = Len,
- padding = Padding}, _) ->
+ padding = Padding}, _, _) ->
Len == byte_size(Padding) andalso
list_to_binary(lists:duplicate(Len, Len)) == Padding.
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 34006612a2..b6059eac58 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 };
@@ -407,7 +414,9 @@ certify(#certificate{} = Cert,
ssl_options = Opts} = State, Connection) ->
case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef, Opts#ssl_options.depth,
Opts#ssl_options.verify,
- Opts#ssl_options.verify_fun, Role) of
+ Opts#ssl_options.verify_fun,
+ Opts#ssl_options.partial_chain,
+ Role) of
{PeerCert, PublicKeyInfo} ->
handle_peer_cert(Role, PeerCert, PublicKeyInfo,
State#state{client_certificate_requested = false}, Connection);
@@ -589,6 +598,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 +609,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 +617,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});
@@ -926,27 +937,27 @@ terminate(_Reason, _StateName, #state{transport_cb = Transport,
Transport:close(Socket).
format_status(normal, [_, State]) ->
- [{data, [{"StateData", State}]}];
+ [{data, [{"StateData", State}]}];
format_status(terminate, [_, State]) ->
SslOptions = (State#state.ssl_options),
- NewOptions = SslOptions#ssl_options{password = "***",
- cert = "***",
- cacerts = "***",
- key = "***",
- dh = "***",
- psk_identity = "***",
- srp_identity = "***"},
- [{data, [{"StateData", State#state{connection_states = "***",
- protocol_buffers = "***",
- user_data_buffer = "***",
- tls_handshake_history = "***",
- session = "***",
- private_key = "***",
- diffie_hellman_params = "***",
- diffie_hellman_keys = "***",
- srp_params = "***",
- srp_keys = "***",
- premaster_secret = "***",
+ NewOptions = SslOptions#ssl_options{password = ?SECRET_PRINTOUT,
+ cert = ?SECRET_PRINTOUT,
+ cacerts = ?SECRET_PRINTOUT,
+ key = ?SECRET_PRINTOUT,
+ dh = ?SECRET_PRINTOUT,
+ psk_identity = ?SECRET_PRINTOUT,
+ srp_identity = ?SECRET_PRINTOUT},
+ [{data, [{"StateData", State#state{connection_states = ?SECRET_PRINTOUT,
+ protocol_buffers = ?SECRET_PRINTOUT,
+ user_data_buffer = ?SECRET_PRINTOUT,
+ tls_handshake_history = ?SECRET_PRINTOUT,
+ session = ?SECRET_PRINTOUT,
+ private_key = ?SECRET_PRINTOUT,
+ diffie_hellman_params = ?SECRET_PRINTOUT,
+ diffie_hellman_keys = ?SECRET_PRINTOUT,
+ srp_params = ?SECRET_PRINTOUT,
+ srp_keys = ?SECRET_PRINTOUT,
+ premaster_secret = ?SECRET_PRINTOUT,
ssl_options = NewOptions
}}]}].
%%--------------------------------------------------------------------
@@ -1034,9 +1045,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..b9a1ef3a84 100644
--- a/lib/ssl/src/ssl_connection.hrl
+++ b/lib/ssl/src/ssl_connection.hrl
@@ -46,11 +46,11 @@
socket :: port(),
ssl_options :: #ssl_options{},
socket_options :: #socket_options{},
- connection_states :: #connection_states{},
- protocol_buffers :: term(), %% #protocol_buffers{} from tls_record.hrl or dtls_recor.hrl
- tls_handshake_history :: ssl_handshake:ssl_handshake_history(),
+ connection_states :: #connection_states{} | secret_printout(),
+ protocol_buffers :: term() | secret_printout() , %% #protocol_buffers{} from tls_record.hrl or dtls_recor.hrl
+ tls_handshake_history :: ssl_handshake:ssl_handshake_history() | secret_printout(),
cert_db :: reference(),
- session :: #session{},
+ session :: #session{} | secret_printout(),
session_cache :: db_handle(),
session_cache_cb :: atom(),
negotiated_version :: ssl_record:ssl_version(),
@@ -58,18 +58,18 @@
key_algorithm :: ssl_cipher:key_algo(),
hashsign_algorithm = {undefined, undefined},
cert_hashsign_algorithm,
- public_key_info ::ssl_handshake:public_key_info(),
- private_key ::public_key:private_key(),
- diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side
- diffie_hellman_keys, % {PublicKey, PrivateKey}
+ public_key_info :: ssl_handshake:public_key_info(),
+ private_key :: public_key:private_key() | secret_printout(),
+ diffie_hellman_params:: #'DHParameter'{} | undefined | secret_printout(),
+ diffie_hellman_keys :: {PublicKey :: binary(), PrivateKey :: binary()} | #'ECPrivateKey'{} | undefined | secret_printout(),
psk_identity :: binary(), % server psk identity hint
- srp_params :: #srp_user{},
- srp_keys ::{PublicKey :: binary(), PrivateKey :: binary()},
- premaster_secret :: binary(),
+ srp_params :: #srp_user{} | secret_printout(),
+ srp_keys ::{PublicKey :: binary(), PrivateKey :: binary()} | secret_printout(),
+ premaster_secret :: binary() | secret_printout() ,
file_ref_db :: db_handle(),
cert_db_ref :: certdb_ref(),
bytes_to_read :: undefined | integer(), %% bytes to read in passive mode
- user_data_buffer :: undefined | binary(),
+ user_data_buffer :: undefined | binary() | secret_printout(),
renegotiation :: undefined | {boolean(), From::term() | internal | peer},
start_or_recv_from :: term(),
timer :: undefined | reference(), % start_or_recive_timer
@@ -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..88ccb94e0b 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -49,7 +49,7 @@
finished/5, next_protocol/1]).
%% Handle handshake messages
--export([certify/7, client_certificate_verify/6, certificate_verify/6, verify_signature/5,
+-export([certify/8, client_certificate_verify/6, certificate_verify/6, verify_signature/5,
master_secret/5, server_key_exchange_hash/2, verify_connection/6,
init_handshake_history/0, update_handshake_history/2, verify_server_key/5
]).
@@ -201,13 +201,13 @@ client_certificate_verify(OwnCert, MasterSecret, Version,
end.
%%--------------------------------------------------------------------
--spec certificate_request(ssl_cipher:erl_cipher_suite(), db_handle(), certdb_ref(), ssl_record:ssl_version()) ->
+-spec certificate_request(ssl_cipher:cipher_suite(), db_handle(), certdb_ref(), ssl_record:ssl_version()) ->
#certificate_request{}.
%%
%% Description: Creates a certificate_request message, called by the server.
%%--------------------------------------------------------------------
certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version) ->
- Types = certificate_types(CipherSuite),
+ Types = certificate_types(ssl_cipher:suite_definition(CipherSuite), Version),
HashSigns = advertised_hash_signs(Version),
Authorities = certificate_authorities(CertDbHandle, CertDbRef),
#certificate_request{
@@ -383,13 +383,13 @@ verify_signature(_Version, Hash, {HashAlgo, ecdsa}, Signature,
%%--------------------------------------------------------------------
-spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit,
- verify_peer | verify_none, {fun(), term},
+ verify_peer | verify_none, {fun(), term}, fun(),
client | server) -> {der_cert(), public_key_info()} | #alert{}.
%%
%% Description: Handles a certificate handshake message
%%--------------------------------------------------------------------
certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef,
- MaxPathLen, _Verify, VerifyFunAndState, Role) ->
+ MaxPathLen, _Verify, VerifyFunAndState, PartialChain, Role) ->
[PeerCert | _] = ASN1Certs,
ValidationFunAndState =
@@ -421,7 +421,7 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef,
try
{TrustedErlCert, CertPath} =
- ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef),
+ ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef, PartialChain),
case public_key:pkix_path_validation(TrustedErlCert,
CertPath,
[{max_path_length,
@@ -1098,19 +1098,31 @@ supported_ecc(_) ->
%%-------------certificate handling --------------------------------
-certificate_types({KeyExchange, _, _, _})
- when KeyExchange == rsa;
- KeyExchange == dhe_dss;
- KeyExchange == dhe_rsa;
- KeyExchange == ecdhe_rsa ->
- <<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>;
+certificate_types(_, {N, M}) when N >= 3 andalso M >= 3 ->
+ case proplists:get_bool(ecdsa,
+ proplists:get_value(public_keys, crypto:supports())) of
+ true ->
+ <<?BYTE(?ECDSA_SIGN), ?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>;
+ false ->
+ <<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>
+ end;
+
+certificate_types({KeyExchange, _, _, _}, _) when KeyExchange == rsa;
+ KeyExchange == dhe_rsa;
+ KeyExchange == ecdhe_rsa ->
+ <<?BYTE(?RSA_SIGN)>>;
-certificate_types({KeyExchange, _, _, _})
- when KeyExchange == dh_ecdsa;
- KeyExchange == dhe_ecdsa ->
+certificate_types({KeyExchange, _, _, _}, _) when KeyExchange == dhe_dss;
+ KeyExchange == srp_dss ->
+ <<?BYTE(?DSS_SIGN)>>;
+
+certificate_types({KeyExchange, _, _, _}, _) when KeyExchange == dh_ecdsa;
+ KeyExchange == dhe_ecdsa;
+ KeyExchange == ecdh_ecdsa;
+ KeyExchange == ecdhe_ecdsa ->
<<?BYTE(?ECDSA_SIGN)>>;
-certificate_types(_) ->
+certificate_types(_, _) ->
<<?BYTE(?RSA_SIGN)>>.
certificate_authorities(CertDbHandle, CertDbRef) ->
@@ -1719,6 +1731,14 @@ 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), Rest/binary>>, Acc) when Len == 0 ->
+ dec_hello_extensions(Rest, Acc#hello_extensions{sni = ""}); %% Server may send an empy SNI
+
+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 +1751,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_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index fd0d87bd5f..bb4e732517 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. 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
@@ -24,6 +24,8 @@
-include_lib("public_key/include/public_key.hrl").
+-define(SECRET_PRINTOUT, "***").
+
-type reason() :: term().
-type reply() :: term().
-type msg() :: term().
@@ -36,6 +38,7 @@
-type issuer() :: tuple().
-type serialnumber() :: integer().
-type cert_key() :: {reference(), integer(), issuer()}.
+-type secret_printout() :: list().
%% basic binary constructors
-define(BOOLEAN(X), X:8/unsigned-big-integer).
@@ -74,22 +77,23 @@
versions :: [ssl_record:ssl_version()], %% ssl_record:atom_version() in API
verify :: verify_none | verify_peer,
verify_fun, %%:: fun(CertVerifyErrors::term()) -> boolean(),
+ partial_chain :: fun(),
fail_if_no_peer_cert :: boolean(),
verify_client_once :: boolean(),
%% fun(Extensions, State, Verify, AccError) -> {Extensions, State, AccError}
validate_extensions_fun,
depth :: integer(),
certfile :: binary(),
- cert :: public_key:der_encoded(),
+ cert :: public_key:der_encoded() | secret_printout(),
keyfile :: binary(),
- key :: {'RSAPrivateKey' | 'DSAPrivateKey' | 'ECPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()},
- password :: string(),
- cacerts :: [public_key:der_encoded()],
+ key :: {'RSAPrivateKey' | 'DSAPrivateKey' | 'ECPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()} | secret_printout(),
+ password :: string() | secret_printout(),
+ cacerts :: [public_key:der_encoded()] | secret_printout(),
cacertfile :: binary(),
- dh :: public_key:der_encoded(),
- dhfile :: binary(),
+ dh :: public_key:der_encoded() | secret_printout(),
+ dhfile :: binary() | secret_printout(),
user_lookup_fun, % server option, fun to lookup the user
- psk_identity :: binary(),
+ psk_identity :: binary() | secret_printout() ,
srp_identity, % client option {User, Password}
ciphers, %
%% Local policy for the server if it want's to reuse the session
@@ -113,7 +117,8 @@
server_name_indication = undefined,
%% Should the server prefer its own cipher order over the one provided by
%% the client?
- honor_cipher_order = false
+ honor_cipher_order = false,
+ padding_check = true
}).
-record(socket_options,
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index fbc73e0e42..c4f1f7f193 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,10 +30,10 @@
lookup_trusted_cert/4,
new_session_id/1, clean_cert_db/2,
register_session/2, register_session/3, invalidate_session/2,
- invalidate_session/3, clear_pem_cache/0, manager_name/1]).
+ invalidate_session/3, invalidate_pem/1, clear_pem_cache/0, manager_name/1]).
% Spawn export
--export([init_session_validator/1]).
+-export([init_session_validator/1, init_pem_cache_validator/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -49,11 +49,13 @@
session_lifetime,
certificate_db,
session_validation_timer,
- last_delay_timer = {undefined, undefined}%% Keep for testing purposes
+ last_delay_timer = {undefined, undefined},%% Keep for testing purposes
+ last_pem_check,
+ clear_pem_cache
}).
--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).
@@ -117,14 +119,13 @@ connection_init(Trustedcerts, Role) ->
%% Description: Cache a pem file and return its content.
%%--------------------------------------------------------------------
cache_pem_file(File, DbHandle) ->
- MD5 = crypto:hash(md5, File),
- case ssl_pkix_db:lookup_cached_pem(DbHandle, MD5) of
+ case ssl_pkix_db:lookup_cached_pem(DbHandle, File) of
[{Content,_}] ->
{ok, Content};
[Content] ->
{ok, Content};
undefined ->
- call({cache_pem, {MD5, File}})
+ call({cache_pem, File})
end.
%%--------------------------------------------------------------------
@@ -191,6 +192,11 @@ invalidate_session(Host, Port, Session) ->
invalidate_session(Port, Session) ->
cast({invalidate_session, Port, Session}).
+
+-spec invalidate_pem(File::binary()) -> ok.
+invalidate_pem(File) ->
+ cast({invalidate_pem, File}).
+
%%====================================================================
%% gen_server callbacks
%%====================================================================
@@ -212,12 +218,16 @@ init([Name, Opts]) ->
SessionCache = CacheCb:init(proplists:get_value(session_cb_init_args, Opts, [])),
Timer = erlang:send_after(SessionLifeTime * 1000 + 5000,
self(), validate_sessions),
- erlang:send_after(?CLEAR_PEM_CACHE, self(), clear_pem_cache),
+ Interval = pem_check_interval(),
+ erlang:send_after(Interval, self(), clear_pem_cache),
{ok, #state{certificate_db = CertDb,
session_cache = SessionCache,
session_cache_cb = CacheCb,
session_lifetime = SessionLifeTime,
- session_validation_timer = Timer}}.
+ session_validation_timer = Timer,
+ last_pem_check = os:timestamp(),
+ clear_pem_cache = Interval
+ }}.
%%--------------------------------------------------------------------
-spec handle_call(msg(), from(), #state{}) -> {reply, reply(), #state{}}.
@@ -256,7 +266,7 @@ handle_call({{new_session_id,Port}, _},
{reply, Id, State};
-handle_call({{cache_pem, File}, _Pid}, _,
+handle_call({{cache_pem,File}, _Pid}, _,
#state{certificate_db = Db} = State) ->
try ssl_pkix_db:cache_pem_file(File, Db) of
Result ->
@@ -303,7 +313,12 @@ handle_cast({invalidate_session, Host, Port,
handle_cast({invalidate_session, Port, #session{session_id = ID} = Session},
#state{session_cache = Cache,
session_cache_cb = CacheCb} = State) ->
- invalidate_session(Cache, CacheCb, {Port, ID}, Session, State).
+ invalidate_session(Cache, CacheCb, {Port, ID}, Session, State);
+
+handle_cast({invalidate_pem, File},
+ #state{certificate_db = [_, _, PemCache]} = State) ->
+ ssl_pkix_db:remove(File, PemCache),
+ {noreply, State}.
%%--------------------------------------------------------------------
-spec handle_info(msg(), #state{}) -> {noreply, #state{}}.
@@ -328,15 +343,13 @@ handle_info({delayed_clean_session, Key}, #state{session_cache = Cache,
CacheCb:delete(Cache, Key),
{noreply, State};
-handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace]} = State) ->
- case ssl_pkix_db:db_size(PemChace) of
- N when N < ?NOT_TO_BIG ->
- ok;
- _ ->
- ssl_pkix_db:clear(PemChace)
- end,
- erlang:send_after(?CLEAR_PEM_CACHE, self(), clear_pem_cache),
- {noreply, State};
+handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace],
+ clear_pem_cache = Interval,
+ last_pem_check = CheckPoint} = State) ->
+ NewCheckPoint = os:timestamp(),
+ start_pem_cache_validator(PemChace, CheckPoint),
+ erlang:send_after(Interval, self(), clear_pem_cache),
+ {noreply, State#state{last_pem_check = NewCheckPoint}};
handle_info({clean_cert_db, Ref, File},
@@ -482,10 +495,9 @@ new_id(Port, Tries, Cache, CacheCb) ->
clean_cert_db(Ref, CertDb, RefDb, PemCache, File) ->
case ssl_pkix_db:ref_count(Ref, RefDb, 0) of
0 ->
- MD5 = crypto:hash(md5, File),
- case ssl_pkix_db:lookup_cached_pem(PemCache, MD5) of
+ case ssl_pkix_db:lookup_cached_pem(PemCache, File) of
[{Content, Ref}] ->
- ssl_pkix_db:insert(MD5, Content, PemCache);
+ ssl_pkix_db:insert(File, Content, PemCache);
_ ->
ok
end,
@@ -494,3 +506,39 @@ clean_cert_db(Ref, CertDb, RefDb, PemCache, File) ->
_ ->
ok
end.
+
+start_pem_cache_validator(PemCache, CheckPoint) ->
+ spawn_link(?MODULE, init_pem_cache_validator,
+ [[get(ssl_manager), PemCache, CheckPoint]]).
+
+init_pem_cache_validator([SslManagerName, PemCache, CheckPoint]) ->
+ put(ssl_manager, SslManagerName),
+ ssl_pkix_db:foldl(fun pem_cache_validate/2,
+ CheckPoint, PemCache).
+
+pem_cache_validate({File, _}, CheckPoint) ->
+ case file:read_file_info(File, []) of
+ {ok, #file_info{mtime = Time}} ->
+ case is_before_checkpoint(Time, CheckPoint) of
+ true ->
+ ok;
+ false ->
+ invalidate_pem(File)
+ end;
+ _ ->
+ invalidate_pem(File)
+ end,
+ CheckPoint.
+
+pem_check_interval() ->
+ case application:get_env(ssl, ssl_pem_cache_clean) of
+ {ok, Interval} when is_integer(Interval) ->
+ Interval;
+ _ ->
+ ?CLEAR_PEM_CACHE
+ end.
+
+is_before_checkpoint(Time, CheckPoint) ->
+ calendar:datetime_to_gregorian_seconds(calendar:now_to_datetime(CheckPoint)) -
+ calendar:datetime_to_gregorian_seconds(Time) > 0.
+
diff --git a/lib/ssl/src/ssl_pkix_db.erl b/lib/ssl/src/ssl_pkix_db.erl
index e59aba0618..8531445ba4 100644
--- a/lib/ssl/src/ssl_pkix_db.erl
+++ b/lib/ssl/src/ssl_pkix_db.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. 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
@@ -81,10 +81,10 @@ lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) ->
{ok, Certs}
end.
-lookup_cached_pem([_, _, PemChache], MD5) ->
- lookup_cached_pem(PemChache, MD5);
-lookup_cached_pem(PemChache, MD5) ->
- lookup(MD5, PemChache).
+lookup_cached_pem([_, _, PemChache], File) ->
+ lookup_cached_pem(PemChache, File);
+lookup_cached_pem(PemChache, File) ->
+ lookup(File, PemChache).
%%--------------------------------------------------------------------
-spec add_trusted_certs(pid(), {erlang:timestamp(), string()} |
@@ -100,36 +100,35 @@ add_trusted_certs(_Pid, {der, DerList}, [CerDb, _,_]) ->
{ok, NewRef};
add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache] = Db) ->
- MD5 = crypto:hash(md5, File),
- case lookup_cached_pem(Db, MD5) of
+ case lookup_cached_pem(Db, File) of
[{_Content, Ref}] ->
ref_count(Ref, RefDb, 1),
{ok, Ref};
[Content] ->
Ref = make_ref(),
update_counter(Ref, 1, RefDb),
- insert(MD5, {Content, Ref}, PemChache),
+ insert(File, {Content, Ref}, PemChache),
add_certs_from_pem(Content, Ref, CertsDb),
{ok, Ref};
undefined ->
- new_trusted_cert_entry({MD5, File}, Db)
+ new_trusted_cert_entry(File, Db)
end.
%%--------------------------------------------------------------------
%%
%% Description: Cache file as binary in DB
%%--------------------------------------------------------------------
--spec cache_pem_file({binary(), binary()}, [db_handle()]) -> {ok, term()}.
-cache_pem_file({MD5, File}, [_CertsDb, _RefDb, PemChache]) ->
+-spec cache_pem_file(binary(), [db_handle()]) -> {ok, term()}.
+cache_pem_file(File, [_CertsDb, _RefDb, PemChache]) ->
{ok, PemBin} = file:read_file(File),
Content = public_key:pem_decode(PemBin),
- insert(MD5, Content, PemChache),
+ insert(File, Content, PemChache),
{ok, Content}.
--spec cache_pem_file(reference(), {binary(), binary()}, [db_handle()]) -> {ok, term()}.
-cache_pem_file(Ref, {MD5, File}, [_CertsDb, _RefDb, PemChache]) ->
+-spec cache_pem_file(reference(), binary(), [db_handle()]) -> {ok, term()}.
+cache_pem_file(Ref, File, [_CertsDb, _RefDb, PemChache]) ->
{ok, PemBin} = file:read_file(File),
Content = public_key:pem_decode(PemBin),
- insert(MD5, {Content, Ref}, PemChache),
+ insert(File, {Content, Ref}, PemChache),
{ok, Content}.
%%--------------------------------------------------------------------
@@ -245,9 +244,9 @@ add_certs(Cert, Ref, CertsDb) ->
error_logger:info_report(Report)
end.
-new_trusted_cert_entry(FileRef, [CertsDb, RefDb, _] = Db) ->
+new_trusted_cert_entry(File, [CertsDb, RefDb, _] = Db) ->
Ref = make_ref(),
update_counter(Ref, 1, RefDb),
- {ok, Content} = cache_pem_file(Ref, FileRef, Db),
+ {ok, Content} = cache_pem_file(Ref, File, Db),
add_certs_from_pem(Content, Ref, CertsDb),
{ok, Ref}.
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 7337225bc4..025a46bf65 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2015. 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
@@ -48,7 +48,7 @@
-export([compress/3, uncompress/3, compressions/0]).
%% Payload encryption/decryption
--export([cipher/4, decipher/3, is_correct_mac/2]).
+-export([cipher/4, decipher/4, is_correct_mac/2]).
-export_type([ssl_version/0, ssl_atom_version/0]).
@@ -376,8 +376,9 @@ cipher(Version, Fragment,
{CipherFragment, CipherS1} =
ssl_cipher:cipher(BulkCipherAlgo, CipherS0, MacHash, Fragment, Version),
{CipherFragment, WriteState0#connection_state{cipher_state = CipherS1}}.
+
%%--------------------------------------------------------------------
--spec decipher(ssl_version(), binary(), #connection_state{}) -> {binary(), binary(), #connection_state{}} | #alert{}.
+-spec decipher(ssl_version(), binary(), #connection_state{}, boolean()) -> {binary(), binary(), #connection_state{}} | #alert{}.
%%
%% Description: Payload decryption
%%--------------------------------------------------------------------
@@ -387,8 +388,8 @@ decipher(Version, CipherFragment,
BulkCipherAlgo,
hash_size = HashSz},
cipher_state = CipherS0
- } = ReadState) ->
- case ssl_cipher:decipher(BulkCipherAlgo, HashSz, CipherS0, CipherFragment, Version) of
+ } = ReadState, PaddingCheck) ->
+ case ssl_cipher:decipher(BulkCipherAlgo, HashSz, CipherS0, CipherFragment, Version, PaddingCheck) of
{PlainFragment, Mac, CipherS1} ->
CS1 = ReadState#connection_state{cipher_state = CipherS1},
{PlainFragment, Mac, CS1};
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 2ab085321a..77d3aa7889 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. 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
@@ -329,7 +329,10 @@ terminate(Reason, StateName, State) ->
%% code_change(OldVsn, StateName, State, Extra) -> {ok, StateName, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
-code_change(_OldVsn, StateName, State, _Extra) ->
+code_change(_OldVsn, StateName, State0, {Direction, From, To}) ->
+ State = convert_state(State0, Direction, From, To),
+ {ok, StateName, State};
+code_change(_OldVsn, StateName, State, _) ->
{ok, StateName, State}.
format_status(Type, Data) ->
@@ -444,12 +447,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),
@@ -475,8 +482,9 @@ next_record(#state{protocol_buffers = #protocol_buffers{tls_packets = [], tls_ci
next_record(#state{protocol_buffers =
#protocol_buffers{tls_packets = [], tls_cipher_texts = [CT | Rest]}
= Buffers,
- connection_states = ConnStates0} = State) ->
- case tls_record:decode_cipher_text(CT, ConnStates0) of
+ connection_states = ConnStates0,
+ ssl_options = #ssl_options{padding_check = Check}} = State) ->
+ case tls_record:decode_cipher_text(CT, ConnStates0, Check) of
{Plain, ConnStates} ->
{Plain, State#state{protocol_buffers =
Buffers#protocol_buffers{tls_cipher_texts = Rest},
@@ -954,3 +962,14 @@ workaround_transport_delivery_problems(Socket, gen_tcp = Transport) ->
Transport:recv(Socket, 0, 30000);
workaround_transport_delivery_problems(Socket, Transport) ->
Transport:close(Socket).
+
+convert_state(#state{ssl_options = Options} = State, up, "5.3.5", "5.3.6") ->
+ State#state{ssl_options = convert_options_partial_chain(Options, up)};
+convert_state(#state{ssl_options = Options} = State, down, "5.3.6", "5.3.5") ->
+ State#state{ssl_options = convert_options_partial_chain(Options, down)}.
+
+convert_options_partial_chain(Options, up) ->
+ {Head, Tail} = lists:split(5, tuple_to_list(Options)),
+ list_to_tuple(Head ++ [{partial_chain, fun(_) -> unknown_ca end}] ++ Tail);
+convert_options_partial_chain(Options, down) ->
+ list_to_tuple(proplists:delete(partial_chain, tuple_to_list(Options))).
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index f50ea22f39..ed61da2d62 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -34,7 +34,7 @@
-export([get_tls_records/2]).
%% Decoding
--export([decode_cipher_text/2]).
+-export([decode_cipher_text/3]).
%% Encoding
-export([encode_plain_text/4]).
@@ -142,19 +142,21 @@ encode_plain_text(Type, Version, Data,
{CipherText, ConnectionStates#connection_states{current_write = WriteState#connection_state{sequence_number = Seq +1}}}.
%%--------------------------------------------------------------------
--spec decode_cipher_text(#ssl_tls{}, #connection_states{}) ->
+-spec decode_cipher_text(#ssl_tls{}, #connection_states{}, boolean()) ->
{#ssl_tls{}, #connection_states{}}| #alert{}.
%%
%% Description: Decode cipher text
%%--------------------------------------------------------------------
decode_cipher_text(#ssl_tls{type = Type, version = Version,
- fragment = CipherFragment} = CipherText, ConnnectionStates0) ->
- ReadState0 = ConnnectionStates0#connection_states.current_read,
- #connection_state{compression_state = CompressionS0,
- sequence_number = Seq,
- security_parameters = SecParams} = ReadState0,
- CompressAlg = SecParams#security_parameters.compression_algorithm,
- case ssl_record:decipher(Version, CipherFragment, ReadState0) of
+ fragment = CipherFragment} = CipherText,
+ #connection_states{current_read =
+ #connection_state{
+ compression_state = CompressionS0,
+ sequence_number = Seq,
+ security_parameters=
+ #security_parameters{compression_algorithm = CompressAlg}
+ } = ReadState0} = ConnnectionStates0, PaddingCheck) ->
+ case ssl_record:decipher(Version, CipherFragment, ReadState0, PaddingCheck) of
{PlainFragment, Mac, ReadState1} ->
MacHash = calc_mac_hash(Type, Version, PlainFragment, ReadState1),
case ssl_record:is_correct_mac(Mac, MacHash) of
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 2f8ff6f04e..0d241707d9 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2013. All Rights Reserved.
+# Copyright Ericsson AB 1999-2015. 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,6 +46,7 @@ MODULES = \
ssl_npn_handshake_SUITE \
ssl_packet_SUITE \
ssl_payload_SUITE \
+ ssl_pem_cache_SUITE \
ssl_session_cache_SUITE \
ssl_to_openssl_SUITE \
ssl_ECC_SUITE \
diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl
index 22dc951ac1..daf4466f11 100644
--- a/lib/ssl/test/erl_make_certs.erl
+++ b/lib/ssl/test/erl_make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2011-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
@@ -325,14 +325,14 @@ sign_algorithm(#'RSAPrivateKey'{}, Opts) ->
{Type, 'NULL'};
sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) ->
{?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}};
-sign_algorithm(#'ECPrivateKey'{}, Opts) ->
+sign_algorithm(#'ECPrivateKey'{parameters = Parms}, Opts) ->
Type = case proplists:get_value(digest, Opts, sha1) of
sha1 -> ?'ecdsa-with-SHA1';
sha512 -> ?'ecdsa-with-SHA512';
sha384 -> ?'ecdsa-with-SHA384';
sha256 -> ?'ecdsa-with-SHA256'
end,
- {Type, 'NULL'}.
+ {Type, Parms}.
make_key(rsa, _Opts) ->
%% (OBS: for testing only)
diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl
index 608f2f11c3..3566a8a0a5 100644
--- a/lib/ssl/test/ssl_ECC_SUITE.erl
+++ b/lib/ssl/test/ssl_ECC_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. 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
@@ -57,41 +57,51 @@ all_versions_groups ()->
].
key_cert_combinations() ->
- [client_ec_server_ec,
- client_rsa_server_ec,
- client_ec_server_rsa,
- client_rsa_server_rsa].
+ [client_ecdh_server_ecdh,
+ client_rsa_server_ecdh,
+ client_ecdh_server_rsa,
+ client_rsa_server_rsa,
+ client_ecdsa_server_ecdsa,
+ client_ecdsa_server_rsa,
+ client_rsa_server_ecdsa
+ ].
%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- catch crypto:stop(),
+init_per_suite(Config0) ->
+ end_per_suite(Config0),
try crypto:start() of
ok ->
- ssl:start(),
- Config
+ %% make rsa certs using oppenssl
+ Result =
+ (catch make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0))),
+ ct:log("Make certs ~p~n", [Result]),
+ Config1 = ssl_test_lib:make_ecdsa_cert(Config0),
+ Config2 = ssl_test_lib:make_ecdh_rsa_cert(Config1),
+ ssl_test_lib:cert_options(Config2)
catch _:_ ->
{skip, "Crypto did not start"}
end.
end_per_suite(_Config) ->
- ssl:stop(),
+ application:stop(ssl),
application:stop(crypto).
%%--------------------------------------------------------------------
-init_per_group(erlang_client, Config) ->
+init_per_group(erlang_client = Group, Config) ->
case ssl_test_lib:is_sane_ecc(openssl) of
true ->
- common_init_per_group(erlang_client, [{server_type, openssl},
- {client_type, erlang} | Config]);
+ common_init_per_group(Group, [{server_type, openssl},
+ {client_type, erlang} | Config]);
false ->
{skip, "Known ECC bug in openssl"}
end;
-init_per_group(erlang_server, Config) ->
+init_per_group(erlang_server = Group, Config) ->
case ssl_test_lib:is_sane_ecc(openssl) of
true ->
- common_init_per_group(erlang_client, [{server_type, erlang},
- {client_type, openssl} | Config]);
+ common_init_per_group(Group, [{server_type, erlang},
+ {client_type, openssl} | Config]);
false ->
{skip, "Known ECC bug in openssl"}
end;
@@ -99,11 +109,21 @@ init_per_group(erlang_server, Config) ->
init_per_group(erlang = Group, Config) ->
case ssl_test_lib:sufficient_crypto_support(Group) of
true ->
- common_init_per_group(erlang, [{server_type, erlang},
- {client_type, erlang} | Config]);
+ common_init_per_group(Group, [{server_type, erlang},
+ {client_type, erlang} | Config]);
+ false ->
+ {skip, "Crypto does not support ECC"}
+ end;
+
+init_per_group(openssl = Group, Config) ->
+ case ssl_test_lib:sufficient_crypto_support(Group) of
+ true ->
+ common_init_per_group(Group, [{server_type, openssl},
+ {client_type, openssl} | Config]);
false ->
{skip, "Crypto does not support ECC"}
- end;
+ end;
+
init_per_group(Group, Config) ->
common_init_per_group(Group, Config).
@@ -121,76 +141,118 @@ end_per_group(_GroupName, Config) ->
%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config) ->
+init_per_testcase(TestCase, Config) ->
ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]),
ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]),
+ end_per_testcase(TestCase, Config),
+ ssl:start(),
Config.
-end_per_testcase(_TestCase, Config) ->
+end_per_testcase(_TestCase, Config) ->
+ application:stop(ssl),
Config.
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-client_ec_server_ec(Config) when is_list(Config) ->
- basic_test("ec1.crt", "ec1.key", "ec2.crt", "ec2.key", Config).
-
-client_ec_server_rsa(Config) when is_list(Config) ->
- basic_test("ec1.crt", "ec1.key", "rsa1.crt", "rsa1.key", Config).
+client_ecdh_server_ecdh(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdh_rsa_opts, Config),
+ SOpts = ?config(server_ecdh_rsa_verify_opts, Config),
+ basic_test(COpts, SOpts, Config).
+
+client_ecdh_server_rsa(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdh_rsa_opts, Config),
+ SOpts = ?config(server_ecdh_rsa_verify_opts, Config),
+ basic_test(COpts, SOpts, Config).
+
+client_rsa_server_ecdh(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdh_rsa_opts, Config),
+ SOpts = ?config(server_ecdh_rsa_verify_opts, Config),
+ basic_test(COpts, SOpts, Config).
+
+client_rsa_server_rsa(Config) when is_list(Config) ->
+ COpts = ?config(client_verification_opts, Config),
+ SOpts = ?config(server_verification_opts, Config),
+ basic_test(COpts, SOpts, Config).
+
+client_ecdsa_server_ecdsa(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdsa_opts, Config),
+ SOpts = ?config(server_ecdsa_verify_opts, Config),
+ basic_test(COpts, SOpts, Config).
-client_rsa_server_ec(Config) when is_list(Config) ->
- basic_test("rsa1.crt", "rsa1.key", "ec2.crt", "ec2.key", Config).
+client_ecdsa_server_rsa(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdsa_opts, Config),
+ SOpts = ?config(server_ecdsa_verify_opts, Config),
+ basic_test(COpts, SOpts, Config).
-client_rsa_server_rsa(Config) when is_list(Config) ->
- basic_test("rsa1.crt", "rsa1.key", "rsa2.crt", "rsa2.key", Config).
+client_rsa_server_ecdsa(Config) when is_list(Config) ->
+ COpts = ?config(client_ecdsa_opts, Config),
+ SOpts = ?config(server_ecdsa_verify_opts, Config),
+ basic_test(COpts, SOpts, Config).
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
-basic_test(ClientCert, ClientKey, ServerCert, ServerKey, Config) ->
- DataDir = ?config(data_dir, Config),
+basic_test(COpts, SOpts, Config) ->
+ basic_test(proplists:get_value(certfile, COpts),
+ proplists:get_value(keyfile, COpts),
+ proplists:get_value(cacertfile, COpts),
+ proplists:get_value(certfile, SOpts),
+ proplists:get_value(keyfile, SOpts),
+ proplists:get_value(cacertfile, SOpts),
+ Config).
+
+basic_test(ClientCert, ClientKey, ClientCA, ServerCert, ServerKey, ServerCA, Config) ->
SType = ?config(server_type, Config),
CType = ?config(client_type, Config),
{Server, Port} = start_server(SType,
- filename:join(DataDir, "CA.pem"),
- filename:join(DataDir, ServerCert),
- filename:join(DataDir, ServerKey),
+ ClientCA, ServerCA,
+ ServerCert,
+ ServerKey,
Config),
- Client = start_client(CType, Port, filename:join(DataDir, "CA.pem"),
- filename:join(DataDir, ClientCert),
- filename:join(DataDir, ClientKey), Config),
- check_result(Server, SType, Client, CType).
+ Client = start_client(CType, Port, ServerCA, ClientCA,
+ ClientCert,
+ ClientKey, Config),
+ check_result(Server, SType, Client, CType),
+ close(Server, Client).
-start_client(openssl, Port, CA, Cert, Key, _) ->
+start_client(openssl, Port, CA, OwnCa, Cert, Key, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ NewCA = new_ca(filename:join(PrivDir, "new_ca.pem"), CA, OwnCa),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
- Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ Cert ++ " -CAfile " ++ CA
- ++ " -key " ++ Key ++ " -host localhost -msg",
+ Cmd = "openssl s_client -verify 2 -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
+ " -cert " ++ Cert ++ " -CAfile " ++ NewCA
+ ++ " -key " ++ Key ++ " -host localhost -msg -debug",
OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
true = port_command(OpenSslPort, "Hello world"),
OpenSslPort;
-start_client(erlang, Port, CA, Cert, Key, Config) ->
+start_client(erlang, Port, CA, _, Cert, Key, Config) ->
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{verify, verify_peer}, {cacertfile, CA},
+ {options, [{verify, verify_peer},
+ {cacertfile, CA},
{certfile, Cert}, {keyfile, Key}]}]).
-start_server(openssl, CA, Cert, Key, _) ->
+start_server(openssl, CA, OwnCa, Cert, Key, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ NewCA = new_ca(filename:join(PrivDir, "new_ca.pem"), CA, OwnCa),
+
Port = ssl_test_lib:inet_port(node()),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++
- " -cert " ++ Cert ++ " -CAfile " ++ CA
- ++ " -key " ++ Key ++ " -Verify 2 -msg",
+ " -verify 2 -cert " ++ Cert ++ " -CAfile " ++ NewCA
+ ++ " -key " ++ Key ++ " -msg -debug",
OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
ssl_test_lib:wait_for_openssl_server(),
true = port_command(OpenSslPort, "Hello world"),
{OpenSslPort, Port};
-start_server(erlang, CA, Cert, Key, Config) ->
+start_server(erlang, CA, _, Cert, Key, Config) ->
+
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -217,9 +279,31 @@ openssl_check(_, Config) ->
TLSVersion = ?config(tls_version, Config),
case ssl_test_lib:check_sane_openssl_version(TLSVersion) of
true ->
- ssl:start(),
Config;
false ->
{skip, "TLS version not supported by openssl"}
end.
+close(Port1, Port2) when is_port(Port1), is_port(Port2) ->
+ ssl_test_lib:close_port(Port1),
+ ssl_test_lib:close_port(Port2);
+close(Port, Pid) when is_port(Port) ->
+ ssl_test_lib:close_port(Port),
+ ssl_test_lib:close(Pid);
+close(Pid, Port) when is_port(Port) ->
+ ssl_test_lib:close_port(Port),
+ ssl_test_lib:close(Pid);
+close(Client, Server) ->
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%% Work around OpenSSL bug, apparently the same bug as we had fixed in
+%% 11629690ba61f8e0c93ef9b2b6102fd279825977
+new_ca(FileName, CA, OwnCa) ->
+ {ok, P1} = file:read_file(CA),
+ E1 = public_key:pem_decode(P1),
+ {ok, P2} = file:read_file(OwnCa),
+ E2 = public_key:pem_decode(P2),
+ Pem = public_key:pem_encode(E2 ++E1),
+ file:write_file(FileName, Pem),
+ FileName.
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/CA.pem b/lib/ssl/test/ssl_ECC_SUITE_data/CA.pem
deleted file mode 100644
index f82efdefc5..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/CA.pem
+++ /dev/null
@@ -1,14 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICGjCCAYegAwIBAgIQZIIqq4RXfpBKJXV69Jc4BjAJBgUrDgMCHQUAMB0xGzAZ
-BgNVBAMTEklTQSBUZXN0IEF1dGhvcml0eTAeFw0xMjAzMjAxNzEzMjFaFw0zOTEy
-MzEyMzU5NTlaMB0xGzAZBgNVBAMTEklTQSBUZXN0IEF1dGhvcml0eTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEAqnt6FSyFQVSDyP7mY63IhCzgysTxBEg1qDb8
-nBHj9REReZA5UQ5iyEOdTbdLyOaSk2rJyA2wdTjYkNnLzK49nZFlpf89r3/bakAM
-wZv69S3FJi9W2z9m4JPv/5+QCYnFNRSnnHw3maNElwoQyknx96I3W7EuVOvKtKhh
-4DaD0WsCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zBOBgNVHQEERzBFgBBCHwn2
-8AmbN+cvJl1iJ1bsoR8wHTEbMBkGA1UEAxMSSVNBIFRlc3QgQXV0aG9yaXR5ghBk
-giqrhFd+kEoldXr0lzgGMAkGBSsOAwIdBQADgYEAIlVecua5Cr1z/cdwQ8znlgOU
-U+y/uzg0nupKkopzVnRYhwV4hxZt3izAz4C/SJZB7eL0bUKlg1ceGjbQsGEm0fzF
-LEV3vym4G51bxv03Iecwo96G4NgjJ7+9/7ciBVzfxZyfuCpYG1M2LyrbOyuevtTy
-2+vIueT0lv6UftgBfIE=
------END CERTIFICATE-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt b/lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt
deleted file mode 100644
index 7d2b9cde9d..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBhjCB8AIBBjANBgkqhkiG9w0BAQUFADAdMRswGQYDVQQDExJJU0EgVGVzdCBB
-dXRob3JpdHkwHhcNMTMwODA4MTAxNDI3WhcNMjMwODA2MTAxNDI3WjBFMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExFTATBgNVBAcTDEZvcnQgQmVsdm9p
-cjEMMAoGA1UEAxMDZWMxMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEpiRIxUCESROR
-P8IByg+vBv1fDdAg7yXfAh95GxFtvhBqZs6ATwaRKyLmZYgUm/4NUAyUeqmTBb7s
-2msKo5mnNzANBgkqhkiG9w0BAQUFAAOBgQAmwzoB1DVO69FQOUdBVnyups4t0c1c
-8h+1z/5P4EtPltk4o3mRn0AZogqdXCpNbuSGbSJh+dep5xW30VLxNHdc+tZSLK6j
-pT7A3hymMk8qbi13hxeH/VpEP25y1EjHowow9Wmb6ebtT/v7qFQ9AAHD9ONcIM4I
-FCC8vdFo7M5GgQ==
------END CERTIFICATE-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec1.key b/lib/ssl/test/ssl_ECC_SUITE_data/ec1.key
deleted file mode 100644
index 2dc9508b3c..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/ec1.key
+++ /dev/null
@@ -1,8 +0,0 @@
------BEGIN EC PARAMETERS-----
-BgUrgQQACg==
------END EC PARAMETERS-----
------BEGIN EC PRIVATE KEY-----
-MHQCAQEEIOO0WK8znNzLyZIoGRIlaKnCNr2Wy8uk9i+GGFIhDGNAoAcGBSuBBAAK
-oUQDQgAEpiRIxUCESRORP8IByg+vBv1fDdAg7yXfAh95GxFtvhBqZs6ATwaRKyLm
-ZYgUm/4NUAyUeqmTBb7s2msKo5mnNw==
------END EC PRIVATE KEY-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt b/lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt
deleted file mode 100644
index b0558a0ebc..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBhjCB8AIBBzANBgkqhkiG9w0BAQUFADAdMRswGQYDVQQDExJJU0EgVGVzdCBB
-dXRob3JpdHkwHhcNMTMwODA4MTAxNDM0WhcNMjMwODA2MTAxNDM0WjBFMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExFTATBgNVBAcTDEZvcnQgQmVsdm9p
-cjEMMAoGA1UEAxMDZWMyMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzXaYReUyvoYl
-FwGOe0MJEXWCUncMfr2xG4GMjGYlfZsvLGEokefsJIvW+I+9jgUT2UFjxFXYNAvm
-uD1A1iWVWjANBgkqhkiG9w0BAQUFAAOBgQBFa6iIlrT9DWptIdB8uSYvp7qwiHxN
-hiVH5YhGIHHqjGZqtRHrSxqNEYMXXrgH9Hxc6gDbk9PsHZyVVoh/HgVWddqW1inh
-tStZm420PAKCuH4T6Cfsk76GE2m7FRzJvw9TM1f2A5nIy9abyrpup8lZGcIL4Kmq
-1Fix1LRtrmLNTA==
------END CERTIFICATE-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec2.key b/lib/ssl/test/ssl_ECC_SUITE_data/ec2.key
deleted file mode 100644
index 366d13648b..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/ec2.key
+++ /dev/null
@@ -1,8 +0,0 @@
------BEGIN EC PARAMETERS-----
-BgUrgQQACg==
------END EC PARAMETERS-----
------BEGIN EC PRIVATE KEY-----
-MHQCAQEEIPR3ORUpAFMTQhUJ0jllN38LKWziG8yP2H54Y/9vh1PwoAcGBSuBBAAK
-oUQDQgAEzXaYReUyvoYlFwGOe0MJEXWCUncMfr2xG4GMjGYlfZsvLGEokefsJIvW
-+I+9jgUT2UFjxFXYNAvmuD1A1iWVWg==
------END EC PRIVATE KEY-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt b/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt
deleted file mode 100644
index ed9beacf68..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDVjCCAr8CAQkwDQYJKoZIhvcNAQEFBQAwHTEbMBkGA1UEAxMSSVNBIFRlc3Qg
-QXV0aG9yaXR5MB4XDTEzMDgwODEwMTUzNFoXDTQwMTIyNDEwMTUzNFowRjELMAkG
-A1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRUwEwYDVQQHEwxGb3J0IEJlbHZv
-aXIxDTALBgNVBAMTBHJzYTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQC62v40w1AjV3oJuyYC2Fw6XhTOi1il6xZFnB9J1WhCmuxAB/VMhBcNypx38mNk
-eQ7a/ERQ5ddhZey29DYeFYU8oqfDURgWx5USHufb90xBen9KPmX3VNuQ8ZFP2q8Q
-b01/oRHBJQRBuaCtFHzpGIVBjC6dD5yeQgJsYaF4u+PBbonsIGROXMybcvUzXmjU
-dwpy2NhjGQL5sWcOdIeRP43APSyRYvq4tuBUZk2XxWfBcvA8LpcoYPMlRTf6jGL1
-/fAAcCYJ9lh3h92w0NZ/7ZRa/ebTplxK6yqCftuSKui1KdL69m0WZqHl79AUSfs9
-lsOwx9lHkyYvJeMofyeDbZ+3OYLmVqEBG1fza2aV2XVh9zJ8fAwmXy/c2IDhw/oD
-HAe/rSg/Sgt03ydIKqtZHbl3v0EexQQRlJRULIzdtON02dJMUd4EFUgQ9OUtEmC2
-Psj9Jdu1g5cevU7Mymu8Ot+fjHiGTcBUsXNuXFCbON3Gw7cIDl4+iv+cpDHHVC9L
-HK3PMEq3vu3qOGXSz+LDOoqkfROcLG7BclBuN2zoVSsMHFkB4aJhwy7eHhGz0z2W
-c6LTVd+GAApdY80kmjOjT//QxHEsX/n1useHza3OszQqZiArr4ub4rtq+l1DxAS/
-DWrZ/JGsbKL8cjWso6qBF94xTi8WhjkKuUYhsm+qLAbNOQIDAQABMA0GCSqGSIb3
-DQEBBQUAA4GBAIcuzqRkfypV/9Z85ZQCCoejPm5Urhv7dfg1/B3QtazogPBZLgL5
-e60fG1uAw5GmqTViHLvW06z73oQvJrFkrCLVvadDNtrKYKXnXqdkgVyk36F/B737
-A43HGnMfSxCfRhIOuKZB9clP5PiNlhw36yi3DratqT6TUvI69hg8a7jA
------END CERTIFICATE-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key b/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key
deleted file mode 100644
index 6e0d913d79..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEAutr+NMNQI1d6CbsmAthcOl4UzotYpesWRZwfSdVoQprsQAf1
-TIQXDcqcd/JjZHkO2vxEUOXXYWXstvQ2HhWFPKKnw1EYFseVEh7n2/dMQXp/Sj5l
-91TbkPGRT9qvEG9Nf6ERwSUEQbmgrRR86RiFQYwunQ+cnkICbGGheLvjwW6J7CBk
-TlzMm3L1M15o1HcKctjYYxkC+bFnDnSHkT+NwD0skWL6uLbgVGZNl8VnwXLwPC6X
-KGDzJUU3+oxi9f3wAHAmCfZYd4fdsNDWf+2UWv3m06ZcSusqgn7bkirotSnS+vZt
-Fmah5e/QFEn7PZbDsMfZR5MmLyXjKH8ng22ftzmC5lahARtX82tmldl1YfcyfHwM
-Jl8v3NiA4cP6AxwHv60oP0oLdN8nSCqrWR25d79BHsUEEZSUVCyM3bTjdNnSTFHe
-BBVIEPTlLRJgtj7I/SXbtYOXHr1OzMprvDrfn4x4hk3AVLFzblxQmzjdxsO3CA5e
-Por/nKQxx1QvSxytzzBKt77t6jhl0s/iwzqKpH0TnCxuwXJQbjds6FUrDBxZAeGi
-YcMu3h4Rs9M9lnOi01XfhgAKXWPNJJozo0//0MRxLF/59brHh82tzrM0KmYgK6+L
-m+K7avpdQ8QEvw1q2fyRrGyi/HI1rKOqgRfeMU4vFoY5CrlGIbJvqiwGzTkCAwEA
-AQKCAgBkXyaWKSRvF5pSh9lPRfGk2MzMdkXUOofoNIkKHDy5KocljiDSTVIk8mVC
-eU2ytuSn9UKtQgmEJEAXtu8rEdxUSftcC7+o3OTSqw9ZNWoc8jRWKVaUmVyoa1rn
-Tk0jwuYaXOcwnTXAKHqK/qpqe+V45FhVvgEfcc3jcj5OoH8jdMFZubyn62ltRz83
-rMsa9icCskDqWpEil40IUshP2ZfHYBUEs+qCNpoiPCIKGNw3KgqqCUzhP9LcfmYn
-jCnMge/eDGAikdXLv4vyYvwWFATRK/pGTuLcy542IvbHeY0vY5wVezH2CoOFBGD9
-xQ/UcZwE5hVtQToNsYhoRIVxL/3Of0qDk1M6W2Plh2MAstyejIHE3ct0pPfW3rsu
-j/9Z/H0P9Q5ghSjarwOp2qGrrz6/4LVbbTDY8V1L928l4SqbUMtEQxcxTBN8YFoD
-mPV3Jc3zls9wiiEX53RcH8MK5tjrcRwWqurTZvi/pkLfXlGDgKGCOaa3HgWVQyU+
-L6jVZM+u1nwN+jNXQYGeLEro/6tvG8WQbRMHQoxLG+rm4V3/SwH0DcfrVFDTg+i6
-3wMU1GC/aQEdTFWXvHAkpwrf4M9QWvjtheiaSxtBUoAY6l+ixCVHKrIk6glKLEjx
-92HxmcJdopQScFETAyg8eVKV0kOGfVeFEpIqwq7hVedmTflpQQKCAQEA44h4dAta
-cYeBqBr8eljWcgs79gmgwBEQxQUnwE/zuzLKn5NxAW324Kh25V/n/MupUzBlLPWn
-91UHfw9PCXT8/HvgYQ4S5sXbKRbGmuPSsTmz4Rfe2ix6RggVNUOwORVNDyM7SQh7
-USdzZH5dMxKfF5L/b4Byx7eQZaoeKlfaXcqgikNZZ6pkhVCNxUKi9vvjS9r2wwCd
-xtgu5MfTpdEci0zH1+uuRisVRcEbcRX9umUTCiZrmEeddZXNiwTAS3FtX7qGzuq9
-LKIeETwcOZrWj0E48UvbSfK4Axn7sf5J0n7/Qo7I089S5QQEI6ZDP501i71dNFhn
-qfcY30c1k3TC7QKCAQEA0juuVHExKNLLNmQejNPfuHYoH0Uk2BH/8x96/Mkj6k6K
-SUCHDS3iWOljXGw8YtpS8v5mGBGgMhJ+s/vCRM6R9eXYTc8u2ktY/kjyW0PgW8/Z
-vb9VrQpn5svTNwj2Q8qYsTqXnQKO7YuL+hnQpQNAcID6FTeOASVLGObEf810qRfN
-4y3RqCWUnYXXTyXj+cJdbXTxfF7HVZPIAQKqE7J5Qo9ynYILY62oSmUGC6m8VKyE
-rrvDMK1IVi0X4w+Jx4HX0IC2+DBKxCaLWT69bE1IwjB06Q5zoTQPVi6c6qQp7K0H
-kqSyLJ/ctwcEubu0DPNmvMlgWtAbAsoESA5GbIit/QKCAQEAxRzp9OYNAUM6AK74
-QOmLRZsT4+6tUxa1p2jy6fiZlnfG731kra9c630mG0n9iJPK6aWIUO20CGGiL+HM
-P84YiIaseIgfucp4NV1kyrRJR31MptjuF6Xme5ru/IjaNmmMq2uDJZ7ybfi2T73k
-8aTVLDANl8P4K6qLrnc00MvxAcXTVFRKNLN5h8CkQNqcoUjPvVxA3+g9xxBrd4jh
-gsnoZ4kpq5WiEWmrcRV8t3gsqfh8CRQFrBOGhmIzgZapG/J0pTTLKqBTKEJ9t8KS
-VRkdfVcshGWJ4MMjxJQS5zz7KR8Z9cgKlOwLzRiwmU2k/owr4hY3k2xuyeClrHBd
-KpRBdQKCAQBvDk/dE55gbloi9WieBB6eluxC+IeqDHgkunCBsM9kKvEqGQg+kgqL
-5V4zqImNvr8q1fCgrk7tpI+CDHBnYKgCOdS15cheUIdGbMp6I7UVSws/DR/5NRIF
-/Y4p+HX/Abr/hHAq5PsTyS+8gn6RbNJRnBB/vMUrHcQ5902+JY6G9KgyZjXmmVOU
-kutWSDHR8jbgZ3JZvMeYEWUKA5pMpW8hFh35zoStt0K7afpzlsqCAFBm7ZEC2cbo
-nxGLRN4HojObVSNSoFAepi3eiyINYBYbXvWjV5sFgTbI0/7YhLgQ6qahdJcas6go
-l3CLnPhUDxAqkkZwMpbSNl1kowXYt6sRAoIBAAOWnXgf9Bdb9OWKGgt42gVfC4cz
-zj2JoLpbDTtbEdHNn8XQvPhGbpdtgnsuEMijIMy1UTlmv17jbFWdZTDeN31EUJrC
-smgKX0OlVFKD90AI0BiIREK0hJUBV0pV4JoUjwnQBHGvranD06/wAtHEqgqF1Ipp
-DCAKwxggM7qtB1R1vkrc/aLQej+mlwA8N6q92rnEsg+EnEbhtLDDZQcV/q5cSDCN
-MMcnM+QdyjKwEeCVXHaqNfeSqKg/Ab2eZbS9VxA+XZD73+eUY/JeJsg7LfZrRz0T
-ij5LCS7A+nVB5/B5tGkk4fcNhk2n356be6l46S98BEgtuwGLC9pqXf7zyp4=
------END RSA PRIVATE KEY-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt b/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt
deleted file mode 100644
index 06ca92dda3..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDVjCCAr8CAQowDQYJKoZIhvcNAQEFBQAwHTEbMBkGA1UEAxMSSVNBIFRlc3Qg
-QXV0aG9yaXR5MB4XDTEzMDgwODEwMTYwMloXDTQwMTIyNDEwMTYwMlowRjELMAkG
-A1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRUwEwYDVQQHEwxGb3J0IEJlbHZv
-aXIxDTALBgNVBAMTBHJzYTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQCjQUe0BGOpULjOAmLbXM4SSQzJvxJbCFi3tryyd+OARq6Fdp6/fslVhsr0PhWE
-X8yRbAugIjseTpLwz+1OC6LavOGV1ixzGTI/9HDXGKbf8qoCrSdh28sqQJnmqGT4
-UCKLn6Rqjg2iyBBcSK3LrtKEPI4C7NaSOZUtANkppvziEMwm+0r16sgHh2Xx6mxd
-22q01kq1lJqwEnIDPMSz3+ESUVQQ4T3ka7yFIhc9PYmILIXkZi0x7AiDeRkIILul
-GQrduTWSPGY3prXeDAbmQNazxrHp8fcR2AfFSI6HYxMALq9jWxc4xDIkss6BO2Et
-riJOIgXFpbyVsYCbkI1kXhEWFDt3uJBIcmtJKGzro4xv+XLG6BbUeTJgSHXMc7Cb
-fX87+CBIFR5a/aqkEKh/mcvsDdaV+kpNKdr7q4wAuIQb8g7IyXEDuAm1VZjQs9WC
-KFRGSq9sergEw9gna0iThRZjD+dzNzB17XmlAK4wa98a7MntwqpAt/GsCFOiPM8E
-c+8gpuo8WqC0kP8OpImyw9cQhlZ3dca1qkr2cyKyAOGxUxyA67FgiHSsxJJ2Xhse
-o49qeKTjMZd8zhSokM2TH6qEf7YfOePU51YRfAHUhzRmE31N/MExqDjFjklksEtM
-iHhbPo+cOoxV8x1u13umdUvtTaAUSBA/DpvzWdnORvnaqQIDAQABMA0GCSqGSIb3
-DQEBBQUAA4GBAFD+O7h+5R5S1rIN9eC+oEGpvRhMG4v4G3pJp+c7bbtO7ifFx1WP
-bta1b5YtiQYcKP0ORABm/3Kcvsb3VbaMH/zkxWEbASZsmIcBY3ml4f2kkn6WT2hD
-Wc6VMIAR3N6Mj1b30yI1qYVIid+zIouiykMB+zqllm+Uar0SPNjKxDU/
------END CERTIFICATE-----
diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key b/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key
deleted file mode 100644
index d415ef0391..0000000000
--- a/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJJwIBAAKCAgEAo0FHtARjqVC4zgJi21zOEkkMyb8SWwhYt7a8snfjgEauhXae
-v37JVYbK9D4VhF/MkWwLoCI7Hk6S8M/tTgui2rzhldYscxkyP/Rw1xim3/KqAq0n
-YdvLKkCZ5qhk+FAii5+kao4NosgQXEity67ShDyOAuzWkjmVLQDZKab84hDMJvtK
-9erIB4dl8epsXdtqtNZKtZSasBJyAzzEs9/hElFUEOE95Gu8hSIXPT2JiCyF5GYt
-MewIg3kZCCC7pRkK3bk1kjxmN6a13gwG5kDWs8ax6fH3EdgHxUiOh2MTAC6vY1sX
-OMQyJLLOgTthLa4iTiIFxaW8lbGAm5CNZF4RFhQ7d7iQSHJrSShs66OMb/lyxugW
-1HkyYEh1zHOwm31/O/ggSBUeWv2qpBCof5nL7A3WlfpKTSna+6uMALiEG/IOyMlx
-A7gJtVWY0LPVgihURkqvbHq4BMPYJ2tIk4UWYw/nczcwde15pQCuMGvfGuzJ7cKq
-QLfxrAhTojzPBHPvIKbqPFqgtJD/DqSJssPXEIZWd3XGtapK9nMisgDhsVMcgOux
-YIh0rMSSdl4bHqOPanik4zGXfM4UqJDNkx+qhH+2Hznj1OdWEXwB1Ic0ZhN9TfzB
-Mag4xY5JZLBLTIh4Wz6PnDqMVfMdbtd7pnVL7U2gFEgQPw6b81nZzkb52qkCAwEA
-AQKCAgBORLHXwHL3bdfsDIDQooG5ioQzBQQL2MiP63A0L/5GNZzeJ6ycKnDkLCeJ
-SWqPeE5fOemo8EBfm1QfV9BxpmqBbCTK7U+KLv5EYzDmLs9ydqjDd7h11iZlL2uZ
-hgpCckjdn7/3xfsLm9ccJ0wLZtlOxKlhBaMpn6nBVbLHoWOEDoGR/tBFbjZQRb2+
-aaFirhtOb56Jx6ER4QYAP1Ye1qrVWWBwZ0yBApXzThDOL36MZqwagFISqRK71YcG
-uoq78HGhM3ZXkdV/wNFYj3OPWG6W6h/KBVNqnqO7FbofdoRZhghYHgfYE1fm+ELA
-+nLwr5eK1gzmYTs0mVELRBZFlEOkCfYNOnuRgysFezEklS+ICp3HzIhYXza3kyTf
-B2ZBwZZVCv/94MKyibyANErmv1a5ugY5Hsn9/WKC8qTto+qLYoyFCvBjzj0PSaVX
-/3cty2DY0SK16K1Y4AOPtJMYTXYB3tVX8Akgjz1F6REBtZSOXrSQ3Vhy1ORl3Hzf
-WCBYDqL8K0hJiBVgkvneIyIjmFHsdM60Nr7EldBEnJ/UrPzsl2VuWFPZlnasfUaW
-x+vq1H4Dfz+bHt8coBRHDjKgUvwkfFeBQOBR5DG3vMrxguVRA1EYYMRR5C3yxk2m
-ARAtdh4VxUQDQjjrmr7Dl/y1rU34aInXIrrFWpuvIhl8Ht09sQKCAQEA1pXKK5f0
-HkKfM/qk5xzF+WdHClBrPXi0XwLN6UQ+WWMMNhkGZ+FMPXl/6IJDT91s6DA3tPhr
-OZF64n9ZFaGgHNBXNiB+Txjv5vZeSBMFt3hSonqt42aijx6gXfmLnkA+TYpa6Wex
-YCeEgdH8LocJa7Gj2vzrYliPYk3deh6SnZZ6N8bI+ciwK3ZGF/pkWaTX83dIFq3w
-YyZ+0dEpNGbA9812wNVourPg3OfqG3/CdnTfvY1M9KCC3JalpyzQL4Zm5soXF0wj
-36C2yTxA02AyFz3TvUIBrvsN6i0gmGfE79+UIp29JYrFRsIgBDt+ze2vQWUz2MX5
-GeX6/yCBgiTXtwKCAQEAwsNf6k2m5Cw+WtuLzzUfBBJCN+t1lrnYJ6lF0HubW6TZ
-vX1kBWyc+Rpo4ljr/+f4R9aC/gTEQOmV/hNVZy1RU2dAI8cH+r6JWG9lgif+8h//
-5R81txE7gnuK1Na7PmvnQPPN661zsQZ5e1ENPXS3TJmUW/M01JxAMqEQjvAPa/II
-H2KjL5NX28k9Hiw9rP6n+qXAfG/LEwXgoVCcehPwfANqQ1l95UgOdKDmjG94dipI
-h2DEK70ZbrsgQbT60Wd8I5h0yhiQsik2/bVkqLmcG4SSg0/5cf2vZMApgoH/adUz
-rJFdthm7iGPLhwS6fbhXew17Af96FvzfkifUV+cgnwKCAQBNUlYyFSQKz1jMgxFu
-kciokNVhWw75bIgaAEmwNz38OZuJ1sSfI+iz8hbr8hxNJ+15UP6RwD3q1YghG2A/
-Uij+mPgD8ftxhvvTDo10jR4vOTUVhP0phq8mwRNqKWRs1ptcl3Egz5NzoWm22bJ0
-FYaIfs8bNq2el2i7NHGM8n1EOZe6h2+dyfno/0pMk5YbUzHZce7Q9UY8g/+InUSq
-tCfuYuPaokuFkxGAqDSMSiIJSx3gEI1dTIU69TGlppkxts1XdhSR+YanqyKSKpr1
-T6FdDJNCjAlNQvuFmVM4d5PYF4kqXApu/60MTSD6RXHwxCe1ecEP6G5VLbCew9jG
-y33LAoIBAGsWyC9pwQEm/qYwn4AwYjx32acrtX1J9HtiTLvkqzjJvNu/DXcaEHm7
-tr32TNVp9A9z+JS5hDt49Hs+oC/aMCRe2lqRvmZ1y8kvfy4A1eLGC4stDPj65bDK
-QzziURRyejYxmCElPz6wI63VlCUdfwgEThn88SiSPY5ZF2SwxJoC+8peDwJCzwVP
-cmabxtHPOAfOibciNRPhoHCyhUdunUVjD1O26k1ewGwKaJoBVMgMWdLuNw8hq9FB
-3OukGmF3uD9OPbE9rpn3pX/89Dr9y8MpsvG20J6H8Z/BNVHILus/SmlxiIhvP7kv
-viIgTHaCHL/RWrhvg+8N3dRcSBqJQFsCggEAFe2TMEq2AlnBn4gsuAOIuZPYKQCg
-2a+tl1grQzmNth6AGGQcIqShadICD6SnVMIS64HHV/m18Cuz7GhJ06ZVjXJsHueG
-UpTE9wAmI2LxnNkupkLJu+SVcW3N86PujWmQBFpHkd+IRPLS51xjD9W5zLJ7HL4/
-fnKO+B+ZK6Imxbe5C5vJezkGfeOSyQoVtt6MT/XtSKNEGPBX+M6fLKgUMMg2H2Mt
-/SsD7DkOzFteKXzaEg/K8oOTpsOPkVDwNl2KErlEqbJv0k7yEVw50mYmsn/OLjh8
-+9EibISwCODbPxB+PhV6u2ue1IvGLRqtsN60lFOvbGn+kSewy9EUVHHQDQ==
------END RSA PRIVATE KEY-----
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 2f440f1f3c..2d4d2452e3 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. 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
@@ -256,11 +256,6 @@ init_per_testcase(Case, Config) when Case == unordered_protocol_versions_client
_ ->
{skip, "TLS 1.2 need but not supported on this platform"}
end;
-init_per_testcase(no_authority_key_identifier, Config) ->
- %% Clear cach so that root cert will not
- %% be found.
- ssl:clear_pem_cache(),
- Config;
init_per_testcase(protocol_versions, Config) ->
ssl:stop(),
@@ -1371,6 +1366,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 +1392,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_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 14047c6e9c..dab7a941db 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2013. 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
@@ -58,6 +58,10 @@ tests() ->
server_verify_none,
server_require_peer_cert_ok,
server_require_peer_cert_fail,
+ server_require_peer_cert_partial_chain,
+ server_require_peer_cert_allow_partial_chain,
+ server_require_peer_cert_do_not_allow_partial_chain,
+ server_require_peer_cert_partial_chain_fun_fail,
verify_fun_always_run_client,
verify_fun_always_run_server,
cert_expired,
@@ -143,8 +147,8 @@ server_verify_none() ->
[{doc,"Test server option verify_none"}].
server_verify_none(Config) when is_list(Config) ->
- ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
Active = ?config(active, Config),
ReceiveFunction = ?config(receive_function, Config),
@@ -261,6 +265,163 @@ server_require_peer_cert_fail(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
+
+server_require_peer_cert_partial_chain() ->
+ [{doc, "Client sends an incompleate chain, by default not acceptable."}].
+
+server_require_peer_cert_partial_chain(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ?config(server_verification_opts, Config)],
+ ClientOpts = ?config(client_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ {ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts)),
+ [{_,RootCA,_}, {_, _, _}] = public_key:pem_decode(ClientCAs),
+
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{active, false},
+ {cacerts, [RootCA]} |
+ proplists:delete(cacertfile, ClientOpts)]}]),
+ receive
+ {Server, {error, {tls_alert, "unknown ca"}}} ->
+ receive
+ {Client, {error, {tls_alert, "unknown ca"}}} ->
+ ok;
+ {Client, {error, closed}} ->
+ ok
+ end
+ end.
+%%--------------------------------------------------------------------
+server_require_peer_cert_allow_partial_chain() ->
+ [{doc, "Server trusts intermediat CA and accepts a partial chain. (partial_chain option)"}].
+
+server_require_peer_cert_allow_partial_chain(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ?config(server_verification_opts, Config)],
+ ClientOpts = ?config(client_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
+ [{_,_,_}, {_, IntermidiateCA, _}] = public_key:pem_decode(ServerCAs),
+
+ PartialChain = fun(CertChain) ->
+ case lists:member(IntermidiateCA, CertChain) of
+ true ->
+ {trusted_ca, IntermidiateCA};
+ false ->
+ unknown_ca
+ end
+ end,
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{cacerts, [IntermidiateCA]},
+ {partial_chain, PartialChain} |
+ proplists:delete(cacertfile, ServerOpts)]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+ %%--------------------------------------------------------------------
+server_require_peer_cert_do_not_allow_partial_chain() ->
+ [{doc, "Server does not accept the chain sent by the client as ROOT CA is unkown, "
+ "and we do not choose to trust the intermediate CA. (partial_chain option)"}].
+
+server_require_peer_cert_do_not_allow_partial_chain(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ?config(server_verification_opts, Config)],
+ ClientOpts = ?config(client_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
+ [{_,_,_}, {_, IntermidiateCA, _}] = public_key:pem_decode(ServerCAs),
+
+ PartialChain = fun(_CertChain) ->
+ unknown_ca
+ end,
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{cacerts, [IntermidiateCA]},
+ {partial_chain, PartialChain} |
+ proplists:delete(cacertfile, ServerOpts)]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ receive
+ {Server, {error, {tls_alert, "unknown ca"}}} ->
+ receive
+ {Client, {error, {tls_alert, "unknown ca"}}} ->
+ ok;
+ {Client, {error, closed}} ->
+ ok
+ end
+ end.
+
+ %%--------------------------------------------------------------------
+server_require_peer_cert_partial_chain_fun_fail() ->
+ [{doc, "If parial_chain fun crashes, treat it as if it returned unkown_ca"}].
+
+server_require_peer_cert_partial_chain_fun_fail(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ?config(server_verification_opts, Config)],
+ ClientOpts = ?config(client_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
+ [{_,_,_}, {_, IntermidiateCA, _}] = public_key:pem_decode(ServerCAs),
+
+ PartialChain = fun(_CertChain) ->
+ ture = false %% crash on purpose
+ end,
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{cacerts, [IntermidiateCA]},
+ {partial_chain, PartialChain} |
+ proplists:delete(cacertfile, ServerOpts)]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ receive
+ {Server, {error, {tls_alert, "unknown ca"}}} ->
+ receive
+ {Client, {error, {tls_alert, "unknown ca"}}} ->
+ ok;
+ {Client, {error, closed}} ->
+ ok
+ end
+ end.
+
+%%--------------------------------------------------------------------
verify_fun_always_run_client() ->
[{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
@@ -282,7 +443,7 @@ verify_fun_always_run_client(Config) when is_list(Config) ->
{unknown, UserState};
(_, valid, [ChainLen]) ->
{valid, [ChainLen + 1]};
- (_, valid_peer, [2]) ->
+ (_, valid_peer, [1]) ->
{fail, "verify_fun_was_always_run"};
(_, valid_peer, UserState) ->
{valid, UserState}
@@ -321,7 +482,7 @@ verify_fun_always_run_server(Config) when is_list(Config) ->
{unknown, UserState};
(_, valid, [ChainLen]) ->
{valid, [ChainLen + 1]};
- (_, valid_peer, [2]) ->
+ (_, valid_peer, [1]) ->
{fail, "verify_fun_was_always_run"};
(_, valid_peer, UserState) ->
{valid, UserState}
@@ -434,10 +595,16 @@ cert_expired(Config) when is_list(Config) ->
Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
- {options, [{verify, verify_peer} | ClientOpts]}]),
-
- ssl_test_lib:check_result(Server, {error, {tls_alert, "certificate expired"}},
- Client, {error, {tls_alert, "certificate expired"}}).
+ {options, [{verify, verify_peer} | ClientOpts]}]),
+ receive
+ {Client, {error, {tls_alert, "certificate expired"}}} ->
+ receive
+ {Server, {error, {tls_alert, "certificate expired"}}} ->
+ ok;
+ {Server, {error, closed}} ->
+ ok
+ end
+ end.
two_digits_str(N) when N < 10 ->
lists:flatten(io_lib:format("0~p", [N]));
@@ -632,7 +799,7 @@ no_authority_key_identifier() ->
no_authority_key_identifier(Config) when is_list(Config) ->
ClientOpts = ?config(client_verification_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
PrivDir = ?config(priv_dir, Config),
KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
@@ -804,7 +971,7 @@ unknown_server_ca_fail() ->
[{doc,"Test that the client fails if the ca is unknown in verify_peer mode"}].
unknown_server_ca_fail(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
@@ -833,11 +1000,11 @@ unknown_server_ca_fail(Config) when is_list(Config) ->
{verify_fun, FunAndState}
| ClientOpts]}]),
receive
- {Server, {error, {tls_alert, "unknown ca"}}} ->
+ {Client, {error, {tls_alert, "unknown ca"}}} ->
receive
- {Client, {error, {tls_alert, "unknown ca"}}} ->
+ {Server, {error, {tls_alert, "unknown ca"}}} ->
ok;
- {Client, {error, closed}} ->
+ {Server, {error, closed}} ->
ok
end
end.
@@ -848,7 +1015,7 @@ unknown_server_ca_accept_verify_none() ->
[{doc,"Test that the client succeds if the ca is unknown in verify_none mode"}].
unknown_server_ca_accept_verify_none(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -873,7 +1040,7 @@ unknown_server_ca_accept_verify_peer() ->
" with a verify_fun that accepts the unknown ca error"}].
unknown_server_ca_accept_verify_peer(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -912,7 +1079,7 @@ unknown_server_ca_accept_backwardscompatibility() ->
[{doc,"Test that old style verify_funs will work"}].
unknown_server_ca_accept_backwardscompatibility(Config) when is_list(Config) ->
ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
diff --git a/lib/ssl/test/ssl_cipher_SUITE.erl b/lib/ssl/test/ssl_cipher_SUITE.erl
index 45e91786d4..0e48b674e0 100644
--- a/lib/ssl/test/ssl_cipher_SUITE.erl
+++ b/lib/ssl/test/ssl_cipher_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,7 +38,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [aes_decipher_good, aes_decipher_good_tls11, aes_decipher_fail, aes_decipher_fail_tls11].
+ [aes_decipher_good, aes_decipher_fail, padding_test].
groups() ->
[].
@@ -73,93 +73,123 @@ end_per_testcase(_TestCase, Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
aes_decipher_good() ->
- [{doc,"Decipher a known cryptotext."}].
+ [{doc,"Decipher a known cryptotext using a correct key"}].
aes_decipher_good(Config) when is_list(Config) ->
HashSz = 32,
- CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
- key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>},
- Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8,
- 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160,
- 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122,
- 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>,
- Content = <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56, "HELLO\n">>,
- Mac = <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>,
- Version = {3,0},
- {Content, Mac, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version),
- Version1 = {3,1},
- {Content, Mac, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1),
- ok.
-
-%%--------------------------------------------------------------------
-
-aes_decipher_good_tls11() ->
- [{doc,"Decipher a known TLS 1.1 cryptotext."}].
-
-%% the fragment is actuall a TLS 1.1 record, with
-%% Version = TLS 1.1, we get the correct NextIV in #cipher_state
-aes_decipher_good_tls11(Config) when is_list(Config) ->
- HashSz = 32,
- CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
- key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>},
- Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8,
- 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160,
- 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122,
- 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>,
- Content = <<"HELLO\n">>,
- NextIV = <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>,
- Mac = <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>,
- Version = {3,2},
- {Content, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version),
- Version1 = {3,2},
- {Content, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1),
- ok.
+ CipherState = correct_cipher_state(),
+ decipher_check_good(HashSz, CipherState, {3,0}),
+ decipher_check_good(HashSz, CipherState, {3,1}),
+ decipher_check_good(HashSz, CipherState, {3,2}),
+ decipher_check_good(HashSz, CipherState, {3,3}).
%%--------------------------------------------------------------------
aes_decipher_fail() ->
- [{doc,"Decipher a known cryptotext."}].
+ [{doc,"Decipher a known cryptotext using a incorrect key"}].
-%% same as above, last byte of key replaced
aes_decipher_fail(Config) when is_list(Config) ->
HashSz = 32,
- CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
- key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>},
- Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8,
- 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160,
- 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122,
- 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>,
- Version = {3,0},
- {Content, Mac, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version),
- 32 = byte_size(Content),
- 32 = byte_size(Mac),
- Version1 = {3,1},
- {Content1, Mac1, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1),
- 32 = byte_size(Content1),
- 32 = byte_size(Mac1),
- ok.
-%%--------------------------------------------------------------------
-
-aes_decipher_fail_tls11() ->
- [{doc,"Decipher a known TLS 1.1 cryptotext."}].
-
-%% same as above, last byte of key replaced
-%% stricter padding checks in TLS 1.1 mean we get an alert instead
-aes_decipher_fail_tls11(Config) when is_list(Config) ->
- HashSz = 32,
- CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
- key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>},
- Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8,
- 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160,
- 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122,
- 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>,
- Version = {3,2},
- #alert{level = ?FATAL, description = ?BAD_RECORD_MAC} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version),
- Version1 = {3,3},
- #alert{level = ?FATAL, description = ?BAD_RECORD_MAC} =
- ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1),
- ok.
+ CipherState = incorrect_cipher_state(),
+ decipher_check_fail(HashSz, CipherState, {3,0}),
+ decipher_check_fail(HashSz, CipherState, {3,1}),
+ decipher_check_fail(HashSz, CipherState, {3,2}),
+ decipher_check_fail(HashSz, CipherState, {3,3}).
%%--------------------------------------------------------------------
+padding_test(Config) when is_list(Config) ->
+ HashSz = 16,
+ CipherState = correct_cipher_state(),
+ pad_test(HashSz, CipherState, {3,0}),
+ pad_test(HashSz, CipherState, {3,1}),
+ pad_test(HashSz, CipherState, {3,2}),
+ pad_test(HashSz, CipherState, {3,3}).
+
+%%--------------------------------------------------------------------
+% Internal functions --------------------------------------------------------
+%%--------------------------------------------------------------------
+decipher_check_good(HashSz, CipherState, Version) ->
+ {Content, NextIV, Mac} = content_nextiv_mac(Version),
+ {Content, Mac, #cipher_state{iv = NextIV}} =
+ ssl_cipher:decipher(?AES, HashSz, CipherState, aes_fragment(Version), Version, true).
+
+decipher_check_fail(HashSz, CipherState, Version) ->
+ {Content, NextIV, Mac} = content_nextiv_mac(Version),
+ true = {Content, Mac, #cipher_state{iv = NextIV}} =/=
+ ssl_cipher:decipher(?AES, HashSz, CipherState, aes_fragment(Version), Version, true).
+
+pad_test(HashSz, CipherState, {3,0} = Version) ->
+ %% 3.0 does not have padding test
+ {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
+ {Content, Mac, #cipher_state{iv = NextIV}} =
+ ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, true),
+ {Content, Mac, #cipher_state{iv = NextIV}} =
+ ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, false);
+pad_test(HashSz, CipherState, {3,1} = Version) ->
+ %% 3.1 should have padding test, but may be disabled
+ {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
+ BadCont = badpad_content(Content),
+ {Content, Mac, #cipher_state{iv = NextIV}} =
+ ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,1}) , {3,1}, false),
+ {BadCont, Mac, #cipher_state{iv = NextIV}} =
+ ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,1}), {3,1}, true);
+pad_test(HashSz, CipherState, Version) ->
+ %% 3.2 and 3.3 must have padding test
+ {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
+ BadCont = badpad_content(Content),
+ {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState,
+ badpad_aes_fragment(Version), Version, false),
+ {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState,
+ badpad_aes_fragment(Version), Version, true).
+
+aes_fragment({3,N}) when N == 0; N == 1->
+ <<197,9,6,109,242,87,80,154,85,250,110,81,119,95,65,185,53,206,216,153,246,169,
+ 119,177,178,238,248,174,253,220,242,81,33,0,177,251,91,44,247,53,183,198,165,
+ 63,20,194,159,107>>;
+
+aes_fragment(_) ->
+ <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8,
+ 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160,
+ 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122,
+ 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>.
+
+badpad_aes_fragment({3,N}) when N == 0; N == 1 ->
+ <<186,139,125,10,118,21,26,248,120,108,193,104,87,118,145,79,225,55,228,10,105,
+ 30,190,37,1,88,139,243,210,99,65,41>>;
+badpad_aes_fragment(_) ->
+ <<137,31,14,77,228,80,76,103,183,125,55,250,68,190,123,131,117,23,229,180,207,
+ 94,121,137,117,157,109,99,113,61,190,138,131,229,201,120,142,179,172,48,77,
+ 234,19,240,33,38,91,93>>.
+
+content_nextiv_mac({3,N}) when N == 0; N == 1 ->
+ {<<"HELLO\n">>,
+ <<33,0, 177,251, 91,44, 247,53, 183,198, 165,63, 20,194, 159,107>>,
+ <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>};
+content_nextiv_mac(_) ->
+ {<<"HELLO\n">>,
+ <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>,
+ <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>}.
+
+badpad_content_nextiv_mac({3,N}) when N == 0; N == 1 ->
+ {<<"HELLO\n">>,
+ <<225,55,228,10,105,30,190,37,1,88,139,243,210,99,65,41>>,
+ <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>
+ };
+badpad_content_nextiv_mac(_) ->
+ {<<"HELLO\n">>,
+ <<133,211,45,189,179,229,56,86,11,178,239,159,14,160,253,140>>,
+ <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>
+ }.
+
+badpad_content(Content) ->
+ %% BadContent will fail mac test
+ <<16#F0, Content/binary>>.
+
+correct_cipher_state() ->
+ #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
+ key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>}.
+
+incorrect_cipher_state() ->
+ #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
+ key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>}.
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index 5f36842f9e..8dca733526 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -38,6 +38,8 @@ 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,
+ decode_empty_server_sni_correctly,
select_proper_tls_1_2_rsa_default_hashsign].
%%--------------------------------------------------------------------
@@ -98,6 +100,20 @@ 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.
+
+decode_empty_server_sni_correctly(_Config) ->
+ Exts = #hello_extensions{sni = ""},
+ SNI = <<?UINT16(?SNI_EXT),?UINT16(0)>>,
+ 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/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl
new file mode 100644
index 0000000000..843079e2fe
--- /dev/null
+++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2015. 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/.2
+%%
+%% 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(ssl_pem_cache_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-define(CLEANUP_INTERVAL, 5000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [pem_cleanup].
+
+groups() ->
+ [].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl:start(),
+ %% make rsa certs using oppenssl
+ Result =
+ (catch make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0))),
+ ct:log("Make certs ~p~n", [Result]),
+
+ Config1 = ssl_test_lib:make_dsa_cert(Config0),
+ ssl_test_lib:cert_options(Config1)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ application:stop(crypto).
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(pem_cleanup, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, ssl_pem_cache_clean, ?CLEANUP_INTERVAL),
+ ssl:start(),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ %%ssl:stop(),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+pem_cleanup() ->
+ [{doc, "Test pem cache invalidate mechanism"}].
+pem_cleanup(Config)when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ Size = ssl_pkix_db:db_size(get_pem_cache()),
+ Certfile = proplists:get_value(certfile, ServerOpts),
+ {ok, FileInfo} = file:read_file_info(Certfile),
+ Time = later(),
+ ok = file:write_file_info(Certfile, FileInfo#file_info{mtime = Time}),
+ ct:sleep(2 * ?CLEANUP_INTERVAL),
+ Size1 = ssl_pkix_db:db_size(get_pem_cache()),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ false = Size == Size1.
+
+get_pem_cache() ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ case element(5, State) of
+ [_CertDb, _FileRefDb, PemChace] ->
+ PemChace;
+ _ ->
+ undefined
+ end.
+
+later()->
+ DateTime = calendar:now_to_local_time(os:timestamp()),
+ Gregorian = calendar:datetime_to_gregorian_seconds(DateTime),
+ calendar:gregorian_seconds_to_datetime(Gregorian + (2 * ?CLEANUP_INTERVAL)).
+
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 150b5037d7..74d71263de 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -450,7 +450,7 @@ make_ecdsa_cert(Config) ->
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
{server_ecdsa_verify_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ClientCaCertFile},
+ {cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
{verify, verify_peer}]},
{client_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true},
@@ -475,7 +475,7 @@ make_ecdh_rsa_cert(Config) ->
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
{server_ecdh_rsa_verify_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ClientCaCertFile},
+ {cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
{verify, verify_peer}]},
{client_ecdh_rsa_opts, [{ssl_imp, new},{reuseaddr, true},
@@ -1136,3 +1136,36 @@ filter_suites(Ciphers0) ->
Supported1 = ssl_cipher:filter_suites(Supported0),
Supported2 = [ssl:suite_definition(S) || S <- Supported1],
[Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported2)].
+
+-define(OPENSSL_QUIT, "Q\n").
+close_port(Port) ->
+ catch port_command(Port, ?OPENSSL_QUIT),
+ close_loop(Port, 500, false).
+
+close_loop(Port, Time, SentClose) ->
+ receive
+ {Port, {data,Debug}} when is_port(Port) ->
+ ct:log("openssl ~s~n",[Debug]),
+ close_loop(Port, Time, SentClose);
+ {ssl,_,Msg} ->
+ ct:log("ssl Msg ~s~n",[Msg]),
+ close_loop(Port, Time, SentClose);
+ {Port, closed} ->
+ ct:log("Port Closed~n",[]),
+ ok;
+ {'EXIT', Port, Reason} ->
+ ct:log("Port Closed ~p~n",[Reason]),
+ ok;
+ Msg ->
+ ct:log("Port Msg ~p~n",[Msg]),
+ close_loop(Port, Time, SentClose)
+ after Time ->
+ case SentClose of
+ false ->
+ ct:log("Closing port ~n",[]),
+ catch erlang:port_close(Port),
+ close_loop(Port, Time, true);
+ true ->
+ ct:log("Timeout~n",[])
+ end
+ end.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index d36e441c7a..942c446ec4 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -226,7 +226,7 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -259,7 +259,7 @@ basic_erlang_server_openssl_client(Config) when is_list(Config) ->
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false),
ok.
%%--------------------------------------------------------------------
@@ -298,7 +298,7 @@ erlang_client_openssl_server(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -332,11 +332,9 @@ erlang_server_openssl_client(Config) when is_list(Config) ->
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false).
-%%--------------------------------------------------------------------
-
erlang_client_openssl_server_dsa_cert() ->
[{doc,"Test erlang server with openssl client"}].
erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
@@ -376,7 +374,7 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false),
ok.
@@ -414,7 +412,7 @@ erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) ->
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
@@ -450,7 +448,7 @@ erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false),
ok.
@@ -496,7 +494,7 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false),
ok.
@@ -542,7 +540,7 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
@@ -581,7 +579,7 @@ erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
%% Clean close down! Server needs to be closed first !!
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
@@ -624,7 +622,7 @@ erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -666,7 +664,7 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -708,7 +706,7 @@ erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
ssl_test_lib:close(Server),
process_flag(trap_exit, false).
@@ -821,7 +819,7 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) ->
[{versions, [Version]} | ClientOpts]}]),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client1),
process_flag(trap_exit, false),
ok.
@@ -878,7 +876,7 @@ expired_session(Config) when is_list(Config) ->
{from, self()}, {options, ClientOpts}]),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client2),
process_flag(trap_exit, false).
@@ -1089,7 +1087,7 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
Result = ssl_test_lib:wait_for_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
ssl_test_lib:close(Client),
Return = case Result of
@@ -1136,7 +1134,7 @@ start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, Opens
Callback(Client, OpensslPort),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -1175,7 +1173,7 @@ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callbac
Callback(Client, OpensslPort),
%% Clean close down! Server needs to be closed first !!
- close_port(OpensslPort),
+ ssl_test_lib:close_port(OpensslPort),
ssl_test_lib:close(Client),
process_flag(trap_exit, false).
@@ -1205,7 +1203,7 @@ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callbac
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false).
@@ -1234,7 +1232,7 @@ start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenS
ssl_test_lib:close(Server),
- close_port(OpenSslPort),
+ ssl_test_lib:close_port(OpenSslPort),
process_flag(trap_exit, false).
@@ -1282,39 +1280,6 @@ delayed_send(Socket, [ErlData, OpenSslData]) ->
ssl:send(Socket, ErlData),
erlang_ssl_receive(Socket, OpenSslData).
-close_port(Port) ->
- catch port_command(Port, ?OPENSSL_QUIT),
- close_loop(Port, 500, false).
-
-close_loop(Port, Time, SentClose) ->
- receive
- {Port, {data,Debug}} when is_port(Port) ->
- ct:log("openssl ~s~n",[Debug]),
- close_loop(Port, Time, SentClose);
- {ssl,_,Msg} ->
- ct:log("ssl Msg ~s~n",[Msg]),
- close_loop(Port, Time, SentClose);
- {Port, closed} ->
- ct:log("Port Closed~n",[]),
- ok;
- {'EXIT', Port, Reason} ->
- ct:log("Port Closed ~p~n",[Reason]),
- ok;
- Msg ->
- ct:log("Port Msg ~p~n",[Msg]),
- close_loop(Port, Time, SentClose)
- after Time ->
- case SentClose of
- false ->
- ct:log("Closing port ~n",[]),
- catch erlang:port_close(Port),
- close_loop(Port, Time, true);
- true ->
- ct:log("Timeout~n",[])
- end
- end.
-
-
server_sent_garbage(Socket) ->
receive
server_sent_garbage ->
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 004cacf7fc..bda974da0e 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 5.3.5
+SSL_VSN = 5.3.8
diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml
index 942fd1f45e..0771682a25 100644
--- a/lib/stdlib/doc/src/dict.xml
+++ b/lib/stdlib/doc/src/dict.xml
@@ -121,7 +121,7 @@
<c><anno>Dict</anno></c> together with an extra argument <c>Acc</c>
(short for accumulator). <c><anno>Fun</anno></c> must return a new
accumulator which is passed to the next call. <c><anno>Acc0</anno></c> is
- returned if the list is empty. The evaluation order is
+ returned if the dict is empty. The evaluation order is
undefined.</p>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml
index 7f25f5b7bc..95eefb8f9b 100644
--- a/lib/stdlib/doc/src/erl_tar.xml
+++ b/lib/stdlib/doc/src/erl_tar.xml
@@ -80,6 +80,12 @@
</section>
<section>
+ <title>OTHER STORAGE MEDIA</title>
+ <p>The <c>erl_ftp</c> module normally accesses the tar-file on disk using the <seealso marker="kernel:file">file module</seealso>. When other needs arise, there is a way to define your own low-level Erlang functions to perform the writing and reading on the storage media. See <seealso marker="#init/3">init/3</seealso> for usage.</p>
+ <p>An example of this is the sftp support in <seealso marker="ssh:ssh_sftp#open_tar/3">ssh_sftp:open_tar/3</seealso>. That function opens a tar file on a remote machine using an sftp channel.</p>
+ </section>
+
+ <section>
<title>LIMITATIONS</title>
<p>For maximum compatibility, it is safe to archive files with names
up to 100 characters in length. Such tar files can generally be
@@ -99,7 +105,8 @@
<v>TarDescriptor = term()</v>
<v>Filename = filename()</v>
<v>Options = [Option]</v>
- <v>Option = dereference|verbose</v>
+ <v>Option = dereference|verbose|{chunks,ChunkSize}</v>
+ <v>ChunkSize = positive_integer()</v>
<v>RetValue = ok|{error,{Filename,Reason}}</v>
<v>Reason = term()</v>
</type>
@@ -119,6 +126,12 @@
<item>
<p>Print an informational message about the file being added.</p>
</item>
+ <tag><c>{chunks,ChunkSize}</c></tag>
+ <item>
+ <p>Read data in parts from the file. This is intended for memory-limited
+ machines that for example builds a tar file on a remote machine over
+ <seealso marker="ssh:ssh_sftp#open_tar/3">sftp</seealso>.</p>
+ </item>
</taglist>
</desc>
</func>
@@ -389,6 +402,101 @@
</warning>
</desc>
</func>
+
+ <func>
+ <name>init(UserPrivate, AccessMode, Fun) -> {ok,TarDescriptor} | {error,Reason}
+</name>
+ <fsummary>Creates a TarDescriptor used in subsequent tar operations when
+ defining own low-level storage access functions
+ </fsummary>
+ <type>
+ <v>UserPrivate = term()</v>
+ <v>AccessMode = [write] | [read]</v>
+ <v>Fun when AccessMode is [write] = fun(write, {UserPrivate,DataToWrite})->...;
+ (position,{UserPrivate,Position})->...;
+ (close, UserPrivate)->...
+ end
+ </v>
+ <v>Fun when AccessMode is [read] = fun(read2, {UserPrivate,Size})->...;
+ (position,{UserPrivate,Position})->...;
+ (close, UserPrivate)->...
+ end
+ </v>
+ <v>TarDescriptor = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>The <c>Fun</c> is the definition of what to do when the different
+ storage operations functions are to be called from the higher tar
+ handling functions (<c>add/3</c>, <c>add/4</c>, <c>close/1</c>...).
+ </p>
+ <p>The <c>Fun</c> will be called when the tar function wants to do
+ a low-level operation, like writing a block to a file. The Fun is called
+ as <c>Fun(Op,{UserPrivate,Parameters...})</c> where <c>Op</c> is the operation name,
+ <c>UserPrivate</c> is the term passed as the first argument to <c>init/1</c> and
+ <c>Parameters...</c> are the data added by the tar function to be passed down to
+ the storage handling function.
+ </p>
+ <p>The parameter <c>UserPrivate</c> is typically the result of opening a low level
+ structure like a file descriptor, a sftp channel id or such. The different <c>Fun</c>
+ clauses operates on that very term.
+ </p>
+ <p>The fun clauses parameter lists are:
+ <taglist>
+ <tag><c>(write, {UserPrivate,DataToWrite})</c></tag>
+ <item>Write the term <c>DataToWrite</c> using <c>UserPrivate</c></item>
+ <tag><c>(close, UserPrivate)</c></tag>
+ <item>Close the access.</item>
+ <tag><c>(read2, {UserPrivate,Size})</c></tag>
+ <item>Read using <c>UserPrivate</c> but only <c>Size</c> bytes. Note that there is
+ only an arity-2 read function, not an arity-1
+ </item>
+ <tag><c> (position,{UserPrivate,Position})</c></tag>
+ <item>Sets the position of <c>UserPrivate</c> as defined for files in <seealso marker="kernel:file#position-2">file:position/2</seealso></item>
+ <tag><c></c></tag>
+ <item></item>
+ </taglist>
+ </p>
+ <p>A complete <c>Fun</c> parameter for reading and writing on files using the
+ <seealso marker="kernel:file">file module</seealso> could be:
+ </p>
+ <code type="none">
+ ExampleFun =
+ fun(write, {Fd,Data}) -> file:write(Fd, Data);
+ (position, {Fd,Pos}) -> file:position(Fd, Pos);
+ (read2, {Fd,Size}) -> file:read(Fd,Size);
+ (close, Fd) -> file:close(Fd)
+ end
+ </code>
+ <p>where <c>Fd</c> was given to the <c>init/3</c> function as:</p>
+ <code>
+ {ok,Fd} = file:open(Name,...).
+ {ok,TarDesc} = erl_tar:init(Fd, [write], ExampleFun),
+ </code>
+ <p>The <c>TarDesc</c> is then used:</p>
+ <code>
+ erl_tar:add(TarDesc, SomeValueIwantToAdd, FileNameInTarFile),
+ ....,
+ erl_tar:close(TarDesc)
+ </code>
+ <p>When the erl_tar core wants to e.g. write a piece of Data, it would call
+ <c>ExampleFun(write,{UserPrivate,Data})</c>.
+ </p>
+ <note>
+ <p>The example above with <c>file</c> module operations is not necessary to
+ use directly since that is what the <seealso marker="#open">open</seealso> function
+ in principle does.
+ </p>
+ </note>
+ <warning>
+ <p>The <c>TarDescriptor</c> term is not a file descriptor.
+ You should not rely on the specific contents of the <c>TarDescriptor</c>
+ term, as it may change in future versions as more features are added
+ to the <c>erl_tar</c> module.</p>
+ </warning>
+ </desc>
+ </func>
+
<func>
<name>table(Name) -> RetValue</name>
<fsummary>Retrieve the name of all files in a tar file</fsummary>
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/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml
index 9328704e11..21da404c35 100644
--- a/lib/stdlib/doc/src/io_protocol.xml
+++ b/lib/stdlib/doc/src/io_protocol.xml
@@ -49,7 +49,7 @@ current I/O-protocol.</p>
<p>The original I/O-protocol was simple and flexible. Demands for spacial
and execution time efficiency has triggered extensions to the protocol
over the years, making the protocol larger and somewhat less easy to
-implement than the original. It can certainly be argumented that the
+implement than the original. It can certainly be argued that the
current protocol is too complex, but this text describes how it looks
today, not how it should have looked.</p>
@@ -76,10 +76,11 @@ the server eventually sends a corresponding <c>io_reply</c> tuple.</p>
the I/O server sends the IO reply to.</item>
<item><c>ReplyAs</c> can be any datum and is returned in the corresponding
-<c>io_reply</c>. The <seealso marker="stdlib:io">io</seealso> module simply uses the pid()
-of the I/O server as the <c>ReplyAs</c> datum, but a more complicated client
+<c>io_reply</c>. The <seealso marker="stdlib:io">io</seealso> module monitors
+the I/O server, and uses the monitor reference as the <c>ReplyAs</c> datum.
+A more complicated client
could have several outstanding I/O requests to the same I/O server and
-would then use i.e. a <c>reference()</c> or something else to differentiate among
+would then use different references (or something else) to differentiate among
the incoming IO replies. The <c>ReplyAs</c> element should be considered
opaque by the I/O server. Note that the <c>pid()</c> of the I/O server is not
explicitly present in the <c>io_reply</c> tuple. The reply can be sent from any
diff --git a/lib/stdlib/doc/src/maps.xml b/lib/stdlib/doc/src/maps.xml
index b37f7fd7fd..f766c843be 100644
--- a/lib/stdlib/doc/src/maps.xml
+++ b/lib/stdlib/doc/src/maps.xml
@@ -319,6 +319,23 @@ false</code>
</func>
<func>
+ <name name="with" arity="2"/>
+ <fsummary></fsummary>
+ <desc>
+ <p>
+ Returns a new map <c><anno>Map2</anno></c> with the keys <c>K1</c> through <c>Kn</c> and their associated values from map <c><anno>Map1</anno></c>.
+ Any key in <c><anno>Ks</anno></c> that does not exist in <c><anno>Map1</anno></c> are ignored.
+ </p>
+ <p>Example:</p>
+ <code type="none">
+> Map = #{42 => value_three,1337 => "value two","a" => 1},
+ Ks = ["a",42,"other key"],
+ maps:with(Ks,Map).
+#{42 => value_three,"a" => 1}</code>
+ </desc>
+ </func>
+
+ <func>
<name name="without" arity="2"/>
<fsummary></fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index 15e6fdfa9f..8582bfc9f9 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -30,6 +30,282 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 2.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The documentation of string:tokens/2 now explicitly
+ specifies that adjacent separator characters do not give
+ any empty strings in the resulting list of tokens.</p>
+ <p>
+ Own Id: OTP-12036</p>
+ </item>
+ <item>
+ <p>
+ Fix broken deprecation warnings in ssh application</p>
+ <p>
+ Own Id: OTP-12187</p>
+ </item>
+ <item>
+ <p>
+ Maps: Properly align union typed assoc values in
+ documentation</p>
+ <p>
+ Own Id: OTP-12190</p>
+ </item>
+ <item>
+ <p>
+ Fix filelib:wildcard/2 when 'Cwd' ends with a dot</p>
+ <p>
+ Own Id: OTP-12212</p>
+ </item>
+ <item>
+ <p>
+ Allow <c>Name/Arity</c> syntax in maps values inside
+ attributes.</p>
+ <p>
+ Own Id: OTP-12213</p>
+ </item>
+ <item>
+ <p>
+ Fix edlin to correctly save text killed with ctrl-u.
+ Prior to this fix, entering text into the Erlang shell
+ and then killing it with ctrl-u followed by yanking it
+ back with ctrl-y would result in the yanked text being
+ the reverse of the original killed text.</p>
+ <p>
+ Own Id: OTP-12224</p>
+ </item>
+ <item>
+ <p>
+ If a callback function was terminated with exit/1, there
+ would be no stack trace in the ERROR REPORT produced by
+ gen_server. This has been corrected.</p>
+ <p>
+ To keep the backwards compatibility, the actual exit
+ reason for the process is not changed.</p>
+ <p>
+ Own Id: OTP-12263 Aux Id: seq12733 </p>
+ </item>
+ <item>
+ <p>
+ Warnings produced by <c>ms_transform</c> could point out
+ the wrong line number.</p>
+ <p>
+ Own Id: OTP-12264</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Supports tar file creation on other media than file
+ systems mounted on the local machine.</p>
+ <p>
+ The <c>erl_tar</c> api is extended with
+ <c>erl_tar:init/3</c> that enables usage of user provided
+ media storage routines. A ssh-specific set of such
+ routines is hidden in the new function
+ <c>ssh_sftp:open_tar/3</c> to simplify creating a tar
+ archive on a remote ssh server.</p>
+ <p>
+ A chunked file reading option is added to
+ <c>erl_tar:add/3,4</c> to save memory on e.g small
+ embedded systems. The size of the slices read from a file
+ in that case can be specified.</p>
+ <p>
+ Own Id: OTP-12180 Aux Id: seq12715 </p>
+ </item>
+ <item>
+ <p>
+ I/O requests are optimized for long message queues in the
+ calling process.</p>
+ <p>
+ Own Id: OTP-12315</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The type spec of the FormFunc argument to
+ sys:handle_debug/4 was erroneously pointing to dbg_fun().
+ This is now corrected and the new type is format_fun().</p>
+ <p>
+ Own Id: OTP-11800</p>
+ </item>
+ <item>
+ <p>
+ Behaviors such as gen_fsm and gen_server should always
+ invoke format_status/2 before printing the state to the
+ logs.</p>
+ <p>
+ Own Id: OTP-11967</p>
+ </item>
+ <item>
+ <p> The documentation of <c>dets:insert_new/2</c> has
+ been corrected. (Thanks to Alexei Sholik for reporting
+ the bug.) </p>
+ <p>
+ Own Id: OTP-12024</p>
+ </item>
+ <item>
+ <p>
+ Printing a term with io_lib:format and control sequence
+ w, precision P and field width F, where F&lt; P would
+ fail in one of the two following ways:</p>
+ <p>
+ 1) If P &lt; printed length of the term, an infinite loop
+ would be entered, consuming all available memory.</p>
+ <p>
+ 2) If P &gt;= printed length of the term, an exception
+ would be raised.</p>
+ <p>
+ These two problems are now corrected.</p>
+ <p>
+ Own Id: OTP-12041</p>
+ </item>
+ <item>
+ <p>
+ The documentation of <c>maps:values/1</c> has been
+ corrected.</p>
+ <p>
+ Own Id: OTP-12055</p>
+ </item>
+ <item>
+ <p>
+ Expand shell functions in map expressions.</p>
+ <p>
+ Own Id: OTP-12063</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add maps:with/2</p>
+ <p>
+ Own Id: OTP-12137</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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 +619,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 +2469,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 +2487,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/string.xml b/lib/stdlib/doc/src/string.xml
index c96cc95a44..b05d5cbc08 100644
--- a/lib/stdlib/doc/src/string.xml
+++ b/lib/stdlib/doc/src/string.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>
@@ -124,6 +124,10 @@
<code type="none">
> tokens("abc defxxghix jkl", "x ").
["abc", "def", "ghi", "jkl"] </code>
+ <p>Note that, as shown in the example above, two or more
+ adjacent separator characters in <c><anno>String</anno></c>
+ will be treated as one. That is, there will not be any empty
+ strings in the resulting list of tokens.</p>
</desc>
</func>
<func>
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/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index bebfbd4514..29b8940c62 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -50,12 +50,8 @@
encoded files in several circumstances. Most notable is the support
for UTF-8 in files read by <c>file:consult/1</c>, release handler support
for UTF-8 and more support for Unicode character sets in the
- I/O-system.</p>
-
- <p>In Erlang/OTP 17.0, the encoding default for Erlang source files was
- switched to UTF-8 and in Erlang/OTP 18.0 Erlang will support atoms in the full
- Unicode range, meaning full Unicode function and module
- names</p>
+ I/O-system. In Erlang/OTP 17.0, the encoding default for Erlang source files was
+ switched to UTF-8.</p>
<p>This guide outlines the current Unicode support and gives a couple
of recipes for working with Unicode data.</p>
@@ -289,8 +285,8 @@
<tag>The language</tag>
<item>Having the source code in UTF-8 also allows you to write
string literals containing Unicode characters with code points &gt;
- 255, although atoms, module names and function names will be
- restricted to the ISO-Latin-1 range until the Erlang/OTP 18.0 release. Binary
+ 255, although atoms, module names and function names are
+ restricted to the ISO-Latin-1 range. Binary
literals where you use the <c>/utf8</c> type, can also be
expressed using Unicode characters &gt; 255. Having module names
using characters other than 7-bit ASCII can cause trouble on
@@ -385,8 +381,7 @@ external_charlist() = maybe_improper_list(char() |
using characters from the ISO-latin-1 character set and atoms are
restricted to the same ISO-latin-1 range. These restrictions in the
language are of course independent of the encoding of the source
- file. Erlang/OTP 18.0 is expected to handle functions named in
- Unicode as well as Unicode atoms.</p>
+ file.</p>
<section>
<title>Bit-syntax</title>
<p>The bit-syntax contains types for coping with binary data in the
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
index 4850a59eb6..8d07a356dd 100644
--- a/lib/stdlib/src/binary.erl
+++ b/lib/stdlib/src/binary.erl
@@ -89,9 +89,9 @@ copy(_, _) ->
decode_unsigned(_) ->
erlang:nif_error(undef).
--spec decode_unsigned(Subject, Endianess) -> Unsigned when
+-spec decode_unsigned(Subject, Endianness) -> Unsigned when
Subject :: binary(),
- Endianess :: big | little,
+ Endianness :: big | little,
Unsigned :: non_neg_integer().
decode_unsigned(_, _) ->
@@ -103,9 +103,9 @@ decode_unsigned(_, _) ->
encode_unsigned(_) ->
erlang:nif_error(undef).
--spec encode_unsigned(Unsigned, Endianess) -> binary() when
+-spec encode_unsigned(Unsigned, Endianness) -> binary() when
Unsigned :: non_neg_integer(),
- Endianess :: big | little.
+ Endianness :: big | little.
encode_unsigned(_, _) ->
erlang:nif_error(undef).
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index c2256c0cf9..9860adf04d 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -509,9 +509,12 @@ m(M) ->
{exports,E} = lists:keyfind(exports, 1, L),
Time = get_compile_time(L),
COpts = get_compile_options(L),
- format("Module ~w compiled: ",[M]), print_time(Time),
- format("Compiler options: ~p~n", [COpts]),
+ format("Module: ~w~n", [M]),
+ print_md5(L),
+ format("Compiled: "),
+ print_time(Time),
print_object_file(M),
+ format("Compiler options: ~p~n", [COpts]),
format("Exports: ~n",[]), print_exports(keysort(1, E)).
print_object_file(Mod) ->
@@ -522,6 +525,12 @@ print_object_file(Mod) ->
ignore
end.
+print_md5(L) ->
+ case lists:keyfind(md5, 1, L) of
+ {md5,<<MD5:128>>} -> io:format("MD5: ~.16b~n",[MD5]);
+ _ -> ok
+ end.
+
get_compile_time(L) ->
case get_compile_info(L, time) of
{ok,Val} -> Val;
@@ -569,8 +578,8 @@ split_print_exports([{F1, A1}|T1], [{F2, A2} | T2]) ->
split_print_exports([], []) -> ok.
print_time({Year,Month,Day,Hour,Min,_Secs}) ->
- format("Date: ~s ~w ~w, ", [month(Month),Day,Year]),
- format("Time: ~.2.0w.~.2.0w~n", [Hour,Min]);
+ format("~s ~w ~w, ", [month(Month),Day,Year]),
+ format("~.2.0w:~.2.0w~n", [Hour,Min]);
print_time(notime) ->
format("No compile time info available~n",[]).
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index c32da1624f..a4bd45ea19 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]);
@@ -2838,17 +2839,22 @@ fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) ->
tempfile(Fname) ->
Tmp = lists:concat([Fname, ".TMP"]),
- tempfile(Tmp, 10).
-
-tempfile(Tmp, 0) ->
- Tmp;
-tempfile(Tmp, N) ->
case file:delete(Tmp) of
- {error, eacces} -> % 'dets_process_died' happened anyway... (W-nd-ws)
- timer:sleep(1000),
- tempfile(Tmp, N-1);
- _ ->
- Tmp
+ {error, _Reason} -> % typically enoent
+ ok;
+ ok ->
+ assure_no_file(Tmp)
+ end,
+ Tmp.
+
+assure_no_file(File) ->
+ case file:read_file_info(File) of
+ {ok, _FileInfo} ->
+ %% Wait for some other process to close the file:
+ timer:sleep(100),
+ assure_no_file(File);
+ {error, _} ->
+ ok
end.
%% -> {ok, NewHead} | {try_again, integer()} | Error
diff --git a/lib/stdlib/src/dets_server.erl b/lib/stdlib/src/dets_server.erl
index 268c201047..3164d40f35 100644
--- a/lib/stdlib/src/dets_server.erl
+++ b/lib/stdlib/src/dets_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-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
@@ -171,9 +171,15 @@ handle_info({pending_reply, {Ref, Result0}}, State) ->
link(Pid),
do_link(Store, FromPid),
true = ets:insert(Store, {FromPid, Tab}),
- true = ets:insert(?REGISTRY, {Tab, 1, Pid}),
- true = ets:insert(?OWNERS, {Pid, Tab}),
+ %% do_internal_open() has already done the following:
+ %% true = ets:insert(?REGISTRY, {Tab, 1, Pid}),
+ %% true = ets:insert(?OWNERS, {Pid, Tab}),
{ok, Tab};
+ {Reply, internal_open} ->
+ %% Clean up what do_internal_open() did:
+ true = ets:delete(?REGISTRY, Tab),
+ true = ets:delete(?OWNERS, Pid),
+ Reply;
{Reply, _} -> % ok or Error
Reply
end,
@@ -309,6 +315,12 @@ do_internal_open(State, From, Args) ->
[T, _, _] -> T;
[_, _] -> Ref
end,
+ %% Pretend the table is open. If someone else tries to
+ %% open the file it will always become a pending
+ %% 'add_user' request. If someone tries to use the table
+ %% there will be a delay, but that is OK.
+ true = ets:insert(?REGISTRY, {Tab, 1, Pid}),
+ true = ets:insert(?OWNERS, {Pid, Tab}),
pending_call(Tab, Pid, Ref, From, Args, internal_open, State);
Error ->
{Error, State}
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index be9a4f5107..b3bc5f6d92 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -390,7 +390,7 @@ do_op(end_of_line, Bef, [C|Aft], Rs) ->
do_op(end_of_line, Bef, [], Rs) ->
{{Bef,[]},Rs};
do_op(ctlu, Bef, Aft, Rs) ->
- put(kill_buffer, Bef),
+ put(kill_buffer, reverse(Bef)),
{{[], Aft}, [{delete_chars, -length(Bef)} | Rs]};
do_op(beep, Bef, Aft, Rs) ->
{{Bef,Aft},[beep|Rs]};
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..64a00acd88 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},
@@ -697,9 +702,10 @@ record_update(R, Name, Fs, Us0, St0) ->
record_match(R, Name, Lr, Fs, Us, St0) ->
{Ps,News,St1} = record_upd_fs(Fs, Us, St0),
NLr = neg_line(Lr),
+ RLine = record_offset(Lr, St1),
{{'case',Lr,R,
- [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Ps]}],[],
- [{tuple,Lr,[{atom,Lr,Name} | News]}]},
+ [{clause,Lr,[{tuple,RLine,[{atom,Lr,Name} | Ps]}],[],
+ [{tuple,RLine,[{atom,Lr,Name} | News]}]},
{clause,NLr,[{var,NLr,'_'}],[],
[call_error(NLr, {tuple,NLr,[{atom,NLr,badrecord},{atom,NLr,Name}]})]}
]},
@@ -728,6 +734,10 @@ record_setel(R, Name, Fs, Us0) ->
Lr = element(2, hd(Us)),
Wildcards = duplicate(length(Fs), {var,Lr,'_'}),
NLr = neg_line(Lr),
+ %% Note: calling record_offset() here is not necessary since it is
+ %% targeted at Dialyzer which always calls the compiler with
+ %% 'strict_record_updates' meaning that record_setel() will never
+ %% be called.
{'case',Lr,R,
[{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Wildcards]}],[],
[foldr(fun ({I,Lf,Val}, Acc) ->
@@ -836,7 +846,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 +971,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/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index e1ae3b7aea..1d4a2a1fef 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -753,6 +753,9 @@ attribute_farity({cons,L,H,T}) ->
attribute_farity({tuple,L,Args0}) ->
Args = attribute_farity_list(Args0),
{tuple,L,Args};
+attribute_farity({map,L,Args0}) ->
+ Args = attribute_farity_map(Args0),
+ {map,L,Args};
attribute_farity({op,L,'/',{atom,_,_}=Name,{integer,_,_}=Arity}) ->
{tuple,L,[Name,Arity]};
attribute_farity(Other) -> Other.
@@ -760,6 +763,10 @@ attribute_farity(Other) -> Other.
attribute_farity_list(Args) ->
[attribute_farity(A) || A <- Args].
+%% It is not meaningful to have farity keys.
+attribute_farity_map(Args) ->
+ [{Op,L,K,attribute_farity(V)} || {Op,L,K,V} <- Args].
+
-spec error_bad_decl(integer(), attributes()) -> no_return().
error_bad_decl(L, S) ->
@@ -954,7 +961,9 @@ abstract([H|T], L, none=E) ->
abstract(List, L, E) when is_list(List) ->
abstract_list(List, [], L, E);
abstract(Tuple, L, E) when is_tuple(Tuple) ->
- {tuple,L,abstract_tuple_list(tuple_to_list(Tuple), L, E)}.
+ {tuple,L,abstract_tuple_list(tuple_to_list(Tuple), L, E)};
+abstract(Map, L, E) when is_map(Map) ->
+ {map,L,abstract_map_fields(maps:to_list(Map),L,E)}.
abstract_list([H|T], String, L, E) ->
case is_integer(H) andalso H >= 0 andalso E(H) of
@@ -979,6 +988,9 @@ abstract_tuple_list([H|T], L, E) ->
abstract_tuple_list([], _L, _E) ->
[].
+abstract_map_fields(Fs,L,E) ->
+ [{map_field_assoc,L,abstract(K,L,E),abstract(V,L,E)}||{K,V}<-Fs].
+
abstract_byte(Byte, L) when is_integer(Byte) ->
{bin_element, L, {integer, L, Byte}, default, default};
abstract_byte(Bits, L) ->
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 82bc2c1460..1fd6d2a8df 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -300,7 +300,15 @@ map_pair_types(Fs) ->
tuple_type(Fs, fun map_pair_type/1).
map_pair_type({type,_Line,map_field_assoc,Ktype,Vtype}) ->
- {seq,[],[]," =>",[ltype(Ktype),ltype(Vtype)]}.
+ map_assoc_typed(ltype(Ktype), Vtype).
+
+map_assoc_typed(B, {type,_,union,Ts}) ->
+ {first,[B,$\s],{seq,[],[],[],map_assoc_union_type(Ts)}};
+map_assoc_typed(B, Type) ->
+ {list,[{cstep,[B," =>"],ltype(Type)}]}.
+
+map_assoc_union_type([T|Ts]) ->
+ [[leaf("=> "),ltype(T)] | ltypes(Ts, fun union_elem/1)].
record_type(Name, Fields) ->
{first,[record_name(Name)],field_types(Fields)}.
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index ae59d5f44f..6fd6bb888b 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -1075,7 +1075,7 @@ scan_number([$#|Cs]=Cs0, St, Line, Col, Toks, Ncs0) ->
Ncs = lists:reverse(Ncs0),
case catch list_to_integer(Ncs) of
B when B >= 2, B =< 1+$Z-$A+10 ->
- Bcs = ?STR(St, Ncs++[$#]),
+ Bcs = Ncs++[$#],
scan_based_int(Cs, St, Line, Col, Toks, {B,[],Bcs});
B ->
Len = length(Ncs),
@@ -1108,7 +1108,7 @@ scan_based_int(Cs, St, Line, Col, Toks, {B,Ncs0,Bcs}) ->
Ncs = lists:reverse(Ncs0),
case catch erlang:list_to_integer(Ncs, B) of
N when is_integer(N) ->
- tok3(Cs, St, Line, Col, Toks, integer, ?STR(St, Bcs++Ncs), N);
+ tok3(Cs, St, Line, Col, Toks, integer, Bcs++Ncs, N);
_ ->
Len = length(Bcs)+length(Ncs),
Ncol = incr_column(Col, Len),
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index acf7a5cd40..caa3276d09 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -22,7 +22,7 @@
%% Purpose: Unix tar (tape archive) utility.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([create/2, create/3, extract/1, extract/2, table/1, table/2,
+-export([init/3, create/2, create/3, extract/1, extract/2, table/1, table/2,
open/2, close/1, add/3, add/4,
t/1, tt/1, format_error/1]).
@@ -30,10 +30,16 @@
-record(add_opts,
{read_info, % Fun to use for read file/link info.
+ chunk_size = 0, % For file reading when sending to sftp. 0=do not chunk
verbose = false :: boolean()}). % Verbose on/off.
%% Opens a tar archive.
+init(UsrHandle, AccessMode, Fun) when is_function(Fun,2) ->
+ {ok, {AccessMode,{tar_descriptor,UsrHandle,Fun}}}.
+
+%%%================================================================
+%%% The open function with friends is to keep the file and binary api of this module
open(Name, Mode) ->
case open_mode(Mode) of
{ok, Access, Raw, Opts} ->
@@ -46,27 +52,37 @@ open1({binary,Bin}, read, _Raw, Opts) ->
case file:open(Bin, [ram,binary,read]) of
{ok,File} ->
_ = [ram_file:uncompress(File) || Opts =:= [compressed]],
- {ok,{read,File}};
+ init(File,read,file_fun());
Error ->
Error
end;
open1({file, Fd}, read, _Raw, _Opts) ->
- {ok, {read, Fd}};
+ init(Fd, read, file_fun());
open1(Name, Access, Raw, Opts) ->
case file:open(Name, Raw ++ [binary, Access|Opts]) of
{ok, File} ->
- {ok, {Access, File}};
+ init(File, Access, file_fun());
{error, Reason} ->
{error, {Name, Reason}}
end.
+file_fun() ->
+ fun(write, {Fd,Data}) -> file:write(Fd, Data);
+ (position, {Fd,Pos}) -> file:position(Fd, Pos);
+ (read2, {Fd,Size}) -> file:read(Fd,Size);
+ (close, Fd) -> file:close(Fd)
+ end.
+
+%%% End of file and binary api (except for open_mode/1 downwards
+%%%================================================================
+
%% Closes a tar archive.
close({read, File}) ->
- ok = file:close(File);
+ ok = do_close(File);
close({write, File}) ->
PadResult = pad_file(File),
- ok = file:close(File),
+ ok = do_close(File),
PadResult;
close(_) ->
{error, einval}.
@@ -75,7 +91,6 @@ close(_) ->
add(File, Name, Options) ->
add(File, Name, Name, Options).
-
add({write, File}, Name, NameInArchive, Options) ->
Opts = #add_opts{read_info=fun(F) -> file:read_link_info(F) end},
add1(File, Name, NameInArchive, add_opts(Options, Opts));
@@ -88,6 +103,8 @@ add_opts([dereference|T], Opts) ->
add_opts(T, Opts#add_opts{read_info=fun(F) -> file:read_file_info(F) end});
add_opts([verbose|T], Opts) ->
add_opts(T, Opts#add_opts{verbose=true});
+add_opts([{chunks,N}|T], Opts) ->
+ add_opts(T, Opts#add_opts{chunk_size=N});
add_opts([_|T], Opts) ->
add_opts(T, Opts);
add_opts([], Opts) ->
@@ -321,16 +338,46 @@ add1(TarFile, Name, NameInArchive, Opts) ->
{error, {Name, Reason}}
end.
+add1(Tar, Name, Header, chunked, Options) ->
+ add_verbose(Options, "a ~ts [chunked ", [Name]),
+ try
+ ok = do_write(Tar, Header),
+ {ok,D} = file:open(Name, [read,binary]),
+ {ok,NumBytes} = add_read_write_chunks(D, Tar, Options#add_opts.chunk_size, 0, Options),
+ _ = file:close(D),
+ ok = do_write(Tar, padding(NumBytes,?record_size))
+ of
+ ok ->
+ add_verbose(Options, "~n", []),
+ ok
+ catch
+ error:{badmatch,{error,Error}} ->
+ add_verbose(Options, "~n", []),
+ {error,{Name,Error}}
+ end;
add1(Tar, Name, Header, Bin, Options) ->
add_verbose(Options, "a ~ts~n", [Name]),
- file:write(Tar, [Header, Bin, padding(byte_size(Bin), ?record_size)]).
+ do_write(Tar, [Header, Bin, padding(byte_size(Bin), ?record_size)]).
+
+add_read_write_chunks(D, Tar, ChunkSize, SumNumBytes, Options) ->
+ case file:read(D, ChunkSize) of
+ {ok,Bin} ->
+ ok = do_write(Tar, Bin),
+ add_verbose(Options, ".", []),
+ add_read_write_chunks(D, Tar, ChunkSize, SumNumBytes+byte_size(Bin), Options);
+ eof ->
+ add_verbose(Options, "]", []),
+ {ok,SumNumBytes};
+ Other ->
+ Other
+ end.
add_directory(TarFile, DirName, NameInArchive, Info, Options) ->
case file:list_dir(DirName) of
{ok, []} ->
add_verbose(Options, "a ~ts~n", [DirName]),
Header = create_header(NameInArchive, Info),
- file:write(TarFile, Header);
+ do_write(TarFile, Header);
{ok, Files} ->
Add = fun (File) ->
add1(TarFile,
@@ -396,7 +443,7 @@ to_string(Str0, Count) ->
%% Pads out end of file.
pad_file(File) ->
- {ok,Position} = file:position(File, {cur,0}),
+ {ok,Position} = do_position(File, {cur,0}),
%% There must be at least two zero records at the end.
Fill = case ?block_size - (Position rem ?block_size) of
Fill0 when Fill0 < 2*?record_size ->
@@ -407,7 +454,7 @@ pad_file(File) ->
%% Large enough.
Fill0
end,
- file:write(File, zeroes(Fill)).
+ do_write(File, zeroes(Fill)).
split_filename(Name) when length(Name) =< ?th_name_len ->
{"", Name};
@@ -485,27 +532,36 @@ read_opts([_|Rest], Opts) ->
read_opts([], Opts) ->
Opts.
+foldl_read({AccessMode,TD={tar_descriptor,_UsrHandle,_AccessFun}}, Fun, Accu, Opts) ->
+ case AccessMode of
+ read ->
+ foldl_read0(TD, Fun, Accu, Opts);
+ _ ->
+ {error,{read_mode_expected,AccessMode}}
+ end;
foldl_read(TarName, Fun, Accu, Opts) ->
case open(TarName, [read|Opts#read_opts.open_mode]) of
{ok, {read, File}} ->
- Result =
- case catch foldl_read1(Fun, Accu, File, Opts) of
- {'EXIT', Reason} ->
- exit(Reason);
- {error, {Reason, Format, Args}} ->
- read_verbose(Opts, Format, Args),
- {error, Reason};
- {error, Reason} ->
- {error, Reason};
- Ok ->
- Ok
- end,
- ok = file:close(File),
+ Result = foldl_read0(File, Fun, Accu, Opts),
+ ok = do_close(File),
Result;
Error ->
Error
end.
+foldl_read0(File, Fun, Accu, Opts) ->
+ case catch foldl_read1(Fun, Accu, File, Opts) of
+ {'EXIT', Reason} ->
+ exit(Reason);
+ {error, {Reason, Format, Args}} ->
+ read_verbose(Opts, Format, Args),
+ {error, Reason};
+ {error, Reason} ->
+ {error, Reason};
+ Ok ->
+ Ok
+ end.
+
foldl_read1(Fun, Accu0, File, Opts) ->
case get_header(File) of
eof ->
@@ -559,7 +615,7 @@ check_extract(Name, #read_opts{files=Files}) ->
ordsets:is_element(Name, Files).
get_header(File) ->
- case file:read(File, ?record_size) of
+ case do_read(File, ?record_size) of
eof ->
throw({error,eof});
{ok, Bin} when is_binary(Bin) ->
@@ -690,7 +746,7 @@ get_element(File, #tar_header{size = 0}) ->
skip_to_next(File),
{ok,<<>>};
get_element(File, #tar_header{size = Size}) ->
- case file:read(File, Size) of
+ case do_read(File, Size) of
{ok,Bin}=Res when byte_size(Bin) =:= Size ->
skip_to_next(File),
Res;
@@ -880,7 +936,7 @@ skip(File, Size) ->
%% Note: There is no point in handling failure to get the current position
%% in the file. If it doesn't work, something serious is wrong.
Amount = ((Size + ?record_size - 1) div ?record_size) * ?record_size,
- {ok,_} = file:position(File, {cur, Amount}),
+ {ok,_} = do_position(File, {cur, Amount}),
ok.
%% Skips to the next record in the file.
@@ -888,9 +944,9 @@ skip(File, Size) ->
skip_to_next(File) ->
%% Note: There is no point in handling failure to get the current position
%% in the file. If it doesn't work, something serious is wrong.
- {ok, Position} = file:position(File, {cur, 0}),
+ {ok, Position} = do_position(File, {cur, 0}),
NewPosition = ((Position + ?record_size - 1) div ?record_size) * ?record_size,
- {ok,NewPosition} = file:position(File, NewPosition),
+ {ok,NewPosition} = do_position(File, NewPosition),
ok.
%% Prints the message on if the verbose option is given.
@@ -916,6 +972,9 @@ posix_to_erlang_time(Sec) ->
read_file_and_info(Name, Opts) ->
ReadInfo = Opts#add_opts.read_info,
case ReadInfo(Name) of
+ {ok,Info} when Info#file_info.type =:= regular,
+ Opts#add_opts.chunk_size>0 ->
+ {ok,chunked,Info};
{ok,Info} when Info#file_info.type =:= regular ->
case file:read_file(Name) of
{ok,Bin} ->
@@ -962,3 +1021,12 @@ open_mode([], Access, Raw, Opts) ->
{ok, Access, Raw, Opts};
open_mode(_, _, _, _) ->
{error, einval}.
+
+%%%================================================================
+do_write({tar_descriptor,UsrHandle,Fun}, Data) -> Fun(write,{UsrHandle,Data}).
+
+do_position({tar_descriptor,UsrHandle,Fun}, Pos) -> Fun(position,{UsrHandle,Pos}).
+
+do_read({tar_descriptor,UsrHandle,Fun}, Len) -> Fun(read2,{UsrHandle,Len}).
+
+do_close({tar_descriptor,UsrHandle,Fun}) -> Fun(close,UsrHandle).
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index c0921e4cf1..daae1fd2d2 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;
@@ -371,7 +371,7 @@ compile_wildcard(Pattern, Cwd0) ->
[Root|Rest] = filename:split(Pattern),
case filename:pathtype(Root) of
relative ->
- Cwd = filename:join([Cwd0]),
+ Cwd = prepare_base(Cwd0),
compile_wildcard_2([Root|Rest], {cwd,Cwd});
_ ->
compile_wildcard_2(Rest, {root,0,Root})
@@ -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/gen_event.erl b/lib/stdlib/src/gen_event.erl
index d39dd89d3a..469acdc37c 100644
--- a/lib/stdlib/src/gen_event.erl
+++ b/lib/stdlib/src/gen_event.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
@@ -49,8 +49,6 @@
-import(error_logger, [error_msg/2]).
--define(reply(X), From ! {element(2,Tag), X}).
-
-record(handler, {module :: atom(),
id = false,
state,
@@ -249,49 +247,49 @@ handle_msg(Msg, Parent, ServerName, MSL, Debug) ->
{notify, Event} ->
{Hib,MSL1} = server_notify(Event, handle_event, MSL, ServerName),
loop(Parent, ServerName, MSL1, Debug, Hib);
- {From, Tag, {sync_notify, Event}} ->
+ {_From, Tag, {sync_notify, Event}} ->
{Hib, MSL1} = server_notify(Event, handle_event, MSL, ServerName),
- ?reply(ok),
+ reply(Tag, ok),
loop(Parent, ServerName, MSL1, Debug, Hib);
{'EXIT', From, Reason} ->
MSL1 = handle_exit(From, Reason, MSL, ServerName),
loop(Parent, ServerName, MSL1, Debug, false);
- {From, Tag, {call, Handler, Query}} ->
+ {_From, Tag, {call, Handler, Query}} ->
{Hib, Reply, MSL1} = server_call(Handler, Query, MSL, ServerName),
- ?reply(Reply),
+ reply(Tag, Reply),
loop(Parent, ServerName, MSL1, Debug, Hib);
- {From, Tag, {add_handler, Handler, Args}} ->
+ {_From, Tag, {add_handler, Handler, Args}} ->
{Hib, Reply, MSL1} = server_add_handler(Handler, Args, MSL),
- ?reply(Reply),
+ reply(Tag, Reply),
loop(Parent, ServerName, MSL1, Debug, Hib);
- {From, Tag, {add_sup_handler, Handler, Args, SupP}} ->
+ {_From, Tag, {add_sup_handler, Handler, Args, SupP}} ->
{Hib, Reply, MSL1} = server_add_sup_handler(Handler, Args, MSL, SupP),
- ?reply(Reply),
+ reply(Tag, Reply),
loop(Parent, ServerName, MSL1, Debug, Hib);
- {From, Tag, {delete_handler, Handler, Args}} ->
+ {_From, Tag, {delete_handler, Handler, Args}} ->
{Reply, MSL1} = server_delete_handler(Handler, Args, MSL,
ServerName),
- ?reply(Reply),
+ reply(Tag, Reply),
loop(Parent, ServerName, MSL1, Debug, false);
- {From, Tag, {swap_handler, Handler1, Args1, Handler2, Args2}} ->
+ {_From, Tag, {swap_handler, Handler1, Args1, Handler2, Args2}} ->
{Hib, Reply, MSL1} = server_swap_handler(Handler1, Args1, Handler2,
Args2, MSL, ServerName),
- ?reply(Reply),
+ reply(Tag, Reply),
loop(Parent, ServerName, MSL1, Debug, Hib);
- {From, Tag, {swap_sup_handler, Handler1, Args1, Handler2, Args2,
+ {_From, Tag, {swap_sup_handler, Handler1, Args1, Handler2, Args2,
Sup}} ->
{Hib, Reply, MSL1} = server_swap_handler(Handler1, Args1, Handler2,
Args2, MSL, Sup, ServerName),
- ?reply(Reply),
+ reply(Tag, Reply),
loop(Parent, ServerName, MSL1, Debug, Hib);
- {From, Tag, stop} ->
+ {_From, Tag, stop} ->
catch terminate_server(normal, Parent, MSL, ServerName),
- ?reply(ok);
- {From, Tag, which_handlers} ->
- ?reply(the_handlers(MSL)),
+ reply(Tag, ok);
+ {_From, Tag, which_handlers} ->
+ reply(Tag, the_handlers(MSL)),
loop(Parent, ServerName, MSL, Debug, false);
- {From, Tag, get_modules} ->
- ?reply(get_modules(MSL)),
+ {_From, Tag, get_modules} ->
+ reply(Tag, get_modules(MSL)),
loop(Parent, ServerName, MSL, Debug, false);
Other ->
{Hib, MSL1} = server_notify(Other, handle_info, MSL, ServerName),
@@ -303,6 +301,10 @@ terminate_server(Reason, Parent, MSL, ServerName) ->
do_unlink(Parent, MSL),
exit(Reason).
+reply({From, Ref}, Msg) ->
+ From ! {Ref, Msg},
+ ok.
+
%% unlink the supervisor process of all supervised handlers.
%% We do not want a handler supervisor to EXIT due to the
%% termination of the event manager (server).
diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl
index e914f7d0b2..5afe3e8b09 100644
--- a/lib/stdlib/src/gen_fsm.erl
+++ b/lib/stdlib/src/gen_fsm.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
@@ -594,7 +594,8 @@ reply(Name, {To, Tag}, Reply, Debug, StateName) ->
terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
case catch Mod:terminate(Reason, StateName, StateData) of
{'EXIT', R} ->
- error_info(R, Name, Msg, StateName, StateData, Debug),
+ FmtStateData = format_status(terminate, Mod, get(), StateData),
+ error_info(R, Name, Msg, StateName, FmtStateData, Debug),
exit(R);
_ ->
case Reason of
@@ -605,17 +606,7 @@ terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
{shutdown,_}=Shutdown ->
exit(Shutdown);
_ ->
- FmtStateData =
- case erlang:function_exported(Mod, format_status, 2) of
- true ->
- Args = [get(), StateData],
- case catch Mod:format_status(terminate, Args) of
- {'EXIT', _} -> StateData;
- Else -> Else
- end;
- _ ->
- StateData
- end,
+ FmtStateData = format_status(terminate, Mod, get(), StateData),
error_info(Reason,Name,Msg,StateName,FmtStateData,Debug),
exit(Reason)
end
@@ -680,21 +671,29 @@ format_status(Opt, StatusData) ->
Header = gen:format_status_header("Status for state machine",
Name),
Log = sys:get_debug(log, Debug, []),
- DefaultStatus = [{data, [{"StateData", StateData}]}],
- Specfic =
- case erlang:function_exported(Mod, format_status, 2) of
- true ->
- case catch Mod:format_status(Opt,[PDict,StateData]) of
- {'EXIT', _} -> DefaultStatus;
- StatusList when is_list(StatusList) -> StatusList;
- Else -> [Else]
- end;
- _ ->
- DefaultStatus
- end,
+ Specfic = format_status(Opt, Mod, PDict, StateData),
+ Specfic = case format_status(Opt, Mod, PDict, StateData) of
+ S when is_list(S) -> S;
+ S -> [S]
+ end,
[{header, Header},
{data, [{"Status", SysState},
{"Parent", Parent},
{"Logged events", Log},
{"StateName", StateName}]} |
Specfic].
+
+format_status(Opt, Mod, PDict, State) ->
+ DefStatus = case Opt of
+ terminate -> State;
+ _ -> [{data, [{"StateData", State}]}]
+ end,
+ case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ case catch Mod:format_status(Opt, [PDict, State]) of
+ {'EXIT', _} -> DefStatus;
+ Else -> Else
+ end;
+ _ ->
+ DefStatus
+ end.
diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl
index 202a931fae..18ef4a2507 100644
--- a/lib/stdlib/src/gen_server.erl
+++ b/lib/stdlib/src/gen_server.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
@@ -567,28 +567,88 @@ start_monitor(Node, Name) when is_atom(Node), is_atom(Name) ->
end
end.
+%% ---------------------------------------------------
+%% Helper functions for try-catch of callbacks.
+%% Returns the return value of the callback, or
+%% {'EXIT', ExitReason, ReportReason} (if an exception occurs)
+%%
+%% ExitReason is the reason that shall be used when the process
+%% terminates.
+%%
+%% ReportReason is the reason that shall be printed in the error
+%% report.
+%%
+%% These functions are introduced in order to add the stack trace in
+%% the error report produced when a callback is terminated with
+%% erlang:exit/1 (OTP-12263).
+%% ---------------------------------------------------
+
+try_dispatch({'$gen_cast', Msg}, Mod, State) ->
+ try_dispatch(Mod, handle_cast, Msg, State);
+try_dispatch(Info, Mod, State) ->
+ try_dispatch(Mod, handle_info, Info, State).
+
+try_dispatch(Mod, Func, Msg, State) ->
+ try
+ {ok, Mod:Func(Msg, State)}
+ catch
+ throw:R ->
+ {ok, R};
+ error:R ->
+ Stacktrace = erlang:get_stacktrace(),
+ {'EXIT', {R, Stacktrace}, {R, Stacktrace}};
+ exit:R ->
+ Stacktrace = erlang:get_stacktrace(),
+ {'EXIT', R, {R, Stacktrace}}
+ end.
+
+try_handle_call(Mod, Msg, From, State) ->
+ try
+ {ok, Mod:handle_call(Msg, From, State)}
+ catch
+ throw:R ->
+ {ok, R};
+ error:R ->
+ Stacktrace = erlang:get_stacktrace(),
+ {'EXIT', {R, Stacktrace}, {R, Stacktrace}};
+ exit:R ->
+ Stacktrace = erlang:get_stacktrace(),
+ {'EXIT', R, {R, Stacktrace}}
+ end.
+
+try_terminate(Mod, Reason, State) ->
+ try
+ {ok, Mod:terminate(Reason, State)}
+ catch
+ throw:R ->
+ {ok, R};
+ error:R ->
+ Stacktrace = erlang:get_stacktrace(),
+ {'EXIT', {R, Stacktrace}, {R, Stacktrace}};
+ exit:R ->
+ Stacktrace = erlang:get_stacktrace(),
+ {'EXIT', R, {R, Stacktrace}}
+ end.
+
+
%%% ---------------------------------------------------
%%% Message handling functions
%%% ---------------------------------------------------
-dispatch({'$gen_cast', Msg}, Mod, State) ->
- Mod:handle_cast(Msg, State);
-dispatch(Info, Mod, State) ->
- Mod:handle_info(Info, State).
-
handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
- case catch Mod:handle_call(Msg, From, State) of
- {reply, Reply, NState} ->
+ Result = try_handle_call(Mod, Msg, From, State),
+ case Result of
+ {ok, {reply, Reply, NState}} ->
reply(From, Reply),
loop(Parent, Name, NState, Mod, infinity, []);
- {reply, Reply, NState, Time1} ->
+ {ok, {reply, Reply, NState, Time1}} ->
reply(From, Reply),
loop(Parent, Name, NState, Mod, Time1, []);
- {noreply, NState} ->
+ {ok, {noreply, NState}} ->
loop(Parent, Name, NState, Mod, infinity, []);
- {noreply, NState, Time1} ->
+ {ok, {noreply, NState, Time1}} ->
loop(Parent, Name, NState, Mod, Time1, []);
- {stop, Reason, Reply, NState} ->
+ {ok, {stop, Reason, Reply, NState}} ->
{'EXIT', R} =
(catch terminate(Reason, Name, Msg, Mod, NState, [])),
reply(From, Reply),
@@ -596,26 +656,27 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
Other -> handle_common_reply(Other, Parent, Name, Msg, Mod, State)
end;
handle_msg(Msg, Parent, Name, State, Mod) ->
- Reply = (catch dispatch(Msg, Mod, State)),
+ Reply = try_dispatch(Msg, Mod, State),
handle_common_reply(Reply, Parent, Name, Msg, Mod, State).
handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) ->
- case catch Mod:handle_call(Msg, From, State) of
- {reply, Reply, NState} ->
+ Result = try_handle_call(Mod, Msg, From, State),
+ case Result of
+ {ok, {reply, Reply, NState}} ->
Debug1 = reply(Name, From, Reply, NState, Debug),
loop(Parent, Name, NState, Mod, infinity, Debug1);
- {reply, Reply, NState, Time1} ->
+ {ok, {reply, Reply, NState, Time1}} ->
Debug1 = reply(Name, From, Reply, NState, Debug),
loop(Parent, Name, NState, Mod, Time1, Debug1);
- {noreply, NState} ->
+ {ok, {noreply, NState}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
loop(Parent, Name, NState, Mod, infinity, Debug1);
- {noreply, NState, Time1} ->
+ {ok, {noreply, NState, Time1}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
loop(Parent, Name, NState, Mod, Time1, Debug1);
- {stop, Reason, Reply, NState} ->
+ {ok, {stop, Reason, Reply, NState}} ->
{'EXIT', R} =
(catch terminate(Reason, Name, Msg, Mod, NState, Debug)),
_ = reply(Name, From, Reply, NState, Debug),
@@ -624,39 +685,39 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) ->
handle_common_reply(Other, Parent, Name, Msg, Mod, State, Debug)
end;
handle_msg(Msg, Parent, Name, State, Mod, Debug) ->
- Reply = (catch dispatch(Msg, Mod, State)),
+ Reply = try_dispatch(Msg, Mod, State),
handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug).
handle_common_reply(Reply, Parent, Name, Msg, Mod, State) ->
case Reply of
- {noreply, NState} ->
+ {ok, {noreply, NState}} ->
loop(Parent, Name, NState, Mod, infinity, []);
- {noreply, NState, Time1} ->
+ {ok, {noreply, NState, Time1}} ->
loop(Parent, Name, NState, Mod, Time1, []);
- {stop, Reason, NState} ->
+ {ok, {stop, Reason, NState}} ->
terminate(Reason, Name, Msg, Mod, NState, []);
- {'EXIT', What} ->
- terminate(What, Name, Msg, Mod, State, []);
- _ ->
- terminate({bad_return_value, Reply}, Name, Msg, Mod, State, [])
+ {'EXIT', ExitReason, ReportReason} ->
+ terminate(ExitReason, ReportReason, Name, Msg, Mod, State, []);
+ {ok, BadReply} ->
+ terminate({bad_return_value, BadReply}, Name, Msg, Mod, State, [])
end.
handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) ->
case Reply of
- {noreply, NState} ->
+ {ok, {noreply, NState}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
loop(Parent, Name, NState, Mod, infinity, Debug1);
- {noreply, NState, Time1} ->
+ {ok, {noreply, NState, Time1}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
loop(Parent, Name, NState, Mod, Time1, Debug1);
- {stop, Reason, NState} ->
+ {ok, {stop, Reason, NState}} ->
terminate(Reason, Name, Msg, Mod, NState, Debug);
- {'EXIT', What} ->
- terminate(What, Name, Msg, Mod, State, Debug);
- _ ->
- terminate({bad_return_value, Reply}, Name, Msg, Mod, State, Debug)
+ {'EXIT', ExitReason, ReportReason} ->
+ terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug);
+ {ok, BadReply} ->
+ terminate({bad_return_value, BadReply}, Name, Msg, Mod, State, Debug)
end.
reply(Name, {To, Tag}, Reply, State, Debug) ->
@@ -717,13 +778,20 @@ print_event(Dev, Event, Name) ->
%%% Terminate the server.
%%% ---------------------------------------------------
+-spec terminate(_, _, _, _, _, _) -> no_return().
terminate(Reason, Name, Msg, Mod, State, Debug) ->
- case catch Mod:terminate(Reason, State) of
- {'EXIT', R} ->
- error_info(R, Name, Msg, State, Debug),
- exit(R);
+ terminate(Reason, Reason, Name, Msg, Mod, State, Debug).
+
+-spec terminate(_, _, _, _, _, _, _) -> no_return().
+terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug) ->
+ Reply = try_terminate(Mod, ExitReason, State),
+ case Reply of
+ {'EXIT', ExitReason1, ReportReason1} ->
+ FmtState = format_status(terminate, Mod, get(), State),
+ error_info(ReportReason1, Name, Msg, FmtState, Debug),
+ exit(ExitReason1);
_ ->
- case Reason of
+ case ExitReason of
normal ->
exit(normal);
shutdown ->
@@ -731,19 +799,9 @@ terminate(Reason, Name, Msg, Mod, State, Debug) ->
{shutdown,_}=Shutdown ->
exit(Shutdown);
_ ->
- FmtState =
- case erlang:function_exported(Mod, format_status, 2) of
- true ->
- Args = [get(), State],
- case catch Mod:format_status(terminate, Args) of
- {'EXIT', _} -> State;
- Else -> Else
- end;
- _ ->
- State
- end,
- error_info(Reason, Name, Msg, FmtState, Debug),
- exit(Reason)
+ FmtState = format_status(terminate, Mod, get(), State),
+ error_info(ReportReason, Name, Msg, FmtState, Debug),
+ exit(ExitReason)
end
end.
@@ -875,23 +933,29 @@ name_to_pid(Name) ->
%%-----------------------------------------------------------------
format_status(Opt, StatusData) ->
[PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData,
- Header = gen:format_status_header("Status for generic server",
- Name),
+ Header = gen:format_status_header("Status for generic server", Name),
Log = sys:get_debug(log, Debug, []),
- DefaultStatus = [{data, [{"State", State}]}],
- Specfic =
- case erlang:function_exported(Mod, format_status, 2) of
- true ->
- case catch Mod:format_status(Opt, [PDict, State]) of
- {'EXIT', _} -> DefaultStatus;
- StatusList when is_list(StatusList) -> StatusList;
- Else -> [Else]
- end;
- _ ->
- DefaultStatus
- end,
+ Specfic = case format_status(Opt, Mod, PDict, State) of
+ S when is_list(S) -> S;
+ S -> [S]
+ end,
[{header, Header},
{data, [{"Status", SysState},
{"Parent", Parent},
{"Logged events", Log}]} |
Specfic].
+
+format_status(Opt, Mod, PDict, State) ->
+ DefStatus = case Opt of
+ terminate -> State;
+ _ -> [{data, [{"State", State}]}]
+ end,
+ case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ case catch Mod:format_status(Opt, [PDict, State]) of
+ {'EXIT', _} -> DefStatus;
+ Else -> Else
+ end;
+ _ ->
+ DefStatus
+ end.
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index 27e2a82b41..b9ace2f442 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.erl
@@ -566,12 +566,23 @@ request(Name, Request) when is_atom(Name) ->
execute_request(Pid, {Convert,Converted}) ->
Mref = erlang:monitor(process, Pid),
- Pid ! {io_request,self(),Pid,Converted},
- if
- Convert ->
- convert_binaries(wait_io_mon_reply(Pid, Mref));
- true ->
- wait_io_mon_reply(Pid, Mref)
+ Pid ! {io_request,self(),Mref,Converted},
+
+ receive
+ {io_reply, Mref, Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ if
+ Convert ->
+ convert_binaries(Reply);
+ true ->
+ Reply
+ end;
+ {'DOWN', Mref, _, _, _} ->
+ receive
+ {'EXIT', Pid, _What} -> true
+ after 0 -> true
+ end,
+ {error,terminated}
end.
requests(Requests) -> %Requests as atomic action
@@ -597,26 +608,6 @@ default_input() ->
default_output() ->
group_leader().
-wait_io_mon_reply(From, Mref) ->
- receive
- {io_reply, From, Reply} ->
- erlang:demonitor(Mref, [flush]),
- Reply;
- {'EXIT', From, _What} ->
- receive
- {'DOWN', Mref, _, _, _} -> true
- after 0 -> true
- end,
- {error,terminated};
- {'DOWN', Mref, _, _, _} ->
- receive
- {'EXIT', From, _What} -> true
- after 0 -> true
- end,
- {error,terminated}
- end.
-
-
%% io_requests(Requests)
%% Transform requests into correct i/o server messages. Only handle the
%% one we KNOW must be changed, others, including incorrect ones, are
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..ba4d6a5c87 100644
--- a/lib/stdlib/src/maps.erl
+++ b/lib/stdlib/src/maps.erl
@@ -24,6 +24,7 @@
map/2,
size/1,
without/2,
+ with/2,
get/3
]).
@@ -133,10 +134,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).
@@ -201,3 +202,13 @@ size(Map) when is_map(Map) ->
without(Ks, M) when is_list(Ks), is_map(M) ->
maps:from_list([{K,V}||{K,V} <- maps:to_list(M), not lists:member(K, Ks)]).
+
+
+-spec with(Ks, Map1) -> Map2 when
+ Ks :: [K],
+ Map1 :: map(),
+ Map2 :: map(),
+ K :: term().
+
+with(Ks, M) when is_list(Ks), is_map(M) ->
+ maps:from_list([{K,V}||{K,V} <- maps:to_list(M), lists:member(K, Ks)]).
diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index 27dfcf52e1..97564e2e44 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -725,10 +725,10 @@ transform_head([V],OuterBound) ->
th(NewV,NewBind,OuterBound).
-toplevel_head_match({match,Line,{var,_,VName},Expr},B,OB) ->
+toplevel_head_match({match,_,{var,Line,VName},Expr},B,OB) ->
warn_var_clash(Line,VName,OB),
{Expr,new_bind({VName,'$_'},B)};
-toplevel_head_match({match,Line,Expr,{var,_,VName}},B,OB) ->
+toplevel_head_match({match,_,Expr,{var,Line,VName}},B,OB) ->
warn_var_clash(Line,VName,OB),
{Expr,new_bind({VName,'$_'},B)};
toplevel_head_match(Other,B,_OB) ->
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index c0ee8799c8..6c25beabe9 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -421,13 +421,13 @@ obsolete_1(ssh_cm, stop_listener, 1) ->
obsolete_1(ssh_cm, session_open, A) when A =:= 2; A =:= 4 ->
{removed,{ssh_connection,session_channel,A},"R14B"};
obsolete_1(ssh_cm, direct_tcpip, A) when A =:= 6; A =:= 8 ->
- {removed,{ssh_connection,direct_tcpip,A}};
+ {removed,{ssh_connection,direct_tcpip,A},"R14B"};
obsolete_1(ssh_cm, tcpip_forward, 3) ->
{removed,{ssh_connection,tcpip_forward,3},"R14B"};
obsolete_1(ssh_cm, cancel_tcpip_forward, 3) ->
{removed,{ssh_connection,cancel_tcpip_forward,3},"R14B"};
obsolete_1(ssh_cm, open_pty, A) when A =:= 3; A =:= 7; A =:= 9 ->
- {removed,{ssh_connection,open_pty,A},"R14"};
+ {removed,{ssh_connection,open_pty,A},"R14B"};
obsolete_1(ssh_cm, setenv, 5) ->
{removed,{ssh_connection,setenv,5},"R14B"};
obsolete_1(ssh_cm, shell, 2) ->
@@ -441,11 +441,11 @@ obsolete_1(ssh_cm, winch, A) when A =:= 4; A =:= 6 ->
obsolete_1(ssh_cm, signal, 3) ->
{removed,{ssh_connection,signal,3},"R14B"};
obsolete_1(ssh_cm, attach, A) when A =:= 2; A =:= 3 ->
- {removed,{ssh,attach,A}};
+ {removed,"no longer useful; removed in R14B"};
obsolete_1(ssh_cm, detach, 2) ->
- {removed,"no longer useful; will be removed in R14B"};
+ {removed,"no longer useful; removed in R14B"};
obsolete_1(ssh_cm, set_user_ack, 4) ->
- {removed,"no longer useful; will be removed in R14B"};
+ {removed,"no longer useful; removed in R14B"};
obsolete_1(ssh_cm, adjust_window, 3) ->
{removed,{ssh_connection,adjust_window,3},"R14B"};
obsolete_1(ssh_cm, close, 2) ->
@@ -461,9 +461,9 @@ obsolete_1(ssh_cm, send_ack, A) when 3 =< A, A =< 5 ->
obsolete_1(ssh_ssh, connect, A) when 1 =< A, A =< 3 ->
{removed,{ssh,shell,A},"R14B"};
obsolete_1(ssh_sshd, listen, A) when 0 =< A, A =< 3 ->
- {removed,{ssh,daemon,[1,2,3]},"R14"};
+ {removed,{ssh,daemon,[1,2,3]},"R14B"};
obsolete_1(ssh_sshd, stop, 1) ->
- {removed,{ssh,stop_listener,1}};
+ {removed,{ssh,stop_listener,1},"R14B"};
%% Added in R13A.
obsolete_1(regexp, _, _) ->
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 1eb6fc2e86..bf2a4e7ac5 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -216,10 +216,8 @@ ensure_link(SpawnOpts) ->
init_p(Parent, Ancestors, Fun) when is_function(Fun) ->
put('$ancestors', [Parent|Ancestors]),
- {module,Mod} = erlang:fun_info(Fun, module),
- {name,Name} = erlang:fun_info(Fun, name),
- {arity,Arity} = erlang:fun_info(Fun, arity),
- put('$initial_call', {Mod,Name,Arity}),
+ Mfa = erlang:fun_info_mfa(Fun),
+ put('$initial_call', Mfa),
try
Fun()
catch
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..aa9899da3b 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.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..7802ea884f 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-2](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3
+ {<<"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-2](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3
+ {<<"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..3b08ac165e 100644
--- a/lib/stdlib/test/dets_SUITE.erl
+++ b/lib/stdlib/test/dets_SUITE.erl
@@ -223,8 +223,7 @@ open(Config, Version) ->
?format("Crashing dets server \n", []),
process_flag(trap_exit, true),
- Procs = [whereis(?DETS_SERVER) | map(fun(Tab) -> dets:info(Tab, pid) end,
- Tabs)],
+ Procs = [whereis(?DETS_SERVER) | [dets:info(Tab, pid) || Tab <- Tabs]],
foreach(fun(Pid) -> exit(Pid, kill) end, Procs),
timer:sleep(100),
c:flush(), %% flush all the EXIT sigs
@@ -235,18 +234,32 @@ open(Config, Version) ->
open_files(1, All, Version),
?format("Checking contents of repaired files \n", []),
check(Tabs, Data),
-
- close_all(Tabs),
+ close_all(Tabs),
delete_files(All),
- P1 = pps(),
+
{Ports0, Procs0} = P0,
- {Ports1, Procs1} = P1,
- true = Ports1 =:= Ports0,
- %% The dets_server process has been restarted:
- [_] = Procs0 -- Procs1,
- [_] = Procs1 -- Procs0,
- ok.
+ Test = fun() ->
+ P1 = pps(),
+ {Ports1, Procs1} = P1,
+ show("Old port", Ports0 -- Ports1),
+ show("New port", Ports1 -- Ports0),
+ show("Old procs", Procs0 -- Procs1),
+ show("New procs", Procs1 -- Procs0),
+ io:format("Remaining Dets-pids (should be nil): ~p~n",
+ [find_dets_pids()]),
+ true = Ports1 =:= Ports0,
+ %% The dets_server process has been restarted:
+ [_] = Procs0 -- Procs1,
+ [_] = Procs1 -- Procs0,
+ ok
+ end,
+ case catch Test() of
+ ok -> ok;
+ _ ->
+ timer:sleep(500),
+ ok = Test()
+ end.
check(Tabs, Data) ->
foreach(fun(Tab) ->
@@ -2032,6 +2045,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 ->
@@ -3269,12 +3288,22 @@ simultaneous_open(Config) ->
File = filename(Tab, Config),
ok = monit(Tab, File),
- ok = kill_while_repairing(Tab, File),
- ok = kill_while_init(Tab, File),
- ok = open_ro(Tab, File),
- ok = open_w(Tab, File, 0, Config),
- ok = open_w(Tab, File, 100, Config),
- ok.
+ case feasible() of
+ false -> {comment, "OK, but did not run all of the test"};
+ true ->
+ ok = kill_while_repairing(Tab, File),
+ ok = kill_while_init(Tab, File),
+ ok = open_ro(Tab, File),
+ ok = open_w(Tab, File, 0, Config),
+ ok = open_w(Tab, File, 100, Config)
+ end.
+
+feasible() ->
+ LP = erlang:system_info(logical_processors),
+ (is_integer(LP)
+ andalso LP >= erlang:system_info(schedulers_online)
+ andalso not erlang:system_info(debug_compiled)
+ andalso not erlang:system_info(lock_checking)).
%% One process logs and another process closes the log. Before
%% monitors were used, this would make the client never return.
@@ -3301,7 +3330,6 @@ kill_while_repairing(Tab, File) ->
Delay = 1000,
dets:start(),
Parent = self(),
- Ps = processes(),
F = fun() ->
R = (catch dets:open_file(Tab, [{file,File}])),
timer:sleep(Delay),
@@ -3312,7 +3340,7 @@ kill_while_repairing(Tab, File) ->
P1 = spawn(F),
P2 = spawn(F),
P3 = spawn(F),
- DetsPid = find_dets_pid([P1, P2, P3 | Ps]),
+ DetsPid = find_dets_pid(),
exit(DetsPid, kill),
receive {P1,R1} -> R1 end,
@@ -3336,12 +3364,6 @@ kill_while_repairing(Tab, File) ->
file:delete(File),
ok.
-find_dets_pid(P0) ->
- case lists:sort(processes() -- P0) of
- [P, _] -> P;
- _ -> timer:sleep(100), find_dets_pid(P0)
- end.
-
find_dets_pid() ->
case find_dets_pids() of
[] ->
@@ -3415,6 +3437,13 @@ open_ro(Tab, File) ->
open_w(Tab, File, Delay, Config) ->
create_opened_log(File),
+
+ Tab2 = t2,
+ File2 = filename(Tab2, Config),
+ file:delete(File2),
+ {ok,Tab2} = dets:open_file(Tab2, [{file,File2}]),
+ ok = dets:close(Tab2),
+
Parent = self(),
F = fun() ->
R = dets:open_file(Tab, [{file,File}]),
@@ -3424,16 +3453,16 @@ open_w(Tab, File, Delay, Config) ->
Pid1 = spawn(F),
Pid2 = spawn(F),
Pid3 = spawn(F),
- undefined = dets:info(Tab), % is repairing now
- 0 = qlen(),
- Tab2 = t2,
- File2 = filename(Tab2, Config),
- file:delete(File2),
+ ok = wait_for_repair_to_start(Tab),
+
+ %% It is assumed that it takes some time to repair the file.
{ok,Tab2} = dets:open_file(Tab2, [{file,File2}]),
+ %% The Dets server managed to handle to open_file request.
+ 0 = qlen(), % still repairing
+
ok = dets:close(Tab2),
file:delete(File2),
- 0 = qlen(), % still repairing
receive {Pid1,R1} -> {ok, Tab} = R1 end,
receive {Pid2,R2} -> {ok, Tab} = R2 end,
@@ -3450,6 +3479,15 @@ open_w(Tab, File, Delay, Config) ->
file:delete(File),
ok.
+wait_for_repair_to_start(Tab) ->
+ case catch dets_server:get_pid(Tab) of
+ {'EXIT', _} ->
+ timer:sleep(1),
+ wait_for_repair_to_start(Tab);
+ Pid when is_pid(Pid) ->
+ ok
+ end.
+
qlen() ->
{_, {_, N}} = lists:keysearch(message_queue_len, 1, process_info(self())),
N.
@@ -4344,6 +4382,7 @@ check_badarg({'EXIT', {badarg, [{M,F,A,_} | _]}}, M, F, Args) ->
true = test_server:is_native(M) andalso length(Args) =:= A.
check_pps({Ports0,Procs0} = P0) ->
+ ok = check_dets_tables(),
case pps() of
P0 ->
ok;
@@ -4369,13 +4408,45 @@ check_pps({Ports0,Procs0} = P0) ->
end
end.
+%% Copied from dets_server.erl:
+-define(REGISTRY, dets_registry).
+-define(OWNERS, dets_owners).
+-define(STORE, dets).
+
+check_dets_tables() ->
+ Store = [T ||
+ T <- ets:all(),
+ ets:info(T, name) =:= ?STORE,
+ owner(T) =:= dets],
+ S = case Store of
+ [Tab] -> ets:tab2list(Tab);
+ [] -> []
+ end,
+ case {ets:tab2list(?REGISTRY), ets:tab2list(?OWNERS), S} of
+ {[], [], []} -> ok;
+ {R, O, _} ->
+ io:format("Registry: ~p~n", [R]),
+ io:format("Owners: ~p~n", [O]),
+ io:format("Store: ~p~n", [S]),
+ not_ok
+ end.
+
+owner(Tab) ->
+ Owner = ets:info(Tab, owner),
+ case process_info(Owner, registered_name) of
+ {registered_name, Name} -> Name;
+ _ -> Owner
+ end.
+
show(_S, []) ->
ok;
-show(S, [Pid|Pids]) when is_pid(Pid) ->
- io:format("~s: ~p~n", [S, erlang:process_info(Pid)]),
+show(S, [{Pid, Name, InitCall}|Pids]) when is_pid(Pid) ->
+ io:format("~s: ~w (~w), ~w: ~p~n",
+ [S, Pid, proc_reg_name(Name), InitCall,
+ erlang:process_info(Pid)]),
show(S, Pids);
-show(S, [Port|Ports]) when is_port(Port)->
- io:format("~s: ~p~n", [S, erlang:port_info(Port)]),
+show(S, [{Port, _}|Ports]) when is_port(Port)->
+ io:format("~s: ~w: ~p~n", [S, Port, erlang:port_info(Port)]),
show(S, Ports).
pps() ->
@@ -4391,5 +4462,8 @@ process_list() ->
safe_second_element(process_info(P, initial_call))} ||
P <- processes()].
+proc_reg_name({registered_name, Name}) -> Name;
+proc_reg_name([]) -> no_reg_name.
+
safe_second_element({_,Info}) -> Info;
safe_second_element(Other) -> Other.
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index babf3a49eb..927fe0b595 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -604,20 +604,20 @@ import_export(Config) when is_list(Config) ->
misc_attrs(suite) ->
[];
misc_attrs(Config) when is_list(Config) ->
- ?line ok = pp_forms(<<"-module(m). ">>),
- ?line ok = pp_forms(<<"-module(m, [Aafjlksfjdlsjflsdfjlsdjflkdsfjlk,"
- "Blsjfdlslfjsdf]). ">>),
- ?line ok = pp_forms(<<"-export([]). ">>),
- ?line ok = pp_forms(<<"-export([foo/2, bar/0]). ">>),
- ?line ok = pp_forms(<<"-export([bar/0]). ">>),
- ?line ok = pp_forms(<<"-import(lists, []). ">>),
- ?line ok = pp_forms(<<"-import(lists, [map/2]). ">>),
- ?line ok = pp_forms(<<"-import(lists, [map/2, foreach/2]). ">>),
- ?line ok = pp_forms(<<"-'wild '({attr2,3}). ">>),
- ?line ok = pp_forms(<<"-record(a, {b,c}). ">>),
- ?line ok = pp_forms(<<"-record(' a ', {}). ">>),
- ?line ok = pp_forms(<<"-record(' a ', {foo = foo:bar()}). ">>),
-
+ ok = pp_forms(<<"-module(m). ">>),
+ ok = pp_forms(<<"-module(m, [Aafjlksfjdlsjflsdfjlsdjflkdsfjlk,"
+ "Blsjfdlslfjsdf]). ">>),
+ ok = pp_forms(<<"-export([]). ">>),
+ ok = pp_forms(<<"-export([foo/2, bar/0]). ">>),
+ ok = pp_forms(<<"-export([bar/0]). ">>),
+ ok = pp_forms(<<"-import(lists, []). ">>),
+ ok = pp_forms(<<"-import(lists, [map/2]). ">>),
+ ok = pp_forms(<<"-import(lists, [map/2, foreach/2]). ">>),
+ ok = pp_forms(<<"-'wild '({attr2,3}). ">>),
+ ok = pp_forms(<<"-record(a, {b,c}). ">>),
+ ok = pp_forms(<<"-record(' a ', {}). ">>),
+ ok = pp_forms(<<"-record(' a ', {foo = foo:bar()}). ">>),
+ ok = pp_forms(<<"-custom1(#{test1 => init/2, test2 => [val/1, val/2]}). ">>),
ok.
dialyzer_attrs(suite) ->
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index 35067e8116..9be9f641c8 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -204,20 +204,20 @@ reserved_words() ->
[begin
?line {RW, true} = {RW, erl_scan:reserved_word(RW)},
S = atom_to_list(RW),
- Ts = [{RW,1}],
+ Ts = [{RW,{1,1}}],
?line test_string(S, Ts)
end || RW <- L],
ok.
atoms() ->
- ?line test_string("a
- b", [{atom,1,a},{atom,2,b}]),
- ?line test_string("'a b'", [{atom,1,'a b'}]),
- ?line test_string("a", [{atom,1,a}]),
- ?line test_string("a@2", [{atom,1,a@2}]),
- ?line test_string([39,65,200,39], [{atom,1,'AÈ'}]),
- ?line test_string("ärlig östen", [{atom,1,ärlig},{atom,1,östen}]),
+ test_string("a
+ b", [{atom,{1,1},a},{atom,{2,18},b}]),
+ test_string("'a b'", [{atom,{1,1},'a b'}]),
+ test_string("a", [{atom,{1,1},a}]),
+ test_string("a@2", [{atom,{1,1},a@2}]),
+ test_string([39,65,200,39], [{atom,{1,1},'AÈ'}]),
+ test_string("ärlig östen", [{atom,{1,1},ärlig},{atom,{1,7},östen}]),
?line {ok,[{atom,_,'$a'}],{1,6}} =
erl_scan:string("'$\\a'", {1,1}),
?line test("'$\\a'"),
@@ -230,7 +230,7 @@ punctuations() ->
%% One token at a time:
[begin
W = list_to_atom(S),
- Ts = [{W,1}],
+ Ts = [{W,{1,1}}],
?line test_string(S, Ts)
end || S <- L],
Three = ["/=:=", "<=:=", "==:=", ">=:="], % three tokens...
@@ -246,53 +246,60 @@ punctuations() ->
[begin
W1 = list_to_atom(S1),
W2 = list_to_atom(S2),
- Ts = [{W1,1},{W2,1}],
+ Ts = [{W1,{1,1}},{W2,{1,-L2+1}}],
?line test_string(S, Ts)
- end || {S,[{_,S1,S2}|_]} <- SL],
+ end || {S,[{L2,S1,S2}|_]} <- SL],
- PTs1 = [{'!',1},{'(',1},{')',1},{',',1},{';',1},{'=',1},{'[',1},
- {']',1},{'{',1},{'|',1},{'}',1}],
+ PTs1 = [{'!',{1,1}},{'(',{1,2}},{')',{1,3}},{',',{1,4}},{';',{1,5}},
+ {'=',{1,6}},{'[',{1,7}},{']',{1,8}},{'{',{1,9}},{'|',{1,10}},
+ {'}',{1,11}}],
?line test_string("!(),;=[]{|}", PTs1),
- PTs2 = [{'#',1},{'&',1},{'*',1},{'+',1},{'/',1},
- {':',1},{'<',1},{'>',1},{'?',1},{'@',1},
- {'\\',1},{'^',1},{'`',1},{'~',1}],
+ PTs2 = [{'#',{1,1}},{'&',{1,2}},{'*',{1,3}},{'+',{1,4}},{'/',{1,5}},
+ {':',{1,6}},{'<',{1,7}},{'>',{1,8}},{'?',{1,9}},{'@',{1,10}},
+ {'\\',{1,11}},{'^',{1,12}},{'`',{1,13}},{'~',{1,14}}],
?line test_string("#&*+/:<>?@\\^`~", PTs2),
- ?line test_string(".. ", [{'..',1}]),
- ?line test("1 .. 2"),
- ?line test_string("...", [{'...',1}]),
+ test_string(".. ", [{'..',{1,1}}]),
+ test_string("1 .. 2",
+ [{integer,{1,1},1},{'..',{1,3}},{integer,{1,6},2}]),
+ test_string("...", [{'...',{1,1}}]),
ok.
comments() ->
?line test("a %%\n b"),
?line {ok,[],1} = erl_scan:string("%"),
?line test("a %%\n b"),
- ?line {ok,[{atom,_,a},{atom,_,b}],{2,3}} =
+ {ok,[{atom,{1,1},a},{atom,{2,2},b}],{2,3}} =
erl_scan:string("a %%\n b",{1,1}),
- ?line {ok,[{atom,_,a},{comment,_,"%%"},{atom,_,b}],{2,3}} =
+ {ok,[{atom,{1,1},a},{comment,{1,3},"%%"},{atom,{2,2},b}],{2,3}} =
erl_scan:string("a %%\n b",{1,1}, [return_comments]),
- ?line {ok,[{atom,_,a},
- {white_space,_," "},
- {white_space,_,"\n "},
- {atom,_,b}],
- {2,3}} =
+ {ok,[{atom,{1,1},a},
+ {white_space,{1,2}," "},
+ {white_space,{1,5},"\n "},
+ {atom,{2,2},b}],
+ {2,3}} =
erl_scan:string("a %%\n b",{1,1},[return_white_spaces]),
- ?line {ok,[{atom,_,a},
- {white_space,_," "},
- {comment,_,"%%"},
- {white_space,_,"\n "},
- {atom,_,b}],
- {2,3}} = erl_scan:string("a %%\n b",{1,1},[return]),
+ {ok,[{atom,{1,1},a},
+ {white_space,{1,2}," "},
+ {comment,{1,3},"%%"},
+ {white_space,{1,5},"\n "},
+ {atom,{2,2},b}],
+ {2,3}} = erl_scan:string("a %%\n b",{1,1},[return]),
ok.
errors() ->
?line {error,{1,erl_scan,{string,$',"qa"}},1} = erl_scan:string("'qa"), %'
+ {error,{{1,1},erl_scan,{string,$',"qa"}},{1,4}} = %'
+ erl_scan:string("'qa", {1,1}, []), %'
?line {error,{1,erl_scan,{string,$","str"}},1} = %"
erl_scan:string("\"str"), %"
+ {error,{{1,1},erl_scan,{string,$","str"}},{1,5}} = %"
+ erl_scan:string("\"str", {1,1}, []), %"
?line {error,{1,erl_scan,char},1} = erl_scan:string("$"),
- ?line test_string([34,65,200,34], [{string,1,"AÈ"}]),
- ?line test_string("\\", [{'\\',1}]),
+ {error,{{1,1},erl_scan,char},{1,2}} = erl_scan:string("$", {1,1}, []),
+ test_string([34,65,200,34], [{string,{1,1},"AÈ"}]),
+ test_string("\\", [{'\\',{1,1}}]),
?line {'EXIT',_} =
(catch {foo, erl_scan:string('$\\a', {1,1})}), % type error
?line {'EXIT',_} =
@@ -304,7 +311,7 @@ errors() ->
integers() ->
[begin
I = list_to_integer(S),
- Ts = [{integer,1,I}],
+ Ts = [{integer,{1,1},I}],
?line test_string(S, Ts)
end || S <- [[N] || N <- lists:seq($0, $9)] ++ ["2323","000"] ],
ok.
@@ -313,14 +320,16 @@ base_integers() ->
[begin
B = list_to_integer(BS),
I = erlang:list_to_integer(S, B),
- Ts = [{integer,1,I}],
+ Ts = [{integer,{1,1},I}],
?line test_string(BS++"#"++S, Ts)
end || {BS,S} <- [{"2","11"}, {"5","23234"}, {"12","05a"},
{"16","abcdef"}, {"16","ABCDEF"}] ],
?line {error,{1,erl_scan,{base,1}},1} = erl_scan:string("1#000"),
+ {error,{{1,1},erl_scan,{base,1}},{1,2}} =
+ erl_scan:string("1#000", {1,1}, []),
- ?line test_string("12#bc", [{integer,1,11},{atom,1,c}]),
+ test_string("12#bc", [{integer,{1,1},11},{atom,{1,5},c}]),
[begin
Str = BS ++ "#" ++ S,
@@ -329,40 +338,53 @@ base_integers() ->
end || {BS,S} <- [{"3","3"},{"15","f"}, {"12","c"}] ],
?line {ok,[{integer,1,239},{'@',1}],1} = erl_scan:string("16#ef@"),
- ?line {ok,[{integer,1,14},{atom,1,g@}],1} = erl_scan:string("16#eg@"),
+ {ok,[{integer,{1,1},239},{'@',{1,6}}],{1,7}} =
+ erl_scan:string("16#ef@", {1,1}, []),
+ {ok,[{integer,{1,1},14},{atom,{1,5},g@}],{1,7}} =
+ erl_scan:string("16#eg@", {1,1}, []),
ok.
floats() ->
[begin
F = list_to_float(FS),
- Ts = [{float,1,F}],
+ Ts = [{float,{1,1},F}],
?line test_string(FS, Ts)
end || FS <- ["1.0","001.17","3.31200","1.0e0","1.0E17",
"34.21E-18", "17.0E+14"]],
- ?line test_string("1.e2", [{integer,1,1},{'.',1},{atom,1,e2}]),
+ test_string("1.e2", [{integer,{1,1},1},{'.',{1,2}},{atom,{1,3},e2}]),
?line {error,{1,erl_scan,{illegal,float}},1} =
erl_scan:string("1.0e400"),
+ {error,{{1,1},erl_scan,{illegal,float}},{1,8}} =
+ erl_scan:string("1.0e400", {1,1}, []),
[begin
- ?line {error,{1,erl_scan,{illegal,float}},1} = erl_scan:string(S)
+ {error,{1,erl_scan,{illegal,float}},1} = erl_scan:string(S),
+ {error,{{1,1},erl_scan,{illegal,float}},{1,_}} =
+ erl_scan:string(S, {1,1}, [])
end || S <- ["1.14Ea"]],
ok.
dots() ->
- Dot = [{".", {ok,[{dot,1}],1}},
- {". ", {ok,[{dot,1}],1}},
- {".\n", {ok,[{dot,1}],2}},
- {".%", {ok,[{dot,1}],1}},
- {".\210",{ok,[{dot,1}],1}},
- {".% öh",{ok,[{dot,1}],1}},
- {".%\n", {ok,[{dot,1}],2}},
- {".$", {error,{1,erl_scan,char},1}},
- {".$\\", {error,{1,erl_scan,char},1}},
- {".a", {ok,[{'.',1},{atom,1,a}],1}}
+ Dot = [{".", {ok,[{dot,1}],1}, {ok,[{dot,{1,1}}],{1,2}}},
+ {". ", {ok,[{dot,1}],1}, {ok,[{dot,{1,1}}],{1,3}}},
+ {".\n", {ok,[{dot,1}],2}, {ok,[{dot,{1,1}}],{2,1}}},
+ {".%", {ok,[{dot,1}],1}, {ok,[{dot,{1,1}}],{1,3}}},
+ {".\210",{ok,[{dot,1}],1}, {ok,[{dot,{1,1}}],{1,3}}},
+ {".% öh",{ok,[{dot,1}],1}, {ok,[{dot,{1,1}}],{1,6}}},
+ {".%\n", {ok,[{dot,1}],2}, {ok,[{dot,{1,1}}],{2,1}}},
+ {".$", {error,{1,erl_scan,char},1},
+ {error,{{1,2},erl_scan,char},{1,3}}},
+ {".$\\", {error,{1,erl_scan,char},1},
+ {error,{{1,2},erl_scan,char},{1,4}}},
+ {".a", {ok,[{'.',1},{atom,1,a}],1},
+ {ok,[{'.',{1,1}},{atom,{1,2},a}],{1,3}}}
],
- ?line [R = erl_scan:string(S) || {S, R} <- Dot],
+ [begin
+ R = erl_scan:string(S),
+ R2 = erl_scan:string(S, {1,1}, [])
+ end || {S, R, R2} <- Dot],
?line {ok,[{dot,_}=T1],{1,2}} = erl_scan:string(".", {1,1}, text),
?line [{column,1},{length,1},{line,1},{text,"."}] =
@@ -379,55 +401,55 @@ dots() ->
?line {error,{{1,2},erl_scan,char},{1,4}} =
erl_scan:string(".$\\", {1,1}),
- ?line test(". "),
- ?line test(". "),
- ?line test(".\n"),
- ?line test(".\n\n"),
- ?line test(".\n\r"),
- ?line test(".\n\n\n"),
- ?line test(".\210"),
- ?line test(".%\n"),
- ?line test(".a"),
-
- ?line test("%. \n. "),
+ test_string(". ", [{dot,{1,1}}]),
+ test_string(". ", [{dot,{1,1}}]),
+ test_string(".\n", [{dot,{1,1}}]),
+ test_string(".\n\n", [{dot,{1,1}}]),
+ test_string(".\n\r", [{dot,{1,1}}]),
+ test_string(".\n\n\n", [{dot,{1,1}}]),
+ test_string(".\210", [{dot,{1,1}}]),
+ test_string(".%\n", [{dot,{1,1}}]),
+ test_string(".a", [{'.',{1,1}},{atom,{1,2},a}]),
+
+ test_string("%. \n. ", [{dot,{2,1}}]),
?line {more,C} = erl_scan:tokens([], "%. ",{1,1}, return),
- ?line {done,{ok,[{comment,_,"%. "},
- {white_space,_,"\n"},
- {dot,_}],
- {2,3}}, ""} =
+ {done,{ok,[{comment,{1,1},"%. "},
+ {white_space,{1,4},"\n"},
+ {dot,{2,1}}],
+ {2,3}}, ""} =
erl_scan:tokens(C, "\n. ", {1,1}, return), % any loc, any options
?line [test_string(S, R) ||
- {S, R} <- [{".$\n", [{'.',1},{char,1,$\n}]},
- {"$\\\n", [{char,1,$\n}]},
- {"'\\\n'", [{atom,1,'\n'}]},
- {"$\n", [{char,1,$\n}]}] ],
+ {S, R} <- [{".$\n", [{'.',{1,1}},{char,{1,2},$\n}]},
+ {"$\\\n", [{char,{1,1},$\n}]},
+ {"'\\\n'", [{atom,{1,1},'\n'}]},
+ {"$\n", [{char,{1,1},$\n}]}] ],
ok.
chars() ->
[begin
L = lists:flatten(io_lib:format("$\\~.8b", [C])),
- Ts = [{char,1,C}],
+ Ts = [{char,{1,1},C}],
?line test_string(L, Ts)
end || C <- lists:seq(0, 255)],
%% Leading zeroes...
[begin
L = lists:flatten(io_lib:format("$\\~3.8.0b", [C])),
- Ts = [{char,1,C}],
+ Ts = [{char,{1,1},C}],
?line test_string(L, Ts)
end || C <- lists:seq(0, 255)],
%% $\^\n now increments the line...
[begin
L = "$\\^" ++ [C],
- Ts = [{char,1,C band 2#11111}],
+ Ts = [{char,{1,1},C band 2#11111}],
?line test_string(L, Ts)
end || C <- lists:seq(0, 255)],
[begin
L = "$\\" ++ [C],
- Ts = [{char,1,V}],
+ Ts = [{char,{1,1},V}],
?line test_string(L, Ts)
end || {C,V} <- [{$n,$\n}, {$r,$\r}, {$t,$\t}, {$v,$\v},
{$b,$\b}, {$f,$\f}, {$e,$\e}, {$s,$\s},
@@ -440,45 +462,45 @@ chars() ->
No = EC ++ Ds ++ X ++ New,
[begin
L = "$\\" ++ [C],
- Ts = [{char,1,C}],
+ Ts = [{char,{1,1},C}],
?line test_string(L, Ts)
end || C <- lists:seq(0, 255) -- No],
[begin
L = "'$\\" ++ [C] ++ "'",
- Ts = [{atom,1,list_to_atom("$"++[C])}],
+ Ts = [{atom,{1,1},list_to_atom("$"++[C])}],
?line test_string(L, Ts)
end || C <- lists:seq(0, 255) -- No],
- ?line test_string("\"\\013a\\\n\"", [{string,1,"\va\n"}]),
+ test_string("\"\\013a\\\n\"", [{string,{1,1},"\va\n"}]),
- ?line test_string("'\n'", [{atom,1,'\n'}]),
- ?line test_string("\"\n\a\"", [{string,1,"\na"}]),
+ test_string("'\n'", [{atom,{1,1},'\n'}]),
+ test_string("\"\n\a\"", [{string,{1,1},"\na"}]),
%% No escape
[begin
L = "$" ++ [C],
- Ts = [{char,1,C}],
+ Ts = [{char,{1,1},C}],
?line test_string(L, Ts)
end || C <- lists:seq(0, 255) -- (No ++ [$\\])],
- ?line test_string("$\n", [{char,1,$\n}]),
+ test_string("$\n", [{char,{1,1},$\n}]),
?line {error,{{1,1},erl_scan,char},{1,4}} =
erl_scan:string("$\\^",{1,1}),
- ?line test_string("$\\\n", [{char,1,$\n}]),
+ test_string("$\\\n", [{char,{1,1},$\n}]),
%% Robert's scanner returns line 1:
- ?line test_string("$\\\n", [{char,1,$\n}]),
- ?line test_string("$\n\n", [{char,1,$\n}]),
+ test_string("$\\\n", [{char,{1,1},$\n}]),
+ test_string("$\n\n", [{char,{1,1},$\n}]),
?line test("$\n\n"),
ok.
variables() ->
- ?line test_string(" \237_Aouåeiyäö", [{var,1,'_Aouåeiyäö'}]),
- ?line test_string("A_b_c@", [{var,1,'A_b_c@'}]),
- ?line test_string("V@2", [{var,1,'V@2'}]),
- ?line test_string("ABDÀ", [{var,1,'ABDÀ'}]),
- ?line test_string("Ärlig Östen", [{var,1,'Ärlig'},{var,1,'Östen'}]),
+ test_string(" \237_Aouåeiyäö", [{var,{1,7},'_Aouåeiyäö'}]),
+ test_string("A_b_c@", [{var,{1,1},'A_b_c@'}]),
+ test_string("V@2", [{var,{1,1},'V@2'}]),
+ test_string("ABDÀ", [{var,{1,1},'ABDÀ'}]),
+ test_string("Ärlig Östen", [{var,{1,1},'Ärlig'},{var,{1,7},'Östen'}]),
ok.
eof() ->
@@ -508,11 +530,25 @@ eof() ->
?line {done,{ok,[{atom,1,a}],1},eof} =
erl_scan:tokens(C5,eof,1),
+ %% With column.
+ {more, C6} = erl_scan:tokens([], "a", {1,1}),
+ %% An error before R13A.
+ %% {done,{error,{1,erl_scan,scan},1},eof} =
+ {done,{ok,[{atom,{1,1},a}],{1,2}},eof} =
+ erl_scan:tokens(C6,eof,1),
+
%% A dot followed by eof is special:
?line {more, C} = erl_scan:tokens([], "a.", 1),
?line {done,{ok,[{atom,1,a},{dot,1}],1},eof} = erl_scan:tokens(C,eof,1),
?line {ok,[{atom,1,foo},{dot,1}],1} = erl_scan:string("foo."),
+ %% With column.
+ {more, CCol} = erl_scan:tokens([], "a.", {1,1}),
+ {done,{ok,[{atom,{1,1},a},{dot,{1,2}}],{1,3}},eof} =
+ erl_scan:tokens(CCol,eof,1),
+ {ok,[{atom,{1,1},foo},{dot,{1,4}}],{1,5}} =
+ erl_scan:string("foo.", {1,1}, []),
+
ok.
illegal() ->
@@ -816,34 +852,34 @@ unicode() ->
erl_scan:string([1089]),
?line {error,{{1,1},erl_scan,{illegal,character}},{1,2}} =
erl_scan:string([1089], {1,1}),
- ?line {error,{1,erl_scan,{illegal,atom}},1} =
+ {error,{1,erl_scan,{illegal,atom}},1} =
erl_scan:string("'a"++[1089]++"b'", 1),
- ?line {error,{{1,1},erl_scan,{illegal,atom}},{1,6}} =
+ {error,{{1,1},erl_scan,{illegal,atom}},{1,6}} =
erl_scan:string("'a"++[1089]++"b'", {1,1}),
?line test("\"a"++[1089]++"b\""),
- ?line {ok,[{char,1,1}],1} =
+ {ok,[{char,1,1}],1} =
erl_scan:string([$$,$\\,$^,1089], 1),
- ?line {error,{1,erl_scan,Error},1} =
+ {error,{1,erl_scan,Error},1} =
erl_scan:string("\"qa\x{aaa}", 1),
- ?line "unterminated string starting with \"qa"++[2730]++"\"" =
+ "unterminated string starting with \"qa"++[2730]++"\"" =
erl_scan:format_error(Error),
?line {error,{{1,1},erl_scan,_},{1,11}} =
erl_scan:string("\"qa\\x{aaa}",{1,1}),
- ?line {error,{{1,1},erl_scan,{illegal,atom}},{1,12}} =
+ {error,{{1,1},erl_scan,{illegal,atom}},{1,12}} =
erl_scan:string("'qa\\x{aaa}'",{1,1}),
- ?line {ok,[{char,1,1089}],1} =
+ {ok,[{char,1,1089}],1} =
erl_scan:string([$$,1089], 1),
- ?line {ok,[{char,1,1089}],1} =
+ {ok,[{char,1,1089}],1} =
erl_scan:string([$$,$\\,1089], 1),
Qs = "$\\x{aaa}",
- ?line {ok,[{char,1,$\x{aaa}}],1} =
+ {ok,[{char,1,$\x{aaa}}],1} =
erl_scan:string(Qs, 1),
- ?line {ok,[Q2],{1,9}} =
+ {ok,[Q2],{1,9}} =
erl_scan:string("$\\x{aaa}", {1,1}, [text]),
- ?line [{category,char},{column,1},{length,8},
+ [{category,char},{column,1},{length,8},
{line,1},{symbol,16#aaa},{text,Qs}] =
erl_scan:token_info(Q2),
@@ -1164,7 +1200,13 @@ otp_11807(Config) when is_list(Config) ->
(catch erl_parse:abstract("string", [{encoding,bad}])),
ok.
-test_string(String, Expected) ->
+test_string(String, ExpectedWithCol) ->
+ {ok, ExpectedWithCol, _EndWithCol} = erl_scan:string(String, {1, 1}, []),
+ Expected = [ begin
+ {L,_C} = element(2, T),
+ setelement(2, T, L)
+ end
+ || T <- ExpectedWithCol ],
{ok, Expected, _End} = erl_scan:string(String),
test(String).
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index 8203a03a7a..bd313390b3 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() ->
[].
@@ -86,6 +88,7 @@ wildcard_two(Config) when is_list(Config) ->
?line ok = file:make_dir(Dir),
?line do_wildcard_1(Dir, fun(Wc) -> io:format("~p~n",[{Wc,Dir, X = filelib:wildcard(Wc, Dir)}]),X end),
?line do_wildcard_1(Dir, fun(Wc) -> filelib:wildcard(Wc, Dir++"/") end),
+ ?line do_wildcard_1(Dir, fun(Wc) -> filelib:wildcard(Wc, Dir++"/.") end),
case os:type() of
{win32,_} ->
ok;
@@ -367,9 +370,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 +409,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 +428,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 +448,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/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index 8aeec07ae8..39f0442824 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_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
@@ -31,7 +31,9 @@
-export([shutdown/1]).
--export([ sys1/1, call_format_status/1, error_format_status/1, get_state/1, replace_state/1]).
+-export([ sys1/1,
+ call_format_status/1, error_format_status/1, terminate_crash_format/1,
+ get_state/1, replace_state/1]).
-export([hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]).
@@ -66,7 +68,8 @@ groups() ->
start8, start9, start10, start11, start12]},
{abnormal, [], [abnormal1, abnormal2]},
{sys, [],
- [sys1, call_format_status, error_format_status, get_state, replace_state]}].
+ [sys1, call_format_status, error_format_status, terminate_crash_format,
+ get_state, replace_state]}].
init_per_suite(Config) ->
Config.
@@ -403,7 +406,7 @@ error_format_status(Config) when is_list(Config) ->
receive
{error,_GroupLeader,{Pid,
"** State machine"++_,
- [Pid,{_,_,badreturn},idle,StateData,_]}} ->
+ [Pid,{_,_,badreturn},idle,{formatted,StateData},_]}} ->
ok;
Other ->
?line io:format("Unexpected: ~p", [Other]),
@@ -413,6 +416,29 @@ error_format_status(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+terminate_crash_format(Config) when is_list(Config) ->
+ error_logger_forwarder:register(),
+ OldFl = process_flag(trap_exit, true),
+ StateData = crash_terminate,
+ {ok, Pid} = gen_fsm:start(gen_fsm_SUITE, {state_data, StateData}, []),
+ stop_it(Pid),
+ receive
+ {error,_GroupLeader,{Pid,
+ "** State machine"++_,
+ [Pid,{_,_,_},idle,{formatted, StateData},_]}} ->
+ ok;
+ Other ->
+ io:format("Unexpected: ~p", [Other]),
+ ?t:fail()
+ after 5000 ->
+ io:format("Timeout: expected error logger msg", []),
+ ?t:fail()
+ end,
+ _ = ?t:messages_get(),
+ process_flag(trap_exit, OldFl),
+ ok.
+
+
get_state(Config) when is_list(Config) ->
State = self(),
{ok, Pid} = gen_fsm:start(?MODULE, {state_data, State}, []),
@@ -867,7 +893,8 @@ init({state_data, StateData}) ->
init(_) ->
{ok, idle, state_data}.
-
+terminate(_, _State, crash_terminate) ->
+ exit({crash, terminate});
terminate({From, stopped}, State, _Data) ->
From ! {self(), {stopped, State}},
ok;
@@ -1005,6 +1032,6 @@ handle_sync_event({get, _Pid}, _From, State, Data) ->
{reply, {state, State, Data}, State, Data}.
format_status(terminate, [_Pdict, StateData]) ->
- StateData;
+ {formatted, StateData};
format_status(normal, [_Pdict, _StateData]) ->
[format_status_called].
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 960e7f60e7..0f03fda30a 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_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
@@ -32,7 +32,8 @@
spec_init_local_registered_parent/1,
spec_init_global_registered_parent/1,
otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1,
- error_format_status/1, get_state/1, replace_state/1, call_with_huge_message_queue/1
+ error_format_status/1, terminate_crash_format/1,
+ get_state/1, replace_state/1, call_with_huge_message_queue/1
]).
% spawn export
@@ -56,7 +57,8 @@ all() ->
call_remote_n3, spec_init,
spec_init_local_registered_parent,
spec_init_global_registered_parent, otp_5854, hibernate,
- otp_7669, call_format_status, error_format_status,
+ otp_7669,
+ call_format_status, error_format_status, terminate_crash_format,
get_state, replace_state,
call_with_huge_message_queue].
@@ -273,7 +275,9 @@ crash(Config) when is_list(Config) ->
receive
{error,_GroupLeader4,{Pid4,
"** Generic server"++_,
- [Pid4,crash,state4,crashed]}} ->
+ [Pid4,crash,{formatted, state4},
+ {crashed,[{?MODULE,handle_call,3,_}
+ |_Stacktrace]}]}} ->
ok;
Other4a ->
?line io:format("Unexpected: ~p", [Other4a]),
@@ -1024,7 +1028,9 @@ error_format_status(Config) when is_list(Config) ->
receive
{error,_GroupLeader,{Pid,
"** Generic server"++_,
- [Pid,crash,State,crashed]}} ->
+ [Pid,crash,{formatted, State},
+ {crashed,[{?MODULE,handle_call,3,_}
+ |_Stacktrace]}]}} ->
ok;
Other ->
?line io:format("Unexpected: ~p", [Other]),
@@ -1034,6 +1040,33 @@ error_format_status(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+%% Verify that error when terminating correctly calls our format_status/2 fun
+%%
+terminate_crash_format(Config) when is_list(Config) ->
+ error_logger_forwarder:register(),
+ OldFl = process_flag(trap_exit, true),
+ State = crash_terminate,
+ {ok, Pid} = gen_server:start_link(?MODULE, {state, State}, []),
+ gen_server:call(Pid, stop),
+ receive {'EXIT', Pid, {crash, terminate}} -> ok end,
+ receive
+ {error,_GroupLeader,{Pid,
+ "** Generic server"++_,
+ [Pid,stop, {formatted, State},
+ {{crash, terminate},[{?MODULE,terminate,2,_}
+ |_Stacktrace]}]}} ->
+ ok;
+ Other ->
+ io:format("Unexpected: ~p", [Other]),
+ ?t:fail()
+ after 5000 ->
+ io:format("Timeout: expected error logger msg", []),
+ ?t:fail()
+ end,
+ ?t:messages_get(),
+ process_flag(trap_exit, OldFl),
+ ok.
+
%% Verify that sys:get_state correctly returns gen_server state
%%
get_state(suite) ->
@@ -1323,10 +1356,12 @@ terminate({From, stopped}, _State) ->
terminate({From, stopped_info}, _State) ->
From ! {self(), stopped_info},
ok;
+terminate(_, crash_terminate) ->
+ exit({crash, terminate});
terminate(_Reason, _State) ->
ok.
format_status(terminate, [_PDict, State]) ->
- State;
+ {formatted, State};
format_status(normal, [_PDict, _State]) ->
format_status_called.
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 5a8971c071..2203dd8f51 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -30,7 +30,8 @@
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,
+ io_with_huge_message_queue/1]).
-export([pretty/2]).
@@ -69,7 +70,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, io_with_huge_message_queue].
groups() ->
[].
@@ -2213,3 +2215,49 @@ 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.
+
+%% Test that the time for a huge message queue is not
+%% significantly slower than with an empty message queue.
+io_with_huge_message_queue(Config) when is_list(Config) ->
+ case test_server:is_native(gen) of
+ true ->
+ {skip,
+ "gen is native - huge message queue optimization "
+ "is not implemented"};
+ false ->
+ do_io_with_huge_message_queue(Config)
+ end.
+
+do_io_with_huge_message_queue(Config) ->
+ PrivDir = ?privdir(Config),
+ File = filename:join(PrivDir, "slask"),
+ {ok, F1} = file:open(File, [write]),
+
+ {Time,ok} = timer:tc(fun() -> writes(1000, F1) end),
+
+ [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ erlang:garbage_collect(),
+ {NewTime,ok} = timer:tc(fun() -> writes(1000, F1) end),
+ file:close(F1),
+ io:format("Time for empty message queue: ~p", [Time]),
+ io:format("Time for huge message queue: ~p", [NewTime]),
+
+ IsCover = test_server:is_cover(),
+ case (NewTime+1) / (Time+1) of
+ Q when Q < 10; IsCover ->
+ ok;
+ Q ->
+ io:format("Q = ~p", [Q]),
+ ?t:fail()
+ end,
+ ok.
+
+writes(0, _) -> ok;
+writes(N, F1) ->
+ file:write(F1, "hello\n"),
+ writes(N - 1, F1).
diff --git a/lib/stdlib/test/maps_SUITE.erl b/lib/stdlib/test/maps_SUITE.erl
index c826ee731a..dda20a615b 100644
--- a/lib/stdlib/test/maps_SUITE.erl
+++ b/lib/stdlib/test/maps_SUITE.erl
@@ -24,10 +24,7 @@
-include_lib("test_server/include/test_server.hrl").
-% Default timetrap timeout (set in init_per_testcase).
-% This should be set relatively high (10-15 times the expected
-% max testcasetime).
--define(default_timeout, ?t:minutes(4)).
+-define(default_timeout, ?t:minutes(1)).
% Test server specific exports
-export([all/0]).
@@ -37,13 +34,13 @@
-export([init_per_testcase/2]).
-export([end_per_testcase/2]).
--export([get3/1]).
+-export([t_get_3/1,t_with_2/1,t_without_2/1]).
suite() ->
[{ct_hooks, [ts_install_cth]}].
all() ->
- [get3].
+ [t_get_3,t_with_2,t_without_2].
init_per_suite(Config) ->
Config.
@@ -52,7 +49,7 @@ end_per_suite(_Config) ->
ok.
init_per_testcase(_Case, Config) ->
- ?line Dog=test_server:timetrap(?default_timeout),
+ Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
end_per_testcase(_Case, Config) ->
@@ -60,10 +57,24 @@ end_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-get3(Config) when is_list(Config) ->
+t_get_3(Config) when is_list(Config) ->
Map = #{ key1 => value1, key2 => value2 },
DefaultValue = "Default value",
- ?line value1 = maps:get(key1, Map, DefaultValue),
- ?line value2 = maps:get(key2, Map, DefaultValue),
- ?line DefaultValue = maps:get(key3, Map, DefaultValue),
+ value1 = maps:get(key1, Map, DefaultValue),
+ value2 = maps:get(key2, Map, DefaultValue),
+ DefaultValue = maps:get(key3, Map, DefaultValue),
+ ok.
+
+t_without_2(_Config) ->
+ Ki = [11,22,33,44,55,66,77,88,99],
+ M0 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100)]),
+ M1 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100) -- Ki]),
+ M1 = maps:without([{k,I}||I <- Ki],M0),
+ ok.
+
+t_with_2(_Config) ->
+ Ki = [11,22,33,44,55,66,77,88,99],
+ M0 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100)]),
+ M1 = maps:from_list([{{k,I},{v,I}}||I<-Ki]),
+ M1 = maps:with([{k,I}||I <- Ki],M0),
ok.
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index 4ec13ed472..1577caa80f 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -91,21 +91,23 @@ warnings(Config) when is_list(Config) ->
" end)">>,
?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] =
compile_ww(Prog),
- Prog2 = <<"C=5, "
- "ets:fun2ms(fun({A,B} = C) "
- " when is_integer(A) and (A+5 > B) -> "
- " {A andalso B,C} "
- " end)">>,
- ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] =
+ Prog2 = <<"C = 5,
+ ets:fun2ms(fun ({A,B} =
+ C) when is_integer(A) and (A+5 > B) ->
+ {A andalso B,C}
+ end)">>,
+ [{_,[{3,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] =
compile_ww(Prog2),
Rec3 = <<"-record(a,{a,b,c,d=foppa}).">>,
- Prog3 = <<"A=3,C=5, "
- "ets:fun2ms(fun(#a{a = A, b = B} = C) "
- " when is_integer(A) and (A+5 > B) -> "
- " {A andalso B,C} "
- " end)">>,
- ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}},
- {_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] =
+ Prog3 = <<"A = 3,
+ C = 5,
+ ets:fun2ms(fun (C
+ = #a{a = A, b = B})
+ when is_integer(A) and (A+5 > B) ->
+ {A andalso B,C}
+ end)">>,
+ [{_,[{3,ms_transform,{?WARN_NUMBER_SHADOW,'C'}},
+ {4,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] =
compile_ww(Rec3,Prog3),
Rec4 = <<"-record(a,{a,b,c,d=foppa}).">>,
Prog4 = <<"A=3,C=5, "
@@ -867,6 +869,7 @@ compile_ww(Records,Expr) ->
"-include_lib(\"stdlib/include/ms_transform.hrl\").\n",
"-export([tmp/0]).\n",
Records/binary,"\n",
+ "-file(?FILE, 0). ",
"tmp() ->\n",
Expr/binary,".\n">>,
FN=temp_name(),
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/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl
index 59821220b4..3d09bd27ff 100644
--- a/lib/stdlib/test/stdlib_SUITE.erl
+++ b/lib/stdlib/test/stdlib_SUITE.erl
@@ -78,17 +78,29 @@ appup_test(_Config) ->
appup_tests(_App,{[],[]}) ->
{skip,"no previous releases available"};
-appup_tests(App,{OkVsns,NokVsns}) ->
+appup_tests(App,{OkVsns0,NokVsns}) ->
application:load(App),
{_,_,Vsn} = lists:keyfind(App,1,application:loaded_applications()),
AppupFileName = atom_to_list(App) ++ ".appup",
AppupFile = filename:join([code:lib_dir(App),ebin,AppupFileName]),
{ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile),
ct:log("~p~n",[AppupScript]),
- ct:log("Testing ok versions: ~p~n",[OkVsns]),
+ OkVsns =
+ case OkVsns0 -- [Vsn] of
+ OkVsns0 ->
+ OkVsns0;
+ Ok ->
+ ct:log("Current version, ~p, is same as in previous release.~n"
+ "Removing this from the list of ok versions.",
+ [Vsn]),
+ Ok
+ end,
+ ct:log("Testing that appup allows upgrade from these versions: ~p~n",
+ [OkVsns]),
check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}),
check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}),
- ct:log("Testing not ok versions: ~p~n",[NokVsns]),
+ ct:log("Testing that appup does not allow upgrade from these versions: ~p~n",
+ [NokVsns]),
check_appup(NokVsns,UpFrom,error),
check_appup(NokVsns,DownTo,error),
ok.
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 6349139925..9b6d65011e 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -654,6 +654,7 @@ open_add_close(Config) when is_list(Config) ->
?line ok = erl_tar:add(AD, FileOne, []),
?line ok = erl_tar:add(AD, FileTwo, "second file", []),
?line ok = erl_tar:add(AD, FileThree, [verbose]),
+ ?line ok = erl_tar:add(AD, FileThree, "chunked", [{chunks,11411},verbose]),
?line ok = erl_tar:add(AD, ADir, [verbose]),
?line ok = erl_tar:add(AD, AnotherDir, [verbose]),
?line ok = erl_tar:close(AD),
@@ -661,7 +662,7 @@ open_add_close(Config) when is_list(Config) ->
?line ok = erl_tar:t(TarOne),
?line ok = erl_tar:tt(TarOne),
- ?line {ok,[FileOne,"second file",FileThree,ADir,SomeContent]} = erl_tar:table(TarOne),
+ ?line {ok,[FileOne,"second file",FileThree,"chunked",ADir,SomeContent]} = erl_tar:table(TarOne),
?line delete_files(["oac_file","oac_small","oac_big",Dir,AnotherDir,ADir]),
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index 37a6590b06..5be130bac9 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 2.0
+STDLIB_VSN = 2.3
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 4e1e6d8cb1..b0f11bb243 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -31,6 +31,66 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 1.6.17</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Teach Maps to erl_syntax</p>
+ <p>
+ Affected functions: <list>
+ <item>erl_syntax:abstract/1</item>
+ <item>erl_syntax:concrete/1</item>
+ <item>erl_syntax:is_leaf/1</item>
+ <item>erl_syntax:is_literal/1</item> </list></p>
+ <p>
+ Own Id: OTP-12265</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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..3ca7a8197e 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -88,7 +88,7 @@
%% This is a so-called Erlang I/O ErrorInfo structure; see the {@link
%% //stdlib/io} module for details.
--type errorinfo() :: term(). % {integer(), atom(), term()}.
+-type errorinfo() :: {integer(), atom(), term()}.
-type option() :: atom() | {atom(), term()}.
@@ -184,16 +184,42 @@ 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;
- {error, _} = Error ->
- Error
+ {error, Error} ->
+ {error, {0, file, Error}} % defer to file:format_error/1
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/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 46a5ca48df..40372a2106 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -669,6 +669,9 @@ is_leaf(Node) ->
operator -> true; % nonstandard type
string -> true;
text -> true; % nonstandard type
+ map_expr ->
+ map_expr_fields(Node) =:= [] andalso
+ map_expr_argument(Node) =:= none;
tuple -> tuple_elements(Node) =:= [];
underscore -> true;
variable -> true;
@@ -6093,6 +6096,9 @@ abstract([]) ->
nil();
abstract(T) when is_tuple(T) ->
tuple(abstract_list(tuple_to_list(T)));
+abstract(T) when is_map(T) ->
+ map_expr([map_field_assoc(abstract(Key),abstract(Value))
+ || {Key,Value} <- maps:to_list(T)]);
abstract(T) when is_binary(T) ->
binary([binary_field(integer(B)) || B <- binary_to_list(T)]);
abstract(T) ->
@@ -6154,6 +6160,14 @@ concrete(Node) ->
| concrete(list_tail(Node))];
tuple ->
list_to_tuple(concrete_list(tuple_elements(Node)));
+ map_expr ->
+ As = [tuple([map_field_assoc_name(F),
+ map_field_assoc_value(F)]) || F <- map_expr_fields(Node)],
+ M0 = maps:from_list(concrete_list(As)),
+ case map_expr_argument(Node) of
+ none -> M0;
+ Node0 -> maps:merge(concrete(Node0),M0)
+ end;
binary ->
Fs = [revert_binary_field(
binary_field(binary_field_body(F),
@@ -6209,10 +6223,31 @@ is_literal(T) ->
is_literal(list_head(T)) andalso is_literal(list_tail(T));
tuple ->
lists:all(fun is_literal/1, tuple_elements(T));
+ map_expr ->
+ case map_expr_argument(T) of
+ none -> true;
+ Arg -> is_literal(Arg)
+ end andalso lists:all(fun is_literal_map_field/1, map_expr_fields(T));
+ binary ->
+ lists:all(fun is_literal_binary_field/1, binary_fields(T));
_ ->
false
end.
+is_literal_binary_field(F) ->
+ case binary_field_types(F) of
+ [] -> is_literal(binary_field_body(F));
+ _ -> false
+ end.
+
+is_literal_map_field(F) ->
+ case type(F) of
+ map_field_assoc ->
+ is_literal(map_field_assoc_name(F)) andalso
+ is_literal(map_field_assoc_value(F));
+ map_field_exact ->
+ false
+ end.
%% =====================================================================
%% @doc Returns an `erl_parse'-compatible representation of a
diff --git a/lib/syntax_tools/test/Makefile b/lib/syntax_tools/test/Makefile
index d4733b9a42..f67e3f8984 100644
--- a/lib/syntax_tools/test/Makefile
+++ b/lib/syntax_tools/test/Makefile
@@ -61,5 +61,6 @@ release_tests_spec: make_emakefile
$(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) syntax_tools.spec syntax_tools.cover "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
+ @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
release_docs_spec:
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index 6fb3e5ccfb..3c6b33f459 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -24,12 +24,16 @@
init_per_group/2,end_per_group/2]).
%% Test cases
--export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1]).
+-export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1,
+ t_abstract_type/1,t_erl_parse_type/1,t_epp_dodger/1,
+ t_comment_scan/1,t_igor/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test,appup_test,smoke_test,revert,revert_map].
+ [app_test,appup_test,smoke_test,revert,revert_map,
+ t_abstract_type,t_erl_parse_type,t_epp_dodger,
+ t_comment_scan,t_igor].
groups() ->
[].
@@ -54,15 +58,15 @@ appup_test(Config) when is_list(Config) ->
%% Read and parse all source in the OTP release.
smoke_test(Config) when is_list(Config) ->
- ?line Dog = ?t:timetrap(?t:minutes(12)),
- ?line Wc = filename:join([code:lib_dir(),"*","src","*.erl"]),
- ?line Fs = filelib:wildcard(Wc),
- ?line io:format("~p files\n", [length(Fs)]),
- ?line case p_run(fun smoke_test_file/1, Fs) of
- 0 -> ok;
- N -> ?line ?t:fail({N,errors})
- end,
- ?line ?t:timetrap_cancel(Dog).
+ Dog = ?t:timetrap(?t:minutes(12)),
+ Wc = filename:join([code:lib_dir(),"*","src","*.erl"]),
+ Fs = filelib:wildcard(Wc),
+ io:format("~p files\n", [length(Fs)]),
+ case p_run(fun smoke_test_file/1, Fs) of
+ 0 -> ok;
+ N -> ?t:fail({N,errors})
+ end,
+ ?t:timetrap_cancel(Dog).
smoke_test_file(File) ->
case epp_dodger:parse_file(File) of
@@ -94,9 +98,9 @@ revert(Config) when is_list(Config) ->
io:format("~p files\n", [length(Fs)]),
case p_run(fun (File) -> revert_file(File, Path) end, Fs) of
0 -> ok;
- N -> ?line ?t:fail({N,errors})
+ N -> ?t:fail({N,errors})
end,
- ?line ?t:timetrap_cancel(Dog).
+ ?t:timetrap_cancel(Dog).
revert_file(File, Path) ->
case epp:parse_file(File, Path, []) of
@@ -110,14 +114,298 @@ revert_file(File, Path) ->
end.
%% Testing bug fix for reverting map_field_assoc
-revert_map(Config) ->
+revert_map(Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(1)),
- ?line [{map_field_assoc,16,{atom,17,name},{var,18,'Value'}}] =
- erl_syntax:revert_forms([{tree,map_field_assoc,
- {attr,16,[],none},
- {map_field_assoc,
- {atom,17,name},{var,18,'Value'}}}]),
- ?line ?t:timetrap_cancel(Dog).
+ [{map_field_assoc,16,{atom,17,name},{var,18,'Value'}}] =
+ erl_syntax:revert_forms([{tree,map_field_assoc,
+ {attr,16,[],none},
+ {map_field_assoc,{atom,17,name},{var,18,'Value'}}}]),
+ ?t:timetrap_cancel(Dog).
+
+
+
+%% api tests
+
+t_abstract_type(Config) when is_list(Config) ->
+ F = fun validate_abstract_type/1,
+ ok = validate(F,[{hi,atom},
+ {1,integer},
+ {1.0,float},
+ {$a,integer},
+ {[],nil},
+ {[<<1,2>>,a,b],list},
+ {[2,3,<<1,2>>,a,b],list},
+ {[$a,$b,$c],string},
+ {"hello world",string},
+ {<<1,2,3>>,binary},
+ {#{a=>1,"b"=>2},map_expr},
+ {#{#{i=>1}=>1,"b"=>#{v=>2}},map_expr},
+ {{a,b,c},tuple}]),
+ ok.
+
+t_erl_parse_type(Config) when is_list(Config) ->
+ F = fun validate_erl_parse_type/1,
+ %% leaf types
+ ok = validate(F,[{"1",integer,true},
+ {"123456789",integer,true},
+ {"$h", char,true},
+ {"3.1415", float,true},
+ {"1.33e36", float,true},
+ {"\"1.33e36: hello\"", string,true},
+ {"Var1", variable,true},
+ {"_", underscore,true},
+ {"[]", nil,true},
+ {"{}", tuple,true},
+ {"#{}",map_expr,true},
+ {"'some atom'", atom, true}]),
+ %% composite types
+ ok = validate(F,[{"case X of t -> t; f -> f end", case_expr,false},
+ {"try X of t -> t catch C:R -> error end", try_expr,false},
+ {"receive X -> X end", receive_expr,false},
+ {"receive M -> X1 after T -> X2 end", receive_expr,false},
+ {"catch (X)", catch_expr,false},
+ {"fun(X) -> X end", fun_expr,false},
+ {"fun Foo(X) -> X end", named_fun_expr,false},
+ {"fun foo/2", implicit_fun,false},
+ {"fun bar:foo/2", implicit_fun,false},
+ {"if X -> t; true -> f end", if_expr,false},
+ {"<<1,2,3,4>>", binary,false},
+ {"<<1,2,3,4:5>>", binary,false},
+ {"<<V1:63,V2:22/binary, V3/bits>>", binary,false},
+ {"begin X end", block_expr,false},
+ {"foo(X1,X2)", application,false},
+ {"bar:foo(X1,X2)", application,false},
+ {"[1,2,3,4]", list,false},
+ {"[1|4]", list, false},
+ {"[<<1>>,<<2>>,-2,<<>>,[more,list]]", list,false},
+ {"[1|[2|[3|[4|[]]]]]", list,false},
+ {"#{ a=>1, b=>2 }", map_expr,false},
+ {"#{3=>3}#{ a=>1, b=>2 }", map_expr,false},
+ {"#{ a:=1, b:=2 }", map_expr,false},
+ {"M#{ a=>1, b=>2 }", map_expr,false},
+ {"[V||V <- Vs]", list_comp,false},
+ {"<< <<B>> || <<B>> <= Bs>>", binary_comp,false},
+ {"#state{ a = A, b = B}", record_expr,false},
+ {"#state{}", record_expr,false},
+ {"#s{ a = #def{ a=A }, b = B}", record_expr,false},
+ {"State#state{ a = A, b = B}", record_expr,false},
+ {"State#state.a", record_access,false},
+ {"#state.a", record_index_expr,false},
+ {"-X", prefix_expr,false},
+ {"X1 + X2", infix_expr,false},
+ {"(X1 + X2) * X3", infix_expr,false},
+ {"X1 = X2", match_expr,false},
+ {"{a,b,c}", tuple,false}]),
+ ok.
+
+%% the macro ?MODULE seems faulty
+t_epp_dodger(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Filenames = ["syntax_tools_SUITE_test_module.erl",
+ "syntax_tools_test.erl"],
+ ok = test_epp_dodger(Filenames,DataDir,PrivDir),
+ ok.
+
+t_comment_scan(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Filenames = ["syntax_tools_SUITE_test_module.erl",
+ "syntax_tools_test.erl"],
+ ok = test_comment_scan(Filenames,DataDir),
+ ok.
+
+t_igor(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ FileM1 = filename:join(DataDir,"m1.erl"),
+ FileM2 = filename:join(DataDir,"m2.erl"),
+ ["m.erl",_]=R = igor:merge(m,[FileM1,FileM2],[{outdir,PrivDir}]),
+ io:format("igor:merge/3 = ~p~n", [R]),
+ ok.
+
+test_comment_scan([],_) -> ok;
+test_comment_scan([File|Files],DataDir) ->
+ Filename = filename:join(DataDir,File),
+ {ok, Fs0} = epp:parse_file(Filename, [], []),
+ Comments = erl_comment_scan:file(Filename),
+ Fun = fun(Node) ->
+ case erl_syntax:is_form(Node) of
+ true ->
+ C1 = erl_syntax:comment(2,[" This is a form."]),
+ Node1 = erl_syntax:add_precomments([C1],Node),
+ Node1;
+ false ->
+ Node
+ end
+ end,
+ Fs1 = erl_recomment:recomment_forms(Fs0, Comments),
+ Fs2 = erl_syntax_lib:map(Fun, Fs1),
+ io:format("File: ~s~n", [Filename]),
+ io:put_chars(erl_prettypr:format(Fs2, [{paper, 120},
+ {ribbon, 110}])),
+ test_comment_scan(Files,DataDir).
+
+
+test_epp_dodger([], _, _) -> ok;
+test_epp_dodger([Filename|Files],DataDir,PrivDir) ->
+ io:format("Parsing ~p~n", [Filename]),
+ InFile = filename:join(DataDir, Filename),
+ Parsers = [{fun epp_dodger:parse_file/1,parse_file},
+ {fun epp_dodger:quick_parse_file/1,quick_parse_file},
+ {fun (File) ->
+ {ok,Dev} = file:open(File,[read]),
+ Res = epp_dodger:parse(Dev),
+ file:close(File),
+ Res
+ end, parse},
+ {fun (File) ->
+ {ok,Dev} = file:open(File,[read]),
+ Res = epp_dodger:quick_parse(Dev),
+ file:close(File),
+ Res
+ end, quick_parse}],
+ FsForms = parse_with(Parsers, InFile),
+ ok = pretty_print_parse_forms(FsForms,PrivDir,Filename),
+ test_epp_dodger(Files,DataDir,PrivDir).
+
+parse_with([],_) -> [];
+parse_with([{Fun,ParserType}|Funs],File) ->
+ {ok, Fs} = Fun(File),
+ [{Fs,ParserType}|parse_with(Funs,File)].
+
+pretty_print_parse_forms([],_,_) -> ok;
+pretty_print_parse_forms([{Fs0,Type}|FsForms],PrivDir,Filename) ->
+ Parser = atom_to_list(Type),
+ OutFile = filename:join(PrivDir, Parser ++"_" ++ Filename),
+ io:format("Pretty print ~p (~w) to ~p~n", [Filename,Type,OutFile]),
+ Comment = fun (Node,{CntCase,CntTry}=Cnt) ->
+ case erl_syntax:type(Node) of
+ case_expr ->
+ C1 = erl_syntax:comment(2,["Before a case expression"]),
+ Node1 = erl_syntax:add_precomments([C1],Node),
+ C2 = erl_syntax:comment(2,["After a case expression"]),
+ Node2 = erl_syntax:add_postcomments([C2],Node1),
+ {Node2,{CntCase+1,CntTry}};
+ try_expr ->
+ C1 = erl_syntax:comment(2,["Before a try expression"]),
+ Node1 = erl_syntax:set_precomments(Node,
+ erl_syntax:get_precomments(Node) ++ [C1]),
+ C2 = erl_syntax:comment(2,["After a try expression"]),
+ Node2 = erl_syntax:set_postcomments(Node1,
+ erl_syntax:get_postcomments(Node1) ++ [C2]),
+ {Node2,{CntCase,CntTry+1}};
+ _ ->
+ {Node,Cnt}
+ end
+ end,
+ Fs1 = erl_syntax:form_list(Fs0),
+ {Fs2,{CC,CT}} = erl_syntax_lib:mapfold(Comment,{0,0}, Fs1),
+ io:format("Commented on ~w cases and ~w tries~n", [CC,CT]),
+ PP = erl_prettypr:format(Fs2),
+ ok = file:write_file(OutFile,iolist_to_binary(PP)),
+ pretty_print_parse_forms(FsForms,PrivDir,Filename).
+
+
+validate(_,[]) -> ok;
+validate(F,[V|Vs]) ->
+ ok = F(V),
+ validate(F,Vs).
+
+
+validate_abstract_type({Lit,Type}) ->
+ Tree = erl_syntax:abstract(Lit),
+ ok = validate_special_type(Type,Tree),
+ Type = erl_syntax:type(Tree),
+ true = erl_syntax:is_literal(Tree),
+ ErlT = erl_syntax:revert(Tree),
+ Type = erl_syntax:type(ErlT),
+ ok = validate_special_type(Type,ErlT),
+ Conc = erl_syntax:concrete(Tree),
+ Lit = Conc,
+ ok.
+
+validate_erl_parse_type({String,Type,Leaf}) ->
+ ErlT = string_to_expr(String),
+ ok = validate_special_type(Type,ErlT),
+ Type = erl_syntax:type(ErlT),
+ Leaf = erl_syntax:is_leaf(ErlT),
+ Tree = erl_syntax_lib:map(fun(Node) -> Node end, ErlT),
+ Type = erl_syntax:type(Tree),
+ _ = erl_syntax:meta(Tree),
+ ok = validate_special_type(Type,Tree),
+ RevT = erl_syntax:revert(Tree),
+ ok = validate_special_type(Type,RevT),
+ Type = erl_syntax:type(RevT),
+ ok.
+
+validate_special_type(string,Node) ->
+ Val = erl_syntax:string_value(Node),
+ true = erl_syntax:is_string(Node,Val),
+ _ = erl_syntax:string_literal(Node),
+ ok;
+validate_special_type(variable,Node) ->
+ _ = erl_syntax:variable_literal(Node),
+ ok;
+validate_special_type(fun_expr,Node) ->
+ A = erl_syntax:fun_expr_arity(Node),
+ true = is_integer(A),
+ ok;
+validate_special_type(named_fun_expr,Node) ->
+ A = erl_syntax:named_fun_expr_arity(Node),
+ true = is_integer(A),
+ ok;
+validate_special_type(tuple,Node) ->
+ Size = erl_syntax:tuple_size(Node),
+ true = is_integer(Size),
+ ok;
+validate_special_type(float,Node) ->
+ Str = erl_syntax:float_literal(Node),
+ Val = list_to_float(Str),
+ Val = erl_syntax:float_value(Node),
+ false = erl_syntax:is_proper_list(Node),
+ false = erl_syntax:is_list_skeleton(Node),
+ ok;
+validate_special_type(integer,Node) ->
+ Str = erl_syntax:integer_literal(Node),
+ Val = list_to_integer(Str),
+ true = erl_syntax:is_integer(Node,Val),
+ Val = erl_syntax:integer_value(Node),
+ false = erl_syntax:is_proper_list(Node),
+ ok;
+validate_special_type(nil,Node) ->
+ true = erl_syntax:is_proper_list(Node),
+ ok;
+validate_special_type(list,Node) ->
+ true = erl_syntax:is_list_skeleton(Node),
+ _ = erl_syntax:list_tail(Node),
+ ErrV = erl_syntax:list_head(Node),
+ false = erl_syntax:is_string(Node,ErrV),
+ Norm = erl_syntax:normalize_list(Node),
+ list = erl_syntax:type(Norm),
+ case erl_syntax:is_proper_list(Node) of
+ true ->
+ true = erl_syntax:is_list_skeleton(Node),
+ Compact = erl_syntax:compact_list(Node),
+ list = erl_syntax:type(Compact),
+ [_|_] = erl_syntax:list_elements(Node),
+ _ = erl_syntax:list_elements(Node),
+ N = erl_syntax:list_length(Node),
+ true = N > 0,
+ ok;
+ false ->
+ ok
+ end;
+validate_special_type(_,_) ->
+ ok.
+
+%%% scan_and_parse
+
+string_to_expr(String) ->
+ io:format("Str: ~p~n", [String]),
+ {ok, Ts, _} = erl_scan:string(String++"."),
+ {ok,[Expr]} = erl_parse:parse_exprs(Ts),
+ Expr.
+
p_run(Test, List) ->
N = erlang:system_info(schedulers),
@@ -138,4 +426,3 @@ p_run_loop(Test, List, N, Refs0, Errors0) ->
Refs = Refs0 -- [Ref],
p_run_loop(Test, List, N, Refs, Errors)
end.
-
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl
new file mode 100644
index 0000000000..d0d1911199
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl
@@ -0,0 +1,22 @@
+%%
+%% File: m1.erl
+%% Author: Björn-Egil Dahlberg
+%% Created: 2014-10-24
+%%
+
+-module(m1).
+
+-export([foo/0,bar/1,baz/2]).
+
+foo() ->
+ [m2:foo(),
+ m2:bar()].
+
+bar(A) ->
+ [m2:foo(A),
+ m2:bar(A),
+ m2:record_update(3,m2:record())].
+
+baz(A,B) ->
+ [m2:foo(A,B),
+ m2:bar(A,B)].
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl
new file mode 100644
index 0000000000..781139317d
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl
@@ -0,0 +1,26 @@
+%%
+%% File: m2.erl
+%% Author: Björn-Egil Dahlberg
+%% Created: 2014-10-24
+%%
+
+-module(m2).
+
+
+-export([foo/0,foo/1,foo/2,
+ bar/0,bar/1,bar/2,
+ record_update/2, record/0]).
+
+foo() -> ok.
+foo(A) -> [item,A].
+foo(A,B) -> A + B.
+
+bar() -> true.
+bar(A) -> {element,A}.
+bar(A,B) -> A*B.
+
+-record(rec, {a,b}).
+
+record() -> #rec{a=3,b=0}.
+record_update(V,#rec{a=V0}=R) ->
+ R#rec{a=V0+V,b=V0}.
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl
new file mode 100644
index 0000000000..07c419b4b7
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl
@@ -0,0 +1,540 @@
+-module(syntax_tools_SUITE_test_module).
+
+-export([foo1/1,foo2/3,start_child/2]).
+
+-export([len/1,equal/2,concat/2,chr/2,rchr/2,str/2,rstr/2,
+ span/2,cspan/2,substr/2,substr/3,tokens/2,chars/2,chars/3]).
+-export([copies/2,words/1,words/2,strip/1,strip/2,strip/3,
+ sub_word/2,sub_word/3,left/2,left/3,right/2,right/3,
+ sub_string/2,sub_string/3,centre/2,centre/3, join/2]).
+-export([to_upper/1, to_lower/1]).
+
+-import(lists,[reverse/1,member/2]).
+
+
+%% @type some_type() = map()
+%% @type some_other_type() = {a, #{ list() => term()}}
+
+-type some_type() :: map().
+-type some_other_type() :: {'a', #{ list() => term()} }.
+
+-spec foo1(Map :: #{ 'a' => integer(), 'b' => term()}) -> term().
+
+%% @doc Gets value from map.
+
+foo1(#{ a:= 1, b := V}) -> V.
+
+%% @spec foo2(some_type(), Type2 :: some_other_type(), map()) -> Value
+%% @doc Gets value from map.
+
+-spec foo2(
+ Type1 :: some_type(),
+ Type2 :: some_other_type(),
+ 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}.
+
+
+%% From string.erl
+%% Robert's bit
+
+%% len(String)
+%% Return the length of a string.
+
+-spec len(String) -> Length when
+ String :: string(),
+ Length :: non_neg_integer().
+
+len(S) -> length(S).
+
+%% equal(String1, String2)
+%% Test if 2 strings are equal.
+
+-spec equal(String1, String2) -> boolean() when
+ String1 :: string(),
+ String2 :: string().
+
+equal(S, S) -> true;
+equal(_, _) -> false.
+
+%% concat(String1, String2)
+%% Concatenate 2 strings.
+
+-spec concat(String1, String2) -> String3 when
+ String1 :: string(),
+ String2 :: string(),
+ String3 :: string().
+
+concat(S1, S2) -> S1 ++ S2.
+
+%% chr(String, Char)
+%% rchr(String, Char)
+%% Return the first/last index of the character in a string.
+
+-spec chr(String, Character) -> Index when
+ String :: string(),
+ Character :: char(),
+ Index :: non_neg_integer().
+
+chr(S, C) when is_integer(C) -> chr(S, C, 1).
+
+chr([C|_Cs], C, I) -> I;
+chr([_|Cs], C, I) -> chr(Cs, C, I+1);
+chr([], _C, _I) -> 0.
+
+-spec rchr(String, Character) -> Index when
+ String :: string(),
+ Character :: char(),
+ Index :: non_neg_integer().
+
+rchr(S, C) when is_integer(C) -> rchr(S, C, 1, 0).
+
+rchr([C|Cs], C, I, _L) -> %Found one, now find next!
+ rchr(Cs, C, I+1, I);
+rchr([_|Cs], C, I, L) ->
+ rchr(Cs, C, I+1, L);
+rchr([], _C, _I, L) -> L.
+
+%% str(String, SubString)
+%% rstr(String, SubString)
+%% index(String, SubString)
+%% Return the first/last index of the sub-string in a string.
+%% index/2 is kept for backwards compatibility.
+
+-spec str(String, SubString) -> Index when
+ String :: string(),
+ SubString :: string(),
+ Index :: non_neg_integer().
+
+str(S, Sub) when is_list(Sub) -> str(S, Sub, 1).
+
+str([C|S], [C|Sub], I) ->
+ case prefix(Sub, S) of
+ true -> I;
+ false -> str(S, [C|Sub], I+1)
+ end;
+str([_|S], Sub, I) -> str(S, Sub, I+1);
+str([], _Sub, _I) -> 0.
+
+-spec rstr(String, SubString) -> Index when
+ String :: string(),
+ SubString :: string(),
+ Index :: non_neg_integer().
+
+rstr(S, Sub) when is_list(Sub) -> rstr(S, Sub, 1, 0).
+
+rstr([C|S], [C|Sub], I, L) ->
+ case prefix(Sub, S) of
+ true -> rstr(S, [C|Sub], I+1, I);
+ false -> rstr(S, [C|Sub], I+1, L)
+ end;
+rstr([_|S], Sub, I, L) -> rstr(S, Sub, I+1, L);
+rstr([], _Sub, _I, L) -> L.
+
+prefix([C|Pre], [C|String]) -> prefix(Pre, String);
+prefix([], String) when is_list(String) -> true;
+prefix(Pre, String) when is_list(Pre), is_list(String) -> false.
+
+%% span(String, Chars) -> Length.
+%% cspan(String, Chars) -> Length.
+
+-spec span(String, Chars) -> Length when
+ String :: string(),
+ Chars :: string(),
+ Length :: non_neg_integer().
+
+span(S, Cs) when is_list(Cs) -> span(S, Cs, 0).
+
+span([C|S], Cs, I) ->
+ case member(C, Cs) of
+ true -> span(S, Cs, I+1);
+ false -> I
+ end;
+span([], _Cs, I) -> I.
+
+-spec cspan(String, Chars) -> Length when
+ String :: string(),
+ Chars :: string(),
+ Length :: non_neg_integer().
+
+cspan(S, Cs) when is_list(Cs) -> cspan(S, Cs, 0).
+
+cspan([C|S], Cs, I) ->
+ case member(C, Cs) of
+ true -> I;
+ false -> cspan(S, Cs, I+1)
+ end;
+cspan([], _Cs, I) -> I.
+
+%% substr(String, Start)
+%% substr(String, Start, Length)
+%% Extract a sub-string from String.
+
+-spec substr(String, Start) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer().
+
+substr(String, 1) when is_list(String) ->
+ String;
+substr(String, S) when is_integer(S), S > 1 ->
+ substr2(String, S).
+
+-spec substr(String, Start, Length) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer(),
+ Length :: non_neg_integer().
+
+substr(String, S, L) when is_integer(S), S >= 1, is_integer(L), L >= 0 ->
+ substr1(substr2(String, S), L).
+
+substr1([C|String], L) when L > 0 -> [C|substr1(String, L-1)];
+substr1(String, _L) when is_list(String) -> []. %Be nice!
+
+substr2(String, 1) when is_list(String) -> String;
+substr2([_|String], S) -> substr2(String, S-1).
+
+%% tokens(String, Seperators).
+%% Return a list of tokens seperated by characters in Seperators.
+
+-spec tokens(String, SeparatorList) -> Tokens when
+ String :: string(),
+ SeparatorList :: string(),
+ Tokens :: [Token :: nonempty_string()].
+
+tokens(S, Seps) ->
+ tokens1(S, Seps, []).
+
+tokens1([C|S], Seps, Toks) ->
+ case member(C, Seps) of
+ true -> tokens1(S, Seps, Toks);
+ false -> tokens2(S, Seps, Toks, [C])
+ end;
+tokens1([], _Seps, Toks) ->
+ reverse(Toks).
+
+tokens2([C|S], Seps, Toks, Cs) ->
+ case member(C, Seps) of
+ true -> tokens1(S, Seps, [reverse(Cs)|Toks]);
+ false -> tokens2(S, Seps, Toks, [C|Cs])
+ end;
+tokens2([], _Seps, Toks, Cs) ->
+ reverse([reverse(Cs)|Toks]).
+
+-spec chars(Character, Number) -> String when
+ Character :: char(),
+ Number :: non_neg_integer(),
+ String :: string().
+
+chars(C, N) -> chars(C, N, []).
+
+-spec chars(Character, Number, Tail) -> String when
+ Character :: char(),
+ Number :: non_neg_integer(),
+ Tail :: string(),
+ String :: string().
+
+chars(C, N, Tail) when N > 0 ->
+ chars(C, N-1, [C|Tail]);
+chars(C, 0, Tail) when is_integer(C) ->
+ Tail.
+
+%% Torbjörn's bit.
+
+%%% COPIES %%%
+
+-spec copies(String, Number) -> Copies when
+ String :: string(),
+ Copies :: string(),
+ Number :: non_neg_integer().
+
+copies(CharList, Num) when is_list(CharList), is_integer(Num), Num >= 0 ->
+ copies(CharList, Num, []).
+
+copies(_CharList, 0, R) ->
+ R;
+copies(CharList, Num, R) ->
+ copies(CharList, Num-1, CharList++R).
+
+%%% WORDS %%%
+
+-spec words(String) -> Count when
+ String :: string(),
+ Count :: pos_integer().
+
+words(String) -> words(String, $\s).
+
+-spec words(String, Character) -> Count when
+ String :: string(),
+ Character :: char(),
+ Count :: pos_integer().
+
+words(String, Char) when is_integer(Char) ->
+ w_count(strip(String, both, Char), Char, 0).
+
+w_count([], _, Num) -> Num+1;
+w_count([H|T], H, Num) -> w_count(strip(T, left, H), H, Num+1);
+w_count([_H|T], Char, Num) -> w_count(T, Char, Num).
+
+%%% SUB_WORDS %%%
+
+-spec sub_word(String, Number) -> Word when
+ String :: string(),
+ Word :: string(),
+ Number :: integer().
+
+sub_word(String, Index) -> sub_word(String, Index, $\s).
+
+-spec sub_word(String, Number, Character) -> Word when
+ String :: string(),
+ Word :: string(),
+ Number :: integer(),
+ Character :: char().
+
+sub_word(String, Index, Char) when is_integer(Index), is_integer(Char) ->
+ case words(String, Char) of
+ Num when Num < Index ->
+ [];
+ _Num ->
+ s_word(strip(String, left, Char), Index, Char, 1, [])
+ end.
+
+s_word([], _, _, _,Res) -> reverse(Res);
+s_word([Char|_],Index,Char,Index,Res) -> reverse(Res);
+s_word([H|T],Index,Char,Index,Res) -> s_word(T,Index,Char,Index,[H|Res]);
+s_word([Char|T],Stop,Char,Index,Res) when Index < Stop ->
+ s_word(strip(T,left,Char),Stop,Char,Index+1,Res);
+s_word([_|T],Stop,Char,Index,Res) when Index < Stop ->
+ s_word(T,Stop,Char,Index,Res).
+
+%%% STRIP %%%
+
+-spec strip(string()) -> string().
+
+strip(String) -> strip(String, both).
+
+-spec strip(String, Direction) -> Stripped when
+ String :: string(),
+ Stripped :: string(),
+ Direction :: left | right | both.
+
+strip(String, left) -> strip_left(String, $\s);
+strip(String, right) -> strip_right(String, $\s);
+strip(String, both) ->
+ strip_right(strip_left(String, $\s), $\s).
+
+-spec strip(String, Direction, Character) -> Stripped when
+ String :: string(),
+ Stripped :: string(),
+ Direction :: left | right | both,
+ Character :: char().
+
+strip(String, right, Char) -> strip_right(String, Char);
+strip(String, left, Char) -> strip_left(String, Char);
+strip(String, both, Char) ->
+ strip_right(strip_left(String, Char), Char).
+
+strip_left([Sc|S], Sc) ->
+ strip_left(S, Sc);
+strip_left([_|_]=S, Sc) when is_integer(Sc) -> S;
+strip_left([], Sc) when is_integer(Sc) -> [].
+
+strip_right([Sc|S], Sc) ->
+ case strip_right(S, Sc) of
+ [] -> [];
+ T -> [Sc|T]
+ end;
+strip_right([C|S], Sc) ->
+ [C|strip_right(S, Sc)];
+strip_right([], Sc) when is_integer(Sc) ->
+ [].
+
+%%% LEFT %%%
+
+-spec left(String, Number) -> Left when
+ String :: string(),
+ Left :: string(),
+ Number :: non_neg_integer().
+
+left(String, Len) when is_integer(Len) -> left(String, Len, $\s).
+
+-spec left(String, Number, Character) -> Left when
+ String :: string(),
+ Left :: string(),
+ Number :: non_neg_integer(),
+ Character :: char().
+
+left(String, Len, Char) when is_integer(Char) ->
+ Slen = length(String),
+ if
+ Slen > Len -> substr(String, 1, Len);
+ Slen < Len -> l_pad(String, Len-Slen, Char);
+ Slen =:= Len -> String
+ end.
+
+l_pad(String, Num, Char) -> String ++ chars(Char, Num).
+
+%%% RIGHT %%%
+
+-spec right(String, Number) -> Right when
+ String :: string(),
+ Right :: string(),
+ Number :: non_neg_integer().
+
+right(String, Len) when is_integer(Len) -> right(String, Len, $\s).
+
+-spec right(String, Number, Character) -> Right when
+ String :: string(),
+ Right :: string(),
+ Number :: non_neg_integer(),
+ Character :: char().
+
+right(String, Len, Char) when is_integer(Char) ->
+ Slen = length(String),
+ if
+ Slen > Len -> substr(String, Slen-Len+1);
+ Slen < Len -> r_pad(String, Len-Slen, Char);
+ Slen =:= Len -> String
+ end.
+
+r_pad(String, Num, Char) -> chars(Char, Num, String).
+
+%%% CENTRE %%%
+
+-spec centre(String, Number) -> Centered when
+ String :: string(),
+ Centered :: string(),
+ Number :: non_neg_integer().
+
+centre(String, Len) when is_integer(Len) -> centre(String, Len, $\s).
+
+-spec centre(String, Number, Character) -> Centered when
+ String :: string(),
+ Centered :: string(),
+ Number :: non_neg_integer(),
+ Character :: char().
+
+centre(String, 0, Char) when is_list(String), is_integer(Char) ->
+ []; % Strange cases to centre string
+centre(String, Len, Char) when is_integer(Char) ->
+ Slen = length(String),
+ if
+ Slen > Len -> substr(String, (Slen-Len) div 2 + 1, Len);
+ Slen < Len ->
+ N = (Len-Slen) div 2,
+ r_pad(l_pad(String, Len-(Slen+N), Char), N, Char);
+ Slen =:= Len -> String
+ end.
+
+%%% SUB_STRING %%%
+
+-spec sub_string(String, Start) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer().
+
+sub_string(String, Start) -> substr(String, Start).
+
+-spec sub_string(String, Start, Stop) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer(),
+ Stop :: pos_integer().
+
+sub_string(String, Start, Stop) -> substr(String, Start, Stop - Start + 1).
+
+%% ISO/IEC 8859-1 (latin1) letters are converted, others are ignored
+%%
+
+to_lower_char(C) when is_integer(C), $A =< C, C =< $Z ->
+ C + 32;
+to_lower_char(C) when is_integer(C), 16#C0 =< C, C =< 16#D6 ->
+ C + 32;
+to_lower_char(C) when is_integer(C), 16#D8 =< C, C =< 16#DE ->
+ C + 32;
+to_lower_char(C) ->
+ C.
+
+to_upper_char(C) when is_integer(C), $a =< C, C =< $z ->
+ C - 32;
+to_upper_char(C) when is_integer(C), 16#E0 =< C, C =< 16#F6 ->
+ C - 32;
+to_upper_char(C) when is_integer(C), 16#F8 =< C, C =< 16#FE ->
+ C - 32;
+to_upper_char(C) ->
+ C.
+
+-spec to_lower(String) -> Result when
+ String :: io_lib:latin1_string(),
+ Result :: io_lib:latin1_string()
+ ; (Char) -> CharResult when
+ Char :: char(),
+ CharResult :: char().
+
+to_lower(S) when is_list(S) ->
+ [to_lower_char(C) || C <- S];
+to_lower(C) when is_integer(C) ->
+ to_lower_char(C).
+
+-spec to_upper(String) -> Result when
+ String :: io_lib:latin1_string(),
+ Result :: io_lib:latin1_string()
+ ; (Char) -> CharResult when
+ Char :: char(),
+ CharResult :: char().
+
+to_upper(S) when is_list(S) ->
+ [to_upper_char(C) || C <- S];
+to_upper(C) when is_integer(C) ->
+ to_upper_char(C).
+
+-spec join(StringList, Separator) -> String when
+ StringList :: [string()],
+ Separator :: string(),
+ String :: string().
+
+join([], Sep) when is_list(Sep) ->
+ [];
+join([H|T], Sep) ->
+ H ++ lists:append([Sep ++ X || X <- T]).
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl
new file mode 100644
index 0000000000..dd3f88d7a8
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl
@@ -0,0 +1,115 @@
+%%
+%% File: syntax_tools_test.erl
+%% Author: Björn-Egil Dahlberg
+%% Created: 2014-10-23
+%%
+
+-module(syntax_tools_test).
+
+-export([foo1/0,foo2/2,foo3/0,foo4/3,foo5/1]).
+
+-include_lib("kernel/include/file.hrl").
+-record(state, { a, b, c, d}).
+-attribute([foo/0]).
+
+-define(attrib, some_attrib).
+
+-?attrib([foo2/2]).
+
+-define(macro_simple1, ok).
+-define(MACRO_SIMPLE2, (other)).
+-define(macro_simple3, ?MODULE).
+-define(macro_simple4, [?macro_simple3,?MODULE,?MACRO_SIMPLE2]).
+-define(macro_simple5, (process_info)).
+-define(macro_string, "hello world").
+-define(macro_argument1(X), (X + 3)).
+-define(macro_argument2(X,Y), (X + 3 * Y)).
+-define(macro_block(X), begin X end).
+-define(macro_if(X1,X2), if X1 -> X2; true -> none end).
+
+
+-ifdef(macro_def1).
+-define(macro_cond1, yep).
+-else.
+-define(macro_cond1, nope).
+-endif.
+-ifndef(macro_def2).
+-define(macro_cond2, nope).
+-else.
+-define(macro_cond2, yep).
+-endif.
+-undef(macro_def1).
+-undef(macro_def2).
+
+%% basic test
+foo1() ->
+ ok.
+
+%% macro test
+foo2(A,B) ->
+ % string combining ?
+ [?macro_string, ?macro_string
+ ?macro_string,
+ "hello world "
+ "more hello",
+ [?macro_simple1,
+ ?MACRO_SIMPLE2,
+ ?macro_simple3,
+ ?macro_simple4,
+ ?macro_simple5,
+ ?macro_string,
+ ?macro_cond1,
+ ?macro_cond2,
+ ?macro_block(A),
+ ?macro_if(A,B),
+ ?macro_argument1(A),
+ ?macro_argument1(begin A end),
+ ?macro_block(<<"hello">>),
+ ?macro_block("hello"),
+ ?macro_block([$h,$e,$l,$l,$0]),
+ ?macro_argument1(id(<<"hello">>)),
+ ?macro_argument1(if A -> B; true -> 3.14 end),
+ ?macro_argument1(case A of ok -> B; C -> C end),
+ ?macro_argument1(receive M -> M after 100 -> 3 end),
+ ?macro_argument1(try foo5(A) catch C:?macro_simple5 -> {C,B} end),
+ ?macro_argument2(A,B)],
+ A,B,ok].
+
+id(I) -> I.
+%% basic terms
+
+foo3() ->
+ [atom,
+ 'some other atom',
+ {tuple,1,2,3},
+ 1,2,3,3333,
+ 3,3333,2,1,
+ [$a,$b,$c],
+ "hello world",
+ <<"hello world">>,
+ <<1,2,3,4,5:6>>,
+ 3.1415,
+ 1.03e33].
+
+%% application and records
+
+foo4(A,B,#state{c = C}=S) ->
+ Ls = foo3(),
+ S1 = #state{ a = 1, b = 2 },
+ [foo2(A,Ls),B,C,
+ B(3,C),
+ erlang:process_info(self()),
+ erlang:?macro_simple5(self()),
+ A:?MACRO_SIMPLE2(),
+ A:?macro_simple1(),
+ A:process_info(self()),
+ A:B(3),
+ S#state{ a = 2, b = B, d = S1 }].
+
+foo5(A) ->
+ try foo2(A,A) of
+ R -> R
+ catch
+ error:?macro_simple5 ->
+ nope
+ end.
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index cf396ce636..673362d01d 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.17
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index 556fe94a2a..68dc1fec88 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -32,6 +32,86 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The source code to html code generator in Test Server
+ (and Common Test) would fail to generate anchors in the
+ html code for functions with non-expandable macros,
+ resulting in bad html links to such functions. This
+ correction lets the code generator ignore macros that
+ can't be expanded (i.e. not pre-process them), so that
+ correct anchors will always be produced.</p>
+ <p>
+ Own Id: OTP-11766 Aux Id: seq12556 </p>
+ </item>
+ <item>
+ <p>
+ Make sure to install .hrl files when needed</p>
+ <p>
+ Own Id: OTP-12197</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Distribute <c>autoconf</c> helpers to applications at
+ build time instead of having multiple identical copies
+ committed in the repository.</p>
+ <p>
+ Own Id: OTP-12348</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/Makefile b/lib/test_server/src/Makefile
index ab4dd4d95d..35bbad3c22 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -124,7 +124,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)/src"
$(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src"
- $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src"
+ $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(TS_HRL_FILES) "$(RELSYSDIR)/src"
$(INSTALL_DIR) "$(RELSYSDIR)/include"
$(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include"
$(INSTALL_DIR) "$(RELSYSDIR)/ebin"
diff --git a/lib/test_server/src/config.guess b/lib/test_server/src/config.guess
deleted file mode 100755
index f475ceb413..0000000000
--- a/lib/test_server/src/config.guess
+++ /dev/null
@@ -1,1534 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-#
-# Originally written by Per Bothner.
-#
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-#
-# Please send patches with a ChangeLog entry to [email protected].
-
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# ([email protected] 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:Bitrig:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # [email protected] (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH="x86_64"
- fi
- fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[4567])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep -q __LP64__
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- aarch64_be:Linux:*:*)
- UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_PCS_VFP
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
- fi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- or32:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
- # Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
- # this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- OS_REL='.3'
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <[email protected]>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
- x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
- exit ;;
-esac
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <[email protected]> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/lib/test_server/src/config.sub b/lib/test_server/src/config.sub
deleted file mode 100755
index bb6edbdb47..0000000000
--- a/lib/test_server/src/config.sub
+++ /dev/null
@@ -1,1789 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-
-
-# Please send patches with a ChangeLog entry to [email protected].
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | be32 | be64 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 \
- | or1k | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pyramid \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | we32k \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
- ;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- xscaleeb)
- basic_machine=armeb-unknown
- ;;
-
- xscaleel)
- basic_machine=armel-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pyramid-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i386-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
- ;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -dicos*)
- os=-dicos
- ;;
- -nacl*)
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- hexagon-*)
- os=-elf
- ;;
- tic54x-*)
- os=-coff
- ;;
- tic55x-*)
- os=-coff
- ;;
- tic6x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or1k-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -cnk*|-aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
-
diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in
index cd723bcd4d..8398825d95 100644
--- a/lib/test_server/src/configure.in
+++ b/lib/test_server/src/configure.in
@@ -357,7 +357,23 @@ AC_CHECK_FUNCS(usleep)
# First check if the library is available, then if we can choose between
# two versions of gethostbyname
AC_HAVE_LIBRARY(resolv)
-AC_CHECK_LIB(resolv, res_gethostbyname,[DEFS="$DEFS -DHAVE_RES_GETHOSTBYNAME=1"])
+AC_CHECK_LIB(resolv, res_gethostbyname,[AC_DEFINE(HAVE_RES_GETHOSTBYNAME,1)])
+
+#--------------------------------------------------------------------
+# Check for isfinite
+#--------------------------------------------------------------------
+
+AC_MSG_CHECKING([for isfinite])
+AC_TRY_LINK([#include <math.h>],
+ [isfinite(0);], have_isfinite=yes, have_isfinite=no)
+
+if test $have_isfinite = yes; then
+ AC_DEFINE(HAVE_ISFINITE,1)
+ AC_MSG_RESULT(yes)
+else
+ AC_DEFINE(HAVE_FINITE,1)
+ AC_MSG_RESULT(no)
+fi
#--------------------------------------------------------------------
# Emulator compatible flags (for drivers)
diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl
index 952036502a..7cfaa2c325 100644
--- a/lib/test_server/src/erl2html2.erl
+++ b/lib/test_server/src/erl2html2.erl
@@ -22,11 +22,11 @@
%%%------------------------------------------------------------------
-module(erl2html2).
--export([convert/2, convert/3]).
+-export([convert/3, convert/4]).
-convert([], _Dest) -> % Fake clause.
+convert([], _Dest, _InclPath) -> % Fake clause.
ok;
-convert(File, Dest) ->
+convert(File, Dest, InclPath) ->
%% The generated code uses the BGCOLOR attribute in the
%% BODY tag, which wasn't valid until HTML 3.2. Also,
%% good HTML should either override all colour attributes
@@ -48,12 +48,12 @@ convert(File, Dest) ->
"</head>\n\n"
"<body bgcolor=\"white\" text=\"black\""
" link=\"blue\" vlink=\"purple\" alink=\"red\">\n"],
- convert(File, Dest, Header).
+ convert(File, Dest, InclPath, Header).
-convert(File, Dest, Header) ->
+convert(File, Dest, InclPath, Header) ->
%% statistics(runtime),
- case parse_file(File) of
+ case parse_file(File, InclPath) of
{ok,Functions} ->
%% {_, Time1} = statistics(runtime),
%% io:format("Parsed file in ~.2f Seconds.~n",[Time1/1000]),
@@ -88,34 +88,75 @@ convert(File, Dest, Header) ->
%%%
%%% All function clauses are also marked in order to allow
%%% possibly_enhance/2 to write these in bold.
-parse_file(File) ->
- case epp:open(File, [], []) of
+%%%
+%%% Use expanded preprocessor directives if possible (epp). Only if
+%%% this fails, fall back on using non-expanded code (epp_dodger).
+
+parse_file(File, InclPath) ->
+ case epp:open(File, InclPath, []) of
{ok,Epp} ->
- Forms = parse_file(Epp,File,false),
- epp:close(Epp),
- {ok,Forms};
- {error,E} ->
- {error,E}
+ try parse_preprocessed_file(Epp,File,false) of
+ Forms ->
+ epp:close(Epp),
+ {ok,Forms}
+ catch
+ _:{error,_Reason,true} ->
+ parse_non_preprocessed_file(File);
+ _:{error,_Reason,false} ->
+ {ok,[]}
+ end;
+ Error = {error,_} ->
+ Error
end.
-
-parse_file(Epp,File,InCorrectFile) ->
+parse_preprocessed_file(Epp,File,InCorrectFile) ->
case epp:parse_erl_form(Epp) of
{ok,Form} ->
case Form of
{attribute,_,file,{File,_}} ->
- parse_file(Epp,File,true);
+ parse_preprocessed_file(Epp,File,true);
{attribute,_,file,{_OtherFile,_}} ->
- parse_file(Epp,File,false);
+ parse_preprocessed_file(Epp,File,false);
{function,L,F,A,[_|C]} when InCorrectFile ->
Clauses = [{clause,CL} || {clause,CL,_,_,_} <- C],
[{atom_to_list(F),A,L} | Clauses] ++
- parse_file(Epp,File,true);
+ parse_preprocessed_file(Epp,File,true);
+ _ ->
+ parse_preprocessed_file(Epp,File,InCorrectFile)
+ end;
+ {error,Reason={_L,epp,{undefined,_Macro,none}}} ->
+ throw({error,Reason,InCorrectFile});
+ {error,_Reason} ->
+ parse_preprocessed_file(Epp,File,InCorrectFile);
+ {eof,_Location} ->
+ []
+ end.
+
+parse_non_preprocessed_file(File) ->
+ case file:open(File, []) of
+ {ok,Epp} ->
+ Forms = parse_non_preprocessed_file(Epp, File, 1),
+ file:close(Epp),
+ {ok,Forms};
+ Error = {error,_E} ->
+ Error
+ end.
+
+parse_non_preprocessed_file(Epp, File, Location) ->
+ case epp_dodger:parse_form(Epp, Location) of
+ {ok,Tree,Location1} ->
+ try erl_syntax:revert(Tree) of
+ {function,L,F,A,[_|C]} ->
+ Clauses = [{clause,CL} || {clause,CL,_,_,_} <- C],
+ [{atom_to_list(F),A,L} | Clauses] ++
+ parse_non_preprocessed_file(Epp, File, Location1);
_ ->
- parse_file(Epp,File,InCorrectFile)
+ parse_non_preprocessed_file(Epp, File, Location1)
+ catch
+ _:_ -> parse_non_preprocessed_file(Epp, File, Location1)
end;
- {error,_E} ->
- parse_file(Epp,File,InCorrectFile);
+ {error,_E,Location1} ->
+ parse_non_preprocessed_file(Epp, File, Location1);
{eof,_Location} ->
[]
end.
diff --git a/lib/test_server/src/install-sh b/lib/test_server/src/install-sh
deleted file mode 100755
index a5897de6ea..0000000000
--- a/lib/test_server/src/install-sh
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
- --help display this help and exit.
- --version display version info and exit.
-
- -c (ignored)
- -C install only if different (preserve the last data modification time)
- -d create directories instead of installing files.
- -g GROUP $chgrpprog installed files to GROUP.
- -m MODE $chmodprog installed files to MODE.
- -o USER $chownprog installed files to USER.
- -s $stripprog installed files.
- -t DIRECTORY install into DIRECTORY.
- -T report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
- RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) ;;
-
- -C) copy_on_change=true;;
-
- -d) dir_arg=true;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
-
- -o) chowncmd="$chownprog $2"
- shift;;
-
- -s) stripcmd=$stripprog;;
-
- -t) dst_arg=$2
- shift;;
-
- -T) no_target_directory=true;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
- shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dst_arg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dst_arg"
- shift # fnord
- fi
- shift # arg
- dst_arg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dst_arg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix='/';;
- -*) prefix='./';;
- *) prefix='';;
- esac
-
- eval "$initialize_posix_glob"
-
- oIFS=$IFS
- IFS=/
- $posix_glob set -f
- set fnord $dstdir
- shift
- $posix_glob set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # If -C, don't bother to copy if it wouldn't change the file.
- if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
- set X $old && old=:$2:$4:$5:$6 &&
- set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
- test "$old" = "$new" &&
- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
- then
- rm -f "$dsttmp"
- else
- # Rename the file to the real destination.
- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
- {
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- fi || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/lib/test_server/src/test_server.app.src b/lib/test_server/src/test_server.app.src
index 5672baa6ef..173f7075db 100644
--- a/lib/test_server/src/test_server.app.src
+++ b/lib/test_server/src/test_server.app.src
@@ -34,5 +34,5 @@
{env, []},
{runtime_dependencies, ["tools-2.6.14","stdlib-2.0","runtime_tools-1.8.14",
"observer-2.0","kernel-3.0","inets-5.10",
- "erts-6.0"]}]}.
+ "syntax_tools-1.6.16","erts-6.0"]}]}.
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..488f38d05d 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>" ++
@@ -1903,15 +1927,20 @@ html_possibly_convert(Src, SrcInfo, Dest) ->
{ok,DestInfo} when DestInfo#file_info.mtime >= SrcInfo#file_info.mtime ->
ok; % dest file up to date
_ ->
+ InclPath = case application:get_env(test_server, include) of
+ {ok,Incls} -> Incls;
+ _ -> []
+ end,
+
OutDir = get(test_server_log_dir_base),
case test_server_sup:framework_call(get_html_wrapper,
["Module "++Src,false,
OutDir,undefined,
encoding(Src)], "") of
Empty when (Empty == "") ; (element(2,Empty) == "") ->
- erl2html2:convert(Src, Dest);
+ erl2html2:convert(Src, Dest, InclPath);
{_,Header,_} ->
- erl2html2:convert(Src, Dest, Header)
+ erl2html2:convert(Src, Dest, InclPath, Header)
end
end.
@@ -5087,15 +5116,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});
-
-cover_compile({App,CoverFile}) ->
- {Exclude,Include,Cross} = read_cover_file(CoverFile),
- 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_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 +5192,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 +5245,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 +5264,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/test/erl2html2_SUITE.erl b/lib/test_server/test/erl2html2_SUITE.erl
index 37c2b74d8e..908985c879 100644
--- a/lib/test_server/test/erl2html2_SUITE.erl
+++ b/lib/test_server/test/erl2html2_SUITE.erl
@@ -161,7 +161,7 @@ convert_module(Mod,Config) ->
Src = filename:join(DataDir,Mod++".erl"),
Dst = filename:join(PrivDir,Mod++".erl.html"),
io:format("<a href=\"~s\">~s</a>\n",[Src,filename:basename(Src)]),
- ok = erl2html2:convert(Src, Dst, "<html><body>"),
+ ok = erl2html2:convert(Src, Dst, [], "<html><body>"),
io:format("<a href=\"~s\">~s</a>\n",[Dst,filename:basename(Dst)]),
{Src,Dst}.
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 4eb70aa2cd..18d7583c35 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.2
diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml
index 3ebacf5546..73fd563fbd 100644
--- a/lib/tools/doc/src/eprof.xml
+++ b/lib/tools/doc/src/eprof.xml
@@ -35,7 +35,7 @@
used. The profiling is done using the Erlang trace BIFs. Tracing of
local function calls for a specified set of processes is enabled when
profiling is begun, and disabled when profiling is stopped.</p>
- <p>When using Eprof expect a slowdown in program execution.</p>
+ <p>When using Eprof, expect a slowdown in program execution.</p>
</description>
<funcs>
<func>
diff --git a/lib/tools/doc/src/fprof.xml b/lib/tools/doc/src/fprof.xml
index ef8b82c9fa..f83c049fcd 100644
--- a/lib/tools/doc/src/fprof.xml
+++ b/lib/tools/doc/src/fprof.xml
@@ -789,7 +789,7 @@ create_file_slow(FD, M, N) ->
function was first unsuspended and then garbage
collected. Otherwise the printout would show
<c>garbage_collect</c> being called from <c>suspend</c> but not
- not which function that might have caused the garbage
+ which function that might have caused the garbage
collection.
</p>
<p>Let us now get back to the test code:</p>
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 136e0a3127..6f9563bb68 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -30,6 +30,74 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a typo in erlang-mode comment.</p>
+ <p>
+ Own Id: OTP-12214</p>
+ </item>
+ <item>
+ <p>
+ Add a skeleton for -spec in Erlang mode for Emacs</p>
+ <p>
+ Own Id: OTP-12283</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Cover no longer crashes when compiling <c>receive</c> and
+ the like with just an <c>after</c> clause. Thanks to
+ José Valim for providing a fix.</p>
+ <p>
+ Own Id: OTP-12328</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.7</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add log2 histogram to lcnt for lock wait time</p>
+ <p>
+ Own Id: OTP-12059</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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-skels.el b/lib/tools/emacs/erlang-skels.el
index 7379215d68..78929ac510 100644
--- a/lib/tools/emacs/erlang-skels.el
+++ b/lib/tools/emacs/erlang-skels.el
@@ -31,6 +31,7 @@
("Module" "module" erlang-skel-module)
("Author" "author" erlang-skel-author)
("Function" "function" erlang-skel-function)
+ ("Spec" "spec" erlang-skel-spec)
()
("Small Header" "small-header"
erlang-skel-small-header erlang-skel-header)
@@ -54,6 +55,8 @@
erlang-skel-gen-event erlang-skel-header)
("gen_fsm" "gen-fsm"
erlang-skel-gen-fsm erlang-skel-header)
+ ("wx_object" "wx-object"
+ erlang-skel-wx-object erlang-skel-header)
("Library module" "gen-lib"
erlang-skel-lib erlang-skel-header)
("Corba callback" "gen-corba-cb"
@@ -147,6 +150,10 @@ Please see the function `tempo-define-template'.")
"*The template of a function skeleton.
Please see the function `tempo-define-template'.")
+(defvar erlang-skel-spec
+ '("-spec " (erlang-skel-get-function-name) "(" (erlang-skel-get-function-args) ") -> undefined.")
+ "*The template of a -spec for the function following point.
+Please see the function `tempo-define-template'.")
;; Attribute templates
@@ -577,7 +584,7 @@ Please see the function `tempo-define-template'.")
"-record(state, {})." n n
(erlang-skel-double-separator-start 3)
- "%%% gen_event callbacks" n
+ "%%% API" n
(erlang-skel-double-separator-end 3) n
(erlang-skel-separator-start 2)
"%% @doc" n
@@ -851,6 +858,137 @@ Please see the function `tempo-define-template'.")
"*The template of a gen_fsm.
Please see the function `tempo-define-template'.")
+(defvar erlang-skel-wx-object
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(wx_object)." n n
+
+ "-include_lib(\"wx/include/wx.hrl\")." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% wx_object callbacks" n
+ "-export([init/1, handle_call/3, handle_cast/2, "
+ "handle_info/2," n>
+ "handle_event/2, terminate/2, code_change/3])." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Starts the server" n
+ "%%" n
+ "%% @spec start_link() -> wxWindow()" n
+ (erlang-skel-separator-end 2)
+ "start_link() ->" n>
+ "wx_object:start_link(?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% wx_object callbacks" n
+ (erlang-skel-double-separator-end 3)
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Initializes the server" n
+ "%%" n
+ "%% @spec init(Args) -> {wxWindow(), State} |" n
+ "%% {wxWindow(), State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, Reason}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "wx:new()," n>
+ "Frame = wxFrame:new()," n>
+ "{Frame, #state{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling events" n
+ "%%" n
+ "%% @spec handle_event(wx{}, State) ->" n
+ "%% {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_event(#wx{}, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling call messages" n
+ "%%" n
+ "%% @spec handle_call(Request, From, State) ->" n
+ "%% {reply, Reply, State} |" n
+ "%% {reply, Reply, State, Timeout} |" n
+ "%% {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, Reply, State} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_call(_Request, _From, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling cast messages" n
+ "%%" n
+ "%% @spec handle_cast(Msg, State) -> {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_cast(_Msg, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling all non call/cast messages" n
+ "%%" n
+ "%% @spec handle_info(Info, State) -> {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_info(_Info, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called by a wx_object when it is about to" n
+ "%% terminate. It should be the opposite of Module:init/1 and do any" n
+ "%% necessary cleaning up. When it returns, the wx_object terminates" n
+ "%% with Reason. The return value is ignored." n
+ "%%" n
+ "%% @spec terminate(Reason, State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ "%%" n
+ "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
+ (erlang-skel-separator-end 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a generic server.
+Please see the function `tempo-define-template'.")
+
(defvar erlang-skel-lib
'((erlang-skel-include erlang-skel-large-header)
@@ -1546,6 +1684,16 @@ The first character of DD is space if the value is less than 10."
(substring date 4 7)
(substring date -4))))
+(defun erlang-skel-get-function-name ()
+ (save-excursion
+ (erlang-beginning-of-function -1)
+ (erlang-get-function-name)))
+
+(defun erlang-skel-get-function-args ()
+ (save-excursion
+ (erlang-beginning-of-function -1)
+ (erlang-get-function-arguments)))
+
;; Local variables:
;; coding: iso-8859-1
;; End:
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index ec5a1f4bc5..c56759ebb9 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -7,7 +7,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
@@ -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"
@@ -887,6 +886,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"flush_monitor_message"
"format_cpu_topology"
"fun_info"
+ "fun_info_mfa"
"fun_to_list"
"function_exported"
"garbage_collect_message_area"
@@ -899,7 +899,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/cover.erl b/lib/tools/src/cover.erl
index 113fa24bd5..31754015f7 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1696,6 +1696,8 @@ fix_expr(T, Line, Bump) when is_tuple(T) ->
fix_expr(E, _Line, _Bump) ->
E.
+fix_clauses([], _Line, _Bump) ->
+ [];
fix_clauses(Cs, Line, Bump) ->
case bumps_line(lists:last(Cs), Line) of
true ->
diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl
index 20ee32c861..d5ba8aa52f 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,25 +319,48 @@ 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),
- Print2 = filter_print(Print1, Opts),
- print_lock_information(Print2, proplists:get_value(print, Opts))
+ Print = filter_print(locks2print(Combos, Duration), Opts),
+ print_lock_information(Print, proplists:get_value(print, Opts))
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)
+ end, Combos),
+
+ {reply, ok, State};
+
handle_call(raw, _From, #state{ locks = Locks} = State)->
{reply, Locks, State};
@@ -347,7 +376,6 @@ handle_call(swap_pid_keys, _From, #state{ locks = Locks } = State)->
(L) ->
L
end, Locks),
-
{reply, ok, State#state{ locks = SwappedLocks}};
% settings
@@ -380,6 +408,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 +420,6 @@ handle_call(Command, _From, State) ->
%%
%% -------------------------------------------------------------------- %%
-handle_cast(stop, State) ->
- {stop, normal, State};
handle_cast(_, State) ->
{noreply, State}.
@@ -432,15 +460,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;
@@ -462,20 +507,22 @@ filter_locks(Locks, Lockname) ->
% 4. max length of locks
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).
+ 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, name) -> reverse_sort_locks(#print.name, Locks);
+sort_locks(Locks, id) -> reverse_sort_locks(#print.id, Locks);
+sort_locks(Locks, type) -> reverse_sort_locks(#print.type, Locks);
+sort_locks(Locks, tries) -> reverse_sort_locks(#print.tries, Locks);
+sort_locks(Locks, colls) -> reverse_sort_locks(#print.colls, Locks);
+sort_locks(Locks, ratio) -> reverse_sort_locks(#print.cr, Locks);
+sort_locks(Locks, time) -> reverse_sort_locks(#print.time, Locks);
+sort_locks(Locks, _) -> sort_locks(Locks, time).
+
+reverse_sort_locks(Ix, Locks) ->
+ lists:reverse(lists:keysort(Ix, Locks)).
% cut locks not above certain thresholds
threshold_locks(Locks, Thresholds) ->
@@ -556,45 +603,65 @@ 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(Vs) ->
+ [$||histogram_values_to_string(Vs,$|)].
+
+histogram_values_to_string([0|Vs],End) ->
+ [$\s|histogram_values_to_string(Vs,End)];
+histogram_values_to_string([V|Vs],End) when V > 0.66 ->
+ [$X|histogram_values_to_string(Vs,End)];
+histogram_values_to_string([V|Vs],End) when V > 0.33 ->
+ [$x|histogram_values_to_string(Vs,End)];
+histogram_values_to_string([_|Vs],End) ->
+ [$.|histogram_values_to_string(Vs,End)];
+histogram_values_to_string([],End) ->
+ [End].
+
%% state making
data2state(Data, State) ->
@@ -606,22 +673,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 +724,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 +783,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 +795,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 +807,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 +824,8 @@ print_header(Opts) ->
colls = "#collisions",
cr = "collisions [%]",
time = "time [us]",
- dtr = "duration [%]"
+ dtr = "duration [%]",
+ hist = "histogram [log2(us)]"
},
Divider = #print{
name = lists:duplicate(1 + length(Header#print.name), 45),
@@ -735,39 +836,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, 20, s(L#print.hist) } | format_lock(L, Opts)];
+ {histogram, W} -> [{left, W - length(s(L#print.hist)) - 1, 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 +885,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 +930,8 @@ 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([{left, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string(" ~~s~~~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 +948,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/cover_SUITE_data/b.erl b/lib/tools/test/cover_SUITE_data/b.erl
index 13f39b8cb9..0a418a58d8 100644
--- a/lib/tools/test/cover_SUITE_data/b.erl
+++ b/lib/tools/test/cover_SUITE_data/b.erl
@@ -1,5 +1,5 @@
-module(b).
--export([start/0, loop/0]).
+-export([start/0, loop/0, wait/0]).
start() ->
spawn(?MODULE, loop, []).
@@ -12,3 +12,9 @@ loop() ->
stop ->
done
end.
+
+%% This checks for a bug in expressions which have no
+%% "main" clauses (only after and friends) followed by
+%% a return value in the same line.
+wait() ->
+ receive after 1000 -> done end, ok.
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..d9651c30e3 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.6.14
+TOOLS_VSN = 2.7.1
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/aclocal.m4 b/lib/wx/aclocal.m4
deleted file mode 100644
index ed492d55ff..0000000000
--- a/lib/wx/aclocal.m4
+++ /dev/null
@@ -1,1954 +0,0 @@
-dnl
-dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
-dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
-dnl
-dnl %CopyrightEnd%
-dnl
-
-dnl
-dnl aclocal.m4
-dnl
-dnl Local macros used in configure.in. The Local Macros which
-dnl could/should be part of autoconf are prefixed LM_, macros specific
-dnl to the Erlang system are prefixed ERL_.
-dnl
-
-AC_DEFUN(LM_PRECIOUS_VARS,
-[
-
-dnl ERL_TOP
-AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory])
-
-dnl Tools
-AC_ARG_VAR(CC, [C compiler])
-AC_ARG_VAR(CFLAGS, [C compiler flags])
-AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags])
-AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler])
-AC_ARG_VAR(CPP, [C/C++ preprocessor])
-AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags])
-AC_ARG_VAR(CXX, [C++ compiler])
-AC_ARG_VAR(CXXFLAGS, [C++ compiler flags])
-AC_ARG_VAR(LD, [linker (is often overridden by configure)])
-AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)])
-AC_ARG_VAR(LIBS, [libraries])
-AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
-AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)])
-AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)])
-AC_ARG_VAR(RANLIB, [ranlib])
-AC_ARG_VAR(AR, [ar])
-AC_ARG_VAR(GETCONF, [getconf])
-
-dnl Cross system root
-AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)])
-
-dnl Cross compilation variables
-AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
-
-dnl Cross compilation variables for OSE
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)])
-AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file])
-AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
-
-])
-
-AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
-[
-erl_xcomp_without_sysroot=no
-if test "$cross_compiling" = "yes"; then
- test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes
- test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot"
-else
- erl_xcomp_sysroot=
- erl_xcomp_isysroot=
-fi
-])
-
-AC_DEFUN(LM_CHECK_GETCONF,
-[
-if test "$cross_compiling" != "yes"; then
- AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false])
-else
- dnl First check if we got a `<HOST>-getconf' in $PATH
- host_getconf="$host_alias-getconf"
- AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false])
- if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then
- dnl We should perhaps give up if we have'nt found it by now, but at
- dnl least in one Tilera MDE `getconf' under sysroot is a bourne
- dnl shell script which we can use. We try to find `<HOST>-getconf'
- dnl or `getconf' under sysconf, but only under sysconf since
- dnl `getconf' in $PATH is almost guaranteed to be for the build
- dnl machine.
- GETCONF=
- prfx="$erl_xcomp_sysroot"
- AC_PATH_TOOL([GETCONF], [getconf], [false],
- ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"])
- fi
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_WINDOWS_ENVIRONMENT
-dnl
-dnl
-dnl Tries to determine thw windows build environment, i.e.
-dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC
-dnl
-
-AC_DEFUN(LM_WINDOWS_ENVIRONMENT,
-[
-MIXED_CYGWIN=no
-MIXED_MSYS=no
-
-AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment)
-if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([Cygwin and VC])
- MIXED_CYGWIN_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
- elif test -x /usr/bin/msysinfo; then
- CFLAGS="-O2"
- MIXED_MSYS=yes
- AC_MSG_RESULT([MSYS and VC])
- MIXED_MSYS_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
-else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_VC=no
- MIXED_MSYS_VC=no
-fi
-AC_SUBST(MIXED_CYGWIN_VC)
-AC_SUBST(MIXED_MSYS_VC)
-
-MIXED_VC=no
-if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then
- MIXED_VC=yes
-fi
-
-AC_SUBST(MIXED_VC)
-
-if test "x$MIXED_MSYS" != "xyes"; then
- AC_MSG_CHECKING(for mixed cygwin and native MinGW environment)
- if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([yes])
- MIXED_CYGWIN_MINGW=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW"
- else
- AC_MSG_RESULT([undeterminable])
- AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
- fi
- else
- AC_MSG_RESULT([no])
- MIXED_CYGWIN_MINGW=no
- fi
-else
- MIXED_CYGWIN_MINGW=no
-fi
-AC_SUBST(MIXED_CYGWIN_MINGW)
-
-AC_MSG_CHECKING(if we mix cygwin with any native compiler)
-if test "X$MIXED_CYGWIN" = "Xyes"; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_CYGWIN)
-
-AC_MSG_CHECKING(if we mix msys with another native compiler)
-if test "X$MIXED_MSYS" = "Xyes" ; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
-AC_SUBST(MIXED_MSYS)
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_FIND_EMU_CC
-dnl
-dnl
-dnl Tries fairly hard to find a C compiler that can handle jump tables.
-dnl Defines the @EMU_CC@ variable for the makefiles and
-dnl inserts NO_JUMP_TABLE in the header if one cannot be found...
-dnl
-
-AC_DEFUN(LM_FIND_EMU_CC,
- [AC_CACHE_CHECK(for a compiler that handles jumptables,
- ac_cv_prog_emu_cc,
- [
-AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
-lbl1:
- return 1;
-lbl2:
- return 2;
-],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
-
-if test $ac_cv_prog_emu_cc = no; then
- for ac_progname in emu_cc.sh gcc-4.2 gcc; do
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_progname; then
- ac_cv_prog_emu_cc=$ac_dir/$ac_progname
- break
- fi
- done
- IFS="$ac_save_ifs"
- if test $ac_cv_prog_emu_cc != no; then
- break
- fi
- done
-fi
-
-if test $ac_cv_prog_emu_cc != no; then
- save_CC=$CC
- save_CFLAGS=$CFLAGS
- save_CPPFLAGS=$CPPFLAGS
- CC=$ac_cv_prog_emu_cc
- CFLAGS=""
- CPPFLAGS=""
- AC_TRY_COMPILE([],[
-#if defined(__clang_major__) && __clang_major__ >= 3
- /* clang 3.x or later is fine */
-#elif defined(__llvm__)
-#error "this version of llvm is unable to correctly compile beam_emu.c"
-#endif
- __label__ lbl1;
- __label__ lbl2;
- int x = magic();
- static void *jtab[2];
-
- jtab[0] = &&lbl1;
- jtab[1] = &&lbl2;
- goto *jtab[x];
- lbl1:
- return 1;
- lbl2:
- return 2;
- ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
- CC=$save_CC
- CFLAGS=$save_CFLAGS
- CPPFLAGS=$save_CPPFLAGS
-fi
-])
-if test $ac_cv_prog_emu_cc = no; then
- AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables])
- EMU_CC=$CC
-else
- EMU_CC=$ac_cv_prog_emu_cc
-fi
-AC_SUBST(EMU_CC)
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_INSTALL_DIR
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl Figure out how to create directories with parents.
-dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better)
-dnl
-dnl We prefer 'install -d', but use 'mkdir -p' if it exists.
-dnl If none of these methods works, we give up.
-dnl
-
-
-AC_DEFUN(LM_PROG_INSTALL_DIR,
-[AC_CACHE_CHECK(how to create a directory including parents,
-ac_cv_prog_mkdir_p,
-[
-temp_name_base=config.$$
-temp_name=$temp_name_base/x/y/z
-$INSTALL -d $temp_name >/dev/null 2>&1
-ac_cv_prog_mkdir_p=none
-if test -d $temp_name; then
- ac_cv_prog_mkdir_p="$INSTALL -d"
-else
- mkdir -p $temp_name >/dev/null 2>&1
- if test -d $temp_name; then
- ac_cv_prog_mkdir_p="mkdir -p"
- fi
-fi
-rm -fr $temp_name_base
-])
-
-case "${ac_cv_prog_mkdir_p}" in
- none) AC_MSG_ERROR(don't know how create directories with parents) ;;
- *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_PERL5
-dnl
-dnl Try to find perl version 5. If found set PERL to the absolute path
-dnl of the program, if not found set PERL to false.
-dnl
-dnl On some systems /usr/bin/perl is perl 4 and e.g.
-dnl /usr/local/bin/perl is perl 5. We try to handle this case by
-dnl putting a couple of
-dnl Tries to handle the case that there are two programs called perl
-dnl in the path and one of them is perl 5 and the other isn't.
-dnl
-AC_DEFUN(LM_PROG_PERL5,
-[AC_PATH_PROGS(PERL, perl5 perl, false,
- /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH})
-changequote(, )dnl
-dnl[ That bracket is needed to balance the right bracket below
-if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then
-changequote([, ])dnl
- ac_cv_path_PERL=false
- PERL=false
-dnl AC_MSG_WARN(perl version 5 not found)
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SO_BSDCOMPAT
-dnl
-dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux)
-dnl
-AC_DEFUN(LM_DECL_SO_BSDCOMPAT,
-[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat,
-AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;],
- ac_cv_decl_so_bsdcompat=yes,
- ac_cv_decl_so_bsdcompat=no))
-
-case "${ac_cv_decl_so_bsdcompat}" in
- "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[],
- [Define if you have SO_BSDCOMPAT flag on sockets]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_INADDR_LOOPBACK
-dnl
-dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default
-dnl
-
-AC_DEFUN(LM_DECL_INADDR_LOOPBACK,
-[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h],
- ac_cv_decl_inaddr_loopback,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>], [int i = INADDR_LOOPBACK;],
-ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no)
-])
-
-if test ${ac_cv_decl_inaddr_loopback} = no; then
- AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h],
- ac_cv_decl_inaddr_loopback_rpc,
- AC_TRY_COMPILE([#include <rpc/types.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_rpc=yes,
- ac_cv_decl_inaddr_loopback_rpc=no))
-
- case "${ac_cv_decl_inaddr_loopback_rpc}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[],
- [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;;
- * )
- AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h],
- ac_cv_decl_inaddr_loopback_winsock2,
- AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>],
- [int i = INADDR_LOOPBACK;],
- ac_cv_decl_inaddr_loopback_winsock2=yes,
- ac_cv_decl_inaddr_loopback_winsock2=no))
- case "${ac_cv_decl_inaddr_loopback_winsock2}" in
- "yes" )
- AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[],
- [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;;
- * )
- # couldn't find it anywhere
- AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[],
- [Define if you don't have a definition of INADDR_LOOPBACK]) ;;
- esac;;
- esac
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_SOCKADDR_SA_LEN
-dnl
-dnl Check if the sockaddr structure has the field sa_len
-dnl
-
-AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN,
-[AC_CACHE_CHECK([whether struct sockaddr has sa_len field],
- ac_cv_struct_sockaddr_sa_len,
-AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;],
- ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no))
-
-dnl FIXME convbreak
-case ${ac_cv_struct_sockaddr_sa_len} in
- "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;;
- *) ;;
-esac
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_EXCEPTION
-dnl
-dnl Check to see whether the system supports the matherr function
-dnl and its associated type "struct exception".
-dnl
-
-AC_DEFUN(LM_STRUCT_EXCEPTION,
-[AC_CACHE_CHECK([for struct exception (and matherr function)],
- ac_cv_struct_exception,
-AC_TRY_COMPILE([#include <math.h>],
- [struct exception x; x.type = DOMAIN; x.type = SING;],
- ac_cv_struct_exception=yes, ac_cv_struct_exception=no))
-
-case "${ac_cv_struct_exception}" in
- "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;;
- * ) ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_IPV6
-dnl
-dnl Check for ipv6 support and what the in6_addr structure is called.
-dnl (early linux used in_addr6 insted of in6_addr)
-dnl
-
-AC_DEFUN(LM_SYS_IPV6,
-[AC_MSG_CHECKING(for IP version 6 support)
-AC_CACHE_VAL(ac_cv_sys_ipv6_support,
-[ok_so_far=yes
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no)
-
-if test $ok_so_far = yes; then
- ac_cv_sys_ipv6_support=yes
-else
- AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif __OSE__
-#error "no ipv6"
-#else
-#include <netinet/in.h>
-#endif],
- [struct in_addr6 a6; struct sockaddr_in6 s6;],
- ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no)
-fi
-])dnl
-
-dnl
-dnl Have to use old style AC_DEFINE due to BC with old autoconf.
-dnl
-
-case ${ac_cv_sys_ipv6_support} in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- ;;
- in_addr6)
- AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)])
- AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present])
- AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this])
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
-esac
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_SYS_MULTICAST
-dnl
-dnl Check for multicast support. Only checks for multicast options in
-dnl setsockopt(), no check is performed that multicasting actually works.
-dnl If options are found defines HAVE_MULTICAST_SUPPORT
-dnl
-
-AC_DEFUN(LM_SYS_MULTICAST,
-[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support,
-[AC_EGREP_CPP(yes,
-[#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP)
-yes
-#endif
-], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)])
-if test $ac_cv_sys_multicast_support = yes; then
- AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1],
- [Define if setsockopt() accepts multicast options])
-fi
-])dnl
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_DECL_SYS_ERRLIST
-dnl
-dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared
-dnl in a system header file, stdio.h or errno.h.
-dnl
-
-AC_DEFUN(LM_DECL_SYS_ERRLIST,
-[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h],
- ac_cv_decl_sys_errlist,
-[AC_TRY_COMPILE([#include <stdio.h>
-#include <errno.h>], [char *msg = *(sys_errlist + 1);],
- ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)])
-if test $ac_cv_decl_sys_errlist = yes; then
- AC_DEFINE(SYS_ERRLIST_DECLARED,[],
- [define if the variable sys_errlist is declared in a system header file])
-fi
-])
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes
-dnl [, action-if-found [, action-if-not-found]]] )
-dnl
-dnl Checks if the declaration "declaration" of "funname" conflicts
-dnl with the header files idea of how the function should be
-dnl declared. It is useful on systems which lack prototypes and you
-dnl need to provide your own (e.g. when you want to take the address
-dnl of a function). The 4'th argument is expanded if conflicting,
-dnl the 5'th argument otherwise
-dnl
-dnl
-
-AC_DEFUN(LM_CHECK_FUNC_DECL,
-[AC_MSG_CHECKING([for conflicting declaration of $1])
-AC_CACHE_VAL(ac_cv_func_decl_$1,
-[AC_TRY_COMPILE([#include <stdio.h>
-$3],[$2
-char *c = (char *)$1;
-], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")])
-if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then
- AC_MSG_RESULT(yes)
- ifelse([$4], , :, [$4])
-else
- AC_MSG_RESULT(no)
-ifelse([$5], , , [$5
-])dnl
-fi
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl AC_DOUBLE_MIDDLE_ENDIAN
-dnl
-dnl Checks whether doubles are represented in "middle-endian" format.
-dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly,
-dnl as well as DOUBLE_MIDDLE_ENDIAN.
-dnl
-dnl
-
-AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN],
-[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian,
-[# It does not; compile a test program.
-AC_RUN_IFELSE(
-[AC_LANG_SOURCE([[#include <stdlib.h>
-
-int
-main(void)
-{
- int i = 0;
- int zero = 0;
- int bigendian;
- int zero_index = 0;
-
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
-
- /* we'll use the one with 32-bit words */
- union
- {
- double d;
- unsigned int c[2];
- } vint;
-
- union
- {
- double d;
- unsigned long c[2];
- } vlong;
-
- union
- {
- double d;
- unsigned short c[2];
- } vshort;
-
-
- /* Are we little or big endian? From Harbison&Steele. */
- u.l = 1;
- bigendian = (u.c[sizeof (long int) - 1] == 1);
-
- zero_index = bigendian ? 1 : 0;
-
- vint.d = 1.0;
- vlong.d = 1.0;
- vshort.d = 1.0;
-
- if (sizeof(unsigned int) == 4)
- {
- if (vint.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned long) == 4)
- {
- if (vlong.c[zero_index] != 0)
- zero = 1;
- }
- else if (sizeof(unsigned short) == 4)
- {
- if (vshort.c[zero_index] != 0)
- zero = 1;
- }
-
- exit (zero);
-}
-]])],
- [ac_cv_c_double_middle_endian=no],
- [ac_cv_c_double_middle_endian=yes],
- [ac_cv_c_double_middle=unknown])])
-case $ac_cv_c_double_middle_endian in
- yes)
- m4_default([$1],
- [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1,
- [Define to 1 if your processor stores the words in a double in
- middle-endian format (like some ARMs).])]) ;;
- no)
- $2 ;;
- *)
- m4_default([$3],
- [AC_MSG_WARN([unknown double endianness
-presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;;
-esac
-])# AC_C_DOUBLE_MIDDLE_ENDIAN
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_CHECK_THR_LIB
-dnl
-dnl This macro may be used by any OTP application.
-dnl
-dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also
-dnl checks for some pthread headers which will appear in DEFS or config.h.
-dnl
-
-AC_DEFUN(LM_CHECK_THR_LIB,
-[
-
-NEED_NPTL_PTHREAD_H=no
-
-dnl win32?
-AC_MSG_CHECKING([for native win32 threads])
-if test "X$host_os" = "Xwin32"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DWIN32_THREADS"
- THR_LIBS=
- THR_LIB_NAME=win32_threads
- THR_LIB_TYPE=win32_threads
-elif test "X$host_os" = "Xose"; then
- AC_MSG_RESULT(yes)
- THR_DEFS="-DOSE_THREADS"
- THR_LIBS=
- THR_LIB_NAME=ose_threads
- THR_LIB_TYPE=ose_threads
-else
- AC_MSG_RESULT(no)
- THR_DEFS=
- THR_LIBS=
- THR_LIB_NAME=
- THR_LIB_TYPE=posix_unknown
-
-dnl Try to find POSIX threads
-
-dnl The usual pthread lib...
- AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread")
-
-dnl Very old versions of FreeBSD have pthreads in special c library, c_r...
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r")
- fi
-
-dnl QNX has pthreads in standard C library
- if test "x$THR_LIBS" = "x"; then
- AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed")
- fi
-
-dnl On ofs1 the '-pthread' switch should be used
- if test "x$THR_LIBS" = "x"; then
- AC_MSG_CHECKING([if the '-pthread' switch can be used])
- saved_cflags=$CFLAGS
- CFLAGS="$CFLAGS -pthread"
- AC_TRY_LINK([#include <pthread.h>],
- pthread_create((void*)0,(void*)0,(void*)0,(void*)0);,
- [THR_DEFS="-pthread"
- THR_LIBS="-pthread"])
- CFLAGS=$saved_cflags
- if test "x$THR_LIBS" != "x"; then
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- if test "x$THR_LIBS" != "x"; then
- THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS"
- THR_LIB_NAME=pthread
- if test "x$THR_LIBS" = "xnone_needed"; then
- THR_LIBS=
- fi
- case $host_os in
- solaris*)
- THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;;
- linux*)
- THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS"
-
- LM_CHECK_GETCONF
- AC_MSG_CHECKING(for Native POSIX Thread Library)
- libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null`
- if test $? -eq 0; then
- case "$libpthr_vsn" in
- *nptl*|*NPTL*) nptl=yes;;
- *) nptl=no;;
- esac
- elif test "$cross_compiling" = "yes"; then
- case "$erl_xcomp_linux_nptl" in
- "") nptl=cross;;
- yes|no) nptl=$erl_xcomp_linux_nptl;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);;
- esac
- else
- nptl=no
- fi
- AC_MSG_RESULT($nptl)
- if test $nptl = cross; then
- nptl=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $nptl = yes; then
- THR_LIB_TYPE=posix_nptl
- need_nptl_incldir=no
- AC_CHECK_HEADER(nptl/pthread.h,
- [need_nptl_incldir=yes
- NEED_NPTL_PTHREAD_H=yes])
- if test $need_nptl_incldir = yes; then
- # Ahh...
- nptl_path="$C_INCLUDE_PATH:$CPATH"
- if test X$cross_compiling != Xyes; then
- nptl_path="$nptl_path:/usr/local/include:/usr/include"
- else
- IROOT="$erl_xcomp_isysroot"
- test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot"
- test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot])
- nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include"
- fi
- nptl_ws_path=
- save_ifs="$IFS"; IFS=":"
- for dir in $nptl_path; do
- if test "x$dir" != "x"; then
- nptl_ws_path="$nptl_ws_path $dir"
- fi
- done
- IFS=$save_ifs
- nptl_incldir=
- for dir in $nptl_ws_path; do
- AC_CHECK_HEADER($dir/nptl/pthread.h,
- nptl_incldir=$dir/nptl)
- if test "x$nptl_incldir" != "x"; then
- THR_DEFS="$THR_DEFS -isystem $nptl_incldir"
- break
- fi
- done
- if test "x$nptl_incldir" = "x"; then
- AC_MSG_ERROR(Failed to locate nptl system include directory)
- fi
- fi
- fi
- ;;
- *) ;;
- esac
-
- dnl We sometimes need THR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS $THR_DEFS"
-
- dnl
- dnl Check for headers
- dnl
-
- AC_CHECK_HEADER(pthread.h,
- AC_DEFINE(HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- fi
-fi
-
-])
-
-AC_DEFUN(ERL_INTERNAL_LIBS,
-[
-
-ERTS_INTERNAL_X_LIBS=
-
-AC_CHECK_LIB(kstat, kstat_open,
-[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat])
-ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"])
-
-AC_SUBST(ERTS_INTERNAL_X_LIBS)
-
-])
-
-AC_DEFUN(ETHR_CHK_SYNC_OP,
-[
- AC_MSG_CHECKING([for $3-bit $1()])
- case "$2" in
- "1") sync_call="$1(&var);";;
- "2") sync_call="$1(&var, ($4) 0);";;
- "3") sync_call="$1(&var, ($4) 0, ($4) 0);";;
- esac
- have_sync_op=no
- AC_TRY_LINK([],
- [
- $4 res;
- volatile $4 var;
- res = $sync_call
- ],
- [have_sync_op=yes])
- test $have_sync_op = yes && $5
- AC_MSG_RESULT([$have_sync_op])
-])
-
-AC_DEFUN(ETHR_CHK_INTERLOCKED,
-[
- ilckd="$1"
- AC_MSG_CHECKING([for ${ilckd}()])
- case "$2" in
- "1") ilckd_call="${ilckd}(var);";;
- "2") ilckd_call="${ilckd}(var, ($3) 0);";;
- "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";;
- "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";;
- esac
- have_interlocked_op=no
- AC_TRY_LINK(
- [
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <intrin.h>
- ],
- [
- volatile $3 *var;
- volatile $3 arr[2];
-
- $ilckd_call
- return 0;
- ],
- [have_interlocked_op=yes])
- test $have_interlocked_op = yes && $4
- AC_MSG_RESULT([$have_interlocked_op])
-])
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_FIND_ETHR_LIB
-dnl
-dnl NOTE! This macro may be changed at any time! Should *only* be used by
-dnl ERTS!
-dnl
-dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link
-dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS
-dnl except that the ethread lib itself is not included), ETHR_DEFS to
-dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the
-dnl thread library which the ethread library is based on, and ETHR_LIB_NAME
-dnl to the name of the library where the ethread implementation is located.
-dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and
-dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS,
-dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the
-dnl empty string.
-dnl
-
-AC_DEFUN(ERL_FIND_ETHR_LIB,
-[
-
-AC_ARG_ENABLE(native-ethr-impls,
- AS_HELP_STRING([--disable-native-ethr-impls],
- [disable native ethread implementations]),
-[ case "$enableval" in
- no) disable_native_ethr_impls=yes ;;
- *) disable_native_ethr_impls=no ;;
- esac ], disable_native_ethr_impls=no)
-
-test "X$disable_native_ethr_impls" = "Xyes" &&
- AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations])
-
-AC_ARG_ENABLE(x86-out-of-order,
- AS_HELP_STRING([--enable-x86-out-of-order],
- [enable x86/x84_64 out of order support (default disabled)]))
-
-AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
- AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls],
- [prefer gcc native ethread implementations]),
-[ case "$enableval" in
- yes) enable_prefer_gcc_native_ethr_impls=yes ;;
- *) enable_prefer_gcc_native_ethr_impls=no ;;
- esac ], enable_prefer_gcc_native_ethr_impls=no)
-
-test $enable_prefer_gcc_native_ethr_impls = yes &&
- AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations])
-
-AC_ARG_WITH(libatomic_ops,
- AS_HELP_STRING([--with-libatomic_ops=PATH],
- [specify and prefer usage of libatomic_ops in the ethread library]))
-
-AC_ARG_WITH(with_sparc_memory_order,
- AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO],
- [specify sparc memory order (defaults to RMO)]))
-
-LM_CHECK_THR_LIB
-ERL_INTERNAL_LIBS
-
-ethr_have_native_atomics=no
-ethr_have_native_spinlock=no
-ETHR_THR_LIB_BASE="$THR_LIB_NAME"
-ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE"
-ETHR_DEFS="$THR_DEFS"
-ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS"
-ETHR_LIBS=
-ETHR_LIB_NAME=
-
-ethr_modified_default_stack_size=
-
-dnl Name of lib where ethread implementation is located
-ethr_lib_name=ethread
-
-case "$THR_LIB_NAME" in
-
- win32_threads)
- ETHR_THR_LIB_BASE_DIR=win
- # * _WIN32_WINNT >= 0x0400 is needed for
- # TryEnterCriticalSection
- # * _WIN32_WINNT >= 0x0403 is needed for
- # InitializeCriticalSectionAndSpinCount
- # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403.
- #
- # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it
- # and save it in ETHR_DEFS.
- found_win32_winnt=no
- for cppflag in $CPPFLAGS; do
- case $cppflag in
- -DWINVER*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- ;;
- -D_WIN32_WINNT*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- found_win32_winnt=yes
- ;;
- *)
- ;;
- esac
- done
- if test $found_win32_winnt = no; then
- AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
- fi
-
- AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- have_interlocked_op=no
- ethr_have_native_atomics=no
- else
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()]))
- ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()]))
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()]))
- test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes
-
- ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()]))
- fi
- test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
- ;;
-
- pthread|ose_threads)
- case "$THR_LIB_NAME" in
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
- ;;
- ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1,
- [Define if you have OSE style threads])
- ETHR_THR_LIB_BASE_DIR=ose
- AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI_H, 1,
- [Define if you have the "ose_spi/ose_spi.h" header file.]))
- ;;
- esac
- if test "x$THR_LIB_NAME" = "xpthread"; then
- case $host_os in
- openbsd*)
- # The default stack size is insufficient for our needs
- # on OpenBSD. We increase it to 256 kilo words.
- ethr_modified_default_stack_size=256;;
- linux*)
- ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE"
-
- if test X$cross_compiling = Xyes; then
- case X$erl_xcomp_linux_usable_sigusrx in
- X) usable_sigusrx=cross;;
- Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);;
- esac
- case X$erl_xcomp_linux_usable_sigaltstack in
- X) usable_sigaltstack=cross;;
- Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;;
- *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);;
- esac
- else
- # FIXME: Test for actual problems instead of kernel versions
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
- usable_sigusrx=no
- usable_sigaltstack=no;;
- 2.[[2-3]]|2.[[2-3]].*)
- usable_sigusrx=yes
- usable_sigaltstack=no;;
- *)
- usable_sigusrx=yes
- usable_sigaltstack=yes;;
- esac
- fi
-
- AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
- AC_MSG_RESULT($usable_sigusrx)
- if test $usable_sigusrx = cross; then
- usable_sigusrx=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigusrx = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX"
- fi
-
- AC_MSG_CHECKING(if sigaltstack can be used)
- AC_MSG_RESULT($usable_sigaltstack)
- if test $usable_sigaltstack = cross; then
- usable_sigaltstack=yes
- AC_MSG_WARN([result yes guessed because of cross compilation])
- fi
- if test $usable_sigaltstack = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
- fi
- ;;
- *) ;;
- esac
-
- fi
- dnl We sometimes need ETHR_DEFS in order to find certain headers
- dnl (at least for pthread.h on osf1).
- saved_cppflags="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $ETHR_DEFS"
-
- dnl We need the thread library in order to find some functions
- saved_libs="$LIBS"
- LIBS="$LIBS $ETHR_X_LIBS"
-
- dnl
- dnl Check for headers
- dnl
- AC_CHECK_HEADER(pthread.h, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
-[Define if you have the <pthread.h> header file.]))
-
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, \
- AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \
-[Define if the pthread.h header file is in pthread/mit directory.]))
-
- if test $NEED_NPTL_PTHREAD_H = yes; then
- AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \
-[Define if you need the <nptl/pthread.h> header file.])
- fi
-
- AC_CHECK_HEADER(sched.h, \
- AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \
-[Define if you have the <sched.h> header file.]))
-
- AC_CHECK_HEADER(sys/time.h, \
- AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \
-[Define if you have the <sys/time.h> header file.]))
-
- AC_TRY_COMPILE([#include <time.h>
- #include <sys/time.h>],
- [struct timeval *tv; return 0;],
- AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \
-[Define if you can safely include both <sys/time.h> and <time.h>.]))
-
-
- dnl
- dnl Check for functions
- dnl
- if test "x$THR_LIB_NAME" = "xpthread"; then
- AC_CHECK_FUNC(pthread_spin_lock, \
- [ethr_have_native_spinlock=yes \
- AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
-[Define if you have the pthread_spin_lock function.])])
-
- have_sched_yield=no
- have_librt_sched_yield=no
- AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes])
- if test $have_sched_yield = no; then
- AC_CHECK_LIB(rt, sched_yield,
- [have_librt_sched_yield=yes
- ETHR_X_LIBS="$ETHR_X_LIBS -lrt"])
- fi
- if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then
- AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.])
- AC_MSG_CHECKING([whether sched_yield() returns an int])
- sched_yield_ret_int=no
- AC_TRY_COMPILE([
- #ifdef ETHR_HAVE_SCHED_H
- #include <sched.h>
- #endif
- ],
- [int sched_yield();],
- [sched_yield_ret_int=yes])
- AC_MSG_RESULT([$sched_yield_ret_int])
- if test $sched_yield_ret_int = yes; then
- AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.])
- fi
- fi
-
- have_pthread_yield=no
- AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes])
- if test $have_pthread_yield = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.])
- AC_MSG_CHECKING([whether pthread_yield() returns an int])
- pthread_yield_ret_int=no
- AC_TRY_COMPILE([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [int pthread_yield();],
- [pthread_yield_ret_int=yes])
- AC_MSG_RESULT([$pthread_yield_ret_int])
- if test $pthread_yield_ret_int = yes; then
- AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.])
- fi
- fi
-
- have_pthread_rwlock_init=no
- AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes])
- if test $have_pthread_rwlock_init = yes; then
-
- ethr_have_pthread_rwlockattr_setkind_np=no
- AC_CHECK_FUNC(pthread_rwlockattr_setkind_np,
- [ethr_have_pthread_rwlockattr_setkind_np=yes])
-
- if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \
-[Define if you have the pthread_rwlockattr_setkind_np() function.])
-
- AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP])
- ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no
- AC_TRY_LINK([
- #if defined(ETHR_NEED_NPTL_PTHREAD_H)
- #include <nptl/pthread.h>
- #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
- #include <pthread/mit/pthread.h>
- #elif defined(ETHR_HAVE_PTHREAD_H)
- #include <pthread.h>
- #endif
- ],
- [
- pthread_rwlockattr_t *attr;
- return pthread_rwlockattr_setkind_np(attr,
- PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
- ],
- [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes])
- AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np])
- if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \
-[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.])
- fi
- fi
- fi
-
- if test "$force_pthread_rwlocks" = "yes"; then
-
- AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \
-[Define if you want to force usage of pthread rwlocks])
-
- if test $have_pthread_rwlock_init = yes; then
- AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.])
- else
- AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found])
- fi
- fi
-
- AC_CHECK_FUNC(pthread_attr_setguardsize, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \
-[Define if you have the pthread_attr_setguardsize function.]))
-
- linux_futex=no
- AC_MSG_CHECKING([for Linux futexes])
- AC_TRY_LINK([
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/futex.h>
- #include <sys/time.h>
- ],
- [
- int i = 1;
- syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1,
- (void*)0,(void*)0, 0);
- syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0,
- (void*)0,(void*)0, 0);
- return 0;
- ],
- linux_futex=yes)
- AC_MSG_RESULT([$linux_futex])
- test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
-
- fi
-
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_CHECK_SIZEOF(long long)
- AC_CHECK_SIZEOF(__int128_t)
-
- if test "$ac_cv_sizeof_int" = "4"; then
- int32="int"
- elif test "$ac_cv_sizeof_long" = "4"; then
- int32="long"
- elif test "$ac_cv_sizeof_long_long" = "4"; then
- int32="long long"
- else
- AC_MSG_ERROR([No 32-bit type found])
- fi
-
- if test "$ac_cv_sizeof_int" = "8"; then
- int64="int"
- elif test "$ac_cv_sizeof_long" = "8"; then
- int64="long"
- elif test "$ac_cv_sizeof_long_long" = "8"; then
- int64="long long"
- else
- AC_MSG_ERROR([No 64-bit type found])
- fi
-
- int128=no
- if test "$ac_cv_sizeof___int128_t" = "16"; then
- int128="__int128_t"
- fi
-
- if test "X$disable_native_ethr_impls" = "Xyes"; then
- ethr_have_native_atomics=no
- else
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers]))
-
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers]))
- test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes
- ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers]))
- ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers]))
-
- if test $int128 != no; then
- ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers]))
- fi
-
- AC_MSG_CHECKING([for a usable libatomic_ops implementation])
- case "x$with_libatomic_ops" in
- xno | xyes | x)
- libatomic_ops_include=
- ;;
- *)
- if test -d "${with_libatomic_ops}/include"; then
- libatomic_ops_include="-I$with_libatomic_ops/include"
- CPPFLAGS="$CPPFLAGS $libatomic_ops_include"
- else
- AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found])
- fi;;
- esac
- ethr_have_libatomic_ops=no
- AC_TRY_LINK([#include "atomic_ops.h"],
- [
- volatile AO_t x;
- AO_t y;
- int z;
-
- AO_nop_full();
- AO_store(&x, (AO_t) 0);
- z = AO_load(&x);
- z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1);
- ],
- [ethr_have_native_atomics=yes
- ethr_have_libatomic_ops=yes])
- AC_MSG_RESULT([$ethr_have_libatomic_ops])
- if test $ethr_have_libatomic_ops = yes; then
- AC_CHECK_SIZEOF(AO_t, ,
- [
- #include <stdio.h>
- #include "atomic_ops.h"
- ])
- AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used])
-
- AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations])
- if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations])
- fi
- ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include"
- elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then
- AC_MSG_ERROR([No usable libatomic_ops implementation found])
- fi
-
- case "$host_cpu" in
- sparc | sun4u | sparc64 | sun4v)
- case "$with_sparc_memory_order" in
- "TSO")
- AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);;
- "PSO")
- AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);;
- "RMO"|"")
- AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);;
- *)
- AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);;
- esac
- ethr_have_native_atomics=yes;;
- i86pc | i*86 | x86_64 | amd64)
- if test "$enable_x86_out_of_order" = "yes"; then
- AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized])
- fi
- ethr_have_native_atomics=yes;;
- macppc | ppc | powerpc | "Power Macintosh")
- ethr_have_native_atomics=yes;;
- tile)
- ethr_have_native_atomics=yes;;
- *)
- ;;
- esac
-
- fi
-
- test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes
-
- dnl Restore LIBS
- LIBS=$saved_libs
- dnl restore CPPFLAGS
- CPPFLAGS=$saved_cppflags
-
- ;;
- *)
- ;;
-esac
-
-AC_MSG_CHECKING([whether default stack size should be modified])
-if test "x$ethr_modified_default_stack_size" != "x"; then
- AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size])
- AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words])
-else
- AC_MSG_RESULT([no])
-fi
-
-if test "x$ETHR_THR_LIB_BASE" != "x"; then
- ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS"
- ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS"
- ETHR_LIB_NAME=$ethr_lib_name
-fi
-
-AC_CHECK_SIZEOF(void *)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers])
-
-AC_CHECK_SIZEOF(int)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int])
-AC_CHECK_SIZEOF(long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long])
-AC_CHECK_SIZEOF(long long)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long])
-AC_CHECK_SIZEOF(__int64)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64])
-AC_CHECK_SIZEOF(__int128_t)
-AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t])
-
-
-case X$erl_xcomp_bigendian in
- X) ;;
- Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);;
-esac
-
-AC_C_BIGENDIAN
-
-if test "$ac_cv_c_bigendian" = "yes"; then
- AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian])
-fi
-
-case X$erl_xcomp_double_middle_endian in
- X) ;;
- Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;;
- *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);;
-esac
-
-AC_C_DOUBLE_MIDDLE_ENDIAN
-
-ETHR_X86_SSE2_ASM=no
-case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in
- yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64)
- AC_MSG_CHECKING([for gcc sse2 asm support])
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -msse2"
- gcc_sse2_asm=no
- AC_TRY_COMPILE([],
- [
- long long x, *y;
- __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory");
- ],
- [gcc_sse2_asm=yes])
- CFLAGS="$save_CFLAGS"
- AC_MSG_RESULT([$gcc_sse2_asm])
- if test "$gcc_sse2_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements])
- ETHR_X86_SSE2_ASM=yes
- fi
- ;;
- *)
- ;;
-esac
-
-case "$GCC-$host_cpu" in
- yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64)
- gcc_dw_cmpxchg_asm=no
- AC_MSG_CHECKING([for gcc double word cmpxchg asm support])
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
- __asm__ __volatile__(
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "pushl %%ebx\n\t"
- "movl %8, %%ebx\n\t"
-#endif
-#if ETHR_SIZEOF_PTR == 4
- "lock; cmpxchg8b %0\n\t"
-#else
- "lock; cmpxchg16b %0\n\t"
-#endif
- "setz %3\n\t"
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "popl %%ebx\n\t"
-#endif
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]),
-#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__
- "r"(new[0])
-#else
- "b"(new[0])
-#endif
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then
- AC_TRY_COMPILE([],
- [
- char xchgd;
- long new[2], xchg[2], *p;
-#if !defined(__PIC__) || !__PIC__
-# error nope
-#endif
- __asm__ __volatile__(
- "pushl %%ebx\n\t"
- "movl (%7), %%ebx\n\t"
- "movl 4(%7), %%ecx\n\t"
- "lock; cmpxchg8b %0\n\t"
- "setz %3\n\t"
- "popl %%ebx\n\t"
- : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new)
- : "cc", "memory");
-
- ],
- [gcc_dw_cmpxchg_asm=yes])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code])
- fi
- fi
- AC_MSG_RESULT([$gcc_dw_cmpxchg_asm])
- if test "$gcc_dw_cmpxchg_asm" = "yes"; then
- AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction])
- fi;;
- *)
- ;;
-esac
-
-AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
-[Define if you have all ethread defines])
-
-AC_SUBST(ETHR_X_LIBS)
-AC_SUBST(ETHR_LIBS)
-AC_SUBST(ETHR_LIB_NAME)
-AC_SUBST(ETHR_DEFS)
-AC_SUBST(ETHR_THR_LIB_BASE)
-AC_SUBST(ETHR_THR_LIB_BASE_DIR)
-AC_SUBST(ETHR_X86_SSE2_ASM)
-
-])
-
-
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl ERL_TIME_CORRECTION
-dnl
-dnl In the presence of a high resolution realtime timer Erlang can adapt
-dnl its view of time relative to this timer. On solaris such a timer is
-dnl available with the syscall gethrtime(). On other OS's a fallback
-dnl solution using times() is implemented. (However on e.g. FreeBSD times()
-dnl is implemented using gettimeofday so it doesn't make much sense to
-dnl use it there...) On second thought, it seems to be safer to do it the
-dnl other way around. I.e. only use times() on OS's where we know it will
-dnl work...
-dnl
-
-AC_DEFUN(ERL_TIME_CORRECTION,
-[if test x$ac_cv_func_gethrtime = x; then
- AC_CHECK_FUNC(gethrtime)
-fi
-if test x$clock_gettime_correction = xunknown; then
- AC_TRY_COMPILE([#include <time.h>],
- [struct timespec ts;
- long long result;
- clock_gettime(CLOCK_MONOTONIC,&ts);
- result = ((long long) ts.tv_sec) * 1000000000LL +
- ((long long) ts.tv_nsec);],
- clock_gettime_compiles=yes,
- clock_gettime_compiles=no)
-else
- clock_gettime_compiles=no
-fi
-
-
-AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction,
-[
-case $clock_gettime_correction in
- yes)
- erl_cv_time_correction=clock_gettime;;
- no|unknown)
- case $ac_cv_func_gethrtime in
- yes)
- erl_cv_time_correction=hrtime ;;
- no)
- case $host_os in
- linux*)
- case $clock_gettime_correction in
- unknown)
- if test x$clock_gettime_compiles = xyes; then
- if test X$cross_compiling != Xyes; then
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
- erl_cv_time_correction=times ;;
- *)
- erl_cv_time_correction=clock_gettime;;
- esac
- else
- case X$erl_xcomp_linux_clock_gettime_correction in
- X)
- erl_cv_time_correction=cross;;
- Xyes|Xno)
- if test $erl_xcomp_linux_clock_gettime_correction = yes; then
- erl_cv_time_correction=clock_gettime
- else
- erl_cv_time_correction=times
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);;
- esac
- fi
- else
- erl_cv_time_correction=times
- fi
- ;;
- *)
- erl_cv_time_correction=times ;;
- esac
- ;;
- *)
- erl_cv_time_correction=none ;;
- esac
- ;;
- esac
- ;;
-esac
-])
-
-xrtlib=""
-case $erl_cv_time_correction in
- times)
- AC_DEFINE(CORRECT_USING_TIMES,[],
- [Define if you do not have a high-res. timer & want to use times() instead])
- ;;
- clock_gettime|cross)
- if test $erl_cv_time_correction = cross; then
- erl_cv_time_correction=clock_gettime
- AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
- fi
- xrtlib="-lrt"
- AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
- [Define if you want to use clock_gettime to simulate gethrtime])
- ;;
-esac
-dnl
-dnl Check if gethrvtime is working, and if to use procfs ioctl
-dnl or (yet to be written) write to the procfs ctl file.
-dnl
-
-AC_MSG_CHECKING([if gethrvtime works and how to use it])
-AC_TRY_RUN([
-/* gethrvtime procfs ioctl test */
-/* These need to be undef:ed to not break activation of
- * micro level process accounting on /proc/self
- */
-#ifdef _LARGEFILE_SOURCE
-# undef _LARGEFILE_SOURCE
-#endif
-#ifdef _FILE_OFFSET_BITS
-# undef _FILE_OFFSET_BITS
-#endif
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/signal.h>
-#include <sys/fault.h>
-#include <sys/syscall.h>
-#include <sys/procfs.h>
-#include <fcntl.h>
-
-int main() {
- long msacct = PR_MSACCT;
- int fd;
- long long start, stop;
- int i;
- pid_t pid = getpid();
- char proc_self[30] = "/proc/";
-
- sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid);
- if ( (fd = open(proc_self, O_WRONLY)) == -1)
- exit(1);
- if (ioctl(fd, PIOCSET, &msacct) < 0)
- exit(2);
- if (close(fd) < 0)
- exit(3);
- start = gethrvtime();
- for (i = 0; i < 100; i++)
- stop = gethrvtime();
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
-}
-],
-erl_gethrvtime=procfs_ioctl,
-erl_gethrvtime=false,
-[
-case X$erl_xcomp_gethrvtime_procfs_ioctl in
- X)
- erl_gethrvtime=cross;;
- Xyes|Xno)
- if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then
- erl_gethrvtime=procfs_ioctl
- else
- erl_gethrvtime=false
- fi;;
- *)
- AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);;
-esac
-])
-
-case $erl_gethrvtime in
- procfs_ioctl)
- AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
- [define if gethrvtime() works and uses ioctl() to /proc/self])
- AC_MSG_RESULT(uses ioctl to procfs)
- ;;
- *)
- if test $erl_gethrvtime = cross; then
- erl_gethrvtime=false
- AC_MSG_RESULT(cross)
- AC_MSG_WARN([result 'not working' guessed because of cross compilation])
- else
- AC_MSG_RESULT(not working)
- fi
-
- dnl
- dnl Check if clock_gettime (linux) is working
- dnl
-
- AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time])
- save_libs=$LIBS
- LIBS="-lrt"
- AC_TRY_RUN([
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- int main() {
- long long start, stop;
- int i;
- struct timespec tp;
-
- if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0)
- exit(1);
- start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- for (i = 0; i < 100; i++)
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
- stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec;
- if (start == 0)
- exit(4);
- if (start == stop)
- exit(5);
- exit(0); return 0;
- }
- ],
- erl_clock_gettime=yes,
- erl_clock_gettime=no,
- [
- case X$erl_xcomp_clock_gettime_cpu_time in
- X) erl_clock_gettime=cross;;
- Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;;
- *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);;
- esac
- ])
- LIBS=$save_libs
- case $host_os in
- linux*)
- AC_MSG_RESULT([no; not stable])
- LIBRT=$xrtlib
- ;;
- *)
- AC_MSG_RESULT($erl_clock_gettime)
- case $erl_clock_gettime in
- yes)
- AC_DEFINE(HAVE_CLOCK_GETTIME,[],
- [define if clock_gettime() works for getting process time])
- LIBRT=-lrt
- ;;
- cross)
- erl_clock_gettime=no
- AC_MSG_WARN([result no guessed because of cross compilation])
- LIBRT=$xrtlib
- ;;
- *)
- LIBRT=$xrtlib
- ;;
- esac
- ;;
- esac
- AC_SUBST(LIBRT)
- ;;
-esac
-])dnl
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_TRY_ENABLE_CFLAG
-dnl
-dnl
-dnl Tries a CFLAG and sees if it can be enabled without compiler errors
-dnl $1: textual cflag to add
-dnl $2: variable to store the modified CFLAG in
-dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
-dnl
-dnl
-AC_DEFUN([LM_TRY_ENABLE_CFLAG], [
- AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
- saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $$2";
- AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false)
- CFLAGS=$saved_CFLAGS;
- if test "X$can_enable_flag" = "Xtrue"; then
- AC_MSG_RESULT([yes])
- AS_VAR_SET($2, "$1 $$2")
- else
- AC_MSG_RESULT([no])
- fi
-])
-
-dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY
-dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]])
-dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a
-dnl AC_LANG_JAVA instead...)
-AC_DEFUN(ERL_TRY_LINK_JAVA,
-[java_link='$JAVAC conftest.java 1>&AC_FD_CC'
-changequote(, )dnl
-cat > conftest.java <<EOF
-$1
-class conftest { public static void main(String[] args) {
- $2
- ; return; }}
-EOF
-changequote([, ])dnl
-if AC_TRY_EVAL(java_link) && test -s conftest.class; then
- ifelse([$3], , :, [rm -rf conftest*
- $3])
-else
- echo "configure: failed program was:" 1>&AC_FD_CC
- cat conftest.java 1>&AC_FD_CC
- echo "configure: PATH was $PATH" 1>&AC_FD_CC
-ifelse([$4], , , [ rm -rf conftest*
- $4
-])dnl
-fi
-rm -f conftest*])
-#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */
-
-
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/autoconf/config.guess b/lib/wx/autoconf/config.guess
deleted file mode 100755
index f475ceb413..0000000000
--- a/lib/wx/autoconf/config.guess
+++ /dev/null
@@ -1,1534 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-#
-# Originally written by Per Bothner.
-#
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-#
-# Please send patches with a ChangeLog entry to [email protected].
-
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# ([email protected] 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:Bitrig:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # [email protected] (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH="x86_64"
- fi
- fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[4567])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep -q __LP64__
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- aarch64_be:Linux:*:*)
- UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_PCS_VFP
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
- fi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- or32:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
- # Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
- # this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- OS_REL='.3'
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <[email protected]>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
- x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
- exit ;;
-esac
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <[email protected]> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/lib/wx/autoconf/config.sub b/lib/wx/autoconf/config.sub
deleted file mode 100755
index bb6edbdb47..0000000000
--- a/lib/wx/autoconf/config.sub
+++ /dev/null
@@ -1,1789 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-02-12'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program. This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-
-
-# Please send patches with a ChangeLog entry to [email protected].
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <[email protected]>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | be32 | be64 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 \
- | or1k | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pyramid \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | we32k \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
- ;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- xscaleeb)
- basic_machine=armeb-unknown
- ;;
-
- xscaleel)
- basic_machine=armel-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pyramid-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i386-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
- ;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -dicos*)
- os=-dicos
- ;;
- -nacl*)
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- hexagon-*)
- os=-elf
- ;;
- tic54x-*)
- os=-coff
- ;;
- tic55x-*)
- os=-coff
- ;;
- tic6x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or1k-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -cnk*|-aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
-
diff --git a/lib/wx/autoconf/install-sh b/lib/wx/autoconf/install-sh
deleted file mode 100755
index f694552bc2..0000000000
--- a/lib/wx/autoconf/install-sh
+++ /dev/null
@@ -1,258 +0,0 @@
-#! /bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-#
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-srcxtra=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- if [ $# -ne 1 ]; then
- srcxtra="$srcxtra $1"
- fi
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-srcxtra="$src $srcxtra"
-src=""
-dstsave=$dst
-
-if [ x"$dir_arg" != x ]; then
- srcxtra="$srcxtra $dst"
-fi
-
-# Now loop over $srcxtra
-
-for src in $srcxtra ; do
-
-dst=$dstsave
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi
-
-done &&
-
-
-exit 0
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..52087398e7 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -31,6 +31,82 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 1.3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a minor typo in the graphicsContext example.</p>
+ <p>
+ Own Id: OTP-12259</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Distribute <c>autoconf</c> helpers to applications at
+ build time instead of having multiple identical copies
+ committed in the repository.</p>
+ <p>
+ Own Id: OTP-12348</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Wx 1.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Implement --enable-sanitizers[=sanitizers]. Similar to
+ debugging with Valgrind, it's very useful to enable
+ -fsanitize= switches to catch bugs at runtime.</p>
+ <p>
+ Own Id: OTP-12153</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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/examples/demo/ex_graphicsContext.erl b/lib/wx/examples/demo/ex_graphicsContext.erl
index 59bfe7ff64..9047f1d135 100644
--- a/lib/wx/examples/demo/ex_graphicsContext.erl
+++ b/lib/wx/examples/demo/ex_graphicsContext.erl
@@ -54,7 +54,7 @@ do_init(Config) ->
%% Setup sizers
MainSizer = wxBoxSizer:new(?wxVERTICAL),
Sizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel,
- [{label, "wxGrapicsContext"}]),
+ [{label, "wxGraphicsContext"}]),
Win = wxPanel:new(Panel, []),
Pen = ?wxBLACK_PEN,
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/src/wxe_server.erl b/lib/wx/src/wxe_server.erl
index 465b9da2e0..153e2475ba 100644
--- a/lib/wx/src/wxe_server.erl
+++ b/lib/wx/src/wxe_server.erl
@@ -223,14 +223,18 @@ handle_connect(Object, #evh{handler=undefined, cb=Callback} = EvData0,
Error ->
{reply, Error, State0}
end;
-handle_connect(Object, EvData=#evh{handler=Handler},
+handle_connect(Object, EvData=#evh{handler=Handler},
From, State0 = #state{users=Users}) ->
%% Correct process is already listening just register it
put(Handler, From),
- User0 = #user{events=Listeners0} = gb_trees:get(From, Users),
- User = User0#user{events=[{Object,EvData}|Listeners0]},
- State = State0#state{users=gb_trees:update(From, User, Users)},
- {reply, ok, State}.
+ case gb_trees:lookup(From, Users) of
+ {value, User0 = #user{events=Listeners0}} ->
+ User = User0#user{events=[{Object,EvData}|Listeners0]},
+ State = State0#state{users=gb_trees:update(From, User, Users)},
+ {reply, ok, State};
+ none -> %% We are closing up the shop
+ {reply, {error, terminating}, State0}
+ end.
invoke_cb({{Ev=#wx{}, Ref=#wx_ref{}}, FunId,_}, _S) ->
%% Event callbacks
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/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl
index 076f16ba16..f9f8788d8f 100644
--- a/lib/wx/test/wx_event_SUITE.erl
+++ b/lib/wx/test/wx_event_SUITE.erl
@@ -336,12 +336,14 @@ connect_in_callback(Config) ->
end}]),
wxWindow:show(F1),
receive
- {continue, F1} -> Tester ! {continue, F1}
+ {continue, F1} ->
+ true = wxFrame:disconnect(F1, size),
+ Tester ! {continue, F1}
end
end,
- wxFrame:connect(Frame,size,
+ wxFrame:connect(Frame,show,
[{callback,
- fun(#wx{event=#wxSize{}},_SizeEv) ->
+ fun(#wx{event=#wxShow{}},_SizeEv) ->
io:format("Frame got size~n",[]),
spawn(TestWindow)
end}]),
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index 5523c20440..78c24ec093 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 1.2
+WX_VSN = 1.3.2
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)].
-