aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/appmon/src/Makefile4
-rw-r--r--lib/asn1/c_src/Makefile4
-rw-r--r--lib/asn1/c_src/asn1_erl_nif.c54
-rw-r--r--lib/asn1/doc/src/asn1_ug.xml120
-rw-r--r--lib/asn1/doc/src/asn1ct.xml55
-rw-r--r--lib/asn1/src/.gitignore2
-rw-r--r--lib/asn1/src/Makefile67
-rw-r--r--lib/asn1/src/asn1.app.src5
-rw-r--r--lib/asn1/src/asn1_records.hrl6
-rw-r--r--lib/asn1/src/asn1ct.erl150
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl96
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl131
-rw-r--r--lib/asn1/src/asn1ct_eval_ext.funcs1
-rw-r--r--lib/asn1/src/asn1ct_eval_per.funcs2
-rw-r--r--lib/asn1/src/asn1ct_eval_uper.funcs2
-rw-r--r--lib/asn1/src/asn1ct_func.erl105
-rw-r--r--lib/asn1/src/asn1ct_gen.erl143
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl392
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl392
-rw-r--r--lib/asn1/src/asn1ct_gen_per_rt2ct.erl314
-rw-r--r--lib/asn1/src/asn1ct_imm.erl160
-rw-r--r--lib/asn1/src/asn1ct_value.erl45
-rw-r--r--lib/asn1/src/asn1rt_ber_bin.erl525
-rw-r--r--lib/asn1/src/asn1rt_ber_bin_v2.erl1992
-rw-r--r--lib/asn1/src/asn1rt_check.erl360
-rw-r--r--lib/asn1/src/asn1rt_nif.erl25
-rw-r--r--lib/asn1/src/asn1rt_per_bin_rt2ct.erl1587
-rw-r--r--lib/asn1/src/asn1rt_uper_bin.erl1487
-rw-r--r--lib/asn1/src/asn1rtt_ber.erl1561
-rw-r--r--lib/asn1/src/asn1rtt_check.erl276
-rw-r--r--lib/asn1/src/asn1rtt_ext.erl72
-rw-r--r--lib/asn1/src/asn1rtt_per.erl976
-rw-r--r--lib/asn1/src/asn1rtt_per_common.erl126
-rw-r--r--lib/asn1/src/asn1rtt_real_common.erl292
-rw-r--r--lib/asn1/src/asn1rtt_uper.erl1042
-rw-r--r--lib/asn1/src/prepare_templates.erl135
-rw-r--r--lib/asn1/test/Makefile1
-rw-r--r--lib/asn1/test/asn1_SUITE.erl78
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Prim.asn16
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PrimStrings.asn13
-rw-r--r--lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl2
-rw-r--r--lib/asn1/test/asn1_app_test.erl3
-rw-r--r--lib/asn1/test/asn1_test_lib.erl15
-rw-r--r--lib/asn1/test/ber_decode_error.erl43
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl52
-rw-r--r--lib/asn1/test/testDoubleEllipses.erl8
-rw-r--r--lib/asn1/test/testNBAPsystem.erl3
-rw-r--r--lib/asn1/test/testParamBasic.erl8
-rw-r--r--lib/asn1/test/testPrimStrings.erl291
-rw-r--r--lib/asn1/test/testSSLspecs.erl23
-rw-r--r--lib/asn1/test/testSeqSetDefaultVal.erl4
-rw-r--r--lib/asn1/test/testTypeValueNotation.erl2
-rw-r--r--lib/asn1/test/test_compile_options.erl10
-rw-r--r--lib/asn1/test/test_inline.erl270
-rw-r--r--lib/common_test/doc/src/notes.xml116
-rw-r--r--lib/common_test/priv/Makefile.in6
-rw-r--r--lib/common_test/src/Makefile6
-rw-r--r--lib/common_test/test/ct_hooks_SUITE.erl2
-rw-r--r--lib/common_test/test/ct_master_SUITE.erl3
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE.erl5
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl7
-rw-r--r--lib/common_test/test/ct_surefire_SUITE.erl77
-rw-r--r--lib/common_test/test/ct_test_support.erl4
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/compile.xml26
-rw-r--r--lib/compiler/src/Makefile13
-rw-r--r--lib/compiler/src/beam_validator.erl2
-rw-r--r--lib/compiler/src/compile.erl50
-rw-r--r--lib/compiler/src/compiler.app.src1
-rw-r--r--lib/compiler/src/core_lint.erl3
-rw-r--r--lib/compiler/src/sys_core_fold.erl149
-rw-r--r--lib/compiler/src/sys_expand_pmod.erl433
-rw-r--r--lib/compiler/src/sys_pre_expand.erl85
-rw-r--r--lib/compiler/test/Makefile1
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl48
-rw-r--r--lib/compiler/test/inline_SUITE.erl43
-rw-r--r--lib/compiler/test/pmod_SUITE.erl121
-rw-r--r--lib/compiler/test/pmod_SUITE_data/pmod_basic.erl83
-rw-r--r--lib/cosEvent/src/Makefile16
-rw-r--r--lib/cosEventDomain/src/Makefile10
-rw-r--r--lib/cosFileTransfer/src/Makefile10
-rw-r--r--lib/cosNotification/src/Makefile24
-rw-r--r--lib/cosProperty/src/Makefile10
-rw-r--r--lib/cosTime/src/Makefile18
-rw-r--r--lib/cosTransactions/src/Makefile10
-rw-r--r--lib/crypto/c_src/Makefile.in12
-rw-r--r--lib/crypto/src/Makefile6
-rw-r--r--lib/debugger/src/Makefile6
-rw-r--r--lib/debugger/src/dbg_ieval.erl8
-rw-r--r--lib/debugger/src/dbg_ui_trace.erl4
-rw-r--r--lib/debugger/src/dbg_wx_trace.erl2
-rw-r--r--lib/debugger/src/i.erl4
-rw-r--r--lib/debugger/src/int.erl72
-rw-r--r--lib/dialyzer/src/Makefile12
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl27
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/results/inets2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl4
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl22
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/cerl_hipeify1
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/comm_layer2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/pubsub0
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_acceptor.erl119
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_connection.erl207
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.erl83
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.hrl29
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_logger.erl143
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port.erl241
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port_sup.erl88
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl57
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_api.erl99
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_publish.erl49
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/unknown_arity_function_spec.erl10
-rw-r--r--lib/diameter/doc/src/Makefile4
-rw-r--r--lib/diameter/doc/src/diameter.xml68
-rw-r--r--lib/diameter/doc/src/diameter_tcp.xml7
-rw-r--r--lib/diameter/doc/src/notes.xml16
-rw-r--r--lib/diameter/doc/src/seealso.ent1
-rw-r--r--lib/diameter/src/Makefile22
-rw-r--r--lib/diameter/src/base/diameter.app.src2
-rw-r--r--lib/diameter/src/base/diameter.appup.src31
-rw-r--r--lib/diameter/src/base/diameter_codec.erl8
-rw-r--r--lib/diameter/src/base/diameter_peer.erl13
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl52
-rw-r--r--lib/diameter/src/base/diameter_service.erl111
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl29
-rw-r--r--lib/diameter/src/modules.mk9
-rw-r--r--lib/diameter/src/transport/diameter_sctp.erl6
-rw-r--r--lib/diameter/src/transport/diameter_tcp.erl4
-rw-r--r--lib/diameter/test/Makefile15
-rw-r--r--lib/diameter/test/diameter_event_SUITE.erl182
-rw-r--r--lib/diameter/test/diameter_traffic_SUITE.erl258
-rw-r--r--lib/diameter/test/modules.mk3
-rw-r--r--lib/diameter/vsn.mk9
-rw-r--r--lib/edoc/priv/Makefile7
-rw-r--r--lib/edoc/src/Makefile6
-rw-r--r--lib/eldap/doc/src/eldap.xml2
-rw-r--r--lib/eldap/src/Makefile8
-rw-r--r--lib/eldap/src/eldap.erl31
-rw-r--r--lib/erl_docgen/priv/dtd/common.refs.dtd7
-rw-r--r--lib/erl_docgen/priv/dtd/erlref.dtd3
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl12
-rw-r--r--lib/erl_docgen/src/Makefile4
-rw-r--r--lib/erl_docgen/vsn.mk3
-rw-r--r--lib/erl_interface/aclocal.m47
-rw-r--r--lib/erl_interface/doc/src/ei.xml64
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml18
-rw-r--r--lib/erl_interface/include/ei.h40
-rw-r--r--lib/erl_interface/include/erl_interface.h40
-rw-r--r--lib/erl_interface/src/Makefile5
-rw-r--r--lib/erl_interface/src/Makefile.in145
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c7
-rw-r--r--lib/erl_interface/src/connect/ei_connect_int.h2
-rw-r--r--lib/erl_interface/src/connect/eirecv.c12
-rw-r--r--lib/erl_interface/src/decode/decode_atom.c159
-rw-r--r--lib/erl_interface/src/decode/decode_boolean.c36
-rw-r--r--lib/erl_interface/src/decode/decode_fun.c6
-rw-r--r--lib/erl_interface/src/decode/decode_pid.c14
-rw-r--r--lib/erl_interface/src/decode/decode_port.c13
-rw-r--r--lib/erl_interface/src/decode/decode_ref.c28
-rw-r--r--lib/erl_interface/src/encode/encode_atom.c154
-rw-r--r--lib/erl_interface/src/encode/encode_fun.c4
-rw-r--r--lib/erl_interface/src/encode/encode_pid.c24
-rw-r--r--lib/erl_interface/src/encode/encode_port.c23
-rw-r--r--lib/erl_interface/src/encode/encode_ref.c24
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c18
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.c158
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.h4
-rw-r--r--lib/erl_interface/src/legacy/erl_format.c20
-rw-r--r--lib/erl_interface/src/legacy/erl_malloc.c20
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c413
-rw-r--r--lib/erl_interface/src/legacy/global_whereis.c11
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.c40
-rw-r--r--lib/erl_interface/src/misc/ei_format.c4
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c7
-rw-r--r--lib/erl_interface/src/misc/ei_x_encode.c21
-rw-r--r--lib/erl_interface/src/misc/get_type.c79
-rw-r--r--lib/erl_interface/src/misc/putget.h7
-rw-r--r--lib/erl_interface/src/misc/show_msg.c14
-rw-r--r--lib/erl_interface/src/prog/ei_fake_prog.c6
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE.erl121
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c396
-rw-r--r--lib/et/src/Makefile4
-rw-r--r--lib/eunit/src/Makefile4
-rw-r--r--lib/gs/contribs/bonk/Makefile8
-rw-r--r--lib/gs/contribs/cols/Makefile12
-rw-r--r--lib/gs/contribs/mandel/Makefile12
-rw-r--r--lib/gs/contribs/othello/Makefile8
-rw-r--r--lib/gs/src/Makefile6
-rw-r--r--lib/hipe/Makefile10
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl5
-rw-r--r--lib/hipe/cerl/erl_types.erl38
-rw-r--r--lib/hipe/main/Makefile8
-rw-r--r--lib/hipe/rtl/Makefile4
-rw-r--r--lib/ic/c_src/Makefile.in10
-rw-r--r--lib/ic/examples/all-against-all/client.c1
-rw-r--r--lib/ic/examples/c-client/client.c1
-rw-r--r--lib/ic/examples/c-server/client.c1
-rw-r--r--lib/ic/examples/pre_post_condition/Makefile4
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Makefile5
-rw-r--r--lib/ic/src/Makefile4
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src12
-rw-r--r--lib/inets/src/http_client/httpc_response.erl5
-rw-r--r--lib/inets/src/inets_app/Makefile4
-rw-r--r--lib/inets/test/httpc_SUITE.erl34
-rw-r--r--lib/jinterface/java_src/Makefile2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile19
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java6
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java64
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java60
-rw-r--r--lib/jinterface/test/nc_SUITE.erl146
-rw-r--r--lib/kernel/doc/src/application.xml9
-rw-r--r--lib/kernel/doc/src/error_handler.xml51
-rw-r--r--lib/kernel/doc/src/file.xml53
-rw-r--r--lib/kernel/doc/src/packages.xml208
-rw-r--r--lib/kernel/doc/src/ref_man.xml1
-rw-r--r--lib/kernel/include/dist.hrl1
-rw-r--r--lib/kernel/include/file.hrl59
-rw-r--r--lib/kernel/internal_doc/distribution_handshake.txt216
-rw-r--r--lib/kernel/src/Makefile12
-rw-r--r--lib/kernel/src/application.erl16
-rw-r--r--lib/kernel/src/application_controller.erl71
-rw-r--r--lib/kernel/src/auth.erl2
-rw-r--r--lib/kernel/src/code.erl4
-rw-r--r--lib/kernel/src/code_server.erl4
-rw-r--r--lib/kernel/src/disk_log.erl46
-rw-r--r--lib/kernel/src/disk_log_1.erl6
-rw-r--r--lib/kernel/src/dist_util.erl3
-rw-r--r--lib/kernel/src/error_handler.erl53
-rw-r--r--lib/kernel/src/file.erl8
-rw-r--r--lib/kernel/src/group.erl147
-rw-r--r--lib/kernel/src/inet_config.erl35
-rw-r--r--lib/kernel/src/inet_parse.erl2
-rw-r--r--lib/kernel/src/kernel_config.erl2
-rw-r--r--lib/kernel/src/net_kernel.erl8
-rw-r--r--lib/kernel/src/os.erl2
-rw-r--r--lib/kernel/src/user.erl172
-rw-r--r--lib/kernel/src/user_drv.erl2
-rw-r--r--lib/kernel/test/Makefile1
-rw-r--r--lib/kernel/test/application_SUITE.erl13
-rw-r--r--lib/kernel/test/error_handler_SUITE.erl68
-rw-r--r--lib/kernel/test/file_SUITE.erl61
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl82
-rw-r--r--lib/kernel/test/global_SUITE.erl35
-rw-r--r--lib/megaco/aclocal.m47
-rw-r--r--lib/megaco/configure.in10
-rw-r--r--lib/megaco/doc/src/definitions/term.defs1
-rw-r--r--lib/megaco/doc/src/definitions/term.defs.xml7
-rw-r--r--lib/megaco/examples/meas/Makefile.in8
-rw-r--r--lib/megaco/src/app/Makefile4
-rw-r--r--lib/megaco/src/binary/Makefile5
-rw-r--r--lib/megaco/src/binary/depend.mk48
-rw-r--r--lib/megaco/src/flex/Makefile.in46
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src10
-rw-r--r--lib/mnesia/include/mnemosyne.hrl18
-rw-r--r--lib/mnesia/src/Makefile9
-rw-r--r--lib/mnesia/src/mnesia.erl2
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl4
-rw-r--r--lib/mnesia/src/mnesia_sup.erl13
-rw-r--r--lib/mnesia/test/mnesia.spec3
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl1
-rw-r--r--lib/mnesia/test/mnesia_config_test.erl42
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl3
-rw-r--r--lib/observer/src/Makefile7
-rw-r--r--lib/odbc/aclocal.m47
-rw-r--r--lib/odbc/c_src/Makefile.in6
-rw-r--r--lib/odbc/c_src/odbcserver.c50
-rw-r--r--lib/odbc/src/Makefile4
-rw-r--r--lib/orber/COSS/CosNaming/Makefile8
-rw-r--r--lib/orber/c_src/Makefile.in6
-rw-r--r--lib/orber/examples/Stack/Makefile4
-rw-r--r--lib/orber/src/Makefile16
-rw-r--r--lib/orber/src/orber_ifr_exceptiondef.erl20
-rw-r--r--lib/os_mon/c_src/Makefile.in16
-rw-r--r--lib/os_mon/mibs/Makefile8
-rw-r--r--lib/os_mon/src/Makefile6
-rw-r--r--lib/otp_mibs/mibs/Makefile2
-rw-r--r--lib/otp_mibs/src/Makefile4
-rw-r--r--lib/parsetools/include/yeccpre.hrl8
-rw-r--r--lib/parsetools/src/Makefile7
-rw-r--r--lib/parsetools/src/leex.erl2
-rw-r--r--lib/parsetools/src/yecc.erl6
-rw-r--r--lib/parsetools/src/yeccparser.erl4
-rw-r--r--lib/parsetools/test/leex_SUITE.erl37
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl58
-rw-r--r--lib/percept/src/Makefile4
-rw-r--r--lib/pman/src/Makefile4
-rw-r--r--lib/public_key/asn1/Makefile8
-rw-r--r--lib/public_key/asn1/OTP-PUB-KEY.asn1config3
-rw-r--r--lib/public_key/asn1/PKCS-10.asn126
-rw-r--r--lib/public_key/doc/src/cert_records.xml54
-rw-r--r--lib/public_key/doc/src/introduction.xml20
-rw-r--r--lib/public_key/doc/src/part.xml8
-rw-r--r--lib/public_key/doc/src/public_key.xml164
-rw-r--r--lib/public_key/doc/src/public_key_records.xml12
-rw-r--r--lib/public_key/doc/src/using_public_key.xml8
-rw-r--r--lib/public_key/include/public_key.hrl19
-rw-r--r--lib/public_key/src/Makefile7
-rw-r--r--lib/public_key/src/pubkey_cert.erl228
-rw-r--r--lib/public_key/src/pubkey_crl.erl701
-rw-r--r--lib/public_key/src/pubkey_pem.erl12
-rw-r--r--lib/public_key/src/public_key.app.src1
-rw-r--r--lib/public_key/src/public_key.erl188
-rw-r--r--lib/public_key/test/erl_make_certs.erl7
-rw-r--r--lib/public_key/test/pbe_SUITE.erl105
-rw-r--r--lib/public_key/test/pkits_SUITE.erl1351
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLIssuerNameCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLSignatureCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BadSignedCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotAfterDateCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotBeforeDateCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCRLCertCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedNewKeyCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeyCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeySelfIssuedCertCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/DSACACRL.pem7
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/DSAParametersInheritedCACRL.pem8
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/GeneralizedTimeCRLnextUpdateCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCAPanyPolicyMapping1to2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/LongSerialNumberCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/Mapping1to2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingFromanyPolicyCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingToanyPolicyCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/MissingbasicConstraintsCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/NameOrderCACRL.pem14
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/NegativeSerialNumberCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/NoPoliciesCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/NoissuingDistributionPointCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/OldCRLnextUpdateCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/P1anyPolicyMapping1to2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PanyPolicyMapping1to2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subCAP123CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subsubCAP123P12CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subCAP12CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP12P1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP2P2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubsubCAP12P2P1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subCAP1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subsubCAP1P2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP3CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280MandatoryAttributeTypesCACRL.pem14
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280OptionalAttributeTypesCACRL.pem14
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/RevokedsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/RolloverfromPrintableStringtoUTF8StringCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/TrustAnchorRootCRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCABadCRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCAGoodCRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/UIDCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringCaseInsensitiveMatchCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringEncodedNamesCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLEntryExtensionCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLExtensionCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/WrongCRLCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/anyPolicyCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsCriticalcAFalseCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalcAFalseCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1CRL.pem16
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1deltaCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2CRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2deltaCRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3CRL.pem14
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3deltaCRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLIndicatorNoBaseCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint1CACRL.pem16
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint2CACRL.pem14
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA1CRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3CRL.pem14
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3cRLIssuerCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA4cRLIssuerCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA5CRL.pem35
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy0CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCAIAP5CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subsubCA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCAIPM5CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCAIPM5CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalcRLSignFalseCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalkeyCertSignFalseCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalcRLSignFalseCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalkeyCertSignFalseCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA1CRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA2CRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA3CRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN4CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN5CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS1CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA3CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI1CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsAttributeCertsCACRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsCACertsCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsUserCertsCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1compromiseCRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1otherreasonsCRL.pem13
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL1.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL2.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3compromiseCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3otherreasonsCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4compromiseCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4otherreasonsCRL.pem15
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCA2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA0CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA1CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA4CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA00CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA11CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA41CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA11XCRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA41XCRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/pre2000CRLnextUpdateCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubsubCACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7CACRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subCARE2CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubCARE2RE4CRL.pem12
-rw-r--r--lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubsubCARE2RE4CRL.pem12
-rw-r--r--lib/public_key/test/public_key_SUITE.erl283
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/src/Makefile7
-rw-r--r--lib/runtime_tools/c_src/Makefile.in26
-rw-r--r--lib/runtime_tools/src/Makefile7
-rw-r--r--lib/runtime_tools/src/runtime_tools_sup.erl2
-rw-r--r--lib/sasl/src/Makefile6
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl6
-rw-r--r--lib/snmp/doc/src/Makefile2
-rw-r--r--lib/snmp/doc/src/notes.xml146
-rw-r--r--lib/snmp/mibs/Makefile.in8
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl6
-rw-r--r--lib/snmp/src/app/Makefile4
-rw-r--r--lib/snmp/src/app/snmp.appup.src574
-rw-r--r--lib/snmp/src/compile/depend.mk4
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl37
-rw-r--r--lib/snmp/src/manager/snmpm_user_default.erl6
-rw-r--r--lib/ssh/doc/src/ssh.xml3
-rw-r--r--lib/ssh/src/Makefile4
-rw-r--r--lib/ssh/src/ssh.appup.src2
-rw-r--r--lib/ssh/src/ssh.erl48
-rw-r--r--lib/ssh/src/ssh_client_key_api.erl2
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl14
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml1284
-rw-r--r--lib/ssl/src/Makefile4
-rw-r--r--lib/ssl/src/ssl.appup.src15
-rw-r--r--lib/ssl/src/ssl_alert.erl11
-rw-r--r--lib/ssl/src/ssl_certificate_db.erl51
-rw-r--r--lib/ssl/src/ssl_connection.erl130
-rw-r--r--lib/ssl/src/ssl_handshake.erl188
-rw-r--r--lib/ssl/src/ssl_handshake.hrl9
-rw-r--r--lib/ssl/src/ssl_manager.erl46
-rw-r--r--lib/ssl/src/ssl_tls_dist_proxy.erl50
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl57
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl44
-rw-r--r--lib/ssl/test/ssl_test_lib.erl77
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl2
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/doc/src/base64.xml5
-rw-r--r--lib/stdlib/doc/src/epp.xml19
-rw-r--r--lib/stdlib/doc/src/io.xml76
-rw-r--r--lib/stdlib/doc/src/io_lib.xml71
-rw-r--r--lib/stdlib/doc/src/proc_lib.xml9
-rw-r--r--lib/stdlib/doc/src/unicode.xml20
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml18
-rw-r--r--lib/stdlib/examples/erl_id_trans.erl5
-rw-r--r--lib/stdlib/src/Makefile15
-rw-r--r--lib/stdlib/src/base64.erl31
-rw-r--r--lib/stdlib/src/beam_lib.erl28
-rw-r--r--lib/stdlib/src/c.erl17
-rw-r--r--lib/stdlib/src/dets.erl8
-rw-r--r--lib/stdlib/src/dets_utils.erl2
-rw-r--r--lib/stdlib/src/dets_v8.erl2
-rw-r--r--lib/stdlib/src/dets_v9.erl2
-rw-r--r--lib/stdlib/src/edlin.erl109
-rw-r--r--lib/stdlib/src/epp.erl45
-rw-r--r--lib/stdlib/src/erl_compile.erl10
-rw-r--r--lib/stdlib/src/erl_internal.erl1
-rw-r--r--lib/stdlib/src/erl_lint.erl78
-rw-r--r--lib/stdlib/src/erl_parse.yrl12
-rw-r--r--lib/stdlib/src/erl_pp.erl12
-rw-r--r--lib/stdlib/src/erl_scan.erl21
-rw-r--r--lib/stdlib/src/erl_tar.erl18
-rw-r--r--lib/stdlib/src/escript.erl14
-rw-r--r--lib/stdlib/src/ets.erl4
-rw-r--r--lib/stdlib/src/file_sorter.erl6
-rw-r--r--lib/stdlib/src/io.erl14
-rw-r--r--lib/stdlib/src/io_lib.erl230
-rw-r--r--lib/stdlib/src/io_lib_format.erl13
-rw-r--r--lib/stdlib/src/io_lib_fread.erl6
-rw-r--r--lib/stdlib/src/io_lib_pretty.erl30
-rw-r--r--lib/stdlib/src/lib.erl18
-rw-r--r--lib/stdlib/src/ms_transform.erl4
-rw-r--r--lib/stdlib/src/proc_lib.erl64
-rw-r--r--lib/stdlib/src/qlc.erl10
-rw-r--r--lib/stdlib/src/qlc_pt.erl6
-rw-r--r--lib/stdlib/src/queue.erl14
-rw-r--r--lib/stdlib/src/shell.erl2
-rw-r--r--lib/stdlib/src/slave.erl2
-rw-r--r--lib/stdlib/src/string.erl8
-rw-r--r--lib/stdlib/src/unicode.erl25
-rw-r--r--lib/stdlib/src/zip.erl10
-rw-r--r--lib/stdlib/test/Makefile1
-rw-r--r--lib/stdlib/test/epp_SUITE.erl9
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl18
-rw-r--r--lib/stdlib/test/erl_expand_records_SUITE.erl33
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl22
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl22
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl121
-rw-r--r--lib/stdlib/test/escript_SUITE.erl17
-rw-r--r--lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang10
-rw-r--r--lib/stdlib/test/io_SUITE.erl8
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl6
-rw-r--r--lib/stdlib/test/shell_SUITE.erl17
-rw-r--r--lib/syntax_tools/src/Makefile8
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl7
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl67
-rw-r--r--lib/test_server/src/Makefile6
-rw-r--r--lib/test_server/src/ts_lib.erl1
-rw-r--r--lib/test_server/test/erl2html2_SUITE.erl26
-rw-r--r--lib/toolbar/src/Makefile4
-rw-r--r--lib/tools/c_src/Makefile.in10
-rw-r--r--lib/tools/emacs/erlang.el94
-rw-r--r--lib/tools/src/Makefile6
-rw-r--r--lib/tools/src/cover.erl20
-rw-r--r--lib/tools/src/lcnt.erl10
-rw-r--r--lib/tools/src/make.erl12
-rw-r--r--lib/tools/src/tags.erl6
-rw-r--r--lib/tools/src/xref.erl2
-rw-r--r--lib/tools/src/xref_base.erl58
-rw-r--r--lib/tools/src/xref_compiler.erl24
-rw-r--r--lib/tools/src/xref_reader.erl9
-rw-r--r--lib/tools/src/xref_utils.erl10
-rw-r--r--lib/tools/test/Makefile1
-rw-r--r--lib/tools/test/emacs_SUITE.erl76
-rw-r--r--lib/tools/test/xref_SUITE.erl62
-rw-r--r--lib/tv/src/Makefile4
-rw-r--r--lib/tv/src/tv_main.hrl1
-rw-r--r--lib/typer/src/Makefile6
-rw-r--r--lib/webtool/src/Makefile4
-rw-r--r--lib/wx/aclocal.m47
-rw-r--r--lib/wx/api_gen/wx_extra/bugs.h6
-rw-r--r--lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src (renamed from lib/stdlib/test/erl_eval_helper.erl)26
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl59
-rw-r--r--lib/wx/api_gen/wxapi.conf7
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp22
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h2841
-rw-r--r--lib/wx/examples/demo/demo_html_tagger.erl1
-rw-r--r--lib/wx/src/Makefile12
-rw-r--r--lib/wx/src/gen/wxTreeCtrl.erl56
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl2843
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl2841
-rw-r--r--lib/wx/test/wx_class_SUITE.erl10
-rw-r--r--lib/xmerl/src/Makefile20
617 files changed, 20054 insertions, 20698 deletions
diff --git a/lib/appmon/src/Makefile b/lib/appmon/src/Makefile
index 9dc47ab84e..c42ce068b4 100644
--- a/lib/appmon/src/Makefile
+++ b/lib/appmon/src/Makefile
@@ -83,10 +83,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile
index dc926947af..70238335c4 100644
--- a/lib/asn1/c_src/Makefile
+++ b/lib/asn1/c_src/Makefile
@@ -94,10 +94,10 @@ docs:
$(OBJDIR)/%.o: %.c
- $(CC) -c $(CFLAGS) -O3 -o $@ $<
+ $(V_CC) -c $(CFLAGS) -O3 -o $@ $<
$(NIF_SHARED_OBJ_FILE): $(NIF_OBJ_FILES)
- $(LD) $(LDFLAGS) -o $(NIF_SHARED_OBJ_FILE) $(NIF_OBJ_FILES) $(CLIB_FLAGS) $(LIBS)
+ $(V_LD) $(LDFLAGS) -o $(NIF_SHARED_OBJ_FILE) $(NIF_OBJ_FILES) $(CLIB_FLAGS) $(LIBS)
# ----------------------------------------------------
# Release Target
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c
index dbff14f9b3..7f1870d5b0 100644
--- a/lib/asn1/c_src/asn1_erl_nif.c
+++ b/lib/asn1/c_src/asn1_erl_nif.c
@@ -27,7 +27,6 @@
#define ASN1_OK 0
#define ASN1_ERROR -1
#define ASN1_COMPL_ERROR 1
-#define ASN1_MEMORY_ERROR 0
#define ASN1_DECODE_ERROR 2
#define ASN1_TAG_ERROR -3
#define ASN1_LEN_ERROR -4
@@ -851,11 +850,8 @@ int ber_decode_begin(ErlNifEnv* env, ERL_NIF_TERM *term, unsigned char *in_buf,
};
// The remaining binary after one ASN1 segment has been decoded
- if ((rest_data = enif_make_new_binary(env, in_buf_len - ib_index, &rest))
- == NULL) {
- *term = enif_make_atom(env, "could_not_alloc_binary");
- return ASN1_ERROR;
- }
+ rest_data = enif_make_new_binary(env, in_buf_len - ib_index, &rest);
+ memcpy(rest_data, in_buf+ib_index, in_buf_len - ib_index);
*term = enif_make_tuple2(env, decoded_term, rest);
return ASN1_OK;
@@ -1221,7 +1217,33 @@ static ERL_NIF_TERM encode_per_complete(ErlNifEnv* env, int argc,
return enif_make_binary(env, &out_binary);
}
-static ERL_NIF_TERM decode_ber_tlv(ErlNifEnv* env, int argc,
+static ERL_NIF_TERM
+make_ber_error_term(ErlNifEnv* env, unsigned int return_code,
+ unsigned int err_pos)
+{
+ ERL_NIF_TERM reason;
+ ERL_NIF_TERM t;
+
+ switch (return_code) {
+ case ASN1_TAG_ERROR:
+ reason = enif_make_atom(env, "invalid_tag");
+ break;
+ case ASN1_LEN_ERROR:
+ case ASN1_INDEF_LEN_ERROR:
+ reason = enif_make_atom(env, "invalid_length");
+ break;
+ case ASN1_VALUE_ERROR:
+ reason = enif_make_atom(env, "invalid_value");
+ break;
+ default:
+ reason = enif_make_atom(env, "unknown");
+ break;
+ }
+ t = enif_make_tuple2(env, reason, enif_make_int(env, err_pos));
+ return enif_make_tuple2(env, enif_make_atom(env, "error"), t);
+}
+
+static ERL_NIF_TERM decode_ber_tlv_raw(ErlNifEnv* env, int argc,
const ERL_NIF_TERM argv[]) {
ErlNifBinary in_binary;
ERL_NIF_TERM return_term;
@@ -1230,11 +1252,11 @@ static ERL_NIF_TERM decode_ber_tlv(ErlNifEnv* env, int argc,
if (!enif_inspect_iolist_as_binary(env, argv[0], &in_binary))
return enif_make_badarg(env);
- if ((return_code = ber_decode_begin(env, &return_term, in_binary.data,
- in_binary.size, &err_pos)) != ASN1_OK
- )
- return enif_make_tuple2(env, enif_make_atom(env,"error"), enif_make_tuple2(env,
- enif_make_int(env, return_code),enif_make_int(env, err_pos)));
+ return_code = ber_decode_begin(env, &return_term, in_binary.data,
+ in_binary.size, &err_pos);
+ if (return_code != ASN1_OK) {
+ return make_ber_error_term(env, return_code, err_pos);
+ }
return return_term;
}
@@ -1297,8 +1319,10 @@ static void unload(ErlNifEnv* env, void* priv_data) {
}
-static ErlNifFunc nif_funcs[] = { { "encode_per_complete", 1,
- encode_per_complete }, { "decode_ber_tlv", 1, decode_ber_tlv }, {
- "encode_ber_tlv", 1, encode_ber_tlv } };
+static ErlNifFunc nif_funcs[] = {
+ { "encode_per_complete", 1, encode_per_complete },
+ { "decode_ber_tlv_raw", 1, decode_ber_tlv_raw },
+ { "encode_ber_tlv", 1, encode_ber_tlv },
+};
ERL_NIF_INIT(asn1rt_nif, nif_funcs, load, NULL, upgrade, unload)
diff --git a/lib/asn1/doc/src/asn1_ug.xml b/lib/asn1/doc/src/asn1_ug.xml
index 6cb251c3e2..a0ab98cf7a 100644
--- a/lib/asn1/doc/src/asn1_ug.xml
+++ b/lib/asn1/doc/src/asn1_ug.xml
@@ -324,13 +324,6 @@ erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn
are several places to search in. The compiler will always
search the current directory first.</p>
</item>
- <tag><c>+compact_bit_string</c></tag>
- <item>
- <p>Gives the user the option to use a compact format of the BIT
- STRING type to save memory space, typing space and
- increase encode/decode performance, for details see
- <seealso marker="#BIT STRING">BIT STRING </seealso>type section.</p>
- </item>
<tag><c>+der</c></tag>
<item>
<p>DER encoding rule. Only when using <c>-ber</c> option.</p>
@@ -352,22 +345,6 @@ erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn
list or a binary. Earlier versions of the compiler ignored
those following bytes.</p>
</item>
- <tag><c>{inline,OutputName}</c></tag>
- <item>
- <p>Compiling with this option gives one output module
- containing all asn1 run-time functionality. The asn1 specs
- are provided in a target module <c>Module.set.asn</c> as
- described in the <seealso marker="asn1ct#asn1set">reference manual</seealso>. The name of the resulting module
- containing generated encode/decode functions and inlined
- run-time functions will be <c>OutputName.erl</c>. The
- merging/inlining of code is done by the <c>igor</c> module
- of <c>syntax_tools</c>. By default the functions generated
- from the first asn1 spec in the <c>.set.asn</c> are
- exported, unless a <c>{export,[atom()]}</c> or
- <c>{export_all,true}</c> option are provided. The list of
- atoms are names of choosen asn1 specs from the
- <c>.set.asn</c> file. See further examples of usage <seealso marker="#inlineExamples">below</seealso></p>
- </item>
<tag><c>+'Any Erlc Option'</c></tag>
<item>
<p>You may add any option to the Erlang compiler when
@@ -454,21 +431,8 @@ asn1rt:decode('H323-MESSAGES','SomeChoiceType',Bytes). </pre>
any reason. Maybe you need to compile the same specs for
different encoding/decoding standards.</item>
<item>You want only one resulting module.</item>
- <item>If it is crucial to have a minimal system. Using
- <c>{inline,OutputModule}</c> includes all necessary run-time
- functions of the asn1 application, but skips those modules not
- used.</item>
- <item>Upgrading issues: Even if you upgrade your Erlang system
- you may want to continue running the old asn1 run-time
- functionality.</item>
- <item>Performance issues: If you have an asn1 system with a lot
- of cross references you may gain in performance. Measurements
- must be done for each case.</item>
</list>
- <p>You may choose either the plain multi file compilation that just
- merges the chosen asn1 specs or the <c>{inline,OutputModule}</c>
- that also includes the used asn1 run-time functionality.</p>
- <p>For both cases you need to specify which asn1 specs you will
+ <p>You need to specify which asn1 specs you will
compile in a module that must have the extension
<c>.set.asn</c>. You chose name of the module and provide the
names of the asn1 specs. For instance, if you have the specs
@@ -482,17 +446,7 @@ File3.asn </pre>
<code type="none">
~> erlc MyModule.set.asn </code>
<p>the result will be one merged module <c>MyModule.erl</c> with
- the generated code from the three asn1 specs. But if you compile
- with:</p>
- <code type="none">
-~> erlc +"{inline,'OutputModule'}" MyModule.set.asn </code>
- <p>the result will be a module <c>OutputModule.erl</c> that
- contains all encode/decode functions for the three asn1 specs and
- all used functions from the asn1 run-time modules, in this case
- <c>asn1rt_ber_bin</c>. In the former case all encode/decode
- functions are exported but in the latter only the encode/decode
- functions of the first spec in the <c>.set.asn</c>, i.e. those
- from <c>File1.asn</c>.
+ the generated code from the three asn1 specs.
</p>
</section>
@@ -688,7 +642,7 @@ Day1 = saturday,
<section>
<marker id="BIT STRING"></marker>
- <title>BIT STRING </title>
+ <title>BIT STRING</title>
<p>The BIT STRING type can be used to model information which
is made up of arbitrary length series of bits. It is intended
to be used for a selection of flags, not for binary files. <br></br>
@@ -699,56 +653,66 @@ Day1 = saturday,
Bits1 ::= BIT STRING
Bits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}
</pre>
- <p>There are four different notations available for representation of
+ <p>There are five different notations available for representation of
BIT STRING values in Erlang and as input to the encode functions.</p>
<list type="ordered">
- <item>A list of binary digits (0 or 1).</item>
- <item>A hexadecimal number (or an integer). This format should be
- avoided, since it is easy to misinterpret a <c>BIT STRING</c>
- value in this format. This format may be withdrawn in a future
- release.</item>
+ <item>A bitstring. By default, a BIT STRING with no
+ symbolic names will be decoded to an Erlang bitstring.</item>
<item>A list of atoms corresponding to atoms in the <c>NamedBitList</c>
- in the BIT STRING definition.</item>
+ in the BIT STRING definition. A BIT STRING with symbolic
+ names will always be decoded to this format.</item>
+ <item>A list of binary digits (0 or 1). This format is always
+ accepted as input to the encode functions. A BIT STRING will
+ be decoded to this format if <em>legacy_bit_string</em> option
+ has been given. <em>This format may be withdrawn in a future
+ release.</em>
+ </item>
<item>As <c>{Unused,Binary}</c> where <c>Unused</c> denotes how
- many trailing zero-bits 0 to 7 that are unused in the least
- significant byte in <c>Binary</c>. This notation is only
- available when the ASN.1 files have been compiled with the
- <em>+compact_bit_string</em> flag in the option list. In
- this case it is possible to use all kinds of notation when
- encoding. But the result when decoding is always in the
- compact form. The benefit from this notation is a more
- compact notation when one has large BIT STRINGs. The
- encode/decode performance is also much better in the case of
- large BIT STRINGs. </item>
+ many trailing zero-bits 0 to 7 that are unused in the least
+ significant byte in <c>Binary</c>. This format is always
+ accepted as input to the encode functions. A BIT STRING will
+ be decoded to this format if <em>compact_bit_string</em> has
+ been given. <em>This format may be withdrawn in a future
+ release.</em>
+ </item>
+ <item>A hexadecimal number (or an integer). This format should be
+ avoided, since it is easy to misinterpret a <c>BIT STRING</c>
+ value in this format. <em>This format may be withdrawn in a future
+ release.</em>
+ </item>
</list>
<note>
- <p>Note that it is advised not to use the integer format of a
- BIT STRING, see the second point above.</p>
+ <p>It is recommended to either use the bitstring format (for
+ BIT STRINGs with no symbolic names) or a list of symbolic
+ names (for BIT STRINGs with symbolic names). The other formats
+ should be avoided since they may be withdrawn in a future
+ release.
+ </p>
</note>
<pre>
-Bits1Val1 = [0,1,0,1,1],
+Bits1Val1 = &lt;&lt;0:1,1:1,0:1,1:1,1:1&gt;&gt;,
Bits1Val2 = 16#1A,
-Bits1Val3 = {3,&lt;&lt;0:1,1:1,0:1,1:1,1:1,0:3&gt;&gt;}
+Bits1Val3 = {3,&lt;&lt;0:1,1:1,0:1,1:1,1:1,0:3&gt;&gt;},
+Bits1Val4 = [0,1,0,1,1]
</pre>
- <p>Note that <c>Bits1Val1</c>, <c>Bits1Val2</c> and <c>Bits1Val3</c>
- denote the same value.</p>
+ <p>Note that <c>Bits1Val1</c>, <c>Bits1Val2</c>, <c>Bits1Val3</c>,
+ and <c>Bits1Val1</c> denote the same value.</p>
<pre>
Bits2Val1 = [gnu,punk],
-Bits2Val2 = 2#1110,
+Bits2Val2 = &lt;&lt;2#1110:4&gt;&gt;,
Bits2Val3 = [bar,gnu,gnome],
-Bits2Val4 = [0,1,1,1]
</pre>
- <p>The above <c>Bits2Val2</c>, <c>Bits2Val3</c> and <c>Bits2Val4</c>
- also all denote the same value.</p>
+ <p><c>Bits2Val2</c> and <c>Bits2Val3</c> above denote the same value.</p>
<p><c>Bits2Val1</c> is assigned symbolic values. The assignment means
that the bits corresponding to <c>gnu</c> and <c>punk</c> i.e. bits
2 and 14 are set to 1 and the rest set to 0. The symbolic values
appear as a list of values. If a named value appears, which is not
specified in the type definition, a run-time error will occur.</p>
<p>The compact notation equivalent to the empty BIT STRING is
- <c><![CDATA[{0,<<>>}]]></c>, which in the other notations is <c>[]</c> or
+ <c><![CDATA[{0,<<>>}]]></c>, which in the other notations is
+ <c><![CDATA[<<>>]]></c>, <c>[]</c>, or
<c>0</c>.</p>
- <p>BIT STRINGS may also be sub-typed with for example a SIZE
+ <p>BIT STRINGS may also be sub-typed with, for example, a SIZE
specification:</p>
<pre>
Bits3 ::= BIT STRING (SIZE(0..31)) </pre>
diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index bb3c6a4f0f..b269276a92 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -64,8 +64,9 @@
<v>Asn1module = atom() | string()</v>
<v>Options = [Option| OldOption]</v>
<v>Option = ber | per | uper | der | compact_bit_string |
+ legacy_bit_string |
noobj | {n2n, EnumTypeName} |{outdir, Dir} | {i, IncludeDir} |
- asn1config | undec_rest | {inline, OutputName} | inline |
+ asn1config | undec_rest |
{macro_name_prefix, Prefix} | {record_name_prefix, Prefix} | verbose | warnings_as_errors</v>
<v>OldOption = ber | per</v>
<v>Reason = term()</v>
@@ -154,22 +155,26 @@ File3.asn </pre>
<tag><c>compact_bit_string</c></tag>
<item>
<p>
- Makes it possible to use a compact notation for values
- of the BIT STRING type in Erlang. The notation:
+ The BIT STRING type will be decoded to the "compact notation".
+ <em>This option is not recommended for new code.</em>
</p>
- <pre>
-BitString = {Unused, Binary},
-Unused = integer(),
-Binary = binary()
- </pre>
+ <p>For details see
+ <seealso marker="asn1_ug#BIT STRING">
+ BIT STRING type section in the Users Guide
+ </seealso>.
+ </p>
+ </item>
+ <tag><c>legacy_bit_string</c></tag>
+ <item>
<p>
- <c>Unused</c> must be a number in the range 0 to 7. It
- tells how many bits in the least significant byte in
- <c>Binary</c> that is unused.
- For details see
+ The BIT STRING type will be decoded to the legacy
+ format, i.e. a list of zeroes and ones.
+ <em>This option is not recommended for new code.</em>
+ </p>
+ <p>For details see
<seealso marker="asn1_ug#BIT STRING">
- BIT STRING type section in users guide
- </seealso>.
+ BIT STRING type section in the Users Guide
+ </seealso>.
</p>
</item>
<tag><c>{n2n, EnumTypeName}</c></tag>
@@ -233,28 +238,6 @@ Binary = binary()
list or a binary. Earlier versions of the compiler ignored
those following bytes.</p>
</item>
- <tag><c>{inline, OutputName}</c></tag>
- <item>
- <p>Compiling with this option gives one output module
- containing all asn1 run-time functionality. The asn1 specs
- are provided in a target module Module.set.asn as described
- <seealso marker="#asn1set">above</seealso>. The name of the
- resulting module containing generated encode/decode functions
- and in-lined run-time functions will be
- <c>OutputName.erl</c>. The merging/in-lining of code is done
- by the <c>igor</c> module of <c>syntax_tools</c>. By default
- the functions generated from the first asn1 spec in the
- <c>.set.asn</c> are exported, unless a
- <c>{export, [atom()]}</c> or <c>{export_all, true}</c> option
- are provided. The list of atoms are names of chosen asn1
- specs from the <c>.set.asn</c> file. </p>
- </item>
- <tag><c>inline</c></tag>
- <item>
- <p>It is also possible to use the sole argument <c>inline</c>.
- It is as <c>{inline, OutputName}</c>, but the output file gets the
- default name of the source <c>.set.asn</c> file.</p>
- </item>
<tag><c>{macro_name_prefix, Prefix}</c></tag>
<item>
<p>All macro names generated by the compiler are prefixed with
diff --git a/lib/asn1/src/.gitignore b/lib/asn1/src/.gitignore
new file mode 100644
index 0000000000..621f8f3623
--- /dev/null
+++ b/lib/asn1/src/.gitignore
@@ -0,0 +1,2 @@
+/asn1ct_rtt.erl
+/asn1ct_eval_*.erl
diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile
index 8d9422144e..faef9efd49 100644
--- a/lib/asn1/src/Makefile
+++ b/lib/asn1/src/Makefile
@@ -42,11 +42,17 @@ RELSYSDIR = $(RELEASE_PATH)/lib/asn1-$(VSN)
#
EBIN = ../ebin
+
+EVAL_CT_MODULES = asn1ct_eval_ext \
+ asn1ct_eval_per \
+ asn1ct_eval_uper
+
CT_MODULES= \
asn1ct \
asn1ct_check \
asn1_db \
asn1ct_pretty_format \
+ asn1ct_func \
asn1ct_gen \
asn1ct_gen_per \
asn1ct_gen_per_rt2ct \
@@ -55,27 +61,16 @@ CT_MODULES= \
asn1ct_constructed_ber_bin_v2 \
asn1ct_gen_ber_bin_v2 \
asn1ct_imm \
+ asn1ct_rtt \
asn1ct_value \
asn1ct_tok \
asn1ct_parser2 \
- asn1ct_table
+ asn1ct_table \
+ $(EVAL_CT_MODULES)
RT_MODULES= \
asn1rt \
- asn1rt_ber_bin \
- asn1rt_ber_bin_v2 \
- asn1rt_per_bin_rt2ct \
- asn1rt_uper_bin \
- asn1rt_check \
asn1rt_nif
-# asn1_sup \
-# asn1_app \
-# asn1_server
-
-
-# the rt module to use is defined in asn1_records.hrl
-# and must be updated when an incompatible change is done in the rt modules
-
MODULES= $(CT_MODULES) $(RT_MODULES)
@@ -110,7 +105,7 @@ endif
ERL_COMPILE_FLAGS += \
-I$(ERL_TOP)/lib/stdlib \
- +warn_unused_vars
+ -Werror
YRL_FLAGS =
@@ -136,13 +131,20 @@ info:
# ----------------------------------------------------
$(EBIN)/asn1ct.$(EMULATOR):asn1ct.erl
- $(ERLC) -b$(EMULATOR) -o$(EBIN) $(ERL_COMPILE_FLAGS) -Dvsn=\"$(VSN)\" $<
+ $(V_ERLC) -b$(EMULATOR) -o$(EBIN) $(ERL_COMPILE_FLAGS) -Dvsn=\"$(VSN)\" $<
+
+$(EBIN)/asn1ct_func.$(EMULATOR): asn1ct_func.erl
+ $(ERLC) -o$(EBIN) $(ERL_COMPILE_FLAGS) -I../rt_templates $<
+
+asn1ct_eval_%.erl: asn1ct_eval_%.funcs
+ erl -pa $(EBIN) -noshell -noinput \
+ -run prepare_templates gen_asn1ct_eval $< >$@
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
@@ -165,6 +167,34 @@ release_spec: opt
release_docs_spec:
#
+# Run-time library template files.
+#
+
+RT_TEMPLATES = asn1rtt_check \
+ asn1rtt_ext \
+ asn1rtt_per_common \
+ asn1rtt_real_common \
+ asn1rtt_ber \
+ asn1rtt_per \
+ asn1rtt_uper
+
+RT_TEMPLATES_ERL = $(RT_TEMPLATES:%=%.erl)
+RT_TEMPLATES_TARGET = $(RT_TEMPLATES:%=%.$(EMULATOR))
+
+asn1ct_rtt.erl: prepare_templates.$(EMULATOR) $(RT_TEMPLATES_TARGET)
+ erl -noshell -noinput -run prepare_templates gen_asn1ct_rtt \
+ $(RT_TEMPLATES_TARGET) >asn1ct_rtt.erl
+
+prepare_templates.$(EMULATOR): prepare_templates.erl
+ erlc prepare_templates.erl
+
+asn1rtt_%.$(EMULATOR): asn1rtt_%.erl
+ erlc +debug_info $<
+
+$(EVAL_CT_MODULES:%=%.erl): prepare_templates.$(EMULATOR) \
+ $(EBIN)/asn1ct_rtt.$(EMULATOR)
+
+#
# Dependencies
#
@@ -175,6 +205,7 @@ $(EBIN)/asn1ct_check.beam: asn1ct_check.erl asn1_records.hrl
$(EBIN)/asn1ct_constructed_ber_bin_v2.beam: asn1ct_constructed_ber_bin_v2.erl \
asn1_records.hrl
$(EBIN)/asn1ct_constructed_per.beam: asn1ct_constructed_per.erl asn1_records.hrl
+$(EBIN)/asn1ct_func.beam: asn1ct_func.erl
$(EBIN)/asn1ct_gen.beam: asn1ct_gen.erl asn1_records.hrl
$(EBIN)/asn1ct_gen_ber_bin_v2.beam: asn1ct_gen_ber_bin_v2.erl asn1_records.hrl
$(EBIN)/asn1ct_gen_per.beam: asn1ct_gen_per.erl asn1_records.hrl
diff --git a/lib/asn1/src/asn1.app.src b/lib/asn1/src/asn1.app.src
index 64b33a8a30..f2ee8deb75 100644
--- a/lib/asn1/src/asn1.app.src
+++ b/lib/asn1/src/asn1.app.src
@@ -3,11 +3,6 @@
{vsn, "%VSN%"},
{modules, [
asn1rt,
- asn1rt_per_bin_rt2ct,
- asn1rt_uper_bin,
- asn1rt_ber_bin,
- asn1rt_ber_bin_v2,
- asn1rt_check,
asn1rt_nif
]},
{registered, [
diff --git a/lib/asn1/src/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl
index 59a9acb7e7..c229aa0759 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -24,12 +24,6 @@
-define(dbg(Fmt, Args), no_debug).
-endif.
--define('RT_BER_BIN',"asn1rt_ber_bin").
--define('RT_PER_BIN',"asn1rt_per_bin").
-
-%% Some encoding are common for BER and PER. Shared code are in RT_COMMON
--define('RT_COMMON',asn1rt_ber_bin).
-
-define('COMPLETE_ENCODE',1).
-define('TLV_DECODE',2).
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index 98877320a0..46602a3071 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -41,6 +41,7 @@
maybe_rename_function/3,latest_sindex/0,current_sindex/0,
set_current_sindex/1,next_sindex/0,maybe_saved_sindex/2,
parse_and_save/2,verbose/3,warning/3,warning/4,error/3]).
+-export([get_bit_string_format/0]).
-include("asn1_records.hrl").
-include_lib("stdlib/include/erl_compile.hrl").
@@ -86,10 +87,14 @@ compile(File) ->
compile(File,[]).
compile(File, Options0) when is_list(Options0) ->
- Options1 = translate_options(Options0),
- Options2 = includes(File,Options1),
- Includes = strip_includes(Options2),
- in_process(fun() -> compile_proc(File, Includes, Options2) end).
+ try translate_options(Options0) of
+ Options1 ->
+ Options2 = includes(File,Options1),
+ Includes = strip_includes(Options2),
+ in_process(fun() -> compile_proc(File, Includes, Options2) end)
+ catch throw:Error ->
+ Error
+ end.
compile_proc(File, Includes, Options) ->
case input_file_type(File, Includes) of
@@ -115,63 +120,18 @@ compile1(File,Options) when is_list(Options) ->
DbFile = outfile(Base,"asn1db",Options),
Includes = [I || {i,I} <- Options],
EncodingRule = get_rule(Options),
- asn1ct_table:new(asn1_functab),
Continue1 = scan(File,Options),
Continue2 = parse(Continue1,File,Options),
Continue3 = check(Continue2,File,OutFile,Includes,EncodingRule,
DbFile,Options,[]),
Continue4 = generate(Continue3,OutFile,EncodingRule,Options),
- asn1ct_table:delete(asn1_functab),
- Ret = compile_erl(Continue4,OutFile,Options),
- case inline(is_inline(Options),
- inline_output(Options,filename:rootname(File)),
- lists:concat([OutFile,".erl"]),Options) of
- false ->
- Ret;
- InlineRet ->
- InlineRet
- end.
+ compile_erl(Continue4, OutFile, Options).
%%****************************************************************************%%
%% functions dealing with compiling of several input files to one output file %%
%%****************************************************************************%%
-%%%
-%% inline/4
-%% merges the resulting erlang modules with
-%% the appropriate run-time modules so the resulting module contains all
-%% run-time asn1 functionality. Then compiles the resulting file to beam code.
-%% The merging is done by the igor module. If this function is used in older
-%% versions than R10B the igor module, part of user contribution syntax_tools,
-%% must be provided. It is possible to pass options for the ASN1 compiler
-%% Types:
-%% Name -> atom()
-%% Modules -> [filename()]
-%% Options -> [term()]
-%% filename() -> file:filename()
-inline(true,Name,Module,Options) ->
- RTmodule = get_runtime_mod(Options),
- IgorOptions = igorify_options(remove_asn_flags(Options)),
- IgorName = list_to_atom(filename:rootname(filename:basename(Name))),
-% io:format("*****~nName: ~p~nModules: ~p~nIgorOptions: ~p~n*****~n",
-% [IgorName,Modules++RTmodule,IgorOptions]),
- verbose("Inlining modules: ~p in ~p~n",[[Module]++RTmodule,IgorName],Options),
- case catch igor:merge(IgorName,[Module]++RTmodule,[{preprocess,true},{stubs,false},{backups,false}]++IgorOptions) of
- {'EXIT',{undef,Reason}} -> %% module igor first in R10B
- error("Module igor in syntax_tools must be available:~n~p~n",
- [Reason],Options),
- {error,'no_compilation'};
- {'EXIT',Reason} ->
- error("Merge by igor module failed due to ~p~n",[Reason],Options),
- {error,'no_compilation'};
- _ ->
-%% io:format("compiling output module: ~p~n",[generated_file(Name,IgorOptions)]),
- erl_compile(generated_file(Name,IgorOptions),Options)
- end;
-inline(_,_,_,_) ->
- false.
-
%% compile_set/3 merges and compiles a number of asn1 modules
%% specified in a .set.asn file to one .erl file.
compile_set(SetBase,Files,Options)
@@ -183,7 +143,6 @@ compile_set(SetBase,Files,Options)
DbFile = outfile(SetBase,"asn1db",Options),
Includes = [I || {i,I} <- Options],
EncodingRule = get_rule(Options),
- asn1ct_table:new(asn1_functab),
ScanRes = scan_set(Files,Options),
ParseRes = parse_set(ScanRes,Options),
Result =
@@ -208,7 +167,6 @@ compile_set(SetBase,Files,Options)
{error,{'unexpected error in scan/parse phase',
lists:map(fun(X)->element(3,X) end,Other)}}
end,
- asn1ct_table:delete(asn1_functab),
Result.
check_set(ParseRes,SetBase,OutFile,Includes,EncRule,DbFile,
@@ -222,15 +180,7 @@ check_set(ParseRes,SetBase,OutFile,Includes,EncRule,DbFile,
asn1ct_table:delete([renamed_defs, original_imports, automatic_tags]),
- Ret = compile_erl(Continue2,OutFile,Options),
- case inline(is_inline(Options),
- inline_output(Options,filename:rootname(OutFile)),
- lists:concat([OutFile,".erl"]),Options) of
- false ->
- Ret;
- InlineRet ->
- InlineRet
- end.
+ compile_erl(Continue2, OutFile, Options).
%% merge_modules/2 -> returns a module record where the typeorval lists are merged,
%% the exports lists are merged, the imports lists are merged when the
@@ -817,12 +767,9 @@ check({true,M},File,OutFile,Includes,EncodingRule,DbFile,Options,InputMods) ->
check({false,M},_,_,_,_,_,_,_) ->
{false,M}.
-generate({true,{M,_Module,GenTOrV}},OutFile,EncodingRule,Options) ->
+generate({true,{M,_Module,GenTOrV}}, OutFile, EncodingRule, Options) ->
debug_on(Options),
- case lists:member(compact_bit_string,Options) of
- true -> put(compact_bit_string,true);
- _ -> ok
- end,
+ setup_bit_string_format(Options),
put(encoding_options,Options),
asn1ct_table:new(check_functions),
@@ -844,8 +791,8 @@ generate({true,{M,_Module,GenTOrV}},OutFile,EncodingRule,Options) ->
ok
end,
debug_off(Options),
- put(compact_bit_string,false),
erase(encoding_options),
+ cleanup_bit_string_format(),
erase(tlv_format), % used in ber
erase(class_default_type),% used in ber
asn1ct_table:delete(check_functions),
@@ -863,6 +810,26 @@ generate({true,{M,_Module,GenTOrV}},OutFile,EncodingRule,Options) ->
generate({false,M},_,_,_) ->
{false,M}.
+setup_bit_string_format(Opts) ->
+ Format = case {lists:member(compact_bit_string, Opts),
+ lists:member(legacy_bit_string, Opts)} of
+ {false,false} -> bitstring;
+ {true,false} -> compact;
+ {false,true} -> legacy;
+ {true,true} ->
+ Message = "Contradicting options given: "
+ "compact_bit_string and legacy_bit_string",
+ exit({error,{asn1,Message}})
+ end,
+ put(bit_string_format, Format).
+
+cleanup_bit_string_format() ->
+ erase(bit_string_format).
+
+get_bit_string_format() ->
+ get(bit_string_format).
+
+
%% parse_and_save parses an asn1 spec and saves the unchecked parse
%% tree in a data base file.
%% Does not support multifile compilation files
@@ -1069,18 +1036,8 @@ get_rule(Options) ->
ber
end.
-get_runtime_mod(Options) ->
- RtMod1=
- case get_rule(Options) of
- per -> "asn1rt_per_bin_rt2ct.erl";
- ber -> ["asn1rt_ber_bin_v2.erl"];
- uper -> ["asn1rt_uper_bin.erl"]
- end,
- RtMod1++["asn1rt_check.erl","asn1rt.erl"].
-
%% translate_options(NewOptions) -> OldOptions
%% Translate the new option names to the old option name.
-%% FIXME. We should rewrite all code to handle the new option names.
translate_options([ber_bin|T]) ->
io:format("Warning: The option 'ber_bin' is now called 'ber'.\n"),
@@ -1097,6 +1054,12 @@ translate_options([nif|T]) ->
translate_options([optimize|T]) ->
io:format("Warning: The option 'optimize' is no longer needed.\n"),
translate_options(T);
+translate_options([inline|T]) ->
+ io:format("Warning: The option 'inline' is no longer needed.\n"),
+ translate_options(T);
+translate_options([{inline,_}|_]) ->
+ io:format("ERROR: The option {inline,OutputFilename} is no longer supported.\n"),
+ throw({error,{unsupported_option,inline}});
translate_options([H|T]) ->
[H|translate_options(T)];
translate_options([]) -> [].
@@ -1122,6 +1085,7 @@ remove_asn_flags(Options) ->
X /= get_rule(Options),
X /= optimize,
X /= compact_bit_string,
+ X /= legacy_bit_string,
X /= debug,
X /= asn1config,
X /= record_name_prefix].
@@ -1134,23 +1098,6 @@ debug_on(Options) ->
true
end.
-igorify_options(Options) ->
- case lists:keysearch(outdir,1,Options) of
- {value,{_,Dir}} ->
- Options1 = lists:keydelete(outdir,1,Options),
- [{dir,Dir}|Options1];
- _ ->
- Options
- end.
-
-generated_file(Name,Options) ->
- case lists:keysearch(dir,1,Options) of
- {value,{_,Dir}} ->
- filename:join([Dir,filename:basename(Name)]);
- _ ->
- Name
- end.
-
debug_off(_Options) ->
erase(asndebug).
@@ -1191,21 +1138,6 @@ option_add(Option, Options, Fun) ->
strip_includes(Includes) ->
[I || {i, I} <- Includes].
-is_inline(Options) ->
- case lists:member(inline,Options) of
- true -> true;
- _ ->
- lists:keymember(inline,1,Options)
- end.
-
-inline_output(Options,Default) ->
- case [X||{inline,X}<-Options] of
- [OutputName] ->
- OutputName;
- _ ->
- Default
- end.
-
%% compile(AbsFileName, Options)
%% Compile entry point for erl_compile.
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
index 78cb9297d8..d5097e83c5 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -66,9 +66,9 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
ValName =
case Typename of
['EXTERNAL'] ->
- emit([indent(4),
- "NewVal = asn1rt_check:transform_to_EXTERNAL1990(Val),",
- nl]),
+ emit([indent(4),"NewVal = ",
+ {call,ext,transform_to_EXTERNAL1990,["Val"]},
+ com,nl]),
"NewVal";
_ ->
"Val"
@@ -162,7 +162,8 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
emit([nl," BytesSoFar = "]),
case SeqOrSet of
'SET' when (D#type.def)#'SET'.sorted == dynamic ->
- emit("asn1rt_check:dynamicsort_SET_components(["),
+ asn1ct_func:need({ber,dynamicsort_SET_components,1}),
+ emit("dynamicsort_SET_components(["),
mkvlist(asn1ct_name:all(encBytes)),
emit(["]),",nl]);
_ ->
@@ -177,8 +178,8 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
mkvplus(AllLengths)
end,
emit([",",nl]),
- emit(["?RT_BER:encode_tags(TagIn, BytesSoFar, LenSoFar)."
- ,nl]).
+ call(encode_tags, ["TagIn","BytesSoFar","LenSoFar"]),
+ emit([".",nl]).
gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:start(),
@@ -207,7 +208,8 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
_ ->
emit([{curr,tlv}," = "])
end,
- emit(["?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]),
+ call(match_tags, [{prev,tlv},"TagIn"]),
+ emit([com,nl]),
asn1ct_name:new(tlv),
asn1ct_name:new(v),
@@ -287,8 +289,9 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
"', "]),
mkvlist(asn1ct_name:all(term)),
emit(["},",nl]),
- emit([" asn1rt_check:transform_to_EXTERNAL1994",
- "(OldFormat).",nl]);
+ emit([" ",
+ {call,ext,transform_to_EXTERNAL1994,
+ ["OldFormat"]},".",nl]);
_ ->
emit([" {'",RecordName,"', "]),
mkvlist(asn1ct_name:all(term)),
@@ -371,7 +374,8 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
_ ->
emit([{curr,tlv}," = "])
end,
- emit(["?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]),
+ call(match_tags, [{prev,tlv},"TagIn"]),
+ emit([com,nl]),
asn1ct_name:new(v),
@@ -492,7 +496,8 @@ gen_encode_sof(Erules,Typename,_InnerTypename,D) when is_record(D,type) ->
emit([" {EncBytes,EncLen} = 'enc_",asn1ct_gen:list2name(Typename),
"_components'(Val",Objfun,",[],0),",nl]),
- emit([" ?RT_BER:encode_tags(TagIn, EncBytes, EncLen).",nl,nl]),
+ emit([" ",{call,ber,encode_tags,["TagIn","EncBytes","EncLen"]},
+ ".",nl,nl]),
gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont).
@@ -512,8 +517,8 @@ gen_decode_sof(Erules,TypeName,_InnerTypeName,D) when is_record(D,type) ->
emit([" %%-------------------------------------------------",nl]),
asn1ct_name:new(tlv),
- emit([{curr,tlv},
- " = ?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]),
+ emit([{curr,tlv}," = ",
+ {call,ber,match_tags,[{prev,tlv},"TagIn"]},com,nl]),
asn1ct_name:new(v),
emit(["["]),
@@ -551,8 +556,9 @@ gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont)
case catch lists:member(der,get(encoding_options)) of
true when SeqOrSetOf=='SET OF'->
+ asn1ct_func:need({ber,dynamicsort_SETOF,1}),
emit([indent(3),
- "{asn1rt_check:dynamicsort_SETOF(AccBytes),AccLen};",nl,nl]);
+ "{dynamicsort_SETOF(AccBytes),AccLen};",nl,nl]);
_ ->
emit([indent(3),"{lists:reverse(AccBytes),AccLen};",nl,nl])
end,
@@ -672,8 +678,9 @@ gen_dec_sequence_call2(Erules,TopType,{Root1,EList,Root2},_Ext,DecObjInf) ->
%% including the first mandatory element.
TagList = get_root2_taglist(Root2,[]),
emit({com,nl}),
- emit([{curr,tlv}," = ?RT_BER:skip_ExtensionAdditions(",
- {prev,tlv},", ",{asis,TagList},"),",nl]),
+ emit([{curr,tlv}," = ",
+ {call,ber,skip_ExtensionAdditions,
+ [{prev,tlv},{asis,TagList}]},com,nl]),
asn1ct_name:new(tlv),
gen_dec_sequence_call1(Erules,TopType,Root2,
length(Root1)+length(EList),noext,
@@ -805,8 +812,8 @@ gen_enc_choice1(Erules,TopType,_Tag,CompList,_Ext) ->
emit([" {EncBytes,EncLen} = case element(1,Val) of",nl]),
gen_enc_choice2(Erules,TopType,CompList),
emit([nl," end,",nl,nl]),
-
- emit(["?RT_BER:encode_tags(TagIn, EncBytes, EncLen).",nl]).
+ call(encode_tags, ["TagIn","EncBytes","EncLen"]),
+ emit([".",nl]).
gen_enc_choice2(Erules,TopType,[H1|T]) when is_record(H1,'ComponentType') ->
@@ -859,8 +866,8 @@ gen_enc_choice2(_Erules,_TopType,[]) ->
gen_dec_choice(Erules,TopType, _ChTag, CompList, Ext) ->
asn1ct_name:clear(),
asn1ct_name:new(tlv),
- emit([{curr,tlv},
- " = ?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]),
+ emit([{curr,tlv}," = ",
+ {call,ber,match_tags,[{prev,tlv},"TagIn"]},com,nl]),
asn1ct_name:new(tlv),
asn1ct_name:new(v),
emit(["case (case ",{prev,tlv},
@@ -876,8 +883,8 @@ gen_dec_choice(Erules,TopType, _ChTag, CompList, Ext) ->
emit([indent(9),"exit({error,{asn1,{invalid_choice_tag,",
{curr,else},"}}})",nl]);
_ ->
- emit([indent(9),"{asn1_ExtAlt, ?RT_BER:encode(",{curr,else},
- asn1ct_gen:nif_parameter(),")}",nl])
+ emit([indent(9),"{asn1_ExtAlt,",
+ {call,ber,ber_encode,[{curr,else}]},"}",nl])
end,
emit([indent(3),"end",nl]),
asn1ct_name:new(tag),
@@ -1018,29 +1025,20 @@ gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj)
case OptOrMand of
mandatory ->
emit(["{",{curr,encBytes},",",{curr,encLen},
- "} = "]),
- emit(["?RT_BER:encode_open_type(",{curr,tmpBytes},
- ",",{asis,Tag},")"]);
+ "} = ",
+ {call,ber,encode_open_type,
+ [{curr,tmpBytes},{asis,Tag}]},nl]);
_ ->
-% emit(["{",{next,tmpBytes},", _} = "]),
emit(["{",{next,tmpBytes},",",{curr,tmpLen},
- "} = "]),
- emit(["?RT_BER:encode_open_type(",{curr,tmpBytes},
- ",",{asis,Tag},"),",nl]),
+ "} = ",
+ {call,ber,encode_open_type,
+ [{curr,tmpBytes},{asis,Tag}]},com,nl]),
emit(IndDeep),
emit(["{",{next,tmpBytes},", ",{curr,tmpLen},"}"])
end;
Err ->
throw({asn1,{'internal error',Err}})
end;
-%% {{#'ObjectClassFieldType'{type={objectfield,PrimFieldName1,
-%% PFNList}},_},
-%% {componentrelation,_,_}} ->
-%% %% this is when the dotted list in the FieldName has more
-%% %% than one element
-%% {_LeadingAttrName,Fun} = EncObj,
-%% emit(["?RT_BER:encode_open_type(",Fun,"(",{asis,PrimFieldName1},
-%% ", ",Element,", ",{asis,PFNList},"))"]);
_ ->
case WhatKind of
{primitive,bif} ->
@@ -1238,15 +1236,11 @@ gen_dec_call({typefield,_},_,_,_Cname,Type,BytesVar,Tag,_,_,false,_) ->
asn1ct_name:new(tmptlv),
{FirstPFName,RestPFName} =
-% asn1ct_gen:get_constraint(Type#type.constraint,
-% tableconstraint_info),
(Type#type.def)#'ObjectClassFieldType'.fieldname,
emit([nl,indent(6),"begin",nl]),
-% emit([indent(9),{curr,opendec}," = ?RT_BER:decode_open_type(",
- emit([indent(9),{curr,tmptlv}," = ?RT_BER:decode_open_type(",
- BytesVar,",",{asis,Tag},asn1ct_gen:nif_parameter(),"),",nl]),
-% emit([indent(9),"{",{curr,tmptlv},",_} = ?RT_BER:decode(",
-% {curr,opendec},"),",nl]),
+ emit([indent(9),{curr,tmptlv}," = ",
+ {call,ber,decode_open_type,
+ [BytesVar,{asis,Tag}]},com,nl]),
emit([indent(9),"case (catch ObjFun(",{asis,FirstPFName},
", ",{curr,tmptlv},", ",{asis,RestPFName},
@@ -1259,8 +1253,7 @@ gen_dec_call({typefield,_},_,_,_Cname,Type,BytesVar,Tag,_,_,false,_) ->
emit([indent(9),"end",nl,indent(6),"end",nl]),
[];
gen_dec_call({typefield,_},_,_,Cname,Type,BytesVar,Tag,_,_,_DecObjInf,OptOrMandComp) ->
- emit(["?RT_BER:decode_open_type(",BytesVar,",",{asis,Tag},
- asn1ct_gen:nif_parameter(),")"]),
+ call(decode_open_type, [BytesVar,{asis,Tag}]),
RefedFieldName =
% asn1ct_gen:get_constraint(Type#type.constraint,
% tableconstraint_info),
@@ -1268,8 +1261,7 @@ gen_dec_call({typefield,_},_,_,Cname,Type,BytesVar,Tag,_,_,_DecObjInf,OptOrMandC
[{Cname,RefedFieldName,asn1ct_gen:mk_var(asn1ct_name:curr(term)),
asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}];
gen_dec_call({objectfield,PrimFieldName,PFNList},_,_,Cname,_,BytesVar,Tag,_,_,_,OptOrMandComp) ->
- emit(["?RT_BER:decode_open_type(",BytesVar,",",{asis,Tag},
- asn1ct_gen:nif_parameter(),")"]),
+ call(decode_open_type, [BytesVar,{asis,Tag}]),
[{Cname,{PrimFieldName,PFNList},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,
@@ -1301,7 +1293,6 @@ gen_dec_call1({primitive,bif},InnerType,Erules,TopType,Cname,Type,BytesVar,
asn1ct:add_generated_refed_func({[Cname|TopType],undecoded,
Tag,Type}),
asn1ct:update_gen_state(namelist,Rest),
-% emit(["?RT_BER:match_tags(",BytesVar,",",{asis,Tag},")"]);
emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',",
BytesVar,"}"]);
{_,{fixedtypevaluefield,_,Btype}} ->
@@ -1320,7 +1311,6 @@ gen_dec_call1('ASN1_OPEN_TYPE',_InnerType,Erules,TopType,Cname,Type,BytesVar,
asn1ct:update_gen_state(namelist,Rest),
emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',",
BytesVar,"}"]);
-% emit(["?RT_BER:match_tags(",BytesVar,",",{asis,Tag},")"]);
{_,#'ObjectClassFieldType'{type=OpenType}} ->
?ASN1CT_GEN_BER:gen_dec_prim(Erules,#type{def=OpenType},
BytesVar,Tag,[],
@@ -1393,7 +1383,8 @@ gen_dec_call1(WhatKind,_,_Erules,TopType,Cname,Type,BytesVar,
parts,
[],Type}),
emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',"]),
- EmitDecFunCall("?RT_BER:match_tags"),
+ asn1ct_func:need({ber,match_tags,2}),
+ EmitDecFunCall("match_tags"),
emit("}");
_ ->
{DecFunName,_,_}=
@@ -1522,3 +1513,6 @@ value_match1(Value,[],Acc,Depth) ->
Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")"));
value_match1(Value,[{VI,_}|VIs],Acc,Depth) ->
value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1).
+
+call(F, Args) ->
+ asn1ct_func:call(ber, F, Args).
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index 27070be966..3c59c73108 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -32,6 +32,7 @@
%-compile(export_all).
-import(asn1ct_gen, [emit/1,demit/1,get_record_name_prefix/0]).
+-import(asn1ct_func, [call/3]).
%% ENCODE GENERATOR FOR SEQUENCE TYPE ** **********
@@ -66,9 +67,9 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
end,
case Typename of
['EXTERNAL'] ->
- emit({{next,val},
- " = asn1rt_check:transform_to_EXTERNAL1990(",
- {curr,val},"),",nl}),
+ emit([{next,val}," = ",
+ {call,ext,transform_to_EXTERNAL1990,
+ [{curr,val}]},com,nl]),
asn1ct_name:new(val);
_ ->
ok
@@ -86,7 +87,8 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
end,asn1ct_name:all(fixopt)),
emit({"{",{next,val},",Opt} = {",{curr,val},",[",FixOpts,"]},",nl});
{_,_,false} ->
- Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(",
+ asn1ct_func:need({Erule,fixoptionals,3}),
+ Fixoptcall = ",Opt} = fixoptionals(",
emit({"{",{next,val},Fixoptcall,
{asis,Optionals},",",length(Optionals),
",",{curr,val},"),",nl})
@@ -121,8 +123,9 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
lists:foreach(ExtGroupFun,ExtGroupPosLenList)
end,
asn1ct_name:new(tmpval),
- emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},",",
- {curr,val},"),",nl]);
+ emit(["Extensions = ",
+ {call,Erule,fixextensions,[{asis,Ext},{curr,val}]},
+ com,nl]);
_ -> true
end,
EncObj =
@@ -191,10 +194,10 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
MaybeComma1 =
case Ext of
{ext,_Pos,NumExt2} when NumExt2 > 0 ->
- emit({"?RT_PER:setext(Extensions =/= [])"}),
+ call(Erule, setext, ["Extensions =/= []"]),
", ";
{ext,_Pos,_} ->
- emit({"?RT_PER:setext(false)"}),
+ call(Erule, setext, ["false"]),
", ";
_ ->
""
@@ -383,9 +386,10 @@ gen_dec_constructed_imm_2(Typename, CompList,
"'"}),
mkvlist(asn1ct_name:all(term)),
emit({"},",nl}),
- emit({" ASN11994Format =",nl,
- " asn1rt_check:transform_to_EXTERNAL1994",
- "(OldFormat),",nl}),
+ emit([" ASN11994Format =",nl,
+ " ",
+ {call,ext,transform_to_EXTERNAL1994,
+ ["OldFormat"]},com,nl]),
emit(" {ASN11994Format,");
_ ->
emit(["{{'",RecordName,"'"]),
@@ -513,7 +517,7 @@ gen_encode_sof(Erule,Typename,SeqOrSetOf,D) when is_record(D,type) ->
_->
""
end,
- gen_encode_length(SizeConstraint, is_optimized(Erule)),
+ gen_encode_length(Erule, SizeConstraint),
emit({indent(3),"'enc_",asn1ct_gen:list2name(Typename),
"_components'(Val",ObjFun,", [])"}),
emit({nl,"].",nl}),
@@ -527,7 +531,7 @@ gen_encode_sof(Erule,Typename,SeqOrSetOf,D) when is_record(D,type) ->
%% Logic copied from asn1_per_bin_rt2ct:encode_constrained_number
-gen_encode_length({Lb,Ub},true) when Ub =< 65535, Lb >= 0 ->
+gen_encode_length(per, {Lb,Ub}) when Ub =< 65535, Lb >= 0 ->
Range = Ub - Lb + 1,
V2 = ["(length(Val) - ",Lb,")"],
Encode = if
@@ -554,12 +558,20 @@ gen_encode_length({Lb,Ub},true) when Ub =< 65535, Lb >= 0 ->
Range =< 65536 ->
{"[20,2,<<",V2,":16>>]"};
true ->
- {"?RT_PER:encode_length(",{asis,{Lb,Ub}},",length(Val))"}
+ {call,per,encode_length,
+ [{asis,{Lb,Ub}},"length(Val)"]}
end,
emit({nl,Encode,",",nl});
-gen_encode_length(SizeConstraint,_) ->
- emit({nl,indent(3),"?RT_PER:encode_length(",
- {asis,SizeConstraint},",length(Val)),",nl}).
+gen_encode_length(Erules, SizeConstraint) ->
+ emit([nl,indent(3),
+ case SizeConstraint of
+ undefined ->
+ {call,Erules,encode_length,["length(Val)"]};
+ _ ->
+ {call,Erules,encode_length,
+ [{asis,SizeConstraint},"length(Val)"]}
+ end,
+ com,nl]).
gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when is_record(D,type) ->
asn1ct_name:start(),
@@ -1003,7 +1015,9 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) ->
case Ext of
{ext,_Ep1,_} ->
- emit(["?RT_PER:encode_open_type(dummy,?RT_PER:complete("]);
+ asn1ct_func:need({Erule,encode_open_type,1}),
+ asn1ct_func:need({Erule,complete,1}),
+ emit(["encode_open_type(complete("]);
_ -> true
end,
@@ -1015,7 +1029,9 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) ->
{notype,T} ->
throw({error,{notype,type_from_object,T}});
{Name,RestFieldNames} when is_atom(Name) ->
- emit({"?RT_PER:encode_open_type([],?RT_PER:complete(",nl}),
+ asn1ct_func:need({Erule,complete,1}),
+ asn1ct_func:need({Erule,encode_open_type,1}),
+ emit({"encode_open_type(complete(",nl}),
emit({" ",Fun,"(",{asis,Name},", ",
Element,", ",{asis,RestFieldNames},")))"});
Other ->
@@ -1025,8 +1041,10 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) ->
{objectfield,PrimFieldName1,PFNList} ->
case DynamicEnc of
{_LeadingAttrName,Fun} ->
- emit({"?RT_PER:encode_open_type([],"
- "?RT_PER:complete(",nl}),
+ asn1ct_func:need({Erule,complete,1}),
+ asn1ct_func:need({Erule,encode_open_type,1}),
+ emit({"encode_open_type("
+ "complete(",nl}),
emit({" ",Fun,"(",{asis,PrimFieldName1},
", ",Element,", ",{asis,PFNList},")))"})
end;
@@ -1105,8 +1123,9 @@ gen_dec_components_call(Erule,TopType,CL={Root1,ExtList,Root2},
NumExtsToSkip = ext_length(ExtList),
Finish =
fun(St) ->
- emit([{next,bytes},"= ?RT_PER:skipextensions(",{curr,bytes},",",
- NumExtsToSkip+1,",Extensions)"]),
+ emit([{next,bytes},"= "]),
+ call(Erule, skipextensions,
+ [{curr,bytes},NumExtsToSkip+1,"Extensions"]),
asn1ct_name:new(bytes),
St
end,
@@ -1276,8 +1295,8 @@ gen_dec_comp_call(Comp, Erule, TopType, Tpos, OptTable, DecInfObj,
St
end},
[{group,[{safe,Comment},{safe,Preamble},
- {safe,OptOrDef}|Lines]++
- [{safe,Postamble},{safe,AdvBuffer}]}].
+ OptOrDef|Lines]++
+ [Postamble,{safe,AdvBuffer}]}].
is_mandatory_predef_tab_c(noext, mandatory,
{"got objfun through args","ObjFun"}) ->
@@ -1499,7 +1518,6 @@ gen_dec_line_dec_inf(Comp, DecInfObj) ->
gen_dec_line_other(Erule, Atype, TopType, Comp) ->
#'ComponentType'{name=Cname,typespec=Type} = Comp,
CurrMod = get(currmod),
- Ctgenmod = asn1ct_gen:ct_gen_module(Erule),
case asn1ct_gen:type(Atype) of
#'Externaltypereference'{module=CurrMod,type=EType} ->
fun(BytesVar) ->
@@ -1513,16 +1531,16 @@ gen_dec_line_other(Erule, Atype, TopType, Comp) ->
{primitive,bif} ->
case Atype of
{fixedtypevaluefield,_,Btype} ->
- gen_dec_prim(Ctgenmod, Erule, Btype);
+ asn1ct_gen_per:gen_dec_imm(Erule, Btype);
_ ->
- gen_dec_prim(Ctgenmod, Erule, Type)
+ asn1ct_gen_per:gen_dec_imm(Erule, Type)
end;
'ASN1_OPEN_TYPE' ->
case Type#type.def of
#'ObjectClassFieldType'{type=OpenType} ->
- gen_dec_prim(Ctgenmod, Erule, #type{def=OpenType});
+ asn1ct_gen_per:gen_dec_imm(Erule, #type{def=OpenType});
_ ->
- gen_dec_prim(Ctgenmod, Erule, Type)
+ asn1ct_gen_per:gen_dec_imm(Erule, Type)
end;
#typereference{val=Dname} ->
fun(BytesVar) ->
@@ -1548,40 +1566,34 @@ gen_dec_line_other(Erule, Atype, TopType, Comp) ->
end
end.
-gen_dec_prim(Ctgenmod, Erule, Type) ->
- case asn1ct_gen_per:gen_dec_imm(Erule, Type) of
- no ->
- fun(BytesVar) ->
- Ctgenmod:gen_dec_prim(Erule, Type, BytesVar)
- end;
- Imm ->
- Imm
- end.
-
gen_enc_choice(Erule,TopType,CompList,Ext) ->
- gen_enc_choice_tag(CompList, [], Ext),
+ gen_enc_choice_tag(Erule, CompList, [], Ext),
emit({com,nl}),
emit({"case element(1,Val) of",nl}),
gen_enc_choice2(Erule,TopType, CompList, Ext),
emit({nl,"end"}).
-gen_enc_choice_tag({C1,C2},_,_) ->
+gen_enc_choice_tag(Erule, {C1,C2}, _, _) ->
N1 = get_name_list(C1),
N2 = get_name_list(C2),
- emit(["?RT_PER:set_choice(element(1,Val),",
- {asis,{N1,N2}},", ",{asis,{length(N1),length(N2)}},")"]);
-
-gen_enc_choice_tag({C1,C2,C3},_,_) ->
+ call(Erule,set_choice,
+ ["element(1, Val)",
+ {asis,{N1,N2}},
+ {asis,{length(N1),length(N2)}}]);
+gen_enc_choice_tag(Erule, {C1,C2,C3}, _, _) ->
N1 = get_name_list(C1),
N2 = get_name_list(C2),
N3 = get_name_list(C3),
Root = N1 ++ N3,
- emit(["?RT_PER:set_choice(element(1,Val),",
- {asis,{Root,N2}},", ",{asis,{length(Root),length(N2)}},")"]);
-gen_enc_choice_tag(C,_,_) ->
+ call(Erule,set_choice,
+ ["element(1, Val)",
+ {asis,{Root,N2}},
+ {asis,{length(Root),length(N2)}}]);
+gen_enc_choice_tag(Erule, C, _, _) ->
N = get_name_list(C),
- emit(["?RT_PER:set_choice(element(1,Val),",
- {asis,N},", ",{asis,length(N)},")"]).
+ call(Erule,set_choice,
+ ["element(1, Val)",
+ {asis,N},{asis,length(N)}]).
get_name_list(L) ->
get_name_list(L,[]).
@@ -1650,17 +1662,18 @@ gen_enc_choice2(_Erule,_,[], _, _) ->
true.
gen_dec_choice(Erule,TopType,CompList,{ext,Pos,NumExt}) ->
- emit({"{Ext,",{curr,bytes},"} = ?RT_PER:getbit(Bytes),",nl}),
+ emit(["{Ext,",{curr,bytes},"} = ",
+ {call,Erule,getbit,["Bytes"]},com,nl]),
asn1ct_name:new(bytes),
gen_dec_choice1(Erule,TopType,CompList,{ext,Pos,NumExt});
gen_dec_choice(Erule,TopType,CompList,noext) ->
gen_dec_choice1(Erule,TopType,CompList,noext).
gen_dec_choice1(Erule,TopType,CompList,noext) ->
- emit({"{Choice,",{curr,bytes},
- "} = ?RT_PER:getchoice(",{prev,bytes},",",
- length(CompList),", 0),",nl}),
- emit({"{Cname,{Val,NewBytes}} = case Choice of",nl}),
+ emit(["{Choice,",{curr,bytes},
+ "} = ",{call,Erule,getchoice,
+ [{prev,bytes},length(CompList),"0"]},com,nl,
+ "{Cname,{Val,NewBytes}} = case Choice of",nl]),
gen_dec_choice2(Erule,TopType,CompList,noext),
emit({nl,"end,",nl}),
emit({nl,"{{Cname,Val},NewBytes}"});
@@ -1671,9 +1684,9 @@ gen_dec_choice1(Erule,TopType,{RootList,ExtList,RootList2},Ext) ->
NewList = RootList ++ RootList2 ++ ExtList,
gen_dec_choice1(Erule,TopType, NewList, Ext);
gen_dec_choice1(Erule,TopType,CompList,{ext,ExtPos,ExtNum}) ->
- emit({"{Choice,",{curr,bytes},
- "} = ?RT_PER:getchoice(",{prev,bytes},",",
- length(CompList)-ExtNum,",Ext ),",nl}),
+ emit(["{Choice,",{curr,bytes},"} = ",
+ {call,Erule,getchoice,
+ [{prev,bytes},length(CompList)-ExtNum,"Ext"]},com,nl]),
emit({"{Cname,{Val,NewBytes}} = case Choice + Ext*",ExtPos-1," of",nl}),
gen_dec_choice2(Erule,TopType,CompList,{ext,ExtPos,ExtNum}),
Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
diff --git a/lib/asn1/src/asn1ct_eval_ext.funcs b/lib/asn1/src/asn1ct_eval_ext.funcs
new file mode 100644
index 0000000000..5761901f89
--- /dev/null
+++ b/lib/asn1/src/asn1ct_eval_ext.funcs
@@ -0,0 +1 @@
+{ext,transform_to_EXTERNAL1994,1}.
diff --git a/lib/asn1/src/asn1ct_eval_per.funcs b/lib/asn1/src/asn1ct_eval_per.funcs
new file mode 100644
index 0000000000..a1ea5cd043
--- /dev/null
+++ b/lib/asn1/src/asn1ct_eval_per.funcs
@@ -0,0 +1,2 @@
+{per,encode_constrained_number,2}.
+{per,encode_small_number,1}.
diff --git a/lib/asn1/src/asn1ct_eval_uper.funcs b/lib/asn1/src/asn1ct_eval_uper.funcs
new file mode 100644
index 0000000000..884a486f40
--- /dev/null
+++ b/lib/asn1/src/asn1ct_eval_uper.funcs
@@ -0,0 +1,2 @@
+{uper,encode_constrained_number,2}.
+{uper,encode_small_number,1}.
diff --git a/lib/asn1/src/asn1ct_func.erl b/lib/asn1/src/asn1ct_func.erl
new file mode 100644
index 0000000000..2d221ca1b9
--- /dev/null
+++ b/lib/asn1/src/asn1ct_func.erl
@@ -0,0 +1,105 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1ct_func).
+-export([start_link/0,need/1,call/3,generate/1]).
+-export([init/1,handle_call/3,handle_cast/2,terminate/2]).
+
+start_link() ->
+ {ok,Pid} = gen_server:start_link(?MODULE, [], []),
+ put(?MODULE, Pid),
+ ok.
+
+call(M, F, Args) ->
+ MFA = {M,F,length(Args)},
+ need(MFA),
+ asn1ct_gen:emit([F,"(",call_args(Args, ""),")"]).
+
+need(MFA) ->
+ asn1ct_rtt:assert_defined(MFA),
+ cast({need,MFA}).
+
+generate(Fd) ->
+ req({generate,Fd}),
+ erase(?MODULE),
+ ok.
+
+req(Req) ->
+ gen_server:call(get(?MODULE), Req, infinity).
+
+cast(Req) ->
+ gen_server:cast(get(?MODULE), Req).
+
+%%% Internal functions.
+
+-record(st, {used}).
+
+init([]) ->
+ St = #st{used=gb_sets:empty()},
+ {ok,St}.
+
+handle_cast({need,MFA}, #st{used=Used0}=St) ->
+ case gb_sets:is_member(MFA, Used0) of
+ false ->
+ Used = pull_in_deps(gb_sets:singleton(MFA), Used0),
+ {noreply,St#st{used=Used}};
+ true ->
+ {noreply,St}
+ end.
+
+handle_call({generate,Fd}, _From, #st{used=Used}=St) ->
+ generate(Fd, Used),
+ {stop,normal,ok,St}.
+
+terminate(_, _) ->
+ ok.
+
+call_args([A|As], Sep) ->
+ [Sep,A|call_args(As, ", ")];
+call_args([], _) -> [].
+
+generate(Fd, Used0) ->
+ Used1 = gb_sets:to_list(Used0),
+ Used = sofs:set(Used1, [mfa]),
+ Code = sofs:relation(asn1ct_rtt:code(), [{mfa,code}]),
+ Funcs0 = sofs:image(Code, Used),
+ Funcs = sofs:to_external(Funcs0),
+ io:put_chars(Fd, Funcs).
+
+pull_in_deps(Ws0, Used0) ->
+ case gb_sets:is_empty(Ws0) of
+ true ->
+ Used0;
+ false ->
+ {MFA,Ws1} = gb_sets:take_smallest(Ws0),
+ Used = gb_sets:add(MFA, Used0),
+ Needs = asn1ct_rtt:dependencies(MFA),
+ Ws = update_worklist(Needs, Used, Ws1),
+ pull_in_deps(Ws, Used)
+ end.
+
+update_worklist([H|T], Used, Ws) ->
+ case gb_sets:is_member(H, Used) of
+ false ->
+ update_worklist(T, Used, gb_sets:add(H, Ws));
+ true ->
+ update_worklist(T, Used, Ws)
+ end;
+update_worklist([], _, Ws) -> Ws.
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 57b12ce186..79f0593c37 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -46,7 +46,6 @@
un_hyphen_var/1]).
-export([gen_encode_constructed/4,
gen_decode_constructed/4]).
--export([nif_parameter/0]).
%% pgen(Outfile, Erules, Module, TypeOrVal, Options)
%% Generate Erlang module (.erl) and (.hrl) file corresponding to an ASN.1 module
@@ -78,6 +77,7 @@ pgen_module(OutFile,Erules,Module,
ErlFile = lists:concat([OutFile,".erl"]),
Fid = fopen(ErlFile,[write]),
put(gen_file_out,Fid),
+ asn1ct_func:start_link(),
gen_head(Erules,Module,HrlGenerated),
pgen_exports(Erules,Module,TypeOrVal),
pgen_dispatcher(Erules,Module,TypeOrVal),
@@ -86,6 +86,11 @@ pgen_module(OutFile,Erules,Module,
pgen_partial_incomplete_decode(Erules),
% gen_vars(asn1_db:mod_to_vars(Module)),
% gen_tag_table(AllTypes),
+ emit([nl,
+ "%%%",nl,
+ "%%% Run-time functions.",nl,
+ "%%%",nl]),
+ asn1ct_func:generate(Fid),
file:close(Fid),
asn1ct:verbose("--~p--~n",[{generated,ErlFile}],Options).
@@ -528,7 +533,8 @@ gen_part_decode_funcs({constructed,bif},TypeName,
{_Name,parts,Tag,_Type}) ->
emit([" case Data of",nl,
" L when is_list(L) ->",nl,
- " 'dec_",TypeName,"'(lists:map(fun(X)->element(1,?RT_BER:decode(X)) end,L),",{asis,Tag},");",nl,
+ " 'dec_",TypeName,"'(lists:map(fun(X) -> element(1, ",
+ {call,ber,ber_decode_erlang,["X"]},") end, L),",{asis,Tag},");",nl,
" _ ->",nl,
" [Res] = 'dec_",TypeName,"'([Data],",{asis,Tag},"),",nl,
" Res",nl,
@@ -802,7 +808,7 @@ 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]).",nl}),
+ emit(["-export([encoding_rule/0,bit_string_format/0]).",nl]),
case Types of
[] -> ok;
_ ->
@@ -912,23 +918,24 @@ gen_selected_decode_exports1([{FuncName,_}|Rest]) ->
gen_selected_decode_exports1(Rest).
pgen_dispatcher(Erules,_Module,{[],_Values,_,_,_Objects,_ObjectSets}) ->
- emit(["encoding_rule() ->",nl]),
- emit([{asis,Erules},".",nl,nl]);
+ gen_info_functions(Erules);
pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
- emit(["-export([encode/2,decode/2,encode_disp/2,decode_disp/2]).",nl,nl]),
- emit(["encoding_rule() ->",nl]),
- emit([" ",{asis,Erules},".",nl,nl]),
+ emit(["-export([encode/2,decode/2]).",nl,nl]),
+ gen_info_functions(Erules),
NoFinalPadding = lists:member(no_final_padding,get(encoding_options)),
{Call,BytesAsBinary} =
case Erules of
per ->
- {["?RT_PER:complete(encode_disp(Type,Data))"],"Bytes"};
+ asn1ct_func:need({Erules,complete,1}),
+ {["complete(encode_disp(Type, Data))"],"Bytes"};
ber ->
{"encode_disp(Type,Data)","iolist_to_binary(Bytes)"};
uper when NoFinalPadding == true ->
- {"?RT_PER:complete_NFP(encode_disp(Type,Data))","Bytes"};
+ asn1ct_func:need({Erules,complete_NFP,1}),
+ {"complete_NFP(encode_disp(Type, Data))","Bytes"};
uper ->
- {["?RT_PER:complete(encode_disp(Type,Data))"],"Bytes"}
+ asn1ct_func:need({Erules,complete,1}),
+ {["complete(encode_disp(Type, Data))"],"Bytes"}
end,
emit(["encode(Type,Data) ->",nl,
"case catch ",Call," of",nl,
@@ -952,12 +959,11 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
DecAnonymous =
case {Erules,Return_rest} of
{ber,false} ->
- io_lib:format("~s~s~s~n",
- ["element(1,?RT_BER:decode(Data",
- nif_parameter(),"))"]);
+ asn1ct_func:need({ber,ber_decode_nif,1}),
+ "element(1, ber_decode_nif(Data))";
{ber,true} ->
- emit(["{Data,Rest} = ?RT_BER:decode(Data0",
- nif_parameter(),"),",nl]),
+ asn1ct_func:need({ber,ber_decode_nif,1}),
+ emit(["{Data,Rest} = ber_decode_nif(Data0),",nl]),
"Data";
_ ->
"Data"
@@ -1020,6 +1026,11 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
emit([nl]),
emit({nl,nl}).
+gen_info_functions(Erules) ->
+ emit(["encoding_rule() -> ",
+ {asis,Erules},".",nl,nl,
+ "bit_string_format() -> ",
+ {asis,asn1ct:get_bit_string_format()},".",nl,nl]).
gen_decode_partial_incomplete(ber) ->
case {asn1ct:read_config_data(partial_incomplete_decode),
@@ -1042,16 +1053,16 @@ gen_decode_partial_incomplete(ber) ->
emit(["decode_partial_incomplete(Type,Data0,",
"Pattern) ->",nl]),
emit([" {Data,_RestBin} =",nl,
- " ?RT_BER:decode_primitive_",
- "incomplete(Pattern,Data0),",nl,
+ " ",{call,ber,decode_primitive_incomplete,
+ ["Pattern","Data0"]},com,nl,
" case catch decode_partial_inc_disp(Type,",
"Data) of",nl]),
EmitCaseClauses(),
emit([".",nl,nl]),
emit(["decode_part(Type, Data0) "
"when is_binary(Data0) ->",nl]),
- emit([" case catch decode_inc_disp(Type,element(1,"
- "?RT_BER:decode(Data0",nif_parameter(),"))) of",nl]),
+ emit([" case catch decode_inc_disp(Type,element(1, ",
+ {call,ber,ber_decode_nif,["Data0"]},")) of",nl]),
EmitCaseClauses(),
emit([";",nl]),
emit(["decode_part(Type, Data0) ->",nl]),
@@ -1095,9 +1106,6 @@ gen_partial_inc_dispatcher([],_) ->
emit(["decode_partial_inc_disp(Type,_Data) ->",nl,
" exit({error,{asn1,{undefined_type,Type}}}).",nl]).
-nif_parameter() ->
- ",nif".
-
gen_dispatcher([F1,F2|T],FuncName,Prefix,ExtraArg) ->
emit([FuncName,"('",F1,"',Data) -> '",Prefix,F1,"'(Data",ExtraArg,")",";",nl]),
gen_dispatcher([F2|T],FuncName,Prefix,ExtraArg);
@@ -1160,6 +1168,9 @@ emit({var,Variable}) ->
emit({asis,What}) ->
format(get(gen_file_out),"~w",[What]);
+emit({call,M,F,A}) ->
+ asn1ct_func:call(M, F, A);
+
emit(nl) ->
nl(get(gen_file_out));
@@ -1384,35 +1395,28 @@ gen_record(_,_,_,NumRecords) -> % skip CLASS etc for now.
gen_head(Erules,Mod,Hrl) ->
Options = get(encoding_options),
- {Rtmac,Rtmod} = case Erules of
- per ->
- emit({"%% Generated by the Erlang ASN.1 PER-"
- "compiler version, utilizing bit-syntax:",
- asn1ct:vsn(),nl}),
- {"RT_PER","asn1rt_per_bin_rt2ct"};
- ber ->
- emit({"%% Generated by the Erlang ASN.1 BER_V2-"
- "compiler version, utilizing bit-syntax:",
- asn1ct:vsn(),nl}),
- {"RT_BER","asn1rt_ber_bin_v2"};
- uper ->
- emit(["%% Generated by the Erlang ASN.1 UNALIGNED"
- " PER-compiler version, utilizing"
- " bit-syntax:",
- asn1ct:vsn(),nl]),
- {"RT_PER","asn1rt_uper_bin"}
+ case Erules of
+ per ->
+ emit(["%% Generated by the Erlang ASN.1 PER-"
+ "compiler version, utilizing bit-syntax:",
+ asn1ct:vsn(),nl]);
+ ber ->
+ emit(["%% Generated by the Erlang ASN.1 BER_V2-"
+ "compiler version, utilizing bit-syntax:",
+ asn1ct:vsn(),nl]);
+ uper ->
+ emit(["%% Generated by the Erlang ASN.1 UNALIGNED"
+ " PER-compiler version, utilizing bit-syntax:",
+ asn1ct:vsn(),nl])
end,
emit({"%% Purpose: encoder and decoder to the types in mod ",Mod,nl,nl}),
emit({"-module('",Mod,"').",nl}),
put(currmod,Mod),
emit({"-compile(nowarn_unused_vars).",nl}),
- case {Hrl,lists:member(inline,get(encoding_options))} of
- {0,_} -> true;
- {_,true} -> true;
- _ ->
- emit({"-include(\"",Mod,".hrl\").",nl})
+ case Hrl of
+ 0 -> ok;
+ _ -> emit({"-include(\"",Mod,".hrl\").",nl})
end,
- emit(["-define('",Rtmac,"',",Rtmod,").",nl]),
emit(["-asn1_info([{vsn,'",asn1ct:vsn(),"'},",nl,
" {module,'",Mod,"'},",nl,
" {options,",io_lib:format("~p",[Options]),"}]).",nl,nl]).
@@ -1493,50 +1497,41 @@ gen_check_call(TopType,Cname,Type,InnerType,WhatKind,DefaultValue,Element) ->
emit(["fun() -> true end ()"])
end.
-gen_prim_check_call(PrimType,DefaultValue,Element,Type) ->
+gen_prim_check_call(PrimType, Default, Element, Type) ->
case unify_if_string(PrimType) of
'BOOLEAN' ->
- emit({"asn1rt_check:check_bool(",DefaultValue,", ",
- Element,")"});
+ check_call(check_bool, [Default,Element]);
'INTEGER' ->
- NNL =
- case Type#type.def of
- {_,NamedNumberList} -> NamedNumberList;
- _ -> []
- end,
- emit({"asn1rt_check:check_int(",DefaultValue,", ",
- Element,", ",{asis,NNL},")"});
+ NNL = case Type#type.def of
+ {_,NamedNumberList} -> NamedNumberList;
+ _ -> []
+ end,
+ check_call(check_int, [Default,Element,{asis,NNL}]);
'BIT STRING' ->
{_,NBL} = Type#type.def,
- emit({"asn1rt_check:check_bitstring(",DefaultValue,", ",
- Element,", ",{asis,NBL},")"});
+ check_call(check_bitstring, [Default,Element,{asis,NBL}]);
'OCTET STRING' ->
- emit({"asn1rt_check:check_octetstring(",DefaultValue,", ",
- Element,")"});
+ check_call(check_octetstring, [Default,Element]);
'NULL' ->
- emit({"asn1rt_check:check_null(",DefaultValue,", ",
- Element,")"});
+ check_call(check_null, [Default,Element]);
'OBJECT IDENTIFIER' ->
- emit({"asn1rt_check:check_objectidentifier(",DefaultValue,
- ", ",Element,")"});
+ check_call(check_objectidentifier, [Default,Element]);
'RELATIVE-OID' ->
- emit({"asn1rt_check:check_objectidentifier(",DefaultValue,
- ", ",Element,")"});
+ check_call(check_objectidentifier, [Default,Element]);
'ObjectDescriptor' ->
- emit({"asn1rt_check:check_objectdescriptor(",DefaultValue,
- ", ",Element,")"});
+ check_call(check_objectdescriptor, [Default,Element]);
'REAL' ->
- emit({"asn1rt_check:check_real(",DefaultValue,
- ", ",Element,")"});
+ check_call(check_real, [Default,Element]);
'ENUMERATED' ->
{_,Enumerations} = Type#type.def,
- emit({"asn1rt_check:check_enum(",DefaultValue,
- ", ",Element,", ",{asis,Enumerations},")"});
+ check_call(check_enum, [Default,Element,{asis,Enumerations}]);
restrictedstring ->
- emit({"asn1rt_check:check_restrictedstring(",DefaultValue,
- ", ",Element,")"})
+ 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) ->
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index 664dfc2086..121f452da8 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -170,139 +170,84 @@ gen_encode_user(Erules,D) when is_record(D,typedef) ->
end.
gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
-
-%%% Constraint is currently not used for BER (except for BitString) and therefore replaced
-%%% with [] as a placeholder
BitStringConstraint = D#type.constraint,
- Constraint = [],
asn1ct_name:new(enumval),
- case D#type.def of
+ Type = case D#type.def of
+ 'OCTET STRING' -> restricted_string;
+ 'ObjectDescriptor'-> restricted_string;
+ 'NumericString' -> restricted_string;
+ 'TeletexString' -> restricted_string;
+ 'T61String' -> restricted_string;
+ 'VideotexString' -> restricted_string;
+ 'GraphicString' -> restricted_string;
+ 'VisibleString' -> restricted_string;
+ 'GeneralString' -> restricted_string;
+ 'PrintableString' -> restricted_string;
+ 'IA5String' -> restricted_string;
+ Other -> Other
+ end,
+ case Type of
+ restricted_string ->
+ call(encode_restricted_string, [Value,DoTag]);
'BOOLEAN' ->
- emit_encode_func('boolean',Value,DoTag);
+ call(encode_boolean, [Value,DoTag]);
'INTEGER' ->
- emit_encode_func('integer',Constraint,Value,DoTag);
+ call(encode_integer, [Value,DoTag]);
{'INTEGER',NamedNumberList} ->
- emit_encode_func('integer',Constraint,Value,
- NamedNumberList,DoTag);
+ call(encode_integer, [Value,{asis,NamedNumberList}, DoTag]);
{'ENUMERATED',NamedNumberList={_,_}} ->
-
emit(["case ",Value," of",nl]),
emit_enc_enumerated_cases(NamedNumberList,DoTag);
{'ENUMERATED',NamedNumberList} ->
-
emit(["case ",Value," of",nl]),
emit_enc_enumerated_cases(NamedNumberList,DoTag);
-
'REAL' ->
- emit_encode_func('real',Constraint,Value,DoTag);
-
+ emit([{call,ber,encode_tags,
+ [DoTag,{call,real_common,ber_encode_real,[Value]}]}]);
{'BIT STRING',NamedNumberList} ->
- emit_encode_func('bit_string',BitStringConstraint,Value,
- NamedNumberList,DoTag);
+ call(encode_bit_string,
+ [{asis,BitStringConstraint},Value,
+ {asis,NamedNumberList},DoTag]);
'ANY' ->
- emit_encode_func('open_type', Value,DoTag);
+ call(encode_open_type, [Value,DoTag]);
'NULL' ->
- emit_encode_func('null',Value,DoTag);
+ call(encode_null, [Value,DoTag]);
'OBJECT IDENTIFIER' ->
- emit_encode_func("object_identifier",Value,DoTag);
+ call(encode_object_identifier, [Value,DoTag]);
'RELATIVE-OID' ->
- emit_encode_func("relative_oid",Value,DoTag);
- 'ObjectDescriptor' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_ObjectDescriptor,DoTag);
- 'OCTET STRING' ->
- emit_encode_func('octet_string',Constraint,Value,DoTag);
- 'NumericString' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_NumericString,DoTag);
- TString when TString == 'TeletexString';
- TString == 'T61String' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_TeletexString,DoTag);
- 'VideotexString' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_VideotexString,DoTag);
- 'GraphicString' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_GraphicString,DoTag);
- 'VisibleString' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_VisibleString,DoTag);
- 'GeneralString' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_GeneralString,DoTag);
- 'PrintableString' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_PrintableString,DoTag);
- 'IA5String' ->
- emit_encode_func('restricted_string',Constraint,Value,
- ?T_IA5String,DoTag);
+ call(encode_relative_oid, [Value,DoTag]);
'UniversalString' ->
- emit_encode_func('universal_string',Constraint,Value,DoTag);
+ call(encode_universal_string, [Value,DoTag]);
'UTF8String' ->
- emit_encode_func('UTF8_string',Constraint,Value,DoTag);
+ call(encode_UTF8_string, [Value,DoTag]);
'BMPString' ->
- emit_encode_func('BMP_string',Constraint,Value,DoTag);
+ call(encode_BMP_string, [Value,DoTag]);
'UTCTime' ->
- emit_encode_func('utc_time',Constraint,Value,DoTag);
+ call(encode_utc_time, [Value,DoTag]);
'GeneralizedTime' ->
- emit_encode_func('generalized_time',Constraint,Value,DoTag);
+ call(encode_generalized_time, [Value,DoTag]);
'ASN1_OPEN_TYPE' ->
- emit_encode_func('open_type', Value,DoTag);
+ call(encode_open_type, [Value,DoTag]);
#'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(D#type.def) of
{fixedtypevaluefield,_,InnerType} ->
gen_encode_prim(Erules,InnerType,DoTag,Value);
'ASN1_OPEN_TYPE' ->
- emit_encode_func('open_type', Value,DoTag);
- XX ->
- exit({'can not encode' ,XX})
- end;
- XX ->
- exit({'can not encode' ,XX})
+ call(encode_open_type, [Value,DoTag])
+ end
end.
-
-emit_encode_func(Name,Value,Tags) when is_atom(Name) ->
- emit_encode_func(atom_to_list(Name),Value,Tags);
-emit_encode_func(Name,Value,Tags) ->
- Fname = "?RT_BER:encode_" ++ Name,
- emit([Fname,"(",Value,", ",Tags,")"]).
-
-emit_encode_func(Name,Constraint,Value,Tags) when is_atom(Name) ->
- emit_encode_func(atom_to_list(Name),Constraint,Value,Tags);
-emit_encode_func(Name,Constraint,Value,Tags) ->
- Fname = "?RT_BER:encode_" ++ Name,
- emit([Fname,"(",{asis,Constraint},", ",Value,", ",Tags,")"]).
-
-emit_encode_func(Name,Constraint,Value,Asis,Tags) when is_atom(Name) ->
- emit_encode_func(atom_to_list(Name),Constraint,Value,Asis,Tags);
-emit_encode_func(Name,Constraint,Value,Asis,Tags) ->
- Fname = "?RT_BER:encode_" ++ Name,
- emit([Fname,"(",{asis,Constraint},", ",Value,
- ", ",{asis,Asis},
- ", ",Tags,")"]).
-
emit_enc_enumerated_cases({L1,L2}, Tags) ->
emit_enc_enumerated_cases(L1++L2, Tags, ext);
emit_enc_enumerated_cases(L, Tags) ->
emit_enc_enumerated_cases(L, Tags, noext).
-emit_enc_enumerated_cases([{EnumName,EnumVal},H2|T], Tags, Ext) ->
- emit([{asis,EnumName}," -> ?RT_BER:encode_enumerated(",EnumVal,",",Tags,");",nl]),
-%% emit(["'",{asis,EnumName},"' -> ?RT_BER:encode_enumerated(",EnumVal,",",Tags,");",nl]),
- emit_enc_enumerated_cases([H2|T], Tags, Ext);
-emit_enc_enumerated_cases([{EnumName,EnumVal}], Tags, Ext) ->
- emit([{asis,EnumName}," -> ?RT_BER:encode_enumerated(",EnumVal,",",Tags,")"]),
-%% emit(["'",{asis,EnumName},"' -> ?RT_BER:encode_enumerated(",EnumVal,",",Tags,")"]),
- case Ext of
- noext -> emit([";",nl]);
- ext ->
- emit([";",nl])
-%% emit([";",nl,"{asn1_enum,",{curr,enumval},"} -> ",
-%% "?RT_BER:encode_enumerated(",{curr,enumval},",",Tags,");",nl]),
-%% asn1ct_name:new(enumval)
- end,
+emit_enc_enumerated_cases([{EnumName,EnumVal}|T], Tags, Ext) ->
+ emit([{asis,EnumName}," -> ",
+ {call,ber,encode_enumerated,[EnumVal,Tags]},";",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"]).
@@ -365,9 +310,10 @@ gen_decode_selected(Erules,Type,FuncName) ->
{value,{_,P}} -> P;
false -> exit({error,{internal,no_pattern_saved}})
end,
- emit([" case ?RT_BER:decode_selective(",{asis,Pattern},",Bin) of",nl,
+ emit([" case ",{call,ber,decode_selective,
+ [{asis,Pattern},"Bin"]}," of",nl,
" {ok,Bin2} when is_binary(Bin2) ->",nl,
- " {Tlv,_} = ?RT_BER:decode(Bin2",asn1ct_gen:nif_parameter(),"),",nl]),
+ " {Tlv,_} = ", {call,ber,ber_decode_nif,["Bin2"]},com,nl]),
emit("{ok,"),
gen_decode_selected_type(Erules,Type),
emit(["};",nl," Err -> exit({error,{selective_decode,Err}})",nl,
@@ -549,147 +495,123 @@ gen_dec_prim(Erules,Att,BytesVar,DoTag,TagIn,Form,OptOrMand) ->
_ -> ""
end,
NewTypeName = case Typename of
- 'ANY' -> 'ASN1_OPEN_TYPE';
- _ -> Typename
+ 'ANY' -> 'ASN1_OPEN_TYPE';
+ 'OCTET STRING' -> restricted_string;
+ 'NumericString' -> restricted_string;
+ 'TeletexString' -> restricted_string;
+ 'T61String' -> restricted_string;
+ 'VideotexString' -> restricted_string;
+ 'GraphicString' -> restricted_string;
+ 'VisibleString' -> restricted_string;
+ 'GeneralString' -> restricted_string;
+ 'PrintableString' -> restricted_string;
+ 'IA5String' -> restricted_string;
+ _ -> Typename
end,
-% DoLength =
case NewTypeName of
'BOOLEAN'->
- emit({"?RT_BER:decode_boolean(",BytesVar,","}),
- add_func({decode_boolean,2});
+ emit(["decode_boolean(",BytesVar,","]),
+ need(decode_boolean, 2);
'INTEGER' ->
- emit({"?RT_BER:decode_integer(",BytesVar,",",
- {asis,int_constr(SingleValue,ValueRange)},","}),
- add_func({decode_integer,3});
+ emit(["decode_integer(",BytesVar,",",
+ {asis,int_constr(SingleValue,ValueRange)},","]),
+ need(decode_integer, 3);
{'INTEGER',NamedNumberList} ->
- emit({"?RT_BER:decode_integer(",BytesVar,",",
+ emit(["decode_integer(",BytesVar,",",
{asis,int_constr(SingleValue,ValueRange)},",",
- {asis,NamedNumberList},","}),
- add_func({decode_integer,4});
+ {asis,NamedNumberList},","]),
+ need(decode_integer, 4);
{'ENUMERATED',NamedNumberList} ->
- emit({"?RT_BER:decode_enumerated(",BytesVar,",",
- {asis,Constraint},",",
- {asis,NamedNumberList},","}),
- add_func({decode_enumerated,4});
+ emit(["decode_enumerated(",BytesVar,",",
+ {asis,NamedNumberList},","]),
+ need(decode_enumerated, 3);
'REAL' ->
- emit({"?RT_BER:decode_real(",BytesVar,","}),
- add_func({decode_real,3});
- {'BIT STRING',NamedNumberList} ->
- case get(compact_bit_string) of
- true ->
- emit({"?RT_BER:decode_compact_bit_string(",
- BytesVar,",",{asis,Constraint},",",
- {asis,NamedNumberList},","}),
- add_func({decode_compact_bit_string,4});
- _ ->
- emit({"?RT_BER:decode_bit_string(",BytesVar,",",
- {asis,Constraint},",",
- {asis,NamedNumberList},","}),
- add_func({decode_bit_string,4})
- end;
+ ok;
+ {'BIT STRING',_NamedNumberList} ->
+ ok;
'NULL' ->
- emit({"?RT_BER:decode_null(",BytesVar,","}),
- add_func({decode_null,2});
+ emit(["decode_null(",BytesVar,","]),
+ need(decode_null, 2);
'OBJECT IDENTIFIER' ->
- emit({"?RT_BER:decode_object_identifier(",BytesVar,","}),
- add_func({decode_object_identifier,2});
+ emit(["decode_object_identifier(",BytesVar,","]),
+ need(decode_object_identifier, 2);
'RELATIVE-OID' ->
- emit({"?RT_BER:decode_relative_oid(",BytesVar,","}),
- add_func({decode_relative_oid,2});
+ emit(["decode_relative_oid(",BytesVar,","]),
+ need(decode_relative_oid, 2);
'ObjectDescriptor' ->
- emit({"?RT_BER:decode_restricted_string(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_ObjectDescriptor},","}),
- add_func({decode_restricted_string,4});
- 'OCTET STRING' ->
- emit({"?RT_BER:decode_octet_string",AsBin,"(",BytesVar,",",{asis,Constraint},","}),
- add_func({decode_octet_string,3});
- 'NumericString' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_NumericString},","}),
- add_func({decode_restricted_string,4});
- TString when TString == 'TeletexString';
- TString == 'T61String' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_TeletexString},","}),
- add_func({decode_restricted_string,4});
- 'VideotexString' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_VideotexString},","}),
- add_func({decode_restricted_string,4});
- 'GraphicString' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_GraphicString},","}),
- add_func({decode_restricted_string,4});
- 'VisibleString' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_VisibleString},","}),
- add_func({decode_restricted_string,4});
- 'GeneralString' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_GeneralString},","}),
- add_func({decode_restricted_string,4});
- 'PrintableString' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_PrintableString},","}),
- add_func({decode_restricted_string,4});
- 'IA5String' ->
- emit({"?RT_BER:decode_restricted_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},",",{asis,?T_IA5String},","}),
- add_func({decode_restricted_string,4}) ;
+ emit(["decode_restricted_string(",
+ BytesVar,",",{asis,Constraint},","]),
+ need(decode_restricted_string, 3);
+ 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;
'UniversalString' ->
- emit({"?RT_BER:decode_universal_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},","}),
- add_func({decode_universal_string,3});
+ emit(["decode_universal_string",AsBin,"(",
+ BytesVar,",",{asis,Constraint},","]),
+ need(decode_universal_string, 3);
'UTF8String' ->
- emit({"?RT_BER:decode_UTF8_string",AsBin,"(",
- BytesVar,","}),
- add_func({decode_UTF8_string,2});
+ emit(["decode_UTF8_string",AsBin,"(",
+ BytesVar,","]),
+ need(decode_UTF8_string, 2);
'BMPString' ->
- emit({"?RT_BER:decode_BMP_string",AsBin,"(",
- BytesVar,",",{asis,Constraint},","}),
- add_func({decode_BMP_string,3});
+ emit(["decode_BMP_string",AsBin,"(",
+ BytesVar,",",{asis,Constraint},","]),
+ need(decode_BMP_string, 3);
'UTCTime' ->
- emit({"?RT_BER:decode_utc_time",AsBin,"(",
- BytesVar,",",{asis,Constraint},","}),
- add_func({decode_utc_time,3});
+ emit(["decode_utc_time",AsBin,"(",
+ BytesVar,",",{asis,Constraint},","]),
+ need(decode_utc_time, 3);
'GeneralizedTime' ->
- emit({"?RT_BER:decode_generalized_time",AsBin,"(",
- BytesVar,",",{asis,Constraint},","}),
- add_func({decode_generalized_time,3});
+ emit(["decode_generalized_time",AsBin,"(",
+ BytesVar,",",{asis,Constraint},","]),
+ need(decode_generalized_time, 3);
'ASN1_OPEN_TYPE' ->
- emit(["?RT_BER:decode_open_type_as_binary(",
+ emit(["decode_open_type_as_binary(",
BytesVar,","]),
- add_func({decode_open_type_as_binary,3});
+ need(decode_open_type_as_binary, 2);
#'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(Att#type.def) of
{fixedtypevaluefield,_,InnerType} ->
gen_dec_prim(Erules,InnerType,BytesVar,DoTag,TagIn,Form,OptOrMand);
'ASN1_OPEN_TYPE' ->
- emit(["?RT_BER:decode_open_type_as_binary(",
+ emit(["decode_open_type_as_binary(",
BytesVar,","]),
- add_func({decode_open_type_as_binary,3});
+ need(decode_open_type_as_binary, 2);
Other ->
- exit({'can not decode' ,Other})
+ exit({'cannot decode',Other})
end;
Other ->
- exit({'can not decode' ,Other})
+ exit({'cannot decode',Other})
end,
- case {DoTag,NewTypeName} of
- {_,#'ObjectClassFieldType'{}} ->
+ 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]);
+ #'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(Att#type.def) of
'ASN1_OPEN_TYPE' ->
- emit([{asis,DoTag},asn1ct_gen:nif_parameter(),")"]);
+ emit([TagStr,")"]);
_ -> ok
end;
- {{string,TagStr},'ASN1_OPEN_TYPE'} ->
- emit([TagStr,asn1ct_gen:nif_parameter(),")"]);
- {_,'ASN1_OPEN_TYPE'} ->
- emit([{asis,DoTag},asn1ct_gen:nif_parameter(),")"]);
- {{string,TagStr},_} ->
- emit([TagStr,")"]);
- _ when is_list(DoTag) ->
- emit([{asis,DoTag},")"])
+ _ ->
+ emit([TagStr,")"])
end.
@@ -701,6 +623,23 @@ int_constr(SingleValue,[]) ->
SingleValue;
int_constr(SV,VR) ->
[SV,VR].
+
+gen_dec_bit_string(BytesVar, _Constraint, [_|_]=NNL, TagStr) ->
+ call(decode_named_bit_string,
+ [BytesVar,{asis,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]);
+ legacy ->
+ call(decode_legacy_bit_string,
+ [BytesVar,{asis,Constraint},TagStr]);
+ bitstring ->
+ call(decode_native_bit_string,
+ [BytesVar,{asis,Constraint},TagStr])
+ end.
+
%% Object code generating for encoding and decoding
%% ------------------------------------------------
@@ -1015,7 +954,7 @@ emit_tlv_format_function() ->
end.
emit_tlv_format_function1() ->
emit(["tlv_format(Bytes) when is_binary(Bytes) ->",nl,
- " {Tlv,_}=?RT_BER:decode(Bytes",asn1ct_gen:nif_parameter(),"),",nl,
+ " {Tlv,_} = ",{call,ber,ber_decode_nif,["Bytes"]},com,nl,
" Tlv;",nl,
"tlv_format(Bytes) ->",nl,
" Bytes.",nl]).
@@ -1449,38 +1388,22 @@ gen_objset_dec(_,ObjSetName,UniqueName,[{ObjName,Val,Fields}],
emit_default_getdec(ObjSetName,UniqueName),
emit([".",nl,nl]),
ok;
-gen_objset_dec(Erules,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
+gen_objset_dec(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
_ClFields,_NthObj) ->
emit(["'getdec_",ObjSetName,"'(_, _) ->",nl]),
emit([indent(2),"fun(_,Bytes, _RestPrimFieldName) ->",nl]),
- case Erules of
- ber ->
- emit([indent(4),"case Bytes of",nl,
- indent(6),"Bin when is_binary(Bin) -> ",nl,
- indent(8),"Bin;",nl,
- indent(6),"_ ->",nl,
- indent(8),"?RT_BER:encode(Bytes",driver_parameter(),")",nl,
- indent(4),"end",nl]);
- _ ->
- emit([indent(6),"Len = case Bytes of",nl,indent(9),
- "Bin when is_binary(Bin) -> size(Bin);",nl,indent(9),
- "_ -> length(Bytes)",nl,indent(6),"end,"]),
- emit([indent(4),"{Bytes,[],Len}",nl])
- end,
+ emit([indent(4),"case Bytes of",nl,
+ indent(6),"Bin when is_binary(Bin) -> ",nl,
+ indent(8),"Bin;",nl,
+ indent(6),"_ ->",nl,
+ indent(8),{call,ber,ber_encode,["Bytes"]},nl,
+ indent(4),"end",nl]),
emit([indent(2),"end.",nl,nl]),
ok;
gen_objset_dec(_,_,_,[],_,_,_) ->
ok.
-driver_parameter() ->
- Options = get(encoding_options),
- case {lists:member(driver,Options),lists:member(nif,Options)} of
- {true,_} -> ",nif";
- {_,true} -> ",nif";
- _ -> ",erlang"
- end.
-
emit_default_getdec(ObjSetName,UniqueName) ->
emit(["'getdec_",ObjSetName,"'(",{asis,UniqueName},", ErrV) ->",nl]),
emit([indent(2), "fun(C,V,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]).
@@ -1771,9 +1694,6 @@ mk_object_val(0, Ack, Len) ->
mk_object_val(Val, Ack, Len) ->
mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
-add_func(F={_Func,_Arity}) ->
- asn1ct_table:insert(asn1_functab, {F}).
-
%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding
%% and therefore we only filter away the ExtensionAdditionGroup start and end markers
extaddgroup2sequence(ExtList) when is_list(ExtList) ->
@@ -1785,4 +1705,8 @@ extaddgroup2sequence(ExtList) when is_list(ExtList) ->
true
end, 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_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index af19edb908..3b320065d2 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -35,6 +35,7 @@
-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
+-import(asn1ct_func, [call/3]).
%% pgen(Erules, Module, TypeOrVal)
%% Generate Erlang module (.erl) and (.hrl) file corresponding to an ASN.1 module
@@ -92,13 +93,6 @@ gen_encode_user(Erules,D) when is_record(D,typedef) ->
Typename = [D#typedef.name],
Def = D#typedef.typespec,
InnerType = asn1ct_gen:get_inner(Def#type.def),
- case InnerType of
- 'SET' -> true;
- 'SEQUENCE' -> true;
- _ ->
- emit({nl,"'enc_",asn1ct_gen:list2name(Typename),"'({'",asn1ct_gen:list2name(Typename),"',Val}) ->",nl}),
- emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val);",nl,nl})
- end,
emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val) ->",nl}),
case asn1ct_gen:type(InnerType) of
{primitive,bif} ->
@@ -134,107 +128,96 @@ gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
asn1ct_name:new(enumval),
case D#type.def of
'INTEGER' ->
- emit({"?RT_PER:encode_integer(", %fel
- {asis,asn1ct_imm:effective_constraint(integer,Constraint)},
- ",",Value,")"});
+ Args = [{asis,asn1ct_imm:effective_constraint(integer,Constraint)},
+ Value],
+ call(Erules, encode_integer, Args);
{'INTEGER',NamedNumberList} ->
- emit({"?RT_PER:encode_integer(",
- {asis,asn1ct_imm:effective_constraint(integer,Constraint)},
- ",",Value,",",
- {asis,NamedNumberList},")"});
+ Args = [{asis,asn1ct_imm:effective_constraint(integer,Constraint)},
+ Value,{asis,NamedNumberList}],
+ call(Erules, encode_integer, Args);
{'ENUMERATED',{Nlist1,Nlist2}} ->
- NewList = lists:concat([[{0,X}||{X,_} <- Nlist1],['EXT_MARK'],[{1,X}||{X,_} <- Nlist2]]),
- NewC = [{'ValueRange',{0,length(Nlist1)-1}}],
- case Erules of
- uper ->
- emit(["case ",Value," of",nl]);
- _ ->
- emit(["case (case ",Value," of {_,",{curr,enumval},"}-> ",
- {curr,enumval},";_->", Value," end) of",nl]),
- asn1ct_name:new(enumval)
- end,
-%% emit_enc_enumerated_cases(Erules,NewC, NewList++[{asn1_enum,length(Nlist1)-1}], 0);
- emit_enc_enumerated_cases(Erules,NewC, NewList, 0);
+ NewList = [{0,X} || {X,_} <- Nlist1] ++ ['EXT_MARK'] ++
+ [{1,X} || {X,_} <- Nlist2],
+ NewC = {0,length(Nlist1)-1},
+ emit(["case ",Value," of",nl]),
+ emit_enc_enumerated_cases(Erules, NewC, NewList, 0);
{'ENUMERATED',NamedNumberList} ->
- NewList = [X||{X,_} <- NamedNumberList],
- NewC = [{'ValueRange',{0,length(NewList)-1}}],
- case Erules of
- uper ->
- emit(["case ",Value," of",nl]);
- _ ->
- emit(["case (case ",Value," of {_,",{curr,enumval},
- "}->",{curr,enumval},";_->",Value," end) of",nl])
- end,
- emit_enc_enumerated_cases(Erules,NewC, NewList, 0);
+ NewList = [X || {X,_} <- NamedNumberList],
+ NewC = {0,length(NewList)-1},
+ emit(["case ",Value," of",nl]),
+ emit_enc_enumerated_cases(Erules, NewC, NewList, 0);
'REAL' ->
- emit({"?RT_PER:encode_real(",Value,")"});
+ emit_enc_real(Erules, Value);
{'BIT STRING',NamedNumberList} ->
- emit({"?RT_PER:encode_bit_string(",
- {asis,Constraint},",",Value,",",
- {asis,NamedNumberList},")"});
+ SizeConstr = get_constraint(Constraint, 'SizeConstraint'),
+ call(Erules, encode_bit_string,
+ [{asis,SizeConstr},Value,
+ {asis,NamedNumberList}]);
'NULL' ->
emit("[]");
'OBJECT IDENTIFIER' ->
- emit({"?RT_PER:encode_object_identifier(",Value,")"});
+ call(Erules, encode_object_identifier, [Value]);
'RELATIVE-OID' ->
- emit({"?RT_PER:encode_relative_oid(",Value,")"});
+ call(Erules, encode_relative_oid, [Value]);
'ObjectDescriptor' ->
- emit({"?RT_PER:encode_ObjectDescriptor(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_ObjectDescriptor,
+ [{asis,Constraint},Value]);
'BOOLEAN' ->
- emit({"?RT_PER:encode_boolean(",Value,")"});
+ call(Erules, encode_boolean, [Value]);
'OCTET STRING' ->
- emit({"?RT_PER:encode_octet_string(",{asis,Constraint},",",Value,")"});
+ case get_constraint(Constraint, 'SizeConstraint') of
+ 0 ->
+ emit("[]");
+ no ->
+ call(Erules, encode_octet_string, [Value]);
+ C ->
+ call(Erules, encode_octet_string, [{asis,C},Value])
+ end;
'NumericString' ->
- emit({"?RT_PER:encode_NumericString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_NumericString, [{asis,Constraint},Value]);
TString when TString == 'TeletexString';
TString == 'T61String' ->
- emit({"?RT_PER:encode_TeletexString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_TeletexString, [{asis,Constraint},Value]);
'VideotexString' ->
- emit({"?RT_PER:encode_VideotexString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_VideotexString, [{asis,Constraint},Value]);
'UTCTime' ->
- emit({"?RT_PER:encode_VisibleString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_VisibleString, [{asis,Constraint},Value]);
'GeneralizedTime' ->
- emit({"?RT_PER:encode_VisibleString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_VisibleString, [{asis,Constraint},Value]);
'GraphicString' ->
- emit({"?RT_PER:encode_GraphicString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_GraphicString, [{asis,Constraint},Value]);
'VisibleString' ->
- emit({"?RT_PER:encode_VisibleString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_VisibleString, [{asis,Constraint},Value]);
'GeneralString' ->
- emit({"?RT_PER:encode_GeneralString(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_GeneralString, [{asis,Constraint},Value]);
'PrintableString' ->
- emit({"?RT_PER:encode_PrintableString(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_PrintableString, [{asis,Constraint},Value]);
'IA5String' ->
- emit({"?RT_PER:encode_IA5String(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_IA5String, [{asis,Constraint},Value]);
'BMPString' ->
- emit({"?RT_PER:encode_BMPString(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_BMPString, [{asis,Constraint},Value]);
'UniversalString' ->
- emit({"?RT_PER:encode_UniversalString(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_UniversalString, [{asis,Constraint},Value]);
'UTF8String' ->
- emit({"?RT_PER:encode_UTF8String(",Value,")"});
+ call(Erules, encode_UTF8String, [Value]);
'ANY' ->
- emit(["?RT_PER:encode_open_type(", {asis,Constraint}, ",",
- Value, ")"]);
+ call(Erules, encode_open_type, [Value]);
'ASN1_OPEN_TYPE' ->
NewValue = case Constraint of
[#'Externaltypereference'{type=Tname}] ->
- io_lib:format(
- "?RT_PER:complete(enc_~s(~s))",[Tname,Value]);
+ asn1ct_func:need({Erules,complete,1}),
+ io_lib:format(
+ "complete(enc_~s(~s))",[Tname,Value]);
[#type{def=#'Externaltypereference'{type=Tname}}] ->
+ asn1ct_func:need({Erules,complete,1}),
io_lib:format(
- "?RT_PER:complete(enc_~s(~s))",
+ "complete(enc_~s(~s))",
[Tname,Value]);
_ -> Value
end,
- emit(["?RT_PER:encode_open_type(", {asis,Constraint}, ",",
- NewValue, ")"]);
+ call(Erules, encode_open_type, [NewValue]);
#'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(D#type.def) of
{fixedtypevaluefield,_,InnerType} ->
@@ -246,46 +229,48 @@ gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
exit({asn1_error,nyi,XX})
end.
-
-emit_enc_enumerated_cases(Erule,C, [H], Count) ->
- emit_enc_enumerated_case(Erule,C, H, Count),
- case H of
- 'EXT_MARK' -> ok;
- _ ->
- emit([";",nl])
- end,
- emit([nl,"EnumVal -> exit({error,{asn1, {enumerated_not_in_range, EnumVal}}})"]),
- emit([nl,"end"]);
-emit_enc_enumerated_cases(Erule, C, ['EXT_MARK'|T], _Count) ->
- emit_enc_enumerated_cases(Erule, C, T, 0);
-emit_enc_enumerated_cases(Erule, C, [H1,H2|T], Count) ->
- emit_enc_enumerated_case(Erule, C, H1, Count),
+emit_enc_real(Erules, Real) ->
+ asn1ct_name:new(tmpval),
+ asn1ct_name:new(tmplen),
+ emit(["begin",nl,
+ "{",{curr,tmpval},com,{curr,tmplen},"} = ",
+ {call,real_common,encode_real,[Real]},com,nl,
+ "[",{call,Erules,encode_length,[{curr,tmplen}]},",",
+ {curr,tmpval},"]",nl,
+ "end"]).
+
+emit_enc_enumerated_cases(Erules, C, ['EXT_MARK'|T], _Count) ->
+ %% Reset enumeration counter.
+ emit_enc_enumerated_cases(Erules, C, T, 0);
+emit_enc_enumerated_cases(Erules, C, [H|T], Count) ->
+ emit_enc_enumerated_case(Erules, C, H, Count),
emit([";",nl]),
- emit_enc_enumerated_cases(Erule, C, [H2|T], Count+1).
+ emit_enc_enumerated_cases(Erules, C, T, Count+1);
+emit_enc_enumerated_cases(_Erules, _, [], _Count) ->
+ emit(["EnumVal -> "
+ "exit({error,{asn1,{enumerated_not_in_range, EnumVal}}})",nl,
+ "end"]).
+emit_enc_enumerated_case(Erules, C, {0,EnumName}, Count) ->
+ %% ENUMERATED with extensionmark; the value lies within then extension root
+ Enc = enc_ext_and_val(Erules, 0, encode_constrained_number, [C,Count]),
+ emit(["'",EnumName,"' -> ",{asis,Enc}]);
+emit_enc_enumerated_case(Erules, _C, {1,EnumName}, Count) ->
+ %% ENUMERATED with extensionmark; the value is higher than extension root
+ Enc = enc_ext_and_val(Erules, 1, encode_small_number, [Count]),
+ emit(["'",EnumName,"' -> ",{asis,Enc}]);
+emit_enc_enumerated_case(Erules, C, EnumName, Count) ->
+ %% ENUMERATED without extension
+ EvalMod = eval_module(Erules),
+ emit(["'",EnumName,"' -> ",
+ {asis,EvalMod:encode_constrained_number(C, Count)}]).
+
+enc_ext_and_val(per, E, F, Args) ->
+ [E|apply(asn1ct_eval_per, F, Args)];
+enc_ext_and_val(uper, E, F, Args) ->
+ <<E:1,(apply(asn1ct_eval_uper, F, Args))/bitstring>>.
-emit_enc_enumerated_case(uper,_C, {asn1_enum,High}, _) ->
- emit([
- "{asn1_enum,EnumV} when is_integer(EnumV), EnumV > ",High," -> ",
- "[<<1:1>>,?RT_PER:encode_small_number(EnumV)]"]);
-emit_enc_enumerated_case(_Per,_C, {asn1_enum,High}, _) ->
- emit([
- "{asn1_enum,EnumV} when is_integer(EnumV), EnumV > ",High," -> ",
- "[{bit,1},?RT_PER:encode_small_number(EnumV)]"]);
-emit_enc_enumerated_case(_Erule, _C, 'EXT_MARK', _Count) ->
- true;
-emit_enc_enumerated_case(uper,_C, {1,EnumName}, Count) ->
- emit(["'",EnumName,"' -> [<<1:1>>,?RT_PER:encode_small_number(",Count,")]"]);
-emit_enc_enumerated_case(_Per,_C, {1,EnumName}, Count) ->
- emit(["'",EnumName,"' -> [{bit,1},?RT_PER:encode_small_number(",Count,")]"]);
-emit_enc_enumerated_case(uper,C, {0,EnumName}, Count) ->
- emit(["'",EnumName,"' -> [<<0:1>>,?RT_PER:encode_integer(",{asis,C},", ",Count,")]"]);
-emit_enc_enumerated_case(_Per,C, {0,EnumName}, Count) ->
- emit(["'",EnumName,"' -> [{bit,0},?RT_PER:encode_integer(",{asis,C},", ",Count,")]"]);
-emit_enc_enumerated_case(_Erule, C, EnumName, Count) ->
- emit(["'",EnumName,"' -> ?RT_PER:encode_integer(",{asis,C},", ",Count,")"]).
-
get_constraint([{Key,V}], Key) ->
V;
get_constraint([], _) ->
@@ -446,7 +431,7 @@ gen_encode_field_call(ObjName,FieldName,Type) ->
Def = Type#typedef.typespec,
case Type#typedef.name of
{primitive,bif} ->
- gen_encode_prim(per,Def,"false",
+ gen_encode_prim(uper,Def,"false",
"Val"),
[];
{constructed,bif} ->
@@ -584,7 +569,7 @@ gen_decode_field_call(ObjName,FieldName,Bytes,Type) ->
Def = Type#typedef.typespec,
case Type#typedef.name of
{primitive,bif} ->
- gen_dec_prim(per,Def,Bytes),
+ gen_dec_prim(uper, Def, Bytes),
[];
{constructed,bif} ->
emit({" 'dec_",ObjName,'_',FieldName,
@@ -845,7 +830,7 @@ emit_inner_of_fun(TDef=#typedef{name={ExtMod,Name},typespec=Type},
case {ExtMod,Name} of
{primitive,bif} ->
emit(indent(12)),
- gen_encode_prim(per,Type,dotag,"Val"),
+ gen_encode_prim(uper,Type,dotag,"Val"),
{[],0};
{constructed,bif} ->
emit([indent(12),"'enc_",
@@ -988,7 +973,7 @@ emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},
case {ExtName,Name} of
{primitive,bif} ->
emit(indent(12)),
- gen_dec_prim(per,Type,"Val"),
+ gen_dec_prim(uper, Type, "Val"),
0;
{constructed,bif} ->
emit({indent(12),"'dec_",
@@ -1006,7 +991,7 @@ emit_inner_of_decfun(Type,_) when is_record(Type,type) ->
case Type#type.def of
Def when is_atom(Def) ->
emit({indent(9),Def," ->",nl,indent(12)}),
- gen_dec_prim(erules,Type,"Val");
+ gen_dec_prim(uper, Type, "Val");
TRef when is_record(TRef,typereference) ->
T = TRef#typereference.val,
emit({indent(9),T," ->",nl,indent(12),"'dec_",T,"'(Val)"});
@@ -1104,6 +1089,31 @@ gen_dec_imm_1('ASN1_OPEN_TYPE', Constraint, Aligned) ->
imm_decode_open_type(Constraint, Aligned);
gen_dec_imm_1('ANY', _Constraint, Aligned) ->
imm_decode_open_type([], Aligned);
+gen_dec_imm_1({'BIT STRING',NNL}, Constr0, Aligned) ->
+ Constr = get_constraint(Constr0, 'SizeConstraint'),
+ Imm = asn1ct_imm:per_dec_raw_bitstring(Constr, Aligned),
+ case NNL of
+ [] ->
+ case asn1ct:get_bit_string_format() of
+ compact ->
+ gen_dec_bit_string(decode_compact_bit_string,
+ Imm);
+ legacy ->
+ gen_dec_bit_string(decode_legacy_bit_string,
+ Imm);
+ bitstring ->
+ gen_dec_copy_bitstring(Imm)
+ end;
+ [_|_] ->
+ D = fun(V, Buf) ->
+ As = [V,{asis,NNL}],
+ Call = {call,per_common,decode_named_bit_string,As},
+ emit(["{",Call,com,Buf,"}"])
+ end,
+ {call,D,Imm}
+ end;
+gen_dec_imm_1('NULL', _Constr, _Aligned) ->
+ {value,'NULL'};
gen_dec_imm_1('BOOLEAN', _Constr, _Aligned) ->
asn1ct_imm:per_dec_boolean();
gen_dec_imm_1({'ENUMERATED',{Base,Ext}}, _Constr, Aligned) ->
@@ -1116,97 +1126,84 @@ gen_dec_imm_1({'INTEGER',NamedNumberList}, Constraint, Aligned) ->
asn1ct_imm:per_dec_named_integer(Constraint,
NamedNumberList,
Aligned);
+gen_dec_imm_1('BMPString'=Type, Constraint, Aligned) ->
+ gen_dec_k_m_string(Type, Constraint, Aligned);
+gen_dec_imm_1('NumericString'=Type, Constraint, Aligned) ->
+ gen_dec_k_m_string(Type, Constraint, Aligned);
+gen_dec_imm_1('PrintableString'=Type, Constraint, Aligned) ->
+ gen_dec_k_m_string(Type, Constraint, Aligned);
+gen_dec_imm_1('VisibleString'=Type, Constraint, Aligned) ->
+ gen_dec_k_m_string(Type, Constraint, Aligned);
+gen_dec_imm_1('IA5String'=Type, Constraint, Aligned) ->
+ gen_dec_k_m_string(Type, Constraint, Aligned);
+gen_dec_imm_1('UniversalString'=Type, Constraint, Aligned) ->
+ gen_dec_k_m_string(Type, Constraint, Aligned);
+gen_dec_imm_1('UTCTime', Constraint, Aligned) ->
+ gen_dec_k_m_string('VisibleString', Constraint, Aligned);
+gen_dec_imm_1('GeneralizedTime', Constraint, Aligned) ->
+ gen_dec_k_m_string('VisibleString', Constraint, Aligned);
gen_dec_imm_1('OCTET STRING', Constraint, Aligned) ->
SzConstr = get_constraint(Constraint, 'SizeConstraint'),
Imm = asn1ct_imm:per_dec_octet_string(SzConstr, Aligned),
{convert,binary_to_list,Imm};
-gen_dec_imm_1(_, _, _) -> no.
-
-gen_dec_prim(Erule, Type, BytesVar) ->
- case gen_dec_imm(Erule, Type) of
- no ->
- gen_dec_prim_1(Erule, Type, BytesVar);
- Imm ->
- asn1ct_imm:dec_code_gen(Imm, BytesVar)
+gen_dec_imm_1('TeletexString', _Constraint, Aligned) ->
+ gen_dec_restricted_string(Aligned);
+gen_dec_imm_1('T61String', _Constraint, Aligned) ->
+ gen_dec_restricted_string(Aligned);
+gen_dec_imm_1('VideotexString', _Constraint, Aligned) ->
+ gen_dec_restricted_string(Aligned);
+gen_dec_imm_1('GraphicString', _Constraint, Aligned) ->
+ gen_dec_restricted_string(Aligned);
+gen_dec_imm_1('GeneralString', _Constraint, Aligned) ->
+ gen_dec_restricted_string(Aligned);
+gen_dec_imm_1('ObjectDescriptor', _Constraint, Aligned) ->
+ gen_dec_restricted_string(Aligned);
+gen_dec_imm_1('OBJECT IDENTIFIER', _Constraint, Aligned) ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,per_common,decode_oid,[V]},com,
+ Buf,"}"])
+ end,
+ {call,Dec,gen_dec_restricted_string(Aligned)};
+gen_dec_imm_1('RELATIVE-OID', _Constraint, Aligned) ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,per_common,decode_relative_oid,[V]},com,
+ Buf,"}"])
+ end,
+ {call,Dec,gen_dec_restricted_string(Aligned)};
+gen_dec_imm_1('UTF8String', _Constraint, Aligned) ->
+ asn1ct_imm:per_dec_restricted_string(Aligned);
+gen_dec_imm_1('REAL', _Constraint, Aligned) ->
+ asn1ct_imm:per_dec_real(Aligned);
+gen_dec_imm_1(#'ObjectClassFieldType'{}=TypeName, Constraint, Aligned) ->
+ case asn1ct_gen:get_inner(TypeName) of
+ {fixedtypevaluefield,_,InnerType} ->
+ gen_dec_imm_1(InnerType, Constraint, Aligned);
+ T ->
+ gen_dec_imm_1(T, Constraint, Aligned)
end.
-gen_dec_prim_1(Erule,
- #type{def=Typename,constraint=Constraint}=Att,
- BytesVar) ->
- case Typename of
- 'REAL' ->
- emit({"?RT_PER:decode_real(",BytesVar,")"});
-
- {'BIT STRING',NamedNumberList} ->
- case get(compact_bit_string) of
- true ->
- emit({"?RT_PER:decode_compact_bit_string(",
- BytesVar,",",{asis,Constraint},",",
- {asis,NamedNumberList},")"});
- _ ->
- emit({"?RT_PER:decode_bit_string(",BytesVar,",",
- {asis,Constraint},",",
- {asis,NamedNumberList},")"})
- end;
- 'NULL' ->
- emit({"{'NULL',",BytesVar,"}"});
- 'OBJECT IDENTIFIER' ->
- emit({"?RT_PER:decode_object_identifier(",
- BytesVar,")"});
- 'RELATIVE-OID' ->
- emit({"?RT_PER:decode_relative_oid(",
- BytesVar,")"});
- 'ObjectDescriptor' ->
- emit({"?RT_PER:decode_ObjectDescriptor(",
- BytesVar,")"});
- 'NumericString' ->
- emit({"?RT_PER:decode_NumericString(",BytesVar,",",
- {asis,Constraint},")"});
- TString when TString == 'TeletexString';
- TString == 'T61String' ->
- emit({"?RT_PER:decode_TeletexString(",BytesVar,",",
- {asis,Constraint},")"});
- 'VideotexString' ->
- emit({"?RT_PER:decode_VideotexString(",BytesVar,",",
- {asis,Constraint},")"});
- 'UTCTime' ->
- emit({"?RT_PER:decode_VisibleString(",BytesVar,",",
- {asis,Constraint},")"});
- 'GeneralizedTime' ->
- emit({"?RT_PER:decode_VisibleString(",BytesVar,",",
- {asis,Constraint},")"});
- 'GraphicString' ->
- emit({"?RT_PER:decode_GraphicString(",BytesVar,",",
- {asis,Constraint},")"});
- 'VisibleString' ->
- emit({"?RT_PER:decode_VisibleString(",BytesVar,",",
- {asis,Constraint},")"});
- 'GeneralString' ->
- emit({"?RT_PER:decode_GeneralString(",BytesVar,",",
- {asis,Constraint},")"});
- 'PrintableString' ->
- emit({"?RT_PER:decode_PrintableString(",BytesVar,",",{asis,Constraint},")"});
- 'IA5String' ->
- emit({"?RT_PER:decode_IA5String(",BytesVar,",",{asis,Constraint},")"});
- 'BMPString' ->
- emit({"?RT_PER:decode_BMPString(",BytesVar,",",
- {asis,Constraint},")"});
- 'UniversalString' ->
- emit({"?RT_PER:decode_UniversalString(",BytesVar,
- ",",{asis,Constraint},")"});
- 'UTF8String' ->
- emit({"?RT_PER:decode_UTF8String(",BytesVar,")"});
- #'ObjectClassFieldType'{} ->
- case asn1ct_gen:get_inner(Typename) of
- {fixedtypevaluefield,_,InnerType} ->
- gen_dec_prim(Erule, InnerType, BytesVar);
- T ->
- gen_dec_prim(Erule, Att#type{def=T}, BytesVar)
- end;
- Other ->
- exit({'cant decode' ,Other})
- end.
+gen_dec_bit_string(F, Imm) ->
+ D = fun(V, Buf) ->
+ emit(["{",{call,per_common,F,[V]},com,Buf,"}"])
+ end,
+ {call,D,Imm}.
+gen_dec_copy_bitstring(Imm) ->
+ D = fun(V, Buf) ->
+ emit(["{list_to_bitstring([",V,"]),",Buf,"}"])
+ end,
+ {call,D,Imm}.
+
+gen_dec_k_m_string(Type, Constraint, Aligned) ->
+ asn1ct_imm:per_dec_k_m_string(Type, Constraint, Aligned).
+
+gen_dec_restricted_string(Aligned) ->
+ Imm = asn1ct_imm:per_dec_restricted_string(Aligned),
+ {convert,binary_to_list,Imm}.
+
+gen_dec_prim(Erule, Type, BytesVar) ->
+ Imm = gen_dec_imm(Erule, Type),
+ asn1ct_imm:dec_code_gen(Imm, BytesVar).
is_already_generated(Operation,Name) ->
case get(class_default_type) of
@@ -1280,3 +1277,6 @@ imm_dec_open_type_1(Type, Aligned) ->
"end"])
end,
{call,D,asn1ct_imm:per_dec_open_type(Aligned)}.
+
+eval_module(per) -> asn1ct_eval_per;
+eval_module(uper) -> asn1ct_eval_uper.
diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
index 4f4563833f..8dd0297f89 100644
--- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
+++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
@@ -34,6 +34,7 @@
-import(asn1ct_gen, [emit/1,demit/1]).
-import(asn1ct_gen_per, [is_already_generated/2,more_genfields/1,
get_class_fields/1,get_object_field/2]).
+-import(asn1ct_func, [call/3]).
%% pgen(Erules, Module, TypeOrVal)
%% Generate Erlang module (.erl) and (.hrl) file corresponding to an ASN.1 module
@@ -82,13 +83,6 @@ gen_encode_user(Erules,D) when is_record(D,typedef) ->
Typename = [D#typedef.name],
Def = D#typedef.typespec,
InnerType = asn1ct_gen:get_inner(Def#type.def),
- case InnerType of
- 'SET' -> true;
- 'SEQUENCE' -> true;
- _ ->
- emit({nl,"'enc_",asn1ct_gen:list2name(Typename),"'({'",asn1ct_gen:list2name(Typename),"',Val}) ->",nl}),
- emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val);",nl,nl})
- end,
emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val) ->",nl}),
case asn1ct_gen:type(InnerType) of
{primitive,bif} ->
@@ -137,41 +131,30 @@ gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
emit([" %%INTEGER with effective constraint: ",
{asis,EffectiveConstr},nl]),
emit_enc_integer_NNL(Erules,EffectiveConstr,Value,NamedNumberList);
- {'ENUMERATED',{Nlist1,Nlist2}} ->
- NewList = lists:append([[{0,X}||{X,_} <- Nlist1],['EXT_MARK'],[{1,X}||{X,_} <- Nlist2]]),
- NewC = [{'ValueRange',{0,length(Nlist1)-1}}],
- emit(["case ",Value," of",nl]),
-%% emit_enc_enumerated_cases(Erules,NewC, NewList++[{asn1_enum,length(Nlist1)-1}], 0);
- emit_enc_enumerated_cases(Erules,NewC, NewList, 0);
- {'ENUMERATED',NamedNumberList} ->
- NewList = [X||{X,_} <- NamedNumberList],
- NewC = effective_constraint(integer,
- [{'ValueRange',
- {0,length(NewList)-1}}]),
- NewVal = enc_enum_cases(Value,NewList),
- emit_enc_integer(Erules,NewC,NewVal);
-
+ {'ENUMERATED',_} ->
+ asn1ct_gen_per:gen_encode_prim(Erules, D, DoTag, Value);
'REAL' ->
- emit({"?RT_PER:encode_real(",Value,")"});
+ emit_enc_real(Erules, Value);
{'BIT STRING',NamedNumberList} ->
EffectiveC = effective_constraint(bitstring,Constraint),
case EffectiveC of
- 0 -> emit({"[]"});
+ 0 ->
+ emit({"[]"});
_ ->
- emit({"?RT_PER:encode_bit_string(",
- {asis,EffectiveC},",",Value,",",
- {asis,NamedNumberList},")"})
+ call(Erules, encode_bit_string,
+ [{asis,EffectiveC},Value,
+ {asis,NamedNumberList}])
end;
'NULL' ->
emit("[]");
'OBJECT IDENTIFIER' ->
- emit({"?RT_PER:encode_object_identifier(",Value,")"});
+ call(Erules, encode_object_identifier, [Value]);
'RELATIVE-OID' ->
- emit({"?RT_PER:encode_relative_oid(",Value,")"});
+ call(Erules, encode_relative_oid, [Value]);
'ObjectDescriptor' ->
- emit({"?RT_PER:encode_ObjectDescriptor(",{asis,Constraint},
- ",",Value,")"});
+ call(Erules, encode_ObjectDescriptor,
+ [{asis,Constraint},Value]);
'BOOLEAN' ->
emit({"case ",Value," of",nl,
" true -> [1];",nl,
@@ -185,19 +168,19 @@ gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
emit_enc_known_multiplier_string('NumericString',Constraint,Value);
TString when TString == 'TeletexString';
TString == 'T61String' ->
- emit({"?RT_PER:encode_TeletexString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_TeletexString, [{asis,Constraint},Value]);
'VideotexString' ->
- emit({"?RT_PER:encode_VideotexString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_VideotexString, [{asis,Constraint},Value]);
'UTCTime' ->
emit_enc_known_multiplier_string('VisibleString',Constraint,Value);
'GeneralizedTime' ->
emit_enc_known_multiplier_string('VisibleString',Constraint,Value);
'GraphicString' ->
- emit({"?RT_PER:encode_GraphicString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_GraphicString, [{asis,Constraint},Value]);
'VisibleString' ->
emit_enc_known_multiplier_string('VisibleString',Constraint,Value);
'GeneralString' ->
- emit({"?RT_PER:encode_GeneralString(",{asis,Constraint},",",Value,")"});
+ call(Erules, encode_GeneralString, [{asis,Constraint},Value]);
'PrintableString' ->
emit_enc_known_multiplier_string('PrintableString',Constraint,Value);
'IA5String' ->
@@ -207,23 +190,23 @@ gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
'UniversalString' ->
emit_enc_known_multiplier_string('UniversalString',Constraint,Value);
'UTF8String' ->
- emit({"?RT_PER:encode_UTF8String(",Value,")"});
+ call(Erules, encode_UTF8String, [Value]);
'ANY' ->
- emit(["?RT_PER:encode_open_type(", {asis,Constraint}, ",",
- Value, ")"]);
+ call(Erules, encode_open_type, [Value]);
'ASN1_OPEN_TYPE' ->
NewValue = case Constraint of
[#'Externaltypereference'{type=Tname}] ->
- io_lib:format(
- "?RT_PER:complete(enc_~s(~s))",[Tname,Value]);
+ asn1ct_func:need({Erules,complete,1}),
+ io_lib:format(
+ "complete(enc_~s(~s))",[Tname,Value]);
[#type{def=#'Externaltypereference'{type=Tname}}] ->
+ asn1ct_func:need({Erules,complete,1}),
io_lib:format(
- "?RT_PER:complete(enc_~s(~s))",
+ "complete(enc_~s(~s))",
[Tname,Value]);
_ -> Value
end,
- emit(["?RT_PER:encode_open_type(", {asis,Constraint}, ",",
- NewValue, ")"]);
+ call(Erules, encode_open_type, [NewValue]);
#'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(D#type.def) of
{fixedtypevaluefield,_,InnerType} ->
@@ -235,6 +218,17 @@ gen_encode_prim(Erules,D,DoTag,Value) when is_record(D,type) ->
exit({asn1_error,nyi,XX})
end.
+emit_enc_real(Erules, Real) ->
+ asn1ct_name:new(tmpval),
+ asn1ct_name:new(tmplen),
+ emit(["begin",nl,
+ "{",{curr,tmpval},com,{curr,tmplen},"} = ",
+ {call,real_common,encode_real,[Real]},com,nl,
+ "[",{call,Erules,encode_length,[{curr,tmplen}]},",",nl,
+ {call,Erules,octets_to_complete,
+ [{curr,tmplen},{curr,tmpval}]},"]",nl,
+ "end"]).
+
emit_enc_known_multiplier_string(StringType,C,Value) ->
SizeC =
case get_constraint(C,'SizeConstraint') of
@@ -254,62 +248,34 @@ emit_enc_known_multiplier_string(StringType,C,Value) ->
NumBits = get_NumBits(C,StringType),
CharOutTab = get_CharOutTab(C,StringType),
%% NunBits and CharOutTab for chars_encode
- emit_enc_k_m_string(StringType,SizeC,NumBits,CharOutTab,Value).
+ emit_enc_k_m_string(SizeC, NumBits, CharOutTab, Value).
-emit_enc_k_m_string(_StringType,0,_NumBits,_CharOutTab,_Value) ->
+emit_enc_k_m_string(0, _NumBits, _CharOutTab, _Value) ->
emit({"[]"});
-emit_enc_k_m_string(StringType,SizeC,NumBits,CharOutTab,Value) ->
- emit({"?RT_PER:encode_known_multiplier_string(",{asis,StringType},",",
- {asis,SizeC},",",NumBits,",",{asis,CharOutTab},",",Value,")"}).
-
-emit_dec_known_multiplier_string(StringType,C,BytesVar) ->
- SizeC = get_constraint(C,'SizeConstraint'),
- PAlphabC = get_constraint(C,'PermittedAlphabet'),
- case {StringType,PAlphabC} of
- {'BMPString',{_,_}} ->
- exit({error,{asn1,
- {'not implemented',
- "BMPString with PermittedAlphabet "
- "constraint"}}});
- _ ->
- ok
- end,
- NumBits = get_NumBits(C,StringType),
- CharInTab = get_CharInTab(C,StringType),
- case SizeC of
- 0 ->
- emit({"{[],",BytesVar,"}"});
- _ ->
- emit({"?RT_PER:decode_known_multiplier_string(",
- {asis,StringType},",",{asis,SizeC},",",NumBits,
- ",",{asis,CharInTab},",",BytesVar,")"})
- end.
+emit_enc_k_m_string(SizeC, NumBits, CharOutTab, Value) ->
+ call(per, encode_known_multiplier_string,
+ [{asis,SizeC},NumBits,{asis,CharOutTab},Value]).
%% copied from run time module
-get_CharOutTab(C,StringType) ->
- get_CharTab(C,StringType,out).
-
-get_CharInTab(C,StringType) ->
- get_CharTab(C,StringType,in).
-
-get_CharTab(C,StringType,InOut) ->
+get_CharOutTab(C, StringType) ->
case get_constraint(C,'PermittedAlphabet') of
{'SingleValue',Sv} ->
- get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut);
+ get_CharTab2(C, StringType, hd(Sv), lists:max(Sv), Sv);
no ->
case StringType of
'IA5String' ->
{0,16#7F,notab};
'VisibleString' ->
- get_CharTab2(C,StringType,16#20,16#7F,notab,InOut);
+ get_CharTab2(C, StringType, 16#20, 16#7F, notab);
'PrintableString' ->
Chars = lists:sort(
" '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
- get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut);
+ get_CharTab2(C, StringType, hd(Chars),
+ lists:max(Chars), Chars);
'NumericString' ->
- get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut);
+ get_CharTab2(C, StringType, 16#20, $9, " 0123456789");
'UniversalString' ->
{0,16#FFFFFFFF,notab};
'BMPString' ->
@@ -317,18 +283,13 @@ get_CharTab(C,StringType,InOut) ->
end
end.
-get_CharTab2(C,StringType,Min,Max,Chars,InOut) ->
+get_CharTab2(C, StringType, Min, Max, Chars) ->
BitValMax = (1 bsl get_NumBits(C,StringType))-1,
if
Max =< BitValMax ->
{0,Max,notab};
true ->
- case InOut of
- out ->
- {Min,Max,create_char_tab(Min,Chars)};
- in ->
- {Min,Max,list_to_tuple(Chars)}
- end
+ {Min,Max,create_char_tab(Min,Chars)}
end.
create_char_tab(Min,L) ->
@@ -397,7 +358,7 @@ charbits1(NumOfChars) ->
%% copied from run time module
-emit_enc_octet_string(_Erules,Constraint,Value) ->
+emit_enc_octet_string(Erules, Constraint, Value) ->
case get_constraint(Constraint,'SizeConstraint') of
0 ->
emit({" []"});
@@ -446,7 +407,8 @@ emit_enc_octet_string(_Erules,Constraint,Value) ->
" end",nl,
" end"]);
C ->
- emit({" ?RT_PER:encode_octet_string(",{asis,C},",false,",Value,")",nl})
+ call(Erules, encode_octet_string,
+ [{asis,C},false,Value])
end.
emit_enc_integer_case(Value) ->
@@ -533,71 +495,12 @@ emit_enc_integer(_Erule,[{_,{Lb,Ub},Range,_}],Value) when Range =< 65536 ->
nl," end",nl]),
emit_enc_integer_end_case();
+emit_enc_integer(Erule, [{'ValueRange',{Lb,Ub}=VR}], Value)
+ when is_integer(Lb), is_integer(Ub) ->
+ call(Erule, encode_constrained_number, [{asis,VR},Value]);
-emit_enc_integer(_Erule,C,Value) ->
- emit({" ?RT_PER:encode_integer(",{asis,C},",",Value,")"}).
-
-
-
-
-enc_enum_cases(Value,NewList) ->
- asn1ct_name:new(tmpval),
- TmpVal = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)),
- Cases=enc_enum_cases1(NewList),
- lists:flatten(io_lib:format("(case ~s of "++Cases++
- "~s ->exit({error,"
- "{asn1,{enumerated,~s}}})"
- " end)",
- [Value,TmpVal,TmpVal])).
-enc_enum_cases1(NNL) ->
- enc_enum_cases1(NNL,0).
-enc_enum_cases1([H|T],Index) ->
- io_lib:format("~w->~w;",[H,Index])++enc_enum_cases1(T,Index+1);
-enc_enum_cases1([],_) ->
- "".
-
-
-emit_enc_enumerated_cases(Erule, C, [H], Count) ->
- emit_enc_enumerated_case(Erule, C, H, Count),
- case H of
- 'EXT_MARK' ->
- ok;
- _ ->
- emit([";",nl])
- end,
- emit([nl,"EnumVal -> exit({error,{asn1, {enumerated_not_in_range, EnumVal}}})"]),
- emit([nl,"end"]);
-emit_enc_enumerated_cases(Erule, C, ['EXT_MARK'|T], _Count) ->
- emit_enc_enumerated_cases(Erule, C, T, 0);
-emit_enc_enumerated_cases(Erule, C, [H1,H2|T], Count) ->
- emit_enc_enumerated_case(Erule, C, H1, Count),
- emit([";",nl]),
- emit_enc_enumerated_cases(Erule, C, [H2|T], Count+1).
-
-
-%% The function clauses matching on tuples with first element
-%% asn1_enum, 1 or 0 and the atom 'EXT_MARK' are for ENUMERATED
-%% with extension mark.
-%% emit_enc_enumerated_case(_Erule,_C, {asn1_enum,High}, _) ->
-%% %% ENUMERATED with extensionmark
-%% %% value higher than the extension base and not
-%% %% present in the extension range.
-%% emit(["{asn1_enum,EnumV} when is_integer(EnumV), EnumV > ",High," -> ",
-%% "[1,?RT_PER:encode_small_number(EnumV)]"]);
-emit_enc_enumerated_case(_Erule,_C, {1,EnumName}, Count) ->
- %% ENUMERATED with extensionmark
- %% values higher than extension root
- emit(["'",EnumName,"' -> [1,?RT_PER:encode_small_number(",Count,")]"]);
-emit_enc_enumerated_case(_Erule,C, {0,EnumName}, Count) ->
- %% ENUMERATED with extensionmark
- %% values within extension root
-%% emit(["'",EnumName,"' -> [0,?RT_PER:encode_integer(",{asis,C},", ",Count,")]"]);
- emit(["'",EnumName,"' -> ",{asis,[0|asn1rt_per_bin_rt2ct:encode_integer(C,Count)]}]);
-emit_enc_enumerated_case(_Erule, _C, 'EXT_MARK', _Count) ->
- true.
-%% %% This clause is invoked in case of an ENUMERATED without extension mark
-%% emit_enc_enumerated_case(_Erule,_C, EnumName, Count) ->
-%% emit(["'",EnumName,"' -> ",Count]).
+emit_enc_integer(Erule, C, Value) ->
+ call(Erule, encode_integer, [{asis,C},Value]).
get_constraint([{Key,V}],Key) ->
@@ -1367,7 +1270,7 @@ emit_inner_of_decfun(Type,_) when is_record(Type,type) ->
case Type#type.def of
Def when is_atom(Def) ->
emit({indent(9),Def," ->",nl,indent(12)}),
- gen_dec_prim(erules,Type,"Val");
+ gen_dec_prim(per, Type, "Val");
TRef when is_record(TRef,typereference) ->
T = TRef#typereference.val,
emit({indent(9),T," ->",nl,indent(12),"'dec_",T,"'(Val)"});
@@ -1456,105 +1359,8 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
-gen_dec_prim(Erules,Att,BytesVar) ->
- Typename = Att#type.def,
- Constraint = Att#type.constraint,
- case Typename of
- 'INTEGER' ->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
- {'INTEGER',_NamedNumberList} ->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
- 'REAL' ->
- emit(["?RT_PER:decode_real(",BytesVar,")"]);
-
- {'BIT STRING',NamedNumberList} ->
- case get(compact_bit_string) of
- true ->
- emit({"?RT_PER:decode_compact_bit_string(",
- BytesVar,",",{asis,Constraint},",",
- {asis,NamedNumberList},")"});
- _ ->
- emit({"?RT_PER:decode_bit_string(",BytesVar,",",
- {asis,Constraint},",",
- {asis,NamedNumberList},")"})
- end;
- 'NULL' ->
- emit({"{'NULL',",BytesVar,"}"});
- 'OBJECT IDENTIFIER' ->
- emit({"?RT_PER:decode_object_identifier(",
- BytesVar,")"});
- 'RELATIVE-OID' ->
- emit({"?RT_PER:decode_relative_oid(",
- BytesVar,")"});
- 'ObjectDescriptor' ->
- emit({"?RT_PER:decode_ObjectDescriptor(",
- BytesVar,")"});
- {'ENUMERATED',_} ->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
- 'BOOLEAN'->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
-
- 'OCTET STRING' ->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
-
- 'NumericString' ->
- emit_dec_known_multiplier_string('NumericString',
- Constraint,BytesVar);
- TString when TString == 'TeletexString';
- TString == 'T61String' ->
- emit({"?RT_PER:decode_TeletexString(",BytesVar,",",
- {asis,Constraint},")"});
-
- 'VideotexString' ->
- emit({"?RT_PER:decode_VideotexString(",BytesVar,",",
- {asis,Constraint},")"});
-
- 'UTCTime' ->
- emit_dec_known_multiplier_string('VisibleString',
- Constraint,BytesVar);
- 'GeneralizedTime' ->
- emit_dec_known_multiplier_string('VisibleString',
- Constraint,BytesVar);
- 'GraphicString' ->
- emit({"?RT_PER:decode_GraphicString(",BytesVar,",",
- {asis,Constraint},")"});
-
- 'VisibleString' ->
- emit_dec_known_multiplier_string('VisibleString',
- Constraint,BytesVar);
- 'GeneralString' ->
- emit({"?RT_PER:decode_GeneralString(",BytesVar,",",
- {asis,Constraint},")"});
-
- 'PrintableString' ->
- emit_dec_known_multiplier_string('PrintableString',
- Constraint,BytesVar);
- 'IA5String' ->
- emit_dec_known_multiplier_string('IA5String',Constraint,BytesVar);
-
- 'BMPString' ->
- emit_dec_known_multiplier_string('BMPString',Constraint,BytesVar);
-
- 'UniversalString' ->
- emit_dec_known_multiplier_string('UniversalString',
- Constraint,BytesVar);
-
- 'UTF8String' ->
- emit({"?RT_PER:decode_UTF8String(",BytesVar,")"});
- 'ANY' ->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
- 'ASN1_OPEN_TYPE' ->
- asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
- #'ObjectClassFieldType'{} ->
- case asn1ct_gen:get_inner(Att#type.def) of
- {fixedtypevaluefield,_,InnerType} ->
- gen_dec_prim(Erules,InnerType,BytesVar);
- T ->
- gen_dec_prim(Erules,Att#type{def=T},BytesVar)
- end;
- Other ->
- exit({'cant decode' ,Other})
- end.
+gen_dec_prim(Erules, Att, BytesVar) ->
+ asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar).
%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
%% the components within the ExtensionAdditionGroup is treated in a similar way as if they
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index 34bb0b8714..5bdaed8f4f 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -18,10 +18,13 @@
%%
%%
-module(asn1ct_imm).
--export([per_dec_boolean/0,per_dec_enumerated/2,per_dec_enumerated/3,
+-export([per_dec_raw_bitstring/2,
+ per_dec_boolean/0,per_dec_enumerated/2,per_dec_enumerated/3,
per_dec_extension_map/1,
- per_dec_integer/2,per_dec_length/3,per_dec_named_integer/3,
- per_dec_octet_string/2,per_dec_open_type/1]).
+ per_dec_integer/2,per_dec_k_m_string/3,
+ per_dec_length/3,per_dec_named_integer/3,
+ per_dec_octet_string/2,per_dec_open_type/1,per_dec_real/1,
+ per_dec_restricted_string/1]).
-export([optimize_alignment/1,optimize_alignment/2,
dec_slim_cg/2,dec_code_gen/2]).
-export([effective_constraint/2]).
@@ -59,9 +62,17 @@ per_dec_boolean() ->
{map,{get_bits,1,[1]},[{0,false},{1,true}]}.
per_dec_enumerated(NamedList0, Aligned) ->
- Constraint = [{'ValueRange',{0,length(NamedList0)-1}}],
- NamedList = per_dec_enumerated_fix_list(NamedList0, [enum_error], 0),
+ 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}.
per_dec_enumerated(BaseNamedList, NamedListExt0, Aligned) ->
@@ -100,13 +111,36 @@ per_dec_named_integer(Constraint, NamedList0, Aligned) ->
NamedList = [{K,V} || {V,K} <- NamedList0] ++ [integer_default],
{map,Int,NamedList}.
+per_dec_k_m_string(StringType, Constraint, Aligned) ->
+ SzConstr = get_constraint(Constraint, 'SizeConstraint'),
+ N = string_num_bits(StringType, Constraint, Aligned),
+ Imm = dec_string(SzConstr, N, Aligned),
+ Chars = char_tab(Constraint, StringType, N),
+ convert_string(N, Chars, Imm).
+
per_dec_octet_string(Constraint, Aligned) ->
dec_string(Constraint, 8, Aligned).
+per_dec_raw_bitstring(Constraint, Aligned) ->
+ dec_string(Constraint, 1, Aligned).
+
per_dec_open_type(Aligned) ->
{get_bits,decode_unconstrained_length(true, Aligned),
[8,binary,{align,Aligned}]}.
+per_dec_real(Aligned) ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,real_common,decode_real,[V]},
+ com,Buf,"}"])
+ end,
+ {call,Dec,
+ {get_bits,decode_unconstrained_length(true, Aligned),
+ [8,binary,{align,Aligned}]}}.
+
+per_dec_restricted_string(Aligned) ->
+ DecLen = decode_unconstrained_length(true, Aligned),
+ {get_bits,DecLen,[8,binary]}.
+
%%%
%%% Local functions.
@@ -116,7 +150,7 @@ dec_string(Sv, U, _Aligned) when is_integer(Sv), U*Sv =< 16 ->
{get_bits,Sv,[U,binary]};
dec_string(Sv, U, Aligned) when is_integer(Sv), Sv < 16#10000 ->
{get_bits,Sv,[U,binary,{align,Aligned}]};
-dec_string(C, U, Aligned) when is_list(C) ->
+dec_string([_|_]=C, U, Aligned) when is_list(C) ->
dec_string({hd(C),lists:max(C)}, U, Aligned);
dec_string({Sv,Sv}, U, Aligned) ->
dec_string(Sv, U, Aligned);
@@ -129,8 +163,9 @@ dec_string({Lb,Ub}, U, Aligned) when Ub < 16#10000 ->
dec_string(_, U, Aligned) ->
Al = [{align,Aligned}],
DecRest = fun(V, Buf) ->
- emit(["?RT_PER:decode_fragmented(",V,", ",
- Buf,", ",U,")"])
+ asn1ct_func:call(per_common,
+ decode_fragmented,
+ [V,Buf,U])
end,
{'case',[{test,{get_bits,1,[1|Al]},0,
{value,{get_bits,
@@ -228,6 +263,103 @@ per_num_bits(N) when N =< 64 -> 6;
per_num_bits(N) when N =< 128 -> 7;
per_num_bits(N) when N =< 255 -> 8.
+matched_range({get_bits,Bits0,[U|Flags]}) when is_integer(U) ->
+ case lists:member(signed, Flags) of
+ false ->
+ Bits = U*Bits0,
+ {0,(1 bsl Bits) - 1};
+ true ->
+ unknown
+ end;
+matched_range(_Op) -> unknown.
+
+string_num_bits(StringType, Constraint, Aligned) ->
+ case get_constraint(Constraint, 'PermittedAlphabet') of
+ {'SingleValue',Sv} ->
+ charbits(length(Sv), Aligned);
+ no ->
+ case StringType of
+ 'IA5String' ->
+ charbits(128, Aligned);
+ 'VisibleString' ->
+ charbits(95, Aligned);
+ 'PrintableString' ->
+ charbits(74, Aligned);
+ 'NumericString' ->
+ charbits(11, Aligned);
+ 'UniversalString' ->
+ 32;
+ 'BMPString' ->
+ 16
+ end
+ end.
+
+charbits(NumChars, false) ->
+ uper_num_bits(NumChars);
+charbits(NumChars, true) ->
+ 1 bsl uper_num_bits(uper_num_bits(NumChars)).
+
+convert_string(8, notab, Imm) ->
+ {convert,binary_to_list,Imm};
+convert_string(NumBits, notab, Imm) when NumBits < 8 ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,per_common,decode_chars,
+ [V,NumBits]},com,Buf,"}"])
+ end,
+ {call,Dec,Imm};
+convert_string(NumBits, notab, Imm) when NumBits =:= 16 ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,per_common,decode_chars_16bit,
+ [V]},com,Buf,"}"])
+ end,
+ {call,Dec,Imm};
+convert_string(NumBits, notab, Imm) ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,per_common,decode_big_chars,
+ [V,NumBits]},com,Buf,"}"])
+ end,
+ {call,Dec,Imm};
+convert_string(NumBits, Chars, Imm) ->
+ Dec = fun(V, Buf) ->
+ emit(["{",{call,per_common,decode_chars,
+ [V,NumBits,{asis,Chars}]},com,Buf,"}"])
+ end,
+ {call,Dec,Imm}.
+
+char_tab(C, StringType, NumBits) ->
+ case get_constraint(C, 'PermittedAlphabet') of
+ {'SingleValue',Sv} ->
+ char_tab_1(Sv, NumBits);
+ no ->
+ case StringType of
+ 'IA5String' ->
+ notab;
+ 'VisibleString' ->
+ notab;
+ 'PrintableString' ->
+ Chars = " '()+,-./0123456789:=?"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz",
+ char_tab_1(Chars, NumBits);
+ 'NumericString' ->
+ char_tab_1(" 0123456789", NumBits);
+ 'UniversalString' ->
+ notab;
+ 'BMPString' ->
+ notab
+ end
+ end.
+
+char_tab_1(Chars, NumBits) ->
+ Max = lists:max(Chars),
+ BitValMax = (1 bsl NumBits) - 1,
+ if
+ Max =< BitValMax ->
+ notab;
+ true ->
+ list_to_tuple(lists:sort(Chars))
+ end.
+
%%%
%%% Remove unnecessary aligning to octet boundaries.
%%%
@@ -259,6 +391,8 @@ opt_al({'case',Cs0}, A0) ->
opt_al({map,E0,Cs}, A0) ->
{E,A} = opt_al(E0, A0),
{{map,E,Cs},A};
+opt_al('NULL'=Null, A) ->
+ {Null,A};
opt_al(I, A) when is_integer(I) ->
{I,A}.
@@ -346,6 +480,8 @@ flatten({map,E0,Cs0}, Buf0, St0) ->
{Dst,St2} = new_var("Int", St1),
Cs = flatten_map_cs(Cs0, E),
{{Dst,DstBuf},Pre++[{'map',E,Cs,{Dst,DstBuf}}],St2};
+flatten({value,'NULL'}, Buf0, St0) ->
+ {{"'NULL'",Buf0},[],St0};
flatten({value,V0}, Buf0, St0) when is_integer(V0) ->
{{V0,Buf0},[],St0};
flatten({value,V0}, Buf0, St0) ->
@@ -515,8 +651,6 @@ dcg_list_inside([{get_bits,{Sz,_},Fl0,{Dst,DstBuf}}|T], _) ->
dcg_list_inside(T, DstBuf);
dcg_list_inside(L, Dst) -> {L,Dst}.
-bit_flags([1|T], Acc) ->
- bit_flags(T, Acc);
bit_flags([{align,_}|T], Acc) ->
bit_flags(T, Acc);
bit_flags([non_zero|T], Acc) ->
@@ -528,7 +662,11 @@ bit_flags([H|T], Acc) ->
bit_flags([], []) ->
"";
bit_flags([], Acc) ->
- "/" ++ bit_flags_1(Acc, "").
+ case "/" ++ bit_flags_1(Acc, "") of
+ "/unit:1" -> [];
+ Opts -> Opts
+ end.
+
bit_flags_1([H|T], Sep) ->
Sep ++ H ++ bit_flags_1(T, "-");
diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl
index 389642c446..8f3dc1d8b8 100644
--- a/lib/asn1/src/asn1ct_value.erl
+++ b/lib/asn1/src/asn1ct_value.erl
@@ -54,7 +54,7 @@ from_type(M,Typename,Type) when is_record(Type,type) ->
{notype,_} ->
true;
{primitive,bif} ->
- from_type_prim(Type);
+ from_type_prim(M, Type);
'ASN1_OPEN_TYPE' ->
case Type#type.constraint of
[#'Externaltypereference'{type=TrefConstraint}] ->
@@ -65,7 +65,7 @@ from_type(M,Typename,Type) when is_record(Type,type) ->
end;
{constructed,bif} when Typename == ['EXTERNAL'] ->
Val=from_type_constructed(M,Typename,InnerType,Type),
- asn1rt_check:transform_to_EXTERNAL1994(Val);
+ asn1ct_eval_ext:transform_to_EXTERNAL1994(Val);
{constructed,bif} ->
from_type_constructed(M,Typename,InnerType,Type)
end;
@@ -164,7 +164,7 @@ gen_list(_,_,_,0) ->
gen_list(M,Typename,Oftype,N) ->
[from_type(M,Typename,Oftype)|gen_list(M,Typename,Oftype,N-1)].
-from_type_prim(D) ->
+from_type_prim(M, D) ->
C = D#type.constraint,
case D#type.def of
'INTEGER' ->
@@ -212,18 +212,7 @@ from_type_prim(D) ->
NN = [X||{X,_} <- NamedNumberList],
case NN of
[] ->
- Bl1 =lists:reverse(adjust_list(size_random(C),[1,0,1,1])),
- Bl2 = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,Bl1)),
- case {length(Bl2),get_constraint(C,'SizeConstraint')} of
- {Len,Len} ->
- Bl2;
- {_Len,Int} when is_integer(Int) ->
- Bl1;
- {Len,{Min,_}} when Min > Len ->
- Bl1;
- _ ->
- Bl2
- end;
+ random_unnamed_bit_string(M, C);
_ ->
[lists:nth(random(length(NN)),NN)]
end;
@@ -320,6 +309,32 @@ c_string(C,Default) ->
Default
end.
+random_unnamed_bit_string(M, C) ->
+ Bl1 = lists:reverse(adjust_list(size_random(C), [1,0,1,1])),
+ Bl2 = lists:reverse(lists:dropwhile(fun(0)-> true;
+ (1) -> false
+ end,Bl1)),
+ Val = case {length(Bl2),get_constraint(C, 'SizeConstraint')} of
+ {Len,Len} ->
+ Bl2;
+ {_Len,Int} when is_integer(Int) ->
+ Bl1;
+ {Len,{Min,_}} when Min > Len ->
+ Bl1;
+ _ ->
+ Bl2
+ end,
+ case M:bit_string_format() of
+ legacy ->
+ Val;
+ bitstring ->
+ << <<B:1>> || B <- Val >>;
+ compact ->
+ BitString = << <<B:1>> || B <- Val >>,
+ PadLen = (8 - (bit_size(BitString) band 7)) band 7,
+ {PadLen,<<BitString/bitstring,0:PadLen>>}
+ end.
+
%% FIXME:
%% random_sign(integer) ->
%% case random(2) of
diff --git a/lib/asn1/src/asn1rt_ber_bin.erl b/lib/asn1/src/asn1rt_ber_bin.erl
deleted file mode 100644
index ec1549804b..0000000000
--- a/lib/asn1/src/asn1rt_ber_bin.erl
+++ /dev/null
@@ -1,525 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-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%
-%%
-%%
--module(asn1rt_ber_bin).
-
--export([decode_length/1,
- encode_real/2, encode_real/3,
- decode_real/2, decode_real/4,
- decode_tag/1]).
-
--include("asn1_records.hrl").
-
-%% the encoding of class of tag bits 8 and 7
--define(UNIVERSAL, 0).
-
-%%% primitive or constructed encoding % bit 6
--define(PRIMITIVE, 0).
--define(CONSTRUCTED, 2#00100000).
-
-%%% The tag-number for universal types
--define(N_REAL, 9).
-
-encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
- <<(Class bsr 6):2,(Form bsr 5):1,TagNo:5>>;
-
-encode_tag_val({Class, Form, TagNo}) ->
- {Octets,_Len} = mk_object_val(TagNo),
- BinOct = list_to_binary(Octets),
- <<(Class bsr 6):2, (Form bsr 5):1, 31:5,BinOct/binary>>.
-
-%%===============================================================================
-%% Decode a tag
-%%
-%% decode_tag(OctetListBuffer) -> {{Class, Form, TagNo}, RestOfBuffer, RemovedBytes}
-%%===============================================================================
-
-%% multiple octet tag
-decode_tag(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
- {TagNo, Buffer1, RemovedBytes} = decode_tag(Buffer, 0, 1),
- {{(Class bsl 6), (Form bsl 5), TagNo}, Buffer1, RemovedBytes};
-
-%% single tag (< 31 tags)
-decode_tag(<<Class:2,Form:1,TagNo:5, Buffer/binary>>) ->
- {{(Class bsl 6), (Form bsl 5), TagNo}, Buffer, 1}.
-
-%% last partial tag
-decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck, RemovedBytes) ->
- TagNo = (TagAck bsl 7) bor PartialTag,
- %%<<TagNo>> = <<TagAck:1, PartialTag:7>>,
- {TagNo, Buffer, RemovedBytes+1};
-% more tags
-decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck, RemovedBytes) ->
- TagAck1 = (TagAck bsl 7) bor PartialTag,
- %%<<TagAck1:16>> = <<TagAck:1, PartialTag:7,0:8>>,
- decode_tag(Buffer, TagAck1, RemovedBytes+1).
-
-%%------------------------------------------------------------------
-%% check_tags_i is the same as check_tags except that it stops and
-%% returns the remaining tags not checked when it encounters an
-%% indefinite length field
-%% only called internally within this module
-
-check_tags_i([Tag], Buffer, OptOrMand) -> % optimized very usual case
- {[],check_one_tag(Tag, Buffer, OptOrMand)};
-check_tags_i(Tags, Buffer, OptOrMand) ->
- check_tags_i(Tags, Buffer, 0, OptOrMand).
-
-check_tags_i([Tag1,Tag2|TagRest], Buffer, Rb, OptOrMand)
- when Tag1#tag.type == 'IMPLICIT' ->
- check_tags_i([Tag1#tag{type=Tag2#tag.type}|TagRest], Buffer, Rb, OptOrMand);
-
-check_tags_i([Tag1|TagRest], Buffer, Rb, OptOrMand) ->
- {Form_Length,Buffer2,Rb1} = check_one_tag(Tag1, Buffer, OptOrMand),
- case TagRest of
- [] -> {TagRest, {Form_Length, Buffer2, Rb + Rb1}};
- _ ->
- case Form_Length of
- {?CONSTRUCTED,_} ->
- {TagRest, {Form_Length, Buffer2, Rb + Rb1}};
- _ ->
- check_tags_i(TagRest, Buffer2, Rb + Rb1, mandatory)
- end
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% This function is called from generated code
-
-check_one_tag(Tag=#tag{class=ExpectedClass,number=ExpectedNumber}, Buffer, OptOrMand) ->
- case catch decode_tag(Buffer) of
- {'EXIT',_Reason} ->
- tag_error(no_data,Tag,Buffer,OptOrMand);
- {{ExpectedClass,Form,ExpectedNumber},Buffer2,Rb} ->
- {{L,Buffer3},RemBytes2} = decode_length(Buffer2),
- {{Form,L}, Buffer3, RemBytes2+Rb};
- {ErrorTag,_,_} ->
- tag_error(ErrorTag, Tag, Buffer, OptOrMand)
- end.
-
-tag_error(ErrorTag, Tag, Buffer, OptOrMand) ->
- case OptOrMand of
- mandatory ->
- exit({error,{asn1, {invalid_tag,
- {ErrorTag, Tag, Buffer}}}});
- _ ->
- exit({error,{asn1, {no_optional_tag,
- {ErrorTag, Tag, Buffer}}}})
- end.
-%%=======================================================================
-%%
-%% Encode all tags in the list Tags and return a possibly deep list of
-%% bytes with tag and length encoded
-%%
-%% prepend_tags(Tags, BytesSoFar, LenSoFar) -> {Bytes, Len}
-encode_tags(Tags, BytesSoFar, LenSoFar) ->
- NewTags = encode_tags1(Tags, []),
- %% NewTags contains the resulting tags in reverse order
- encode_tags2(NewTags, BytesSoFar, LenSoFar).
-
-%encode_tags2([#tag{class=?UNIVERSAL,number=No}|Trest], BytesSoFar, LenSoFar) ->
-% {Bytes2,L2} = encode_length(LenSoFar),
-% encode_tags2(Trest,[[No|Bytes2],BytesSoFar], LenSoFar + 1 + L2);
-encode_tags2([Tag|Trest], BytesSoFar, LenSoFar) ->
- {Bytes1,L1} = encode_one_tag(Tag),
- {Bytes2,L2} = encode_length(LenSoFar),
- encode_tags2(Trest, [Bytes1,Bytes2|BytesSoFar],
- LenSoFar + L1 + L2);
-encode_tags2([], BytesSoFar, LenSoFar) ->
- {BytesSoFar,LenSoFar}.
-
-encode_tags1([Tag1, Tag2| Trest], Acc) when Tag1#tag.type =:= 'IMPLICIT' ->
- encode_tags1([Tag1#tag{type=Tag2#tag.type,form=Tag2#tag.form}|Trest],Acc);
-encode_tags1([Tag1 | Trest], Acc) ->
- encode_tags1(Trest, [Tag1|Acc]);
-encode_tags1([], Acc) ->
- Acc. % the resulting tags are returned in reverse order
-
-encode_one_tag(Bin) when is_binary(Bin) ->
- {Bin,byte_size(Bin)};
-encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
- NewForm = case Type of
- 'EXPLICIT' ->
- ?CONSTRUCTED;
- _ ->
- Form
- end,
- Bytes = encode_tag_val({Class,NewForm,No}),
- {Bytes,size(Bytes)}.
-
-%%============================================================================
-%%
-%% Real value, ITU_T X.690 Chapter 8.5
-%%============================================================================
-%%
-%% encode real value
-%%============================================================================
-
-%% only base 2 internally so far!!
-encode_real(_C,0, DoTag) ->
- dotag(DoTag, ?N_REAL, {[],0});
-encode_real(_C,'PLUS-INFINITY', DoTag) ->
- dotag(DoTag, ?N_REAL, {[64],1});
-encode_real(_C,'MINUS-INFINITY', DoTag) ->
- dotag(DoTag, ?N_REAL, {[65],1});
-encode_real(C,Val, DoTag) when is_tuple(Val); is_list(Val) ->
- dotag(DoTag, ?N_REAL, encode_real(C,Val)).
-
-%%%%%%%%%%%%%%
-%% only base 2 encoding!
-%% binary encoding:
-%% +------------+ +------------+ +-+-+-+-+---+---+
-%% | (tag)9 | | n + p + 1 | |1|S|BB |FF |EE |
-%% +------------+ +------------+ +-+-+-+-+---+---+
-%%
-%% +------------+ +------------+
-%% | | | |
-%% +------------+ ...+------------+
-%% n octets for exponent
-%%
-%% +------------+ +------------+
-%% | | | |
-%% +------------+ ...+------------+
-%% p octets for pos mantissa
-%%
-%% S is 0 for positive sign
-%% 1 for negative sign
-%% BB: encoding base, 00 = 2, (01 = 8, 10 = 16)
-%% 01 and 10 not used
-%% FF: scale factor 00 = 0 (used in base 2 encoding)
-%% EE: encoding of the exponent:
-%% 00 - on the following octet
-%% 01 - on the 2 following octets
-%% 10 - on the 3 following octets
-%% 11 - encoding of the length of the two's-complement encoding of
-%% exponent on the following octet, and two's-complement
-%% encoding of exponent on the other octets.
-%%
-%% In DER and base 2 encoding the mantissa is encoded as value 0 or
-%% bit shifted until it is an odd number. Thus, do this for BER as
-%% well.
-%% This interface also used by RT_COMMON
-encode_real(_C,{Mantissa, Base, Exponent}) when Base =:= 2 ->
-%% io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
- {Man,ExpAdd} = truncate_zeros(Mantissa), %% DER adjustment
- Exp = Exponent + ExpAdd,
- OctExp = if Exp >= 0 -> list_to_binary(encode_integer_pos(Exp, []));
- true -> list_to_binary(encode_integer_neg(Exp, []))
- end,
-%% ok = io:format("OctExp: ~w~n",[OctExp]),
- SignBit = if Man > 0 -> 0; % bit 7 is pos or neg, no Zeroval
- true -> 1
- end,
-%% ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
- SFactor = 0,
- OctExpLen = size(OctExp),
- if OctExpLen > 255 ->
- exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
- true -> true %% make real assert later..
- end,
- {LenCode, EOctets} = case OctExpLen of % bit 2,1
- 1 -> {0, OctExp};
- 2 -> {1, OctExp};
- 3 -> {2, OctExp};
- _ -> {3, <<OctExpLen, OctExp/binary>>}
- end,
- BB = 0, %% 00 for base 2
- FirstOctet = <<1:1,SignBit:1,BB:2,SFactor:2,LenCode:2>>,
- OctMantissa = if Man > 0 -> list_to_binary(minimum_octets(Man));
- true -> list_to_binary(minimum_octets(-(Man))) % signbit keeps track of sign
- end,
- %% ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
- Bin = <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>,
- {Bin, size(Bin)};
-encode_real(C,{Mantissa,Base,Exponent})
- when Base =:= 10, is_integer(Mantissa), is_integer(Exponent) ->
- %% always encode as NR3 due to DER on the format
- %% mmmm.Eseeee where
- %% m := digit
- %% s := '-' | '+' | []
- %% '+' only allowed in +0
- %% e := digit
- %% ex: 1234.E-5679
-%% {Man,AddExp} = truncate_zeros(Mantissa,0),
-%% ManNum = trunc(Mantissa),
-%% {TruncatedMan,NumZeros} = truncate_zeros10(Mantissa),
- ManStr = integer_to_list(Mantissa),
-
- encode_real_as_string(C,ManStr,Exponent);
-encode_real(_C,{_,Base,_}) ->
- exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}});
-%% base 10
-encode_real(C,Real) when is_list(Real) ->
- %% The Real string may come in as a NR1, NR2 or NR3 string.
- {Mantissa, Exponent} =
- case string:tokens(Real,"Ee") of
- [NR2] ->
- {NR2,0};
- [NR3MB,NR3E] ->
- %% remove beginning zeros
- {NR3MB,list_to_integer(NR3E)}
- end,
-
- %% .Decimal | Number | Number.Decimal
- ZeroDecimal =
- fun("0") -> "";
- (L) -> L
- end,
- {NewMantissa,LenDecimal} =
- case Mantissa of
- [$.|Dec] ->
- NewMan = remove_trailing_zeros(Dec),
- {NewMan,length(ZeroDecimal(NewMan))};
- _ ->
- case string:tokens(Mantissa,",.") of
- [Num] -> %% No decimal-mark
- {integer_to_list(list_to_integer(Num)),0};
- [Num,Dec] ->
- NewDec = ZeroDecimal(remove_trailing_zeros(Dec)),
- NewMan = integer_to_list(list_to_integer(Num)) ++ NewDec,
- {integer_to_list(list_to_integer(NewMan)),
- length(NewDec)}
- end
- end,
-
-% DER_Exponent = integer_to_list(Exponent - ExpReduce),
- encode_real_as_string(C,NewMantissa,Exponent - LenDecimal).
-
-encode_real_as_string(_C,Mantissa,Exponent)
- when is_list(Mantissa), is_integer(Exponent) ->
- %% Remove trailing zeros in Mantissa and add this to Exponent
- TruncMant = remove_trailing_zeros(Mantissa),
-
- ExpIncr = length(Mantissa) - length(TruncMant),
-
- ExpStr = integer_to_list(Exponent + ExpIncr),
-
- ExpBin =
- case ExpStr of
- "0" ->
- <<"E+0">>;
- _ ->
- ExpB = list_to_binary(ExpStr),
- <<$E,ExpB/binary>>
- end,
- ManBin = list_to_binary(TruncMant),
- NR3 = 3,
- {<<NR3,ManBin/binary,$.,ExpBin/binary>>,2 + size(ManBin) + size(ExpBin)}.
-
-remove_trailing_zeros(IntStr) ->
- case lists:dropwhile(fun($0)-> true;
- (_) -> false
- end, lists:reverse(IntStr)) of
- [] ->
- "0";
- ReversedIntStr ->
- lists:reverse(ReversedIntStr)
- end.
-
-truncate_zeros(Num) ->
- truncate_zeros(Num,0).
-truncate_zeros(0,Sum) ->
- {0,Sum};
-truncate_zeros(M,Sum) ->
- case M band 16#f =:= M band 16#e of
- true -> truncate_zeros(M bsr 1,Sum+1);
- _ -> {M,Sum}
- end.
-
-
-%%============================================================================
-%% decode real value
-%%
-%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
-%% {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
-%% RestBuff}
-%%
-%% only for base 2 decoding sofar!!
-%%============================================================================
-
-decode_real(Buffer, C, Tags, OptOrMand) ->
- NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_REAL}),
- decode_real_notag(Buffer, C, NewTags, OptOrMand).
-
-%% This interface used by RT_COMMON
-decode_real(Buffer,Len) ->
- decode_real2(Buffer,[],Len,0).
-
-decode_real_notag(Buffer, C, Tags, OptOrMand) ->
- {_RestTags, {{_,Len}, Buffer0, Rb0}} =
- check_tags_i(Tags, Buffer, OptOrMand),
- decode_real2(Buffer0, C, Len, Rb0).
-
-decode_real2(Buffer, _C, 0, _RemBytes) ->
- {0,Buffer};
-decode_real2(Buffer0, _C, Len, RemBytes1) ->
- <<First, Buffer2/binary>> = Buffer0,
- if
- First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
- First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
-%% First =:= 2#00000000 -> {0, Buffer2};
- First =:= 1 orelse First =:= 2 orelse First =:= 3 ->
- %% charcter string encoding of base 10
- {NRx,Rest} = split_binary(Buffer2,Len-1),
- {binary_to_list(NRx),Rest,Len};
- true ->
- %% have some check here to verify only supported bases (2)
- %% not base 8 or 16
- <<_B7:1,Sign:1,BB:2,_FF:2,EE:2>> = <<First>>,
- Base =
- case BB of
- 0 -> 2; % base 2, only one so far
- _ -> exit({error,{asn1, {non_supported_base, BB}}})
- end,
- {FirstLen, {Exp, Buffer3,_Rb2}, RemBytes2} =
- case EE of
- 0 -> {2, decode_integer2(1, Buffer2, RemBytes1), RemBytes1+1};
- 1 -> {3, decode_integer2(2, Buffer2, RemBytes1), RemBytes1+2};
- 2 -> {4, decode_integer2(3, Buffer2, RemBytes1), RemBytes1+3};
- 3 ->
- <<ExpLen1,RestBuffer/binary>> = Buffer2,
- { ExpLen1 + 2,
- decode_integer2(ExpLen1, RestBuffer, RemBytes1),
- RemBytes1+ExpLen1}
- end,
- %% io:format("FirstLen: ~w, Exp: ~w, Buffer3: ~w ~n",
-
- Length = Len - FirstLen,
- <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
- {{Mantissa, Buffer4}, RemBytes3} =
- if Sign =:= 0 ->
- %% io:format("sign plus~n"),
- {{LongInt, RestBuff}, 1 + Length};
- true ->
- %% io:format("sign minus~n"),
- {{-LongInt, RestBuff}, 1 + Length}
- end,
- {{Mantissa, Base, Exp}, Buffer4, RemBytes2+RemBytes3}
- end.
-
-encode_integer_pos(0, L=[B|_Acc]) when B < 128 ->
- L;
-encode_integer_pos(N, Acc) ->
- encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
-
-encode_integer_neg(-1, L=[B1|_T]) when B1 > 127 ->
- L;
-encode_integer_neg(N, Acc) ->
- encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
-
-
-%%%%%%%%%%%
-%% mk_object_val(Value) -> {OctetList, Len}
-%% returns a Val as a list of octets, the 8 bit is allways set to one except
-%% for the last octet, where its 0
-%%
-
-
-mk_object_val(Val) when Val =< 127 ->
- {[255 band Val], 1};
-mk_object_val(Val) ->
- mk_object_val(Val bsr 7, [Val band 127], 1).
-mk_object_val(0, Ack, Len) ->
- {Ack, Len};
-mk_object_val(Val, Ack, Len) ->
- mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
-
-
-%%============================================================================
-%% Length handling
-%%
-%% Encode length
-%%
-%% encode_length(Int | indefinite) ->
-%% [<127]| [128 + Int (<127),OctetList] | [16#80]
-%%============================================================================
-
-encode_length(L) when L =< 16#7F ->
- {[L],1};
-encode_length(L) ->
- Oct = minimum_octets(L),
- Len = length(Oct),
- if
- Len =< 126 ->
- {[ (16#80+Len) | Oct ],Len+1};
- true ->
- exit({error,{asn1, to_long_length_oct, Len}})
- end.
-
-
-%% Val must be >= 0
-minimum_octets(Val) ->
- minimum_octets(Val,[]).
-
-minimum_octets(0,Acc) ->
- Acc;
-minimum_octets(Val, Acc) ->
- minimum_octets((Val bsr 8),[Val band 16#FF | Acc]).
-
-
-%%===========================================================================
-%% Decode length
-%%
-%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |
-%% {{Length, RestOctetsL}, NoRemovedBytes}
-%%===========================================================================
-
-decode_length(<<1:1,0:7,T/binary>>) ->
- {{indefinite, T}, 1};
-decode_length(<<0:1,Length:7,T/binary>>) ->
- {{Length,T},1};
-decode_length(<<1:1,LL:7,T/binary>>) ->
- <<Length:LL/unit:8,Rest/binary>> = T,
- {{Length,Rest}, LL+1}.
-
-
-dotag([], Tag, {Bytes,Len}) ->
- dotag_universal(Tag,Bytes,Len);
-dotag(Tags, Tag, {Bytes,Len}) ->
- encode_tags(Tags ++ [#tag{class=?UNIVERSAL,number=Tag,form=?PRIMITIVE}],
- Bytes, Len).
-
-dotag_universal(UniversalTag,Bytes,Len) when Len =< 16#7F->
- {[UniversalTag,Len,Bytes],2+Len};
-dotag_universal(UniversalTag,Bytes,Len) ->
- {EncLen,LenLen}=encode_length(Len),
- {[UniversalTag,EncLen,Bytes],1+LenLen+Len}.
-
-%% decoding postitive integer values.
-decode_integer2(Len,Bin = <<0:1,_:7,_Bs/binary>>,RemovedBytes) ->
- <<Int:Len/unit:8,Buffer2/binary>> = Bin,
- {Int,Buffer2,RemovedBytes};
-%% decoding negative integer values.
-decode_integer2(Len,<<1:1,B2:7,Bs/binary>>,RemovedBytes) ->
- <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
- Int = N - (1 bsl (8 * Len - 1)),
- {Int,Buffer2,RemovedBytes}.
-
-new_tags([],LastTag) ->
- [LastTag];
-new_tags(Tags = [#tag{type='IMPLICIT'}],_LastTag) ->
- Tags;
-new_tags([T1 = #tag{type='IMPLICIT'},#tag{type=T2Type}|Rest],LastTag) ->
- new_tags([T1#tag{type=T2Type}|Rest],LastTag);
-new_tags(Tags,LastTag) ->
- case lists:last(Tags) of
- #tag{type='IMPLICIT'} ->
- Tags;
- _ ->
- Tags ++ [LastTag]
- end.
diff --git a/lib/asn1/src/asn1rt_ber_bin_v2.erl b/lib/asn1/src/asn1rt_ber_bin_v2.erl
deleted file mode 100644
index 92ca11cf89..0000000000
--- a/lib/asn1/src/asn1rt_ber_bin_v2.erl
+++ /dev/null
@@ -1,1992 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-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(asn1rt_ber_bin_v2).
-
-%% encoding / decoding of BER
-
--export([decode/1, decode/2, match_tags/2, encode/1, encode/2]).
--export([fixoptionals/2,
- encode_tag_val/1,
- encode_tags/3,
- skip_ExtensionAdditions/2]).
--export([encode_boolean/2,decode_boolean/2,
- encode_integer/3,encode_integer/4,
- decode_integer/3, decode_integer/4,
- encode_enumerated/2,
- encode_enumerated/4,decode_enumerated/4,
- encode_real/3,decode_real/2,
- encode_bit_string/4,decode_bit_string/4,
- decode_compact_bit_string/4,
- encode_octet_string/3,decode_octet_string/3,
- 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/4,decode_restricted_string/4,
- encode_universal_string/3,decode_universal_string/3,
- encode_UTF8_string/3,decode_UTF8_string/2,
- encode_BMP_string/3,decode_BMP_string/3,
- encode_generalized_time/3,decode_generalized_time/3,
- encode_utc_time/3,decode_utc_time/3,
- encode_length/1,decode_length/1,
- decode_tag_and_length/1]).
-
--export([encode_open_type/1,encode_open_type/2,
- decode_open_type/2,decode_open_type/3,
- decode_open_type_as_binary/2,
- decode_open_type_as_binary/3]).
-
--export([decode_primitive_incomplete/2,decode_selective/2]).
-
-% the encoding of class of tag bits 8 and 7
--define(UNIVERSAL, 0).
--define(APPLICATION, 16#40).
--define(CONTEXT, 16#80).
--define(PRIVATE, 16#C0).
-
-%%% primitive or constructed encoding % bit 6
--define(PRIMITIVE, 0).
--define(CONSTRUCTED, 2#00100000).
-
-%%% The tag-number for universal types
--define(N_BOOLEAN, 1).
--define(N_INTEGER, 2).
--define(N_BIT_STRING, 3).
--define(N_OCTET_STRING, 4).
--define(N_NULL, 5).
--define(N_OBJECT_IDENTIFIER, 6).
--define(N_OBJECT_DESCRIPTOR, 7).
--define(N_EXTERNAL, 8).
--define(N_REAL, 9).
--define(N_ENUMERATED, 10).
--define(N_EMBEDDED_PDV, 11).
--define(N_SEQUENCE, 16).
--define(N_SET, 17).
--define(N_NumericString, 18).
--define(N_PrintableString, 19).
--define(N_TeletexString, 20).
--define(N_VideotexString, 21).
--define(N_IA5String, 22).
--define(N_UTCTime, 23).
--define(N_GeneralizedTime, 24).
--define(N_GraphicString, 25).
--define(N_VisibleString, 26).
--define(N_GeneralString, 27).
--define(N_UniversalString, 28).
--define(N_BMPString, 30).
-
-
-% the complete tag-word of built-in types
--define(T_BOOLEAN, ?UNIVERSAL bor ?PRIMITIVE bor 1).
--define(T_INTEGER, ?UNIVERSAL bor ?PRIMITIVE bor 2).
--define(T_BIT_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
--define(T_OCTET_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED
--define(T_NULL, ?UNIVERSAL bor ?PRIMITIVE bor 5).
--define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6).
--define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7).
--define(T_EXTERNAL, ?UNIVERSAL bor ?PRIMITIVE bor 8).
--define(T_REAL, ?UNIVERSAL bor ?PRIMITIVE bor 9).
--define(T_ENUMERATED, ?UNIVERSAL bor ?PRIMITIVE bor 10).
--define(T_EMBEDDED_PDV, ?UNIVERSAL bor ?PRIMITIVE bor 11).
--define(T_SEQUENCE, ?UNIVERSAL bor ?CONSTRUCTED bor 16).
--define(T_SET, ?UNIVERSAL bor ?CONSTRUCTED bor 17).
--define(T_NumericString, ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
--define(T_PrintableString, ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
--define(T_TeletexString, ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
--define(T_VideotexString, ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed
--define(T_IA5String, ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed
--define(T_UTCTime, ?UNIVERSAL bor ?PRIMITIVE bor 23).
--define(T_GeneralizedTime, ?UNIVERSAL bor ?PRIMITIVE bor 24).
--define(T_GraphicString, ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed
--define(T_VisibleString, ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed
--define(T_GeneralString, ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed
--define(T_UniversalString, ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed
--define(T_BMPString, ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed
-
-% encode(Tlv={_Tag={?PRIMITIVE,_},_VList}) ->
-% encode_primitive(Tlv);
-% encode(Tlv) ->
-% encode_constructed(Tlv).
-
-encode(Tlv) ->
- encode(Tlv,erlang).
-
-encode(Tlv,_) when is_binary(Tlv) ->
- Tlv;
-encode([Tlv],Method) ->
- encode(Tlv,Method);
-encode(Tlv, nif) ->
- asn1rt_nif:encode_ber_tlv(Tlv);
-encode(Tlv, _) ->
- encode_erl(Tlv).
-
-encode_erl({TlvTag,TlvVal}) when is_list(TlvVal) ->
- %% constructed form of value
- encode_tlv(TlvTag,TlvVal,?CONSTRUCTED);
-encode_erl({TlvTag,TlvVal}) ->
- encode_tlv(TlvTag,TlvVal,?PRIMITIVE).
-
-encode_tlv(TlvTag,TlvVal,Form) ->
- Tag = encode_tlv_tag(TlvTag,Form),
- {Val,VLen} = encode_tlv_val(TlvVal),
- {Len,_LLen} = encode_length(VLen),
- BinLen = list_to_binary(Len),
- <<Tag/binary,BinLen/binary,Val/binary>>.
-
-encode_tlv_tag(ClassTagNo,Form) ->
- Class = ClassTagNo bsr 16,
- encode_tag_val({Class bsl 6,Form,(ClassTagNo - (Class bsl 16))}).
-
-encode_tlv_val(TlvL) when is_list(TlvL) ->
- encode_tlv_list(TlvL,[]);
-encode_tlv_val(Bin) ->
- {Bin,size(Bin)}.
-
-encode_tlv_list([Tlv|Tlvs],Acc) ->
- EncTlv = encode_erl(Tlv),
- encode_tlv_list(Tlvs,[EncTlv|Acc]);
-encode_tlv_list([],Acc) ->
- Bin=list_to_binary(lists:reverse(Acc)),
- {Bin,size(Bin)}.
-
-decode(B) ->
- decode(B, erlang).
-
-%% asn1-1.7
-decode(B, nif) ->
- case asn1rt_nif:decode_ber_tlv(B) of
- {error, Reason} -> handle_error(Reason, B);
- Else -> Else
- end;
-decode(B,erlang) when is_binary(B) ->
- decode_primitive(B);
-decode(Tlv,erlang) ->
- {Tlv,<<>>}.
-
-handle_error([],_)->
- exit({error,{asn1,{"memory allocation problem"}}});
-handle_error({$1,_},L) -> % error in nif
- exit({error,{asn1,L}});
-handle_error({$2,T},L) -> % error in nif due to wrong tag
- exit({error,{asn1,{"bad tag after byte:",error_pos(T),L}}});
-handle_error({$3,T},L) -> % error in driver due to length error
- exit({error,{asn1,{"bad length field after byte:",
- error_pos(T),L}}});
-handle_error({$4,T},L) -> % error in driver due to indefinite length error
- exit({error,{asn1,
- {"indefinite length without end bytes after byte:",
- error_pos(T),L}}});
-handle_error({$5,T},L) -> % error in driver due to indefinite length error
- exit({error,{asn1,{"bad encoded value after byte:",
- error_pos(T),L}}});
-handle_error(ErrL,L) ->
- exit({error,{asn1,ErrL,L}}).
-
-error_pos([]) ->
- "unknown position";
-error_pos([B])->
- B;
-error_pos([B|Bs]) ->
- BS = 8 * length(Bs),
- B bsl BS + error_pos(Bs).
-
-decode_primitive(Bin) ->
- {Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
- case Form of
- 1 -> % constructed
- {{TagNo,decode_constructed(V)},Rest};
- 0 -> % primitive
- {{TagNo,V},Rest};
- 2 -> % constructed indefinite
- {Vlist,Rest2} = decode_constructed_indefinite(V,[]),
- {{TagNo,Vlist},Rest2}
- end.
-
-decode_constructed(Bin) when byte_size(Bin) =:= 0 ->
- [];
-decode_constructed(Bin) ->
- {Tlv,Rest} = decode_primitive(Bin),
- [Tlv|decode_constructed(Rest)].
-
-decode_constructed_indefinite(<<0,0,Rest/binary>>,Acc) ->
- {lists:reverse(Acc),Rest};
-decode_constructed_indefinite(Bin,Acc) ->
- {Tlv,Rest} = decode_primitive(Bin),
- decode_constructed_indefinite(Rest, [Tlv|Acc]).
-
-%% decode_primitive_incomplete/2 decodes an encoded message incomplete
-%% by help of the pattern attribute (first argument).
-decode_primitive_incomplete([[default,TagNo]],Bin) -> %default
- case decode_tag_and_length(Bin) of
- {Form,TagNo,V,Rest} ->
- decode_incomplete2(Form,TagNo,V,[],Rest);
- _ ->
- %{asn1_DEFAULT,Bin}
- asn1_NOVALUE
- end;
-decode_primitive_incomplete([[default,TagNo,Directives]],Bin) -> %default, constructed type, Directives points into this type
- case decode_tag_and_length(Bin) of
- {Form,TagNo,V,Rest} ->
- decode_incomplete2(Form,TagNo,V,Directives,Rest);
- _ ->
- %{asn1_DEFAULT,Bin}
- asn1_NOVALUE
- end;
-decode_primitive_incomplete([[opt,TagNo]],Bin) -> %optional
- case decode_tag_and_length(Bin) of
- {Form,TagNo,V,Rest} ->
- decode_incomplete2(Form,TagNo,V,[],Rest);
- _ ->
- %{{TagNo,asn1_NOVALUE},Bin}
- asn1_NOVALUE
- end;
-decode_primitive_incomplete([[opt,TagNo,Directives]],Bin) -> %optional
- case decode_tag_and_length(Bin) of
- {Form,TagNo,V,Rest} ->
- decode_incomplete2(Form,TagNo,V,Directives,Rest);
- _ ->
- %{{TagNo,asn1_NOVALUE},Bin}
- asn1_NOVALUE
- end;
-%% An optional that shall be undecoded
-decode_primitive_incomplete([[opt_undec,Tag]],Bin) ->
- case decode_tag_and_length(Bin) of
- {_,Tag,_,_} ->
- decode_incomplete_bin(Bin);
- _ ->
- asn1_NOVALUE
- end;
-%% A choice alternative that shall be undecoded
-decode_primitive_incomplete([[alt_undec,TagNo]|RestAlts],Bin) ->
-% decode_incomplete_bin(Bin);
-% case decode_tlv(Bin) of
- case decode_tag_and_length(Bin) of
-% {{_Form,TagNo,_Len,_V},_R} ->
- {_,TagNo,_,_} ->
- decode_incomplete_bin(Bin);
- _ ->
- decode_primitive_incomplete(RestAlts,Bin)
- end;
-decode_primitive_incomplete([[alt,TagNo]|RestAlts],Bin) ->
- case decode_tag_and_length(Bin) of
- {_Form,TagNo,V,Rest} ->
- {{TagNo,V},Rest};
- _ ->
- decode_primitive_incomplete(RestAlts,Bin)
- end;
-decode_primitive_incomplete([[alt,TagNo,Directives]|RestAlts],Bin) ->
- case decode_tag_and_length(Bin) of
- {Form,TagNo,V,Rest} ->
- decode_incomplete2(Form,TagNo,V,Directives,Rest);
- _ ->
- decode_primitive_incomplete(RestAlts,Bin)
- end;
-decode_primitive_incomplete([[alt_parts,TagNo]],Bin) ->
- case decode_tag_and_length(Bin) of
- {_Form,TagNo,V,Rest} ->
- {{TagNo,V},Rest};
- _ ->
- asn1_NOVALUE
- end;
-decode_primitive_incomplete([[alt_parts,TagNo]|RestAlts],Bin) ->
- case decode_tag_and_length(Bin) of
- {_Form,TagNo,V,Rest} ->
- {{TagNo,decode_parts_incomplete(V)},Rest};
- _ ->
- decode_primitive_incomplete(RestAlts,Bin)
- end;
-decode_primitive_incomplete([[undec,_TagNo]|_RestTag],Bin) -> %incomlete decode
- decode_incomplete_bin(Bin);
-decode_primitive_incomplete([[parts,TagNo]|_RestTag],Bin) ->
- case decode_tag_and_length(Bin) of
- {_Form,TagNo,V,Rest} ->
- {{TagNo,decode_parts_incomplete(V)},Rest};
- Err ->
- {error,{asn1,"tag failure",TagNo,Err}}
- end;
-decode_primitive_incomplete([mandatory|RestTag],Bin) ->
- {Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
- decode_incomplete2(Form,TagNo,V,RestTag,Rest);
-%% A choice that is a toptype or a mandatory component of a
-%% SEQUENCE or SET.
-decode_primitive_incomplete([[mandatory|Directives]],Bin) ->
- {Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
- decode_incomplete2(Form,TagNo,V,Directives,Rest);
-decode_primitive_incomplete([],Bin) ->
- decode_primitive(Bin).
-
-%% decode_parts_incomplete/1 receives a number of values encoded in
-%% sequence and returns the parts as unencoded binaries
-decode_parts_incomplete(<<>>) ->
- [];
-decode_parts_incomplete(Bin) ->
- {ok,Rest} = skip_tag(Bin),
- {ok,Rest2} = skip_length_and_value(Rest),
- LenPart = size(Bin) - size(Rest2),
- <<Part:LenPart/binary,RestBin/binary>> = Bin,
- [Part|decode_parts_incomplete(RestBin)].
-
-
-%% decode_incomplete2 checks if V is a value of a constructed or
-%% primitive type, and continues the decode propeerly.
-decode_incomplete2(_Form=2,TagNo,V,TagMatch,_) ->
- %% constructed indefinite length
- {Vlist,Rest2} = decode_constr_indef_incomplete(TagMatch,V,[]),
- {{TagNo,Vlist},Rest2};
-decode_incomplete2(1,TagNo,V,[TagMatch],Rest) when is_list(TagMatch) ->
- {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest};
-decode_incomplete2(1,TagNo,V,TagMatch,Rest) ->
- {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest};
-decode_incomplete2(0,TagNo,V,_TagMatch,Rest) ->
- {{TagNo,V},Rest}.
-
-decode_constructed_incomplete([Tags=[Ts]],Bin) when is_list(Ts) ->
- decode_constructed_incomplete(Tags,Bin);
-decode_constructed_incomplete(_TagMatch,<<>>) ->
- [];
-decode_constructed_incomplete([mandatory|RestTag],Bin) ->
- {Tlv,Rest} = decode_primitive(Bin),
- [Tlv|decode_constructed_incomplete(RestTag,Rest)];
-decode_constructed_incomplete(Directives=[[Alt,_]|_],Bin)
- when Alt == alt_undec; Alt == alt; Alt == alt_parts ->
- {_Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
- case incomplete_choice_alt(TagNo,Directives) of
- {alt_undec,_} ->
- LenA = size(Bin)-size(Rest),
- <<A:LenA/binary,Rest/binary>> = Bin,
- A;
- {alt,InnerDirectives} ->
- {Tlv,Rest} = decode_primitive_incomplete(InnerDirectives,V),
- {TagNo,Tlv};
- {alt_parts,_} ->
- [{TagNo,decode_parts_incomplete(V)}];
- no_match -> %% if a choice alternative was encoded that
- %% was not specified in the config file,
- %% thus decode component anonomous.
- {Tlv,_}=decode_primitive(Bin),
- Tlv
- end;
-decode_constructed_incomplete([TagNo|RestTag],Bin) ->
-%% {Tlv,Rest} = decode_primitive_incomplete([TagNo],Bin),
- case decode_primitive_incomplete([TagNo],Bin) of
- {Tlv,Rest} ->
- [Tlv|decode_constructed_incomplete(RestTag,Rest)];
- asn1_NOVALUE ->
- decode_constructed_incomplete(RestTag,Bin)
- end;
-decode_constructed_incomplete([],Bin) ->
- {Tlv,Rest}=decode_primitive(Bin),
- [Tlv|decode_constructed_incomplete([],Rest)].
-
-decode_constr_indef_incomplete(_TagMatch,<<0,0,Rest/binary>>,Acc) ->
- {lists:reverse(Acc),Rest};
-decode_constr_indef_incomplete([Tag|RestTags],Bin,Acc) ->
-% {Tlv,Rest} = decode_primitive_incomplete([Tag],Bin),
- case decode_primitive_incomplete([Tag],Bin) of
- {Tlv,Rest} ->
- decode_constr_indef_incomplete(RestTags,Rest,[Tlv|Acc]);
- asn1_NOVALUE ->
- decode_constr_indef_incomplete(RestTags,Bin,Acc)
- end.
-
-
-decode_incomplete_bin(Bin) ->
- {ok,Rest} = skip_tag(Bin),
- {ok,Rest2} = skip_length_and_value(Rest),
- IncLen = size(Bin) - size(Rest2),
- <<IncBin:IncLen/binary,Ret/binary>> = Bin,
- {IncBin,Ret}.
-
-incomplete_choice_alt(TagNo,[[Alt,TagNo]|Directives]) ->
- {Alt,Directives};
-incomplete_choice_alt(TagNo,[D]) when is_list(D) ->
- incomplete_choice_alt(TagNo,D);
-incomplete_choice_alt(TagNo,[_H|Directives]) ->
- incomplete_choice_alt(TagNo,Directives);
-incomplete_choice_alt(_,[]) ->
- no_match.
-
-
-
-
-%% decode_selective(Pattern, Binary) the first argument is a pattern that tells
-%% what to do with the next element the second is the BER encoded
-%% message as a binary
-%% Returns {ok,Value} or {error,Reason}
-%% Value is a binary that in turn must be decoded to get the decoded
-%% value.
-decode_selective([],Binary) ->
- {ok,Binary};
-decode_selective([skip|RestPattern],Binary)->
- {ok,RestBinary}=skip_tag(Binary),
- {ok,RestBinary2}=skip_length_and_value(RestBinary),
- decode_selective(RestPattern,RestBinary2);
-decode_selective([[skip_optional,Tag]|RestPattern],Binary) ->
- case skip_optional_tag(Tag,Binary) of
- {ok,RestBinary} ->
- {ok,RestBinary2}=skip_length_and_value(RestBinary),
- decode_selective(RestPattern,RestBinary2);
- missing ->
- decode_selective(RestPattern,Binary)
- end;
-decode_selective([[choosen,Tag]],Binary) ->
- return_value(Tag,Binary);
-% case skip_optional_tag(Tag,Binary) of %may be optional/default
-% {ok,RestBinary} ->
-% {ok,Value} = get_value(RestBinary);
-% missing ->
-% {ok,<<>>}
-% end;
-decode_selective([[choosen,Tag]|RestPattern],Binary) ->
- case skip_optional_tag(Tag,Binary) of
- {ok,RestBinary} ->
- {ok,Value} = get_value(RestBinary),
- decode_selective(RestPattern,Value);
- missing ->
- {ok,<<>>}
- end;
-decode_selective(P,_) ->
- {error,{asn1,{partial_decode,"bad pattern",P}}}.
-
-return_value(Tag,Binary) ->
- {ok,{Tag,RestBinary}}=get_tag(Binary),
- {ok,{LenVal,_RestBinary2}} = get_length_and_value(RestBinary),
- {ok,<<Tag/binary,LenVal/binary>>}.
-
-
-%% skip_tag and skip_length_and_value are rutines used both by
-%% decode_partial_incomplete and decode_selective (decode/2).
-
-skip_tag(<<_:3,31:5,Rest/binary>>)->
- skip_long_tag(Rest);
-skip_tag(<<_:3,_Tag:5,Rest/binary>>) ->
- {ok,Rest}.
-
-skip_long_tag(<<1:1,_:7,Rest/binary>>) ->
- skip_long_tag(Rest);
-skip_long_tag(<<0:1,_:7,Rest/binary>>) ->
- {ok,Rest}.
-
-skip_optional_tag(<<>>,Binary) ->
- {ok,Binary};
-skip_optional_tag(<<Tag,RestTag/binary>>,<<Tag,Rest/binary>>) ->
- skip_optional_tag(RestTag,Rest);
-skip_optional_tag(_,_) ->
- missing.
-
-
-
-
-skip_length_and_value(Binary) ->
- case decode_length(Binary) of
- {indefinite,RestBinary} ->
- skip_indefinite_value(RestBinary);
- {Length,RestBinary} ->
- <<_:Length/unit:8,Rest/binary>> = RestBinary,
- {ok,Rest}
- end.
-
-skip_indefinite_value(<<0,0,Rest/binary>>) ->
- {ok,Rest};
-skip_indefinite_value(Binary) ->
- {ok,RestBinary}=skip_tag(Binary),
- {ok,RestBinary2} = skip_length_and_value(RestBinary),
- skip_indefinite_value(RestBinary2).
-
-get_value(Binary) ->
- case decode_length(Binary) of
- {indefinite,RestBinary} ->
- get_indefinite_value(RestBinary,[]);
- {Length,RestBinary} ->
- <<Value:Length/binary,_Rest/binary>> = RestBinary,
- {ok,Value}
- end.
-
-get_indefinite_value(<<0,0,_Rest/binary>>,Acc) ->
- {ok,list_to_binary(lists:reverse(Acc))};
-get_indefinite_value(Binary,Acc) ->
- {ok,{Tag,RestBinary}}=get_tag(Binary),
- {ok,{LenVal,RestBinary2}} = get_length_and_value(RestBinary),
- get_indefinite_value(RestBinary2,[LenVal,Tag|Acc]).
-
-get_tag(<<H:1/binary,Rest/binary>>) ->
- case H of
- <<_:3,31:5>> ->
- get_long_tag(Rest,[H]);
- _ -> {ok,{H,Rest}}
- end.
-get_long_tag(<<H:1/binary,Rest/binary>>,Acc) ->
- case H of
- <<0:1,_:7>> ->
- {ok,{list_to_binary(lists:reverse([H|Acc])),Rest}};
- _ ->
- get_long_tag(Rest,[H|Acc])
- end.
-
-get_length_and_value(Bin = <<0:1,Length:7,_T/binary>>) ->
- <<Len,Val:Length/binary,Rest/binary>> = Bin,
- {ok,{<<Len,Val/binary>>, Rest}};
-get_length_and_value(Bin = <<1:1,0:7,_T/binary>>) ->
- get_indefinite_length_and_value(Bin);
-get_length_and_value(<<1:1,LL:7,T/binary>>) ->
- <<Length:LL/unit:8,Rest/binary>> = T,
- <<Value:Length/binary,Rest2/binary>> = Rest,
- {ok,{<<1:1,LL:7,Length:LL/unit:8,Value/binary>>,Rest2}}.
-
-get_indefinite_length_and_value(<<H,T/binary>>) ->
- get_indefinite_length_and_value(T,[H]).
-
-get_indefinite_length_and_value(<<0,0,Rest/binary>>,Acc) ->
- {ok,{list_to_binary(lists:reverse(Acc)),Rest}};
-get_indefinite_length_and_value(Binary,Acc) ->
- {ok,{Tag,RestBinary}}=get_tag(Binary),
- {ok,{LenVal,RestBinary2}}=get_length_and_value(RestBinary),
- get_indefinite_length_and_value(RestBinary2,[LenVal,Tag|Acc]).
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% match_tags takes a Tlv (Tag, Length, Value) structure and matches
-%% it with the tags in TagList. If the tags does not match the function
-%% crashes otherwise it returns the remaining Tlv after that the tags have
-%% been removed.
-%%
-%% match_tags(Tlv, TagList)
-%%
-
-match_tags({T,V},[T]) ->
- V;
-match_tags({T,V}, [T|Tt]) ->
- match_tags(V,Tt);
-match_tags([{T,V}],[T|Tt]) ->
- match_tags(V, Tt);
-match_tags(Vlist = [{T,_V}|_], [T]) ->
- Vlist;
-match_tags(Tlv, []) ->
- Tlv;
-match_tags(Tlv = {Tag,_V},[T|_Tt]) ->
- exit({error,{asn1,{wrong_tag,{{expected,T},{got,Tag,Tlv}}}}}).
-
-%%%
-%% skips components that do not match a tag in Tags
-skip_ExtensionAdditions([],_Tags) ->
- [];
-skip_ExtensionAdditions(TLV=[{Tag,_}|Rest],Tags) ->
- case [X||X=T<-Tags,T==Tag] of
- [] ->
- %% skip this TLV and continue with next
- skip_ExtensionAdditions(Rest,Tags);
- _ ->
- TLV
- end.
-
-
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-%% Optionals, preset not filled optionals with asn1_NOVALUE
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-
-fixoptionals(OptList,Val) when is_list(Val) ->
- fixoptionals(OptList,Val,1,[],[]).
-
-fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
- fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
-fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
- fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
-fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
- fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
-fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
- fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
-fixoptionals([],[],_,_Acc1,Acc2) ->
- % return Val as a record
- list_to_tuple([asn1_RECORDNAME|lists:reverse(Acc2)]).
-
-
-%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
-%% 8bit Int | binary
-encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
- <<(Class bsr 6):2,(Form bsr 5):1,TagNo:5>>;
-
-encode_tag_val({Class, Form, TagNo}) ->
- {Octets,_Len} = mk_object_val(TagNo),
- BinOct = list_to_binary(Octets),
- <<(Class bsr 6):2, (Form bsr 5):1, 31:5,BinOct/binary>>.
-
-
-%%===============================================================================
-%% Decode a tag
-%%
-%% decode_tag(OctetListBuffer) -> {{Form, (Class bsl 16)+ TagNo}, RestOfBuffer, RemovedBytes}
-%%===============================================================================
-
-decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) when TagNo < 31 ->
- {Form, (Class bsl 16) + TagNo, V, RestBuffer};
-decode_tag_and_length(<<Class:2, 1:1, TagNo:5, 1:1, 0:7, T/binary>>) when TagNo < 31 ->
- {2, (Class bsl 16) + TagNo, T, <<>>};
-decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 1:1, LL:7, Length:LL/unit:8,V:Length/binary, T/binary>>) when TagNo < 31 ->
- {Form, (Class bsl 16) + TagNo, V, T};
-decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) ->
- {Form, (Class bsl 16) + TagNo, V, RestBuffer};
-decode_tag_and_length(<<Class:2, 1:1, 31:5, 0:1, TagNo:7, 1:1, 0:7, T/binary>>) ->
- {2, (Class bsl 16) + TagNo, T, <<>>};
-decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 1:1, LL:7, Length:LL/unit:8, V:Length/binary, T/binary>>) ->
- {Form, (Class bsl 16) + TagNo, V, T};
-decode_tag_and_length(<<Class:2, Form:1, 31:5, 1:1, TagPart1:7, 0:1, TagPartLast, Buffer/binary>>) ->
- TagNo = (TagPart1 bsl 7) bor TagPartLast,
- {Length, RestBuffer} = decode_length(Buffer),
- << V:Length/binary, RestBuffer2/binary>> = RestBuffer,
- {Form, (Class bsl 16) + TagNo, V, RestBuffer2};
-decode_tag_and_length(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
- {TagNo, Buffer1} = decode_tag(Buffer, 0),
- {Length, RestBuffer} = decode_length(Buffer1),
- << V:Length/binary, RestBuffer2/binary>> = RestBuffer,
- {Form, (Class bsl 16) + TagNo, V, RestBuffer2}.
-
-
-
-%% last partial tag
-decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck) ->
- TagNo = (TagAck bsl 7) bor PartialTag,
- %%<<TagNo>> = <<TagAck:1, PartialTag:7>>,
- {TagNo, Buffer};
-% more tags
-decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck) ->
- TagAck1 = (TagAck bsl 7) bor PartialTag,
- %%<<TagAck1:16>> = <<TagAck:1, PartialTag:7,0:8>>,
- decode_tag(Buffer, TagAck1).
-
-
-%%=======================================================================
-%%
-%% Encode all tags in the list Tags and return a possibly deep list of
-%% bytes with tag and length encoded
-%% The taglist must be in reverse order (fixed by the asn1 compiler)
-%% e.g [T1,T2] will result in
-%% {[EncodedT2,EncodedT1|BytesSoFar],LenSoFar+LenT2+LenT1}
-%%
-
-encode_tags([Tag|Trest], BytesSoFar, LenSoFar) ->
-% remove {Bytes1,L1} = encode_one_tag(Tag),
- {Bytes2,L2} = encode_length(LenSoFar),
- encode_tags(Trest, [Tag,Bytes2|BytesSoFar],
- LenSoFar + size(Tag) + L2);
-encode_tags([], BytesSoFar, LenSoFar) ->
- {BytesSoFar,LenSoFar}.
-
-encode_tags(TagIn, {BytesSoFar,LenSoFar}) ->
- encode_tags(TagIn, BytesSoFar, LenSoFar).
-
-% encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
-% NewForm = case Type of
-% 'EXPLICIT' ->
-% ?CONSTRUCTED;
-% _ ->
-% Form
-% end,
-% Bytes = encode_tag_val({Class,NewForm,No}),
-% {Bytes,size(Bytes)}.
-
-
-%%===============================================================================
-%%
-%% This comment is valid for all the encode/decode functions
-%%
-%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound}
-%% used for PER-coding but not for BER-coding.
-%%
-%% Val = Value. If Val is an atom then it is a symbolic integer value
-%% (i.e the atom must be one of the names in the NamedNumberList).
-%% The NamedNumberList is used to translate the atom to an integer value
-%% before encoding.
-%%
-%%===============================================================================
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_open_type(Value) -> io_list (i.e nested list with integers, binaries)
-%% Value = list of bytes of an already encoded value (the list must be flat)
-%% | binary
-
-%%
-encode_open_type(Val) when is_list(Val) ->
-% {Val,length(Val)};
- encode_open_type(list_to_binary(Val));
-encode_open_type(Val) ->
- {Val, size(Val)}.
-
-%%
-encode_open_type(Val, T) when is_list(Val) ->
- encode_open_type(list_to_binary(Val),T);
-encode_open_type(Val,[]) ->
- {Val, size(Val)};
-encode_open_type(Val,Tag) ->
- encode_tags(Tag,Val, size(Val)).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_open_type(Tlv, TagIn) -> Value
-%% Tlv = {Tag,V} | V where V -> binary()
-%% TagIn = [TagVal] where TagVal -> int()
-%% Value = binary with decoded data (which must be decoded again as some type)
-%%
-decode_open_type(Tlv, TagIn) ->
- decode_open_type(Tlv, TagIn, erlang).
-decode_open_type(Tlv, TagIn, Method) ->
- case match_tags(Tlv,TagIn) of
- Bin when is_binary(Bin) ->
- {InnerTlv,_} = decode(Bin,Method),
- InnerTlv;
- TlvBytes -> TlvBytes
- end.
-
-
-decode_open_type_as_binary(Tlv, TagIn) ->
- decode_open_type_as_binary(Tlv, TagIn, erlang).
-decode_open_type_as_binary(Tlv,TagIn, Method)->
- case match_tags(Tlv,TagIn) of
- V when is_binary(V) ->
- V;
- [Tlv2] -> encode(Tlv2, Method);
- Tlv2 -> encode(Tlv2, Method)
- end.
-
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-%% Boolean, ITU_T X.690 Chapter 8.2
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-
-%%===============================================================================
-%% encode_boolean(Integer, ReversedTagList) -> {[Octet],Len}
-%%===============================================================================
-
-encode_boolean({Name, Val}, TagIn) when is_atom(Name) ->
- encode_boolean(Val, TagIn);
-encode_boolean(true, TagIn) ->
- encode_tags(TagIn, [16#FF],1);
-encode_boolean(false, TagIn) ->
- encode_tags(TagIn, [0],1);
-encode_boolean(X,_) ->
- exit({error,{asn1, {encode_boolean, X}}}).
-
-
-%%===============================================================================
-%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
-%% {false, Remain, RemovedBytes}
-%%===============================================================================
-decode_boolean(Tlv,TagIn) ->
- Val = match_tags(Tlv, TagIn),
- case Val of
- <<0:8>> ->
- false;
- <<_:8>> ->
- true;
- _ ->
- exit({error,{asn1, {decode_boolean, Val}}})
- end.
-
-
-%%===========================================================================
-%% Integer, ITU_T X.690 Chapter 8.3
-
-%% encode_integer(Constraint, Value, Tag) -> [octet list]
-%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
-%% Value = INTEGER | {Name,INTEGER}
-%% Tag = tag | notag
-%%===========================================================================
-
-encode_integer(C, Val, Tag) when is_integer(Val) ->
- encode_tags(Tag, encode_integer(C, Val));
-encode_integer(C,{Name,Val},Tag) when is_atom(Name) ->
- encode_integer(C,Val,Tag);
-encode_integer(_C, Val, _Tag) ->
- exit({error,{asn1, {encode_integer, Val}}}).
-
-
-
-encode_integer(C, Val, NamedNumberList, Tag) when is_atom(Val) ->
- case lists:keysearch(Val, 1, NamedNumberList) of
- {value,{_, NewVal}} ->
- encode_tags(Tag, encode_integer(C, NewVal));
- _ ->
- exit({error,{asn1, {encode_integer_namednumber, Val}}})
- end;
-encode_integer(C,{_Name,Val},NamedNumberList,Tag) ->
- encode_integer(C,Val,NamedNumberList,Tag);
-encode_integer(C, Val, _NamedNumberList, Tag) ->
- encode_tags(Tag, encode_integer(C, Val)).
-
-
-encode_integer(_, Val) ->
- Bytes =
- if
- Val >= 0 ->
- encode_integer_pos(Val, []);
- true ->
- encode_integer_neg(Val, [])
- end,
- {Bytes,length(Bytes)}.
-
-encode_integer_pos(0, L=[B|_Acc]) when B < 128 ->
- L;
-encode_integer_pos(N, Acc) ->
- encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
-
-encode_integer_neg(-1, L=[B1|_T]) when B1 > 127 ->
- L;
-encode_integer_neg(N, Acc) ->
- encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
-
-%%===============================================================================
-%% decode integer
-%% (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
-%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
-%%===============================================================================
-
-decode_integer(Tlv,Range,NamedNumberList,TagIn) ->
- V = match_tags(Tlv,TagIn),
- Int = decode_integer(V),
- range_check_integer(Int,Range),
- number2name(Int,NamedNumberList).
-
-decode_integer(Tlv,Range,TagIn) ->
- V = match_tags(Tlv, TagIn),
- Int = decode_integer(V),
- range_check_integer(Int,Range),
- Int.
-
-%% decoding postitive integer values.
-decode_integer(Bin = <<0:1,_:7,_/binary>>) ->
- Len = size(Bin),
-% <<Int:Len/unit:8,Buffer2/binary>> = Bin,
- <<Int:Len/unit:8>> = Bin,
- Int;
-%% decoding negative integer values.
-decode_integer(Bin = <<1:1,B2:7,Bs/binary>>) ->
- Len = size(Bin),
-% <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
- <<N:Len/unit:8>> = <<B2,Bs/binary>>,
- Int = N - (1 bsl (8 * Len - 1)),
- Int.
-
-range_check_integer(Int,Range) ->
- case Range of
- [] -> % No length constraint
- Int;
- {Lb,Ub} when Int >= Lb, Ub >= Int -> % variable length constraint
- Int;
- Int -> % fixed value constraint
- Int;
- {_,_} ->
- exit({error,{asn1,{integer_range,Range,Int}}});
- SingleValue when is_integer(SingleValue) ->
- exit({error,{asn1,{integer_range,Range,Int}}});
- _ -> % some strange constraint that we don't support yet
- Int
- end.
-
-number2name(Int,[]) ->
- Int;
-number2name(Int,NamedNumberList) ->
- case lists:keysearch(Int, 2, NamedNumberList) of
- {value,{NamedVal, _}} ->
- NamedVal;
- _ ->
- 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(false,Val));
-encode_enumerated({Name,Val}, TagIn) when is_atom(Name) ->
- encode_enumerated(Val, TagIn).
-
-%% The encode_enumerated functions below this line can be removed when the
-%% new code generation is stable. (the functions might have to be kept here
-%% a while longer for compatibility reasons)
-
-encode_enumerated(C, Val, {NamedNumberList,ExtList}, TagIn) when is_atom(Val) ->
- case catch encode_enumerated(C, Val, NamedNumberList, TagIn) of
- {'EXIT',_} -> encode_enumerated(C, Val, ExtList, TagIn);
- Result -> Result
- end;
-
-encode_enumerated(C, Val, NamedNumberList, TagIn) when is_atom(Val) ->
- case lists:keysearch(Val, 1, NamedNumberList) of
- {value, {_, NewVal}} ->
- encode_tags(TagIn, encode_integer(C, NewVal));
- _ ->
- exit({error,{asn1, {enumerated_not_in_range, Val}}})
- end;
-
-encode_enumerated(C, {asn1_enum, Val}, {_,_}, TagIn) when is_integer(Val) ->
- encode_tags(TagIn, encode_integer(C,Val));
-
-encode_enumerated(C, {Name,Val}, NamedNumberList, TagIn) when is_atom(Name) ->
- encode_enumerated(C, Val, NamedNumberList, TagIn);
-
-encode_enumerated(_C, Val, _NamedNumberList, _TagIn) ->
- exit({error,{asn1, {enumerated_not_namednumber, Val}}}).
-
-
-
-%%============================================================================
-%% decode enumerated value
-%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> Value
-%%===========================================================================
-decode_enumerated(Tlv, Range, NamedNumberList, Tags) ->
- Buffer = match_tags(Tlv,Tags),
- decode_enumerated_notag(Buffer, Range, NamedNumberList, Tags).
-
-decode_enumerated_notag(Buffer, _Range, {NamedNumberList,ExtList}, _Tags) ->
-
- IVal = decode_integer2(size(Buffer), Buffer),
- case decode_enumerated1(IVal, NamedNumberList) of
- {asn1_enum,IVal} ->
- decode_enumerated1(IVal,ExtList);
- EVal ->
- EVal
- end;
-decode_enumerated_notag(Buffer, _Range, NNList, _Tags) ->
- IVal = decode_integer2(size(Buffer), 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:keysearch(Val, 2, NamedNumberList) of
- {value,{NamedVal, _}} ->
- NamedVal;
- _ ->
- {asn1_enum,Val}
- end.
-
-
-%%============================================================================
-%%
-%% Real value, ITU_T X.690 Chapter 8.5
-%%============================================================================
-%%
-%% encode real value
-%%============================================================================
-
-%% only base 2 internally so far!!
-encode_real(_C,0, TagIn) ->
- encode_tags(TagIn, {[],0});
-encode_real(_C,'PLUS-INFINITY', TagIn) ->
- encode_tags(TagIn, {[64],1});
-encode_real(_C,'MINUS-INFINITY', TagIn) ->
- encode_tags(TagIn, {[65],1});
-encode_real(C,Val, TagIn) when is_tuple(Val); is_list(Val) ->
- encode_tags(TagIn, encode_real(C,Val)).
-
-
-
-encode_real(C,Val) ->
- asn1rt_ber_bin:encode_real(C,Val).
-
-
-%%============================================================================
-%% decode real value
-%%
-%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
-%% {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
-%% RestBuff}
-%%
-%% only for base 2 and 10 decoding sofar!!
-%%============================================================================
-
-decode_real(Tlv, Tags) ->
- Buffer = match_tags(Tlv,Tags),
- decode_real_notag(Buffer).
-
-decode_real_notag(Buffer) ->
- Len =
- case Buffer of
- Bin when is_binary(Bin) ->
- size(Bin);
- {_T,_V} ->
- exit({error,{asn1,{real_not_in_primitive_form,Buffer}}})
- end,
- {Val,_Rest,Len} = asn1rt_ber_bin:decode_real(Buffer,Len),
- Val.
-%% exit({error,{asn1, {unimplemented,real}}}).
-%% decode_real2(Buffer, Form, size(Buffer)).
-
-% decode_real2(Buffer, Form, Len) ->
-% <<First, Buffer2/binary>> = Buffer,
-% if
-% First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
-% First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
-% First =:= 2#00000000 -> {0, Buffer2};
-% true ->
-% %% have some check here to verify only supported bases (2)
-% <<B7:1,B6:1,B5_4:2,B3_2:2,B1_0:2>> = <<First>>,
-% Sign = B6,
-% Base =
-% case B5_4 of
-% 0 -> 2; % base 2, only one so far
-% _ -> exit({error,{asn1, {non_supported_base, First}}})
-% end,
-% ScalingFactor =
-% case B3_2 of
-% 0 -> 0; % no scaling so far
-% _ -> exit({error,{asn1, {non_supported_scaling, First}}})
-% end,
-
-% {FirstLen,Exp,Buffer3} =
-% case B1_0 of
-% 0 ->
-% <<_:1/unit:8,Buffer21/binary>> = Buffer2,
-% {2, decode_integer2(1, Buffer2),Buffer21};
-% 1 ->
-% <<_:2/unit:8,Buffer21/binary>> = Buffer2,
-% {3, decode_integer2(2, Buffer2)};
-% 2 ->
-% <<_:3/unit:8,Buffer21/binary>> = Buffer2,
-% {4, decode_integer2(3, Buffer2)};
-% 3 ->
-% <<ExpLen1,RestBuffer/binary>> = Buffer2,
-% <<_:ExpLen1/unit:8,RestBuffer2/binary>> = RestBuffer,
-% { ExpLen1 + 2,
-% decode_integer2(ExpLen1, RestBuffer, RemBytes1),
-% RestBuffer2}
-% end,
-% Length = Len - FirstLen,
-% <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
-% {Mantissa, Buffer4} =
-% if Sign =:= 0 ->
-
-% {LongInt, RestBuff};% sign plus,
-% true ->
-
-% {-LongInt, RestBuff}% sign minus
-% end,
-% case Form of
-% tuple ->
-% {Val,Buf,RemB} = Exp,
-% {{Mantissa, Base, {Val,Buf}}, Buffer4, RemBytes2+RemBytes3};
-% _value ->
-% comming
-% end
-% end.
-
-
-%%============================================================================
-%% Bitstring value, ITU_T X.690 Chapter 8.6
-%%
-%% encode bitstring value
-%%
-%% bitstring NamedBitList
-%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
-%% the Constraint must then have some information of the
-%% bitlength.
-%% - [list of ones and zeroes] all bits
-%% - integer value representing the bitlist
-%% C is constrint Len, only valid when identifiers
-%%============================================================================
-
-encode_bit_string(C,Bin={Unused,BinBits},NamedBitList,TagIn) when is_integer(Unused), is_binary(BinBits) ->
- encode_bin_bit_string(C,Bin,NamedBitList,TagIn);
-encode_bit_string(C, [FirstVal | RestVal], NamedBitList, TagIn) when is_atom(FirstVal) ->
- encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn);
-
-encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, TagIn) ->
- encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, TagIn);
-
-encode_bit_string(C, [FirstVal| RestVal], NamedBitList, TagIn) when is_integer(FirstVal) ->
- encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, TagIn);
-
-encode_bit_string(_C, 0, _NamedBitList, TagIn) ->
- encode_tags(TagIn, <<0>>,1);
-
-encode_bit_string(_C, [], _NamedBitList, TagIn) ->
- encode_tags(TagIn, <<0>>,1);
-
-encode_bit_string(C, IntegerVal, NamedBitList, TagIn) when is_integer(IntegerVal) ->
- BitListVal = int_to_bitlist(IntegerVal),
- encode_bit_string_bits(C, BitListVal, NamedBitList, TagIn);
-
-encode_bit_string(C, {Name,BitList}, NamedBitList, TagIn) when is_atom(Name) ->
- encode_bit_string(C, BitList, NamedBitList, TagIn).
-
-
-
-int_to_bitlist(0) ->
- [];
-int_to_bitlist(Int) when is_integer(Int), Int >= 0 ->
- [Int band 1 | int_to_bitlist(Int bsr 1)].
-
-
-%%=================================================================
-%% Encode BIT STRING of the form {Unused,BinBits}.
-%% Unused is the number of unused bits in the last byte in BinBits
-%% and BinBits is a binary representing the BIT STRING.
-%%=================================================================
-encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,TagIn)->
- case get_constraint(C,'SizeConstraint') of
- no ->
- remove_unused_then_dotag(TagIn, Unused, BinBits);
- {_Min,Max} ->
- BBLen = (size(BinBits)*8)-Unused,
- if
- BBLen > Max ->
- exit({error,{asn1,
- {bitstring_length,
- {{was,BBLen},{maximum,Max}}}}});
- true ->
- remove_unused_then_dotag(TagIn, Unused, BinBits)
- end;
- Size ->
- case ((size(BinBits)*8)-Unused) of
- BBSize when BBSize =< Size ->
- remove_unused_then_dotag(TagIn, Unused, BinBits);
- BBSize ->
- exit({error,{asn1,
- {bitstring_length,
- {{was,BBSize},{should_be,Size}}}}})
- end
- end.
-
-remove_unused_then_dotag(TagIn,Unused,BinBits) ->
- case Unused of
- 0 when (size(BinBits) == 0) ->
- encode_tags(TagIn,<<0>>,1);
- 0 ->
- Bin = <<Unused,BinBits/binary>>,
- encode_tags(TagIn,Bin,size(Bin));
- Num ->
- N = (size(BinBits)-1),
- <<BBits:N/binary,LastByte>> = BinBits,
- encode_tags(TagIn,
- [Unused,binary_to_list(BBits) ++[(LastByte bsr Num) bsl Num]],
- 1+size(BinBits))
- end.
-
-
-%%=================================================================
-%% Encode named bits
-%%=================================================================
-
-encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn) ->
- ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
- Size =
- case get_constraint(C,'SizeConstraint') of
- no ->
- 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).
-
-
-%%----------------------------------------
-%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
-%% [sorted_list_of_bitpositions_to_set]
-%%----------------------------------------
-
-get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
-get_all_bitposes([Val | Rest], NamedBitList, Ack) when is_atom(Val) ->
- case lists:keysearch(Val, 1, NamedBitList) of
- {value, {_ValName, ValPos}} ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
- _ ->
- exit({error,{asn1, {bitstring_namedbit, Val}}})
- end;
-get_all_bitposes([], _NamedBitList, Ack) ->
- lists:sort(Ack).
-
-
-%%----------------------------------------
-%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
-%% returns list of Len length, with all in SetPos set.
-%% in positioning in list the first element is 0, the second 1 etc.., but
-%% Len will make a list of length Len, not Len + 1.
-%% BitList = make_and_set_list(C, ToSetPos, 0),
-%%----------------------------------------
-
-make_and_set_list(0, [], _) -> [];
-make_and_set_list(0, _, _) ->
- exit({error,{asn1,bitstring_sizeconstraint}});
-make_and_set_list(Len, [XPos|SetPos], XPos) ->
- [1 | make_and_set_list(Len - 1, SetPos, XPos + 1)];
-make_and_set_list(Len, [Pos|SetPos], XPos) ->
- [0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
-make_and_set_list(Len, [], XPos) ->
- [0 | make_and_set_list(Len - 1, [], XPos + 1)].
-
-
-
-
-
-
-%%=================================================================
-%% Encode bit string for lists of ones and zeroes
-%%=================================================================
-encode_bit_string_bits(C, BitListVal, _NamedBitList, TagIn) when is_list(BitListVal) ->
- case get_constraint(C,'SizeConstraint') of
- no ->
- {Len, Unused, OctetList} = encode_bitstring(BitListVal),
- %%add unused byte to the Len
- encode_tags(TagIn, [Unused | OctetList], Len+1);
- Constr={Min,_Max} when is_integer(Min) ->
- %% Max may be an integer or 'MAX'
- encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
- {Constr={_,_},[]} ->%Constr={Min,Max}
- %% constraint with extension mark
- encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
- Constr={{_,_},{_,_}} ->%{{Min1,Max1},{Min2,Max2}}
- %% constraint with extension mark
- encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
- Size ->
- case length(BitListVal) of
- BitSize when BitSize == Size ->
- {Len, Unused, OctetList} = encode_bitstring(BitListVal),
- %%add unused byte to the Len
- encode_tags(TagIn, [Unused | OctetList], Len+1);
- BitSize when BitSize < Size ->
- PaddedList = pad_bit_list(Size-BitSize,BitListVal),
- {Len, Unused, OctetList} = encode_bitstring(PaddedList),
- %%add unused byte to the Len
- encode_tags(TagIn, [Unused | OctetList], Len+1);
- BitSize ->
- exit({error,{asn1,
- {bitstring_length, {{was,BitSize},{should_be,Size}}}}})
- end
-
- end.
-
-encode_constr_bit_str_bits({{_Min1,Max1},{Min2,Max2}},BitListVal,TagIn) ->
- BitLen = length(BitListVal),
- case BitLen of
- Len when Len > Max2 ->
- exit({error,{asn1,{bitstring_length,{{was,BitLen},
- {maximum,Max2}}}}});
- Len when Len > Max1, Len < Min2 ->
- exit({error,{asn1,{bitstring_length,{{was,BitLen},
- {not_allowed_interval,
- Max1,Min2}}}}});
- _ ->
- {Len, Unused, OctetList} = encode_bitstring(BitListVal),
- %%add unused byte to the Len
- encode_tags(TagIn, [Unused, OctetList], Len+1)
- end;
-encode_constr_bit_str_bits({Min,Max},BitListVal,TagIn) ->
- BitLen = length(BitListVal),
- if
- BitLen > Max ->
- exit({error,{asn1,{bitstring_length,{{was,BitLen},
- {maximum,Max}}}}});
- BitLen < Min ->
- exit({error,{asn1,{bitstring_length,{{was,BitLen},
- {minimum,Max}}}}});
- true ->
- {Len, Unused, OctetList} = encode_bitstring(BitListVal),
- %%add unused byte to the Len
- encode_tags(TagIn, [Unused, OctetList], Len+1)
- end.
-
-
-%% returns a list of length Size + length(BitListVal), with BitListVal
-%% as the most significant elements followed by padded zero elements
-pad_bit_list(Size,BitListVal) ->
- Tail = lists:duplicate(Size,0),
- lists:append(BitListVal,Tail).
-
-%%=================================================================
-%% Do the actual encoding
-%% ([bitlist]) -> {ListLen, UnusedBits, OctetList}
-%%=================================================================
-
-encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
- Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
- (B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
- encode_bitstring(Rest, [Val], 1);
-encode_bitstring(Val) ->
- {Unused, Octet} = unused_bitlist(Val, 7, 0),
- {1, Unused, [Octet]}.
-
-encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) ->
- Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
- (B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
- encode_bitstring(Rest, [Ack | [Val]], Len + 1);
-%%even multiple of 8 bits..
-encode_bitstring([], Ack, Len) ->
- {Len, 0, Ack};
-%% unused bits in last octet
-encode_bitstring(Rest, Ack, Len) ->
-% io:format("uneven ~w ~w ~w~n",[Rest, Ack, Len]),
- {Unused, Val} = unused_bitlist(Rest, 7, 0),
- {Len + 1, Unused, [Ack | [Val]]}.
-
-%%%%%%%%%%%%%%%%%%
-%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
-%% {Unused bits, Last octet with bits moved to right}
-unused_bitlist([], Trail, Ack) ->
- {Trail + 1, Ack};
-unused_bitlist([Bit | Rest], Trail, Ack) ->
-%% io:format("trail Bit: ~w Rest: ~w Trail: ~w Ack:~w~n",[Bit, Rest, Trail, Ack]),
- unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack).
-
-
-%%============================================================================
-%% decode bitstring value
-%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
-%%============================================================================
-
-decode_compact_bit_string(Buffer, Range, NamedNumberList, Tags) ->
-% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
- decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags,
- NamedNumberList,bin).
-
-decode_bit_string(Buffer, Range, NamedNumberList, Tags) ->
-% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
- decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags,
- NamedNumberList,old).
-
-
-decode_bit_string2(<<0>>,_NamedNumberList,BinOrOld) ->
- case BinOrOld of
- bin ->
- {0,<<>>};
- _ ->
- []
- end;
-decode_bit_string2(<<Unused,Bits/binary>>,NamedNumberList,BinOrOld) ->
- case NamedNumberList of
- [] ->
- case BinOrOld of
- bin ->
- {Unused,Bits};
- _ ->
- decode_bitstring2(size(Bits), Unused, Bits)
- end;
- _ ->
- BitString = decode_bitstring2(size(Bits), Unused, Bits),
- decode_bitstring_NNL(BitString,NamedNumberList)
- end.
-
-%%----------------------------------------
-%% Decode the in buffer to bits
-%%----------------------------------------
-decode_bitstring2(1,Unused,<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) ->
- lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0],8-Unused);
-decode_bitstring2(Len, Unused,
- <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
- [B7, B6, B5, B4, B3, B2, B1, B0 |
- decode_bitstring2(Len - 1, Unused, Buffer)].
-
-%%decode_bitstring2(1, Unused, Buffer) ->
-%% make_bits_of_int(hd(Buffer), 128, 8-Unused);
-%%decode_bitstring2(Len, Unused, [BitVal | Buffer]) ->
-%% [B7, B6, B5, B4, B3, B2, B1, B0] = make_bits_of_int(BitVal, 128, 8),
-%% [B7, B6, B5, B4, B3, B2, B1, B0 |
-%% decode_bitstring2(Len - 1, Unused, Buffer)].
-
-
-%%make_bits_of_int(_, _, 0) ->
-%% [];
-%%make_bits_of_int(BitVal, MaskVal, Unused) when Unused > 0 ->
-%% X = case MaskVal band BitVal of
-%% 0 -> 0 ;
-%% _ -> 1
-%% end,
-%% [X | make_bits_of_int(BitVal, MaskVal bsr 1, Unused - 1)].
-
-
-
-%%----------------------------------------
-%% Decode the bitlist to names
-%%----------------------------------------
-
-
-decode_bitstring_NNL(BitList,NamedNumberList) ->
- decode_bitstring_NNL(BitList,NamedNumberList,0,[]).
-
-
-decode_bitstring_NNL([],_,_No,Result) ->
- lists:reverse(Result);
-
-decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
- if
- B == 0 ->
- decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
- true ->
- decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
- end;
-decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
- decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
-decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
- decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
-
-
-%%============================================================================
-%% Octet string, ITU_T X.690 Chapter 8.7
-%%
-%% encode octet string
-%% The OctetList must be a flat list of integers in the range 0..255
-%% the function does not check this because it takes to much time
-%%============================================================================
-encode_octet_string(_C, OctetList, TagIn) when is_binary(OctetList) ->
- encode_tags(TagIn, OctetList, size(OctetList));
-encode_octet_string(_C, OctetList, TagIn) when is_list(OctetList) ->
- encode_tags(TagIn, OctetList, length(OctetList));
-encode_octet_string(C, {Name,OctetList}, TagIn) when is_atom(Name) ->
- encode_octet_string(C, OctetList, TagIn).
-
-
-%%============================================================================
-%% decode octet string
-%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
-%%
-%% Octet string is decoded as a restricted string
-%%============================================================================
-decode_octet_string(Buffer, Range, Tags) ->
-% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
- decode_restricted_string(Buffer, Range, ?N_OCTET_STRING,
- Tags, [], old).
-
-%%============================================================================
-%% Null value, ITU_T X.690 Chapter 8.8
-%%
-%% encode NULL value
-%%============================================================================
-
-encode_null({Name, _Val}, TagIn) when is_atom(Name) ->
- encode_tags(TagIn, [], 0);
-encode_null(_Val, TagIn) ->
- encode_tags(TagIn, [], 0).
-
-%%============================================================================
-%% decode NULL value
-%% (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
-%%============================================================================
-
-decode_null(Tlv, Tags) ->
- Val = match_tags(Tlv, Tags),
- case Val of
- <<>> ->
- 'NULL';
- _ ->
- exit({error,{asn1,{decode_null,Val}}})
- end.
-
-%%============================================================================
-%% Object identifier, ITU_T X.690 Chapter 8.19
-%%
-%% encode Object Identifier value
-%%============================================================================
-
-encode_object_identifier({Name,Val}, TagIn) when is_atom(Name) ->
- encode_object_identifier(Val, TagIn);
-encode_object_identifier(Val, TagIn) ->
- encode_tags(TagIn, e_object_identifier(Val)).
-
-e_object_identifier({'OBJECT IDENTIFIER', V}) ->
- e_object_identifier(V);
-e_object_identifier({Cname, V}) when is_atom(Cname), is_tuple(V) ->
- e_object_identifier(tuple_to_list(V));
-e_object_identifier({Cname, V}) when is_atom(Cname), is_list(V) ->
- e_object_identifier(V);
-e_object_identifier(V) when is_tuple(V) ->
- e_object_identifier(tuple_to_list(V));
-
-%%%%%%%%%%%%%%%
-%% e_object_identifier([List of Obect Identifiers]) ->
-%% {[Encoded Octetlist of ObjIds], IntLength}
-%%
-e_object_identifier([E1, E2 | Tail]) ->
- Head = 40*E1 + E2, % wow!
- {H,Lh} = mk_object_val(Head),
- {R,Lr} = lists:mapfoldl(fun enc_obj_id_tail/2,0,Tail),
- {[H|R], Lh+Lr}.
-
-enc_obj_id_tail(H, Len) ->
- {B, L} = mk_object_val(H),
- {B,Len+L}.
-
-
-%%%%%%%%%%%
-%% mk_object_val(Value) -> {OctetList, Len}
-%% returns a Val as a list of octets, the 8 bit is allways set to one except
-%% for the last octet, where its 0
-%%
-
-
-mk_object_val(Val) when Val =< 127 ->
- {[255 band Val], 1};
-mk_object_val(Val) ->
- mk_object_val(Val bsr 7, [Val band 127], 1).
-mk_object_val(0, Ack, Len) ->
- {Ack, Len};
-mk_object_val(Val, Ack, Len) ->
- mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
-
-
-
-%%============================================================================
-%% decode Object Identifier value
-%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
-%%============================================================================
-
-decode_object_identifier(Tlv, Tags) ->
- Val = match_tags(Tlv, Tags),
- [AddedObjVal|ObjVals] = dec_subidentifiers(Val,0,[]),
- {Val1, Val2} = if
- AddedObjVal < 40 ->
- {0, AddedObjVal};
- AddedObjVal < 80 ->
- {1, AddedObjVal - 40};
- true ->
- {2, AddedObjVal - 80}
- end,
- list_to_tuple([Val1, Val2 | ObjVals]).
-
-dec_subidentifiers(<<>>,_Av,Al) ->
- lists:reverse(Al);
-dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al) ->
- dec_subidentifiers(T,(Av bsl 7) + H,Al);
-dec_subidentifiers(<<H,T/binary>>,Av,Al) ->
- dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al]).
-
-%%============================================================================
-%% RELATIVE-OID, ITU_T X.690 Chapter 8.20
-%%
-%% encode Relative Object Identifier
-%%============================================================================
-encode_relative_oid({Name,Val},TagIn) when is_atom(Name) ->
- encode_relative_oid(Val,TagIn);
-encode_relative_oid(Val,TagIn) when is_tuple(Val) ->
- encode_relative_oid(tuple_to_list(Val),TagIn);
-encode_relative_oid(Val,TagIn) ->
- encode_tags(TagIn, enc_relative_oid(Val)).
-
-enc_relative_oid(Tuple) when is_tuple(Tuple) ->
- enc_relative_oid(tuple_to_list(Tuple));
-enc_relative_oid(Val) ->
- lists:mapfoldl(fun(X,AccIn) ->
- {SO,L}=mk_object_val(X),
- {SO,L+AccIn}
- end
- ,0,Val).
-
-%%============================================================================
-%% decode Relative Object Identifier value
-%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
-%%============================================================================
-decode_relative_oid(Tlv, Tags) ->
- Val = match_tags(Tlv, Tags),
- ObjVals = dec_subidentifiers(Val,0,[]),
- list_to_tuple(ObjVals).
-
-%%============================================================================
-%% Restricted character string types, ITU_T X.690 Chapter 8.20
-%%
-%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
-%%============================================================================
-%% The StringType arg is kept for future use but might be removed
-encode_restricted_string(_C, OctetList, _StringType, TagIn)
- when is_binary(OctetList) ->
- encode_tags(TagIn, OctetList, size(OctetList));
-encode_restricted_string(_C, OctetList, _StringType, TagIn)
- when is_list(OctetList) ->
- encode_tags(TagIn, OctetList, length(OctetList));
-encode_restricted_string(C,{Name,OctetL}, StringType, TagIn) when is_atom(Name)->
- encode_restricted_string(C, OctetL, StringType, TagIn).
-
-%%============================================================================
-%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
-%% (Buffer, Range, StringType, HasTag, TotalLen) ->
-%% {String, Remain, RemovedBytes}
-%%============================================================================
-
-decode_restricted_string(Buffer, Range, StringType, Tags) ->
- decode_restricted_string(Buffer, Range, StringType, Tags, [], old).
-
-
-decode_restricted_string(Tlv, Range, StringType, TagsIn,
- NamedNumberList, BinOrOld) ->
- Val = match_tags(Tlv, TagsIn),
- Val2 =
- case Val of
- PartList = [_H|_T] -> % constructed val
- Bin = collect_parts(PartList),
- decode_restricted(Bin, StringType,
- NamedNumberList, BinOrOld);
- Bin ->
- decode_restricted(Bin, StringType,
- NamedNumberList, BinOrOld)
- end,
- check_and_convert_restricted_string(Val2,StringType,Range,NamedNumberList,BinOrOld).
-
-
-
-% case StringType of
-% ?N_BIT_STRING when BinOrOld == bin ->
-% {concat_bit_binaries(AccVal, Val), AccRb+Rb};
-% _ when is_binary(Val),is_binary(AccVal) ->
-% {<<AccVal/binary,Val/binary>>,AccRb+Rb};
-% _ when is_binary(Val), AccVal==[] ->
-% {Val,AccRb+Rb};
-% _ ->
-% {AccVal++Val, AccRb+Rb}
-% end,
-
-
-
-decode_restricted(Bin, StringType, NamedNumberList,BinOrOld) ->
- case StringType of
- ?N_BIT_STRING ->
- decode_bit_string2(Bin, NamedNumberList, BinOrOld);
- ?N_UniversalString ->
- mk_universal_string(binary_to_list(Bin));
- ?N_BMPString ->
- mk_BMP_string(binary_to_list(Bin));
- _ ->
- Bin
- end.
-
-
-check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrOld) ->
- {StrLen,NewVal} = case StringType of
- ?N_BIT_STRING when NamedNumberList /= [] ->
- {no_check,Val};
- ?N_BIT_STRING when is_list(Val) ->
- {length(Val),Val};
- ?N_BIT_STRING when is_tuple(Val) ->
- {(size(element(2,Val))*8) - element(1,Val),Val};
- _ when is_binary(Val) ->
- {size(Val),binary_to_list(Val)};
- _ when is_list(Val) ->
- {length(Val), Val}
- end,
- case Range of
- _ when StrLen == no_check ->
- NewVal;
- [] -> % No length constraint
- NewVal;
- {Lb,Ub} when StrLen >= Lb, Ub >= StrLen -> % variable length constraint
- NewVal;
- {{Lb,_Ub},[]} when StrLen >= Lb ->
- NewVal;
- {{Lb,_Ub},_Ext=[Min|_]} when StrLen >= Lb; StrLen >= Min ->
- NewVal;
- {{Lb1,Ub1},{Lb2,Ub2}} when StrLen >= Lb1, StrLen =< Ub1;
- StrLen =< Ub2, StrLen >= Lb2 ->
- NewVal;
- StrLen -> % fixed length constraint
- NewVal;
- {_,_} ->
- exit({error,{asn1,{length,Range,Val}}});
- _Len when is_integer(_Len) ->
- exit({error,{asn1,{length,Range,Val}}});
- _ -> % some strange constraint that we don't support yet
- NewVal
- end.
-
-
-%%============================================================================
-%% encode Universal string
-%%============================================================================
-
-encode_universal_string(C, {Name, Universal}, TagIn) when is_atom(Name) ->
- encode_universal_string(C, Universal, TagIn);
-encode_universal_string(_C, Universal, TagIn) ->
- OctetList = mk_uni_list(Universal),
- encode_tags(TagIn, OctetList, length(OctetList)).
-
-mk_uni_list(In) ->
- mk_uni_list(In,[]).
-
-mk_uni_list([],List) ->
- lists:reverse(List);
-mk_uni_list([{A,B,C,D}|T],List) ->
- mk_uni_list(T,[D,C,B,A|List]);
-mk_uni_list([H|T],List) ->
- mk_uni_list(T,[H,0,0,0|List]).
-
-%%===========================================================================
-%% decode Universal strings
-%% (Buffer, Range, StringType, HasTag, LenIn) ->
-%% {String, Remain, RemovedBytes}
-%%===========================================================================
-
-decode_universal_string(Buffer, Range, Tags) ->
- decode_restricted_string(Buffer, Range, ?N_UniversalString,
- Tags, [], old).
-
-
-mk_universal_string(In) ->
- mk_universal_string(In,[]).
-
-mk_universal_string([],Acc) ->
- lists:reverse(Acc);
-mk_universal_string([0,0,0,D|T],Acc) ->
- mk_universal_string(T,[D|Acc]);
-mk_universal_string([A,B,C,D|T],Acc) ->
- mk_universal_string(T,[{A,B,C,D}|Acc]).
-
-
-%%============================================================================
-%% encode UTF8 string
-%%============================================================================
-
-encode_UTF8_string(_C,UTF8String,TagIn) when is_binary(UTF8String) ->
- encode_tags(TagIn, UTF8String, size(UTF8String));
-encode_UTF8_string(_C,UTF8String,TagIn) ->
- encode_tags(TagIn, UTF8String, length(UTF8String)).
-
-
-%%============================================================================
-%% decode UTF8 string
-%%============================================================================
-
-decode_UTF8_string(Tlv,TagsIn) ->
- Val = match_tags(Tlv, TagsIn),
- case Val of
- PartList = [_H|_T] -> % constructed val
- collect_parts(PartList);
- Bin ->
- Bin
- end.
-
-
-%%============================================================================
-%% encode BMP string
-%%============================================================================
-
-encode_BMP_string(C, {Name,BMPString}, TagIn) when is_atom(Name)->
- encode_BMP_string(C, BMPString, TagIn);
-encode_BMP_string(_C, BMPString, TagIn) ->
- OctetList = mk_BMP_list(BMPString),
- encode_tags(TagIn, OctetList, length(OctetList)).
-
-mk_BMP_list(In) ->
- mk_BMP_list(In,[]).
-
-mk_BMP_list([],List) ->
- lists:reverse(List);
-mk_BMP_list([{0,0,C,D}|T],List) ->
- mk_BMP_list(T,[D,C|List]);
-mk_BMP_list([H|T],List) ->
- mk_BMP_list(T,[H,0|List]).
-
-%%============================================================================
-%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList}
-%% (Buffer, Range, StringType, HasTag, TotalLen) ->
-%% {String, Remain, RemovedBytes}
-%%============================================================================
-decode_BMP_string(Buffer, Range, Tags) ->
- decode_restricted_string(Buffer, Range, ?N_BMPString,
- Tags, [], old).
-
-mk_BMP_string(In) ->
- mk_BMP_string(In,[]).
-
-mk_BMP_string([],US) ->
- lists:reverse(US);
-mk_BMP_string([0,B|T],US) ->
- mk_BMP_string(T,[B|US]);
-mk_BMP_string([C,D|T],US) ->
- mk_BMP_string(T,[{0,0,C,D}|US]).
-
-
-%%============================================================================
-%% Generalized time, ITU_T X.680 Chapter 39
-%%
-%% encode Generalized time
-%%============================================================================
-
-encode_generalized_time(C, {Name,OctetList}, TagIn) when is_atom(Name) ->
- encode_generalized_time(C, OctetList, TagIn);
-encode_generalized_time(_C, OctetList, TagIn) ->
- encode_tags(TagIn, OctetList, length(OctetList)).
-
-%%============================================================================
-%% decode Generalized time
-%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
-%%============================================================================
-
-decode_generalized_time(Tlv, _Range, Tags) ->
- Val = match_tags(Tlv, Tags),
- NewVal = case Val of
- PartList = [_H|_T] -> % constructed
- collect_parts(PartList);
- Bin ->
- Bin
- end,
- binary_to_list(NewVal).
-
-%%============================================================================
-%% Universal time, ITU_T X.680 Chapter 40
-%%
-%% encode UTC time
-%%============================================================================
-
-encode_utc_time(C, {Name,OctetList}, TagIn) when is_atom(Name) ->
- encode_utc_time(C, OctetList, TagIn);
-encode_utc_time(_C, OctetList, TagIn) ->
- encode_tags(TagIn, OctetList, length(OctetList)).
-
-%%============================================================================
-%% decode UTC time
-%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
-%%============================================================================
-
-decode_utc_time(Tlv, _Range, Tags) ->
- Val = match_tags(Tlv, Tags),
- NewVal = case Val of
- PartList = [_H|_T] -> % constructed
- collect_parts(PartList);
- Bin ->
- Bin
- end,
- binary_to_list(NewVal).
-
-
-%%============================================================================
-%% Length handling
-%%
-%% Encode length
-%%
-%% encode_length(Int | indefinite) ->
-%% [<127]| [128 + Int (<127),OctetList] | [16#80]
-%%============================================================================
-
-encode_length(indefinite) ->
- {[16#80],1}; % 128
-encode_length(L) when L =< 16#7F ->
- {[L],1};
-encode_length(L) ->
- Oct = minimum_octets(L),
- Len = length(Oct),
- if
- Len =< 126 ->
- {[ (16#80+Len) | Oct ],Len+1};
- true ->
- exit({error,{asn1, to_long_length_oct, Len}})
- end.
-
-
-%% Val must be >= 0
-minimum_octets(Val) ->
- minimum_octets(Val,[]).
-
-minimum_octets(0,Acc) ->
- Acc;
-minimum_octets(Val, Acc) ->
- minimum_octets((Val bsr 8),[Val band 16#FF | Acc]).
-
-
-%%===========================================================================
-%% Decode length
-%%
-%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |
-%% {{Length, RestOctetsL}, NoRemovedBytes}
-%%===========================================================================
-
-decode_length(<<1:1,0:7,T/binary>>) ->
- {indefinite, T};
-decode_length(<<0:1,Length:7,T/binary>>) ->
- {Length,T};
-decode_length(<<1:1,LL:7,T/binary>>) ->
- <<Length:LL/unit:8,Rest/binary>> = T,
- {Length,Rest}.
-
-
-
-%%-------------------------------------------------------------------------
-%% INTERNAL HELPER FUNCTIONS (not exported)
-%%-------------------------------------------------------------------------
-
-
-%% decoding postitive integer values.
-decode_integer2(Len,Bin = <<0:1,_:7,_Bs/binary>>) ->
- <<Int:Len/unit:8>> = Bin,
- Int;
-%% decoding negative integer values.
-decode_integer2(Len,<<1:1,B2:7,Bs/binary>>) ->
- <<N:Len/unit:8>> = <<B2,Bs/binary>>,
- Int = N - (1 bsl (8 * Len - 1)),
- Int.
-
-get_constraint(C,Key) ->
- case lists:keysearch(Key,1,C) of
- false ->
- no;
- {value,{_,V}} ->
- V
- end.
-
-collect_parts(TlvList) ->
- collect_parts(TlvList,[]).
-
-collect_parts([{_,L}|Rest],Acc) when is_list(L) ->
- collect_parts(Rest,[collect_parts(L)|Acc]);
-collect_parts([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest],_Acc) ->
- collect_parts_bit(Rest,[Bits],Unused);
-collect_parts([{_T,V}|Rest],Acc) ->
- collect_parts(Rest,[V|Acc]);
-collect_parts([],Acc) ->
- list_to_binary(lists:reverse(Acc)).
-
-collect_parts_bit([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest],Acc,Uacc) ->
- collect_parts_bit(Rest,[Bits|Acc],Unused+Uacc);
-collect_parts_bit([],Acc,Uacc) ->
- list_to_binary([Uacc|lists:reverse(Acc)]).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/asn1/src/asn1rt_check.erl b/lib/asn1/src/asn1rt_check.erl
deleted file mode 100644
index 35b993fc71..0000000000
--- a/lib/asn1/src/asn1rt_check.erl
+++ /dev/null
@@ -1,360 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-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%
-%%
-%%
--module(asn1rt_check).
-
--export([check_bool/2,
- check_int/3,
- check_bitstring/3,
- check_octetstring/2,
- check_null/2,
- check_objectidentifier/2,
- check_objectdescriptor/2,
- check_real/2,
- check_enum/3,
- check_restrictedstring/2]).
-
--export([transform_to_EXTERNAL1990/1,
- transform_to_EXTERNAL1994/1]).
-
--export([dynamicsort_SET_components/1,
- dynamicsort_SETOF/1]).
-
-check_bool(_Bool,asn1_DEFAULT) ->
- true;
-check_bool(Bool,Bool) when Bool == true; Bool == false ->
- true;
-check_bool(_Bool1,Bool2) ->
- throw({error,Bool2}).
-
-check_int(_,asn1_DEFAULT,_) ->
- true;
-check_int(Value,Value,_) when is_integer(Value) ->
- true;
-check_int(DefValue,Value,NNL) when is_atom(Value) ->
- case lists:keysearch(Value,1,NNL) of
- {value,{_,DefValue}} ->
- true;
- _ ->
- throw({error,DefValue})
- end;
-check_int(DefaultValue,_Value,_) ->
- throw({error,DefaultValue}).
-
-% check_bitstring([H|T],[H|T],_) when is_integer(H) ->
-% true;
-% check_bitstring(V,V,_) when is_integer(V) ->
-% true;
-%% Two equal lists or integers
-check_bitstring(_,asn1_DEFAULT,_) ->
- true;
-check_bitstring(V,V,_) ->
- true;
-%% Default value as a list of 1 and 0 and user value as an integer
-check_bitstring(L=[H|T],Int,_) when is_integer(Int),is_integer(H) ->
- case bit_list_to_int(L,length(T)) of
- Int -> true;
- _ -> throw({error,L,Int})
- end;
-%% Default value as an integer, val as list
-check_bitstring(Int,Val,NBL) when is_integer(Int),is_list(Val) ->
- BL = int_to_bit_list(Int,[],length(Val)),
- check_bitstring(BL,Val,NBL);
-%% Default value and user value as lists of ones and zeros
-check_bitstring(L1=[H1|_T1],L2=[H2|_T2],NBL=[_H|_T]) when is_integer(H1),is_integer(H2) ->
- L2new = remove_trailing_zeros(L2),
- check_bitstring(L1,L2new,NBL);
-%% Default value as a list of 1 and 0 and user value as a list of atoms
-check_bitstring(L1=[H1|_T1],L2=[H2|_T2],NBL) when is_integer(H1),is_atom(H2) ->
- L3 = bit_list_to_nbl(L1,NBL,0,[]),
- check_bitstring(L3,L2,NBL);
-%% Both default value and user value as a list of atoms
-check_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_bitstring(L1=[H1|_T1],L2=[H2|_T2],NBL) when is_atom(H1),is_integer(H2) ->
- L3 = bit_list_to_nbl(L2,NBL,0,[]),
- check_bitstring(L1,L3,NBL);
-%% User value in compact format
-check_bitstring(DefVal,CBS={_,_},NBL) ->
- NewVal = cbs_to_bit_list(CBS),
- check_bitstring(DefVal,NewVal,NBL);
-check_bitstring(DV,V,_) ->
- throw({error,DV,V}).
-
-
-bit_list_to_int([0|Bs],ShL)->
- bit_list_to_int(Bs,ShL-1) + 0;
-bit_list_to_int([1|Bs],ShL) ->
- bit_list_to_int(Bs,ShL-1) + (1 bsl ShL);
-bit_list_to_int([],_) ->
- 0.
-
-int_to_bit_list(0,Acc,0) ->
- Acc;
-int_to_bit_list(Int,Acc,Len) ->
- 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:keysearch(Pos,2,NBL) of
- {value,{N,_}} ->
- bit_list_to_nbl(T,NBL,Pos+1,[N|Acc]);
- _ ->
- 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 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 size(Bin) == 1 ->
- Used = 8-Unused,
- <<Int:Used,_:Unused>> = Bin,
- int_to_bit_list(Int,[],Used).
-
-
-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})
- 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) ->
- true;
-check_null('NULL','NULL') ->
- true;
-check_null(_,V) ->
- throw({error,V}).
-
-check_objectidentifier(_,asn1_DEFAULT) ->
- true;
-check_objectidentifier(OI,OI) ->
- 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})
- end;
-check_objectidentifier1([],[],_) ->
- 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_objectdescriptor(_,asn1_DEFAULT) ->
- true;
-check_objectdescriptor(OD,OD) ->
- true;
-check_objectdescriptor(OD,OD) ->
- throw({error,{not_implemented_yet,check_objectdescriptor}}).
-
-check_real(_,asn1_DEFAULT) ->
- true;
-check_real(R,R) ->
- true;
-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:keysearch(Atom,1,Enumerations) of
- {value,{_,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]) ->
- check_restrictedstring(Rest1,Rest2);
-check_restrictedstring([V1|Rest1],[V2|Rest2]) ->
- check_restrictedstring(V1,V2),
- check_restrictedstring(Rest1,Rest2);
-%% tuple format of value
-check_restrictedstring({V1,V2},[V1,V2]) ->
- true;
-check_restrictedstring([V1,V2],{V1,V2}) ->
- true;
-%% quadruple format of value
-check_restrictedstring({V1,V2,V3,V4},[V1,V2,V3,V4]) ->
- true;
-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}}).
-
-transform_to_EXTERNAL1990(Val) when is_tuple(Val),size(Val) == 4 ->
- transform_to_EXTERNAL1990(tuple_to_list(Val),[]);
-transform_to_EXTERNAL1990(Val) when is_tuple(Val) ->
- %% Data already in ASN1 1990 format
- Val.
-
-transform_to_EXTERNAL1990(['EXTERNAL'|Rest],Acc) ->
- transform_to_EXTERNAL1990(Rest,['EXTERNAL'|Acc]);
-transform_to_EXTERNAL1990([{syntax,Syntax}|Rest],Acc) ->
- transform_to_EXTERNAL1990(Rest,[asn1_NOVALUE,Syntax|Acc]);
-transform_to_EXTERNAL1990([{'presentation-context-id',PCid}|Rest],Acc) ->
- transform_to_EXTERNAL1990(Rest,[PCid,asn1_NOVALUE|Acc]);
-transform_to_EXTERNAL1990([{'context-negotiation',Context_negot}|Rest],Acc) ->
- {_,Presentation_Cid,Transfer_syntax} = Context_negot,
- transform_to_EXTERNAL1990(Rest,[Presentation_Cid,Transfer_syntax|Acc]);
-transform_to_EXTERNAL1990([asn1_NOVALUE|Rest],Acc) ->
- transform_to_EXTERNAL1990(Rest,[asn1_NOVALUE|Acc]);
-transform_to_EXTERNAL1990([Data_val_desc,Data_value],Acc) when is_list(Data_value)->
- list_to_tuple(lists:reverse([{'octet-aligned',Data_value},
- Data_val_desc|Acc]));
-transform_to_EXTERNAL1990([Data_val_desc,Data_value],Acc)
- when is_binary(Data_value)->
- list_to_tuple(lists:reverse([{'single-ASN1-type',Data_value},
- Data_val_desc|Acc]));
-transform_to_EXTERNAL1990([Data_value],Acc)
- when is_list(Data_value); is_binary(Data_value) ->
- list_to_tuple(lists:reverse([{'octet-aligned',Data_value}|Acc])).
-
-
-transform_to_EXTERNAL1994(V={'EXTERNAL',DRef,IndRef,Data_v_desc,Encoding}) ->
- Identification =
- case {DRef,IndRef} of
- {DRef,asn1_NOVALUE} ->
- {syntax,DRef};
- {asn1_NOVALUE,IndRef} ->
- {'presentation-context-id',IndRef};
- _ ->
- {'context-negotiation',
- {'EXTERNAL_identification_context-negotiation',IndRef,DRef}}
- end,
- case Encoding of
- {_,Val} when is_list(Val);is_binary(Val) ->
- {'EXTERNAL',Identification,Data_v_desc,Val};
-
- _ ->
- V
- end.
-
-
-%% dynamicsort_SET_components(Arg) ->
-%% Res Arg -> list()
-%% Res -> list()
-%% Sorts the elements in Arg according to the encoded tag in
-%% increasing order.
-dynamicsort_SET_components(ListOfEncCs) ->
- BinL = lists:map(fun(X) -> list_to_binary(X) end,ListOfEncCs),
- TagBinL = lists:map(fun(X) ->
- {{T,_,TN},_,_} = asn1rt_ber_bin:decode_tag(X),
- {{T,TN},X}
- end,BinL),
- ClassTagNoSorted = lists:keysort(1,TagBinL),
- lists:map(fun({_,El}) -> El end,ClassTagNoSorted).
-
-%% dynamicsort_SETOF(Arg) -> Res
-%% Arg -> list()
-%% Res -> list()
-%% Sorts the elements in Arg in increasing size
-dynamicsort_SETOF(ListOfEncVal) ->
- BinL = lists:map(fun(L) when is_list(L) -> list_to_binary(L);
- (B) -> B end,ListOfEncVal),
- lists:sort(BinL).
diff --git a/lib/asn1/src/asn1rt_nif.erl b/lib/asn1/src/asn1rt_nif.erl
index de1fb94816..0b2e5a62a5 100644
--- a/lib/asn1/src/asn1rt_nif.erl
+++ b/lib/asn1/src/asn1rt_nif.erl
@@ -77,10 +77,31 @@ load_nif() ->
Status
end.
-encode_per_complete(_TagValueList) ->
+decode_ber_tlv(Binary) ->
+ case decode_ber_tlv_raw(Binary) of
+ {error,Reason} ->
+ exit({error,{asn1,Reason}});
+ Other ->
+ Other
+ end.
+
+encode_per_complete(TagValueList) ->
+ case encode_per_complete_raw(TagValueList) of
+ {error,Reason} -> handle_error(Reason, TagValueList);
+ Other when is_binary(Other) -> Other
+ end.
+
+handle_error([], _)->
+ exit({error,{asn1,enomem}});
+handle_error($1, L) -> % error in complete in driver
+ exit({error,{asn1,L}});
+handle_error(ErrL, L) ->
+ exit({error,{asn1,ErrL,L}}).
+
+encode_per_complete_raw(_TagValueList) ->
erlang:nif_error({nif_not_loaded,module,?MODULE,line,?LINE}).
-decode_ber_tlv(_Binary) ->
+decode_ber_tlv_raw(_Binary) ->
erlang:nif_error({nif_not_loaded,module,?MODULE,line,?LINE}).
encode_ber_tlv(_TagValueList) ->
diff --git a/lib/asn1/src/asn1rt_per_bin_rt2ct.erl b/lib/asn1/src/asn1rt_per_bin_rt2ct.erl
deleted file mode 100644
index 5997232f13..0000000000
--- a/lib/asn1/src/asn1rt_per_bin_rt2ct.erl
+++ /dev/null
@@ -1,1587 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-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(asn1rt_per_bin_rt2ct).
-%% encoding / decoding of PER aligned
-
--include("asn1_records.hrl").
-
--export([decode_fragmented/3]).
--export([setchoiceext/1, setext/1, fixoptionals/3, fixextensions/2,
- skipextensions/3, getbit/1, getchoice/3 ]).
--export([set_choice/3, encode_integer/2, encode_integer/3 ]).
--export([encode_small_number/1,
- encode_length/2,
- encode_small_length/1,
- decode_compact_bit_string/3]).
--export([encode_bit_string/3, decode_bit_string/3 ]).
--export([encode_octet_string/2,
- encode_object_identifier/1, decode_object_identifier/1,
- encode_real/1, decode_real/1,
- encode_relative_oid/1, decode_relative_oid/1,
- complete/1]).
-
--export([encode_open_type/2, decode_open_type/2]).
-
--export([encode_GeneralString/2, decode_GeneralString/2,
- encode_GraphicString/2, decode_GraphicString/2,
- encode_TeletexString/2, decode_TeletexString/2,
- encode_VideotexString/2, decode_VideotexString/2,
- encode_ObjectDescriptor/2, decode_ObjectDescriptor/1,
- encode_UTF8String/1,decode_UTF8String/1
- ]).
-
--export([encode_unconstrained_number/1,
- encode_octet_string/3,
- encode_known_multiplier_string/5,
- decode_known_multiplier_string/5]).
-
-
--export([eint_positive/1]).
--export([pre_complete_bits/2]).
-
--define('16K',16384).
--define('32K',32768).
--define('64K',65536).
-
-%%--------------------------------------------------------
-%% setchoiceext(InRootSet) -> [{bit,X}]
-%% X is set to 1 when InRootSet==false
-%% X is set to 0 when InRootSet==true
-%%
-setchoiceext(true) ->
- [0];
-setchoiceext(false) ->
- [1].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% setext(true|false) -> CompleteList
-%%
-
-setext(false) ->
-% [{debug,ext},{bits,1,0}];
- [0];
-setext(true) ->
-% [{debug,ext},{bits,1,1}];
- [1].
-
-fixoptionals(OptList,_OptLength,Val) when is_tuple(Val) ->
-% Bits = fixoptionals(OptList,Val,0),
-% {Val,{bits,OptLength,Bits}};
-% {Val,[10,OptLength,Bits]};
- {Val,fixoptionals(OptList,Val,[])};
-
-fixoptionals([],_,Acc) ->
- %% Optbits
- lists:reverse(Acc);
-fixoptionals([{Pos,DefVal}|Ot],Val,Acc) ->
- case element(Pos,Val) of
- asn1_DEFAULT -> fixoptionals(Ot,Val,[0|Acc]);
- DefVal -> fixoptionals(Ot,Val,[0|Acc]);
- _ -> fixoptionals(Ot,Val,[1|Acc])
- end;
-fixoptionals([Pos|Ot],Val,Acc) ->
- case element(Pos,Val) of
- asn1_NOVALUE -> fixoptionals(Ot,Val,[0|Acc]);
- asn1_DEFAULT -> fixoptionals(Ot,Val,[0|Acc]);
- _ -> fixoptionals(Ot,Val,[1|Acc])
- end.
-
-
-fixextensions({ext,ExtPos,ExtNum},Val) ->
- case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
- 0 -> [];
- ExtBits ->
- [encode_small_length(ExtNum),pre_complete_bits(ExtNum,ExtBits)]
- end.
-
-fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
- Acc;
-fixextensions(Pos,ExtPos,Val,Acc) ->
- Bit = case catch(element(Pos+1,Val)) of
- asn1_NOVALUE ->
- 0;
- asn1_NOEXTVALUE ->
- 0;
- {'EXIT',_} ->
- 0;
- _ ->
- 1
- end,
- fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
-
-skipextensions(Bytes,Nr,ExtensionBitstr) when is_bitstring(ExtensionBitstr) ->
- Prev = Nr - 1,
- case ExtensionBitstr of
- <<_:Prev,1:1,_/bitstring>> ->
- {_,Bytes2} = decode_open_type(Bytes,[]),
- skipextensions(Bytes2, Nr+1, ExtensionBitstr);
- <<_:Prev,0:1,_/bitstring>> ->
- skipextensions(Bytes, Nr+1, ExtensionBitstr);
- _ ->
- Bytes
- end.
-
-
-getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
- {0,Bytes};
-getchoice(Bytes,_,1) ->
- decode_small_number(Bytes);
-getchoice(Bytes,NumChoices,0) ->
- decode_constrained_number(Bytes,{0,NumChoices-1}).
-
-
-%% getbits_as_binary(Num,Bytes) -> {Bin,Rest}
-%% Num = integer(),
-%% Bytes = bitstring(),
-%% Bin = bitstring(),
-%% Rest = bitstring()
-getbits_as_binary(Num,Bytes) when is_bitstring(Bytes) ->
- <<BS:Num/bitstring,Rest/bitstring>> = Bytes,
- {BS,Rest}.
-
-getbits_as_list(Num,Bytes) when is_bitstring(Bytes) ->
- <<BitStr:Num/bitstring,Rest/bitstring>> = Bytes,
- {[ B || <<B:1>> <= BitStr],Rest}.
-
-
-getbit(Buffer) ->
- <<B:1,Rest/bitstring>> = Buffer,
- {B,Rest}.
-
-
-getbits(Buffer,Num) when is_bitstring(Buffer) ->
- <<Bs:Num,Rest/bitstring>> = Buffer,
- {Bs,Rest}.
-
-align(Bin) when is_binary(Bin) ->
- Bin;
-align(BitStr) when is_bitstring(BitStr) ->
- AlignBits = bit_size(BitStr) rem 8,
- <<_:AlignBits,Rest/binary>> = BitStr,
- Rest.
-
-
-%% First align buffer, then pick the first Num octets.
-%% Returns octets as an integer with bit significance as in buffer.
-getoctets(Buffer,Num) when is_binary(Buffer) ->
- <<Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
- {Val,RestBin};
-getoctets(Buffer,Num) when is_bitstring(Buffer) ->
- AlignBits = bit_size(Buffer) rem 8,
- <<_:AlignBits,Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
- {Val,RestBin}.
-
-
-%% First align buffer, then pick the first Num octets.
-%% Returns octets as a binary
-getoctets_as_bin(Bin,Num) when is_binary(Bin) ->
- <<Octets:Num/binary,RestBin/binary>> = Bin,
- {Octets,RestBin};
-getoctets_as_bin(Bin,Num) when is_bitstring(Bin) ->
- AlignBits = bit_size(Bin) rem 8,
- <<_:AlignBits,Val:Num/binary,RestBin/binary>> = Bin,
- {Val,RestBin}.
-
-
-%% same as above but returns octets as a List
-getoctets_as_list(Buffer,Num) ->
- {Bin,Buffer2} = getoctets_as_bin(Buffer,Num),
- {binary_to_list(Bin),Buffer2}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
-%% Alt = atom()
-%% Altnum = integer() | {integer(),integer()}% number of alternatives
-%% Choices = [atom()] | {[atom()],[atom()]}
-%% When Choices is a tuple the first list is the Rootset and the
-%% second is the Extensions and then Altnum must also be a tuple with the
-%% lengths of the 2 lists
-%%
-set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
- case set_choice_tag(Alt,L1) of
- N when is_integer(N), Len1 > 1 ->
-% [{bits,1,0}, % the value is in the root set
-% encode_constrained_number({0,Len1-1},N)];
- [0, % the value is in the root set
- encode_constrained_number({0,Len1-1},N)];
- N when is_integer(N) ->
-% [{bits,1,0}]; % no encoding if only 0 or 1 alternative
- [0]; % no encoding if only 0 or 1 alternative
- false ->
-% [{bits,1,1}, % extension value
- [1, % extension value
- case set_choice_tag(Alt,L2) of
- N2 when is_integer(N2) ->
- encode_small_number(N2);
- false ->
- unknown_choice_alt
- end]
- end;
-set_choice(Alt,L,Len) ->
- case set_choice_tag(Alt,L) of
- N when is_integer(N), Len > 1 ->
- encode_constrained_number({0,Len-1},N);
- N when is_integer(N) ->
- []; % no encoding if only 0 or 1 alternative
- false ->
- [unknown_choice_alt]
- end.
-
-set_choice_tag(Alt,Choices) ->
- set_choice_tag(Alt,Choices,0).
-
-set_choice_tag(Alt,[Alt|_Rest],Tag) ->
- Tag;
-set_choice_tag(Alt,[_H|Rest],Tag) ->
- set_choice_tag(Alt,Rest,Tag+1);
-set_choice_tag(_Alt,[],_Tag) ->
- false.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_fragmented_XXX; decode of values encoded fragmented according
-%% to ITU-T X.691 clause 10.9.3.8. The unit (XXX) is either bits, octets,
-%% characters or number of components (in a choice,sequence or similar).
-%% Buffer is a buffer binary().
-%% C is the constrained length.
-%% If the buffer is not aligned, this function does that.
-decode_fragmented_bits(Buffer,C) when is_binary(Buffer) ->
- decode_fragmented_bits(Buffer,C,[]);
-decode_fragmented_bits(Buffer,C) when is_bitstring(Buffer) ->
- AlignBits = bit_size(Buffer) rem 8,
- <<_:AlignBits,Rest/binary>> = Buffer,
- decode_fragmented_bits(Rest,C,[]).
-
-decode_fragmented_bits(<<3:2,Len:6,Bin/binary>>,C,Acc) ->
- {Value,Bin2} = split_binary(Bin, Len * ?'16K'), % Len = 1 | 2 | 3 | 4
- decode_fragmented_bits(Bin2,C,[Value|Acc]);
-decode_fragmented_bits(<<0:1,0:7,Bin/binary>>,C,Acc) ->
- BinBits = erlang:list_to_bitstring(lists:reverse(Acc)),
- case C of
- Int when is_integer(Int),C == bit_size(BinBits) ->
- {BinBits,Bin};
- Int when is_integer(Int) ->
- exit({error,{asn1,{illegal_value,C,BinBits}}})
- end;
-decode_fragmented_bits(<<0:1,Len:7,Bin/binary>>,C,Acc) ->
- <<Value:Len/bitstring,Rest/bitstring>> = Bin,
- BinBits = erlang:list_to_bitstring([Value|Acc]),
- case C of
- Int when is_integer(Int),C == bit_size(BinBits) ->
- {BinBits,Rest};
- Int when is_integer(Int) ->
- exit({error,{asn1,{illegal_value,C,BinBits}}})
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_open_type(Constraint, Value) -> CompleteList
-%% Value = list of bytes of an already encoded value (the list must be flat)
-%% | binary
-%% Contraint = not used in this version
-%%
-encode_open_type(_Constraint, Val) when is_list(Val) ->
- Bin = list_to_binary(Val),
- case size(Bin) of
- Size when Size>255 ->
- [encode_length(undefined,Size),[21,<<Size:16>>,Bin]];
- Size ->
- [encode_length(undefined,Size),[20,Size,Bin]]
- end;
-encode_open_type(_Constraint, Val) when is_binary(Val) ->
- case size(Val) of
- Size when Size>255 ->
- [encode_length(undefined,size(Val)),[21,<<Size:16>>,Val]]; % octets implies align
- Size ->
- [encode_length(undefined,Size),[20,Size,Val]]
- end.
-%% the binary_to_list is not optimal but compatible with the current solution
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_open_type(Buffer,Constraint) -> Value
-%% Constraint is not used in this version
-%% Buffer = [byte] with PER encoded data
-%% Value = [byte] with decoded data (which must be decoded again as some type)
-%%
-decode_open_type(Bytes, _Constraint) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- getoctets_as_bin(Bytes2,Len).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
-%% encode_integer(Constraint,Value) -> CompleteList
-%% encode_integer(Constraint,{Name,Value}) -> CompleteList
-%%
-%%
-encode_integer(C,V,NamedNumberList) when is_atom(V) ->
- case lists:keysearch(V,1,NamedNumberList) of
- {value,{_,NewV}} ->
- encode_integer(C,NewV);
- _ ->
- exit({error,{asn1,{namednumber,V}}})
- end;
-encode_integer(C,V,_NamedNumberList) when is_integer(V) ->
- encode_integer(C,V);
-encode_integer(C,{Name,V},NamedNumberList) when is_atom(Name) ->
- encode_integer(C,V,NamedNumberList).
-
-encode_integer(C,{Name,Val}) when is_atom(Name) ->
- encode_integer(C,Val);
-
-encode_integer([{Rc,_Ec}],Val) when is_tuple(Rc) -> % XXX when is this invoked? First argument most often a list,...Ok this is the extension case...but it doesn't work.
- case (catch encode_integer([Rc],Val)) of
- {'EXIT',{error,{asn1,_}}} ->
-% [{bits,1,1},encode_unconstrained_number(Val)];
- [1,encode_unconstrained_number(Val)];
- Encoded ->
-% [{bits,1,0},Encoded]
- [0,Encoded]
- end;
-
-encode_integer([],Val) ->
- encode_unconstrained_number(Val);
-%% The constraint is the effective constraint, and in this case is a number
-encode_integer([{'SingleValue',V}],V) ->
- [];
-encode_integer([{'ValueRange',VR={Lb,Ub},Range,PreEnc}],Val) when Val >= Lb,
- Ub >= Val ->
- %% this case when NamedNumberList
- encode_constrained_number(VR,Range,PreEnc,Val);
-encode_integer([{'ValueRange',{Lb,'MAX'}}],Val) ->
- encode_semi_constrained_number(Lb,Val);
-encode_integer([{'ValueRange',{'MIN',_}}],Val) ->
- encode_unconstrained_number(Val);
-encode_integer([{'ValueRange',VR={_Lb,_Ub}}],Val) ->
- encode_constrained_number(VR,Val);
-encode_integer(_,Val) ->
- exit({error,{asn1,{illegal_value,Val}}}).
-
-
-%% X.691:10.6 Encoding of a normally small non-negative whole number
-%% Use this for encoding of CHOICE index if there is an extension marker in
-%% the CHOICE
-encode_small_number({Name,Val}) when is_atom(Name) ->
- encode_small_number(Val);
-encode_small_number(Val) when Val =< 63 ->
-% [{bits,1,0},{bits,6,Val}];
-% [{bits,7,Val}]; % same as above but more efficient
- [10,7,Val]; % same as above but more efficient
-encode_small_number(Val) ->
-% [{bits,1,1},encode_semi_constrained_number(0,Val)].
- [1,encode_semi_constrained_number(0,Val)].
-
-decode_small_number(Bytes) ->
- {Bit,Bytes2} = getbit(Bytes),
- case Bit of
- 0 ->
- getbits(Bytes2,6);
- 1 ->
- decode_semi_constrained_number(Bytes2)
- end.
-
-%% X.691:10.7 Encoding of a semi-constrained whole number
-%% might be an optimization encode_semi_constrained_number(0,Val) ->
-encode_semi_constrained_number(C,{Name,Val}) when is_atom(Name) ->
- encode_semi_constrained_number(C,Val);
-encode_semi_constrained_number({Lb,'MAX'},Val) ->
- encode_semi_constrained_number(Lb,Val);
-encode_semi_constrained_number(Lb,Val) ->
- Val2 = Val - Lb,
- Oct = eint_positive(Val2),
- Len = length(Oct),
- if
- Len < 128 ->
- %{octets,[Len|Oct]}; % equiv with encode_length(undefined,Len) but faster
- [20,Len+1,[Len|Oct]];
- Len < 256 ->
- [encode_length(undefined,Len),[20,Len,Oct]];
- true ->
- [encode_length(undefined,Len),[21,<<Len:16>>,Oct]]
- end.
-
-decode_semi_constrained_number(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {V,Bytes3} = getoctets(Bytes2,Len),
- {V,Bytes3}.
-
-encode_constrained_number({Lb,_Ub},_Range,{bits,N},Val) ->
- Val2 = Val-Lb,
-% {bits,N,Val2};
- [10,N,Val2];
-encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) when N < 256->
- %% N is 8 or 16 (1 or 2 octets)
- Val2 = Val-Lb,
-% {octets,<<Val2:N/unit:8>>};
- [20,N,Val2];
-encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) -> % N>255
- %% N is 8 or 16 (1 or 2 octets)
- Val2 = Val-Lb,
-% {octets,<<Val2:N/unit:8>>};
- [21,<<N:16>>,Val2];
-encode_constrained_number({Lb,_Ub},Range,_,Val) ->
- Val2 = Val-Lb,
- if
- Range =< 16#1000000 -> % max 3 octets
- Octs = eint_positive(Val2),
-% [encode_length({1,3},size(Octs)),{octets,Octs}];
- L = length(Octs),
- [encode_length({1,3},L),[20,L,Octs]];
- Range =< 16#100000000 -> % max 4 octets
- Octs = eint_positive(Val2),
-% [encode_length({1,4},size(Octs)),{octets,Octs}];
- L = length(Octs),
- [encode_length({1,4},L),[20,L,Octs]];
- Range =< 16#10000000000 -> % max 5 octets
- Octs = eint_positive(Val2),
-% [encode_length({1,5},size(Octs)),{octets,Octs}];
- L = length(Octs),
- [encode_length({1,5},L),[20,L,Octs]];
- true ->
- exit({not_supported,{integer_range,Range}})
- end.
-
-encode_constrained_number(Range,{Name,Val}) when is_atom(Name) ->
- encode_constrained_number(Range,Val);
-encode_constrained_number({Lb,Ub},Val) when Val >= Lb, Ub >= Val ->
- Range = Ub - Lb + 1,
- Val2 = Val - Lb,
- if
- Range == 1 -> [];
- Range == 2 ->
-% Size = {bits,1,Val2};
- [Val2];
- Range =< 4 ->
-% Size = {bits,2,Val2};
- [10,2,Val2];
- Range =< 8 ->
- [10,3,Val2];
- Range =< 16 ->
- [10,4,Val2];
- Range =< 32 ->
- [10,5,Val2];
- Range =< 64 ->
- [10,6,Val2];
- Range =< 128 ->
- [10,7,Val2];
- Range =< 255 ->
- [10,8,Val2];
- Range =< 256 ->
-% Size = {octets,[Val2]};
- [20,1,Val2];
- Range =< 65536 ->
-% Size = {octets,<<Val2:16>>};
- [20,2,<<Val2:16>>];
- Range =< (1 bsl (255*8)) ->
- Octs = binary:encode_unsigned(Val2),
- RangeOcts = binary:encode_unsigned(Range - 1),
- OctsLen = erlang:byte_size(Octs),
- RangeOctsLen = erlang:byte_size(RangeOcts),
- LengthBitsNeeded = minimum_bits(RangeOctsLen - 1),
- [10,LengthBitsNeeded,OctsLen-1,20,OctsLen,Octs];
- true ->
- exit({not_supported,{integer_range,Range}})
- end;
-encode_constrained_number({_,_},Val) ->
- exit({error,{asn1,{illegal_value,Val}}}).
-
-decode_constrained_number(Buffer,VR={Lb,Ub}) ->
- Range = Ub - Lb + 1,
- decode_constrained_number(Buffer,VR,Range).
-
-decode_constrained_number(Buffer,{Lb,_Ub},Range) ->
- % Val2 = Val - Lb,
- {Val,Remain} =
- if
- Range == 1 ->
- {0,Buffer};
- Range == 2 ->
- getbits(Buffer,1);
- Range =< 4 ->
- getbits(Buffer,2);
- Range =< 8 ->
- getbits(Buffer,3);
- Range =< 16 ->
- getbits(Buffer,4);
- Range =< 32 ->
- getbits(Buffer,5);
- Range =< 64 ->
- getbits(Buffer,6);
- Range =< 128 ->
- getbits(Buffer,7);
- Range =< 255 ->
- getbits(Buffer,8);
- Range =< 256 ->
- getoctets(Buffer,1);
- Range =< 65536 ->
- getoctets(Buffer,2);
- Range =< (1 bsl (255*8)) ->
- OList = binary:bin_to_list(binary:encode_unsigned(Range - 1)),
- RangeOctLen = length(OList),
- {Len, Bytes} = decode_length(Buffer, {1, RangeOctLen}),
- {Octs, RestBytes} = getoctets_as_bin(Bytes, Len),
- {binary:decode_unsigned(Octs), RestBytes};
- true ->
- exit({not_supported,{integer_range,Range}})
- end,
- {Val+Lb,Remain}.
-
-%% For some reason the minimum bits needed in the length field in
-%% the encoding of constrained whole numbers must always be at least 2?
-minimum_bits(N) when N < 4 -> 2;
-minimum_bits(N) when N < 8 -> 3;
-minimum_bits(N) when N < 16 -> 4;
-minimum_bits(N) when N < 32 -> 5;
-minimum_bits(N) when N < 64 -> 6;
-minimum_bits(N) when N < 128 -> 7;
-minimum_bits(_N) -> 8.
-
-%% X.691:10.8 Encoding of an unconstrained whole number
-
-encode_unconstrained_number(Val) when Val >= 0 ->
- Oct = eint(Val,[]),
- Len = length(Oct),
- if
- Len < 128 ->
- %{octets,[Len|Oct]}; % equiv with encode_length(undefined,Len) but faster
- [20,Len+1,[Len|Oct]];
- Len < 256 ->
-% [encode_length(undefined,Len),20,Len,Oct];
- [20,Len+2,<<2:2,Len:14>>,Oct];% equiv with encode_length(undefined,Len) but faster
- true ->
-% [encode_length(undefined,Len),{octets,Oct}]
- [encode_length(undefined,Len),[21,<<Len:16>>,Oct]]
- end;
-encode_unconstrained_number(Val) -> % negative
- Oct = enint(Val,[]),
- Len = length(Oct),
- if
- Len < 128 ->
-% {octets,[Len|Oct]}; % equiv with encode_length(undefined,Len) but faster
- [20,Len+1,[Len|Oct]];% equiv with encode_length(undefined,Len) but faster
- Len < 256 ->
-% [encode_length(undefined,Len),20,Len,Oct];
- [20,Len+2,<<2:2,Len:14>>,Oct];% equiv with encode_length(undefined,Len) but faster
- true ->
- %[encode_length(undefined,Len),{octets,Oct}]
- [encode_length(undefined,Len),[21,<<Len:16>>,Oct]]
- end.
-
-
-%% used for positive Values which don't need a sign bit
-%% returns a list
-eint_positive(Val) ->
- case eint(Val,[]) of
- [0,B1|T] ->
- [B1|T];
- T ->
- T
- end.
-
-
-eint(0, [B|Acc]) when B < 128 ->
- [B|Acc];
-eint(N, Acc) ->
- eint(N bsr 8, [N band 16#ff| Acc]).
-
-enint(-1, [B1|T]) when B1 > 127 ->
- [B1|T];
-enint(N, Acc) ->
- enint(N bsr 8, [N band 16#ff|Acc]).
-
-%% X.691:10.9 Encoding of a length determinant
-%%encode_small_length(undefined,Len) -> % null means no UpperBound
-%% encode_small_number(Len).
-
-%% X.691:10.9.3.5
-%% X.691:10.9.3.7
-encode_length(undefined,Len) -> % un-constrained
- if
- Len < 128 ->
-% {octets,[Len]};
- [20,1,Len];
- Len < 16384 ->
- %{octets,<<2:2,Len:14>>};
- [20,2,<<2:2,Len:14>>];
- true -> % should be able to endode length >= 16384 i.e. fragmented length
- exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
- end;
-
-encode_length({0,'MAX'},Len) ->
- encode_length(undefined,Len);
-encode_length(Vr={Lb,Ub},Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
- encode_constrained_number(Vr,Len);
-encode_length({Lb,_Ub},Len) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
- encode_length(undefined,Len);
-encode_length({Vr={Lb,Ub},Ext},Len)
- when Ub =< 65535 ,Lb >= 0,Len=<Ub, is_list(Ext) ->
- %% constrained extensible
- [0,encode_constrained_number(Vr,Len)];
-encode_length({{Lb,_},Ext},Len) when is_list(Ext) ->
- [1,encode_semi_constrained_number(Lb,Len)];
-encode_length(SingleValue,_Len) when is_integer(SingleValue) ->
- [].
-
-%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension
-%% additions in a sequence or set
-encode_small_length(Len) when Len =< 64 ->
-%% [{bits,1,0},{bits,6,Len-1}];
-% {bits,7,Len-1}; % the same as above but more efficient
- [10,7,Len-1];
-encode_small_length(Len) ->
-% [{bits,1,1},encode_length(undefined,Len)].
- [1,encode_length(undefined,Len)].
-
-
-decode_length(Buffer,undefined) -> % un-constrained
- case align(Buffer) of
- <<0:1,Oct:7,Rest/binary>> ->
- {Oct,Rest};
- <<2:2,Val:14,Rest/binary>> ->
- {Val,Rest};
- <<3:2,_Val:14,_Rest/binary>> ->
- %% this case should be fixed
- exit({error,{asn1,{decode_length,{nyi,above_16k}}}})
- end;
-
-decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
- decode_constrained_number(Buffer,{Lb,Ub});
-decode_length(Buffer,{Lb,_Ub}) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
- decode_length(Buffer,undefined);
-decode_length(Buffer,{{Lb,Ub},Ext}) when is_list(Ext) ->
- case getbit(Buffer) of
- {0,Buffer2} ->
- decode_length(Buffer2, {Lb,Ub});
- {1,Buffer2} ->
- decode_length(Buffer2, undefined)
- end;
-
-
-%When does this case occur with {_,_Lb,Ub} ??
-% X.691:10.9.3.5
-decode_length(Bin,{_,_Lb,_Ub}) -> % Unconstrained or large Ub NOTE! this case does not cover case when Ub > 65535
- case Bin of
- <<0:1,Val:7,Rest/bitstring>> ->
- {Val,Rest};
- _ ->
- case align(Bin) of
- <<2:2,Val:14,Rest/binary>> ->
- {Val,Rest};
- <<3:2,_:14,_Rest/binary>> ->
- exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
- end
- end;
-decode_length(Buffer,SingleValue) when is_integer(SingleValue) ->
- {SingleValue,Buffer}.
-
-
-
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-%% Bitstring value, ITU_T X.690 Chapter 8.5
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-
-%%===============================================================================
-%% encode bitstring value
-%%===============================================================================
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% bitstring NamedBitList
-%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
-%% the Constraint must then have some information of the
-%% bitlength.
-%% - [list of ones and zeroes] all bits
-%% - integer value representing the bitlist
-%% C is constraint Len, only valid when identifiers
-
-
-%% when the value is a list of {Unused,BinBits}, where
-%% Unused = integer(),
-%% BinBits = binary().
-
-encode_bit_string(C,Bin={Unused,BinBits},NamedBitList) when is_integer(Unused),
- is_binary(BinBits) ->
- encode_bin_bit_string(C,Bin,NamedBitList);
-
-%% when the value is a list of named bits
-
-encode_bit_string(C, LoNB=[FirstVal | _RestVal], NamedBitList) when is_atom(FirstVal) ->
- ToSetPos = get_all_bitposes(LoNB, NamedBitList, []),
- BitList = make_and_set_list(ToSetPos,0),
- encode_bit_string(C,BitList,NamedBitList);% consider the constraint
-
-encode_bit_string(C, BL=[{bit,_} | _RestVal], NamedBitList) ->
- ToSetPos = get_all_bitposes(BL, NamedBitList, []),
- BitList = make_and_set_list(ToSetPos,0),
- encode_bit_string(C,BitList,NamedBitList);
-
-%% when the value is a list of ones and zeroes
-encode_bit_string(Int, BitListValue, _)
- when is_list(BitListValue),is_integer(Int),Int =< 16 ->
- %% The type is constrained by a single value size constraint
- %% range_check(Int,length(BitListValue)),
- [40,Int,length(BitListValue),BitListValue];
-encode_bit_string(Int, BitListValue, _)
- when is_list(BitListValue),is_integer(Int), Int =< 255 ->
- %% The type is constrained by a single value size constraint
- %% range_check(Int,length(BitListValue)),
- [2,40,Int,length(BitListValue),BitListValue];
-encode_bit_string(Int, BitListValue, _)
- when is_list(BitListValue),is_integer(Int), Int < ?'64K' ->
- {Code,DesiredLength,Length} =
- case length(BitListValue) of
- B1 when B1 > Int ->
- exit({error,{'BIT_STRING_length_greater_than_SIZE',
- Int,BitListValue}});
- B1 when B1 =< 255,Int =< 255 ->
- {40,Int,B1};
- B1 when B1 =< 255 ->
- {42,<<Int:16>>,B1};
- B1 ->
- {43,<<Int:16>>,<<B1:16>>}
- end,
- %% The type is constrained by a single value size constraint
- [2,Code,DesiredLength,Length,BitListValue];
-encode_bit_string(no, BitListValue,[])
- when is_list(BitListValue) ->
- [encode_length(undefined,length(BitListValue)),
- 2,BitListValue];
-encode_bit_string({{Fix,Fix},Ext}, BitListValue,[])
- when is_integer(Fix), is_list(Ext) ->
- case length(BitListValue) of
- Len when Len =< Fix ->
- [0,encode_bit_string(Fix,BitListValue,[])];
- _ ->
- [1,encode_bit_string(no,BitListValue,[])]
- end;
-encode_bit_string(C, BitListValue,[])
- when is_list(BitListValue) ->
- [encode_length(C,length(BitListValue)),
- 2,BitListValue];
-encode_bit_string(no, BitListValue,_NamedBitList)
- when is_list(BitListValue) ->
- %% this case with an unconstrained BIT STRING can be made more efficient
- %% if the complete driver can take a special code so the length field
- %% is encoded there.
- NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
- lists:reverse(BitListValue))),
- [encode_length(undefined,length(NewBitLVal)),
- 2,NewBitLVal];
-encode_bit_string({{Fix,Fix},Ext}, BitListValue,_NamedBitList)
- when is_integer(Fix), is_list(Ext) ->
- case length(BitListValue) of
- Len when Len =< Fix ->
- [0,encode_bit_string(Fix,BitListValue,_NamedBitList)];
- _ ->
- [1,encode_bit_string(no,BitListValue,_NamedBitList)]
- end;
-encode_bit_string(C,BitListValue,_NamedBitList)
- when is_list(BitListValue) ->% C = {_,'MAX'}
-% NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
-% lists:reverse(BitListValue))),
- NewBitLVal = bit_string_trailing_zeros(BitListValue,C),
- [encode_length(C,length(NewBitLVal)),
- 2,NewBitLVal];
-
-
-%% when the value is an integer
-encode_bit_string(C, IntegerVal, NamedBitList) when is_integer(IntegerVal)->
- BitList = int_to_bitlist(IntegerVal),
- encode_bit_string(C,BitList,NamedBitList);
-
-%% when the value is a tuple
-encode_bit_string(C,{Name,Val}, NamedBitList) when is_atom(Name) ->
- encode_bit_string(C,Val,NamedBitList).
-
-bit_string_trailing_zeros(BitList,C) when is_integer(C) ->
- bit_string_trailing_zeros1(BitList,C,C);
-bit_string_trailing_zeros(BitList,{Lb,Ub}) when is_integer(Lb) ->
- bit_string_trailing_zeros1(BitList,Lb,Ub);
-bit_string_trailing_zeros(BitList,{{Lb,Ub},_}) when is_integer(Lb) ->
- bit_string_trailing_zeros1(BitList,Lb,Ub);
-bit_string_trailing_zeros(BitList,_) ->
- BitList.
-
-bit_string_trailing_zeros1(BitList,Lb,Ub) ->
- case length(BitList) of
- Lb -> BitList;
- B when B<Lb -> BitList++lists:duplicate(Lb-B,0);
- D -> F = fun(L,LB,LB,_,_)->lists:reverse(L);
- ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun);
- (L,L1,_,UB,_)when L1 =< UB -> lists:reverse(L);
- (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING,
- BitList}}) end,
- F(lists:reverse(BitList),D,Lb,Ub,F)
- end.
-
-%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
-%% Unused = integer(),i.e. number unused bits in least sign. byte of
-%% BinBits = binary().
-encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList)
- when is_integer(C),C=<16 ->
- range_check(C,bit_size(BinBits) - Unused),
- [45,C,size(BinBits),BinBits];
-encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList)
- when is_integer(C), C =< 255 ->
- range_check(C,bit_size(BinBits) - Unused),
- [2,45,C,size(BinBits),BinBits];
-encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList)
- when is_integer(C), C =< 65535 ->
- range_check(C,bit_size(BinBits) - Unused),
- case size(BinBits) of
- Size when Size =< 255 ->
- [2,46,<<C:16>>,Size,BinBits];
- Size ->
- [2,47,<<C:16>>,<<Size:16>>,BinBits]
- end;
-%% encode_bin_bit_string(C,{_Unused,BinBits},_NamedBitList)
-%% when is_integer(C) ->
-%% exit({error,{asn1, {bitstring_size, not_supported, C}}});
-encode_bin_bit_string(C,UnusedAndBin={_,_},NamedBitList) ->
-% UnusedAndBin1 = {Unused1,Bin1} =
- {Unused1,Bin1} =
- %% removes all trailing bits if NamedBitList is not empty
- remove_trailing_bin(NamedBitList,UnusedAndBin),
- case C of
- {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
-% [encode_length({Lb,Ub},size(Bin1)*8 - Unused1),
-% align,UnusedAndBin1];
- Size=size(Bin1),
- [encode_length({Lb,Ub},Size*8 - Unused1),
- 2,octets_unused_to_complete(Unused1,Size,Bin1)];
- no ->
- Size=size(Bin1),
- [encode_length(undefined,Size*8 - Unused1),
- 2,octets_unused_to_complete(Unused1,Size,Bin1)];
- {{Fix,Fix},Ext} when is_integer(Fix),is_list(Ext) ->
- %%[encode_length(Sc,size(Bin1)*8 - Unused1),
- case size(Bin1)*8 - Unused1 of
- Size when Size =< Fix ->
- [0,encode_bin_bit_string(Fix,UnusedAndBin,NamedBitList)];
- _Size ->
- [1,encode_bin_bit_string(no,UnusedAndBin,NamedBitList)]
- end;
- Sc ->
- Size=size(Bin1),
- [encode_length(Sc,Size*8 - Unused1),
- 2,octets_unused_to_complete(Unused1,Size,Bin1)]
- end.
-
-range_check(C,C) when is_integer(C) ->
- ok;
-range_check(C1,C2) when is_integer(C1) ->
- exit({error,{asn1,{bit_string_out_of_range,{C1,C2}}}}).
-
-remove_trailing_bin([], {Unused,Bin}) ->
- {Unused,Bin};
-remove_trailing_bin(_NamedNumberList,{_Unused,<<>>}) ->
- {0,<<>>};
-remove_trailing_bin(NamedNumberList, {_Unused,Bin}) ->
- Size = size(Bin)-1,
- <<Bfront:Size/binary, LastByte:8>> = Bin,
- %% clear the Unused bits to be sure
-% LastByte1 = LastByte band (((1 bsl Unused) -1) bxor 255),% why this???
- Unused1 = trailingZeroesInNibble(LastByte band 15),
- Unused2 =
- case Unused1 of
- 4 ->
- 4 + trailingZeroesInNibble(LastByte bsr 4);
- _ -> Unused1
- end,
- case Unused2 of
- 8 ->
- remove_trailing_bin(NamedNumberList,{0,Bfront});
- _ ->
- {Unused2,Bin}
- end.
-
-
-trailingZeroesInNibble(0) ->
- 4;
-trailingZeroesInNibble(1) ->
- 0;
-trailingZeroesInNibble(2) ->
- 1;
-trailingZeroesInNibble(3) ->
- 0;
-trailingZeroesInNibble(4) ->
- 2;
-trailingZeroesInNibble(5) ->
- 0;
-trailingZeroesInNibble(6) ->
- 1;
-trailingZeroesInNibble(7) ->
- 0;
-trailingZeroesInNibble(8) ->
- 3;
-trailingZeroesInNibble(9) ->
- 0;
-trailingZeroesInNibble(10) ->
- 1;
-trailingZeroesInNibble(11) ->
- 0;
-trailingZeroesInNibble(12) -> %#1100
- 2;
-trailingZeroesInNibble(13) ->
- 0;
-trailingZeroesInNibble(14) ->
- 1;
-trailingZeroesInNibble(15) ->
- 0.
-
-%%%%%%%%%%%%%%%
-%% The result is presented as a list of named bits (if possible)
-%% else as a tuple {Unused,Bits}. Unused is the number of unused
-%% bits, least significant bits in the last byte of Bits. Bits is
-%% the BIT STRING represented as a binary.
-%%
-decode_compact_bit_string(Buffer, C, NamedNumberList) ->
- case get_constraint(C,'SizeConstraint') of
- 0 -> % fixed length
- {{8,0},Buffer};
- V when is_integer(V),V=<16 -> %fixed length 16 bits or less
- compact_bit_string(Buffer,V,NamedNumberList);
- V when is_integer(V),V=<65536 -> %fixed length > 16 bits
- Bytes2 = align(Buffer),
- compact_bit_string(Bytes2,V,NamedNumberList);
- V when is_integer(V) -> % V > 65536 => fragmented value
- {BitStr,Buffer2} = decode_fragmented_bits(Buffer,V),
- case bit_size(BitStr) band 7 of
- 0 -> {{0,BitStr},Buffer2};
- N -> {{8-N,<<BitStr/bitstring,0:(8-N)>>},Buffer2}
- end;
- {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
- %% This case may demand decoding of fragmented length/value
- {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList);
- no ->
- %% This case may demand decoding of fragmented length/value
- {Len,Bytes2} = decode_length(Buffer,undefined),
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList);
- {{Fix,Fix},Ext} = Sc when is_integer(Fix), is_list(Ext) ->
- case decode_length(Buffer,Sc) of
- {Len,Bytes2} when Len > Fix ->
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList);
- {Len,Bytes2} when Len > 16 ->
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList);
- {Len,Bytes2} ->
- compact_bit_string(Bytes2,Len,NamedNumberList)
- end;
- Sc ->
- {Len,Bytes2} = decode_length(Buffer,Sc),
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList)
- end.
-
-
-%%%%%%%%%%%%%%%
-%% The result is presented as a list of named bits (if possible)
-%% else as a list of 0 and 1.
-%%
-decode_bit_string(Buffer, C, NamedNumberList) ->
- case get_constraint(C,'SizeConstraint') of
- {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
- {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
- Bytes3 = align(Bytes2),
- bit_list_or_named(Bytes3,Len,NamedNumberList);
- no ->
- {Len,Bytes2} = decode_length(Buffer,undefined),
- Bytes3 = align(Bytes2),
- bit_list_or_named(Bytes3,Len,NamedNumberList);
- 0 -> % fixed length
- {[],Buffer}; % nothing to encode
- V when is_integer(V),V=<16 -> % fixed length 16 bits or less
- bit_list_or_named(Buffer,V,NamedNumberList);
- V when is_integer(V),V=<65536 ->
- Bytes2 = align(Buffer),
- bit_list_or_named(Bytes2,V,NamedNumberList);
- V when is_integer(V) ->
- Bytes2 = align(Buffer),
- {BinBits,_Bytes3} = decode_fragmented_bits(Bytes2,V),
- bit_list_or_named(BinBits,V,NamedNumberList);
- {{Fix,Fix},Ext} =Sc when is_integer(Fix), is_list(Ext) ->
- case decode_length(Buffer,Sc) of
- {Len,Bytes2} when Len > Fix ->
- Bytes3 = align(Bytes2),
- bit_list_or_named(Bytes3,Len,NamedNumberList);
- {Len,Bytes2} when Len > 16 ->
- Bytes3 = align(Bytes2),
- bit_list_or_named(Bytes3,Len,NamedNumberList);
- {Len,Bytes2} ->
- bit_list_or_named(Bytes2,Len,NamedNumberList)
- end;
- Sc -> % extension marker
- {Len,Bytes2} = decode_length(Buffer,Sc),
- Bytes3 = align(Bytes2),
- bit_list_or_named(Bytes3,Len,NamedNumberList)
- end.
-
-
-%% if no named bits are declared we will return a
-%% {Unused,Bits}. Unused = integer(),
-%% Bits = binary().
-compact_bit_string(Buffer,Len,[]) ->
- {BitStr,Rest} = getbits_as_binary(Len,Buffer), % {{Unused,BinBits},NewBuffer}
- PadLen = (8 - (bit_size(BitStr) rem 8)) rem 8,
- {{PadLen,<<BitStr/bitstring,0:PadLen>>},Rest};
-compact_bit_string(Buffer,Len,NamedNumberList) ->
- bit_list_or_named(Buffer,Len,NamedNumberList).
-
-
-%% if no named bits are declared we will return a
-%% BitList = [0 | 1]
-
-bit_list_or_named(Buffer,Len,[]) ->
- getbits_as_list(Len,Buffer);
-
-%% if there are named bits declared we will return a named
-%% BitList where the names are atoms and unnamed bits represented
-%% as {bit,Pos}
-%% BitList = [atom() | {bit,Pos}]
-%% Pos = integer()
-
-bit_list_or_named(Buffer,Len,NamedNumberList) ->
- {BitList,Rest} = getbits_as_list(Len,Buffer),
- {bit_list_or_named1(0,BitList,NamedNumberList,[]), Rest}.
-
-bit_list_or_named1(Pos,[0|Bt],Names,Acc) ->
- bit_list_or_named1(Pos+1,Bt,Names,Acc);
-bit_list_or_named1(Pos,[1|Bt],Names,Acc) ->
- case lists:keysearch(Pos,2,Names) of
- {value,{Name,_}} ->
- bit_list_or_named1(Pos+1,Bt,Names,[Name|Acc]);
- _ ->
- bit_list_or_named1(Pos+1,Bt,Names,[{bit,Pos}|Acc])
- end;
-bit_list_or_named1(_Pos,[],_Names,Acc) ->
- lists:reverse(Acc).
-
-
-
-%%%%%%%%%%%%%%%
-%%
-
-int_to_bitlist(Int) when is_integer(Int), Int > 0 ->
- [Int band 1 | int_to_bitlist(Int bsr 1)];
-int_to_bitlist(0) ->
- [].
-
-
-%%%%%%%%%%%%%%%%%%
-%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
-%% [sorted_list_of_bitpositions_to_set]
-
-get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
-
-get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
- case lists:keysearch(Val, 1, NamedBitList) of
- {value, {_ValName, ValPos}} ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
- _ ->
- exit({error,{asn1, {bitstring_namedbit, Val}}})
- end;
-get_all_bitposes([], _NamedBitList, Ack) ->
- lists:sort(Ack).
-
-%%%%%%%%%%%%%%%%%%
-%% make_and_set_list([list of positions to set to 1])->
-%% returns list with all in SetPos set.
-%% in positioning in list the first element is 0, the second 1 etc.., but
-%%
-
-make_and_set_list([XPos|SetPos], XPos) ->
- [1 | make_and_set_list(SetPos, XPos + 1)];
-make_and_set_list([Pos|SetPos], XPos) ->
- [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
-make_and_set_list([], _) ->
- [].
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% X.691:16
-%% encode_octet_string(Constraint,ExtensionMarker,Val)
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-encode_octet_string(C,Val) ->
- encode_octet_string(C,false,Val).
-
-encode_octet_string(C,Bool,{_Name,Val}) ->
- encode_octet_string(C,Bool,Val);
-encode_octet_string(_C,true,_Val) ->
- exit({error,{asn1,{'not_supported',extensionmarker}}});
-encode_octet_string(SZ={_,_},false,Val) ->
-% [encode_length(SZ,length(Val)),align,
-% {octets,Val}];
- Len = length(Val),
- try
- [encode_length(SZ,Len),2,
- octets_to_complete(Len,Val)]
- catch
- exit:{error,{asn1,{encode_length,_}}} ->
- encode_fragmented_octet_string(Val)
- end;
-encode_octet_string(SZ,false,Val) when is_list(SZ) ->
- Len = length(Val),
- try
- [encode_length({hd(SZ),lists:max(SZ)},Len),2,
- octets_to_complete(Len,Val)]
- catch
- exit:{error,{asn1,{encode_length,_}}} ->
- encode_fragmented_octet_string(Val)
- end;
-encode_octet_string(Sv,false,Val) when is_integer(Sv) ->
- encode_fragmented_octet_string(Val);
-encode_octet_string(no,false,Val) ->
- Len = length(Val),
- try
- [encode_length(undefined,Len),2,
- octets_to_complete(Len,Val)]
- catch
- exit:{error,{asn1,{encode_length,_}}} ->
- encode_fragmented_octet_string(Val)
- end;
-encode_octet_string(C,_,_) ->
- exit({error,{not_implemented,C}}).
-
-encode_fragmented_octet_string(Val) ->
- Bin = iolist_to_binary(Val),
- efos_1(Bin).
-
-efos_1(<<B1:16#C000/binary,B2:16#4000/binary,T/binary>>) ->
- [20,1,<<3:2,4:6>>,
- octets_to_complete(16#C000, B1),
- octets_to_complete(16#4000, B2)|efos_1(T)];
-efos_1(<<B:16#C000/binary,T/binary>>) ->
- [20,1,<<3:2,3:6>>,octets_to_complete(16#C000, B)|efos_1(T)];
-efos_1(<<B:16#8000/binary,T/binary>>) ->
- [20,1,<<3:2,2:6>>,octets_to_complete(16#8000, B)|efos_1(T)];
-efos_1(<<B:16#4000/binary,T/binary>>) ->
- [20,1,<<3:2,1:6>>,octets_to_complete(16#4000, B)|efos_1(T)];
-efos_1(<<>>) ->
- [20,1,0];
-efos_1(<<B/bitstring>>) ->
- Len = byte_size(B),
- [encode_length(undefined, Len),octets_to_complete(Len, B)].
-
-decode_fragmented(SegSz0, Buf0, Unit) ->
- SegSz = SegSz0 * Unit * ?'16K',
- <<Res:SegSz/bitstring,Buf/bitstring>> = Buf0,
- decode_fragmented_1(Buf, Unit, Res).
-
-decode_fragmented_1(<<0:1,N:7,Buf0/bitstring>>, Unit, Res) ->
- Sz = N*Unit,
- <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
- {<<Res/bitstring,S/bitstring>>,Buf};
-decode_fragmented_1(<<1:1,0:1,N:14,Buf0/bitstring>>, Unit, Res) ->
- Sz = N*Unit,
- <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
- {<<Res/bitstring,S/bitstring>>,Buf};
-decode_fragmented_1(<<1:1,1:1,SegSz0:6,Buf0/bitstring>>, Unit, Res0) ->
- SegSz = SegSz0 * Unit * ?'16K',
- <<Frag:SegSz/bitstring,Buf/bitstring>> = Buf0,
- Res = <<Res0/bitstring,Frag/bitstring>>,
- decode_fragmented_1(Buf, Unit, Res).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Restricted char string types
-%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
-%% X.691:26 and X.680:34-36
-%%encode_restricted_string(aligned,'BMPString',Constraints,Extension,Val)
-
-
-encode_restricted_string(aligned,{Name,Val}) when is_atom(Name) ->
- encode_restricted_string(aligned,Val);
-
-encode_restricted_string(aligned,Val) when is_list(Val)->
- Len = length(Val),
- [encode_length(undefined,Len),octets_to_complete(Len,Val)].
-
-
-encode_known_multiplier_string(StringType,SizeC,NumBits,CharOutTab,{Name,Val}) when is_atom(Name) ->
- encode_known_multiplier_string(StringType,SizeC,NumBits,CharOutTab,Val);
-encode_known_multiplier_string(_StringType,SizeC,NumBits,CharOutTab,Val) ->
- Result = chars_encode2(Val,NumBits,CharOutTab),
- case SizeC of
- Ub when is_integer(Ub), Ub*NumBits =< 16 ->
- Result;
- Ub when is_integer(Ub),Ub =<65535 -> % fixed length
- [2,Result];
- {Ub,Lb} ->
- [encode_length({Ub,Lb},length(Val)),2,Result];
- no ->
- [encode_length(undefined,length(Val)),2,Result]
- end.
-
-decode_restricted_string(Bytes,aligned) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- getoctets_as_list(Bytes2,Len).
-
-decode_known_multiplier_string(StringType,SizeC,NumBits,CharInTab,Bytes) ->
- case SizeC of
- Ub when is_integer(Ub), Ub*NumBits =< 16 ->
- chars_decode(Bytes,NumBits,StringType,CharInTab,Ub);
- Ub when is_integer(Ub),Ub =<65535 -> % fixed length
- Bytes1 = align(Bytes),
- chars_decode(Bytes1,NumBits,StringType,CharInTab,Ub);
- Vl when is_list(Vl) ->
- {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}),
- Bytes2 = align(Bytes1),
- chars_decode(Bytes2,NumBits,StringType,CharInTab,Len);
- no ->
- {Len,Bytes1} = decode_length(Bytes,undefined),
- Bytes2 = align(Bytes1),
- chars_decode(Bytes2,NumBits,StringType,CharInTab,Len);
- {Lb,Ub}->
- {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}),
- Bytes2 = align(Bytes1),
- chars_decode(Bytes2,NumBits,StringType,CharInTab,Len)
- end.
-
-encode_GeneralString(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_GeneralString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_GraphicString(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_GraphicString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_ObjectDescriptor(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_ObjectDescriptor(Bytes) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_TeletexString(_C,Val) -> % equivalent with T61String
- encode_restricted_string(aligned,Val).
-decode_TeletexString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_VideotexString(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_VideotexString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes}
-%%
-getBMPChars(<<T/binary>>, 0, Acc) ->
- {lists:reverse(Acc),T};
-getBMPChars(<<0,O2,Bytes1/bitstring>>, Len, Acc) ->
- getBMPChars(Bytes1,Len-1,[O2|Acc]);
-getBMPChars(<<O1,O2,Bytes1/bitstring>>, Len, Acc) ->
- getBMPChars(Bytes1,Len-1,[{0,0,O1,O2}|Acc]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% chars_encode(C,StringType,Value) -> ValueList
-%%
-%% encodes chars according to the per rules taking the constraint PermittedAlphabet
-%% into account.
-%% This function does only encode the value part and NOT the length
-
-% chars_encode(C,StringType,Value) ->
-% case {StringType,get_constraint(C,'PermittedAlphabet')} of
-% {'UniversalString',{_,Sv}} ->
-% exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
-% {'BMPString',{_,Sv}} ->
-% exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
-% _ ->
-% {NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
-% chars_encode2(Value,NumBits,CharOutTab)
-% end.
-
-
-chars_encode2([H|T],NumBits,T1={Min,Max,notab}) when H =< Max, H >= Min ->
-% [[10,NumBits,H-Min]|chars_encode2(T,NumBits,T1)];
- [pre_complete_bits(NumBits,H-Min)|chars_encode2(T,NumBits,T1)];
-chars_encode2([H|T],NumBits,T1={Min,Max,Tab}) when H =< Max, H >= Min ->
-% [[10,NumBits,element(H-Min+1,Tab)]|chars_encode2(T,NumBits,T1)];
- [pre_complete_bits(NumBits,exit_if_false(H,element(H-Min+1,Tab)))|
- chars_encode2(T,NumBits,T1)];
-chars_encode2([{A,B,C,D}|T],NumBits,T1={Min,_Max,notab}) ->
- %% no value range check here (ought to be, but very expensive)
-% [{bits,NumBits,(A*B*C*D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
-% [[10,NumBits,((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min]|chars_encode2(T,NumBits,T1)];
- [pre_complete_bits(NumBits,
- ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min)|
- chars_encode2(T,NumBits,T1)];
-chars_encode2([H={A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
- %% no value range check here (ought to be, but very expensive)
- [pre_complete_bits(NumBits,exit_if_false(H,element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)))|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([H|_T],_NumBits,{_Min,_Max,_Tab}) ->
- exit({error,{asn1,{illegal_char_value,H}}});
-chars_encode2([],_,_) ->
- [].
-
-exit_if_false(V,false)->
- exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}});
-exit_if_false(_,V) ->V.
-
-pre_complete_bits(NumBits,Val) when NumBits =< 8 ->
- [10,NumBits,Val];
-pre_complete_bits(NumBits,Val) when NumBits =< 16 ->
- [10,NumBits-8,Val bsr 8,10,8,(Val band 255)];
-pre_complete_bits(NumBits,Val) when NumBits =< 2040 -> % 255 * 8
-% LBUsed = NumBits rem 8,
-% {Unused,Len} = case (8 - LBUsed) of
-% 8 -> {0,NumBits div 8};
-% U -> {U,(NumBits div 8) + 1}
-% end,
-% NewVal = Val bsr LBUsed,
-% [30,Unused,Len,<<NewVal:Len/unit:8,Val:LBUsed,0:Unused>>].
- Unused = (8 - (NumBits rem 8)) rem 8,
- Len = NumBits + Unused,
- [30,Unused,Len div 8,<<(Val bsl Unused):Len>>].
-
-
-chars_decode(Bytes,_,'BMPString',_,Len) ->
- getBMPChars(Bytes,Len,[]);
-chars_decode(Bytes,NumBits,_StringType,CharInTab,Len) ->
- chars_decode2(Bytes,CharInTab,NumBits,Len).
-
-
-chars_decode2(Bytes,CharInTab,NumBits,Len) ->
- chars_decode2(Bytes,CharInTab,NumBits,Len,[]).
-
-chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) ->
- {lists:reverse(Acc),Bytes};
-chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- Result =
- if
- Char < 256 -> Char;
- true ->
- list_to_tuple(binary_to_list(<<Char:32>>))
- end,
- chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]);
-chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]);
-
-%% BMPString and UniversalString with PermittedAlphabet is currently not supported
-chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_UTF8String(Val) -> CompleteList
-%% Val -> <<utf8encoded binary>>
-%% CompleteList -> [apropriate codes and values for driver complete]
-%%
-encode_UTF8String(Val) when is_binary(Val) ->
- [encode_length(undefined,size(Val)),
- octets_to_complete(size(Val),Val)];
-encode_UTF8String(Val) ->
- encode_UTF8String(list_to_binary(Val)).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_UTF8String(Bytes) -> {Utf8Binary,RemainingBytes}
-%% Utf8Binary -> <<utf8 encoded binary>>
-%% RemainingBytes -> <<buffer>>
-decode_UTF8String(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {_Bin,_Bytes3} = getoctets_as_bin(Bytes2,Len).
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_object_identifier(Val) -> CompleteList
-%% encode_object_identifier({Name,Val}) -> CompleteList
-%% Val -> {Int1,Int2,...,IntN} % N >= 2
-%% Name -> atom()
-%% Int1 -> integer(0..2)
-%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
-%% Int3-N -> integer()
-%% CompleteList -> [{bits,8,Val}|{octets,Ol}|align|...]
-%%
-encode_object_identifier({Name,Val}) when is_atom(Name) ->
- encode_object_identifier(Val);
-encode_object_identifier(Val) ->
- OctetList = e_object_identifier(Val),
- Octets = list_to_binary(OctetList),
- [encode_length(undefined,size(Octets)),
- octets_to_complete(size(Octets),Octets)].
-
-e_object_identifier({'OBJECT IDENTIFIER',V}) ->
- e_object_identifier(V);
-e_object_identifier({Cname,V}) when is_atom(Cname),is_tuple(V) ->
- e_object_identifier(tuple_to_list(V));
-e_object_identifier({Cname,V}) when is_atom(Cname),is_list(V) ->
- e_object_identifier(V);
-e_object_identifier(V) when is_tuple(V) ->
- e_object_identifier(tuple_to_list(V));
-
-%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
-e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 ->
- Head = 40*E1 + E2, % weird
- e_object_elements([Head|Tail],[]);
-e_object_identifier(Oid=[_,_|_Tail]) ->
- exit({error,{asn1,{'illegal_value',Oid}}}).
-
-e_object_elements([],Acc) ->
- lists:reverse(Acc);
-e_object_elements([H|T],Acc) ->
- e_object_elements(T,[e_object_element(H)|Acc]).
-
-e_object_element(Num) when Num < 128 ->
- [Num];
-e_object_element(Num) ->
- [e_o_e(Num bsr 7)|[Num band 2#1111111]].
-e_o_e(Num) when Num < 128 ->
- Num bor 2#10000000;
-e_o_e(Num) ->
- [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]].
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_object_identifier(Bytes) -> {ObjId,RemainingBytes}
-%% ObjId -> {integer(),integer(),...} % at least 2 integers
-%% RemainingBytes -> [integer()] when integer() (0..255)
-decode_object_identifier(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- [First|Rest] = dec_subidentifiers(Octs,0,[]),
- Idlist = if
- First < 40 ->
- [0,First|Rest];
- First < 80 ->
- [1,First - 40|Rest];
- true ->
- [2,First - 80|Rest]
- end,
- {list_to_tuple(Idlist),Bytes3}.
-
-dec_subidentifiers([H|T],Av,Al) when H >=16#80 ->
- dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al);
-dec_subidentifiers([H|T],Av,Al) ->
- dec_subidentifiers(T,0,[(Av bsl 7) + H |Al]);
-dec_subidentifiers([],_Av,Al) ->
- lists:reverse(Al).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_relative_oid(Val) -> CompleteList
-%% encode_relative_oid({Name,Val}) -> CompleteList
-encode_relative_oid({Name,Val}) when is_atom(Name) ->
- encode_relative_oid(Val);
-encode_relative_oid(Val) when is_tuple(Val) ->
- encode_relative_oid(tuple_to_list(Val));
-encode_relative_oid(Val) when is_list(Val) ->
- Octets = list_to_binary([e_object_element(X)||X <- Val]),
- [encode_length(undefined,size(Octets)),
- octets_to_complete(size(Octets),Octets)].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_relative_oid(Val) -> CompleteList
-%% decode_relative_oid({Name,Val}) -> CompleteList
-decode_relative_oid(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- ObjVals = dec_subidentifiers(Octs,0,[]),
- {list_to_tuple(ObjVals),Bytes3}.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_real(Val) -> CompleteList
-%% encode_real({Name,Val}) -> CompleteList
-encode_real({Name,Val}) when is_atom(Name) ->
- encode_real(Val);
-encode_real(Real) ->
- {EncVal,Len} = ?RT_COMMON:encode_real([],Real),
- [encode_length(undefined,Len),octets_to_complete(size(EncVal),EncVal)].
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_real(Val) -> {REALvalue,Rest}
-%% decode_real({Name,Val}) -> {REALvalue,Rest}
-decode_real(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {RealVal,Rest,Len} = ?RT_COMMON:decode_real(Bytes2,Len),
- {RealVal,Rest}.
-
-
-get_constraint([{Key,V}],Key) ->
- V;
-get_constraint([],_) ->
- no;
-get_constraint(C,Key) ->
- case lists:keysearch(Key,1,C) of
- false ->
- no;
- {value,{_,V}} ->
- V
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% complete(InList) -> ByteList
-%% Takes a coded list with bits and bytes and converts it to a list of bytes
-%% Should be applied as the last step at encode of a complete ASN.1 type
-%%
-
--ifdef(nodriver).
-
-complete(L) ->
- erlang_complete(L).
-
--else.
-
-%% asn1-1.7
-complete(L) ->
- case asn1rt_nif:encode_per_complete(L) of
- {error, Reason} -> handle_error(Reason, L);
- Else when is_binary(Else) -> Else
- end.
-
-handle_error([],_)->
- exit({error,{asn1,{"memory allocation problem in driver"}}});
-handle_error($1,L) -> % error in complete in driver
- exit({error,{asn1,L}});
-handle_error(ErrL,L) ->
- exit({error,{asn1,ErrL,L}}).
-
--endif.
-
-
-octets_to_complete(Len,Val) when Len < 256 ->
- [20,Len,Val];
-octets_to_complete(Len,Val) ->
- [21,<<Len:16>>,Val].
-
-octets_unused_to_complete(Unused,Len,Val) when Len < 256 ->
- [30,Unused,Len,Val];
-octets_unused_to_complete(Unused,Len,Val) ->
- [31,Unused,<<Len:16>>,Val].
diff --git a/lib/asn1/src/asn1rt_uper_bin.erl b/lib/asn1/src/asn1rt_uper_bin.erl
deleted file mode 100644
index fc65d80245..0000000000
--- a/lib/asn1/src/asn1rt_uper_bin.erl
+++ /dev/null
@@ -1,1487 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-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%
-%%
-%%
--module(asn1rt_uper_bin).
-
-%% encoding / decoding of PER unaligned
-
--include("asn1_records.hrl").
-
-%%-compile(export_all).
-
--export([decode_fragmented/3]).
--export([setext/1, fixoptionals/3,
- fixextensions/2,
- skipextensions/3, getbit/1, getchoice/3 ]).
--export([set_choice/3, encode_integer/2, encode_integer/3]).
--export([encode_small_number/1, encode_boolean/1,
- encode_length/2,
- encode_small_length/1,
- decode_compact_bit_string/3]).
--export([encode_bit_string/3, decode_bit_string/3 ]).
--export([encode_octet_string/2,
- encode_relative_oid/1, decode_relative_oid/1,
- encode_object_identifier/1, decode_object_identifier/1,
- encode_real/1, decode_real/1,
- complete/1, complete_NFP/1]).
-
-
- -export([encode_open_type/2, decode_open_type/2]).
-
- -export([encode_UniversalString/2, decode_UniversalString/2,
- encode_PrintableString/2, decode_PrintableString/2,
- encode_GeneralString/2, decode_GeneralString/2,
- encode_GraphicString/2, decode_GraphicString/2,
- encode_TeletexString/2, decode_TeletexString/2,
- encode_VideotexString/2, decode_VideotexString/2,
- encode_VisibleString/2, decode_VisibleString/2,
- encode_UTF8String/1, decode_UTF8String/1,
- encode_BMPString/2, decode_BMPString/2,
- encode_IA5String/2, decode_IA5String/2,
- encode_NumericString/2, decode_NumericString/2,
- encode_ObjectDescriptor/2, decode_ObjectDescriptor/1
- ]).
-
--define('16K',16384).
--define('32K',32768).
--define('64K',65536).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% setext(true|false) -> CompleteList
-%%
-
-setext(false) ->
- <<0:1>>;
-setext(true) ->
- <<1:1>>.
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% This is the new fixoptionals/3 which is used by the new generates
-%%
-fixoptionals(OptList,OptLength,Val) when is_tuple(Val) ->
- Bits = fixoptionals(OptList,Val,0),
- {Val,<<Bits:OptLength>>};
-
-fixoptionals([],_Val,Acc) ->
- %% Optbits
- Acc;
-fixoptionals([{Pos,DefVal}|Ot],Val,Acc) ->
- case element(Pos,Val) of
- asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1);
- DefVal -> fixoptionals(Ot,Val,Acc bsl 1);
- _ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1)
- end;
-fixoptionals([Pos|Ot],Val,Acc) ->
- case element(Pos,Val) of
- asn1_NOVALUE -> fixoptionals(Ot,Val,Acc bsl 1);
- asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1);
- _ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1)
- end.
-
-
-fixextensions({ext,ExtPos,ExtNum},Val) ->
- case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
- 0 -> [];
- ExtBits ->
- [encode_small_length(ExtNum),<<ExtBits:ExtNum>>]
- end.
-
-fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
- Acc;
-fixextensions(Pos,ExtPos,Val,Acc) ->
- Bit = case catch(element(Pos+1,Val)) of
- asn1_NOVALUE ->
- 0;
- asn1_NOEXTVALUE ->
- 0;
- {'EXIT',_} ->
- 0;
- _ ->
- 1
- end,
- fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
-
-skipextensions(Bytes,Nr,ExtensionBitstr) when is_bitstring(ExtensionBitstr) ->
- Prev = Nr - 1,
- case ExtensionBitstr of
- <<_:Prev,1:1,_/bitstring>> ->
- {_,Bytes2} = decode_open_type(Bytes,[]),
- skipextensions(Bytes2, Nr+1, ExtensionBitstr);
- <<_:Prev,0:1,_/bitstring>> ->
- skipextensions(Bytes, Nr+1, ExtensionBitstr);
- _ ->
- Bytes
- end.
-
-
-getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
- {0,Bytes};
-getchoice(Bytes,_,1) ->
- decode_small_number(Bytes);
-getchoice(Bytes,NumChoices,0) ->
- decode_constrained_number(Bytes,{0,NumChoices-1}).
-
-
-%% getbits_as_binary(Num,Bytes) -> {{Unused,BinBits},RestBytes},
-%% Num = integer(),
-%% Bytes = list() | tuple(),
-%% Unused = integer(),
-%% BinBits = binary(),
-%% RestBytes = tuple()
-getbits_as_binary(Num,Bytes) when is_bitstring(Bytes) ->
- <<BS:Num/bitstring,Rest/bitstring>> = Bytes,
- {BS,Rest}.
-
-getbits_as_list(Num,Bytes) when is_bitstring(Bytes) ->
- <<BitStr:Num/bitstring,Rest/bitstring>> = Bytes,
- {[ B || <<B:1>> <= BitStr],Rest}.
-
-getbit(Buffer) ->
- <<B:1,Rest/bitstring>> = Buffer,
- {B,Rest}.
-
-
-getbits(Buffer,Num) when is_bitstring(Buffer) ->
- <<Bs:Num,Rest/bitstring>> = Buffer,
- {Bs,Rest}.
-
-
-
-%% Pick the first Num octets.
-%% Returns octets as an integer with bit significance as in buffer.
-getoctets(Buffer,Num) when is_bitstring(Buffer) ->
- <<Val:Num/integer-unit:8,RestBitStr/bitstring>> = Buffer,
- {Val,RestBitStr}.
-
-%% Pick the first Num octets.
-%% Returns octets as a binary
-getoctets_as_bin(Bin,Num) when is_bitstring(Bin) ->
- <<Octets:Num/binary,RestBin/bitstring>> = Bin,
- {Octets,RestBin}.
-
-%% same as above but returns octets as a List
-getoctets_as_list(Buffer,Num) ->
- {Bin,Buffer2} = getoctets_as_bin(Buffer,Num),
- {binary_to_list(Bin),Buffer2}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
-%% Alt = atom()
-%% Altnum = integer() | {integer(),integer()}% number of alternatives
-%% Choices = [atom()] | {[atom()],[atom()]}
-%% When Choices is a tuple the first list is the Rootset and the
-%% second is the Extensions and then Altnum must also be a tuple with the
-%% lengths of the 2 lists
-%%
-set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
- case set_choice_tag(Alt,L1) of
- N when is_integer(N), Len1 > 1 ->
- [<<0:1>>, % the value is in the root set
- encode_integer([{'ValueRange',{0,Len1-1}}],N)];
- N when is_integer(N) ->
- <<0:1>>; % no encoding if only 0 or 1 alternative
- false ->
- [<<1:1>>, % extension value
- case set_choice_tag(Alt,L2) of
- N2 when is_integer(N2) ->
- encode_small_number(N2);
- false ->
- unknown_choice_alt
- end]
- end;
-set_choice(Alt,L,Len) ->
- case set_choice_tag(Alt,L) of
- N when is_integer(N), Len > 1 ->
- encode_integer([{'ValueRange',{0,Len-1}}],N);
- N when is_integer(N) ->
- []; % no encoding if only 0 or 1 alternative
- false ->
- [unknown_choice_alt]
- end.
-
-set_choice_tag(Alt,Choices) ->
- set_choice_tag(Alt,Choices,0).
-
-set_choice_tag(Alt,[Alt|_Rest],Tag) ->
- Tag;
-set_choice_tag(Alt,[_H|Rest],Tag) ->
- set_choice_tag(Alt,Rest,Tag+1);
-set_choice_tag(_Alt,[],_Tag) ->
- false.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_fragmented_XXX; decode of values encoded fragmented according
-%% to ITU-T X.691 clause 10.9.3.8. The unit (XXX) is either bits, octets,
-%% characters or number of components (in a choice,sequence or similar).
-%% Buffer is a buffer {Used, Bin}.
-%% C is the constrained length.
-%% If the buffer is not aligned, this function does that.
-decode_fragmented_bits(Buffer,C) ->
- decode_fragmented_bits(Buffer,C,[]).
-decode_fragmented_bits(<<3:2,Len:6,BitStr/bitstring>>,C,Acc) ->
-%% {Value,Bin2} = split_binary(Bin, Len * ?'16K'),
- FragLen = (Len*?'16K') div 8,
- <<Value:FragLen/binary,BitStr2/bitstring>> = BitStr,
- decode_fragmented_bits(BitStr2,C,[Value|Acc]);
-decode_fragmented_bits(<<0:1,0:7,BitStr/bitstring>>,C,Acc) ->
- BinBits = list_to_binary(lists:reverse(Acc)),
- case C of
- Int when is_integer(Int),C == size(BinBits) ->
- {BinBits,BitStr};
- Int when is_integer(Int) ->
- exit({error,{asn1,{illegal_value,C,BinBits}}})
- end;
-decode_fragmented_bits(<<0:1,Len:7,BitStr/bitstring>>,C,Acc) ->
- <<Val:Len/bitstring,Rest/bitstring>> = BitStr,
-%% <<Value:Len/binary-unit:1,Bin2/binary>> = Bin,
- ResBitStr = list_to_bitstring(lists:reverse([Val|Acc])),
- case C of
- Int when is_integer(Int),C == bit_size(ResBitStr) ->
- {ResBitStr,Rest};
- Int when is_integer(Int) ->
- exit({error,{asn1,{illegal_value,C,ResBitStr}}})
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_open_type(Constraint, Value) -> CompleteList
-%% Value = list of bytes of an already encoded value (the list must be flat)
-%% | binary
-%% Contraint = not used in this version
-%%
-encode_open_type(C, Val) when is_list(Val) ->
- encode_open_type(C, list_to_binary(Val));
-encode_open_type(_C, Val) when is_binary(Val) ->
- [encode_length(undefined,size(Val)),Val].
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_open_type(Buffer,Constraint) -> Value
-%% Constraint is not used in this version
-%% Buffer = [byte] with PER encoded data
-%% Value = [byte] with decoded data (which must be decoded again as some type)
-%%
-decode_open_type(Bytes, _C) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- getoctets_as_bin(Bytes2,Len).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
-%% encode_integer(Constraint,Value) -> CompleteList
-%% encode_integer(Constraint,{Name,Value}) -> CompleteList
-%%
-%%
-encode_integer(C,V,NamedNumberList) when is_atom(V) ->
- case lists:keysearch(V,1,NamedNumberList) of
- {value,{_,NewV}} ->
- encode_integer(C,NewV);
- _ ->
- exit({error,{asn1,{namednumber,V}}})
- end;
-encode_integer(C,V,_NamedNumberList) when is_integer(V) ->
- encode_integer(C,V);
-encode_integer(C,{Name,V},NamedNumberList) when is_atom(Name) ->
- encode_integer(C,V,NamedNumberList).
-
-encode_integer(C,{Name,Val}) when is_atom(Name) ->
- encode_integer(C,Val);
-
-encode_integer([{Rc,_Ec}],Val) when is_tuple(Rc) -> % XXX when is this invoked? First argument most often a list,...Ok this is the extension case...but it doesn't work.
- case (catch encode_integer([Rc],Val)) of
- {'EXIT',{error,{asn1,_}}} ->
- [<<1:1>>,encode_unconstrained_number(Val)];
- Encoded ->
- [<<0:1>>,Encoded]
- end;
-encode_integer(C,Val ) when is_list(C) ->
- case get_constraint(C,'SingleValue') of
- no ->
- encode_integer1(C,Val);
- V when is_integer(V),V == Val ->
- []; % a type restricted to a single value encodes to nothing
- V when is_list(V) ->
- case lists:member(Val,V) of
- true ->
- encode_integer1(C,Val);
- _ ->
- exit({error,{asn1,{illegal_value,Val}}})
- end;
- _ ->
- exit({error,{asn1,{illegal_value,Val}}})
- end.
-
-encode_integer1(C, Val) ->
- case VR = get_constraint(C,'ValueRange') of
- no ->
- encode_unconstrained_number(Val);
- {Lb,'MAX'} ->
- encode_semi_constrained_number(Lb,Val);
- %% positive with range
- {Lb,Ub} when Val >= Lb,
- Ub >= Val ->
- encode_constrained_number(VR,Val);
- _ ->
- exit({error,{asn1,{illegal_value,VR,Val}}})
- end.
-
-%% X.691:10.6 Encoding of a normally small non-negative whole number
-%% Use this for encoding of CHOICE index if there is an extension marker in
-%% the CHOICE
-encode_small_number({Name,Val}) when is_atom(Name) ->
- encode_small_number(Val);
-encode_small_number(Val) when Val =< 63 ->
- <<Val:7>>;
-encode_small_number(Val) ->
- [<<1:1>>,encode_semi_constrained_number(0,Val)].
-
-decode_small_number(Bytes) ->
- {Bit,Bytes2} = getbit(Bytes),
- case Bit of
- 0 ->
- getbits(Bytes2,6);
- 1 ->
- decode_semi_constrained_number(Bytes2)
- end.
-
-%% X.691:10.7 Encoding of a semi-constrained whole number
-%% might be an optimization encode_semi_constrained_number(0,Val) ->
-encode_semi_constrained_number(C,{Name,Val}) when is_atom(Name) ->
- encode_semi_constrained_number(C,Val);
-encode_semi_constrained_number({Lb,'MAX'},Val) ->
- encode_semi_constrained_number(Lb,Val);
-encode_semi_constrained_number(Lb,Val) ->
- %% encoding in minimum no of octets preceeded by a length
- Val2 = Val - Lb,
-%% NumBits = num_bits(Val2),
- Bin = eint_bin_positive(Val2),
- Size = size(Bin),
- if
- Size < 128 ->
- [<<Size>>,Bin]; % equiv with encode_length(undefined,Len) but faster
- Size < 16384 ->
- [<<2:2,Size:14>>,Bin];
- true ->
- [encode_length(undefined,Size),Bin]
- end.
-
-decode_semi_constrained_number(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {V,Bytes3} = getoctets(Bytes2,Len),
- {V,Bytes3}.
-
-encode_constrained_number(Range,{Name,Val}) when is_atom(Name) ->
- encode_constrained_number(Range,Val);
-encode_constrained_number({Lb,Ub},Val) when Val >= Lb, Ub >= Val ->
- Range = Ub - Lb + 1,
- Val2 = Val - Lb,
- NumBits = num_bits(Range),
- <<Val2:NumBits>>;
-encode_constrained_number(Range,Val) ->
- exit({error,{asn1,{integer_range,Range,value,Val}}}).
-
-
-decode_constrained_number(Buffer,{Lb,Ub}) ->
- Range = Ub - Lb + 1,
- NumBits = num_bits(Range),
- {Val,Remain} = getbits(Buffer,NumBits),
- {Val+Lb,Remain}.
-
-%% X.691:10.8 Encoding of an unconstrained whole number
-
-encode_unconstrained_number(Val) when Val >= 0 ->
- Oct = eint_bin_2Cs(Val),
- Len = size(Oct),
- if
- Len < 128 ->
- [<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster
- Len < 16384 ->
- [<<2:2,Len:14>>,Oct];
- true ->
- [encode_length(undefined,Len),<<Len:16>>,Oct]
- end;
-encode_unconstrained_number(Val) -> % negative
- Oct = enint(Val,[]),
- Len = size(Oct),
- if
- Len < 128 ->
- [<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster
- Len < 16384 ->
- [<<2:2,Len:14>>,Oct];
- true ->
- [encode_length(undefined,Len),Oct]
- end.
-
-
-eint_bin_2Cs(Int) ->
- case eint_bin_positive(Int) of
- Bin = <<B,_/binary>> when B > 16#7f ->
- <<0,Bin/binary>>;
- Bin -> Bin
- end.
-
-%% returns the integer as a binary
-eint_bin_positive(Val) when Val < 16#100 ->
- <<Val>>;
-eint_bin_positive(Val) when Val < 16#10000 ->
- <<Val:16>>;
-eint_bin_positive(Val) when Val < 16#1000000 ->
- <<Val:24>>;
-eint_bin_positive(Val) when Val < 16#100000000 ->
- <<Val:32>>;
-eint_bin_positive(Val) ->
- list_to_binary([eint_bin_positive2(Val bsr 32)|<<Val:32>>]).
-eint_bin_positive2(Val) when Val < 16#100 ->
- <<Val>>;
-eint_bin_positive2(Val) when Val < 16#10000 ->
- <<Val:16>>;
-eint_bin_positive2(Val) when Val < 16#1000000 ->
- <<Val:24>>;
-eint_bin_positive2(Val) when Val < 16#100000000 ->
- <<Val:32>>;
-eint_bin_positive2(Val) ->
- [eint_bin_positive2(Val bsr 32)|<<Val:32>>].
-
-
-
-
-enint(-1, [B1|T]) when B1 > 127 ->
- list_to_binary([B1|T]);
-enint(N, Acc) ->
- enint(N bsr 8, [N band 16#ff|Acc]).
-
-
-%% X.691:10.9 Encoding of a length determinant
-%%encode_small_length(undefined,Len) -> % null means no UpperBound
-%% encode_small_number(Len).
-
-%% X.691:10.9.3.5
-%% X.691:10.9.3.7
-encode_length(undefined,Len) -> % un-constrained
- if
- Len < 128 ->
- <<Len>>;
- Len < 16384 ->
- <<2:2,Len:14>>;
- true -> % should be able to endode length >= 16384
- error({error,{asn1,{encode_length,{nyi,above_16k}}}})
- end;
-
-encode_length({0,'MAX'},Len) ->
- encode_length(undefined,Len);
-encode_length(Vr={Lb,Ub},Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
- encode_constrained_number(Vr,Len);
-encode_length({Lb,_Ub},Len) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
- encode_length(undefined,Len);
-encode_length({Vr={Lb,Ub},Ext},Len)
- when Ub =< 65535 ,Lb >= 0, Len=<Ub, is_list(Ext) ->
- %% constrained extensible
- [<<0:1>>,encode_constrained_number(Vr,Len)];
-encode_length({{Lb,_Ub},Ext},Len) when is_list(Ext) ->
- [<<1:1>>,encode_semi_constrained_number(Lb,Len)];
-encode_length(SingleValue,_Len) when is_integer(SingleValue) ->
- [].
-
-%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension
-%% additions in a sequence or set
-encode_small_length(Len) when Len =< 64 ->
- <<(Len-1):7>>;
-encode_small_length(Len) ->
- [<<1:1>>,encode_length(undefined,Len)].
-
-
-%% un-constrained
-decode_length(<<0:1,Oct:7,Rest/bitstring>>,undefined) ->
- {Oct,Rest};
-decode_length(<<2:2,Val:14,Rest/bitstring>>,undefined) ->
- {Val,Rest};
-decode_length(<<3:2,_:14,_Rest/bitstring>>,undefined) ->
- exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
-
-decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
- decode_constrained_number(Buffer,{Lb,Ub});
-decode_length(Buffer,{Lb,_}) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
- decode_length(Buffer,undefined);
-decode_length(Buffer,{VR={_Lb,_Ub},Ext}) when is_list(Ext) ->
- {0,Buffer2} = getbit(Buffer),
- decode_length(Buffer2, VR);
-
-
-%When does this case occur with {_,_Lb,Ub} ??
-% X.691:10.9.3.5
-decode_length(Bin,{_,_Lb,_Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub NOTE! this case does not cover case when Ub > 65535
- case Bin of
- <<0:1,Val:7,Rest/bitstring>> ->
- {Val,Rest};
- <<2:2,Val:14,Rest/bitstring>> ->
- {Val,Rest};
- <<3:2,_:14,_Rest/bitstring>> ->
- exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
- end;
-decode_length(Buffer,SingleValue) when is_integer(SingleValue) ->
- {SingleValue,Buffer}.
-
-
- % X.691:11
-encode_boolean(true) ->
- <<1:1>>;
-encode_boolean(false) ->
- <<0:1>>;
-encode_boolean({Name,Val}) when is_atom(Name) ->
- encode_boolean(Val);
-encode_boolean(Val) ->
- exit({error,{asn1,{encode_boolean,Val}}}).
-
-
-%%============================================================================
-%%============================================================================
-%% Bitstring value, ITU_T X.690 Chapter 8.5
-%%============================================================================
-%%============================================================================
-
-%%============================================================================
-%% encode bitstring value
-%%============================================================================
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% bitstring NamedBitList
-%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
-%% the Constraint must then have some information of the
-%% bitlength.
-%% - [list of ones and zeroes] all bits
-%% - integer value representing the bitlist
-%% C is constraint Len, only valid when identifiers
-
-
-%% when the value is a list of {Unused,BinBits}, where
-%% Unused = integer(),
-%% BinBits = binary().
-
-encode_bit_string(C,Bin={Unused,BinBits},NamedBitList) when is_integer(Unused),
- is_binary(BinBits) ->
- encode_bin_bit_string(get_constraint(C,'SizeConstraint'),Bin,NamedBitList);
-
-encode_bit_string(C, BitListVal, NamedBitList) ->
- encode_bit_string1(get_constraint(C,'SizeConstraint'), BitListVal, NamedBitList).
-%% when the value is a list of named bits
-encode_bit_string1(C, LoNB=[FirstVal | _RestVal], NamedBitList) when is_atom(FirstVal) ->
- ToSetPos = get_all_bitposes(LoNB, NamedBitList, []),
- BitList = make_and_set_list(ToSetPos,0),
- encode_bit_string1(C,BitList,NamedBitList);
-
-encode_bit_string1(C, BL=[{bit,_No} | _RestVal], NamedBitList) ->
- ToSetPos = get_all_bitposes(BL, NamedBitList, []),
- BitList = make_and_set_list(ToSetPos,0),
- encode_bit_string1(C,BitList,NamedBitList);
-%% when the value is a list of ones and zeroes
-encode_bit_string1(Int, BitListValue, _)
- when is_list(BitListValue),is_integer(Int) ->
- %% The type is constrained by a single value size constraint
- bit_list2bitstr(Int,BitListValue);
-encode_bit_string1(no, BitListValue,[])
- when is_list(BitListValue) ->
- Len = length(BitListValue),
- [encode_length(undefined,Len),bit_list2bitstr(Len,BitListValue)];
-encode_bit_string1(C, BitListValue,[])
- when is_list(BitListValue) ->
- Len = length(BitListValue),
- [encode_length(C,Len),bit_list2bitstr(Len,BitListValue)];
-encode_bit_string1(no, BitListValue,_NamedBitList)
- when is_list(BitListValue) ->
- %% this case with an unconstrained BIT STRING can be made more efficient
- %% if the complete driver can take a special code so the length field
- %% is encoded there.
- NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
- lists:reverse(BitListValue))),
- Len = length(NewBitLVal),
- [encode_length(undefined,Len),bit_list2bitstr(Len,NewBitLVal)];
-encode_bit_string1(C,BitListValue,_NamedBitList)
- when is_list(BitListValue) ->% C = {_,'MAX'}
- NewBitStr = bitstr_trailing_zeros(BitListValue,C),
- [encode_length(C,bit_size(NewBitStr)),NewBitStr];
-
-
-%% when the value is an integer
-encode_bit_string1(C, IntegerVal, NamedBitList) when is_integer(IntegerVal)->
- BitList = int_to_bitlist(IntegerVal),
- encode_bit_string1(C,BitList,NamedBitList);
-
-%% when the value is a tuple
-encode_bit_string1(C,{Name,Val}, NamedBitList) when is_atom(Name) ->
- encode_bit_string1(C,Val,NamedBitList).
-
-bit_list2bitstr(Len,BitListValue) ->
- case length(BitListValue) of
- Len ->
- << <<B:1>> ||B <- BitListValue>>;
- L when L > Len -> % truncate
- << << <<B:1>> ||B <- BitListValue>> :Len/bitstring>>;
- L -> % Len > L -> pad
- << << <<B:1>> ||B <- BitListValue>>/bitstring ,0:(Len-L)>>
- end.
-
-adjust_trailing_zeros(Len,Bin) when Len == bit_size(Bin) ->
- Bin;
-adjust_trailing_zeros(Len,Bin) when Len > bit_size(Bin) ->
- <<Bin/bitstring,0:(Len-bit_size(Bin))>>;
-adjust_trailing_zeros(Len,Bin) ->
- <<Bin:Len/bitstring>>.
-
-bitstr_trailing_zeros(BitList,C) when is_integer(C) ->
- bitstr_trailing_zeros1(BitList,C,C);
-bitstr_trailing_zeros(BitList,{Lb,Ub}) when is_integer(Lb) ->
- bitstr_trailing_zeros1(BitList,Lb,Ub);
-bitstr_trailing_zeros(BitList,{{Lb,Ub},_}) when is_integer(Lb) ->
- bitstr_trailing_zeros1(BitList,Lb,Ub);
-bitstr_trailing_zeros(BitList,_) ->
- bit_list2bitstr(length(BitList),BitList).
-
-bitstr_trailing_zeros1(BitList,Lb,Ub) ->
- case length(BitList) of
- Lb -> bit_list2bitstr(Lb,BitList);
- B when B<Lb -> bit_list2bitstr(Lb,BitList);
- D -> F = fun(L,LB,LB,_,_)->bit_list2bitstr(LB,lists:reverse(L));
- ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun);
- (L,L1,_,UB,_)when L1 =< UB ->
- bit_list2bitstr(L1,lists:reverse(L));
- (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING,
- BitList}}) end,
- F(lists:reverse(BitList),D,Lb,Ub,F)
- end.
-
-%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
-%% Unused = integer(),i.e. number unused bits in least sign. byte of
-%% BinBits = binary().
-encode_bin_bit_string(C,{_,BinBits},_NamedBitList)
- when is_integer(C),C=<16 ->
- adjust_trailing_zeros(C,BinBits);
-encode_bin_bit_string(C,{_Unused,BinBits},_NamedBitList)
- when is_integer(C) ->
- adjust_trailing_zeros(C,BinBits);
-encode_bin_bit_string(C,UnusedAndBin={_,_},NamedBitList) ->
- %% removes all trailing bits if NamedBitList is not empty
- BitStr = remove_trailing_bin(NamedBitList,UnusedAndBin),
- case C of
- {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
- [encode_length({Lb,Ub},bit_size(BitStr)),BitStr];
- no ->
- [encode_length(undefined,bit_size(BitStr)),BitStr];
- Sc ->
- [encode_length(Sc,bit_size(BitStr)),BitStr]
- end.
-
-
-remove_trailing_bin([], {Unused,Bin}) ->
- BS = bit_size(Bin)-Unused,
- <<BitStr:BS/bitstring,_:Unused>> = Bin,
- BitStr;
-remove_trailing_bin(_NamedNumberList,{_Unused,<<>>}) ->
- <<>>;
-remove_trailing_bin(NamedNumberList, {_Unused,Bin}) ->
- Size = size(Bin)-1,
- <<Bfront:Size/binary, LastByte:8>> = Bin,
-
- %% clear the Unused bits to be sure
- Unused1 = trailingZeroesInNibble(LastByte band 15),
- Unused2 =
- case Unused1 of
- 4 ->
- 4 + trailingZeroesInNibble(LastByte bsr 4);
- _ -> Unused1
- end,
- case Unused2 of
- 8 ->
- remove_trailing_bin(NamedNumberList,{0,Bfront});
- _ ->
- BS = bit_size(Bin) - Unused2,
- <<BitStr:BS/bitstring,_:Unused2>> = Bin,
- BitStr
- end.
-
-trailingZeroesInNibble(0) ->
- 4;
-trailingZeroesInNibble(1) ->
- 0;
-trailingZeroesInNibble(2) ->
- 1;
-trailingZeroesInNibble(3) ->
- 0;
-trailingZeroesInNibble(4) ->
- 2;
-trailingZeroesInNibble(5) ->
- 0;
-trailingZeroesInNibble(6) ->
- 1;
-trailingZeroesInNibble(7) ->
- 0;
-trailingZeroesInNibble(8) ->
- 3;
-trailingZeroesInNibble(9) ->
- 0;
-trailingZeroesInNibble(10) ->
- 1;
-trailingZeroesInNibble(11) ->
- 0;
-trailingZeroesInNibble(12) -> %#1100
- 2;
-trailingZeroesInNibble(13) ->
- 0;
-trailingZeroesInNibble(14) ->
- 1;
-trailingZeroesInNibble(15) ->
- 0.
-
-%%%%%%%%%%%%%%%
-%% The result is presented as a list of named bits (if possible)
-%% else as a tuple {Unused,Bits}. Unused is the number of unused
-%% bits, least significant bits in the last byte of Bits. Bits is
-%% the BIT STRING represented as a binary.
-%%
-decode_compact_bit_string(Buffer, C, NamedNumberList) ->
- case get_constraint(C,'SizeConstraint') of
- 0 -> % fixed length
- {{8,0},Buffer};
- V when is_integer(V),V=<16 -> %fixed length 16 bits or less
- compact_bit_string(Buffer,V,NamedNumberList);
- V when is_integer(V),V=<65536 -> %fixed length > 16 bits
- compact_bit_string(Buffer,V,NamedNumberList);
- V when is_integer(V) -> % V > 65536 => fragmented value
- {Bin,Buffer2} = decode_fragmented_bits(Buffer,V),
- PadLen = (8 - (bit_size(Bin) rem 8)) rem 8,
- {{PadLen,<<Bin/bitstring,0:PadLen>>},Buffer2};
-%% {0,_} -> {{0,Bin},Buffer2};
-%% {U,_} -> {{8-U,Bin},Buffer2}
- {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
- %% This case may demand decoding of fragmented length/value
- {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
- compact_bit_string(Bytes2,Len,NamedNumberList);
- no ->
- %% This case may demand decoding of fragmented length/value
- {Len,Bytes2} = decode_length(Buffer,undefined),
- compact_bit_string(Bytes2,Len,NamedNumberList);
- Sc ->
- {Len,Bytes2} = decode_length(Buffer,Sc),
- compact_bit_string(Bytes2,Len,NamedNumberList)
- end.
-
-
-%%%%%%%%%%%%%%%
-%% The result is presented as a list of named bits (if possible)
-%% else as a list of 0 and 1.
-%%
-decode_bit_string(Buffer, C, NamedNumberList) ->
- case get_constraint(C,'SizeConstraint') of
- {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
- {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
- bit_list_or_named(Bytes2,Len,NamedNumberList);
- no ->
- {Len,Bytes2} = decode_length(Buffer,undefined),
- bit_list_or_named(Bytes2,Len,NamedNumberList);
- 0 -> % fixed length
- {[],Buffer}; % nothing to encode
- V when is_integer(V),V=<16 -> % fixed length 16 bits or less
- bit_list_or_named(Buffer,V,NamedNumberList);
- V when is_integer(V),V=<65536 ->
- bit_list_or_named(Buffer,V,NamedNumberList);
- V when is_integer(V) ->
- {BinBits,_} = decode_fragmented_bits(Buffer,V),
- bit_list_or_named(BinBits,V,NamedNumberList);
- Sc -> % extension marker
- {Len,Bytes2} = decode_length(Buffer,Sc),
- bit_list_or_named(Bytes2,Len,NamedNumberList)
- end.
-
-
-%% if no named bits are declared we will return a
-%% {Unused,Bits}. Unused = integer(),
-%% Bits = binary().
-compact_bit_string(Buffer,Len,[]) ->
- {BitStr,Rest} = getbits_as_binary(Len,Buffer), % {{Unused,BinBits},NewBuffer}
- PadLen = (8 - (bit_size(BitStr) rem 8)) rem 8,
- {{PadLen,<<BitStr/bitstring,0:PadLen>>},Rest};
-compact_bit_string(Buffer,Len,NamedNumberList) ->
- bit_list_or_named(Buffer,Len,NamedNumberList).
-
-
-%% if no named bits are declared we will return a
-%% BitList = [0 | 1]
-
-bit_list_or_named(Buffer,Len,[]) ->
- getbits_as_list(Len,Buffer);
-
-%% if there are named bits declared we will return a named
-%% BitList where the names are atoms and unnamed bits represented
-%% as {bit,Pos}
-%% BitList = [atom() | {bit,Pos}]
-%% Pos = integer()
-
-bit_list_or_named(Buffer,Len,NamedNumberList) ->
- {BitList,Rest} = getbits_as_list(Len,Buffer),
- {bit_list_or_named1(0,BitList,NamedNumberList,[]), Rest}.
-
-bit_list_or_named1(Pos,[0|Bt],Names,Acc) ->
- bit_list_or_named1(Pos+1,Bt,Names,Acc);
-bit_list_or_named1(Pos,[1|Bt],Names,Acc) ->
- case lists:keysearch(Pos,2,Names) of
- {value,{Name,_}} ->
- bit_list_or_named1(Pos+1,Bt,Names,[Name|Acc]);
- _ ->
- bit_list_or_named1(Pos+1,Bt,Names,[{bit,Pos}|Acc])
- end;
-bit_list_or_named1(_,[],_,Acc) ->
- lists:reverse(Acc).
-
-
-
-%%%%%%%%%%%%%%%
-%%
-
-int_to_bitlist(Int) when is_integer(Int), Int > 0 ->
- [Int band 1 | int_to_bitlist(Int bsr 1)];
-int_to_bitlist(0) ->
- [].
-
-
-%%%%%%%%%%%%%%%%%%
-%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
-%% [sorted_list_of_bitpositions_to_set]
-
-get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
-
-get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
- case lists:keysearch(Val, 1, NamedBitList) of
- {value, {_ValName, ValPos}} ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
- _ ->
- exit({error,{asn1, {bitstring_namedbit, Val}}})
- end;
-get_all_bitposes([], _NamedBitList, Ack) ->
- lists:sort(Ack).
-
-%%%%%%%%%%%%%%%%%%
-%% make_and_set_list([list of positions to set to 1])->
-%% returns list with all in SetPos set.
-%% in positioning in list the first element is 0, the second 1 etc.., but
-%%
-
-make_and_set_list([XPos|SetPos], XPos) ->
- [1 | make_and_set_list(SetPos, XPos + 1)];
-make_and_set_list([Pos|SetPos], XPos) ->
- [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
-make_and_set_list([], _) ->
- [].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% X.691:16
-%% encode_octet_string(Constraint,Val)
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-encode_octet_string(C,{_Name,Val}) ->
- encode_octet_string(C,Val);
-encode_octet_string(C,Val) ->
- case get_constraint(C,'SizeConstraint') of
- 0 ->
- <<>>;
- 1 ->
- list_to_binary(Val);
- 2 ->
- list_to_binary(Val);
- {_,_}=VR ->
- try
- [encode_length(VR, length(Val)),list_to_binary(Val)]
- catch
- error:{error,{asn1,{encode_length,_}}} ->
- encode_fragmented_octet_string(Val)
- end;
- Sv when is_integer(Sv), Sv =:= length(Val) -> % fixed length
- if
- Sv =< 65535 ->
- list_to_binary(Val);
- true ->
- encode_fragmented_octet_string(Val)
- end;
- Sv when is_list(Sv) ->
- try
- [encode_length({hd(Sv),lists:max(Sv)},
- length(Val)),list_to_binary(Val)]
- catch
- error:{error,{asn1,{encode_length,_}}} ->
- encode_fragmented_octet_string(Val)
- end;
- no ->
- try
- [encode_length(undefined, length(Val)),list_to_binary(Val)]
- catch
- error:{error,{asn1,{encode_length,_}}} ->
- encode_fragmented_octet_string(Val)
- end
- end.
-
-encode_fragmented_octet_string(Val) ->
- Bin = list_to_binary(Val),
- efos_1(Bin).
-
-efos_1(<<B:16#10000/binary,T/binary>>) ->
- [<<3:2,4:6>>,B|efos_1(T)];
-efos_1(<<B:16#C000/binary,T/binary>>) ->
- [<<3:2,3:6>>,B|efos_1(T)];
-efos_1(<<B:16#8000/binary,T/binary>>) ->
- [<<3:2,2:6>>,B|efos_1(T)];
-efos_1(<<B:16#4000/binary,T/binary>>) ->
- [<<3:2,1:6>>,B|efos_1(T)];
-efos_1(<<B/bitstring>>) ->
- Len = byte_size(B),
- [encode_length(undefined, Len),B].
-
-decode_fragmented(SegSz0, Buf0, Unit) ->
- SegSz = SegSz0 * Unit * ?'16K',
- <<Res:SegSz/bitstring,Buf/bitstring>> = Buf0,
- decode_fragmented_1(Buf, Unit, Res).
-
-decode_fragmented_1(<<0:1,N:7,Buf0/bitstring>>, Unit, Res) ->
- Sz = N*Unit,
- <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
- {<<Res/bitstring,S/bitstring>>,Buf};
-decode_fragmented_1(<<1:1,0:1,N:14,Buf0/bitstring>>, Unit, Res) ->
- Sz = N*Unit,
- <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
- {<<Res/bitstring,S/bitstring>>,Buf};
-decode_fragmented_1(<<1:1,1:1,SegSz0:6,Buf0/bitstring>>, Unit, Res0) ->
- SegSz = SegSz0 * Unit * ?'16K',
- <<Frag:SegSz/bitstring,Buf/bitstring>> = Buf0,
- Res = <<Res0/bitstring,Frag/bitstring>>,
- decode_fragmented_1(Buf, Unit, Res).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Restricted char string types
-%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
-%% X.691:26 and X.680:34-36
-%%encode_restricted_string('BMPString',Constraints,Extension,Val)
-
-
-encode_restricted_string({Name,Val}) when is_atom(Name) ->
- encode_restricted_string(Val);
-
-encode_restricted_string(Val) when is_list(Val)->
- [encode_length(undefined,length(Val)),list_to_binary(Val)].
-
-encode_known_multiplier_string(StringType,C,{Name,Val}) when is_atom(Name) ->
- encode_known_multiplier_string(StringType,C,Val);
-
-encode_known_multiplier_string(StringType,C,Val) ->
- Result = chars_encode(C,StringType,Val),
- NumBits = get_NumBits(C,StringType),
- case get_constraint(C,'SizeConstraint') of
- Ub when is_integer(Ub), Ub*NumBits =< 16 ->
- Result;
- 0 ->
- [];
- Ub when is_integer(Ub),Ub =<65535 -> % fixed length
- Result;
- {Ub,Lb} ->
- [encode_length({Ub,Lb},length(Val)),Result];
- Vl when is_list(Vl) ->
- [encode_length({lists:min(Vl),lists:max(Vl)},length(Val)),Result];
- no ->
- [encode_length(undefined,length(Val)),Result]
- end.
-
-decode_restricted_string(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- getoctets_as_list(Bytes2,Len).
-
-decode_known_multiplier_string(Bytes,StringType,C,_Ext) ->
- NumBits = get_NumBits(C,StringType),
- case get_constraint(C,'SizeConstraint') of
- Ub when is_integer(Ub), Ub*NumBits =< 16 ->
- chars_decode(Bytes,NumBits,StringType,C,Ub);
- Ub when is_integer(Ub),Ub =<65535 -> % fixed length
- chars_decode(Bytes,NumBits,StringType,C,Ub);
- 0 ->
- {[],Bytes};
- Vl when is_list(Vl) ->
- {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}),
- chars_decode(Bytes1,NumBits,StringType,C,Len);
- no ->
- {Len,Bytes1} = decode_length(Bytes,undefined),
- chars_decode(Bytes1,NumBits,StringType,C,Len);
- {Lb,Ub}->
- {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}),
- chars_decode(Bytes1,NumBits,StringType,C,Len)
- end.
-
-
-encode_NumericString(C,Val) ->
- encode_known_multiplier_string('NumericString',C,Val).
-decode_NumericString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,'NumericString',C,false).
-
-encode_PrintableString(C,Val) ->
- encode_known_multiplier_string('PrintableString',C,Val).
-decode_PrintableString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,'PrintableString',C,false).
-
-encode_VisibleString(C,Val) -> % equivalent with ISO646String
- encode_known_multiplier_string('VisibleString',C,Val).
-decode_VisibleString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,'VisibleString',C,false).
-
-encode_IA5String(C,Val) ->
- encode_known_multiplier_string('IA5String',C,Val).
-decode_IA5String(Bytes,C) ->
- decode_known_multiplier_string(Bytes,'IA5String',C,false).
-
-encode_BMPString(C,Val) ->
- encode_known_multiplier_string('BMPString',C,Val).
-decode_BMPString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,'BMPString',C,false).
-
-encode_UniversalString(C,Val) ->
- encode_known_multiplier_string('UniversalString',C,Val).
-decode_UniversalString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,'UniversalString',C,false).
-
-
-%% end of known-multiplier strings for which PER visible constraints are
-%% applied
-
-encode_GeneralString(_C,Val) ->
- encode_restricted_string(Val).
-decode_GeneralString(Bytes,_C) ->
- decode_restricted_string(Bytes).
-
-encode_GraphicString(_C,Val) ->
- encode_restricted_string(Val).
-decode_GraphicString(Bytes,_C) ->
- decode_restricted_string(Bytes).
-
-encode_ObjectDescriptor(_C,Val) ->
- encode_restricted_string(Val).
-decode_ObjectDescriptor(Bytes) ->
- decode_restricted_string(Bytes).
-
-encode_TeletexString(_C,Val) -> % equivalent with T61String
- encode_restricted_string(Val).
-decode_TeletexString(Bytes,_C) ->
- decode_restricted_string(Bytes).
-
-encode_VideotexString(_C,Val) ->
- encode_restricted_string(Val).
-decode_VideotexString(Bytes,_C) ->
- decode_restricted_string(Bytes).
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes}
-%%
-getBMPChars(Bytes,1) ->
- {O1,Bytes2} = getbits(Bytes,8),
- {O2,Bytes3} = getbits(Bytes2,8),
- if
- O1 == 0 ->
- {[O2],Bytes3};
- true ->
- {[{0,0,O1,O2}],Bytes3}
- end;
-getBMPChars(Bytes,Len) ->
- getBMPChars(Bytes,Len,[]).
-
-getBMPChars(Bytes,0,Acc) ->
- {lists:reverse(Acc),Bytes};
-getBMPChars(Bytes,Len,Acc) ->
- {Octs,Bytes1} = getoctets_as_list(Bytes,2),
- case Octs of
- [0,O2] ->
- getBMPChars(Bytes1,Len-1,[O2|Acc]);
- [O1,O2]->
- getBMPChars(Bytes1,Len-1,[{0,0,O1,O2}|Acc])
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% chars_encode(C,StringType,Value) -> ValueList
-%%
-%% encodes chars according to the per rules taking the constraint PermittedAlphabet
-%% into account.
-%% This function does only encode the value part and NOT the length
-
-chars_encode(C,StringType,Value) ->
- case {StringType,get_constraint(C,'PermittedAlphabet')} of
- {'UniversalString',{_,_Sv}} ->
- exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
- {'BMPString',{_,_Sv}} ->
- exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
- _ ->
- {NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
- chars_encode2(Value,NumBits,CharOutTab)
- end.
-
-chars_encode2([H|T],NumBits,{Min,Max,notab}) when H =< Max, H >= Min ->
- %%[{bits,NumBits,H-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
- [<<(H-Min):NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([H|T],NumBits,{Min,Max,Tab}) when H =< Max, H >= Min ->
-%% [{bits,NumBits,exit_if_false(H,element(H-Min+1,Tab))}|chars_encode2(T,NumBits,{Min,Max,Tab})];
- Ch = exit_if_false(H,element(H-Min+1,Tab)),
- [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,Tab})];
-chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,notab}) ->
- %% no value range check here (ought to be, but very expensive)
-%% [{bits,NumBits,((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
- Ch = ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,
- [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
- %% no value range check here (ought to be, but very expensive)
-%% [{bits,NumBits,exit_if_false({A,B,C,D},element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab))}|chars_encode2(T,NumBits,{Min,Max,notab})];
- Ch = exit_if_false({A,B,C,D},element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)),
- [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([H|_T],_,{_,_,_}) ->
- exit({error,{asn1,{illegal_char_value,H}}});
-chars_encode2([],_,_) ->
- [].
-
-exit_if_false(V,false)->
- exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}});
-exit_if_false(_,V) ->V.
-
-
-get_NumBits(C,StringType) ->
- case get_constraint(C,'PermittedAlphabet') of
- {'SingleValue',Sv} ->
- charbits(length(Sv));
- no ->
- case StringType of
- 'IA5String' ->
- charbits(128); % 16#00..16#7F
- 'VisibleString' ->
- charbits(95); % 16#20..16#7E
- 'PrintableString' ->
- charbits(74); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
- 'NumericString' ->
- charbits(11); % $ ,"0123456789"
- 'UniversalString' ->
- 32;
- 'BMPString' ->
- 16
- end
- end.
-
-get_CharOutTab(C,StringType) ->
- get_CharTab(C,StringType,out).
-
-get_CharInTab(C,StringType) ->
- get_CharTab(C,StringType,in).
-
-get_CharTab(C,StringType,InOut) ->
- case get_constraint(C,'PermittedAlphabet') of
- {'SingleValue',Sv} ->
- get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut);
- no ->
- case StringType of
- 'IA5String' ->
- {0,16#7F,notab};
- 'VisibleString' ->
- get_CharTab2(C,StringType,16#20,16#7F,notab,InOut);
- 'PrintableString' ->
- Chars = lists:sort(
- " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
- get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut);
- 'NumericString' ->
- get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut);
- 'UniversalString' ->
- {0,16#FFFFFFFF,notab};
- 'BMPString' ->
- {0,16#FFFF,notab}
- end
- end.
-
-get_CharTab2(C,StringType,Min,Max,Chars,InOut) ->
- BitValMax = (1 bsl get_NumBits(C,StringType))-1,
- if
- Max =< BitValMax ->
- {0,Max,notab};
- true ->
- case InOut of
- out ->
- {Min,Max,create_char_tab(Min,Chars)};
- in ->
- {Min,Max,list_to_tuple(Chars)}
- end
- end.
-
-create_char_tab(Min,L) ->
- list_to_tuple(create_char_tab(Min,L,0)).
-create_char_tab(Min,[Min|T],V) ->
- [V|create_char_tab(Min+1,T,V+1)];
-create_char_tab(_Min,[],_V) ->
- [];
-create_char_tab(Min,L,V) ->
- [false|create_char_tab(Min+1,L,V)].
-
-%% See Table 20.3 in Dubuisson
-charbits(NumOfChars) when NumOfChars =< 2 -> 1;
-charbits(NumOfChars) when NumOfChars =< 4 -> 2;
-charbits(NumOfChars) when NumOfChars =< 8 -> 3;
-charbits(NumOfChars) when NumOfChars =< 16 -> 4;
-charbits(NumOfChars) when NumOfChars =< 32 -> 5;
-charbits(NumOfChars) when NumOfChars =< 64 -> 6;
-charbits(NumOfChars) when NumOfChars =< 128 -> 7;
-charbits(NumOfChars) when NumOfChars =< 256 -> 8;
-charbits(NumOfChars) when NumOfChars =< 512 -> 9;
-charbits(NumOfChars) when NumOfChars =< 1024 -> 10;
-charbits(NumOfChars) when NumOfChars =< 2048 -> 11;
-charbits(NumOfChars) when NumOfChars =< 4096 -> 12;
-charbits(NumOfChars) when NumOfChars =< 8192 -> 13;
-charbits(NumOfChars) when NumOfChars =< 16384 -> 14;
-charbits(NumOfChars) when NumOfChars =< 32768 -> 15;
-charbits(NumOfChars) when NumOfChars =< 65536 -> 16;
-charbits(NumOfChars) when is_integer(NumOfChars) ->
- 16 + charbits1(NumOfChars bsr 16).
-
-charbits1(0) ->
- 0;
-charbits1(NumOfChars) ->
- 1 + charbits1(NumOfChars bsr 1).
-
-
-chars_decode(Bytes,_,'BMPString',C,Len) ->
- case get_constraint(C,'PermittedAlphabet') of
- no ->
- getBMPChars(Bytes,Len);
- _ ->
- exit({error,{asn1,
- {'not implemented',
- "BMPString with PermittedAlphabet constraint"}}})
- end;
-chars_decode(Bytes,NumBits,StringType,C,Len) ->
- CharInTab = get_CharInTab(C,StringType),
- chars_decode2(Bytes,CharInTab,NumBits,Len).
-
-
-chars_decode2(Bytes,CharInTab,NumBits,Len) ->
- chars_decode2(Bytes,CharInTab,NumBits,Len,[]).
-
-chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) ->
- {lists:reverse(Acc),Bytes};
-chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- Result =
- if
- Char < 256 -> Char;
- true ->
- list_to_tuple(binary_to_list(<<Char:32>>))
- end,
- chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]);
-chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]);
-
-%% BMPString and UniversalString with PermittedAlphabet is currently not supported
-chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]).
-
-
-%% UTF8String
-encode_UTF8String(Val) when is_binary(Val) ->
- [encode_length(undefined,size(Val)),Val];
-encode_UTF8String(Val) ->
- Bin = list_to_binary(Val),
- encode_UTF8String(Bin).
-
-decode_UTF8String(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- getoctets_as_bin(Bytes2,Len).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_object_identifier(Val) -> CompleteList
-%% encode_object_identifier({Name,Val}) -> CompleteList
-%% Val -> {Int1,Int2,...,IntN} % N >= 2
-%% Name -> atom()
-%% Int1 -> integer(0..2)
-%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
-%% Int3-N -> integer()
-%% CompleteList -> [binary()|bitstring()|list()]
-%%
-encode_object_identifier({Name,Val}) when is_atom(Name) ->
- encode_object_identifier(Val);
-encode_object_identifier(Val) ->
- OctetList = e_object_identifier(Val),
- Octets = list_to_binary(OctetList), % performs a flatten at the same time
- [encode_length(undefined,size(Octets)),Octets].
-
-%% This code is copied from asn1_encode.erl (BER) and corrected and modified
-
-e_object_identifier({'OBJECT IDENTIFIER',V}) ->
- e_object_identifier(V);
-e_object_identifier({Cname,V}) when is_atom(Cname),is_tuple(V) ->
- e_object_identifier(tuple_to_list(V));
-e_object_identifier({Cname,V}) when is_atom(Cname),is_list(V) ->
- e_object_identifier(V);
-e_object_identifier(V) when is_tuple(V) ->
- e_object_identifier(tuple_to_list(V));
-
-%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
-e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 ->
- Head = 40*E1 + E2, % weird
- e_object_elements([Head|Tail],[]);
-e_object_identifier(Oid=[_,_|_Tail]) ->
- exit({error,{asn1,{'illegal_value',Oid}}}).
-
-e_object_elements([],Acc) ->
- lists:reverse(Acc);
-e_object_elements([H|T],Acc) ->
- e_object_elements(T,[e_object_element(H)|Acc]).
-
-e_object_element(Num) when Num < 128 ->
- [Num];
-e_object_element(Num) ->
- [e_o_e(Num bsr 7)|[Num band 2#1111111]].
-e_o_e(Num) when Num < 128 ->
- Num bor 2#10000000;
-e_o_e(Num) ->
- [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]].
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_object_identifier(Bytes) -> {ObjId,RemainingBytes}
-%% ObjId -> {integer(),integer(),...} % at least 2 integers
-%% RemainingBytes -> [integer()] when integer() (0..255)
-decode_object_identifier(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- [First|Rest] = dec_subidentifiers(Octs,0,[]),
- Idlist = if
- First < 40 ->
- [0,First|Rest];
- First < 80 ->
- [1,First - 40|Rest];
- true ->
- [2,First - 80|Rest]
- end,
- {list_to_tuple(Idlist),Bytes3}.
-
-dec_subidentifiers([H|T],Av,Al) when H >=16#80 ->
- dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al);
-dec_subidentifiers([H|T],Av,Al) ->
- dec_subidentifiers(T,0,[(Av bsl 7) + H |Al]);
-dec_subidentifiers([],_Av,Al) ->
- lists:reverse(Al).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_relative_oid(Val) -> CompleteList
-%% encode_relative_oid({Name,Val}) -> CompleteList
-encode_relative_oid({Name,Val}) when is_atom(Name) ->
- encode_relative_oid(Val);
-encode_relative_oid(Val) when is_tuple(Val) ->
- encode_relative_oid(tuple_to_list(Val));
-encode_relative_oid(Val) when is_list(Val) ->
- Octets = list_to_binary([e_object_element(X)||X <- Val]),
- [encode_length(undefined,size(Octets)),Octets].
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_relative_oid(Val) -> CompleteList
-%% decode_relative_oid({Name,Val}) -> CompleteList
-decode_relative_oid(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- ObjVals = dec_subidentifiers(Octs,0,[]),
- {list_to_tuple(ObjVals),Bytes3}.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_real(Val) -> CompleteList
-%% encode_real({Name,Val}) -> CompleteList
-encode_real({Name,Val}) when is_atom(Name) ->
- encode_real(Val);
-encode_real(Real) ->
- {EncVal,Len} = ?RT_COMMON:encode_real([],Real),
- [encode_length(undefined,Len),EncVal].
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_real(Val) -> {REALvalue,Rest}
-%% decode_real({Name,Val}) -> {REALvalue,Rest}
-decode_real(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- <<Bytes3:Len/binary,Rest/bitstring>> = Bytes2,
- {RealVal,Rest,Len} = ?RT_COMMON:decode_real(Bytes3,Len),
- {RealVal,Rest}.
-
-
-get_constraint([{Key,V}],Key) ->
- V;
-get_constraint([],_Key) ->
- no;
-get_constraint(C,Key) ->
- case lists:keysearch(Key,1,C) of
- false ->
- no;
- {value,{_,V}} ->
- V
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% complete(InList) -> ByteList
-%% Takes a coded list with bits and bytes and converts it to a list of bytes
-%% Should be applied as the last step at encode of a complete ASN.1 type
-%%
-complete(InList) when is_list(InList) ->
- case complete1(InList) of
- <<>> ->
- <<0>>;
- Res ->
- case bit_size(Res) band 7 of
- 0 -> Res;
- Bits -> <<Res/bitstring,0:(8-Bits)>>
- end
- end;
-complete(InList) when is_binary(InList) ->
- InList;
-complete(InList) when is_bitstring(InList) ->
- PadLen = 8 - (bit_size(InList) band 7),
- <<InList/bitstring,0:PadLen>>.
-
-complete1(L) when is_list(L) ->
- list_to_bitstring(L).
-
-%% Special version of complete that does not align the completed message.
-complete_NFP(InList) when is_list(InList) ->
- list_to_bitstring(InList);
-complete_NFP(InList) when is_bitstring(InList) ->
- InList.
-
-%% unaligned helpers
-
-%% 10.5.6 NOTE: If "range" satisfies the inequality 2^m < "range" =<
-%% 2^(m+1) then the number of bits = m + 1
-
-num_bits(N) ->
- num_bits(N,1,0).
-num_bits(N,T,B) when N=<T->B;
-num_bits(N,T,B) ->num_bits(N,T bsl 1, B+1).
diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl
new file mode 100644
index 0000000000..889a421e4f
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -0,0 +1,1561 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_ber).
+
+%% encoding / decoding of BER
+
+-export([ber_decode_nif/1,ber_decode_erlang/1,match_tags/2,ber_encode/1]).
+-export([encode_tags/2,
+ encode_tags/3,
+ skip_ExtensionAdditions/2]).
+-export([encode_boolean/2,decode_boolean/2,
+ encode_integer/2,encode_integer/3,
+ decode_integer/3,decode_integer/4,
+ encode_enumerated/2,decode_enumerated/3,
+ encode_bit_string/4,
+ decode_named_bit_string/3,
+ decode_compact_bit_string/3,
+ decode_legacy_bit_string/3,
+ decode_native_bit_string/3,
+ 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_restricted_string/2,decode_restricted_string/3,
+ encode_universal_string/2,decode_universal_string/3,
+ encode_UTF8_string/2,decode_UTF8_string/2,
+ encode_BMP_string/2,decode_BMP_string/3,
+ encode_generalized_time/2,decode_generalized_time/3,
+ encode_utc_time/2,decode_utc_time/3]).
+
+-export([encode_open_type/2,decode_open_type/2,
+ decode_open_type_as_binary/2]).
+
+-export([decode_primitive_incomplete/2,decode_selective/2]).
+
+%% For DER.
+-export([dynamicsort_SET_components/1,dynamicsort_SETOF/1]).
+
+%% the encoding of class of tag bits 8 and 7
+-define(UNIVERSAL, 0).
+-define(APPLICATION, 16#40).
+-define(CONTEXT, 16#80).
+-define(PRIVATE, 16#C0).
+
+%%% primitive or constructed encoding % bit 6
+-define(PRIMITIVE, 0).
+-define(CONSTRUCTED, 2#00100000).
+
+%%% The tag-number for universal types
+-define(N_BOOLEAN, 1).
+-define(N_INTEGER, 2).
+-define(N_BIT_STRING, 3).
+-define(N_OCTET_STRING, 4).
+-define(N_NULL, 5).
+-define(N_OBJECT_IDENTIFIER, 6).
+-define(N_OBJECT_DESCRIPTOR, 7).
+-define(N_EXTERNAL, 8).
+-define(N_REAL, 9).
+-define(N_ENUMERATED, 10).
+-define(N_EMBEDDED_PDV, 11).
+-define(N_SEQUENCE, 16).
+-define(N_SET, 17).
+-define(N_NumericString, 18).
+-define(N_PrintableString, 19).
+-define(N_TeletexString, 20).
+-define(N_VideotexString, 21).
+-define(N_IA5String, 22).
+-define(N_UTCTime, 23).
+-define(N_GeneralizedTime, 24).
+-define(N_GraphicString, 25).
+-define(N_VisibleString, 26).
+-define(N_GeneralString, 27).
+-define(N_UniversalString, 28).
+-define(N_BMPString, 30).
+
+
+% the complete tag-word of built-in types
+-define(T_BOOLEAN, ?UNIVERSAL bor ?PRIMITIVE bor 1).
+-define(T_INTEGER, ?UNIVERSAL bor ?PRIMITIVE bor 2).
+-define(T_BIT_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
+-define(T_OCTET_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED
+-define(T_NULL, ?UNIVERSAL bor ?PRIMITIVE bor 5).
+-define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6).
+-define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7).
+-define(T_EXTERNAL, ?UNIVERSAL bor ?PRIMITIVE bor 8).
+-define(T_REAL, ?UNIVERSAL bor ?PRIMITIVE bor 9).
+-define(T_ENUMERATED, ?UNIVERSAL bor ?PRIMITIVE bor 10).
+-define(T_EMBEDDED_PDV, ?UNIVERSAL bor ?PRIMITIVE bor 11).
+-define(T_SEQUENCE, ?UNIVERSAL bor ?CONSTRUCTED bor 16).
+-define(T_SET, ?UNIVERSAL bor ?CONSTRUCTED bor 17).
+-define(T_NumericString, ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
+-define(T_PrintableString, ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
+-define(T_TeletexString, ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
+-define(T_VideotexString, ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed
+-define(T_IA5String, ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed
+-define(T_UTCTime, ?UNIVERSAL bor ?PRIMITIVE bor 23).
+-define(T_GeneralizedTime, ?UNIVERSAL bor ?PRIMITIVE bor 24).
+-define(T_GraphicString, ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed
+-define(T_VisibleString, ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed
+-define(T_GeneralString, ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed
+-define(T_UniversalString, ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed
+-define(T_BMPString, ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed
+
+ber_encode([Tlv]) ->
+ ber_encode(Tlv);
+ber_encode(Tlv) when is_binary(Tlv) ->
+ Tlv;
+ber_encode(Tlv) ->
+ asn1rt_nif:encode_ber_tlv(Tlv).
+
+ber_decode_nif(B) ->
+ asn1rt_nif:decode_ber_tlv(B).
+
+ber_decode_erlang(B) when is_binary(B) ->
+ decode_primitive(B);
+ber_decode_erlang(Tlv) ->
+ {Tlv,<<>>}.
+
+decode_primitive(Bin) ->
+ {Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
+ case Form of
+ 1 -> % constructed
+ {{TagNo,decode_constructed(V)},Rest};
+ 0 -> % primitive
+ {{TagNo,V},Rest};
+ 2 -> % constructed indefinite
+ {Vlist,Rest2} = decode_constructed_indefinite(V,[]),
+ {{TagNo,Vlist},Rest2}
+ end.
+
+decode_constructed(Bin) when byte_size(Bin) =:= 0 ->
+ [];
+decode_constructed(Bin) ->
+ {Tlv,Rest} = decode_primitive(Bin),
+ [Tlv|decode_constructed(Rest)].
+
+decode_constructed_indefinite(<<0,0,Rest/binary>>,Acc) ->
+ {lists:reverse(Acc),Rest};
+decode_constructed_indefinite(Bin,Acc) ->
+ {Tlv,Rest} = decode_primitive(Bin),
+ decode_constructed_indefinite(Rest, [Tlv|Acc]).
+
+%% decode_primitive_incomplete/2 decodes an encoded message incomplete
+%% by help of the pattern attribute (first argument).
+decode_primitive_incomplete([[default,TagNo]],Bin) -> %default
+ case decode_tag_and_length(Bin) of
+ {Form,TagNo,V,Rest} ->
+ decode_incomplete2(Form,TagNo,V,[],Rest);
+ _ ->
+ %{asn1_DEFAULT,Bin}
+ asn1_NOVALUE
+ end;
+decode_primitive_incomplete([[default,TagNo,Directives]],Bin) -> %default, constructed type, Directives points into this type
+ case decode_tag_and_length(Bin) of
+ {Form,TagNo,V,Rest} ->
+ decode_incomplete2(Form,TagNo,V,Directives,Rest);
+ _ ->
+ %{asn1_DEFAULT,Bin}
+ asn1_NOVALUE
+ end;
+decode_primitive_incomplete([[opt,TagNo]],Bin) -> %optional
+ case decode_tag_and_length(Bin) of
+ {Form,TagNo,V,Rest} ->
+ decode_incomplete2(Form,TagNo,V,[],Rest);
+ _ ->
+ %{{TagNo,asn1_NOVALUE},Bin}
+ asn1_NOVALUE
+ end;
+decode_primitive_incomplete([[opt,TagNo,Directives]],Bin) -> %optional
+ case decode_tag_and_length(Bin) of
+ {Form,TagNo,V,Rest} ->
+ decode_incomplete2(Form,TagNo,V,Directives,Rest);
+ _ ->
+ %{{TagNo,asn1_NOVALUE},Bin}
+ asn1_NOVALUE
+ end;
+%% An optional that shall be undecoded
+decode_primitive_incomplete([[opt_undec,Tag]],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {_,Tag,_,_} ->
+ decode_incomplete_bin(Bin);
+ _ ->
+ asn1_NOVALUE
+ end;
+%% A choice alternative that shall be undecoded
+decode_primitive_incomplete([[alt_undec,TagNo]|RestAlts],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {_,TagNo,_,_} ->
+ decode_incomplete_bin(Bin);
+ _ ->
+ decode_primitive_incomplete(RestAlts,Bin)
+ end;
+decode_primitive_incomplete([[alt,TagNo]|RestAlts],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {_Form,TagNo,V,Rest} ->
+ {{TagNo,V},Rest};
+ _ ->
+ decode_primitive_incomplete(RestAlts,Bin)
+ end;
+decode_primitive_incomplete([[alt,TagNo,Directives]|RestAlts],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {Form,TagNo,V,Rest} ->
+ decode_incomplete2(Form,TagNo,V,Directives,Rest);
+ _ ->
+ decode_primitive_incomplete(RestAlts,Bin)
+ end;
+decode_primitive_incomplete([[alt_parts,TagNo]],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {_Form,TagNo,V,Rest} ->
+ {{TagNo,V},Rest};
+ _ ->
+ asn1_NOVALUE
+ end;
+decode_primitive_incomplete([[alt_parts,TagNo]|RestAlts],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {_Form,TagNo,V,Rest} ->
+ {{TagNo,decode_parts_incomplete(V)},Rest};
+ _ ->
+ decode_primitive_incomplete(RestAlts,Bin)
+ end;
+decode_primitive_incomplete([[undec,_TagNo]|_RestTag],Bin) -> %incomlete decode
+ decode_incomplete_bin(Bin);
+decode_primitive_incomplete([[parts,TagNo]|_RestTag],Bin) ->
+ case decode_tag_and_length(Bin) of
+ {_Form,TagNo,V,Rest} ->
+ {{TagNo,decode_parts_incomplete(V)},Rest};
+ Err ->
+ {error,{asn1,"tag failure",TagNo,Err}}
+ end;
+decode_primitive_incomplete([mandatory|RestTag],Bin) ->
+ {Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
+ decode_incomplete2(Form,TagNo,V,RestTag,Rest);
+%% A choice that is a toptype or a mandatory component of a
+%% SEQUENCE or SET.
+decode_primitive_incomplete([[mandatory|Directives]],Bin) ->
+ {Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
+ decode_incomplete2(Form,TagNo,V,Directives,Rest);
+decode_primitive_incomplete([],Bin) ->
+ decode_primitive(Bin).
+
+%% decode_parts_incomplete/1 receives a number of values encoded in
+%% sequence and returns the parts as unencoded binaries
+decode_parts_incomplete(<<>>) ->
+ [];
+decode_parts_incomplete(Bin) ->
+ {ok,Rest} = skip_tag(Bin),
+ {ok,Rest2} = skip_length_and_value(Rest),
+ LenPart = byte_size(Bin) - byte_size(Rest2),
+ <<Part:LenPart/binary,RestBin/binary>> = Bin,
+ [Part|decode_parts_incomplete(RestBin)].
+
+
+%% decode_incomplete2 checks if V is a value of a constructed or
+%% primitive type, and continues the decode propeerly.
+decode_incomplete2(_Form=2,TagNo,V,TagMatch,_) ->
+ %% constructed indefinite length
+ {Vlist,Rest2} = decode_constr_indef_incomplete(TagMatch,V,[]),
+ {{TagNo,Vlist},Rest2};
+decode_incomplete2(1,TagNo,V,[TagMatch],Rest) when is_list(TagMatch) ->
+ {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest};
+decode_incomplete2(1,TagNo,V,TagMatch,Rest) ->
+ {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest};
+decode_incomplete2(0,TagNo,V,_TagMatch,Rest) ->
+ {{TagNo,V},Rest}.
+
+decode_constructed_incomplete([Tags=[Ts]],Bin) when is_list(Ts) ->
+ decode_constructed_incomplete(Tags,Bin);
+decode_constructed_incomplete(_TagMatch,<<>>) ->
+ [];
+decode_constructed_incomplete([mandatory|RestTag],Bin) ->
+ {Tlv,Rest} = decode_primitive(Bin),
+ [Tlv|decode_constructed_incomplete(RestTag,Rest)];
+decode_constructed_incomplete(Directives=[[Alt,_]|_],Bin)
+ when Alt =:= alt_undec; Alt =:= alt; Alt =:= alt_parts ->
+ {_Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
+ case incomplete_choice_alt(TagNo, Directives) of
+ {alt_undec,_} ->
+ LenA = byte_size(Bin) - byte_size(Rest),
+ <<A:LenA/binary,Rest/binary>> = Bin,
+ A;
+ {alt,InnerDirectives} ->
+ {Tlv,Rest} = decode_primitive_incomplete(InnerDirectives,V),
+ {TagNo,Tlv};
+ {alt_parts,_} ->
+ [{TagNo,decode_parts_incomplete(V)}];
+ no_match -> %% if a choice alternative was encoded that
+ %% was not specified in the config file,
+ %% thus decode component anonomous.
+ {Tlv,_}=decode_primitive(Bin),
+ Tlv
+ end;
+decode_constructed_incomplete([TagNo|RestTag],Bin) ->
+ case decode_primitive_incomplete([TagNo],Bin) of
+ {Tlv,Rest} ->
+ [Tlv|decode_constructed_incomplete(RestTag,Rest)];
+ asn1_NOVALUE ->
+ decode_constructed_incomplete(RestTag,Bin)
+ end;
+decode_constructed_incomplete([],Bin) ->
+ {Tlv,Rest}=decode_primitive(Bin),
+ [Tlv|decode_constructed_incomplete([],Rest)].
+
+decode_constr_indef_incomplete(_TagMatch,<<0,0,Rest/binary>>,Acc) ->
+ {lists:reverse(Acc),Rest};
+decode_constr_indef_incomplete([Tag|RestTags],Bin,Acc) ->
+ case decode_primitive_incomplete([Tag],Bin) of
+ {Tlv,Rest} ->
+ decode_constr_indef_incomplete(RestTags,Rest,[Tlv|Acc]);
+ asn1_NOVALUE ->
+ decode_constr_indef_incomplete(RestTags,Bin,Acc)
+ end.
+
+
+decode_incomplete_bin(Bin) ->
+ {ok,Rest} = skip_tag(Bin),
+ {ok,Rest2} = skip_length_and_value(Rest),
+ IncLen = byte_size(Bin) - byte_size(Rest2),
+ <<IncBin:IncLen/binary,Ret/binary>> = Bin,
+ {IncBin,Ret}.
+
+incomplete_choice_alt(TagNo,[[Alt,TagNo]|Directives]) ->
+ {Alt,Directives};
+incomplete_choice_alt(TagNo,[D]) when is_list(D) ->
+ incomplete_choice_alt(TagNo,D);
+incomplete_choice_alt(TagNo,[_H|Directives]) ->
+ incomplete_choice_alt(TagNo,Directives);
+incomplete_choice_alt(_,[]) ->
+ no_match.
+
+
+%% decode_selective(Pattern, Binary) the first argument is a pattern that tells
+%% what to do with the next element the second is the BER encoded
+%% message as a binary
+%% Returns {ok,Value} or {error,Reason}
+%% Value is a binary that in turn must be decoded to get the decoded
+%% value.
+decode_selective([],Binary) ->
+ {ok,Binary};
+decode_selective([skip|RestPattern],Binary)->
+ {ok,RestBinary}=skip_tag(Binary),
+ {ok,RestBinary2}=skip_length_and_value(RestBinary),
+ decode_selective(RestPattern,RestBinary2);
+decode_selective([[skip_optional,Tag]|RestPattern],Binary) ->
+ case skip_optional_tag(Tag,Binary) of
+ {ok,RestBinary} ->
+ {ok,RestBinary2}=skip_length_and_value(RestBinary),
+ decode_selective(RestPattern,RestBinary2);
+ missing ->
+ decode_selective(RestPattern,Binary)
+ end;
+decode_selective([[choosen,Tag]],Binary) ->
+ return_value(Tag,Binary);
+decode_selective([[choosen,Tag]|RestPattern],Binary) ->
+ case skip_optional_tag(Tag,Binary) of
+ {ok,RestBinary} ->
+ {ok,Value} = get_value(RestBinary),
+ decode_selective(RestPattern,Value);
+ missing ->
+ {ok,<<>>}
+ end;
+decode_selective(P,_) ->
+ {error,{asn1,{partial_decode,"bad pattern",P}}}.
+
+return_value(Tag,Binary) ->
+ {ok,{Tag,RestBinary}}=get_tag(Binary),
+ {ok,{LenVal,_RestBinary2}} = get_length_and_value(RestBinary),
+ {ok,<<Tag/binary,LenVal/binary>>}.
+
+
+%% skip_tag and skip_length_and_value are rutines used both by
+%% decode_partial_incomplete and decode_selective (decode/2).
+
+skip_tag(<<_:3,31:5,Rest/binary>>)->
+ skip_long_tag(Rest);
+skip_tag(<<_:3,_Tag:5,Rest/binary>>) ->
+ {ok,Rest}.
+
+skip_long_tag(<<1:1,_:7,Rest/binary>>) ->
+ skip_long_tag(Rest);
+skip_long_tag(<<0:1,_:7,Rest/binary>>) ->
+ {ok,Rest}.
+
+skip_optional_tag(<<>>,Binary) ->
+ {ok,Binary};
+skip_optional_tag(<<Tag,RestTag/binary>>,<<Tag,Rest/binary>>) ->
+ skip_optional_tag(RestTag,Rest);
+skip_optional_tag(_,_) ->
+ missing.
+
+
+skip_length_and_value(Binary) ->
+ case decode_length(Binary) of
+ {indefinite,RestBinary} ->
+ skip_indefinite_value(RestBinary);
+ {Length,RestBinary} ->
+ <<_:Length/unit:8,Rest/binary>> = RestBinary,
+ {ok,Rest}
+ end.
+
+skip_indefinite_value(<<0,0,Rest/binary>>) ->
+ {ok,Rest};
+skip_indefinite_value(Binary) ->
+ {ok,RestBinary}=skip_tag(Binary),
+ {ok,RestBinary2} = skip_length_and_value(RestBinary),
+ skip_indefinite_value(RestBinary2).
+
+get_value(Binary) ->
+ case decode_length(Binary) of
+ {indefinite,RestBinary} ->
+ get_indefinite_value(RestBinary,[]);
+ {Length,RestBinary} ->
+ <<Value:Length/binary,_Rest/binary>> = RestBinary,
+ {ok,Value}
+ end.
+
+get_indefinite_value(<<0,0,_Rest/binary>>,Acc) ->
+ {ok,list_to_binary(lists:reverse(Acc))};
+get_indefinite_value(Binary,Acc) ->
+ {ok,{Tag,RestBinary}}=get_tag(Binary),
+ {ok,{LenVal,RestBinary2}} = get_length_and_value(RestBinary),
+ get_indefinite_value(RestBinary2,[LenVal,Tag|Acc]).
+
+get_tag(<<H:1/binary,Rest/binary>>) ->
+ case H of
+ <<_:3,31:5>> ->
+ get_long_tag(Rest,[H]);
+ _ -> {ok,{H,Rest}}
+ end.
+get_long_tag(<<H:1/binary,Rest/binary>>,Acc) ->
+ case H of
+ <<0:1,_:7>> ->
+ {ok,{list_to_binary(lists:reverse([H|Acc])),Rest}};
+ _ ->
+ get_long_tag(Rest,[H|Acc])
+ end.
+
+get_length_and_value(Bin = <<0:1,Length:7,_T/binary>>) ->
+ <<Len,Val:Length/binary,Rest/binary>> = Bin,
+ {ok,{<<Len,Val/binary>>, Rest}};
+get_length_and_value(Bin = <<1:1,0:7,_T/binary>>) ->
+ get_indefinite_length_and_value(Bin);
+get_length_and_value(<<1:1,LL:7,T/binary>>) ->
+ <<Length:LL/unit:8,Rest/binary>> = T,
+ <<Value:Length/binary,Rest2/binary>> = Rest,
+ {ok,{<<1:1,LL:7,Length:LL/unit:8,Value/binary>>,Rest2}}.
+
+get_indefinite_length_and_value(<<H,T/binary>>) ->
+ get_indefinite_length_and_value(T,[H]).
+
+get_indefinite_length_and_value(<<0,0,Rest/binary>>,Acc) ->
+ {ok,{list_to_binary(lists:reverse(Acc)),Rest}};
+get_indefinite_length_and_value(Binary,Acc) ->
+ {ok,{Tag,RestBinary}}=get_tag(Binary),
+ {ok,{LenVal,RestBinary2}}=get_length_and_value(RestBinary),
+ get_indefinite_length_and_value(RestBinary2,[LenVal,Tag|Acc]).
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% match_tags takes a Tlv (Tag, Length, Value) structure and matches
+%% it with the tags in TagList. If the tags does not match the function
+%% crashes otherwise it returns the remaining Tlv after that the tags have
+%% been removed.
+%%
+%% match_tags(Tlv, TagList)
+%%
+
+match_tags({T,V}, [T]) ->
+ V;
+match_tags({T,V}, [T|Tt]) ->
+ match_tags(V,Tt);
+match_tags([{T,V}], [T|Tt]) ->
+ match_tags(V, Tt);
+match_tags([{T,_V}|_]=Vlist, [T]) ->
+ Vlist;
+match_tags(Tlv, []) ->
+ Tlv;
+match_tags({Tag,_V}=Tlv, [T|_Tt]) ->
+ exit({error,{asn1,{wrong_tag,{{expected,T},{got,Tag,Tlv}}}}}).
+
+%%%
+%% skips components that do not match a tag in Tags
+skip_ExtensionAdditions([], _Tags) ->
+ [];
+skip_ExtensionAdditions([{Tag,_}|Rest]=TLV, Tags) ->
+ case [X || X=T <- Tags, T =:= Tag] of
+ [] ->
+ %% skip this TLV and continue with next
+ skip_ExtensionAdditions(Rest,Tags);
+ _ ->
+ TLV
+ end.
+
+
+%%===============================================================================
+%% Decode a tag
+%%
+%% decode_tag(OctetListBuffer) -> {{Form, (Class bsl 16)+ TagNo}, RestOfBuffer, RemovedBytes}
+%%===============================================================================
+
+decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) when TagNo < 31 ->
+ {Form, (Class bsl 16) bor TagNo, V, RestBuffer};
+decode_tag_and_length(<<Class:2, 1:1, TagNo:5, 1:1, 0:7, T/binary>>) when TagNo < 31 ->
+ {2, (Class bsl 16) + TagNo, T, <<>>};
+decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 1:1, LL:7, Length:LL/unit:8,V:Length/binary, T/binary>>) when TagNo < 31 ->
+ {Form, (Class bsl 16) bor TagNo, V, T};
+decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) ->
+ {Form, (Class bsl 16) bor TagNo, V, RestBuffer};
+decode_tag_and_length(<<Class:2, 1:1, 31:5, 0:1, TagNo:7, 1:1, 0:7, T/binary>>) ->
+ {2, (Class bsl 16) bor TagNo, T, <<>>};
+decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 1:1, LL:7, Length:LL/unit:8, V:Length/binary, T/binary>>) ->
+ {Form, (Class bsl 16) bor TagNo, V, T};
+decode_tag_and_length(<<Class:2, Form:1, 31:5, 1:1, TagPart1:7, 0:1, TagPartLast, Buffer/binary>>) ->
+ TagNo = (TagPart1 bsl 7) bor TagPartLast,
+ {Length, RestBuffer} = decode_length(Buffer),
+ << V:Length/binary, RestBuffer2/binary>> = RestBuffer,
+ {Form, (Class bsl 16) bor TagNo, V, RestBuffer2};
+decode_tag_and_length(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
+ {TagNo, Buffer1} = decode_tag(Buffer, 0),
+ {Length, RestBuffer} = decode_length(Buffer1),
+ << V:Length/binary, RestBuffer2/binary>> = RestBuffer,
+ {Form, (Class bsl 16) bor TagNo, V, RestBuffer2}.
+
+
+
+%% last partial tag
+decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck) ->
+ TagNo = (TagAck bsl 7) bor PartialTag,
+ {TagNo, Buffer};
+% more tags
+decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck) ->
+ TagAck1 = (TagAck bsl 7) bor PartialTag,
+ decode_tag(Buffer, TagAck1).
+
+%%=======================================================================
+%%
+%% Encode all tags in the list Tags and return a possibly deep list of
+%% bytes with tag and length encoded
+%% The taglist must be in reverse order (fixed by the asn1 compiler)
+%% e.g [T1,T2] will result in
+%% {[EncodedT2,EncodedT1|BytesSoFar],LenSoFar+LenT2+LenT1}
+%%
+
+encode_tags([Tag|Trest], BytesSoFar, LenSoFar) ->
+ {Bytes2,L2} = encode_length(LenSoFar),
+ encode_tags(Trest, [Tag,Bytes2|BytesSoFar],
+ LenSoFar + byte_size(Tag) + L2);
+encode_tags([], BytesSoFar, LenSoFar) ->
+ {BytesSoFar,LenSoFar}.
+
+encode_tags(TagIn, {BytesSoFar,LenSoFar}) ->
+ encode_tags(TagIn, BytesSoFar, LenSoFar).
+
+%%===============================================================================
+%%
+%% This comment is valid for all the encode/decode functions
+%%
+%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound}
+%% used for PER-coding but not for BER-coding.
+%%
+%% Val = Value. If Val is an atom then it is a symbolic integer value
+%% (i.e the atom must be one of the names in the NamedNumberList).
+%% The NamedNumberList is used to translate the atom to an integer value
+%% before encoding.
+%%
+%%===============================================================================
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_open_type(Value) -> io_list (i.e nested list with integers, binaries)
+%% Value = list of bytes of an already encoded value (the list must be flat)
+%% | binary
+
+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)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% decode_open_type(Tlv, TagIn) -> Value
+%% Tlv = {Tag,V} | V where V -> binary()
+%% TagIn = [TagVal] where TagVal -> int()
+%% Value = binary with decoded data (which must be decoded again as some type)
+%%
+decode_open_type(Tlv, TagIn) ->
+ case match_tags(Tlv, TagIn) of
+ Bin when is_binary(Bin) ->
+ {InnerTlv,_} = ber_decode_nif(Bin),
+ InnerTlv;
+ TlvBytes -> TlvBytes
+ end.
+
+decode_open_type_as_binary(Tlv, TagIn)->
+ ber_encode(match_tags(Tlv, TagIn)).
+
+%%===============================================================================
+%%===============================================================================
+%%===============================================================================
+%% Boolean, ITU_T X.690 Chapter 8.2
+%%===============================================================================
+%%===============================================================================
+%%===============================================================================
+
+%%===============================================================================
+%% encode_boolean(Integer, ReversedTagList) -> {[Octet],Len}
+%%===============================================================================
+
+encode_boolean(true, TagIn) ->
+ encode_tags(TagIn, [16#FF],1);
+encode_boolean(false, TagIn) ->
+ encode_tags(TagIn, [0],1);
+encode_boolean(X,_) ->
+ exit({error,{asn1, {encode_boolean, X}}}).
+
+
+%%===============================================================================
+%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
+%% {false, Remain, RemovedBytes}
+%%===============================================================================
+decode_boolean(Tlv,TagIn) ->
+ Val = match_tags(Tlv, TagIn),
+ case Val of
+ <<0:8>> ->
+ false;
+ <<_:8>> ->
+ true;
+ _ ->
+ exit({error,{asn1, {decode_boolean, Val}}})
+ end.
+
+
+%%===========================================================================
+%% Integer, ITU_T X.690 Chapter 8.3
+
+%% encode_integer(Constraint, Value, Tag) -> [octet list]
+%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
+%% Value = INTEGER | {Name,INTEGER}
+%% Tag = tag | notag
+%%===========================================================================
+
+encode_integer(Val, Tag) when is_integer(Val) ->
+ encode_tags(Tag, encode_integer(Val));
+encode_integer(Val, _Tag) ->
+ exit({error,{asn1,{encode_integer,Val}}}).
+
+
+encode_integer(Val, NamedNumberList, Tag) when is_atom(Val) ->
+ case lists:keyfind(Val, 1, NamedNumberList) of
+ {_, NewVal} ->
+ encode_tags(Tag, encode_integer(NewVal));
+ _ ->
+ exit({error,{asn1, {encode_integer_namednumber, Val}}})
+ end;
+encode_integer(Val, _NamedNumberList, Tag) ->
+ encode_tags(Tag, encode_integer(Val)).
+
+encode_integer(Val) ->
+ Bytes =
+ if
+ Val >= 0 ->
+ encode_integer_pos(Val, []);
+ true ->
+ encode_integer_neg(Val, [])
+ end,
+ {Bytes,length(Bytes)}.
+
+encode_integer_pos(0, [B|_Acc]=L) when B < 128 ->
+ L;
+encode_integer_pos(N, Acc) ->
+ encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
+
+encode_integer_neg(-1, [B1|_T]=L) when B1 > 127 ->
+ L;
+encode_integer_neg(N, Acc) ->
+ encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
+
+%%===============================================================================
+%% decode integer
+%% (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
+%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
+%%===============================================================================
+
+decode_integer(Tlv, Range, NamedNumberList, TagIn) ->
+ V = match_tags(Tlv, TagIn),
+ Int = range_check_integer(decode_integer(V), Range),
+ number2name(Int, NamedNumberList).
+
+decode_integer(Tlv, Range, TagIn) ->
+ V = match_tags(Tlv, TagIn),
+ Int = decode_integer(V),
+ range_check_integer(Int, Range).
+
+decode_integer(Bin) ->
+ Len = byte_size(Bin),
+ <<Int:Len/signed-unit:8>> = Bin,
+ Int.
+
+range_check_integer(Int, Range) ->
+ case Range of
+ [] -> % No length constraint
+ Int;
+ {Lb,Ub} when Int >= Lb, Ub >= Int -> % variable length constraint
+ Int;
+ {_,_} ->
+ exit({error,{asn1,{integer_range,Range,Int}}});
+ Int -> % fixed value constraint
+ Int;
+ SingleValue when is_integer(SingleValue) ->
+ exit({error,{asn1,{integer_range,Range,Int}}});
+ _ -> % some strange constraint that we don't support yet
+ Int
+ end.
+
+number2name(Int, []) ->
+ Int;
+number2name(Int, NamedNumberList) ->
+ case lists:keyfind(Int, 2, NamedNumberList) of
+ {NamedVal,_} ->
+ NamedVal;
+ _ ->
+ 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
+%%
+%% encode bitstring value
+%%
+%% bitstring NamedBitList
+%% Val can be of:
+%% - [identifiers] where only named identifers are set to one,
+%% the Constraint must then have some information of the
+%% bitlength.
+%% - [list of ones and zeroes] all bits
+%% - integer value representing the bitlist
+%% C is constrint Len, only valid when identifiers
+%%============================================================================
+
+encode_bit_string(C, Bits, NamedBitList, TagIn) when is_bitstring(Bits) ->
+ PadLen = (8 - (bit_size(Bits) band 7)) band 7,
+ Compact = {PadLen,<<Bits/bitstring,0:PadLen>>},
+ encode_bin_bit_string(C, Compact, NamedBitList, TagIn);
+encode_bit_string(C,Bin={Unused,BinBits},NamedBitList,TagIn) when is_integer(Unused), is_binary(BinBits) ->
+ encode_bin_bit_string(C,Bin,NamedBitList,TagIn);
+encode_bit_string(C, [FirstVal | RestVal], NamedBitList, TagIn) when is_atom(FirstVal) ->
+ encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn);
+
+encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, TagIn) ->
+ encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, TagIn);
+
+encode_bit_string(C, [FirstVal| RestVal], NamedBitList, TagIn) when is_integer(FirstVal) ->
+ encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, TagIn);
+
+encode_bit_string(_C, 0, _NamedBitList, TagIn) ->
+ encode_tags(TagIn, <<0>>,1);
+
+encode_bit_string(_C, [], _NamedBitList, TagIn) ->
+ encode_tags(TagIn, <<0>>,1);
+
+encode_bit_string(C, IntegerVal, NamedBitList, TagIn) when is_integer(IntegerVal) ->
+ BitListVal = int_to_bitlist(IntegerVal),
+ encode_bit_string_bits(C, BitListVal, NamedBitList, TagIn).
+
+
+int_to_bitlist(0) ->
+ [];
+int_to_bitlist(Int) when is_integer(Int), Int >= 0 ->
+ [Int band 1 | int_to_bitlist(Int bsr 1)].
+
+
+%%=================================================================
+%% Encode BIT STRING of the form {Unused,BinBits}.
+%% Unused is the number of unused bits in the last byte in BinBits
+%% and BinBits is a binary representing the BIT STRING.
+%%=================================================================
+encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,TagIn)->
+ case get_constraint(C,'SizeConstraint') of
+ no ->
+ remove_unused_then_dotag(TagIn, Unused, BinBits);
+ {_Min,Max} ->
+ BBLen = (byte_size(BinBits)*8)-Unused,
+ if
+ BBLen > Max ->
+ exit({error,{asn1,
+ {bitstring_length,
+ {{was,BBLen},{maximum,Max}}}}});
+ true ->
+ remove_unused_then_dotag(TagIn, Unused, BinBits)
+ end;
+ Size ->
+ case ((byte_size(BinBits)*8)-Unused) of
+ BBSize when BBSize =< Size ->
+ remove_unused_then_dotag(TagIn, Unused, BinBits);
+ BBSize ->
+ exit({error,{asn1,
+ {bitstring_length,
+ {{was,BBSize},{should_be,Size}}}}})
+ end
+ end.
+
+remove_unused_then_dotag(TagIn,Unused,BinBits) ->
+ case Unused of
+ 0 when byte_size(BinBits) =:= 0 ->
+ encode_tags(TagIn, <<0>>, 1);
+ 0 ->
+ Bin = <<Unused,BinBits/binary>>,
+ encode_tags(TagIn,Bin,size(Bin));
+ Num ->
+ N = byte_size(BinBits)-1,
+ <<BBits:N/binary,LastByte>> = BinBits,
+ encode_tags(TagIn,
+ [Unused,binary_to_list(BBits) ++[(LastByte bsr Num) bsl Num]],
+ 1+byte_size(BinBits))
+ end.
+
+
+%%=================================================================
+%% Encode named bits
+%%=================================================================
+
+encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn) ->
+ ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
+ Size =
+ case get_constraint(C,'SizeConstraint') of
+ no ->
+ 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).
+
+
+%%----------------------------------------
+%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
+%% [sorted_list_of_bitpositions_to_set]
+%%----------------------------------------
+
+get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
+ get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
+get_all_bitposes([Val | Rest], NamedBitList, Ack) when is_atom(Val) ->
+ case lists:keyfind(Val, 1, NamedBitList) of
+ {_ValName, ValPos} ->
+ get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
+ _ ->
+ exit({error,{asn1, {bitstring_namedbit, Val}}})
+ end;
+get_all_bitposes([], _NamedBitList, Ack) ->
+ lists:sort(Ack).
+
+
+%%----------------------------------------
+%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
+%% returns list of Len length, with all in SetPos set.
+%% in positioning in list the first element is 0, the second 1 etc.., but
+%% Len will make a list of length Len, not Len + 1.
+%% BitList = make_and_set_list(C, ToSetPos, 0),
+%%----------------------------------------
+
+make_and_set_list(0, [], _) -> [];
+make_and_set_list(0, _, _) ->
+ exit({error,{asn1,bitstring_sizeconstraint}});
+make_and_set_list(Len, [XPos|SetPos], XPos) ->
+ [1 | make_and_set_list(Len - 1, SetPos, XPos + 1)];
+make_and_set_list(Len, [Pos|SetPos], XPos) ->
+ [0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
+make_and_set_list(Len, [], XPos) ->
+ [0 | make_and_set_list(Len - 1, [], XPos + 1)].
+
+
+
+
+
+
+%%=================================================================
+%% Encode bit string for lists of ones and zeroes
+%%=================================================================
+encode_bit_string_bits(C, BitListVal, _NamedBitList, TagIn) when is_list(BitListVal) ->
+ case get_constraint(C,'SizeConstraint') of
+ no ->
+ {Len, Unused, OctetList} = encode_bitstring(BitListVal),
+ %%add unused byte to the Len
+ encode_tags(TagIn, [Unused | OctetList], Len+1);
+ Constr={Min,_Max} when is_integer(Min) ->
+ %% Max may be an integer or 'MAX'
+ encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
+ {Constr={_,_},[]} ->%Constr={Min,Max}
+ %% constraint with extension mark
+ encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
+ Constr={{_,_},{_,_}} ->%{{Min1,Max1},{Min2,Max2}}
+ %% constraint with extension mark
+ encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
+ Size ->
+ case length(BitListVal) of
+ BitSize when BitSize == Size ->
+ {Len, Unused, OctetList} = encode_bitstring(BitListVal),
+ %%add unused byte to the Len
+ encode_tags(TagIn, [Unused | OctetList], Len+1);
+ BitSize when BitSize < Size ->
+ PaddedList = pad_bit_list(Size-BitSize,BitListVal),
+ {Len, Unused, OctetList} = encode_bitstring(PaddedList),
+ %%add unused byte to the Len
+ encode_tags(TagIn, [Unused | OctetList], Len+1);
+ BitSize ->
+ exit({error,{asn1,
+ {bitstring_length, {{was,BitSize},{should_be,Size}}}}})
+ end
+
+ end.
+
+encode_constr_bit_str_bits({{_Min1,Max1},{Min2,Max2}},BitListVal,TagIn) ->
+ BitLen = length(BitListVal),
+ case BitLen of
+ Len when Len > Max2 ->
+ exit({error,{asn1,{bitstring_length,{{was,BitLen},
+ {maximum,Max2}}}}});
+ Len when Len > Max1, Len < Min2 ->
+ exit({error,{asn1,{bitstring_length,{{was,BitLen},
+ {not_allowed_interval,
+ Max1,Min2}}}}});
+ _ ->
+ {Len, Unused, OctetList} = encode_bitstring(BitListVal),
+ %%add unused byte to the Len
+ encode_tags(TagIn, [Unused, OctetList], Len+1)
+ end;
+encode_constr_bit_str_bits({Min,Max},BitListVal,TagIn) ->
+ BitLen = length(BitListVal),
+ if
+ BitLen > Max ->
+ exit({error,{asn1,{bitstring_length,{{was,BitLen},
+ {maximum,Max}}}}});
+ BitLen < Min ->
+ exit({error,{asn1,{bitstring_length,{{was,BitLen},
+ {minimum,Max}}}}});
+ true ->
+ {Len, Unused, OctetList} = encode_bitstring(BitListVal),
+ %%add unused byte to the Len
+ encode_tags(TagIn, [Unused, OctetList], Len+1)
+ end.
+
+
+%% returns a list of length Size + length(BitListVal), with BitListVal
+%% as the most significant elements followed by padded zero elements
+pad_bit_list(Size, BitListVal) ->
+ Tail = lists:duplicate(Size,0),
+ lists:append(BitListVal, Tail).
+
+%%=================================================================
+%% Do the actual encoding
+%% ([bitlist]) -> {ListLen, UnusedBits, OctetList}
+%%=================================================================
+
+encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
+ Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
+ (B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
+ encode_bitstring(Rest, [Val], 1);
+encode_bitstring(Val) ->
+ {Unused, Octet} = unused_bitlist(Val, 7, 0),
+ {1, Unused, [Octet]}.
+
+encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) ->
+ Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
+ (B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
+ encode_bitstring(Rest, [Ack | [Val]], Len + 1);
+%%even multiple of 8 bits..
+encode_bitstring([], Ack, Len) ->
+ {Len, 0, Ack};
+%% unused bits in last octet
+encode_bitstring(Rest, Ack, Len) ->
+ {Unused, Val} = unused_bitlist(Rest, 7, 0),
+ {Len + 1, Unused, [Ack | [Val]]}.
+
+%%%%%%%%%%%%%%%%%%
+%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
+%% {Unused bits, Last octet with bits moved to right}
+unused_bitlist([], Trail, Ack) ->
+ {Trail + 1, Ack};
+unused_bitlist([Bit | Rest], Trail, Ack) ->
+ unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack).
+
+
+%%============================================================================
+%% decode bitstring value
+%%============================================================================
+
+decode_compact_bit_string(Buffer, Range, 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)
+ 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).
+
+decode_native_bit_string(Buffer, Range, 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)
+ end.
+
+decode_named_bit_string(Buffer, NamedNumberList, Tags) ->
+ case match_and_collect(Buffer, Tags) of
+ <<0>> ->
+ [];
+ <<Unused,Bits/binary>> ->
+ BitString = decode_bitstring2(byte_size(Bits), Unused, Bits),
+ decode_bitstring_NNL(BitString, NamedNumberList)
+ end.
+
+%%----------------------------------------
+%% Decode the in buffer to bits
+%%----------------------------------------
+decode_bitstring2(1, Unused,
+ <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) ->
+ lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0], 8-Unused);
+decode_bitstring2(Len, Unused,
+ <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
+ [B7,B6,B5,B4,B3,B2,B1,B0|
+ decode_bitstring2(Len - 1, Unused, Buffer)].
+
+%%----------------------------------------
+%% Decode the bitlist to names
+%%----------------------------------------
+
+decode_bitstring_NNL(BitList, NamedNumberList) ->
+ decode_bitstring_NNL(BitList, NamedNumberList, 0, []).
+
+
+decode_bitstring_NNL([],_,_No,Result) ->
+ lists:reverse(Result);
+decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
+ if
+ B =:= 0 ->
+ decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
+ true ->
+ decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
+ end;
+decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
+ decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
+decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
+ decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
+
+%%============================================================================
+%% Null value, ITU_T X.690 Chapter 8.8
+%%
+%% encode NULL value
+%%============================================================================
+
+encode_null(_Val, TagIn) ->
+ encode_tags(TagIn, [], 0).
+
+%%============================================================================
+%% decode NULL value
+%% (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
+%%============================================================================
+
+decode_null(Tlv, Tags) ->
+ Val = match_tags(Tlv, Tags),
+ case Val of
+ <<>> ->
+ 'NULL';
+ _ ->
+ exit({error,{asn1,{decode_null,Val}}})
+ end.
+
+%%============================================================================
+%% Object identifier, ITU_T X.690 Chapter 8.19
+%%
+%% encode Object Identifier value
+%%============================================================================
+
+encode_object_identifier(Val, TagIn) ->
+ encode_tags(TagIn, e_object_identifier(Val)).
+
+e_object_identifier({'OBJECT IDENTIFIER', V}) ->
+ e_object_identifier(V);
+e_object_identifier(V) when is_tuple(V) ->
+ e_object_identifier(tuple_to_list(V));
+
+%%%%%%%%%%%%%%%
+%% e_object_identifier([List of Obect Identifiers]) ->
+%% {[Encoded Octetlist of ObjIds], IntLength}
+%%
+e_object_identifier([E1,E2|Tail]) ->
+ Head = 40*E1 + E2, % wow!
+ {H,Lh} = mk_object_val(Head),
+ {R,Lr} = lists:mapfoldl(fun enc_obj_id_tail/2, 0, Tail),
+ {[H|R],Lh+Lr}.
+
+enc_obj_id_tail(H, Len) ->
+ {B,L} = mk_object_val(H),
+ {B,Len+L}.
+
+
+%%%%%%%%%%%
+%% mk_object_val(Value) -> {OctetList, Len}
+%% returns a Val as a list of octets, the 8th bit is always set to one
+%% except for the last octet, where it's 0
+%%
+
+
+mk_object_val(Val) when Val =< 127 ->
+ {[255 band Val], 1};
+mk_object_val(Val) ->
+ mk_object_val(Val bsr 7, [Val band 127], 1).
+mk_object_val(0, Ack, Len) ->
+ {Ack, Len};
+mk_object_val(Val, Ack, Len) ->
+ mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
+
+
+
+%%============================================================================
+%% decode Object Identifier value
+%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
+%%============================================================================
+
+decode_object_identifier(Tlv, Tags) ->
+ Val = match_tags(Tlv, Tags),
+ [AddedObjVal|ObjVals] = dec_subidentifiers(Val,0,[]),
+ {Val1, Val2} = if
+ AddedObjVal < 40 ->
+ {0, AddedObjVal};
+ AddedObjVal < 80 ->
+ {1, AddedObjVal - 40};
+ true ->
+ {2, AddedObjVal - 80}
+ end,
+ list_to_tuple([Val1, Val2 | ObjVals]).
+
+dec_subidentifiers(<<>>,_Av,Al) ->
+ lists:reverse(Al);
+dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al) ->
+ dec_subidentifiers(T,(Av bsl 7) + H,Al);
+dec_subidentifiers(<<H,T/binary>>,Av,Al) ->
+ dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al]).
+
+%%============================================================================
+%% RELATIVE-OID, ITU_T X.690 Chapter 8.20
+%%
+%% encode Relative Object Identifier
+%%============================================================================
+
+encode_relative_oid(Val,TagIn) when is_tuple(Val) ->
+ encode_relative_oid(tuple_to_list(Val),TagIn);
+encode_relative_oid(Val,TagIn) ->
+ encode_tags(TagIn, enc_relative_oid(Val)).
+
+enc_relative_oid(Tuple) when is_tuple(Tuple) ->
+ enc_relative_oid(tuple_to_list(Tuple));
+enc_relative_oid(Val) ->
+ lists:mapfoldl(fun(X,AccIn) ->
+ {SO,L} = mk_object_val(X),
+ {SO,L+AccIn}
+ end, 0, Val).
+
+%%============================================================================
+%% decode Relative Object Identifier value
+%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
+%%============================================================================
+decode_relative_oid(Tlv, Tags) ->
+ Val = match_tags(Tlv, Tags),
+ ObjVals = dec_subidentifiers(Val,0,[]),
+ list_to_tuple(ObjVals).
+
+%%============================================================================
+%% Restricted character string types, ITU_T X.690 Chapter 8.20
+%%
+%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
+%%============================================================================
+encode_restricted_string(OctetList, TagIn) when is_binary(OctetList) ->
+ encode_tags(TagIn, OctetList, byte_size(OctetList));
+encode_restricted_string(OctetList, TagIn) when is_list(OctetList) ->
+ encode_tags(TagIn, OctetList, length(OctetList)).
+
+%%============================================================================
+%% 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, StrLen, Range) ->
+ case Range of
+ {Lb,Ub} when StrLen >= Lb, Ub >= StrLen -> % variable length constraint
+ Val;
+ {{Lb,_Ub},[]} when StrLen >= Lb ->
+ Val;
+ {{Lb,_Ub},_Ext=[Min|_]} when StrLen >= Lb; StrLen >= Min ->
+ Val;
+ {{Lb1,Ub1},{Lb2,Ub2}} when StrLen >= Lb1, StrLen =< Ub1;
+ StrLen =< Ub2, StrLen >= Lb2 ->
+ Val;
+ StrLen -> % fixed length constraint
+ Val;
+ {_,_} ->
+ exit({error,{asn1,{length,Range,Val}}});
+ _Len when is_integer(_Len) ->
+ exit({error,{asn1,{length,Range,Val}}});
+ _ -> % some strange constraint that we don't support yet
+ Val
+ end.
+
+
+%%============================================================================
+%% encode Universal string
+%%============================================================================
+
+encode_universal_string(Universal, TagIn) ->
+ OctetList = mk_uni_list(Universal),
+ encode_tags(TagIn, OctetList, length(OctetList)).
+
+mk_uni_list(In) ->
+ mk_uni_list(In,[]).
+
+mk_uni_list([],List) ->
+ lists:reverse(List);
+mk_uni_list([{A,B,C,D}|T],List) ->
+ mk_uni_list(T,[D,C,B,A|List]);
+mk_uni_list([H|T],List) ->
+ mk_uni_list(T,[H,0,0,0|List]).
+
+%%===========================================================================
+%% decode Universal strings
+%% (Buffer, Range, StringType, HasTag, LenIn) ->
+%% {String, Remain, RemovedBytes}
+%%===========================================================================
+
+decode_universal_string(Buffer, Range, 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(In) ->
+ mk_universal_string(In, []).
+
+mk_universal_string([], Acc) ->
+ lists:reverse(Acc);
+mk_universal_string([0,0,0,D|T], Acc) ->
+ mk_universal_string(T, [D|Acc]);
+mk_universal_string([A,B,C,D|T], Acc) ->
+ mk_universal_string(T, [{A,B,C,D}|Acc]).
+
+
+%%============================================================================
+%% encode UTF8 string
+%%============================================================================
+
+encode_UTF8_string(UTF8String, TagIn) when is_binary(UTF8String) ->
+ encode_tags(TagIn, UTF8String, byte_size(UTF8String));
+encode_UTF8_string(UTF8String, TagIn) ->
+ encode_tags(TagIn, UTF8String, length(UTF8String)).
+
+
+%%============================================================================
+%% decode UTF8 string
+%%============================================================================
+
+decode_UTF8_string(Tlv,TagsIn) ->
+ Val = match_tags(Tlv, TagsIn),
+ case Val of
+ [_|_]=PartList -> % constructed val
+ collect_parts(PartList);
+ Bin ->
+ Bin
+ end.
+
+
+%%============================================================================
+%% encode BMP string
+%%============================================================================
+
+encode_BMP_string(BMPString, TagIn) ->
+ OctetList = mk_BMP_list(BMPString),
+ encode_tags(TagIn, OctetList, length(OctetList)).
+
+mk_BMP_list(In) ->
+ mk_BMP_list(In, []).
+
+mk_BMP_list([],List) ->
+ lists:reverse(List);
+mk_BMP_list([{0,0,C,D}|T], List) ->
+ mk_BMP_list(T, [D,C|List]);
+mk_BMP_list([H|T], List) ->
+ mk_BMP_list(T, [H,0|List]).
+
+%%============================================================================
+%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList}
+%% (Buffer, Range, StringType, HasTag, TotalLen) ->
+%% {String, Remain, RemovedBytes}
+%%============================================================================
+decode_BMP_string(Buffer, Range, 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(In) ->
+ mk_BMP_string(In,[]).
+
+mk_BMP_string([], US) ->
+ lists:reverse(US);
+mk_BMP_string([0,B|T], US) ->
+ mk_BMP_string(T, [B|US]);
+mk_BMP_string([C,D|T], US) ->
+ mk_BMP_string(T, [{0,0,C,D}|US]).
+
+
+%%============================================================================
+%% Generalized time, ITU_T X.680 Chapter 39
+%%
+%% encode Generalized time
+%%============================================================================
+
+encode_generalized_time(OctetList, TagIn) ->
+ encode_tags(TagIn, OctetList, length(OctetList)).
+
+%%============================================================================
+%% decode Generalized time
+%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
+%%============================================================================
+
+decode_generalized_time(Tlv, _Range, Tags) ->
+ Val = match_tags(Tlv, Tags),
+ NewVal = case Val of
+ [_H|_T]=PartList -> % constructed
+ collect_parts(PartList);
+ Bin ->
+ Bin
+ end,
+ binary_to_list(NewVal).
+
+%%============================================================================
+%% Universal time, ITU_T X.680 Chapter 40
+%%
+%% encode UTC time
+%%============================================================================
+
+encode_utc_time(OctetList, TagIn) ->
+ encode_tags(TagIn, OctetList, length(OctetList)).
+
+%%============================================================================
+%% decode UTC time
+%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
+%%============================================================================
+
+decode_utc_time(Tlv, _Range, Tags) ->
+ Val = match_tags(Tlv, Tags),
+ NewVal = case Val of
+ [_|_]=PartList -> % constructed
+ collect_parts(PartList);
+ Bin ->
+ Bin
+ end,
+ binary_to_list(NewVal).
+
+
+%%============================================================================
+%% Length handling
+%%
+%% Encode length
+%%
+%% encode_length(Int) ->
+%% [<127]| [128 + Int (<127),OctetList] | [16#80]
+%%============================================================================
+
+encode_length(L) when L =< 16#7F ->
+ {[L],1};
+encode_length(L) ->
+ Oct = minimum_octets(L),
+ Len = length(Oct),
+ if
+ Len =< 126 ->
+ {[16#80 bor Len|Oct],Len+1};
+ true ->
+ exit({error,{asn1, too_long_length_oct, Len}})
+ end.
+
+%% Val must be >= 0
+minimum_octets(Val) ->
+ minimum_octets(Val, []).
+
+minimum_octets(0, Acc) ->
+ Acc;
+minimum_octets(Val, Acc) ->
+ minimum_octets(Val bsr 8, [Val band 16#FF|Acc]).
+
+
+%%===========================================================================
+%% Decode length
+%%
+%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |
+%% {{Length, RestOctetsL}, NoRemovedBytes}
+%%===========================================================================
+
+decode_length(<<1:1,0:7,T/binary>>) ->
+ {indefinite,T};
+decode_length(<<0:1,Length:7,T/binary>>) ->
+ {Length,T};
+decode_length(<<1:1,LL:7,Length:LL/unit:8,T/binary>>) ->
+ {Length,T}.
+
+%% dynamicsort_SET_components(Arg) ->
+%% Res Arg -> list()
+%% Res -> list()
+%% Sorts the elements in Arg according to the encoded tag in
+%% increasing order.
+dynamicsort_SET_components(ListOfEncCs) ->
+ TagBinL = [begin
+ Bin = list_to_binary(L),
+ {dynsort_decode_tag(Bin),Bin}
+ end || L <- ListOfEncCs],
+ [E || {_,E} <- lists:keysort(1, TagBinL)].
+
+%% dynamicsort_SETOF(Arg) -> Res
+%% Arg -> list()
+%% Res -> list()
+%% Sorts the elements in Arg in increasing size
+dynamicsort_SETOF(ListOfEncVal) ->
+ BinL = lists:map(fun(L) when is_list(L) -> list_to_binary(L);
+ (B) -> B end, ListOfEncVal),
+ lists:sort(BinL).
+
+%% multiple octet tag
+dynsort_decode_tag(<<Class:2,_Form:1,31:5,Buffer/binary>>) ->
+ TagNum = dynsort_decode_tag(Buffer, 0),
+ {Class,TagNum};
+
+%% single tag (< 31 tags)
+dynsort_decode_tag(<<Class:2,_Form:1,TagNum:5,_/binary>>) ->
+ {Class,TagNum}.
+
+dynsort_decode_tag(<<0:1,PartialTag:7,_/binary>>, TagAcc) ->
+ (TagAcc bsl 7) bor PartialTag;
+dynsort_decode_tag(<<_:1,PartialTag:7,Buffer/binary>>, TagAcc0) ->
+ TagAcc = (TagAcc0 bsl 7) bor PartialTag,
+ dynsort_decode_tag(Buffer, TagAcc).
+
+
+%%-------------------------------------------------------------------------
+%% INTERNAL HELPER FUNCTIONS (not exported)
+%%-------------------------------------------------------------------------
+
+match_and_collect(Tlv, TagsIn) ->
+ Val = match_tags(Tlv, TagsIn),
+ case Val of
+ [_|_]=PartList -> % constructed val
+ collect_parts(PartList);
+ Bin when is_binary(Bin) ->
+ Bin
+ end.
+
+get_constraint(C, Key) ->
+ case lists:keyfind(Key, 1, C) of
+ false ->
+ no;
+ {_,V} ->
+ V
+ end.
+
+collect_parts(TlvList) ->
+ collect_parts(TlvList, []).
+
+collect_parts([{_,L}|Rest], Acc) when is_list(L) ->
+ collect_parts(Rest, [collect_parts(L)|Acc]);
+collect_parts([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest], _Acc) ->
+ collect_parts_bit(Rest, [Bits], Unused);
+collect_parts([{_T,V}|Rest], Acc) ->
+ collect_parts(Rest, [V|Acc]);
+collect_parts([], Acc) ->
+ list_to_binary(lists:reverse(Acc)).
+
+collect_parts_bit([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest], Acc, Uacc) ->
+ collect_parts_bit(Rest, [Bits|Acc], Unused+Uacc);
+collect_parts_bit([], Acc, Uacc) ->
+ list_to_binary([Uacc|lists:reverse(Acc)]).
diff --git a/lib/asn1/src/asn1rtt_check.erl b/lib/asn1/src/asn1rtt_check.erl
new file mode 100644
index 0000000000..e78b65a8fb
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_check.erl
@@ -0,0 +1,276 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_check).
+
+-export([check_bool/2,
+ check_int/3,
+ check_bitstring/3,
+ 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_int(_, asn1_DEFAULT, _) ->
+ true;
+check_int(Value, Value, _) when is_integer(Value) ->
+ true;
+check_int(DefValue, Value, NNL) when is_atom(Value) ->
+ case lists:keyfind(Value, 1, NNL) of
+ {_,DefValue} ->
+ true;
+ _ ->
+ throw({error,DefValue})
+ end;
+check_int(DefaultValue, _Value, _) ->
+ throw({error,DefaultValue}).
+
+%% Two equal lists or integers
+check_bitstring(_, asn1_DEFAULT, _) ->
+ true;
+check_bitstring(V, V, _) ->
+ true;
+%% Default value as a list of 1 and 0 and user value as an integer
+check_bitstring(L=[H|T], Int, _) when is_integer(Int), is_integer(H) ->
+ case bit_list_to_int(L, length(T)) of
+ Int -> true;
+ _ -> throw({error,L,Int})
+ end;
+%% Default value as an integer, val as list
+check_bitstring(Int, Val, NBL) when is_integer(Int), is_list(Val) ->
+ BL = int_to_bit_list(Int, [], length(Val)),
+ check_bitstring(BL, Val, NBL);
+%% Default value and user value as lists of ones and zeros
+check_bitstring(L1=[H1|_T1], L2=[H2|_T2], NBL=[_H|_T]) when is_integer(H1), is_integer(H2) ->
+ L2new = remove_trailing_zeros(L2),
+ check_bitstring(L1, L2new, NBL);
+%% Default value as a list of 1 and 0 and user value as a list of atoms
+check_bitstring(L1=[H1|_T1], L2=[H2|_T2], NBL) when is_integer(H1), is_atom(H2) ->
+ L3 = bit_list_to_nbl(L1, NBL, 0, []),
+ check_bitstring(L3, L2, NBL);
+%% Both default value and user value as a list of atoms
+check_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_bitstring(L1=[H1|_T1], L2=[H2|_T2], NBL) when is_atom(H1), is_integer(H2) ->
+ L3 = bit_list_to_nbl(L2, NBL, 0, []),
+ check_bitstring(L1, L3, NBL);
+%% User value in compact format
+check_bitstring(DefVal,CBS={_,_}, NBL) ->
+ NewVal = cbs_to_bit_list(CBS),
+ check_bitstring(DefVal, NewVal, NBL);
+check_bitstring(DV, V, _) ->
+ throw({error,DV,V}).
+
+
+bit_list_to_int([0|Bs], ShL)->
+ bit_list_to_int(Bs, ShL-1) + 0;
+bit_list_to_int([1|Bs], ShL) ->
+ bit_list_to_int(Bs, ShL-1) + (1 bsl ShL);
+bit_list_to_int([], _) ->
+ 0.
+
+int_to_bit_list(0, Acc, 0) ->
+ Acc;
+int_to_bit_list(Int, Acc, Len) ->
+ 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({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).
+
+
+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})
+ 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) ->
+ true;
+check_null('NULL', 'NULL') ->
+ true;
+check_null(_, V) ->
+ throw({error,V}).
+
+check_objectidentifier(_, asn1_DEFAULT) ->
+ true;
+check_objectidentifier(OI, OI) ->
+ 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})
+ end;
+check_objectidentifier1([], [], _) ->
+ 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_objectdescriptor(_, asn1_DEFAULT) ->
+ true;
+check_objectdescriptor(OD, OD) ->
+ true;
+check_objectdescriptor(OD, OD) ->
+ throw({error,{not_implemented_yet,check_objectdescriptor}}).
+
+check_real(_, asn1_DEFAULT) ->
+ true;
+check_real(R, R) ->
+ true;
+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]) ->
+ check_restrictedstring(Rest1, Rest2);
+check_restrictedstring([V1|Rest1], [V2|Rest2]) ->
+ check_restrictedstring(V1, V2),
+ check_restrictedstring(Rest1, Rest2);
+%% tuple format of value
+check_restrictedstring({V1,V2}, [V1,V2]) ->
+ true;
+check_restrictedstring([V1,V2], {V1,V2}) ->
+ true;
+%% quadruple format of value
+check_restrictedstring({V1,V2,V3,V4}, [V1,V2,V3,V4]) ->
+ true;
+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}}).
diff --git a/lib/asn1/src/asn1rtt_ext.erl b/lib/asn1/src/asn1rtt_ext.erl
new file mode 100644
index 0000000000..7510b01f17
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_ext.erl
@@ -0,0 +1,72 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_ext).
+-export([transform_to_EXTERNAL1990/1,transform_to_EXTERNAL1994/1]).
+
+transform_to_EXTERNAL1990({_,_,_,_}=Val) ->
+ transform_to_EXTERNAL1990(tuple_to_list(Val), []);
+transform_to_EXTERNAL1990(Val) when is_tuple(Val) ->
+ %% Data already in ASN1 1990 format
+ Val.
+
+transform_to_EXTERNAL1990(['EXTERNAL'|Rest], Acc) ->
+ transform_to_EXTERNAL1990(Rest, ['EXTERNAL'|Acc]);
+transform_to_EXTERNAL1990([{syntax,Syntax}|Rest], Acc) ->
+ transform_to_EXTERNAL1990(Rest, [asn1_NOVALUE,Syntax|Acc]);
+transform_to_EXTERNAL1990([{'presentation-context-id',PCid}|Rest], Acc) ->
+ transform_to_EXTERNAL1990(Rest, [PCid,asn1_NOVALUE|Acc]);
+transform_to_EXTERNAL1990([{'context-negotiation',Context_negot}|Rest], Acc) ->
+ {_,Presentation_Cid,Transfer_syntax} = Context_negot,
+ transform_to_EXTERNAL1990(Rest, [Presentation_Cid,Transfer_syntax|Acc]);
+transform_to_EXTERNAL1990([asn1_NOVALUE|Rest], Acc) ->
+ transform_to_EXTERNAL1990(Rest, [asn1_NOVALUE|Acc]);
+transform_to_EXTERNAL1990([Data_val_desc,Data_value], Acc)
+ when is_list(Data_value)->
+ list_to_tuple(lists:reverse([{'octet-aligned',Data_value},
+ Data_val_desc|Acc]));
+transform_to_EXTERNAL1990([Data_val_desc,Data_value], Acc)
+ when is_binary(Data_value) ->
+ list_to_tuple(lists:reverse([{'single-ASN1-type',Data_value},
+ Data_val_desc|Acc]));
+transform_to_EXTERNAL1990([Data_value], Acc)
+ when is_list(Data_value); is_binary(Data_value) ->
+ list_to_tuple(lists:reverse([{'octet-aligned',Data_value}|Acc])).
+
+
+transform_to_EXTERNAL1994({'EXTERNAL',DRef,IndRef,Data_v_desc,Encoding}=V) ->
+ Identification =
+ case {DRef,IndRef} of
+ {DRef,asn1_NOVALUE} ->
+ {syntax,DRef};
+ {asn1_NOVALUE,IndRef} ->
+ {'presentation-context-id',IndRef};
+ _ ->
+ {'context-negotiation',
+ {'EXTERNAL_identification_context-negotiation',IndRef,DRef}}
+ end,
+ case Encoding of
+ {'octet-aligned',Val} when is_list(Val); is_binary(Val) ->
+ %% Transform to the EXTERNAL 1994 definition.
+ {'EXTERNAL',Identification,Data_v_desc,Val};
+ _ ->
+ %% Keep the EXTERNAL 1990 definition to avoid losing
+ %% information.
+ V
+ end.
diff --git a/lib/asn1/src/asn1rtt_per.erl b/lib/asn1/src/asn1rtt_per.erl
new file mode 100644
index 0000000000..4713125ffc
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_per.erl
@@ -0,0 +1,976 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_per).
+
+-export([setext/1, fixextensions/2,
+ skipextensions/3, getbit/1, getchoice/3,
+ set_choice/3,encode_integer/2,
+ encode_small_number/1,
+ encode_constrained_number/2,
+ encode_length/1,
+ encode_length/2,
+ encode_bit_string/3,
+ encode_object_identifier/1,
+ encode_relative_oid/1,
+ complete/1,
+ encode_open_type/1,
+ encode_GeneralString/2,
+ encode_GraphicString/2,
+ encode_TeletexString/2,
+ encode_VideotexString/2,
+ encode_ObjectDescriptor/2,
+ encode_UTF8String/1,
+ encode_octet_string/3,
+ encode_known_multiplier_string/4,
+ octets_to_complete/2]).
+
+-define('16K',16384).
+-define('32K',32768).
+-define('64K',65536).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% setext(true|false) -> CompleteList
+%%
+
+setext(false) ->
+ [0];
+setext(true) ->
+ [1].
+
+fixextensions({ext,ExtPos,ExtNum},Val) ->
+ case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
+ 0 -> [];
+ ExtBits ->
+ [encode_small_length(ExtNum)|pre_complete_bits(ExtNum,ExtBits)]
+ end.
+
+fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
+ Acc;
+fixextensions(Pos,ExtPos,Val,Acc) ->
+ Bit = case catch(element(Pos+1,Val)) of
+ asn1_NOVALUE ->
+ 0;
+ asn1_NOEXTVALUE ->
+ 0;
+ {'EXIT',_} ->
+ 0;
+ _ ->
+ 1
+ end,
+ fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
+
+skipextensions(Bytes0, Nr, ExtensionBitstr) when is_bitstring(ExtensionBitstr) ->
+ Prev = Nr - 1,
+ case ExtensionBitstr of
+ <<_:Prev,1:1,_/bitstring>> ->
+ {Len,Bytes1} = decode_length(Bytes0),
+ <<_:Len/binary,Bytes2/bitstring>> = Bytes1,
+ skipextensions(Bytes2, Nr+1, ExtensionBitstr);
+ <<_:Prev,0:1,_/bitstring>> ->
+ skipextensions(Bytes0, Nr+1, ExtensionBitstr);
+ _ ->
+ Bytes0
+ end.
+
+
+getchoice(Bytes, 1, 0) -> % only 1 alternative is not encoded
+ {0,Bytes};
+getchoice(Bytes, _, 1) ->
+ decode_small_number(Bytes);
+getchoice(Bytes, NumChoices, 0) ->
+ decode_constrained_number(Bytes, {0,NumChoices-1}).
+
+
+getbit(Buffer) ->
+ <<B:1,Rest/bitstring>> = Buffer,
+ {B,Rest}.
+
+getbits(Buffer, Num) when is_bitstring(Buffer) ->
+ <<Bs:Num,Rest/bitstring>> = Buffer,
+ {Bs,Rest}.
+
+align(Bin) when is_binary(Bin) ->
+ Bin;
+align(BitStr) when is_bitstring(BitStr) ->
+ AlignBits = bit_size(BitStr) rem 8,
+ <<_:AlignBits,Rest/binary>> = BitStr,
+ Rest.
+
+
+%% First align buffer, then pick the first Num octets.
+%% Returns octets as an integer with bit significance as in buffer.
+getoctets(Buffer, Num) when is_binary(Buffer) ->
+ <<Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
+ {Val,RestBin};
+getoctets(Buffer, Num) when is_bitstring(Buffer) ->
+ AlignBits = bit_size(Buffer) rem 8,
+ <<_:AlignBits,Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
+ {Val,RestBin}.
+
+
+%% First align buffer, then pick the first Num octets.
+%% Returns octets as a binary
+getoctets_as_bin(Bin,Num) when is_binary(Bin) ->
+ <<Octets:Num/binary,RestBin/binary>> = Bin,
+ {Octets,RestBin};
+getoctets_as_bin(Bin,Num) when is_bitstring(Bin) ->
+ AlignBits = bit_size(Bin) rem 8,
+ <<_:AlignBits,Val:Num/binary,RestBin/binary>> = Bin,
+ {Val,RestBin}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
+%% Alt = atom()
+%% Altnum = integer() | {integer(),integer()}% number of alternatives
+%% Choices = [atom()] | {[atom()],[atom()]}
+%% When Choices is a tuple the first list is the Rootset and the
+%% second is the Extensions and then Altnum must also be a tuple with the
+%% lengths of the 2 lists
+%%
+set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
+ case set_choice_tag(Alt,L1) of
+ N when is_integer(N), Len1 > 1 ->
+ [0, % the value is in the root set
+ encode_constrained_number({0,Len1-1},N)];
+ N when is_integer(N) ->
+ [0]; % no encoding if only 0 or 1 alternative
+ false ->
+ [1, % extension value
+ case set_choice_tag(Alt, L2) of
+ N2 when is_integer(N2) ->
+ encode_small_number(N2);
+ false ->
+ unknown_choice_alt
+ end]
+ end;
+set_choice(Alt, L, Len) ->
+ case set_choice_tag(Alt, L) of
+ N when is_integer(N), Len > 1 ->
+ encode_constrained_number({0,Len-1},N);
+ N when is_integer(N) ->
+ []; % no encoding if only 0 or 1 alternative
+ false ->
+ [unknown_choice_alt]
+ end.
+
+set_choice_tag(Alt,Choices) ->
+ set_choice_tag(Alt,Choices,0).
+
+set_choice_tag(Alt,[Alt|_Rest],Tag) ->
+ Tag;
+set_choice_tag(Alt,[_H|Rest],Tag) ->
+ set_choice_tag(Alt,Rest,Tag+1);
+set_choice_tag(_Alt,[],_Tag) ->
+ false.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_open_type(Constraint, Value) -> CompleteList
+%% Value = list of bytes of an already encoded value (the list must be flat)
+%% | binary
+%% Contraint = not used in this version
+%%
+encode_open_type(Val) when is_list(Val) ->
+ Bin = list_to_binary(Val),
+ case byte_size(Bin) of
+ Size when Size > 255 ->
+ [encode_length(Size),21,<<Size:16>>,Bin];
+ Size ->
+ [encode_length(Size),20,Size,Bin]
+ end;
+encode_open_type(Val) when is_binary(Val) ->
+ case byte_size(Val) of
+ Size when Size > 255 ->
+ [encode_length(Size),21,<<Size:16>>,Val]; % octets implies align
+ Size ->
+ [encode_length(Size),20,Size,Val]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_integer(Constraint, Value) -> CompleteList
+%%
+encode_integer([{Rc,_Ec}],Val) when is_tuple(Rc) ->
+ try
+ [0|encode_integer([Rc], Val)]
+ catch
+ _:{error,{asn1,_}} ->
+ [1|encode_unconstrained_number(Val)]
+ end;
+encode_integer([], Val) ->
+ encode_unconstrained_number(Val);
+%% The constraint is the effective constraint, and in this case is a number
+encode_integer([{'SingleValue',V}], V) ->
+ [];
+encode_integer([{'ValueRange',{Lb,Ub}=VR,Range,PreEnc}],Val)
+ when Val >= Lb, Ub >= Val ->
+ %% this case when NamedNumberList
+ encode_constrained_number(VR, Range, PreEnc, Val);
+encode_integer([{'ValueRange',{Lb,'MAX'}}], Val) ->
+ encode_semi_constrained_number(Lb, Val);
+encode_integer([{'ValueRange',{'MIN',_}}], Val) ->
+ encode_unconstrained_number(Val);
+encode_integer([{'ValueRange',VR={_Lb,_Ub}}], Val) ->
+ encode_constrained_number(VR, Val);
+encode_integer(_,Val) ->
+ exit({error,{asn1,{illegal_value,Val}}}).
+
+
+%% X.691:10.6 Encoding of a normally small non-negative whole number
+%% Use this for encoding of CHOICE index if there is an extension marker in
+%% the CHOICE
+encode_small_number(Val) when Val < 64 ->
+ [10,7,Val];
+encode_small_number(Val) ->
+ [1|encode_semi_constrained_number(0, Val)].
+
+decode_small_number(Bytes) ->
+ {Bit,Bytes2} = getbit(Bytes),
+ case Bit of
+ 0 ->
+ getbits(Bytes2, 6);
+ 1 ->
+ decode_semi_constrained_number(Bytes2)
+ end.
+
+%% X.691:10.7 Encoding of a semi-constrained whole number
+encode_semi_constrained_number(Lb, Val) ->
+ Val2 = Val - Lb,
+ Oct = eint_positive(Val2),
+ Len = length(Oct),
+ if
+ Len < 128 ->
+ [20,Len+1,Len|Oct];
+ Len < 256 ->
+ [encode_length(Len),20,Len|Oct];
+ true ->
+ [encode_length(Len),21,<<Len:16>>|Oct]
+ end.
+
+decode_semi_constrained_number(Bytes) ->
+ {Len,Bytes2} = decode_length(Bytes),
+ getoctets(Bytes2, Len).
+
+encode_constrained_number({Lb,_Ub},_Range,{bits,N},Val) ->
+ Val2 = Val-Lb,
+ [10,N,Val2];
+encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) when N < 256->
+ %% N is 8 or 16 (1 or 2 octets)
+ Val2 = Val-Lb,
+ [20,N,Val2];
+encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) -> % N>255
+ %% N is 8 or 16 (1 or 2 octets)
+ Val2 = Val-Lb,
+ [21,<<N:16>>,Val2];
+encode_constrained_number({Lb,_Ub},Range,_,Val) ->
+ Val2 = Val-Lb,
+ if
+ Range =< 16#1000000 -> % max 3 octets
+ Octs = eint_positive(Val2),
+ L = length(Octs),
+ [encode_length({1,3},L),[20,L,Octs]];
+ Range =< 16#100000000 -> % max 4 octets
+ Octs = eint_positive(Val2),
+ L = length(Octs),
+ [encode_length({1,4},L),[20,L,Octs]];
+ Range =< 16#10000000000 -> % max 5 octets
+ Octs = eint_positive(Val2),
+ L = length(Octs),
+ [encode_length({1,5},L),[20,L,Octs]];
+ true ->
+ exit({not_supported,{integer_range,Range}})
+ end.
+
+encode_constrained_number({Lb,Ub}, Val) when Val >= Lb, Ub >= Val ->
+ Range = Ub - Lb + 1,
+ Val2 = Val - Lb,
+ if
+ Range == 1 -> [];
+ Range == 2 ->
+ [Val2];
+ Range =< 4 ->
+ [10,2,Val2];
+ Range =< 8 ->
+ [10,3,Val2];
+ Range =< 16 ->
+ [10,4,Val2];
+ Range =< 32 ->
+ [10,5,Val2];
+ Range =< 64 ->
+ [10,6,Val2];
+ Range =< 128 ->
+ [10,7,Val2];
+ Range =< 255 ->
+ [10,8,Val2];
+ Range =< 256 ->
+ [20,1,Val2];
+ Range =< 65536 ->
+ [20,2,<<Val2:16>>];
+ Range =< (1 bsl (255*8)) ->
+ Octs = binary:encode_unsigned(Val2),
+ RangeOcts = binary:encode_unsigned(Range - 1),
+ OctsLen = byte_size(Octs),
+ RangeOctsLen = byte_size(RangeOcts),
+ LengthBitsNeeded = minimum_bits(RangeOctsLen - 1),
+ [10,LengthBitsNeeded,OctsLen-1,20,OctsLen,Octs];
+ true ->
+ exit({not_supported,{integer_range,Range}})
+ end;
+encode_constrained_number({_,_},Val) ->
+ exit({error,{asn1,{illegal_value,Val}}}).
+
+decode_constrained_number(Buffer,VR={Lb,Ub}) ->
+ Range = Ub - Lb + 1,
+ decode_constrained_number(Buffer,VR,Range).
+
+decode_constrained_number(Buffer,{Lb,_Ub},Range) ->
+ % Val2 = Val - Lb,
+ {Val,Remain} =
+ if
+ Range == 1 ->
+ {0,Buffer};
+ Range == 2 ->
+ getbits(Buffer,1);
+ Range =< 4 ->
+ getbits(Buffer,2);
+ Range =< 8 ->
+ getbits(Buffer,3);
+ Range =< 16 ->
+ getbits(Buffer,4);
+ Range =< 32 ->
+ getbits(Buffer,5);
+ Range =< 64 ->
+ getbits(Buffer,6);
+ Range =< 128 ->
+ getbits(Buffer,7);
+ Range =< 255 ->
+ getbits(Buffer,8);
+ Range =< 256 ->
+ getoctets(Buffer,1);
+ Range =< 65536 ->
+ getoctets(Buffer,2);
+ Range =< (1 bsl (255*8)) ->
+ OList = binary:bin_to_list(binary:encode_unsigned(Range - 1)),
+ RangeOctLen = length(OList),
+ {Len, Bytes} = decode_length(Buffer, {1, RangeOctLen}),
+ {Octs, RestBytes} = getoctets_as_bin(Bytes, Len),
+ {binary:decode_unsigned(Octs), RestBytes};
+ true ->
+ exit({not_supported,{integer_range,Range}})
+ end,
+ {Val+Lb,Remain}.
+
+%% For some reason the minimum bits needed in the length field in
+%% the encoding of constrained whole numbers must always be at least 2?
+minimum_bits(N) when N < 4 -> 2;
+minimum_bits(N) when N < 8 -> 3;
+minimum_bits(N) when N < 16 -> 4;
+minimum_bits(N) when N < 32 -> 5;
+minimum_bits(N) when N < 64 -> 6;
+minimum_bits(N) when N < 128 -> 7;
+minimum_bits(_N) -> 8.
+
+%% X.691:10.8 Encoding of an unconstrained whole number
+
+encode_unconstrained_number(Val) ->
+ Oct = if
+ Val >= 0 ->
+ eint(Val, []);
+ true ->
+ enint(Val, [])
+ end,
+ Len = length(Oct),
+ if
+ Len < 128 ->
+ [20,Len + 1,Len|Oct];
+ Len < 256 ->
+ [20,Len + 2,<<2:2,Len:14>>|Oct];
+ true ->
+ [encode_length(Len),21,<<Len:16>>|Oct]
+ end.
+
+%% used for positive Values which don't need a sign bit
+%% returns a list
+eint_positive(Val) ->
+ case eint(Val,[]) of
+ [0,B1|T] ->
+ [B1|T];
+ T ->
+ T
+ end.
+
+
+eint(0, [B|Acc]) when B < 128 ->
+ [B|Acc];
+eint(N, Acc) ->
+ eint(N bsr 8, [N band 16#ff| Acc]).
+
+enint(-1, [B1|T]) when B1 > 127 ->
+ [B1|T];
+enint(N, Acc) ->
+ enint(N bsr 8, [N band 16#ff|Acc]).
+
+%% X.691:10.9 Encoding of a length determinant
+%%encode_small_length(undefined,Len) -> % null means no UpperBound
+%% encode_small_number(Len).
+
+%% X.691:10.9.3.5
+%% X.691:10.9.3.7
+encode_length(Len) -> % unconstrained
+ if
+ Len < 128 ->
+ [20,1,Len];
+ Len < 16384 ->
+ <<20,2,2:2,Len:14>>;
+ true -> % should be able to endode length >= 16384 i.e. fragmented length
+ exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
+ end.
+
+encode_length(undefined, Len) -> % un-constrained
+ encode_length(Len);
+encode_length({0,'MAX'},Len) ->
+ encode_length(undefined,Len);
+encode_length({Lb,Ub}=Vr, Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
+ encode_constrained_number(Vr,Len);
+encode_length({Lb,_Ub}, Len) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
+ encode_length(Len);
+encode_length({{Lb,Ub}=Vr,Ext}, Len)
+ when Ub =< 65535 ,Lb >= 0,Len=<Ub, is_list(Ext) ->
+ %% constrained extensible
+ [0|encode_constrained_number(Vr,Len)];
+encode_length({{Lb,_},Ext},Len) when is_list(Ext) ->
+ [1|encode_semi_constrained_number(Lb, Len)];
+encode_length(SingleValue, _Len) when is_integer(SingleValue) ->
+ [].
+
+%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension
+%% additions in a sequence or set
+encode_small_length(Len) when Len =< 64 ->
+ [10,7,Len-1];
+encode_small_length(Len) ->
+ [1,encode_length(Len)].
+
+
+decode_length(Buffer) -> % un-constrained
+ case align(Buffer) of
+ <<0:1,Oct:7,Rest/binary>> ->
+ {Oct,Rest};
+ <<2:2,Val:14,Rest/binary>> ->
+ {Val,Rest};
+ <<3:2,_Val:14,_Rest/binary>> ->
+ %% this case should be fixed
+ exit({error,{asn1,{decode_length,{nyi,above_16k}}}})
+ end.
+
+decode_length(Buffer, {Lb,Ub}) when Ub =< 65535, Lb >= 0 -> % constrained
+ decode_constrained_number(Buffer, {Lb,Ub});
+decode_length(Buffer, {Lb,_Ub}) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
+ decode_length(Buffer).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% bitstring NamedBitList
+%% Val can be of:
+%% - [identifiers] where only named identifers are set to one,
+%% the Constraint must then have some information of the
+%% bitlength.
+%% - [list of ones and zeroes] all bits
+%% - integer value representing the bitlist
+%% C is constraint Len, only valid when identifiers
+
+
+%% when the value is a list of {Unused,BinBits}, where
+%% Unused = integer(),
+%% BinBits = binary().
+
+encode_bit_string(C, Bits, NamedBitList) when is_bitstring(Bits) ->
+ PadLen = (8 - (bit_size(Bits) band 7)) band 7,
+ Compact = {PadLen,<<Bits/bitstring,0:PadLen>>},
+ encode_bin_bit_string(C, Compact, NamedBitList);
+encode_bit_string(C, {Unused,BinBits}=Bin, NamedBitList)
+ when is_integer(Unused), is_binary(BinBits) ->
+ encode_bin_bit_string(C,Bin,NamedBitList);
+
+%% when the value is a list of named bits
+
+encode_bit_string(C, LoNB=[FirstVal | _RestVal], NamedBitList) when is_atom(FirstVal) ->
+ ToSetPos = get_all_bitposes(LoNB, NamedBitList, []),
+ BitList = make_and_set_list(ToSetPos,0),
+ encode_bit_string(C,BitList,NamedBitList);% consider the constraint
+
+encode_bit_string(C, BL=[{bit,_} | _RestVal], NamedBitList) ->
+ ToSetPos = get_all_bitposes(BL, NamedBitList, []),
+ BitList = make_and_set_list(ToSetPos,0),
+ encode_bit_string(C,BitList,NamedBitList);
+
+%% when the value is a list of ones and zeroes
+encode_bit_string(Int, BitListValue, _)
+ when is_list(BitListValue),is_integer(Int),Int =< 16 ->
+ %% The type is constrained by a single value size constraint
+ %% range_check(Int,length(BitListValue)),
+ [40,Int,length(BitListValue),BitListValue];
+encode_bit_string(Int, BitListValue, _)
+ when is_list(BitListValue),is_integer(Int), Int =< 255 ->
+ %% The type is constrained by a single value size constraint
+ %% range_check(Int,length(BitListValue)),
+ [2,40,Int,length(BitListValue),BitListValue];
+encode_bit_string(Int, BitListValue, _)
+ when is_list(BitListValue),is_integer(Int), Int < ?'64K' ->
+ {Code,DesiredLength,Length} =
+ case length(BitListValue) of
+ B1 when B1 > Int ->
+ exit({error,{'BIT_STRING_length_greater_than_SIZE',
+ Int,BitListValue}});
+ B1 when B1 =< 255,Int =< 255 ->
+ {40,Int,B1};
+ B1 when B1 =< 255 ->
+ {42,<<Int:16>>,B1};
+ B1 ->
+ {43,<<Int:16>>,<<B1:16>>}
+ end,
+ %% The type is constrained by a single value size constraint
+ [2,Code,DesiredLength,Length,BitListValue];
+encode_bit_string(no, BitListValue,[])
+ when is_list(BitListValue) ->
+ [encode_length(length(BitListValue)),
+ 2|BitListValue];
+encode_bit_string({{Fix,Fix},Ext}, BitListValue,[])
+ when is_integer(Fix), is_list(Ext) ->
+ case length(BitListValue) of
+ Len when Len =< Fix ->
+ [0|encode_bit_string(Fix, BitListValue, [])];
+ _ ->
+ [1|encode_bit_string(no, BitListValue, [])]
+ end;
+encode_bit_string(C, BitListValue,[])
+ when is_list(BitListValue) ->
+ [encode_length(C, length(BitListValue)),
+ 2|BitListValue];
+encode_bit_string(no, BitListValue,_NamedBitList)
+ when is_list(BitListValue) ->
+ %% this case with an unconstrained BIT STRING can be made more efficient
+ %% if the complete driver can take a special code so the length field
+ %% is encoded there.
+ NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
+ lists:reverse(BitListValue))),
+ [encode_length(length(NewBitLVal)),2|NewBitLVal];
+encode_bit_string({{Fix,Fix},Ext}, BitListValue, NamedBitList)
+ when is_integer(Fix), is_list(Ext) ->
+ case length(BitListValue) of
+ Len when Len =< Fix ->
+ [0|encode_bit_string(Fix, BitListValue, NamedBitList)];
+ _ ->
+ [1|encode_bit_string(no, BitListValue, NamedBitList)]
+ end;
+encode_bit_string(C, BitListValue, _NamedBitList)
+ when is_list(BitListValue) -> % C = {_,'MAX'}
+ NewBitLVal = bit_string_trailing_zeros(BitListValue, C),
+ [encode_length(C, length(NewBitLVal)),2|NewBitLVal];
+
+
+%% when the value is an integer
+encode_bit_string(C, IntegerVal, NamedBitList) when is_integer(IntegerVal)->
+ BitList = int_to_bitlist(IntegerVal),
+ encode_bit_string(C,BitList,NamedBitList).
+
+bit_string_trailing_zeros(BitList,C) when is_integer(C) ->
+ bit_string_trailing_zeros1(BitList,C,C);
+bit_string_trailing_zeros(BitList,{Lb,Ub}) when is_integer(Lb) ->
+ bit_string_trailing_zeros1(BitList,Lb,Ub);
+bit_string_trailing_zeros(BitList,{{Lb,Ub},_}) when is_integer(Lb) ->
+ bit_string_trailing_zeros1(BitList,Lb,Ub);
+bit_string_trailing_zeros(BitList,_) ->
+ BitList.
+
+bit_string_trailing_zeros1(BitList,Lb,Ub) ->
+ case length(BitList) of
+ Lb -> BitList;
+ B when B < Lb -> BitList++lists:duplicate(Lb-B, 0);
+ D -> F = fun(L,LB,LB,_,_)->lists:reverse(L);
+ ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun);
+ (L,L1,_,UB,_)when L1 =< UB -> lists:reverse(L);
+ (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING,
+ BitList}}) end,
+ F(lists:reverse(BitList),D,Lb,Ub,F)
+ end.
+
+%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
+%% Unused = integer(),i.e. number unused bits in least sign. byte of
+%% BinBits = binary().
+encode_bin_bit_string(C, {Unused,BinBits}, _NamedBitList)
+ when is_integer(C),C=<16 ->
+ range_check(C, bit_size(BinBits) - Unused),
+ [45,C,size(BinBits),BinBits];
+encode_bin_bit_string(C, {Unused,BinBits}, _NamedBitList)
+ when is_integer(C), C =< 255 ->
+ range_check(C, bit_size(BinBits) - Unused),
+ [2,45,C,size(BinBits),BinBits];
+encode_bin_bit_string(C, {Unused,BinBits}, _NamedBitList)
+ when is_integer(C), C =< 65535 ->
+ range_check(C, bit_size(BinBits) - Unused),
+ case byte_size(BinBits) of
+ Size when Size =< 255 ->
+ [2,46,<<C:16>>,Size,BinBits];
+ Size ->
+ [2,47,<<C:16>>,<<Size:16>>,BinBits]
+ end;
+encode_bin_bit_string(C,UnusedAndBin={_,_},NamedBitList) ->
+ {Unused1,Bin1} =
+ %% removes all trailing bits if NamedBitList is not empty
+ remove_trailing_bin(NamedBitList,UnusedAndBin),
+ case C of
+ {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
+ Size = byte_size(Bin1),
+ [encode_length({Lb,Ub}, Size*8 - Unused1),
+ 2,octets_unused_to_complete(Unused1,Size,Bin1)];
+ no ->
+ Size = byte_size(Bin1),
+ [encode_length(Size*8 - Unused1),
+ 2|octets_unused_to_complete(Unused1, Size, Bin1)];
+ {{Fix,Fix},Ext} when is_integer(Fix),is_list(Ext) ->
+ case byte_size(Bin1)*8 - Unused1 of
+ Size when Size =< Fix ->
+ [0|encode_bin_bit_string(Fix,UnusedAndBin,NamedBitList)];
+ _Size ->
+ [1|encode_bin_bit_string(no,UnusedAndBin,NamedBitList)]
+ end;
+ Sc ->
+ Size = byte_size(Bin1),
+ [encode_length(Sc, Size*8 - Unused1),
+ 2|octets_unused_to_complete(Unused1,Size,Bin1)]
+ end.
+
+range_check(C,C) when is_integer(C) ->
+ ok;
+range_check(C1,C2) when is_integer(C1) ->
+ exit({error,{asn1,{bit_string_out_of_range,{C1,C2}}}}).
+
+remove_trailing_bin([], {Unused,Bin}) ->
+ {Unused,Bin};
+remove_trailing_bin(_NamedNumberList,{_Unused,<<>>}) ->
+ {0,<<>>};
+remove_trailing_bin(NamedNumberList, {_Unused,Bin}) ->
+ Size = byte_size(Bin)-1,
+ <<Bfront:Size/binary, LastByte:8>> = Bin,
+ %% clear the Unused bits to be sure
+ Unused1 = trailingZeroesInNibble(LastByte band 15),
+ Unused2 =
+ case Unused1 of
+ 4 ->
+ 4 + trailingZeroesInNibble(LastByte bsr 4);
+ _ -> Unused1
+ end,
+ case Unused2 of
+ 8 ->
+ remove_trailing_bin(NamedNumberList,{0,Bfront});
+ _ ->
+ {Unused2,Bin}
+ end.
+
+
+trailingZeroesInNibble(0) ->
+ 4;
+trailingZeroesInNibble(1) ->
+ 0;
+trailingZeroesInNibble(2) ->
+ 1;
+trailingZeroesInNibble(3) ->
+ 0;
+trailingZeroesInNibble(4) ->
+ 2;
+trailingZeroesInNibble(5) ->
+ 0;
+trailingZeroesInNibble(6) ->
+ 1;
+trailingZeroesInNibble(7) ->
+ 0;
+trailingZeroesInNibble(8) ->
+ 3;
+trailingZeroesInNibble(9) ->
+ 0;
+trailingZeroesInNibble(10) ->
+ 1;
+trailingZeroesInNibble(11) ->
+ 0;
+trailingZeroesInNibble(12) -> %#1100
+ 2;
+trailingZeroesInNibble(13) ->
+ 0;
+trailingZeroesInNibble(14) ->
+ 1;
+trailingZeroesInNibble(15) ->
+ 0.
+
+
+%%%%%%%%%%%%%%%
+%%
+
+int_to_bitlist(Int) when is_integer(Int), Int > 0 ->
+ [Int band 1 | int_to_bitlist(Int bsr 1)];
+int_to_bitlist(0) ->
+ [].
+
+
+%%%%%%%%%%%%%%%%%%
+%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
+%% [sorted_list_of_bitpositions_to_set]
+
+get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
+ get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
+
+get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
+ case lists:keyfind(Val, 1, NamedBitList) of
+ {_ValName, ValPos} ->
+ get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
+ false ->
+ exit({error,{asn1, {bitstring_namedbit, Val}}})
+ end;
+get_all_bitposes([], _NamedBitList, Ack) ->
+ lists:sort(Ack).
+
+%%%%%%%%%%%%%%%%%%
+%% make_and_set_list([list of positions to set to 1])->
+%% returns list with all in SetPos set.
+%% in positioning in list the first element is 0, the second 1 etc.., but
+%%
+
+make_and_set_list([XPos|SetPos], XPos) ->
+ [1 | make_and_set_list(SetPos, XPos + 1)];
+make_and_set_list([Pos|SetPos], XPos) ->
+ [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
+make_and_set_list([], _) ->
+ [].
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% X.691:16
+%% encode_octet_string(Constraint,ExtensionMarker,Val)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+encode_octet_string(_C, true, _Val) ->
+ exit({error,{asn1,{'not_supported',extensionmarker}}});
+encode_octet_string({_,_}=SZ, false, Val) ->
+ Len = length(Val),
+ try
+ [encode_length(SZ, Len),2|octets_to_complete(Len, Val)]
+ catch
+ exit:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
+encode_octet_string(SZ, false, Val) when is_list(SZ) ->
+ Len = length(Val),
+ try
+ [encode_length({hd(SZ),lists:max(SZ)},Len),2|
+ octets_to_complete(Len,Val)]
+ catch
+ exit:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
+encode_octet_string(Sv, false, Val) when is_integer(Sv) ->
+ encode_fragmented_octet_string(Val);
+encode_octet_string(no, false, Val) ->
+ Len = length(Val),
+ try
+ [encode_length(Len),2|octets_to_complete(Len, Val)]
+ catch
+ exit:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
+encode_octet_string(C, _, _) ->
+ exit({error,{not_implemented,C}}).
+
+encode_fragmented_octet_string(Val) ->
+ Bin = iolist_to_binary(Val),
+ efos_1(Bin).
+
+efos_1(<<B1:16#C000/binary,B2:16#4000/binary,T/binary>>) ->
+ [20,1,<<3:2,4:6>>,
+ octets_to_complete(16#C000, B1),
+ octets_to_complete(16#4000, B2)|efos_1(T)];
+efos_1(<<B:16#C000/binary,T/binary>>) ->
+ [20,1,<<3:2,3:6>>,octets_to_complete(16#C000, B)|efos_1(T)];
+efos_1(<<B:16#8000/binary,T/binary>>) ->
+ [20,1,<<3:2,2:6>>,octets_to_complete(16#8000, B)|efos_1(T)];
+efos_1(<<B:16#4000/binary,T/binary>>) ->
+ [20,1,<<3:2,1:6>>,octets_to_complete(16#4000, B)|efos_1(T)];
+efos_1(<<>>) ->
+ [20,1,0];
+efos_1(<<B/bitstring>>) ->
+ Len = byte_size(B),
+ [encode_length(Len)|octets_to_complete(Len, B)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Restricted char string types
+%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
+%% X.691:26 and X.680:34-36
+
+encode_restricted_string(Val) when is_list(Val)->
+ Len = length(Val),
+ [encode_length(Len)|octets_to_complete(Len, Val)].
+
+encode_known_multiplier_string(SizeC, NumBits, CharOutTab, Val) ->
+ Result = chars_encode2(Val, NumBits, CharOutTab),
+ case SizeC of
+ Ub when is_integer(Ub), Ub*NumBits =< 16 ->
+ Result;
+ Ub when is_integer(Ub), Ub =<65535 -> % fixed length
+ [2,Result];
+ {Ub,Lb} ->
+ [encode_length({Ub,Lb},length(Val)),2,Result];
+ no ->
+ [encode_length(length(Val)),2,Result]
+ end.
+
+encode_GeneralString(_C,Val) ->
+ encode_restricted_string(Val).
+
+encode_GraphicString(_C,Val) ->
+ encode_restricted_string(Val).
+
+encode_ObjectDescriptor(_C,Val) ->
+ encode_restricted_string(Val).
+
+encode_TeletexString(_C,Val) -> % equivalent with T61String
+ encode_restricted_string(Val).
+
+encode_VideotexString(_C,Val) ->
+ encode_restricted_string(Val).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% chars_encode(C,StringType,Value) -> ValueList
+%%
+%% encodes chars according to the per rules taking the constraint
+%% PermittedAlphabet into account.
+%%
+%% This function only encodes the value part and NOT the length.
+
+chars_encode2([H|T],NumBits,T1={Min,Max,notab}) when H =< Max, H >= Min ->
+ [pre_complete_bits(NumBits,H-Min)|chars_encode2(T,NumBits,T1)];
+chars_encode2([H|T],NumBits,T1={Min,Max,Tab}) when H =< Max, H >= Min ->
+ [pre_complete_bits(NumBits,exit_if_false(H,element(H-Min+1,Tab)))|
+ chars_encode2(T,NumBits,T1)];
+chars_encode2([{A,B,C,D}|T],NumBits,T1={Min,_Max,notab}) ->
+ %% no value range check here (ought to be, but very expensive)
+ [pre_complete_bits(NumBits,
+ ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min)|
+ chars_encode2(T,NumBits,T1)];
+chars_encode2([H={A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
+ %% no value range check here (ought to be, but very expensive)
+ [pre_complete_bits(NumBits,exit_if_false(H,element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)))|chars_encode2(T,NumBits,{Min,Max,notab})];
+chars_encode2([H|_T],_NumBits,{_Min,_Max,_Tab}) ->
+ exit({error,{asn1,{illegal_char_value,H}}});
+chars_encode2([],_,_) ->
+ [].
+
+exit_if_false(V,false)->
+ exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}});
+exit_if_false(_,V) ->V.
+
+pre_complete_bits(NumBits,Val) when NumBits =< 8 ->
+ [10,NumBits,Val];
+pre_complete_bits(NumBits,Val) when NumBits =< 16 ->
+ [10,NumBits-8,Val bsr 8,10,8,(Val band 255)];
+pre_complete_bits(NumBits,Val) when NumBits =< 2040 -> % 255 * 8
+ Unused = (8 - (NumBits rem 8)) rem 8,
+ Len = NumBits + Unused,
+ [30,Unused,Len div 8,<<(Val bsl Unused):Len>>].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_UTF8String(Val) -> CompleteList
+%% Val -> <<utf8encoded binary>>
+%% CompleteList -> [apropriate codes and values for driver complete]
+%%
+encode_UTF8String(Val) when is_binary(Val) ->
+ Sz = byte_size(Val),
+ [encode_length(Sz),octets_to_complete(Sz, Val)];
+encode_UTF8String(Val) ->
+ encode_UTF8String(list_to_binary(Val)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_object_identifier(Val) -> CompleteList
+%% encode_object_identifier({Name,Val}) -> CompleteList
+%% Val -> {Int1,Int2,...,IntN} % N >= 2
+%% Name -> atom()
+%% Int1 -> integer(0..2)
+%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
+%% Int3-N -> integer()
+%% CompleteList -> [{bits,8,Val}|{octets,Ol}|align|...]
+%%
+encode_object_identifier(Val) ->
+ OctetList = e_object_identifier(Val),
+ Octets = list_to_binary(OctetList),
+ Sz = byte_size(Octets),
+ [encode_length(Sz),
+ octets_to_complete(Sz, Octets)].
+
+e_object_identifier({'OBJECT IDENTIFIER',V}) ->
+ e_object_identifier(V);
+e_object_identifier(V) when is_tuple(V) ->
+ e_object_identifier(tuple_to_list(V));
+
+%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
+e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 ->
+ Head = 40*E1 + E2, % weird
+ e_object_elements([Head|Tail],[]);
+e_object_identifier(Oid=[_,_|_Tail]) ->
+ exit({error,{asn1,{'illegal_value',Oid}}}).
+
+e_object_elements([],Acc) ->
+ lists:reverse(Acc);
+e_object_elements([H|T],Acc) ->
+ e_object_elements(T,[e_object_element(H)|Acc]).
+
+e_object_element(Num) when Num < 128 ->
+ [Num];
+e_object_element(Num) ->
+ [e_o_e(Num bsr 7)|[Num band 2#1111111]].
+e_o_e(Num) when Num < 128 ->
+ Num bor 2#10000000;
+e_o_e(Num) ->
+ [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_relative_oid(Val) -> CompleteList
+%% encode_relative_oid({Name,Val}) -> CompleteList
+encode_relative_oid(Val) when is_tuple(Val) ->
+ encode_relative_oid(tuple_to_list(Val));
+encode_relative_oid(Val) when is_list(Val) ->
+ Octets = list_to_binary([e_object_element(X)||X <- Val]),
+ Sz = byte_size(Octets),
+ [encode_length(Sz)|octets_to_complete(Sz, Octets)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% complete(InList) -> ByteList
+%% Takes a coded list with bits and bytes and converts it to a list of bytes
+%% Should be applied as the last step at encode of a complete ASN.1 type
+%%
+
+complete(L) ->
+ asn1rt_nif:encode_per_complete(L).
+
+octets_to_complete(Len,Val) when Len < 256 ->
+ [20,Len,Val];
+octets_to_complete(Len,Val) ->
+ [21,<<Len:16>>,Val].
+
+octets_unused_to_complete(Unused,Len,Val) when Len < 256 ->
+ [30,Unused,Len,Val];
+octets_unused_to_complete(Unused,Len,Val) ->
+ [31,Unused,<<Len:16>>,Val].
diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl
new file mode 100644
index 0000000000..a7d359a288
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -0,0 +1,126 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_per_common).
+
+-include("asn1_records.hrl").
+
+-export([decode_fragmented/3,
+ decode_compact_bit_string/1,
+ decode_legacy_bit_string/1,
+ decode_named_bit_string/2,
+ decode_chars/2,decode_chars/3,
+ decode_chars_16bit/1,
+ decode_big_chars/2,
+ decode_oid/1,decode_relative_oid/1]).
+
+-define('16K',16384).
+
+decode_fragmented(SegSz0, Buf0, Unit) ->
+ SegSz = SegSz0 * Unit * ?'16K',
+ <<Res:SegSz/bitstring,Buf/bitstring>> = Buf0,
+ decode_fragmented_1(Buf, Unit, Res).
+
+decode_fragmented_1(<<0:1,N:7,Buf0/bitstring>>, Unit, Res) ->
+ Sz = N*Unit,
+ <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
+ {<<Res/bitstring,S/bitstring>>,Buf};
+decode_fragmented_1(<<1:1,0:1,N:14,Buf0/bitstring>>, Unit, Res) ->
+ Sz = N*Unit,
+ <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
+ {<<Res/bitstring,S/bitstring>>,Buf};
+decode_fragmented_1(<<1:1,1:1,SegSz0:6,Buf0/bitstring>>, Unit, Res0) ->
+ SegSz = SegSz0 * Unit * ?'16K',
+ <<Frag:SegSz/bitstring,Buf/bitstring>> = Buf0,
+ Res = <<Res0/bitstring,Frag/bitstring>>,
+ decode_fragmented_1(Buf, Unit, Res).
+
+decode_named_bit_string(Val, NNL) ->
+ Bits = [B || <<B:1>> <= Val],
+ decode_named_bit_string_1(0, Bits, NNL, []).
+
+decode_legacy_bit_string(Val) ->
+ [B || <<B:1>> <= Val].
+
+decode_compact_bit_string(Val) ->
+ PadLen = (8 - (bit_size(Val) band 7)) band 7,
+ {PadLen,<<Val/bitstring,0:PadLen>>}.
+
+decode_chars(Val, N) ->
+ [C || <<C:N>> <= Val].
+
+decode_chars(Val, N, Chars) ->
+ [element(C+1, Chars) || <<C:N>> <= Val].
+
+decode_chars_16bit(Val) ->
+ Cs = [C || <<C:16>> <= Val],
+ decode_chars_16bit_1(Cs).
+
+decode_big_chars(Val, N) ->
+ decode_big_chars_1(decode_chars(Val, N)).
+
+decode_oid(Octets) ->
+ [First|Rest] = dec_subidentifiers(Octets, 0, []),
+ Idlist = if
+ First < 40 ->
+ [0,First|Rest];
+ First < 80 ->
+ [1,First - 40|Rest];
+ true ->
+ [2,First - 80|Rest]
+ end,
+ list_to_tuple(Idlist).
+
+decode_relative_oid(Octets) ->
+ list_to_tuple(dec_subidentifiers(Octets, 0, [])).
+
+%%%
+%%% Internal functions.
+%%%
+
+decode_named_bit_string_1(Pos, [0|Bt], Names, Acc) ->
+ decode_named_bit_string_1(Pos+1, Bt, Names, Acc);
+decode_named_bit_string_1(Pos, [1|Bt], Names, Acc) ->
+ case lists:keyfind(Pos, 2, Names) of
+ {Name,_} ->
+ decode_named_bit_string_1(Pos+1, Bt, Names, [Name|Acc]);
+ false ->
+ decode_named_bit_string_1(Pos+1, Bt, Names, [{bit,Pos}|Acc])
+ end;
+decode_named_bit_string_1(_Pos, [], _Names, Acc) ->
+ lists:reverse(Acc).
+
+decode_chars_16bit_1([H|T]) when H < 256 ->
+ [H|decode_chars_16bit_1(T)];
+decode_chars_16bit_1([H|T]) ->
+ [{0,0,H bsr 8,H band 255}|decode_chars_16bit_1(T)];
+decode_chars_16bit_1([]) -> [].
+
+decode_big_chars_1([H|T]) when H < 256 ->
+ [H|decode_big_chars_1(T)];
+decode_big_chars_1([H|T]) ->
+ [list_to_tuple(binary_to_list(<<H:32>>))|decode_big_chars_1(T)];
+decode_big_chars_1([]) -> [].
+
+dec_subidentifiers([H|T], Av, Al) when H >=16#80 ->
+ dec_subidentifiers(T, (Av bsl 7) bor (H band 16#7F), Al);
+dec_subidentifiers([H|T], Av, Al) ->
+ dec_subidentifiers(T, 0, [(Av bsl 7) bor H|Al]);
+dec_subidentifiers([], _Av, Al) ->
+ lists:reverse(Al).
diff --git a/lib/asn1/src/asn1rtt_real_common.erl b/lib/asn1/src/asn1rtt_real_common.erl
new file mode 100644
index 0000000000..540f0d60a5
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_real_common.erl
@@ -0,0 +1,292 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_real_common).
+
+-export([encode_real/1,decode_real/1,
+ ber_encode_real/1]).
+
+%%============================================================================
+%%
+%% Real value, ITU_T X.690 Chapter 8.5
+%%============================================================================
+%%
+%% encode real value
+%%============================================================================
+
+ber_encode_real(0) ->
+ {[],0};
+ber_encode_real('PLUS-INFINITY') ->
+ {[64],1};
+ber_encode_real('MINUS-INFINITY') ->
+ {[65],1};
+ber_encode_real(Val) when is_tuple(Val); is_list(Val) ->
+ encode_real(Val).
+
+%%%%%%%%%%%%%%
+%% only base 2 encoding!
+%% binary encoding:
+%% +------------+ +------------+ +-+-+-+-+---+---+
+%% | (tag)9 | | n + p + 1 | |1|S|BB |FF |EE |
+%% +------------+ +------------+ +-+-+-+-+---+---+
+%%
+%% +------------+ +------------+
+%% | | | |
+%% +------------+ ...+------------+
+%% n octets for exponent
+%%
+%% +------------+ +------------+
+%% | | | |
+%% +------------+ ...+------------+
+%% p octets for pos mantissa
+%%
+%% S is 0 for positive sign
+%% 1 for negative sign
+%% BB: encoding base, 00 = 2, (01 = 8, 10 = 16)
+%% 01 and 10 not used
+%% FF: scale factor 00 = 0 (used in base 2 encoding)
+%% EE: encoding of the exponent:
+%% 00 - on the following octet
+%% 01 - on the 2 following octets
+%% 10 - on the 3 following octets
+%% 11 - encoding of the length of the two's-complement encoding of
+%% exponent on the following octet, and two's-complement
+%% encoding of exponent on the other octets.
+%%
+%% In DER and base 2 encoding the mantissa is encoded as value 0 or
+%% bit shifted until it is an odd number. Thus, do this for BER as
+%% well.
+
+encode_real(Real) ->
+ encode_real([], Real).
+
+encode_real(_C, {Mantissa, Base, Exponent}) when Base =:= 2 ->
+%% io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
+ {Man,ExpAdd} = truncate_zeros(Mantissa), %% DER adjustment
+ Exp = Exponent + ExpAdd,
+ OctExp = if Exp >= 0 -> list_to_binary(encode_pos_integer(Exp, []));
+ true -> list_to_binary(encode_neg_integer(Exp, []))
+ end,
+%% ok = io:format("OctExp: ~w~n",[OctExp]),
+ SignBit = if Man > 0 -> 0; % bit 7 is pos or neg, no Zeroval
+ true -> 1
+ end,
+%% ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
+ SFactor = 0,
+ OctExpLen = size(OctExp),
+ if OctExpLen > 255 ->
+ exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
+ true -> true %% make real assert later..
+ end,
+ {LenCode, EOctets} = case OctExpLen of % bit 2,1
+ 1 -> {0, OctExp};
+ 2 -> {1, OctExp};
+ 3 -> {2, OctExp};
+ _ -> {3, <<OctExpLen, OctExp/binary>>}
+ end,
+ BB = 0, %% 00 for base 2
+ FirstOctet = <<1:1,SignBit:1,BB:2,SFactor:2,LenCode:2>>,
+ OctMantissa = if Man > 0 -> list_to_binary(real_mininum_octets(Man));
+ true -> list_to_binary(real_mininum_octets(-(Man))) % signbit keeps track of sign
+ end,
+ %% ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
+ Bin = <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>,
+ {Bin, size(Bin)};
+encode_real(C, {Mantissa,Base,Exponent})
+ when Base =:= 10, is_integer(Mantissa), is_integer(Exponent) ->
+ %% always encode as NR3 due to DER on the format
+ %% mmmm.Eseeee where
+ %% m := digit
+ %% s := '-' | '+' | []
+ %% '+' only allowed in +0
+ %% e := digit
+ %% ex: 1234.E-5679
+ ManStr = integer_to_list(Mantissa),
+
+ encode_real_as_string(C,ManStr,Exponent);
+encode_real(_C, {_,Base,_}) ->
+ exit({error,{asn1, {encode_real_non_supported_encoding, Base}}});
+%% base 10
+encode_real(C, Real) when is_list(Real) ->
+ %% The Real string may come in as a NR1, NR2 or NR3 string.
+ {Mantissa, Exponent} =
+ case string:tokens(Real,"Ee") of
+ [NR2] ->
+ {NR2,0};
+ [NR3MB,NR3E] ->
+ %% remove beginning zeros
+ {NR3MB,list_to_integer(NR3E)}
+ end,
+
+ %% .Decimal | Number | Number.Decimal
+ ZeroDecimal =
+ fun("0") -> "";
+ (L) -> L
+ end,
+ {NewMantissa,LenDecimal} =
+ case Mantissa of
+ [$.|Dec] ->
+ NewMan = remove_trailing_zeros(Dec),
+ {NewMan,length(ZeroDecimal(NewMan))};
+ _ ->
+ case string:tokens(Mantissa,",.") of
+ [Num] -> %% No decimal-mark
+ {integer_to_list(list_to_integer(Num)),0};
+ [Num,Dec] ->
+ NewDec = ZeroDecimal(remove_trailing_zeros(Dec)),
+ NewMan = integer_to_list(list_to_integer(Num)) ++ NewDec,
+ {integer_to_list(list_to_integer(NewMan)),
+ length(NewDec)}
+ end
+ end,
+
+ encode_real_as_string(C, NewMantissa, Exponent - LenDecimal).
+
+encode_real_as_string(_C, Mantissa, Exponent)
+ when is_list(Mantissa), is_integer(Exponent) ->
+ %% Remove trailing zeros in Mantissa and add this to Exponent
+ TruncMant = remove_trailing_zeros(Mantissa),
+
+ ExpIncr = length(Mantissa) - length(TruncMant),
+
+ ExpStr = integer_to_list(Exponent + ExpIncr),
+
+ ExpBin =
+ case ExpStr of
+ "0" ->
+ <<"E+0">>;
+ _ ->
+ ExpB = list_to_binary(ExpStr),
+ <<$E,ExpB/binary>>
+ end,
+ ManBin = list_to_binary(TruncMant),
+ NR3 = 3,
+ {<<NR3,ManBin/binary,$.,ExpBin/binary>>,
+ 2 + byte_size(ManBin) + byte_size(ExpBin)}.
+
+remove_trailing_zeros(IntStr) ->
+ case lists:dropwhile(fun($0)-> true;
+ (_) -> false
+ end, lists:reverse(IntStr)) of
+ [] ->
+ "0";
+ ReversedIntStr ->
+ lists:reverse(ReversedIntStr)
+ end.
+
+truncate_zeros(Num) ->
+ truncate_zeros(Num, 0).
+truncate_zeros(0, Sum) ->
+ {0,Sum};
+truncate_zeros(M, Sum) ->
+ case M band 16#f =:= M band 16#e of
+ true -> truncate_zeros(M bsr 1, Sum+1);
+ _ -> {M,Sum}
+ end.
+
+
+%%============================================================================
+%% decode real value
+%%
+%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
+%% {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
+%% RestBuff}
+%%
+%% only for base 2 decoding sofar!!
+%%============================================================================
+
+decode_real(Buffer) ->
+ Sz = byte_size(Buffer),
+ {RealVal,<<>>,Sz} = decode_real2(Buffer, [], Sz, 0),
+ RealVal.
+
+decode_real2(Buffer, _C, 0, _RemBytes) ->
+ {0,Buffer};
+decode_real2(Buffer0, _C, Len, RemBytes1) ->
+ <<First, Buffer2/binary>> = Buffer0,
+ if
+ First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
+ First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
+ First =:= 1 orelse First =:= 2 orelse First =:= 3 ->
+ %% charcter string encoding of base 10
+ {NRx,Rest} = split_binary(Buffer2,Len-1),
+ {binary_to_list(NRx),Rest,Len};
+ true ->
+ %% have some check here to verify only supported bases (2)
+ %% not base 8 or 16
+ <<_B7:1,Sign:1,BB:2,_FF:2,EE:2>> = <<First>>,
+ Base =
+ case BB of
+ 0 -> 2; % base 2, only one so far
+ _ -> exit({error,{asn1, {non_supported_base, BB}}})
+ end,
+ {FirstLen, {Exp, Buffer3,_Rb2}, RemBytes2} =
+ case EE of
+ 0 -> {2, decode_integer2(1, Buffer2, RemBytes1), RemBytes1+1};
+ 1 -> {3, decode_integer2(2, Buffer2, RemBytes1), RemBytes1+2};
+ 2 -> {4, decode_integer2(3, Buffer2, RemBytes1), RemBytes1+3};
+ 3 ->
+ <<ExpLen1,RestBuffer/binary>> = Buffer2,
+ { ExpLen1 + 2,
+ decode_integer2(ExpLen1, RestBuffer, RemBytes1),
+ RemBytes1+ExpLen1}
+ end,
+ %% io:format("FirstLen: ~w, Exp: ~w, Buffer3: ~w ~n",
+
+ Length = Len - FirstLen,
+ <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
+ {{Mantissa, Buffer4}, RemBytes3} =
+ if Sign =:= 0 ->
+ %% io:format("sign plus~n"),
+ {{LongInt, RestBuff}, 1 + Length};
+ true ->
+ %% io:format("sign minus~n"),
+ {{-LongInt, RestBuff}, 1 + Length}
+ end,
+ {{Mantissa, Base, Exp}, Buffer4, RemBytes2+RemBytes3}
+ 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 16#ff| Acc]).
+
+encode_neg_integer(-1, [B1|_T]=L) when B1 > 127 ->
+ L;
+encode_neg_integer(N, Acc) ->
+ encode_neg_integer(N bsr 8, [N band 16#ff|Acc]).
+
+
+%% Val must be >= 0
+real_mininum_octets(Val) ->
+ real_mininum_octets(Val, []).
+
+real_mininum_octets(0, Acc) ->
+ Acc;
+real_mininum_octets(Val, Acc) ->
+ real_mininum_octets(Val bsr 8, [Val band 16#FF | Acc]).
+
+%% decoding postitive integer values.
+decode_integer2(Len, <<0:1,_:7,_Bs/binary>> = Bin, RemovedBytes) ->
+ <<Int:Len/unit:8,Buffer2/binary>> = Bin,
+ {Int,Buffer2,RemovedBytes};
+%% decoding negative integer values.
+decode_integer2(Len, <<1:1,B2:7,Bs/binary>>, RemovedBytes) ->
+ <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
+ Int = N - (1 bsl (8 * Len - 1)),
+ {Int,Buffer2,RemovedBytes}.
diff --git a/lib/asn1/src/asn1rtt_uper.erl b/lib/asn1/src/asn1rtt_uper.erl
new file mode 100644
index 0000000000..b5e8a3c3bb
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_uper.erl
@@ -0,0 +1,1042 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(asn1rtt_uper).
+
+-export([setext/1, fixoptionals/3,
+ fixextensions/2,
+ skipextensions/3, getbit/1, getchoice/3 ]).
+-export([set_choice/3, encode_integer/2, encode_integer/3]).
+-export([encode_small_number/1, encode_constrained_number/2,
+ encode_boolean/1,
+ encode_length/1, encode_length/2,
+ encode_bit_string/3]).
+-export([encode_octet_string/1,encode_octet_string/2,
+ encode_relative_oid/1,
+ encode_object_identifier/1,
+ complete/1, complete_NFP/1]).
+
+ -export([encode_open_type/1]).
+
+ -export([encode_UniversalString/2,
+ encode_PrintableString/2,
+ encode_GeneralString/2,
+ encode_GraphicString/2,
+ encode_TeletexString/2,
+ encode_VideotexString/2,
+ encode_VisibleString/2,
+ encode_UTF8String/1,
+ encode_BMPString/2,
+ encode_IA5String/2,
+ encode_NumericString/2,
+ encode_ObjectDescriptor/2
+ ]).
+
+-define('16K',16384).
+-define('32K',32768).
+-define('64K',65536).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% setext(true|false) -> CompleteList
+%%
+
+setext(false) ->
+ <<0:1>>;
+setext(true) ->
+ <<1:1>>.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This is the new fixoptionals/3 which is used by the new generates
+%%
+fixoptionals(OptList,OptLength,Val) when is_tuple(Val) ->
+ Bits = fixoptionals(OptList,Val,0),
+ {Val,<<Bits:OptLength>>};
+
+fixoptionals([],_Val,Acc) ->
+ %% Optbits
+ Acc;
+fixoptionals([{Pos,DefVal}|Ot],Val,Acc) ->
+ case element(Pos,Val) of
+ asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1);
+ DefVal -> fixoptionals(Ot,Val,Acc bsl 1);
+ _ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1)
+ end;
+fixoptionals([Pos|Ot],Val,Acc) ->
+ case element(Pos,Val) of
+ asn1_NOVALUE -> fixoptionals(Ot,Val,Acc bsl 1);
+ asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1);
+ _ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1)
+ end.
+
+
+fixextensions({ext,ExtPos,ExtNum},Val) ->
+ case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
+ 0 -> [];
+ ExtBits ->
+ [encode_small_length(ExtNum),<<ExtBits:ExtNum>>]
+ end.
+
+fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
+ Acc;
+fixextensions(Pos,ExtPos,Val,Acc) ->
+ Bit = case catch(element(Pos+1,Val)) of
+ asn1_NOVALUE ->
+ 0;
+ asn1_NOEXTVALUE ->
+ 0;
+ {'EXIT',_} ->
+ 0;
+ _ ->
+ 1
+ end,
+ fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
+
+skipextensions(Bytes0, Nr, ExtensionBitstr) when is_bitstring(ExtensionBitstr) ->
+ Prev = Nr - 1,
+ case ExtensionBitstr of
+ <<_:Prev,1:1,_/bitstring>> ->
+ {Len,Bytes1} = decode_length(Bytes0),
+ <<_:Len/binary,Bytes2/bitstring>> = Bytes1,
+ skipextensions(Bytes2, Nr+1, ExtensionBitstr);
+ <<_:Prev,0:1,_/bitstring>> ->
+ skipextensions(Bytes0, Nr+1, ExtensionBitstr);
+ _ ->
+ Bytes0
+ end.
+
+
+getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
+ {0,Bytes};
+getchoice(Bytes,_,1) ->
+ decode_small_number(Bytes);
+getchoice(Bytes,NumChoices,0) ->
+ decode_constrained_number(Bytes,{0,NumChoices-1}).
+
+
+getbit(Buffer) ->
+ <<B:1,Rest/bitstring>> = Buffer,
+ {B,Rest}.
+
+getbits(Buffer, Num) when is_bitstring(Buffer) ->
+ <<Bs:Num,Rest/bitstring>> = Buffer,
+ {Bs,Rest}.
+
+
+%% Pick the first Num octets.
+%% Returns octets as an integer with bit significance as in buffer.
+getoctets(Buffer, Num) when is_bitstring(Buffer) ->
+ <<Val:Num/integer-unit:8,RestBitStr/bitstring>> = Buffer,
+ {Val,RestBitStr}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
+%% Alt = atom()
+%% Altnum = integer() | {integer(),integer()}% number of alternatives
+%% Choices = [atom()] | {[atom()],[atom()]}
+%% When Choices is a tuple the first list is the Rootset and the
+%% second is the Extensions and then Altnum must also be a tuple with the
+%% lengths of the 2 lists
+%%
+set_choice(Alt, {L1,L2}, {Len1,_Len2}) ->
+ case set_choice_tag(Alt, L1) of
+ N when is_integer(N), Len1 > 1 ->
+ [<<0:1>>, % the value is in the root set
+ encode_integer([{'ValueRange',{0,Len1-1}}],N)];
+ N when is_integer(N) ->
+ <<0:1>>; % no encoding if only 0 or 1 alternative
+ false ->
+ [<<1:1>>, % extension value
+ case set_choice_tag(Alt,L2) of
+ N2 when is_integer(N2) ->
+ encode_small_number(N2);
+ false ->
+ unknown_choice_alt
+ end]
+ end;
+set_choice(Alt,L,Len) ->
+ case set_choice_tag(Alt,L) of
+ N when is_integer(N), Len > 1 ->
+ encode_integer([{'ValueRange',{0,Len-1}}],N);
+ N when is_integer(N) ->
+ []; % no encoding if only 0 or 1 alternative
+ false ->
+ [unknown_choice_alt]
+ end.
+
+set_choice_tag(Alt,Choices) ->
+ set_choice_tag(Alt,Choices,0).
+
+set_choice_tag(Alt,[Alt|_Rest],Tag) ->
+ Tag;
+set_choice_tag(Alt,[_H|Rest],Tag) ->
+ set_choice_tag(Alt,Rest,Tag+1);
+set_choice_tag(_Alt,[],_Tag) ->
+ false.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_open_type(Constraint, Value) -> CompleteList
+%% Value = list of bytes of an already encoded value (the list must be flat)
+%% | binary
+%% Contraint = not used in this version
+%%
+encode_open_type(Val) when is_list(Val) ->
+ encode_open_type(list_to_binary(Val));
+encode_open_type(Val) when is_binary(Val) ->
+ [encode_length(byte_size(Val)),Val].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
+%% encode_integer(Constraint,Value) -> CompleteList
+%% encode_integer(Constraint,{Name,Value}) -> CompleteList
+%%
+%%
+encode_integer(C, V, NamedNumberList) when is_atom(V) ->
+ case lists:keyfind(V, 1, NamedNumberList) of
+ {_,NewV} ->
+ encode_integer(C, NewV);
+ false ->
+ exit({error,{asn1,{namednumber,V}}})
+ end;
+encode_integer(C, V, _NamedNumberList) when is_integer(V) ->
+ encode_integer(C, V).
+
+encode_integer([{Rc,_Ec}],Val) when is_tuple(Rc) ->
+ try
+ [<<0:1>>,encode_integer([Rc], Val)]
+ catch
+ _:{error,{asn1,_}} ->
+ [<<1:1>>,encode_unconstrained_number(Val)]
+ end;
+encode_integer(C, Val) when is_list(C) ->
+ case get_constraint(C, 'SingleValue') of
+ no ->
+ encode_integer1(C,Val);
+ V when is_integer(V), V =:= Val ->
+ []; % a type restricted to a single value encodes to nothing
+ V when is_list(V) ->
+ case lists:member(Val,V) of
+ true ->
+ encode_integer1(C,Val);
+ _ ->
+ exit({error,{asn1,{illegal_value,Val}}})
+ end;
+ _ ->
+ exit({error,{asn1,{illegal_value,Val}}})
+ end.
+
+encode_integer1(C, Val) ->
+ case VR = get_constraint(C, 'ValueRange') of
+ no ->
+ encode_unconstrained_number(Val);
+ {Lb,'MAX'} ->
+ encode_semi_constrained_number(Lb, Val);
+ %% positive with range
+ {Lb,Ub} when Val >= Lb, Ub >= Val ->
+ encode_constrained_number(VR,Val);
+ _ ->
+ exit({error,{asn1,{illegal_value,VR,Val}}})
+ end.
+
+%% X.691:10.6 Encoding of a normally small non-negative whole number
+%% Use this for encoding of CHOICE index if there is an extension marker in
+%% the CHOICE
+encode_small_number(Val) when Val < 64 ->
+ <<Val:7>>;
+encode_small_number(Val) ->
+ [<<1:1>>|encode_semi_constrained_number(0, Val)].
+
+decode_small_number(Bytes) ->
+ {Bit,Bytes2} = getbit(Bytes),
+ case Bit of
+ 0 ->
+ getbits(Bytes2,6);
+ 1 ->
+ decode_semi_constrained_number(Bytes2)
+ end.
+
+%% X.691:10.7 Encoding of a semi-constrained whole number
+encode_semi_constrained_number(Lb, Val) ->
+ %% encoding in minimum number of octets preceeded by a length
+ Val2 = Val - Lb,
+ Bin = eint_bin_positive(Val2),
+ Size = byte_size(Bin),
+ if
+ Size < 128 ->
+ [<<Size>>,Bin];
+ Size < 16384 ->
+ [<<2:2,Size:14>>,Bin];
+ true ->
+ [encode_length(Size),Bin]
+ end.
+
+decode_semi_constrained_number(Bytes) ->
+ {Len,Bytes2} = decode_length(Bytes),
+ {V,Bytes3} = getoctets(Bytes2,Len),
+ {V,Bytes3}.
+
+encode_constrained_number({Lb,Ub}, Val) when Val >= Lb, Ub >= Val ->
+ Range = Ub - Lb + 1,
+ Val2 = Val - Lb,
+ NumBits = num_bits(Range),
+ <<Val2:NumBits>>;
+encode_constrained_number(Range,Val) ->
+ exit({error,{asn1,{integer_range,Range,value,Val}}}).
+
+
+decode_constrained_number(Buffer, {Lb,Ub}) ->
+ Range = Ub - Lb + 1,
+ NumBits = num_bits(Range),
+ {Val,Remain} = getbits(Buffer,NumBits),
+ {Val+Lb,Remain}.
+
+%% X.691:10.8 Encoding of an unconstrained whole number
+
+encode_unconstrained_number(Val) when Val >= 0 ->
+ Oct = eint_bin_2Cs(Val),
+ Len = byte_size(Oct),
+ if
+ Len < 128 ->
+ [<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster
+ Len < 16384 ->
+ [<<2:2,Len:14>>,Oct];
+ true ->
+ [encode_length(Len),<<Len:16>>,Oct]
+ end;
+encode_unconstrained_number(Val) -> % negative
+ Oct = enint(Val,[]),
+ Len = byte_size(Oct),
+ if
+ Len < 128 ->
+ [<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster
+ Len < 16384 ->
+ [<<2:2,Len:14>>,Oct];
+ true ->
+ [encode_length(Len),Oct]
+ end.
+
+
+eint_bin_2Cs(Int) ->
+ case eint_bin_positive(Int) of
+ <<B,_/binary>> = Bin when B > 16#7f ->
+ <<0,Bin/binary>>;
+ Bin -> Bin
+ end.
+
+%% returns the integer as a binary
+eint_bin_positive(Val) when Val < 16#100 ->
+ <<Val>>;
+eint_bin_positive(Val) when Val < 16#10000 ->
+ <<Val:16>>;
+eint_bin_positive(Val) when Val < 16#1000000 ->
+ <<Val:24>>;
+eint_bin_positive(Val) when Val < 16#100000000 ->
+ <<Val:32>>;
+eint_bin_positive(Val) ->
+ list_to_binary([eint_bin_positive2(Val bsr 32),<<Val:32>>]).
+
+eint_bin_positive2(Val) when Val < 16#100 ->
+ <<Val>>;
+eint_bin_positive2(Val) when Val < 16#10000 ->
+ <<Val:16>>;
+eint_bin_positive2(Val) when Val < 16#1000000 ->
+ <<Val:24>>;
+eint_bin_positive2(Val) when Val < 16#100000000 ->
+ <<Val:32>>;
+eint_bin_positive2(Val) ->
+ [eint_bin_positive2(Val bsr 32),<<Val:32>>].
+
+
+
+
+enint(-1, [B1|T]) when B1 > 127 ->
+ list_to_binary([B1|T]);
+enint(N, Acc) ->
+ enint(N bsr 8, [N band 16#ff|Acc]).
+
+
+%% X.691:10.9 Encoding of a length determinant
+%%encode_small_length(undefined,Len) -> % null means no UpperBound
+%% encode_small_number(Len).
+
+%% X.691:10.9.3.5
+%% X.691:10.9.3.7
+encode_length(Len) -> % un-constrained
+ if
+ Len < 128 ->
+ <<Len>>;
+ Len < 16384 ->
+ <<2:2,Len:14>>;
+ true -> % should be able to endode length >= 16384
+ error({error,{asn1,{encode_length,{nyi,above_16k}}}})
+ end.
+
+encode_length(undefined, Len) -> % unconstrained
+ encode_length(Len);
+encode_length({0,'MAX'},Len) ->
+ encode_length(undefined, Len);
+encode_length({Lb,Ub}=Vr, Len) when Ub =< 65535, Lb >= 0 -> % constrained
+ encode_constrained_number(Vr,Len);
+encode_length({Lb,_Ub}, Len) when is_integer(Lb), Lb >= 0 -> % Ub > 65535
+ encode_length(Len);
+encode_length({{Lb,Ub}=Vr,Ext},Len)
+ when Ub =< 65535, Lb >= 0, Len =< Ub, is_list(Ext) ->
+ %% constrained extensible
+ [<<0:1>>,encode_constrained_number(Vr,Len)];
+encode_length({{Lb,_Ub},Ext}, Len) when is_list(Ext) ->
+ [<<1:1>>,encode_semi_constrained_number(Lb, Len)];
+encode_length(SingleValue, _Len) when is_integer(SingleValue) ->
+ [].
+
+%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension
+%% additions in a sequence or set
+encode_small_length(Len) when Len =< 64 ->
+ <<(Len-1):7>>;
+encode_small_length(Len) ->
+ [<<1:1>>,encode_length(Len)].
+
+
+%% un-constrained
+decode_length(<<0:1,Oct:7,Rest/bitstring>>) ->
+ {Oct,Rest};
+decode_length(<<2:2,Val:14,Rest/bitstring>>) ->
+ {Val,Rest};
+decode_length(<<3:2,_:14,_Rest/bitstring>>) ->
+ exit({error,{asn1,{decode_length,{nyi,above_16k}}}}).
+
+ % X.691:11
+encode_boolean(true) ->
+ <<1:1>>;
+encode_boolean(false) ->
+ <<0:1>>;
+encode_boolean(Val) ->
+ exit({error,{asn1,{encode_boolean,Val}}}).
+
+
+%%============================================================================
+%%============================================================================
+%% Bitstring value, ITU_T X.690 Chapter 8.5
+%%============================================================================
+%%============================================================================
+
+%%============================================================================
+%% encode bitstring value
+%%============================================================================
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% bitstring NamedBitList
+%% Val can be of:
+%% - [identifiers] where only named identifers are set to one,
+%% the Constraint must then have some information of the
+%% bitlength.
+%% - [list of ones and zeroes] all bits
+%% - integer value representing the bitlist
+%% C is constraint Len, only valid when identifiers are present
+
+
+%% when the value is a list of {Unused,BinBits}, where
+%% Unused = integer(),
+%% BinBits = binary().
+
+encode_bit_string(C, Bits, NamedBitList) when is_bitstring(Bits) ->
+ PadLen = (8 - (bit_size(Bits) band 7)) band 7,
+ Compact = {PadLen,<<Bits/bitstring,0:PadLen>>},
+ encode_bit_string(C, Compact, NamedBitList);
+encode_bit_string(C, {Unused,BinBits}=Bin, NamedBitList)
+ when is_integer(Unused), is_binary(BinBits) ->
+ encode_bin_bit_string(C, Bin, NamedBitList);
+
+encode_bit_string(C, BitListVal, NamedBitList) ->
+ encode_bit_string1(C, BitListVal, NamedBitList).
+
+%% when the value is a list of named bits
+encode_bit_string1(C, [FirstVal|_RestVal]=LoNB, NamedBitList)
+ when is_atom(FirstVal) ->
+ ToSetPos = get_all_bitposes(LoNB, NamedBitList, []),
+ BitList = make_and_set_list(ToSetPos, 0),
+ encode_bit_string1(C, BitList, NamedBitList);
+encode_bit_string1(C, [{bit,_No}|_RestVal]=BL, NamedBitList) ->
+ ToSetPos = get_all_bitposes(BL, NamedBitList, []),
+ BitList = make_and_set_list(ToSetPos, 0),
+ encode_bit_string1(C, BitList, NamedBitList);
+%% when the value is a list of ones and zeroes
+encode_bit_string1(Int, BitListValue, _)
+ when is_list(BitListValue), is_integer(Int) ->
+ %% The type is constrained by a single value size constraint
+ bit_list2bitstr(Int, BitListValue);
+encode_bit_string1(no, BitListValue, [])
+ when is_list(BitListValue) ->
+ Len = length(BitListValue),
+ [encode_length(Len),bit_list2bitstr(Len,BitListValue)];
+encode_bit_string1(C, BitListValue,[])
+ when is_list(BitListValue) ->
+ Len = length(BitListValue),
+ [encode_length(C, Len),bit_list2bitstr(Len,BitListValue)];
+encode_bit_string1(no, BitListValue,_NamedBitList)
+ when is_list(BitListValue) ->
+ NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
+ lists:reverse(BitListValue))),
+ Len = length(NewBitLVal),
+ [encode_length(Len),bit_list2bitstr(Len,NewBitLVal)];
+encode_bit_string1(C, BitListValue, _NamedBitList)
+ when is_list(BitListValue) ->% C = {_,'MAX'}
+ NewBitStr = bitstr_trailing_zeros(BitListValue, C),
+ [encode_length(C, bit_size(NewBitStr)),NewBitStr];
+
+
+%% when the value is an integer
+encode_bit_string1(C, IntegerVal, NamedBitList) when is_integer(IntegerVal)->
+ BitList = int_to_bitlist(IntegerVal),
+ encode_bit_string1(C, BitList, NamedBitList).
+
+bit_list2bitstr(Len,BitListValue) ->
+ case length(BitListValue) of
+ Len ->
+ << <<B:1>> || B <- BitListValue>>;
+ L when L > Len -> % truncate
+ <<(<< <<B:1>> || B <- BitListValue>>):Len/bitstring>>;
+ L -> % Len > L -> pad
+ <<(<< <<B:1>> || B <- BitListValue>>)/bitstring,0:(Len-L)>>
+ end.
+
+adjust_trailing_zeros(Len, Bin) when Len =:= bit_size(Bin) ->
+ Bin;
+adjust_trailing_zeros(Len, Bin) when Len > bit_size(Bin) ->
+ <<Bin/bitstring,0:(Len-bit_size(Bin))>>;
+adjust_trailing_zeros(Len,Bin) ->
+ <<Bin:Len/bitstring>>.
+
+bitstr_trailing_zeros(BitList, C) when is_integer(C) ->
+ bitstr_trailing_zeros1(BitList, C, C);
+bitstr_trailing_zeros(BitList, {Lb,Ub}) when is_integer(Lb) ->
+ bitstr_trailing_zeros1(BitList,Lb,Ub);
+bitstr_trailing_zeros(BitList, {{Lb,Ub},_}) when is_integer(Lb) ->
+ bitstr_trailing_zeros1(BitList, Lb, Ub);
+bitstr_trailing_zeros(BitList, _) ->
+ bit_list2bitstr(length(BitList), BitList).
+
+bitstr_trailing_zeros1(BitList, Lb, Ub) ->
+ case length(BitList) of
+ Lb -> bit_list2bitstr(Lb, BitList);
+ B when B < Lb -> bit_list2bitstr(Lb, BitList);
+ D -> F = fun(L,LB,LB,_,_)->bit_list2bitstr(LB,lists:reverse(L));
+ ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun);
+ (L,L1,_,UB,_)when L1 =< UB ->
+ bit_list2bitstr(L1,lists:reverse(L));
+ (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING,
+ BitList}}) end,
+ F(lists:reverse(BitList),D,Lb,Ub,F)
+ end.
+
+%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
+%% Unused = integer(),i.e. number unused bits in least sign. byte of
+%% BinBits = binary().
+encode_bin_bit_string(C, {_,BinBits}, _NamedBitList)
+ when is_integer(C), C =< 16 ->
+ adjust_trailing_zeros(C, BinBits);
+encode_bin_bit_string(C, {_Unused,BinBits}, _NamedBitList)
+ when is_integer(C) ->
+ adjust_trailing_zeros(C, BinBits);
+encode_bin_bit_string(C, {_,_}=UnusedAndBin, NamedBitList) ->
+ %% removes all trailing bits if NamedBitList is not empty
+ BitStr = remove_trailing_bin(NamedBitList, UnusedAndBin),
+ case C of
+ {Lb,Ub} when is_integer(Lb),is_integer(Ub) ->
+ [encode_length({Lb,Ub},bit_size(BitStr)),BitStr];
+ no ->
+ [encode_length(bit_size(BitStr)),BitStr];
+ Sc ->
+ [encode_length(Sc,bit_size(BitStr)),BitStr]
+ end.
+
+
+remove_trailing_bin([], {Unused,Bin}) ->
+ BS = bit_size(Bin)-Unused,
+ <<BitStr:BS/bitstring,_:Unused>> = Bin,
+ BitStr;
+remove_trailing_bin(_NamedNumberList, {_Unused,<<>>}) ->
+ <<>>;
+remove_trailing_bin(NamedNumberList, {_Unused,Bin}) ->
+ Size = byte_size(Bin)-1,
+ <<Bfront:Size/binary, LastByte:8>> = Bin,
+
+ %% clear the Unused bits to be sure
+ Unused1 = trailingZeroesInNibble(LastByte band 15),
+ Unused2 =
+ case Unused1 of
+ 4 ->
+ 4 + trailingZeroesInNibble(LastByte bsr 4);
+ _ -> Unused1
+ end,
+ case Unused2 of
+ 8 ->
+ remove_trailing_bin(NamedNumberList,{0,Bfront});
+ _ ->
+ BS = bit_size(Bin) - Unused2,
+ <<BitStr:BS/bitstring,_:Unused2>> = Bin,
+ BitStr
+ end.
+
+trailingZeroesInNibble(0) ->
+ 4;
+trailingZeroesInNibble(1) ->
+ 0;
+trailingZeroesInNibble(2) ->
+ 1;
+trailingZeroesInNibble(3) ->
+ 0;
+trailingZeroesInNibble(4) ->
+ 2;
+trailingZeroesInNibble(5) ->
+ 0;
+trailingZeroesInNibble(6) ->
+ 1;
+trailingZeroesInNibble(7) ->
+ 0;
+trailingZeroesInNibble(8) ->
+ 3;
+trailingZeroesInNibble(9) ->
+ 0;
+trailingZeroesInNibble(10) ->
+ 1;
+trailingZeroesInNibble(11) ->
+ 0;
+trailingZeroesInNibble(12) -> %#1100
+ 2;
+trailingZeroesInNibble(13) ->
+ 0;
+trailingZeroesInNibble(14) ->
+ 1;
+trailingZeroesInNibble(15) ->
+ 0.
+
+
+%%%%%%%%%%%%%%%
+%%
+
+int_to_bitlist(Int) when is_integer(Int), Int > 0 ->
+ [Int band 1 | int_to_bitlist(Int bsr 1)];
+int_to_bitlist(0) ->
+ [].
+
+
+%%%%%%%%%%%%%%%%%%
+%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
+%% [sorted_list_of_bitpositions_to_set]
+
+get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
+ get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
+
+get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
+ case lists:keyfind(Val, 1, NamedBitList) of
+ {_ValName, ValPos} ->
+ get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
+ false ->
+ exit({error,{asn1, {bitstring_namedbit, Val}}})
+ end;
+get_all_bitposes([], _NamedBitList, Ack) ->
+ lists:sort(Ack).
+
+%%%%%%%%%%%%%%%%%%
+%% make_and_set_list([list of positions to set to 1])->
+%% returns list with all in SetPos set.
+%% in positioning in list the first element is 0, the second 1 etc.., but
+%%
+
+make_and_set_list([XPos|SetPos], XPos) ->
+ [1 | make_and_set_list(SetPos, XPos + 1)];
+make_and_set_list([Pos|SetPos], XPos) ->
+ [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
+make_and_set_list([], _) ->
+ [].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% X.691:16
+%% encode_octet_string(Val)
+%% encode_octet_string(Constraint, Val)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+encode_octet_string(Val) ->
+ try
+ [encode_length(length(Val)),list_to_binary(Val)]
+ catch
+ error:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end.
+
+encode_octet_string(C, Val) ->
+ case C of
+ 1 ->
+ list_to_binary(Val);
+ 2 ->
+ list_to_binary(Val);
+ {_,_}=VR ->
+ try
+ [encode_length(VR, length(Val)),list_to_binary(Val)]
+ catch
+ error:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
+ Sv when is_integer(Sv), Sv =:= length(Val) -> % fixed length
+ if
+ Sv =< 65535 ->
+ list_to_binary(Val);
+ true ->
+ encode_fragmented_octet_string(Val)
+ end;
+ Sv when is_list(Sv) ->
+ try
+ [encode_length({hd(Sv),lists:max(Sv)},
+ length(Val)),list_to_binary(Val)]
+ catch
+ error:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end
+ end.
+
+
+encode_fragmented_octet_string(Val) ->
+ Bin = list_to_binary(Val),
+ efos_1(Bin).
+
+efos_1(<<B:16#10000/binary,T/binary>>) ->
+ [<<3:2,4:6>>,B|efos_1(T)];
+efos_1(<<B:16#C000/binary,T/binary>>) ->
+ [<<3:2,3:6>>,B|efos_1(T)];
+efos_1(<<B:16#8000/binary,T/binary>>) ->
+ [<<3:2,2:6>>,B|efos_1(T)];
+efos_1(<<B:16#4000/binary,T/binary>>) ->
+ [<<3:2,1:6>>,B|efos_1(T)];
+efos_1(<<B/bitstring>>) ->
+ Len = byte_size(B),
+ [encode_length(Len),B].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Restricted char string types
+%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
+%% X.691:26 and X.680:34-36
+%%encode_restricted_string('BMPString',Constraints,Extension,Val)
+
+
+encode_restricted_string(Val) when is_list(Val)->
+ [encode_length(length(Val)),list_to_binary(Val)].
+
+encode_known_multiplier_string(StringType, C, Val) ->
+ Result = chars_encode(C, StringType, Val),
+ NumBits = get_NumBits(C, StringType),
+ case get_constraint(C, 'SizeConstraint') of
+ Ub when is_integer(Ub), Ub*NumBits =< 16 ->
+ Result;
+ 0 ->
+ [];
+ Ub when is_integer(Ub),Ub =<65535 -> % fixed length
+ Result;
+ {Ub,Lb} ->
+ [encode_length({Ub,Lb}, length(Val)),Result];
+ Vl when is_list(Vl) ->
+ [encode_length({lists:min(Vl),lists:max(Vl)}, length(Val)),Result];
+ no ->
+ [encode_length(length(Val)),Result]
+ end.
+
+encode_NumericString(C,Val) ->
+ encode_known_multiplier_string('NumericString',C,Val).
+
+encode_PrintableString(C,Val) ->
+ encode_known_multiplier_string('PrintableString',C,Val).
+
+encode_VisibleString(C,Val) -> % equivalent with ISO646String
+ encode_known_multiplier_string('VisibleString',C,Val).
+
+encode_IA5String(C,Val) ->
+ encode_known_multiplier_string('IA5String',C,Val).
+
+encode_BMPString(C,Val) ->
+ encode_known_multiplier_string('BMPString',C,Val).
+
+encode_UniversalString(C,Val) ->
+ encode_known_multiplier_string('UniversalString',C,Val).
+
+
+%% end of known-multiplier strings for which PER visible constraints are
+%% applied
+
+encode_GeneralString(_C,Val) ->
+ encode_restricted_string(Val).
+
+encode_GraphicString(_C,Val) ->
+ encode_restricted_string(Val).
+
+encode_ObjectDescriptor(_C,Val) ->
+ encode_restricted_string(Val).
+
+encode_TeletexString(_C,Val) -> % equivalent with T61String
+ encode_restricted_string(Val).
+
+encode_VideotexString(_C,Val) ->
+ encode_restricted_string(Val).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% chars_encode(C,StringType,Value) -> ValueList
+%%
+%% encodes chars according to the per rules taking the constraint PermittedAlphabet
+%% into account.
+%% This function does only encode the value part and NOT the length
+
+chars_encode(C,StringType,Value) ->
+ case {StringType,get_constraint(C,'PermittedAlphabet')} of
+ {'UniversalString',{_,_Sv}} ->
+ exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
+ {'BMPString',{_,_Sv}} ->
+ exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
+ _ ->
+ {NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
+ chars_encode2(Value,NumBits,CharOutTab)
+ end.
+
+chars_encode2([H|T],NumBits,{Min,Max,notab}) when H =< Max, H >= Min ->
+ [<<(H-Min):NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
+chars_encode2([H|T],NumBits,{Min,Max,Tab}) when H =< Max, H >= Min ->
+ Ch = exit_if_false(H,element(H-Min+1,Tab)),
+ [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,Tab})];
+chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,notab}) ->
+ %% no value range check here (ought to be, but very expensive)
+ Ch = ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,
+ [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
+chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
+ %% no value range check here (ought to be, but very expensive)
+ Ch = exit_if_false({A,B,C,D},element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)),
+ [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
+chars_encode2([H|_T],_,{_,_,_}) ->
+ exit({error,{asn1,{illegal_char_value,H}}});
+chars_encode2([],_,_) ->
+ [].
+
+exit_if_false(V,false)->
+ exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}});
+exit_if_false(_,V) ->V.
+
+
+get_NumBits(C,StringType) ->
+ case get_constraint(C,'PermittedAlphabet') of
+ {'SingleValue',Sv} ->
+ charbits(length(Sv));
+ no ->
+ case StringType of
+ 'IA5String' ->
+ charbits(128); % 16#00..16#7F
+ 'VisibleString' ->
+ charbits(95); % 16#20..16#7E
+ 'PrintableString' ->
+ charbits(74); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
+ 'NumericString' ->
+ charbits(11); % $ ,"0123456789"
+ 'UniversalString' ->
+ 32;
+ 'BMPString' ->
+ 16
+ end
+ end.
+
+get_CharOutTab(C,StringType) ->
+ case get_constraint(C,'PermittedAlphabet') of
+ {'SingleValue',Sv} ->
+ get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv);
+ no ->
+ case StringType of
+ 'IA5String' ->
+ {0,16#7F,notab};
+ 'VisibleString' ->
+ get_CharTab2(C,StringType,16#20,16#7F,notab);
+ 'PrintableString' ->
+ Chars = lists:sort(
+ " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
+ get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars);
+ 'NumericString' ->
+ get_CharTab2(C,StringType,16#20,$9," 0123456789");
+ 'UniversalString' ->
+ {0,16#FFFFFFFF,notab};
+ 'BMPString' ->
+ {0,16#FFFF,notab}
+ end
+ end.
+
+get_CharTab2(C,StringType,Min,Max,Chars) ->
+ BitValMax = (1 bsl get_NumBits(C,StringType))-1,
+ if
+ Max =< BitValMax ->
+ {0,Max,notab};
+ true ->
+ {Min,Max,create_char_tab(Min,Chars)}
+ end.
+
+create_char_tab(Min,L) ->
+ list_to_tuple(create_char_tab(Min,L,0)).
+create_char_tab(Min,[Min|T],V) ->
+ [V|create_char_tab(Min+1,T,V+1)];
+create_char_tab(_Min,[],_V) ->
+ [];
+create_char_tab(Min,L,V) ->
+ [false|create_char_tab(Min+1,L,V)].
+
+%% See Table 20.3 in Dubuisson
+charbits(NumOfChars) when NumOfChars =< 2 -> 1;
+charbits(NumOfChars) when NumOfChars =< 4 -> 2;
+charbits(NumOfChars) when NumOfChars =< 8 -> 3;
+charbits(NumOfChars) when NumOfChars =< 16 -> 4;
+charbits(NumOfChars) when NumOfChars =< 32 -> 5;
+charbits(NumOfChars) when NumOfChars =< 64 -> 6;
+charbits(NumOfChars) when NumOfChars =< 128 -> 7;
+charbits(NumOfChars) when NumOfChars =< 256 -> 8;
+charbits(NumOfChars) when NumOfChars =< 512 -> 9;
+charbits(NumOfChars) when NumOfChars =< 1024 -> 10;
+charbits(NumOfChars) when NumOfChars =< 2048 -> 11;
+charbits(NumOfChars) when NumOfChars =< 4096 -> 12;
+charbits(NumOfChars) when NumOfChars =< 8192 -> 13;
+charbits(NumOfChars) when NumOfChars =< 16384 -> 14;
+charbits(NumOfChars) when NumOfChars =< 32768 -> 15;
+charbits(NumOfChars) when NumOfChars =< 65536 -> 16;
+charbits(NumOfChars) when is_integer(NumOfChars) ->
+ 16 + charbits1(NumOfChars bsr 16).
+
+charbits1(0) ->
+ 0;
+charbits1(NumOfChars) ->
+ 1 + charbits1(NumOfChars bsr 1).
+
+
+%% UTF8String
+encode_UTF8String(Val) when is_binary(Val) ->
+ [encode_length(byte_size(Val)),Val];
+encode_UTF8String(Val) ->
+ Bin = list_to_binary(Val),
+ encode_UTF8String(Bin).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_object_identifier(Val) -> CompleteList
+%% encode_object_identifier({Name,Val}) -> CompleteList
+%% Val -> {Int1,Int2,...,IntN} % N >= 2
+%% Name -> atom()
+%% Int1 -> integer(0..2)
+%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
+%% Int3-N -> integer()
+%% CompleteList -> [binary()|bitstring()|list()]
+%%
+encode_object_identifier(Val) ->
+ OctetList = e_object_identifier(Val),
+ Octets = list_to_binary(OctetList), % performs a flatten at the same time
+ [encode_length(byte_size(Octets)),Octets].
+
+%% This code is copied from asn1_encode.erl (BER) and corrected and modified
+
+e_object_identifier({'OBJECT IDENTIFIER',V}) ->
+ e_object_identifier(V);
+e_object_identifier(V) when is_tuple(V) ->
+ e_object_identifier(tuple_to_list(V));
+
+%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
+e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 ->
+ Head = 40*E1 + E2, % weird
+ e_object_elements([Head|Tail],[]);
+e_object_identifier(Oid=[_,_|_Tail]) ->
+ exit({error,{asn1,{'illegal_value',Oid}}}).
+
+e_object_elements([],Acc) ->
+ lists:reverse(Acc);
+e_object_elements([H|T],Acc) ->
+ e_object_elements(T,[e_object_element(H)|Acc]).
+
+e_object_element(Num) when Num < 128 ->
+ [Num];
+e_object_element(Num) ->
+ [e_o_e(Num bsr 7)|[Num band 2#1111111]].
+e_o_e(Num) when Num < 128 ->
+ Num bor 2#10000000;
+e_o_e(Num) ->
+ [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_relative_oid(Val) -> CompleteList
+%% encode_relative_oid({Name,Val}) -> CompleteList
+encode_relative_oid(Val) when is_tuple(Val) ->
+ encode_relative_oid(tuple_to_list(Val));
+encode_relative_oid(Val) when is_list(Val) ->
+ Octets = list_to_binary([e_object_element(X)||X <- Val]),
+ [encode_length(byte_size(Octets)),Octets].
+
+
+get_constraint([{Key,V}],Key) ->
+ V;
+get_constraint([],_Key) ->
+ no;
+get_constraint(C,Key) ->
+ case lists:keyfind(Key, 1, C) of
+ false ->
+ no;
+ {_,V} ->
+ V
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% complete(InList) -> ByteList
+%% Takes a coded list with bits and bytes and converts it to a list of bytes
+%% Should be applied as the last step at encode of a complete ASN.1 type
+%%
+complete(InList) when is_list(InList) ->
+ case complete1(InList) of
+ <<>> ->
+ <<0>>;
+ Res ->
+ case bit_size(Res) band 7 of
+ 0 -> Res;
+ Bits -> <<Res/bitstring,0:(8-Bits)>>
+ end
+ end;
+complete(InList) when is_binary(InList) ->
+ InList;
+complete(InList) when is_bitstring(InList) ->
+ PadLen = 8 - (bit_size(InList) band 7),
+ <<InList/bitstring,0:PadLen>>.
+
+complete1(L) when is_list(L) ->
+ list_to_bitstring(L).
+
+%% Special version of complete that does not align the completed message.
+complete_NFP(InList) when is_list(InList) ->
+ list_to_bitstring(InList);
+complete_NFP(InList) when is_bitstring(InList) ->
+ InList.
+
+%% unaligned helpers
+
+%% 10.5.6 NOTE: If "range" satisfies the inequality 2^m < "range" =<
+%% 2^(m+1) then the number of bits = m + 1
+
+num_bits(N) -> num_bits(N, 1, 0).
+
+num_bits(N,T,B) when N =< T -> B;
+num_bits(N,T,B) -> num_bits(N, T bsl 1, B+1).
diff --git a/lib/asn1/src/prepare_templates.erl b/lib/asn1/src/prepare_templates.erl
new file mode 100644
index 0000000000..83155b2e52
--- /dev/null
+++ b/lib/asn1/src/prepare_templates.erl
@@ -0,0 +1,135 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(prepare_templates).
+-export([gen_asn1ct_rtt/1,gen_asn1ct_eval/1]).
+
+gen_asn1ct_rtt(Ms) ->
+ io:format("%% Generated by ~s. DO NOT EDIT THIS FILE.\n"
+ "%%\n"
+ "%% Input files:\n", [?MODULE]),
+ [io:put_chars(["%% ",M,$\n]) || M <- Ms],
+ io:nl(),
+ io:put_chars("-module(asn1ct_rtt).\n"
+ "-export([assert_defined/1,dependencies/1,code/0]).\n"
+ "\n"),
+ Forms = lists:sort(lists:append([abstract(M) || M <- Ms])),
+ Exp = lists:sort(exports(Forms)),
+ defined(Exp),
+ io:nl(),
+ Calls = calls(Forms),
+ R = sofs:relation(Calls),
+ Fam0 = sofs:relation_to_family(R),
+ Fam = sofs:to_external(Fam0),
+ dependencies(Fam),
+ io:nl(),
+ Funcs = [begin
+ Bin = list_to_binary([$\n|erl_pp:function(Func)]),
+ {{M,F,A},Bin}
+ end || {M,{function,_,F,A,_}=Func} <- Forms],
+ io:format("code() ->\n~p.\n\n", [Funcs]),
+ halt(0).
+
+gen_asn1ct_eval([File]) ->
+ {ok,Funcs} = file:consult(File),
+ asn1ct_func:start_link(),
+ [asn1ct_func:need(MFA) || MFA <- Funcs],
+ io:format("%% Generated by ~s. DO NOT EDIT THIS FILE.\n"
+ "%%\n"
+ "%% Input file: ~s\n\n", [?MODULE,File]),
+ io:format("-module(~s).\n", [filename:rootname(File)]),
+ gen_asn1ct_eval_exp(Funcs),
+ asn1ct_func:generate(group_leader()),
+ halt(0).
+
+gen_asn1ct_eval_exp(Funcs) ->
+ io:put_chars("-export(["),
+ gen_asn1ct_eval_exp_1(Funcs, ""),
+ io:put_chars("]).\n").
+
+gen_asn1ct_eval_exp_1([{_,F,A}|T], Sep) ->
+ io:put_chars(Sep),
+ io:format("~p/~p", [F,A]),
+ gen_asn1ct_eval_exp_1(T, ",\n");
+gen_asn1ct_eval_exp_1([], _) -> ok.
+
+defined([H|T]) ->
+ io:format("assert_defined(~p) -> ok", [H]),
+ case T of
+ [] ->
+ io:put_chars(".\n");
+ [_|_] ->
+ io:put_chars(";\n"),
+ defined(T)
+ end.
+
+dependencies([{K,V}|T]) ->
+ io:format("dependencies(~p) ->\n~p;\n", [K,V]),
+ dependencies(T);
+dependencies([]) ->
+ io:put_chars("dependencies(_) -> [].\n").
+
+abstract(File) ->
+ {ok,{M0,[{abstract_code,Abstract}]}} =
+ beam_lib:chunks(File, [abstract_code]),
+ {raw_abstract_v1,Forms} = Abstract,
+ M = module(M0),
+ [{M,F} || F <- Forms].
+
+module(M0) ->
+ "asn1rtt_" ++ M = atom_to_list(M0),
+ list_to_atom(M).
+
+exports([{M,{attribute,_,export,L}}|T]) ->
+ [{M,F,A} || {F,A} <- L] ++ exports(T);
+exports([_|T]) ->
+ exports(T);
+exports([]) -> [].
+
+calls([{M,{function,_,F,A,Body}}|T]) ->
+ MFA = {M,F,A},
+ case find_calls(Body, M) -- [MFA] of
+ [] ->
+ calls(T);
+ [_|_]=Calls ->
+ [{MFA,Callee} || Callee <- Calls] ++ calls(T)
+ end;
+calls([_|T]) ->
+ calls(T);
+calls([]) -> [].
+
+find_calls([{call,_,{atom,_,F},Args}|T], M) ->
+ Calls = find_calls(Args, M) ++ find_calls(T, M),
+ Arity = length(Args),
+ case is_bif(F, Arity) of
+ false ->
+ [{M,F,Arity}|Calls];
+ true ->
+ Calls
+ end;
+find_calls([{'fun',_,{function,F,A}}|T], M) ->
+ [{M,F,A}|find_calls(T, M)];
+find_calls([H|T], M) ->
+ find_calls(H, M) ++ find_calls(T, M);
+find_calls(Tuple, M) when is_tuple(Tuple) ->
+ find_calls(tuple_to_list(Tuple), M);
+find_calls(_, _) -> [].
+
+is_bif(F, Arity) ->
+ erl_internal:bif(F, Arity).
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index 1794d6bb71..1fa495d8f1 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -102,7 +102,6 @@ MODULES= \
test_driver_load \
testSelectionTypes \
test_undecoded_rest \
- test_inline \
testTcapsystem \
testNBAPsystem \
test_compile_options \
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index 325293f35d..0d09929f6d 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -66,12 +66,12 @@ groups() ->
{appup_test, [], [{asn1_appup_test, all}]},
{parallel, parallel([]),
- [{group, ber},
+ [cover,
+ {group, ber},
% Uses 'P-Record', 'Constraints', 'MEDIA-GATEWAY-CONTROL'...
{group, [], [parse,
test_driver_load,
test_undecoded_rest,
- test_inline,
specialized_decodes,
special_decode_performance,
testMegaco,
@@ -296,6 +296,28 @@ case_dir([C|Config], Opt) ->
%% Test cases
%%------------------------------------------------------------------------------
+%% Cover run-time functions that are only called by the ASN.1 compiler
+%% (if any).
+cover(_) ->
+ Wc = filename:join([code:lib_dir(asn1),"ebin","asn1ct_eval_*.beam"]),
+ Beams = filelib:wildcard(Wc),
+ true = Beams =/= [],
+ [begin
+ M0 = filename:basename(Beam),
+ M1 = filename:rootname(M0),
+ M = list_to_atom(M1),
+ "asn1ct_eval_" ++ Group0 = M1,
+ Group = list_to_atom(Group0),
+ io:format("%%\n"
+ "%% ~s\n"
+ "%%\n", [M]),
+ asn1ct_func:start_link(),
+ [asn1ct_func:need({Group,F,A}) ||
+ {F,A} <- M:module_info(exports), F =/= module_info],
+ asn1ct_func:generate(group_leader())
+ end || Beam <- Beams],
+ ok.
+
testPrim(Config) -> test(Config, fun testPrim/3).
testPrim(Config, Rule, Opts) ->
asn1_test_lib:compile_all(["Prim", "Real"], Config, [Rule|Opts]),
@@ -323,11 +345,16 @@ testPrimStrings(Config) -> test(Config, fun testPrimStrings/3).
testPrimStrings(Config, Rule, Opts) ->
asn1_test_lib:compile_all(["PrimStrings", "BitStr"], Config, [Rule|Opts]),
testPrimStrings_cases(Rule),
+ asn1_test_lib:compile_all(["PrimStrings", "BitStr"], Config,
+ [legacy_bit_string,Rule|Opts]),
+ testPrimStrings:bit_string(Rule),
+ asn1_test_lib:compile_all(["PrimStrings", "BitStr"], Config,
+ [compact_bit_string,Rule|Opts]),
+ testPrimStrings:bit_string(Rule),
?only_ber(testPrimStrings:more_strings(Rule)).
testPrimStrings_cases(Rule) ->
testPrimStrings:bit_string(Rule),
- testPrimStrings:bit_string_unnamed(Rule),
testPrimStrings:octet_string(Rule),
testPrimStrings:numeric_string(Rule),
testPrimStrings:other_strings(Rule),
@@ -978,14 +1005,8 @@ testSSLspecs(Config, Rule, Opts) ->
ok = testSSLspecs:compile(Config,
[Rule, compact_bit_string, der|Opts]),
testSSLspecs:run(Rule),
-
- case code:which(asn1ct) of
- cover_compiled ->
- ok;
- _ ->
- ok = testSSLspecs:compile_inline(Config, Rule),
- ok = testSSLspecs:run_inline(Rule)
- end.
+ ok = testSSLspecs:compile_combined(Config, Rule),
+ ok = testSSLspecs:run_combined(Rule).
testNortel(Config) -> test(Config, fun testNortel/3).
testNortel(Config, Rule, Opts) ->
@@ -996,23 +1017,7 @@ test_undecoded_rest(Config, Rule, Opts) ->
asn1_test_lib:compile("P-Record", Config, [Rule|Opts]),
ok = test_undecoded_rest:test([], Config),
asn1_test_lib:compile("P-Record", Config, [Rule,undec_rest|Opts]),
- case Rule of
- ber -> ok;
- _ -> test_undecoded_rest:test(undec_rest, Config)
- end.
-
-test_inline(Config) ->
- test(Config, fun test_inline/3, [ber]).
-test_inline(Config, Rule, Opts) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip, "Not runnable when cover compiled"};
- _ ->
- test_inline:compile(Config, Opts),
- test_inline:main(Config, Rule),
- test_inline:inline1(Config, Rule, Opts),
- test_inline:performance2()
- end.
+ test_undecoded_rest:test(undec_rest, Config).
testTcapsystem(Config) ->
test(Config, fun testTcapsystem/3, [ber]).
@@ -1025,17 +1030,12 @@ testNBAPsystem(Config, Rule, Opts) ->
testNBAPsystem:test(Rule, Config).
test_compile_options(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip, "Not runnable when cover compiled"};
- _ ->
- ok = test_compile_options:wrong_path(Config),
- ok = test_compile_options:path(Config),
- ok = test_compile_options:noobj(Config),
- ok = test_compile_options:record_name_prefix(Config),
- ok = test_compile_options:verbose(Config),
- ok = test_compile_options:warnings_as_errors(Config)
- end.
+ ok = test_compile_options:wrong_path(Config),
+ ok = test_compile_options:path(Config),
+ ok = test_compile_options:noobj(Config),
+ ok = test_compile_options:record_name_prefix(Config),
+ ok = test_compile_options:verbose(Config),
+ ok = test_compile_options:warnings_as_errors(Config).
testDoubleEllipses(Config) -> test(Config, fun testDoubleEllipses/3).
testDoubleEllipses(Config, Rule, Opts) ->
diff --git a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
index 1a905988f5..17a5d3490a 100644
--- a/lib/asn1/test/asn1_SUITE_data/Prim.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
@@ -29,4 +29,10 @@ BEGIN
Null ::= NULL
+ -- Test that REAL numbers can co-exist with other data types.
+ App-X-Real ::= REAL (WITH COMPONENTS {
+ mantissa (-16777215..16777215),
+ base (2),
+ exponent (-125..128) } )
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1 b/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
index 9b6b34a776..cfaf4cf034 100644
--- a/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
@@ -87,14 +87,17 @@ BS1024 ::= BIT STRING (SIZE (1024))
NsExpCon ::= [71] EXPLICIT NumericString
Ps ::= PrintableString
+ Ps11 ::= PrintableString (FROM ("0123456789*"))
Ts ::= TeletexString
Vxs ::= VideotexString
Vis ::= VisibleString
+ Vis8 ::= VisibleString (FROM ("01234567"))
IA5 ::= IA5String
+ IA5Visible ::= IA5String (FROM (" ".."~"))
Grs ::= GraphicString
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
index 8148381d92..1aec3e1fab 100644
--- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -140,7 +140,7 @@ run3() ->
Barring = #'AC-BarringConfig'{
'ac-BarringFactor' = p00,
'ac-BarringTime' = s4,
- 'ac-BarringForSpecialAC' = [0,0,0,0,0]},
+ 'ac-BarringForSpecialAC' = <<0:5>>},
roundtrip(SI),
roundtrip(SI#'SystemInformationBlockType2'{
'ssac-BarringForMMTEL-Voice-r9'=Barring}),
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl
index 9dbe1b50e0..1225e36778 100644
--- a/lib/asn1/test/asn1_app_test.erl
+++ b/lib/asn1/test/asn1_app_test.erl
@@ -139,7 +139,8 @@ check_asn1ct_modules(Extra) ->
asn1ct_gen_ber,asn1ct_constructed_ber_bin_v2,
asn1ct_gen_ber_bin_v2,asn1ct_value,
asn1ct_tok,asn1ct_parser2,asn1ct_table,
- asn1ct_imm],
+ asn1ct_imm,asn1ct_func,asn1ct_rtt,
+ asn1ct_eval_ext,asn1ct_eval_per,asn1ct_eval_uper],
case Extra -- ASN1CTMods of
[] ->
ok;
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
index fda635d0eb..1e40fd7b9e 100644
--- a/lib/asn1/test/asn1_test_lib.erl
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -61,15 +61,12 @@ compile_erlang(Mod, Config, Options) ->
[{i, CaseDir}, {outdir, CaseDir}|Options]).
should_load(File, Options) ->
- should_load(File, lists:member(abs, Options),
- proplists:lookup(inline, Options)).
-
-should_load(_File, true, _Inline) ->
- false;
-should_load(_File, _Abs, {inline, Module}) when Module /= true ->
- {module, Module};
-should_load(File, _Abs, _Inline) ->
- {module, list_to_atom(strip_extension(filename:basename(File)))}.
+ case lists:member(abs, Options) of
+ true ->
+ false;
+ false ->
+ {module,list_to_atom(strip_extension(filename:basename(File)))}
+ end.
strip_extension(File) ->
strip_extension(File, filename:extension(File)).
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
index ff6e386a88..af0105bf26 100644
--- a/lib/asn1/test/ber_decode_error.erl
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -21,31 +21,34 @@
-export([run/1]).
--include_lib("test_server/include/test_server.hrl").
-
run([]) ->
- ?line {ok,B} = asn1_wrapper:encode('Constructed','S3',{'S3',17}),
- ?line [T,L|V] = lists:flatten(B),
- ?line Bytes = [T,L+3|V] ++ [2,1,3],
- ?line case asn1_wrapper:decode('Constructed','S3',Bytes) of
- {error,{asn1,{unexpected,_}}} -> ok
- end,
- %% Unexpected bytes must be accepted if there is an extensionmark
- ?line {ok,{'S3ext',17}} = asn1_wrapper:decode('Constructed','S3ext',Bytes),
- ok;
-run([driver]) ->
- %% test of OTP-4797, bad indata to driver does not cause an EXIT
- ?line {error,_Reason} = asn1rt:decode('Constructed','S3',[3,5]),
- ok;
-run([nif]) ->
- %% test of OTP-4797, bad indata to driver does not cause an EXIT
- ?line {error,_Reason} = asn1rt:decode('Constructed','S3',[3,5]),
- ok.
-
+ {ok,B} = asn1_wrapper:encode('Constructed','S3',{'S3',17}),
+ [T,L|V] = lists:flatten(B),
+ Bytes = [T,L+3|V] ++ [2,1,3],
+ case asn1_wrapper:decode('Constructed','S3',Bytes) of
+ {error,{asn1,{unexpected,_}}} -> ok
+ end,
+ %% Unexpected bytes must be accepted if there is an extensionmark
+ {ok,{'S3ext',17}} = asn1_wrapper:decode('Constructed','S3ext',Bytes),
+ %% Truncated tag.
+ {error,{asn1,{invalid_tag,_}}} =
+ (catch 'Constructed':decode('I', <<31,255,255>>)),
+ %% Overlong tag.
+ {error,{asn1,{invalid_tag,_}}} =
+ (catch 'Constructed':decode('I', <<31,255,255,255,127>>)),
+ %% Invalid length.
+ {error,{asn1,{invalid_length,_}}} =
+ (catch 'Constructed':decode('I', <<8,255>>)),
+ %% Other errors.
+ {error,{asn1,{invalid_value,_}}} =
+ (catch 'Constructed':decode('I', <<>>)),
+ {error,{asn1,{invalid_value,_}}} =
+ (catch 'Constructed':decode('I', <<8,7>>)),
+ ok.
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
index 4f67942922..f06cc7c117 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -52,22 +52,36 @@ test(Config) ->
check_EXTERNAL({'EXTERNAL',Identif,DVD,DV})->
- ?line ok=check_EXTERNAL_Idef(Identif),
- ?line ok = check_EXTERNAL_DVD(DVD),
- ?line ok = check_EXTERNAL_DV(DV).
-check_EXTERNAL_Idef({Alt,_}) when Alt=='context-negotiation';
- Alt=='presentation-context-id';
- Alt==syntax ->
- ok;
-check_EXTERNAL_Idef(I) ->
- {error,"failed on identification alternative",I}.
-check_EXTERNAL_DVD(DVD) when is_list(DVD) ->
- ok;
-check_EXTERNAL_DVD(asn1_NOVALUE) ->
- ok;
-check_EXTERNAL_DVD(DVD) ->
- {error,"failed on data-value-descriptor alternative",DVD}.
-check_EXTERNAL_DV(DV) when is_list(DV);is_binary(DV) ->
- ok;
-check_EXTERNAL_DV(DV) ->
- {error,"failed on data-value alternative",DV}.
+ %% EXTERNAL in the 1994 format.
+ case Identif of
+ {'context-negotiation',_} ->
+ ok;
+ {'presentation-context-id',Id} ->
+ true = is_integer(Id);
+ {syntax,ObjId} ->
+ check_object_identifier(ObjId)
+ end,
+ check_EXTERNAL_DVD(DVD),
+ check_EXTERNAL_DV(DV);
+check_EXTERNAL({'EXTERNAL',ObjId,IndirectRef,Descriptor,Enc})->
+ %% EXTERNAL in the 1990 format.
+ check_object_identifier(ObjId),
+ true = is_integer(IndirectRef),
+ true = is_binary(Descriptor) orelse is_list(Descriptor),
+ case Enc of
+ {arbitrary,_} -> ok;
+ {'single-ASN1-type',_} -> ok;
+ {'octet-aligned',_} -> ok
+ end.
+
+check_EXTERNAL_DVD(DVD) when is_list(DVD) -> ok;
+check_EXTERNAL_DVD(asn1_NOVALUE) -> ok.
+
+check_EXTERNAL_DV(DV) when is_list(DV); is_binary(DV) -> ok.
+
+check_object_identifier(Tuple) when is_tuple(Tuple) ->
+ %% An OBJECT IDENTIFIER is a tuple with integer elements.
+ case [E || E <- tuple_to_list(Tuple),
+ not is_integer(E)] of
+ [] -> ok
+ end.
diff --git a/lib/asn1/test/testDoubleEllipses.erl b/lib/asn1/test/testDoubleEllipses.erl
index 9030a99ce2..72ff693667 100644
--- a/lib/asn1/test/testDoubleEllipses.erl
+++ b/lib/asn1/test/testDoubleEllipses.erl
@@ -51,7 +51,7 @@ main(_Rules) ->
b = [1,0,1,0], e = true,
c = false, f = 14, g = 16}),
?line {ok,#'SeqAltV2'{a = 10, d = 12,
- b = [1,0,1,0], e = true,
+ b = <<2#1010:4>>, e = true,
h = asn1_NOVALUE, i = asn1_NOVALUE,
c = false, f = 14, g = 16}} =
asn1_wrapper:decode('DoubleEllipses','SeqAltV2',Bytes3),
@@ -62,7 +62,7 @@ main(_Rules) ->
h = "PS", i = 13,
c = false, f = 14, g = 16}),
?line {ok,#'SeqAlt'{a = 10, d = 12,
- b = [1,0,1,0], e = true,
+ b = <<2#1010:4>>, e = true,
c = false, f = 14, g = 16}} =
asn1_wrapper:decode('DoubleEllipses','SeqAlt',Bytes4),
@@ -83,7 +83,7 @@ main(_Rules) ->
b = [1,0,1,0], e = true,
c = false, f = 14, g = 16}),
?line {ok,#'SetAltV2'{a = 10, d = 12,
- b = [1,0,1,0], e = true,
+ b = <<2#1010:4>>, e = true,
h = asn1_NOVALUE, i = asn1_NOVALUE,
c = false, f = 14, g = 16}} =
asn1_wrapper:decode('DoubleEllipses','SetAltV2',Bytes7),
@@ -94,7 +94,7 @@ main(_Rules) ->
h = "PS", i = 13,
c = false, f = 14, g = 16}),
?line {ok,#'SetAlt'{a = 10, d = 12,
- b = [1,0,1,0], e = true,
+ b = <<2#1010:4>>, e = true,
c = false, f = 14, g = 16}} =
asn1_wrapper:decode('DoubleEllipses','SetAlt',Bytes8),
ok.
diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl
index 4e8381e51e..3e7dfb0522 100644
--- a/lib/asn1/test/testNBAPsystem.erl
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -142,8 +142,7 @@ audit_req() ->
protocolIEs =
[#'ProtocolIE-Field'{id=114,
criticality=ignore,
- value={'Start-Of-Audit-Sequence-Indicator',
- 'start-of-audit-sequence' }
+ value='start-of-audit-sequence'
}
]
}.
diff --git a/lib/asn1/test/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl
index b5780195b8..e5e2de804c 100644
--- a/lib/asn1/test/testParamBasic.erl
+++ b/lib/asn1/test/testParamBasic.erl
@@ -40,8 +40,8 @@ main(Rules) ->
?line {ok,Bytes12} =
asn1_wrapper:encode('ParamBasic','T12',
#'T12'{number = 11,
- string = [1,0,1,0,1]}),
- ?line {ok,{'T12',11,[1,0,1,0,1]}} =
+ string = <<2#10101:5>>}),
+ {ok,{'T12',11,<<2#10101:5>>}} =
asn1_wrapper:decode('ParamBasic','T12',Bytes12),
?line {ok,Bytes13} =
@@ -54,8 +54,8 @@ main(Rules) ->
?line {ok,Bytes14} =
asn1_wrapper:encode('ParamBasic','T22',
#'T22'{number = 11,
- string = [1,0,1,0,1]}),
- ?line {ok,{'T22',11,[1,0,1,0,1]}} =
+ string = <<2#10101:5>>}),
+ {ok,{'T22',11,<<2#10101:5>>}} =
asn1_wrapper:decode('ParamBasic','T22',Bytes14),
case Rules of
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
index 263d9e5ed2..935e730ca1 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -20,7 +20,6 @@
-module(testPrimStrings).
-export([bit_string/1]).
--export([bit_string_unnamed/1]).
-export([octet_string/1]).
-export([numeric_string/1]).
-export([other_strings/1]).
@@ -37,93 +36,35 @@ bit_string(Rules) ->
%%==========================================================
%% Bs1 ::= BIT STRING
%%==========================================================
+
+ bs_roundtrip('Bs1', 0, <<>>),
+ bs_roundtrip('Bs1', 4, <<1:3>>),
+ bs_roundtrip('Bs1', 15, <<15:4>>),
+ bs_roundtrip('Bs1', 255, <<255:8>>),
+
+ bs_roundtrip('Bs1', 256, [0,0,0,0,0,0,0,0,1]),
+ bs_roundtrip('Bs1', 257, [1,0,0,0,0,0,0,0,1]),
+ bs_roundtrip('Bs1', 444, [0,0,1,1,1,1,0,1,1]),
- ?line {ok,Bytes1} = asn1_wrapper:encode('PrimStrings','Bs1',0),
- ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes1)),
-
- ?line {ok,Bytes2} = asn1_wrapper:encode('PrimStrings','Bs1',4),
- ?line {ok,[0,0,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes2)),
-
- ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','Bs1',15),
- ?line {ok,[1,1,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes3)),
-
- ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','Bs1',255),
- ?line {ok,[1,1,1,1,1,1,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes4)),
-
- ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','Bs1',256),
- ?line {ok,[0,0,0,0,0,0,0,0,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes5)),
-
- ?line {ok,Bytes6} = asn1_wrapper:encode('PrimStrings','Bs1',257),
- ?line {ok,[1,0,0,0,0,0,0,0,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes6)),
-
- ?line {ok,Bytes7} = asn1_wrapper:encode('PrimStrings','Bs1',444),
- ?line {ok,[0,0,1,1,1,1,0,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes7)),
-
- ?line {ok,Bytes8} = asn1_wrapper:encode('PrimStrings','Bs1',12345678901234567890),
- ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes8)),
-
-%% Removed due to beam cannot handle this big integers
-%% Bs1_1 = 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
-%% ?line {ok,Bytes9} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_1),
-%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes9)),
-
-%% Bs1_2 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
-%% ?line {ok,Bytes10} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_2),
-%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes10)),
-
- ?line {ok,Bytes11} = asn1_wrapper:encode('PrimStrings','Bs1',[1,1,1,1,1,1,1,1]),
- ?line {ok,[1,1,1,1,1,1,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes11)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings','Bs1',[0,1,0,0,1,0]),
- ?line {ok,[0,1,0,0,1,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes12)),
-
- ?line {ok,Bytes13} = asn1_wrapper:encode('PrimStrings','Bs1',[1,0,0,0,0,0,0,0,0]),
- ?line {ok,[1,0,0,0,0,0,0,0,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes13)),
- ok;
- per ->
- ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings','Bs1',[0,1,0,0,1,0]),
- ?line {ok,[0,1,0,0,1,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes12)),
-
- ?line {ok,Bytes13} = asn1_wrapper:encode('PrimStrings','Bs1',[1,0,0,0,0,0,0,0,0]),
- ?line {ok,[1,0,0,0,0,0,0,0,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes13)),
- ok
- end,
-
- ?line {ok,Bytes14} =
- asn1_wrapper:encode('PrimStrings','Bs1',[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
- ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes14)),
-
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line Bytes15 = [35,8,3,2,0,73,3,2,4,32],
- ?line {ok,[0,1,0,0,1,0,0,1,0,0,1,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes15)),
-
- ?line Bytes16 = [35,9,3,2,0,234,3,3,7,156,0],
- ?line {ok,[1,1,1,0,1,0,1,0,1,0,0,1,1,1,0,0,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes16)),
-
- ?line Bytes17 = [35,128,3,2,0,73,3,2,4,32,0,0],
- ?line {ok,[0,1,0,0,1,0,0,1,0,0,1,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes17)),
-
- ?line Bytes18 = [35,128,3,2,0,234,3,3,7,156,0,0,0],
- ?line {ok,[1,1,1,0,1,0,1,0,1,0,0,1,1,1,0,0,0]} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes18)),
- ok;
-
- per ->
- ok
- end,
+ {ok,Enc1} = 'PrimStrings':encode('Bs1', 12345678901234567890),
+ {ok,_} = 'PrimStrings':decode('Bs1', Enc1),
+
+ bs_roundtrip('Bs1', [1,1,1,1,1,1,1,1]),
+ bs_roundtrip('Bs1', [0,1,0,0,1,0]),
+ bs_roundtrip('Bs1', [1,0,0,0,0,0,0,0,0]),
+ bs_roundtrip('Bs1', [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ bs_decode('Bs1', <<35,8,3,2,0,73,3,2,4,32>>,
+ [0,1,0,0,1,0,0,1,0,0,1,0]),
+ bs_decode('Bs1', <<35,9,3,2,0,234,3,3,7,156,0>>,
+ [1,1,1,0,1,0,1,0,1,0,0,1,1,1,0,0,0]),
+ bs_decode('Bs1', <<35,128,3,2,0,234,3,3,7,156,0,0,0>>,
+ [1,1,1,0,1,0,1,0,1,0,0,1,1,1,0,0,0]);
+ per ->
+ ok
+ end,
%%==========================================================
@@ -156,77 +97,55 @@ bit_string(Rules) ->
%% Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
%%==========================================================
- ?line {ok,Bytes31} = asn1_wrapper:encode('PrimStrings','Bs3',[mo,tu,fr]),
- ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes31)),
-
- ?line {ok,Bytes32} = asn1_wrapper:encode('PrimStrings','Bs3',[0,1,1,0,0,1,0]),
- ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes32)),
-
+ roundtrip('Bs3', [mo,tu,fr]),
+ bs_roundtrip('Bs3', [0,1,1,0,0,1,0], [mo,tu,fr]),
%%==========================================================
%% Bs7 ::= BIT STRING (SIZE (24))
%%==========================================================
- ?line {ok,Bytes33} = asn1_wrapper:encode('PrimStrings','Bs7',53245),
- ?line {ok,[1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0]} =
- asn1_wrapper:decode('PrimStrings','Bs7',Bytes33),
-
- ?line {ok,Bytes34} = asn1_wrapper:encode('PrimStrings','Bs7',[1,0,1,0]),
- ?line {ok,[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]} =
- asn1_wrapper:decode('PrimStrings','Bs7',Bytes34),
+ bs_roundtrip('Bs7', 53245,
+ [1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0]),
+ bs_roundtrip('Bs7', [1,0,1,0],
+ [1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),
%%==========================================================
%% BsPri ::= [PRIVATE 61] BIT STRING
%%==========================================================
- ?line {ok,Bytes41} = asn1_wrapper:encode('PrimStrings','BsPri',45),
- ?line {ok,[1,0,1,1,0,1]} = asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes41)),
+ bs_roundtrip('BsPri', 45, [1,0,1,1,0,1]),
- ?line {ok,Bytes42} = asn1_wrapper:encode('PrimStrings','BsPri',211),
- ?line {ok,[1,1,0,0,1,0,1,1]} = asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes42)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','BsPri',[223,61,4,5,75,226,96]),
-
- ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','BsPri',[255,61,128,3,4,5,75,226,96,0,0]),
-
- ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','BsPri',[255,61,9,3,2,0,75,3,3,5,226,96]),
-
- ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','BsPri',[255,61,128,3,2,0,75,3,3,5,226,96,0,0]),
- ok;
-
- per ->
- ok
- end,
+ bs_roundtrip('BsPri', 211, [1,1,0,0,1,0,1,1]),
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ bs_decode('BsPri', <<223,61,4,5,75,226,96>>,
+ [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
+ bs_decode('BsPri', <<255,61,128,3,4,5,75,226,96,0,0>>,
+ [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
+ bs_decode('BsPri', <<255,61,9,3,2,0,75,3,3,5,226,96>>,
+ [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
+ bs_decode('BsPri', <<255,61,128,3,2,0,75,3,3,5,226,96,0,0>>,
+ [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]);
+ per ->
+ ok
+ end,
%%==========================================================
%% BsExpPri ::= [PRIVATE 61] EXPLICIT BIT STRING
%%==========================================================
- ?line {ok,Bytes51} = asn1_wrapper:encode('PrimStrings','BsExpPri',45),
- ?line {ok,[1,0,1,1,0,1]} =
- asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes51)),
-
- ?line {ok,Bytes52} = asn1_wrapper:encode('PrimStrings','BsExpPri',211),
- ?line {ok,[1,1,0,0,1,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes52)),
+ bs_roundtrip('BsExpPri', 45, [1,0,1,1,0,1]),
+ bs_roundtrip('BsExpPri', 211, [1,1,0,0,1,0,1,1]),
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
- asn1_wrapper:decode('PrimStrings','BsExpPri',[255,61,6,3,4,5,75,226,96]),
- ok;
-
- per ->
- ok
- end,
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ bs_decode('BsExpPri', <<255,61,6,3,4,5,75,226,96>>,
+ [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]);
+ per ->
+ ok
+ end,
%%==========================================================
%% TestS ::= BIT STRING {a(0),b(1)} (SIZE (3..8)), test case for OTP-4353
@@ -248,14 +167,10 @@ bit_string(Rules) ->
%% BS5932 ::= BIT STRING (SIZE (5..MAX))
%% test case for OTP-5932
%%==========================================================
+ bs_roundtrip('BSMAX', [1,0,1,0,1]),
case asn1_wrapper:erule(Rules) of
ber ->
- ?line {error,_} = asn1_wrapper:encode('PrimStrings','BSMAX',
- [1,0,1]),
- ?line {ok,Bytes55} =
- asn1_wrapper:encode('PrimStrings','BSMAX',[1,0,1,0,1]),
- ?line {ok,[1,0,1,0,1]} =
- asn1_wrapper:decode('PrimStrings','BSMAX',Bytes55);
+ {error,_} = 'PrimStrings':encode('BSMAX', [1,0,1]);
_ ->
ok
end,
@@ -274,47 +189,13 @@ bit_string(Rules) ->
end,
BSList255 = BSmaker(BSmaker,0,255,{1,0},[]),
+ bs_roundtrip('BS255', BSList255),
BSList256 = BSmaker(BSmaker,0,256,{1,0},[]),
+ bs_roundtrip('BS256', BSList256),
BSList1024 = BSmaker(BSmaker,0,1024,{1,0},[]),
- ?line {ok,Bytes56} =
- asn1_wrapper:encode('PrimStrings','BS255',BSList255),
- ?line {ok,BSList255} =
- asn1_wrapper:decode('PrimStrings','BS255',Bytes56),
- ?line {ok,Bytes57} =
- asn1_wrapper:encode('PrimStrings','BS256',BSList256),
- ?line {ok,BSList256} =
- asn1_wrapper:decode('PrimStrings','BS256',Bytes57),
- ?line {ok,Bytes58} =
- asn1_wrapper:encode('PrimStrings','BS1024',BSList1024),
- ?line {ok,BSList1024} =
- asn1_wrapper:decode('PrimStrings','BS1024',Bytes58).
-
-
-
-bit_string_unnamed(Rules) ->
- case asn1_wrapper:erule(Rules) of
- ber ->
- ok;
- per ->
- ?line {ok,Bytes1} =
- case catch asn1_wrapper:encode('PrimStrings','TransportLayerAddress',[0,1,1,0]) of
- Ret = {ok,_} -> Ret;
- Err ->
- Config = file:consult(test_config),
- ?line OutDir = ?config(priv_dir,Config),
- MyOut = "/home/bertil/daily_build",
- file:copy(filename:join([OutDir,"PrimStrings.erl"]),
- filename:join([MyOut,"PrimStrings.erl"])),
- file:copy(filename:join([OutDir,"PrimStrings.beam"]),
- filename:join([MyOut,"PrimStrings.beam"])),
- file:copy(code:which(asn1rt_per_v1),
- filename:join([MyOut,"asn1rt_per_v1.beam"])),
- file:copy(filename:join([code:lib_dir(asn1),src,"asn1rt_per_v1.erl"]),filename:join([MyOut,"asn1rt_per_v1.erl"])),
- io:format("Err: ~p~n",[Err]),
- Err
- end,
- ?line {ok,[0,1,1,0]} = asn1_wrapper:decode('PrimStrings','TransportLayerAddress',lists:flatten(Bytes1))
- end.
+ bs_roundtrip('BS1024', BSList1024),
+
+ bs_roundtrip('TransportLayerAddress', [0,1,1,0]).
octet_string(Rules) ->
@@ -534,7 +415,7 @@ other_strings(_Rules) ->
roundtrip('Ps', [47,23,99,75,47]),
roundtrip('Ps', []),
-
+ roundtrip('Ps11', "*0123456789*"),
%%==========================================================
%% Vis ::= VisibleString
@@ -542,7 +423,8 @@ other_strings(_Rules) ->
roundtrip('Vis', [47,23,99,75,47]),
roundtrip('Vis', []),
-
+ roundtrip('Vis8', "7654321001234567"),
+ roundtrip('Vis8', []),
%%==========================================================
%% IA5 ::= IA5String
@@ -553,6 +435,9 @@ other_strings(_Rules) ->
IA5_1 = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
roundtrip('IA5', IA5_1),
+
+ roundtrip('IA5Visible', lists:seq($\s, $~)),
+
ok.
@@ -828,3 +713,39 @@ roundtrip(Type, Value) ->
{ok,Encoded} = 'PrimStrings':encode(Type, Value),
{ok,Value} = 'PrimStrings':decode(Type, Encoded),
ok.
+
+bs_roundtrip(Type, Value) ->
+ bs_roundtrip(Type, Value, Value).
+
+bs_roundtrip(Type, Value, Expected) ->
+ M = 'PrimStrings',
+ {ok,Encoded} = M:encode(Type, Value),
+ case M:decode(Type, Encoded) of
+ {ok,Expected} ->
+ ok;
+ {ok,Other} ->
+ Expected = convert(Other, Expected)
+ end.
+
+bs_decode(Type, Encoded, Expected) ->
+ M = 'PrimStrings',
+ case M:decode(Type, Encoded) of
+ {ok,Expected} ->
+ ok;
+ {ok,Other} ->
+ Expected = convert(Other, Expected)
+ end.
+
+convert(Val, E) when is_bitstring(Val) ->
+ convert_1(Val, E);
+convert({Unused,Bin}, E) ->
+ Sz = bit_size(Bin) - Unused,
+ <<Val:Sz/bitstring,_:Unused>> = Bin,
+ convert_1(Val, E);
+convert(List, E) when is_list(List) ->
+ Val = << <<B:1>> || B <- List >>,
+ convert_1(Val, E).
+
+convert_1(Val, E) when is_list(E) ->
+ [B || <<B:1>> <= Val];
+convert_1(Val, E) when is_bitstring(E) -> Val.
diff --git a/lib/asn1/test/testSSLspecs.erl b/lib/asn1/test/testSSLspecs.erl
index 45c5da50f0..08da92243e 100644
--- a/lib/asn1/test/testSSLspecs.erl
+++ b/lib/asn1/test/testSSLspecs.erl
@@ -20,7 +20,7 @@
-module(testSSLspecs).
--export([compile/2,run/1,compile_inline/2,run_inline/1]).
+-export([compile/2,run/1,compile_combined/2,run_combined/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -42,15 +42,13 @@ compile(Config, Options) ->
asn1_test_lib:compile_all(["PKIX1Explicit93", "PKIX1Implicit93"],
Config, NewOptions).
-compile_inline(Config, ber=Rule) ->
+compile_combined(Config, ber=Rule) ->
DataDir = ?config(data_dir, Config),
CaseDir = ?config(case_dir, Config),
Options = [{i, CaseDir}, {i, DataDir}, Rule,
- der, compact_bit_string, asn1config, inline],
- ok = remove_db_file_inline(CaseDir),
- asn1_test_lib:compile("OTP-PKIX.set.asn", Config, Options);
-compile_inline(_Config, _Rule) ->
- ok.
+ der, compact_bit_string, asn1config],
+ ok = remove_db_files_combined(CaseDir),
+ asn1_test_lib:compile("OTP-PKIX.set.asn", Config, Options).
remove_db_files(Dir) ->
?line ok = remove_db_file(Dir ++ "PKIX1Explicit93.asn1db"),
@@ -65,7 +63,7 @@ remove_db_file(File) ->
Err
end.
-remove_db_file_inline(Dir) ->
+remove_db_files_combined(Dir) ->
?line ok = remove_db_file(Dir ++ "OTP-PKIX.asn1db"),
?line ok = remove_db_file(Dir ++ "SSL-PKIX.asn1db"),
?line ok = remove_db_file(Dir ++ "PKIXAttributeCertificate.asn1db"),
@@ -74,14 +72,11 @@ remove_db_file_inline(Dir) ->
?line ok = remove_db_file(Dir ++ "PKIX1Implicit88.asn1db").
run(ber) ->
- run1(1);
-run(_) ->
- ok.
+ run1(1).
run1(6) ->
?line f1(6),
?line f2(6),
-%% ?line transform3(ex(7)),
?line transform4(ex(7));
run1(N) ->
?line f1(N),
@@ -146,12 +141,10 @@ ex(7) ->
{1,2,840,113549,1,9,1},
[[19,5,111,116,112,67,65]]}.
-run_inline(ber) ->
+run_combined(ber) ->
Cert = cert(),
?line {ok,{'CertificatePKIX1Explicit88',{Type,UnDec},_,_}} = 'OTP-PKIX':decode_TBSCert_exclusive(Cert),
?line {ok,_} = 'OTP-PKIX':decode_part(Type,UnDec),
- ok;
-run_inline(_) ->
ok.
cert() ->
diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl
index ab484db5f2..6e680feafa 100644
--- a/lib/asn1/test/testSeqSetDefaultVal.erl
+++ b/lib/asn1/test/testSeqSetDefaultVal.erl
@@ -134,7 +134,7 @@ main(_Rules) ->
c={5,<<64>>},
d=0}),
- ?line {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],[]}} =
+ {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],<<>>}} =
asn1_wrapper:decode('Default','SeqBS',[48,3,131,1,0]),
?line {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],[1,0,0,1]}} =
@@ -161,7 +161,7 @@ main(_Rules) ->
c={5,<<64>>},
d=0}),
- ?line {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],[]}} =
+ {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],<<>>}} =
asn1_wrapper:decode('Default','SetBS',[49,3,131,1,0]),
?line {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],[1,0,0,1]}} =
diff --git a/lib/asn1/test/testTypeValueNotation.erl b/lib/asn1/test/testTypeValueNotation.erl
index 59f7385f08..d21b054e8d 100644
--- a/lib/asn1/test/testTypeValueNotation.erl
+++ b/lib/asn1/test/testTypeValueNotation.erl
@@ -28,7 +28,7 @@ main(_Rule, _Option) ->
int = 12,
bool = true,
enum = a,
- bitstr = [1, 0, 1, 0],
+ bitstr = <<2#1010:4>>,
null = 'NULL',
oid = {1, 2, 55},
vstr = "Hello World"},
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
index b973c5fbcc..179299c78d 100644
--- a/lib/asn1/test/test_compile_options.erl
+++ b/lib/asn1/test/test_compile_options.erl
@@ -51,14 +51,13 @@ path(Config) ->
{ok,CWD} = file:get_cwd(),
?line file:set_cwd(filename:join([DataDir,subdir])),
- %%?line ok=asn1ct:compile(filename:join([DataDir,"../MyMerge.set.asn"]),[{inline,mymerge},{outdir,OutDir}]),
- ?line ok=asn1ct:compile("../MyMerge.set.asn",[{inline,mymerge},{outdir,OutDir}]),
+ ok = asn1ct:compile("../MyMerge.set.asn",[{outdir,OutDir}]),
?line ok=outfiles_check(OutDir),
?line outfiles_remove(OutDir),
file:set_cwd(filename:join([DataDir,subdir,subsubdir])),
- ?line ok = asn1ct:compile('../../MyMerge.set.asn',[{inline,mymerge},{i,'..'},{outdir,OutDir}]),
+ ok = asn1ct:compile('../../MyMerge.set.asn',[{i,'..'},{outdir,OutDir}]),
?line ok=outfiles_check(OutDir,outfiles2()),
file:set_cwd(CWD),
@@ -182,11 +181,10 @@ outfiles_check(OutDir,[H|T]) ->
outfiles_check(OutDir,T).
outfiles1() ->
- ["mymerge.erl","mymerge.beam","MyMerge.asn1db","MyMerge.beam",
+ ["MyMerge.asn1db","MyMerge.beam",
"MyMerge.erl","MyMerge.hrl"].
outfiles2() ->
- ["MyMerge.beam","mymerge.erl","MyMerge.asn1db","MyMerge.erl",
- "mymerge.beam"].
+ ["MyMerge.beam","MyMerge.asn1db","MyMerge.erl"].
outfiles_remove(OutDir) ->
lists:foreach(fun(F)-> file:delete(filename:join([OutDir,F])) end,
diff --git a/lib/asn1/test/test_inline.erl b/lib/asn1/test/test_inline.erl
deleted file mode 100644
index e03ad739f9..0000000000
--- a/lib/asn1/test/test_inline.erl
+++ /dev/null
@@ -1,270 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-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(test_inline).
-
--export([compile/2,main/2,inline1/3,performance/1,performance2/0]).
--export([mvrasn_inlined_encdec/2,mvrasn_encdec/2,
- mi_encdec/2,m_encdec/2]).
-
--include_lib("test_server/include/test_server.hrl").
--define(times, 5000).
--define(times2, 50000).
-
-compile(Config, Options) ->
- CaseDir = ?config(case_dir, Config),
- asn1_test_lib:compile("Mvrasn.set.asn", Config, [{inline, mvrasn_inlined}|Options]),
- asn1_test_lib:compile("Mod.set.asn", Config, [{inline, m}|Options]),
- ok = remove_inlined_files(CaseDir, [filename:join([CaseDir, X])||X<-["m.erl", "m.beam"]]),
- asn1_test_lib:compile("Mod.set.asn", Config, [inline|Options]),
- ok = remove_inlined_files(CaseDir, []).
-
-inline1(Config, Rule, Opt) ->
- CaseDir = ?config(case_dir, Config),
-
- asn1_test_lib:compile("P-Record", Config, [{inline, 'inlined_P_Record'}|Opt]),
- test_inline1(),
-
- ok=remove_inlined_files2(CaseDir, ber),
-
- case Rule of
- ber ->
- asn1_test_lib:compile("P-Record", Config,
- [ber, inline, asn1config|Opt]),
- test_inline2(Rule, 'P-Record'),
- remove_inlined_files3(CaseDir, Rule),
- asn1_test_lib:compile("p_record.set.asn", Config,
- [ber, inline, asn1config|Opt]),
- test_inline2(Rule, 'p_record'),
- remove_inlined_files4(CaseDir, Rule);
- _ ->
- ok
- end.
-
-main(Config, _Erule) ->
- Val = val(Config),
- ?line {ok,Bytes}=asn1_wrapper:encode(mvrasn_inlined,'InsertSubscriberDataArg',Val),
- ?line {ok,_Val2}=asn1_wrapper:decode(mvrasn_inlined,'InsertSubscriberDataArg',Bytes).
-
-test_inline1() ->
- PRecMsg = {'PersonnelRecord',{'Name',"Sven","S","Svensson"},
- "manager",123,"20000202",{'Name',"Inga","K","Svensson"},
- asn1_DEFAULT},
- ?line {ok,Bytes}=asn1_wrapper:encode('inlined_P_Record','PersonnelRecord',
- PRecMsg),
- ?line {ok,_}=asn1_wrapper:decode('inlined_P_Record',
- 'PersonnelRecord',Bytes).
-
-test_inline2(ber,Mod) ->
- PRecMsg = {'PersonnelRecord',{'Name',"Sven","S","Svensson"},
- "manager",123,"20000202",{'Name',"Inga","K","Svensson"},
- asn1_DEFAULT},
- ?line {ok,Bytes} = Mod:encode('PersonnelRecord',PRecMsg),
- {ok,_} = Mod:sel_dec(Bytes);
-test_inline2(_,_) ->
- ok.
-
-val(Config) ->
- {ok,Val} = asn1ct:value('Mvrasn','InsertSubscriberDataArg',
- [{i, ?config(case_dir, Config)}]),
- Val.
-
-performance(Config) ->
- Val = val(Config),
- %% warm up
- timer:tc(?MODULE,mvrasn_inlined_encdec,[2,Val]),
- %% performance test
- ?line {Time1,ok}=timer:tc(?MODULE,mvrasn_inlined_encdec,[?times,Val]),
- %% warm up
- timer:tc(?MODULE,mvrasn_encdec,[2,Val]),
- %% performance test
- ?line {Time2,ok}=timer:tc(?MODULE,mvrasn_encdec,[?times,Val]),
-
- ?line Comment = "inlined_code: "++
- integer_to_list(round(Time1/?times))++
- " micro,<br>original_code: "++
- integer_to_list(round(Time2/?times))++
-% " micro,~ninlined_code[inline]: "++
-% integer_to_list(round(Time3/?times))++
- " micro",
- {comment,Comment}.
-
-
-mvrasn_inlined_encdec(0,_) ->
- ok;
-mvrasn_inlined_encdec(N,V) ->
- ?line {ok,B}=mvrasn_inlined:encode('InsertSubscriberDataArg',V),
- ?line {ok,_R}=mvrasn_inlined:decode('InsertSubscriberDataArg',B),
- mvrasn_inlined_encdec(N-1,V).
-
-mvrasn_encdec(0,_) ->
- ok;
-mvrasn_encdec(N,V) ->
- ?line {ok,B}='Mvrasn-11-6':encode('InsertSubscriberDataArg',V),
- ?line {ok,_R}='Mvrasn-11-6':decode('InsertSubscriberDataArg',B),
- mvrasn_encdec(N-1,V).
-
-%% mvrasn_inlined_i_encdec(0,_) ->
-%% ok;
-%% mvrasn_inlined_i_encdec(N,V) ->
-%% {ok,B}=mvrasn_inlined_i:encode('InsertSubscriberDataArg',V),
-%% {ok,_R}=mvrasn_inlined_i:decode('InsertSubscriberDataArg',B),
-%% mvrasn_inlined_i_encdec(N-1,V).
-
-performance2() ->
- Val = mval(),
- %% warm up
- timer:tc(?MODULE,mi_encdec,[?times,Val]),
- %% performance test
- {Time1,_R1}=timer:tc(?MODULE,mi_encdec,[?times2,Val]),
- %% warm up
- timer:tc(?MODULE,m_encdec,[?times,Val]),
- %% performance test
- {Time2,_R2}=timer:tc(?MODULE,m_encdec,[?times2,Val]),
- ?line Comment = "inlined_code: "++
- integer_to_list(round(Time1/?times2))++
- " micro,<br>original_code: "++
- integer_to_list(round(Time2/?times2))++
- " micro<br>"++
- "The inlined code was "++
- integer_to_list(round(((Time2-Time1)/Time2)*100))++
- " % faster than the original code.",
- {comment,Comment}.
-
-mi_encdec(0,_) ->
- ok;
-mi_encdec(N,Val) ->
- {ok,B}=m:encode('L',Val),
- {ok,_R}=m:decode('L',B),
-% io:format("a"),
- mi_encdec(N-1,Val).
-
-m_encdec(0,_) ->
- ok;
-m_encdec(N,Val) ->
- {ok,B}='Mod':encode('L',Val),
- {ok,_R}='Mod':decode('L',B),
- m_encdec(N-1,Val).
-
-
--record('L', {country, region, name}).
--record('OtherName', {locationName, thingName}).
--record('FamilyName', {prefix, secondname}).
--record('Lang', {l}).
--record('Inhabitant', {name, country}).
--record('Country', {name, language}).
--record('PersonName', {name1, name2}).
--record('LocName', {region, name}).
--record('Reg', {name, inhabitants}).
-
-
-mval() ->
- 'L'().
-'L'() ->
- #'L'{
- country='Co'(),
- region='Reg'(),
- name='Name'(othername)}.
-'Co'() ->
- 'Country'().
-'Country'()->
- #'Country'{name='Name'(othername),
- language='Lang'()}.
-'Lang'()->
- #'Lang'{l="englsh"}.
-'Reg'() ->
- #'Reg'{
- name='Name'(othername),
- inhabitants='Inhabitants'()}.
-'Inhabitants'()->
- lists:duplicate(5,'Inhabitant'()).
-'Inhabitant'()->
- #'Inhabitant'{name='Name'(person),
- country='Country'()}.
-'Name'(person) ->
- {person,'PersonName'()};
-'Name'(othername) ->
- {othername,'OtherName'()}.
-'PersonName'()->
- #'PersonName'{name1='FirstName'(firstname),
- name2='FamilyName'()}.
-'OtherName'()->
- #'OtherName'{locationName='LocName'(),
- thingName='ThingName'()}.
-'FirstName'(firstname)->
- {firstname,"Henry"};
-'FirstName'(nickname) ->
- {nickname,"nick"}.
-'FamilyName'() ->
- #'FamilyName'{prefix=none,
- secondname="Lloyd"}.
-'ThingName'()->
- "Enkoping".
-'LocName'()->
- #'LocName'{
- region=svealand,
- name="Enkoping"}.
-
-remove_inlined_files(Dir,Files) ->
- ModList=[filename:join([Dir,X])||X<-["Mod"]],
- FileList=Files++ mods2files(ModList,".asn1db")++
- mods2files(ModList,".beam")++
- mods2files(ModList,".erl")++mods2files(ModList,".hrl"),
- lists:foreach(fun(X) ->
- io:format("X: ~p~n",[X]),
- ?line ok=file:delete(X)
- end,FileList),
- ok.
-mods2files(ModList,Extension) ->
- [X++Extension||X<-ModList].
-
-
-remove_inlined_files2(Dir,Rule) ->
- ?line ok=remove_inlined_files3(Dir,Rule),
- TargetErl=filename:join([Dir,"inlined_P_Record.erl"]),
- TargetBeam=filename:join([Dir,"inlined_P_Record.beam"]),
- lists:foreach(fun(X) ->
- ?line ok=file:delete(X)
- end,[TargetErl,TargetBeam]),
- ok.
-remove_inlined_files3(Dir,ber) ->
- Erl=filename:join([Dir,"P-Record.erl"]),
- Beam=filename:join([Dir,"P-Record.beam"]),
- Asn1DB=filename:join([Dir,"P-Record.asn1db"]),
- Hrl=filename:join([Dir,"P-Record.hrl"]),
- lists:foreach(fun(X) ->
- ?line ok=file:delete(X)
- end,[Erl,Beam,Asn1DB,Hrl]),
- ok;
-remove_inlined_files3(_,_) ->
- ok.
-
-remove_inlined_files4(Dir,ber) ->
- Erl=filename:join([Dir,"p_record.erl"]),
- Beam=filename:join([Dir,"p_record.beam"]),
- Asn1DB=filename:join([Dir,"p_record.asn1db"]),
- Hrl=filename:join([Dir,"p_record.hrl"]),
- ErlBak=filename:join([Dir,"p_record.erl.bak"]),
- file:delete(ErlBak),
- lists:foreach(fun(X) ->
- ?line ok=file:delete(X)
- end,[Erl,Beam,Asn1DB,Hrl]),
- ok;
-remove_inlined_files4(_,_) ->
- ok.
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 8c3b13951d..0345fab8e8 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -32,6 +32,122 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Severe errors detected by <c>test_server</c> (e.g. if log
+ files directories cannot be created) will now be reported
+ to <c>common_test</c> and noted in the <c>common_test</c>
+ logs.</p>
+ <p>
+ Own Id: OTP-9769 Aux Id: kunagi-202 [113] </p>
+ </item>
+ <item>
+ <p>
+ If a busy test case generated lots of error messages,
+ cth_log_redirect:post_end_per_testcase would crash with a
+ timeout while waiting for the error logger to finish
+ handling all error reports. The default timer was 5
+ seconds. This has now been extended to 5 minutes.</p>
+ <p>
+ Own Id: OTP-10040 Aux Id: kunagi-173 [84] </p>
+ </item>
+ <item>
+ <p>
+ Some bugfixes in <c>ct_snmp:</c></p>
+ <p>
+ <list> <item> ct_snmp will now use the value of the
+ 'agent_vsns' config variable when setting the 'variables'
+ parameter to snmp application agent configuration.
+ Earlier this had to be done separately - i.e. the
+ supported versions had to be specified twice. </item>
+ <item> Snmp application failed to write notify.conf since
+ ct_snmp gave the notify type as a string instead of an
+ atom. This has been corrected. </item> </list></p>
+ <p>
+ Own Id: OTP-10432</p>
+ </item>
+ <item>
+ <p>
+ Some bugfixes in <c>ct_snmp</c>:</p>
+ <p>
+ <list> <item> Functions <c>register_users/2</c>,
+ <c>register_agents/2</c> and <c>register_usm_users/2</c>,
+ and the corresponding <c>unregister_*/1</c> functions
+ were not executable. These are corrected/rewritten.
+ </item> <item> Function <c>update_usm_users/2</c> is
+ removed, and an unregister function is added instead.
+ Update can now be done with unregister_usm_users and then
+ register_usm_users. </item> <item> Functions
+ <c>unregister_*/2</c> are added, so specific
+ users/agents/usm users can be unregistered. </item>
+ <item> Function <c>unload_mibs/1</c> is added for
+ completeness. </item> <item> Overriding configuration
+ files did not work, since the files were written in
+ priv_dir instead of in the configuration dir
+ (priv_dir/conf). This has been corrected. </item> <item>
+ Arguments to <c>register_usm_users/2</c> were faulty
+ documented. This has been corrected. </item> </list></p>
+ <p>
+ Own Id: OTP-10434 Aux Id: kunagi-264 [175] </p>
+ </item>
+ <item>
+ <p>
+ Faulty exported specs in common test has been corrected
+ to <c>ct_netconfc:hook_options/0</c> and
+ <c>inet:hostname/0</c></p>
+ <p>
+ Own Id: OTP-10601</p>
+ </item>
+ <item>
+ <p>
+ The netconf client in common_test did not adjust the
+ window after receiving data. Due to this, the client
+ stopped receiving data after a while. This has been
+ corrected.</p>
+ <p>
+ Own Id: OTP-10646</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ The earlier undocumented cross cover feature for
+ accumulating cover data over multiple tests has now been
+ fixed and documented.</p>
+ <p>
+ Own Id: OTP-9870 Aux Id: kunagi-206 [117] </p>
+ </item>
+ <item>
+ <p>
+ CT drops error reason when groups/0 crashes.</p>
+ <p>
+ Own Id: OTP-10631 Aux Id: kunagi-345 [256] </p>
+ </item>
+ <item>
+ <p>
+ Problem opening sftp connection with ct_ssh.</p>
+ <p>
+ Own Id: OTP-10632 Aux Id: kunagi-346 [257] </p>
+ </item>
+ <item>
+ <p>
+ Event handler on a ct_master node causes hanging.</p>
+ <p>
+ Own Id: OTP-10634 Aux Id: kunagi-347 [258] </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.6.3.1</title>
<section><title>Known Bugs and Problems</title>
diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in
index 4372ab124e..5a9fabbe45 100644
--- a/lib/common_test/priv/Makefile.in
+++ b/lib/common_test/priv/Makefile.in
@@ -68,15 +68,15 @@ JS = jquery-latest.js jquery.tablesorter.min.js
include ../../test_server/vsn.mk
debug opt:
- sed -e 's;@CT_VSN@;$(VSN);' \
+ $(V_at)sed -e 's;@CT_VSN@;$(VSN);' \
-e 's;@TS_VSN@;$(TEST_SERVER_VSN);' \
../install.sh.in > install.sh
- chmod 775 install.sh
+ $(V_at)chmod 775 install.sh
docs:
clean:
- rm -f $(SCRIPTS)
+ $(V_at)rm -f $(SCRIPTS)
# ----------------------------------------------------
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index dd2923ece9..31906b4568 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -97,7 +97,7 @@ DTD_FILES = \
# ----------------------------------------------------
ERL_COMPILE_FLAGS += -pa ../ebin -I../include -I $(ERL_TOP)/lib/snmp/include/ \
-I../../test_server/include -I../../xmerl/inc/ \
- -I $(ERL_TOP)/lib/kernel/include
+ -I $(ERL_TOP)/lib/kernel/include -Werror
# ----------------------------------------------------
# Targets
@@ -127,10 +127,10 @@ clean:
# Special Build Targets
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl
index 405df1e978..796a0832d7 100644
--- a/lib/common_test/test/ct_hooks_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE.erl
@@ -64,7 +64,7 @@ end_per_testcase(TestCase, Config) ->
suite() ->
- [{timetrap,{seconds,20}}].
+ [{timetrap,{minutes,1}}].
all() ->
all(suite).
diff --git a/lib/common_test/test/ct_master_SUITE.erl b/lib/common_test/test/ct_master_SUITE.erl
index 56a343a96f..b89d7d4dc5 100644
--- a/lib/common_test/test/ct_master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE.erl
@@ -154,6 +154,9 @@ make_spec(DataDir, FileName, NodeNames, Suites, Config) ->
{init,NodeName,[
{node_start,[{startup_functions,[]},
{monitor_master,true},
+ {boot_timeout,10},
+ {init_timeout,10},
+ {startup_timeout,10},
{env,Env}]},
{eval,{erlang,nodes,[]}}]
}
diff --git a/lib/common_test/test/ct_netconfc_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE.erl
index 3042a924fe..c89a4cdabe 100644
--- a/lib/common_test/test/ct_netconfc_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE.erl
@@ -43,12 +43,11 @@
%% there will be clashes with logging processes etc).
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- Config1 = ct_test_support:init_per_suite(Config),
case application:load(crypto) of
- {error,Reason} ->
+ {error,Reason} when Reason=/={already_loaded,crypto} ->
{skip, Reason};
_ ->
- Config1
+ ct_test_support:init_per_suite(Config)
end.
end_per_suite(Config) ->
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
index d337158bce..54526e8e83 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
@@ -1044,12 +1044,9 @@ gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) ->
Key = gen_dsa2(LSize, NSize),
{Key, encode_key(Key)}.
-encode_key(Key = #'RSAPrivateKey'{}) ->
- {ok, Der} = 'OTP-PUB-KEY':encode('RSAPrivateKey', Key),
- {'RSAPrivateKey', list_to_binary(Der), not_encrypted};
encode_key(Key = #'DSAPrivateKey'{}) ->
- {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key),
- {'DSAPrivateKey', list_to_binary(Der), not_encrypted}.
+ Der = public_key:der_encode('DSAPrivateKey', Key),
+ {'DSAPrivateKey', Der, not_encrypted}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/common_test/test/ct_surefire_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE.erl
index 69e98cef48..b86b47f0a2 100644
--- a/lib/common_test/test/ct_surefire_SUITE.erl
+++ b/lib/common_test/test/ct_surefire_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012. All Rights Reserved.
+%% Copyright Ericsson AB 2012-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
@@ -32,6 +32,7 @@
-include_lib("common_test/include/ct_event.hrl").
-include_lib("xmerl/include/xmerl.hrl").
+-include_lib("kernel/include/file.hrl").
-define(eh, ct_test_support_eh).
@@ -77,53 +78,52 @@ all() ->
%%%-----------------------------------------------------------------
%%%
default(Config) when is_list(Config) ->
- run(default,[cth_surefire],Config),
- PrivDir = ?config(priv_dir,Config),
- XmlRe = filename:join([PrivDir,"*","junit_report.xml"]),
- check_xml(default,XmlRe).
+ run(default,[cth_surefire],"junit_report.xml",Config).
absolute_path(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir,Config),
Path = filename:join(PrivDir,"abspath.xml"),
- run(absolute_path,[{cth_surefire,[{path,Path}]}],Config),
- check_xml(absolute_path,Path).
+ run(absolute_path,[{cth_surefire,[{path,Path}]}],Path,Config).
relative_path(Config) when is_list(Config) ->
Path = "relpath.xml",
- run(relative_path,[{cth_surefire,[{path,Path}]}],Config),
- PrivDir = ?config(priv_dir,Config),
- XmlRe = filename:join([PrivDir,"*",Path]),
- check_xml(relative_path,XmlRe).
+ run(relative_path,[{cth_surefire,[{path,Path}]}],Path,Config).
url(Config) when is_list(Config) ->
Path = "url.xml",
- run(url,[{cth_surefire,[{url_base,?url_base},
- {path,Path}]}],Config),
- PrivDir = ?config(priv_dir,Config),
- XmlRe = filename:join([PrivDir,"*",Path]),
- check_xml(url,XmlRe).
+ run(url,[{cth_surefire,[{url_base,?url_base},{path,Path}]}],
+ Path,Config).
logdir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir,Config),
- LogDir = filename:join(PrivDir,"specific_logdir"),
- file:make_dir(LogDir),
+ Opts = ct_test_support:get_opts(Config),
+ LogDir =
+ case lists:keyfind(logdir,1,Opts) of
+ {logdir,LD} -> LD;
+ false -> ?config(priv_dir,Config)
+ end,
+ MyLogDir = filename:join(LogDir,"specific_logdir"),
+ ensure_exists_empty(MyLogDir),
Path = "logdir.xml",
- run(logdir,[{cth_surefire,[{path,Path}]}],Config,[{logdir,LogDir}]),
- PrivDir = ?config(priv_dir,Config),
- XmlRe = filename:join([LogDir,"*",Path]),
- check_xml(logdir,XmlRe).
+ run(logdir,[{cth_surefire,[{path,Path}]}],Path,Config,[{logdir,MyLogDir}]).
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
-run(Case,CTHs,Config) ->
- run(Case,CTHs,Config,[]).
-run(Case,CTHs,Config,ExtraOpts) ->
+run(Case,CTHs,Report,Config) ->
+ run(Case,CTHs,Report,Config,[]).
+run(Case,CTHs,Report,Config,ExtraOpts) ->
DataDir = ?config(data_dir, Config),
Suite = filename:join(DataDir, "surefire_SUITE"),
{Opts,ERPid} = setup([{suite,Suite},{ct_hooks,CTHs},{label,Case}|ExtraOpts],
Config),
- ok = execute(Case, Opts, ERPid, Config).
+ ok = execute(Case, Opts, ERPid, Config),
+ LogDir =
+ case lists:keyfind(logdir,1,Opts) of
+ {logdir,LD} -> LD;
+ false -> ?config(priv_dir,Config)
+ end,
+ Re = filename:join([LogDir,"*",Report]),
+ check_xml(Case,Re).
setup(Test, Config) ->
Opts0 = ct_test_support:get_opts(Config),
@@ -349,3 +349,26 @@ get_numbers_from_attrs([_|A],T,E,F,S) ->
get_numbers_from_attrs(A,T,E,F,S);
get_numbers_from_attrs([],T,E,F,S) ->
{T,E,F,S}.
+
+ensure_exists_empty(Dir) ->
+ case file:list_dir(Dir) of
+ {error,enoent} ->
+ file:make_dir(Dir);
+ {ok,Files} ->
+ del_files(Dir,Files)
+ end.
+
+del_files(Dir,[F0|Fs] ) ->
+ F = filename:join(Dir,F0),
+ case file:read_file_info(F) of
+ {ok,#file_info{type=directory}} ->
+ {ok,Files} = file:list_dir(F),
+ del_files(F,Files),
+ file:del_dir(F),
+ del_files(Dir,Fs);
+ _ ->
+ file:delete(F),
+ del_files(Dir,Fs)
+ end;
+del_files(_,[]) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index fc572aa82f..8814570e99 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -1043,8 +1043,8 @@ result_match({SkipOrFail,{ErrorInd,{EMod,EFunc,{Why,'_'}}}},
true;
result_match({failed,{timetrap_timeout,{'$approx',Num}}},
{failed,{timetrap_timeout,Value}}) ->
- if Value >= trunc(Num-0.02*Num),
- Value =< trunc(Num+0.02*Num) -> true;
+ if Value >= trunc(Num-0.05*Num),
+ Value =< trunc(Num+0.05*Num) -> true;
true -> false
end;
result_match({user_timetrap_error,{Why,'_'}},
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index f9bb22867e..c92fb2ca37 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1 +1 @@
-COMMON_TEST_VSN = 1.6.3
+COMMON_TEST_VSN = 1.7
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index 27d750f929..ddaae2655d 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -816,6 +816,32 @@ pi() -> 3.1416.
</section>
<section>
+ <title>Inlining of list functions</title>
+ <p>The compiler can also inline a variety of list manipulation functions
+ from the stdlib's lists module.</p>
+
+ <p>This feature must be explicitly enabled with a compiler option or a
+ <c>-compile()</c> attribute in the source module.</p>
+
+ <p>To enable inlining of list functions, use the <c>inline_list_funcs</c>
+ option.</p>
+
+ <p>The following functions are inlined:</p>
+ <list type="bulleted">
+ <item><seealso marker="stdlib:lists#all/2">lists:all/2</seealso></item>
+ <item><seealso marker="stdlib:lists#any/2">lists:any/2</seealso></item>
+ <item><seealso marker="stdlib:lists#foreach/2">lists:foreach/2</seealso></item>
+ <item><seealso marker="stdlib:lists#map/2">lists:map/2</seealso></item>
+ <item><seealso marker="stdlib:lists#flatmap/2">lists:flatmap/2</seealso></item>
+ <item><seealso marker="stdlib:lists#filter/2">lists:filter/2</seealso></item>
+ <item><seealso marker="stdlib:lists#foldl/3">lists:foldl/3</seealso></item>
+ <item><seealso marker="stdlib:lists#foldr/3">lists:foldr/3</seealso></item>
+ <item><seealso marker="stdlib:lists#mapfoldl/3">lists:mapfoldl/3</seealso></item>
+ <item><seealso marker="stdlib:lists#mapfoldr/3">lists:mapfoldr/3</seealso></item>
+ </list>
+ </section>
+
+ <section>
<title>Parse Transformations</title>
<p>Parse transformations are used when a programmer wants to use
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index cbcbf79839..5fbc41b0f7 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -82,7 +82,6 @@ MODULES = \
sys_core_dsetel \
sys_core_fold \
sys_core_inline \
- sys_expand_pmod \
sys_pre_attributes \
sys_pre_expand \
v3_codegen \
@@ -123,7 +122,7 @@ ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
endif
ERL_COMPILE_FLAGS += +inline +warn_unused_import \
- +warnings_as_errors \
+ -Werror \
-I../../stdlib/include -I$(EGEN) -W
# ----------------------------------------------------
@@ -145,19 +144,19 @@ clean:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(EGEN)/beam_opcodes.erl $(EGEN)/beam_opcodes.hrl: genop.tab
- $(PERL) $(ERL_TOP)/erts/emulator/utils/beam_makeops -compiler -outdir $(EGEN) $<
+ $(gen_verbose)$(PERL) $(ERL_TOP)/erts/emulator/utils/beam_makeops -compiler -outdir $(EGEN) $<
$(EBIN)/beam_asm.beam: $(ESRC)/beam_asm.erl $(EGEN)/beam_opcodes.hrl
- $(ERLC) $(ERL_COMPILE_FLAGS) -DCOMPILER_VSN='"$(VSN)"' -o$(EBIN) $<
+ $(V_ERLC) $(ERL_COMPILE_FLAGS) -DCOMPILER_VSN='"$(VSN)"' -o$(EBIN) $<
$(EBIN)/cerl_inline.beam: $(ESRC)/cerl_inline.erl
- $(ERLC) $(ERL_COMPILE_FLAGS) +nowarn_shadow_vars -o$(EBIN) $<
+ $(V_ERLC) $(ERL_COMPILE_FLAGS) +nowarn_shadow_vars -o$(EBIN) $<
# ----------------------------------------------------
# Release Target
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 29758b8fb4..c5a3883b2a 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -62,7 +62,7 @@ files([F|Fs]) ->
case file(F) of
ok -> ok;
{error,Es} ->
- io:format("~p:~n~s~n", [F,format_error(Es)])
+ io:format("~tp:~n~ts~n", [F,format_error(Es)])
end,
files(Fs);
files([]) -> ok.
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 10e7f5e9ce..d2baf51edd 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -202,38 +202,38 @@ format_error(bad_crypto_key) ->
format_error(no_crypto_key) ->
"no crypto key supplied.";
format_error({native, E}) ->
- io_lib:fwrite("native-code compilation failed with reason: ~P.",
+ io_lib:fwrite("native-code compilation failed with reason: ~tP.",
[E, 25]);
format_error({native_crash,E,Stk}) ->
- io_lib:fwrite("native-code compilation crashed with reason: ~P.\n~P\n",
+ io_lib:fwrite("native-code compilation crashed with reason: ~tP.\n~tP\n",
[E,25,Stk,25]);
format_error({open,E}) ->
- io_lib:format("open error '~s'", [file:format_error(E)]);
+ io_lib:format("open error '~ts'", [file:format_error(E)]);
format_error({epp,E}) ->
epp:format_error(E);
format_error(write_error) ->
"error writing file";
format_error({rename,From,To,Error}) ->
- io_lib:format("failed to rename ~s to ~s: ~s",
+ io_lib:format("failed to rename ~ts to ~ts: ~ts",
[From,To,file:format_error(Error)]);
format_error({delete,File,Error}) ->
- io_lib:format("failed to delete file ~s: ~s",
+ io_lib:format("failed to delete file ~ts: ~ts",
[File,file:format_error(Error)]);
format_error({delete_temp,File,Error}) ->
- io_lib:format("failed to delete temporary file ~s: ~s",
+ io_lib:format("failed to delete temporary file ~ts: ~ts",
[File,file:format_error(Error)]);
format_error({parse_transform,M,R}) ->
- io_lib:format("error in parse transform '~s': ~p", [M, R]);
+ io_lib:format("error in parse transform '~s': ~tp", [M, R]);
format_error({undef_parse_transform,M}) ->
io_lib:format("undefined parse transform '~s'", [M]);
format_error({core_transform,M,R}) ->
- io_lib:format("error in core transform '~s': ~p", [M, R]);
+ io_lib:format("error in core transform '~s': ~tp", [M, R]);
format_error({crash,Pass,Reason}) ->
- io_lib:format("internal error in ~p;\ncrash reason: ~p", [Pass,Reason]);
+ io_lib:format("internal error in ~p;\ncrash reason: ~tp", [Pass,Reason]);
format_error({bad_return,Pass,Reason}) ->
- io_lib:format("internal error in ~p;\nbad return value: ~p", [Pass,Reason]);
+ io_lib:format("internal error in ~p;\nbad return value: ~tp", [Pass,Reason]);
format_error({module_name,Mod,Filename}) ->
- io_lib:format("Module name '~s' does not match file name '~s'",
+ io_lib:format("Module name '~s' does not match file name '~ts'",
[Mod,Filename]).
%% The compile state record.
@@ -248,7 +248,7 @@ format_error({module_name,Mod,Filename}) ->
abstract_code=[], %Abstract code for debugger.
options=[] :: [option()], %Options for compilation
mod_options=[] :: [option()], %Options for module_info
- encoding=none :: none | epp:source_coding(),
+ encoding=none :: none | epp:source_encoding(),
errors=[],
warnings=[]}).
@@ -271,7 +271,7 @@ internal_comp(Passes, File, Suffix, St0) ->
ofile=objfile(Base, St0)},
Run = case member(time, St1#compile.options) of
true ->
- io:format("Compiling ~p\n", [File]),
+ io:format("Compiling ~tp\n", [File]),
fun run_tc/2;
false -> fun({_Name,Fun}, St) -> catch Fun(St) end
end,
@@ -895,7 +895,6 @@ foldl_core_transforms(St, []) -> {ok,St}.
%%% Fetches the module name from a list of forms. The module attribute must
%%% be present.
-get_module([{attribute,_,module,{M,_As}} | _]) -> M;
get_module([{attribute,_,module,M} | _]) -> M;
get_module([_ | Rest]) ->
get_module(Rest).
@@ -907,11 +906,8 @@ add_default_base(St, Forms) ->
F = St#compile.filename,
case F of
"" ->
- M = case get_module(Forms) of
- PackageModule when is_list(PackageModule) -> last(PackageModule);
- M0 -> M0
- end,
- St#compile{base = atom_to_list(M)};
+ M = get_module(Forms),
+ St#compile{base=atom_to_list(M)};
_ ->
St
end.
@@ -1093,7 +1089,7 @@ makedep_output(#compile{code=Code,options=Opts,ofile=Ofile}=St) ->
{ok,Output1,CloseOutput} ->
try
%% Write the Makefile.
- io:fwrite(Output1, "~s", [Code]),
+ io:fwrite(Output1, "~ts", [Code]),
%% Close the file if relevant.
if
CloseOutput -> file:close(Output1);
@@ -1423,28 +1419,28 @@ report_warnings(#compile{options=Opts,warnings=Ws0}) ->
end.
format_message(F, P, [{{Line,Column}=Loc,Mod,E}|Es]) ->
- M = {{F,Loc},io_lib:format("~s:~w:~w ~s~ts\n",
+ M = {{F,Loc},io_lib:format("~ts:~w:~w ~s~ts\n",
[F,Line,Column,P,Mod:format_error(E)])},
[M|format_message(F, P, Es)];
format_message(F, P, [{Line,Mod,E}|Es]) ->
- M = {{F,{Line,0}},io_lib:format("~s:~w: ~s~ts\n",
+ M = {{F,{Line,0}},io_lib:format("~ts:~w: ~s~ts\n",
[F,Line,P,Mod:format_error(E)])},
[M|format_message(F, P, Es)];
format_message(F, P, [{Mod,E}|Es]) ->
- M = {none,io_lib:format("~s: ~s~ts\n", [F,P,Mod:format_error(E)])},
+ M = {none,io_lib:format("~ts: ~s~ts\n", [F,P,Mod:format_error(E)])},
[M|format_message(F, P, Es)];
format_message(_, _, []) -> [].
%% list_errors(File, ErrorDescriptors) -> ok
list_errors(F, [{{Line,Column},Mod,E}|Es]) ->
- io:fwrite("~s:~w:~w: ~ts\n", [F,Line,Column,Mod:format_error(E)]),
+ io:fwrite("~ts:~w:~w: ~ts\n", [F,Line,Column,Mod:format_error(E)]),
list_errors(F, Es);
list_errors(F, [{Line,Mod,E}|Es]) ->
- io:fwrite("~s:~w: ~ts\n", [F,Line,Mod:format_error(E)]),
+ io:fwrite("~ts:~w: ~ts\n", [F,Line,Mod:format_error(E)]),
list_errors(F, Es);
list_errors(F, [{Mod,E}|Es]) ->
- io:fwrite("~s: ~ts\n", [F,Mod:format_error(E)]),
+ io:fwrite("~ts: ~ts\n", [F,Mod:format_error(E)]),
list_errors(F, Es);
list_errors(_F, []) -> ok.
diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src
index 94c78e68f9..9a02121d8b 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.app.src
@@ -57,7 +57,6 @@
sys_core_dsetel,
sys_core_fold,
sys_core_inline,
- sys_expand_pmod,
sys_pre_attributes,
sys_pre_expand,
v3_codegen,
diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl
index b513a8965c..21296a8b66 100644
--- a/lib/compiler/src/core_lint.erl
+++ b/lib/compiler/src/core_lint.erl
@@ -247,7 +247,8 @@ gbody(E, Def, Rt, St0) ->
false -> St1
end.
-gexpr(#c_var{name=N}, Def, _Rt, St) -> expr_var(N, Def, St);
+gexpr(#c_var{name=N}, Def, _Rt, St) when is_atom(N); is_integer(N) ->
+ expr_var(N, Def, St);
gexpr(#c_literal{}, _Def, _Rt, St) -> St;
gexpr(#c_cons{hd=H,tl=T}, Def, _Rt, St) ->
gexpr_list([H,T], Def, St);
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 18fba7962b..fbd7452301 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -686,11 +686,14 @@ call_1(#c_call{anno=Anno}, lists, all, [Arg1,Arg2], Sub) ->
C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]},
clauses = [CC1, CC2, CC3]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
body=#c_literal{val=true}},
- Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err2)},
+ body=match_fail([{function_name,{'lists^all',1}}|Anno], Err2)},
Fun = #c_fun{vars=[Xs],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -713,11 +716,14 @@ call_1(#c_call{anno=Anno}, lists, any, [Arg1,Arg2], Sub) ->
C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]},
clauses = [CC1, CC2, CC3]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
body=#c_literal{val=false}},
- Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err2)},
+ body=match_fail([{function_name,{'lists^any',1}}|Anno], Err2)},
Fun = #c_fun{vars=[Xs],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -733,11 +739,14 @@ call_1(#c_call{anno=Anno}, lists, foreach, [Arg1,Arg2], Sub) ->
C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
body=#c_seq{arg=#c_apply{anno=Anno, op=F, args=[X]},
body=#c_apply{anno=Anno, op=Loop, args=[Xs]}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
body=#c_literal{val=ok}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^foreach',1}}|Anno], Err)},
Fun = #c_fun{vars=[Xs],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -756,14 +765,18 @@ call_1(#c_call{anno=Anno}, lists, map, [Arg1,Arg2], Sub) ->
op=F,
args=[X]},
body=#c_cons{hd=H,
+ anno=[compiler_generated],
tl=#c_apply{anno=Anno,
op=Loop,
args=[Xs]}}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
body=#c_literal{val=[]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^map',1}}|Anno], Err)},
Fun = #c_fun{vars=[Xs],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -780,18 +793,21 @@ call_1(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2], Sub) ->
C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true},
body=#c_let{vars=[H],
arg=#c_apply{anno=Anno, op=F, args=[X]},
- body=#c_call{anno=Anno,
+ body=#c_call{anno=[compiler_generated|Anno],
module=#c_literal{val=erlang},
name=#c_literal{val='++'},
args=[H,
#c_apply{anno=Anno,
op=Loop,
args=[Xs]}]}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
body=#c_literal{val=[]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^flatmap',1}}|Anno], Err)},
Fun = #c_fun{vars=[Xs],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -807,7 +823,7 @@ call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) ->
B = #c_var{name='B'},
Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]},
CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true},
- body=#c_cons{hd=X, tl=Xs}},
+ body=#c_cons{anno=[compiler_generated], hd=X, tl=Xs}},
CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true},
body=Xs},
CC3 = #c_clause{pats=[X], guard=#c_literal{val=true},
@@ -821,11 +837,14 @@ call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) ->
op=Loop,
args=[Xs]},
body=Case}}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=1}]},
body=#c_literal{val=[]}},
- Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err2)},
+ body=match_fail([{function_name,{'lists^filter',1}}|Anno], Err2)},
Fun = #c_fun{vars=[Xs],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -845,10 +864,14 @@ call_1(#c_call{anno=Anno}, lists, foldl, [Arg1,Arg2,Arg3], Sub) ->
args=[Xs, #c_apply{anno=Anno,
op=F,
args=[X, A]}]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, body=A},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
+ body=A},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^foldl',2}}|Anno], Err)},
Fun = #c_fun{vars=[Xs, A],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -868,10 +891,14 @@ call_1(#c_call{anno=Anno}, lists, foldr, [Arg1,Arg2,Arg3], Sub) ->
args=[X, #c_apply{anno=Anno,
op=Loop,
args=[Xs, A]}]}},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, body=A},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
+ body=A},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^foldr',2}}|Anno], Err)},
Fun = #c_fun{vars=[Xs, A],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -901,7 +928,10 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) ->
op=Loop,
args=[Xs, Avar]},
#c_tuple{es=[Xs, Avar]},
- #c_tuple{es=[#c_cons{hd=X, tl=Xs}, Avar]})
+ #c_tuple{anno=[compiler_generated],
+ es=[#c_cons{anno=[compiler_generated],
+ hd=X, tl=Xs},
+ Avar]})
%%% Multiple-value version
%%% #c_let{vars=[Xs,A],
%%% %% The tuple here will be optimised
@@ -910,14 +940,18 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) ->
%%% body=#c_values{es=[#c_cons{hd=X, tl=Xs},
%%% A]}}
)},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
%%% Tuple passing version
- body=#c_tuple{es=[#c_literal{val=[]}, Avar]}},
+ body=#c_tuple{anno=[compiler_generated],
+ es=[#c_literal{val=[]}, Avar]}},
%%% Multiple-value version
%%% body=#c_values{es=[#c_literal{val=[]}, A]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^mapfoldl',2}}|Anno], Err)},
Fun = #c_fun{vars=[Xs, Avar],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -955,7 +989,9 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) ->
#c_tuple{es=[Xs, Avar]},
Match(#c_apply{anno=Anno, op=F, args=[X, Avar]},
#c_tuple{es=[X, Avar]},
- #c_tuple{es=[#c_cons{hd=X, tl=Xs}, Avar]}))
+ #c_tuple{anno=[compiler_generated],
+ es=[#c_cons{anno=[compiler_generated],
+ hd=X, tl=Xs}, Avar]}))
%%% Multiple-value version
%%% body=#c_let{vars=[Xs,A],
%%% %% The tuple will be optimised away
@@ -965,14 +1001,18 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) ->
%%% #c_values{es=[#c_cons{hd=X, tl=Xs},
%%% A]})}
},
- C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true},
+ C2 = #c_clause{pats=[#c_literal{val=[]}],
+ guard=#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=is_function},
+ args=[F, #c_literal{val=2}]},
%%% Tuple passing version
- body=#c_tuple{es=[#c_literal{val=[]}, Avar]}},
+ body=#c_tuple{anno=[compiler_generated],
+ es=[#c_literal{val=[]}, Avar]}},
%%% Multiple-value version
%%% body=#c_values{es=[#c_literal{val=[]}, A]}},
- Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]},
+ Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]},
C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true},
- body=match_fail(Anno, Err)},
+ body=match_fail([{function_name,{'lists^mapfoldr',2}}|Anno], Err)},
Fun = #c_fun{vars=[Xs, Avar],
body=#c_case{arg=Xs, clauses=[C1, C2, C3]}},
L = #c_var{name='L'},
@@ -2632,16 +2672,19 @@ bsm_nonempty([#c_clause{pats=Ps}|Cs], Pos) ->
bsm_nonempty([], _ ) -> false.
%% bsm_ensure_no_partition(Cs, Pos) -> ok (exception if problem)
-%% We must make sure that binary matching is not partitioned between
+%% We must make sure that matching is not partitioned between
%% variables like this:
%% foo(<<...>>) -> ...
-%% foo(Var) when ... -> ...
-%% foo(<<...>>) ->
+%% foo(<Variable>) when ... -> ...
+%% foo(<Any non-variable pattern>) ->
%% If there is such partition, we are not allowed to reuse the binary variable
-%% for the match context. Also, arguments to the left of the argument that
-%% is matched against a binary, are only allowed to be simple variables, not
-%% used in guards. The reason is that we must know that the binary is only
-%% matched in one place.
+%% for the match context.
+%%
+%% Also, arguments to the left of the argument that is matched
+%% against a binary, are only allowed to be simple variables, not
+%% used in guards. The reason is that we must know that the binary is
+%% only matched in one place (i.e. there must be only one bs_start_match2
+%% instruction emitted).
bsm_ensure_no_partition(Cs, Pos) ->
bsm_ensure_no_partition_1(Cs, Pos, before).
@@ -2649,6 +2692,12 @@ bsm_ensure_no_partition(Cs, Pos) ->
%% Loop through each clause.
bsm_ensure_no_partition_1([#c_clause{pats=Ps,guard=G}|Cs], Pos, State0) ->
State = bsm_ensure_no_partition_2(Ps, Pos, G, simple_vars, State0),
+ case State of
+ 'after' ->
+ bsm_ensure_no_partition_after(Cs, Pos);
+ _ ->
+ ok
+ end,
bsm_ensure_no_partition_1(Cs, Pos, State);
bsm_ensure_no_partition_1([], _, _) -> ok.
@@ -2658,8 +2707,7 @@ bsm_ensure_no_partition_2([#c_binary{}=Where|_], 1, _, Vstate, State) ->
before when Vstate =:= simple_vars -> within;
before -> bsm_problem(Where, Vstate);
within when Vstate =:= simple_vars -> within;
- within -> bsm_problem(Where, Vstate);
- 'after' -> bsm_problem(Where, bin_partition)
+ within -> bsm_problem(Where, Vstate)
end;
bsm_ensure_no_partition_2([#c_alias{}=Alias|_], 1, N, Vstate, State) ->
%% Retrieve the real pattern that the alias refers to and check that.
@@ -2708,6 +2756,15 @@ bsm_ensure_no_partition_2([#c_var{name=V}|Ps], N, G, Vstate, S) ->
bsm_ensure_no_partition_2([_|Ps], N, G, _, S) ->
bsm_ensure_no_partition_2(Ps, N-1, G, bin_argument_order, S).
+bsm_ensure_no_partition_after([#c_clause{pats=Ps}|Cs], Pos) ->
+ case nth(Pos, Ps) of
+ #c_var{} ->
+ bsm_ensure_no_partition_after(Cs, Pos);
+ P ->
+ bsm_problem(P, bin_partition)
+ end;
+bsm_ensure_no_partition_after([], _) -> ok.
+
bsm_could_match_binary(#c_alias{pat=P}) -> bsm_could_match_binary(P);
bsm_could_match_binary(#c_cons{}) -> false;
bsm_could_match_binary(#c_tuple{}) -> false;
@@ -2832,7 +2889,7 @@ format_error(useless_building) ->
format_error(bin_opt_alias) ->
"INFO: the '=' operator will prevent delayed sub binary optimization";
format_error(bin_partition) ->
- "INFO: non-consecutive clauses that match binaries "
+ "INFO: matching non-variables after a previous clause matching a variable "
"will prevent delayed sub binary optimization";
format_error(bin_left_var_used_in_guard) ->
"INFO: a variable to the left of the binary pattern is used in a guard; "
diff --git a/lib/compiler/src/sys_expand_pmod.erl b/lib/compiler/src/sys_expand_pmod.erl
deleted file mode 100644
index da644b4f0b..0000000000
--- a/lib/compiler/src/sys_expand_pmod.erl
+++ /dev/null
@@ -1,433 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-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%
-%%
--module(sys_expand_pmod).
-
-%% Expand function definition forms of parameterized module. We assume
-%% all record definitions, imports, queries, etc., have been expanded
-%% away. Any calls on the form 'foo(...)' must be calls to local
-%% functions. Auto-generated functions (module_info,...) have not yet
-%% been added to the function definitions, but are listed in 'defined'
-%% and 'exports'. The automatic 'new/N' function is neither added to the
-%% definitions nor to the 'exports'/'defines' lists yet.
-
--export([forms/4]).
-
--record(pmod, {parameters, exports, defined, predef}).
-
-%% TODO: more abstract handling of predefined/static functions.
-
-forms(Fs0, Ps, Es0, Ds0) ->
- PreDef = [{module_info,0},{module_info,1}],
- forms(Fs0, Ps, Es0, Ds0, PreDef).
-
-forms(Fs0, Ps, Es0, Ds0, PreDef) ->
- St0 = #pmod{parameters=Ps,exports=Es0,defined=Ds0, predef=PreDef},
- {Fs1, St1} = forms(Fs0, St0),
- Es1 = update_function_names(Es0, St1),
- Ds1 = update_function_names(Ds0, St1),
- Fs2 = update_forms(Fs1, St1),
- {Fs2,Es1,Ds1}.
-
-%% This is extremely simplistic for now; all functions get an extra
-%% parameter, whether they need it or not, except for static functions.
-
-update_function_names(Es, St) ->
- [update_function_name(E, St) || E <- Es].
-
-update_function_name(E={F,A}, St) when F =/= new ->
- case ordsets:is_element(E, St#pmod.predef) of
- true -> E;
- false -> {F, A + 1}
- end;
-update_function_name(E, _St) ->
- E.
-
-update_forms([{function,L,N,A,Cs}|Fs],St) when N =/= new ->
- [{function,L,N,A+1,Cs}|update_forms(Fs,St)];
-update_forms([F|Fs],St) ->
- [F|update_forms(Fs,St)];
-update_forms([],_St) ->
- [].
-
-%% Process the program forms.
-
-forms([F0|Fs0],St0) ->
- {F1,St1} = form(F0,St0),
- {Fs1,St2} = forms(Fs0,St1),
- {[F1|Fs1],St2};
-forms([], St0) ->
- {[], St0}.
-
-%% Only function definitions are of interest here. State is not updated.
-form({function,Line,Name0,Arity0,Clauses0},St) when Name0 =/= new ->
- {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0, St),
- {{function,Line,Name,Arity,Clauses},St};
-%% Pass anything else through
-form(F,St) -> {F,St}.
-
-function(Name, Arity, Clauses0, St) ->
- Clauses1 = clauses(Clauses0,St),
- {Name,Arity,Clauses1}.
-
-clauses([C|Cs],St) ->
- {clause,L,H,G,B} = clause(C,St),
- T = {tuple,L,[{var,L,V} || V <- ['_'|St#pmod.parameters]]},
- [{clause,L,H++[{match,L,T,{var,L,'THIS'}}],G,B}|clauses(Cs,St)];
-clauses([],_St) -> [].
-
-clause({clause,Line,H0,G0,B0},St) ->
- H1 = head(H0,St),
- G1 = guard(G0,St),
- B1 = exprs(B0,St),
- {clause,Line,H1,G1,B1}.
-
-head(Ps,St) -> patterns(Ps,St).
-
-patterns([P0|Ps],St) ->
- P1 = pattern(P0,St),
- [P1|patterns(Ps,St)];
-patterns([],_St) -> [].
-
-string_to_conses([], _Line, Tail) ->
- Tail;
-string_to_conses([E|Rest], Line, Tail) ->
- {cons, Line, {integer, Line, E}, string_to_conses(Rest, Line, Tail)}.
-
-pattern({var,_Line,_V}=Var,_St) -> Var;
-pattern({match,Line,L0,R0},St) ->
- L1 = pattern(L0,St),
- R1 = pattern(R0,St),
- {match,Line,L1,R1};
-pattern({integer,_Line,_I}=Integer,_St) -> Integer;
-pattern({char,_Line,_C}=Char,_St) -> Char;
-pattern({float,_Line,_F}=Float,_St) -> Float;
-pattern({atom,_Line,_A}=Atom,_St) -> Atom;
-pattern({string,_Line,_S}=String,_St) -> String;
-pattern({nil,_Line}=Nil,_St) -> Nil;
-pattern({cons,Line,H0,T0},St) ->
- H1 = pattern(H0,St),
- T1 = pattern(T0,St),
- {cons,Line,H1,T1};
-pattern({tuple,Line,Ps0},St) ->
- Ps1 = pattern_list(Ps0,St),
- {tuple,Line,Ps1};
-pattern({bin,Line,Fs},St) ->
- Fs2 = pattern_grp(Fs,St),
- {bin,Line,Fs2};
-pattern({op,_Line,'++',{nil,_},R},St) ->
- pattern(R,St);
-pattern({op,_Line,'++',{cons,Li,{char,_C2,_I}=Char,T},R},St) ->
- pattern({cons,Li,Char,{op,Li,'++',T,R}},St);
-pattern({op,_Line,'++',{cons,Li,{integer,_L2,_I}=Integer,T},R},St) ->
- pattern({cons,Li,Integer,{op,Li,'++',T,R}},St);
-pattern({op,_Line,'++',{string,Li,L},R},St) ->
- pattern(string_to_conses(L, Li, R),St);
-pattern({op,_Line,_Op,_A}=Op4,_St) -> Op4;
-pattern({op,_Line,_Op,_L,_R}=Op5,_St) -> Op5.
-
-pattern_grp([{bin_element,L1,E1,S1,T1} | Fs],St) ->
- S2 = case S1 of
- default ->
- default;
- _ ->
- expr(S1,St)
- end,
- T2 = case T1 of
- default ->
- default;
- _ ->
- bit_types(T1)
- end,
- [{bin_element,L1,expr(E1,St),S2,T2} | pattern_grp(Fs,St)];
-pattern_grp([],_St) ->
- [].
-
-bit_types([]) ->
- [];
-bit_types([Atom | Rest]) when is_atom(Atom) ->
- [Atom | bit_types(Rest)];
-bit_types([{Atom, Integer} | Rest]) when is_atom(Atom), is_integer(Integer) ->
- [{Atom, Integer} | bit_types(Rest)].
-
-pattern_list([P0|Ps],St) ->
- P1 = pattern(P0,St),
- [P1|pattern_list(Ps,St)];
-pattern_list([],_St) -> [].
-
-guard([G0|Gs],St) when is_list(G0) ->
- [guard0(G0,St) | guard(Gs,St)];
-guard(L,St) ->
- guard0(L,St).
-
-guard0([G0|Gs],St) ->
- G1 = guard_test(G0,St),
- [G1|guard0(Gs,St)];
-guard0([],_St) -> [].
-
-guard_test(Expr={call,Line,{atom,La,F},As0},St) ->
- case erl_internal:type_test(F, length(As0)) of
- true ->
- As1 = gexpr_list(As0,St),
- {call,Line,{atom,La,F},As1};
- _ ->
- gexpr(Expr,St)
- end;
-guard_test(Any,St) ->
- gexpr(Any,St).
-
-gexpr({var,_L,_V}=Var,_St) -> Var;
-% %% alternative implementation of accessing module parameters
-% case index(V,St#pmod.parameters) of
-% N when N > 0 ->
-% {call,L,{remote,L,{atom,L,erlang},{atom,L,element}},
-% [{integer,L,N+1},{var,L,'THIS'}]};
-% _ ->
-% Var
-% end;
-gexpr({integer,_Line,_I}=Integer,_St) -> Integer;
-gexpr({char,_Line,_C}=Char,_St) -> Char;
-gexpr({float,_Line,_F}=Float,_St) -> Float;
-gexpr({atom,_Line,_A}=Atom,_St) -> Atom;
-gexpr({string,_Line,_S}=String,_St) -> String;
-gexpr({nil,_Line}=Nil,_St) -> Nil;
-gexpr({cons,Line,H0,T0},St) ->
- H1 = gexpr(H0,St),
- T1 = gexpr(T0,St),
- {cons,Line,H1,T1};
-gexpr({tuple,Line,Es0},St) ->
- Es1 = gexpr_list(Es0,St),
- {tuple,Line,Es1};
-gexpr({call,Line,{atom,_La,F}=Atom,As0},St) ->
- true = erl_internal:guard_bif(F, length(As0)),
- As1 = gexpr_list(As0,St),
- {call,Line,Atom,As1};
-%% Pre-expansion generated calls to erlang:is_record/3 must also be handled
-gexpr({call,Line,{remote,La,{atom,Lb,erlang},{atom,Lc,is_record}},[_,_,_]=As0},St) ->
- As1 = gexpr_list(As0,St),
- {call,Line,{remote,La,{atom,Lb,erlang},{atom,Lc,is_record}},As1};
-%% Guard BIFs can be remote, but only in the module erlang...
-gexpr({call,Line,{remote,La,{atom,Lb,erlang},{atom,Lc,F}},As0},St) ->
- A = length(As0),
- true =
- erl_internal:guard_bif(F, A) orelse erl_internal:arith_op(F, A) orelse
- erl_internal:comp_op(F, A) orelse erl_internal:bool_op(F, A),
- As1 = gexpr_list(As0,St),
- {call,Line,{remote,La,{atom,Lb,erlang},{atom,Lc,F}},As1};
-%% Unfortunately, writing calls as {M,F}(...) is also allowed.
-gexpr({call,Line,{tuple,La,[{atom,Lb,erlang},{atom,Lc,F}]},As0},St) ->
- A = length(As0),
- true =
- erl_internal:guard_bif(F, A) orelse erl_internal:arith_op(F, A) orelse
- erl_internal:comp_op(F, A) orelse erl_internal:bool_op(F, A),
- As1 = gexpr_list(As0,St),
- {call,Line,{tuple,La,[{atom,Lb,erlang},{atom,Lc,F}]},As1};
-gexpr({bin,Line,Fs},St) ->
- Fs2 = pattern_grp(Fs,St),
- {bin,Line,Fs2};
-gexpr({op,Line,Op,A0},St) ->
- true = erl_internal:arith_op(Op, 1) orelse erl_internal:bool_op(Op, 1),
- A1 = gexpr(A0,St),
- {op,Line,Op,A1};
-gexpr({op,Line,Op,L0,R0},St) ->
- true =
- Op =:= 'andalso' orelse Op =:= 'orelse' orelse
- erl_internal:arith_op(Op, 2) orelse
- erl_internal:bool_op(Op, 2) orelse erl_internal:comp_op(Op, 2),
- L1 = gexpr(L0,St),
- R1 = gexpr(R0,St),
- {op,Line,Op,L1,R1}.
-
-gexpr_list([E0|Es],St) ->
- E1 = gexpr(E0,St),
- [E1|gexpr_list(Es,St)];
-gexpr_list([],_St) -> [].
-
-exprs([E0|Es],St) ->
- E1 = expr(E0,St),
- [E1|exprs(Es,St)];
-exprs([],_St) -> [].
-
-expr({var,_L,_V}=Var,_St) ->
- Var;
-% case index(V,St#pmod.parameters) of
-% N when N > 0 ->
-% {call,L,{remote,L,{atom,L,erlang},{atom,L,element}},
-% [{integer,L,N+1},{var,L,'THIS'}]};
-% _ ->
-% Var
-% end;
-expr({integer,_Line,_I}=Integer,_St) -> Integer;
-expr({float,_Line,_F}=Float,_St) -> Float;
-expr({atom,_Line,_A}=Atom,_St) -> Atom;
-expr({string,_Line,_S}=String,_St) -> String;
-expr({char,_Line,_C}=Char,_St) -> Char;
-expr({nil,_Line}=Nil,_St) -> Nil;
-expr({cons,Line,H0,T0},St) ->
- H1 = expr(H0,St),
- T1 = expr(T0,St),
- {cons,Line,H1,T1};
-expr({lc,Line,E0,Qs0},St) ->
- Qs1 = lc_bc_quals(Qs0,St),
- E1 = expr(E0,St),
- {lc,Line,E1,Qs1};
-expr({bc,Line,E0,Qs0},St) ->
- Qs1 = lc_bc_quals(Qs0,St),
- E1 = expr(E0,St),
- {bc,Line,E1,Qs1};
-expr({tuple,Line,Es0},St) ->
- Es1 = expr_list(Es0,St),
- {tuple,Line,Es1};
-expr({block,Line,Es0},St) ->
- Es1 = exprs(Es0,St),
- {block,Line,Es1};
-expr({'if',Line,Cs0},St) ->
- Cs1 = icr_clauses(Cs0,St),
- {'if',Line,Cs1};
-expr({'case',Line,E0,Cs0},St) ->
- E1 = expr(E0,St),
- Cs1 = icr_clauses(Cs0,St),
- {'case',Line,E1,Cs1};
-expr({'receive',Line,Cs0},St) ->
- Cs1 = icr_clauses(Cs0,St),
- {'receive',Line,Cs1};
-expr({'receive',Line,Cs0,To0,ToEs0},St) ->
- To1 = expr(To0,St),
- ToEs1 = exprs(ToEs0,St),
- Cs1 = icr_clauses(Cs0,St),
- {'receive',Line,Cs1,To1,ToEs1};
-expr({'try',Line,Es0,Scs0,Ccs0,As0},St) ->
- Es1 = exprs(Es0,St),
- Scs1 = icr_clauses(Scs0,St),
- Ccs1 = icr_clauses(Ccs0,St),
- As1 = exprs(As0,St),
- {'try',Line,Es1,Scs1,Ccs1,As1};
-expr({'fun',_,{function,_,_,_}}=ExtFun,_St) ->
- ExtFun;
-expr({'fun',Line,Body,Info},St) ->
- case Body of
- {clauses,Cs0} ->
- Cs1 = fun_clauses(Cs0,St),
- {'fun',Line,{clauses,Cs1},Info};
- {function,F,A} = Function ->
- {F1,A1} = update_function_name({F,A},St),
- if A1 =:= A ->
- {'fun',Line,Function,Info};
- true ->
- %% Must rewrite local fun-name to a fun that does a
- %% call with the extra THIS parameter.
- As = make_vars(A, Line),
- As1 = As ++ [{var,Line,'THIS'}],
- Call = {call,Line,{atom,Line,F1},As1},
- Cs = [{clause,Line,As,[],[Call]}],
- {'fun',Line,{clauses,Cs},Info}
- end;
- {function,_M,_F,_A} = Fun4 -> %This is an error in lint!
- {'fun',Line,Fun4,Info}
- end;
-expr({call,Lc,{atom,_,instance}=Name,As0},St) ->
- %% All local functions 'instance(...)' are static by definition,
- %% so they do not take a 'THIS' argument when called
- As1 = expr_list(As0,St),
- {call,Lc,Name,As1};
-expr({call,Lc,{atom,_,new}=Name,As0},St) ->
- %% All local functions 'new(...)' are static by definition,
- %% so they do not take a 'THIS' argument when called
- As1 = expr_list(As0,St),
- {call,Lc,Name,As1};
-expr({call,Lc,{atom,_,module_info}=Name,As0},St)
- when length(As0) =:= 0; length(As0) =:= 1 ->
- %% The module_info/0 and module_info/1 functions are also static.
- As1 = expr_list(As0,St),
- {call,Lc,Name,As1};
-expr({call,Lc,{atom,_Lf,_F}=Atom,As0},St) ->
- %% Local function call - needs THIS parameter.
- As1 = expr_list(As0,St),
- {call,Lc,Atom,As1 ++ [{var,0,'THIS'}]};
-expr({call,Line,F0,As0},St) ->
- %% Other function call
- F1 = expr(F0,St),
- As1 = expr_list(As0,St),
- {call,Line,F1,As1};
-expr({'catch',Line,E0},St) ->
- E1 = expr(E0,St),
- {'catch',Line,E1};
-expr({match,Line,P0,E0},St) ->
- E1 = expr(E0,St),
- P1 = pattern(P0,St),
- {match,Line,P1,E1};
-expr({bin,Line,Fs},St) ->
- Fs2 = pattern_grp(Fs,St),
- {bin,Line,Fs2};
-expr({op,Line,Op,A0},St) ->
- A1 = expr(A0,St),
- {op,Line,Op,A1};
-expr({op,Line,Op,L0,R0},St) ->
- L1 = expr(L0,St),
- R1 = expr(R0,St),
- {op,Line,Op,L1,R1};
-%% The following are not allowed to occur anywhere!
-expr({remote,Line,M0,F0},St) ->
- M1 = expr(M0,St),
- F1 = expr(F0,St),
- {remote,Line,M1,F1}.
-
-expr_list([E0|Es],St) ->
- E1 = expr(E0,St),
- [E1|expr_list(Es,St)];
-expr_list([],_St) -> [].
-
-icr_clauses([C0|Cs],St) ->
- C1 = clause(C0,St),
- [C1|icr_clauses(Cs,St)];
-icr_clauses([],_St) -> [].
-
-lc_bc_quals([{generate,Line,P0,E0}|Qs],St) ->
- E1 = expr(E0,St),
- P1 = pattern(P0,St),
- [{generate,Line,P1,E1}|lc_bc_quals(Qs,St)];
-lc_bc_quals([{b_generate,Line,P0,E0}|Qs],St) ->
- E1 = expr(E0,St),
- P1 = pattern(P0,St),
- [{b_generate,Line,P1,E1}|lc_bc_quals(Qs,St)];
-lc_bc_quals([E0|Qs],St) ->
- E1 = expr(E0,St),
- [E1|lc_bc_quals(Qs,St)];
-lc_bc_quals([],_St) -> [].
-
-fun_clauses([C0|Cs],St) ->
- C1 = clause(C0,St),
- [C1|fun_clauses(Cs,St)];
-fun_clauses([],_St) -> [].
-
-%% %% Return index from 1 upwards, or 0 if not in the list.
-%%
-%% index(X,Ys) -> index(X,Ys,1).
-%%
-%% index(X,[X|Ys],A) -> A;
-%% index(X,[Y|Ys],A) -> index(X,Ys,A+1);
-%% index(X,[],A) -> 0.
-
-make_vars(N, L) ->
- make_vars(1, N, L).
-
-make_vars(N, M, L) when N =< M ->
- V = list_to_atom("X"++integer_to_list(N)),
- [{var,L,V} | make_vars(N + 1, M, L)];
-make_vars(_, _, _) ->
- [].
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
index a8c69c3cb1..7d918a55ed 100644
--- a/lib/compiler/src/sys_pre_expand.erl
+++ b/lib/compiler/src/sys_pre_expand.erl
@@ -28,13 +28,12 @@
%% Main entry point.
-export([module/2]).
--import(ordsets, [from_list/1,add_element/2,union/2]).
+-import(ordsets, [from_list/1,union/2]).
-import(lists, [member/2,foldl/3,foldr/3]).
-include("../include/erl_bits.hrl").
-record(expand, {module=[], %Module name
- parameters=undefined, %Module parameters
exports=[], %Exports
imports=[], %Imports
compile=[], %Compile flags
@@ -74,88 +73,20 @@ module(Fs0, Opts0) ->
},
%% Expand the functions.
{Tfs,St1} = forms(Fs, define_functions(Fs, St0)),
- {Efs,St2} = expand_pmod(Tfs, St1),
%% Get the correct list of exported functions.
- Exports = case member(export_all, St2#expand.compile) of
- true -> gb_sets:to_list(St2#expand.defined);
- false -> St2#expand.exports
+ Exports = case member(export_all, St1#expand.compile) of
+ true -> gb_sets:to_list(St1#expand.defined);
+ false -> St1#expand.exports
end,
%% Generate all functions from stored info.
- {Ats,St3} = module_attrs(St2#expand{exports = Exports}),
+ {Ats,St3} = module_attrs(St1#expand{exports = Exports}),
{Mfs,St4} = module_predef_funcs(St3),
- {St4#expand.module, St4#expand.exports, Ats ++ Efs ++ Mfs,
+ {St4#expand.module, St4#expand.exports, Ats ++ Tfs ++ Mfs,
St4#expand.compile}.
compiler_options(Forms) ->
lists:flatten([C || {attribute,_,compile,C} <- Forms]).
-expand_pmod(Fs0, St0) ->
- case St0#expand.parameters of
- undefined ->
- {Fs0,St0};
- Ps0 ->
- Base = get_base(St0#expand.attributes),
- Ps = if is_atom(Base) ->
- ['BASE' | Ps0];
- true ->
- Ps0
- end,
- Def = gb_sets:to_list(St0#expand.defined),
- {Fs1,Xs,Ds} = sys_expand_pmod:forms(Fs0, Ps,
- St0#expand.exports,
- Def),
- St1 = St0#expand{exports=Xs,defined=gb_sets:from_list(Ds)},
- {Fs2,St2} = add_instance(Ps, Fs1, St1),
- {Fs3,St3} = ensure_new(Base, Ps0, Fs2, St2),
- {Fs3,St3#expand{attributes = [{abstract, 0, [true]}
- | St3#expand.attributes]}}
- end.
-
-get_base(As) ->
- case lists:keyfind(extends, 1, As) of
- {extends,_,[Base]} when is_atom(Base) ->
- Base;
- _ ->
- []
- end.
-
-ensure_new(Base, Ps, Fs, St) ->
- case has_new(Fs) of
- true ->
- {Fs, St};
- false ->
- add_new(Base, Ps, Fs, St)
- end.
-
-has_new([{function,_L,new,_A,_Cs} | _Fs]) ->
- true;
-has_new([_ | Fs]) ->
- has_new(Fs);
-has_new([]) ->
- false.
-
-add_new(Base, Ps, Fs, St) ->
- Vs = [{var,0,V} || V <- Ps],
- As = if is_atom(Base) ->
- [{call,0,{remote,0,{atom,0,Base},{atom,0,new}},Vs} | Vs];
- true ->
- Vs
- end,
- Body = [{call,0,{atom,0,instance},As}],
- add_func(new, Vs, Body, Fs, St).
-
-add_instance(Ps, Fs, St) ->
- Vs = [{var,0,V} || V <- Ps],
- AbsMod = [{tuple,0,[{atom,0,St#expand.module}|Vs]}],
- add_func(instance, Vs, AbsMod, Fs, St).
-
-add_func(Name, Args, Body, Fs, St) ->
- A = length(Args),
- F = {function,0,Name,A,[{clause,0,Args,[],Body}]},
- NA = {Name,A},
- {[F|Fs],St#expand{exports=add_element(NA, St#expand.exports),
- defined=gb_sets:add_element(NA, St#expand.defined)}}.
-
%% define_function(Form, State) -> State.
%% Add function to defined if form is a function.
@@ -235,10 +166,6 @@ forms([], St) -> {[],St}.
%% attribute(Attribute, Value, Line, State) -> State'.
%% Process an attribute, this just affects the state.
-attribute(module, {Module, As}, _L, St) ->
- true = is_atom(Module),
- St#expand{module=Module,
- parameters=As};
attribute(module, Module, _L, St) ->
true = is_atom(Module),
St#expand{module=Module};
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index 3b065ec3b9..b9c5be09ce 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -29,7 +29,6 @@ MODULES= \
match_SUITE \
misc_SUITE \
num_bif_SUITE \
- pmod_SUITE \
receive_SUITE \
record_SUITE \
trycatch_SUITE \
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index d63d2235d7..e8a92c509e 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -33,7 +33,8 @@
matching_meets_construction/1,simon/1,matching_and_andalso/1,
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]).
+ cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1,
+ no_partition/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -57,7 +58,8 @@ groups() ->
matching_meets_construction,simon,
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]}].
+ cover_beam_bool,matched_out_size,follow_fail_branch,
+ no_partition]}].
init_per_suite(Config) ->
@@ -1133,6 +1135,48 @@ ffb_2(<<_,T/bitstring>>, List, A) ->
[_|_] -> bit_size(T)
end.
+no_partition(_) ->
+ one = no_partition_1(<<"string">>, a1),
+ {two,<<"string">>} = no_partition_1(<<"string">>, a2),
+ {two,<<>>} = no_partition_1(<<>>, a2),
+ {two,a} = no_partition_1(a, a2),
+ three = no_partition_1(undefined, a3),
+ {four,a,[]} = no_partition_1([a], a4),
+ {five,a,b} = no_partition_1({a,b}, a5),
+
+ one = no_partition_2(<<"string">>, a1),
+ two = no_partition_2(<<"string">>, a2),
+ two = no_partition_2(<<>>, a2),
+ two = no_partition_2(a, a2),
+ three = no_partition_2(undefined, a3),
+ four = no_partition_2(42, a4),
+ five = no_partition_2([], a5),
+ six = no_partition_2(42.0, a6),
+ ok.
+
+no_partition_1(<<"string">>, a1) ->
+ one;
+no_partition_1(V, a2) ->
+ {two,V};
+no_partition_1(undefined, a3) ->
+ three;
+no_partition_1([H|T], a4) ->
+ {four,H,T};
+no_partition_1({A,B}, a5) ->
+ {five,A,B}.
+
+no_partition_2(<<"string">>, a1) ->
+ one;
+no_partition_2(_, a2) ->
+ two;
+no_partition_2(undefined, a3) ->
+ three;
+no_partition_2(42, a4) ->
+ four;
+no_partition_2([], a5) ->
+ five;
+no_partition_2(42.0, a6) ->
+ six.
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl
index e2eb6a0dec..6dc7548437 100644
--- a/lib/compiler/test/inline_SUITE.erl
+++ b/lib/compiler/test/inline_SUITE.erl
@@ -258,6 +258,49 @@ lists(Config) when is_list(Config) ->
%% Cleanup.
erase(?MODULE),
+
+ {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} =
+ (catch lists:map(fun (X) -> X end, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} =
+ (catch lists:flatmap(fun (X) -> X end, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} =
+ (catch lists:foreach(fun (X) -> X end, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} =
+ (catch lists:filter(fun (_) -> true end, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} =
+ (catch lists:any(fun (_) -> false end, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} =
+ (catch lists:all(fun (_) -> true end, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} =
+ (catch lists:foldl(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} =
+ (catch lists:foldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} =
+ (catch lists:mapfoldl(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)),
+ {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} =
+ (catch lists:mapfoldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)),
+
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} =
+ (catch lists:map(not_a_function, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} =
+ (catch lists:flatmap(not_a_function, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} =
+ (catch lists:foreach(not_a_function, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} =
+ (catch lists:filter(not_a_function, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} =
+ (catch lists:any(not_a_function, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} =
+ (catch lists:all(not_a_function, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} =
+ (catch lists:foldl(not_a_function, acc, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} =
+ (catch lists:foldr(not_a_function, acc, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} =
+ (catch lists:mapfoldl(not_a_function, acc, [])),
+ {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} =
+ (catch lists:mapfoldr(not_a_function, acc, [])),
+
ok.
my_apply(M, F, A, Init) ->
diff --git a/lib/compiler/test/pmod_SUITE.erl b/lib/compiler/test/pmod_SUITE.erl
deleted file mode 100644
index 5dd09a7245..0000000000
--- a/lib/compiler/test/pmod_SUITE.erl
+++ /dev/null
@@ -1,121 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-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%
-%%
--module(pmod_SUITE).
-
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- init_per_testcase/2,end_per_testcase/2,
- basic/1, otp_8447/1]).
-
--include_lib("test_server/include/test_server.hrl").
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- test_lib:recompile(?MODULE),
- [basic, otp_8447].
-
-groups() ->
- [].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
- Dog = test_server:timetrap(?t:minutes(1)),
- [{watchdog,Dog}|Config].
-
-end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
- Dog = ?config(watchdog, Config),
- ?t:timetrap_cancel(Dog),
- ok.
-
-basic(Config) when is_list(Config) ->
- ?line basic_1(Config, []),
- ?line basic_1(Config, [inline]),
- ?line basic_1(Config, [{inline,500},inline]),
- ok.
-
-basic_1(Config, Opts) ->
- io:format("Options: ~p\n", [Opts]),
- ?line ok = compile_load(pmod_basic, Config, Opts),
-
- ?line Prop1 = pmod_basic:new([{a,xb},{b,true},{c,false}]),
- ?line Prop2 = pmod_basic:new([{y,zz}]),
- ?line io:format("Prop1 = ~p\n", [Prop1]),
- ?line io:format("Prop2 = ~p\n", [Prop2]),
-
- ?line {a,xb} = Prop1:lookup(a),
- ?line none = Prop1:lookup(glurf),
- ?line false = Prop1:or_props([]),
- ?line true = Prop1:or_props([b,c]),
- ?line true = Prop1:or_props([b,d]),
- ?line false = Prop1:or_props([d]),
-
- ?line none = Prop2:lookup(kalle),
- ?line {y,zz} = Prop2:lookup(y),
- ?line {a,xb} = Prop1:lookup(a),
-
- ?line Prop3 = Prop1:prepend({blurf,true}),
- ?line io:format("Prop3 = ~p\n", [Prop3]),
- ?line {blurf,true} = Prop3:lookup(blurf),
-
- Prop4 = Prop3:append(42),
- ?line io:format("Prop4 = ~p\n", [Prop4]),
- ?line {42,5} = Prop4:stupid_sum(),
-
- %% Some record guards.
- ?line ok = Prop4:bar({s,0}),
- ?line ok = Prop4:bar_bar({s,blurf}),
- ?line error = Prop4:bar_bar({s,a,b}),
- ?line error = Prop4:bar_bar([]),
-
- %% Call from a fun.
- Fun = fun(Arg) -> Prop4:bar(Arg) end,
- ?line ok = Fun({s,0}),
-
- [{y,[1,2]},{x,[5,19]}] = Prop4:collapse([{y,[2,1]},{x,[19,5]}]),
- ok.
-
-otp_8447(Config) when is_list(Config) ->
- ?line P = pmod_basic:new(foo),
- ?line [0,0,1,1,1,0,0,1] = P:bc1(),
- ?line <<10:4>> = P:bc2(),
- ok.
-
-compile_load(Module, Conf, Opts) ->
- ?line Dir = ?config(data_dir,Conf),
- ?line Src = filename:join(Dir, atom_to_list(Module)),
- ?line Out = ?config(priv_dir,Conf),
- ?line CompRc = compile:file(Src, [report,{outdir,Out}|Opts]),
- ?line {ok,Module} = CompRc,
- ?line code:purge(Module),
- ?line {module,Module} =
- code:load_abs(filename:join(Out, atom_to_list(Module))),
- ok.
diff --git a/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl b/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl
deleted file mode 100644
index 19cce452dc..0000000000
--- a/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl
+++ /dev/null
@@ -1,83 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-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%
-%%
--module(pmod_basic, [Props]).
-
--export([lookup/1,or_props/1,prepend/1,append/1,stupid_sum/0]).
--export([bar/1,bar_bar/1]).
--export([bc1/0, bc2/0]).
--export([collapse/1]).
-
-lookup(Key) ->
- proplists:lookup(Key, Props).
-
-or_props(Keys) ->
- Res = or_props_1(Keys, false),
- true = is_bool(Res), %is_bool/1 does not use Props.
- Res.
-
-prepend(Term) ->
- new([Term|Props]).
-
-append(Term) ->
- pmod_basic:new(Props++[Term]).
-
-or_props_1([K|Ks], Acc) ->
- or_props_1(Ks, proplists:get_bool(K, Props) or Acc);
-or_props_1([], Acc) -> Acc.
-
-is_bool(true) -> true;
-is_bool(false) -> true;
-is_bool(_) -> false.
-
-stupid_sum() ->
- put(counter, 0),
- Res = stupid_sum_1(Props, 0),
- {Res,get(counter)}.
-
-stupid_sum_1([H|T], Sum0) ->
- try add(Sum0, H) of
- Sum -> stupid_sum_1(T, Sum)
- catch
- error:_ -> stupid_sum_1(T, Sum0)
- after
- bump()
- end;
-stupid_sum_1([], Sum) -> Sum.
-
-bump() ->
- put(counter, get(counter)+1).
-
-add(A, B) ->
- A+B.
-
--record(s, {a}).
-
-bar(S) when S#s.a == 0 -> ok.
-
-bar_bar(S) when is_record(S, s) -> ok;
-bar_bar(_) -> error.
-
-bc1() ->
- [A || <<A:1>> <= <<"9">> ].
-
-bc2() ->
- << <<A:1>> || A <- [1,0,1,0] >>.
-
-collapse(L) ->
- lists:keymap(fun lists:sort/1, 2, L).
diff --git a/lib/cosEvent/src/Makefile b/lib/cosEvent/src/Makefile
index 7787fad786..2864ee0538 100644
--- a/lib/cosEvent/src/Makefile
+++ b/lib/cosEvent/src/Makefile
@@ -168,9 +168,9 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
$(APPUP_TARGET): $(APPUP_SRC)
- sed -e 's;%VSN%;$(VSN);' $(APPUP_SRC) > $(APPUP_TARGET)
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $(APPUP_SRC) > $(APPUP_TARGET)
docs:
@@ -179,12 +179,12 @@ docs:
# ----------------------------------------------------
IDL-GENERATED: CosEventChannelAdmin.idl cosEventApp.idl CosEventComm.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosEventChannelAdmin.cfg"}' CosEventChannelAdmin.idl
- mv $(GEN_HRL_FILES1) $(EXTERNAL_INC_PATH)
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"cosEventApp.cfg"}' cosEventApp.idl
- erlc $(ERL_IDL_FLAGS) CosEventComm.idl
- mv $(GEN_HRL_FILES3) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosEventChannelAdmin.cfg"}' CosEventChannelAdmin.idl
+ $(V_at)mv $(GEN_HRL_FILES1) $(EXTERNAL_INC_PATH)
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"cosEventApp.cfg"}' cosEventApp.idl
+ $(V_at)erlc $(ERL_IDL_FLAGS) CosEventComm.idl
+ $(V_at)mv $(GEN_HRL_FILES3) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/cosEventDomain/src/Makefile b/lib/cosEventDomain/src/Makefile
index 213d433c72..b4b74bd192 100644
--- a/lib/cosEventDomain/src/Makefile
+++ b/lib/cosEventDomain/src/Makefile
@@ -141,9 +141,9 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
$(APPUP_TARGET): $(APPUP_SRC)
- sed -e 's;%VSN%;$(VSN);' $(APPUP_SRC) > $(APPUP_TARGET)
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $(APPUP_SRC) > $(APPUP_TARGET)
docs:
@@ -151,9 +151,9 @@ docs:
# Special Build Targets
# ----------------------------------------------------
IDL-GENERATED: CosEventDomainAdmin.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosEventDomainAdmin.cfg"}' CosEventDomainAdmin.idl
- mv $(GEN_HRL_FILES) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosEventDomainAdmin.cfg"}' CosEventDomainAdmin.idl
+ $(V_at)mv $(GEN_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/cosFileTransfer/src/Makefile b/lib/cosFileTransfer/src/Makefile
index d552349ede..9d3abb9bba 100644
--- a/lib/cosFileTransfer/src/Makefile
+++ b/lib/cosFileTransfer/src/Makefile
@@ -151,10 +151,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
@@ -162,9 +162,9 @@ docs:
# Special Build Targets
# ----------------------------------------------------
IDL-GENERATED: CosFileTransfer.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosFileTransfer.cfg"}' CosFileTransfer.idl
- mv $(LOCAL_HRL_FILES) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosFileTransfer.cfg"}' CosFileTransfer.idl
+ $(V_at)mv $(LOCAL_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/cosNotification/src/Makefile b/lib/cosNotification/src/Makefile
index decf598bbf..13153bd7a1 100644
--- a/lib/cosNotification/src/Makefile
+++ b/lib/cosNotification/src/Makefile
@@ -332,10 +332,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
@@ -344,16 +344,16 @@ docs:
# ----------------------------------------------------
IDL-GENERATED: CosNotification.idl CosNotifyChannelAdmin.idl \
CosNotifyFilter.idl cosNotificationAppComm.idl CosNotifyComm.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotification.cfg"}' CosNotification.idl
- mv $(GEN_NOTIFICATION_HRL_FILES) $(EXTERNAL_INC_PATH)
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyChannelAdmin.cfg"}' CosNotifyChannelAdmin.idl
- mv $(GEN_CHANNELADMIN_HRL_FILES) $(EXTERNAL_INC_PATH)
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyFilter.cfg"}' CosNotifyFilter.idl
- mv $(GEN_NOTIFYFILTER_HRL_FILES) $(EXTERNAL_INC_PATH)
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"cosNotificationComm.cfg"}' cosNotificationAppComm.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyComm.cfg"}' CosNotifyComm.idl
- mv $(GEN_NOTIFYCOMM_HRL_FILES) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotification.cfg"}' CosNotification.idl
+ $(V_at)mv $(GEN_NOTIFICATION_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyChannelAdmin.cfg"}' CosNotifyChannelAdmin.idl
+ $(V_at)mv $(GEN_CHANNELADMIN_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyFilter.cfg"}' CosNotifyFilter.idl
+ $(V_at)mv $(GEN_NOTIFYFILTER_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"cosNotificationComm.cfg"}' cosNotificationAppComm.idl
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyComm.cfg"}' CosNotifyComm.idl
+ $(V_at)mv $(GEN_NOTIFYCOMM_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(IDL_GEN_ERL_FILES) $(IDL_GEN_HRL_FILES): IDL-GENERATED
diff --git a/lib/cosProperty/src/Makefile b/lib/cosProperty/src/Makefile
index 54d1b6021c..d7b75d8bc5 100644
--- a/lib/cosProperty/src/Makefile
+++ b/lib/cosProperty/src/Makefile
@@ -151,10 +151,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
@@ -162,9 +162,9 @@ docs:
# Special Build Targets
# ----------------------------------------------------
IDL-GENERATED: CosProperty.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosProperty.cfg"}' CosProperty.idl
- mv $(LOCAL_HRL_FILES) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosProperty.cfg"}' CosProperty.idl
+ $(V_at)mv $(LOCAL_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/cosTime/src/Makefile b/lib/cosTime/src/Makefile
index e8536a3f0a..0ab2b414ce 100644
--- a/lib/cosTime/src/Makefile
+++ b/lib/cosTime/src/Makefile
@@ -166,10 +166,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
@@ -177,13 +177,13 @@ docs:
# Special Build Targets
# ----------------------------------------------------
IDL-GENERATED: TimeBase.idl CosTime.idl CosTimerEvent.idl
- erlc $(ERL_IDL_FLAGS) TimeBase.idl
- mv $(GEN_TIMEBASE_HRL_FILES) $(EXTERNAL_INC_PATH)
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTime.cfg"}' CosTime.idl
- mv $(GEN_COSTIME_HRL_FILES) $(EXTERNAL_INC_PATH)
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTimerEvent.cfg"}' CosTimerEvent.idl
- mv $(GEN_COSTIMEREVENT_HRL_FILES) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) TimeBase.idl
+ $(V_at)mv $(GEN_TIMEBASE_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTime.cfg"}' CosTime.idl
+ $(V_at)mv $(GEN_COSTIME_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTimerEvent.cfg"}' CosTimerEvent.idl
+ $(V_at)mv $(GEN_COSTIMEREVENT_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/cosTransactions/src/Makefile b/lib/cosTransactions/src/Makefile
index 1d935c4d1d..7b4a9cf858 100644
--- a/lib/cosTransactions/src/Makefile
+++ b/lib/cosTransactions/src/Makefile
@@ -145,10 +145,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
@@ -156,9 +156,9 @@ docs:
# Special Build Targets
# ----------------------------------------------------
IDL-GENERATED: CosTransactions.idl
- erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTransactions.cfg"}' CosTransactions.idl
- mv $(GEN_HRL_FILES) $(EXTERNAL_INC_PATH)
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTransactions.cfg"}' CosTransactions.idl
+ $(V_at)mv $(GEN_HRL_FILES) $(EXTERNAL_INC_PATH)
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in
index e19d6617f3..a20ddff05c 100644
--- a/lib/crypto/c_src/Makefile.in
+++ b/lib/crypto/c_src/Makefile.in
@@ -108,16 +108,16 @@ _create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR))
debug opt valgrind: $(NIF_LIB) $(CALLBACK_LIB)
$(OBJDIR)/%$(TYPEMARKER).o: %.c
- $(INSTALL_DIR) $(OBJDIR)
- $(CC) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_at)$(INSTALL_DIR) $(OBJDIR)
+ $(V_CC) -c -o $@ $(ALL_CFLAGS) $<
$(LIBDIR)/crypto$(TYPEMARKER).so: $(CRYPTO_OBJS)
- $(INSTALL_DIR) $(LIBDIR)
- $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB)
+ $(V_at)$(INSTALL_DIR) $(LIBDIR)
+ $(V_LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB)
$(LIBDIR)/crypto$(TYPEMARKER).dll: $(CRYPTO_OBJS)
- $(INSTALL_DIR) $(LIBDIR)
- $(LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(CRYPTO_OBJS) -l$(SSL_CRYPTO_LIBNAME) -l$(SSL_SSL_LIBNAME)
+ $(V_at)$(INSTALL_DIR) $(LIBDIR)
+ $(V_LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(CRYPTO_OBJS) -l$(SSL_CRYPTO_LIBNAME) -l$(SSL_SSL_LIBNAME)
ifeq ($(DYNAMIC_CRYPTO_LIB),yes)
$(LIBDIR)/crypto_callback$(TYPEMARKER).so: $(CALLBACK_OBJS)
diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile
index 910e89363c..5e09a09aa6 100644
--- a/lib/crypto/src/Makefile
+++ b/lib/crypto/src/Makefile
@@ -57,7 +57,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -DCRYPTO_VSN=\"$(VSN)\"
+ERL_COMPILE_FLAGS += +warn_obsolete_guard -DCRYPTO_VSN=\"$(VSN)\" -Werror
# ----------------------------------------------------
# Targets
@@ -70,10 +70,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/debugger/src/Makefile b/lib/debugger/src/Makefile
index e8b350c0c7..0b4b35412a 100644
--- a/lib/debugger/src/Makefile
+++ b/lib/debugger/src/Makefile
@@ -98,7 +98,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard
+ERL_COMPILE_FLAGS += +warn_obsolete_guard -Werror
# ----------------------------------------------------
@@ -112,10 +112,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index 3c084c53ac..f5744a6e14 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -345,15 +345,15 @@ trace(What, Args, true) ->
{Called, {Le,Li,M,F,As}} = Args,
case Called of
extern ->
- io_lib:format("++ (~w) <~w> ~w:~w~s~n",
+ io_lib:format("++ (~w) <~w> ~w:~w~ts~n",
[Le,Li,M,F,format_args(As)]);
local ->
- io_lib:format("++ (~w) <~w> ~w~s~n",
+ io_lib:format("++ (~w) <~w> ~w~ts~n",
[Le,Li,F,format_args(As)])
end;
call_fun ->
{Le,Li,F,As} = Args,
- io_lib:format("++ (~w) <~w> ~w~s~n",
+ io_lib:format("++ (~w) <~w> ~w~ts~n",
[Le, Li, F, format_args(As)]);
return ->
{Le,Val} = Args,
@@ -362,7 +362,7 @@ trace(What, Args, true) ->
bif ->
{Le,Li,M,F,As} = Args,
- io_lib:format("++ (~w) <~w> ~w:~w~s~n",
+ io_lib:format("++ (~w) <~w> ~w:~w~ts~n",
[Le, Li, M, F, format_args(As)])
end,
dbg_icmd:tell_attached({trace_output, Str});
diff --git a/lib/debugger/src/dbg_ui_trace.erl b/lib/debugger/src/dbg_ui_trace.erl
index 8017069c50..3e1fb2dcae 100644
--- a/lib/debugger/src/dbg_ui_trace.erl
+++ b/lib/debugger/src/dbg_ui_trace.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -321,7 +321,7 @@ gui_cmd('Messages', State) ->
fun(Msg, N) ->
Str1 = io_lib:format(" ~w:", [N]),
dbg_ui_trace_win:eval_output(Str1, bold),
- Str2 = io_lib:format(" ~s~n",[io_lib:print(Msg)]),
+ Str2 = io_lib:format(" ~ts~n",[io_lib:print(Msg)]),
dbg_ui_trace_win:eval_output(Str2, normal),
N+1
end,
diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl
index 0a3cac905f..bd92cb4b42 100644
--- a/lib/debugger/src/dbg_wx_trace.erl
+++ b/lib/debugger/src/dbg_wx_trace.erl
@@ -331,7 +331,7 @@ gui_cmd('Messages', State) ->
fun(Msg, N) ->
Str1 = io_lib:format(" ~w:", [N]),
dbg_wx_trace_win:eval_output(State#state.win,Str1, bold),
- Str2 = io_lib:format(" ~s~n",[io_lib:print(Msg)]),
+ Str2 = io_lib:format(" ~ts~n",[io_lib:print(Msg)]),
dbg_wx_trace_win:eval_output(State#state.win,Str2, normal),
N+1
end,
diff --git a/lib/debugger/src/i.erl b/lib/debugger/src/i.erl
index 4d0b862196..5805501524 100644
--- a/lib/debugger/src/i.erl
+++ b/lib/debugger/src/i.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -197,7 +197,7 @@ get_file(Mod) ->
end.
ilformat(A1, A2) ->
- format("~-20s ~s\n", [A1,A2]).
+ format("~-20s ~ts\n", [A1,A2]).
%% -------------------------------------------
%% Print all break points in modules.
diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl
index 1c9f2eddd1..bdd671cff1 100644
--- a/lib/debugger/src/int.erl
+++ b/lib/debugger/src/int.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -517,7 +517,7 @@ int_mod(AbsMod, Dist) when is_atom(AbsMod); is_list(AbsMod) ->
[App, AbsMod]),
error;
_Error ->
- io:format("** Invalid beam file or no abstract code: ~p\n",
+ io:format("** Invalid beam file or no abstract code: ~tp\n",
[AbsMod]),
error
end.
@@ -674,38 +674,50 @@ everywhere(local, Fun) ->
Fun().
scan_module_name(File) ->
- case erl_prim_loader:get_file(filename:absname(File)) of
- {ok, Bin, _FullPath} ->
- Chars = binary_to_list(Bin),
- R = (catch {ok, scan_module_name_1(Chars)}),
- case R of
- {ok, A} when is_atom(A) -> A;
- _ -> error
- end;
- _ ->
- error
+ try
+ {ok, Bin, _FullPath} =
+ erl_prim_loader:get_file(filename:absname(File)),
+ scan_module_name_1([], <<>>, Bin, enc(Bin))
+ catch
+ _:_ ->
+ throw({error, no_beam})
end.
-scan_module_name_1(Chars) ->
- case erl_scan:tokens("", Chars, 1) of
- {done, {ok, Ts, _}, Rest} ->
- scan_module_name_2(Ts, Rest);
- _ ->
- error
+scan_module_name_1(Cont0, B0, Bin0, Enc) ->
+ N = min(100, byte_size(Bin0)),
+ {Bin1, Bin} = erlang:split_binary(Bin0, N),
+ {Chars, B1} =
+ case unicode:characters_to_list(list_to_binary([B0, Bin1]), Enc) of
+ {incomplete, List, Binary} ->
+ {List, Binary};
+ List when is_list(List), List =/= [] ->
+ {List, <<>>}
+ end,
+ scan_module_name_2(Cont0, Chars, B1, Bin, Enc).
+
+scan_module_name_2(Cont0, Chars, B1, Bin, Enc) ->
+ case erl_scan:tokens(Cont0, Chars, _AnyLine = 1) of
+ {done, {ok, Ts, _}, Rest} ->
+ scan_module_name_3(Ts, Rest, B1, Bin, Enc);
+ {more, Cont} ->
+ scan_module_name_1(Cont, B1, Bin, Enc)
end.
-scan_module_name_2([{'-',_},{atom,_,module},{'(',_} | _]=Ts, _Chars) ->
- scan_module_name_3(Ts);
-scan_module_name_2([{'-',_},{atom,_,_} | _], Chars) ->
- scan_module_name_1(Chars);
-scan_module_name_2(_, _) ->
- error.
-
-scan_module_name_3(Ts) ->
- case erl_parse:parse_form(Ts) of
- {ok, {attribute,_,module,{M,_}}} -> M;
- {ok, {attribute,_,module,M}} -> M;
- _ -> error
+scan_module_name_3([{'-',_},{atom,_,module},{'(',_} | _]=Ts,
+ _Chars, _B1, _Bin, _Enc) ->
+ scan_module_name_4(Ts);
+scan_module_name_3([{'-',_},{atom,_,_} | _], Chars, B1, Bin, Enc) ->
+ scan_module_name_2("", Chars, B1, Bin, Enc).
+
+scan_module_name_4(Ts) ->
+ {ok, {attribute,_,module,M}} = erl_parse:parse_form(Ts),
+ true = is_atom(M),
+ M.
+
+enc(Bin) ->
+ case epp:read_encoding_from_binary(Bin) of
+ none -> epp:default_encoding();
+ Encoding -> Encoding
end.
%%--Stop interpreting modules-----------------------------------------
diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile
index 63cc1c98f1..bb2edd419a 100644
--- a/lib/dialyzer/src/Makefile
+++ b/lib/dialyzer/src/Makefile
@@ -108,22 +108,22 @@ clean:
# ----------------------------------------------------
$(EBIN)/dialyzer_cl_parse.$(EMULATOR): dialyzer_cl_parse.erl ../vsn.mk
- erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_cl_parse.erl
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_cl_parse.erl
$(EBIN)/dialyzer_plt.$(EMULATOR): dialyzer_plt.erl ../vsn.mk
- erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_plt.erl
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_plt.erl
$(EBIN)/dialyzer_gui.$(EMULATOR): dialyzer_gui.erl ../vsn.mk
- erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_gui.erl
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_gui.erl
$(EBIN)/dialyzer_gui_wx.$(EMULATOR): dialyzer_gui_wx.erl ../vsn.mk
- erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_gui_wx.erl
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_gui_wx.erl
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ---------------------------------------------------------------------
# dependencies -- I wish they were somehow automatically generated
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 0b932d5a1f..157c951f77 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -254,14 +254,35 @@ check_extraneous([C|Cs], SuccType) ->
end.
check_extraneous_1(Contract, SuccType) ->
- CRngs = erl_types:t_elements(erl_types:t_fun_range(Contract)),
+ CRng = erl_types:t_fun_range(Contract),
+ CRngs = erl_types:t_elements(CRng),
STRng = erl_types:t_fun_range(SuccType),
?debug("CR = ~p\nSR = ~p\n", [CRngs, STRng]),
- case [CR || CR <- CRngs, erl_types:t_is_none(erl_types:t_inf(CR, STRng, opaque))] of
- [] -> ok;
+ case [CR || CR <- CRngs,
+ erl_types:t_is_none(erl_types:t_inf(CR, STRng, opaque))] of
+ [] ->
+ CRngList = list_part(CRng),
+ STRngList = list_part(STRng),
+ case is_not_nil_list(CRngList) andalso is_not_nil_list(STRngList) of
+ false -> ok;
+ true ->
+ CRngElements = erl_types:t_list_elements(CRngList),
+ STRngElements = erl_types:t_list_elements(STRngList),
+ Inf = erl_types:t_inf(CRngElements, STRngElements, opaque),
+ case erl_types:t_is_none(Inf) of
+ true -> {error, invalid_contract};
+ false -> ok
+ end
+ end;
CRs -> {error, {extra_range, erl_types:t_sup(CRs), STRng}}
end.
+list_part(Type) ->
+ erl_types:t_inf(erl_types:t_list(), Type, opaque).
+
+is_not_nil_list(Type) ->
+ erl_types:t_is_list(Type) andalso not erl_types:t_is_nil(Type).
+
%% This is the heart of the "range function"
-spec process_contracts([contract_pair()], [erl_types:erl_type()]) -> erl_types:erl_type().
diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/inets b/lib/dialyzer/test/r9c_SUITE_data/results/inets
index d789d8d246..629378d673 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/results/inets
+++ b/lib/dialyzer/test/r9c_SUITE_data/results/inets
@@ -35,7 +35,7 @@ mod_auth_plain.erl:159: The variable _ can never match since previous clauses co
mod_auth_plain.erl:83: The variable O can never match since previous clauses completely covered the type [[any()]]
mod_cgi.erl:372: The pattern {'http_response', NewAccResponse} can never match the type 'ok'
mod_dir.erl:101: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom())) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
-mod_dir.erl:72: The pattern {'error', Reason} can never match the type {'ok',[[[any()] | non_neg_integer()],...]}
+mod_dir.erl:72: The pattern {'error', Reason} can never match the type {'ok',[[[any()] | char()],...]}
mod_get.erl:135: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]>
mod_head.erl:80: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]>
mod_htaccess.erl:460: The pattern {'error', BadData} can never match the type {'ok',_}
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
index b4f03fab03..17cc9a953d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
@@ -1806,7 +1806,6 @@ system_info2(dump_log_update_in_place) ->
system_info2(dump_log_update_in_place) ->
mnesia_monitor:get_env(dump_log_update_in_place);
system_info2(max_wait_for_decision) -> mnesia_monitor:get_env(max_wait_for_decision);
-system_info2(embedded_mnemosyne) -> mnesia_monitor:get_env(embedded_mnemosyne);
system_info2(ignore_fallback_at_startup) -> mnesia_monitor:get_env(ignore_fallback_at_startup);
system_info2(fallback_error_function) -> mnesia_monitor:get_env(fallback_error_function);
system_info2(log_version) -> mnesia_log:version();
@@ -1840,7 +1839,6 @@ system_info_items(yes) ->
dump_log_time_threshold,
dump_log_update_in_place,
dump_log_write_threshold,
- embedded_mnemosyne,
event_module,
extra_db_nodes,
fallback_activated,
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
index b64419d5a8..a1c25b5120 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
@@ -631,7 +631,6 @@ env() ->
dump_log_time_threshold,
dump_log_update_in_place,
dump_log_write_threshold,
- embedded_mnemosyne,
event_module,
extra_db_nodes,
ignore_fallback_at_startup,
@@ -660,8 +659,6 @@ default_env(dump_log_update_in_place) ->
true;
default_env(dump_log_write_threshold) ->
1000;
-default_env(embedded_mnemosyne) ->
- false;
default_env(event_module) ->
mnesia_event;
default_env(extra_db_nodes) ->
@@ -703,7 +700,6 @@ do_check_type(event_module, A) when atom(A) -> A;
do_check_type(ignore_fallback_at_startup, B) -> bool(B);
do_check_type(fallback_error_function, {Mod, Func})
when atom(Mod), atom(Func) -> {Mod, Func};
-do_check_type(embedded_mnemosyne, B) -> bool(B);
do_check_type(extra_db_nodes, L) when list(L) ->
Fun = fun(N) when N == node() -> false;
(A) when atom(A) -> true
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl
index 78609ffdde..970e0e5f47 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_sup.erl
@@ -57,9 +57,8 @@ init() ->
Event = event_procs(),
Kernel = kernel_procs(),
- Mnemosyne = mnemosyne_procs(),
- {ok, {Flags, Event ++ Kernel ++ Mnemosyne}}.
+ {ok, {Flags, Event ++ Kernel}}.
event_procs() ->
KillAfter = timer:seconds(30),
@@ -72,16 +71,6 @@ kernel_procs() ->
KA = infinity,
[{K, {K, start, []}, permanent, KA, supervisor, [K, supervisor]}].
-mnemosyne_procs() ->
- case mnesia_monitor:get_env(embedded_mnemosyne) of
- true ->
- Q = mnemosyne_sup,
- KA = infinity,
- [{Q, {Q, start, []}, permanent, KA, supervisor, [Q, supervisor]}];
- false ->
- []
- end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% event handler
@@ -107,11 +96,8 @@ add_event_handler() ->
kill() ->
Mnesia = [mnesia_fallback | mnesia:ms()],
- Mnemosyne = mnemosyne_ms(),
Kill = fun(Name) -> catch exit(whereis(Name), kill) end,
- lists:foreach(Kill, Mnemosyne),
lists:foreach(Kill, Mnesia),
- lists:foreach(fun ensure_dead/1, Mnemosyne),
lists:foreach(fun ensure_dead/1, Mnesia),
timer:sleep(10),
case lists:keymember(mnesia, 1, application:which_applications()) of
@@ -128,9 +114,3 @@ ensure_dead(Name) ->
timer:sleep(10),
ensure_dead(Name)
end.
-
-mnemosyne_ms() ->
- case mnesia_monitor:get_env(embedded_mnemosyne) of
- true -> mnemosyne:ms();
- false -> []
- end.
diff --git a/lib/dialyzer/test/small_SUITE_data/results/cerl_hipeify b/lib/dialyzer/test/small_SUITE_data/results/cerl_hipeify
index 06dc0d63ee..91ed552eec 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/cerl_hipeify
+++ b/lib/dialyzer/test/small_SUITE_data/results/cerl_hipeify
@@ -1,4 +1,3 @@
-cerl_hipeify.erl:370: Function will never be called
cerl_hipeify.erl:370: Guard test fun((none()) -> no_return()) =:= F::{_,_,_} | {_,_,_,_} | {_,_,_,_,_} | {_,_,_,_,_,_} | {_,_,_,_,_,_,_} can never succeed
cerl_hipeify.erl:641: Function env__new_function_name/2 will never be called
diff --git a/lib/dialyzer/test/small_SUITE_data/results/comm_layer b/lib/dialyzer/test/small_SUITE_data/results/comm_layer
deleted file mode 100644
index cb4bf14eb4..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/results/comm_layer
+++ /dev/null
@@ -1,2 +0,0 @@
-
-comm_layer.erl:76: Invalid type specification for function 'comm_layer_dir.comm_layer':this/0. The success typing is () -> {_,integer(),pid()}
diff --git a/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum b/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum
new file mode 100644
index 0000000000..6eaf60b91d
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum
@@ -0,0 +1,2 @@
+
+empty_list_infimum.erl:38: Invalid type specification for function empty_list_infimum:list_vhost_permissions/1. The success typing is (_) -> [[{_,_}]] \ No newline at end of file
diff --git a/lib/dialyzer/test/small_SUITE_data/results/pubsub b/lib/dialyzer/test/small_SUITE_data/results/pubsub
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/results/pubsub
+++ /dev/null
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_acceptor.erl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_acceptor.erl
deleted file mode 100644
index 2ca1468911..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_acceptor.erl
+++ /dev/null
@@ -1,119 +0,0 @@
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_acceptor.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description : Acceptor
-%%% This module accepts new connections and starts corresponding
-%%% comm_connection processes.
-%%%
-%%% Created : 18 Apr 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id $
--module(comm_layer_dir.comm_acceptor).
-
--export([start_link/1, init/2]).
-
--import(config).
--import(gen_tcp).
--import(inet).
--import(log).
--import(lists).
--import(process_dictionary).
-
-start_link(InstanceId) ->
- Pid = spawn_link(comm_layer_dir.comm_acceptor, init, [InstanceId, self()]),
- receive
- {started} ->
- {ok, Pid}
- end.
-
-init(InstanceId, Supervisor) ->
- process_dictionary:register_process(InstanceId, acceptor, self()),
- erlang:register(comm_layer_acceptor, self()),
- log:log(info,"[ CC ] listening on ~p:~p", [config:listenIP(), config:listenPort()]),
- LS = case config:listenIP() of
- undefined ->
- open_listen_port(config:listenPort(), first_ip());
- _ ->
- open_listen_port(config:listenPort(), config:listenIP())
- end,
- {ok, {_LocalAddress, LocalPort}} = inet:sockname(LS),
- comm_port:set_local_address(undefined, LocalPort),
- %io:format("this() == ~w~n", [{LocalAddress, LocalPort}]),
- Supervisor ! {started},
- server(LS).
-
-server(LS) ->
- case gen_tcp:accept(LS) of
- {ok, S} ->
- case comm_port:get_local_address_port() of
- {undefined, LocalPort} ->
- {ok, {MyIP, _LocalPort}} = inet:sockname(S),
- comm_port:set_local_address(MyIP, LocalPort);
- _ ->
- ok
- end,
- receive
- {tcp, S, Msg} ->
- {endpoint, Address, Port} = binary_to_term(Msg),
- % auto determine remote address, when not sent correctly
- NewAddress = if Address =:= {0,0,0,0} orelse Address =:= {127,0,0,1} ->
- case inet:peername(S) of
- {ok, {PeerAddress, _Port}} ->
- % io:format("Sent Address ~p\n",[Address]),
- % io:format("Peername is ~p\n",[PeerAddress]),
- PeerAddress;
- {error, _Why} ->
- % io:format("Peername error ~p\n",[Why]).
- Address
- end;
- true ->
- % io:format("Address is ~p\n",[Address]),
- Address
- end,
- NewPid = comm_connection:new(NewAddress, Port, S),
- gen_tcp:controlling_process(S, NewPid),
- inet:setopts(S, [{active, once}, {send_timeout, config:read(tcp_send_timeout)}]),
- comm_port:register_connection(NewAddress, Port, NewPid, S)
- end,
- server(LS);
- Other ->
- log:log(warn,"[ CC ] unknown message ~p", [Other])
- end.
-
-open_listen_port({From, To}, IP) ->
- open_listen_port(lists:seq(From, To), IP);
-open_listen_port([Port | Rest], IP) ->
- case gen_tcp:listen(Port, [binary, {packet, 4}, {reuseaddr, true},
- {active, once}, {ip, IP}]) of
- {ok, Socket} ->
- Socket;
- {error, Reason} ->
- log:log(error,"[ CC ] can't listen on ~p: ~p~n", [Port, Reason]),
- open_listen_port(Rest, IP)
- end;
-open_listen_port([], _) ->
- abort;
-open_listen_port(Port, IP) ->
- open_listen_port([Port], IP).
-
--include_lib("kernel/include/inet.hrl").
-
-first_ip() ->
- {ok, Hostname} = inet:gethostname(),
- {ok, HostEntry} = inet:gethostbyname(Hostname),
- erlang:hd(HostEntry#hostent.h_addr_list).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_connection.erl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_connection.erl
deleted file mode 100644
index 5a8f9710d6..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_connection.erl
+++ /dev/null
@@ -1,207 +0,0 @@
-%% -*- coding: utf-8 -*-
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_connection.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description : creates and destroys connections and represents the
-%%% endpoint of a connection where messages are received and
-%% send from/to the network.
-%%%
-%%% Created : 18 Apr 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id $
--module(comm_layer_dir.comm_connection).
-
--export([send/3, open_new/4, new/3, open_new_async/4]).
-
--import(config).
--import(gen_tcp).
--import(inet).
--import(io).
--import(io_lib).
--import(log).
--import(timer).
-
--include("comm_layer.hrl").
-
-%% @doc new accepted connection. called by comm_acceptor
-%% @spec new(inet:ip_address(), int(), socket()) -> pid()
-new(Address, Port, Socket) ->
- spawn(fun () -> loop(Socket, Address, Port) end).
-
-%% @doc open new connection
-%% @spec open_new(inet:ip_address(), int(), inet:ip_address(), int()) ->
-%% {local_ip, inet:ip_address(), int(), pid(), inet:socket()}
-%% | fail
-%% | {connection, pid(), inet:socket()}
-open_new(Address, Port, undefined, MyPort) ->
- Myself = self(),
- LocalPid = spawn(fun () ->
- case new_connection(Address, Port, MyPort) of
- fail ->
- Myself ! {new_connection_failed};
- Socket ->
- {ok, {MyIP, _MyPort}} = inet:sockname(Socket),
- Myself ! {new_connection_started, MyIP, MyPort, Socket},
- loop(Socket, Address, Port)
- end
- end),
- receive
- {new_connection_failed} ->
- fail;
- {new_connection_started, MyIP, MyPort, S} ->
- {local_ip, MyIP, MyPort, LocalPid, S}
- end;
-open_new(Address, Port, _MyAddress, MyPort) ->
- Owner = self(),
- LocalPid = spawn(fun () ->
- case new_connection(Address, Port, MyPort) of
- fail ->
- Owner ! {new_connection_failed};
- Socket ->
- Owner ! {new_connection_started, Socket},
- loop(Socket, Address, Port)
- end
- end),
- receive
- {new_connection_failed} ->
- fail;
- {new_connection_started, Socket} ->
- {connection, LocalPid, Socket}
- end.
-
-% ===============================================================================
-% @doc open a new connection asynchronously
-% ===============================================================================
--spec(open_new_async/4 :: (any(), any(), any(), any()) -> pid()).
-open_new_async(Address, Port, _MyAddr, MyPort) ->
- Pid = spawn(fun () ->
- case new_connection(Address, Port, MyPort) of
- fail ->
- comm_port:unregister_connection(Address, Port),
- ok;
- Socket ->
- loop(Socket, Address, Port)
- end
- end),
- Pid.
-
-
-send({Address, Port, Socket}, Pid, Message) ->
- BinaryMessage = term_to_binary({deliver, Pid, Message}),
- SendTimeout = config:read(tcp_send_timeout),
- {Time, Result} = timer:tc(gen_tcp, send, [Socket, BinaryMessage]),
- if
- Time > 1200 * SendTimeout ->
- log:log(error,"[ CC ] send to ~p took ~p: ~p",
- [Address, Time, inet:getopts(Socket, [keep_alive, send_timeout])]);
- true ->
- ok
- end,
- case Result of
- ok ->
- ?LOG_MESSAGE(erlang:element(1, Message), byte_size(BinaryMessage)),
- ok;
- {error, closed} ->
- comm_port:unregister_connection(Address, Port),
- close_connection(Socket);
- {error, _Reason} ->
- %log:log(error,"[ CC ] couldn't send to ~p:~p (~p)", [Address, Port, Reason]),
- comm_port:unregister_connection(Address, Port),
- close_connection(Socket)
- end.
-
-loop(fail, Address, Port) ->
- comm_port:unregister_connection(Address, Port),
- ok;
-loop(Socket, Address, Port) ->
- receive
- {send, Pid, Message} ->
- case send({Address, Port, Socket}, Pid, Message) of
- ok -> loop(Socket, Address, Port);
- _ -> ok
- end;
- {tcp_closed, Socket} ->
- comm_port:unregister_connection(Address, Port),
- gen_tcp:close(Socket);
- {tcp, Socket, Data} ->
- case binary_to_term(Data) of
- {deliver, Process, Message} ->
- Process ! Message,
- inet:setopts(Socket, [{active, once}]),
- loop(Socket, Address, Port);
- {user_close} ->
- comm_port:unregister_connection(Address, Port),
- gen_tcp:close(Socket);
- {youare, _Address, _Port} ->
- %% @TODO what do we get from this information?
- inet:setopts(Socket, [{active, once}]),
- loop(Socket, Address, Port);
- Unknown ->
- log:log(warn,"[ CC ] unknown message ~p", [Unknown]),
- inet:setopts(Socket, [{active, once}]),
- loop(Socket, Address, Port)
- end;
-
- {youare, _IP, _Port} ->
- loop(Socket, Address, Port);
-
- Unknown ->
- log:log(warn,"[ CC ] unknown message2 ~p", [Unknown]) ,
- loop(Socket, Address, Port)
- end.
-
-% ===============================================================================
-
--spec(new_connection(inet:ip_address(), integer(), integer()) -> inet:socket() | fail).
-new_connection(Address, Port, MyPort) ->
- case gen_tcp:connect(Address, Port, [binary, {packet, 4}, {nodelay, true}, {active, once},
- {send_timeout, config:read(tcp_send_timeout)}],
- config:read(tcp_connect_timeout)) of
- {ok, Socket} ->
- % send end point data
- case inet:sockname(Socket) of
- {ok, {MyAddress, _MyPort}} ->
- Message = term_to_binary({endpoint, MyAddress, MyPort}),
- gen_tcp:send(Socket, Message),
- case inet:peername(Socket) of
- {ok, {RemoteIP, RemotePort}} ->
- YouAre = term_to_binary({youare, RemoteIP, RemotePort}),
- gen_tcp:send(Socket, YouAre),
- Socket;
- {error, _Reason} ->
- %log:log(error,"[ CC ] reconnect to ~p because socket is ~p",
- % [Address, Reason]),
- close_connection(Socket),
- new_connection(Address, Port, MyPort)
- end;
- {error, _Reason} ->
- %log:log(error,"[ CC ] reconnect to ~p because socket is ~p",
- % [Address, Reason]),
- close_connection(Socket),
- new_connection(Address, Port, MyPort)
- end;
- {error, _Reason} ->
- %log:log(error,"[ CC ] couldn't connect to ~p:~p (~p)",
- %[Address, Port, Reason]),
- fail
- end.
-
-close_connection(Socket) ->
- spawn( fun () ->
- gen_tcp:close(Socket)
- end ).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.erl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.erl
deleted file mode 100644
index b7fdd183e1..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.erl
+++ /dev/null
@@ -1,83 +0,0 @@
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_layer.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description : Public interface to Communication Layer.
-%%% Generic functions to send messages.
-%%% Distinguishes on runtime whether the destination is in the
-%%% same Erlang virtual machine (use ! for sending) or on a remote
-%%% site (use comm_port:send()).
-%%%
-%%% Created : 04 Feb 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id $
--module(comm_layer_dir.comm_layer).
-
--author('[email protected]').
--vsn('$Id: comm_layer.erl,v 1.1 2009/11/06 12:41:36 maria Exp $ ').
-
--export([start_link/0, send/2, this/0, here/1]).
-
--import(io).
--import(util).
--import(log).
-
--include("comm_layer.hrl").
-
-
-% @TODO: should be ip
--type(process_id() :: {any(), integer(), pid()}).
-%%====================================================================
-%% public functions
-%%====================================================================
-
-%% @doc starts the communication port (for supervisor)
-%% @spec start_link() -> {ok,Pid} | ignore | {error,Error}
-start_link() ->
- comm_port_sup:start_link().
-
-%% @doc a process descriptor has to specify the erlang vm
-%% + the process inside. {IP address, port, pid}
-%% @type process_id() = {inet:ip_address(), int(), pid()}.
-%% @spec send(process_id(), term()) -> ok
-
-send({{_IP1, _IP2, _IP3, _IP4} = _IP, _Port, _Pid} = Target, Message) ->
- {MyIP,MyPort} = comm_port:get_local_address_port(),
- %io:format("send: ~p:~p -> ~p:~p(~p) : ~p\n", [MyIP, MyPort, _IP, _Port, _Pid, Message]),
- IsLocal = (MyIP == _IP) and (MyPort == _Port),
- if
- IsLocal ->
- ?LOG_MESSAGE(erlang:element(1, Message), byte_size(term_to_binary(Message))),
- _Pid ! Message;
- true ->
- comm_port:send(Target, Message)
- end;
-
-send(Target, Message) ->
- log:log(error,"[ CC ] wrong call to cs_send:send: ~w ! ~w", [Target, Message]),
- log:log(error,"[ CC ] stacktrace: ~w", [util:get_stacktrace()]),
- ok.
-
-%% @doc returns process descriptor for the calling process
--spec(this/0 :: () -> atom()).%process_id()).
-this() ->
- here(self()).
-
--spec(here/1 :: (pid()) -> process_id()).
-here(Pid) ->
- {LocalIP, LocalPort} = comm_port:get_local_address_port(),
- {LocalIP, LocalPort, Pid}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.hrl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.hrl
deleted file mode 100644
index 54f31b7c55..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_layer.hrl
+++ /dev/null
@@ -1,29 +0,0 @@
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_layer.hrl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description :
-%%%
-%%% Created : 31 Jul 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id: comm_layer.hrl,v 1.1 2009/11/06 12:41:36 maria Exp $
--author('[email protected]').
--vsn('$Id: comm_layer.hrl,v 1.1 2009/11/06 12:41:36 maria Exp $ ').
-
-% enable logging of message statistics
-%-define(LOG_MESSAGE(TAG, SIZE), comm_layer.comm_logger:log(TAG, SIZE)).
--define(LOG_MESSAGE(TAG, SIZE), ok).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_logger.erl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_logger.erl
deleted file mode 100644
index b8882758af..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_logger.erl
+++ /dev/null
@@ -1,143 +0,0 @@
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_logger.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description :
-%%%
-%%% Created : 31 Jul 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id: comm_logger.erl,v 1.1 2009/11/06 12:41:36 maria Exp $
--module(comm_layer_dir.comm_logger).
-
--author('[email protected]').
--vsn('$Id: comm_logger.erl,v 1.1 2009/11/06 12:41:36 maria Exp $ ').
-
--behaviour(gen_server).
-
--import(gb_trees).
--import(gen_server).
-
-%% API
--export([start_link/0]).
-
--export([log/2, dump/0]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--record(state, {start, map}).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-%%--------------------------------------------------------------------
-%% Function: log(Tag, Size) -> ok
-%% Description: logs a message type with its size
-%%--------------------------------------------------------------------
-log(Tag, Size) ->
- gen_server:cast(?MODULE, {log, Tag, Size}).
-
-%%--------------------------------------------------------------------
-%% Function: dump() -> {gb_tree:gb_trees(), {Date, Time}}
-%% Description: gets the logging state
-%%--------------------------------------------------------------------
-dump() ->
- gen_server:call(?MODULE, {dump}).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([]) ->
- {ok, #state{start=erlang:now(), map=gb_trees:empty()}}.
-
-%%--------------------------------------------------------------------
-%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} |
-%% {stop, Reason, State}
-%% Description: Handling call messages
-%%--------------------------------------------------------------------
-handle_call({dump}, _From, State) ->
- Reply = {State#state.map, State#state.start},
- {reply, Reply, State};
-handle_call(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
-handle_cast({log, Tag, Size}, State) ->
- case gb_trees:lookup(Tag, State#state.map) of
- none ->
- {noreply, State#state{map=gb_trees:insert(Tag, {Size, 1}, State#state.map)}};
- {value, {OldSize, OldCount}} ->
- {noreply, State#state{map=gb_trees:update(Tag, {Size + OldSize, OldCount + 1}, State#state.map)}}
- end;
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_info(Info, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling all non call/cast messages
-%%--------------------------------------------------------------------
-handle_info(_Info, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description: This function is called by a gen_server when it is about to
-%% terminate. It should be the opposite of Module:init/1 and do any necessary
-%% cleaning up. When it returns, the gen_server terminates with Reason.
-%% The return value is ignored.
-%%--------------------------------------------------------------------
-terminate(_Reason, _State) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% Description: Convert process state when code is changed
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port.erl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port.erl
deleted file mode 100644
index d9fcb5e625..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port.erl
+++ /dev/null
@@ -1,241 +0,0 @@
-%% -*- coding: utf-8 -*-
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_port.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description : Main CommLayer Interface
-%%% Maps remote addresses to comm_connection PIDs.
-%%%
-%%% Created : 18 Apr 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id $
--module(comm_layer_dir.comm_port).
-
--author('[email protected]').
--vsn('$Id: comm_port.erl,v 1.1 2009/11/06 12:41:36 maria Exp $ ').
-
--behaviour(gen_server).
-
--import(ets).
--import(gen_server).
--import(io).
--import(log).
-
--define(ASYNC, true).
-%-define(SYNC, true).
-
-%% API
--export([start_link/0,
- send/2,
- unregister_connection/2, register_connection/4,
- set_local_address/2, get_local_address_port/0]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
-%%====================================================================
-%% API
-%%====================================================================
-
-%% @doc
-%% @spec send({inet:ip_address(), int(), pid()}, term()) -> ok
--ifdef(ASYNC).
-send({Address, Port, Pid}, Message) ->
- gen_server:call(?MODULE, {send, Address, Port, Pid, Message}, 20000).
--endif.
--ifdef(SYNC).
-send({Address, Port, Pid}, Message) ->
- case ets:lookup(?MODULE, {Address, Port}) of
- [{{Address, Port}, {_LPid, Socket}}] ->
- comm_connection:send({Address, Port, Socket}, Pid, Message),
- ok;
- [] ->
- gen_server:call(?MODULE, {send, Address, Port, Pid, Message}, 20000)
- end.
--endif.
-
-
-%% @doc
-%% @spec unregister_connection(inet:ip_address(), int()) -> ok
-unregister_connection(Adress, Port) ->
- gen_server:call(?MODULE, {unregister_conn, Adress, Port}, 20000).
-
-%% @doc
-%% @spec register_connection(inet:ip_address(), int(), pid(), gen_tcp:socket()) -> ok | duplicate
-register_connection(Adress, Port, Pid, Socket) ->
- gen_server:call(?MODULE, {register_conn, Adress, Port, Pid, Socket}, 20000).
-
-%% @doc
-%% @spec set_local_address(inet:ip_address(), int()) -> ok
-set_local_address(Address, Port) ->
- gen_server:call(?MODULE, {set_local_address, Address, Port}, 20000).
-
-
-%% @doc
-%% @spec get_local_address_port() -> {inet:ip_address(),int()}
-get_local_address_port() ->
- case ets:lookup(?MODULE, local_address_port) of
- [{local_address_port, Value}] ->
- Value;
- [] ->
- undefined
- end.
-
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([]) ->
- ets:new(?MODULE, [set, protected, named_table]),
- {ok, ok}. % empty state.
-
-%%--------------------------------------------------------------------
-%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} |
-%% {stop, Reason, State}
-%% Description: Handling call messages
-%%--------------------------------------------------------------------
-handle_call({send, Address, Port, Pid, Message}, _From, State) ->
- send(Address, Port, Pid, Message, State);
-
-handle_call({unregister_conn, Address, Port}, _From, State) ->
- ets:delete(?MODULE, {Address, Port}),
- {reply, ok, State};
-
-handle_call({register_conn, Address, Port, Pid, Socket}, _From, State) ->
- case ets:lookup(?MODULE, {Address, Port}) of
- [{{Address, Port}, _}] ->
- {reply, duplicate, State};
- [] ->
- ets:insert(?MODULE, {{Address, Port}, {Pid, Socket}}),
- {reply, ok, State}
- end;
-
-handle_call({set_local_address, Address, Port}, _From, State) ->
- ets:insert(?MODULE, {local_address_port, {Address,Port}}),
- {reply, ok, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_info(Info, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling all non call/cast messages
-%%--------------------------------------------------------------------
-handle_info(_Info, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description: This function is called by a gen_server when it is about to
-%% terminate. It should be the opposite of Module:init/1 and do any necessary
-%% cleaning up. When it returns, the gen_server terminates with Reason.
-%% The return value is ignored.
-%%--------------------------------------------------------------------
-terminate(_Reason, _State) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% Description: Convert process state when code is changed
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-
--ifdef(ASYNC).
-send(Address, Port, Pid, Message, State) ->
- {DepAddr,DepPort} = get_local_address_port(),
- if
- DepAddr == undefined ->
- open_sync_connection(Address, Port, Pid, Message, State);
- true ->
- case ets:lookup(?MODULE, {Address, Port}) of
- [{{Address, Port}, {ConnPid, _Socket}}] ->
- ConnPid ! {send, Pid, Message},
- {reply, ok, State};
- [] ->
- ConnPid = comm_connection:open_new_async(Address, Port,
- DepAddr, DepPort),
- ets:insert(?MODULE, {{Address, Port}, {ConnPid, undef}}),
- ConnPid ! {send, Pid, Message},
- {reply, ok, State}
- end
- end.
--endif.
-
--ifdef(SYNC).
-send(Address, Port, Pid, Message, State) ->
- case ets:lookup(?MODULE, {Address, Port}) of
- [{{Address, Port}, {_LPid, Socket}}] ->
- comm_connection:send({Address, Port, Socket}, Pid, Message),
- {reply, ok, State};
- [] ->
- open_sync_connection(Address, Port, Pid, Message, State)
- end.
--endif.
-
-
-open_sync_connection(Address, Port, Pid, Message, State) ->
- {DepAddr,DepPort} = get_local_address_port(),
- case comm_connection:open_new(Address, Port, DepAddr, DepPort) of
- {local_ip, MyIP, MyPort, MyPid, MySocket} ->
- comm_connection:send({Address, Port, MySocket}, Pid, Message),
- log:log(info,"[ CC ] this() == ~w", [{MyIP, MyPort}]),
- % set_local_address(t, {MyIP,MyPort}}),
- % register_connection(Address, Port, MyPid, MySocket),
- ets:insert(?MODULE, {local_address_port, {MyIP,MyPort}}),
- ets:insert(?MODULE, {{Address, Port}, {MyPid, MySocket}}),
- {reply, ok, State};
- fail ->
- % drop message (remote node not reachable, failure detector will notice)
- {reply, ok, State};
- {connection, LocalPid, NewSocket} ->
- comm_connection:send({Address, Port, NewSocket}, Pid, Message),
- ets:insert(?MODULE, {{Address, Port}, {LocalPid, NewSocket}}),
- % register_connection(Address, Port, LPid, NewSocket),
- {reply, ok, State}
- end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port_sup.erl b/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port_sup.erl
deleted file mode 100644
index d7a25b14ab..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/comm_layer/comm_port_sup.erl
+++ /dev/null
@@ -1,88 +0,0 @@
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : comm_port_sup.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description :
-%%%
-%%% Created : 04 Feb 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id: comm_port_sup.erl,v 1.1 2009/11/06 12:41:36 maria Exp $
--module(comm_layer_dir.comm_port_sup).
-
--author('[email protected]').
--vsn('$Id: comm_port_sup.erl,v 1.1 2009/11/06 12:41:36 maria Exp $ ').
-
--behaviour(supervisor).
-
--import(supervisor).
--import(randoms).
--import(string).
--import(config).
-
--export([start_link/0, init/1]).
-
-%%====================================================================
-%% API functions
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the supervisor
-%%--------------------------------------------------------------------
-start_link() ->
- supervisor:start_link(?MODULE, []).
-
-%%====================================================================
-%% Supervisor callbacks
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
-%% ignore |
-%% {error, Reason}
-%% Description: Whenever a supervisor is started using
-%% supervisor:start_link/[2,3], this function is called by the new process
-%% to find out about restart strategy, maximum restart frequency and child
-%% specifications.
-%%--------------------------------------------------------------------
-init([]) ->
- InstanceId = string:concat("comm_port_", randoms:getRandomId()),
- CommPort =
- {comm_port,
- {comm_layer_dir.comm_port, start_link, []},
- permanent,
- brutal_kill,
- worker,
- []},
- CommAcceptor =
- {comm_acceptor,
- {comm_layer_dir.comm_acceptor, start_link, [InstanceId]},
- permanent,
- brutal_kill,
- worker,
- []},
- CommLogger =
- {comm_logger,
- {comm_layer_dir.comm_logger, start_link, []},
- permanent,
- brutal_kill,
- worker,
- []},
- {ok, {{one_for_all, 10, 1},
- [
- CommPort,
- CommLogger,
- CommAcceptor
- ]}}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl b/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl
new file mode 100644
index 0000000000..b58fa732cb
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl
@@ -0,0 +1,57 @@
+%%
+%% The Original Code is RabbitMQ.
+%%
+%% The Initial Developer of the Original Code is VMware, Inc.
+%%
+
+-module(empty_list_infimum).
+
+-record(permission, {configure, write, read}).
+-record(user_vhost, {username, virtual_host}).
+-record(user_permission, {user_vhost, permission}).
+
+%%----------------------------------------------------------------------------
+
+-export([i_delete/1]).
+
+-type(vhost() :: binary()).
+
+-type(info_key() :: atom()).
+-type(info_keys() :: [info_key()]).
+
+-type(info() :: {info_key(), any()}).
+-type(infos() :: [info()]).
+
+%%----------------------------------------------------------------------------
+
+-spec i_delete(vhost()) -> 'ok'.
+
+i_delete(VHostPath) ->
+ [ok || _ <- list_vhost_permissions(VHostPath)],
+ ok.
+
+%%----------------------------------------------------------------------------
+
+vhost_perms_info_keys() ->
+ [user, configure, write, read].
+
+-spec list_vhost_permissions(vhost()) -> infos().
+
+list_vhost_permissions(VHostPath) ->
+ list_permissions(vhost_perms_info_keys(), rabbit_foo:some_list()).
+
+filter_props(Keys, Props) ->
+ [T || T = {K, _} <- Props, lists:member(K, Keys)].
+
+list_permissions(Keys, SomeList) ->
+ [filter_props(Keys, [{user, Username},
+ {vhost, VHostPath},
+ {configure, ConfigurePerm},
+ {write, WritePerm},
+ {read, ReadPerm}]) ||
+ #user_permission{user_vhost = #user_vhost{username = Username,
+ virtual_host = VHostPath},
+ permission = #permission{configure = ConfigurePerm,
+ write = WritePerm,
+ read = ReadPerm}} <-
+ SomeList].
diff --git a/lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_api.erl b/lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_api.erl
deleted file mode 100644
index 85ea292077..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_api.erl
+++ /dev/null
@@ -1,99 +0,0 @@
-% Copyright 2007-2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : pubsub_api.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description : Publish API function
-%%%
-%%% Created : 17 Sep 2007 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2007-2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id $
--module(pubsub_dir.pubsub_api).
-
--author('[email protected]').
--vsn('$Id: pubsub_api.erl,v 1.1 2009/11/06 12:39:55 maria Exp $ ').
-
--export([publish/2, subscribe/2, unsubscribe/2, get_subscribers/1]).
-
--import(transstore.transaction_api).
--import(io).
--import(lists).
-
-%%====================================================================
-%% public functions
-%%====================================================================
-
-%% @doc publishs an event under a given topic.
-%% called e.g. from the java-interface
-%% @spec publish(string(), string()) -> ok
-publish(Topic, Content) ->
- Subscribers = get_subscribers(Topic),
- io:format("calling subscribers ~p~n", [Subscribers]),
- lists:foreach(fun (Subscriber) ->
- io:format("calling ~p~n", [Subscriber]),
- pubsub_publish:publish(Subscriber, Topic, Content)
- end,
- Subscribers),
- ok.
-
-%% @doc subscribes a url for a topic.
-%% called e.g. from the java-interface
-%% @spec subscribe(string(), string()) -> ok | {fail, term()}
-subscribe(Topic, URL) ->
- TFun = fun(TransLog) ->
- {{Success, _ValueOrReason} = Result, TransLog1} = transaction_api:read(Topic, TransLog),
- {Result2, TransLog2} = if
- Success == fail ->
- transaction_api:write(Topic, [URL], TransLog); %obacht: muss TransLog sein!
- true ->
- {value, Subscribers} = Result,
- transaction_api:write(Topic, [URL | Subscribers], TransLog1)
- end,
- if
- Result2 == ok ->
- {{ok, ok}, TransLog2};
- true ->
- {Result2, TransLog2}
- end
- end,
- transaction_api:do_transaction(TFun, fun (_) -> ok end, fun (X) -> {fail, X} end).
-
-%% @doc unsubscribes a url for a topic.
--spec(unsubscribe/2 :: (string(), string()) -> ok | {fail, any()}).
-unsubscribe(Topic, URL) ->
- TFun = fun(TransLog) ->
- {Subscribers, TransLog1} = transaction_api:read2(TransLog, Topic),
- case lists:member(URL, Subscribers) of
- true ->
- NewSubscribers = lists:delete(URL, Subscribers),
- TransLog2 = transaction_api:write2(TransLog1, Topic, NewSubscribers),
- {{ok, ok}, TransLog2};
- false ->
- {{fail, not_found}, TransLog}
- end
- end,
- transaction_api:do_transaction(TFun, fun (_) -> ok end, fun (X) -> {fail, X} end).
-
-%% @doc queries the subscribers of a query
-%% @spec get_subscribers(string()) -> [string()]
-get_subscribers(Topic) ->
- {Fl, _Value} = transaction_api:quorum_read(Topic),
- if
- Fl == fail -> %% Fl is either Fail or the Value/Subscribers
- [];
- true ->
- Fl
- end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_publish.erl b/lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_publish.erl
deleted file mode 100644
index 601dbad74b..0000000000
--- a/lib/dialyzer/test/small_SUITE_data/src/pubsub/pubsub_publish.erl
+++ /dev/null
@@ -1,49 +0,0 @@
-% Copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%
-% Licensed under the Apache License, Version 2.0 (the "License");
-% you may not use this file except in compliance with the License.
-% You may obtain a copy of the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS,
-% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-% See the License for the specific language governing permissions and
-% limitations under the License.
-%%%-------------------------------------------------------------------
-%%% File : pubsub_publish.erl
-%%% Author : Thorsten Schuett <[email protected]>
-%%% Description : Publish function
-%%%
-%%% Created : 26 Mar 2008 by Thorsten Schuett <[email protected]>
-%%%-------------------------------------------------------------------
-%% @author Thorsten Schuett <[email protected]>
-%% @copyright 2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
-%% @version $Id $
--module(pubsub_dir.pubsub_publish).
-
--author('[email protected]').
--vsn('$Id: pubsub_publish.erl,v 1.1 2009/11/06 12:39:55 maria Exp $ ').
-
--export([publish/3, publish_internal/3]).
-
--import(json).
--import(io).
--import(http).
--import(jsonrpc).
-
-%%====================================================================
-%% public functions
-%%====================================================================
-
-%% @doc publishs an event to a given url.
-%% @spec publish(string(), string(), string()) -> ok
-%% @todo use pool:pspawn
-publish(URL, Topic, Content) ->
- spawn(fun () -> pubsub_publish:publish_internal(URL, Topic, Content) end),
- ok.
-
-publish_internal(URL, Topic, Content) ->
- Res = jsonrpc:call(URL, [], {call, notify, [Topic, Content]}),
- io:format("~p ~p~n", [Res, URL]).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/unknown_arity_function_spec.erl b/lib/dialyzer/test/small_SUITE_data/src/unknown_arity_function_spec.erl
new file mode 100644
index 0000000000..c7d7459614
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/unknown_arity_function_spec.erl
@@ -0,0 +1,10 @@
+-module(unknown_arity_function_spec).
+
+-export([test/2]).
+
+%-type t() :: 42 | fun((...) -> t()).
+%-type f() :: fun((...) -> 42).
+
+-spec test(fun((...) -> 42), list()) -> 42.
+test(F, L) ->
+ 42 = apply(F, L).
diff --git a/lib/diameter/doc/src/Makefile b/lib/diameter/doc/src/Makefile
index 8ad38ba0d5..0cbe1f000f 100644
--- a/lib/diameter/doc/src/Makefile
+++ b/lib/diameter/doc/src/Makefile
@@ -173,8 +173,8 @@ release_spec:
depend.mk: depend.sed Makefile seealso.ent \
$(XML_REF_FILES) $(XML_CHAPTER_FILES)
- sed -f seehere.sed seealso.ent > seehere.ent
- (for f in $(XML_REF_FILES) $(XML_CHAPTER_FILES); do \
+ $(gen_verbose)sed -f seehere.sed seealso.ent > seehere.ent
+ $(V_at)(for f in $(XML_REF_FILES) $(XML_CHAPTER_FILES); do \
sed -f $< $$f | sed "s@%FILE%@`basename $$f .xml`@g"; \
done) \
> $@
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index b7669b760b..7e50f338d3 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -69,8 +69,8 @@ Incoming Diameter requests are communicated as callbacks to a
specified in the service configuration.</p>
<p>
-Beware the difference between <em>diameter</em> (not capitalised) and
-<em>Diameter</em> (capitalised).
+Beware the difference between <em>diameter</em> (not capitalized) and
+<em>Diameter</em> (capitalized).
The former refers to the Erlang application named diameter whose main
api is defined here, the latter to Diameter protocol in the sense of
&the_rfc;.</p>
@@ -488,16 +488,23 @@ candidates list.</p>
<marker id="service_event"/>
</item>
-
-<tag><c>service_event() = #diameter_event{}</c></tag>
+<tag><c>service_event() = #diameter_event{service = &service_name;,
+ info = &service_event_info;}</c></tag>
<item>
<p>
An event message sent to processes that have subscribed to these using
&subscribe;.</p>
+<marker id="service_event_info"/>
+</item>
+
+<tag><c>service_event_info() = term()</c></tag>
+
+<item>
+
<p>
-The <c>info</c> field of the event record can have one of the
-following types.</p>
+The <c>info</c> field of a &service_event; record.
+Can have one of the following types.</p>
<taglist>
@@ -534,9 +541,9 @@ Otherwise a connection has reestablished without the loss or
connectivity.</p>
<p>
-Note that a single <c>up</c>/<c>down</c> event for a given peer
-corresponds to one &app_peer_up;/&app_peer_down;
-callback for each of the Diameter applications negotiated during
+Note that a single <c>up</c> or <c>down</c> event for a given peer
+corresponds to multiple &app_peer_up; or &app_peer_down;
+callbacks, one for each of the Diameter applications negotiated during
capablilities exchange.
That is, the event communicates connectivity with the
peer as a whole while the callbacks communicate connectivity with
@@ -582,7 +589,7 @@ CB = &evaluable;
<p>
An incoming CER has been answered with the indicated result code or
discarded.
-<c>Caps</c> contains pairs of values for the the local node and remote
+<c>Caps</c> contains pairs of values for the local node and remote
peer.
<c>Pkt</c> contains the CER in question.
In the case of rejection by a capabilities callback, the tuple
@@ -600,7 +607,7 @@ Pkt = #diameter_packet{}
<p>
An incoming CER contained errors and has been answered with the
indicated result code.
-<c>Caps</c> contains only values for the the local node.
+<c>Caps</c> contains only values for the local node.
<c>Pkt</c> contains the CER in question.</p>
</item>
@@ -624,7 +631,7 @@ ResultCode = integer()
An incoming CEA has been rejected for the indicated reason.
An integer-valued <c>Result</c> indicates the result code sent
by the peer.
-<c>Caps</c> contains pairs of values for the the local node and remote
+<c>Caps</c> contains pairs of values for the local node and remote
peer.
<c>Pkt</c> contains the CEA in question.
In the case of rejection by a capabilities callback, the tuple
@@ -640,7 +647,7 @@ Pkt = #diameter_packet{}
<p>
An incoming CEA contained errors and has been rejected.
-<c>Caps</c> contains only values for the the local node.
+<c>Caps</c> contains only values for the local node.
<c>Pkt</c> contains the CEA in question.</p>
</item>
@@ -667,11 +674,14 @@ Config = {connect|listen, [transport_opt()]}
An RFC 3539 watchdog state machine has changed state.</p>
</item>
-</taglist>
-
+<tag><c>any()</c></tag>
+<item>
<p>
For forward compatibility, a subscriber should be prepared to receive
info fields of forms other than the above.</p>
+</item>
+
+</taglist>
<marker id="service_name"/>
</item>
@@ -709,6 +719,15 @@ passed to &call;, while for an
incoming request the application identifier in the message
header determines the application, the identifier being specified in
the application's &dictionary; file.</p>
+
+<warning>
+<p>
+The capabilities advertised by a node must match its configured
+applications. In particular, <c>application</c> configuration must
+be matched by corresponding &capability; configuration, of
+Application-Id AVP's in particular.</p>
+</warning>
+
</item>
<tag><c>{restrict_connections, false
@@ -787,6 +806,16 @@ The list of Diameter applications to which the transport should be
restricted.
Defaults to all applications configured on the service in question.
Applications not configured on the service in question are ignored.</p>
+
+<warning>
+<p>
+The capabilities advertised by a node must match its configured
+applications.
+In particular, setting <c>applications</c> on a transport typically
+implies having to set matching Application-Id AVP's in a
+&capabilities; tuple.</p>
+</warning>
+
</item>
<marker id="capabilities"/>
@@ -858,9 +887,8 @@ case the corresponding callbacks are applied until either all return
The number of milliseconds after which a transport process having an
established transport connection will be terminated if the expected
capabilities exchange message (CER or CEA) is not received from the peer.
-For a connecting transport, the timing reconnection attempts is
-governed by &watchdog_timer; or
-&reconnect_timer; expiry.
+For a connecting transport, the timing of reconnection attempts is
+governed by &watchdog_timer; or &reconnect_timer; expiry.
For a listening transport, the peer determines the timing.</p>
<p>
@@ -877,7 +905,7 @@ transport connection having watchdog state <c>OKAY</c>.
Applied to <c>Reason=transport|service|application</c> and the
<c>&transport_ref;</c> and
<c>&app_peer;</c>
-in question, <c>Reason</c> indicating whether the the diameter
+in question, <c>Reason</c> indicating whether the diameter
application is being stopped, the service in question is being stopped
at &stop_service; or
the transport in question is being removed at &remove_transport;,
@@ -1733,7 +1761,7 @@ a service.</p>
It is not an error to subscribe to events from a service
that does not yet exist.
Doing so before adding transports is required to guarantee the
-reception of all related events.</p>
+reception of all transport-related events.</p>
</desc>
</func>
diff --git a/lib/diameter/doc/src/diameter_tcp.xml b/lib/diameter/doc/src/diameter_tcp.xml
index e3b8c733b7..fe2389d57d 100644
--- a/lib/diameter/doc/src/diameter_tcp.xml
+++ b/lib/diameter/doc/src/diameter_tcp.xml
@@ -26,7 +26,7 @@
<erlref>
<header>
<copyright>
-<year>2011</year><year>2012</year>
+<year>2011</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -65,9 +65,8 @@ It can be specified as the value of a <c>transport_module</c> option to
&mod_add_transport;
and implements the behaviour documented in
&man_transport;.
-TLS security is supported, both as an upgrade following
-capabilities exchange as specified by &the_rfc; and
-at connection establishment as in the current draft standard.</p>
+TLS security is supported, either as an upgrade following
+capabilities exchange or at connection establishment.</p>
<p>
Note that the ssl application is required for TLS and must be started
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index d448b01eba..d241e2bd19 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -42,6 +42,22 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>Diameter 1.3.1</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ Fix function clause resulting from use of an eval
+ callback.</p>
+ <p>
+ Own Id: OTP-10685</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Diameter 1.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/diameter/doc/src/seealso.ent b/lib/diameter/doc/src/seealso.ent
index 4647c42f85..9945bcadd3 100644
--- a/lib/diameter/doc/src/seealso.ent
+++ b/lib/diameter/doc/src/seealso.ent
@@ -54,6 +54,7 @@ significant.
<!ENTITY mod_evaluable '<seealso marker="diameter#evaluable">diameter:evaluable()</seealso>'>
<!ENTITY mod_peer_filter '<seealso marker="diameter#peer_filter">diameter:peer_filter()</seealso>'>
<!ENTITY mod_service_event '<seealso marker="diameter#service_event">diameter:service_event()</seealso>'>
+<!ENTITY mod_service_event_info '<seealso marker="diameter#service_event_info">diameter:service_event_info()</seealso>'>
<!ENTITY mod_service_name '<seealso marker="diameter#service_name">diameter:service_name()</seealso>'>
<!ENTITY mod_service_opt '<seealso marker="diameter#service_opt">diameter:service_opt()</seealso>'>
<!ENTITY mod_transport_opt '<seealso marker="diameter#transport_opt">diameter:transport_opt()</seealso>'>
diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile
index 060659bce9..a08c204a23 100644
--- a/lib/diameter/src/Makefile
+++ b/lib/diameter/src/Makefile
@@ -104,7 +104,7 @@ endif
ERL_COMPILE_FLAGS += \
+'{parse_transform,sys_pre_attributes}' \
- +'{attribute,insert,app_vsn,$(APP_VSN)}' \
+ +'{attribute,insert,app_vsn,"$(APP_VSN)"}' \
+warn_export_vars \
+warn_unused_vars \
-pa $(ABS_EBIN) \
@@ -119,26 +119,34 @@ ERL_COMPILE_FLAGS += \
# erl/hrl from dictionary file.
gen/diameter_gen_%.erl gen/diameter_gen_%.hrl: dict/%.dia
- ../bin/diameterc -o gen -i $(EBIN) $<
+ $(dia_verbose)../bin/diameterc -o gen -i $(EBIN) $<
opt: $(TARGET_FILES)
+# Build unofficial patches with some degree of traceability. Refuse to
+# build if there are diffs from HEAD since that defeats the purpose.
+patch:
+ git diff --exit-code HEAD
+ $(MAKE) opt PRE_VSN="-$(shell git rev-list --max-count=1 HEAD | cut -c 1-8)"
+
debug:
@$(MAKE) TYPE=debug opt
# The dictionary parser.
gen/$(DICT_YRL).erl: compiler/$(DICT_YRL).yrl
- $(ERLC) -Werror -o $(@D) $<
+ $(yecc_verbose)$(ERLC) -Werror -o $(@D) $<
# Generate the app file.
$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk
- M=`echo $(notdir $(APP_MODULES)) | tr ' ' ,`; \
+ $(gen_verbose)M=`echo $(notdir $(APP_MODULES)) | tr ' ' ,`; \
+ R=`echo $(REGISTERED) | tr ' ' ,`; \
sed -e 's;%VSN%;$(VSN);' \
-e "s;%MODULES%;$$M;" \
+ -e "s;%REGISTERED%;$$R;" \
$< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
app: $(APP_TARGET) $(APPUP_TARGET)
dict: $(DICT_ERLS)
@@ -254,7 +262,7 @@ depend: depend.mk
# Generate dependencies makefile.
depend.mk: depend.sed $(MODULES:%=%.erl) Makefile
- (for f in $(MODULES); do \
+ $(gen_verbose)(for f in $(MODULES); do \
(echo $$f; cat $$f.erl) | sed -f $<; \
done) \
> $@
@@ -265,7 +273,7 @@ depend.mk: depend.sed $(MODULES:%=%.erl) Makefile
.PHONY: debug opt release_docs_spec release_spec
.PHONY: $(TARGET_DIRS:%/=%) $(TARGET_DIRS:%/=release_src_%)
.PHONY: $(EXAMPLE_DIRS:%/=release_examples_%)
-.PHONY: plt dialyze
+.PHONY: plt dialyze patch
# Keep intermediate files.
.SECONDARY: $(DICT_ERLS) $(DICT_HRLS) gen/$(DICT_YRL:%=%.erl)
diff --git a/lib/diameter/src/base/diameter.app.src b/lib/diameter/src/base/diameter.app.src
index c092fdb022..7e17cd6c9f 100644
--- a/lib/diameter/src/base/diameter.app.src
+++ b/lib/diameter/src/base/diameter.app.src
@@ -21,7 +21,7 @@
[{description, "Diameter protocol"},
{vsn, "%VSN%"},
{modules, [%MODULES%]},
- {registered, []},
+ {registered, [%REGISTERED%]},
{applications, [stdlib, kernel]},
{env, []},
{mod, {diameter_app, []}}
diff --git a/lib/diameter/src/base/diameter.appup.src b/lib/diameter/src/base/diameter.appup.src
index 5655f98c1b..f6d772b534 100644
--- a/lib/diameter/src/base/diameter.appup.src
+++ b/lib/diameter/src/base/diameter.appup.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -24,27 +24,10 @@
{"0.10", [{restart_application, diameter}]},
{"1.0", [{restart_application, diameter}]},
{"1.1", [{restart_application, diameter}]},
- {"1.2", [{load, diameter},
- {load, diameter_capx},
- {load, diameter_codec},
- {load, diameter_peer},
- {load, diameter_reg},
- %% order significant from here
- {load, diameter_session},
- {load, diameter_peer_fsm},
- {load, diameter_service},
- {load, diameter_watchdog},
- {load, diameter_config}]},
- {"1.2.1", [{load, diameter},
- {load, diameter_capx},
- {load, diameter_peer},
- {load, diameter_reg},
- %% order significant from here
- {load, diameter_session},
- {load, diameter_peer_fsm},
- {load, diameter_service},
- {load, diameter_watchdog},
- {load, diameter_config}]}
+ {"1.2", [{restart_application, diameter}]},
+ {"1.2.1", [{restart_application, diameter}]},
+ {"1.3", [{restart_application, diameter}]},
+ {"1.3.1", [{restart_application, diameter}]}
],
[
{"0.9", [{restart_application, diameter}]},
@@ -52,6 +35,8 @@
{"1.0", [{restart_application, diameter}]},
{"1.1", [{restart_application, diameter}]},
{"1.2", [{restart_application, diameter}]},
- {"1.2.1", [{restart_application, diameter}]}
+ {"1.2.1", [{restart_application, diameter}]},
+ {"1.3", [{restart_application, diameter}]},
+ {"1.3.1", [{restart_application, diameter}]}
]
}.
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index a94d37f7a8..0b0bfe3f0a 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -193,9 +193,11 @@ encode_avps(Avps) ->
msg_header(Mod, 'answer-message' = MsgName, Header) ->
?BASE = Mod,
- #diameter_header{cmd_code = Code} = Header,
- {_, Flags, ApplId} = ?BASE:msg_header(MsgName),
- {Code, Flags, ApplId};
+ #diameter_header{application_id = Aid,
+ cmd_code = Code}
+ = Header,
+ {-1, Flags, ?DIAMETER_APP_ID_COMMON} = ?BASE:msg_header(MsgName),
+ {Code, Flags, Aid};
msg_header(Mod, MsgName, _) ->
Mod:msg_header(MsgName).
diff --git a/lib/diameter/src/base/diameter_peer.erl b/lib/diameter/src/base/diameter_peer.erl
index 1b2f32ddff..25c9eab4cb 100644
--- a/lib/diameter/src/base/diameter_peer.erl
+++ b/lib/diameter/src/base/diameter_peer.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -33,9 +33,6 @@
abort/1,
notify/2]).
-%% Old interface only called from old code.
--export([start/3]). %% < diameter-1.2 (R15B02)
-
%% Server start.
-export([start_link/0]).
@@ -73,14 +70,6 @@ notify(SvcName, T) ->
rpc:abcast(nodes(), ?SERVER, {notify, SvcName, T}).
%%% ---------------------------------------------------------------------------
-%%% # start/3
-%%% ---------------------------------------------------------------------------
-
-%% From old code: make it restart.
-start(_T, _Opts, #diameter_service{}) ->
- {error, restart}.
-
-%%% ---------------------------------------------------------------------------
%%% # start/1
%%% ---------------------------------------------------------------------------
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index c4320fcb99..5dab6214b1 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -95,10 +95,8 @@
-record(state,
{state %% of RFC 3588 Peer State Machine
- :: 'Wait-Conn-Ack' %% old code
- | {'Wait-Conn-Ack', uint32()}
+ :: {'Wait-Conn-Ack', uint32()}
| recv_CER
- | 'Wait-CEA' %% old code
| {'Wait-CEA', uint32(), uint32()}
| 'Open',
mode :: accept | connect | {connect, reference()},
@@ -142,8 +140,7 @@
%%% Output: Pid
%%% ---------------------------------------------------------------------------
--spec start(T, [Opt], #diameter_service{} %% from old code
- | {diameter:sequence(),
+-spec start(T, [Opt], {diameter:sequence(),
diameter:restriction(),
#diameter_service{}})
-> pid()
@@ -175,9 +172,6 @@ init(T) ->
proc_lib:init_ack({ok, self()}),
gen_server:enter_loop(?MODULE, [], i(T)).
-i({WPid, Type, Opts, #diameter_service{} = Svc}) -> %% from old code
- i({WPid, Type, Opts, {?NOMASK, [node() | nodes()], Svc}});
-
i({WPid, T, Opts, {Mask, Nodes, #diameter_service{applications = Apps,
capabilities = LCaps}
= Svc}}) ->
@@ -334,10 +328,6 @@ eraser(Key) ->
%% transition/2
-%% Started in old code.
-transition(T, #state{state = 'Wait-Conn-Ack' = PS} = S) ->
- transition(T, S#state{state = {PS, ?EVENT_TIMEOUT}});
-
%% Connection to peer.
transition({diameter, {TPid, connected, Remote}},
#state{transport = TPid,
@@ -388,8 +378,9 @@ transition({diameter, {recv, Pkt}}, S) ->
recv(Pkt, S);
%% Timeout when still in the same state ...
-transition({timeout, PS}, #state{state = PS}) ->
- {stop, {capx(PS), timeout}};
+transition({timeout = T, PS}, #state{state = PS} = S) ->
+ close({capx(PS), T}, S),
+ stop;
%% ... or not.
transition({timeout, _}, _) ->
@@ -400,10 +391,6 @@ transition({send, Msg}, #state{transport = TPid}) ->
send(TPid, Msg),
ok;
-%% Messages from old (diameter_service) code.
-transition(shutdown = T, #state{parent = Pid} = S) ->
- transition({T, Pid, service}, S); %% Reason irrelevant: old code has no cb
-
%% Request for graceful shutdown at remove_transport, stop_service of
%% application shutdown.
transition({shutdown = T, Pid}, S) ->
@@ -507,22 +494,13 @@ build_CER(#state{service = #diameter_service{capabilities = LCaps}}) ->
%% encode/1
encode(Rec) ->
- Seq = diameter_session:sequence(sequence()),
+ Seq = diameter_session:sequence({_,_} = getr(?SEQUENCE_KEY)),
Hdr = #diameter_header{version = ?DIAMETER_VERSION,
end_to_end_id = Seq,
hop_by_hop_id = Seq},
diameter_codec:encode(?BASE, #diameter_packet{header = Hdr,
msg = Rec}).
-sequence() ->
- case getr(?SEQUENCE_KEY) of
- {_,_} = Mask ->
- Mask;
- undefined -> %% started in old code
- putr(?SEQUENCE_KEY, ?NOMASK),
- ?NOMASK
- end.
-
%% recv/2
%% RFC 3588 has result code 5015 for an invalid length but if a
@@ -584,10 +562,8 @@ rcv('CEA',
#diameter_packet{header = #diameter_header{end_to_end_id = Eid,
hop_by_hop_id = Hid}}
= Pkt,
- #state{state = {'Wait-CEA' = T, Hid, Eid}}
+ #state{state = {'Wait-CEA', Hid, Eid}}
= S) ->
- handle_CEA(Pkt, S#state{state = T});
-rcv('CEA', Pkt, #state{state = 'Wait-CEA'} = S) -> %% old code
handle_CEA(Pkt, S);
%% Incoming CER
@@ -1020,14 +996,10 @@ dpr(Reason, #state{state = 'Open',
dpr = false,
service = #diameter_service{capabilities = Caps}}
= S) ->
- case getr(?DPR_KEY) of
- CBs when is_list(CBs) ->
- Ref = getr(?REF_KEY),
- Peer = {self(), Caps},
- dpr(CBs, [Reason, Ref, Peer], S);
- undefined -> %% started in old code
- send_dpr(Reason, [], S)
- end;
+ CBs = getr(?DPR_KEY),
+ Ref = getr(?REF_KEY),
+ Peer = {self(), Caps},
+ dpr(CBs, [Reason, Ref, Peer], S);
%% Connection is open, DPR already sent.
dpr(_, #state{state = 'Open'}) ->
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 91384b8b91..d2a416166f 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -361,9 +361,6 @@ find_state(SvcName) ->
fs([#state{} = S]) ->
S;
-fs([S]) -> %% inserted from old code
- upgrade(S);
-
fs([]) ->
false.
@@ -462,10 +459,6 @@ i(_, false) ->
%%% # handle_call(Req, From, State)
%%% ---------------------------------------------------------------------------
-handle_call(T, From, S)
- when not is_record(S, state) ->
- handle_call(T, From, upgrade(S));
-
handle_call(state, _, S) ->
{reply, S, S};
@@ -489,10 +482,6 @@ handle_call({pick_peer, Local, Remote, App}, _From, S) ->
handle_call({call_module, AppMod, Req}, From, S) ->
call_module(AppMod, Req, From, S);
-%% Call from old code.
-handle_call({info, Item}, _From, S) ->
- {reply, service_info(Item, S), S};
-
handle_call(stop, _From, S) ->
shutdown(service, S),
{stop, normal, ok, S};
@@ -500,14 +489,6 @@ handle_call(stop, _From, S) ->
%% gets the reply. We deal with this in the call to the server,
%% stating a monitor that waits for DOWN before returning.
-%% Watchdog is asking for the sequence mask.
-handle_call(sequence, _From, #state{options = [{_, Mask} | _]} = S) ->
- {reply, Mask, S};
-
-%% Watchdog is asking for the nodes restriction.
-handle_call(restriction, _From, #state{options = [_,_,_,{_,R} | _]} = S) ->
- {reply, R, S};
-
handle_call(Req, From, S) ->
unexpected(handle_call, [Req, From], S),
{reply, nok, S}.
@@ -530,10 +511,7 @@ handle_info(T, #state{} = S) ->
{noreply, S};
{stop, Reason} ->
{stop, {shutdown, Reason}, S}
- end;
-
-handle_info(T, S) ->
- handle_info(T, upgrade(S)).
+ end.
%% transition/2
@@ -576,9 +554,9 @@ transition({reconnect, Pid}, S) ->
ok;
%% Watchdog is sending notification of a state transition. Note that
-%% the connection_up/down messages are pre-date this message and are
-%% still used. A watchdog message will follow these and communicate
-%% the same state as was set in handling connection_up/down.
+%% the connection_up/down messages pre-date this message and are still
+%% used. A watchdog message will follow these and communicate the same
+%% state as was set in handling connection_up/down.
transition({watchdog, Pid, {TPid, From, To}}, #state{service_name = SvcName,
peerT = PeerT}) ->
#peer{ref = Ref, type = T, options = Opts, op_state = {OS,_}}
@@ -643,39 +621,10 @@ transition({failover, TRef, Seqs}, S) ->
failover(TRef, Seqs, S),
ok;
-%% Ensure upgraded state is stored in state table.
-transition(upgrade, _) ->
- ok;
-
transition(Req, S) ->
unexpected(handle_info, [Req], S),
ok.
-%% upgrade/1
-
-upgrade({state, Id, Svc, Name, Svc, PT, CT, SB, UB, SD, LD, MPid}) ->
- S = #state{id = Id,
- service_name = Name,
- service = Svc,
- peerT = PT,
- connT = CT,
- shared_peers = SD,
- local_peers = LD,
- monitor = MPid,
- options = [{sequence, ?NOMASK},
- {share_peers, SB},
- {use_shared_peers, UB},
- {restrict_connections, ?RESTRICT}]},
- upgrade_insert(S),
- S.
-
-upgrade_insert(#state{service = #diameter_service{pid = Pid}} = S) ->
- if Pid == self() ->
- ets:insert(?STATE_TABLE, S);
- true ->
- Pid ! upgrade
- end.
-
%%% ---------------------------------------------------------------------------
%%% # terminate(Reason, State)
%%% ---------------------------------------------------------------------------
@@ -859,10 +808,10 @@ i(SvcName) ->
true = ets:insert_new(?STATE_TABLE, S),
%% Start fsms for each transport.
+ send_event(SvcName, start),
lists:foreach(fun(T) -> start_fsm(T,S) end, CL),
init_shared(S),
- send_event(SvcName, start),
S.
cfg_acc({SvcName, #diameter_service{applications = Apps} = Rec, Opts},
@@ -944,6 +893,7 @@ type(connect = T) -> T.
start(Ref, Type, Opts, #state{peerT = PeerT,
connT = ConnT,
+ options = SvcOpts,
service_name = SvcName,
service = Svc})
when Type == connect;
@@ -951,6 +901,7 @@ start(Ref, Type, Opts, #state{peerT = PeerT,
Pid = s(Type, Ref, {ConnT,
Opts,
SvcName,
+ SvcOpts,
merge_service(Opts, Svc)}),
insert(PeerT, #peer{pid = Pid,
type = Type,
@@ -963,13 +914,8 @@ start(Ref, Type, Opts, #state{peerT = PeerT,
%% record is what is passed back into application callbacks.
s(Type, Ref, T) ->
- case diameter_watchdog:start({Type, Ref}, T) of
- {_MRef, Pid} ->
- Pid;
- Pid when is_pid(Pid) -> %% from old code
- erlang:monitor(process, Pid),
- Pid
- end.
+ {_MRef, Pid} = diameter_watchdog:start({Type, Ref}, T),
+ Pid.
%% merge_service/2
@@ -1116,12 +1062,7 @@ init_conn(Id, Alias, {TPid, _} = TC, {SvcName, Apps}) ->
%% find_app/2
find_app(Alias, Apps) ->
- case lists:keyfind(Alias, #diameter_app.alias, Apps) of
- #diameter_app{options = E} = A when is_atom(E) -> %% upgrade
- A#diameter_app{options = [{answer_errors, E}]};
- A ->
- A
- end.
+ lists:keyfind(Alias, #diameter_app.alias, Apps).
%% Don't bring down the service (and all associated connections)
%% regardless of what happens.
@@ -1457,7 +1398,7 @@ make_prepare_packet(Mask, #diameter_packet{header = Hdr} = Pkt) ->
make_prepare_packet(Mask, Msg) ->
make_prepare_packet(Mask, #diameter_packet{msg = Msg}).
-%% make_prepare_header/1
+%% make_prepare_header/2
make_prepare_header(Mask, undefined) ->
Seq = diameter_session:sequence(Mask),
@@ -1465,10 +1406,11 @@ make_prepare_header(Mask, undefined) ->
hop_by_hop_id = Seq});
make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined,
- hop_by_hop_id = undefined}) ->
+ hop_by_hop_id = undefined}
+ = H) ->
Seq = diameter_session:sequence(Mask),
- make_prepare_header(#diameter_header{end_to_end_id = Seq,
- hop_by_hop_id = Seq});
+ make_prepare_header(H#diameter_header{end_to_end_id = Seq,
+ hop_by_hop_id = Seq});
make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined} = H) ->
Seq = diameter_session:sequence(Mask),
@@ -1818,9 +1760,6 @@ request_peer_down(TPid, S) ->
%%% recv_request/3
%%% ---------------------------------------------------------------------------
-recv_request(TPid, Pkt, {ConnT, SvcName, Apps}) -> %% upgrade
- recv_request(TPid, Pkt, {ConnT, SvcName, Apps, ?NOMASK});
-
recv_request(TPid, Pkt, {ConnT, SvcName, Apps, Mask}) ->
try ets:lookup(ConnT, TPid) of
[C] ->
@@ -2053,15 +1992,21 @@ request_cb({eval_packet, RC, F}, App, Mask, T, TC, Fs, Pkt) ->
request_cb(RC, App, Mask, T, TC, [F|Fs], Pkt);
request_cb({eval, RC, F}, App, Mask, T, TC, Fs, Pkt) ->
- request_cb(RC, App, Mask, T, TC, Pkt, Fs),
+ request_cb(RC, App, Mask, T, TC, Fs, Pkt),
diameter_lib:eval(F).
%% protocol_error/5
protocol_error(RC, {_, OH, OR}, TPid, Fs, Pkt) ->
- #diameter_packet{avps = Avps} = Pkt,
+ #diameter_packet{avps = Avps, errors = Es} = Pkt,
?LOG({error, RC}, Pkt),
- reply(answer_message({OH, OR, RC}, Avps), ?BASE, TPid, Fs, Pkt).
+ reply(answer_message({OH, OR, RC}, Avps),
+ ?BASE,
+ TPid,
+ Fs,
+ Pkt#diameter_packet{errors = [RC | Es]}).
+%% Note that reply/5 may set the result code once more. It's set in
+%% answer_message/2 in case reply/5 doesn't.
%% protocol_error/4
@@ -2174,7 +2119,8 @@ is_loop(Code, Vid, OH, Avps) ->
%%
%% Send a locally originating reply.
-%% Skip the setting of Result-Code and Failed-AVP's below.
+%% Skip the setting of Result-Code and Failed-AVP's below. This is
+%% currently undocumented.
reply([Msg], Dict, TPid, Fs, Pkt)
when is_list(Msg);
is_tuple(Msg) ->
@@ -2242,6 +2188,9 @@ rc(RC) ->
%% rc/4
+rc(#diameter_packet{msg = Rec} = Pkt, RC, Failed, Dict) ->
+ Pkt#diameter_packet{msg = rc(Rec, RC, Failed, Dict)};
+
rc(Rec, RC, Failed, Dict)
when is_integer(RC) ->
set(Rec,
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index 243ad0a986..a5429c967c 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -68,11 +68,12 @@
%% that a failed capabilities exchange produces the desired exit
%% reason.
--spec start(Type, {RecvData, [Opt], SvcName, #diameter_service{}})
+-spec start(Type, {RecvData, [Opt], SvcName, SvcOpts, #diameter_service{}})
-> {reference(), pid()}
when Type :: {connect|accept, diameter:transport_ref()},
RecvData :: term(),
Opt :: diameter:transport_opt(),
+ SvcOpts :: [diameter:service_opt()],
SvcName :: diameter:service_name().
start({_,_} = Type, T) ->
@@ -107,23 +108,20 @@ i({Ref, {_, Pid, _} = T}) ->
make_state(T);
{'DOWN', MRef, process, _, _} = D ->
exit({shutdown, D})
- end;
-
-i({_, Pid, _} = T) -> %% from old code
- erlang:monitor(process, Pid),
- make_state(T).
+ end.
make_state({T, Pid, {RecvData,
Opts,
SvcName,
+ SvcOpts,
#diameter_service{applications = Apps,
capabilities = Caps}
= Svc}}) ->
random:seed(now()),
putr(restart, {T, Opts, Svc}), %% save seeing it in trace
putr(dwr, dwr(Caps)), %%
- {_,_} = Mask = call(Pid, sequence),
- Restrict = call(Pid, restriction),
+ {_,_} = Mask = proplists:get_value(sequence, SvcOpts),
+ Restrict = proplists:get_value(restrict_connections, SvcOpts),
Nodes = restrict_nodes(Restrict),
#watchdog{parent = Pid,
transport = monitor(diameter_peer_fsm:start(T,
@@ -136,10 +134,6 @@ make_state({T, Pid, {RecvData,
sequence = Mask,
restrict = {Restrict, lists:member(node(), Nodes)}}.
-%% Retrieve the sequence mask from the parent from the parent, rather
-%% than having it passed into init/1, for upgrade reasons: the call to
-%% diameter_service:receive_message/3 passes back the mask.
-
%% handle_call/3
handle_call(_, _, State) ->
@@ -342,15 +336,6 @@ transition({state, Pid}, #watchdog{status = S}) ->
%% ===========================================================================
-%% Only call "upwards", to the parent service.
-call(Pid, Req) ->
- try
- gen_server:call(Pid, Req, infinity)
- catch
- exit: Reason ->
- exit({shutdown, {Req, Reason}})
- end.
-
monitor(Pid) ->
erlang:monitor(process, Pid),
Pid.
diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk
index 01f9284881..25207625be 100644
--- a/lib/diameter/src/modules.mk
+++ b/lib/diameter/src/modules.mk
@@ -103,3 +103,12 @@ EXAMPLES = \
dict/rfc4072_eap.dia \
dict/rfc4590_digest.dia \
dict/rfc4740_sip.dia
+
+# Registered server names.
+
+REGISTERED = \
+ diameter_config \
+ diameter_peer \
+ diameter_reg \
+ diameter_stats \
+ diameter_sync
diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl
index 79b8b851fb..3cb13d7043 100644
--- a/lib/diameter/src/transport/diameter_sctp.erl
+++ b/lib/diameter/src/transport/diameter_sctp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -188,8 +188,6 @@ i({connect, Pid, Opts, Addrs, Ref}) ->
#transport{parent = Pid,
mode = {connect, connect(Sock, RAs, RP, [])},
socket = Sock};
-i({connect, _, _, _} = T) -> %% from old code
- x(T);
%% An accepting transport spawned by diameter.
i({accept, Pid, LPid, Sock, Ref})
@@ -201,8 +199,6 @@ i({accept, Pid, LPid, Sock, Ref})
#transport{parent = Pid,
mode = {accept, LPid},
socket = Sock};
-i({accept, _, _, _} = T) -> %% from old code
- x(T);
%% An accepting transport spawned at association establishment.
i({accept, Ref, LPid, Sock, Id}) ->
diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl
index f3fbbee609..7ec7b1c5e7 100644
--- a/lib/diameter/src/transport/diameter_tcp.erl
+++ b/lib/diameter/src/transport/diameter_tcp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -80,7 +80,7 @@
%% Accepting/connecting transport process state.
-record(transport,
- {socket :: inet:socket() | ssl:sslsock(), %% accept or connect socket
+ {socket :: inet:socket() | ssl:sslsocket(), %% accept/connect socket
parent :: pid(), %% of process that started us
module :: module(), %% gen_tcp-like module
frag = <<>> :: binary() | {tref(), frag()}, %% message fragment
diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile
index 866d135bd9..aa4b7eaeb1 100644
--- a/lib/diameter/test/Makefile
+++ b/lib/diameter/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2012. All Rights Reserved.
+# Copyright Ericsson AB 2010-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
@@ -62,17 +62,15 @@ ERL_COMPILE_FLAGS += +warn_export_vars \
# Targets
# ----------------------------------------------------
+all debug opt: $(TARGET_FILES)
+
# Require success ...
-all: opt
+run: $(SUITES)
# ... or not.
any: opt
$(MAKE) -i $(SUITES)
-run: $(SUITES)
-
-debug opt: $(TARGET_FILES)
-
clean:
rm -f $(TARGET_FILES)
rm -f depend.mk
@@ -101,7 +99,10 @@ help:
@echo " Compile all test suites."
@echo
@echo " run:"
- @echo " Compile and run all test suites."
+ @echo " Compile and run all test suites, stop on failure."
+ @echo
+ @echo " any:"
+ @echo " Compile and run all test suites, ignore any failures."
@echo
@echo " $(SUITES):"
@echo " Compile and run a specific test suite."
diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl
new file mode 100644
index 0000000000..7c1c76f22a
--- /dev/null
+++ b/lib/diameter/test/diameter_event_SUITE.erl
@@ -0,0 +1,182 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+
+%%
+%% Tests of events sent as a consequence of diameter:subscribe/1.
+%% Watchdog events are dealt with more extensively in the watchdog
+%% suite.
+%%
+
+-module(diameter_event_SUITE).
+
+-export([suite/0,
+ all/0,
+ init_per_testcase/2,
+ end_per_testcase/2]).
+
+%% testcases
+-export([start/1,
+ start_server/1,
+ up/1,
+ down/1,
+ cea_timeout/1,
+ stop/1]).
+
+-include("diameter.hrl").
+
+%% ===========================================================================
+
+-define(util, diameter_util).
+
+-define(ADDR, {127,0,0,1}).
+-define(REALM, "REALM").
+
+-define(SERVER, "SERVER.SERVER-REALM").
+-define(CLIENT, "CLIENT.CLIENT-REALM").
+
+-define(DICT_COMMON, ?DIAMETER_DICT_COMMON).
+-define(DICT_ACCT, ?DIAMETER_DICT_ACCOUNTING).
+
+-define(SERVER_CAPX_TMO, 6000).
+
+%% Config for diameter:start_service/2.
+-define(SERVICE(Host, Dicts),
+ [{'Origin-Host', Host},
+ {'Origin-Realm', realm(Host)},
+ {'Host-IP-Address', [?ADDR]},
+ {'Vendor-Id', 12345},
+ {'Product-Name', "OTP/diameter"},
+ {'Acct-Application-Id', [D:id() || D <- Dicts]}
+ | [{application, [{dictionary, D},
+ {module, #diameter_callback{}}]}
+ || D <- Dicts]]).
+
+%% Diameter Result-Code's:
+-define(NO_COMMON_APP, 5010).
+
+%% ===========================================================================
+
+suite() ->
+ [{timetrap, {seconds, 60}}].
+
+all() ->
+ [start,
+ start_server,
+ up,
+ down,
+ cea_timeout,
+ stop].
+
+init_per_testcase(Name, Config) ->
+ [{name, Name} | Config].
+
+end_per_testcase(_, _) ->
+ ok.
+
+%% ===========================================================================
+%% start/stop testcases
+
+start(_Config) ->
+ ok = diameter:start().
+
+start_server(Config) ->
+ diameter:subscribe(?SERVER),
+ ok = diameter:start_service(?SERVER, ?SERVICE(?SERVER, [?DICT_COMMON])),
+ LRef = ?util:listen(?SERVER, tcp, [{capabilities_cb, fun capx_cb/2},
+ {capx_timeout, ?SERVER_CAPX_TMO}]),
+ [PortNr] = ?util:lport(tcp, LRef, 20),
+ ?util:write_priv(Config, portnr, PortNr),
+ start = event(?SERVER).
+
+%% Connect with matching capabilities and expect the connection to
+%% come up.
+up(Config) ->
+ {Svc, Ref} = connect(Config, []),
+ start = event(Svc),
+ {up, Ref, {_,_Caps}, _Config, #diameter_packet{}} = event(Svc),
+ {watchdog, Ref, _, {initial, okay}, _} = event(Svc).
+
+%% 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).
+down(Config) ->
+ {Svc, Ref} = connect(Config, [{capabilities, [{'Acct-Application-Id',
+ [?DICT_ACCT:id()]}]},
+ {applications, [?DICT_ACCT]},
+ {reconnect_timer, 5000}]),
+ start = event(Svc),
+ {watchdog, Ref, _, {initial, down}, _} = event(Svc),
+ {closed, Ref, {'CEA', ?NO_COMMON_APP, _, #diameter_packet{}}, _}
+ = event(Svc),
+ {reconnect, Ref, _} = event(Svc).
+
+%% 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}]),
+ start = event(Svc),
+ {watchdog, Ref, _, {initial, down}, _} = event(Svc),
+ {closed, Ref, {'CEA', timeout}, _} = event(Svc).
+
+stop(_Config) ->
+ ok = diameter:stop().
+
+%% ----------------------------------------
+
+%% Keep the server from sending CEA until the client has timed out.
+capx_cb(_, #diameter_caps{origin_host = {_, "cea_timeout-" ++ _}}) ->
+ receive after ?SERVER_CAPX_TMO -> ok end;
+
+%% Or not.
+capx_cb(_, _Caps) ->
+ ok.
+
+%% ----------------------------------------
+
+%% Use the testcase name to construct Origin-Host of the client so
+%% that the server can match on it in capx_cb/2.
+connect(Config, Opts) ->
+ Pre = atom_to_list(proplists:get_value(name, Config)),
+ Name = Pre ++ uniq() ++ ?CLIENT,
+ diameter:subscribe(Name),
+ ok = start_service(Name, ?SERVICE(Name, [?DICT_COMMON, ?DICT_ACCT])),
+ {ok, Ref} = diameter:add_transport(Name, opts(Config, Opts)),
+ {Name, Ref}.
+
+uniq() ->
+ {MS,S,US} = now(),
+ lists:flatten(io_lib:format("-~p-~p-~p-", [MS,S,US])).
+
+event(Name) ->
+ receive #diameter_event{service = Name, info = T} -> T end.
+
+start_service(Name, Opts) ->
+ diameter:start_service(Name, [{monitor, self()} | Opts]).
+
+opts(Config, Opts) ->
+ PortNr = ?util:read_priv(Config, portnr),
+
+ {connect, [{transport_module, diameter_tcp},
+ {transport_config, [{ip, ?ADDR}, {port, 0},
+ {raddr, ?ADDR}, {rport, PortNr}]}
+ | Opts]}.
+
+realm(Host) ->
+ tl(lists:dropwhile(fun(C) -> C /= $. end, Host)).
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index c157b0e304..b03a9ce4d1 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -38,7 +38,9 @@
result_codes/1,
send_ok/1,
send_nok/1,
+ send_eval/1,
send_bad_answer/1,
+ send_protocol_error/1,
send_arbitrary/1,
send_unknown/1,
send_unknown_mandatory/1,
@@ -47,6 +49,9 @@
send_unsupported_app/1,
send_error_bit/1,
send_unsupported_version/1,
+ send_invalid_avp_bits/1,
+ send_invalid_avp_length/1,
+ send_invalid_reject/1,
send_long/1,
send_nopeer/1,
send_noapp/1,
@@ -112,17 +117,23 @@
%% Sequence mask for End-to-End and Hop-by-Hop identifiers.
-define(CLIENT_MASK, {1,26}). %% 1 in top 6 bits
-%% Run tests cases in different encoding variants. Send outgoing
-%% messages as lists or records.
+%% How to construct messages, as record or list.
-define(ENCODINGS, [list, record]).
-%% Identifers for client connections.
--define(CONNECTIONS, [c1,c2,c3]).
+%% How to send answers, in a diameter_packet or not.
+-define(CONTAINERS, [pkt, msg]).
+
+%% Send over multiple connections that are mapped onto
+%% [{E,P} || E <- ?ENCODINGS, P <- ?CONTAINERS].
+-define(CONNECTIONS, [c0,c1,c2,c3]).
%% Not really what we should be setting unless the message is sent in
%% the common application but diameter doesn't care.
-define(APP_ID, ?DIAMETER_APP_ID_COMMON).
+%% An Application-ID the server doesn't support.
+-define(BAD_APP, 42).
+
%% Config for diameter:start_service/2.
-define(SERVICE(Name),
[{'Origin-Host', Name ++ "." ++ ?REALM},
@@ -158,6 +169,8 @@
?'DIAMETER_BASE_RESULT-CODE_DIAMETER_REALM_NOT_SERVED').
-define(UNABLE_TO_DELIVER,
?'DIAMETER_BASE_RESULT-CODE_DIAMETER_UNABLE_TO_DELIVER').
+-define(INVALID_AVP_LENGTH,
+ ?'DIAMETER_BASE_RESULT-CODE_DIAMETER_INVALID_AVP_LENGTH').
-define(EVENT_RECORD,
?'DIAMETER_BASE_ACCOUNTING-RECORD-TYPE_EVENT_RECORD').
@@ -170,6 +183,8 @@
?'DIAMETER_BASE_TERMINATION-CAUSE_DIAMETER_LOGOUT').
-define(BAD_ANSWER,
?'DIAMETER_BASE_TERMINATION-CAUSE_DIAMETER_BAD_ANSWER').
+-define(USER_MOVED,
+ ?'DIAMETER_BASE_TERMINATION-CAUSE_DIAMETER_USER_MOVED').
-define(A, list_to_atom).
-define(L, atom_to_list).
@@ -183,14 +198,17 @@ suite() ->
all() ->
[start, start_services, add_transports, result_codes]
- ++ [{group, ?util:name([E,C]), P} || E <- ?ENCODINGS,
- C <- ?CONNECTIONS,
- P <- [[], [parallel]]]
+ ++ [{group, ?util:name([R,C,A]), P} || R <- ?ENCODINGS,
+ C <- ?CONTAINERS,
+ A <- ?ENCODINGS,
+ P <- [[], [parallel]]]
++ [remove_transports, stop_services, stop].
groups() ->
Ts = tc(),
- [{?util:name([E,C]), [], Ts} || E <- ?ENCODINGS, C <- ?CONNECTIONS].
+ [{?util:name([R,C,A]), [], Ts} || R <- ?ENCODINGS,
+ C <- ?CONTAINERS,
+ A <- ?ENCODINGS].
init_per_group(Name, Config) ->
[{group, Name} | Config].
@@ -209,7 +227,9 @@ end_per_testcase(_, _) ->
tc() ->
[send_ok,
send_nok,
+ send_eval,
send_bad_answer,
+ send_protocol_error,
send_arbitrary,
send_unknown,
send_unknown_mandatory,
@@ -218,6 +238,9 @@ tc() ->
send_unsupported_app,
send_error_bit,
send_unsupported_version,
+ send_invalid_avp_bits,
+ send_invalid_avp_length,
+ send_invalid_reject,
send_long,
send_nopeer,
send_noapp,
@@ -260,7 +283,9 @@ start_services(_Config) ->
add_transports(Config) ->
LRef = ?util:listen(?SERVER, tcp, [{capabilities_cb, fun capx/2}]),
- Cs = [?util:connect(?CLIENT, tcp, LRef, [{id, C}]) || C <- ?CONNECTIONS],
+ Cs = [?util:connect(?CLIENT, tcp, LRef, [{id, C},
+ {capabilities, [osi(C)]}])
+ || C <- ?CONNECTIONS],
?util:write_priv(Config, "transport", [LRef | Cs]).
remove_transports(Config) ->
@@ -278,11 +303,15 @@ capx(_, #diameter_caps{origin_host = {OH,DH}}) ->
io:format("connection: ~p -> ~p~n", [DH,OH]),
ok.
+osi(Id) ->
+ [$c,N] = atom_to_list(Id),
+ {'Origin-State-Id', N - $0}.
+
%% ===========================================================================
%% Ensure that result codes have the expected values.
result_codes(_Config) ->
- {2001, 3001, 3002, 3003, 3004, 3007, 3008, 3009, 5001, 5011}
+ {2001, 3001, 3002, 3003, 3004, 3007, 3008, 3009, 5001, 5011, 5014}
= {?SUCCESS,
?COMMAND_UNSUPPORTED,
?UNABLE_TO_DELIVER,
@@ -292,13 +321,14 @@ result_codes(_Config) ->
?INVALID_HDR_BITS,
?INVALID_AVP_BITS,
?AVP_UNSUPPORTED,
- ?UNSUPPORTED_VERSION}.
+ ?UNSUPPORTED_VERSION,
+ ?INVALID_AVP_LENGTH}.
%% Send an ACR and expect success.
send_ok(Config) ->
Req = ['ACR', {'Accounting-Record-Type', ?EVENT_RECORD},
{'Accounting-Record-Number', 1}],
-
+
#diameter_base_accounting_ACA{'Result-Code' = ?SUCCESS}
= call(Config, Req).
@@ -306,10 +336,18 @@ send_ok(Config) ->
send_nok(Config) ->
Req = ['ACR', {'Accounting-Record-Type', ?EVENT_RECORD},
{'Accounting-Record-Number', 0}],
-
+
#'diameter_base_answer-message'{'Result-Code' = ?INVALID_AVP_BITS}
= call(Config, Req).
+%% Send an ACR and expect success.
+send_eval(Config) ->
+ Req = ['ACR', {'Accounting-Record-Type', ?EVENT_RECORD},
+ {'Accounting-Record-Number', 3}],
+
+ #diameter_base_accounting_ACA{'Result-Code' = ?SUCCESS}
+ = call(Config, Req).
+
%% Send an accounting ACR that the server tries to answer with an
%% inappropriate header, resulting in no answer being sent and the
%% request timing out.
@@ -318,6 +356,15 @@ send_bad_answer(Config) ->
{'Accounting-Record-Number', 2}],
{error, timeout} = call(Config, Req).
+%% Send an ACR that the server callback answers explicitly with a
+%% protocol error.
+send_protocol_error(Config) ->
+ Req = ['ACR', {'Accounting-Record-Type', ?EVENT_RECORD},
+ {'Accounting-Record-Number', 4}],
+
+ #'diameter_base_answer-message'{'Result-Code' = ?TOO_BUSY}
+ = call(Config, Req).
+
%% Send an ASR with an arbitrary AVP and expect success and the same
%% AVP in the reply.
send_arbitrary(Config) ->
@@ -385,6 +432,29 @@ send_unsupported_version(Config) ->
#diameter_base_STA{'Result-Code' = ?UNSUPPORTED_VERSION}
= call(Config, Req).
+%% Send a request containing an incorrect AVP length.
+send_invalid_avp_bits(Config) ->
+ Req = ['STR', {'Termination-Cause', ?LOGOUT}],
+
+ #'diameter_base_answer-message'{'Result-Code' = ?INVALID_AVP_BITS}
+ = call(Config, Req).
+
+%% Send a request containing an AVP length that doesn't match the
+%% AVP's type.
+send_invalid_avp_length(Config) ->
+ Req = ['STR', {'Termination-Cause', ?LOGOUT}],
+
+ #'diameter_base_STA'{'Result-Code' = ?INVALID_AVP_LENGTH}
+ = call(Config, Req).
+
+%% Send a request containing 5xxx errors that the server rejects with
+%% 3xxx.
+send_invalid_reject(Config) ->
+ Req = ['STR', {'Termination-Cause', ?USER_MOVED}],
+
+ #'diameter_base_answer-message'{'Result-Code' = ?TOO_BUSY}
+ = call(Config, Req).
+
%% Send something long that will be fragmented by TCP.
send_long(Config) ->
Req = ['STR', {'Termination-Cause', ?LOGOUT},
@@ -559,21 +629,44 @@ call(Config, Req) ->
call(Config, Req, Opts) ->
Name = proplists:get_value(testcase, Config),
- [Encoding, Client] = ?util:name(proplists:get_value(group, Config)),
+ [Encoding, C, E] = ?util:name(proplists:get_value(group, Config)),
diameter:call(?CLIENT,
dict(Req),
- req(Req, Encoding),
- [{extra, [Name, Client]} | Opts]).
+ msg(Req, Encoding),
+ [{extra, [Name, client(E,C)]} | Opts]).
+
+client(E, C) ->
+ list_to_atom([$c, $0 + 2*codec(E) + container(C)]).
+
+client(N) ->
+ {codec(N bsr 1), container(N rem 2)}.
-req(['ACR' = H | T], record) ->
+codec(record) -> 0;
+codec(list) -> 1;
+codec(0) -> record;
+codec(1) -> list.
+
+%% Here we're just mapping booleans but the readable atoms are part of
+%% (constructed) group names, so it's good that they're readable.
+
+container(pkt) -> 0;
+container(msg) -> 1;
+container(0) -> pkt;
+container(1) -> msg.
+
+msg([H|T], record)
+ when H == 'ACR';
+ H == 'ACA' ->
?ACCT:'#new-'(?ACCT:msg2rec(H), T);
-req([H|T], record) ->
+msg([H|T], record) ->
?BASE:'#new-'(?BASE:msg2rec(H), T);
-req(T, _) ->
+msg(T, _) ->
T.
dict(['ACR' | _]) ->
?ACCT;
+dict(#diameter_base_accounting_ACR{}) ->
+ ?ACCT;
dict(_) ->
?BASE.
@@ -647,6 +740,40 @@ prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, send_detach, _, _) ->
log(#diameter_packet{} = P, T) ->
io:format("~p: ~p~n", [T,P]).
+%% prepare/3
+
+prepare(Pkt, Caps, send_invalid_avp_bits) ->
+ Req = prepare(Pkt, Caps),
+ %% Last AVP in our STR is Termination-Cause of type Unsigned32:
+ %% set its length improperly.
+ #diameter_packet{header = #diameter_header{length = L},
+ bin = B}
+ = E
+ = diameter_codec:encode(?BASE, Pkt#diameter_packet{msg = Req}),
+ Offset = L - 7, %% to AVP Length
+ <<H:Offset/binary, 12:24/integer, T:4/binary>> = B,
+ E#diameter_packet{bin = <<H/binary, 13:24/integer, T/binary>>};
+
+prepare(Pkt, Caps, N)
+ when N == send_invalid_avp_length;
+ N == send_invalid_reject ->
+ Req = prepare(Pkt, Caps),
+ %% Second last AVP in our STR is Auth-Application-Id of type
+ %% Unsigned32: Send a value of length 8.
+ #diameter_packet{header = #diameter_header{length = L},
+ bin = B0}
+ = E
+ = diameter_codec:encode(?BASE, Pkt#diameter_packet{msg = Req}),
+ Offset = L - 7 - 12, %% to AVP Length
+ <<H0:Offset/binary, 12:24/integer, T:16/binary>> = B0,
+ <<V, L:24/integer, H/binary>> = H0, %% assert
+ E#diameter_packet{bin = <<V,
+ (L+4):24/integer,
+ H/binary,
+ 16:24/integer,
+ 0:32/integer,
+ T/binary>>};
+
prepare(Pkt, Caps, send_unsupported) ->
Req = prepare(Pkt, Caps),
#diameter_packet{bin = <<H:5/binary, _CmdCode:3/binary, T/binary>>}
@@ -659,7 +786,7 @@ prepare(Pkt, Caps, send_unsupported_app) ->
#diameter_packet{bin = <<H:8/binary, _ApplId:4/binary, T/binary>>}
= E
= diameter_codec:encode(?BASE, Pkt#diameter_packet{msg = Req}),
- E#diameter_packet{bin = <<H/binary, 42:32/integer, T/binary>>};
+ E#diameter_packet{bin = <<H/binary, ?BAD_APP:32/integer, T/binary>>};
prepare(Pkt, Caps, send_error_bit) ->
#diameter_packet{header = Hdr} = Pkt,
@@ -678,6 +805,8 @@ prepare(Pkt, Caps, send_anything) ->
prepare(Pkt, Caps, _Name) ->
prepare(Pkt, Caps).
+%% prepare/2
+
prepare(#diameter_packet{msg = Req}, Caps)
when is_record(Req, diameter_base_accounting_ACR);
'ACR' == hd(Req) ->
@@ -741,9 +870,26 @@ handle_answer(Pkt, Req, ?CLIENT, Peer, Name, _Id) ->
handle_answer(Pkt, _Req, ?CLIENT, _Peer, send_detach, _Id, {Pid, Ref}) ->
Pid ! {Ref, Pkt}.
-answer(#diameter_packet{msg = Rec, errors = []}, _Req, _Peer, _) ->
+answer(Pkt, Req, _Peer, Name) ->
+ #diameter_packet{header = H, msg = Rec, errors = Es} = Pkt,
+ ApplId = app(Req, Name),
+ #diameter_header{application_id = ApplId} = H, %% assert
+ answer(Rec, Es, Name).
+
+answer(Rec, [_|_], N)
+ when N == send_invalid_avp_bits;
+ N == send_invalid_avp_length;
+ N == send_invalid_reject ->
+ Rec;
+answer(Rec, [], _) ->
Rec.
+app(_, send_unsupported_app) ->
+ ?BAD_APP;
+app(Req, _) ->
+ Dict = dict(Req),
+ Dict:id().
+
%% handle_error/6
handle_error(Reason, _Req, ?CLIENT, _Peer, _Name, _Id) ->
@@ -761,12 +907,24 @@ handle_request(#diameter_packet{header = H, msg = M}, ?SERVER, {_Ref, Caps}) ->
{V,B} = ?CLIENT_MASK,
V = EI bsr B, %% assert
V = HI bsr B, %%
- request(M, Caps).
+ #diameter_caps{origin_state_id = {_,[N]}} = Caps,
+ answer(client(N), request(M, Caps)).
+
+answer(T, {Tag, Action, Post}) ->
+ {Tag, answer(T, Action), Post};
+answer({E,C}, {reply, Ans}) ->
+ answer(C, {reply, msg(Ans, E)});
+answer(pkt, {reply, Ans}) ->
+ {reply, #diameter_packet{msg = Ans}};
+answer(_, T) ->
+ T.
+%% send_nok
request(#diameter_base_accounting_ACR{'Accounting-Record-Number' = 0},
_) ->
{eval_packet, {protocol_error, ?INVALID_AVP_BITS}, [fun log/2, invalid]};
+%% send_bad_answer
request(#diameter_base_accounting_ACR{'Session-Id' = SId,
'Accounting-Record-Type' = RT,
'Accounting-Record-Number' = 2 = RN},
@@ -779,12 +937,27 @@ request(#diameter_base_accounting_ACR{'Session-Id' = SId,
{'Accounting-Record-Type', RT},
{'Accounting-Record-Number', RN}],
- {reply, #diameter_packet{header = #diameter_header{is_error = true},%% not
+ {reply, #diameter_packet{header = #diameter_header{is_error = true},%% NOT
msg = Ans}};
+%% send_eval
+request(#diameter_base_accounting_ACR{'Session-Id' = SId,
+ 'Accounting-Record-Type' = RT,
+ 'Accounting-Record-Number' = 3 = RN},
+ #diameter_caps{origin_host = {OH, _},
+ origin_realm = {OR, _}}) ->
+ Ans = ['ACA', {'Result-Code', ?SUCCESS},
+ {'Session-Id', SId},
+ {'Origin-Host', OH},
+ {'Origin-Realm', OR},
+ {'Accounting-Record-Type', RT},
+ {'Accounting-Record-Number', RN}],
+ {eval, {reply, Ans}, {erlang, now, []}};
+
+%% send_ok
request(#diameter_base_accounting_ACR{'Session-Id' = SId,
'Accounting-Record-Type' = RT,
- 'Accounting-Record-Number' = RN},
+ 'Accounting-Record-Number' = 1 = RN},
#diameter_caps{origin_host = {OH, _},
origin_realm = {OR, _}}) ->
{reply, ['ACA', {'Result-Code', ?SUCCESS},
@@ -794,26 +967,42 @@ request(#diameter_base_accounting_ACR{'Session-Id' = SId,
{'Accounting-Record-Type', RT},
{'Accounting-Record-Number', RN}]};
+%% send_protocol_error
+request(#diameter_base_accounting_ACR{'Accounting-Record-Number' = 4},
+ #diameter_caps{origin_host = {OH, _},
+ origin_realm = {OR, _}}) ->
+ Ans = ['answer-message', {'Result-Code', ?TOO_BUSY},
+ {'Origin-Host', OH},
+ {'Origin-Realm', OR}],
+ {reply, Ans};
+
request(#diameter_base_ASR{'Session-Id' = SId,
'AVP' = Avps},
#diameter_caps{origin_host = {OH, _},
origin_realm = {OR, _}}) ->
- {reply, #diameter_base_ASA{'Result-Code' = ?SUCCESS,
- 'Session-Id' = SId,
- 'Origin-Host' = OH,
- 'Origin-Realm' = OR,
- 'AVP' = Avps}};
+ {reply, ['ASA', {'Result-Code', ?SUCCESS},
+ {'Session-Id', SId},
+ {'Origin-Host', OH},
+ {'Origin-Realm', OR},
+ {'AVP', Avps}]};
+
+%% send_invalid_reject
+request(#diameter_base_STR{'Termination-Cause' = ?USER_MOVED}, _Caps) ->
+ {protocol_error, ?TOO_BUSY};
+%% send_noreply
request(#diameter_base_STR{'Termination-Cause' = T},
_Caps)
when T /= ?LOGOUT ->
discard;
+%% send_destination_5
request(#diameter_base_STR{'Destination-Realm'= R},
#diameter_caps{origin_realm = {OR, _}})
when R /= undefined, R /= OR ->
{protocol_error, ?REALM_NOT_SERVED};
+%% send_destination_6
request(#diameter_base_STR{'Destination-Host'= [H]},
#diameter_caps{origin_host = {OH, _}})
when H /= OH ->
@@ -822,11 +1011,12 @@ request(#diameter_base_STR{'Destination-Host'= [H]},
request(#diameter_base_STR{'Session-Id' = SId},
#diameter_caps{origin_host = {OH, _},
origin_realm = {OR, _}}) ->
- {reply, #diameter_base_STA{'Result-Code' = ?SUCCESS,
- 'Session-Id' = SId,
- 'Origin-Host' = OH,
- 'Origin-Realm' = OR}};
+ {reply, ['STA', {'Result-Code', ?SUCCESS},
+ {'Session-Id', SId},
+ {'Origin-Host', OH},
+ {'Origin-Realm', OR}]};
+%% send_error
request(#diameter_base_RAR{}, _Caps) ->
receive after 2000 -> ok end,
{protocol_error, ?TOO_BUSY}.
diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk
index 5898e125ae..80b1769d04 100644
--- a/lib/diameter/test/modules.mk
+++ b/lib/diameter/test/modules.mk
@@ -40,7 +40,8 @@ MODULES = \
diameter_relay_SUITE \
diameter_tls_SUITE \
diameter_failover_SUITE \
- diameter_dpr_SUITE
+ diameter_dpr_SUITE \
+ diameter_event_SUITE
HRL_FILES = \
diameter_ct.hrl
diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk
index c9f74ffcec..74f4c57b70 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2012. All Rights Reserved.
+# Copyright Ericsson AB 2010-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
@@ -18,8 +18,5 @@
# %CopyrightEnd%
APPLICATION = diameter
-DIAMETER_VSN = 1.3
-PRE_VSN =
-APP_VSN = "$(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)"
-
-TICKETS =
+DIAMETER_VSN = 1.4
+APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)
diff --git a/lib/edoc/priv/Makefile b/lib/edoc/priv/Makefile
index 73c42c05eb..9873136201 100644
--- a/lib/edoc/priv/Makefile
+++ b/lib/edoc/priv/Makefile
@@ -27,8 +27,11 @@ GEN_SCRIPT_SRC = edoc_generate.src
GEN_SCRIPT = edoc_generate
PRIV_FILES = stylesheet.css erlang.png edoc.dtd
-debug opt:
- sed -e "s/%EDOC_VSN%/$(EDOC_VSN)/g" \
+debug opt: $(GEN_SCRIPT)
+
+$(GEN_SCRIPT): ../vsn.mk ../../xmerl/vsn.mk ../../syntax_tools/vsn.mk \
+ $(GEN_SCRIPT_SRC)
+ $(vsn_verbose)sed -e "s/%EDOC_VSN%/$(EDOC_VSN)/g" \
-e "s/%XMERL_VSN%/$(XMERL_VSN)/g" \
-e "s/%SYNTAX_TOOLS_VSN%/$(SYNTAX_TOOLS_VSN)/g" \
$(GEN_SCRIPT_SRC) > $(GEN_SCRIPT)
diff --git a/lib/edoc/src/Makefile b/lib/edoc/src/Makefile
index 72354ac711..4e5a4182da 100644
--- a/lib/edoc/src/Makefile
+++ b/lib/edoc/src/Makefile
@@ -67,17 +67,17 @@ distclean: clean
realclean: clean
$(EBIN)/%.$(EMULATOR):%.erl
- erlc -W $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index 04dad2eee7..bd6f00af1f 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -68,7 +68,7 @@ filter() See present/1, substrings/2,
<fsummary>Open a connection to an LDAP server.</fsummary>
<type>
<v>Handle = handle()</v>
- <v>Option = {port, integer()} | {log, function()} | {timeout, integer()} | {ssl, boolean()}</v>
+ <v>Option = {port, integer()} | {log, function()} | {timeout, integer()} | {ssl, boolean()} | {sslopts, list()}</v>
</type>
<desc>
<p>Setup a connection to an LDAP server, the <c>HOST</c>'s are tried in order.</p>
diff --git a/lib/eldap/src/Makefile b/lib/eldap/src/Makefile
index 46fb805bcc..e7cbb776bd 100644
--- a/lib/eldap/src/Makefile
+++ b/lib/eldap/src/Makefile
@@ -59,7 +59,7 @@ APP_TARGET = $(EBIN)/$(APP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I../include -I../ebin
+ERL_COMPILE_FLAGS += -I../include -I../ebin -Werror
# ----------------------------------------------------
# Targets
@@ -75,10 +75,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(ELDAP_VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(ELDAP_VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(ELDAP_VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(ELDAP_VSN);' $< > $@
docs:
@@ -88,7 +88,7 @@ $(TARGET_FILES): $(HRL_FILES)
# Special Build Targets
# ----------------------------------------------------
$(ASN1_HRL): ../asn1/$(ASN1_FILES)
- $(ERLC) -o $(EBIN) -bber $(ERL_COMPILE_FLAGS) ../asn1/ELDAPv3.asn1
+ $(asn_verbose)$(ERLC) -o $(EBIN) -bber $(ERL_COMPILE_FLAGS) ../asn1/ELDAPv3.asn1
# ----------------------------------------------------
# Release Target
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index 5753cc4749..d11f904996 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -42,7 +42,8 @@
log, % User provided log function
timeout = infinity, % Request timeout
anon_auth = false, % Allow anonymous authentication
- use_tls = false % LDAP/LDAPS
+ use_tls = false, % LDAP/LDAPS
+ tls_opts = [] % ssl:ssloptsion()
}).
%%% For debug purposes
@@ -353,6 +354,10 @@ parse_args([{ssl, true}|T], Cpid, Data) ->
parse_args(T, Cpid, Data#eldap{use_tls = true});
parse_args([{ssl, _}|T], Cpid, Data) ->
parse_args(T, Cpid, Data);
+parse_args([{sslopts, Opts}|T], Cpid, Data) when is_list(Opts) ->
+ parse_args(T, Cpid, Data#eldap{use_tls = true, tls_opts = Opts ++ Data#eldap.tls_opts});
+parse_args([{sslopts, _}|T], Cpid, Data) ->
+ parse_args(T, Cpid, Data);
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) ->
@@ -384,8 +389,8 @@ try_connect([],_) ->
do_connect(Host, Data, Opts) when Data#eldap.use_tls == false ->
gen_tcp:connect(Host, Data#eldap.port, Opts, Data#eldap.timeout);
do_connect(Host, Data, Opts) when Data#eldap.use_tls == true ->
- ssl:connect(Host, Data#eldap.port, [{verify,0}|Opts]).
-
+ SslOpts = [{verify,0} | Opts ++ Data#eldap.tls_opts],
+ ssl:connect(Host, Data#eldap.port, SslOpts).
loop(Cpid, Data) ->
receive
@@ -694,7 +699,6 @@ do_recv(S, #eldap{use_tls=true, timeout=Timeout}, Len) ->
recv_response(S, Data) ->
case do_recv(S, Data, 0) of
{ok, Packet} ->
- check_tag(Packet),
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Packet) of
{ok,Resp} -> {ok,Resp};
Error -> throw(Error)
@@ -703,21 +707,6 @@ recv_response(S, Data) ->
throw({gen_tcp_error, Reason})
end.
-%%% Sanity check of received packet
-check_tag(Data) ->
- try
- {_Tag, Data1, _Rb} = asn1rt_ber_bin:decode_tag(l2b(Data)),
- try
- {{_Len, _Data2}, _Rb2} = asn1rt_ber_bin:decode_length(l2b(Data1)),
- ok
- catch
- _ -> throw({error,decoded_tag_length})
- end
- catch
- _ ->
- throw({error, decoded_tag})
- end.
-
%%% Check for expected kind of reply
check_reply(Data, {ok,Msg}, Op) when
Msg#'LDAPMessage'.messageID == Data#eldap.id ->
@@ -1110,7 +1099,3 @@ get_head(Str,Tail) ->
%%% Should always succeed !
get_head([H|Tail],Tail,Rhead) -> lists:reverse([H|Rhead]);
get_head([H|Rest],Tail,Rhead) -> get_head(Rest,Tail,[H|Rhead]).
-
-l2b(B) when is_binary(B) -> B;
-l2b(L) when is_list(L) -> list_to_binary(L).
-
diff --git a/lib/erl_docgen/priv/dtd/common.refs.dtd b/lib/erl_docgen/priv/dtd/common.refs.dtd
index c1237766e1..93592607df 100644
--- a/lib/erl_docgen/priv/dtd/common.refs.dtd
+++ b/lib/erl_docgen/priv/dtd/common.refs.dtd
@@ -26,10 +26,12 @@
<!ELEMENT description (%block;|quote|br|marker|warning|note)* >
<!ELEMENT funcs (func)+ >
-<!ELEMENT func (name+,type_desc+,fsummary,type?,desc?) >
+<!ELEMENT func (name+,type_desc*,fsummary,type?,desc?) >
<!-- ELEMENT name is defined in each ref dtd -->
<!ELEMENT fsummary (#PCDATA|c|em)* >
-<!ELEMENT type (v,d?)+ >
+<!ELEMENT type (v,d?)* >
+<!ATTLIST type variable CDATA #IMPLIED
+ name_i CDATA #IMPLIED>
<!ELEMENT v (#PCDATA) >
<!ELEMENT d (#PCDATA|c|em)* >
<!ELEMENT desc (%block;|quote|br|marker|warning|note|anno)* >
@@ -41,3 +43,4 @@
<!ELEMENT datatypes (datatype)+ >
<!ELEMENT datatype (name+,desc?) >
<!ELEMENT type_desc (#PCDATA) >
+<!ATTLIST type_desc variable CDATA #REQUIRED>
diff --git a/lib/erl_docgen/priv/dtd/erlref.dtd b/lib/erl_docgen/priv/dtd/erlref.dtd
index 9905086ff4..0cc5cfa06d 100644
--- a/lib/erl_docgen/priv/dtd/erlref.dtd
+++ b/lib/erl_docgen/priv/dtd/erlref.dtd
@@ -29,3 +29,6 @@
<!-- `name' is used in common.refs.dtd and must therefore
be defined in each *ref. dtd -->
<!ELEMENT name (#PCDATA) >
+<!ATTLIST name name CDATA #IMPLIED
+ arity CDATA #IMPLIED
+ clause_i CDATA #IMPLIED>
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index 7de5af2a49..c846bdbf34 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -1102,11 +1102,13 @@
<xsl:template match="taglist/item">
<xsl:param name="partnum"/>
- <fo:block xsl:use-attribute-sets="tagitem">
- <xsl:apply-templates>
- <xsl:with-param name="partnum" select="$partnum"/>
- </xsl:apply-templates>
- </fo:block>
+ <fo:block-container>
+ <fo:block xsl:use-attribute-sets="tagitem">
+ <xsl:apply-templates>
+ <xsl:with-param name="partnum" select="$partnum"/>
+ </xsl:apply-templates>
+ </fo:block>
+ </fo:block-container>
</xsl:template>
diff --git a/lib/erl_docgen/src/Makefile b/lib/erl_docgen/src/Makefile
index 6c8b438b25..ef96f5dbf2 100644
--- a/lib/erl_docgen/src/Makefile
+++ b/lib/erl_docgen/src/Makefile
@@ -78,10 +78,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 2599dc0ff7..a2262198dc 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1,2 +1 @@
-ERL_DOCGEN_VSN = 0.3.3
-
+ERL_DOCGEN_VSN = 0.3.4
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
index 5d555a5123..918e30a886 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -1861,17 +1861,16 @@ 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 CFLAGS])
+ AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $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 $CFLAGS")
+ AS_VAR_SET($2, "$1 $$2")
else
AC_MSG_RESULT([no])
- AS_VAR_SET($2, "$CFLAGS")
fi
])
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 539e16d837..117c787da6 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -82,6 +82,25 @@
function returns the size required (note that for strings an
extra byte is needed for the 0 string terminator).</p>
</description>
+ <section>
+ <title>DATA TYPES</title>
+
+ <taglist>
+ <tag><marker id="erlang_char_encoding"/>enum erlang_char_encoding</tag>
+ <item>
+ <p/>
+ <code type="none">
+enum erlang_char_encoding {
+ ERLANG_ASCII, ERLANG_LATIN1, ERLANG_UTF8
+};
+</code>
+ <p>The character encoding used for atoms. <c>ERLANG_ASCII</c> represents 7-bit ASCII.
+ Latin1 and UTF8 are different extensions of 7-bit ASCII. All 7-bit ASCII characters
+ are valid Latin1 and UTF8 characters. ASCII and Latin1 both represent each character
+ by one byte. A UTF8 character can consist of one to four bytes.</p>
+ </item>
+ </taglist>
+ </section>
<funcs>
<func>
<name><ret>void</ret><nametext>ei_set_compat_rel(release_number)</nametext></name>
@@ -225,12 +244,32 @@
<fsummary>Encode an atom</fsummary>
<desc>
<p>Encodes an atom in the binary format. The <c><![CDATA[p]]></c> parameter
- is the name of the atom. Only upto <c><![CDATA[MAXATOMLEN]]></c> bytes
+ is the name of the atom in latin1 encoding. Only upto <c>MAXATOMLEN-1</c> bytes
are encoded. The name should be zero-terminated, except for
the <c><![CDATA[ei_x_encode_atom_len()]]></c> function.</p>
</desc>
</func>
<func>
+ <name><ret>int</ret><nametext>ei_encode_atom_as(char *buf, int *index, const char *p, enum erlang_char_encoding from_enc, enum erlang_char_encoding to_enc)</nametext></name>
+ <name><ret>int</ret><nametext>ei_encode_atom_len_as(char *buf, int *index, const char *p, int len, enum erlang_char_encoding from_enc, enum erlang_char_encoding to_enc)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_atom_as(ei_x_buff* x, const char *p, enum erlang_char_encoding from_enc, enum erlang_char_encoding to_enc)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_atom_len_as(ei_x_buff* x, const char *p, int len, enum erlang_char_encoding from_enc, enum erlang_char_encoding to_enc)</nametext></name>
+ <fsummary>Encode an atom</fsummary>
+ <desc>
+ <p>Encodes an atom in the binary format with character encoding
+ <c><seealso marker="#erlang_char_encoding">to_enc</seealso></c> (latin1 or utf8).
+ The <c>p</c> parameter is the name of the atom with character encoding
+ <c><seealso marker="#erlang_char_encoding">from_enc</seealso></c> (ascii, latin1 or utf8).
+ The name must either be zero-terminated or a function variant with a <c>len</c>
+ parameter must be used.</p>
+ <p>The encoding will fail if <c>p</c> is not a valid string in encoding <c>from_enc</c>,
+ if the string is too long or if it can not be represented with character encoding <c>to_enc</c>.</p>
+ <p>These functions were introduced in R16 release of Erlang/OTP as part of a first step
+ to support UTF8 atoms. Atoms encoded with <c>ERLANG_UTF8</c>
+ can not be decoded by earlier releases than R16.</p>
+ </desc>
+ </func>
+ <func>
<name><ret>int</ret><nametext>ei_encode_binary(char *buf, int *index, const void *p, long len)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_binary(ei_x_buff* x, const void *p, long len)</nametext></name>
<fsummary>Encode a binary</fsummary>
@@ -490,11 +529,32 @@ ei_x_encode_empty_list(&amp;x);
<fsummary>Decode an atom</fsummary>
<desc>
<p>This function decodes an atom from the binary format. The
- name of the atom is placed at <c><![CDATA[p]]></c>. There can be at most
+ null terminated name of the atom is placed at <c><![CDATA[p]]></c>. There can be at most
<c><![CDATA[MAXATOMLEN]]></c> bytes placed in the buffer.</p>
</desc>
</func>
<func>
+ <name><ret>int</ret><nametext>ei_decode_atom_as(const char *buf, int *index, char *p, int plen, enum erlang_char_encoding want, enum erlang_char_encoding* was, enum erlang_char_encoding* result)</nametext></name>
+ <fsummary>Decode an atom</fsummary>
+ <desc>
+ <p>This function decodes an atom from the binary format. The
+ null terminated name of the atom is placed in buffer at <c>p</c> of length
+ <c>plen</c> bytes.</p>
+ <p>The wanted string encoding is specified by <c><seealso marker="#erlang_char_encoding">
+ want</seealso></c>. The original encoding used in the
+ binary format (latin1 or utf8) can be obtained from <c>*was</c>. The actual encoding of the resulting string
+ (7-bit ascii, latin1 or utf8) can be obtained from <c>*result</c>. Both <c>was</c> and <c>result</c> can be <c>NULL</c>.
+
+ <c>*result</c> may differ from <c>want</c> if <c>want</c> is a bitwise-or'd combination like
+ <c>ERLANG_LATIN1|ERLANG_UTF8</c> or if <c>*result</c> turn out to be pure 7-bit ascii
+ (compatible with both latin1 and utf8).</p>
+ <p>This function fails if the atom is too long for the buffer
+ or if it can not be represented with encoding <c>want</c>.</p>
+ <p>This function was introduced in R16 release of Erlang/OTP as part of a first step
+ to support UTF8 atoms.</p>
+ </desc>
+ </func>
+ <func>
<name><ret>int</ret><nametext>ei_decode_binary(const char *buf, int *index, void *p, long *len)</nametext></name>
<fsummary>Decode a binary</fsummary>
<desc>
diff --git a/lib/erl_interface/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml
index f403618c59..c7840d7813 100644
--- a/lib/erl_interface/doc/src/erl_eterm.xml
+++ b/lib/erl_interface/doc/src/erl_eterm.xml
@@ -77,10 +77,12 @@
</p>
<taglist>
<tag><c><![CDATA[char *ERL_ATOM_PTR(t)]]></c></tag>
+ <tag><c><![CDATA[char *ERL_ATOM_PTR_UTF8(t)]]></c></tag>
<item>A string representing atom <c><![CDATA[t]]></c>.
</item>
<tag><c><![CDATA[int ERL_ATOM_SIZE(t)]]></c></tag>
- <item>The length (in characters) of atom t.</item>
+ <tag><c><![CDATA[int ERL_ATOM_SIZE_UTF8(t)]]></c></tag>
+ <item>The length (in bytes) of atom t.</item>
<tag><c><![CDATA[void *ERL_BIN_PTR(t)]]></c></tag>
<item>A pointer to the contents of <c><![CDATA[t]]></c></item>
<tag><c><![CDATA[int ERL_BIN_SIZE(t)]]></c></tag>
@@ -92,6 +94,7 @@
<tag><c><![CDATA[double ERL_FLOAT_VALUE(t)]]></c></tag>
<item>The floating point value of <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[ETERM *ERL_PID_NODE(t)]]></c></tag>
+ <tag><c><![CDATA[ETERM *ERL_PID_NODE_UTF8(t)]]></c></tag>
<item>The Node in pid <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[int ERL_PID_NUMBER(t)]]></c></tag>
<item>The sequence number in pid <c><![CDATA[t]]></c>.</item>
@@ -104,6 +107,7 @@
<tag><c><![CDATA[int ERL_PORT_CREATION(t)]]></c></tag>
<item>The creation number in port <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[ETERM *ERL_PORT_NODE(t)]]></c></tag>
+ <tag><c><![CDATA[ETERM *ERL_PORT_NODE_UTF8(t)]]></c></tag>
<item>The node in port <c><![CDATA[t]]></c>.</item>
<tag><c><![CDATA[int ERL_REF_NUMBER(t)]]></c></tag>
<item>The first part of the reference number in ref <c><![CDATA[t]]></c>. Use
@@ -296,7 +300,7 @@ iohead ::= Binary
<name><ret>ETERM *</ret><nametext>erl_mk_atom(string)</nametext></name>
<fsummary>Creates an atom</fsummary>
<type>
- <v>char *string;</v>
+ <v>const char *string;</v>
</type>
<desc>
<p>Creates an atom.</p>
@@ -305,10 +309,12 @@ iohead ::= Binary
<p>Returns an Erlang term containing an atom. Note that it is
the callers responsibility to make sure that <c><![CDATA[string]]></c>
contains a valid name for an atom.</p>
- <p><c><![CDATA[ERL_ATOM_PTR(atom)]]></c> can be used to retrieve the
- atom name (as a string). Note that the string is not
- 0-terminated in the atom. <c><![CDATA[ERL_ATOM_SIZE(atom)]]></c>returns
- the length of the atom name.</p>
+ <p><c><![CDATA[ERL_ATOM_PTR(atom)]]></c> and <c><![CDATA[ERL_ATOM_PTR_UTF8(atom)]]></c>
+ can be used to retrieve the atom name (as a null terminated string). <c><![CDATA[ERL_ATOM_SIZE(atom)]]></c>
+ and <c><![CDATA[ERL_ATOM_SIZE_UTF8(atom)]]></c> returns the length of the atom name.</p>
+ <note><p>Note that the UTF8 variants were introduced in Erlang/OTP releases R16
+ and the string returned by <c>ERL_ATOM_PTR(atom)</c> was not null terminated on older releases.</p>
+ </note>
</desc>
</func>
<func>
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index ae815b414a..2278a28adb 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -115,6 +115,9 @@
#define ERL_FLOAT_EXT 'c'
#define NEW_FLOAT_EXT 'F'
#define ERL_ATOM_EXT 'd'
+#define ERL_SMALL_ATOM_EXT 's'
+#define ERL_ATOM_UTF8_EXT 'v'
+#define ERL_SMALL_ATOM_UTF8_EXT 'w'
#define ERL_REFERENCE_EXT 'e'
#define ERL_NEW_REFERENCE_EXT 'r'
#define ERL_PORT_EXT 'f'
@@ -183,12 +186,21 @@ extern volatile int __erl_errno;
#define EI_MAXHOSTNAMELEN 64
#define EI_MAXALIVELEN 63
#define EI_MAX_COOKIE_SIZE 512
-#define MAXATOMLEN 255
+#define MAXATOMLEN (255 + 1)
+#define MAXATOMLEN_UTF8 (255*4 + 1)
#define MAXNODELEN EI_MAXALIVELEN+1+EI_MAXHOSTNAMELEN
+enum erlang_char_encoding {
+ ERLANG_ASCII = 1,
+ ERLANG_LATIN1 = 2,
+ ERLANG_UTF8 = 4,
+ ERLANG_ANY = ERLANG_ASCII|ERLANG_LATIN1|ERLANG_UTF8
+};
+
/* a pid */
typedef struct {
- char node[MAXATOMLEN+1];
+ char node[MAXATOMLEN_UTF8];
+ enum erlang_char_encoding node_org_enc;
unsigned int num;
unsigned int serial;
unsigned int creation;
@@ -196,14 +208,16 @@ typedef struct {
/* a port */
typedef struct {
- char node[MAXATOMLEN+1];
+ char node[MAXATOMLEN_UTF8];
+ enum erlang_char_encoding node_org_enc;
unsigned int id;
unsigned int creation;
} erlang_port;
/* a ref */
typedef struct {
- char node[MAXATOMLEN+1];
+ char node[MAXATOMLEN_UTF8];
+ enum erlang_char_encoding node_org_enc;
int len;
unsigned int n[3];
unsigned int creation;
@@ -223,15 +237,16 @@ typedef struct {
long msgtype;
erlang_pid from;
erlang_pid to;
- char toname[MAXATOMLEN+1];
- char cookie[MAXATOMLEN+1];
+ char toname[MAXATOMLEN_UTF8];
+ char cookie[MAXATOMLEN_UTF8];
erlang_trace token;
} erlang_msg;
/* a fun */
typedef struct {
long arity;
- char module[MAXATOMLEN+1];
+ char module[MAXATOMLEN_UTF8];
+ enum erlang_char_encoding module_org_enc;
char md5[16];
long index;
long old_index;
@@ -256,7 +271,7 @@ typedef struct {
union {
long i_val;
double d_val;
- char atom_name[MAXATOMLEN+1];
+ char atom_name[MAXATOMLEN_UTF8];
erlang_pid pid;
erlang_port port;
erlang_ref ref;
@@ -425,9 +440,17 @@ int ei_encode_string_len(char *buf, int *index, const char *p, int len);
int ei_x_encode_string(ei_x_buff* x, const char* s);
int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len);
int ei_encode_atom(char *buf, int *index, const char *p);
+int ei_encode_atom_as(char *buf, int *index, const char *p,
+ enum erlang_char_encoding from, enum erlang_char_encoding to);
int ei_encode_atom_len(char *buf, int *index, const char *p, int len);
+int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
+ enum erlang_char_encoding from, enum erlang_char_encoding to);
int ei_x_encode_atom(ei_x_buff* x, const char* s);
+int ei_x_encode_atom_as(ei_x_buff* x, const char* s,
+ enum erlang_char_encoding from, enum erlang_char_encoding to);
int ei_x_encode_atom_len(ei_x_buff* x, const char* s, int len);
+int ei_x_encode_atom_len_as(ei_x_buff* x, const char* s, int len,
+ enum erlang_char_encoding from, enum erlang_char_encoding to);
int ei_encode_binary(char *buf, int *index, const void *p, long len);
int ei_x_encode_binary(ei_x_buff* x, const void* s, int len);
int ei_encode_pid(char *buf, int *index, const erlang_pid *p);
@@ -477,6 +500,7 @@ int ei_decode_boolean(const char *buf, int *index, int *p);
int ei_decode_char(const char *buf, int *index, char *p);
int ei_decode_string(const char *buf, int *index, char *p);
int ei_decode_atom(const char *buf, int *index, char *p);
+int ei_decode_atom_as(const char *buf, int *index, char *p, int destlen, enum erlang_char_encoding want, enum erlang_char_encoding* was, enum erlang_char_encoding* result);
int ei_decode_binary(const char *buf, int *index, void *p, long *len);
int ei_decode_fun(const char* buf, int* index, erlang_fun* p);
void free_fun(erlang_fun* f);
diff --git a/lib/erl_interface/include/erl_interface.h b/lib/erl_interface/include/erl_interface.h
index 1c4a94700d..98acc0d71d 100644
--- a/lib/erl_interface/include/erl_interface.h
+++ b/lib/erl_interface/include/erl_interface.h
@@ -95,19 +95,24 @@
#define ERL_FLOAT_VALUE(x) ((x)->uval.fval.f)
-#define ERL_ATOM_PTR(x) ((x)->uval.aval.a)
-#define ERL_ATOM_SIZE(x) ((x)->uval.aval.len)
+#define ERL_ATOM_PTR(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.aval.d)
+#define ERL_ATOM_PTR_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.aval.d)
+#define ERL_ATOM_SIZE(x) erl_atom_size_latin1((Erl_Atom_data*) &(x)->uval.aval.d)
+#define ERL_ATOM_SIZE_UTF8(x) erl_atom_size_utf8((Erl_Atom_data*) &(x)->uval.aval.d)
-#define ERL_PID_NODE(x) ((x)->uval.pidval.node)
+#define ERL_PID_NODE(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.pidval.node)
+#define ERL_PID_NODE_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.pidval.node)
#define ERL_PID_NUMBER(x) ((x)->uval.pidval.number)
#define ERL_PID_SERIAL(x) ((x)->uval.pidval.serial)
#define ERL_PID_CREATION(x) ((x)->uval.pidval.creation)
-#define ERL_PORT_NODE(x) ((x)->uval.portval.node)
+#define ERL_PORT_NODE(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.portval.node)
+#define ERL_PORT_NODE_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.portval.node)
#define ERL_PORT_NUMBER(x) ((x)->uval.portval.number)
#define ERL_PORT_CREATION(x) ((x)->uval.portval.creation)
-#define ERL_REF_NODE(x) ((x)->uval.refval.node)
+#define ERL_REF_NODE(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.refval.node)
+#define ERL_REF_NODE_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.refval.node)
#define ERL_REF_NUMBER(x) ((x)->uval.refval.n[0])
#define ERL_REF_NUMBERS(x) ((x)->uval.refval.n)
#define ERL_REF_LEN(x) ((x)->uval.refval.len)
@@ -183,14 +188,26 @@ typedef struct {
} Erl_Float;
typedef struct {
+ char *utf8;
+ int lenU;
+ char *latin1;
+ int lenL;
+} Erl_Atom_data;
+
+char* erl_atom_ptr_latin1(Erl_Atom_data*);
+char* erl_atom_ptr_utf8(Erl_Atom_data*);
+int erl_atom_size_latin1(Erl_Atom_data*);
+int erl_atom_size_utf8(Erl_Atom_data*);
+char* erl_atom_init_latin1(Erl_Atom_data*, const char*);
+
+typedef struct {
Erl_Header h;
- int len;
- char *a;
+ Erl_Atom_data d;
} Erl_Atom;
typedef struct {
Erl_Header h;
- char * node;
+ Erl_Atom_data node;
unsigned int number;
unsigned int serial;
unsigned char creation;
@@ -198,14 +215,14 @@ typedef struct {
typedef struct {
Erl_Header h;
- char * node;
+ Erl_Atom_data node;
unsigned int number;
unsigned char creation;
} Erl_Port;
typedef struct {
Erl_Header h;
- char * node;
+ Erl_Atom_data node;
int len;
unsigned int n[3];
unsigned char creation;
@@ -289,7 +306,7 @@ typedef struct _eterm {
} ETERM;
-#define MAXREGLEN 255 /* max length of registered (atom) name */
+#define MAXREGLEN (255*4) /* max length of registered (atom) name */
typedef struct {
int type; /* one of the message type constants in eiext.h */
@@ -409,6 +426,7 @@ unsigned char erl_ext_type(unsigned char*); /* Note: returned 'char' before R9C
unsigned char *erl_peek_ext(unsigned char*,int);
int erl_term_len(ETERM*);
+int cmp_latin1_vs_utf8(const char* sL, int lenL, const char* sU, int lenU);
/* -------------------------------------------------------------------- */
/* Wrappers around ei functions */
diff --git a/lib/erl_interface/src/Makefile b/lib/erl_interface/src/Makefile
index 5f0367bec1..03e2ce14f0 100644
--- a/lib/erl_interface/src/Makefile
+++ b/lib/erl_interface/src/Makefile
@@ -22,10 +22,11 @@
# FIXME let configure put in this last part TARGET
+include $(ERL_TOP)/make/output.mk
include $(ERL_TOP)/make/target.mk
debug opt shared purify quantify purecov gcov:
- $(MAKE) -f $(TARGET)/Makefile TYPE=$@
+ $(make_verbose)$(MAKE) -f $(TARGET)/Makefile TYPE=$@
clean depend docs release release_docs tests release_tests check:
- $(MAKE) -f $(TARGET)/Makefile $@
+ $(make_verbose)$(MAKE) -f $(TARGET)/Makefile $@
diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in
index cb41391fe9..ebacc1cee0 100644
--- a/lib/erl_interface/src/Makefile.in
+++ b/lib/erl_interface/src/Makefile.in
@@ -38,6 +38,8 @@ TARGET = @TARGET@
include ../vsn.mk
include $(TARGET)/eidefs.mk
+include $(ERL_TOP)/make/output.mk
+
USING_MINGW=@MIXED_CYGWIN_MINGW@
USING_MSYS_VC==@MIXED_MSYS_VC@
USING_CYGWIN_VC==@MIXED_MSYS_VC@
@@ -98,6 +100,12 @@ LD = @LD@
AR = @AR@
RANLIB = @RANLIB@
+ifeq ($(V),0)
+AR_FLAGS=rc
+else
+AR_FLAGS=rcv
+endif
+
INCFLAGS = -I. -I../include -Iconnect -Iencode -Idecode -Imisc -Iepmd \
-Iregistry -I$(TARGET)
@@ -552,16 +560,18 @@ distclean: clean
ifeq ($(findstring vxworks,$(TARGET)),vxworks)
$(TARGET)/config.h:
- echo "/* Generated by Makefile */" > $@
- echo "#define HAVE_STRERROR 1" >> $@
- echo "#define HAVE_SOCKLEN_T 1" >> $@
+ $(gen_verbose)
+ $(V_at)echo "/* Generated by Makefile */" > $@
+ $(V_at)echo "#define HAVE_STRERROR 1" >> $@
+ $(V_at)echo "#define HAVE_SOCKLEN_T 1" >> $@
endif
ifeq ($(findstring ose,$(TARGET)),ose)
$(TARGET)/config.h:
- echo "/* Generated by Makefile */" > $@
- echo "#define HAVE_STRERROR 1" >> $@
- echo "#define HAVE_SOCKLEN_T 1" >> $@
+ $(gen_verbose)
+ $(V_at)echo "/* Generated by Makefile */" > $@
+ $(V_at)echo "#define HAVE_STRERROR 1" >> $@
+ $(V_at)echo "#define HAVE_SOCKLEN_T 1" >> $@
endif
###########################################################################
@@ -569,19 +579,19 @@ endif
###########################################################################
$(ST_OBJDIR)/%.o: %.c
- $(CC) $(CFLAGS) -c $< -o $@
+ $(V_CC) $(CFLAGS) -c $< -o $@
$(MT_OBJDIR)/%.o: %.c
- $(CC) $(MTFLAG) $(CFLAGS) $(THR_DEFS) -c $< -o $@
+ $(V_CC) $(MTFLAG) $(CFLAGS) $(THR_DEFS) -c $< -o $@
$(MD_OBJDIR)/%.o: %.c
- $(CC) -MD $(CFLAGS) $(THR_DEFS) -c $< -o $@
+ $(V_CC) -MD $(CFLAGS) $(THR_DEFS) -c $< -o $@
$(MD_OBJDIR)/%.o: %.c
- $(CC) -MD $(CFLAGS) $(THR_DEFS) -c $< -o $@
+ $(V_CC) -MD $(CFLAGS) $(THR_DEFS) -c $< -o $@
$(MDD_OBJDIR)/%.o: %.c
- $(CC) -MDd $(CFLAGS) $(THR_DEFS) -c $< -o $@
+ $(V_CC) -MDd $(CFLAGS) $(THR_DEFS) -c $< -o $@
###########################################################################
# Create directories
@@ -598,67 +608,67 @@ ifeq ($(TARGET),win32)
# Windows archive creation
$(ST_EILIB) : $(ST_EIOBJECTS)
- $(AR) -out:$@ $(ST_EIOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(ST_EIOBJECTS)
+ $(V_RANLIB) $@
$(ST_ERLLIB) : $(ST_ERLOBJECTS)
- $(AR) -out:$@ $(ST_ERLOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(ST_ERLOBJECTS)
+ $(V_RANLIB) $@
$(MT_EILIB) : $(MT_EIOBJECTS)
- $(AR) -out:$@ $(MT_EIOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(MT_EIOBJECTS)
+ $(V_RANLIB) $@
$(MT_ERLLIB) : $(MT_ERLOBJECTS)
- $(AR) -out:$@ $(MT_ERLOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(MT_ERLOBJECTS)
+ $(V_RANLIB) $@
$(MD_EILIB) : $(MD_EIOBJECTS)
- $(AR) -out:$@ $(MD_EIOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(MD_EIOBJECTS)
+ $(V_RANLIB) $@
$(MD_ERLLIB) : $(MD_ERLOBJECTS)
- $(AR) -out:$@ $(MD_ERLOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(MD_ERLOBJECTS)
+ $(V_RANLIB) $@
$(MDD_EILIB) : $(MDD_EIOBJECTS)
- $(AR) -out:$@ $(MDD_EIOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(MDD_EIOBJECTS)
+ $(V_RANLIB) $@
$(MDD_ERLLIB) : $(MDD_ERLOBJECTS)
- $(AR) -out:$@ $(MDD_ERLOBJECTS)
- $(RANLIB) $@
+ $(V_AR) -out:$@ $(MDD_ERLOBJECTS)
+ $(V_RANLIB) $@
else
# Unix archive creation
$(ST_EILIB) : $(ST_EIOBJECTS)
- rm -f $@
- $(AR) rcv $@ $(ST_EIOBJECTS)
+ $(V_at)rm -f $@
+ $(V_AR) $(AR_FLAGS) $@ $(ST_EIOBJECTS)
ifdef RANLIB
- $(RANLIB) $@
+ $(V_RANLIB) $@
endif
$(ST_ERLLIB) : $(ST_ERLOBJECTS)
- rm -f $@
- $(AR) rcv $@ $(ST_ERLOBJECTS)
+ $(V_at)rm -f $@
+ $(V_AR) $(AR_FLAGS) $@ $(ST_ERLOBJECTS)
ifdef RANLIB
- $(RANLIB) $@
+ $(V_RANLIB) $@
endif
$(MT_EILIB) : $(MT_EIOBJECTS)
- rm -f $@
- $(AR) rcv $@ $(MT_EIOBJECTS)
+ $(V_at)rm -f $@
+ $(V_AR) $(AR_FLAGS) $@ $(MT_EIOBJECTS)
ifdef RANLIB
- $(RANLIB) $@
+ $(V_RANLIB) $@
endif
$(MT_ERLLIB) : $(MT_ERLOBJECTS)
- rm -f $@
- $(AR) rcv $@ $(MT_ERLOBJECTS)
+ $(V_at)rm -f $@
+ $(V_AR) $(AR_FLAGS) $@ $(MT_ERLOBJECTS)
ifdef RANLIB
- $(RANLIB) $@
+ $(V_RANLIB) $@
endif
endif
@@ -669,18 +679,18 @@ endif
ifeq ($(TARGET),win32)
$(ERL_CALL): $(ERLCALL) ../include/ei.h $(MD_EILIB)
- $(PURIFY) $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $(ERLCALL) \
+ $(ld_verbose)$(PURIFY) $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $(ERLCALL) \
-L$(OBJDIR) -lei_md $(THR_LIBS) $(LIBS) -lsocket
else
ifeq ($(findstring vxworks,$(TARGET)),vxworks)
$(ERL_CALL): $(ST_OBJDIR)/erl_call.o $(ST_OBJDIR)/erl_start.o ../include/ei.h $(ST_EILIB)
- $(LD) -r -d -o $@ $(ST_OBJDIR)/erl_call.o $(ST_OBJDIR)/erl_start.o -L$(OBJDIR) -lei $(LIBS)
+ $(V_LD) -r -d -o $@ $(ST_OBJDIR)/erl_call.o $(ST_OBJDIR)/erl_start.o -L$(OBJDIR) -lei $(LIBS)
$(ST_OBJDIR)/erl_call.o: prog/erl_call.c
- $(CC) $(CFLAGS) -c $< -o $@
+ $(V_CC) $(CFLAGS) -c $< -o $@
$(ST_OBJDIR)/erl_start.o: prog/erl_start.c
- $(CC) $(CFLAGS) -c $< -o $@
+ $(V_CC) $(CFLAGS) -c $< -o $@
else
ifeq ($(findstring ose,$(TARGET)),ose)
@@ -688,11 +698,11 @@ $(ERL_CALL):
else
ifdef THR_DEFS
$(ERL_CALL): $(ERLCALL) ../include/ei.h $(MT_EILIB)
- $(PURIFY) $(CC) $(PROG_CFLAGS) $(THR_DEFS) $(LDFLAGS) -o $@ $(ERLCALL) \
+ $(ld_verbose)$(PURIFY) $(CC) $(PROG_CFLAGS) $(THR_DEFS) $(LDFLAGS) -o $@ $(ERLCALL) \
-L$(OBJDIR) -lei $(THR_LIBS) $(LIBS)
else
$(ERL_CALL): $(ERLCALL) ../include/ei.h $(ST_EILIB)
- $(PURIFY) $(CC) $(PROG_CFLAGS) $(LDFLAGS) -o $@ $(ERLCALL) \
+ $(ld_verbose)$(PURIFY) $(CC) $(PROG_CFLAGS) $(LDFLAGS) -o $@ $(ERLCALL) \
-L$(OBJDIR) -lei $(LIBS)
endif
endif
@@ -707,36 +717,36 @@ check: $(FAKE_TARGETS)
ifndef THR_DEFS
$(ST_OBJDIR)/erl_fake_prog_st$(EXE): prog/erl_fake_prog.c $(ST_ERLLIB) $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lerl_interface -lei \
+ $(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lerl_interface -lei \
$(LIBS)
$(ST_OBJDIR)/ei_fake_prog_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lei $(LIBS)
+ $(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lei $(LIBS)
$(ST_OBJDIR)/erl_fake_prog_cxx_st$(EXE): prog/erl_fake_prog.c \
$(ST_ERLLIB) $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) \
+ $(V_CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) \
-lerl_interface -lei $(LIBS)
$(ST_OBJDIR)/ei_fake_prog_cxx_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) -lei $(LIBS)
+ $(V_CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) -lei $(LIBS)
else
$(ST_OBJDIR)/erl_fake_prog_st$(EXE): prog/erl_fake_prog.c $(ST_ERLLIB) $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lerl_interface_st -lei_st \
+ $(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lerl_interface_st -lei_st \
$(LIBS)
$(ST_OBJDIR)/ei_fake_prog_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lei_st $(LIBS)
+ $(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lei_st $(LIBS)
$(ST_OBJDIR)/erl_fake_prog_cxx_st$(EXE): prog/erl_fake_prog.c \
$(ST_ERLLIB) $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) \
+ $(V_CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) \
-lerl_interface_st -lei_st $(LIBS)
$(ST_OBJDIR)/ei_fake_prog_cxx_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
- $(CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) -lei_st $(LIBS)
+ $(V_CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) -lei_st $(LIBS)
endif
@@ -744,63 +754,63 @@ endif
$(MT_OBJDIR)/erl_fake_prog_mt$(EXE): prog/erl_fake_prog.c \
$(MT_ERLLIB) $(MT_EILIB)
- $(CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
+ $(V_CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
-lerl_interface -lei $(THR_LIBS) $(LIBS)
$(MT_OBJDIR)/ei_fake_prog_mt$(EXE): prog/ei_fake_prog.c $(MT_EILIB)
- $(CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< \
+ $(V_CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< \
-L$(OBJDIR) -lei $(THR_LIBS) $(LIBS)
$(MT_OBJDIR)/erl_fake_prog_mt_cxx$(EXE): prog/erl_fake_prog.c \
$(MT_ERLLIB) $(MT_EILIB)
- $(CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
+ $(V_CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lerl_interface -lei \
$(THR_LIBS) $(LIBS)
$(MT_OBJDIR)/ei_fake_prog_mt_cxx$(EXE): prog/ei_fake_prog.c $(MT_EILIB)
- $(CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
+ $(V_CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lei $(THR_LIBS) $(LIBS)
####
$(MD_OBJDIR)/erl_fake_prog_md$(EXE): prog/erl_fake_prog.c \
$(MD_ERLLIB) $(MD_EILIB)
- $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
+ $(V_CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
-lerl_interface_r -lei_r $(THR_LIBS) $(LIBS)
$(MD_OBJDIR)/ei_fake_prog_md$(EXE): prog/ei_fake_prog.c $(MD_EILIB)
- $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< \
+ $(V_CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< \
-L$(OBJDIR) -lei_r $(THR_LIBS) $(LIBS)
$(MD_OBJDIR)/erl_fake_prog_md_cxx$(EXE): prog/erl_fake_prog.c \
$(MD_ERLLIB) $(MD_EILIB)
- $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
+ $(V_CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lerl_interface_r -lei_r \
$(THR_LIBS) $(LIBS)
$(MD_OBJDIR)/ei_fake_prog_md_cxx$(EXE): prog/ei_fake_prog.c $(MD_EILIB)
- $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
+ $(V_CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lei_r $(THR_LIBS) $(LIBS)
####
$(MDD_OBJDIR)/erl_fake_prog_mdd$(EXE): prog/erl_fake_prog.c \
$(MDD_ERLLIB) $(MDD_EILIB)
- $(CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
+ $(V_CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
-lerl_interface_r -lei_r $(THR_LIBS) $(LIBS)
$(MDD_OBJDIR)/ei_fake_prog_mdd$(EXE): prog/ei_fake_prog.c $(MDD_EILIB)
- $(CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< \
+ $(V_CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< \
-L$(OBJDIR) -lei_r $(THR_LIBS) $(LIBS)
$(MDD_OBJDIR)/erl_fake_prog_mdd_cxx$(EXE): prog/erl_fake_prog.c \
$(MDD_ERLLIB) $(MDD_EILIB)
- $(CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
+ $(V_CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lerl_interface_r -lei_r \
$(THR_LIBS) $(LIBS)
$(MDD_OBJDIR)/ei_fake_prog_mdd_cxx$(EXE): prog/ei_fake_prog.c $(MDD_EILIB)
- $(CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
+ $(V_CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lei_r $(THR_LIBS) $(LIBS)
###########################################################################
@@ -808,9 +818,10 @@ $(MDD_OBJDIR)/ei_fake_prog_mdd_cxx$(EXE): prog/ei_fake_prog.c $(MDD_EILIB)
###########################################################################
depend:
- @echo "Generating dependency file depend.mk..."
+ $(gen_verbose)
+ $(V_colon)@echo "Generating dependency file depend.mk..."
@echo "# Generated dependency rules" > depend.mk; \
- $(CC) $(CFLAGS) -MM $(SOURCES) | \
+ $(V_CC) $(CFLAGS) -MM $(SOURCES) | \
sed 's&$(TARGET)&\$$\(TARGET\)&g' | \
sed 's/^.*:/\$$\(ST_OBJDIR\)\/&/' >> depend.mk; \
echo >> depend.mk; \
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 34362b4b9f..4421bbb7fe 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -459,6 +459,7 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname,
/* memmove(&ec->this_ipaddr, thisipaddr, sizeof(ec->this_ipaddr)); */
strcpy(ec->self.node,thisnodename);
+ ec->self.node_org_enc = ERLANG_LATIN1;
ec->self.num = 0;
ec->self.serial = 0;
ec->self.creation = creation;
@@ -1070,7 +1071,7 @@ int ei_rpc(ei_cnode* ec, int fd, char *mod, char *fun,
int i, index;
ei_term t;
erlang_msg msg;
- char rex[MAXATOMLEN+1];
+ char rex[MAXATOMLEN];
if (ei_rpc_to(ec, fd, mod, fun, inbuf, inbuflen) < 0) {
return -1;
@@ -1332,7 +1333,9 @@ static int send_name_or_challenge(int fd, char *nodename,
| DFLAG_EXTENDED_PIDS_PORTS
| DFLAG_FUN_TAGS
| DFLAG_NEW_FUN_TAGS
- | DFLAG_NEW_FLOATS));
+ | DFLAG_NEW_FLOATS
+ | DFLAG_SMALL_ATOM_TAGS
+ | DFLAG_UTF8_ATOMS));
if (f_chall)
put32be(s, challenge);
memcpy(s, nodename, strlen(nodename));
diff --git a/lib/erl_interface/src/connect/ei_connect_int.h b/lib/erl_interface/src/connect/ei_connect_int.h
index 3c42b49b82..81c384e38d 100644
--- a/lib/erl_interface/src/connect/ei_connect_int.h
+++ b/lib/erl_interface/src/connect/ei_connect_int.h
@@ -102,6 +102,8 @@ extern int h_errno;
#define DFLAG_NEW_FUN_TAGS 0x80
#define DFLAG_EXTENDED_PIDS_PORTS 0x100
#define DFLAG_NEW_FLOATS 0x800
+#define DFLAG_SMALL_ATOM_TAGS 0x4000
+#define DFLAG_UTF8_ATOMS 0x10000
ei_cnode *ei_fd_to_cnode(int fd);
int ei_distversion(int fd);
diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c
index 86852f947d..075f78e3d2 100644
--- a/lib/erl_interface/src/connect/eirecv.c
+++ b/lib/erl_interface/src/connect/eirecv.c
@@ -108,7 +108,7 @@ ei_recv_internal (int fd,
switch (msg->msgtype) {
case ERL_SEND: /* { SEND, Cookie, ToPid } */
if (ei_tracelevel >= 4) show_this_msg = 1;
- if (ei_decode_atom(header,&index,msg->cookie)
+ if (ei_decode_atom_as(header,&index,msg->cookie,sizeof(msg->cookie),ERLANG_UTF8,NULL,NULL)
|| ei_decode_pid(header,&index,&msg->to))
{
erl_errno = EIO;
@@ -120,8 +120,8 @@ ei_recv_internal (int fd,
case ERL_REG_SEND: /* { REG_SEND, From, Cookie, ToName } */
if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
- || ei_decode_atom(header,&index,msg->cookie)
- || ei_decode_atom(header,&index,msg->toname))
+ || ei_decode_atom_as(header,&index,msg->cookie,sizeof(msg->cookie),ERLANG_UTF8,NULL,NULL)
+ || ei_decode_atom_as(header,&index,msg->toname,sizeof(msg->toname),ERLANG_UTF8,NULL,NULL))
{
erl_errno = EIO;
return -1;
@@ -157,7 +157,7 @@ ei_recv_internal (int fd,
case ERL_SEND_TT: /* { SEND_TT, Cookie, ToPid, TraceToken } */
if (ei_tracelevel >= 4) show_this_msg = 1;
- if (ei_decode_atom(header,&index,msg->cookie)
+ if (ei_decode_atom_as(header,&index,msg->cookie,sizeof(msg->cookie),ERLANG_UTF8,NULL,NULL)
|| ei_decode_pid(header,&index,&msg->to)
|| ei_decode_trace(header,&index,&msg->token))
{
@@ -171,8 +171,8 @@ ei_recv_internal (int fd,
case ERL_REG_SEND_TT: /* { REG_SEND_TT, From, Cookie, ToName, TraceToken } */
if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
- || ei_decode_atom(header,&index,msg->cookie)
- || ei_decode_atom(header,&index,msg->toname)
+ || ei_decode_atom_as(header,&index,msg->cookie,sizeof(msg->cookie),ERLANG_UTF8,NULL,NULL)
+ || ei_decode_atom_as(header,&index,msg->toname,sizeof(msg->toname),ERLANG_UTF8,NULL,NULL)
|| ei_decode_trace(header,&index,&msg->token))
{
erl_errno = EIO;
diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c
index c2e6a0426e..9779ad3f35 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -21,24 +21,155 @@
#include "eiext.h"
#include "putget.h"
+
int ei_decode_atom(const char *buf, int *index, char *p)
{
- const char *s = buf + *index;
- const char *s0 = s;
- int len;
+ return ei_decode_atom_as(buf, index, p, MAXATOMLEN, ERLANG_LATIN1, NULL, NULL);
+}
+
+int ei_decode_atom_as(const char *buf, int *index, char* p, int destlen,
+ enum erlang_char_encoding want_enc,
+ enum erlang_char_encoding* was_encp,
+ enum erlang_char_encoding* res_encp)
+{
+ const char *s = buf + *index;
+ const char *s0 = s;
+ int len;
+ enum erlang_char_encoding got_enc;
+
+ switch (get8(s)) {
+ case ERL_ATOM_EXT:
+ len = get16be(s);
+ got_enc = ERLANG_LATIN1;
+ break;
+ case ERL_SMALL_ATOM_EXT:
+ len = get8(s);
+ got_enc = ERLANG_LATIN1;
+ break;
+ case ERL_ATOM_UTF8_EXT:
+ len = get16be(s);
+ got_enc = ERLANG_UTF8;
+ break;
+ case ERL_SMALL_ATOM_UTF8_EXT:
+ len = get8(s);
+ got_enc = ERLANG_UTF8;
+ break;
+ default:
+ return -1;
+ }
+
+ if ((want_enc & got_enc) || want_enc == ERLANG_ASCII) {
+ int i, found_non_ascii = 0;
+ if (len >= destlen)
+ return -1;
+ for (i=0; i<len; i++) {
+ if (s[i] & 0x80) found_non_ascii = 1;
+ if (p) p[i] = s[i];
+ }
+ if (p) p[len] = 0;
+ if (want_enc == ERLANG_ASCII && found_non_ascii) {
+ return -1;
+ }
+ if (res_encp) {
+ *res_encp = found_non_ascii ? got_enc : ERLANG_ASCII;
+ }
+ }
+ else {
+ int plen = (got_enc == ERLANG_LATIN1) ?
+ latin1_to_utf8(p, s, len, destlen-1, res_encp) :
+ utf8_to_latin1(p, s, len, destlen-1, res_encp);
+ if (plen < 0) return -1;
+ if (p) p[plen] = 0;
+ }
+ if (was_encp) {
+ *was_encp = got_enc;
+ }
+
+ s += len;
+ *index += s-s0;
+ return 0;
+}
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
+int utf8_to_latin1(char* dst, const char* src, int slen, int destlen,
+ enum erlang_char_encoding* res_encp)
+{
+ const char* const dst_start = dst;
+ const char* const dst_end = dst + destlen;
+ int found_non_ascii = 0;
+
+ while (slen > 0) {
+ if (dst >= dst_end) return -1;
+ if ((src[0] & 0x80) == 0) {
+ if (dst_start) {
+ *dst = *src;
+ }
+ ++dst;
+ ++src;
+ --slen;
+ }
+ else if (slen > 1 &&
+ (src[0] & 0xFE) == 0xC2 &&
+ (src[1] & 0xC0) == 0x80) {
+ if (dst_start) {
+ *dst = (char) ((src[0] << 6) | (src[1] & 0x3F));
+ }
+ ++dst;
+ src += 2;
+ slen -= 2;
+ found_non_ascii = 1;
+ }
+ else return -1;
+ }
+ if (res_encp) {
+ *res_encp = found_non_ascii ? ERLANG_LATIN1 : ERLANG_ASCII;
+ }
+ return dst - dst_start;
+}
- if (len > MAXATOMLEN) return -1;
+int latin1_to_utf8(char* dst, const char* src, int slen, int destlen,
+ enum erlang_char_encoding* res_encp)
+{
+ const char* const src_end = src + slen;
+ const char* const dst_start = dst;
+ const char* const dst_end = dst + destlen;
+ int found_non_ascii = 0;
- if (p) {
- memmove(p,s,len);
- p[len] = (char)0;
- }
- s += len;
- *index += s-s0;
-
- return 0;
+ while (src < src_end) {
+ if (dst >= dst_end) return -1;
+ if ((src[0] & 0x80) == 0) {
+ if (dst_start) {
+ *dst = *src;
+ }
+ ++dst;
+ }
+ else {
+ if (dst_start) {
+ unsigned char ch = *src;
+ dst[0] = 0xC0 | (ch >> 6);
+ dst[1] = 0x80 | (ch & 0x3F);
+ }
+ dst += 2;
+ found_non_ascii = 1;
+ }
+ ++src;
+ }
+ if (res_encp) {
+ *res_encp = found_non_ascii ? ERLANG_UTF8 : ERLANG_ASCII;
+ }
+ return dst - dst_start;
}
+
+
+
+int ei_internal_get_atom(const char** bufp, char* p,
+ enum erlang_char_encoding* was_encp)
+{
+ int ix = 0;
+ if (ei_decode_atom_as(*bufp, &ix, p, MAXATOMLEN_UTF8, ERLANG_UTF8, was_encp, NULL) < 0)
+ return -1;
+ *bufp += ix;
+ return 0;
+}
+
+
diff --git a/lib/erl_interface/src/decode/decode_boolean.c b/lib/erl_interface/src/decode/decode_boolean.c
index 9fd09c63f1..f20690249b 100644
--- a/lib/erl_interface/src/decode/decode_boolean.c
+++ b/lib/erl_interface/src/decode/decode_boolean.c
@@ -24,34 +24,20 @@
/* c non-zero -> erlang "true" atom, otherwise "false" */
int ei_decode_boolean(const char *buf, int *index, int *p)
{
- const char *s = buf + *index;
- const char *s0 = s;
- int len;
+ char tbuf[6];
int t;
- if (get8(s) != ERL_ATOM_EXT) return -1;
+ if (ei_decode_atom_as(buf, index, tbuf, sizeof(tbuf), ERLANG_ASCII, NULL, NULL) < 0)
+ return -1;
- len = get16be(s);
-
- switch (len) {
- case 4:
- /* typecast makes ansi happy */
- if (strncmp((char*)s,"true",4)) return -1;
- t = 1;
- break;
-
- case 5:
- if (strncmp((char*)s,"false",5)) return -1;
- t = 0;
- break;
-
- default:
- return -1;
- }
-
- s += len;
+ if (memcmp(tbuf, "true", 5) == 0)
+ t = 1;
+ else if (memcmp(tbuf, "false", 6) == 0)
+ t = 0;
+ else
+ return -1;
+
if (p) *p = t;
- *index += s-s0;
-
return 0;
}
+
diff --git a/lib/erl_interface/src/decode/decode_fun.c b/lib/erl_interface/src/decode/decode_fun.c
index 64fb9e86d8..7bbef5db44 100644
--- a/lib/erl_interface/src/decode/decode_fun.c
+++ b/lib/erl_interface/src/decode/decode_fun.c
@@ -42,7 +42,8 @@ int ei_decode_fun(const char *buf, int *index, erlang_fun *p)
if (ei_decode_pid(s, &ix, (p == NULL ? (erlang_pid*)NULL : &p->pid)) < 0)
return -1;
/* then the module (atom) */
- if (ei_decode_atom(s, &ix, (p == NULL ? (char*)NULL : p->module)) < 0)
+ if (ei_decode_atom_as(s, &ix, (p == NULL ? (char*)NULL : p->module),
+ MAXATOMLEN_UTF8, ERLANG_UTF8, &p->module_org_enc, NULL) < 0)
return -1;
/* then the index */
if (ei_decode_long(s, &ix, (p == NULL ? (long*)NULL : &p->index)) < 0)
@@ -84,7 +85,8 @@ int ei_decode_fun(const char *buf, int *index, erlang_fun *p)
if (p != NULL) p->n_free_vars = i;
/* then the module (atom) */
ix = 0;
- if (ei_decode_atom(s, &ix, (p == NULL ? (char*)NULL : p->module)) < 0)
+ if (ei_decode_atom_as(s, &ix, (p == NULL ? (char*)NULL : p->module),
+ MAXATOMLEN_UTF8, ERLANG_UTF8, &p->module_org_enc, NULL) < 0)
return -1;
/* then the old_index */
if (ei_decode_long(s, &ix, (p == NULL ? (long*)NULL : &p->old_index)) < 0)
diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c
index 9ed1c36db6..e79952195d 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -21,26 +21,16 @@
#include "eiext.h"
#include "putget.h"
+
int ei_decode_pid(const char *buf, int *index, erlang_pid *p)
{
const char *s = buf + *index;
const char *s0 = s;
- int len;
if (get8(s) != ERL_PID_EXT) return -1;
/* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
-
- len = get16be(s);
-
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ if (get_atom(&s, p->node, &p->node_org_enc) < 0) return -1;
/* now the numbers: num (4), serial (4), creation (1) */
if (p) {
diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c
index 28abed801a..5fd96b51a4 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -25,22 +25,11 @@ int ei_decode_port(const char *buf, int *index, erlang_port *p)
{
const char *s = buf + *index;
const char *s0 = s;
- int len;
if (get8(s) != ERL_PORT_EXT) return -1;
/* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
-
- len = get16be(s);
-
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ if (get_atom(&s, p->node, &p->node_org_enc) < 0) return -1;
/* now the numbers: num (4), creation (1) */
if (p) {
diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c
index 7b15808bc5..7294e5d239 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -21,27 +21,18 @@
#include "eiext.h"
#include "putget.h"
+
int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
{
const char *s = buf + *index;
const char *s0 = s;
- int count, len, i;
+ int count, i;
switch (get8(s)) {
case ERL_REFERENCE_EXT:
- /* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
-
- len = get16be(s);
-
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ /* nodename */
+ if (get_atom(&s, p->node, &p->node_org_enc) < 0) return -1;
/* now the numbers: num (4), creation (1) */
if (p) {
@@ -62,15 +53,7 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
if (p) p->len = count;
/* then the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ if (get_atom(&s, p->node, &p->node_org_enc) < 0) return -1;
/* creation */
if (p) {
@@ -95,3 +78,4 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
return -1;
}
}
+
diff --git a/lib/erl_interface/src/encode/encode_atom.c b/lib/erl_interface/src/encode/encode_atom.c
index 6f41f045e0..044f17cb60 100644
--- a/lib/erl_interface/src/encode/encode_atom.c
+++ b/lib/erl_interface/src/encode/encode_atom.c
@@ -22,29 +22,108 @@
#include "eiext.h"
#include "putget.h"
+
+static int copy_ascii_atom(char* dst, const char* src, int slen);
+static int copy_utf8_atom(char* dst, const char* src, int slen);
+
+
int ei_encode_atom(char *buf, int *index, const char *p)
{
size_t len = strlen(p);
- if (len >= INT_MAX) return -1;
- return ei_encode_atom_len(buf, index, p, len);
+ if (len >= MAXATOMLEN)
+ len = MAXATOMLEN - 1;
+ return ei_encode_atom_len_as(buf, index, p, len, ERLANG_LATIN1, ERLANG_LATIN1);
}
int ei_encode_atom_len(char *buf, int *index, const char *p, int len)
{
+ /* This function is documented to truncate at MAXATOMLEN (256) */
+ if (len >= MAXATOMLEN)
+ len = MAXATOMLEN - 1;
+ return ei_encode_atom_len_as(buf, index, p, len, ERLANG_LATIN1, ERLANG_LATIN1);
+}
+
+int ei_encode_atom_as(char *buf, int *index, const char *p,
+ enum erlang_char_encoding from_enc,
+ enum erlang_char_encoding to_enc)
+{
+ return ei_encode_atom_len_as(buf, index, p, strlen(p), from_enc, to_enc);
+}
+
+int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
+ enum erlang_char_encoding from_enc,
+ enum erlang_char_encoding to_enc)
+{
char *s = buf + *index;
char *s0 = s;
+ int offs;
- /* This function is documented to truncate at MAXATOMLEN (256) */
- if (len > MAXATOMLEN)
- len = MAXATOMLEN;
+ if (len >= MAXATOMLEN && (from_enc & (ERLANG_LATIN1|ERLANG_ASCII))) {
+ return -1;
+ }
- if (!buf) s += 3;
- else {
- put8(s,ERL_ATOM_EXT);
- put16be(s,len);
+ switch(to_enc) {
+ case ERLANG_LATIN1:
+ if (buf) {
+ put8(s,ERL_ATOM_EXT);
+ switch (from_enc) {
+ case ERLANG_UTF8:
+ len = utf8_to_latin1(s+2, p, len, MAXATOMLEN-1, NULL);
+ if (len < 0) return -1;
+ break;
+ case ERLANG_ASCII:
+ if (copy_ascii_atom(s+2, p, len) < 0) return -1;
+ break;
+ case ERLANG_LATIN1:
+ memcpy(s+2, p, len);
+ break;
+ default:
+ return -1;
+ }
+ put16be(s,len);
+ }
+ else {
+ s += 3;
+ if (from_enc == ERLANG_UTF8) {
+ len = utf8_to_latin1(NULL, p, len, MAXATOMLEN-1, NULL);
+ if (len < 0) return -1;
+ }
+ }
+ break;
+
+ case ERLANG_UTF8:
+ offs = 1 + 1;
+ switch (from_enc) {
+ case ERLANG_LATIN1:
+ if (len >= 256/2) offs++;
+ len = latin1_to_utf8((buf ? s+offs : NULL), p, len, MAXATOMLEN_UTF8-1, NULL);
+ break;
+ case ERLANG_ASCII:
+ if (buf && copy_ascii_atom(s+offs, p, len) < 0) return -1;
+ break;
+ case ERLANG_UTF8:
+ if (len >= 256) offs++;
+ if (buf && copy_utf8_atom(s+offs, p, len) < 0) return -1;
+ break;
+ default:
+ return -1;
+ }
+ if (buf) {
+ if (offs == 2) {
+ put8(s, ERL_SMALL_ATOM_UTF8_EXT);
+ put8(s, len);
+ }
+ else {
+ put8(s, ERL_ATOM_UTF8_EXT);
+ put16be(s, len);
+ }
+ }
+ else s+= offs;
+ break;
- memmove(s,p,len); /* unterminated string */
+ default:
+ return -1;
}
s += len;
@@ -53,3 +132,58 @@ int ei_encode_atom_len(char *buf, int *index, const char *p, int len)
return 0;
}
+int
+ei_internal_put_atom(char** bufp, const char* p, int slen,
+ enum erlang_char_encoding to_enc)
+{
+ int ix = 0;
+ if (ei_encode_atom_len_as(*bufp, &ix, p, slen, ERLANG_UTF8, to_enc) < 0)
+ return -1;
+ *bufp += ix;
+ return 0;
+}
+
+
+int copy_ascii_atom(char* dst, const char* src, int slen)
+{
+ while (slen > 0) {
+ if ((src[0] & 0x80) != 0) return -1;
+ *dst++ = *src++;
+ slen--;
+ }
+ return 0;
+}
+
+int copy_utf8_atom(char* dst, const char* src, int slen)
+{
+ int num_chars = 0;
+
+ while (slen > 0) {
+ if (++num_chars >= MAXATOMLEN) return -1;
+ if ((src[0] & 0x80) != 0) {
+ if ((src[0] & 0xE0) == 0xC0) {
+ if (slen < 2 || (src[1] & 0xC0) != 0x80) return -1;
+ *dst++ = *src++;
+ slen--;
+ }
+ else if ((src[0] & 0xF0) == 0xE0) {
+ if (slen < 3 || (src[1] & 0xC0) != 0x80 || (src[2] & 0xC0) != 0x80) return -1;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ slen -= 2;
+ }
+ else if ((src[0] & 0xF8) == 0xF0) {
+ if (slen < 4 || (src[1] & 0xC0) != 0x80 || (src[2] & 0xC0) != 0x80 || (src[3] & 0xC0) != 0x80) return -1;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ slen -= 3;
+ }
+ else return -1;
+ }
+ *dst++ = *src++;
+ slen--;
+ }
+ return 0;
+}
+
diff --git a/lib/erl_interface/src/encode/encode_fun.c b/lib/erl_interface/src/encode/encode_fun.c
index 54ee2083d6..4daee32648 100644
--- a/lib/erl_interface/src/encode/encode_fun.c
+++ b/lib/erl_interface/src/encode/encode_fun.c
@@ -35,7 +35,7 @@ int ei_encode_fun(char *buf, int *index, const erlang_fun *p)
ix += sizeof(char) + 4;
if (ei_encode_pid(buf, &ix, &p->pid) < 0)
return -1;
- if (ei_encode_atom(buf, &ix, p->module) < 0)
+ if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, p->module_org_enc) < 0)
return -1;
if (ei_encode_long(buf, &ix, p->index) < 0)
return -1;
@@ -60,7 +60,7 @@ int ei_encode_fun(char *buf, int *index, const erlang_fun *p)
} else
size_p = NULL;
ix += 1 + 4 + 1 + sizeof(p->md5) + 4 + 4;
- if (ei_encode_atom(buf, &ix, p->module) < 0)
+ if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, p->module_org_enc) < 0)
return -1;
if (ei_encode_long(buf, &ix, p->old_index) < 0)
return -1;
diff --git a/lib/erl_interface/src/encode/encode_pid.c b/lib/erl_interface/src/encode/encode_pid.c
index ee7f235c17..0cf3ef4efb 100644
--- a/lib/erl_interface/src/encode/encode_pid.c
+++ b/lib/erl_interface/src/encode/encode_pid.c
@@ -24,29 +24,23 @@
int ei_encode_pid(char *buf, int *index, const erlang_pid *p)
{
char *s = buf + *index;
- char *s0 = s;
- int len = strlen(p->node);
-
- if (!buf) s += 13 + len;
- else {
- put8(s,ERL_PID_EXT);
- /* first the nodename */
- put8(s,ERL_ATOM_EXT);
+ ++(*index); /* skip ERL_PID_EXT */
+ if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8, p->node_org_enc) < 0)
+ return -1;
+
+ if (buf) {
+ put8(s,ERL_PID_EXT);
- put16be(s,len);
-
- memmove(s, p->node, len);
- s += len;
+ s = buf + *index;
/* now the integers */
put32be(s,p->num & 0x7fff); /* 15 bits */
put32be(s,p->serial & 0x1fff); /* 13 bits */
put8(s,(p->creation & 0x03)); /* 2 bits */
}
-
- *index += s-s0;
-
+
+ *index += 4 + 4 + 1;
return 0;
}
diff --git a/lib/erl_interface/src/encode/encode_port.c b/lib/erl_interface/src/encode/encode_port.c
index fbbb33182e..2bf9e26d78 100644
--- a/lib/erl_interface/src/encode/encode_port.c
+++ b/lib/erl_interface/src/encode/encode_port.c
@@ -24,28 +24,23 @@
int ei_encode_port(char *buf, int *index, const erlang_port *p)
{
char *s = buf + *index;
- char *s0 = s;
- int len = strlen(p->node);
-
- if (!buf) s += 9 + len;
- else {
- put8(s,ERL_PORT_EXT);
- /* first the nodename */
- put8(s,ERL_ATOM_EXT);
+ ++(*index); /* skip ERL_PORT_EXT */
+ if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8,
+ p->node_org_enc) < 0) {
+ return -1;
+ }
+ if (buf) {
+ put8(s,ERL_PORT_EXT);
- put16be(s,len);
-
- memmove(s, p->node, len);
- s += len;
+ s = buf + *index;
/* now the integers */
put32be(s,p->id & 0x0fffffff /* 28 bits */);
put8(s,(p->creation & 0x03));
}
- *index += s-s0;
-
+ *index += 4 + 1;
return 0;
}
diff --git a/lib/erl_interface/src/encode/encode_ref.c b/lib/erl_interface/src/encode/encode_ref.c
index 292b452864..e8b3173315 100644
--- a/lib/erl_interface/src/encode/encode_ref.c
+++ b/lib/erl_interface/src/encode/encode_ref.c
@@ -24,36 +24,32 @@
int ei_encode_ref(char *buf, int *index, const erlang_ref *p)
{
char *s = buf + *index;
- char *s0 = s;
- int len = strlen(p->node);
int i;
+ (*index) += 1 + 2; /* skip to node atom */
+ if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8,
+ p->node_org_enc) < 0) {
+ return -1;
+ }
+
/* Always encode as an extended reference; all participating parties
are now expected to be able to decode extended references. */
- if (!buf) s += 1 + 2 + (3+len) + p->len*4 + 1;
- else {
+ if (buf) {
put8(s,ERL_NEW_REFERENCE_EXT);
/* first, number of integers */
put16be(s, p->len);
/* then the nodename */
- put8(s,ERL_ATOM_EXT);
-
- put16be(s,len);
-
- memmove(s, p->node, len);
- s += len;
+ s = buf + *index;
/* now the integers */
put8(s,(p->creation & 0x03));
for (i = 0; i < p->len; i++)
put32be(s,p->n[i]);
-
- }
-
- *index += s-s0;
+ }
+ *index += p->len*4 + 1;
return 0;
}
diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c
index 41d4fa3138..f82704ea8b 100644
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ b/lib/erl_interface/src/legacy/erl_connect.c
@@ -125,7 +125,7 @@ static ei_cnode erl_if_ec;
int erl_connect_init(int this_node_number, char *cookie, short creation)
{
- char nn[MAXATOMLEN+1];
+ char nn[MAXATOMLEN];
sprintf(nn, "c%d", this_node_number);
@@ -247,9 +247,15 @@ int erl_send(int fd, ETERM *to ,ETERM *msg)
erl_errno = EINVAL;
return -1;
}
-
- strncpy(topid.node, (char *)ERL_PID_NODE(to), sizeof(topid.node));
- topid.node[sizeof(topid.node)-1] = '\0';
+
+ if (to->uval.pidval.node.latin1) {
+ strcpy(topid.node, to->uval.pidval.node.latin1);
+ topid.node_org_enc = ERLANG_LATIN1;
+ }
+ else {
+ strcpy(topid.node, to->uval.pidval.node.utf8);
+ topid.node_org_enc = ERLANG_UTF8;
+ }
topid.num = ERL_PID_NUMBER(to);
topid.serial = ERL_PID_SERIAL(to);
topid.creation = ERL_PID_CREATION(to);
@@ -263,7 +269,7 @@ static int erl_do_receive_msg(int fd, ei_x_buff* x, ErlMessage* emsg)
erlang_msg msg;
int r;
- msg.from.node[0] = msg.to.node[0] = '\0';
+ msg.from.node[0] = msg.to.node[0] = msg.toname[0] = '\0';
r = ei_do_receive_msg(fd, 0, &msg, x, 0);
if (r == ERL_MSG) {
@@ -299,7 +305,7 @@ static int erl_do_receive_msg(int fd, ei_x_buff* x, ErlMessage* emsg)
emsg->to = erl_mk_pid(msg.to.node, msg.to.num, msg.to.serial, msg.to.creation);
else
emsg->to = NULL;
- memcpy(emsg->to_name, msg.toname, MAXATOMLEN+1);
+ strcpy(emsg->to_name, msg.toname);
return r;
}
diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c
index 8d559f0f55..aa0fd5ddcf 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ b/lib/erl_interface/src/legacy/erl_eterm.c
@@ -36,6 +36,7 @@
#include "erl_error.h"
#include "erl_internal.h"
#include "ei_internal.h"
+#include "putget.h"
#define ERL_IS_BYTE(x) (ERL_IS_INTEGER(x) && (ERL_INT_VALUE(x) & ~0xFF) == 0)
@@ -142,9 +143,7 @@ ETERM *erl_mk_atom (const char *s)
ep = erl_alloc_eterm(ERL_ATOM);
ERL_COUNT(ep) = 1;
- ERL_ATOM_SIZE(ep) = strlen(s);
- if ((ERL_ATOM_PTR(ep) = strsave(s)) == NULL)
- {
+ if (erl_atom_init_latin1(&ep->uval.aval.d, s) == NULL) {
erl_free_term(ep);
erl_errno = ENOMEM;
return NULL;
@@ -152,6 +151,65 @@ ETERM *erl_mk_atom (const char *s)
return ep;
}
+char* erl_atom_ptr_latin1(Erl_Atom_data* a)
+{
+ if (a->latin1 == NULL) {
+ enum erlang_char_encoding enc;
+ a->lenL = utf8_to_latin1(NULL, a->utf8, a->lenU, a->lenU, &enc);
+ if (a->lenL < 0) {
+ a->lenL = 0;
+ return NULL;
+ }
+ if (enc == ERLANG_ASCII) {
+ a->latin1 = a->utf8;
+ }
+ else {
+ a->latin1 = malloc(a->lenL+1);
+ utf8_to_latin1(a->latin1, a->utf8, a->lenU, a->lenL, NULL);
+ a->latin1[a->lenL] = '\0';
+ }
+ }
+ return a->latin1;
+}
+
+char* erl_atom_ptr_utf8(Erl_Atom_data* a)
+{
+ if (a->utf8 == NULL) {
+ int dlen = a->lenL * 2; /* over estimation */
+ a->utf8 = malloc(dlen + 1);
+ a->lenU = latin1_to_utf8(a->utf8, a->latin1, a->lenL, dlen, NULL);
+ a->utf8[a->lenU] = '\0';
+ }
+ return a->utf8;
+
+}
+int erl_atom_size_latin1(Erl_Atom_data* a)
+{
+ if (a->latin1 == NULL) {
+ erl_atom_ptr_latin1(a);
+ }
+ return a->lenL;
+}
+int erl_atom_size_utf8(Erl_Atom_data* a)
+{
+ if (a->utf8 == NULL) {
+ erl_atom_ptr_utf8(a);
+ }
+ return a->lenU;
+}
+char* erl_atom_init_latin1(Erl_Atom_data* a, const char* s)
+{
+ a->lenL = strlen(s);
+ if ((a->latin1 = strsave(s)) == NULL)
+ {
+ return NULL;
+ }
+ a->utf8 = NULL;
+ a->lenU = 0;
+ return a->latin1;
+}
+
+
/*
* Given a string as input, creates a list.
*/
@@ -208,12 +266,19 @@ ETERM *erl_mk_pid(const char *node,
ep = erl_alloc_eterm(ERL_PID);
ERL_COUNT(ep) = 1;
- if ((ERL_PID_NODE(ep) = strsave(node)) == NULL)
+ if (erl_atom_init_latin1(&ep->uval.pidval.node, node) == NULL)
{
erl_free_term(ep);
erl_errno = ENOMEM;
return NULL;
}
+ erl_mk_pid_helper(ep, number, serial, creation);
+ return ep;
+}
+
+void erl_mk_pid_helper(ETERM *ep, unsigned int number,
+ unsigned int serial, unsigned char creation)
+{
ERL_PID_NUMBER(ep) = number & 0x7fff; /* 15 bits */
if (ei_internal_use_r9_pids_ports()) {
ERL_PID_SERIAL(ep) = serial & 0x07; /* 3 bits */
@@ -222,7 +287,6 @@ ETERM *erl_mk_pid(const char *node,
ERL_PID_SERIAL(ep) = serial & 0x1fff; /* 13 bits */
}
ERL_PID_CREATION(ep) = creation & 0x03; /* 2 bits */
- return ep;
}
/*
@@ -239,12 +303,18 @@ ETERM *erl_mk_port(const char *node,
ep = erl_alloc_eterm(ERL_PORT);
ERL_COUNT(ep) = 1;
- if ((ERL_PORT_NODE(ep) = strsave(node)) == NULL)
+ if (erl_atom_init_latin1(&ep->uval.portval.node, node) == NULL)
{
erl_free_term(ep);
erl_errno = ENOMEM;
return NULL;
}
+ erl_mk_port_helper(ep, number, creation);
+ return ep;
+}
+
+void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned char creation)
+{
if (ei_internal_use_r9_pids_ports()) {
ERL_PORT_NUMBER(ep) = number & 0x3ffff; /* 18 bits */
}
@@ -252,29 +322,29 @@ ETERM *erl_mk_port(const char *node,
ERL_PORT_NUMBER(ep) = number & 0x0fffffff; /* 18 bits */
}
ERL_PORT_CREATION(ep) = creation & 0x03; /* 2 bits */
- return ep;
}
/*
* Create any kind of reference.
*/
-ETERM *__erl_mk_reference (const char *node,
+ETERM *__erl_mk_reference (ETERM* t,
+ const char *node,
size_t len,
unsigned int n[],
unsigned char creation)
{
- ETERM * t;
-
- if (node == NULL) return NULL;
-
- t = erl_alloc_eterm(ERL_REF);
- ERL_COUNT(t) = 1;
-
- if ((ERL_REF_NODE(t) = strsave(node)) == NULL)
- {
- erl_free_term(t);
- erl_errno = ENOMEM;
- return NULL;
+ if (t == NULL) {
+ if (node == NULL) return NULL;
+
+ t = erl_alloc_eterm(ERL_REF);
+ ERL_COUNT(t) = 1;
+
+ if (erl_atom_init_latin1(&t->uval.refval.node, node) == NULL)
+ {
+ erl_free_term(t);
+ erl_errno = ENOMEM;
+ return NULL;
+ }
}
ERL_REF_LEN(t) = len;
ERL_REF_NUMBERS(t)[0] = n[0] & 0x3ffff; /* 18 bits */
@@ -294,7 +364,7 @@ ETERM *erl_mk_ref (const char *node,
{
unsigned int n[3] = {0, 0, 0};
n[0] = number;
- return __erl_mk_reference(node, 1, n, creation);
+ return __erl_mk_reference(NULL, node, 1, n, creation);
}
/*
@@ -307,7 +377,7 @@ erl_mk_long_ref (const char *node,
{
unsigned int n[3] = {0, 0, 0};
n[0] = n3; n[1] = n2; n[2] = n1;
- return __erl_mk_reference(node, 3, n, creation);
+ return __erl_mk_reference(NULL, node, 3, n, creation);
}
/*
@@ -758,6 +828,28 @@ int erl_iolist_length (const ETERM* term)
return -1;
}
+static int erl_atom_copy(Erl_Atom_data* dst, const Erl_Atom_data* src)
+{
+ if (src->latin1 == src->utf8) {
+ dst->latin1 = dst->utf8 = strsave(src->latin1);
+ dst->lenL = dst->lenU = strlen(src->latin1);
+ }
+ else if (src->latin1) {
+ dst->latin1 = strsave(src->latin1);
+ dst->lenL = strlen(src->latin1);
+ dst->utf8 = NULL;
+ dst->lenU = 0;
+ }
+ else {
+ dst->utf8 = strsave(src->utf8);
+ dst->lenU = strlen(src->utf8);
+ dst->latin1 = NULL;
+ dst->lenL = 0;
+ }
+ return (dst->latin1 != NULL || dst->utf8 == NULL);
+}
+
+
/*
* Return a brand NEW COPY of an ETERM.
*/
@@ -796,9 +888,7 @@ ETERM *erl_copy_term(const ETERM *ep)
ERL_FLOAT_VALUE(cp) = ERL_FLOAT_VALUE(ep);
break;
case ERL_ATOM:
- ERL_ATOM_SIZE(cp) = ERL_ATOM_SIZE(ep);
- ERL_ATOM_PTR(cp) = strsave(ERL_ATOM_PTR(ep));
- if (ERL_ATOM_PTR(cp) == NULL)
+ if (!erl_atom_copy(&cp->uval.aval.d, &ep->uval.aval.d))
{
erl_free_term(cp);
erl_errno = ENOMEM;
@@ -810,17 +900,17 @@ ETERM *erl_copy_term(const ETERM *ep)
name and plug in. Somewhat ugly (also done with port and
ref below). */
memcpy(&cp->uval.pidval, &ep->uval.pidval, sizeof(Erl_Pid));
- ERL_PID_NODE(cp) = strsave(ERL_PID_NODE(ep));
+ erl_atom_copy(&cp->uval.pidval.node, &ep->uval.pidval.node);
ERL_COUNT(cp) = 1;
break;
case ERL_PORT:
memcpy(&cp->uval.portval, &ep->uval.portval, sizeof(Erl_Port));
- ERL_PORT_NODE(cp) = strsave(ERL_PORT_NODE(ep));
+ erl_atom_copy(&cp->uval.portval.node, &ep->uval.portval.node);
ERL_COUNT(cp) = 1;
break;
case ERL_REF:
memcpy(&cp->uval.refval, &ep->uval.refval, sizeof(Erl_Ref));
- ERL_REF_NODE(cp) = strsave(ERL_REF_NODE(ep));
+ erl_atom_copy(&cp->uval.refval.node, &ep->uval.refval.node);
ERL_COUNT(cp) = 1;
break;
case ERL_LIST:
@@ -883,29 +973,29 @@ int erl_print_term(FILE *fp, const ETERM *ep)
j = i = doquote = 0;
switch(ERL_TYPE(ep))
{
- case ERL_ATOM:
+ case ERL_ATOM: {
+ char* adata = ERL_ATOM_PTR(ep);
/* FIXME: what if some weird locale is in use? */
- if (!islower((int)ERL_ATOM_PTR(ep)[0]))
+ if (!islower(adata[0]))
doquote = 1;
for (i = 0; !doquote && i < ERL_ATOM_SIZE(ep); i++)
{
- doquote = !(isalnum((int)ERL_ATOM_PTR(ep)[i])
- || (ERL_ATOM_PTR(ep)[i] == '_'));
+ doquote = !(isalnum(adata[i]) || (adata[i] == '_'));
}
if (doquote) {
putc('\'', fp);
ch_written++;
}
- fputs(ERL_ATOM_PTR(ep), fp);
+ fputs(adata, fp);
ch_written += ERL_ATOM_SIZE(ep);
if (doquote) {
putc('\'', fp);
ch_written++;
}
break;
-
+ }
case ERL_VARIABLE:
if (!isupper((int)ERL_VAR_NAME(ep)[0])) {
doquote = 1;
diff --git a/lib/erl_interface/src/legacy/erl_eterm.h b/lib/erl_interface/src/legacy/erl_eterm.h
index 41b008f04f..2e8129d9cd 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.h
+++ b/lib/erl_interface/src/legacy/erl_eterm.h
@@ -55,7 +55,9 @@ typedef struct _heapmark {
} Erl_HeapMark;
-ETERM * __erl_mk_reference(const char *, size_t, unsigned int n[], unsigned char);
+void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned char creation);
+void erl_mk_pid_helper(ETERM*, unsigned,unsigned, unsigned char);
+ETERM * __erl_mk_reference(ETERM*, const char *, size_t, unsigned int n[], unsigned char);
int erl_current_fix_desc(void);
#endif /* _ERL_ETERM_H */
diff --git a/lib/erl_interface/src/legacy/erl_format.c b/lib/erl_interface/src/legacy/erl_format.c
index dc85806c36..533241e396 100644
--- a/lib/erl_interface/src/legacy/erl_format.c
+++ b/lib/erl_interface/src/legacy/erl_format.c
@@ -574,10 +574,22 @@ static int ematch(ETERM *p, ETERM *t)
switch (type_p) {
- case ERL_ATOM:
- return p->uval.aval.len == t->uval.aval.len &&
- memcmp(p->uval.aval.a, t->uval.aval.a, p->uval.aval.len) == 0;
-
+ case ERL_ATOM: {
+ Erl_Atom_data* pa = &p->uval.aval.d;
+ Erl_Atom_data* ta = &t->uval.aval.d;
+ if (pa->utf8 && ta->utf8) {
+ return pa->lenU == ta->lenU && memcmp(pa->utf8, ta->utf8, pa->lenU)==0;
+ }
+ else if (pa->latin1 && ta->latin1) {
+ return pa->lenL == ta->lenL && memcmp(pa->latin1, ta->latin1, pa->lenL)==0;
+ }
+ else if (pa->latin1) {
+ return cmp_latin1_vs_utf8(pa->latin1, pa->lenL, ta->utf8, ta->lenU)==0;
+ }
+ else {
+ return cmp_latin1_vs_utf8(ta->latin1, ta->lenL, pa->utf8, pa->lenU)==0;
+ }
+ }
case ERL_VARIABLE:
if (strcmp(p->uval.vval.name, "_") == 0) /* anon. variable */
return ERL_TRUE;
diff --git a/lib/erl_interface/src/legacy/erl_malloc.c b/lib/erl_interface/src/legacy/erl_malloc.c
index f51a6c69b3..d09239e02d 100644
--- a/lib/erl_interface/src/legacy/erl_malloc.c
+++ b/lib/erl_interface/src/legacy/erl_malloc.c
@@ -112,6 +112,18 @@ do { \
(ptr) = NULL; \
} while (0)
+static void erl_atom_free(Erl_Atom_data* p)
+{
+ erl_free(p->latin1);
+ if (p->utf8 != p->latin1) {
+ erl_free(p->utf8);
+ }
+ p->latin1 = NULL;
+ p->utf8 = NULL;
+ p->lenL = 0;
+ p->lenU = 0;
+}
+
static void _erl_free_term (ETERM *ep, int external, int compound)
{
restart:
@@ -122,7 +134,7 @@ restart:
switch(ERL_TYPE(ep))
{
case ERL_ATOM:
- FREE_AND_CLEAR(ERL_ATOM_PTR(ep));
+ erl_atom_free(&ep->uval.aval.d);
break;
case ERL_VARIABLE:
FREE_AND_CLEAR(ERL_VAR_NAME(ep));
@@ -161,13 +173,13 @@ restart:
FREE_AND_CLEAR(ERL_BIN_PTR(ep));
break;
case ERL_PID:
- FREE_AND_CLEAR(ERL_PID_NODE(ep));
+ erl_atom_free(&ep->uval.pidval.node);
break;
case ERL_PORT:
- FREE_AND_CLEAR(ERL_PORT_NODE(ep));
+ erl_atom_free(&ep->uval.portval.node);
break;
case ERL_REF:
- FREE_AND_CLEAR(ERL_REF_NODE(ep));
+ erl_atom_free(&ep->uval.refval.node);
break;
case ERL_EMPTY_LIST:
case ERL_INTEGER:
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index dad715c762..4c45cebb02 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -44,6 +44,9 @@ int erl_fp_compare(unsigned *a, unsigned *b);
static void erl_long_to_fp(long l, unsigned *d);
#endif
+static int cmpbytes(unsigned char* s1,int l1,unsigned char* s2,int l2);
+static int cmpatoms(unsigned char* s1, int l1, unsigned char tag1, unsigned char* s2, int l2, unsigned char tag2);
+
/* Used when comparing two encoded byte arrays */
/* this global data is ok (from threading point of view) since it is
* initialized once and never changed
@@ -51,7 +54,13 @@ static void erl_long_to_fp(long l, unsigned *d);
#define CMP_ARRAY_SIZE 256
/* FIXME problem for threaded ? */
-static char cmp_array[CMP_ARRAY_SIZE];
+
+static enum
+{
+ ERL_NUM_CMP=1, ERL_ATOM_CMP, ERL_REF_CMP, ERL_FUN_CMP, ERL_PORT_CMP,
+ ERL_PID_CMP, ERL_TUPLE_CMP, ERL_NIL_CMP, ERL_LIST_CMP, ERL_BIN_CMP
+}cmp_array[CMP_ARRAY_SIZE];
+
static int init_cmp_array_p=1; /* initialize array, the first time */
#if defined(VXWORKS) && CPU == PPC860
@@ -69,10 +78,8 @@ static int init_cmp_array_p=1; /* initialize array, the first time */
static int cmp_floats(double f1, double f2);
static INLINE double to_float(long l);
-#define ERL_NUM_CMP 1
-#define ERL_REF_CMP 3
-
#define IS_ERL_NUM(t) (cmp_array[t]==ERL_NUM_CMP)
+#define IS_ERL_ATOM(t) (cmp_array[t]==ERL_ATOM_CMP)
#define CMP_NUM_CLASS_SIZE 256
static unsigned char cmp_num_class[CMP_NUM_CLASS_SIZE];
@@ -100,25 +107,28 @@ void erl_init_marshal(void)
{
if (init_cmp_array_p) {
memset(cmp_array, 0, CMP_ARRAY_SIZE);
- cmp_array[ERL_SMALL_INTEGER_EXT] = 1;
- cmp_array[ERL_INTEGER_EXT] = 1;
- cmp_array[ERL_FLOAT_EXT] = 1;
- cmp_array[NEW_FLOAT_EXT] = 1;
- cmp_array[ERL_SMALL_BIG_EXT] = 1;
- cmp_array[ERL_LARGE_BIG_EXT] = 1;
- cmp_array[ERL_ATOM_EXT] = 2;
- cmp_array[ERL_REFERENCE_EXT] = 3;
- cmp_array[ERL_NEW_REFERENCE_EXT] = 3;
- cmp_array[ERL_FUN_EXT] = 4;
- cmp_array[ERL_NEW_FUN_EXT] = 4;
- cmp_array[ERL_PORT_EXT] = 5;
- cmp_array[ERL_PID_EXT] = 6;
- cmp_array[ERL_SMALL_TUPLE_EXT] = 7;
- cmp_array[ERL_LARGE_TUPLE_EXT] = 7;
- cmp_array[ERL_NIL_EXT] = 8;
- cmp_array[ERL_STRING_EXT] = 9;
- cmp_array[ERL_LIST_EXT] = 9;
- cmp_array[ERL_BINARY_EXT] = 10;
+ cmp_array[ERL_SMALL_INTEGER_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_INTEGER_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_FLOAT_EXT] = ERL_NUM_CMP;
+ cmp_array[NEW_FLOAT_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_SMALL_BIG_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_LARGE_BIG_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_ATOM_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_ATOM_UTF8_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_SMALL_ATOM_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_SMALL_ATOM_UTF8_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_REFERENCE_EXT] = ERL_REF_CMP;
+ cmp_array[ERL_NEW_REFERENCE_EXT] = ERL_REF_CMP;
+ cmp_array[ERL_FUN_EXT] = ERL_FUN_CMP;
+ cmp_array[ERL_NEW_FUN_EXT] = ERL_FUN_CMP;
+ cmp_array[ERL_PORT_EXT] = ERL_PORT_CMP;
+ cmp_array[ERL_PID_EXT] = ERL_PID_CMP;
+ cmp_array[ERL_SMALL_TUPLE_EXT] = ERL_TUPLE_CMP;
+ cmp_array[ERL_LARGE_TUPLE_EXT] = ERL_TUPLE_CMP;
+ cmp_array[ERL_NIL_EXT] = ERL_NIL_CMP;
+ cmp_array[ERL_STRING_EXT] = ERL_LIST_CMP;
+ cmp_array[ERL_LIST_EXT] = ERL_LIST_CMP;
+ cmp_array[ERL_BINARY_EXT] = ERL_BIN_CMP;
init_cmp_array_p = 0;
}
if (init_cmp_num_class_p) {
@@ -156,6 +166,21 @@ static int erl_length_x(const ETERM *ep) {
*==============================================================
*/
+static void encode_atom(Erl_Atom_data* a, unsigned char **ext)
+{
+ int ix = 0;
+ if (a->latin1) {
+ ei_encode_atom_len_as((char*)*ext, &ix, a->latin1, a->lenL,
+ ERLANG_LATIN1, ERLANG_LATIN1);
+ }
+ else if (ei_encode_atom_len_as((char*)*ext, &ix, a->utf8, a->lenU,
+ ERLANG_UTF8, ERLANG_LATIN1) < 0) {
+ ei_encode_atom_len_as((char*)*ext, &ix, a->utf8, a->lenU,
+ ERLANG_UTF8, ERLANG_UTF8);
+ }
+ *ext += ix;
+}
+
/*
* The actual ENCODE engine.
* Returns 0 on success, otherwise 1.
@@ -170,12 +195,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
switch(ERL_TYPE(ep))
{
case ERL_ATOM:
- i = ep->uval.aval.len;
- *(*ext)++ = ERL_ATOM_EXT;
- *(*ext)++ = (i >>8) &0xff;
- *(*ext)++ = i &0xff;
- memcpy((void *) *ext, (const void *) ep->uval.aval.a, i);
- *ext += i;
+ encode_atom(&ep->uval.aval.d, ext);
return 0;
case ERL_INTEGER:
@@ -286,12 +306,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
case ERL_PID:
*(*ext)++ = ERL_PID_EXT;
/* First poke in node as an atom */
- i = strlen((char *)ERL_PID_NODE(ep));
- *(*ext)++ = ERL_ATOM_EXT;
- *(*ext)++ = (i >>8) &0xff;
- *(*ext)++ = i &0xff;
- memcpy(*ext, ERL_PID_NODE(ep), i);
- *ext += i;
+ encode_atom(&ep->uval.pidval.node, ext);
/* And then fill in the integer fields */
i = ERL_PID_NUMBER(ep);
*(*ext)++ = (i >> 24) &0xff;
@@ -319,11 +334,8 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
*(*ext)++ = (len >> 8) &0xff;
*(*ext)++ = len &0xff;
- *(*ext)++ = ERL_ATOM_EXT;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- memcpy(*ext, ERL_REF_NODE(ep), i);
- *ext += i;
+ encode_atom(&ep->uval.refval.node, ext);
+
*(*ext)++ = ERL_REF_CREATION(ep);
/* Then the integer fields */
for (j = 0; j < ERL_REF_LEN(ep); j++) {
@@ -338,12 +350,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
case ERL_PORT:
*(*ext)++ = ERL_PORT_EXT;
/* First poke in node as an atom */
- i = strlen((char *)ERL_PORT_NODE(ep));
- *(*ext)++ = ERL_ATOM_EXT;
- *(*ext)++ = (i >>8) &0xff;
- *(*ext)++ = i &0xff;
- memcpy(*ext, ERL_PORT_NODE(ep), i);
- *ext += i;
+ encode_atom(&ep->uval.portval.node, ext);
/* Then the integer fields */
i = ERL_PORT_NUMBER(ep);
*(*ext)++ = (i >> 24) &0xff;
@@ -494,6 +501,16 @@ int erl_term_len(ETERM *ep)
return 1+erl_term_len_helper(ep, 4);
}
+static int atom_len_helper(Erl_Atom_data* a)
+{
+ if (erl_atom_ptr_latin1(a)) {
+ return 1 + 2 + a->lenL; /* ERL_ATOM_EXT */
+ }
+ else {
+ return 1 + 1 + (a->lenU > 255) + a->lenU;
+ }
+}
+
static int erl_term_len_helper(ETERM *ep, int dist)
{
int len = 0;
@@ -505,8 +522,7 @@ static int erl_term_len_helper(ETERM *ep, int dist)
if (ep) {
switch (ERL_TYPE(ep)) {
case ERL_ATOM:
- i = ep->uval.aval.len;
- len = i + 3;
+ len = atom_len_helper(&ep->uval.aval.d);
break;
case ERL_INTEGER:
@@ -538,20 +554,15 @@ static int erl_term_len_helper(ETERM *ep, int dist)
break;
case ERL_PID:
- /* 1 + N + 4 + 4 + 1 where N = 3 + strlen */
- i = strlen((char *)ERL_PID_NODE(ep));
- len = 13 + i;
+ len = 1 + atom_len_helper(&ep->uval.pidval.node) + 4 + 4 + 1;
break;
case ERL_REF:
- i = strlen((char *)ERL_REF_NODE(ep));
- len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
+ len = 1 + 2 + atom_len_helper(&ep->uval.refval.node) + 1 + ERL_REF_LEN(ep) * 4;
break;
case ERL_PORT:
- /* 1 + N + 4 + 1 where N = 3 + strlen */
- i = strlen((char *)ERL_PORT_NODE(ep));
- len = 9 + i;
+ len = 1 + atom_len_helper(&ep->uval.portval.node) + 4 + 1;
break;
case ERL_EMPTY_LIST:
@@ -644,31 +655,36 @@ int erl_encode_buf(ETERM *ep, unsigned char **ext)
} /* erl_encode_buf */
-/*
- * A nice macro to make it look cleaner in the
- * cases of PID's,PORT's and REF's below.
- * It reads the NODE name from a buffer.
- */
-#define READ_THE_NODE(ext,cp,len,i) \
-/* eat first atom, repr. the node */ \
-if (**ext != ERL_ATOM_EXT) \
- return (ETERM *) NULL; \
-*ext += 1; \
-i = (**ext << 8) | (*ext)[1]; \
-cp = (char *) *(ext) + 2; \
-*ext += (i + 2); \
-len = i
-
-#define STATIC_NODE_BUF_SZ 30
-
-#define SET_NODE(node,node_buf,cp,len) \
-if (len >= STATIC_NODE_BUF_SZ) node = erl_malloc(len+1); \
-else node = node_buf; \
-memcpy(node, cp, len); \
-node[len] = '\0'
-
-#define RESET_NODE(node,len) \
-if (len >= STATIC_NODE_BUF_SZ) free(node)
+
+static int read_atom(unsigned char** ext, Erl_Atom_data* a)
+{
+ char buf[MAXATOMLEN_UTF8];
+ int offs = 0;
+ enum erlang_char_encoding enc;
+ int ret = ei_decode_atom_as((char*)*ext, &offs, buf, MAXATOMLEN_UTF8,
+ ERLANG_LATIN1|ERLANG_UTF8, NULL, &enc);
+ *ext += offs;
+
+ if (ret == 0) {
+ int i = strlen(buf);
+ char* clone = erl_malloc(i+1);
+ memcpy(clone, buf, i+1);
+
+ a->latin1 = NULL;
+ a->lenL = 0;
+ a->utf8 = NULL;
+ a->lenU = 0;
+ if (enc & (ERLANG_LATIN1 | ERLANG_ASCII)) {
+ a->latin1 = clone;
+ a->lenL = i;
+ }
+ if (enc & (ERLANG_UTF8 | ERLANG_ASCII)) {
+ a->utf8 = clone;
+ a->lenU = i;
+ }
+ }
+ return ret;
+}
/*
* The actual DECODE engine.
@@ -679,13 +695,13 @@ static ETERM *erl_decode_it(unsigned char **ext)
char *cp;
ETERM *ep,*tp,*np;
unsigned int u,sign;
- int i,j,len,arity;
+ int i,j,arity;
double ff;
/* Assume we are going to decode an integer */
ep = erl_alloc_eterm(ERL_INTEGER);
ERL_COUNT(ep) = 1;
-
+
switch (*(*ext)++)
{
case ERL_INTEGER_EXT:
@@ -774,138 +790,90 @@ static ETERM *erl_decode_it(unsigned char **ext)
return ep;
case ERL_ATOM_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_ATOM_UTF8_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
+
ERL_TYPE(ep) = ERL_ATOM;
- i = (**ext << 8) | (*ext)[1];
- cp = (char *) *(ext) + 2;
- *ext += (i + 2);
- ep->uval.aval.len = i;
- ep->uval.aval.a = (char *) erl_malloc(i+1);
- memcpy(ep->uval.aval.a, cp, i);
- ep->uval.aval.a[i]='\0';
+ --(*ext);
+ if (read_atom(ext, &ep->uval.aval.d) < 0) return NULL;
return ep;
case ERL_PID_EXT:
- erl_free_term(ep);
- { /* Why not use the constructors? */
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
+ {
unsigned int number, serial;
unsigned char creation;
- ETERM *eterm_p;
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ ERL_TYPE(ep) = ERL_PID;
+ if (read_atom(ext, &ep->uval.pidval.node) < 0) return NULL;
/* get the integers */
-#if 0
- /* FIXME: Remove code or whatever....
- Ints on the wire are big-endian (== network byte order)
- so use ntoh[sl]. (But some are little-endian! Arrrgh!)
- Also, the libc authors can be expected to optimize them
- heavily. However, the marshalling makes no guarantees
- about alignments -- so it won't work at all. */
- number = ntohl(*((unsigned int *)*ext)++);
- serial = ntohl(*((unsigned int *)*ext)++);
-#else
number = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
((*ext)[2]) << 8 | ((*ext)[3]);
*ext += 4;
serial = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
((*ext)[2]) << 8 | ((*ext)[3]);
*ext += 4;
-#endif
creation = *(*ext)++;
- eterm_p = erl_mk_pid(node, number, serial, creation);
- RESET_NODE(node,len);
- return eterm_p;
+ erl_mk_pid_helper(ep, number, serial, creation);
+ return ep;
}
case ERL_REFERENCE_EXT:
- erl_free_term(ep);
{
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
- unsigned int number;
+ unsigned int n[3] = {0, 0, 0};
unsigned char creation;
- ETERM *eterm_p;
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ ERL_TYPE(ep) = ERL_REF;
+ if (read_atom(ext, &ep->uval.refval.node) < 0) return NULL;
/* get the integers */
-#if 0
- number = ntohl(*((unsigned int *)*ext)++);
-#else
- number = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
+ n[0] = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
((*ext)[2]) << 8 | ((*ext)[3]);
*ext += 4;
-#endif
creation = *(*ext)++;
- eterm_p = erl_mk_ref(node, number, creation);
- RESET_NODE(node,len);
- return eterm_p;
+ __erl_mk_reference(ep, NULL, 1, n, creation);
+ return ep;
}
case ERL_NEW_REFERENCE_EXT:
- erl_free_term(ep);
{
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
size_t cnt, i;
unsigned int n[3];
unsigned char creation;
- ETERM *eterm_p;
-#if 0
- cnt = ntohs(*((unsigned short *)*ext)++);
-#else
+ ERL_TYPE(ep) = ERL_REF;
cnt = ((*ext)[0] << 8) | (*ext)[1];
*ext += 2;
-#endif
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ if (read_atom(ext, &ep->uval.refval.node) < 0) return NULL;
/* get the integers */
creation = *(*ext)++;
for(i = 0; i < cnt; i++)
{
-#if 0
- n[i] = ntohl(*((unsigned int *)*ext)++);
-#else
n[i] = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
((*ext)[2]) << 8 | ((*ext)[3]);
*ext += 4;
-#endif
}
- eterm_p = __erl_mk_reference(node, cnt, n, creation);
- RESET_NODE(node,len);
- return eterm_p;
+ __erl_mk_reference(ep, NULL, cnt, n, creation);
+ return ep;
}
case ERL_PORT_EXT:
- erl_free_term(ep);
{
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
unsigned int number;
unsigned char creation;
- ETERM *eterm_p;
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ ERL_TYPE(ep) = ERL_PORT;
+ if (read_atom(ext, &ep->uval.portval.node) < 0) return NULL;
/* get the integers */
-#if 0
- number = ntohl(*((unsigned int *)*ext)++);
-#else
number = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
((*ext)[2]) << 8 | ((*ext)[3]);
*ext += 4;
-#endif
creation = *(*ext)++;
- eterm_p = erl_mk_port(node, number, creation);
- RESET_NODE(node,len);
- return eterm_p;
+ erl_mk_port_helper(ep, number, creation);
+ return ep;
}
case ERL_NIL_EXT:
@@ -1140,6 +1108,9 @@ unsigned char erl_ext_type(unsigned char *ext)
case ERL_INTEGER_EXT:
return ERL_INTEGER;
case ERL_ATOM_EXT:
+ case ERL_ATOM_UTF8_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
return ERL_ATOM;
case ERL_PID_EXT:
return ERL_PID;
@@ -1191,6 +1162,9 @@ int erl_ext_size(unsigned char *t)
case ERL_SMALL_INTEGER_EXT:
case ERL_INTEGER_EXT:
case ERL_ATOM_EXT:
+ case ERL_ATOM_UTF8_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
case ERL_PID_EXT:
case ERL_PORT_EXT:
case ERL_REFERENCE_EXT:
@@ -1229,15 +1203,32 @@ int erl_ext_size(unsigned char *t)
} /* ext_size */
-/*
- * A nice macro that eats up the atom pointed to.
- */
-#define JUMP_ATOM(ext,i) \
-if (**ext != ERL_ATOM_EXT) \
- return 0; \
-*ext += 1; \
-i = (**ext << 8) | (*ext)[1]; \
-*ext += (i + 2)
+
+static int jump_atom(unsigned char** ext)
+{
+ unsigned char* e = *ext;
+ int len;
+
+ switch (*e++) {
+ case ERL_ATOM_EXT:
+ case ERL_ATOM_UTF8_EXT:
+ len = (e[0] << 8) | e[1];
+ e += (len + 2);
+ break;
+
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
+ len = e[0];
+ e += (len + 1);
+ break;
+
+ default:
+ return 0;
+ }
+ *ext = e;
+ return 1;
+}
+
/*
* MOVE the POINTER PAST the ENCODED ETERM we
@@ -1259,25 +1250,27 @@ static int jump(unsigned char **ext)
*ext += 1;
break;
case ERL_ATOM_EXT:
- i = (**ext << 8) | (*ext)[1];
- *ext += (i + 2);
+ case ERL_ATOM_UTF8_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
+ jump_atom(ext);
break;
case ERL_PID_EXT:
/* eat first atom */
- JUMP_ATOM(ext,i);
+ if (!jump_atom(ext)) return 0;
*ext += 9; /* Two int's and the creation field */
break;
case ERL_REFERENCE_EXT:
case ERL_PORT_EXT:
/* first field is an atom */
- JUMP_ATOM(ext,i);
+ if (!jump_atom(ext)) return 0;
*ext += 5; /* One int and the creation field */
break;
case ERL_NEW_REFERENCE_EXT:
n = (**ext << 8) | (*ext)[1];
*ext += 2;
/* first field is an atom */
- JUMP_ATOM(ext,i);
+ if (!jump_atom(ext)) return 0;
*ext += 4*n+1;
break;
case ERL_NIL_EXT:
@@ -1425,6 +1418,58 @@ static int cmpbytes(unsigned char* s1,int l1,unsigned char* s2,int l2)
} /* cmpbytes */
+#define tag2enc(T) ((T)==ERL_ATOM_EXT || (T)==ERL_SMALL_ATOM_EXT ? ERLANG_LATIN1 : ERLANG_UTF8)
+
+static int cmpatoms(unsigned char* s1, int l1, unsigned char tag1,
+ unsigned char* s2, int l2, unsigned char tag2)
+{
+ enum erlang_char_encoding enc1 = tag2enc(tag1);
+ enum erlang_char_encoding enc2 = tag2enc(tag2);
+
+ if (enc1 == enc2) {
+ return cmpbytes(s1, l1,s2,l2);
+ }
+
+ if (enc1 == ERLANG_LATIN1) {
+ return cmp_latin1_vs_utf8((char*)s1, l1, (char*)s2, l2);
+ }
+ else {
+ return -cmp_latin1_vs_utf8((char*)s2, l2, (char*)s1, l1);
+ }
+}
+
+int cmp_latin1_vs_utf8(const char* strL, int lenL, const char* strU, int lenU)
+{
+ unsigned char* sL = (unsigned char*)strL;
+ unsigned char* sU = (unsigned char*)strU;
+ unsigned char* sL_end = sL + lenL;
+ unsigned char* sU_end = sU + lenU;
+
+ while(sL < sL_end && sU < sU_end) {
+ unsigned char UasL;
+ if (*sL >= 0x80) {
+ if (*sU < 0xC4 && (sU+1) < sU_end) {
+ UasL = ((sU[0] & 0x3) << 6) | (sU[1] & 0x3F);
+ }
+ else return -1;
+ }
+ else {
+ UasL = *sU;
+ }
+ if (*sL < UasL) return -1;
+ if (*sL > UasL) return 1;
+
+ sL++;
+ if (*sU < 0x80) sU++;
+ else if (*sU < 0xE0) sU += 2;
+ else if (*sU < 0xF0) sU += 3;
+ else /*if (*sU < 0xF8)*/ sU += 4;
+ }
+
+ return (sU >= sU_end) - (sL >= sL_end); /* -1, 0 or 1 */
+}
+
+
#define CMP_EXT_ERROR_CODE 4711
#define CMP_EXT_INT32_BE(AP, BP) \
@@ -1437,9 +1482,8 @@ do { \
#define CMP_EXT_SKIP_ATOM(EP) \
do { \
- if ((EP)[0] != ERL_ATOM_EXT) \
+ if (!jump_atom(&(EP))) \
return CMP_EXT_ERROR_CODE; \
- (EP) += 3 + ((EP)[1] << 8 | (EP)[2]); \
} while (0)
/*
@@ -1561,6 +1605,7 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
int min, ret,i,j,k;
double ff1, ff2;
unsigned char *tmp1, *tmp2;
+ unsigned char tag1, tag2;
if ( ((*e1)[0] == ERL_STRING_EXT) && ((*e2)[0] == ERL_LIST_EXT) ) {
return cmp_string_list(e1, e2);
@@ -1568,8 +1613,10 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
return -cmp_string_list(e2, e1);
}
- *e2 += 1;
- switch (*(*e1)++)
+ tag1 = *(*e1)++;
+ tag2 = *(*e2)++;
+ i = j = 0;
+ switch (tag1)
{
case ERL_SMALL_INTEGER_EXT:
if (**e1 < **e2) ret = -1;
@@ -1589,11 +1636,17 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
*e1 += 4; *e2 += 4;
return ret;
case ERL_ATOM_EXT:
- i = (**e1 << 8) | (*e1)[1];
- j = (**e2 << 8) | (*e2)[1];
- ret = cmpbytes(*e1 +2, i, *e2 +2, j);
- *e1 += (i + 2);
- *e2 += (j + 2);
+ case ERL_ATOM_UTF8_EXT:
+ i = (**e1) << 8; (*e1)++;
+ j = (**e2) << 8; (*e2)++;
+ /*fall through*/
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
+ i |= (**e1); (*e1)++;
+ j |= (**e2); (*e2)++;
+ ret = cmpatoms(*e1, i, tag1, *e2, j, tag2);
+ *e1 += i;
+ *e2 += j;
return ret;
case ERL_PID_EXT: {
unsigned char *n1 = *e1;
@@ -1622,7 +1675,7 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
}
case ERL_PORT_EXT:
/* First compare node names ... */
- if (**e1 != ERL_ATOM_EXT || **e2 != ERL_ATOM_EXT)
+ if (!IS_ERL_ATOM(**e1) || !IS_ERL_ATOM(**e2))
return CMP_EXT_ERROR_CODE;
ret = cmp_exe2(e1, e2);
*e1 += 5; *e2 += 5;
diff --git a/lib/erl_interface/src/legacy/global_whereis.c b/lib/erl_interface/src/legacy/global_whereis.c
index 2afb193504..e6c556d907 100644
--- a/lib/erl_interface/src/legacy/global_whereis.c
+++ b/lib/erl_interface/src/legacy/global_whereis.c
@@ -85,7 +85,16 @@ ETERM *erl_global_whereis(int fd, const char *name, char *node)
opid = erl_decode((unsigned char*)buf);
/* extract the nodename for the caller */
- if (node) strcpy(node,epid.node);
+ if (node) {
+ char* node_str = ERL_PID_NODE(opid);
+ if (node_str) {
+ strcpy(node, node_str);
+ }
+ else {
+ erl_free_term(opid);
+ return NULL;
+ }
+ }
return opid;
}
diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c
index 0b82ef0e35..65afee89cc 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -32,7 +32,7 @@
int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
{
const char* s = buf + *index, * s0 = s;
- int len, i, n, sign;
+ int i, n, sign;
char c;
if (term == NULL) return -1;
@@ -48,20 +48,13 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
case NEW_FLOAT_EXT:
return ei_decode_double(buf, index, &term->value.d_val);
case ERL_ATOM_EXT:
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.atom_name, s, len);
- term->value.atom_name[len] = '\0';
- s += len;
- break;
+ case ERL_ATOM_UTF8_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
+ return ei_decode_atom(buf, index, term->value.atom_name);
case ERL_REFERENCE_EXT:
/* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.ref.node, s, len);
- term->value.ref.node[len] = '\0';
- s += len;
+ if (get_atom(&s, term->value.ref.node, &term->value.ref.node_org_enc) < 0) return -1;
/* now the numbers: num (4), creation (1) */
term->value.ref.n[0] = get32be(s);
term->value.ref.len = 1;
@@ -71,12 +64,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
/* first the integer count */
term->value.ref.len = get16be(s);
/* then the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.ref.node, s, len);
- term->value.ref.node[len] = '\0';
- s += len;
+ if (get_atom(&s, term->value.ref.node, &term->value.ref.node_org_enc) < 0) return -1;
/* creation */
term->value.ref.creation = get8(s) & 0x03;
/* finally the id integers */
@@ -88,22 +76,12 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
}
break;
case ERL_PORT_EXT:
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.port.node, s, len);
- term->value.port.node[len] = '\0';
+ if (get_atom(&s, term->value.port.node, &term->value.port.node_org_enc) < 0) return -1;
term->value.port.id = get32be(s) & 0x0fffffff; /* 28 bits */;
term->value.port.creation = get8(s) & 0x03;
break;
case ERL_PID_EXT:
- if (get8(s) != ERL_ATOM_EXT) return -1;
- /* name first */
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.pid.node, s, len);
- term->value.pid.node[len] = '\0';
- s += len;
+ if (get_atom(&s, term->value.pid.node, &term->value.port.node_org_enc) < 0) return -1;
/* now the numbers: num (4), serial (4), creation (1) */
term->value.pid.num = get32be(s) & 0x7fff; /* 15 bits */
term->value.pid.serial = get32be(s) & 0x1fff; /* 13 bits */
diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index 281a192535..b5f11e618e 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -139,8 +139,8 @@ static int patom(const char** fmt, ei_x_buff* x)
--(*fmt);
len = *fmt - start;
/* FIXME why truncate atom name and not fail?! */
- if (len > MAXATOMLEN)
- len = MAXATOMLEN;
+ if (len >= MAXATOMLEN)
+ len = MAXATOMLEN-1;
return ei_x_encode_atom_len(x, start, len);
}
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index 5fc6b3542c..f3003a6172 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -115,7 +115,7 @@ static int print_term(FILE* fp, ei_x_buff* x,
const char* buf, int* index)
{
int i, doquote, n, m, ty, r;
- char a[MAXATOMLEN+1], *p;
+ char a[MAXATOMLEN], *p;
int ch_written = 0; /* counter of written chars */
erlang_pid pid;
erlang_port port;
@@ -132,7 +132,10 @@ static int print_term(FILE* fp, ei_x_buff* x,
doquote = 0;
ei_get_type_internal(buf, index, &ty, &n);
switch (ty) {
- case ERL_ATOM_EXT:
+ case ERL_ATOM_EXT:
+ case ERL_ATOM_UTF8_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
if (ei_decode_atom(buf, index, a) < 0)
goto err;
doquote = !islower((int)a[0]);
diff --git a/lib/erl_interface/src/misc/ei_x_encode.c b/lib/erl_interface/src/misc/ei_x_encode.c
index fa1e26ccbb..44dcff7664 100644
--- a/lib/erl_interface/src/misc/ei_x_encode.c
+++ b/lib/erl_interface/src/misc/ei_x_encode.c
@@ -197,18 +197,33 @@ int ei_x_encode_tuple_header(ei_x_buff* x, long n)
int ei_x_encode_atom(ei_x_buff* x, const char* s)
{
- return ei_x_encode_atom_len(x, s, strlen(s));
+ return ei_x_encode_atom_len_as(x, s, strlen(s), ERLANG_LATIN1, ERLANG_LATIN1);
}
int ei_x_encode_atom_len(ei_x_buff* x, const char* s, int len)
{
+ return ei_x_encode_atom_len_as(x, s, len, ERLANG_LATIN1, ERLANG_LATIN1);
+}
+
+int ei_x_encode_atom_as(ei_x_buff* x, const char* s,
+ enum erlang_char_encoding from_enc,
+ enum erlang_char_encoding to_enc)
+{
+ return ei_x_encode_atom_len_as(x, s, strlen(s), from_enc, to_enc);
+}
+
+int ei_x_encode_atom_len_as(ei_x_buff* x, const char* s, int len,
+ enum erlang_char_encoding from_enc,
+ enum erlang_char_encoding to_enc)
+{
int i = x->index;
- ei_encode_atom_len(NULL, &i, s, len);
+ ei_encode_atom_len_as(NULL, &i, s, len, from_enc, to_enc);
if (!x_fix_buff(x, i))
return -1;
- return ei_encode_atom_len(x->buff, &x->index, s, len);
+ return ei_encode_atom_len_as(x->buff, &x->index, s, len, from_enc, to_enc);
}
+
int ei_x_encode_pid(ei_x_buff* x, const erlang_pid* pid)
{
int i = x->index;
diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c
index 2a680d0f94..54465196b0 100644
--- a/lib/erl_interface/src/misc/get_type.c
+++ b/lib/erl_interface/src/misc/get_type.c
@@ -33,78 +33,6 @@ int ei_get_type(const char *buf, const int *index, int *type, int *len)
return ei_get_type_internal(buf, index, type, len);
}
-#if 0
-int ei_get_type(const char *buf, const int *index, int *type, int *len)
-{
- const char *s = buf + *index;
- int itype = get8(s); /* Internal type */
-
- *len = 0;
-
- switch (*type) {
-
- case ERL_SMALL_INTEGER_EXT:
- case ERL_INTEGER_EXT:
- case ERL_SMALL_BIG_EXT:
- case ERL_LARGE_BIG_EXT:
- *type = EI_TYPE_INTEGER;
- break;
-
- case ERL_FLOAT_EXT:
- *type = EI_TYPE_FLOAT;
- break;
-
- case ERL_SMALL_TUPLE_EXT:
- *len = get8(s);
- break;
-
- case ERL_ATOM_EXT:
- case ERL_STRING_EXT:
- *len = get16be(s);
- break;
-
- case ERL_LARGE_TUPLE_EXT:
- case ERL_LIST_EXT:
- case ERL_BINARY_EXT:
- *len = get32be(s);
- break;
-
- case ERL_SMALL_BIG_EXT:
- *len = (get8(s)+1)/2; /* big arity */
- break;
-
- case ERL_LARGE_BIG_EXT:
- *len = (get32be(s)+1)/2; /* big arity */
- break;
-
- case ERL_BINARY_EXT:
- *type = EI_TYPE_BINARY;
- break;
-
- case ERL_PID_EXT:
- *type = EI_TYPE_PID;
- break;
-
- case ERL_PORT_EXT:
- *type = EI_TYPE_PORT;
- break;
-
- case ERL_REFERENCE_EXT:
- case ERL_NEW_REFERENCE_EXT:
- *type = EI_TYPE_REF;
- break;
-
- default:
- break;
- }
-
- /* leave index unchanged */
- return 0;
-}
-#endif
-
-
-/* Old definition of function above */
int ei_get_type_internal(const char *buf, const int *index,
int *type, int *len)
@@ -114,10 +42,15 @@ int ei_get_type_internal(const char *buf, const int *index,
*type = get8(s);
switch (*type) {
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_SMALL_ATOM_UTF8_EXT:
+ *type = ERL_ATOM_EXT;
case ERL_SMALL_TUPLE_EXT:
*len = get8(s);
break;
-
+
+ case ERL_ATOM_UTF8_EXT:
+ *type = ERL_ATOM_EXT;
case ERL_ATOM_EXT:
case ERL_STRING_EXT:
*len = get16be(s);
diff --git a/lib/erl_interface/src/misc/putget.h b/lib/erl_interface/src/misc/putget.h
index 7a43de324b..77ae168f8c 100644
--- a/lib/erl_interface/src/misc/putget.h
+++ b/lib/erl_interface/src/misc/putget.h
@@ -105,6 +105,13 @@
((EI_ULONGLONG)((unsigned char *)(s))[-2] << 8) | \
(EI_ULONGLONG)((unsigned char *)(s))[-1]))
+int utf8_to_latin1(char* dst, const char* src, int slen, int destlen, enum erlang_char_encoding* res_encp);
+int latin1_to_utf8(char* dst, const char* src, int slen, int destlen, enum erlang_char_encoding* res_encp);
+int ei_internal_get_atom(const char** bufp, char* p, enum erlang_char_encoding*);
+int ei_internal_put_atom(char** bufp, const char* p, int slen, enum erlang_char_encoding);
+#define get_atom ei_internal_get_atom
+#define put_atom ei_internal_put_atom
+
typedef union float_ext {
double d;
EI_ULONGLONG val;
diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c
index 194296798b..33b09643ca 100644
--- a/lib/erl_interface/src/misc/show_msg.c
+++ b/lib/erl_interface/src/misc/show_msg.c
@@ -132,13 +132,13 @@ int ei_show_sendmsg(FILE *stream, const char *header, const char *msgbuf)
switch (msg.msgtype) {
case ERL_SEND:
- if (ei_decode_atom(header,&index,msg.cookie)
+ if (ei_decode_atom_as(header,&index,msg.cookie,sizeof(msg.cookie),ERLANG_UTF8,NULL,NULL)
|| ei_decode_pid(header,&index,&msg.to)) return -1;
mbuf = msgbuf;
break;
case ERL_SEND_TT:
- if (ei_decode_atom(header,&index,msg.cookie)
+ if (ei_decode_atom_as(header,&index,msg.cookie,sizeof(msg.cookie),ERLANG_UTF8,NULL,NULL)
|| ei_decode_pid(header,&index,&msg.to)
|| ei_decode_trace(header,&index,&msg.token)) return -1;
mbuf = msgbuf;
@@ -146,15 +146,15 @@ int ei_show_sendmsg(FILE *stream, const char *header, const char *msgbuf)
case ERL_REG_SEND:
if (ei_decode_pid(header,&index,&msg.from)
- || ei_decode_atom(header,&index,msg.cookie)
- || ei_decode_atom(header,&index,msg.toname)) return -1;
+ || ei_decode_atom_as(header,&index,msg.cookie,sizeof(msg.cookie),ERLANG_UTF8,NULL,NULL)
+ || ei_decode_atom_as(header,&index,msg.toname,sizeof(msg.toname),ERLANG_UTF8,NULL,NULL)) return -1;
mbuf = msgbuf;
break;
case ERL_REG_SEND_TT:
if (ei_decode_pid(header,&index,&msg.from)
- || ei_decode_atom(header,&index,msg.cookie)
- || ei_decode_atom(header,&index,msg.toname)
+ || ei_decode_atom_as(header,&index,msg.cookie,sizeof(msg.cookie),ERLANG_UTF8,NULL,NULL)
+ || ei_decode_atom_as(header,&index,msg.toname,sizeof(msg.toname),ERLANG_UTF8,NULL,NULL)
|| ei_decode_trace(header,&index,&msg.token)) return -1;
mbuf = msgbuf;
break;
@@ -457,7 +457,7 @@ static void show_term(const char *termbuf, int *index, FILE *stream)
break;
case ERL_FUN_EXT: {
- char atom[MAXATOMLEN+1];
+ char atom[MAXATOMLEN];
long idx;
long uniq;
const char* s = termbuf + *index, * s0 = s;
diff --git a/lib/erl_interface/src/prog/ei_fake_prog.c b/lib/erl_interface/src/prog/ei_fake_prog.c
index 68eb537211..34101a2851 100644
--- a/lib/erl_interface/src/prog/ei_fake_prog.c
+++ b/lib/erl_interface/src/prog/ei_fake_prog.c
@@ -96,6 +96,7 @@ int main(void)
EI_ULONGLONG *ulonglongp = (EI_ULONGLONG*)NULL;
EI_ULONGLONG ulonglongx = 0;
#endif
+ enum erlang_char_encoding enc;
intx = erl_errno;
@@ -148,9 +149,13 @@ int main(void)
ei_x_encode_string(&eix, charp);
ei_x_encode_string_len(&eix, charp, intx);
ei_encode_atom(charp, intp, charp);
+ ei_encode_atom_as(charp, intp, charp, ERLANG_LATIN1, ERLANG_UTF8);
ei_encode_atom_len(charp, intp, charp, intx);
+ ei_encode_atom_len_as(charp, intp, charp, intx, ERLANG_ASCII, ERLANG_LATIN1);
ei_x_encode_atom(&eix, charp);
+ ei_x_encode_atom_as(&eix, charp, ERLANG_LATIN1, ERLANG_UTF8);
ei_x_encode_atom_len(&eix, charp, intx);
+ ei_x_encode_atom_len_as(&eix, charp, intx, ERLANG_LATIN1, ERLANG_UTF8);
ei_encode_binary(charp, intp, (void *)0, longx);
ei_x_encode_binary(&eix, (void*)0, intx);
ei_encode_pid(charp, intp, &epid);
@@ -181,6 +186,7 @@ int main(void)
ei_decode_char(charp, intp, charp);
ei_decode_string(charp, intp, charp);
ei_decode_atom(charp, intp, charp);
+ ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_WHATEVER, &enc, &enc);
ei_decode_binary(charp, intp, (void *)0, longp);
ei_decode_fun(charp, intp, &efun);
free_fun(&efun);
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
index 85cb62239b..0c98b494ec 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
@@ -118,6 +118,13 @@ test_ei_decode_encode(Config) when is_list(Config) ->
?line send_rec(P, OXPort),
?line send_rec(P, OXRef),
+ %% Unicode atoms
+ [begin send_rec(P, Atom),
+ send_rec(P, mk_pid({Atom,1}, 23434, 3434)),
+ send_rec(P, mk_port({Atom,1}, 2343434)),
+ send_rec(P, mk_ref({Atom,1}, [262143, 8723648, 24097245])),
+ void
+ end || Atom <- unicode_atom_data()],
?line runner:recv_eot(P),
ok.
@@ -127,7 +134,7 @@ test_ei_decode_encode(Config) when is_list(Config) ->
% We read two packets for each test, the ei_decode_encode and ei_x_decode_encode version....
send_rec(P, Term) when is_port(P) ->
- ?t:format("Testing: ~p~n", [Term]),
+ %%?t:format("Testing: ~p~n", [Term]),
P ! {self(), {command, term_to_binary(Term)}},
{_B,Term} = get_buf_and_term(P).
@@ -146,7 +153,7 @@ get_buf_and_term(P) ->
_ ->
B1 = list_to_binary([131,B]), % No magic, add
T = binary_to_term(B1),
- io:format("~w\n~w\n(got no magic)\n",[B,T]),
+ %io:format("~w\n~w\n(got no magic)\n",[B,T]),
{B,T}
end.
@@ -160,7 +167,7 @@ get_binary(P) ->
case runner:get_term(P) of
{bytes,L} ->
B = list_to_binary(L),
- io:format("~w\n",[L]),
+ %%io:format("~w\n",[L]),
% For strange reasons <<131>> show up as <>....
% io:format("~w\n",[B]),
B;
@@ -226,38 +233,36 @@ uint8(Uint) ->
mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) ->
- mk_pid({atom_to_list(NodeName), Creation}, Number, Serial);
-mk_pid({NodeName, Creation}, Number, Serial) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_pid({NodeNameExt, Creation}, Number, Serial);
+mk_pid({NodeNameExt, Creation}, Number, Serial) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?PID_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint32_be(Number),
uint32_be(Serial),
uint8(Creation)])) of
Pid when is_pid(Pid) ->
Pid;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]});
+ exit({badarg, mk_pid, [{NodeNameExt, Creation}, Number, Serial]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end.
mk_port({NodeName, Creation}, Number) when is_atom(NodeName) ->
- mk_port({atom_to_list(NodeName), Creation}, Number);
-mk_port({NodeName, Creation}, Number) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_port({NodeNameExt, Creation}, Number);
+mk_port({NodeNameExt, Creation}, Number) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?PORT_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint32_be(Number),
uint8(Creation)])) of
Port when is_port(Port) ->
Port;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_port, [{NodeName, Creation}, Number]});
+ exit({badarg, mk_port, [{NodeNameExt, Creation}, Number]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end.
@@ -265,33 +270,30 @@ mk_port({NodeName, Creation}, Number) ->
mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName),
is_integer(Creation),
is_list(Numbers) ->
- mk_ref({atom_to_list(NodeName), Creation}, Numbers);
-mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName),
- is_integer(Creation),
- is_integer(Number) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_ref({NodeNameExt, Creation}, Numbers);
+mk_ref({NodeNameExt, Creation}, [Number]) when is_binary(NodeNameExt),
+ is_integer(Creation),
+ is_integer(Number) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?REFERENCE_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint32_be(Number),
uint8(Creation)])) of
Ref when is_reference(Ref) ->
Ref;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]});
+ exit({badarg, mk_ref, [{NodeNameExt, Creation}, [Number]]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end;
-mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName),
- is_integer(Creation),
- is_list(Numbers) ->
+mk_ref({NodeNameExt, Creation}, Numbers) when is_binary(NodeNameExt),
+ is_integer(Creation),
+ is_list(Numbers) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?NEW_REFERENCE_EXT,
uint16_be(length(Numbers)),
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint8(Creation),
lists:map(fun (N) ->
uint32_be(N)
@@ -300,8 +302,67 @@ mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName),
Ref when is_reference(Ref) ->
Ref;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]});
+ exit({badarg, mk_ref, [{NodeNameExt, Creation}, Numbers]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end.
+
+
+unicode_atom_data() ->
+ [uc_atup(lists:seq(16#1f600, 16#1f600+254)),
+ uc_atup(lists:seq(16#1f600, 16#1f600+63)),
+ uc_atup(lists:seq(1, 255)),
+ uc_atup(lists:seq(100, 163)),
+ uc_atup(lists:seq(200, 354)),
+ uc_atup(lists:seq(200, 263)),
+ uc_atup(lists:seq(2000, 2254)),
+ uc_atup(lists:seq(2000, 2063)),
+ uc_atup(lists:seq(65500, 65754)),
+ uc_atup(lists:seq(65500, 65563))
+ | lists:map(fun (N) ->
+ Pow2 = (1 bsl N),
+ uc_atup(lists:seq(Pow2 - 127, Pow2 + 127))
+ end,
+ lists:seq(7, 20))
+ ].
+
+uc_atup(ATxt) ->
+ string_to_atom(ATxt).
+
+string_to_atom(String) ->
+ Utf8List = string_to_utf8_list(String),
+ Len = length(Utf8List),
+ TagLen = case Len < 256 of
+ true -> [119, Len];
+ false -> [118, Len bsr 8, Len band 16#ff]
+ end,
+ binary_to_term(list_to_binary([131, TagLen, Utf8List])).
+
+string_to_utf8_list([]) ->
+ [];
+string_to_utf8_list([CP|CPs]) when is_integer(CP),
+ 0 =< CP,
+ CP =< 16#7F ->
+ [CP | string_to_utf8_list(CPs)];
+string_to_utf8_list([CP|CPs]) when is_integer(CP),
+ 16#80 =< CP,
+ CP =< 16#7FF ->
+ [16#C0 bor (CP bsr 6),
+ 16#80 bor (16#3F band CP)
+ | string_to_utf8_list(CPs)];
+string_to_utf8_list([CP|CPs]) when is_integer(CP),
+ 16#800 =< CP,
+ CP =< 16#FFFF ->
+ [16#E0 bor (CP bsr 12),
+ 16#80 bor (16#3F band (CP bsr 6)),
+ 16#80 bor (16#3F band CP)
+ | string_to_utf8_list(CPs)];
+string_to_utf8_list([CP|CPs]) when is_integer(CP),
+ 16#10000 =< CP,
+ CP =< 16#10FFFF ->
+ [16#F0 bor (CP bsr 18),
+ 16#80 bor (16#3F band (CP bsr 12)),
+ 16#80 bor (16#3F band (CP bsr 6)),
+ 16#80 bor (16#3F band CP)
+ | string_to_utf8_list(CPs)].
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
index 406f02ecfb..e57663f984 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
@@ -29,171 +29,229 @@
*/
-#define EI_DECODE_ENCODE(FUNC,TYPE) \
- { \
- char *buf; \
- char buf2[1024]; \
- TYPE p; \
- int size1 = 0; \
- int size2 = 0; \
- int size3 = 0; \
- int err; \
- ei_x_buff arg; \
-\
- message("ei_decode_" #FUNC ", arg is type " #TYPE); \
- buf = read_packet(NULL); \
- err = ei_decode_ ## FUNC(buf+1, &size1, &p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("decode returned non zero but not -1"); \
- } else { \
- fail("decode returned non zero"); \
- } \
- return; \
- } \
- if (size1 < 1) { \
- fail("size is < 1"); \
- return; \
- } \
-\
- message("ei_encode_" #FUNC " buf is NULL, arg is type " #TYPE); \
- err = ei_encode_ ## FUNC(NULL, &size2, &p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("size calculation returned non zero but not -1"); \
- return; \
- } else { \
- fail("size calculation returned non zero"); \
- return; \
- } \
- } \
- if (size1 != size2) { \
- message("size1 = %d, size2 = %d\n",size1,size2); \
- fail("decode and encode size differs when buf is NULL"); \
- return; \
- } \
- message("ei_encode_" #FUNC ", arg is type " #TYPE); \
- err = ei_encode_ ## FUNC(buf2, &size3, &p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("returned non zero but not -1"); \
- } else { \
- fail("returned non zero"); \
- } \
- return; \
- } \
- if (size1 != size3) { \
- message("size1 = %d, size2 = %d\n",size1,size3); \
- fail("decode and encode size differs"); \
- return; \
- } \
- send_buffer(buf2, size1); \
-\
- message("ei_x_encode_" #FUNC ", arg is type " #TYPE); \
- ei_x_new(&arg); \
- err = ei_x_encode_ ## FUNC(&arg, &p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("returned non zero but not -1"); \
- } else { \
- fail("returned non zero"); \
- } \
- ei_x_free(&arg); \
- return; \
- } \
- if (arg.index < 1) { \
- fail("size is < 1"); \
- ei_x_free(&arg); \
- return; \
- } \
- send_buffer(arg.buff, arg.index); \
- ei_x_free(&arg); \
- }
-
-#define EI_DECODE_ENCODE_BIG(FUNC,TYPE) \
- { \
- char *buf; \
- char buf2[2048]; \
- TYPE *p; \
- int size1 = 0; \
- int size2 = 0; \
- int size3 = 0; \
- int err, index = 0, len, type; \
- ei_x_buff arg; \
-\
- message("ei_decode_" #FUNC ", arg is type " #TYPE); \
- buf = read_packet(NULL); \
- ei_get_type(buf+1, &index, &type, &len); \
- p = ei_alloc_big(len); \
- err = ei_decode_ ## FUNC(buf+1, &size1, p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("decode returned non zero but not -1"); \
- } else { \
- fail("decode returned non zero"); \
- } \
- return; \
- } \
- if (size1 < 1) { \
- fail("size is < 1"); \
- return; \
- } \
-\
- message("ei_encode_" #FUNC " buf is NULL, arg is type " #TYPE); \
- err = ei_encode_ ## FUNC(NULL, &size2, p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("size calculation returned non zero but not -1"); \
- return; \
- } else { \
- fail("size calculation returned non zero"); \
- return; \
- } \
- } \
- if (size1 != size2) { \
- message("size1 = %d, size2 = %d\n",size1,size2); \
- fail("decode and encode size differs when buf is NULL"); \
- return; \
- } \
- message("ei_encode_" #FUNC ", arg is type " #TYPE); \
- err = ei_encode_ ## FUNC(buf2, &size3, p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("returned non zero but not -1"); \
- } else { \
- fail("returned non zero"); \
- } \
- return; \
- } \
- if (size1 != size3) { \
- message("size1 = %d, size2 = %d\n",size1,size3); \
- fail("decode and encode size differs"); \
- return; \
- } \
- send_buffer(buf2, size1); \
-\
- message("ei_x_encode_" #FUNC ", arg is type " #TYPE); \
- ei_x_new(&arg); \
- err = ei_x_encode_ ## FUNC(&arg, p); \
- if (err != 0) { \
- if (err != -1) { \
- fail("returned non zero but not -1"); \
- } else { \
- fail("returned non zero"); \
- } \
- ei_x_free(&arg); \
- return; \
- } \
- if (arg.index < 1) { \
- fail("size is < 1"); \
- ei_x_free(&arg); \
- return; \
- } \
- send_buffer(arg.buff, arg.index); \
- ei_x_free(&arg); \
- ei_free_big(p); \
- }
+/*#define MESSAGE(FMT,A1,A2) message(FMT,A1,A2)*/
+#define MESSAGE(FMT,A1,A2)
+typedef int decodeFT(const char *buf, int *index, void*);
+typedef int encodeFT(char *buf, int *index, void*);
+typedef int x_encodeFT(ei_x_buff*, void*);
+
+struct Type {
+ char* name;
+ char* type;
+ decodeFT* ei_decode_fp;
+ encodeFT* ei_encode_fp;
+ x_encodeFT* ei_x_encode_fp;
+};
+
+typedef struct
+{
+ char name[MAXATOMLEN_UTF8];
+ enum erlang_char_encoding enc;
+}my_atom;
+
+int ei_decode_my_atom(const char *buf, int *index, my_atom* a)
+{
+ return ei_decode_atom_as(buf, index, a->name, sizeof(a->name), ERLANG_UTF8, &a->enc, NULL);
+}
+int ei_encode_my_atom(char *buf, int *index, my_atom* a)
+{
+ return ei_encode_atom_as(buf, index, a->name, ERLANG_UTF8, a->enc);
+}
+int ei_x_encode_my_atom(ei_x_buff* x, my_atom* a)
+{
+ return ei_x_encode_atom_as(x, a->name, ERLANG_UTF8, a->enc);
+}
+
+#define BUFSZ 2000
+
+void decode_encode(struct Type* t, void* obj)
+{
+ char *buf;
+ char buf2[BUFSZ];
+ int size1 = 0;
+ int size2 = 0;
+ int size3 = 0;
+ int err;
+ ei_x_buff arg;
+
+ MESSAGE("ei_decode_%s, arg is type %s", t->name, t->type);
+ buf = read_packet(NULL);
+ err = t->ei_decode_fp(buf+1, &size1, obj);
+ if (err != 0) {
+ if (err != -1) {
+ fail("decode returned non zero but not -1");
+ } else {
+ fail("decode returned non zero");
+ }
+ return;
+ }
+ if (size1 < 1) {
+ fail("size is < 1");
+ return;
+ }
+
+ if (size1 > BUFSZ) {
+ fail("size is > BUFSZ");
+ return;
+ }
+
+ MESSAGE("ei_encode_%s buf is NULL, arg is type %s", t->name, t->type);
+ err = t->ei_encode_fp(NULL, &size2, obj);
+ if (err != 0) {
+ if (err != -1) {
+ fail("size calculation returned non zero but not -1");
+ return;
+ } else {
+ fail("size calculation returned non zero");
+ return;
+ }
+ }
+ if (size1 != size2) {
+ MESSAGE("size1 = %d, size2 = %d\n",size1,size2);
+ fail("decode and encode size differs when buf is NULL");
+ return;
+ }
+ MESSAGE("ei_encode_%s, arg is type %s", t->name, t->type);
+ err = t->ei_encode_fp(buf2, &size3, obj);
+ if (err != 0) {
+ if (err != -1) {
+ fail("returned non zero but not -1");
+ } else {
+ fail("returned non zero");
+ }
+ return;
+ }
+ if (size1 != size3) {
+ MESSAGE("size1 = %d, size2 = %d\n",size1,size3);
+ fail("decode and encode size differs");
+ return;
+ }
+ send_buffer(buf2, size1);
+
+ MESSAGE("ei_x_encode_%s, arg is type %s", t->name, t->type);
+ ei_x_new(&arg);
+ err = t->ei_x_encode_fp(&arg, obj);
+ if (err != 0) {
+ if (err != -1) {
+ fail("returned non zero but not -1");
+ } else {
+ fail("returned non zero");
+ }
+ ei_x_free(&arg);
+ return;
+ }
+ if (arg.index < 1) {
+ fail("size is < 1");
+ ei_x_free(&arg);
+ return;
+ }
+ send_buffer(arg.buff, arg.index);
+ ei_x_free(&arg);
+}
+
+
+#define EI_DECODE_ENCODE(TYPE, ERLANG_TYPE) { \
+ struct Type type_struct = {#TYPE, #ERLANG_TYPE, \
+ (decodeFT*)ei_decode_##TYPE, \
+ (encodeFT*)ei_encode_##TYPE, \
+ (x_encodeFT*)ei_x_encode_##TYPE }; \
+ ERLANG_TYPE type_obj; \
+ decode_encode(&type_struct, &type_obj); \
+ }
+
+
+void decode_encode_big(struct Type* t)
+{
+ char *buf;
+ char buf2[2048];
+ void *p; /* (TYPE*) */
+ int size1 = 0;
+ int size2 = 0;
+ int size3 = 0;
+ int err, index = 0, len, type;
+ ei_x_buff arg;
+
+ MESSAGE("ei_decode_%s, arg is type %s", t->name, t->type);
+ buf = read_packet(NULL);
+ ei_get_type(buf+1, &index, &type, &len);
+ p = ei_alloc_big(len);
+ err = t->ei_decode_fp(buf+1, &size1, p);
+ if (err != 0) {
+ if (err != -1) {
+ fail("decode returned non zero but not -1");
+ } else {
+ fail("decode returned non zero");
+ }
+ return;
+ }
+ if (size1 < 1) {
+ fail("size is < 1");
+ return;
+ }
+
+ MESSAGE("ei_encode_%s buf is NULL, arg is type %s", t->name, t->type);
+ err = t->ei_encode_fp(NULL, &size2, p);
+ if (err != 0) {
+ if (err != -1) {
+ fail("size calculation returned non zero but not -1");
+ return;
+ } else {
+ fail("size calculation returned non zero");
+ return;
+ }
+ }
+ if (size1 != size2) {
+ MESSAGE("size1 = %d, size2 = %d\n",size1,size2);
+ fail("decode and encode size differs when buf is NULL");
+ return;
+ }
+ MESSAGE("ei_encode_%s, arg is type %s", t->name, t->type);
+ err = t->ei_encode_fp(buf2, &size3, p);
+ if (err != 0) {
+ if (err != -1) {
+ fail("returned non zero but not -1");
+ } else {
+ fail("returned non zero");
+ }
+ return;
+ }
+ if (size1 != size3) {
+ MESSAGE("size1 = %d, size2 = %d\n",size1,size3);
+ fail("decode and encode size differs");
+ return;
+ }
+ send_buffer(buf2, size1);
+
+ MESSAGE("ei_x_encode_%s, arg is type %s", t->name, t->type);
+ ei_x_new(&arg);
+ err = t->ei_x_encode_fp(&arg, p);
+ if (err != 0) {
+ if (err != -1) {
+ fail("returned non zero but not -1");
+ } else {
+ fail("returned non zero");
+ }
+ ei_x_free(&arg);
+ return;
+ }
+ if (arg.index < 1) {
+ fail("size is < 1");
+ ei_x_free(&arg);
+ return;
+ }
+ send_buffer(arg.buff, arg.index);
+ ei_x_free(&arg);
+ ei_free_big(p);
+}
+
+#define EI_DECODE_ENCODE_BIG(TYPE, ERLANG_TYPE) { \
+ struct Type type_struct = {#TYPE, #ERLANG_TYPE, \
+ (decodeFT*)ei_decode_##TYPE, \
+ (encodeFT*)ei_encode_##TYPE, \
+ (x_encodeFT*)ei_x_encode_##TYPE }; \
+ decode_encode_big(&type_struct); \
+ }
@@ -201,6 +259,8 @@
TESTCASE(test_ei_decode_encode)
{
+ int i;
+
EI_DECODE_ENCODE(fun , erlang_fun);
EI_DECODE_ENCODE(pid , erlang_pid);
EI_DECODE_ENCODE(port , erlang_port);
@@ -223,6 +283,14 @@ TESTCASE(test_ei_decode_encode)
EI_DECODE_ENCODE(port , erlang_port);
EI_DECODE_ENCODE(ref , erlang_ref);
+ /* Unicode atoms */
+ for (i=0; i<24; i++) {
+ EI_DECODE_ENCODE(my_atom, my_atom);
+ EI_DECODE_ENCODE(pid, erlang_pid);
+ EI_DECODE_ENCODE(port, erlang_port);
+ EI_DECODE_ENCODE(ref, erlang_ref);
+ }
+
report(1);
}
diff --git a/lib/et/src/Makefile b/lib/et/src/Makefile
index c68a3f4efd..386169fe95 100644
--- a/lib/et/src/Makefile
+++ b/lib/et/src/Makefile
@@ -92,10 +92,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/eunit/src/Makefile b/lib/eunit/src/Makefile
index 0a2e71cf7b..e88e28df83 100644
--- a/lib/eunit/src/Makefile
+++ b/lib/eunit/src/Makefile
@@ -104,10 +104,10 @@ $(OBJECTS): $(PARSE_TRANSFORM_BIN)
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/gs/contribs/bonk/Makefile b/lib/gs/contribs/bonk/Makefile
index a630deaf24..d160ca8b73 100644
--- a/lib/gs/contribs/bonk/Makefile
+++ b/lib/gs/contribs/bonk/Makefile
@@ -81,12 +81,12 @@ clean:
# ----------------------------------------------------
$(EBIN)/$(TOOLNAME).gif: $(TOOLNAME).gif
- rm -f $@
- cp $(TOOLNAME).gif $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).gif $@
$(EBIN)/$(TOOLNAME).tool: $(TOOLNAME).tool
- rm -f $@
- cp $(TOOLNAME).tool $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).tool $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/gs/contribs/cols/Makefile b/lib/gs/contribs/cols/Makefile
index 3af91e1dae..3036e9565e 100644
--- a/lib/gs/contribs/cols/Makefile
+++ b/lib/gs/contribs/cols/Makefile
@@ -74,16 +74,16 @@ clean:
# ----------------------------------------------------
$(EBIN)/$(TOOLNAME).gif: $(TOOLNAME).gif
- rm -f $@
- cp $(TOOLNAME).gif $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).gif $@
$(EBIN)/$(TOOLNAME).tool: $(TOOLNAME).tool
- rm -f $@
- cp $(TOOLNAME).tool $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).tool $@
$(EBIN)/help.gif: help.gif
- rm -f $@
- cp help.gif $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp help.gif $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/gs/contribs/mandel/Makefile b/lib/gs/contribs/mandel/Makefile
index 5f0b047955..308ba0cbb0 100644
--- a/lib/gs/contribs/mandel/Makefile
+++ b/lib/gs/contribs/mandel/Makefile
@@ -73,16 +73,16 @@ clean:
# ----------------------------------------------------
$(EBIN)/$(TOOLNAME).gif: $(TOOLNAME).gif
- rm -f $@
- cp $(TOOLNAME).gif $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).gif $@
$(EBIN)/$(TOOLNAME).tool: $(TOOLNAME).tool
- rm -f $@
- cp $(TOOLNAME).tool $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).tool $@
$(EBIN)/help.gif: help.gif
- rm -f $@
- cp help.gif $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp help.gif $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/gs/contribs/othello/Makefile b/lib/gs/contribs/othello/Makefile
index 5f37d164f5..f9d131c315 100644
--- a/lib/gs/contribs/othello/Makefile
+++ b/lib/gs/contribs/othello/Makefile
@@ -76,12 +76,12 @@ clean:
# ----------------------------------------------------
$(EBIN)/$(TOOLNAME).gif: $(TOOLNAME).gif
- rm -f $@
- cp $(TOOLNAME).gif $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).gif $@
$(EBIN)/$(TOOLNAME).tool: $(TOOLNAME).tool
- rm -f $@
- cp $(TOOLNAME).tool $@
+ $(gen_verbose)rm -f $@
+ $(V_at)cp $(TOOLNAME).tool $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/gs/src/Makefile b/lib/gs/src/Makefile
index 4b7a4523b9..0a63d5466e 100644
--- a/lib/gs/src/Makefile
+++ b/lib/gs/src/Makefile
@@ -91,13 +91,13 @@ clean:
# ----------------------------------------------------
gstk_generic.hrl: gs_make.erl ../ebin/gs_make.$(EMULATOR) ../ebin/gs.$(EMULATOR)
- $(ERL) -pa $(EBIN) -s gs_make -s erlang halt -noshell
+ $(gen_verbose)$(ERL) -pa $(EBIN) -s gs_make -s erlang halt -noshell
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(GSTK_GENERIC_TARGET): gstk_generic.hrl
diff --git a/lib/hipe/Makefile b/lib/hipe/Makefile
index 2294f98158..a9e24f4d17 100644
--- a/lib/hipe/Makefile
+++ b/lib/hipe/Makefile
@@ -57,20 +57,20 @@ edocs:
fi
all-subdirs:
- for dir in $(SUB_DIRECTORIES); do \
+ $(V_at)for dir in $(SUB_DIRECTORIES); do \
(cd $$dir; $(MAKE) $(MAKETARGET) EBIN=$(EBIN); cd ..); \
done
# distclean and realclean should clean the bootstrap files
all-subdirs-x:
- for dir in $(SUB_DIRECTORIES); do \
+ $(V_at)for dir in $(SUB_DIRECTORIES); do \
(cd $$dir; $(MAKE) $(MAKETARGET) EBIN=../boot_ebin; cd ..); \
done
clean:
- $(MAKE) MAKETARGET="clean" all-subdirs all-subdirs-x
+ $(V_at)$(MAKE) MAKETARGET="clean" all-subdirs all-subdirs-x
distclean:
- $(MAKE) MAKETARGET="distclean" all-subdirs all-subdirs-x
+ $(V_at)$(MAKE) MAKETARGET="distclean" all-subdirs all-subdirs-x
realclean:
- $(MAKE) MAKETARGET="realclean" all-subdirs all-subdirs-x
+ $(V_at)$(MAKE) MAKETARGET="realclean" all-subdirs all-subdirs-x
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 98d65abba1..d93ad10bd4 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-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-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
@@ -765,7 +765,6 @@ type(erlang, node, 0, _) -> t_node();
%% Guard bif, needs to be here.
type(erlang, node, 1, Xs) ->
strict(arg_types(erlang, node, 1), Xs, fun (_) -> t_node() end);
-type(erlang, nodes, 0, _) -> t_list(t_node());
%% Guard bif, needs to be here.
type(erlang, round, 1, Xs) ->
strict(arg_types(erlang, round, 1), Xs, fun (_) -> t_integer() end);
@@ -2250,8 +2249,6 @@ arg_types(erlang, node, 0) ->
%% Guard bif, needs to be here.
arg_types(erlang, node, 1) ->
[t_identifier()];
-arg_types(erlang, nodes, 0) ->
- [];
%% Guard bif, needs to be here.
arg_types(erlang, round, 1) ->
[t_number()];
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index f5be8fb08f..0f88b32db1 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-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
@@ -63,7 +63,6 @@
t_boolean/0,
t_byte/0,
t_char/0,
- t_charlist/0,
t_collect_vars/1,
t_cons/0,
t_cons/2,
@@ -197,7 +196,6 @@
t_tuple_size/1,
t_tuple_sizes/1,
t_tuple_subtypes/1,
- t_unicode_string/0,
t_unify/2,
t_unify/3,
t_unit/0,
@@ -1458,21 +1456,6 @@ t_is_tuple(_) -> false.
t_bitstrlist() ->
t_iolist(1, t_bitstr()).
--spec t_charlist() -> erl_type().
-
-t_charlist() ->
- t_charlist(1).
-
--spec t_charlist(non_neg_integer()) -> erl_type().
-
-t_charlist(N) when N > 0 ->
- t_maybe_improper_list(t_sup([t_unicode_char(),
- t_unicode_binary(),
- t_charlist(N-1)]),
- t_sup(t_unicode_binary(), t_nil()));
-t_charlist(0) ->
- t_maybe_improper_list(t_any(), t_sup(t_unicode_binary(), t_nil())).
-
-spec t_constant() -> erl_type().
t_constant() ->
@@ -1568,21 +1551,6 @@ t_parameterized_module() ->
t_timeout() ->
t_sup(t_non_neg_integer(), t_atom('infinity')).
--spec t_unicode_binary() -> erl_type().
-
-t_unicode_binary() ->
- t_binary(). % with characters encoded in UTF-8 coding standard
-
--spec t_unicode_char() -> erl_type().
-
-t_unicode_char() ->
- t_integer(). % representing a valid unicode codepoint
-
--spec t_unicode_string() -> erl_type().
-
-t_unicode_string() ->
- t_list(t_unicode_char()).
-
%%-----------------------------------------------------------------------------
%% Some built-in opaque types
%%
@@ -3566,7 +3534,7 @@ t_from_form({type, _L, function, []}, _TypeNames, _InOpaque, _RecDict,
t_from_form({type, _L, 'fun', []}, _TypeNames, _InOpaque, _RecDict,
_VarDict) ->
{t_fun(), []};
-t_from_form({type, _L, 'fun', [{type, _, any, []}, Range]}, TypeNames,
+t_from_form({type, _L, 'fun', [{type, _, any}, Range]}, TypeNames,
InOpaque, RecDict, VarDict) ->
{T, R} = t_from_form(Range, TypeNames, InOpaque, RecDict, VarDict),
{t_fun(T), R};
@@ -3909,7 +3877,7 @@ t_form_to_string({type, _L, binary, [Base, Unit]} = Type) ->
_ -> io_lib:format("Badly formed bitstr type ~w", [Type])
end;
t_form_to_string({type, _L, 'fun', []}) -> "fun()";
-t_form_to_string({type, _L, 'fun', [{type, _, any, []}, Range]}) ->
+t_form_to_string({type, _L, 'fun', [{type, _, any}, Range]}) ->
"fun(...) -> " ++ t_form_to_string(Range);
t_form_to_string({type, _L, 'fun', [{type, _, product, Domain}, Range]}) ->
"fun((" ++ string:join(t_form_to_string_list(Domain), ",") ++ ") -> "
diff --git a/lib/hipe/main/Makefile b/lib/hipe/main/Makefile
index 673431a175..66e4c3e39a 100644
--- a/lib/hipe/main/Makefile
+++ b/lib/hipe/main/Makefile
@@ -76,7 +76,7 @@ ERL_COMPILE_FLAGS += +nowarn_shadow_vars +warn_missing_spec +warn_untyped_record
# ----------------------------------------------------
hipe.hrl: ../vsn.mk hipe.hrl.src
- sed -e "s;%VSN%;$(HIPE_VSN);" ../../hipe/main/hipe.hrl.src > ../../hipe/main/hipe.hrl
+ $(vsn_verbose)sed -e "s;%VSN%;$(HIPE_VSN);" ../../hipe/main/hipe.hrl.src > ../../hipe/main/hipe.hrl
$(EBIN)/hipe.beam: hipe.hrl ../../compiler/src/beam_disasm.hrl
$(EBIN)/hipe_main.beam: hipe.hrl ../icode/hipe_icode.hrl #../rtl/hipe_rtl.hrl
@@ -97,17 +97,17 @@ distclean: clean
realclean: clean
$(DOCS)/%.html:%.erl
- erl -noshell -run edoc_run file '"$<"' '[{dir, "$(DOCS)"}]' -s init stop
+ $(gen_verbose)erl -noshell -run edoc_run file '"$<"' '[{dir, "$(DOCS)"}]' -s init stop
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile
index 426d1bd3ee..7852a2172b 100644
--- a/lib/hipe/rtl/Makefile
+++ b/lib/hipe/rtl/Makefile
@@ -134,13 +134,13 @@ HIPE_MKLITERALS=$(ERL_TOP)/bin/$(TARGET)/hipe_mkliterals$(TYPE_STR)$(FLAVOR_STR)
hipe_literals.hrl: $(HIPE_MKLITERALS)
- $(HIPE_MKLITERALS) $(MKLIT_FLAGS) -e > hipe_literals.hrl
+ $(gen_verbose)$(HIPE_MKLITERALS) $(MKLIT_FLAGS) -e > hipe_literals.hrl
# Need to generate hipe.hrl from one and only one target in one and only
# one makefile; otherwise, clearmake will force rebuilds of hipe over and
# over again.
../main/hipe.hrl: ../vsn.mk ../main/hipe.hrl.src
- (cd ../main && $(MAKE) hipe.hrl)
+ $(V_at)(cd ../main && $(MAKE) hipe.hrl)
# 2012-02-24. Please keep these dependencies up to date. They tend to rot.
# grep ^-include *.erl says a lot, but you need to dig further, e.g:
diff --git a/lib/ic/c_src/Makefile.in b/lib/ic/c_src/Makefile.in
index de46eadb3b..856823b1b3 100644
--- a/lib/ic/c_src/Makefile.in
+++ b/lib/ic/c_src/Makefile.in
@@ -67,7 +67,11 @@ ifeq ($(findstring solaris,$(HOST_OS)),solaris)
SKIP_BUILDING_BINARIES := true
endif
else
+ifeq ($(V),0)
+AR_OUT = rc
+else
AR_OUT = rcv
+endif
CC_FLAGS = @DED_CFLAGS@
LIBRARY = $(LIBDIR)/libic.a
SKIP_BUILDING_BINARIES := false
@@ -128,11 +132,13 @@ docs:
_create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR))
$(LIBRARY): $(OBJ_FILES)
- -$(AR) $(AR_OUT) $@ $(OBJ_FILES)
+ $(ar_verbose)
+ -$(AR) $(AR_OUT) $@ $(OBJ_FILES)
+ $(ranlib_verbose)
-$(RANLIB) $@
$(OBJDIR)/%.o: %.c
- $(CC) $(CC_FLAGS) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_CC) $(CC_FLAGS) -c -o $@ $(ALL_CFLAGS) $<
# ----------------------------------------------------
# Release Target
diff --git a/lib/ic/examples/all-against-all/client.c b/lib/ic/examples/all-against-all/client.c
index e0a52b142d..5dece9cfa6 100644
--- a/lib/ic/examples/all-against-all/client.c
+++ b/lib/ic/examples/all-against-all/client.c
@@ -88,6 +88,7 @@ int main(){
/* Initiating pid*/
strcpy(pid.node,client_node);
+ pid.node_org_enc = ERLANG_LATIN1;
pid.num = 99;
pid.serial = 0;
pid.creation = 0;
diff --git a/lib/ic/examples/c-client/client.c b/lib/ic/examples/c-client/client.c
index 816477cf15..5b11510ce3 100644
--- a/lib/ic/examples/c-client/client.c
+++ b/lib/ic/examples/c-client/client.c
@@ -64,6 +64,7 @@ int main()
/* Initiating pid*/
strcpy(pid.node,CLNODE);
+ pid.node_org_enc = ERLANG_LATIN1;
pid.num = 99;
pid.serial = 0;
pid.creation = 0;
diff --git a/lib/ic/examples/c-server/client.c b/lib/ic/examples/c-server/client.c
index fa570089b5..605e41ddb1 100644
--- a/lib/ic/examples/c-server/client.c
+++ b/lib/ic/examples/c-server/client.c
@@ -58,6 +58,7 @@ int main()
/* Initiating pid*/
strcpy(pid.node, CLNODE);
+ pid.node_org_enc = ERLANG_LATIN1;
pid.num = 99;
pid.serial = 0;
pid.creation = 0;
diff --git a/lib/ic/examples/pre_post_condition/Makefile b/lib/ic/examples/pre_post_condition/Makefile
index d18f81fec9..53e647e793 100644
--- a/lib/ic/examples/pre_post_condition/Makefile
+++ b/lib/ic/examples/pre_post_condition/Makefile
@@ -109,9 +109,9 @@ test: $(TEST_TARGET_FILES)
IDL-GENERATED: ex.idl
- erlc $(ERL_LOCAL_FLAGS) +'{precond,{tracer,pre}}' \
+ $(gen_verbose)erlc $(ERL_LOCAL_FLAGS) +'{precond,{tracer,pre}}' \
+'{{postcond,"m::i::f"},{tracer,post}}' ex.idl
- >IDL-GENERATED
+ $(V_at)>IDL-GENERATED
$(GEN_ERL_MODULES:%=%.erl) $(GEN_HRL_FILES): IDL-GENERATED
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Makefile b/lib/ic/java_src/com/ericsson/otp/ic/Makefile
index cf4c353f3f..273614e8d9 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Makefile
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Makefile
@@ -85,7 +85,10 @@ JAR= jar
JAVADOCFLAGS=-d $(DOCDIR)
JAVAFLAGS=-d $(JAVA_DEST_ROOT)
-JARFLAGS= -cvf
+JARFLAGS= -cf
+ifneq ($(V),0)
+JARFLAGS= -cfv
+endif
JAVA_OPTIONS =
diff --git a/lib/ic/src/Makefile b/lib/ic/src/Makefile
index 280d86a8a4..e8769d2335 100644
--- a/lib/ic/src/Makefile
+++ b/lib/ic/src/Makefile
@@ -175,7 +175,7 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
@@ -183,7 +183,7 @@ docs:
# Special Build Targets
# ----------------------------------------------------
../ebin/icparse.beam: icparse.erl
- $(ERLC) $(ERL_COMPILE_FLAGS) +nowarn_unused_vars +nowarn_unused_function -o$(EBIN) +pj $<
+ $(V_ERLC) $(ERL_COMPILE_FLAGS) +nowarn_unused_vars +nowarn_unused_function -o$(EBIN) +pj $<
icparse.erl: icparse.yrl icyeccpre.hrl
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
index 3143ab427b..a2440adc92 100644
--- a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
@@ -86,15 +86,15 @@ clean:
java_erl_test.built_erl java_erl_test.built_java
java_erl_test.built_java: java_erl_test.idl
- $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl
- echo done > java_erl_test.built_java
+ $(gen_verbose)$(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl
+ $(V_at)echo done > java_erl_test.built_java
$(CLASS_FILES) : $(JAVA_FILES)
- $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
+ $(V_JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
java_erl_test.built_erl: java_erl_test.idl
- $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl
- echo done > java_erl_test.built_erl
+ $(gen_verbose)$(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl
+ $(V_at)echo done > java_erl_test.built_erl
.erl.@EMULATOR@:
- $(ERLC) -I $(IC_INCLUDE_PATH) $<
+ $(V_ERLC) -I $(IC_INCLUDE_PATH) $<
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index 04976447cc..37f5f2ce6d 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -124,6 +124,11 @@ result(Response = {{_, Code, _}, _, _},
(Code =:= 303) orelse
(Code =:= 307) ->
redirect(Response, Request);
+result(Response = {{_, 303, _}, _, _},
+ Request = #request{settings =
+ #http_options{autoredirect = true},
+ method = post}) ->
+ redirect(Response, Request#request{method = get});
result(Response = {{_,503,_}, _, _}, Request) ->
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 7d68145287..22426eee79 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -99,10 +99,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 644b01120c..fbd1b3d38a 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -1326,24 +1326,42 @@ http_redirect(Config) when is_list(Config) ->
= httpc:request(post, {URL302, [],"text/plain", "foobar"},
[], []),
- URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html",
+ URL303 = ?URL_START ++ integer_to_list(Port) ++ "/303.html",
tsp("http_redirect -> issue request 9: "
+ "~n ~p", [URL303]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = httpc:request(get, {URL303, []}, [], []),
+
+ tsp("http_redirect -> issue request 10: "
+ "~n ~p", [URL303]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = httpc:request(head, {URL303, []}, [], []),
+
+ tsp("http_redirect -> issue request 11: "
+ "~n ~p", [URL303]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = httpc:request(post, {URL303, [],"text/plain", "foobar"},
+ [], []),
+
+ URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html",
+
+ tsp("http_redirect -> issue request 12: "
"~n ~p", [URL307]),
{ok, {{_,200,_}, [_ | _], [_|_]}}
= httpc:request(get, {URL307, []}, [], []),
- tsp("http_redirect -> issue request 10: "
+ tsp("http_redirect -> issue request 13: "
"~n ~p", [URL307]),
{ok, {{_,200,_}, [_ | _], []}}
= httpc:request(head, {URL307, []}, [], []),
- tsp("http_redirect -> issue request 11: "
+ tsp("http_redirect -> issue request 14: "
"~n ~p", [URL307]),
{ok, {{_,307,_}, [_ | _], [_|_]}}
= httpc:request(post, {URL307, [],"text/plain", "foobar"},
[], []),
-
+
tsp("http_redirect -> stop dummy server"),
DummyServerPid ! stop,
tsp("http_redirect -> reset ipfamily option (to inet6fb4)"),
@@ -3298,6 +3316,14 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket, Close, Send) ->
"Content-Length:80\r\n\r\n" ++
"<HTML><BODY><a href=" ++ NewUri ++
">New place</a></BODY></HTML>";
+ "/303.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 303 See Other \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
"/307.html" ->
NewUri = ?URL_START ++
integer_to_list(?IP_PORT) ++ "/dummy.html",
diff --git a/lib/jinterface/java_src/Makefile b/lib/jinterface/java_src/Makefile
index 19f99831eb..0aa9c09548 100644
--- a/lib/jinterface/java_src/Makefile
+++ b/lib/jinterface/java_src/Makefile
@@ -47,7 +47,7 @@ POM_SRC= $(POM_FILE).src
# ----------------------------------------------------
$(POM_TARGET): $(POM_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
include $(ERL_TOP)/make/otp_subdir.mk
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 16cb544a16..c76fad5e45 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
@@ -90,6 +90,8 @@ public class AbstractNode {
static final int dFlagExportPtrTag = 0x200; // NOT SUPPORTED
static final int dFlagBitBinaries = 0x400;
static final int dFlagNewFloats = 0x800;
+ static final int dFlagUnicodeIo = 0x1000;
+ static final int dFlagUtf8Atoms = 0x10000;
int ntype = NTYPE_R6;
int proto = 0; // tcp/ip
@@ -98,7 +100,7 @@ public class AbstractNode {
int creation = 0;
int flags = dFlagExtendedReferences | dFlagExtendedPidsPorts
| dFlagBitBinaries | dFlagNewFloats | dFlagFunTags
- | dflagNewFunTags;
+ | dflagNewFunTags | dFlagUtf8Atoms;
/* initialize hostname and default cookie */
static {
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
index 8ae63a1561..f476d4594d 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile
@@ -61,7 +61,10 @@ CLASSPATH = $(JAVA_SRC_ROOT)
JAVADOCFLAGS=-d $(DOCDIR)
JAVAFLAGS=-d $(JAVA_DEST_ROOT)
-JARFLAGS=-cvf
+JARFLAGS=-cf
+ifneq ($(V),0)
+JARFLAGS=-cfv
+endif
JAVA_OPTIONS =
@@ -79,13 +82,13 @@ endif
debug opt: make_dirs $(JAVA_DEST_ROOT)$(JARFILE)
make_dirs:
- if [ ! -d "$(JAVA_DEST_ROOT)" ];then mkdir "$(JAVA_DEST_ROOT)"; fi
+ $(V_at)if [ ! -d "$(JAVA_DEST_ROOT)" ];then mkdir "$(JAVA_DEST_ROOT)"; fi
$(JAVA_DEST_ROOT)$(JARFILE): $(TARGET_FILES)
@(cd $(JAVA_DEST_ROOT) ; $(JAR) $(JARFLAGS) $(JARFILE) $(JAVA_CLASS_SUBDIR))
clean:
- rm -f $(TARGET_FILES) *~
+ $(V_at)rm -f $(TARGET_FILES) *~
docs:
@@ -96,13 +99,13 @@ docs:
# include $(ERL_TOP)/make/otp_release_targets.mk
release release_docs release_tests release_html:
- $(MAKE) $(MFLAGS) RELEASE_PATH="$(RELEASE_PATH)" $(TARGET_MAKEFILE) $@_spec
+ $(V_at)$(MAKE) $(MFLAGS) RELEASE_PATH="$(RELEASE_PATH)" $(TARGET_MAKEFILE) $@_spec
release_spec: opt
- $(INSTALL_DIR) "$(RELSYSDIR)/java_src/com/ericsson/otp/erlang"
- $(INSTALL_DATA) $(JAVA_SRC) "$(RELSYSDIR)/java_src/com/ericsson/otp/erlang"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv"
- $(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) "$(RELSYSDIR)/priv"
+ $(V_at)$(INSTALL_DIR) "$(RELSYSDIR)/java_src/com/ericsson/otp/erlang"
+ $(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"
release_docs_spec:
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 ced4dbb8c2..2768edc6fa 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
@@ -51,7 +51,7 @@ public class OtpErlangAtom extends OtpErlangObject implements Serializable,
"null string value");
}
- if (atom.length() > maxAtomLength) {
+ if (atom.codePointCount(0, atom.length()) > maxAtomLength) {
throw new java.lang.IllegalArgumentException("Atom may not exceed "
+ maxAtomLength + " characters: " + atom);
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
index e70b9a786b..2a4cd4fa2d 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
@@ -88,6 +88,12 @@ public class OtpExternal {
/** The tag used for old Funs */
public static final int funTag = 117;
+ /** The tag used for unicode atoms */
+ public static final int atomUtf8Tag = 118;
+
+ /** The tag used for small unicode atoms */
+ public static final int smallAtomUtf8Tag = 119;
+
/** The tag used for compressed terms */
public static final int compressedTag = 80;
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 ae5f4ee072..c2a79af841 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
@@ -351,26 +351,64 @@ public class OtpInputStream extends ByteArrayInputStream {
*/
public String read_atom() throws OtpErlangDecodeException {
int tag;
- int len;
+ int len = -1;
byte[] strbuf;
String atom;
tag = read1skip_version();
- if (tag != OtpExternal.atomTag) {
- throw new OtpErlangDecodeException(
- "wrong tag encountered, expected " + OtpExternal.atomTag
- + ", got " + tag);
- }
+ switch (tag) {
- len = read2BE();
+ case OtpExternal.atomTag:
+ len = read2BE();
+ strbuf = new byte[len];
+ this.readN(strbuf);
+ try {
+ atom = new String(strbuf, "ISO-8859-1");
+ } catch (final java.io.UnsupportedEncodingException e) {
+ throw new OtpErlangDecodeException(
+ "Failed to decode ISO-8859-1 atom");
+ }
+ if (atom.length() > OtpExternal.maxAtomLength) {
+ /*
+ * Throwing an exception would be better I think,
+ * but truncation seems to be the way it has
+ * been done in other parts of OTP...
+ */
+ atom = atom.substring(0, OtpExternal.maxAtomLength);
+ }
+ break;
- strbuf = new byte[len];
- this.readN(strbuf);
- atom = OtpErlangString.newString(strbuf);
+ case OtpExternal.smallAtomUtf8Tag:
+ len = read1();
+ /* fall through */
+ case OtpExternal.atomUtf8Tag:
+ if (len < 0) {
+ len = read2BE();
+ }
+ strbuf = new byte[len];
+ this.readN(strbuf);
+ try {
+ atom = new String(strbuf, "UTF-8");
+ } catch (final java.io.UnsupportedEncodingException e) {
+ throw new OtpErlangDecodeException(
+ "Failed to decode UTF-8 atom");
+ }
+ if (atom.codePointCount(0, atom.length()) > OtpExternal.maxAtomLength) {
+ /*
+ * Throwing an exception would be better I think,
+ * but truncation seems to be the way it has
+ * been done in other parts of OTP...
+ */
+ final int[] cps = OtpErlangString.stringToCodePoints(atom);
+ atom = new String(cps, 0, OtpExternal.maxAtomLength);
+ }
+ break;
- if (atom.length() > OtpExternal.maxAtomLength) {
- atom = atom.substring(0, OtpExternal.maxAtomLength);
+ default:
+ throw new OtpErlangDecodeException(
+ "wrong tag encountered, expected " + OtpExternal.atomTag
+ + ", or " + OtpExternal.atomUtf8Tag + ", got " + tag);
}
return atom;
@@ -1152,6 +1190,8 @@ public class OtpInputStream extends ByteArrayInputStream {
return new OtpErlangLong(this);
case OtpExternal.atomTag:
+ case OtpExternal.smallAtomUtf8Tag:
+ case OtpExternal.atomUtf8Tag:
return new OtpErlangAtom(this);
case OtpExternal.floatTag:
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 22ebb4688a..10bdf389cd 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -343,9 +343,63 @@ public class OtpOutputStream extends ByteArrayOutputStream {
* the string to write.
*/
public void write_atom(final String atom) {
- write1(OtpExternal.atomTag);
- write2BE(atom.length());
- writeN(atom.getBytes());
+ String enc_atom;
+ byte[] bytes;
+ boolean isLatin1 = true;
+
+ if (atom.codePointCount(0, atom.length()) <= OtpExternal.maxAtomLength) {
+ enc_atom = atom;
+ }
+ else {
+ /*
+ * Throwing an exception would be better I think,
+ * but truncation seems to be the way it has
+ * been done in other parts of OTP...
+ */
+ enc_atom = new String(OtpErlangString.stringToCodePoints(atom),
+ 0, OtpExternal.maxAtomLength);
+ }
+
+ for (int offset = 0; offset < enc_atom.length();) {
+ final int cp = enc_atom.codePointAt(offset);
+ if ((cp & ~0xFF) != 0) {
+ isLatin1 = false;
+ break;
+ }
+ offset += Character.charCount(cp);
+ }
+ try {
+ if (isLatin1) {
+ bytes = enc_atom.getBytes("ISO-8859-1");
+ write1(OtpExternal.atomTag);
+ write2BE(bytes.length);
+ }
+ else {
+ bytes = enc_atom.getBytes("UTF-8");
+ final int length = bytes.length;
+ if (length < 256) {
+ write1(OtpExternal.smallAtomUtf8Tag);
+ write1(length);
+ }
+ else {
+ write1(OtpExternal.atomUtf8Tag);
+ write2BE(length);
+ }
+ }
+ writeN(bytes);
+ } catch (final java.io.UnsupportedEncodingException e) {
+ /*
+ * Sigh, why didn't the API designer add an
+ * OtpErlangEncodeException to these encoding
+ * functions?!? Instead of changing the API we
+ * write an invalid atom and let it fail for
+ * whoever trying to decode this... Sigh,
+ * again...
+ */
+ write1(OtpExternal.smallAtomUtf8Tag);
+ write1(2);
+ write2BE(0xffff); /* Invalid UTF-8 */
+ }
}
/**
diff --git a/lib/jinterface/test/nc_SUITE.erl b/lib/jinterface/test/nc_SUITE.erl
index c91c743498..546c600116 100644
--- a/lib/jinterface/test/nc_SUITE.erl
+++ b/lib/jinterface/test/nc_SUITE.erl
@@ -23,6 +23,15 @@
-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
+-define(VERSION_MAGIC, 131).
+
+-define(ATOM_EXT, 100).
+-define(REFERENCE_EXT, 101).
+-define(PORT_EXT, 102).
+-define(PID_EXT, 103).
+-define(NEW_REFERENCE_EXT, 114).
+-define(ATOM_UTF8_EXT, 118).
+-define(SMALL_ATOM_UTF8_EXT, 119).
-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
init_per_suite/1,
@@ -46,6 +55,10 @@
unicode/1,
unicode_list_to_string/1,
unicode_string_to_list/1,
+ utf8_atom/1,
+ utf8_pid/1,
+ utf8_port/1,
+ utf8_ref/1,
connect/1]).
@@ -59,7 +72,9 @@ all() ->
decompress_roundtrip, compress_roundtrip,
integer_roundtrip, fun_roundtrip, lists_roundtrip,
lists_roundtrip_2, lists_iterator, unicode,
- unicode_list_to_string, unicode_string_to_list, connect].
+ unicode_list_to_string, unicode_string_to_list,
+ utf8_atom, utf8_pid, utf8_port, utf8_ref,
+ connect].
groups() ->
[].
@@ -449,6 +464,71 @@ unicode_string_to_list(Config) when is_list(Config) ->
end, ["unicode"]).
+evil_smiley() ->
+ <<240,159,152,136>>.
+
+evil_smileys(0) ->
+ [];
+evil_smileys(N) ->
+ [evil_smiley() | evil_smileys(N-1)].
+
+utf8_atom(Config) when is_list(Config) ->
+ ES = evil_smiley(),
+ SmallUA = binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?SMALL_ATOM_UTF8_EXT,
+ size(ES),
+ ES])),
+ true = is_atom(SmallUA),
+ NoESs = 300 div size(ES),
+ ESs = evil_smileys(NoESs),
+ LargeUA = binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?ATOM_UTF8_EXT,
+ uint16_be(NoESs*size(ES)),
+ ESs])),
+ true = is_atom(LargeUA),
+ erlang:display({atom, SmallUA, LargeUA}),
+ do_echo([SmallUA, LargeUA], Config).
+
+utf8_nodenames_ext() ->
+ H = "@host",
+ ES = evil_smiley(),
+ SmallUANodeExt = list_to_binary([?SMALL_ATOM_UTF8_EXT,
+ size(ES)+length(H),
+ ES,
+ H]),
+ NoESs = 300 div size(ES),
+ ESs = evil_smileys(NoESs),
+ LargeUANodeExt = list_to_binary([?ATOM_UTF8_EXT,
+ uint16_be(NoESs*size(ES)+length(H)),
+ ESs,
+ H]),
+ {SmallUANodeExt, LargeUANodeExt}.
+
+utf8_pid(Config) when is_list(Config) ->
+ {SmallUANodeExt, LargeUANodeExt} = utf8_nodenames_ext(),
+ SmallPid = mk_pid({SmallUANodeExt, 2}, 4711, 4711),
+ LargePid = mk_pid({LargeUANodeExt, 2}, 4711, 4711),
+ erlang:display({pid, SmallPid, node(SmallPid)}),
+ erlang:display({pid, LargePid, node(LargePid)}),
+ do_echo([SmallPid, LargePid], Config).
+
+utf8_port(Config) when is_list(Config) ->
+ {SmallUANodeExt, LargeUANodeExt} = utf8_nodenames_ext(),
+ SmallPort = mk_port({SmallUANodeExt, 2}, 4711),
+ erlang:display({port, SmallPort, node(SmallPort)}),
+ LargePort = mk_port({LargeUANodeExt, 2}, 4711),
+ erlang:display({port, LargePort, node(LargePort)}),
+ do_echo([SmallPort, LargePort], Config).
+
+utf8_ref(Config) when is_list(Config) ->
+ {SmallUANodeExt, LargeUANodeExt} = utf8_nodenames_ext(),
+ SmallRef = mk_ref({SmallUANodeExt, 2}, [4711, 4711, 4711]),
+ erlang:display({ref, SmallRef, node(SmallRef)}),
+ LargeRef = mk_ref({LargeUANodeExt, 2}, [4711, 4711, 4711]),
+ erlang:display({ref, LargeRef, node(LargeRef)}),
+ do_echo([SmallRef, LargeRef], Config).
+
+
%% Lazy list
cp_gen(N) ->
cp_gen(N, -1, 16#110000).
@@ -647,16 +727,6 @@ make_name() ->
++ "-" ++ integer_to_list(B)
++ "-" ++ integer_to_list(C)).
-
-
--define(VERSION_MAGIC, 131).
-
--define(ATOM_EXT, 100).
--define(REFERENCE_EXT, 101).
--define(PORT_EXT, 102).
--define(PID_EXT, 103).
--define(NEW_REFERENCE_EXT, 114).
-
uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 ->
[(Uint bsr 24) band 16#ff,
(Uint bsr 16) band 16#ff,
@@ -680,72 +750,70 @@ uint8(Uint) ->
mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) ->
- mk_pid({atom_to_list(NodeName), Creation}, Number, Serial);
-mk_pid({NodeName, Creation}, Number, Serial) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_pid({NodeNameExt, Creation}, Number, Serial);
+mk_pid({NodeNameExt, Creation}, Number, Serial) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?PID_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint32_be(Number),
uint32_be(Serial),
uint8(Creation)])) of
Pid when is_pid(Pid) ->
Pid;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]});
+ exit({badarg, mk_pid, [{NodeNameExt, Creation}, Number, Serial]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end.
mk_port({NodeName, Creation}, Number) when is_atom(NodeName) ->
- mk_port({atom_to_list(NodeName), Creation}, Number);
-mk_port({NodeName, Creation}, Number) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_port({NodeNameExt, Creation}, Number);
+mk_port({NodeNameExt, Creation}, Number) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?PORT_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint32_be(Number),
uint8(Creation)])) of
Port when is_port(Port) ->
Port;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_port, [{NodeName, Creation}, Number]});
+ exit({badarg, mk_port, [{NodeNameExt, Creation}, Number]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end.
-mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName),
- is_integer(Creation),
- is_list(Numbers) ->
- mk_ref({atom_to_list(NodeName), Creation}, Numbers);
-mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName),
- is_integer(Creation),
- is_integer(Number) ->
+mk_ref({NodeName, Creation}, [Number] = NL) when is_atom(NodeName),
+ is_integer(Creation),
+ is_integer(Number) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_ref({NodeNameExt, Creation}, NL);
+mk_ref({NodeNameExt, Creation}, [Number]) when is_integer(Creation),
+ is_integer(Number) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?REFERENCE_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint32_be(Number),
uint8(Creation)])) of
Ref when is_reference(Ref) ->
Ref;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]});
+ exit({badarg, mk_ref, [{NodeNameExt, Creation}, [Number]]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end;
-mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName),
+mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName),
is_integer(Creation),
is_list(Numbers) ->
+ <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName),
+ mk_ref({NodeNameExt, Creation}, Numbers);
+mk_ref({NodeNameExt, Creation}, Numbers) when is_integer(Creation),
+ is_list(Numbers) ->
case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
?NEW_REFERENCE_EXT,
uint16_be(length(Numbers)),
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
+ NodeNameExt,
uint8(Creation),
lists:map(fun (N) ->
uint32_be(N)
@@ -754,7 +822,7 @@ mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName),
Ref when is_reference(Ref) ->
Ref;
{'EXIT', {badarg, _}} ->
- exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]});
+ exit({badarg, mk_ref, [{NodeNameExt, Creation}, Numbers]});
Other ->
exit({unexpected_binary_to_term_result, Other})
end.
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 51a3311ec2..9f19efc793 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -121,6 +121,15 @@
</desc>
</func>
<func>
+ <name name="get_env" arity="3"/>
+ <fsummary>Get the value of a configuration parameter using a default</fsummary>
+ <desc>
+ <p>Works like <seealso marker="#get_env/2">get_env/2</seealso> but returns
+ <c><anno>Def</anno></c> value when configuration parameter
+ <c><anno>Par</anno></c> does not exist.</p>
+ </desc>
+ </func>
+ <func>
<name name="get_key" arity="1"/>
<name name="get_key" arity="2"/>
<fsummary>Get the value of an application specification key</fsummary>
diff --git a/lib/kernel/doc/src/error_handler.xml b/lib/kernel/doc/src/error_handler.xml
index acbf9a2c6e..769a869ffa 100644
--- a/lib/kernel/doc/src/error_handler.xml
+++ b/lib/kernel/doc/src/error_handler.xml
@@ -43,19 +43,52 @@
A (possibly empty) list of arguments <c>Arg1,..,ArgN</c>
</type_desc>
<desc>
- <p>This function is evaluated if a call is made to
+ <p>This function is called by the run-time system if a call is made to
<c><anno>Module</anno>:<anno>Function</anno>(Arg1,.., ArgN)</c> and
<c><anno>Module</anno>:<anno>Function</anno>/N</c> is undefined. Note that
<c>undefined_function/3</c> is evaluated inside the process
making the original call.</p>
- <p>If <c><anno>Module</anno></c> is interpreted, the interpreter is invoked
- and the return value of the interpreted
- <c><anno>Function</anno>(Arg1,.., ArgN)</c> call is returned.</p>
- <p>Otherwise, it returns, if possible, the value of
- <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> after an attempt has been
- made to autoload <c><anno>Module</anno></c>. If this is not possible, the
- call to <c><anno>Module</anno>:<anno>Function</anno>(Arg1,.., ArgN)</c> fails with
- exit reason <c>undef</c>.</p>
+
+ <p>This function will first attempt to autoload
+ <c><anno>Module</anno></c>. If that is not possible,
+ an <c>undef</c> exception will be raised.</p>
+
+ <p>If it was possible to load <c><anno>Module</anno></c>
+ and the function <c><anno>Function</anno>/N</c> is exported,
+ it will be called.</p>
+
+ <p>Otherwise, if the function <c>'$handle_undefined_function'/2</c>
+ is exported, it will be called as
+ <c>'$handle_undefined_function'(</c><anno>Function</anno>,
+ <anno>Args</anno>).
+ </p>
+ <warning>
+ <p>Defining <c>'$handle_undefined_function'/2</c> in
+ ordinary application code is highly discouraged. It is very
+ easy to make subtle errors that can take a long time to
+ debug. Furthermore, none of the tools for static code
+ analysis (such as Dialyzer and Xref) supports the use of
+ <c>'$handle_undefined_function'/2</c> and no such support
+ will be added. Only use this function after having carefully
+ considered other, less dangerous, solutions. One example of
+ potential legitimate use is creating stubs for other
+ sub-systems during testing and debugging.
+ </p>
+ </warning>
+ <p>Otherwise an <c>undef</c> exception will be raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="raise_undef_exception" arity="3"/>
+ <fsummary>Raise an undef exception</fsummary>
+ <type_desc variable="Args">
+ A (possibly empty) list of arguments <c>Arg1,..,ArgN</c>
+ </type_desc>
+ <desc>
+ <p>Raise an <c>undef</c> exception with a stacktrace indicating
+ that <c><anno>Module</anno>:<anno>Function</anno>/N</c> is
+ undefined.
+ </p>
</desc>
</func>
<func>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index e30ade1bd2..4a9b7d2ceb 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2012</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -100,7 +100,11 @@
<name name="deep_list"/>
</datatype>
<datatype>
- <name name="fd"/>
+ <name><marker id="type-fd">fd()</marker></name>
+ <desc>
+ <p>A file descriptor representing a file opened in <seealso
+ marker="#raw">raw</seealso> mode.</p>
+ </desc>
</datatype>
<datatype>
<name name="filename"/>
@@ -109,8 +113,8 @@
<name name="io_device"/>
<desc>
<p>As returned by
- <seealso marker="#open/2">file:open/2</seealso>,
- a process handling I/O-protocols.</p>
+ <seealso marker="#open/2">file:open/2</seealso>;
+ <c>pid()</c> is a process handling I/O-protocols.</p>
</desc>
</datatype>
<datatype>
@@ -662,7 +666,8 @@
</item>
<tag><c>raw</c></tag>
<item>
- <p>The <c>raw</c> option allows faster access to a file,
+ <p><marker id="raw"/>
+ The <c>raw</c> option allows faster access to a file,
because no Erlang process is needed to handle the file.
However, a file opened in this way has the following
limitations:</p>
@@ -1251,11 +1256,11 @@
<p>The record <c>file_info</c> contains the following fields.</p>
<taglist>
- <tag><c>size = integer()</c></tag>
+ <tag><c>size = integer() >= 0</c></tag>
<item>
<p>Size of file in bytes.</p>
</item>
- <tag><c>type = device | directory | regular | other</c></tag>
+ <tag><c>type = device | directory | other | regular | symlink</c></tag>
<item>
<p>The type of the file.</p>
</item>
@@ -1263,22 +1268,22 @@
<item>
<p>The current system access to the file.</p>
</item>
- <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() </c></tag>
+ <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
<item>
<p>The last time the file was read.</p>
</item>
- <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() </c></tag>
+ <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
<item>
<p>The last time the file was written.</p>
</item>
- <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() </c></tag>
+ <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >=0</c></tag>
<item>
<p>The interpretation of this time field depends on
the operating system. On Unix, it is the last time
the file or the inode was changed. In Windows, it is
the create time.</p>
</item>
- <tag><c>mode = integer()</c></tag>
+ <tag><c>mode = integer() >= 0</c></tag>
<item>
<p>The file permissions as the sum of the following bit
values:</p>
@@ -1309,33 +1314,33 @@
<p>On Unix platforms, other bits than those listed above
may be set.</p>
</item>
- <tag><c>links = integer()</c></tag>
+ <tag><c>links = integer() >= 0</c></tag>
<item>
<p>Number of links to the file (this will always be 1 for
file systems which have no concept of links).</p>
</item>
- <tag><c>major_device = integer()</c></tag>
+ <tag><c>major_device = integer() >= 0</c></tag>
<item>
<p>Identifies the file system where the file is located.
In Windows, the number indicates a drive as follows:
0 means A:, 1 means B:, and so on.</p>
</item>
- <tag><c>minor_device = integer()</c></tag>
+ <tag><c>minor_device = integer() >= 0</c></tag>
<item>
<p>Only valid for character devices on Unix. In all other
cases, this field is zero.</p>
</item>
- <tag><c>inode = integer()</c></tag>
+ <tag><c>inode = integer() >= 0</c></tag>
<item>
<p>Gives the <c>inode</c> number. On non-Unix file systems,
this field will be zero.</p>
</item>
- <tag><c>uid = integer()</c></tag>
+ <tag><c>uid = integer() >= 0</c></tag>
<item>
<p>Indicates the owner of the file. Will be zero for
non-Unix file systems.</p>
</item>
- <tag><c>gid = integer()</c></tag>
+ <tag><c>gid = integer() >= 0</c></tag>
<item>
<p>Gives the group that the owner of the file belongs to.
Will be zero for non-Unix file systems.</p>
@@ -1766,22 +1771,22 @@
<p>The following fields are used from the record, if they are
given.</p>
<taglist>
- <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer()</c></tag>
+ <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
<item>
<p>The last time the file was read.</p>
</item>
- <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer()</c></tag>
+ <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
<item>
<p>The last time the file was written.</p>
</item>
- <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer()</c></tag>
+ <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
<item>
<p>On Unix, any value give for this field will be ignored
(the "ctime" for the file will be set to the current
time). On Windows, this field is the new creation time to
set for the file.</p>
</item>
- <tag><c>mode = integer()</c></tag>
+ <tag><c>mode = integer() >= 0</c></tag>
<item>
<p>The file permissions as the sum of the following bit
values:</p>
@@ -1812,15 +1817,15 @@
<p>On Unix platforms, other bits than those listed above
may be set.</p>
</item>
- <tag><c>uid = integer()</c></tag>
+ <tag><c>uid = integer() >= 0</c></tag>
<item>
<p>Indicates the owner of the file. Ignored for non-Unix
file systems.</p>
</item>
- <tag><c>gid = integer()</c></tag>
+ <tag><c>gid = integer() >= 0</c></tag>
<item>
<p>Gives the group that the owner of the file belongs to.
- Ignored non-Unix file systems.</p>
+ Ignored for non-Unix file systems.</p>
</item>
</taglist>
<p>Typical error reasons:</p>
diff --git a/lib/kernel/doc/src/packages.xml b/lib/kernel/doc/src/packages.xml
deleted file mode 100644
index 8a82b91a90..0000000000
--- a/lib/kernel/doc/src/packages.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <header>
- <copyright>
- <year>2004</year><year>2012</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- 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.
-
- </legalnotice>
-
- <title>packages</title>
- <prepared>Kenneth Lundin</prepared>
- <responsible>Kenneth Lundin</responsible>
- <docno>1</docno>
- <approved>Kenneth Lundin</approved>
- <checked></checked>
- <date>2004-09-07</date>
- <rev>A</rev>
- <file>packages.sgml</file>
- </header>
- <module>packages</module>
- <modulesummary>Packages in Erlang</modulesummary>
- <description>
- <warning><p>
- Packages has since it was introduced more than 5 years ago been an
- experimental feature. Use it at your own risk, we do not
- actively maintain and develop this feature. It might however be
- supported some
- day.
- </p>
- <p>
- In spite of this packages work quite well, but there are some
- known issues in tools and other parts where packages don't work well.
- </p>
- </warning>
- <p><em>Introduction</em></p>
- <p>Packages are simply namespaces for modules.
- All old Erlang modules automatically belong to the top level
- ("empty-string") namespace, and do not need any changes.</p>
- <p>The full name of a packaged module is written as e.g.
- "<c>fee.fie.foe.foo</c>",
- i.e., as atoms separated by periods,
- where the package name is the part up to
- but not including the last period;
- in this case "<c>fee.fie.foe</c>".
- A more concrete example is the module <c>erl.lang.term</c>,
- which is in the
- package <c>erl.lang</c>.
- Package names can have any number of segments, as in
- <c>erl.lang.list.sort</c>.
- The atoms in the name can be quoted, as in <c>foo.'Bar'.baz</c>,
- or even the
- whole name, as in <c>'foo.bar.baz'</c> but the concatenation of
- atoms and
- periods must not contain two consecutive period characters or
- end with a period,
- as in <c>'foo..bar'</c>, <c>foo.'.bar'</c>, or <c>foo.'bar.'</c>.
- The periods must not be followed by whitespace.</p>
- <p>The code loader maps module names onto the file system directory
- structure.
- E.g., the module <c>erl.lang.term</c> corresponds to a file
- <c>.../erl/lang/term.beam</c>
- in the search path.
- Note that the name of the actual object file corresponds to
- the last part only of the full module name.
- (Thus, old existing modules such as <c>lists</c>
- simply map to <c>.../lists.beam</c>, exactly as before.)</p>
- <p>A packaged module in a file "<c>foo/bar/fred.erl</c>" is declared
- as:</p>
- <code type="none">
--module(foo.bar.fred).</code>
- <p>This can be compiled and loaded from the Erlang shell using
- <c>c(fred)</c>, if
- your current directory is the same as that of the file.
- The object file will be named <c>fred.beam</c>.</p>
- <p>The Erlang search path works exactly as before,
- except that the package segments will be appended to each
- directory in the path in order to find the
- file. E.g., assume the path is <c>["/usr/lib/erl", "/usr/local/lib/otp/legacy/ebin", "/home/barney/erl"]</c>.
- Then, the code for a module named <c>foo.bar.fred</c> will be
- searched for
- first as <c>"/usr/lib/erl/foo/bar/fred.beam"</c>, then
- <c>"/usr/local/lib/otp/legacy/ebin/foo/bar/fred.beam"</c>
- and lastly <c>"/home/barney/erl/foo/bar/fred.beam"</c>.
- A module
- like <c>lists</c>, which is in the top-level package,
- will be looked for as <c>"/usr/lib/erl/lists.beam"</c>,
- <c>"/usr/local/lib/otp/legacy/ebin/lists.beam"</c> and
- <c>"/home/barney/erl/lists.beam"</c>.</p>
- <p><em>Programming</em></p>
- <p>Normally, if a call is made from one module to another,
- it is assumed that the
- called module belongs to the same package as the source module.
- The compiler
- automatically expands such calls. E.g., in:</p>
- <code type="none">
--module(foo.bar.m1).
--export([f/1]).
-
-f(X) -> m2:g(X).</code>
- <p><c>m2:g(X)</c> becomes a call to <c>foo.bar.m2</c>
- If this is not what was intended, the call can be written
- explicitly, as in</p>
- <code type="none">
--module(foo.bar.m1).
--export([f/1]).
-
-f(X) -> fee.fie.foe.m2:g(X).</code>
- <p>Because the called module is given with an explicit package name,
- no expansion is done in this case.</p>
- <p>If a module from another package is used repeatedly in a module,
- an import declaration can make life easier:</p>
- <code type="none">
--module(foo.bar.m1).
--export([f/1, g/1]).
--import(fee.fie.foe.m2).
-
-f(X) -> m2:g(X).
-g(X) -> m2:h(X).</code>
- <p>will make the calls to <c>m2</c> refer to <c>fee.fie.foe.m2</c>.
- More generally, a declaration <c>-import(Package.Module).</c>
- will cause calls to <c>Module</c>
- to be expanded to <c>Package.Module</c>.</p>
- <p>Old-style function imports work as normal (but full module
- names must be
- used); e.g.:</p>
- <code type="none">
--import(fee.fie.foe.m2, [g/1, h/1]).</code>
- <p>however, it is probably better to avoid this form of import
- altogether in new
- code, since it makes it hard to see what calls are really "remote".</p>
- <p>If it is necessary to call a module in the top-level package
- from within a
- named package, the module name can be written either with an
- initial period as
- in e.g. "<c>.lists</c>", or with an empty initial atom, as in
- "<c>''.lists</c>".
- However, the best way is to use an import declaration -
- this is most obvious to
- the eye, and makes sure we don't forget adding a period somewhere:</p>
- <code type="none">
--module(foo.bar.fred).
--export([f/1]).
--import(lists).
-
-f(X) -> lists:reverse(X).</code>
- <p>The dot-syntax for module names can be used in any expression.
- All segments must
- be constant atoms, and the result must be a well-formed
- package/module name.
- E.g.:</p>
- <code type="none">
-spawn(foo.bar.fred, f, [X])</code>
- <p>is equivalent to <c>spawn('foo.bar.fred', f, [X])</c>.</p>
- <p><em>The Erlang Shell</em></p>
- <p>The shell also automatically expands remote calls,
- however currently no
- expansions are made by default.
- The user can change the behaviour by using the <c>import/1</c>
- shell command (or its abbreviation <c>use/1</c>). E.g.:</p>
- <pre>
-1> <input>import(foo.bar.m).</input>
-ok
-2> <input>m:f().</input></pre>
- <p>will evaluate <c>foo.bar.m:f()</c>.
- If a new import is made of the same name,
- this overrides any previous import.
- (It is likely that in the future, some
- system packages will be pre-imported.)</p>
- <p>In addition, the shell command <c>import_all/1</c>
- (and its alias <c>use_all/1</c>)
- imports all modules currently found in the path for a given
- package name. E.g.,
- assuming the files "<c>.../foo/bar/fred.beam</c>",
- "<c>.../foo/bar/barney.beam</c>"
- and "<c>.../foo/bar/bambam.beam</c>" can be found from our current
- path,</p>
- <pre>
-1> <input>import_all(foo.bar).</input></pre>
- <p>will make <c>fred</c>, <c>barney</c> and <c>bambam</c>
- expand to <c>foo.bar.fred</c>,
- <c>foo.bar.barney</c> and <c>foo.bar.bambam</c>, respectively.</p>
- <p>Note: The compiler does not have an "import all" directive, for the
- reason that Erlang has no compile time type checking.
- E.g. if the wrong search
- path is used at compile time, a call <c>m:f(...)</c>
- could be expanded to <c>foo.bar.m:f(...)</c>
- without any warning, instead of the intended
- <c>frob.ozz.m:f(...)</c>, if
- package <c>foo.bar</c> happens to be found first in the path.
- Explicitly
- declaring each use of a module makes for safe code.</p>
- </description>
-</erlref>
-
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
index 9ef0959271..67d91ba585 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -64,6 +64,5 @@
<xi:include href="zlib_stub.xml"/>
<xi:include href="app.xml"/>
<xi:include href="config.xml"/>
- <xi:include href="packages.xml"/>
</application>
diff --git a/lib/kernel/include/dist.hrl b/lib/kernel/include/dist.hrl
index 5b52f6f294..91e13d99a9 100644
--- a/lib/kernel/include/dist.hrl
+++ b/lib/kernel/include/dist.hrl
@@ -36,3 +36,4 @@
-define(DFLAG_UNICODE_IO,16#1000).
-define(DFLAG_DIST_HDR_ATOM_CACHE,16#2000).
-define(DFLAG_SMALL_ATOM_TAGS, 16#4000).
+-define(DFLAG_UTF8_ATOMS, 16#10000).
diff --git a/lib/kernel/include/file.hrl b/lib/kernel/include/file.hrl
index bf97173122..69aec1ee36 100644
--- a/lib/kernel/include/file.hrl
+++ b/lib/kernel/include/file.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -22,32 +22,37 @@
%%--------------------------------------------------------------------------
-record(file_info,
- {size :: non_neg_integer(), % Size of file in bytes.
- type :: 'device' | 'directory' | 'other' | 'regular' | 'symlink',
- access :: 'read' | 'write' | 'read_write' | 'none',
- atime :: file:date_time() | integer(), % The local time the file was last read:
- % {{Year, Mon, Day}, {Hour, Min, Sec}}.
- % atime, ctime, mtime may also be unix epochs()
- mtime :: file:date_time() | integer(), % The local time the file was last written.
- ctime :: file:date_time() | integer(), % The interpretation of this time field
- % is dependent on operating system.
- % On Unix it is the last time the file
- % or the inode was changed. On Windows,
- % it is the creation time.
- mode :: integer(), % File permissions. On Windows,
- % the owner permissions will be
- % duplicated for group and user.
- links :: non_neg_integer(), % Number of links to the file (1 if the
- % filesystem doesn't support links).
- major_device :: integer(), % Identifies the file system (Unix),
- % or the drive number (A: = 0, B: = 1)
- % (Windows).
- %% The following are Unix specific.
- %% They are set to zero on other operating systems.
- minor_device :: integer(), % Only valid for devices.
- inode :: integer(), % Inode number for file.
- uid :: integer(), % User id for owner.
- gid :: integer()}). % Group id for owner.
+ {size :: non_neg_integer(), % Size of file in bytes.
+ type :: 'device' | 'directory' | 'other' | 'regular' | 'symlink',
+ access :: 'read' | 'write' | 'read_write' | 'none',
+ atime :: file:date_time() | non_neg_integer(),
+ % The local time the file was last read:
+ % {{Year, Mon, Day}, {Hour, Min, Sec}}.
+ % atime, ctime, mtime may also be unix epochs()
+ mtime :: file:date_time() | non_neg_integer(),
+ % The local time the file was last written.
+ ctime :: file:date_time() | non_neg_integer(),
+ % The interpretation of this time field
+ % is dependent on operating system.
+ % On Unix it is the last time the file
+ % or the inode was changed. On Windows,
+ % it is the creation time.
+ mode :: non_neg_integer(), % File permissions. On Windows,
+ % the owner permissions will be
+ % duplicated for group and user.
+ links :: non_neg_integer(),
+ % Number of links to the file (1 if the
+ % filesystem doesn't support links).
+ major_device :: non_neg_integer(),
+ % Identifies the file system (Unix),
+ % or the drive number (A: = 0, B: = 1)
+ % (Windows).
+ %% The following are Unix specific.
+ %% They are set to zero on other operating systems.
+ minor_device :: non_neg_integer(), % Only valid for devices.
+ inode :: non_neg_integer(), % Inode number for file.
+ uid :: non_neg_integer(), % User id for owner.
+ gid :: non_neg_integer()}). % Group id for owner.
-record(file_descriptor,
diff --git a/lib/kernel/internal_doc/distribution_handshake.txt b/lib/kernel/internal_doc/distribution_handshake.txt
index 6a3ee22ed3..d00c4ceb02 100644
--- a/lib/kernel/internal_doc/distribution_handshake.txt
+++ b/lib/kernel/internal_doc/distribution_handshake.txt
@@ -1,215 +1 @@
-HOW THE DISTRIBUTION HANDSHAKE WORKS
-------------------------------------
-
-This document describes the distribution handshake introduced in
-the R6 release of Erlang/OTP.
-
-GENERAL
--------
-
-The TCP/IP distribution uses a handshake which expects a
-connection based protocol, i.e. the protocol does not include
-any authentication after the handshake procedure.
-
-This is not entirely safe, as it is vulnerable against takeover
-attacks, but it is a tradeoff between fair safety and performance.
-
-The cookies are never sent in cleartext and the handshake procedure
-expects the client (called A) to be the first one to prove that it can
-generate a sufficient digest. The digest is generated with the
-MD5 message digest algorithm and the challenges are expected to be very
-random numbers.
-
-DEFINITIONS
------------
-
-A challenge is a 32 bit integer number in big endian order. Below the function
-gen_challenge() returns a random 32 bit integer used as a challenge.
-
-A digest is a (16 bytes) MD5 hash of [the Challenge (as text) concatenated
-with the cookie (as text)]. Below, the function gen_digest(Challenge, Cookie)
-generates a digest as described above.
-
-An out_cookie is the cookie used in outgoing communication to a certain node,
-so that A's out_cookie for B should correspond with B's in_cookie for A and
-the other way around. A's out_cookie for B and A's in_cookie for B need *NOT*
-be the same. Below the function out_cookie(Node) returns the current
-node's out_cookie for Node.
-
-An in_cookie is the cookie expected to be used by another node when
-communicating with us, so that A's in_cookie for B corresponds with B's
-out_cookie for A. Below the function in_cookie(Node) returns the current
-node's in_cookie for Node.
-
-The cookies are text strings that can be viewed as passwords.
-
-Every message in the handshake starts with a 16 bit big endian integer
-which contains the length of the message (not counting the two initial bytes).
-In erlang this corresponds to the gen_tcp option {packet, 2}. Note that after
-the handshake, the distribution switches to 4 byte packet headers.
-
-THE HANDSHAKE IN DETAIL
------------------------
-
-Imagine two nodes, node A, which initiates the handshake and node B, which
-accepts the connection.
-
-1) connect/accept: A connects to B via TCP/IP and B accepts the connection.
-
-2) send_name/receive_name: A sends an initial identification to B.
-B receives the message. The message looks
-like this (every "square" being one byte and the packet header removed):
-
-+---+--------+--------+-----+-----+-----+-----+-----+-----+-...-+-----+
-|'n'|Version0|Version1|Flag0|Flag1|Flag2|Flag3|Name0|Name1| ... |NameN|
-+---+--------+--------+-----+-----+-----+-----+-----+-----+-... +-----+
-
-The 'n' is just a message tag,
-Version0 & Version1 is the distribution version selected by node A,
- based on information from EPMD. (16 bit big endian)
-Flag0 ... Flag3 are capability flags, the capabilities defined in dist.hrl.
- (32 bit big endian)
-Name0 ... NameN is the full nodename of A, as a string of bytes (the
- packet length denotes how long it is).
-
-3) recv_status/send_status: B sends a status message to A, which indicates
-if the connection is allowed. Four different status codes are defined:
-ok: The handshake will continue.
-ok_simultaneous: The handshake will continue, but A is informed that B
- has another ongoing connection attempt that will be
- shut down (simultaneous connect where A's name is
- greater than B's name, compared literally),
-nok: The handshake will not continue, as B already has an ongoing handshake
- which it itself has initiated. (simultaneous connect where B's name is
- greater than A's)
-not_allowed: The connection is disallowed for some (unspecified) security
- reason.
-alive: A connection to the node is already active, which either means
- that node A is confused or that the TCP connection breakdown
- of a previous node with this name has not yet reached node B.
- See 3B below.
-
-This is the format of the status message:
-
-+---+-------+-------+-...-+-------+
-|'s'|Status0|Status1| ... |StatusN|
-+---+-------+-------+-...-+-------+
-
-'s' is the message tag
-Status0 ... StatusN is the status as a string (not terminated)
-
-3B) send_status/recv_status: If status was 'alive', node A will answer with
-another status message containing either 'true' which means that the
-connection should continue (The old connection from this node is broken), or
-'false', which simply means that the connection should be closed, the
-connection attempt was a mistake.
-
-4) recv_challenge/send_challenge: If the status was 'ok' or 'ok_simultaneous',
-The handshake continues with B sending A another message, the challenge.
-The challenge contains the same type of information as the "name" message
-initially sent from A to B, with the addition of a 32 bit challenge:
-
-+---+--------+--------+-----+-----+-----+-----+-----+-----+-----+-----+---
-|'n'|Version0|Version1|Flag0|Flag1|Flag2|Flag3|Chal0|Chal1|Chal2|Chal3|
-+---+--------+--------+-----+-----+-----+-----+-----+-----+-----+-----+---
- ------+-----+-...-+-----+
- Name0|Name1| ... |NameN|
- ------+-----+-... +-----+
-
-Where Chal0 ... Chal3 is the challenge as a 32 bit big endian integer
-and the other fields are B's version, flags and full nodename.
-
-5) send_challenge_reply/recv_challenge_reply: Now A has generated
-a digest and its own challenge. Those are sent together in a package
-to B:
-
-+---+-----+-----+-----+-----+-----+-----+-----+-----+-...-+------+
-|'r'|Chal0|Chal1|Chal2|Chal3|Dige0|Dige1|Dige2|Dige3| ... |Dige15|
-+---+-----+-----+-----+-----+-----+-----+-----+-----+-...-+------+
-
-Where 'r' is the tag, Chal0 ... Chal3 is A's challenge for B to handle and
-Dige0 ... Dige15 is the digest that A constructed from the challenge B sent
-in the previous step.
-
-6) recv_challenge_ack/send_challenge_ack: B checks that the digest received
-from A is correct and generates a digest from the challenge received from
-A. The digest is then sent to A. The message looks like this:
-
-+---+-----+-----+-----+-----+-...-+------+
-|'a'|Dige0|Dige1|Dige2|Dige3| ... |Dige15|
-+---+-----+-----+-----+-----+-...-+------+
-
-Where 'a' is the tag and Dige0 ... Dige15 is the digest calculated by B
-for A's challenge.
-
-7) A checks the digest from B and the connection is up.
-
-SEMIGRAPHIC VIEW
-----------------
-
-A (initiator) B (acceptor)
-
-TCP connect ----------------------------------------->
- TCP accept
-
-send_name ----------------------------------------->
- recv_name
-
- <---------------------------------------- send_status
-recv_status
-(if status was 'alive'
- send_status - - - - - - - - - - - - - - - - - - - ->
- recv_status)
- ChB = gen_challenge()
- (ChB)
- <---------------------------------------- send_challenge
-recv_challenge
-
-ChA = gen_challenge(),
-OCA = out_cookie(B),
-DiA = gen_digest(ChB,OCA)
- (ChA, DiA)
-send_challenge_reply -------------------------------->
- recv_challenge_reply
- ICB = in_cookie(A),
- check:
- DiA == gen_digest
- (ChB, ICB) ?
- - if OK:
- OCB = out_cookie(A),
- DiB = gen_digest
- (DiB) (ChA, OCB)
- <----------------------------------------- send_challenge_ack
-recv_challenge_ack DONE
-ICA = in_cookie(B), - else
-check: CLOSE
-DiB == gen_digest(ChA,ICA) ?
-- if OK
- DONE
-- else
- CLOSE
-
-
-THE CURRENTLY DEFINED FLAGS
----------------------------
-Currently the following capability flags are defined:
-
-%% The node should be published and part of the global namespace
--define(DFLAG_PUBLISHED,1).
-
-%% The node implements an atom cache
--define(DFLAG_ATOM_CACHE,2).
-
-%% The node implements extended (3 * 32 bits) references
--define(DFLAG_EXTENDED_REFERENCES,4).
-
-%% The node implements distributed process monitoring.
--define(DFLAG_DIST_MONITOR,8).
-
-%% The node uses separate tag for fun's (lambdas) in the distribution protocol.
--define(DFLAG_FUN_TAGS,16).
-
-An R6 erlang node implements all of the above, while a C or Java node only
-implements DFLAG_EXTENDED_REFERENCES.
-
-Last modified 1999-11-08 -- Patrik Nyblom, OTP
+This information has been moved to the "Distribution Protocol" chapter of "ERTS User's Guide".
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index 60291bbce6..2b529a85b0 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -148,7 +148,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
endif
-ERL_COMPILE_FLAGS += -I../include
+ERL_COMPILE_FLAGS += -I../include -Werror
# ----------------------------------------------------
# Targets
@@ -170,13 +170,13 @@ docs:
# ----------------------------------------------------
../../hipe/main/hipe.hrl: ../../hipe/vsn.mk ../../hipe/main/hipe.hrl.src
- sed -e "s;%VSN%;$(HIPE_VSN);" ../../hipe/main/hipe.hrl.src > ../../hipe/main/hipe.hrl
+ $(vsn_verbose)sed -e "s;%VSN%;$(HIPE_VSN);" ../../hipe/main/hipe.hrl.src > ../../hipe/main/hipe.hrl
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@
EPMD_FLAGS = -Depmd_port_no=$(EPMD_PORT_NO) \
@@ -186,10 +186,10 @@ EPMD_FLAGS = -Depmd_port_no=$(EPMD_PORT_NO) \
-Derlang_daemon_port=$(EPMD_PORT_NO)
$(ESRC)/inet_dns_record_adts.hrl: $(ESRC)/inet_dns_record_adts.pl
- LANG=C $(PERL) $< > $@
+ $(gen_verbose)LANG=C $(PERL) $< > $@
$(EBIN)/erl_epmd.beam: $(ESRC)/erl_epmd.erl
- $(ERLC) $(ERL_COMPILE_FLAGS) $(EPMD_FLAGS) -o$(EBIN) $<
+ $(V_ERLC) $(ERL_COMPILE_FLAGS) $(EPMD_FLAGS) -o$(EBIN) $<
# ----------------------------------------------------
# Release Target
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index 9b7c4aa7b8..4e65883be7 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -23,7 +23,7 @@
which_applications/0, which_applications/1,
loaded_applications/0, permit/2]).
-export([set_env/3, set_env/4, unset_env/2, unset_env/3]).
--export([get_env/1, get_env/2, get_all_env/0, get_all_env/1]).
+-export([get_env/1, get_env/2, get_env/3, get_all_env/0, get_all_env/1]).
-export([get_key/1, get_key/2, get_all_key/0, get_all_key/1]).
-export([get_application/0, get_application/1, info/0]).
-export([start_type/0]).
@@ -264,6 +264,20 @@ get_env(Key) ->
get_env(Application, Key) ->
application_controller:get_env(Application, Key).
+-spec get_env(Application, Par, Def) -> Val when
+ Application :: atom(),
+ Par :: atom(),
+ Def :: term(),
+ Val :: term().
+
+get_env(Application, Key, Def) ->
+ case get_env(Application, Key) of
+ {ok, Val} ->
+ Val;
+ undefined ->
+ Def
+ end.
+
-spec get_all_env() -> Env when
Env :: [{Par :: atom(), Val :: term()}].
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 75ce852001..3c860af48e 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -247,7 +247,7 @@ start_boot_application(Application, RestartType) ->
{{error, {already_loaded, AppName}}, _} ->
gen_server:call(?AC, {start_application, AppName, RestartType}, infinity);
{{error,{bad_environment_value,Env}}, permanent} ->
- Txt = io_lib:format("Bad environment variable: ~p Application: ~p",
+ Txt = io_lib:format("Bad environment variable: ~tp Application: ~p",
[Env, Application]),
exit({error, list_to_atom(lists:flatten(Txt))});
{Error, _} ->
@@ -501,13 +501,13 @@ init(Init, Kernel) ->
{local, ?AC})
end;
{error, ErrorStr} ->
- Str = lists:flatten(io_lib:format("invalid config data: ~s", [ErrorStr])),
+ Str = lists:flatten(io_lib:format("invalid config data: ~ts", [ErrorStr])),
Init ! {ack, self(), {error, to_string(Str)}}
end;
{error, {File, Line, Str}} ->
ReasonStr =
lists:flatten(io_lib:format("error in config file "
- "~p (~w): ~s",
+ "~tp (~w): ~ts",
[File, Line, Str])),
Init ! {ack, self(), {error, to_string(ReasonStr)}}
end.
@@ -537,17 +537,17 @@ check_conf_data(ConfData) when is_list(ConfData) ->
end;
{AppName, List} when is_list(List) ->
ErrMsg = "application: "
- ++ lists:flatten(io_lib:format("~p",[AppName]))
+ ++ lists:flatten(io_lib:format("~tp",[AppName]))
++ "; application name must be an atom",
{error, ErrMsg};
{AppName, _List} ->
ErrMsg = "application: "
- ++ lists:flatten(io_lib:format("~p",[AppName]))
+ ++ lists:flatten(io_lib:format("~tp",[AppName]))
++ "; parameters must be a list",
{error, ErrMsg};
Else ->
ErrMsg = "invalid application name: " ++
- lists:flatten(io_lib:format(" ~p",[Else])),
+ lists:flatten(io_lib:format(" ~tp",[Else])),
{error, ErrMsg}
end;
check_conf_data(_ConfData) ->
@@ -570,10 +570,10 @@ check_para_kernel([{Para, _Val} | ParaList]) when is_atom(Para) ->
check_para_kernel(ParaList);
check_para_kernel([{Para, _Val} | _ParaList]) ->
{error, "application: kernel; invalid parameter: " ++
- lists:flatten(io_lib:format("~p",[Para]))};
+ lists:flatten(io_lib:format("~tp",[Para]))};
check_para_kernel(Else) ->
{error, "application: kernel; invalid parameter list: " ++
- lists:flatten(io_lib:format("~p",[Else]))}.
+ lists:flatten(io_lib:format("~tp",[Else]))}.
check_distributed([]) ->
@@ -594,10 +594,10 @@ check_para([{Para, _Val} | ParaList], AppName) when is_atom(Para) ->
check_para(ParaList, AppName);
check_para([{Para, _Val} | _ParaList], AppName) ->
{error, "application: " ++ AppName ++ "; invalid parameter: " ++
- lists:flatten(io_lib:format("~p",[Para]))};
+ lists:flatten(io_lib:format("~tp",[Para]))};
check_para([Else | _ParaList], AppName) ->
{error, "application: " ++ AppName ++ "; invalid parameter: " ++
- lists:flatten(io_lib:format("~p",[Else]))}.
+ lists:flatten(io_lib:format("~tp",[Else]))}.
-type calls() :: 'info' | 'prep_config_change' | 'which_applications'
@@ -1434,7 +1434,9 @@ make_appl(Name) when is_atom(Name) ->
{ok, [Application]} ->
{ok, make_appl_i(Application)};
{error, Reason} ->
- {error, {file:format_error(Reason), FName}}
+ {error, {file:format_error(Reason), FName}};
+ error ->
+ {error, "bad encoding"}
end
end;
make_appl(Application) ->
@@ -1443,12 +1445,17 @@ make_appl(Application) ->
prim_consult(FullName) ->
case erl_prim_loader:get_file(FullName) of
{ok, Bin, _} ->
- case erl_scan:string(binary_to_list(Bin)) of
- {ok, Tokens, _EndLine} ->
- prim_parse(Tokens, []);
- {error, Reason, _EndLine} ->
- {error, Reason}
- end;
+ case file_binary_to_list(Bin) of
+ {ok, String} ->
+ case erl_scan:string(String, 1, [unicode]) of
+ {ok, Tokens, _EndLine} ->
+ prim_parse(Tokens, []);
+ {error, Reason, _EndLine} ->
+ {error, Reason}
+ end;
+ error ->
+ error
+ end;
error ->
{error, enoent}
end.
@@ -1521,7 +1528,7 @@ do_change_apps(Applications, Config, OldAppls) ->
%% Report errors, but do not terminate
%% (backwards compatible behaviour)
lists:foreach(fun({error, {SysFName, Line, Str}}) ->
- Str2 = lists:flatten(io_lib:format("~p: ~w: ~s~n",
+ Str2 = lists:flatten(io_lib:format("~tp: ~w: ~ts~n",
[SysFName, Line, Str])),
error_logger:format(Str2, [])
end,
@@ -1593,18 +1600,18 @@ conv(_) -> [].
%%% Fix some day: eliminate the duplicated code here
make_term(Str) ->
- case erl_scan:string(Str) of
+ case erl_scan:string(Str, 1, [unicode]) of
{ok, Tokens, _} ->
case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
{ok, Term} ->
Term;
{error, {_,M,Reason}} ->
- error_logger:format("application_controller: ~s: ~s~n",
+ error_logger:format("application_controller: ~ts: ~ts~n",
[M:format_error(Reason), Str]),
throw({error, {bad_environment_value, Str}})
end;
{error, {_,M,Reason}, _} ->
- error_logger:format("application_controller: ~s: ~s~n",
+ error_logger:format("application_controller: ~ts: ~ts~n",
[M:format_error(Reason), Str]),
throw({error, {bad_environment_value, Str}})
end.
@@ -1828,8 +1835,12 @@ load_file(File) ->
{ok, Bin, _FileName} ->
%% Make sure that there is some whitespace at the end of the string
%% (so that reading a file with no NL following the "." will work).
- Str = binary_to_list(Bin) ++ " ",
- scan_file(Str);
+ case file_binary_to_list(Bin) of
+ {ok, String} ->
+ scan_file(String ++ " ");
+ error ->
+ {error, {none, scan_file, "bad encoding"}}
+ end;
error ->
{error, {none, open_file, "configuration file not found"}}
end.
@@ -1947,6 +1958,18 @@ test_make_apps([], Res) ->
test_make_apps([A|Apps], Res) ->
test_make_apps(Apps, [make_appl(A) | Res]).
+file_binary_to_list(Bin) ->
+ Enc = case epp:read_encoding_from_binary(Bin) of
+ none -> epp:default_encoding();
+ Encoding -> Encoding
+ end,
+ case catch unicode:characters_to_list(Bin, Enc) of
+ String when is_list(String) ->
+ {ok, String};
+ _ ->
+ error
+ end.
+
%%-----------------------------------------------------------------
%% String conversion
%% Exit reason needs to be a printable string
diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl
index 6ae786ebd9..165a0f0dc0 100644
--- a/lib/kernel/src/auth.erl
+++ b/lib/kernel/src/auth.erl
@@ -384,7 +384,7 @@ create_cookie(Name) ->
{{error,Reason}, _} ->
{error,
lists:flatten(
- io_lib:format("Failed to write to cookie file '~s': ~p", [Name, Reason]))};
+ io_lib:format("Failed to write to cookie file '~ts': ~p", [Name, Reason]))};
{ok, {error, Reason}} ->
{error, "Failed to change mode: " ++ atom_to_list(Reason)}
end;
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 361f2bdf8a..2908b747d1 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -511,7 +511,7 @@ search([{Dir, File} | Tail]) ->
false ->
search(Tail);
{Dir2, File} ->
- io:format("** ~s hides ~s~n",
+ io:format("** ~ts hides ~ts~n",
[filename:join(Dir, File),
filename:join(Dir2, File)]),
[clash | search(Tail)]
@@ -528,7 +528,7 @@ decorate([File|Tail], Dir) ->
[{Dir, File} | decorate(Tail, Dir)].
filter(_Ext, Dir, error) ->
- io:format("** Bad path can't read ~s~n", [Dir]), [];
+ io:format("** Bad path can't read ~ts~n", [Dir]), [];
filter(Ext, _, {ok,Files}) ->
filter2(Ext, length(Ext), Files).
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index b2d2c19f78..2de175d5db 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1266,11 +1266,11 @@ try_load_module_1(File, Mod, Bin, Caller, #state{moddb=Db}=St) ->
{error,on_load} ->
handle_on_load(Mod, File, Caller, St);
{error,What} = Error ->
- error_msg("Loading of ~s failed: ~p\n", [File, What]),
+ error_msg("Loading of ~ts failed: ~p\n", [File, What]),
{reply,Error,St}
end;
Error ->
- error_msg("Native loading of ~s failed: ~p\n",
+ error_msg("Native loading of ~ts failed: ~p\n",
[File,Error]),
{reply,ok,St}
end
diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl
index 1513fdaec0..9483640a30 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -1527,48 +1527,48 @@ do_format_error({size_mismatch, OldSize, ArgSize}) ->
io_lib:format("The given size ~p does not match the size ~p found on "
"the disk log size file~n", [ArgSize, OldSize]);
do_format_error({read_only_mode, Log}) ->
- io_lib:format("The disk log ~p has been opened read-only, but the "
+ io_lib:format("The disk log ~tp has been opened read-only, but the "
"requested operation needs read-write access~n", [Log]);
do_format_error({format_external, Log}) ->
io_lib:format("The requested operation can only be applied on internally "
- "formatted disk logs, but ~p is externally formatted~n",
+ "formatted disk logs, but ~tp is externally formatted~n",
[Log]);
do_format_error({blocked_log, Log}) ->
- io_lib:format("The blocked disk log ~p does not queue requests, or "
+ io_lib:format("The blocked disk log ~tp does not queue requests, or "
"the log has been blocked by the calling process~n", [Log]);
do_format_error({full, Log}) ->
- io_lib:format("The halt log ~p is full~n", [Log]);
+ io_lib:format("The halt log ~tp is full~n", [Log]);
do_format_error({not_blocked, Log}) ->
- io_lib:format("The disk log ~p is not blocked~n", [Log]);
+ io_lib:format("The disk log ~tp is not blocked~n", [Log]);
do_format_error({not_owner, Pid}) ->
- io_lib:format("The pid ~p is not an owner of the disk log~n", [Pid]);
+ io_lib:format("The pid ~tp is not an owner of the disk log~n", [Pid]);
do_format_error({not_blocked_by_pid, Log}) ->
- io_lib:format("The disk log ~p is blocked, but only the blocking pid "
+ io_lib:format("The disk log ~tp is blocked, but only the blocking pid "
"can unblock a disk log~n", [Log]);
do_format_error({new_size_too_small, Log, CurrentSize}) ->
- io_lib:format("The current size ~p of the halt log ~p is greater than the "
+ io_lib:format("The current size ~p of the halt log ~tp is greater than the "
"requested new size~n", [CurrentSize, Log]);
do_format_error({halt_log, Log}) ->
- io_lib:format("The halt log ~p cannot be wrapped~n", [Log]);
+ io_lib:format("The halt log ~tp cannot be wrapped~n", [Log]);
do_format_error({same_file_name, Log}) ->
- io_lib:format("Current and new file name of the disk log ~p "
+ io_lib:format("Current and new file name of the disk log ~tp "
"are the same~n", [Log]);
do_format_error({arg_mismatch, Option, FirstValue, ArgValue}) ->
- io_lib:format("The value ~p of the disk log option ~p does not match "
- "the current value ~p~n", [ArgValue, Option, FirstValue]);
+ io_lib:format("The value ~tp of the disk log option ~p does not match "
+ "the current value ~tp~n", [ArgValue, Option, FirstValue]);
do_format_error({name_already_open, Log}) ->
- io_lib:format("The disk log ~p has already opened another file~n", [Log]);
+ io_lib:format("The disk log ~tp has already opened another file~n", [Log]);
do_format_error({node_already_open, Log}) ->
- io_lib:format("The distribution option of the disk log ~p does not match "
+ io_lib:format("The distribution option of the disk log ~tp does not match "
"already open log~n", [Log]);
do_format_error({open_read_write, Log}) ->
- io_lib:format("The disk log ~p has already been opened read-write~n",
+ io_lib:format("The disk log ~tp has already been opened read-write~n",
[Log]);
do_format_error({open_read_only, Log}) ->
- io_lib:format("The disk log ~p has already been opened read-only~n",
+ io_lib:format("The disk log ~tp has already been opened read-only~n",
[Log]);
do_format_error({not_internal_wrap, Log}) ->
- io_lib:format("The requested operation cannot be applied since ~p is not "
+ io_lib:format("The requested operation cannot be applied since ~tp is not "
"an internally formatted disk log~n", [Log]);
do_format_error(no_such_log) ->
io_lib:format("There is no disk log with the given name~n", []);
@@ -1579,13 +1579,13 @@ do_format_error(nodedown) ->
io_lib:format("There seems to be no node up that can handle "
"the request~n", []);
do_format_error({corrupt_log_file, FileName}) ->
- io_lib:format("The disk log file \"~s\" contains corrupt data~n",
+ io_lib:format("The disk log file \"~ts\" contains corrupt data~n",
[FileName]);
do_format_error({need_repair, FileName}) ->
- io_lib:format("The disk log file \"~s\" has not been closed properly and "
+ io_lib:format("The disk log file \"~ts\" has not been closed properly and "
"needs repair~n", [FileName]);
do_format_error({not_a_log_file, FileName}) ->
- io_lib:format("The file \"~s\" is not a wrap log file~n", [FileName]);
+ io_lib:format("The file \"~ts\" is not a wrap log file~n", [FileName]);
do_format_error({invalid_header, InvalidHeader}) ->
io_lib:format("The disk log header is not wellformed: ~p~n",
[InvalidHeader]);
@@ -1593,14 +1593,14 @@ do_format_error(end_of_log) ->
io_lib:format("An attempt was made to step outside a not yet "
"full wrap log~n", []);
do_format_error({invalid_index_file, FileName}) ->
- io_lib:format("The wrap log index file \"~s\" cannot be used~n",
+ io_lib:format("The wrap log index file \"~ts\" cannot be used~n",
[FileName]);
do_format_error({no_continuation, BadCont}) ->
io_lib:format("The term ~p is not a chunk continuation~n", [BadCont]);
do_format_error({file_error, FileName, Reason}) ->
- io_lib:format("\"~s\": ~p~n", [FileName, file:format_error(Reason)]);
+ io_lib:format("\"~ts\": ~tp~n", [FileName, file:format_error(Reason)]);
do_format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
do_info(L, Cnt) ->
#log{name = Name, type = Type, mode = Mode, filename = File,
diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl
index 0cb1ed579a..cbf7e1c085 100644
--- a/lib/kernel/src/disk_log_1.erl
+++ b/lib/kernel/src/disk_log_1.erl
@@ -489,7 +489,7 @@ lh(H, _F) -> % cannot happen
repair(In, File) ->
FSz = file_size(File),
- error_logger:info_msg("disk_log: repairing ~p ...\n", [File]),
+ error_logger:info_msg("disk_log: repairing ~tp ...\n", [File]),
Tmp = add_ext(File, "TMP"),
{ok, {_Alloc, Out, {0, _}, _FileSize}} = new_int_file(Tmp, none),
scan_f_read(<<>>, In, Out, File, FSz, Tmp, ?MAX_CHUNK_SIZE, 0, 0).
@@ -758,7 +758,7 @@ mf_int_chunk(Handle, {FileNo, Pos}, Bin, N) ->
NFileNo = inc(FileNo, Handle#handle.maxF),
case catch int_open(FName, true, read_only, any) of
{error, _Reason} ->
- error_logger:info_msg("disk_log: chunk error. File ~p missing.\n\n",
+ error_logger:info_msg("disk_log: chunk error. File ~tp missing.\n\n",
[FName]),
mf_int_chunk(Handle, {NFileNo, 0}, [], N);
{ok, {_Alloc, FdC, _HeadSize, _FileSize}} ->
@@ -786,7 +786,7 @@ mf_int_chunk_read_only(Handle, {FileNo, Pos}, Bin, N) ->
NFileNo = inc(FileNo, Handle#handle.maxF),
case catch int_open(FName, true, read_only, any) of
{error, _Reason} ->
- error_logger:info_msg("disk_log: chunk error. File ~p missing.\n\n",
+ error_logger:info_msg("disk_log: chunk error. File ~tp missing.\n\n",
[FName]),
mf_int_chunk_read_only(Handle, {NFileNo, 0}, [], N);
{ok, {_Alloc, FdC, _HeadSize, _FileSize}} ->
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index e3511988a6..bbb212cebe 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -115,7 +115,8 @@ make_this_flags(RequestType, OtherNode) ->
?DFLAG_NEW_FLOATS bor
?DFLAG_UNICODE_IO bor
?DFLAG_DIST_HDR_ATOM_CACHE bor
- ?DFLAG_SMALL_ATOM_TAGS).
+ ?DFLAG_SMALL_ATOM_TAGS bor
+ ?DFLAG_UTF8_ATOMS).
handshake_other_started(#hs_data{request_type=ReqType}=HSData0) ->
{PreOtherFlags,Node,Version} = recv_name(HSData0),
diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl
index f8bc5f499c..a3aa1f1dcf 100644
--- a/lib/kernel/src/error_handler.erl
+++ b/lib/kernel/src/error_handler.erl
@@ -23,10 +23,12 @@
%% "error_handler: add no_native compiler directive"
-compile(no_native).
-%% A simple error handler.
+%% Callbacks called from the run-time system.
+-export([undefined_function/3,undefined_lambda/3,breakpoint/3]).
--export([undefined_function/3, undefined_lambda/3, stub_function/3,
- breakpoint/3]).
+%% Exported utility functions.
+-export([raise_undef_exception/3]).
+-export([stub_function/3]).
-spec undefined_function(Module, Function, Args) ->
any() when
@@ -41,12 +43,7 @@ undefined_function(Module, Func, Args) ->
true ->
apply(Module, Func, Args);
false ->
- case check_inheritance(Module, Args) of
- {value, Base, Args1} ->
- apply(Base, Func, Args1);
- none ->
- crash(Module, Func, Args)
- end
+ call_undefined_function_handler(Module, Func, Args)
end;
{module, _} ->
crash(Module, Func, Args);
@@ -77,6 +74,14 @@ undefined_lambda(Module, Fun, Args) ->
breakpoint(Module, Func, Args) ->
(int()):eval(Module, Func, Args).
+-spec raise_undef_exception(Module, Function, Args) -> no_return() when
+ Module :: atom(),
+ Function :: atom(),
+ Args :: list().
+
+raise_undef_exception(Module, Func, Args) ->
+ crash({Module,Func,Args,[]}).
+
%% Used to make the call to the 'int' module a "weak" one, to avoid
%% building strong components in xref or dialyzer.
@@ -130,27 +135,11 @@ ensure_loaded(Module) ->
stub_function(Mod, Func, Args) ->
exit({undef,[{Mod,Func,Args,[]}]}).
-check_inheritance(Module, Args) ->
- Attrs = erlang:get_module_info(Module, attributes),
- case lists:keyfind(extends, 1, Attrs) of
- {extends, [Base]} when is_atom(Base), Base =/= Module ->
- %% This is just a heuristic for detecting abstract modules
- %% with inheritance so they can be handled; it would be
- %% much better to do it in the emulator runtime
- case lists:keyfind(abstract, 1, Attrs) of
- {abstract, [true]} ->
- case lists:reverse(Args) of
- [M|Rs] when tuple_size(M) > 1,
- element(1,M) =:= Module,
- tuple_size(element(2,M)) > 0,
- is_atom(element(1,element(2,M))) ->
- {value, Base, lists:reverse(Rs, [element(2,M)])};
- _ ->
- {value, Base, Args}
- end;
- _ ->
- {value, Base, Args}
- end;
- _ ->
- none
+call_undefined_function_handler(Module, Func, Args) ->
+ Handler = '$handle_undefined_function',
+ case erlang:function_exported(Module, Handler, 2) of
+ false ->
+ crash(Module, Func, Args);
+ true ->
+ Module:Handler(Func, Args)
end.
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 16f2dde464..70c4583ad2 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -148,7 +148,7 @@ format_error({Line, ?MODULE, {Reason, Stacktrace}}) ->
io_lib:format("~w: evaluation failed with reason ~w and stacktrace ~w",
[Line, Reason, Stacktrace]);
format_error({Line, Mod, Reason}) ->
- io_lib:format("~w: ~s", [Line, Mod:format_error(Reason)]);
+ io_lib:format("~w: ~ts", [Line, Mod:format_error(Reason)]);
format_error(badarg) ->
"bad argument";
format_error(system_limit) ->
@@ -591,7 +591,7 @@ pread(_, _, _) ->
write(File, Bytes) when (is_pid(File) orelse is_atom(File)) ->
case make_binary(Bytes) of
Bin when is_binary(Bin) ->
- io:request(File, {put_chars,Bin});
+ io:request(File, {put_chars,latin1,Bin});
Error ->
Error
end;
@@ -1345,7 +1345,7 @@ eval_stream(Fd, Handling, Bs) ->
eval_stream(Fd, Handling, 1, undefined, [], Bs).
eval_stream(Fd, H, Line, Last, E, Bs) ->
- eval_stream2(io:parse_erl_exprs(Fd, '', Line), Fd, H, Last, E, Bs).
+ eval_stream2(io:parse_erl_exprs(Fd, '', Line, [unicode]), Fd, H, Last, E, Bs).
eval_stream2({ok,Form,EndLine}, Fd, H, Last, E, Bs0) ->
try erl_eval:exprs(Form, Bs0) of
diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl
index 4d2e31a429..ff835e1047 100644
--- a/lib/kernel/src/group.erl
+++ b/lib/kernel/src/group.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -227,7 +227,7 @@ io_request({put_chars,latin1,Chars}, Drv, Buf) ->
send_drv(Drv, {put_chars, unicode,Binary}),
{ok,ok,Buf};
_ ->
- {error,{error,{put_chars,Chars}},Buf}
+ {error,{error,{put_chars,latin1,Chars}},Buf}
end;
io_request({put_chars,latin1,M,F,As}, Drv, Buf) ->
case catch apply(M, F, As) of
@@ -446,7 +446,6 @@ get_chars_loop(Pbs, M, F, Xa, Drv, Buf0, State, Encoding) ->
end.
get_chars_apply(Pbs, M, F, Xa, Drv, Buf, State0, Line, Encoding) ->
- id(M,F),
case catch M:F(State0, cast(Line,get(read_mode), Encoding), Encoding, Xa) of
{stop,Result,Rest} ->
{ok,Result,append(Rest, Buf, Encoding)};
@@ -456,8 +455,6 @@ get_chars_apply(Pbs, M, F, Xa, Drv, Buf, State0, Line, Encoding) ->
get_chars_loop(Pbs, M, F, Xa, Drv, Buf, State1, Encoding)
end.
-id(M,F) ->
- {M,F}.
%% Convert error code to make it look as before
err_func(io_lib, get_until, {_,F,_}) ->
F;
@@ -515,6 +512,27 @@ get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding)
Drv,
Ls, Encoding)
end;
+%% ^R = backward search, ^S = forward search.
+%% Search is tricky to implement and does a lot of back-and-forth
+%% work with edlin.erl (from stdlib). Edlin takes care of writing
+%% and handling lines and escape characters to get out of search,
+%% whereas this module does the actual searching and appending to lines.
+%% Erlang's shell wasn't exactly meant to traverse the wall between
+%% line and line stack, so we at least restrict it by introducing
+%% new modes: search, search_quit, search_found. These are added to
+%% the regular ones (none, meta_left_sq_bracket) and handle special
+%% cases of history search.
+get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls, Encoding)
+ when ((Mode =:= none) and (Char =:= $\^R)) ->
+ send_drv_reqs(Drv, Rs),
+ %% drop current line, move to search mode. We store the current
+ %% prompt ('N>') and substitute it with the search prompt.
+ send_drv_reqs(Drv, edlin:erase_line(Cont)),
+ put(search_quit_prompt, edlin:prompt(Cont)),
+ Pbs = prompt_bytes("(search)`': ", Encoding),
+ {more_chars,Ncont,Nrs} = edlin:start(Pbs, search),
+ send_drv_reqs(Drv, Nrs),
+ get_line1(edlin:edit_line1(Cs, Ncont), Drv, Ls, Encoding);
get_line1({expand, Before, Cs0, Cont,Rs}, Drv, Ls0, Encoding) ->
send_drv_reqs(Drv, Rs),
ExpandFun = get(expand_fun),
@@ -535,8 +553,59 @@ get_line1({undefined,_Char,Cs,Cont,Rs}, Drv, Ls, Encoding) ->
send_drv_reqs(Drv, Rs),
send_drv(Drv, beep),
get_line1(edlin:edit_line(Cs, Cont), Drv, Ls, Encoding);
+%% The search item was found and accepted (new line entered on the exact
+%% result found)
+get_line1({_What,Cont={line,_Prompt,_Chars,search_found},Rs}, Drv, Ls0, Encoding) ->
+ Line = edlin:current_line(Cont),
+ %% this may create duplicate entries.
+ Ls = save_line(new_stack(get_lines(Ls0)), Line),
+ get_line1({done, Line, "", Rs}, Drv, Ls, Encoding);
+%% The search mode has been exited, but the user wants to remain in line
+%% editing mode wherever that was, but editing the search result.
+get_line1({What,Cont={line,_Prompt,_Chars,search_quit},Rs}, Drv, Ls, Encoding) ->
+ Line = edlin:current_chars(Cont),
+ %% Load back the old prompt with the correct line number.
+ case get(search_quit_prompt) of
+ undefined -> % should not happen. Fallback.
+ LsFallback = save_line(new_stack(get_lines(Ls)), Line),
+ get_line1({done, "\n", Line, Rs}, Drv, LsFallback, Encoding);
+ Prompt -> % redraw the line and keep going with the same stack position
+ NCont = {line,Prompt,{lists:reverse(Line),[]},none},
+ send_drv_reqs(Drv, Rs),
+ send_drv_reqs(Drv, edlin:erase_line(Cont)),
+ send_drv_reqs(Drv, edlin:redraw_line(NCont)),
+ get_line1({What, NCont ,[]}, Drv, pad_stack(Ls), Encoding)
+ end;
+%% Search mode is entered.
+get_line1({What,{line,Prompt,{RevCmd0,_Aft},search},Rs},
+ Drv, Ls0, Encoding) ->
+ send_drv_reqs(Drv, Rs),
+ %% Figure out search direction. ^S and ^R are returned through edlin
+ %% whenever we received a search while being already in search mode.
+ {Search, Ls1, RevCmd} = case RevCmd0 of
+ [$\^S|RevCmd1] ->
+ {fun search_down_stack/2, Ls0, RevCmd1};
+ [$\^R|RevCmd1] ->
+ {fun search_up_stack/2, Ls0, RevCmd1};
+ _ -> % new search, rewind stack for a proper search.
+ {fun search_up_stack/2, new_stack(get_lines(Ls0)), RevCmd0}
+ end,
+ Cmd = lists:reverse(RevCmd),
+ {Ls, NewStack} = case Search(Ls1, Cmd) of
+ {none, Ls2} ->
+ send_drv(Drv, beep),
+ {Ls2, {RevCmd, "': "}};
+ {Line, Ls2} -> % found. Complete the output edlin couldn't have done.
+ send_drv_reqs(Drv, [{put_chars, Encoding, Line}]),
+ {Ls2, {RevCmd, "': "++Line}}
+ end,
+ Cont = {line,Prompt,NewStack,search},
+ more_data(What, Cont, Drv, Ls, Encoding);
get_line1({What,Cont0,Rs}, Drv, Ls, Encoding) ->
send_drv_reqs(Drv, Rs),
+ more_data(What, Cont0, Drv, Ls, Encoding).
+
+more_data(What, Cont0, Drv, Ls, Encoding) ->
receive
{Drv,{data,Cs}} ->
get_line1(edlin:edit_line(Cs, Cont0), Drv, Ls, Encoding);
@@ -557,7 +626,6 @@ get_line1({What,Cont0,Rs}, Drv, Ls, Encoding) ->
get_line1(edlin:edit_line([], Cont0), Drv, Ls, Encoding)
end.
-
get_line_echo_off(Chars, Pbs, Drv) ->
send_drv_reqs(Drv, [{put_chars, unicode,Pbs}]),
get_line_echo_off1(edit_line(Chars,[]), Drv).
@@ -632,12 +700,46 @@ save_line({stack, U, {}, []}, Line) ->
save_line({stack, U, _L, D}, Line) ->
{stack, U, Line, D}.
-get_lines({stack, U, {}, []}) ->
+get_lines(Ls) -> get_all_lines(Ls).
+%get_lines({stack, U, {}, []}) ->
+% U;
+%get_lines({stack, U, {}, D}) ->
+% tl(lists:reverse(D, U));
+%get_lines({stack, U, L, D}) ->
+% get_lines({stack, U, {}, [L|D]}).
+
+%% There's a funny behaviour whenever the line stack doesn't have a "\n"
+%% at its end -- get_lines() seemed to work on the assumption it *will* be
+%% there, but the manipulations done with search history do not require it.
+%%
+%% It is an assumption because the function was built with either the full
+%% stack being on the 'Up' side (we're on the new line) where it isn't
+%% stripped. The only other case when it isn't on the 'Up' side is when
+%% someone has used the up/down arrows (or ^P and ^N) to navigate lines,
+%% in which case, a line with only a \n is stored at the end of the stack
+%% (the \n is returned by edlin:current_line/1).
+%%
+%% get_all_lines works the same as get_lines, but only strips the trailing
+%% character if it's a linebreak. Otherwise it's kept the same. This is
+%% because traversing the stack due to search history will *not* insert
+%% said empty line in the stack at the same time as other commands do,
+%% and thus it should not always be stripped unless we know a new line
+%% is the last entry.
+get_all_lines({stack, U, {}, []}) ->
U;
-get_lines({stack, U, {}, D}) ->
- tl(lists:reverse(D, U));
-get_lines({stack, U, L, D}) ->
- get_lines({stack, U, {}, [L|D]}).
+get_all_lines({stack, U, {}, D}) ->
+ case lists:reverse(D, U) of
+ ["\n"|Lines] -> Lines;
+ Lines -> Lines
+ end;
+get_all_lines({stack, U, L, D}) ->
+ get_all_lines({stack, U, {}, [L|D]}).
+
+%% For the same reason as above, though, we need to expand the stack
+%% in some cases to make sure we play nice with up/down arrows. We need
+%% to insert newlines, but not always.
+pad_stack({stack, U, L, D}) ->
+ {stack, U, L, D++["\n"]}.
save_line_buffer("\n", Lines) ->
save_line_buffer(Lines);
@@ -649,6 +751,27 @@ save_line_buffer(Line, Lines) ->
save_line_buffer(Lines) ->
put(line_buffer, Lines).
+search_up_stack(Stack, Substr) ->
+ case up_stack(Stack) of
+ {none,NewStack} -> {none,NewStack};
+ {L, NewStack} ->
+ case string:str(L, Substr) of
+ 0 -> search_up_stack(NewStack, Substr);
+ _ -> {string:strip(L,right,$\n), NewStack}
+ end
+ end.
+
+search_down_stack(Stack, Substr) ->
+ case down_stack(Stack) of
+ {none,NewStack} -> {none,NewStack};
+ {L, NewStack} ->
+ case string:str(L, Substr) of
+ 0 -> search_down_stack(NewStack, Substr);
+ _ -> {string:strip(L,right,$\n), NewStack}
+ end
+ end.
+
+
%% This is get_line without line editing (except for backspace) and
%% without echo.
get_password_line(Chars, Drv) ->
@@ -687,7 +810,7 @@ edit_password([$\177|Cs],[_|Chars]) ->%% is backspace enough?
edit_password([Char|Cs],Chars) ->
edit_password(Cs,[Char|Chars]).
-%% prompt_bytes(Prompt)
+%% prompt_bytes(Prompt, Encoding)
%% Return a flat list of characters for the Prompt.
prompt_bytes(Prompt, Encoding) ->
lists:flatten(io_lib:format_prompt(Prompt, Encoding)).
diff --git a/lib/kernel/src/inet_config.erl b/lib/kernel/src/inet_config.erl
index 526baca335..aa19bd4779 100644
--- a/lib/kernel/src/inet_config.erl
+++ b/lib/kernel/src/inet_config.erl
@@ -104,7 +104,7 @@ init() ->
%% Add inetrc config entries
case inet_db:add_rc_list(CfgList) of
ok -> ok;
- _ -> error("syntax error in ~s~n", [RcFile])
+ _ -> error("syntax error in ~ts~n", [RcFile])
end,
%% Set up a resolver configuration file for inet_res,
@@ -266,10 +266,10 @@ load_resolv(File, Func) ->
{ok, Ls} ->
inet_db:add_rc_list(Ls);
{error, Reason} ->
- error("parse error in file ~s: ~p", [File, Reason])
+ error("parse error in file ~ts: ~p", [File, Reason])
end;
Error ->
- warning("file not found ~s: ~p~n", [File, Error])
+ warning("file not found ~ts: ~p~n", [File, Error])
end.
%%
@@ -285,12 +285,12 @@ load_hosts(File,Os) ->
inet_db:add_host(IP, [Name|Aliases]) end,
Ls);
{error, Reason} ->
- error("parse error in file ~s: ~p", [File, Reason])
+ error("parse error in file ~ts: ~p", [File, Reason])
end;
Error ->
case Os of
unix ->
- error("file not found ~s: ~p~n", [File, Error]);
+ error("file not found ~ts: ~p~n", [File, Error]);
_ ->
%% for windows or nt the hosts file is not always there
%% and we don't require it
@@ -462,11 +462,11 @@ get_rc(File) ->
{ok,Ls} ->
Ls;
_Error ->
- error("parse error in ~s~n", [File]),
+ error("parse error in ~ts~n", [File]),
error
end;
_Error ->
- error("file ~s not found~n", [File]),
+ error("file ~ts not found~n", [File]),
error
end.
@@ -495,8 +495,12 @@ warning(Fmt, Args) ->
%% Ignore leading whitespace before a token (due to bug in erl_scan) !
%%
parse_inetrc(Bin) ->
- Str = binary_to_list(Bin) ++ "\n",
- parse_inetrc(Str, 1, []).
+ case file_binary_to_list(Bin) of
+ {ok, String} ->
+ parse_inetrc(String ++ "\n", 1, []);
+ error ->
+ {error, 'bad_encoding'}
+ end.
parse_inetrc_skip_line([], _Line, Ack) ->
{ok, reverse(Ack)};
@@ -535,3 +539,16 @@ parse_inetrc(Str, Line, Ack) ->
{more, _} -> %% Bug in erl_scan !!
{error, {'scan_inetrc', {eof, Line}}}
end.
+
+file_binary_to_list(Bin) ->
+ Enc = case epp:read_encoding_from_binary(Bin) of
+ none -> epp:default_encoding();
+ Encoding -> Encoding
+ end,
+ case catch unicode:characters_to_list(Bin, Enc) of
+ String when is_list(String) ->
+ {ok, String};
+ _ ->
+ error
+ end.
+
diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl
index 3551e701b6..a7ac6ce040 100644
--- a/lib/kernel/src/inet_parse.erl
+++ b/lib/kernel/src/inet_parse.erl
@@ -464,7 +464,7 @@ strict_address(Cs) when is_list(Cs) ->
_ ->
ipv6strict_address(Cs)
end;
-strict_address(Cs) ->
+strict_address(_) ->
{error, einval}.
%%
diff --git a/lib/kernel/src/kernel_config.erl b/lib/kernel/src/kernel_config.erl
index b1daf655c9..1649901ba7 100644
--- a/lib/kernel/src/kernel_config.erl
+++ b/lib/kernel/src/kernel_config.erl
@@ -93,7 +93,7 @@ code_change(_OldVsn, State, _Extra) ->
sync_nodes() ->
case catch get_sync_data() of
{error, Reason} = Error ->
- error_logger:format("~p", [Reason]),
+ error_logger:format("~tp", [Reason]),
Error;
{infinity, MandatoryNodes, OptionalNodes} ->
case wait_nodes(MandatoryNodes, OptionalNodes) of
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index 0d59e7af67..fd59205582 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -1340,20 +1340,20 @@ start_protos(Name, [Proto | Ps], Node, Ls) ->
start_protos(Name, Ps, Node, Ls)
end;
{'EXIT', {undef,_}} ->
- error_logger:info_msg("Protocol: ~p: not supported~n", [Proto]),
+ error_logger:info_msg("Protocol: ~tp: not supported~n", [Proto]),
start_protos(Name,Ps, Node, Ls);
{'EXIT', Reason} ->
- error_logger:info_msg("Protocol: ~p: register error: ~p~n",
+ error_logger:info_msg("Protocol: ~tp: register error: ~tp~n",
[Proto, Reason]),
start_protos(Name,Ps, Node, Ls);
{error, duplicate_name} ->
- error_logger:info_msg("Protocol: ~p: the name " ++
+ error_logger:info_msg("Protocol: ~tp: the name " ++
atom_to_list(Node) ++
" seems to be in use by another Erlang node",
[Proto]),
start_protos(Name,Ps, Node, Ls);
{error, Reason} ->
- error_logger:info_msg("Protocol: ~p: register/listen error: ~p~n",
+ error_logger:info_msg("Protocol: ~tp: register/listen error: ~tp~n",
[Proto, Reason]),
start_protos(Name,Ps, Node, Ls)
end;
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index e20a2434b4..c08f5af35a 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -334,7 +334,7 @@ mk_cmd(Cmd) when is_atom(Cmd) -> % backward comp.
mk_cmd(Cmd) ->
%% We insert a new line after the command, in case the command
%% contains a comment character.
- io_lib:format("(~s\n) </dev/null; echo \"\^D\"\n", [Cmd]).
+ io_lib:format("(~ts\n) </dev/null; echo \"\^D\"\n", [Cmd]).
validate(Atom) when is_atom(Atom) ->
diff --git a/lib/kernel/src/user.erl b/lib/kernel/src/user.erl
index d6449d9e5e..c897d46bc2 100644
--- a/lib/kernel/src/user.erl
+++ b/lib/kernel/src/user.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -17,7 +17,7 @@
%% %CopyrightEnd%
%%
-module(user).
--compile( [ inline, { inline_size, 100 } ] ).
+-compile(inline).
%% Basic standard i/o server for user interface port.
@@ -184,38 +184,52 @@ do_io_request(Req, From, ReplyAs, Port, Q0) ->
io_reply(From, ReplyAs, Reply),
Q1;
{exit,What} ->
- send_port(Port, close),
+ ok = send_port(Port, close),
exit(What)
end.
%% New in R13B
%% Encoding option (unicode/latin1)
io_request({put_chars,unicode,Chars}, Port, Q) -> % Binary new in R9C
- put_chars(wrap_characters_to_binary(Chars,unicode, get(encoding)), Port, Q);
+ case wrap_characters_to_binary(Chars, unicode, get(encoding)) of
+ error ->
+ {error,{error,put_chars},Q};
+ Bin ->
+ put_chars(Bin, Port, Q)
+ end;
io_request({put_chars,unicode,Mod,Func,Args}, Port, Q) ->
- Result = case catch apply(Mod,Func,Args) of
- Data when is_list(Data); is_binary(Data) ->
- wrap_characters_to_binary(Data,unicode,get(encoding));
- Undef ->
- Undef
- end,
- put_chars(Result, Port, Q);
+ 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, Q);
+ error ->
+ {error,{error,put_chars},Q}
+ end;
+ Undef ->
+ put_chars(Undef, Port, Q)
+ end;
io_request({put_chars,latin1,Chars}, Port, Q) -> % Binary new in R9C
- Data = case get(encoding) of
- unicode ->
- unicode:characters_to_binary(Chars,latin1,unicode);
- latin1 ->
- erlang:iolist_to_binary(Chars)
- end,
- put_chars(Data, Port, Q);
+ case catch unicode:characters_to_binary(Chars, latin1, get(encoding)) of
+ Data when is_binary(Data) ->
+ put_chars(Data, Port, Q);
+ _ ->
+ {error,{error,put_chars},Q}
+ end;
io_request({put_chars,latin1,Mod,Func,Args}, Port, Q) ->
- Result = case catch apply(Mod,Func,Args) of
- Data when is_list(Data); is_binary(Data) ->
- unicode:characters_to_binary(Data,latin1,get(encoding));
- Undef ->
- Undef
- end,
- put_chars(Result, Port, Q);
+ 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, Q);
+ _ ->
+ {error,{error,put_chars},Q}
+ end;
+ Undef ->
+ put_chars(Undef, Port, Q)
+ end;
io_request({get_chars,Enc,Prompt,N}, Port, Q) -> % New in R9C
get_chars(Prompt, io_lib, collect_chars, N, Port, Q, Enc);
io_request({get_line,Enc,Prompt}, Port, Q) ->
@@ -285,7 +299,8 @@ put_port(List, Port) ->
%% send_port(Port, Command)
send_port(Port, Command) ->
- Port ! {self(),Command}.
+ Port ! {self(),Command},
+ ok.
%% io_reply(From, ReplyAs, Reply)
%% The function for sending i/o command acknowledgement.
@@ -296,7 +311,7 @@ io_reply(From, ReplyAs, Reply) ->
%% put_chars
put_chars(Chars, Port, Q) when is_binary(Chars) ->
- put_port(Chars, Port),
+ ok = put_port(Chars, Port),
{ok,ok,Q};
put_chars(Chars, Port, Q) ->
case catch list_to_binary(Chars) of
@@ -360,16 +375,20 @@ getopts(_Port,Q) ->
Bin = {binary, get(read_mode) =:= binary},
Uni = {encoding, get(encoding)},
{ok,[Bin,Uni],Q}.
-
get_line_bin(Prompt,Port,Q, Enc) ->
- prompt(Port, Prompt),
- case {get(eof),queue:is_empty(Q)} of
- {true,true} ->
- {ok,eof,Q};
- _ ->
- get_line(Prompt,Port, Q, [], Enc)
+ case prompt(Port, Prompt) of
+ error ->
+ {error,{error,get_line},Q};
+ ok ->
+ case {get(eof),queue:is_empty(Q)} of
+ {true,true} ->
+ {ok,eof,Q};
+ _ ->
+ get_line(Prompt,Port, Q, [], Enc)
+ end
end.
+
get_line(Prompt, Port, Q, Acc, Enc) ->
case queue:is_empty(Q) of
true ->
@@ -386,8 +405,12 @@ get_line(Prompt, Port, Q, Acc, Enc) ->
get_line(Prompt, Port, Q, Acc, Enc);
{io_request,From,ReplyAs,Request} when is_pid(From) ->
do_io_request(Request, From, ReplyAs, Port, queue:new()),
- prompt(Port, Prompt),
- get_line(Prompt, Port, Q, Acc, Enc);
+ case prompt(Port, Prompt) of
+ error ->
+ {error,{error,get_line},Q};
+ ok ->
+ get_line(Prompt, Port, Q, Acc, Enc)
+ end;
{'EXIT',From,What} when node(From) =:= node() ->
{exit,What}
end;
@@ -420,6 +443,7 @@ srch(<<X:8,_/binary>>,X,N) ->
{match,[{N,1}]};
srch(<<_:8,T/binary>>,X,N) ->
srch(T,X,N+1).
+
get_line_doit(Prompt, Port, Q, Accu, Enc) ->
case queue:is_empty(Q) of
true ->
@@ -569,12 +593,16 @@ binrev(L, T) ->
%% Entry function.
get_chars(Prompt, M, F, Xa, Port, Q, Enc) ->
- prompt(Port, Prompt),
- case {get(eof),queue:is_empty(Q)} of
- {true,true} ->
- {ok,eof,Q};
- _ ->
- get_chars(Prompt, M, F, Xa, Port, Q, start, Enc)
+ case prompt(Port, Prompt) of
+ error ->
+ {error,{error,get_chars},Q};
+ ok ->
+ case {get(eof),queue:is_empty(Q)} of
+ {true,true} ->
+ {ok,eof,Q};
+ _ ->
+ get_chars(Prompt, M, F, Xa, Port, Q, start, Enc)
+ end
end.
%% First loop. Wait for port data. Respond to output requests.
@@ -608,8 +636,12 @@ get_chars(Prompt, M, F, Xa, Port, Q, State, Enc) ->
get_chars_req(Prompt, M, F, XtraArg, Port, Q, State,
Req, From, ReplyAs, Enc) ->
do_io_request(Req, From, ReplyAs, Port, queue:new()), %Keep Q over this call
- prompt(Port, Prompt),
- get_chars(Prompt, M, F, XtraArg, Port, Q, State, Enc).
+ case prompt(Port, Prompt) of
+ error ->
+ {error,{error,get_chars},Q};
+ ok ->
+ get_chars(Prompt, M, F, XtraArg, Port, Q, State, Enc)
+ end.
%% Second loop. Pass data to client as long as it wants more.
%% A ^G in data interrupts loop if 'noshell' is not undefined.
@@ -671,12 +703,15 @@ get_chars_more(State, M, F, Xa, Port, Q, Enc) ->
%% common case, reduces execution time by 20%
prompt(_Port, '') -> ok;
-
prompt(Port, Prompt) ->
Encoding = get(encoding),
- put_port(wrap_characters_to_binary(io_lib:format_prompt(Prompt, Encoding),
- unicode, Encoding),
- Port).
+ PromptString = io_lib:format_prompt(Prompt, Encoding),
+ case wrap_characters_to_binary(PromptString, unicode, Encoding) of
+ Bin when is_binary(Bin) ->
+ put_port(Bin, Port);
+ error ->
+ error
+ end.
%% Convert error code to make it look as before
err_func(io_lib, get_until, {_,F,_}) ->
@@ -753,21 +788,30 @@ cast(Data, list, unicode, unicode) when is_binary(Data); is_list(Data) ->
_ -> exit({no_translation, unicode, unicode})
end.
-wrap_characters_to_binary(Chars,unicode,latin1) ->
- case unicode:characters_to_binary(Chars,unicode,latin1) of
- {error,_,_} ->
- list_to_binary(
- [ case X of
- High when High > 255 ->
- ["\\x{",erlang:integer_to_list(X, 16),$}];
- Low ->
- Low
- end || X <- unicode:characters_to_list(Chars,unicode) ]);
- Bin ->
- Bin
+wrap_characters_to_binary(Chars, unicode, latin1) ->
+ case catch unicode:characters_to_binary(Chars, unicode, latin1) of
+ Bin when is_binary(Bin) ->
+ Bin;
+ _ ->
+ case catch unicode:characters_to_list(Chars, unicode) of
+ L when is_list(L) ->
+ list_to_binary(
+ [ case X of
+ High when High > 255 ->
+ ["\\x{",erlang:integer_to_list(X, 16),$}];
+ Low ->
+ Low
+ end || X <- L ]);
+ _ ->
+ error
+ end
end;
-
-wrap_characters_to_binary(Bin,From,From) when is_binary(Bin) ->
+wrap_characters_to_binary(Bin, From, From) when is_binary(Bin) ->
Bin;
-wrap_characters_to_binary(Chars,From,To) ->
- unicode:characters_to_binary(Chars,From,To).
+wrap_characters_to_binary(Chars, From, To) ->
+ case catch unicode:characters_to_binary(Chars, From, To) of
+ Bin when is_binary(Bin) ->
+ Bin;
+ _ ->
+ error
+ end.
diff --git a/lib/kernel/src/user_drv.erl b/lib/kernel/src/user_drv.erl
index 8f2ca28f56..47ece5d39e 100644
--- a/lib/kernel/src/user_drv.erl
+++ b/lib/kernel/src/user_drv.erl
@@ -129,7 +129,7 @@ server1(Iport, Oport, Shell) ->
Gr = gr_add_cur(Gr1, Curr, Shell1),
%% Print some information.
io_request({put_chars, unicode,
- flatten(io_lib:format("~s\n",
+ flatten(io_lib:format("~ts\n",
[erlang:system_info(system_version)]))},
Iport, Oport),
%% Enter the server loop.
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 7fd3afe93c..8d2d55777b 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -48,6 +48,7 @@ MODULES= \
erl_distribution_SUITE \
erl_distribution_wb_SUITE \
erl_prim_loader_SUITE \
+ error_handler_SUITE \
error_logger_SUITE \
error_logger_warn_SUITE \
file_SUITE \
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index f469a0af98..2ca8840e1f 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -27,7 +27,7 @@
otp_1586/1, otp_2078/1, otp_2012/1, otp_2718/1, otp_2973/1,
otp_3002/1, otp_3184/1, otp_4066/1, otp_4227/1, otp_5363/1,
otp_5606/1,
- start_phases/1, get_key/1,
+ start_phases/1, get_key/1, get_env/1,
permit_false_start_local/1, permit_false_start_dist/1, script_start/1,
nodedown_start/1, init2973/0, loop2973/0, loop5606/1]).
@@ -49,7 +49,7 @@ all() ->
[failover, failover_comp, permissions, load,
load_use_cache, {group, reported_bugs}, start_phases,
script_start, nodedown_start, permit_false_start_local,
- permit_false_start_dist, get_key,
+ permit_false_start_dist, get_key, get_env,
{group, distr_changed}, config_change, shutdown_func, shutdown_timeout].
groups() ->
@@ -1503,6 +1503,15 @@ loop5606(Pid) ->
Pid ! {self(), Res}
end.
+get_env(suite) -> [];
+get_env(doc) ->
+ ["Tests get_env/* functions"];
+get_env(Conf) when is_list(Conf) ->
+ {ok, _} = application:get_env(kernel, error_logger),
+ undefined = application:get_env(undefined_app, a),
+ undefined = application:get_env(kernel, error_logger_xyz),
+ default = application:get_env(kernel, error_logger_xyz, default),
+ ok.
%%-----------------------------------------------------------------
%% Should be started in a CC view with:
diff --git a/lib/kernel/test/error_handler_SUITE.erl b/lib/kernel/test/error_handler_SUITE.erl
new file mode 100644
index 0000000000..2a86d39b74
--- /dev/null
+++ b/lib/kernel/test/error_handler_SUITE.erl
@@ -0,0 +1,68 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+-module(error_handler_SUITE).
+
+-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ undefined_function_handler/1]).
+
+%% Callback from error_handler.
+-export(['$handle_undefined_function'/2]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [undefined_function_handler].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+%%-----------------------------------------------------------------
+
+undefined_function_handler(_) ->
+ 42 = ?MODULE:forty_two(),
+ 42 = (id(?MODULE)):forty_two(),
+ {ok,{a,b,c}} = ?MODULE:one_arg({a,b,c}),
+ {ok,{a,b,c}} = (id(?MODULE)):one_arg({a,b,c}),
+ {'EXIT',{undef,[{?MODULE,undef_and_not_handled,[[1,2,3]],[]}|_]}} =
+ (catch ?MODULE:undef_and_not_handled([1,2,3])),
+ ok.
+
+'$handle_undefined_function'(forty_two, []) ->
+ 42;
+'$handle_undefined_function'(one_arg, [Arg]) ->
+ {ok,Arg};
+'$handle_undefined_function'(Func, Args) ->
+ error_handler:raise_undef_exception(?MODULE, Func, Args).
+
+id(I) ->
+ I.
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 914f0d6127..ac991b1111 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -60,7 +60,8 @@
-export([ read_not_really_compressed/1,
read_compressed_cooked/1, read_compressed_cooked_binary/1,
read_cooked_tar_problem/1,
- write_compressed/1, compress_errors/1, catenated_gzips/1]).
+ write_compressed/1, compress_errors/1, catenated_gzips/1,
+ compress_async_crash/1]).
-export([ make_link/1, read_link_info_for_non_link/1, symlinks/1]).
@@ -135,7 +136,8 @@ groups() ->
{compression, [],
[read_compressed_cooked, read_compressed_cooked_binary,
read_cooked_tar_problem, read_not_really_compressed,
- write_compressed, compress_errors, catenated_gzips]},
+ write_compressed, compress_errors, catenated_gzips,
+ compress_async_crash]},
{links, [],
[make_link, read_link_info_for_non_link, symlinks]}].
@@ -230,7 +232,7 @@ mini_server(Parent) ->
receive
die ->
ok;
- {io_request,From,To,{put_chars,Data}} ->
+ {io_request,From,To,{put_chars,_Encoding,Data}} ->
Parent ! {io_request,From,To,{put_chars,Data}},
From ! {io_reply, To, ok},
mini_server(Parent);
@@ -2312,6 +2314,57 @@ compress_errors(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+compress_async_crash(suite) -> [];
+compress_async_crash(doc) -> [];
+compress_async_crash(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line Path = filename:join(DataDir, "test.gz"),
+ ExpectedData = <<"qwerty">>,
+
+ ?line _ = ?FILE_MODULE:delete(Path),
+ ?line {ok, Fd} = ?FILE_MODULE:open(Path, [write, binary, compressed]),
+ ?line ok = ?FILE_MODULE:write(Fd, ExpectedData),
+ ?line ok = ?FILE_MODULE:close(Fd),
+
+ % Test that when using async thread pool, the emulator doesn't crash
+ % when the efile port driver is stopped while a compressed file operation
+ % is in progress (being carried by an async thread).
+ ?line ok = compress_async_crash_loop(10000, Path, ExpectedData),
+ ?line ok = ?FILE_MODULE:delete(Path),
+ ok.
+
+compress_async_crash_loop(0, _Path, _ExpectedData) ->
+ ok;
+compress_async_crash_loop(N, Path, ExpectedData) ->
+ Parent = self(),
+ {Pid, Ref} = spawn_monitor(
+ fun() ->
+ ?line {ok, Fd} = ?FILE_MODULE:open(
+ Path, [read, compressed, raw, binary]),
+ Len = byte_size(ExpectedData),
+ Parent ! {self(), continue},
+ ?line {ok, ExpectedData} = ?FILE_MODULE:read(Fd, Len),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ receive foobar -> ok end
+ end),
+ receive
+ {Pid, continue} ->
+ exit(Pid, shutdown),
+ receive
+ {'DOWN', Ref, _, _, Reason} ->
+ ?line shutdown = Reason
+ end;
+ {'DOWN', Ref, _, _, Reason2} ->
+ test_server:fail({worker_exited, Reason2})
+ after 60000 ->
+ exit(Pid, shutdown),
+ erlang:demonitor(Ref, [flush]),
+ test_server:fail(worker_timeout)
+ end,
+ compress_async_crash_loop(N - 1, Path, ExpectedData).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
altname(doc) ->
"Test the file:altname/1 function";
altname(suite) ->
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 5d45b91ee5..a72e76f813 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -42,12 +42,13 @@
killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1,
several_accepts_in_one_go/1, accept_system_limit/1,
active_once_closed/1, send_timeout/1, send_timeout_active/1,
- otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1,
+ otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, wrapping_oct/1,
otp_9389/1]).
%% Internal exports.
-export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1,
- otp_7731_server/1, zombie_server/2]).
+ oct_acceptor/1,
+ otp_7731_server/1, zombie_server/2, do_iter_max_socks/2]).
init_per_testcase(_Func, Config) when is_list(Config) ->
Dog = test_server:timetrap(test_server:seconds(240)),
@@ -75,6 +76,7 @@ all() ->
killing_acceptor, killing_multi_acceptors,
killing_multi_acceptors2, several_accepts_in_one_go, accept_system_limit,
active_once_closed, send_timeout, send_timeout_active, otp_7731,
+ wrapping_oct,
zombie_sockets, otp_7816, otp_8102, otp_9389].
groups() ->
@@ -589,7 +591,13 @@ iter_max_socks(doc) ->
"that we get the same number of sockets every time."];
iter_max_socks(Config) when is_list(Config) ->
N = 20,
- L = do_iter_max_socks(N, initalize),
+ %% Run on a different node in order to limit the effect if this test fails.
+ Dir = filename:dirname(code:which(?MODULE)),
+ {ok,Node} = test_server:start_node(test_iter_max_socks,slave,
+ [{args,"-pa " ++ Dir}]),
+ L = rpc:call(Node,?MODULE,do_iter_max_socks,[N, initalize]),
+ test_server:stop_node(Node),
+
io:format("Result: ~p",[L]),
all_equal(L),
{comment, "Max sockets: " ++ integer_to_list(hd(L))}.
@@ -2575,3 +2583,71 @@ otp_9389_loop(S, OrigLinkHdr, State) ->
3000 ->
?line error({timeout,header})
end.
+
+wrapping_oct(doc) ->
+ "Check that 64bit octet counters work.";
+wrapping_oct(suite) ->
+ [];
+wrapping_oct(Config) when is_list(Config) ->
+ Dog = test_server:timetrap(test_server:seconds(600)),
+ {ok,Sock} = gen_tcp:listen(0,[{active,false},{mode,binary}]),
+ {ok,Port} = inet:port(Sock),
+ spawn_link(?MODULE,oct_acceptor,[Sock]),
+ Res = oct_datapump(Port,16#1FFFFFFFF),
+ gen_tcp:close(Sock),
+ test_server:timetrap_cancel(Dog),
+ ok = Res,
+ ok.
+
+oct_datapump(Port,N) ->
+ {ok,Sock} = gen_tcp:connect("localhost",Port,
+ [{active,false},{mode,binary}]),
+ oct_pump(Sock,N,binary:copy(<<$a:8>>,100000),0).
+
+oct_pump(S,N,_,_) when N =< 0 ->
+ gen_tcp:close(S),
+ ok;
+oct_pump(S,N,Bin,Last) ->
+ case gen_tcp:send(S,Bin) of
+ ok ->
+ {ok,Stat}=inet:getstat(S),
+ {_,R}=lists:keyfind(send_oct,1,Stat),
+ case (R < Last) of
+ true ->
+ io:format("ERROR (output) ~p < ~p~n",[R,Last]),
+ output_counter_error;
+ false ->
+ oct_pump(S,N-byte_size(Bin),Bin,R)
+ end;
+ _ ->
+ input_counter_error
+ end.
+
+
+oct_acceptor(Sock) ->
+ {ok,Data} = gen_tcp:accept(Sock),
+ oct_aloop(Data,0,0).
+
+oct_aloop(S,X,Times) ->
+ case gen_tcp:recv(S,0) of
+ {ok,_} ->
+ {ok,Stat}=inet:getstat(S),
+ {_,R}=lists:keyfind(recv_oct,1,Stat),
+ case (R < X) of
+ true ->
+ io:format("ERROR ~p < ~p~n",[R,X]),
+ gen_tcp:close(S),
+ input_counter_error;
+ false ->
+ case Times rem 16#FFFFF of
+ 0 ->
+ io:format("Read: ~p~n",[R]);
+ _ ->
+ ok
+ end,
+ oct_aloop(S,R,Times+1)
+ end;
+ _ ->
+ gen_tcp:close(S),
+ closed
+ end.
diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl
index b40c50f79f..9428a38660 100644
--- a/lib/kernel/test/global_SUITE.erl
+++ b/lib/kernel/test/global_SUITE.erl
@@ -91,27 +91,9 @@ end_per_group(_GroupName, Config) ->
Config.
init_per_suite(Config) ->
-
- %% Copied from test_server_ctrl ln 647, we have to do this here as
- %% the test_server only does this when run without common_test
- global:sync(),
- case global:whereis_name(test_server) of
- undefined ->
- io:format(user, "Registering test_server globally!~n",[]),
- global:register_name(test_server, whereis(test_server_ctrl));
- Pid ->
- case node() of
- N when N == node(Pid) ->
- io:format(user, "Warning: test_server already running!\n", []),
- global:re_register_name(test_server,self());
- _ ->
- ok
- end
- end,
Config.
end_per_suite(_Config) ->
- global:unregister_name(test_server),
ok.
@@ -135,8 +117,7 @@ end_per_testcase(_Case, Config) ->
?line write_high_level_trace(Config),
?line _ =
gen_server:call(global_name_server, high_level_trace_stop, infinity),
- ?line[global:unregister_name(N) || N <- global:registered_names(),
- N =/= test_server],
+ [global:unregister_name(N) || N <- global:registered_names()],
?line InitRegistered = ?registered,
?line Registered = registered(),
?line [io:format("~s local names: ~p~n", [What, N]) ||
@@ -1840,16 +1821,16 @@ do_otp_3162(StartFun, Config) ->
?line ?UNTIL
([Cp3] =:= lists:sort(rpc:call(Cp1, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, test_server, vera] =:=
+ ?UNTIL([kalle, vera] =:=
lists:sort(rpc:call(Cp1, global, registered_names, []))),
?line ?UNTIL
([Cp3] =:= lists:sort(rpc:call(Cp2, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([stina, test_server, vera] =:=
+ ?UNTIL([stina, vera] =:=
lists:sort(rpc:call(Cp2, global, registered_names, []))),
?line ?UNTIL
([Cp1, Cp2] =:=
lists:sort(rpc:call(Cp3, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, stina, test_server, vera] =:=
+ ?UNTIL([kalle, stina, vera] =:=
lists:sort(rpc:call(Cp3, global, registered_names, []))),
?line pong = rpc:call(Cp2, net_adm, ping, [Cp1]),
@@ -1860,17 +1841,17 @@ do_otp_3162(StartFun, Config) ->
?line
?UNTIL(begin
NN = lists:sort(rpc:call(Cp1, global, registered_names, [])),
- [kalle, stina, test_server, vera] =:= NN
+ [kalle, stina, vera] =:= NN
end),
?line ?UNTIL
([Cp1, Cp3] =:=
lists:sort(rpc:call(Cp2, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, stina, test_server, vera] =:=
+ ?UNTIL([kalle, stina, vera] =:=
lists:sort(rpc:call(Cp2, global, registered_names, []))),
?line ?UNTIL
([Cp1, Cp2] =:=
lists:sort(rpc:call(Cp3, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, stina, test_server, vera] =:=
+ ?UNTIL([kalle, stina, vera] =:=
lists:sort(rpc:call(Cp3, global, registered_names, []))),
write_high_level_trace(Config),
@@ -4154,7 +4135,7 @@ init_condition(Config) ->
{"Global Locks (ETS)", global_locks},
{"Global Pid Names (ETS)", global_pid_names},
{"Global Pid Ids (ETS)", global_pid_ids}]],
- ?UNTIL([test_server] =:= global:registered_names()),
+ ?UNTIL([] =:= global:registered_names()),
?UNTIL([] =:= nodes()),
?UNTIL([node()] =:= get_known(node())),
ok.
diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4
index 5d555a5123..918e30a886 100644
--- a/lib/megaco/aclocal.m4
+++ b/lib/megaco/aclocal.m4
@@ -1861,17 +1861,16 @@ 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 CFLAGS])
+ AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $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 $CFLAGS")
+ AS_VAR_SET($2, "$1 $$2")
else
AC_MSG_RESULT([no])
- AS_VAR_SET($2, "$CFLAGS")
fi
])
diff --git a/lib/megaco/configure.in b/lib/megaco/configure.in
index 9c3858f562..643267a154 100644
--- a/lib/megaco/configure.in
+++ b/lib/megaco/configure.in
@@ -162,6 +162,11 @@ else
fi
AC_SUBST(OTP_EXTRA_FLAGS)
+if test "x$GCC" = xyes; then
+ # Treat certain GCC warnings as errors
+ LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
+fi
+
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
@@ -273,11 +278,6 @@ if test "$PERL" = no_perl; then
AC_MSG_ERROR([Perl is required to build the flex scanner!])
fi
-if test "x$GCC" = xyes; then
- # Treat certain GCC warnings as errors
- LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS])
-fi
-
AC_OUTPUT(examples/meas/Makefile:examples/meas/Makefile.in)
AC_OUTPUT(src/flex/$host/Makefile:src/flex/Makefile.in)
diff --git a/lib/megaco/doc/src/definitions/term.defs b/lib/megaco/doc/src/definitions/term.defs
index f3d6f865d2..57379eaa5d 100644
--- a/lib/megaco/doc/src/definitions/term.defs
+++ b/lib/megaco/doc/src/definitions/term.defs
@@ -110,7 +110,6 @@ the module Erlang in the application kernel","kenneth"},
{"Master Agent","Master Agent","The SNMP agent system consists of one Master Agent which terminates the SNMP protocol","mbj"}, {"MIB","Management Information Base (MIB)","An abstract definition of the management information available through a management interface in a system.","mbj"},
{"matching","matching","See pattern matching.","kenneth"},
{"message queue","message queue","The queue of not yet received messages that are in the mailbox of a process.","olin"},
-{"Mnemosyne","Mnemosyne","Mnemosyne was the query language of Mnesia up to the R11B release. Supersed by QLC.","hakan"},
{"Mnesia","Mnesia","Mnesia is a distributed Database Management System, appropriate for telecommunications applications and other applications with need of continuous operation and soft real-time properties.","hakan"},
{"MIBshort","MIB","See Management Information Base.","mbj"},
{"MIME","MIME","Multi-purpose Internet Mail Extensions.","jocke"},
diff --git a/lib/megaco/doc/src/definitions/term.defs.xml b/lib/megaco/doc/src/definitions/term.defs.xml
index 28ac0d6eaf..1c80ee8d80 100644
--- a/lib/megaco/doc/src/definitions/term.defs.xml
+++ b/lib/megaco/doc/src/definitions/term.defs.xml
@@ -794,13 +794,6 @@ The queue of not yet received messages that are in the mailbox of a process.
<resp>olin</resp>
</term>
<term>
- <id>Mnemosyne</id>
- <shortdef>Mnemosyne</shortdef>
- <def>
-Mnemosyne was the query language of Mnesia up to the R11B release. Supersed by QLC.</def>
- <resp>hakan</resp>
- </term>
- <term>
<id>Mnesia</id>
<shortdef>Mnesia</shortdef>
<def>
diff --git a/lib/megaco/examples/meas/Makefile.in b/lib/megaco/examples/meas/Makefile.in
index c517fd21cf..91e342cd9a 100644
--- a/lib/megaco/examples/meas/Makefile.in
+++ b/lib/megaco/examples/meas/Makefile.in
@@ -147,12 +147,12 @@ release_docs_spec:
# ----------------------------------------------------
meas.sh.skel: meas.sh.skel.src
- @echo "transforming $< to $@"
- $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
+ $(V_colon)@echo "transforming $< to $@"
+ $(vsn_verbose)$(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
mstone1.sh.skel: mstone1.sh.skel.src
- @echo "transforming $< to $@"
- $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
+ $(V_colon)@echo "transforming $< to $@"
+ $(vsn_verbose)$(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
megaco_codec_transform.$(EMULATOR): megaco_codec_transform.erl
diff --git a/lib/megaco/src/app/Makefile b/lib/megaco/src/app/Makefile
index 42030c5b1c..d18da5326a 100644
--- a/lib/megaco/src/app/Makefile
+++ b/lib/megaco/src/app/Makefile
@@ -94,10 +94,10 @@ info:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
diff --git a/lib/megaco/src/binary/Makefile b/lib/megaco/src/binary/Makefile
index 660713605e..c1fd66b848 100644
--- a/lib/megaco/src/binary/Makefile
+++ b/lib/megaco/src/binary/Makefile
@@ -129,12 +129,13 @@ opt: prebuild $(TARGET_FILES)
prebuild: prebuild.skip
prebuild.skip:
- @echo "Building prebuild.skip\c"
+ $(gen_verbose)
+ $(V_colon)@echo "Building prebuild.skip\c"
@touch prebuild.skip
@for a in $(SPEC_ASN1DB); do \
echo $$a >> prebuild.skip; \
done
- @echo ""
+ $(V_colon)@echo ""
v1: $(V2_SPEC_BINS)
diff --git a/lib/megaco/src/binary/depend.mk b/lib/megaco/src/binary/depend.mk
index a1318079be..2dce45981f 100644
--- a/lib/megaco/src/binary/depend.mk
+++ b/lib/megaco/src/binary/depend.mk
@@ -53,8 +53,8 @@ PER_V3_FLAGS = $(ASN1_CT_OPTS)
$(BER_ASN1_V1_SPEC).erl: \
$(BER_ASN1_V1_SPEC).set.asn \
$(ASN1_V1_SPEC).asn
- @echo "$(BER_ASN1_V1_SPEC):"
- $(ERLC) -bber $(BER_V1_FLAGS) $(BER_ASN1_V1_SPEC).set.asn
+ $(V_colon)@echo "$(BER_ASN1_V1_SPEC):"
+ $(asn_verbose)$(ERLC) -bber $(BER_V1_FLAGS) $(BER_ASN1_V1_SPEC).set.asn
$(EBIN)/$(BER_ASN1_V1_SPEC).$(EMULATOR): \
$(BER_ASN1_V1_SPEC).erl
@@ -62,8 +62,8 @@ $(EBIN)/$(BER_ASN1_V1_SPEC).$(EMULATOR): \
$(PER_ASN1_V1_SPEC).erl: \
$(PER_ASN1_V1_SPEC).set.asn \
$(ASN1_V1_SPEC).asn
- @echo "$(PER_ASN1_V1_SPEC):"
- $(ERLC) -bper $(PER_V1_FLAGS) $(PER_ASN1_V1_SPEC).set.asn
+ $(V_colon)@echo "$(PER_ASN1_V1_SPEC):"
+ $(asn_verbose)$(ERLC) -bper $(PER_V1_FLAGS) $(PER_ASN1_V1_SPEC).set.asn
$(EBIN)/$(PER_ASN1_V1_SPEC).$(EMULATOR): \
$(PER_ASN1_V1_SPEC).erl
@@ -74,8 +74,8 @@ $(EBIN)/$(PER_ASN1_V1_SPEC).$(EMULATOR): \
$(BER_ASN1_V2_SPEC).erl: \
$(BER_ASN1_V2_SPEC).set.asn \
$(ASN1_V2_SPEC).asn
- @echo "$(BER_ASN1_V2_SPEC):"
- $(ERLC) -bber $(BER_V2_FLAGS) $(BER_ASN1_V2_SPEC).set.asn
+ $(V_colon)@echo "$(BER_ASN1_V2_SPEC):"
+ $(asn_verbose)$(ERLC) -bber $(BER_V2_FLAGS) $(BER_ASN1_V2_SPEC).set.asn
$(EBIN)/$(BER_ASN1_V2_SPEC).$(EMULATOR): \
$(BER_ASN1_V2_SPEC).erl
@@ -83,8 +83,8 @@ $(EBIN)/$(BER_ASN1_V2_SPEC).$(EMULATOR): \
$(PER_ASN1_V2_SPEC).erl: \
$(PER_ASN1_V2_SPEC).set.asn \
$(ASN1_V2_SPEC).asn
- @echo "$(PER_ASN1_V2_SPEC):"
- $(ERLC) -bper $(PER_V2_FLAGS) $(PER_ASN1_V2_SPEC).set.asn
+ $(V_colon)@echo "$(PER_ASN1_V2_SPEC):"
+ $(asn_verbose)$(ERLC) -bper $(PER_V2_FLAGS) $(PER_ASN1_V2_SPEC).set.asn
$(EBIN)/$(PER_ASN1_V2_SPEC).$(EMULATOR): \
$(PER_ASN1_V2_SPEC).erl
@@ -96,8 +96,8 @@ $(EBIN)/$(PER_ASN1_V2_SPEC).$(EMULATOR): \
$(BER_ASN1_PREV3A_SPEC).erl: \
$(BER_ASN1_PREV3A_SPEC).set.asn \
$(ASN1_PREV3A_SPEC).asn
- @echo "$(BER_ASN1_PREV3A_SPEC):"
- $(ERLC) -bber $(BER_PREV3A_FLAGS) $(BER_ASN1_PREV3A_SPEC).set.asn
+ $(V_colon)@echo "$(BER_ASN1_PREV3A_SPEC):"
+ $(asn_verbose)$(ERLC) -bber $(BER_PREV3A_FLAGS) $(BER_ASN1_PREV3A_SPEC).set.asn
$(EBIN)/$(BER_ASN1_PREV3A_SPEC).$(EMULATOR): \
$(BER_ASN1_PREV3A_SPEC).erl
@@ -105,8 +105,8 @@ $(EBIN)/$(BER_ASN1_PREV3A_SPEC).$(EMULATOR): \
$(PER_ASN1_PREV3A_SPEC).erl: \
$(PER_ASN1_PREV3A_SPEC).set.asn \
$(ASN1_PREV3A_SPEC).asn
- @echo "$(PER_ASN1_PREV3A_SPEC):"
- $(ERLC) -bper $(PER_PREV3A_FLAGS) $(PER_ASN1_PREV3A_SPEC).set.asn
+ $(V_colon)@echo "$(PER_ASN1_PREV3A_SPEC):"
+ $(asn_verbose)$(ERLC) -bper $(PER_PREV3A_FLAGS) $(PER_ASN1_PREV3A_SPEC).set.asn
$(EBIN)/$(PER_ASN1_PREV3A_SPEC).$(EMULATOR): \
$(PER_ASN1_PREV3A_SPEC).erl
@@ -117,8 +117,8 @@ $(EBIN)/$(PER_ASN1_PREV3A_SPEC).$(EMULATOR): \
$(BER_ASN1_PREV3B_SPEC).erl: \
$(BER_ASN1_PREV3B_SPEC).set.asn \
$(ASN1_PREV3B_SPEC).asn
- @echo "$(BER_ASN1_PREV3B_SPEC):"
- $(ERLC) -bber $(BER_PREV3B_FLAGS) $(BER_ASN1_PREV3B_SPEC).set.asn
+ $(V_colon)@echo "$(BER_ASN1_PREV3B_SPEC):"
+ $(asn_verbose)$(ERLC) -bber $(BER_PREV3B_FLAGS) $(BER_ASN1_PREV3B_SPEC).set.asn
$(EBIN)/$(BER_ASN1_PREV3B_SPEC).$(EMULATOR): \
$(BER_ASN1_PREV3B_SPEC).erl
@@ -126,8 +126,8 @@ $(EBIN)/$(BER_ASN1_PREV3B_SPEC).$(EMULATOR): \
$(PER_ASN1_PREV3B_SPEC).erl: \
$(PER_ASN1_PREV3B_SPEC).set.asn \
$(ASN1_PREV3B_SPEC).asn
- @echo "$(PER_ASN1_PREV3B_SPEC):"
- $(ERLC) -bper $(PER_PREV3B_FLAGS) $(PER_ASN1_PREV3B_SPEC).set.asn
+ $(V_colon)@echo "$(PER_ASN1_PREV3B_SPEC):"
+ $(asn_verbose)$(ERLC) -bper $(PER_PREV3B_FLAGS) $(PER_ASN1_PREV3B_SPEC).set.asn
$(EBIN)/$(PER_ASN1_PREV3B_SPEC).$(EMULATOR): \
$(PER_ASN1_PREV3B_SPEC).erl
@@ -138,8 +138,8 @@ $(EBIN)/$(PER_ASN1_PREV3B_SPEC).$(EMULATOR): \
$(BER_ASN1_PREV3C_SPEC).erl: \
$(BER_ASN1_PREV3C_SPEC).set.asn \
$(ASN1_PREV3C_SPEC).asn
- @echo "$(BER_ASN1_PREV3C_SPEC):"
- $(ERLC) -bber $(BER_PREV3C_FLAGS) $(BER_ASN1_PREV3C_SPEC).set.asn
+ $(V_colon)@echo "$(BER_ASN1_PREV3C_SPEC):"
+ $(asn_verbose)$(ERLC) -bber $(BER_PREV3C_FLAGS) $(BER_ASN1_PREV3C_SPEC).set.asn
$(EBIN)/$(BER_ASN1_PREV3C_SPEC).$(EMULATOR): \
$(BER_ASN1_PREV3C_SPEC).erl
@@ -147,8 +147,8 @@ $(EBIN)/$(BER_ASN1_PREV3C_SPEC).$(EMULATOR): \
$(PER_ASN1_PREV3C_SPEC).erl: \
$(PER_ASN1_PREV3C_SPEC).set.asn \
$(ASN1_PREV3C_SPEC).asn
- @echo "$(PER_ASN1_PREV3C_SPEC):"
- $(ERLC) -bper $(PER_PREV3C_FLAGS) $(PER_ASN1_PREV3C_SPEC).set.asn
+ $(V_colon)@echo "$(PER_ASN1_PREV3C_SPEC):"
+ $(asn_verbose)$(ERLC) -bper $(PER_PREV3C_FLAGS) $(PER_ASN1_PREV3C_SPEC).set.asn
$(EBIN)/$(PER_ASN1_PREV3C_SPEC).$(EMULATOR): \
$(PER_ASN1_PREV3C_SPEC).erl
@@ -159,8 +159,8 @@ $(EBIN)/$(PER_ASN1_PREV3C_SPEC).$(EMULATOR): \
$(BER_ASN1_V3_SPEC).erl: \
$(BER_ASN1_V3_SPEC).set.asn \
$(ASN1_V3_SPEC).asn
- @echo "$(BER_ASN1_V3_SPEC):"
- $(ERLC) -bber $(BER_V3_FLAGS) $(BER_ASN1_V3_SPEC).set.asn
+ $(V_colon)@echo "$(BER_ASN1_V3_SPEC):"
+ $(asn_verbose)$(ERLC) -bber $(BER_V3_FLAGS) $(BER_ASN1_V3_SPEC).set.asn
$(EBIN)/$(BER_ASN1_V3_SPEC).$(EMULATOR): \
$(BER_ASN1_V3_SPEC).erl
@@ -168,8 +168,8 @@ $(EBIN)/$(BER_ASN1_V3_SPEC).$(EMULATOR): \
$(PER_ASN1_V3_SPEC).erl: \
$(PER_ASN1_V3_SPEC).set.asn \
$(ASN1_V3_SPEC).asn
- @echo "$(PER_ASN1_V3_SPEC):"
- $(ERLC) -bper $(PER_V3_FLAGS) $(PER_ASN1_V3_SPEC).set.asn
+ $(V_colon)@echo "$(PER_ASN1_V3_SPEC):"
+ $(asn_verbose)$(ERLC) -bper $(PER_V3_FLAGS) $(PER_ASN1_V3_SPEC).set.asn
$(EBIN)/$(PER_ASN1_V3_SPEC).$(EMULATOR): \
$(PER_ASN1_V3_SPEC).erl
diff --git a/lib/megaco/src/flex/Makefile.in b/lib/megaco/src/flex/Makefile.in
index cb5f5412f4..6111cf2304 100644
--- a/lib/megaco/src/flex/Makefile.in
+++ b/lib/megaco/src/flex/Makefile.in
@@ -319,16 +319,16 @@ release_docs_spec:
$(STD_DRV).flex: megaco_flex_scanner_drv.flex.src
ifeq ($(ENABLE_MEGACO_FLEX_SCANNER_LINENO),true)
- @printf "std [flex] scanner - lineno enabled\n"
- $(PERL) -p -e \
+ $(V_colon)@printf "std [flex] scanner - lineno enabled\n"
+ $(gen_verbose)$(PERL) -p -e \
's/%FLEX_VERSION%/$(FLEX_VSN)/ ; \
s/%MEGACO_YY_LINENO_OPTION%/%option yylineno/ ; \
s/%MEGACO_YY_REENTRANT_OPTION%/\/\* %option reentrant \*\// ; \
s/%MEGACO_DUMMY_DECL_YY_LINENO%/\/* static int yylineno = 1; *\//' \
< $< > $@
else
- @printf "std [flex] scanner - lineno disabled\n"
- $(PERL) -p -e \
+ $(V_colon)@printf "std [flex] scanner - lineno disabled\n"
+ $(gen_verbose)$(PERL) -p -e \
's/%FLEX_VERSION%/$(FLEX_VSN)/ ; \
s/%MEGACO_YY_LINENO_OPTION%/\/\* %option yylineno \*\// ; \
s/%MEGACO_YY_REENTRANT_OPTION%/\/\* %option reentrant \*\// ; \
@@ -339,16 +339,16 @@ endif
$(MT_DRV).flex: megaco_flex_scanner_drv.flex.src
ifeq ($(ENABLE_MEGACO_FLEX_SCANNER_LINENO),true)
ifeq ($(ENABLE_REENTRANT_MEGACO_FLEX_SCANNER),true)
- @printf "multi-threaded reentrant [flex] scanner - lineno enabled\n"
- $(PERL) -p -e \
+ $(V_colon)@printf "multi-threaded reentrant [flex] scanner - lineno enabled\n"
+ $(gen_verbose)$(PERL) -p -e \
's/%FLEX_VERSION%/$(FLEX_VSN)/ ; \
s/%MEGACO_YY_LINENO_OPTION%/%option yylineno/ ; \
s/%MEGACO_YY_REENTRANT_OPTION%/%option reentrant/ ; \
s/%MEGACO_DUMMY_DECL_YY_LINENO%/\/* static int yylineno = 1; *\//' \
< $< > $@
else
- @printf "multi-threaded non-reentrant [flex] scanner - lineno enabled\n"
- $(PERL) -p -e \
+ $(V_colon)@printf "multi-threaded non-reentrant [flex] scanner - lineno enabled\n"
+ $(gen_verbose)$(PERL) -p -e \
's/%FLEX_VERSION%/$(FLEX_VSN)/ ; \
s/%MEGACO_YY_LINENO_OPTION%/%option yylineno/ ; \
s/%MEGACO_YY_REENTRANT_OPTION%/\/\* %option reentrant \*\// ; \
@@ -357,16 +357,16 @@ else
endif
else
ifeq ($(ENABLE_REENTRANT_MEGACO_FLEX_SCANNER),true)
- @printf "multi-threaded reentrant [flex] scanner - lineno disabled\n"
- $(PERL) -p -e \
+ $(V_colon)@printf "multi-threaded reentrant [flex] scanner - lineno disabled\n"
+ $(gen_verbose)$(PERL) -p -e \
's/%FLEX_VERSION%/$(FLEX_VSN)/ ; \
s/%MEGACO_YY_LINENO_OPTION%/\/\* %option yylineno \*\// ; \
s/%MEGACO_YY_REENTRANT_OPTION%/%option reentrant/ ; \
s/%MEGACO_DUMMY_DECL_YY_LINENO%/\/* static int yylineno = 1; - REENTRANT SCANNER*\//' \
< $< > $@
else
- @printf "multi-threaded non-reentrant [flex] scanner - lineno disabled\n"
- $(PERL) -p -e \
+ $(V_colon)@printf "multi-threaded non-reentrant [flex] scanner - lineno disabled\n"
+ $(gen_verbose)$(PERL) -p -e \
's/%FLEX_VERSION%/$(FLEX_VSN)/ ; \
s/%MEGACO_YY_LINENO_OPTION%/\/\* %option yylineno \*\// ; \
s/%MEGACO_YY_REENTRANT_OPTION%/\/\* %option reentrant \*\// ; \
@@ -376,31 +376,31 @@ endif
endif
# megaco_flex_scanner_drv.c: megaco_flex_scanner_drv.flex
-# $(LEX) $(LEX_FLAGS) -P$* -o$@ $<
+# $(V_LEX) $(LEX_FLAGS) -P$* -o$@ $<
$(STD_DRV).c: $(STD_DRV).flex
- $(LEX) $(STD_LEX_FLAGS) -P$* -o$@ $<
+ $(V_LEX) $(STD_LEX_FLAGS) -P$* -o$@ $<
$(MT_DRV).c: $(MT_DRV).flex
- $(LEX) $(MT_LEX_FLAGS) -P$* -o$@ $<
+ $(V_LEX) $(MT_LEX_FLAGS) -P$* -o$@ $<
_create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR))
solibs: $(SOLIBS)
$(OBJDIR)/$(STD_DRV).o: $(STD_DRV).c
- @echo "compiling std driver:"
- $(CC) -c $(STD_DRV_NAME) $(CFLAGS) -o $@ $<
+ $(V_colon)@echo "compiling std driver:"
+ $(V_CC) -c $(STD_DRV_NAME) $(CFLAGS) -o $@ $<
$(OBJDIR)/$(MT_DRV).o: $(MT_DRV).c
- @echo "compiling multi-threaded driver:"
- $(CC) -c $(MT_DRV_NAME) $(CFLAGS_MT) -o $@ $<
+ $(V_colon)@echo "compiling multi-threaded driver:"
+ $(V_CC) -c $(MT_DRV_NAME) $(CFLAGS_MT) -o $@ $<
# No need to link with -lfl as we have also defined %option noyywrap -
# and having -lfl doesn't work under Darwin for some reason. - Sean
$(LIBDIR)/$(STD_DRV).$(DED_EXT): $(OBJDIR)/$(STD_DRV).o
- @echo "linking std driver:"
- $(LD) $(LDFLAGS) -o $@ $<
+ $(V_colon)@echo "linking std driver:"
+ $(V_LD) $(LDFLAGS) -o $@ $<
$(LIBDIR)/$(MT_DRV).$(DED_EXT): $(OBJDIR)/$(MT_DRV).o
- @echo "linking multi-threaded driver:"
- $(LD) $(LDFLAGS) -o $@ $<
+ $(V_colon)@echo "linking multi-threaded driver:"
+ $(V_LD) $(LDFLAGS) -o $@ $<
diff --git a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
index b8146c345d..5faddb08c5 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
+++ b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
@@ -76,6 +76,7 @@
typedef struct {
ErlDrvPort port;
+ ErlDrvTermData port_id;
char* digit_map_name_ptr;
int digit_map_name_len;
char* digit_map_value_ptr;
@@ -1497,6 +1498,7 @@ static ErlDrvData mfs_start(ErlDrvPort port, char *buf)
DBG( ("mfs_start -> entry\n") );
dataP->port = port;
+ dataP->port_id = driver_mk_port(port);
dataP->digit_map_name_ptr = NULL;
dataP->digit_map_name_len = 0;
dataP->digit_map_value_ptr = NULL;
@@ -1841,10 +1843,10 @@ static ErlDrvSSizeT mfs_control(ErlDrvData handle,
"\n term_spec_size: %d\n",
dataP->term_spec_index, dataP->term_spec_size) );
- driver_send_term(dataP->port,
- driver_caller(dataP->port),
- dataP->term_spec,
- dataP->term_spec_index);
+ erl_drv_send_term(dataP->port_id,
+ driver_caller(dataP->port),
+ dataP->term_spec,
+ dataP->term_spec_index);
if (dataP->text_buf != NULL) FREE(dataP->text_buf);
if (dataP->term_spec != NULL) FREE(dataP->term_spec);
diff --git a/lib/mnesia/include/mnemosyne.hrl b/lib/mnesia/include/mnemosyne.hrl
deleted file mode 100644
index eb6ec53ae1..0000000000
--- a/lib/mnesia/include/mnemosyne.hrl
+++ /dev/null
@@ -1,18 +0,0 @@
-%% ``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 via the world wide web 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.
-%%
-%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-%% AB. All Rights Reserved.''
-%%
-%% $Id$
-%%
--compile({parse_transform,mnemosyne}).
diff --git a/lib/mnesia/src/Makefile b/lib/mnesia/src/Makefile
index 6f289433ff..3a146c009a 100644
--- a/lib/mnesia/src/Makefile
+++ b/lib/mnesia/src/Makefile
@@ -93,10 +93,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# FLAGS
# ----------------------------------------------------
ERL_COMPILE_FLAGS += \
- +warn_unused_vars \
+ -Werror \
+'{parse_transform,sys_pre_attributes}' \
- +'{attribute,insert,vsn,"mnesia_$(MNESIA_VSN)"}' \
- -W
+ +'{attribute,insert,vsn,"mnesia_$(MNESIA_VSN)"}'
# ----------------------------------------------------
# Targets
@@ -120,10 +119,10 @@ $(TARGET_FILES): $(HRL_FILES)
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 3d30debc53..3488d5c99b 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -2186,7 +2186,6 @@ system_info2(dump_log_time_threshold) -> mnesia_monitor:get_env(dump_log_time_th
system_info2(dump_log_update_in_place) ->
mnesia_monitor:get_env(dump_log_update_in_place);
system_info2(max_wait_for_decision) -> mnesia_monitor:get_env(max_wait_for_decision);
-system_info2(embedded_mnemosyne) -> mnesia_monitor:get_env(embedded_mnemosyne);
system_info2(ignore_fallback_at_startup) -> mnesia_monitor:get_env(ignore_fallback_at_startup);
system_info2(fallback_error_function) -> mnesia_monitor:get_env(fallback_error_function);
system_info2(log_version) -> mnesia_log:version();
@@ -2224,7 +2223,6 @@ system_info_items(yes) ->
dump_log_time_threshold,
dump_log_update_in_place,
dump_log_write_threshold,
- embedded_mnemosyne,
event_module,
extra_db_nodes,
fallback_activated,
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index c08bbc879f..d940bd1cb7 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -673,7 +673,6 @@ env() ->
dump_log_time_threshold,
dump_log_update_in_place,
dump_log_write_threshold,
- embedded_mnemosyne,
event_module,
extra_db_nodes,
ignore_fallback_at_startup,
@@ -706,8 +705,6 @@ default_env(dump_log_update_in_place) ->
true;
default_env(dump_log_write_threshold) ->
1000;
-default_env(embedded_mnemosyne) ->
- false;
default_env(event_module) ->
mnesia_event;
default_env(extra_db_nodes) ->
@@ -757,7 +754,6 @@ do_check_type(event_module, A) when is_atom(A) -> A;
do_check_type(ignore_fallback_at_startup, B) -> bool(B);
do_check_type(fallback_error_function, {Mod, Func})
when is_atom(Mod), is_atom(Func) -> {Mod, Func};
-do_check_type(embedded_mnemosyne, B) -> bool(B);
do_check_type(extra_db_nodes, L) when is_list(L) ->
Fun = fun(N) when N == node() -> false;
(A) when is_atom(A) -> true
diff --git a/lib/mnesia/src/mnesia_sup.erl b/lib/mnesia/src/mnesia_sup.erl
index 9ee4086f50..ef858d2364 100644
--- a/lib/mnesia/src/mnesia_sup.erl
+++ b/lib/mnesia/src/mnesia_sup.erl
@@ -60,9 +60,8 @@ init() ->
Event = event_procs(),
Kernel = kernel_procs(),
- Mnemosyne = mnemosyne_procs(),
- {ok, {Flags, Event ++ Kernel ++ Mnemosyne}}.
+ {ok, {Flags, Event ++ Kernel}}.
event_procs() ->
KillAfter = timer:seconds(30),
@@ -75,16 +74,6 @@ kernel_procs() ->
KA = infinity,
[{K, {K, start, []}, permanent, KA, supervisor, [K, supervisor]}].
-mnemosyne_procs() ->
- case mnesia_monitor:get_env(embedded_mnemosyne) of
- true ->
- Q = mnemosyne_sup,
- KA = infinity,
- [{Q, {Q, start, []}, permanent, KA, supervisor, [Q, supervisor]}];
- false ->
- []
- end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% event handler
diff --git a/lib/mnesia/test/mnesia.spec b/lib/mnesia/test/mnesia.spec
index 204d1519cb..653e515317 100644
--- a/lib/mnesia/test/mnesia.spec
+++ b/lib/mnesia/test/mnesia.spec
@@ -42,9 +42,6 @@
{skip_cases,"../mnesia_test",mnesia_measure_test,
[measure_all_api_functions],
"Not yet implemented"}.
-{skip_cases,"../mnesia_test",mnesia_measure_test,
- [mnemosyne_vs_mnesia_kernel],
- "Not yet implemented"}.
{skip_cases,"../mnesia_test",mnesia_examples_test,
[company],
"Not yet implemented"}.
diff --git a/lib/mnesia/test/mnesia_SUITE.erl b/lib/mnesia/test/mnesia_SUITE.erl
index 2267a94164..5dbb80d4eb 100644
--- a/lib/mnesia/test/mnesia_SUITE.erl
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -105,7 +105,6 @@ groups() ->
{otp_r4b, [],
[{mnesia_config_test, access_module},
{mnesia_config_test, dump_log_load_regulation},
- {mnesia_config_test, embedded_mnemosyne},
{mnesia_config_test, ignore_fallback_at_startup},
{mnesia_config_test, max_wait_for_decision},
{mnesia_consistency_test, consistency_after_restore},
diff --git a/lib/mnesia/test/mnesia_config_test.erl b/lib/mnesia/test/mnesia_config_test.erl
index 93510d539c..fd294780da 100644
--- a/lib/mnesia/test/mnesia_config_test.erl
+++ b/lib/mnesia/test/mnesia_config_test.erl
@@ -36,7 +36,6 @@
dump_log_load_regulation/1,
dump_log_update_in_place/1,
- embedded_mnemosyne/1,
event_module/1,
ignore_fallback_at_startup/1,
inconsistent_database/1,
@@ -104,7 +103,7 @@ end_per_testcase(Func, Conf) ->
all() ->
[access_module, auto_repair, backup_module, debug, dir,
dump_log_load_regulation, {group, dump_log_thresholds},
- dump_log_update_in_place, embedded_mnemosyne,
+ dump_log_update_in_place,
event_module, ignore_fallback_at_startup,
inconsistent_database, max_wait_for_decision,
send_compressed, app_test, {group, schema_config},
@@ -610,45 +609,6 @@ dump_log_load_regulation(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-embedded_mnemosyne(doc) ->
- ["Start Mnemosyne as an embedded part of Mnesia",
- "on some of the nodes"];
-embedded_mnemosyne(suite) ->
- [];
-embedded_mnemosyne(Config) when is_list(Config) ->
- Nodes = ?acquire_nodes(1, Config),
- Param = embedded_mnemosyne,
-
- %% Normal
- NoMnem = false,
- ?match(NoMnem, mnesia:system_info(Param)),
- ?match(undefined, whereis(mnemosyne_catalog)),
- ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
-
- %% Bad
- Bad = arne_anka,
- ?match({error, {bad_type, Param, Bad}},
- mnesia:start([{Param, Bad}])),
-
- case code:priv_dir(mnemosyne) of
- {error, _} -> %% No mnemosyne on later systems
- ok;
- _ ->
- %% Mnemosyne as embedded application
- Mnem = true,
- ?match(undefined, whereis(mnemosyne_catalog)),
- ?match(ok,mnesia:start([{Param, Mnem}])),
- ?match(Mnem, mnesia:system_info(Param)),
- ?match(Pid when is_pid(Pid), whereis(mnemosyne_catalog)),
- ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
- ?match(undefined, whereis(mnemosyne_catalog))
- end,
- ?verify_mnesia([], Nodes),
- ?cleanup(1, Config),
- ok.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
ignore_fallback_at_startup(doc) ->
["Start Mnesia without rollback of the database to the fallback. ",
"Once Mnesia has been (re)started the installed fallback should",
diff --git a/lib/mnesia/test/mnesia_measure_test.erl b/lib/mnesia/test/mnesia_measure_test.erl
index e63689d83a..dfed302814 100644
--- a/lib/mnesia/test/mnesia_measure_test.erl
+++ b/lib/mnesia/test/mnesia_measure_test.erl
@@ -72,8 +72,7 @@ groups() ->
resource_consumption_at_full_load]},
{benchmarks, [],
[{group, meter}, cost, dbn_meters,
- measure_all_api_functions, {group, tpcb},
- mnemosyne_vs_mnesia_kernel]},
+ measure_all_api_functions, {group, tpcb}]},
{tpcb, [], [ram_tpcb, disc_tpcb, disc_only_tpcb]},
{meter, [], [ram_meter, disc_meter, disc_only_meter]}].
diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile
index 7135a6abd5..9069415e44 100644
--- a/lib/observer/src/Makefile
+++ b/lib/observer/src/Makefile
@@ -102,7 +102,8 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ERL_COMPILE_FLAGS += \
-I../include \
-I ../../et/include \
- -I ../../../libraries/et/include
+ -I ../../../libraries/et/include \
+ -Werror
# ----------------------------------------------------
# Targets
@@ -114,10 +115,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(TARGET_FILES): $(INTERNAL_HRL_FILES)
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
index 5d555a5123..918e30a886 100644
--- a/lib/odbc/aclocal.m4
+++ b/lib/odbc/aclocal.m4
@@ -1861,17 +1861,16 @@ 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 CFLAGS])
+ AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $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 $CFLAGS")
+ AS_VAR_SET($2, "$1 $$2")
else
AC_MSG_RESULT([no])
- AS_VAR_SET($2, "$CFLAGS")
fi
])
diff --git a/lib/odbc/c_src/Makefile.in b/lib/odbc/c_src/Makefile.in
index 026da39e6f..6572d28ee8 100644
--- a/lib/odbc/c_src/Makefile.in
+++ b/lib/odbc/c_src/Makefile.in
@@ -108,17 +108,17 @@ docs:
ifdef UNIX_TARGET
$(UNIX_TARGET): $(OBJ_DIR)/odbcserver.o
- $(CC) $(CFLAGS) -o $@ $(OBJ_DIR)/odbcserver.o $(LDFLAGS) $(LIBS)
+ $(V_CC) $(CFLAGS) -o $@ $(OBJ_DIR)/odbcserver.o $(LDFLAGS) $(LIBS)
endif
ifdef WIN32_TARGET
$(WIN32_TARGET): $(OBJ_DIR)/odbcserver.o
- $(LD) $(LDFLAGS) -o $@ $(OBJ_DIR)/odbcserver.o $(ENTRY_OBJ) \
+ $(V_LD) $(LDFLAGS) -o $@ $(OBJ_DIR)/odbcserver.o $(ENTRY_OBJ) \
$(LIBS) $(ENTRY_LDFLAGS)
endif
$(OBJ_DIR)/odbcserver.o: odbcserver.c
- $(CC) $(CFLAGS) $(INCLUDES) $(TARGET_FLAGS) -o $@ -c odbcserver.c
+ $(V_CC) $(CFLAGS) $(INCLUDES) $(TARGET_FLAGS) -o $@ -c odbcserver.c
# ----------------------------------------------------
# Release Target
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index 4a7a5224e5..b4ee20c3ee 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -431,6 +431,20 @@ static db_result_msg handle_db_request(byte *reqstring, db_state *state)
<connStrIn>, returns a message indicating the outcome. */
static db_result_msg db_connect(byte *args, db_state *state)
{
+ /*
+ * Danil Onishchenko aka RubberCthulhu, [email protected]. 2013.01.09.
+ * It's a fix for Oracle ODBC driver for Linux.
+ * The issue: Oracle ODBC driver for Linux ignores setup autocommit mode
+ * during driver initialization before a connection to database has been
+ * established.
+ * Solution: set autocommit mode after a connection to database has been
+ * established.
+ *
+ * BEGIN
+ */
+ SQLLEN auto_commit_mode;
+ /* END */
+
SQLCHAR connStrOut[MAX_CONN_STR_OUT + 1] = {0};
SQLRETURN result;
SQLSMALLINT stringlength2ptr = 0, connlen;
@@ -498,6 +512,42 @@ static db_result_msg db_connect(byte *args, db_state *state)
return msg;
}
+ /*
+ * Danil Onishchenko aka RubberCthulhu, [email protected]. 2013.01.09.
+ * It's a fix for Oracle ODBC driver for Linux.
+ * The issue: Oracle ODBC driver for Linux ignores setup autocommit mode
+ * during driver initialization before a connection to database has been
+ * established.
+ * Solution: set autocommit mode after a connection to database has been
+ * established.
+ *
+ * BEGIN
+ */
+ if(erl_auto_commit_mode == ON) {
+ auto_commit_mode = SQL_AUTOCOMMIT_ON;
+ } else {
+ auto_commit_mode = SQL_AUTOCOMMIT_OFF;
+ }
+
+ if(!sql_success(SQLSetConnectAttr(connection_handle(state),
+ SQL_ATTR_AUTOCOMMIT,
+ (SQLPOINTER)auto_commit_mode, 0))) {
+ diagnos = get_diagnos(SQL_HANDLE_DBC, connection_handle(state), extended_errors(state));
+ strcat((char *)diagnos.error_msg, " Set autocommit mode failed.");
+
+ msg = encode_error_message(diagnos.error_msg, extended_error(state, diagnos.sqlState), diagnos.nativeError);
+
+ if(!sql_success(SQLFreeHandle(SQL_HANDLE_DBC,
+ connection_handle(state))))
+ DO_EXIT(EXIT_FREE);
+ if(!sql_success(SQLFreeHandle(SQL_HANDLE_ENV,
+ environment_handle(state))))
+ DO_EXIT(EXIT_FREE);
+
+ return msg;
+ }
+ /* END */
+
msg = retrive_scrollable_cursor_support_info(state);
return msg;
diff --git a/lib/odbc/src/Makefile b/lib/odbc/src/Makefile
index 2af65cc757..bfbda8aaf4 100644
--- a/lib/odbc/src/Makefile
+++ b/lib/odbc/src/Makefile
@@ -95,9 +95,9 @@ clean:
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/orber/COSS/CosNaming/Makefile b/lib/orber/COSS/CosNaming/Makefile
index 769c08a9e9..814062034c 100644
--- a/lib/orber/COSS/CosNaming/Makefile
+++ b/lib/orber/COSS/CosNaming/Makefile
@@ -117,7 +117,7 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC)
- sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $(APP_SRC) > $(APP_TARGET)
docs:
@@ -125,10 +125,10 @@ docs:
# Special Build Targets
# ----------------------------------------------------
IDL-GENERATED: cos_naming_ext.idl cos_naming.idl
- erlc $(ERL_IDL_FLAGS) +'{this,"CosNaming::NamingContext"}' \
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) +'{this,"CosNaming::NamingContext"}' \
+'{this,"CosNaming::NamingContextExt"}' cos_naming_ext.idl
- erlc $(ERL_IDL_FLAGS) +'{this,"CosNaming::NamingContext"}' cos_naming.idl
- >IDL-GENERATED
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{this,"CosNaming::NamingContext"}' cos_naming.idl
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/orber/c_src/Makefile.in b/lib/orber/c_src/Makefile.in
index 9970642a9f..126ed8af21 100644
--- a/lib/orber/c_src/Makefile.in
+++ b/lib/orber/c_src/Makefile.in
@@ -56,10 +56,10 @@ debug opt: $(OBJDIR) orber
ifeq ($(findstring win32,$(TARGET)),win32)
orber:
- echo "Nothing to build on NT"
+ $(V_colon)echo "Nothing to build on NT"
else
orber:
- echo "Nothing to build"
+ $(V_colon)echo "Nothing to build"
endif
clean:
@@ -74,7 +74,7 @@ $(OBJDIR):
-mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: %.c
- $(CC) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_CC) -c -o $@ $(ALL_CFLAGS) $<
# ----------------------------------------------------
# Release Target
diff --git a/lib/orber/examples/Stack/Makefile b/lib/orber/examples/Stack/Makefile
index f1a5106a7b..1cbb983cd6 100644
--- a/lib/orber/examples/Stack/Makefile
+++ b/lib/orber/examples/Stack/Makefile
@@ -104,8 +104,8 @@ docs:
test: $(TEST_TARGET_FILES)
IDL-GENERATED: stack.idl
- erlc $(ERL_IDL_FLAGS) stack.idl
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) stack.idl
+ $(V_at)>IDL-GENERATED
$(GEN_FILES): IDL-GENERATED
diff --git a/lib/orber/src/Makefile b/lib/orber/src/Makefile
index 6eb659407d..1c6781e5fd 100644
--- a/lib/orber/src/Makefile
+++ b/lib/orber/src/Makefile
@@ -215,10 +215,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(ORBER_VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(ORBER_VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(ORBER_VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(ORBER_VSN);' $< > $@
docs:
@@ -227,17 +227,17 @@ docs:
# ----------------------------------------------------
IDL-GENERATED: $(ERL_TOP)/lib/ic/include/erlang.idl CORBA.idl OrberIFR.idl
- erlc $(ERL_IDL_FLAGS) $(ERL_TOP)/lib/ic/include/erlang.idl
- erlc $(ERL_IDL_FLAGS) CORBA.idl
- erlc $(ERL_IDL_FLAGS) +'{this,"Orber::IFR"}' OrberIFR.idl
- >IDL-GENERATED
+ $(gen_verbose)erlc $(ERL_IDL_FLAGS) $(ERL_TOP)/lib/ic/include/erlang.idl
+ $(V_at)erlc $(ERL_IDL_FLAGS) CORBA.idl
+ $(V_at)erlc $(ERL_IDL_FLAGS) +'{this,"Orber::IFR"}' OrberIFR.idl
+ $(V_at)>IDL-GENERATED
$(GEN_ERL_FILES): IDL-GENERATED
$(TARGET_FILES): IDL-GENERATED
$(GEN_ASN_ERL) $(GEN_ASN_HRL): OrberCSIv2.asn1 OrberCSIv2.set.asn
- erlc $(ERL_COMPILE_FLAGS) $(ASN_FLAGS) +'{inline,"OrberCSIv2"}' OrberCSIv2.set.asn
- rm -f $(GEN_ASN_ERL:%.erl=%.beam)
+ $(asn_verbose)erlc $(ERL_COMPILE_FLAGS) $(ASN_FLAGS) +'{inline,"OrberCSIv2"}' OrberCSIv2.set.asn
+ $(V_at)rm -f $(GEN_ASN_ERL:%.erl=%.beam)
# erlc $(ERL_COMPILE_FLAGS) $(ASN_FLAGS) OrberCSIv2.asn1 ;\
# erlc $(GEN_ASN_ERL)
diff --git a/lib/orber/src/orber_ifr_exceptiondef.erl b/lib/orber/src/orber_ifr_exceptiondef.erl
index 7665d3d1bc..94c25cc4a5 100644
--- a/lib/orber/src/orber_ifr_exceptiondef.erl
+++ b/lib/orber/src/orber_ifr_exceptiondef.erl
@@ -111,26 +111,6 @@ cleanup_for_destroy({ObjType,ObjID}) ?tcheck(ir_ExceptionDef, ObjType) ->
describe({ObjType, ObjID}) ?tcheck(ir_ExceptionDef, ObjType) ->
orber_ifr_contained:describe({ObjType,ObjID}).
-%%% *** This function should be removed. Use
-%%% orber_ifr_repository:lookup_id/2 instead.
-
-%%lookup_id(SearchId) ->
-%% _F = fun() ->
-%% Q = query [X.ir_Internal_ID || X <- table(ir_ExceptionDef)]
-%% end,
-%% mnemosyne:eval(Q)
-%% end,
-%% case orber_ifr_utils:ifr_transaction_read(_F) of
-%% ?read_check_2() ->
-%% {ok, []};
-%% ?read_check_1(Rep_IDs) ->
-%% ExceptionDefs = lists:map(fun(X) -> {ir_ExceptionDef, X} end,
-%% Rep_IDs),
-%% {ok, lists:filter(fun(X) -> orber_ifr_exceptiondef:'_get_id'(X) ==
-%% SearchId end,
-%% ExceptionDefs)}
-%% end.
-
move({ObjType, ObjID}, New_container, New_name, New_version)
?tcheck(ir_ExceptionDef, ObjType) ->
orber_ifr_contained:move({ObjType,ObjID},New_container,New_name,
diff --git a/lib/os_mon/c_src/Makefile.in b/lib/os_mon/c_src/Makefile.in
index e728e43a09..51569f6ec9 100644
--- a/lib/os_mon/c_src/Makefile.in
+++ b/lib/os_mon/c_src/Makefile.in
@@ -93,28 +93,28 @@ docs:
# ----------------------------------------------------
$(BINDIR)/win32sysinfo.exe: $(OBJDIR)/win32sysinfo.o $(ENTRY_OBJ)
- $(LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(OBJDIR)/win32sysinfo.o $(ENTRY_OBJ)
+ $(V_LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(OBJDIR)/win32sysinfo.o $(ENTRY_OBJ)
$(BINDIR)/nteventlog.exe: $(EVLOG_OBJECTS)
- $(LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(EVLOG_OBJECTS) $(ENTRY_OBJ)
+ $(V_LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(EVLOG_OBJECTS) $(ENTRY_OBJ)
$(BINDIR)/ferrule: $(OBJDIR)/ferrule.o
- $(LD) $(LDFLAGS) -o $@ $<
+ $(V_LD) $(LDFLAGS) -o $@ $<
$(BINDIR)/mod_syslog: $(OBJDIR)/mod_syslog.o
- $(LD) $(LDFLAGS) -o $@ $<
+ $(V_LD) $(LDFLAGS) -o $@ $<
$(BINDIR)/memsup: $(OBJDIR)/memsup.o
- $(LD) $(LDFLAGS) -o $@ $<
+ $(V_LD) $(LDFLAGS) -o $@ $<
$(BINDIR)/cpu_sup: $(OBJDIR)/cpu_sup.o
- $(LD) $(LDFLAGS) -o $@ $< $(CPU_SUP_LIBS)
+ $(V_LD) $(LDFLAGS) -o $@ $< $(CPU_SUP_LIBS)
$(OBJDIR)/%.o: %.c
- $(CC) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_CC) -c -o $@ $(ALL_CFLAGS) $<
$(OBJDIR)/%.o: nteventlog/%.c
- $(CC) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_CC) -c -o $@ $(ALL_CFLAGS) $<
$(OBJDIR)/memsup.o: memsup.h
diff --git a/lib/os_mon/mibs/Makefile b/lib/os_mon/mibs/Makefile
index 3e24c3d373..19f3dc8367 100644
--- a/lib/os_mon/mibs/Makefile
+++ b/lib/os_mon/mibs/Makefile
@@ -67,16 +67,16 @@ OTP_MIBDIR = $(shell if test -d ../../otp_mibs; then echo otp_mibs; \
else echo sasl; fi)
$(SNMP_BIN_TARGET_DIR)/OTP-REG.bin: $(ERL_TOP)/lib/$(OTP_MIBDIR)/mibs/OTP-REG.mib
- $(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
+ $(snmp_verbose)$(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
$(SNMP_BIN_TARGET_DIR)/OTP-TC.bin: $(ERL_TOP)/lib/$(OTP_MIBDIR)/mibs/OTP-TC.mib
- $(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
+ $(snmp_verbose)$(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
$(SNMP_BIN_TARGET_DIR)/OTP-MIB.bin: $(ERL_TOP)/lib/$(OTP_MIBDIR)/mibs/OTP-MIB.mib
- $(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
+ $(snmp_verbose)$(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
v1/%.mib.v1: %.mib
- $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $<
+ $(gen_verbose)$(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $<
$(SNMP_BIN_TARGET_DIR)/OTP-OS-MON-MIB.bin: \
$(SNMP_BIN_TARGET_DIR)/OTP-REG.bin \
diff --git a/lib/os_mon/src/Makefile b/lib/os_mon/src/Makefile
index 864d7a09d4..06b9b9b8ae 100644
--- a/lib/os_mon/src/Makefile
+++ b/lib/os_mon/src/Makefile
@@ -59,7 +59,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(INCLUDE)
+ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(INCLUDE) -Werror
# ----------------------------------------------------
# Targets
@@ -78,10 +78,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
#-------------------------------------------------------
# Special dependencies
diff --git a/lib/otp_mibs/mibs/Makefile b/lib/otp_mibs/mibs/Makefile
index 703c4b3ed4..7f43ef31a6 100644
--- a/lib/otp_mibs/mibs/Makefile
+++ b/lib/otp_mibs/mibs/Makefile
@@ -68,7 +68,7 @@ docs:
# ----------------------------------------------------
v1/%.mib.v1: %.mib
- $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $<
+ $(gen_verbose)$(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $<
# ----------------------------------------------------
# Release Target
diff --git a/lib/otp_mibs/src/Makefile b/lib/otp_mibs/src/Makefile
index 03298d39d5..4f03d0228a 100644
--- a/lib/otp_mibs/src/Makefile
+++ b/lib/otp_mibs/src/Makefile
@@ -84,10 +84,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl
index e4c3ba52be..855bff5fdc 100644
--- a/lib/parsetools/include/yeccpre.hrl
+++ b/lib/parsetools/include/yeccpre.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -36,7 +36,7 @@ parse_and_scan({M, F, A}) ->
-spec format_error(any()) -> [char() | list()].
format_error(Message) ->
- case io_lib:deep_unicode_char_list(Message) of
+ case io_lib:deep_char_list(Message) of
true ->
Message;
_ ->
@@ -164,9 +164,9 @@ yecctoken_location(Token) ->
yecctoken2string({atom, _, A}) -> io_lib:write(A);
yecctoken2string({integer,_,N}) -> io_lib:write(N);
yecctoken2string({float,_,F}) -> io_lib:write(F);
-yecctoken2string({char,_,C}) -> io_lib:write_unicode_char(C);
+yecctoken2string({char,_,C}) -> io_lib:write_char(C);
yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]);
-yecctoken2string({string,_,S}) -> io_lib:write_unicode_string(S);
+yecctoken2string({string,_,S}) -> io_lib:write_string(S);
yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A);
yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]);
yecctoken2string({dot, _}) -> "'.'";
diff --git a/lib/parsetools/src/Makefile b/lib/parsetools/src/Makefile
index 4f199da8ee..92bff00998 100644
--- a/lib/parsetools/src/Makefile
+++ b/lib/parsetools/src/Makefile
@@ -58,7 +58,8 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(ERL_TOP)/lib/stdlib/include
+ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(ERL_TOP)/lib/stdlib/include \
+ -Werror
# ----------------------------------------------------
# Targets
@@ -78,10 +79,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index bbef4053b4..32c513f56c 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -1669,7 +1669,7 @@ quote($\d) -> "\\\\d";
quote($\\) -> "\\\\";
quote(C) when is_integer(C) ->
%% Must remove the $ and get the \'s right.
- case io_lib:write_unicode_char(C) of
+ case io_lib:write_char(C) of
[$$,$\\|Cs] -> "\\\\" ++ Cs;
[$$|Cs] -> Cs
end;
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index dbb7d025ae..2f0f70f39b 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -2494,8 +2494,8 @@ pp_tokens1([T | Ts], Line0, Enc, T0) ->
pp_symbol({var,_,Var}, _Enc) -> Var;
pp_symbol({string,_,String}, latin1) ->
- io_lib:write_unicode_string_as_latin1(String);
-pp_symbol({string,_,String}, _Enc) -> io_lib:write_unicode_string(String);
+ io_lib:write_string_as_latin1(String);
+pp_symbol({string,_,String}, _Enc) -> io_lib:write_string(String);
pp_symbol({_,_,Symbol}, latin1) -> io_lib:fwrite(<<"~p">>, [Symbol]);
pp_symbol({_,_,Symbol}, _Enc) -> io_lib:fwrite(<<"~tp">>, [Symbol]);
pp_symbol({Symbol, _}, _Enc) -> Symbol.
diff --git a/lib/parsetools/src/yeccparser.erl b/lib/parsetools/src/yeccparser.erl
index e4b8b06db5..54f9ba5a58 100644
--- a/lib/parsetools/src/yeccparser.erl
+++ b/lib/parsetools/src/yeccparser.erl
@@ -17,7 +17,7 @@ line_of(Token) ->
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -178,7 +178,7 @@ yecctoken2string({integer,_,N}) -> io_lib:write(N);
yecctoken2string({float,_,F}) -> io_lib:write(F);
yecctoken2string({char,_,C}) -> io_lib:write_char(C);
yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]);
-yecctoken2string({string,_,S}) -> io_lib:write_unicode_string(S);
+yecctoken2string({string,_,S}) -> io_lib:write_string(S);
yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A);
yecctoken2string({_Cat, _, Val}) -> io_lib:write(Val);
yecctoken2string({dot, _}) -> "'.'";
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index 4a0f70ba71..afedd79a4e 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -1,4 +1,4 @@
-%% -*- coding: latin-1 -*-
+%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
@@ -649,7 +649,6 @@ reserved_word('fun') -> true;
reserved_word('if') -> true;
reserved_word('let') -> true;
reserved_word('of') -> true;
-reserved_word('query') -> true;
reserved_word('receive') -> true;
reserved_word('when') -> true;
reserved_word('bnot') -> true;
@@ -889,7 +888,7 @@ otp_10302(Config) when is_list(Config) ->
ok = file:write_file(Filename,<<
"%% coding: UTF-8\n"
- "�"
+ "ä"
>>),
{error,[{_,[{2,leex,cannot_parse}]}],[]} =
leex:file(Filename, Ret),
@@ -897,7 +896,7 @@ otp_10302(Config) when is_list(Config) ->
ok = file:write_file(Filename,<<
"%% coding: UTF-8\n"
"Definitions.\n"
- "�"
+ "ä"
>>),
{error,[{_,[{3,leex,cannot_parse}]}],[]} = leex:file(Filename, Ret),
@@ -908,7 +907,7 @@ otp_10302(Config) when is_list(Config) ->
"L = [{A}-{Z}]\n"
"Z = z\n"
"Rules.\n"
- "{L}+ : {token,{list_to_atom(TokenChars),H�pp}}.\n"
+ "{L}+ : {token,{list_to_atom(TokenChars),Häpp}}.\n"
>>),
{error,[{_,[{7,leex,cannot_parse}]}],[]} = leex:file(Filename, Ret),
@@ -923,7 +922,7 @@ otp_10302(Config) when is_list(Config) ->
"Erlang code.\n"
"-export([t/0]).\n"
"t() ->\n"
- " H�pp\n"
+ " Häpp\n"
>>),
{error,[{_,[{11,leex,cannot_parse}]}],[]} = leex:file(Filename, Ret),
@@ -933,7 +932,7 @@ otp_10302(Config) when is_list(Config) ->
"{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
"Erlang code.\n">>,
LeexPre = filename:join(Dir, "leexinc.hrl"),
- ?line ok = file:write_file(LeexPre, <<"%% coding: UTF-8\n �">>),
+ ?line ok = file:write_file(LeexPre, <<"%% coding: UTF-8\n ä">>),
PreErrors = run_test(Config, Mini, LeexPre),
{error,[{IncludeFile,[{2,leex,cannot_parse}]}],[]} = PreErrors,
"leexinc.hrl" = filename:basename(IncludeFile),
@@ -946,16 +945,16 @@ otp_10302(Config) when is_list(Config) ->
"Z = z\n"
"Rules.\n"
"{L}+ : {token,{list_to_atom(TokenChars),\n"
- "begin Häpp = foo, Häpp end,"
- " 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"}}.\n"
+ "begin Häpp = foo, Häpp end,"
+ " 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"}}.\n"
"Erlang code.\n"
"-export([t/0]).\n"
"t() ->\n"
- " %% Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"\n"
+ " %% Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"\n"
" {ok, [R], 1} = string(\"tip\"),\n"
- " {tip,foo,'Häpp',[1024,66],[246,114,110,95,1024]} = R,\n"
- " Häpp = foo,\n"
- " {tip, Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"} = R,\n"
+ " {tip,foo,'Häpp',[1024,66],[246,114,110,95,1024]} = R,\n"
+ " Häpp = foo,\n"
+ " {tip, Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"} = R,\n"
" ok.\n">>,
default,
ok},
@@ -967,16 +966,16 @@ otp_10302(Config) when is_list(Config) ->
"Z = z\n"
"Rules.\n"
"{L}+ : {token,{list_to_atom(TokenChars),\n"
- "begin H�pp = foo, H�pp end,"
- " 'H�pp',\"\\x{400}B\",\"örn_Ѐ\"}}.\n"
+ "begin Häpp = foo, Häpp end,"
+ " 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"}}.\n"
"Erlang code.\n"
"-export([t/0]).\n"
"t() ->\n"
- " %% H�pp, 'H�pp',\"\\x{400}B\",\"örn_Ѐ\"\n"
+ " %% Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"\n"
" {ok, [R], 1} = string(\"tip\"),\n"
- " {tip,foo,'H�pp',[1024,66],[195,182,114,110,95,208,128]} = R,\n"
- " H�pp = foo,\n"
- " {tip, H�pp, 'H�pp',\"\\x{400}B\",\"örn_Ѐ\"} = R,\n"
+ " {tip,foo,'Häpp',[1024,66],[195,182,114,110,95,208,128]} = R,\n"
+ " Häpp = foo,\n"
+ " {tip, Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"} = R,\n"
" ok.\n">>,
default,
ok}],
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
index c306dbe833..3d66a2a525 100644
--- a/lib/parsetools/test/yecc_SUITE.erl
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -1,8 +1,8 @@
-%% -*- coding: latin-1 -*-
+%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-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
@@ -1824,7 +1824,7 @@ otp_10302(Config) when is_list(Config) ->
Filename = filename:join(Dir, "OTP-10302.yrl"),
Ret = [return, {report, true}],
Mini1 = <<"%% coding: utf-8
- Nonterminals H�pp.
+ Nonterminals Häpp.
nt -> t.">>,
ok = file:write_file(Filename, Mini1),
%% This could (and should) be refined:
@@ -1842,7 +1842,7 @@ otp_10302(Config) when is_list(Config) ->
Erlang code.
t() ->
- H�pp.">>,
+ Häpp.">>,
ok = file:write_file(Filename, Mini2),
{error,[{Filename,[{11,Mod2,Err2}]}],[]} =
yecc:file(Filename, Ret),
@@ -1858,10 +1858,10 @@ otp_10302(Config) when is_list(Config) ->
Erlang code.
t() ->
- H�pp.">>,
+ Häpp.">>,
ok = file:write_file(Filename, Mini3),
YeccPre = filename:join(Dir, "yeccpre.hrl"),
- ok = file:write_file(YeccPre, [<<"%% coding: UTF-8\n �.\n">>]),
+ ok = file:write_file(YeccPre, [<<"%% coding: UTF-8\n ä.\n">>]),
Inc = [{includefile,YeccPre}],
{error,[{_,[{2,yecc,cannot_parse}]}],[]} =
yecc:file(Filename, Inc ++ Ret),
@@ -1870,9 +1870,9 @@ otp_10302(Config) when is_list(Config) ->
<<"%% coding: UTF-8
Nonterminals Hopp.
Terminals t.
- Rootsymbol \"örn_Ѐ\".
+ Rootsymbol \"örn_Ѐ\".
Hopp -> t : '$1'.">>),
- {error,[{Filename,[{4,yecc,{bad_symbol,"�rn_"++[1024]}}]}],[]} =
+ {error,[{Filename,[{4,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} =
yecc:file(Filename, Ret),
ok = file:write_file(Filename,
@@ -1880,9 +1880,9 @@ otp_10302(Config) when is_list(Config) ->
Nonterminals Hopp.
Terminals t.
Rootsymbol Hopp.
- Endsymbol \"örn_Ѐ\".
+ Endsymbol \"örn_Ѐ\".
Hopp -> t : '$1'.">>),
- {error,[{Filename,[{5,yecc,{bad_symbol,"�rn_"++[1024]}}]}],[]} =
+ {error,[{Filename,[{5,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} =
yecc:file(Filename, Ret),
ok = file:write_file(Filename,
@@ -1890,9 +1890,9 @@ otp_10302(Config) when is_list(Config) ->
Nonterminals Hopp.
Terminals t.
Rootsymbol Hopp.
- Expect \"örn_Ѐ\".
+ Expect \"örn_Ѐ\".
Hopp -> t : '$1'.">>),
- {error,[{Filename,[{5,yecc,{bad_symbol,"�rn_"++[1024]}}]}],[]} =
+ {error,[{Filename,[{5,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} =
yecc:file(Filename, Ret),
ok = file:write_file(Filename,
@@ -1900,25 +1900,25 @@ otp_10302(Config) when is_list(Config) ->
Nonterminals Hopp.
Terminals t.
Rootsymbol Hopp.
- States \"örn_Ѐ\".
+ States \"örn_Ѐ\".
Hopp -> t : '$1'.">>),
- {error,[{Filename,[{5,yecc,{bad_symbol,"�rn_"++[1024]}}]}],[]} =
+ {error,[{Filename,[{5,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} =
yecc:file(Filename, Ret),
Ts = [{otp_10302_1,<<"
%% coding: UTF-8
- Header \"%% örn_Ѐ\" \"%% \\x{400}B\".
- Nonterminals Häpp list.
+ Header \"%% örn_Ѐ\" \"%% \\x{400}B\".
+ Nonterminals Häpp list.
Terminals element.
- Rootsymbol Häpp.
+ Rootsymbol Häpp.
- Häpp -> list : '$1'.
+ Häpp -> list : '$1'.
list -> element : '$1'.
list -> list element :
begin
- Häpp = foo,
- {Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"}
+ Häpp = foo,
+ {Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"}
end.
Erlang code.
@@ -1928,24 +1928,24 @@ otp_10302(Config) when is_list(Config) ->
t() ->
L = [{element, 1}, {element,2}],
{ok, R} = parse(L),
- Häpp = foo,
+ Häpp = foo,
{_,_,[1024,66],[246,114,110,95,1024]} = R,
- {Häpp,'Häpp',\"\\x{400}B\",\"örn_Ѐ\"} = R,
+ {Häpp,'Häpp',\"\\x{400}B\",\"örn_Ѐ\"} = R,
ok.
">>,default,ok},
{otp_10302_2,<<"
%% coding: Latin-1
- Nonterminals H�pp list.
+ Nonterminals Häpp list.
Terminals element.
- Rootsymbol H�pp.
+ Rootsymbol Häpp.
- H�pp -> list : '$1'.
+ Häpp -> list : '$1'.
list -> element : '$1'.
list -> list element :
begin
- H�pp = foo,
- {H�pp, 'H�pp',\"\\x{400}B\",\"örn_Ѐ\"}
+ Häpp = foo,
+ {Häpp, 'Häpp',\"\\x{400}B\",\"örn_Ѐ\"}
end.
Erlang code.
@@ -1955,9 +1955,9 @@ otp_10302(Config) when is_list(Config) ->
t() ->
L = [{element, 1}, {element,2}],
{ok, R} = parse(L),
- H�pp = foo,
+ Häpp = foo,
{_,_,[1024,66],[195,182,114,110,95,208,128]} = R,
- {H�pp,'H�pp',\"\\x{400}B\",\"örn_Ѐ\"} = R,
+ {Häpp,'Häpp',\"\\x{400}B\",\"örn_Ѐ\"} = R,
ok.
">>,default,ok}],
run(Config, Ts),
diff --git a/lib/percept/src/Makefile b/lib/percept/src/Makefile
index 253a8c2da3..6bf0af9dc6 100644
--- a/lib/percept/src/Makefile
+++ b/lib/percept/src/Makefile
@@ -80,10 +80,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/pman/src/Makefile b/lib/pman/src/Makefile
index fa01fe7238..eb0413bdbc 100644
--- a/lib/pman/src/Makefile
+++ b/lib/pman/src/Makefile
@@ -85,10 +85,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile
index 763b788e53..a4e36c7293 100644
--- a/lib/public_key/asn1/Makefile
+++ b/lib/public_key/asn1/Makefile
@@ -66,7 +66,7 @@ EBIN = ../ebin
EXTRA_ERLC_FLAGS =
ERL_COMPILE_FLAGS += $(EXTRA_ERLC_FLAGS)
-ASN_FLAGS = -bber +der +compact_bit_string +noobj +asn1config +inline
+ASN_FLAGS = -bber +der +compact_bit_string +noobj +asn1config
# ----------------------------------------------------
# Targets
@@ -81,10 +81,10 @@ clean:
docs:
%.erl %.hrl: %.set.asn
- erlc $(ASN_FLAGS) $<
+ $(asn_verbose)erlc $(ASN_FLAGS) $<
$(INCLUDE)/%.hrl: %.hrl
- cp -p $< $@
+ $(gen_verbose)cp -p $< $@
# ----------------------------------------------------
# Release Target
@@ -119,6 +119,6 @@ OTP-PUB-KEY.asn1db: PKIX1Algorithms88.asn1 \
OTP-PKIX.asn1
$(EBIN)/PKCS-FRAME.beam: PKCS-FRAME.erl PKCS-FRAME.hrl
-PKCS-FRAME.erl PKCS-FRAME.hrl: PKCS-FRAME.asn1db
+PKCS-FRAME.erl PKCS-FRAME.hrl: PKCS-FRAME.asn1db
PKCS-FRAME.asn1db: PKCS5v2-0.asn1\
PKCS-8.asn1\
diff --git a/lib/public_key/asn1/OTP-PUB-KEY.asn1config b/lib/public_key/asn1/OTP-PUB-KEY.asn1config
index 86f4c54748..9ca30564af 100644
--- a/lib/public_key/asn1/OTP-PUB-KEY.asn1config
+++ b/lib/public_key/asn1/OTP-PUB-KEY.asn1config
@@ -1,2 +1,3 @@
{exclusive_decode,{'OTP-PUB-KEY',
- [{decode_TBSCert_exclusive,['Certificate',[{tbsCertificate,undecoded}]]}]}}.
+ [{decode_TBSCert_exclusive,['Certificate',[{tbsCertificate,undecoded}]]},
+ {decode_TBSCertList_exclusive,['CertificateList',[{tbsCertList,undecoded}]]}]}}.
diff --git a/lib/public_key/asn1/PKCS-10.asn1 b/lib/public_key/asn1/PKCS-10.asn1
index 333104d230..5ada81c257 100644
--- a/lib/public_key/asn1/PKCS-10.asn1
+++ b/lib/public_key/asn1/PKCS-10.asn1
@@ -20,12 +20,36 @@ IMPORTS
ATTRIBUTE
FROM InformationFramework informationFramework
- Name
+ Name, Extensions, DirectoryString
FROM PKIX1Explicit88 --InformationFramework informationFramework
ALGORITHM
FROM PKCS-7; --AuthenticationFramework authenticationFramework;
+-- start inlined from PKCS-9
+
+--pkcs-9-ub-pkcs9String INTEGER ::= 255
+--pkcs-9-ub-challengePassword INTEGER ::= pkcs-9-ub-pkcs9String
+pkcs-9-at-challengePassword OBJECT IDENTIFIER ::= {pkcs-9 7}
+
+challengePassword ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString --{pkcs-9-ub-challengePassword}
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-challengePassword
+}
+
+pkcs-9-at-extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14}
+
+extensionRequest ATTRIBUTE ::= {
+ WITH SYNTAX ExtensionRequest
+ SINGLE VALUE TRUE
+ ID pkcs-9-at-extensionRequest
+}
+
+ExtensionRequest ::= Extensions
+
+-- end inlined from PKCS-9
+
-- Certificate requests
CertificationRequestInfo ::= SEQUENCE {
diff --git a/lib/public_key/doc/src/cert_records.xml b/lib/public_key/doc/src/cert_records.xml
index b1d2a05200..ac4b4e4489 100644
--- a/lib/public_key/doc/src/cert_records.xml
+++ b/lib/public_key/doc/src/cert_records.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -34,12 +34,11 @@
<file>cert_records.xml</file>
</header>
- <p>This chapter briefly describes erlang records derived from asn1
- specifications used to handle X509 certificates. The intent is to
- describe the data types and not to specify the meaning of each
+ <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
- href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</url>. Also
- descirbed is <p>CertificationRequest</p> that is defined by
+ href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</url> and
<url href="http://www.rsa.com/rsalabs/node.asp?id=2124">PKCS-10</url>.
</p>
@@ -48,7 +47,7 @@
<code> -include_lib("public_key/include/public_key.hrl"). </code>
- <p>The used asn1 specifications are available <c>asn1</c> subdirectory
+ <p>The used ASN1 specifications are available <c>asn1</c> subdirectory
of the application <c>public_key</c>.
</p>
@@ -62,7 +61,7 @@
follows here.</p>
<p><c>oid() - a tuple of integers
- as generated by the asn1 compiler.</c></p>
+ as generated by the ASN1 compiler.</c></p>
<p><c>time() = uct_time() | general_time()</c></p>
@@ -101,7 +100,7 @@
#'Certificate'{
tbsCertificate, % #'TBSCertificate'{}
signatureAlgorithm, % #'AlgorithmIdentifier'{}
- signature % {0, binary()} - asn1 compact bitstring
+ signature % {0, binary()} - ASN1 compact bitstring
}.
#'TBSCertificate'{
@@ -119,7 +118,7 @@
#'AlgorithmIdentifier'{
algorithm, % oid()
- parameters % asn1_der_encoded()
+ parameters % der_encoded()
}.
</code>
@@ -127,7 +126,7 @@
#'OTPCertificate'{
tbsCertificate, % #'OTPTBSCertificate'{}
signatureAlgorithm, % #'SignatureAlgorithm'
- signature % {0, binary()} - asn1 compact bitstring
+ signature % {0, binary()} - ASN1 compact bitstring
}.
#'OTPTBSCertificate'{
@@ -290,7 +289,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
#'Extension'{
extnID, % id_extensions() | oid()
critical, % boolean()
- extnValue % asn1_der_encoded()
+ extnValue % der_encoded()
}.
</code>
@@ -372,7 +371,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
<row>
<cell align="left" valign="middle">id-ce-cRLDistributionPoints</cell>
- <cell align="left" valign="middle">#'DistributionPoint'{}</cell>
+ <cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
</row>
<row>
@@ -461,7 +460,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
#'Attribute'{
type, % oid()
- values % [asn1_der_encoded()]
+ values % [der_encoded()]
}).
#'BasicConstraints'{
@@ -486,9 +485,10 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
}).
#'DistributionPoint'{
- distributionPoint, % general_name() | [#AttributeTypeAndValue{}]
+ distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
+ [#AttributeTypeAndValue{}]}
reasons, % [dist_reason()]
- cRLIssuer % general_name()
+ cRLIssuer % [general_name()]
}).
</code>
@@ -530,7 +530,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
#'CertificateList'{
tbsCertList, % #'TBSCertList{}
signatureAlgorithm, % #'AlgorithmIdentifier'{}
- signature % {0, binary()} - asn1 compact bitstring
+ signature % {0, binary()} - ASN1 compact bitstring
}).
#'TBSCertList'{
@@ -589,7 +589,8 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
<code>
#'IssuingDistributionPoint'{
- distributionPoint, % general_name() | [#AttributeTypeAndValue'{}]
+ distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
+ [#AttributeTypeAndValue'{}]}
onlyContainsUserCerts, % boolean()
onlyContainsCACerts, % boolean()
onlySomeReasons, % [dist_reason()]
@@ -641,30 +642,35 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
#'CertificationRequest'{
certificationRequestInfo #'CertificationRequestInfo'{},
signatureAlgorithm #'CertificationRequest_signatureAlgorithm'{}}.
- signature {0, binary()} - asn1 compact bitstring
+ signature {0, binary()} - ASN1 compact bitstring
}
#'CertificationRequestInfo'{
version atom(),
subject {rdnSequence, [#AttributeTypeAndValue'{}]} ,
subjectPKInfo #'CertificationRequestInfo_subjectPKInfo'{},
- attributes [#AttributeTypeAndValue'{}]
+ attributes [#'AttributePKCS-10' {}]
}
#'CertificationRequestInfo_subjectPKInfo'{
algorithm #'CertificationRequestInfo_subjectPKInfo_algorithm'{}
- subjectPublicKey {0, binary()} - asn1 compact bitstring
+ subjectPublicKey {0, binary()} - ASN1 compact bitstring
}
#'CertificationRequestInfo_subjectPKInfo_algorithm'{
algorithm = oid(),
- parameters = asn1_der_encoded()
+ parameters = der_encoded()
}
#'CertificationRequest_signatureAlgorithm'{
algorithm = oid(),
- parameters = asn1_der_encoded()
- }
+ parameters = der_encoded()
+ }
+
+#'AttributePKCS-10'{
+ type = oid(),
+ values = [der_encoded()]
+}
</code>
</section>
diff --git a/lib/public_key/doc/src/introduction.xml b/lib/public_key/doc/src/introduction.xml
index e0dd5603f7..4b59cc2245 100644
--- a/lib/public_key/doc/src/introduction.xml
+++ b/lib/public_key/doc/src/introduction.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -36,11 +36,13 @@
<section>
<title>Purpose</title>
- <p> This application provides an API to public key infrastructure
- from <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC
- 5280</url> (X.509 certificates) and public key formats defined by
- the <url href="http://www.rsa.com/rsalabs/node.asp?id=2124">
- PKCS-standard</url></p>
+ <p> public_key deals with public key related file formats, digital
+ signatures and <url href="http://www.ietf.org/rfc/rfc5280.txt">
+ X-509 certificates</url>. It is a library application that
+ provides encode/decode, sign/verify, encrypt/decrypt and similar
+ functionality, it does not read or write files it expects or returns
+ file contents or partial file contents as binaries.
+ </p>
</section>
<section>
@@ -51,9 +53,9 @@
<section>
<title>Performance tips</title>
- <p>The public_key decode and encode functions will try to use the nifs
- which are in the asn1 compilers runtime modules if they can be found.
- So for the best performance you want to have the asn1 application in the
+ <p>The public_key decode and encode functions will try to use the NIFs
+ which are in the ASN1 compilers runtime modules if they can be found.
+ So for the best performance you want to have the ASN1 application in the
path of your system. </p>
</section>
diff --git a/lib/public_key/doc/src/part.xml b/lib/public_key/doc/src/part.xml
index ea3123b5bd..08fa4eec58 100644
--- a/lib/public_key/doc/src/part.xml
+++ b/lib/public_key/doc/src/part.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -32,8 +32,10 @@
</header>
<description>
<p> This application provides an API to public key infrastructure
- from RFC 3280 (X.509 certificates) and some public key formats defined
- by the PKCS-standard. </p>
+ from <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC
+ 5280</url> (X.509 certificates) and public key formats defined by
+ the <url href="http://www.rsa.com/rsalabs/node.asp?id=2124">
+ PKCS-standard</url></p>
</description>
<xi:include href="introduction.xml"/>
<xi:include href="public_key_records.xml"/>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index b240d53571..5864de2d57 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -33,12 +33,30 @@
<module>public_key</module>
<modulesummary> API module for public key infrastructure.</modulesummary>
<description>
- <p>This module provides functions to handle public key infrastructure
- from <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</url>- X.509 certificates and some parts of the PKCS-standard.
+ <p>This module provides functions to handle public key infrastructure. It can
+ encode/decode different file formats (PEM, openssh), sign and verify digital signatures and validate
+ certificate paths and certificate revocation lists.
</p>
</description>
<section>
+ <title>public_key</title>
+
+ <list type="bulleted">
+ <item>public_key requires the crypto application.</item>
+
+ <item>Supports <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280 </url> -
+ Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile </item>
+ <item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2125"> PKCS-1 </url> - RSA Cryptography Standard </item>
+ <item>Supports <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> DSA</url>- Digital Signature Algorithm</item>
+ <item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2126"> PKCS-3 </url> - Diffie-Hellman Key Agreement Standard </item>
+ <item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2127"> PKCS-5</url> - Password-Based Cryptography Standard </item>
+ <item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2130"> PKCS-8</url> - Private-Key Information Syntax Standard</item>
+ <item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2132"> PKCS-10</url> - Certification Request Syntax Standard</item>
+ </list>
+ </section>
+
+ <section>
<title>COMMON DATA TYPES </title>
<note><p>All records used in this manual
@@ -58,7 +76,9 @@
<p><code>boolean() = true | false</code></p>
- <p><code>string = [bytes()]</code></p>
+ <p><code>string() = [bytes()]</code></p>
+
+ <p><code>der_encoded() = binary()</code></p>
<p><code>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey' |
'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo' |
@@ -87,6 +107,9 @@
<p><code> dss_digest_type() = 'sha' </code></p>
+ <p><code> crl_reason() = unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise
+ </code></p>
+
<p><code> ssh_file() = openssh_public_key | rfc4716_public_key |
known_hosts | auth_keys </code></p>
@@ -151,7 +174,7 @@
<func>
<name>der_decode(Asn1type, Der) -> term()</name>
- <fsummary> Decodes a public key asn1 der encoded entity.</fsummary>
+ <fsummary> Decodes a public key ASN.1 DER encoded entity.</fsummary>
<type>
<v>Asn1Type = atom()</v>
<d> ASN.1 type present in the public_key applications
@@ -159,7 +182,7 @@
<v>Der = der_encoded()</v>
</type>
<desc>
- <p> Decodes a public key ASN.1 der encoded entity.</p>
+ <p> Decodes a public key ASN.1 DER encoded entity.</p>
</desc>
</func>
@@ -181,14 +204,14 @@
<func>
<name>pem_decode(PemBin) -> [pem_entry()]</name>
<fsummary>Decode PEM binary data and return
- entries as ASN.1 der encoded entities. </fsummary>
+ entries as ASN.1 DER encoded entities. </fsummary>
<type>
<v>PemBin = binary()</v>
<d>Example {ok, PemBin} = file:read_file("cert.pem").</d>
</type>
<desc>
<p>Decode PEM binary data and return
- entries as ASN.1 der encoded entities.</p>
+ entries as ASN.1 DER encoded entities.</p>
</desc>
</func>
@@ -212,8 +235,8 @@
<v> Password = string() </v>
</type>
<desc>
- <p>Decodes a pem entry. pem_decode/1 returns a list of pem
- entries. Note that if the pem entry is of type
+ <p>Decodes a PEM entry. pem_decode/1 returns a list of PEM
+ entries. Note that if the PEM entry is of type
'SubjectPublickeyInfo' it will be further decoded to an
rsa_public_key() or dsa_public_key().</p>
</desc>
@@ -222,7 +245,7 @@
<func>
<name>pem_entry_encode(Asn1Type, Entity) -> pem_entry()</name>
<name>pem_entry_encode(Asn1Type, Entity, {CipherInfo, Password}) -> pem_entry()</name>
- <fsummary> Creates a pem entry that can be fed to pem_encode/1.</fsummary>
+ <fsummary> Creates a PEM entry that can be fed to pem_encode/1.</fsummary>
<type>
<v>Asn1Type = pki_asn1_type()</v>
<v>Entity = term()</v>
@@ -236,7 +259,7 @@
<v>Password = string()</v>
</type>
<desc>
- <p> Creates a pem entry that can be feed to pem_encode/1.</p>
+ <p> Creates a PEM entry that can be feed to pem_encode/1.</p>
</desc>
</func>
@@ -266,12 +289,12 @@
<func>
<name>pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{}</name>
- <fsummary> Decodes an ASN.1 der encoded pkix x509 certificate.</fsummary>
+ <fsummary> Decodes an ASN.1 DER encoded PKIX x509 certificate.</fsummary>
<type>
<v>Cert = der_encoded()</v>
</type>
<desc>
- <p>Decodes an ASN.1 der encoded pkix certificate. The otp option
+ <p>Decodes an ASN.1 DER encoded PKIX certificate. The otp option
will use the customized ASN.1 specification OTP-PKIX.asn1 for
decoding and also recursively decode most of the standard
parts.</p>
@@ -280,14 +303,15 @@
<func>
<name>pkix_encode(Asn1Type, Entity, otp | plain) -> der_encoded()</name>
- <fsummary>Der encodes a pkix x509 certificate or part of such a
+ <fsummary>DER encodes a PKIX x509 certificate or part of such a
certificate.</fsummary>
<type>
<v>Asn1Type = atom()</v>
<d>The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either .</d>
+ <v>Entity = #'Certificate'{} | #'OTPCertificate'{} | a valid subtype</v>
</type>
<desc>
- <p>Der encodes a pkix x509 certificate or part of such a
+ <p>DER encodes a PKIX x509 certificate or part of such a
certificate. This function must be used for encoding certificates or parts of certificates
that are decoded/created in the otp format, whereas for the plain format this
function will directly call der_encode/2. </p>
@@ -357,18 +381,104 @@
</desc>
</func>
- <!-- <func> -->
- <!-- <name>pkix_path_validation()</name> -->
- <!-- <fsummary> Performs a basic path validation according to RFC 5280.</fsummary> -->
- <!-- <type> -->
- <!-- <v></v> -->
- <!-- </type> -->
- <!-- <desc> -->
- <!-- <p> Performs a basic path validation according to RFC 5280.</p> -->
- <!-- </desc> -->
- <!-- </func> -->
+ <func>
+ <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> CertChain = [der_encode()]</v>
+ <d>A list of DER encoded certificates in trust order ending with the peer certificate.</d>
+ <v> Options = proplists:proplists()</v>
+ <v>PublicKeyInfo = {?'rsaEncryption' | ?'id-dsa',
+ 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>
+ </type>
+ <desc>
+ <p>
+ 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
+ from the supplied <c>verify_fun</c>
+ </p>
+
+ <taglist>
+ <p> Available options are: </p>
+
+ <tag>{verify_fun, fun()}</tag>
+ <item>
+ <p>The fun should be defined as:</p>
+
+ <code>
+fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
+ {extension, #'Extension'{}},
+ InitialUserState :: term()) ->
+ {valid, UserState :: term()} | {valid_peer, UserState :: term()} |
+ {fail, Reason :: term()} | {unknown, UserState :: term()}.
+ </code>
+
+ <p>If the verify callback fun returns {fail, Reason}, the
+ verification process is immediately stopped. If the verify
+ callback fun returns {valid, UserState}, the verification
+ process is continued, this can be used to accept specific path
+ validation errors such as <c>selfsigned_peer</c> as well as
+ verifying application specific extensions. If called with an
+ extension unknown to the user application the return value
+ {unknown, UserState} should be used.</p>
+
+ </item>
+ <tag>{max_path_length, integer()}</tag>
+ <item>
+ The <c>max_path_length</c> is the maximum number of non-self-issued
+ intermediate certificates that may follow the peer certificate
+ in a valid certification path. So if <c>max_path_length</c> is 0 the PEER must
+ be signed by the trusted ROOT-CA directly, if 1 the path can
+ be PEER, CA, ROOT-CA, if it is 2 PEER, CA, CA, ROOT-CA and so
+ on.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+
+ <func>
+ <name>pkix_crls_validate(OTPCertificate, DPAndCRLs, Options) -> CRLStatus()</name>
+ <fsummary> Performs CRL validation.</fsummary>
+ <type>
+ <v> OTPCertificate = #'OTPCertificate'{}</v>
+ <v> DPAndCRLs = [{DP::#'DistributionPoint'{} ,CRL::#'CertificateList'{}}] </v>
+ <v> Options = proplists:proplists()</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
+ </seealso></p>
+ <taglist>
+ <p> Available options are: </p>
+ <tag>{update_crl, fun()}</tag>
+ <item>
+ <p>The fun has the following type spec:</p>
+
+ <code> fun(#'DistributionPoint'{}, #'CertificateList'{}) -> #'CertificateList'{}</code>
+
+ <p>The fun should use the information in the distribution point to acesses
+ the lates possible version of the CRL. If this fun is not specified
+ public_key will use the default implementation:
+ </p>
+ <code> fun(_DP, CRL) -> CRL end</code>
+ </item>
+ </taglist>
+ </desc>
+ </func>
-
<func>
<name>pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encode()</name>
<fsummary>Signs certificate.</fsummary>
@@ -389,7 +499,7 @@
<v>Key = rsa_public_key() | dsa_public_key()</v>
</type>
<desc>
- <p> Verify pkix x.509 certificate signature.</p>
+ <p> Verify PKIX x.509 certificate signature.</p>
</desc>
</func>
diff --git a/lib/public_key/doc/src/public_key_records.xml b/lib/public_key/doc/src/public_key_records.xml
index bb90290266..e39ad0ec64 100644
--- a/lib/public_key/doc/src/public_key_records.xml
+++ b/lib/public_key/doc/src/public_key_records.xml
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2008</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -34,7 +34,7 @@
<file>public_key_records.xml</file>
</header>
- <p>This chapter briefly describes Erlang records derived from asn1
+ <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>
@@ -67,9 +67,9 @@
}.
#'OtherPrimeInfo'{
- prime, % integer()
- exponent, % integer()
- coefficient % integer()
+ prime, % integer()
+ exponent, % integer()
+ coefficient % integer()
}.
</code>
diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml
index f0eaeb8654..5d9f1536d9 100644
--- a/lib/public_key/doc/src/using_public_key.xml
+++ b/lib/public_key/doc/src/using_public_key.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2011</year><year>2011</year>
+ <year>2011</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,7 +21,7 @@
</legalnotice>
- <title>Using the public_key API</title>
+ <title>Getting Started</title>
<file>using_public_key.xml</file>
</header>
@@ -40,7 +40,7 @@
<section>
<title>PEM files</title>
- <p> Pulic key data (keys, certificates etc) may be stored in PEM format. PEM files
+ <p> Public key data (keys, certificates etc) may be stored in PEM format. PEM files
comes from the Private Enhanced Mail Internet standard and has a
structure that looks like this:</p>
@@ -63,7 +63,7 @@
<code>1> {ok, PemBin} = file:read_file("dsa.pem").
{ok,&lt;&lt;"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...&gt;&gt;}</code>
- <p>This PEM file only has one entry a private DSA key.</p>
+ <p>This PEM file only has one entry, a private DSA key.</p>
<code>2> [DSAEntry] = public_key:pem_decode(PemBin).
[{'DSAPrivateKey',&lt;&lt;48,130,1,187,2,1,0,2,129,129,0,183,
179,230,217,37,99,144,157,21,228,204,
diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl
index 90ca7256ea..4d1d510f29 100644
--- a/lib/public_key/include/public_key.hrl
+++ b/lib/public_key/include/public_key.hrl
@@ -68,17 +68,32 @@
-record(revoke_state, {
reasons_mask,
cert_status,
- interim_reasons_mask
+ interim_reasons_mask,
+ valid_ext
}).
+
+-define(unspecified, 0).
+-define(keyCompromise, 1).
+-define(cACompromise, 2).
+-define(affiliationChanged, 3).
+-define(superseded, 4).
+-define(cessationOfOperation, 5).
+-define(certificateHold, 6).
+-define(removeFromCRL, 8).
+-define(privilegeWithdrawn, 9).
+-define(aACompromise, 10).
+
-type public_key() :: rsa_public_key() | dsa_public_key().
-type rsa_public_key() :: #'RSAPublicKey'{}.
-type rsa_private_key() :: #'RSAPrivateKey'{}.
-type dsa_private_key() :: #'DSAPrivateKey'{}.
-type dsa_public_key() :: {integer(), #'Dss-Parms'{}}.
+-type der_encoded() :: binary().
+-type decrypt_der() :: binary().
-type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' | 'RSAPublicKey'
| 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter'
- | 'SubjectPublicKeyInfo' | 'CertificationRequest'.
+ | 'SubjectPublicKeyInfo' | 'CertificationRequest' | 'CertificateList'.
-type pem_entry() :: {pki_asn1_type(), binary(), %% DER or Encrypted DER
not_encrypted | {Cipher :: string(), Salt :: binary()}}.
-type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl
diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile
index d5cd13d81a..b8ad68ecc7 100644
--- a/lib/public_key/src/Makefile
+++ b/lib/public_key/src/Makefile
@@ -44,7 +44,8 @@ MODULES = \
pubkey_ssh \
pubkey_pbe \
pubkey_cert \
- pubkey_cert_records
+ pubkey_cert_records \
+ pubkey_crl
HRL_FILES = $(INCLUDE)/public_key.hrl
@@ -91,10 +92,10 @@ clean:
docs:
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index f9e2025479..f53c94b334 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -26,10 +26,11 @@
-export([init_validation_state/3, prepare_for_next_cert/2,
validate_time/3, validate_signature/6,
validate_issuer/4, validate_names/6,
- validate_revoked_status/3, validate_extensions/4,
+ validate_extensions/4,
normalize_general_name/1, digest_type/1, is_self_signed/1,
is_issuer/2, issuer_id/2, is_fixed_dh_cert/1,
- verify_data/1, verify_fun/4]).
+ verify_data/1, verify_fun/4, select_extension/2, match_name/3,
+ extensions_list/1, cert_auth_key_id/1, time_str_2_gregorian_sec/1]).
-define(NULL, 0).
@@ -204,17 +205,6 @@ validate_names(OtpCert, Permit, Exclude, Last, UserState, VerifyFun) ->
end.
%%--------------------------------------------------------------------
--spec validate_revoked_status(#'OTPCertificate'{}, term(), fun()) ->
- term().
-%%
-%% Description: Check if certificate has been revoked.
-%%--------------------------------------------------------------------
-validate_revoked_status(_OtpCert, UserState, _VerifyFun) ->
- %% TODO: Implement or leave for application?!
- %% valid |
- %% throw({bad_cert, cert_revoked})
- UserState.
-%%--------------------------------------------------------------------
-spec validate_extensions(#'OTPCertificate'{}, #path_validation_state{},
term(), fun())->
{#path_validation_state{}, UserState :: term()}.
@@ -256,8 +246,10 @@ is_self_signed(#'OTPCertificate'{tbsCertificate=
%%
%% Description: Checks if <Issuer> issued <Candidate>.
%%--------------------------------------------------------------------
-is_issuer({rdnSequence, Issuer}, {rdnSequence, Candidate}) ->
- is_dir_name(Issuer, Candidate, true).
+is_issuer({rdnSequence, _} = Issuer, {rdnSequence, _} = Candidate) ->
+ {rdnSequence, IssuerDirName} = normalize_general_name(Issuer),
+ {rdnSequence, CandidateDirName} = normalize_general_name(Candidate),
+ is_dir_name(IssuerDirName, CandidateDirName, true).
%%--------------------------------------------------------------------
-spec issuer_id(#'OTPCertificate'{}, self | other) ->
{ok, {integer(), term()}} | {error, issuer_not_found}.
@@ -307,9 +299,9 @@ verify_fun(Otpcert, Result, UserState0, VerifyFun) ->
{valid,UserState} ->
UserState;
{fail, Reason} ->
- case Result of
+ case Reason of
{bad_cert, _} ->
- throw(Result);
+ throw(Reason);
_ ->
throw({bad_cert, Reason})
end;
@@ -321,6 +313,91 @@ verify_fun(Otpcert, Result, UserState0, VerifyFun) ->
UserState
end
end.
+%%--------------------------------------------------------------------
+-spec select_extension(Oid ::tuple(),[#'Extension'{}]) ->
+ #'Extension'{} | undefined.
+%%
+%% Description: Extracts a specific extension from a list of extensions.
+%%--------------------------------------------------------------------
+select_extension(_, []) ->
+ undefined;
+select_extension(Id, [#'Extension'{extnID = Id} = Extension | _]) ->
+ Extension;
+select_extension(Id, [_ | Extensions]) ->
+ select_extension(Id, Extensions).
+
+%%--------------------------------------------------------------------
+%% TODO:
+%%
+%% Description:
+%%--------------------------------------------------------------------
+match_name(rfc822Name, Name, [PermittedName | Rest]) ->
+ match_name(fun is_valid_host_or_domain/2, Name, PermittedName, Rest);
+
+match_name(directoryName, DirName, [PermittedName | Rest]) ->
+ match_name(fun is_rdnSeq/2, DirName, PermittedName, Rest);
+
+match_name(uniformResourceIdentifier, URI, [PermittedName | Rest]) ->
+ case split_uri(URI) of
+ incomplete ->
+ false;
+ {_, _, Host, _, _} ->
+ match_name(fun is_valid_host_or_domain/2, Host,
+ PermittedName, Rest)
+ end;
+
+match_name(emailAddress, Name, [PermittedName | Rest]) ->
+ Fun = fun(Email, PermittedEmail) ->
+ is_valid_email_address(Email, PermittedEmail,
+ string:tokens(PermittedEmail,"@"))
+ end,
+ match_name(Fun, Name, PermittedName, Rest);
+
+match_name(dNSName, Name, [PermittedName | Rest]) ->
+ Fun = fun(Domain, [$.|Domain]) -> true;
+ (Name1,Name2) ->
+ lists:suffix(string:to_lower(Name2),
+ string:to_lower(Name1))
+ end,
+ match_name(Fun, Name, [$.|PermittedName], Rest);
+
+match_name(x400Address, OrAddress, [PermittedAddr | Rest]) ->
+ match_name(fun is_or_address/2, OrAddress, PermittedAddr, Rest);
+
+match_name(ipAdress, IP, [PermittedIP | Rest]) ->
+ Fun = fun([IP1, IP2, IP3, IP4],
+ [IP5, IP6, IP7, IP8, M1, M2, M3, M4]) ->
+ is_permitted_ip([IP1, IP2, IP3, IP4],
+ [IP5, IP6, IP7, IP8],
+ [M1, M2, M3, M4]);
+ ([IP1, IP2, IP3, IP4, IP5, IP6, IP7, IP8,
+ IP9, IP10, IP11, IP12, IP13, IP14, IP15, IP16],
+ [IP17, IP18, IP19, IP20, IP21, IP22, IP23, IP24,
+ IP25, IP26, IP27, IP28, IP29, IP30, IP31, IP32,
+ M1, M2, M3, M4, M5, M6, M7, M8,
+ M9, M10, M11, M12, M13, M14, M15, M16]) ->
+ is_permitted_ip([IP1, IP2, IP3, IP4, IP5, IP6, IP7, IP8,
+ IP9, IP10, IP11, IP12, IP13,
+ IP14, IP15, IP16],
+ [IP17, IP18, IP19, IP20, IP21, IP22, IP23,
+ IP24,IP25, IP26, IP27, IP28, IP29, IP30,
+ IP31, IP32],
+ [M1, M2, M3, M4, M5, M6, M7, M8, M9, M10,
+ M11, M12, M13, M14, M15, M16]);
+ (_,_) ->
+ false
+ end,
+ match_name(Fun, IP, PermittedIP, Rest).
+
+match_name(Fun, Name, PermittedName, []) ->
+ Fun(Name, PermittedName);
+match_name(Fun, Name, PermittedName, [Head | Tail]) ->
+ case Fun(Name, PermittedName) of
+ true ->
+ true;
+ false ->
+ match_name(Fun, Name, Head, Tail)
+ end.
%%--------------------------------------------------------------------
%%% Internal functions
@@ -332,7 +409,7 @@ do_normalize_general_name(Issuer) ->
(Atter) ->
Atter
end,
- lists:sort(lists:map(Normalize, Issuer)).
+ lists:map(Normalize, Issuer).
%% See rfc3280 4.1.2.6 Subject: regarding emails.
extract_email({rdnSequence, List}) ->
@@ -477,13 +554,6 @@ strip_spaces(String) ->
string:tokens(String, " ")),
string:strip(NewString).
-select_extension(_, []) ->
- undefined;
-select_extension(Id, [#'Extension'{extnID = Id} = Extension | _]) ->
- Extension;
-select_extension(Id, [_ | Extensions]) ->
- select_extension(Id, Extensions).
-
%% No extensions present
validate_extensions(OtpCert, asn1_NOVALUE, ValidationState, ExistBasicCon,
SelfSigned, UserState, VerifyFun) ->
@@ -503,18 +573,16 @@ validate_extensions(OtpCert, [], ValidationState =
true ->
{ValidationState#path_validation_state{max_path_length = Len - 1},
UserState0};
- %% basic_constraint must appear in certs used for digital sign
- %% see 4.2.1.10 in rfc 3280
false ->
- UserState = verify_fun(OtpCert, {bad_cert, missing_basic_constraint},
- UserState0, VerifyFun),
- case SelfSigned of
+ %% basic_constraint must appear in certs used for digital sign
+ %% see 4.2.1.10 in rfc 3280
+ case is_digitally_sign_cert(OtpCert) of
true ->
- {ValidationState, UserState};
- false ->
- {ValidationState#path_validation_state{max_path_length =
- Len - 1},
- UserState}
+ missing_basic_constraints(OtpCert, SelfSigned,
+ ValidationState, VerifyFun,
+ UserState0, Len);
+ false -> %% Example CRL signer only
+ {ValidationState, UserState0}
end
end;
@@ -861,74 +929,6 @@ type_subtree_names(Type, SubTrees) ->
[Name || #'GeneralSubtree'{base = {TreeType, Name}} <- SubTrees,
TreeType =:= Type].
-match_name(rfc822Name, Name, [PermittedName | Rest]) ->
- match_name(fun is_valid_host_or_domain/2, Name, PermittedName, Rest);
-
-match_name(directoryName, DirName, [PermittedName | Rest]) ->
- match_name(fun is_rdnSeq/2, DirName, PermittedName, Rest);
-
-match_name(uniformResourceIdentifier, URI, [PermittedName | Rest]) ->
- case split_uri(URI) of
- incomplete ->
- false;
- {_, _, Host, _, _} ->
- match_name(fun is_valid_host_or_domain/2, Host,
- PermittedName, Rest)
- end;
-
-match_name(emailAddress, Name, [PermittedName | Rest]) ->
- Fun = fun(Email, PermittedEmail) ->
- is_valid_email_address(Email, PermittedEmail,
- string:tokens(PermittedEmail,"@"))
- end,
- match_name(Fun, Name, PermittedName, Rest);
-
-match_name(dNSName, Name, [PermittedName | Rest]) ->
- Fun = fun(Domain, [$.|Domain]) -> true;
- (Name1,Name2) ->
- lists:suffix(string:to_lower(Name2),
- string:to_lower(Name1))
- end,
- match_name(Fun, Name, [$.|PermittedName], Rest);
-
-match_name(x400Address, OrAddress, [PermittedAddr | Rest]) ->
- match_name(fun is_or_address/2, OrAddress, PermittedAddr, Rest);
-
-match_name(ipAdress, IP, [PermittedIP | Rest]) ->
- Fun = fun([IP1, IP2, IP3, IP4],
- [IP5, IP6, IP7, IP8, M1, M2, M3, M4]) ->
- is_permitted_ip([IP1, IP2, IP3, IP4],
- [IP5, IP6, IP7, IP8],
- [M1, M2, M3, M4]);
- ([IP1, IP2, IP3, IP4, IP5, IP6, IP7, IP8,
- IP9, IP10, IP11, IP12, IP13, IP14, IP15, IP16],
- [IP17, IP18, IP19, IP20, IP21, IP22, IP23, IP24,
- IP25, IP26, IP27, IP28, IP29, IP30, IP31, IP32,
- M1, M2, M3, M4, M5, M6, M7, M8,
- M9, M10, M11, M12, M13, M14, M15, M16]) ->
- is_permitted_ip([IP1, IP2, IP3, IP4, IP5, IP6, IP7, IP8,
- IP9, IP10, IP11, IP12, IP13,
- IP14, IP15, IP16],
- [IP17, IP18, IP19, IP20, IP21, IP22, IP23,
- IP24,IP25, IP26, IP27, IP28, IP29, IP30,
- IP31, IP32],
- [M1, M2, M3, M4, M5, M6, M7, M8, M9, M10,
- M11, M12, M13, M14, M15, M16]);
- (_,_) ->
- false
- end,
- match_name(Fun, IP, PermittedIP, Rest).
-
-match_name(Fun, Name, PermittedName, []) ->
- Fun(Name, PermittedName);
-match_name(Fun, Name, PermittedName, [Head | Tail]) ->
- case Fun(Name, PermittedName) of
- true ->
- true;
- false ->
- match_name(Fun, Name, Head, Tail)
- end.
-
is_permitted_ip([], [], []) ->
true;
is_permitted_ip([CandidatIp | CandidatIpRest],
@@ -1037,3 +1037,25 @@ is_dh(?'dhpublicnumber')->
true;
is_dh(_) ->
false.
+
+is_digitally_sign_cert(OtpCert) ->
+ TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
+ Extensions = extensions_list(TBSCert#'OTPTBSCertificate'.extensions),
+ case pubkey_cert:select_extension(?'id-ce-keyUsage', Extensions) of
+ undefined ->
+ false;
+ #'Extension'{extnValue = KeyUse} ->
+ lists:member(keyCertSign, KeyUse)
+ end.
+
+missing_basic_constraints(OtpCert, SelfSigned, ValidationState, VerifyFun, UserState0,Len) ->
+ UserState = verify_fun(OtpCert, {bad_cert, missing_basic_constraint},
+ UserState0, VerifyFun),
+ case SelfSigned of
+ true ->
+ {ValidationState, UserState};
+ false ->
+ {ValidationState#path_validation_state{max_path_length =
+ Len - 1},
+ UserState}
+ end.
diff --git a/lib/public_key/src/pubkey_crl.erl b/lib/public_key/src/pubkey_crl.erl
new file mode 100644
index 0000000000..3e4c3c8b6d
--- /dev/null
+++ b/lib/public_key/src/pubkey_crl.erl
@@ -0,0 +1,701 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-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(pubkey_crl).
+
+-include("public_key.hrl").
+
+-export([validate/7, init_revokation_state/0, fresh_crl/3, verify_crl_signature/4,
+ is_delta_crl/1, combines/2, match_one/2]).
+
+-record(userstate, {dpcrls,
+ idp
+ }).
+
+validate(OtpCert, OtherDPCRLs, DP, {DerCRL, CRL}, {DerDeltaCRL, DeltaCRL},
+ Options, RevokedState0) ->
+ RevokedState =
+ case verify_crl(OtpCert, DP, CRL, DerCRL, DeltaCRL,
+ DerDeltaCRL, OtherDPCRLs, Options, RevokedState0) of
+ {valid, Revoked, DeltaRevoked, RevokedState1, IDP} ->
+ TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
+ SerialNumber = TBSCert#'OTPTBSCertificate'.serialNumber,
+ CertIssuer = TBSCert#'OTPTBSCertificate'.issuer,
+ TBSCRL = CRL#'CertificateList'.tbsCertList,
+ CRLIssuer = TBSCRL#'TBSCertList'.issuer,
+ AltNames = subject_alt_names(TBSCert#'OTPTBSCertificate'.extensions),
+ revoked_status(DP, IDP, {directoryName, CRLIssuer},
+ [ {directoryName, CertIssuer} | AltNames], SerialNumber, Revoked,
+ DeltaRevoked, RevokedState1);
+ {invalid, Revoked} ->
+ Revoked
+ end,
+ crl_status(RevokedState).
+
+init_revokation_state() ->
+ #revoke_state{reasons_mask = sets:new(),
+ interim_reasons_mask = sets:new(),
+ cert_status = unrevoked}.
+
+fresh_crl(_, {undefined, undefined}, _) ->
+ %% Typically happens when there is no delta CRL that covers a CRL
+ no_fresh_crl;
+
+fresh_crl(DP, {_, #'CertificateList'{tbsCertList = TBSCRL}} = CRL, CallBack) ->
+ Now = calendar:datetime_to_gregorian_seconds(calendar:universal_time()),
+ UpdateTime =
+ pubkey_cert:time_str_2_gregorian_sec(TBSCRL#'TBSCertList'.nextUpdate),
+ case Now >= UpdateTime of
+ true ->
+ case CallBack(DP, CRL) of
+ CRL ->
+ no_fresh_crl;
+ NewCRL ->
+ fresh_crl(DP, NewCRL, CallBack)
+ end;
+ false ->
+ {fresh, CRL}
+ end.
+
+is_delta_crl(#'CertificateList'{tbsCertList = TBSCRL}) ->
+ Extensions = TBSCRL#'TBSCertList'.crlExtensions,
+ case pubkey_cert:select_extension(?'id-ce-deltaCRLIndicator',
+ Extensions) of
+ undefined ->
+ false;
+ _ ->
+ true
+ end.
+
+combines(CRL, DeltaCRL) ->
+ check_crl_num(CRL, DeltaCRL) andalso
+ check_delta_issuer_and_scope(CRL, DeltaCRL).
+
+crl_status(State)->
+ %% Fun argument is to enable future implementation of CRL checking
+ %% that does not care about all possible reasons.
+ crl_status(State, fun all_reasons/0).
+
+crl_status({skip, #revoke_state{cert_status = Status} = RevokedState}, _) ->
+ {undetermined, status(Status), RevokedState};
+
+crl_status(#revoke_state{cert_status = unrevoked = Status,
+ valid_ext = false} = RevokedState, _) ->
+ {undetermined, Status, RevokedState};
+
+crl_status(#revoke_state{cert_status = Status,
+ valid_ext = false}, _) ->
+ {finished, status(Status)};
+
+crl_status(#revoke_state{reasons_mask = Mask,
+ cert_status = Status,
+ valid_ext = true} = RevokedState, Fun) ->
+ case is_all_reasons(Mask, Fun) of
+ true ->
+ {finished, status(Status)};
+ false when (Status == unrevoked) ->
+ {undetermined, Status, RevokedState};
+ _ ->
+ {finished ,status(Status)}
+ end.
+
+verify_crl(OtpCert, DP, CRL, DerCRL, DeltaCRL, DerDeltaCRL, OtherDPCRLs,
+ Options, State0) ->
+ #'CertificateList'{tbsCertList =
+ #'TBSCertList'{crlExtensions = Extensions,
+ revokedCertificates = TmpRevoked}
+ } = CRL,
+ Revoked = revoked(TmpRevoked),
+ IDP = issuing_distribution_point(Extensions),
+
+ DeltaRevoked = delta_revoked(DeltaCRL),
+
+ ValidExt = verify_extensions(Extensions) and
+ verify_extensions(Revoked),
+
+ IntMask = compute_interim_reasons_mask(DP, IDP),
+
+ RevokedState =
+ State0#revoke_state{interim_reasons_mask = IntMask,
+ valid_ext = ValidExt},
+
+ {Fun, AdditionalArgs} = IssuerFun = proplists:get_value(issuer_fun, Options),
+
+ try verify_issuer_and_scope(OtpCert, DP, IDP, CRL) of
+ {ok, Issuer} ->
+ case Fun(DP, CRL, Issuer, AdditionalArgs) of
+ {ok, TrustedOtpCert, Path} ->
+ verify_mask_and_signatures(Revoked, DeltaRevoked,
+ RevokedState,
+ CRL, DerCRL, DeltaCRL, DerDeltaCRL,
+ IssuerFun, TrustedOtpCert, Path, OtherDPCRLs, IDP);
+ _ ->
+ {invalid, State0#revoke_state{valid_ext = ValidExt}}
+ end;
+ {error, issuer_not_found} ->
+ case Fun(DP, CRL, issuer_not_found, AdditionalArgs) of
+ {ok, TrustedOtpCert, Path} ->
+ verify_mask_and_signatures(Revoked, DeltaRevoked,
+ RevokedState, CRL, DerCRL, DeltaCRL,
+ DerDeltaCRL, IssuerFun,
+ TrustedOtpCert, Path, OtherDPCRLs, IDP);
+ _ ->
+ {invalid, {skip, State0}}
+ end
+ catch
+ throw:{bad_crl, invalid_issuer} ->
+ {invalid, {skip, State0}};
+ throw:_ ->
+ {invalid, State0#revoke_state{valid_ext = ValidExt}}
+ end.
+
+verify_mask_and_signatures(Revoked, DeltaRevoked, RevokedState, CRL, DerCRL, DeltaCRL, DerDeltaCRL,
+ IssuerFun, TrustedOtpCert, Path, OtherDPCRLs, IDP) ->
+
+ ReasonsMask = sets:union(RevokedState#revoke_state.reasons_mask,
+ RevokedState#revoke_state.interim_reasons_mask),
+ try
+ verify_interim_reasons_mask(RevokedState),
+ true = verify_crl_signatures(CRL, DerCRL, DeltaCRL, DerDeltaCRL,
+ TrustedOtpCert, Path, IssuerFun, OtherDPCRLs, IDP),
+ {valid, Revoked, DeltaRevoked, RevokedState#revoke_state{reasons_mask = ReasonsMask}, IDP}
+ catch
+ throw:_ ->
+ {invalid, RevokedState};
+ error:{badmatch, _} ->
+ {invalid, RevokedState}
+ end.
+
+
+verify_crl_signatures(CRL, DerCRL, DeltaCRL, DerDeltaCRL, TrustedOtpCert, Path,
+ IssuerFun, OtherDPCRLs, IDP) ->
+ try
+ VerifyFunAndState =
+ {fun(_, {bad_cert, _} = Reason, _UserState) ->
+ {fail, Reason};
+ (_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (_Cert, valid, UserState) ->
+ {valid, UserState};
+ (Cert, valid_peer, UserState) ->
+ case verify_crl_keybit(Cert, cRLSign) of
+ true ->
+ handle_crlsigner(Cert, IssuerFun, UserState);
+ false ->
+ {fail, crl_sign_bit_not_set}
+ end
+ end, #userstate{dpcrls = OtherDPCRLs, idp = IDP}},
+
+ {ok, {{_,Key, KeyParams},_}} =
+ public_key:pkix_path_validation(TrustedOtpCert, Path,
+ [{verify_fun, VerifyFunAndState}]),
+ true = verify_crl_signature(CRL, DerCRL, Key, KeyParams),
+ true = verify_crl_signature(DeltaCRL, DerDeltaCRL, Key, KeyParams)
+ catch
+ error:{badmatch, _} ->
+ false
+ end.
+
+handle_crlsigner(OtpCert, IssuerFun, #userstate{idp = IDP} = UserState) ->
+ case verify_crl_keybit(OtpCert, keyCertSign) of
+ true ->
+ {valid, UserState};
+ false ->
+ case not is_indirect_crl(IDP) andalso not public_key:pkix_is_self_signed(OtpCert) of
+ true ->
+ validate_crl_signing_cert(OtpCert, IssuerFun, UserState);
+ false ->
+ {valid, UserState}
+ end
+ end.
+
+validate_crl_signing_cert(_, _,#userstate{dpcrls = []} = UserState) ->
+ {valid, UserState};
+validate_crl_signing_cert(OtpCert, IssuerFun, #userstate{dpcrls = CRLInfo} = UserState) ->
+ case public_key:pkix_crls_validate(OtpCert, CRLInfo, [{issuer_fun, IssuerFun}]) of
+ valid ->
+ {valid, UserState};
+ Reason ->
+ {fail, Reason}
+ end.
+
+delta_revoked(undefined)->
+ [];
+delta_revoked(#'CertificateList'{tbsCertList =
+ #'TBSCertList'{revokedCertificates
+ = DeltaRevoked}}) ->
+ revoked(DeltaRevoked).
+
+revoked(asn1_NOVALUE) ->
+ [];
+revoked(Revoked) ->
+ Revoked.
+
+revoked_status(DP, IDP, CRLIssuer, Names, SerialNumber, Revoked, DeltaRevoked, RevokedState0) ->
+ DefaultIssuer0 = default_issuer(CRLIssuer, DeltaRevoked),
+ RevokedState1 = check_revoked(DP, IDP, DefaultIssuer0, Names, SerialNumber, DeltaRevoked, RevokedState0),
+ RevokedState = case RevokedState1#revoke_state.cert_status of
+ unrevoked when RevokedState1#revoke_state.cert_status =/= removeFromCRL ->
+ DefaultIssuer = default_issuer(CRLIssuer, Revoked),
+ check_revoked(DP, IDP, DefaultIssuer, Names, SerialNumber,
+ Revoked, RevokedState1);
+ _ ->
+ RevokedState1
+ end,
+ case RevokedState#revoke_state.cert_status of
+ removeFromCRL ->
+ RevokedState#revoke_state{cert_status = unrevoked};
+ _ ->
+ RevokedState
+ end.
+
+default_issuer(_, []) ->
+ undefined;
+default_issuer(Default, [#'TBSCertList_revokedCertificates_SEQOF'{crlEntryExtensions = Extensions}| _]) ->
+ case extension_value(?'id-ce-certificateIssuer', 'GeneralNames', Extensions) of
+ undefined ->
+ [pubkey_cert_records:transform(Default, decode)];
+ GeneralNames ->
+ gen_names(GeneralNames)
+ end.
+
+is_all_reasons(Mask, AllReasonsFun) ->
+ AllReasons = AllReasonsFun(),
+ case sets:is_subset(AllReasons, Mask) of
+ true ->
+ true;
+ false ->
+ %% As the "uspecified" reason should not
+ %% be explicitly used according to RFC 3280
+ %% and the conformance tests have test cases
+ %% that should succed, and that does not specify
+ %% "unspecified", we tolorate that it is not included.
+ sets:is_subset(sets:del_element(unspecified, AllReasons), Mask)
+ end.
+
+all_reasons() ->
+ sets:from_list([unspecified, keyCompromise,
+ cACompromise, affiliationChanged, superseded,
+ cessationOfOperation, certificateHold,
+ privilegeWithdrawn, aACompromise]).
+
+verify_issuer_and_scope(#'OTPCertificate'{tbsCertificate = TBSCert} = Cert,
+ #'DistributionPoint'{cRLIssuer = DPIssuer} = DP, IDP,
+ #'CertificateList'{tbsCertList = TBSCRL} = CRL)
+ when DPIssuer =/= asn1_NOVALUE ->
+ CRLIssuer = pubkey_cert_records:transform(TBSCRL#'TBSCertList'.issuer, decode),
+ Issuer = dp_crlissuer_to_issuer(DPIssuer),
+ case pubkey_cert:is_issuer(Issuer, CRLIssuer) and is_indirect_crl(IDP) of
+ true ->
+ verify_scope(Cert, DP, IDP),
+ issuer_id(Cert, CRL);
+ false ->
+ %% otherwise verify that the CRL issuer matches the certificate issuer
+ verify_issuer_and_scope(Cert, DP#'DistributionPoint'{
+ distributionPoint = [TBSCert#'OTPTBSCertificate'.issuer],
+ cRLIssuer = asn1_NOVALUE},
+ IDP, CRL)
+ end;
+verify_issuer_and_scope(#'OTPCertificate'{tbsCertificate = TBSCert}= Cert,
+ DP, IDP,
+ #'CertificateList'{tbsCertList = TBSCRL}) ->
+ CRLIssuer = pubkey_cert_records:transform(TBSCRL#'TBSCertList'.issuer, decode),
+ CertIssuer = TBSCert#'OTPTBSCertificate'.issuer,
+ case pubkey_cert:is_issuer(CertIssuer, CRLIssuer) of
+ true ->
+ verify_scope(Cert, DP, IDP),
+ issuer_id(Cert);
+ false ->
+ throw({bad_crl, invalid_issuer})
+ end.
+
+dp_crlissuer_to_issuer(DPCRLIssuer) ->
+ [{directoryName, Issuer}] = pubkey_cert_records:transform(DPCRLIssuer, decode),
+ Issuer.
+
+is_indirect_crl(#'IssuingDistributionPoint'{indirectCRL = Value})->
+ Value;
+is_indirect_crl(_) ->
+ false.
+
+verify_scope(_,_, undefined) ->
+ ok;
+verify_scope(#'OTPCertificate'{tbsCertificate = TBSCert}, #'DistributionPoint'{cRLIssuer = DPIssuer} = DP, IDP) ->
+ CertIssuer = TBSCert#'OTPTBSCertificate'.issuer,
+ Names = case gen_names(DPIssuer) of
+ [{directoryName, TNames}] ->
+ TNames;
+ Other ->
+ Other
+ end,
+ DPName = dp_names(DP#'DistributionPoint'.distributionPoint, Names, CertIssuer),
+ IDPName = dp_names(IDP#'IssuingDistributionPoint'.distributionPoint, Names, CertIssuer),
+ verify_scope(DPName, IDPName, Names, TBSCert, IDP).
+
+verify_scope(asn1_NOVALUE, _, asn1_NOVALUE, _, _) ->
+ throw({bad_crl, scope_error1});
+verify_scope(asn1_NOVALUE, IDPName, DPIssuerNames, TBSCert, IDP) ->
+ verify_dp_name(IDPName, DPIssuerNames),
+ verify_dp_bools(TBSCert, IDP);
+
+verify_scope(DPName, IDPName, _, TBSCert, IDP) ->
+ verify_dp_name(IDPName, DPName),
+ verify_dp_bools(TBSCert, IDP).
+
+dp_names(asn1_NOVALUE, _, _) ->
+ asn1_NOVALUE;
+dp_names({fullName, Name}, _, _) ->
+ gen_names(Name);
+dp_names({nameRelativeToCRLIssuer, Fragment}, asn1_NOVALUE, {rdnSequence, RelativeDestinguistNames}) ->
+ [{directoryName, {rdnSequence, RelativeDestinguistNames ++
+ [lists:map(fun(AttrAndValue) ->
+ pubkey_cert_records:transform(AttrAndValue, decode)
+ end, Fragment)]}}];
+dp_names({nameRelativeToCRLIssuer, Fragment},{rdnSequence, RelativeDestinguistNames}, _) ->
+ [{directoryName, {rdnSequence, RelativeDestinguistNames ++
+ [lists:map(fun(AttrAndValue) ->
+ pubkey_cert_records:transform(AttrAndValue, decode)
+ end, Fragment)]}}];
+dp_names([{rdnSequence, _}] = Name0, _,_) ->
+ [Name] = pubkey_cert_records:transform(Name0, decode),
+ [{directoryName, Name}].
+
+gen_names(asn1_NOVALUE) ->
+ asn1_NOVALUE;
+gen_names([]) ->
+ [];
+gen_names([{NameType, Name} | Rest]) ->
+ [ {NameType, pubkey_cert_records:transform(Name, decode)} | gen_names(Rest)].
+
+verify_dp_name(asn1_NOVALUE, _) ->
+ ok;
+
+verify_dp_name(IDPNames, DPorIssuerNames) ->
+ case match_one(DPorIssuerNames, IDPNames) of
+ true ->
+ ok;
+ false ->
+ throw({bad_crl, scope_error})
+ end.
+
+match_one([], _) ->
+ false;
+match_one([{Type, Name} | Names], CandidateNames) ->
+ Candidates = [NameName || {NameType, NameName} <- CandidateNames, NameType == Type],
+ case Candidates of
+ [] ->
+ false;
+ [_|_] -> case pubkey_cert:match_name(Type, Name, Candidates) of
+ true ->
+ true;
+ false ->
+ match_one(Names, CandidateNames)
+ end
+ end.
+
+verify_dp_bools(TBSCert, IDP) ->
+ BasicConstraints =
+ pubkey_cert:select_extension(?'id-ce-basicConstraints',
+ TBSCert#'OTPTBSCertificate'.extensions),
+
+ case verify_onlyContainsUserCerts(BasicConstraints, IDP) andalso
+ verify_onlyContainsCACerts(BasicConstraints, IDP) andalso
+ verify_onlyContainsAttributeCerts(IDP) of
+ true ->
+ ok;
+ _ ->
+ throw({bad_crl, scope_error})
+ end.
+
+verify_onlyContainsUserCerts(
+ #'Extension'{extnValue = #'BasicConstraints'{cA = true}},
+ #'IssuingDistributionPoint'{onlyContainsUserCerts = true}) ->
+ false;
+verify_onlyContainsUserCerts(_,_) ->
+ true.
+
+verify_onlyContainsCACerts(
+ #'Extension'{extnValue = #'BasicConstraints'{cA = true}},
+ #'IssuingDistributionPoint'{onlyContainsCACerts = true}) ->
+ true;
+verify_onlyContainsCACerts(_,#'IssuingDistributionPoint'{onlyContainsCACerts = true}) ->
+ false;
+verify_onlyContainsCACerts(_,_) ->
+ true.
+
+verify_onlyContainsAttributeCerts(
+ #'IssuingDistributionPoint'{onlyContainsAttributeCerts = Bool}) ->
+ not Bool.
+
+check_crl_num(#'CertificateList'{tbsCertList = TBSCRL},
+ #'CertificateList'{tbsCertList = TBSDeltaCRL})->
+ Extensions = TBSCRL#'TBSCertList'.crlExtensions,
+ DeltaExtensions = TBSDeltaCRL#'TBSCertList'.crlExtensions,
+
+ try
+ CRLNum = assert_extension_value(?'id-ce-cRLNumber', 'CRLNumber', Extensions),
+ DeltaBaseNum = assert_extension_value(?'id-ce-deltaCRLIndicator',
+ 'CRLNumber', DeltaExtensions),
+ DeltaCRLNum = assert_extension_value(?'id-ce-cRLNumber', 'CRLNumber', DeltaExtensions),
+ (CRLNum >= DeltaBaseNum) andalso (CRLNum < DeltaCRLNum)
+ catch
+ throw:no_extension_present ->
+ false
+ end;
+check_crl_num(_,_) ->
+ false.
+
+
+extension_value(Extension, ExtType, Extensions) ->
+ case pubkey_cert:select_extension(Extension, Extensions) of
+ #'Extension'{extnValue = Value} ->
+ public_key:der_decode(ExtType, list_to_binary(Value));
+ _ ->
+ undefined
+ end.
+
+
+assert_extension_value(Extension, ExtType, Extensions) ->
+ case extension_value(Extension, ExtType, Extensions) of
+ undefined ->
+ throw(no_extension_present);
+ Value ->
+ Value
+ end.
+
+check_delta_issuer_and_scope(_, undefined) ->
+ true;
+check_delta_issuer_and_scope(#'CertificateList'{tbsCertList = TBSCRL},
+ #'CertificateList'{tbsCertList = TBSDeltaCRL}) ->
+ case pubkey_cert:is_issuer(TBSCRL#'TBSCertList'.issuer,
+ TBSDeltaCRL#'TBSCertList'.issuer) of
+ true ->
+ check_delta_scope(TBSCRL, TBSDeltaCRL);
+ false ->
+ false
+ end.
+
+check_delta_scope(#'TBSCertList'{crlExtensions = Extensions},
+ #'TBSCertList'{crlExtensions = DeltaExtensions})->
+ IDP = issuing_distribution_point(Extensions),
+ DeltaIDP = issuing_distribution_point(DeltaExtensions),
+
+ AuthKey = authority_key_identifier(Extensions),
+ DeltaAuthKey = authority_key_identifier(DeltaExtensions),
+ is_match(IDP, DeltaIDP) andalso is_match(AuthKey, DeltaAuthKey).
+
+is_match(X, X) ->
+ true;
+is_match(_,_) ->
+ false.
+
+compute_interim_reasons_mask(#'DistributionPoint'{reasons = asn1_NOVALUE},
+ #'IssuingDistributionPoint'{onlySomeReasons =
+ asn1_NOVALUE}) ->
+ all_reasons();
+compute_interim_reasons_mask(#'DistributionPoint'{reasons = asn1_NOVALUE},
+ undefined) ->
+ all_reasons();
+
+compute_interim_reasons_mask(#'DistributionPoint'{reasons = asn1_NOVALUE},
+ #'IssuingDistributionPoint'{onlySomeReasons =
+ IDPReasons}) ->
+ sets:from_list(IDPReasons);
+compute_interim_reasons_mask(#'DistributionPoint'{reasons = DPReasons},
+ #'IssuingDistributionPoint'{onlySomeReasons =
+ asn1_NOVALUE}) ->
+ sets:from_list(DPReasons);
+compute_interim_reasons_mask(#'DistributionPoint'{reasons = DPReasons},
+ undefined) ->
+ sets:from_list(DPReasons);
+compute_interim_reasons_mask(#'DistributionPoint'{reasons = DPReasons},
+ #'IssuingDistributionPoint'{onlySomeReasons =
+ IDPReasons}) ->
+ sets:intersection(sets:from_list(DPReasons), sets:from_list(IDPReasons)).
+
+verify_interim_reasons_mask(#revoke_state{reasons_mask = Mask,
+ interim_reasons_mask = IntMask}) ->
+ case sets:fold(fun(Element, Acc) ->
+ case sets:is_element(Element, Mask) of
+ true ->
+ Acc;
+ false ->
+ true
+ end
+ end, false, IntMask) of
+ true ->
+ ok;
+ false ->
+ throw({bad_crl, mask_error})
+ end.
+
+verify_crl_signature(undefined, undefined, _,_) ->
+ true;
+verify_crl_signature(CRL, DerCRL, Key, KeyParams) ->
+ {DigestType, PlainText, Signature} = extract_crl_verify_data(CRL, DerCRL),
+ case Key of
+ #'RSAPublicKey'{} ->
+ public_key:verify(PlainText, DigestType, Signature, Key);
+ _ ->
+ public_key:verify(PlainText, DigestType, Signature,
+ {Key, KeyParams})
+ end.
+extract_crl_verify_data(CRL, DerCRL) ->
+ {0, Signature} = CRL#'CertificateList'.signature,
+ #'AlgorithmIdentifier'{algorithm = SigAlg} =
+ CRL#'CertificateList'.signatureAlgorithm,
+ PlainText = encoded_tbs_crl(DerCRL),
+ DigestType = pubkey_cert:digest_type(SigAlg),
+ {DigestType, PlainText, Signature}.
+
+encoded_tbs_crl(CRL) ->
+ {ok, PKIXCRL} =
+ 'OTP-PUB-KEY':decode_TBSCertList_exclusive(CRL),
+ {'CertificateList',
+ {'CertificateList_tbsCertList', EncodedTBSCertList}, _, _} = PKIXCRL,
+ EncodedTBSCertList.
+
+check_revoked(_,_,_,_,_,[], State) ->
+ State;
+check_revoked(#'DistributionPoint'{cRLIssuer = DPIssuer} = DP, IDP, DefaultIssuer0, Names, SerialNr,
+ [#'TBSCertList_revokedCertificates_SEQOF'{userCertificate =
+ SerialNr,
+ crlEntryExtensions =
+ Extensions}| Rest],
+ State) ->
+ Reason = revoked_reason(Extensions),
+ case (DPIssuer =/= asn1_NOVALUE) and is_indirect_crl(IDP) of
+ true ->
+ handle_indirect_crl_check(DP, IDP, DefaultIssuer0, Names, SerialNr, Extensions, Reason, Rest, State);
+ false ->
+ State#revoke_state{cert_status = Reason}
+ end;
+
+check_revoked(DP, IDP, DefaultIssuer0, Names, SerialNr,
+ [#'TBSCertList_revokedCertificates_SEQOF'{crlEntryExtensions =
+ Extensions}| Rest], State) ->
+ DefaultIssuer = case extension_value(?'id-ce-certificateIssuer', 'GeneralNames', Extensions) of
+ undefined ->
+ DefaultIssuer0;
+ GeneralNames ->
+ gen_names(GeneralNames)
+ end,
+ check_revoked(DP, IDP, DefaultIssuer, Names, SerialNr, Rest, State).
+
+handle_indirect_crl_check(DP, IDP, DefaultIssuer0, Names, SerialNr, Extensions, Reason, Rest, State) ->
+ case check_crl_issuer_extension(Names, Extensions, DefaultIssuer0) of
+ {true, _} ->
+ State#revoke_state{cert_status = Reason};
+ {false, DefaultIssuer} ->
+ check_revoked(DP, IDP, DefaultIssuer, Names, SerialNr, Rest, State)
+ end.
+
+check_crl_issuer_extension(Names, Extensions, Default0) ->
+ case extension_value(?'id-ce-certificateIssuer', 'GeneralNames', Extensions) of
+ undefined ->
+ {match_one(Default0, Names), Default0};
+ GeneralNames ->
+ Default = gen_names(GeneralNames),
+ {match_one(Default, Names), Default}
+ end.
+
+revoked_reason(Extensions) ->
+ case extension_value(?'id-ce-cRLReasons', 'CRLReason', Extensions) of
+ undefined ->
+ unspecified;
+ Value ->
+ Value
+ end.
+
+verify_crl_keybit(#'OTPCertificate'{tbsCertificate = TBS}, Bit) ->
+ case pubkey_cert:select_extension( ?'id-ce-keyUsage',
+ TBS#'OTPTBSCertificate'.extensions) of
+ #'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = KeyUse} ->
+ lists:member(Bit, KeyUse);
+ _ ->
+ true
+ end.
+
+issuer_id(Cert, #'CertificateList'{tbsCertList = TBSCRL}) ->
+ Extensions =
+ pubkey_cert:extensions_list(TBSCRL#'TBSCertList'.crlExtensions),
+ case authority_key_identifier(Extensions) of
+ undefined ->
+ issuer_id(Cert);
+ #'AuthorityKeyIdentifier'{authorityCertIssuer = asn1_NOVALUE,
+ authorityCertSerialNumber = asn1_NOVALUE} ->
+ issuer_id(Cert);
+ #'AuthorityKeyIdentifier'{authorityCertIssuer = Issuer,
+ authorityCertSerialNumber = Nr} ->
+ {ok, {Nr, Issuer}}
+ end.
+
+issuer_id(#'OTPCertificate'{} = Cert) ->
+ case public_key:pkix_is_self_signed(Cert) of
+ true ->
+ public_key:pkix_issuer_id(Cert, self);
+ false ->
+ public_key:pkix_issuer_id(Cert, other)
+ end.
+
+status(unrevoked) ->
+ unrevoked;
+status(Reason) ->
+ {revoked, Reason}.
+
+verify_extensions([#'TBSCertList_revokedCertificates_SEQOF'{crlEntryExtensions = Ext} | Rest]) ->
+ verify_extensions(pubkey_cert:extensions_list(Ext)) and verify_extensions(Rest);
+verify_extensions([]) ->
+ true;
+verify_extensions([#'Extension'{critical = true, extnID = Id} | Rest]) ->
+ case lists:member(Id, [?'id-ce-authorityKeyIdentifier',
+ ?'id-ce-issuerAltName',
+ ?'id-ce-cRLNumber',
+ ?'id-ce-certificateIssuer',
+ ?'id-ce-deltaCRLIndicator',
+ ?'id-ce-issuingDistributionPoint',
+ ?'id-ce-freshestCRL']) of
+ true ->
+ verify_extensions(Rest);
+ false ->
+ false
+ end;
+verify_extensions([_Ext | Rest]) ->
+ verify_extensions(Rest).
+
+issuing_distribution_point(Extensions) ->
+ Enc = extension_value(?'id-ce-issuingDistributionPoint',
+ 'IssuingDistributionPoint', Extensions),
+ pubkey_cert_records:transform(Enc, decode).
+
+authority_key_identifier(Extensions) ->
+ Enc = extension_value(?'id-ce-authorityKeyIdentifier',
+ 'AuthorityKeyIdentifier', Extensions),
+ pubkey_cert_records:transform(Enc, decode).
+
+subject_alt_names(Extensions) ->
+ Enc = extension_value(?'id-ce-subjectAltName',
+ 'GeneralNames', Extensions),
+ case Enc of
+ undefined ->
+ [];
+ _ ->
+ pubkey_cert_records:transform(Enc, decode)
+ end.
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index 4012825f20..6bdc35fb79 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.erl
@@ -167,6 +167,8 @@ split_lines(Bin) ->
%% Ignore white space at end of line
join_entry([<<"-----END ", _/binary>>| Lines], Entry) ->
{lists:reverse(Entry), Lines};
+join_entry([<<"-----END X509 CRL-----", _/binary>>| Lines], Entry) ->
+ {lists:reverse(Entry), Lines};
join_entry([Line | Lines], Entry) ->
join_entry(Lines, [Line | Entry]).
@@ -198,7 +200,9 @@ pem_start('DHParameter') ->
pem_start('CertificationRequest') ->
<<"-----BEGIN CERTIFICATE REQUEST-----">>;
pem_start('ContentInfo') ->
- <<"-----BEGIN PKCS7-----">>.
+ <<"-----BEGIN PKCS7-----">>;
+pem_start('CertificateList') ->
+ <<"-----BEGIN X509 CRL-----">>.
pem_end(<<"-----BEGIN CERTIFICATE-----">>) ->
<<"-----END CERTIFICATE-----">>;
@@ -220,6 +224,8 @@ pem_end(<<"-----BEGIN CERTIFICATE REQUEST-----">>) ->
<<"-----END CERTIFICATE REQUEST-----">>;
pem_end(<<"-----BEGIN PKCS7-----">>) ->
<<"-----END PKCS7-----">>;
+pem_end(<<"-----BEGIN X509 CRL-----">>) ->
+ <<"-----END X509 CRL-----">>;
pem_end(_) ->
undefined.
@@ -242,7 +248,9 @@ asn1_type(<<"-----BEGIN ENCRYPTED PRIVATE KEY-----">>) ->
asn1_type(<<"-----BEGIN CERTIFICATE REQUEST-----">>) ->
'CertificationRequest';
asn1_type(<<"-----BEGIN PKCS7-----">>) ->
- 'ContentInfo'.
+ 'ContentInfo';
+asn1_type(<<"-----BEGIN X509 CRL-----">>) ->
+ 'CertificateList'.
pem_decrypt() ->
<<"Proc-Type: 4,ENCRYPTED">>.
diff --git a/lib/public_key/src/public_key.app.src b/lib/public_key/src/public_key.app.src
index 4cc81ea573..9f0677606d 100644
--- a/lib/public_key/src/public_key.app.src
+++ b/lib/public_key/src/public_key.app.src
@@ -7,6 +7,7 @@
pubkey_ssh,
pubkey_cert,
pubkey_cert_records,
+ pubkey_crl,
'OTP-PUB-KEY',
'PKCS-FRAME'
]},
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index d5df53e848..9b7d98728f 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -42,7 +42,8 @@
pkix_issuer_id/2,
pkix_normalize_name/1,
pkix_path_validation/3,
- ssh_decode/2, ssh_encode/2
+ ssh_decode/2, ssh_encode/2,
+ pkix_crls_validate/3
]).
-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding'
@@ -50,6 +51,8 @@
-type public_crypt_options() :: [{rsa_pad, rsa_padding()}].
-type rsa_digest_type() :: 'md5' | 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
-type dss_digest_type() :: 'none' | 'sha'. %% None is for backwards compatibility
+-type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded
+ | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise.
-define(UINT32(X), X:32/unsigned-big-integer).
-define(DER_NULL, <<5, 0>>).
@@ -428,9 +431,9 @@ pkix_verify(DerCert, #'RSAPublicKey'{} = RSAKey)
verify(PlainText, DigestType, Signature, RSAKey).
%%--------------------------------------------------------------------
--spec pkix_is_issuer(Cert::binary()| #'OTPCertificate'{},
- IssuerCert::binary()|
- #'OTPCertificate'{}) -> boolean().
+-spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{} | #'CertificateList'{},
+ IssuerCert :: der_encoded()|
+ #'OTPCertificate'{}) -> boolean().
%%
%% Description: Checks if <IssuerCert> issued <Cert>.
%%--------------------------------------------------------------------
@@ -443,7 +446,11 @@ pkix_is_issuer(Cert, IssuerCert) when is_binary(IssuerCert) ->
pkix_is_issuer(#'OTPCertificate'{tbsCertificate = TBSCert},
#'OTPCertificate'{tbsCertificate = Candidate}) ->
pubkey_cert:is_issuer(TBSCert#'OTPTBSCertificate'.issuer,
- Candidate#'OTPTBSCertificate'.subject).
+ Candidate#'OTPTBSCertificate'.subject);
+pkix_is_issuer(#'CertificateList'{tbsCertList = TBSCRL},
+ #'OTPCertificate'{tbsCertificate = Candidate}) ->
+ pubkey_cert:is_issuer(Candidate#'OTPTBSCertificate'.subject,
+ pubkey_cert_records:transform(TBSCRL#'TBSCertList'.issuer, decode)).
%%--------------------------------------------------------------------
-spec pkix_is_self_signed(Cert::binary()| #'OTPCertificate'{}) -> boolean().
@@ -502,7 +509,7 @@ pkix_normalize_name(Issuer) ->
%%--------------------------------------------------------------------
-spec pkix_path_validation(Cert::binary()| #'OTPCertificate'{} | atom(),
CertChain :: [binary()] ,
- Options :: list()) ->
+ Options :: proplists:proplist()) ->
{ok, {PublicKeyInfo :: term(),
PolicyTree :: term()}} |
{error, {bad_cert, Reason :: term()}}.
@@ -511,7 +518,7 @@ pkix_normalize_name(Issuer) ->
pkix_path_validation(PathErr, [Cert | Chain], Options0) when is_atom(PathErr)->
{VerifyFun, Userstat0} =
proplists:get_value(verify_fun, Options0, ?DEFAULT_VERIFYFUN),
- Otpcert = pkix_decode_cert(Cert, otp),
+ Otpcert = otp_cert(Cert),
Reason = {bad_cert, PathErr},
try VerifyFun(Otpcert, Reason, Userstat0) of
{valid, Userstate} ->
@@ -537,6 +544,27 @@ pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
Options),
path_validation(CertChain, ValidationState).
+%--------------------------------------------------------------------
+-spec pkix_crls_validate(#'OTPCertificate'{},
+ [{DP::#'DistributionPoint'{} ,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.
+%%--------------------------------------------------------------------
+pkix_crls_validate(OtpCert, [{_,_,_} |_] = DPAndCRLs, Options) ->
+ pkix_crls_validate(OtpCert, DPAndCRLs, DPAndCRLs,
+ Options, pubkey_crl:init_revokation_state());
+
+pkix_crls_validate(OtpCert, DPAndCRLs0, Options) ->
+ CallBack = proplists:get_value(update_crl, Options, fun(_, CurrCRL) ->
+ CurrCRL
+ end),
+ DPAndCRLs = sort_dp_crls(DPAndCRLs0, CallBack),
+ pkix_crls_validate(OtpCert, DPAndCRLs, DPAndCRLs,
+ Options, pubkey_crl:init_revokation_state()).
+
+
%%--------------------------------------------------------------------
-spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}].
%%
@@ -611,12 +639,13 @@ path_validation([DerCert | Rest], ValidationState = #path_validation_state{
{error, Reason}
end;
-path_validation([DerCert | _] = Path,
+path_validation([Cert | _] = Path,
#path_validation_state{user_state = UserState0,
verify_fun = VerifyFun} =
ValidationState) ->
Reason = {bad_cert, max_path_length_reached},
- OtpCert = pkix_decode_cert(DerCert, otp),
+ OtpCert = otp_cert(Cert),
+
try VerifyFun(OtpCert, Reason, UserState0) of
{valid, UserState} ->
path_validation(Path,
@@ -630,7 +659,7 @@ path_validation([DerCert | _] = Path,
{error, Reason}
end.
-validate(DerCert, #path_validation_state{working_issuer_name = Issuer,
+validate(Cert, #path_validation_state{working_issuer_name = Issuer,
working_public_key = Key,
working_public_key_parameters =
KeyParams,
@@ -641,31 +670,31 @@ validate(DerCert, #path_validation_state{working_issuer_name = Issuer,
verify_fun = VerifyFun} =
ValidationState0) ->
- OtpCert = pkix_decode_cert(DerCert, otp),
+ OtpCert = otp_cert(Cert),
- UserState1 = pubkey_cert:validate_time(OtpCert, UserState0, VerifyFun),
+ {ValidationState1, UserState1} =
+ pubkey_cert:validate_extensions(OtpCert, ValidationState0, UserState0,
+ VerifyFun),
- UserState2 = pubkey_cert:validate_issuer(OtpCert, Issuer, UserState1, VerifyFun),
+ %% We want the key_usage extension to be checked before we validate
+ %% other things so that CRL validation errors will comply to standard
+ %% test suite description
- UserState3 = pubkey_cert:validate_names(OtpCert, Permit, Exclude, Last,
- UserState2,VerifyFun),
+ UserState2 = pubkey_cert:validate_time(OtpCert, UserState1, VerifyFun),
- UserState4 = pubkey_cert:validate_revoked_status(OtpCert, UserState3, VerifyFun),
-
- {ValidationState1, UserState5} =
- pubkey_cert:validate_extensions(OtpCert, ValidationState0, UserState4,
- VerifyFun),
+ UserState3 = pubkey_cert:validate_issuer(OtpCert, Issuer, UserState2, VerifyFun),
- %% We want the key_usage extension to be checked before we validate
- %% the signature.
- UserState6 = pubkey_cert:validate_signature(OtpCert, DerCert,
- Key, KeyParams, UserState5, VerifyFun),
+ UserState4 = pubkey_cert:validate_names(OtpCert, Permit, Exclude, Last,
+ UserState3, VerifyFun),
+
+ UserState5 = pubkey_cert:validate_signature(OtpCert, der_cert(Cert),
+ Key, KeyParams, UserState4, VerifyFun),
UserState = case Last of
false ->
- pubkey_cert:verify_fun(OtpCert, valid, UserState6, VerifyFun);
+ pubkey_cert:verify_fun(OtpCert, valid, UserState5, VerifyFun);
true ->
pubkey_cert:verify_fun(OtpCert, valid_peer,
- UserState6, VerifyFun)
+ UserState5, VerifyFun)
end,
ValidationState =
@@ -676,3 +705,110 @@ validate(DerCert, #path_validation_state{working_issuer_name = Issuer,
sized_binary(Binary) ->
Size = size(Binary),
<<?UINT32(Size), Binary/binary>>.
+
+otp_cert(Der) when is_binary(Der) ->
+ pkix_decode_cert(Der, otp);
+otp_cert(#'OTPCertificate'{} =Cert) ->
+ Cert.
+
+der_cert(#'OTPCertificate'{} = Cert) ->
+ pkix_encode('OTPCertificate', Cert, otp);
+der_cert(Der) when is_binary(Der) ->
+ Der.
+
+pkix_crls_validate(_, [],_, _, _) ->
+ {bad_cert, revocation_status_undetermined};
+pkix_crls_validate(OtpCert, [{DP, CRL, DeltaCRL} | Rest], All, Options, RevokedState0) ->
+ CallBack = proplists:get_value(update_crl, Options, fun(_, CurrCRL) ->
+ CurrCRL
+ end),
+ case pubkey_crl:fresh_crl(DP, CRL, CallBack) of
+ {fresh, CRL} ->
+ do_pkix_crls_validate(OtpCert, [{DP, CRL, DeltaCRL} | Rest],
+ All, Options, RevokedState0);
+ {fresh, NewCRL} ->
+ NewAll = [{DP, NewCRL, DeltaCRL} | All -- [{DP, CRL, DeltaCRL}]],
+ do_pkix_crls_validate(OtpCert, [{DP, NewCRL, DeltaCRL} | Rest],
+ NewAll, Options, RevokedState0);
+ no_fresh_crl ->
+ pkix_crls_validate(OtpCert, Rest, All, Options, RevokedState0)
+ end.
+
+do_pkix_crls_validate(OtpCert, [{DP, CRL, DeltaCRL} | Rest], All, Options, RevokedState0) ->
+ OtherDPCRLs = All -- [{DP, CRL, DeltaCRL}],
+ case pubkey_crl:validate(OtpCert, OtherDPCRLs, DP, CRL, DeltaCRL, Options, RevokedState0) of
+ {undetermined, _, _} when Rest == []->
+ {bad_cert, revocation_status_undetermined};
+ {undetermined, _, RevokedState} when Rest =/= []->
+ pkix_crls_validate(OtpCert, Rest, All, Options, RevokedState);
+ {finished, unrevoked} ->
+ valid;
+ {finished, Status} ->
+ {bad_cert, Status}
+ end.
+
+sort_dp_crls(DpsAndCrls, FreshCB) ->
+ Sorted = do_sort_dp_crls(DpsAndCrls, dict:new()),
+ sort_crls(Sorted, FreshCB, []).
+
+do_sort_dp_crls([], Dict) ->
+ dict:to_list(Dict);
+do_sort_dp_crls([{DP, CRL} | Rest], Dict0) ->
+ Dict = try dict:fetch(DP, Dict0) of
+ _ ->
+ dict:append(DP, CRL, Dict0)
+ catch _:_ ->
+ dict:store(DP, [CRL], Dict0)
+ end,
+ do_sort_dp_crls(Rest, Dict).
+
+sort_crls([], _, Acc) ->
+ Acc;
+
+sort_crls([{DP, AllCRLs} | Rest], FreshCB, Acc)->
+ {DeltaCRLs, CRLs} = do_sort_crls(AllCRLs),
+ DpsAndCRLs = combine(CRLs, DeltaCRLs, DP, FreshCB, []),
+ sort_crls(Rest, FreshCB, DpsAndCRLs ++ Acc).
+
+do_sort_crls(CRLs) ->
+ lists:partition(fun({_, CRL}) ->
+ pubkey_crl:is_delta_crl(CRL)
+ end, CRLs).
+
+combine([], _,_,_,Acc) ->
+ Acc;
+combine([{_, CRL} = Entry | CRLs], DeltaCRLs, DP, FreshCB, Acc) ->
+ DeltaCRL = combine(CRL, DeltaCRLs),
+ case pubkey_crl:fresh_crl(DP, DeltaCRL, FreshCB) of
+ no_fresh_crl ->
+ combine(CRLs, DeltaCRLs, DP, FreshCB, [{DP, Entry, {undefined, undefined}} | Acc]);
+ {fresh, NewDeltaCRL} ->
+ combine(CRLs, DeltaCRLs, DP, FreshCB, [{DP, Entry, NewDeltaCRL} | Acc])
+ end.
+
+combine(CRL, DeltaCRLs) ->
+ Deltas = lists:filter(fun({_,DeltaCRL}) ->
+ pubkey_crl:combines(CRL, DeltaCRL)
+ end, DeltaCRLs),
+ case Deltas of
+ [] ->
+ {undefined, undefined};
+ [Delta] ->
+ Delta;
+ [_,_|_] ->
+ Fun =
+ fun({_, #'CertificateList'{tbsCertList = FirstTBSCRL}} = CRL1,
+ {_, #'CertificateList'{tbsCertList = SecondTBSCRL}} = CRL2) ->
+ Time1 = pubkey_cert:time_str_2_gregorian_sec(
+ FirstTBSCRL#'TBSCertList'.thisUpdate),
+ Time2 = pubkey_cert:time_str_2_gregorian_sec(
+ SecondTBSCRL#'TBSCertList'.thisUpdate),
+ case Time1 > Time2 of
+ true ->
+ CRL1;
+ false ->
+ CRL2
+ end
+ end,
+ lists:foldl(Fun, hd(Deltas), tl(Deltas))
+ end.
diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl
index d6bdd05d01..95e288cd71 100644
--- a/lib/public_key/test/erl_make_certs.erl
+++ b/lib/public_key/test/erl_make_certs.erl
@@ -234,7 +234,7 @@ extensions(Opts) ->
end.
default_extensions(Exts) ->
- Def = [{key_usage,undefined},
+ Def = [{key_usage, default},
{subject_altname, undefined},
{issuer_altname, undefined},
{basic_constraints, default},
@@ -265,6 +265,11 @@ extension({basic_constraints, Data}) ->
#'Extension'{extnID = ?'id-ce-basicConstraints',
extnValue = Data}
end;
+
+extension({key_usage, default}) ->
+ #'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = [keyCertSign], critical = true};
+
extension({Id, Data, Critical}) ->
#'Extension'{extnID = Id, extnValue = Data, critical = Critical}.
diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl
index 380a67db7b..8fba1e8cd3 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-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2011-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
@@ -19,72 +19,16 @@
-module(pbe_SUITE).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("public_key/include/public_key.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% Function: init_per_suite(Config) -> Config
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Initialization before the whole suite
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- try crypto:start() of
- ok ->
- Config
- catch _:_ ->
- {skip, "Crypto did not start"}
- end.
-%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config) -> _
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after the whole suite
-%%--------------------------------------------------------------------
-end_per_suite(_Config) ->
- application:stop(crypto).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, Config) -> Config
-%% Case - atom()
-%% Name of the test case that is about to be run.
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Initialization before each test case
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%% Description: Initialization before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config) ->
- Config.
%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, Config) -> _
-%% Case - atom()
-%% Name of the test case that is about to be run.
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after each test case
+%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-end_per_testcase(_TestCase, _Config) ->
- ok.
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
@@ -96,17 +40,40 @@ all() ->
groups() ->
[].
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ try crypto:start() of
+ ok ->
+ Config
+ 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(_TestCase, Config) ->
+ Config.
+
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
-%% Test cases starts here.
%%--------------------------------------------------------------------
-pbdkdf1(doc) ->
- ["Test with PKCS #5 PBKDF1 Test Vectors"];
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+pbdkdf1() ->
+ [{doc,"Test with PKCS #5 PBKDF1 Test Vectors"}].
pbdkdf1(Config) when is_list(Config) ->
%%Password = "password"
%% = (0x)70617373776F7264
@@ -126,8 +93,8 @@ pbdkdf1(Config) when is_list(Config) ->
16#4A, 16#3D, 16#2A, 16#20, _/binary>> =
pubkey_pbe:pbdkdf1(Password, Salt, Count, sha).
-pbdkdf2(doc) ->
- ["Test with PKCS #5 PBKDF2 Test Vectors"];
+pbdkdf2() ->
+ [{doc,"Test with PKCS #5 PBKDF2 Test Vectors"}].
pbdkdf2(Config) when is_list(Config) ->
%% Input:
%% P = "password" (8 octets)
@@ -225,28 +192,28 @@ pbdkdf2(Config) when is_list(Config) ->
= pubkey_pbe:pbdkdf2("pass\0word",
"sa\0lt", 4096, 16, fun crypto:sha_mac/3, 20).
-encrypted_private_key_info(doc) ->
- ["Tests reading a EncryptedPrivateKeyInfo file encrypted with different ciphers"];
+encrypted_private_key_info() ->
+ [{doc,"Tests reading a EncryptedPrivateKeyInfo file encrypted with different ciphers"}].
encrypted_private_key_info(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
{ok, PemDes} = file:read_file(filename:join(Datadir, "des_cbc_enc_key.pem")),
PemDesEntry = public_key:pem_decode(PemDes),
- test_server:format("Pem entry: ~p" , [PemDesEntry]),
+ 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),
- test_server:format("Pem entry: ~p" , [Pem3DesEntry]),
+ 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),
- test_server:format("Pem entry: ~p" , [PemRc2Entry]),
+ ct:print("Pem entry: ~p" , [PemRc2Entry]),
[{'PrivateKeyInfo', _, {"RC2-CBC",_}} = PubEntry2] = PemRc2Entry,
KeyInfo = public_key:pem_entry_decode(PubEntry2, "password"),
diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl
index e59f299399..d901adaadd 100644
--- a/lib/public_key/test/pkits_SUITE.erl
+++ b/lib/public_key/test/pkits_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -23,16 +23,18 @@
-module(pkits_SUITE).
--compile(export_all).
-
-include_lib("public_key/include/public_key.hrl").
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
-define(error(Format,Args), error(Format,Args,?FILE,?LINE)).
-define(warning(Format,Args), warning(Format,Args,?FILE,?LINE)).
-define(CERTS, "pkits/certs").
-define(MIME, "pkits/smime").
-define(CONV, "pkits/smime-pem").
+-define(CRL, "pkits/crls").
-define(NIST1, "2.16.840.1.101.3.2.1.48.1").
-define(NIST2, "2.16.840.1.101.3.2.1.48.2").
@@ -42,10 +44,13 @@
-define(NIST6, "2.16.840.1.101.3.2.1.48.6").
-record(verify_state, {
- certs_db,
- crl_info,
+ crls,
+ crl_paths,
revoke_state}).
-%%
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -54,9 +59,9 @@ all() ->
{group, validity_periods},
{group, verifying_name_chaining},
{group, verifying_paths_with_self_issued_certificates},
- %%{group, basic_certificate_revocation_tests},
- %%{group, delta_crls},
- %%{group, distribution_points},
+ {group, basic_certificate_revocation_tests},
+ {group, delta_crls},
+ {group, distribution_points},
{group, verifying_basic_constraints},
{group, key_usage},
{group, name_constraints},
@@ -72,20 +77,22 @@ groups() ->
[invalid_name_chain, whitespace_name_chain, capitalization_name_chain,
uid_name_chain, attrib_name_chain, string_name_chain]},
{verifying_paths_with_self_issued_certificates, [],
- [basic_valid, %%basic_invalid,
- crl_signing_valid, crl_signing_invalid]},
- %% {basic_certificate_revocation_tests, [],
- %% [missing_CRL, revoked_CA, revoked_peer, invalid_CRL_signature,
- %% invalid_CRL_issuer, invalid_CRL, valid_CRL,
- %% unknown_CRL_extension, old_CRL, fresh_CRL, valid_serial,
- %% invalid_serial, valid_seperate_keys, invalid_separate_keys]},
- %% {delta_crls, [], [delta_without_crl, valid_delta_crls, invalid_delta_crls]},
- %% {distribution_points, [], [valid_distribution_points,
- %% valid_distribution_points_no_issuing_distribution_point,
- %% invalid_distribution_points, valid_only_contains,
- %% invalid_only_contains, valid_only_some_reasons,
- %% invalid_only_some_reasons, valid_indirect_crl,
- %% invalid_indirect_crl, valid_crl_issuer, invalid_crl_issuer]},
+ [basic_valid, basic_invalid, crl_signing_valid, crl_signing_invalid]},
+ {basic_certificate_revocation_tests, [],
+ [missing_CRL,
+ revoked_CA,
+ revoked_peer,
+ invalid_CRL_signature,
+ invalid_CRL_issuer, invalid_CRL, valid_CRL,
+ unknown_CRL_extension, old_CRL, fresh_CRL, valid_serial,
+ invalid_serial, valid_seperate_keys, invalid_separate_keys]},
+ {delta_crls, [], [delta_without_crl, valid_delta_crls, invalid_delta_crls]},
+ {distribution_points, [], [valid_distribution_points,
+ valid_distribution_points_no_issuing_distribution_point,
+ invalid_distribution_points, valid_only_contains,
+ invalid_only_contains, valid_only_some_reasons,
+ invalid_only_some_reasons, valid_indirect_crl,
+ invalid_indirect_crl, valid_crl_issuer, invalid_crl_issuer]},
{verifying_basic_constraints,[],
[missing_basic_constraints, valid_basic_constraint, invalid_path_constraints,
valid_path_constraints]},
@@ -102,12 +109,25 @@ groups() ->
[unknown_critical_extension, unknown_not_critical_extension]}
].
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ try crypto:start() of
+ ok ->
+ crypto_support_check(Config)
+ 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(_Func, Config) ->
Datadir = proplists:get_value(data_dir, Config),
put(datadir, Datadir),
@@ -116,143 +136,105 @@ init_per_testcase(_Func, Config) ->
end_per_testcase(_Func, Config) ->
Config.
-init_per_suite(Config) ->
- try crypto:start() of
- ok ->
- crypto_support_check(Config)
- catch _:_ ->
- {skip, "Crypto did not start"}
- end.
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
-end_per_suite(_Config) ->
- application:stop(crypto).
-
-%%-----------------------------------------------------------------------------
-valid_rsa_signature(doc) ->
- ["Test rsa signatur verification"];
-valid_rsa_signature(suite) ->
- [];
+%%--------------------------- signature_verification--------------------------------------------------
+valid_rsa_signature() ->
+ [{doc, "Test rsa signatur verification"}].
valid_rsa_signature(Config) when is_list(Config) ->
run([{ "4.1.1", "Valid Certificate Path Test1 EE", ok}]).
-invalid_rsa_signature(doc) ->
- ["Test rsa signatur verification"];
-invalid_rsa_signature(suite) ->
- [];
+invalid_rsa_signature() ->
+ [{doc,"Test rsa signatur verification"}].
invalid_rsa_signature(Config) when is_list(Config) ->
run([{ "4.1.2", "Invalid CA Signature Test2 EE", {bad_cert,invalid_signature}},
{ "4.1.3", "Invalid EE Signature Test3 EE", {bad_cert,invalid_signature}}]).
-valid_dsa_signature(doc) ->
- ["Test dsa signatur verification"];
-valid_dsa_signature(suite) ->
- [];
+valid_dsa_signature() ->
+ [{doc,"Test dsa signatur verification"}].
valid_dsa_signature(Config) when is_list(Config) ->
run([{ "4.1.4", "Valid DSA Signatures Test4 EE", ok},
{ "4.1.5", "Valid DSA Parameter Inheritance Test5 EE", ok}]).
-invalid_dsa_signature(doc) ->
- ["Test dsa signatur verification"];
-invalid_dsa_signature(suite) ->
- [];
+invalid_dsa_signature() ->
+ [{doc,"Test dsa signatur verification"}].
invalid_dsa_signature(Config) when is_list(Config) ->
run([{ "4.1.6", "Invalid DSA Signature Test6 EE",{bad_cert,invalid_signature}}]).
-%%-----------------------------------------------------------------------------
-not_before_invalid(doc) ->
- [""];
-not_before_invalid(suite) ->
- [];
+
+%%-----------------------------validity_periods------------------------------------------------
+not_before_invalid() ->
+ [{doc,"Test valid periods"}].
not_before_invalid(Config) when is_list(Config) ->
run([{ "4.2.1", "Invalid CA notBefore Date Test1 EE",{bad_cert, cert_expired}},
{ "4.2.2", "Invalid EE notBefore Date Test2 EE",{bad_cert, cert_expired}}]).
-not_before_valid(doc) ->
- [""];
-not_before_valid(suite) ->
- [];
+not_before_valid() ->
+ [{doc,"Test valid periods"}].
not_before_valid(Config) when is_list(Config) ->
run([{ "4.2.3", "Valid pre2000 UTC notBefore Date Test3 EE", ok},
{ "4.2.4", "Valid GeneralizedTime notBefore Date Test4 EE", ok}]).
-not_after_invalid(doc) ->
- [""];
-not_after_invalid(suite) ->
- [];
+not_after_invalid() ->
+ [{doc,"Test valid periods"}].
not_after_invalid(Config) when is_list(Config) ->
run([{ "4.2.5", "Invalid CA notAfter Date Test5 EE", {bad_cert, cert_expired}},
{ "4.2.6", "Invalid EE notAfter Date Test6 EE", {bad_cert, cert_expired}},
{ "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7 EE",{bad_cert, cert_expired}}]).
-not_after_valid(doc) ->
- [""];
-not_after_valid(suite) ->
- [];
+not_after_valid() ->
+ [{doc,"Test valid periods"}].
not_after_valid(Config) when is_list(Config) ->
run([{ "4.2.8", "Valid GeneralizedTime notAfter Date Test8 EE", ok}]).
-%%-----------------------------------------------------------------------------
-invalid_name_chain(doc) ->
- [""];
-invalid_name_chain(suite) ->
- [];
+
+%%----------------------------verifying_name_chaining-------------------------------------------------
+invalid_name_chain() ->
+ [{doc,"Test name chaining"}].
invalid_name_chain(Config) when is_list(Config) ->
run([{ "4.3.1", "Invalid Name Chaining Test1 EE", {bad_cert, invalid_issuer}},
{ "4.3.2", "Invalid Name Chaining Order Test2 EE", {bad_cert, invalid_issuer}}]).
-whitespace_name_chain(doc) ->
- [""];
-whitespace_name_chain(suite) ->
- [];
+whitespace_name_chain() ->
+ [{doc,"Test name chaining"}].
whitespace_name_chain(Config) when is_list(Config) ->
run([{ "4.3.3", "Valid Name Chaining Whitespace Test3 EE", ok},
{ "4.3.4", "Valid Name Chaining Whitespace Test4 EE", ok}]).
-capitalization_name_chain(doc) ->
- [""];
-capitalization_name_chain(suite) ->
- [];
+capitalization_name_chain() ->
+ [{doc,"Test name chaining"}].
capitalization_name_chain(Config) when is_list(Config) ->
run([{ "4.3.5", "Valid Name Chaining Capitalization Test5 EE",ok}]).
-uid_name_chain(doc) ->
- [""];
-uid_name_chain(suite) ->
- [];
+uid_name_chain() ->
+ [{doc,"Test name chaining"}].
uid_name_chain(Config) when is_list(Config) ->
run([{ "4.3.6", "Valid Name UIDs Test6 EE",ok}]).
-attrib_name_chain(doc) ->
- [""];
-attrib_name_chain(suite) ->
- [];
+attrib_name_chain() ->
+ [{doc,"Test name chaining"}].
attrib_name_chain(Config) when is_list(Config) ->
run([{ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7 EE", ok},
{ "4.3.8", "Valid RFC3280 Optional Attribute Types Test8 EE", ok}]).
-string_name_chain(doc) ->
- [""];
-string_name_chain(suite) ->
- [];
+string_name_chain() ->
+ [{doc,"Test name chaining"}].
string_name_chain(Config) when is_list(Config) ->
run([{ "4.3.9", "Valid UTF8String Encoded Names Test9 EE", ok},
%%{ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10 EE", ok},
{ "4.3.11", "Valid UTF8String Case Insensitive Match Test11 EE", ok}]).
-%%-----------------------------------------------------------------------------
-
-basic_valid(doc) ->
- [""];
-basic_valid(suite) ->
- [];
+%%----------------------------verifying_paths_with_self_issued_certificates-------------------------------------------------
+basic_valid() ->
+ [{doc,"Test self issued certificates"}].
basic_valid(Config) when is_list(Config) ->
run([{ "4.5.1", "Valid Basic Self-Issued Old With New Test1 EE", ok},
{ "4.5.3", "Valid Basic Self-Issued New With Old Test3 EE", ok},
{ "4.5.4", "Valid Basic Self-Issued New With Old Test4 EE", ok}
]).
-basic_invalid(doc) ->
- [""];
-basic_invalid(suite) ->
- [];
+basic_invalid() ->
+ [{doc,"Test self issued certificates"}].
basic_invalid(Config) when is_list(Config) ->
run([{"4.5.2", "Invalid Basic Self-Issued Old With New Test2 EE",
{bad_cert, {revoked, keyCompromise}}},
@@ -260,84 +242,63 @@ basic_invalid(Config) when is_list(Config) ->
{bad_cert, {revoked, keyCompromise}}}
]).
-crl_signing_valid(doc) ->
- [""];
-crl_signing_valid(suite) ->
- [];
+crl_signing_valid() ->
+ [{doc,"Test self issued certificates"}].
crl_signing_valid(Config) when is_list(Config) ->
run([{ "4.5.6", "Valid Basic Self-Issued CRL Signing Key Test6 EE", ok}]).
-crl_signing_invalid(doc) ->
- [""];
-crl_signing_invalid(suite) ->
- [];
+crl_signing_invalid() ->
+ [{doc,"Test self issued certificates"}].
crl_signing_invalid(Config) when is_list(Config) ->
- run([%% { "4.5.7", "Invalid Basic Self-Issued CRL Signing Key Test7 EE",
- %% {bad_cert, {revoked, keyCompromise}}},
+ run([{ "4.5.7", "Invalid Basic Self-Issued CRL Signing Key Test7 EE",
+ {bad_cert, {revoked, keyCompromise}}},
{ "4.5.8", "Invalid Basic Self-Issued CRL Signing Key Test8 EE",
{bad_cert, invalid_key_usage}}
]).
-%%-----------------------------------------------------------------------------
-missing_CRL(doc) ->
- [""];
-missing_CRL(suite) ->
- [];
+%%-----------------------------basic_certificate_revocation_tests------------------------------------------------
+missing_CRL() ->
+ [{doc,"Test basic CRL handling"}].
missing_CRL(Config) when is_list(Config) ->
- run([{ "4.4.1", "Missing CRL Test1 EE",{bad_cert,
+ run([{ "4.4.1", "Invalid Missing CRL Test1 EE",{bad_cert,
revocation_status_undetermined}}]).
-revoked_CA(doc) ->
- [""];
-revoked_CA(suite) ->
- [];
+revoked_CA() ->
+ [{doc,"Test basic CRL handling"}].
revoked_CA(Config) when is_list(Config) ->
run([{ "4.4.2", "Invalid Revoked CA Test2 EE", {bad_cert,
{revoked, keyCompromise}}}]).
-revoked_peer(doc) ->
- [""];
-revoked_peer(suite) ->
- [];
+revoked_peer() ->
+ [{doc,"Test basic CRL handling"}].
revoked_peer(Config) when is_list(Config) ->
- run([{ "4.4.3", "Invalid Revoked EE Test3 EE", {bad_cert,
- {revoked, keyCompromise}}}]).
+ run([{ "4.4.3", "Invalid Revoked EE Test3 EE",
+ {bad_cert, {revoked, keyCompromise}}}]).
-invalid_CRL_signature(doc) ->
- [""];
-invalid_CRL_signature(suite) ->
- [];
+invalid_CRL_signature() ->
+ [{doc,"Test basic CRL handling"}].
invalid_CRL_signature(Config) when is_list(Config) ->
run([{ "4.4.4", "Invalid Bad CRL Signature Test4 EE",
- {bad_cert, revocation_status_undetermined}}]).
-
-invalid_CRL_issuer(doc) ->
- [""];
-invalid_CRL_issuer(suite) ->
- [];
+ {bad_cert, revocation_status_undetermined}}]).
+invalid_CRL_issuer() ->
+ [{doc,"Test basic CRL handling"}].
invalid_CRL_issuer(Config) when is_list(Config) ->
run({ "4.4.5", "Invalid Bad CRL Issuer Name Test5 EE",
{bad_cert, revocation_status_undetermined}}).
-invalid_CRL(doc) ->
- [""];
-invalid_CRL(suite) ->
- [];
+invalid_CRL() ->
+ [{doc,"Test basic CRL handling"}].
invalid_CRL(Config) when is_list(Config) ->
run([{ "4.4.6", "Invalid Wrong CRL Test6 EE",
{bad_cert, revocation_status_undetermined}}]).
-valid_CRL(doc) ->
- [""];
-valid_CRL(suite) ->
- [];
+valid_CRL() ->
+ [{doc,"Test basic CRL handling"}].
valid_CRL(Config) when is_list(Config) ->
run([{ "4.4.7", "Valid Two CRLs Test7 EE", ok}]).
-unknown_CRL_extension(doc) ->
- [""];
-unknown_CRL_extension(suite) ->
- [];
+unknown_CRL_extension() ->
+ [{doc,"Test basic CRL handling"}].
unknown_CRL_extension(Config) when is_list(Config) ->
run([{ "4.4.8", "Invalid Unknown CRL Entry Extension Test8 EE",
{bad_cert, {revoked, keyCompromise}}},
@@ -346,27 +307,21 @@ unknown_CRL_extension(Config) when is_list(Config) ->
{ "4.4.10", "Invalid Unknown CRL Extension Test10 EE",
{bad_cert, revocation_status_undetermined}}]).
-old_CRL(doc) ->
- [""];
-old_CRL(suite) ->
- [];
+old_CRL() ->
+ [{doc,"Test basic CRL handling"}].
old_CRL(Config) when is_list(Config) ->
run([{ "4.4.11", "Invalid Old CRL nextUpdate Test11 EE",
{bad_cert, revocation_status_undetermined}},
{ "4.4.12", "Invalid pre2000 CRL nextUpdate Test12 EE",
{bad_cert, revocation_status_undetermined}}]).
-fresh_CRL(doc) ->
- [""];
-fresh_CRL(suite) ->
- [];
+fresh_CRL() ->
+ [{doc,"Test basic CRL handling"}].
fresh_CRL(Config) when is_list(Config) ->
run([{ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13 EE", ok}]).
-valid_serial(doc) ->
- [""];
-valid_serial(suite) ->
- [];
+valid_serial() ->
+ [{doc,"Test basic CRL handling"}].
valid_serial(Config) when is_list(Config) ->
run([
{ "4.4.14", "Valid Negative Serial Number Test14 EE",ok},
@@ -374,38 +329,30 @@ valid_serial(Config) when is_list(Config) ->
{ "4.4.17", "Valid Long Serial Number Test17 EE", ok}
]).
-invalid_serial(doc) ->
- [""];
-invalid_serial(suite) ->
- [];
+invalid_serial() ->
+ [{doc,"Test basic CRL handling"}].
invalid_serial(Config) when is_list(Config) ->
run([{ "4.4.15", "Invalid Negative Serial Number Test15 EE",
{bad_cert, {revoked, keyCompromise}}},
{ "4.4.18", "Invalid Long Serial Number Test18 EE",
{bad_cert, {revoked, keyCompromise}}}]).
-valid_seperate_keys(doc) ->
- [""];
-valid_seperate_keys(suite) ->
- [];
+valid_seperate_keys() ->
+ [{doc,"Test basic CRL handling"}].
valid_seperate_keys(Config) when is_list(Config) ->
run([{ "4.4.19", "Valid Separate Certificate and CRL Keys Test19 EE", ok}]).
-invalid_separate_keys(doc) ->
- [""];
-invalid_separate_keys(suite) ->
- [];
+invalid_separate_keys() ->
+ [{doc,"Test basic CRL handling"}].
invalid_separate_keys(Config) when is_list(Config) ->
- run([{ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20",
+ run([{ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20 EE",
{bad_cert, {revoked, keyCompromise}}},
- { "4.4.21", "Invalid Separate Certificate and CRL Keys Test21",
+ { "4.4.21", "Invalid Separate Certificate and CRL Keys Test21 EE",
{bad_cert, revocation_status_undetermined}}
]).
-%%-----------------------------------------------------------------------------
-missing_basic_constraints(doc) ->
- [""];
-missing_basic_constraints(suite) ->
- [];
+%%----------------------------verifying_basic_constraints-------------------------------------------------
+missing_basic_constraints() ->
+ [{doc,"Basic constraint tests"}].
missing_basic_constraints(Config) when is_list(Config) ->
run([{ "4.6.1", "Invalid Missing basicConstraints Test1 EE",
{bad_cert, missing_basic_constraint}},
@@ -414,17 +361,13 @@ missing_basic_constraints(Config) when is_list(Config) ->
{ "4.6.3", "Invalid cA False Test3 EE",
{bad_cert, missing_basic_constraint}}]).
-valid_basic_constraint(doc) ->
- [""];
-valid_basic_constraint(suite) ->
- [];
+valid_basic_constraint() ->
+ [{doc,"Basic constraint tests"}].
valid_basic_constraint(Config) when is_list(Config) ->
run([{"4.6.4", "Valid basicConstraints Not Critical Test4 EE", ok}]).
-invalid_path_constraints(doc) ->
- [""];
-invalid_path_constraints(suite) ->
- [];
+invalid_path_constraints() ->
+ [{doc,"Basic constraint tests"}].
invalid_path_constraints(Config) when is_list(Config) ->
run([{ "4.6.5", "Invalid pathLenConstraint Test5 EE", {bad_cert, max_path_length_reached}},
{ "4.6.6", "Invalid pathLenConstraint Test6 EE", {bad_cert, max_path_length_reached}},
@@ -435,10 +378,8 @@ invalid_path_constraints(Config) when is_list(Config) ->
{ "4.6.16", "Invalid Self-Issued pathLenConstraint Test16 EE",
{bad_cert, max_path_length_reached}}]).
-valid_path_constraints(doc) ->
- [""];
-valid_path_constraints(suite) ->
- [];
+valid_path_constraints() ->
+ [{doc,"Basic constraint tests"}].
valid_path_constraints(Config) when is_list(Config) ->
run([{ "4.6.7", "Valid pathLenConstraint Test7 EE", ok},
{ "4.6.8", "Valid pathLenConstraint Test8 EE", ok},
@@ -447,60 +388,54 @@ valid_path_constraints(Config) when is_list(Config) ->
{ "4.6.15", "Valid Self-Issued pathLenConstraint Test15 EE", ok},
{ "4.6.17", "Valid Self-Issued pathLenConstraint Test17 EE", ok}]).
-%%-----------------------------------------------------------------------------
-invalid_key_usage(doc) ->
- [""];
-invalid_key_usage(suite) ->
- [];
+%%-----------------------------key_usage------------------------------------------------
+invalid_key_usage() ->
+ [{doc,"Key usage tests"}].
invalid_key_usage(Config) when is_list(Config) ->
run([{ "4.7.1", "Invalid keyUsage Critical keyCertSign False Test1 EE",
{bad_cert,invalid_key_usage} },
{ "4.7.2", "Invalid keyUsage Not Critical keyCertSign False Test2 EE",
- {bad_cert,invalid_key_usage}}
- %% { "4.7.4", "Invalid keyUsage Critical cRLSign False Test4 EE",
- %% {bad_cert, revocation_status_undetermined}},
- %% { "4.7.5", "Invalid keyUsage Not Critical cRLSign False Test5 EE",
- %% {bad_cert, revocation_status_undetermined}}
+ {bad_cert,invalid_key_usage}},
+ { "4.7.4", "Invalid keyUsage Critical cRLSign False Test4 EE",
+ {bad_cert, invalid_key_usage}},
+ { "4.7.5", "Invalid keyUsage Not Critical cRLSign False Test5 EE",
+ {bad_cert, invalid_key_usage}}
]).
-valid_key_usage(doc) ->
- [""];
-valid_key_usage(suite) ->
- [];
+valid_key_usage() ->
+ [{doc,"Key usage tests"}].
valid_key_usage(Config) when is_list(Config) ->
run([{ "4.7.3", "Valid keyUsage Not Critical Test3 EE", ok}]).
%%-----------------------------------------------------------------------------
-certificate_policies(doc) -> [""];
-certificate_policies(suite) -> [];
+certificate_policies() ->
+ [{doc,"Not supported yet"}].
certificate_policies(Config) when is_list(Config) ->
- run(certificate_policies()).
+ run(certificate_policies_tests()).
%%-----------------------------------------------------------------------------
-require_explicit_policy(doc) -> [""];
-require_explicit_policy(suite) -> [];
+require_explicit_policy() ->
+ [{doc,"Not supported yet"}].
require_explicit_policy(Config) when is_list(Config) ->
- run(require_explicit_policy()).
+ run(require_explicit_policy_tests()).
%%-----------------------------------------------------------------------------
-policy_mappings(doc) -> [""];
-policy_mappings(suite) -> [];
+policy_mappings() ->
+ [{doc,"Not supported yet"}].
policy_mappings(Config) when is_list(Config) ->
- run(policy_mappings()).
+ run(policy_mappings_tests()).
%%-----------------------------------------------------------------------------
-inhibit_policy_mapping(doc) -> [""];
-inhibit_policy_mapping(suite) -> [];
+inhibit_policy_mapping() ->
+ [{doc,"Not supported yet"}].
inhibit_policy_mapping(Config) when is_list(Config) ->
- run(inhibit_policy_mapping()).
+ run(inhibit_policy_mapping_tests()).
%%-----------------------------------------------------------------------------
-inhibit_any_policy(doc) -> [""];
-inhibit_any_policy(suite) -> [];
+inhibit_any_policy() ->
+ [{doc,"Not supported yet"}].
inhibit_any_policy(Config) when is_list(Config) ->
- run(inhibit_any_policy()).
-%%-----------------------------------------------------------------------------
+ run(inhibit_any_policy_tests()).
+%%-------------------------------name_constraints----------------------------------------------
-valid_DN_name_constraints(doc) ->
- [""];
-valid_DN_name_constraints(suite) ->
- [];
+valid_DN_name_constraints() ->
+ [{doc, "Name constraints tests"}].
valid_DN_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.1", "Valid DN nameConstraints Test1 EE", ok},
{ "4.13.4", "Valid DN nameConstraints Test4 EE", ok},
@@ -511,10 +446,8 @@ valid_DN_name_constraints(Config) when is_list(Config) ->
{ "4.13.18", "Valid DN nameConstraints Test18 EE", ok},
{ "4.13.19", "Valid DN nameConstraints Test19 EE", ok}]).
-invalid_DN_name_constraints(doc) ->
- [""];
-invalid_DN_name_constraints(suite) ->
- [];
+invalid_DN_name_constraints() ->
+ [{doc,"Name constraints tests"}].
invalid_DN_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.2", "Invalid DN nameConstraints Test2 EE", {bad_cert, name_not_permitted}},
{ "4.13.3", "Invalid DN nameConstraints Test3 EE", {bad_cert, name_not_permitted}},
@@ -530,20 +463,15 @@ invalid_DN_name_constraints(Config) when is_list(Config) ->
{ "4.13.20", "Invalid DN nameConstraints Test20 EE",
{bad_cert, name_not_permitted}}]).
-valid_rfc822_name_constraints(doc) ->
- [""];
-valid_rfc822_name_constraints(suite) ->
- [];
+valid_rfc822_name_constraints() ->
+ [{doc,"Name constraints tests"}].
valid_rfc822_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.21", "Valid RFC822 nameConstraints Test21 EE", ok},
{ "4.13.23", "Valid RFC822 nameConstraints Test23 EE", ok},
{ "4.13.25", "Valid RFC822 nameConstraints Test25 EE", ok}]).
-
-invalid_rfc822_name_constraints(doc) ->
- [""];
-invalid_rfc822_name_constraints(suite) ->
- [];
+invalid_rfc822_name_constraints() ->
+ [{doc,"Name constraints tests"}].
invalid_rfc822_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.22", "Invalid RFC822 nameConstraints Test22 EE",
{bad_cert, name_not_permitted}},
@@ -552,71 +480,54 @@ invalid_rfc822_name_constraints(Config) when is_list(Config) ->
{ "4.13.26", "Invalid RFC822 nameConstraints Test26 EE",
{bad_cert, name_not_permitted}}]).
-valid_DN_and_rfc822_name_constraints(doc) ->
- [""];
-valid_DN_and_rfc822_name_constraints(suite) ->
- [];
+valid_DN_and_rfc822_name_constraints() ->
+ [{doc,"Name constraints tests"}].
valid_DN_and_rfc822_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.27", "Valid DN and RFC822 nameConstraints Test27 EE", ok}]).
-invalid_DN_and_rfc822_name_constraints(doc) ->
- [""];
-invalid_DN_and_rfc822_name_constraints(suite) ->
- [];
+invalid_DN_and_rfc822_name_constraints() ->
+ [{doc,"Name constraints tests"}].
invalid_DN_and_rfc822_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28 EE",
{bad_cert, name_not_permitted}},
{ "4.13.29", "Invalid DN and RFC822 nameConstraints Test29 EE",
{bad_cert, name_not_permitted}}]).
-valid_dns_name_constraints(doc) ->
- [""];
-valid_dns_name_constraints(suite) ->
- [];
+valid_dns_name_constraints() ->
+ [{doc,"Name constraints tests"}].
valid_dns_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.30", "Valid DNS nameConstraints Test30 EE", ok},
{ "4.13.32", "Valid DNS nameConstraints Test32 EE", ok}]).
-invalid_dns_name_constraints(doc) ->
- [""];
-invalid_dns_name_constraints(suite) ->
- [];
+invalid_dns_name_constraints() ->
+ [{doc,"Name constraints tests"}].
invalid_dns_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.31", "Invalid DNS nameConstraints Test31 EE", {bad_cert, name_not_permitted}},
{ "4.13.33", "Invalid DNS nameConstraints Test33 EE", {bad_cert, name_not_permitted}},
{ "4.13.38", "Invalid DNS nameConstraints Test38 EE", {bad_cert, name_not_permitted}}]).
-valid_uri_name_constraints(doc) ->
- [""];
-valid_uri_name_constraints(suite) ->
- [];
+valid_uri_name_constraints() ->
+ [{doc,"Name constraints tests"}].
valid_uri_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.34", "Valid URI nameConstraints Test34 EE", ok},
{ "4.13.36", "Valid URI nameConstraints Test36 EE", ok}]).
-invalid_uri_name_constraints(doc) ->
- [""];
-invalid_uri_name_constraints(suite) ->
- [];
+invalid_uri_name_constraints() ->
+ [{doc,"Name constraints tests"}].
invalid_uri_name_constraints(Config) when is_list(Config) ->
run([{ "4.13.35", "Invalid URI nameConstraints Test35 EE",{bad_cert, name_not_permitted}},
{ "4.13.37", "Invalid URI nameConstraints Test37 EE",{bad_cert, name_not_permitted}}]).
-%%-----------------------------------------------------------------------------
-delta_without_crl(doc) ->
- [""];
-delta_without_crl(suite) ->
- [];
+%%------------------------------delta_crls-----------------------------------------------
+delta_without_crl() ->
+ [{doc,"Delta CRL tests"}].
delta_without_crl(Config) when is_list(Config) ->
run([{ "4.15.1", "Invalid deltaCRLIndicator No Base Test1 EE",{bad_cert,
revocation_status_undetermined}},
{"4.15.10", "Invalid delta-CRL Test10 EE", {bad_cert,
revocation_status_undetermined}}]).
-
-valid_delta_crls(doc) ->
- [""];
-valid_delta_crls(suite) ->
- [];
+valid_delta_crls() ->
+ [{doc,"Delta CRL tests"}].
valid_delta_crls(Config) when is_list(Config) ->
run([{ "4.15.2", "Valid delta-CRL Test2 EE", ok},
{ "4.15.5", "Valid delta-CRL Test5 EE", ok},
@@ -624,22 +535,17 @@ valid_delta_crls(Config) when is_list(Config) ->
{ "4.15.8", "Valid delta-CRL Test8 EE", ok}
]).
-invalid_delta_crls(doc) ->
- [""];
-invalid_delta_crls(suite) ->
- [];
+invalid_delta_crls() ->
+ [{doc,"Delta CRL tests"}].
invalid_delta_crls(Config) when is_list(Config) ->
run([{ "4.15.3", "Invalid delta-CRL Test3 EE", {bad_cert,{revoked, keyCompromise}}},
{ "4.15.4", "Invalid delta-CRL Test4 EE", {bad_cert,{revoked, keyCompromise}}},
{ "4.15.6", "Invalid delta-CRL Test6 EE", {bad_cert,{revoked, keyCompromise}}},
{ "4.15.9", "Invalid delta-CRL Test9 EE", {bad_cert,{revoked, keyCompromise}}}]).
-%%-----------------------------------------------------------------------------
-
-valid_distribution_points(doc) ->
- [""];
-valid_distribution_points(suite) ->
- [];
+%%---------------------------distribution_points--------------------------------------------------
+valid_distribution_points() ->
+ [{doc,"CRL Distribution Point tests"}].
valid_distribution_points(Config) when is_list(Config) ->
run([{ "4.14.1", "Valid distributionPoint Test1 EE", ok},
{ "4.14.4", "Valid distributionPoint Test4 EE", ok},
@@ -647,18 +553,14 @@ valid_distribution_points(Config) when is_list(Config) ->
{ "4.14.7", "Valid distributionPoint Test7 EE", ok}
]).
-valid_distribution_points_no_issuing_distribution_point(doc) ->
- [""];
-valid_distribution_points_no_issuing_distribution_point(suite) ->
- [];
+valid_distribution_points_no_issuing_distribution_point() ->
+ [{doc,"CRL Distribution Point tests"}].
valid_distribution_points_no_issuing_distribution_point(Config) when is_list(Config) ->
- run([{ "4.14.10", "Valid No issuingDistributionPoint Test10", ok}
+ run([{ "4.14.10", "Valid No issuingDistributionPoint Test10 EE", ok}
]).
-invalid_distribution_points(doc) ->
- [""];
-invalid_distribution_points(suite) ->
- [];
+invalid_distribution_points() ->
+ [{doc,"CRL Distribution Point tests"}].
invalid_distribution_points(Config) when is_list(Config) ->
run([{ "4.14.2", "Invalid distributionPoint Test2 EE", {bad_cert,{revoked, keyCompromise}}},
{ "4.14.3", "Invalid distributionPoint Test3 EE", {bad_cert,
@@ -670,40 +572,31 @@ invalid_distribution_points(Config) when is_list(Config) ->
revocation_status_undetermined}}
]).
-valid_only_contains(doc) ->
- [""];
-valid_only_contains(suite) ->
- [];
+valid_only_contains() ->
+ [{doc,"CRL Distribution Point tests"}].
valid_only_contains(Config) when is_list(Config) ->
- run([{ "4.14.13", "Valid onlyContainsCACerts CRL Test13 EE", ok}]).
-
+ run([{ "4.14.13", "Valid only Contains CA Certs Test13 EE", ok}]).
-invalid_only_contains(doc) ->
- [""];
-invalid_only_contains(suite) ->
- [];
+invalid_only_contains() ->
+ [{doc,"CRL Distribution Point tests"}].
invalid_only_contains(Config) when is_list(Config) ->
- run([{ "4.14.11", "Invalid onlyContainsUserCerts CRL Test11 EE",
+ run([{ "4.14.11", "Invalid onlyContainsUserCerts Test11 EE",
{bad_cert, revocation_status_undetermined}},
- { "4.14.12", "Invalid onlyContainsCACerts CRL Test12 EE",
+ { "4.14.12", "Invalid onlyContainsCACerts Test12 EE",
{bad_cert, revocation_status_undetermined}},
{ "4.14.14", "Invalid onlyContainsAttributeCerts Test14 EE",
{bad_cert, revocation_status_undetermined}}
]).
-valid_only_some_reasons(doc) ->
- [""];
-valid_only_some_reasons(suite) ->
- [];
+valid_only_some_reasons() ->
+ [{doc,"CRL Distribution Point tests"}].
valid_only_some_reasons(Config) when is_list(Config) ->
run([{ "4.14.18", "Valid onlySomeReasons Test18 EE", ok},
{ "4.14.19", "Valid onlySomeReasons Test19 EE", ok}
]).
-invalid_only_some_reasons(doc) ->
- [""];
-invalid_only_some_reasons(suite) ->
- [];
+invalid_only_some_reasons() ->
+ [{doc,"CRL Distribution Point tests"}].
invalid_only_some_reasons(Config) when is_list(Config) ->
run([{ "4.14.15", "Invalid onlySomeReasons Test15 EE",
{bad_cert,{revoked, keyCompromise}}},
@@ -717,20 +610,16 @@ invalid_only_some_reasons(Config) when is_list(Config) ->
{bad_cert,{revoked, affiliationChanged}}}
]).
-valid_indirect_crl(doc) ->
- [""];
-valid_indirect_crl(suite) ->
- [];
+valid_indirect_crl() ->
+ [{doc,"CRL Distribution Point tests"}].
valid_indirect_crl(Config) when is_list(Config) ->
run([{ "4.14.22", "Valid IDP with indirectCRL Test22 EE", ok},
{ "4.14.24", "Valid IDP with indirectCRL Test24 EE", ok},
{ "4.14.25", "Valid IDP with indirectCRL Test25 EE", ok}
]).
-invalid_indirect_crl(doc) ->
- [""];
-invalid_indirect_crl(suite) ->
- [];
+invalid_indirect_crl() ->
+ [{doc,"CRL Distribution Point tests"}].
invalid_indirect_crl(Config) when is_list(Config) ->
run([{ "4.14.23", "Invalid IDP with indirectCRL Test23 EE",
{bad_cert,{revoked, keyCompromise}}},
@@ -738,20 +627,16 @@ invalid_indirect_crl(Config) when is_list(Config) ->
{bad_cert, revocation_status_undetermined}}
]).
-valid_crl_issuer(doc) ->
- [""];
-valid_crl_issuer(suite) ->
- [];
+valid_crl_issuer() ->
+ [{doc,"CRL Distribution Point tests"}].
valid_crl_issuer(Config) when is_list(Config) ->
- run([{ "4.14.28", "Valid cRLIssuer Test28 EE", ok}%%,
- %%{ "4.14.29", "Valid cRLIssuer Test29 EE", ok},
- %%{ "4.14.33", "Valid cRLIssuer Test33 EE", ok}
+ run([{ "4.14.28", "Valid cRLIssuer Test28 EE", ok},
+ { "4.14.29", "Valid cRLIssuer Test29 EE", ok},
+ { "4.14.33", "Valid cRLIssuer Test33 EE", ok}
]).
-invalid_crl_issuer(doc) ->
- [""];
-invalid_crl_issuer(suite) ->
- [];
+invalid_crl_issuer() ->
+ [{doc,"CRL Distribution Point tests"}].
invalid_crl_issuer(Config) when is_list(Config) ->
run([
{ "4.14.27", "Invalid cRLIssuer Test27 EE", {bad_cert, revocation_status_undetermined}},
@@ -761,44 +646,36 @@ invalid_crl_issuer(Config) when is_list(Config) ->
{ "4.14.35", "Invalid cRLIssuer Test35 EE", {bad_cert, revocation_status_undetermined}}
]).
-
-%%distribution_points() ->
- %%{ "4.14", "Distribution Points" },
-%% [
- %% Although this test is valid it has a circular dependency. As a result
- %% an attempt is made to reursively checks a CRL path and rejected due to
- %% a CRL path validation error. PKITS notes suggest this test does not
- %% need to be run due to this issue.
-%% { "4.14.30", "Valid cRLIssuer Test30", 54 }].
+%% Although this test is valid it has a circular dependency. As a result
+%% an attempt is made to reursively checks a CRL path and rejected due to
+%% a CRL path validation error. PKITS notes suggest this test does not
+%% need to be run due to this issue.
+%% { "4.14.30", "Valid cRLIssuer Test30", 54 }
-%%-----------------------------------------------------------------------------
+%%-------------------------------private_certificate_extensions----------------------------------------------
-unknown_critical_extension(doc) ->
- [""];
-unknown_critical_extension(suite) ->
- [];
+unknown_critical_extension() ->
+ [{doc,"Test that a cert with an unknown critical extension is recjected"}].
unknown_critical_extension(Config) when is_list(Config) ->
run([{ "4.16.2", "Invalid Unknown Critical Certificate Extension Test2 EE",
{bad_cert,unknown_critical_extension}}]).
-unknown_not_critical_extension(doc) ->
- [""];
-unknown_not_critical_extension(suite) ->
- [];
+unknown_not_critical_extension() ->
+ [{doc,"Test that a not critical unknown extension is ignored"}].
unknown_not_critical_extension(Config) when is_list(Config) ->
run([{ "4.16.1", "Valid Unknown Not Critical Certificate Extension Test1 EE", ok}]).
-%%-----------------------------------------------------------------------------
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
run(Tests) ->
[TA] = read_certs("Trust Anchor Root Certificate"),
run(Tests, TA).
run({Chap, Test, Result}, TA) ->
CertChain = cas(Chap) ++ read_certs(Test),
- lists:foreach(fun(C) ->
- io:format("CERT: ~p~n", [public_key:pkix_decode_cert(C, otp)])
- end, CertChain),
Options = path_validation_options(TA, Chap,Test),
try public_key:pkix_path_validation(TA, CertChain, Options) of
{Result, _} -> ok;
@@ -825,7 +702,7 @@ run([],_) -> ok.
path_validation_options(TA, Chap, Test) ->
case needs_crl_options(Chap) of
true ->
- crl_options(TA, Test);
+ crl_options(TA, Chap, Test);
false ->
Fun =
fun(_,{bad_cert, _} = Reason, _) ->
@@ -839,6 +716,56 @@ path_validation_options(TA, Chap, Test) ->
[{verify_fun, {Fun, []}}]
end.
+read_certs(Test) ->
+ File = cert_file(Test),
+ Ders = erl_make_certs:pem_to_der(File),
+ [Cert || {'Certificate', Cert, not_encrypted} <- Ders].
+
+read_crls(Test) ->
+ File = crl_file(Test),
+ Ders = erl_make_certs:pem_to_der(File),
+ [CRL || {'CertificateList', CRL, not_encrypted} <- Ders].
+
+cert_file(Test) ->
+ file(?CONV, lists:append(string:tokens(Test, " -")) ++ ".pem").
+
+crl_file(Test) ->
+ file(?CRL, lists:append(string:tokens(Test, " -")) ++ ".pem").
+
+
+file(Sub,File) ->
+ TestDir = case get(datadir) of
+ undefined -> "./pkits_SUITE_data";
+ Dir when is_list(Dir) ->
+ Dir
+ end,
+ AbsFile = filename:join([TestDir,Sub,File]),
+ case filelib:is_file(AbsFile) of
+ true -> ok;
+ false ->
+ ?error("Couldn't read data from ~p ~n",[AbsFile])
+ end,
+ AbsFile.
+
+error(Format, Args, File0, Line) ->
+ File = filename:basename(File0),
+ Pid = group_leader(),
+ Pid ! {failed, File, Line},
+ io:format(Pid, "~s(~p): ERROR"++Format, [File,Line|Args]).
+
+warning(Format, Args, File0, Line) ->
+ File = filename:basename(File0),
+ io:format("~s(~p): Warning "++Format, [File,Line|Args]).
+
+crypto_support_check(Config) ->
+ try crypto:sha256(<<"Test">>) of
+ _ ->
+ Config
+ catch error:notsup ->
+ crypto:stop(),
+ {skip, "To old version of openssl"}
+ end.
+
needs_crl_options("4.4" ++ _) ->
true;
needs_crl_options("4.5" ++ _) ->
@@ -854,54 +781,69 @@ needs_crl_options("4.15" ++ _) ->
needs_crl_options(_) ->
false.
-crl_options(TA, Test) ->
- case read_crls(Test) of
- [] ->
- [];
- CRLs ->
- Fun =
- fun(_,{bad_cert, _} = Reason, _) ->
- {fail, Reason};
- (_,{extension,
- #'Extension'{extnID = ?'id-ce-cRLDistributionPoints',
- extnValue = Value}}, UserState0) ->
- UserState = update_crls(Value, UserState0),
+crl_options(_TA, Chap, _Test) ->
+ CRLNames = crl_names(Chap),
+ CRLs = crls(CRLNames),
+ Paths = lists:map(fun(CRLName) -> crl_path(CRLName) end, CRLNames),
+
+ ct:print("Paths ~p ~n Names ~p ~n", [Paths, CRLNames]),
+ Fun =
+ fun(_,{bad_cert, _} = Reason, _) ->
+ {fail, Reason};
+ (_,{extension,
+ #'Extension'{extnID = ?'id-ce-cRLDistributionPoints',
+ extnValue = Value}}, UserState0) ->
+ UserState = update_crls(Value, UserState0),
+ {valid, UserState};
+ (_,{extension, _}, UserState) ->
+ {unknown, UserState};
+ (OtpCert, Valid, UserState) when Valid == valid;
+ Valid == valid_peer ->
+ DerCRLs = UserState#verify_state.crls,
+ Paths = UserState#verify_state.crl_paths,
+ Crls = [{DerCRL, public_key:der_decode('CertificateList',
+ DerCRL)} || DerCRL <- DerCRLs],
+
+ CRLInfo0 = crl_info(OtpCert, Crls, []),
+ CRLInfo = lists:reverse(CRLInfo0),
+ PathDb = crl_path_db(lists:reverse(Crls), Paths, []),
+
+ Fun = fun(DP, CRLtoValidate, Id, PathDb0) ->
+ trusted_cert_and_path(DP, CRLtoValidate, Id, PathDb0)
+ end,
+
+ case CRLInfo of
+ [] ->
{valid, UserState};
- (_,{extension, _}, UserState) ->
- {unknown, UserState};
- (OtpCert, Valid, UserState) when Valid == valid;
- Valid == valid_peer ->
- {ErlCerts, CRLs} = UserState#verify_state.crl_info,
- CRLInfo0 =
- crl_info(OtpCert,
- ErlCerts,[{DerCRL, public_key:der_decode('CertificateList',
- DerCRL)} || DerCRL <- CRLs],
- []),
- CRLInfo = lists:reverse(CRLInfo0),
- Certs = UserState#verify_state.certs_db,
- Fun = fun(DP, CRLtoValidate, Id, CertsDb) ->
- trusted_cert_and_path(DP, CRLtoValidate, Id, CertsDb)
- end,
- Ignore = ignore_sign_test_when_building_path(Test),
+ [_|_] ->
case public_key:pkix_crls_validate(OtpCert, CRLInfo,
- [{issuer_fun,{Fun, {Ignore, Certs}}}]) of
+ [{issuer_fun,{Fun, PathDb}}]) of
valid ->
{valid, UserState};
Reason ->
{fail, Reason}
end
- end,
+ end
+ end,
- Certs = read_certs(Test),
- ErlCerts = [public_key:pkix_decode_cert(Cert, otp) || Cert <- Certs],
+ [{verify_fun, {Fun, #verify_state{crls = CRLs,
+ crl_paths = Paths}}}].
- [{verify_fun, {Fun, #verify_state{certs_db = [TA| Certs],
- crl_info = {ErlCerts, CRLs}}}}]
- end.
+crl_path_db([], [], Acc) ->
+ Acc;
+crl_path_db([{_, CRL} |CRLs], [Path | Paths], Acc) ->
+ CertPath = lists:flatten(lists:map(fun([]) ->
+ [];
+ (CertFile) ->
+ ct:print("Certfile ~p", [CertFile]),
+ read_certs(CertFile)
+ end, Path)),
+ crl_path_db(CRLs, Paths, [{CRL, CertPath}| Acc]).
-crl_info(_, _, [], Acc) ->
+
+crl_info(_, [], Acc) ->
Acc;
-crl_info(OtpCert, Certs, [{_, #'CertificateList'{tbsCertList =
+crl_info(OtpCert, [{_, #'CertificateList'{tbsCertList =
#'TBSCertList'{issuer = Issuer,
crlExtensions = CRLExtensions}}}
= CRL | Rest], Acc) ->
@@ -910,22 +852,36 @@ crl_info(OtpCert, Certs, [{_, #'CertificateList'{tbsCertList =
ExtList = pubkey_cert:extensions_list(CRLExtensions),
DPs = case pubkey_cert:select_extension(?'id-ce-cRLDistributionPoints', Extensions) of
#'Extension'{extnValue = Value} ->
- lists:map(fun(Point) -> pubkey_cert_records:transform(Point, decode) end, Value);
- _ ->
- case same_issuer(OtpCert, Issuer) of
- true ->
- [make_dp(ExtList, asn1_NOVALUE, Issuer)];
- false ->
- [make_dp(ExtList, Issuer, ignore)]
- end
+ lists:foldl(fun(Point, Acc0) ->
+ Dp = pubkey_cert_records:transform(Point, decode),
+ IDP = pubkey_cert:select_extension(?'id-ce-issuingDistributionPoint',
+ Extensions),
+ case Dp#'DistributionPoint'.cRLIssuer of
+ asn1_NOVALUE ->
+ [Dp | Acc0];
+ DpCRLIssuer ->
+ CRLIssuer = dp_crlissuer_to_issuer(DpCRLIssuer),
+ CertIssuer = OtpTBSCert#'OTPTBSCertificate'.issuer,
+ case pubkey_cert:is_issuer(CRLIssuer, CertIssuer) of
+ true ->
+ [Dp | Acc0];
+ false when (IDP =/= undefined) ->
+ Acc0;
+ false ->
+ [Dp | Acc0]
+ end
+ end
+ end, [], Value);
+ _ ->
+ case same_issuer(OtpCert, Issuer) of
+ true ->
+ [make_dp(ExtList, asn1_NOVALUE, Issuer)];
+ false ->
+ [make_dp(ExtList, Issuer, ignore)]
+ end
end,
DPsCRLs = lists:map(fun(DP) -> {DP, CRL} end, DPs),
- crl_info(OtpCert, Certs, Rest, DPsCRLs ++ Acc).
-
-ignore_sign_test_when_building_path("Invalid Bad CRL Signature Test4") ->
- true;
-ignore_sign_test_when_building_path(_) ->
- false.
+ crl_info(OtpCert, Rest, DPsCRLs ++ Acc).
same_issuer(OTPCert, Issuer) ->
DecIssuer = pubkey_cert_records:transform(Issuer, decode),
@@ -957,200 +913,23 @@ mk_issuer_dp(Issuer, _) ->
update_crls(_, State) ->
State.
-trusted_cert_and_path(DP, CRL, Id, {Ignore, CertsList}) ->
- case crl_issuer(crl_issuer_name(DP), CRL, Id, CertsList, CertsList, Ignore) of
- {ok, IssuerCert, DerIssuerCert} ->
- Certs = [{public_key:pkix_decode_cert(Cert, otp), Cert} || Cert <- CertsList],
- CertChain = build_chain(Certs, Certs, IssuerCert, Ignore, [DerIssuerCert]),
- {ok, public_key:pkix_decode_cert(hd(CertChain), otp), CertChain};
- Other ->
- Other
- end.
-
-crl_issuer_name(#'DistributionPoint'{cRLIssuer = asn1_NOVALUE}) ->
- undefined;
-crl_issuer_name(#'DistributionPoint'{cRLIssuer = [{directoryName, Issuer}]}) ->
- pubkey_cert_records:transform(Issuer, decode).
+trusted_cert_and_path(_, #'CertificateList'{} = CRL, _, PathDb) ->
+ [TrustedDERCert] = read_certs(crl_root_cert()),
+ TrustedCert = public_key:pkix_decode_cert(TrustedDERCert, otp),
-build_chain([],_, _, _,Acc) ->
- Acc;
-
-build_chain([{First, DerFirst}|Certs], All, Cert, Ignore, Acc) ->
- case public_key:pkix_is_self_signed(Cert) andalso is_test_root(Cert) of
- true ->
- Acc;
- false ->
- case public_key:pkix_is_issuer(Cert, First)
- %%andalso check_extension_cert_signer(First)
- andalso is_signer(First, Cert, Ignore)
- of
- true ->
- build_chain(All, All, First, Ignore, [DerFirst | Acc]);
- false ->
- build_chain(Certs, All, Cert, Ignore, Acc)
- end
- end.
-
-is_signer(_,_, true) ->
- true;
-is_signer(Signer, #'OTPCertificate'{} = Cert,_) ->
- TBSCert = Signer#'OTPCertificate'.tbsCertificate,
- PublicKeyInfo = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
- PublicKey = PublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey,
- AlgInfo = PublicKeyInfo#'OTPSubjectPublicKeyInfo'.algorithm,
- PublicKeyParams = AlgInfo#'PublicKeyAlgorithm'.parameters,
- try pubkey_cert:validate_signature(Cert, public_key:pkix_encode('OTPCertificate',
- Cert, otp),
- PublicKey, PublicKeyParams, true, ?DEFAULT_VERIFYFUN) of
- true ->
- true
- catch
- _:_ ->
- false
- end;
-is_signer(Signer, #'CertificateList'{} = CRL, _) ->
- TBSCert = Signer#'OTPCertificate'.tbsCertificate,
- PublicKeyInfo = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
- PublicKey = PublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey,
- AlgInfo = PublicKeyInfo#'OTPSubjectPublicKeyInfo'.algorithm,
- PublicKeyParams = AlgInfo#'PublicKeyAlgorithm'.parameters,
- pubkey_crl:verify_crl_signature(CRL, public_key:pkix_encode('CertificateList',
- CRL, plain),
- PublicKey, PublicKeyParams).
-
-is_test_root(OtpCert) ->
- TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
- {rdnSequence, AtterList} = TBSCert#'OTPTBSCertificate'.issuer,
- lists:member([{'AttributeTypeAndValue',{2,5,4,3},{printableString,"Trust Anchor"}}],
- AtterList).
-
-check_extension_cert_signer(OtpCert) ->
- TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
- Extensions = TBSCert#'OTPTBSCertificate'.extensions,
- case pubkey_cert:select_extension(?'id-ce-keyUsage', Extensions) of
- #'Extension'{extnValue = KeyUse} ->
- lists:member(keyCertSign, KeyUse);
- _ ->
- true
- end.
-
-check_extension_crl_signer(OtpCert) ->
- TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
- Extensions = TBSCert#'OTPTBSCertificate'.extensions,
- case pubkey_cert:select_extension(?'id-ce-keyUsage', Extensions) of
- #'Extension'{extnValue = KeyUse} ->
- lists:member(cRLSign, KeyUse);
- _ ->
- true
+ case lists:keysearch(CRL, 1, PathDb) of
+ {_, {CRL, [ _| _] = Path}} ->
+ {ok, TrustedCert, [TrustedDERCert | Path]};
+ {_, {CRL, []}} ->
+ {ok, TrustedCert, [TrustedDERCert]}
end.
-crl_issuer(undefined, CRL, issuer_not_found, _, CertsList, Ignore) ->
- crl_issuer(CRL, CertsList, Ignore);
-
-crl_issuer(IssuerName, CRL, issuer_not_found, CertsList, CertsList, Ignore) ->
- crl_issuer(IssuerName, CRL, IssuerName, CertsList, CertsList, Ignore);
-
-crl_issuer(undefined, CRL, Id, [Cert | Rest], All, false) ->
- ErlCert = public_key:pkix_decode_cert(Cert, otp),
- TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate,
- SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber,
- Issuer = public_key:pkix_normalize_name(
- TBSCertificate#'OTPTBSCertificate'.subject),
- Bool = is_signer(ErlCert, CRL, false),
- case {SerialNumber, Issuer} of
- Id when Bool == true ->
- {ok, ErlCert, Cert};
- _ ->
- crl_issuer(undefined, CRL, Id, Rest, All, false)
- end;
-
-crl_issuer(IssuerName, CRL, Id, [Cert | Rest], All, false) ->
- ErlCert = public_key:pkix_decode_cert(Cert, otp),
- TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate,
- SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber,
- %%Issuer = public_key:pkix_normalize_name(
- %% TBSCertificate#'OTPTBSCertificate'.subject),
- Bool = is_signer(ErlCert, CRL, false),
- case {SerialNumber, IssuerName} of
- Id when Bool == true ->
- {ok, ErlCert, Cert};
- {_, IssuerName} when Bool == true ->
- {ok, ErlCert, Cert};
- _ ->
- crl_issuer(IssuerName, CRL, Id, Rest, All, false)
- end;
-
-crl_issuer(undefined, CRL, _, [], CertsList, Ignore) ->
- crl_issuer(CRL, CertsList, Ignore);
-crl_issuer(CRLName, CRL, _, [], CertsList, Ignore) ->
- crl_issuer(CRLName, CRL, CertsList, Ignore).
-
-
-crl_issuer(_, [],_) ->
- {error, issuer_not_found};
-crl_issuer(CRL, [Cert | Rest], Ignore) ->
- ErlCert = public_key:pkix_decode_cert(Cert, otp),
- case public_key:pkix_is_issuer(CRL, ErlCert) andalso
- check_extension_crl_signer(ErlCert) andalso
- is_signer(ErlCert, CRL, Ignore)
- of
- true ->
- {ok, ErlCert,Cert};
- false ->
- crl_issuer(CRL, Rest, Ignore)
- end.
-
-crl_issuer(_,_, [],_) ->
- {error, issuer_not_found};
-crl_issuer(IssuerName, CRL, [Cert | Rest], Ignore) ->
- ErlCert = public_key:pkix_decode_cert(Cert, otp),
- TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate,
- Issuer = public_key:pkix_normalize_name(
- TBSCertificate#'OTPTBSCertificate'.subject),
-
- case
- public_key:pkix_is_issuer(CRL, ErlCert) andalso
- check_extension_crl_signer(ErlCert) andalso
- is_signer(ErlCert, CRL, Ignore)
- of
- true ->
- case pubkey_cert:is_issuer(Issuer, IssuerName) of
- true ->
- {ok, ErlCert,Cert};
- false ->
- crl_issuer(IssuerName, CRL, Rest, Ignore)
- end;
- false ->
- crl_issuer(IssuerName, CRL, Rest, Ignore)
- end.
-
-read_certs(Test) ->
- File = test_file(Test),
- Ders = erl_make_certs:pem_to_der(File),
- [Cert || {'Certificate', Cert, not_encrypted} <- Ders].
-
-read_crls(Test) ->
- File = test_file(Test),
- Ders = erl_make_certs:pem_to_der(File),
- [CRL || {'CertificateList', CRL, not_encrypted} <- Ders].
-test_file(Test) ->
- io:format("TEST: ~p~n", [Test]),
- file(?CONV, lists:append(string:tokens(Test, " -")) ++ ".pem").
+dp_crlissuer_to_issuer(DPCRLIssuer) ->
+ [{directoryName, Issuer}] = pubkey_cert_records:transform(DPCRLIssuer, decode),
+ Issuer.
-file(Sub,File) ->
- TestDir = case get(datadir) of
- undefined -> "./pkits_SUITE_data";
- Dir when is_list(Dir) ->
- Dir
- end,
- AbsFile = filename:join([TestDir,Sub,File]),
- case filelib:is_file(AbsFile) of
- true -> ok;
- false ->
- ?error("Couldn't read data from ~p ~n",[AbsFile])
- end,
- AbsFile.
+%%%%%%%%%%%%%%% CA mappings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cas(Chap) ->
CAS = intermidiate_cas(Chap),
@@ -1242,17 +1021,15 @@ intermidiate_cas(Chap) when Chap == "4.6.2" ->
intermidiate_cas(Chap) when Chap == "4.6.3" ->
["basicConstraints Not Critical cA False CA Cert"];
-intermidiate_cas(Chap) when Chap == "4.5.2";
- Chap == "4.5.5" ->
- ["Basic Self-Issued New Key CA Cert"];
-
-intermidiate_cas(Chap) when Chap == "4.5.1" ->
+intermidiate_cas(Chap) when Chap == "4.5.1";
+ Chap == "4.5.2" ->
["Basic Self-Issued New Key OldWithNew CA Cert", "Basic Self-Issued New Key CA Cert"];
intermidiate_cas(Chap) when Chap == "4.5.3" ->
["Basic Self-Issued Old Key NewWithOld CA Cert", "Basic Self-Issued Old Key CA Cert"];
-intermidiate_cas(Chap) when Chap == "4.5.4" ->
+intermidiate_cas(Chap) when Chap == "4.5.4";
+ Chap == "4.5.5" ->
["Basic Self-Issued Old Key CA Cert"];
intermidiate_cas(Chap) when Chap == "4.13.1";
@@ -1301,9 +1078,6 @@ intermidiate_cas(Chap) when Chap == "4.13.19" ->
["nameConstraints DN1 Self-Issued CA Cert",
"nameConstraints DN1 CA Cert"];
-intermidiate_cas(Chap) when Chap == "4.5.6" ->
- ["Basic Self-Issued CRL Signing Key CA Cert"];
-
intermidiate_cas(Chap) when Chap == "4.7.1";
Chap == "4.7.4" ->
["keyUsage Critical keyCertSign False CA Cert"];
@@ -1387,29 +1161,349 @@ intermidiate_cas(Chap) when Chap == "4.6.16" ->
"pathLenConstraint0 Self-Issued CA Cert",
"pathLenConstraint0 CA Cert"];
-intermidiate_cas(Chap) when Chap == "4.5.7";
- Chap == "4.5.8"
- ->
- ["Basic Self-Issued CRL Signing Key CRL Cert",
- "Basic Self-Issued CRL Signing Key CA Cert"].
+intermidiate_cas(Chap) when Chap == "4.4.1" ->
+ ["No CRL CA Cert"];
-error(Format, Args, File0, Line) ->
- File = filename:basename(File0),
- Pid = group_leader(),
- Pid ! {failed, File, Line},
- io:format(Pid, "~s(~p): ERROR"++Format, [File,Line|Args]).
+intermidiate_cas(Chap) when Chap == "4.4.2" ->
+ ["Revoked subCA Cert", "Good CA Cert"];
-warning(Format, Args, File0, Line) ->
- File = filename:basename(File0),
- io:format("~s(~p): Warning "++Format, [File,Line|Args]).
+intermidiate_cas(Chap) when Chap == "4.4.3" ->
+ ["Good CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.4" ->
+ ["Bad CRL Signature CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.5" ->
+ ["Bad CRL Issuer Name CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.6" ->
+ ["Wrong CRL CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.7" ->
+ ["Two CRLs CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.8" ->
+ ["Unknown CRL Entry Extension CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.9";
+ Chap == "4.4.10" ->
+ ["Unknown CRL Extension CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.11" ->
+ ["Old CRL nextUpdate CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.12" ->
+ ["pre2000 CRL nextUpdate CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.13" ->
+ ["GeneralizedTime CRL nextUpdate CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.14";
+ Chap == "4.4.15" ->
+ ["Negative Serial Number CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.16";
+ Chap == "4.4.17";
+ Chap == "4.4.18" ->
+ ["Long Serial Number CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.19";
+ Chap == "4.4.20" ->
+ ["Separate Certificate and CRL Keys Certificate Signing CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.4.21" ->
+ ["Separate Certificate and CRL Keys CA2 Certificate Signing CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.1";
+ Chap == "4.14.2";
+ Chap == "4.14.3";
+ Chap == "4.14.4" ->
+ ["distributionPoint1 CA Cert"];
+intermidiate_cas(Chap) when Chap == "4.14.5";
+ Chap == "4.14.6";
+ Chap == "4.14.7";
+ Chap == "4.14.8";
+ Chap == "4.14.9" ->
+ ["distributionPoint2 CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.10" ->
+ ["No issuingDistributionPoint CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.11" ->
+ ["onlyContainsUserCerts CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.12";
+ Chap == "4.14.13" ->
+ ["onlyContainsCACerts CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.14" ->
+ ["onlyContainsAttributeCerts CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.15";
+ Chap == "4.14.16" ->
+ ["onlySomeReasons CA1 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.17" ->
+ ["onlySomeReasons CA2 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.18" ->
+ ["onlySomeReasons CA3 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.19";
+ Chap == "4.14.20";
+ Chap == "4.14.21" ->
+ ["onlySomeReasons CA4 Cert"];
+intermidiate_cas(Chap) when Chap == "4.14.22";
+ Chap == "4.14.23" ->
+ ["indirectCRL CA1 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.24";
+ Chap == "4.14.25";
+ Chap == "4.14.26" ->
+ ["indirectCRL CA2 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.27" ->
+ ["indirectCRL CA2 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.28";
+ Chap == "4.14.29" ->
+ ["indirectCRL CA3 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.31";
+ Chap == "4.14.32";
+ Chap == "4.14.33" ->
+ ["indirectCRL CA6 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.14.34";
+ Chap == "4.14.35" ->
+ ["indirectCRL CA5 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.15.1" ->
+ ["deltaCRLIndicator No Base CA Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.15.2";
+ Chap == "4.15.3";
+ Chap == "4.15.4";
+ Chap == "4.15.5";
+ Chap == "4.15.6";
+ Chap == "4.15.7" ->
+ ["deltaCRL CA1 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.15.8";
+ Chap == "4.15.9" ->
+ ["deltaCRL CA2 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.15.10" ->
+ ["deltaCRL CA3 Cert"];
+
+intermidiate_cas(Chap) when Chap == "4.5.6";
+ Chap == "4.5.7" ->
+ ["Basic Self-Issued CRL Signing Key CA Cert"];
+intermidiate_cas(Chap) when Chap == "4.5.8" ->
+ ["Basic Self-Issued CRL Signing Key CRL Cert"].
+
+
+%%%%%%%%%%%%%%% CRL mappings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+crl_names("4.4.1") ->
+ ["Trust Anchor Root CRL"];
+crl_names("4.4.2") ->
+ ["Trust Anchor Root CRL", "Good CA CRL", "Revoked subCA CRL"];
+crl_names("4.4.3") ->
+ ["Trust Anchor Root CRL", "Good CA CRL", "Revoked subCA CRL"];
+crl_names("4.4.4") ->
+ ["Trust Anchor Root CRL", "Bad CRL Signature CA CRL"];
+crl_names("4.4.5") ->
+ ["Trust Anchor Root CRL", "Bad CRL Issuer Name CA CRL"];
+crl_names("4.4.6") ->
+ ["Trust Anchor Root CRL", "Wrong CRL CA CRL"];
+crl_names("4.4.7") ->
+ ["Trust Anchor Root CRL", "Two CRLs CA Good CRL", "Two CRLs CA Bad CRL"];
+crl_names("4.4.8") ->
+ ["Trust Anchor Root CRL", "Unknown CRL Entry Extension CA CRL"];
+crl_names(Chap) when Chap == "4.4.9";
+ Chap == "4.4.10"->
+ ["Trust Anchor Root CRL", "Unknown CRL Extension CA CRL"];
+crl_names("4.4.11") ->
+ ["Trust Anchor Root CRL", "Old CRL nextUpdate CA CRL"];
+crl_names("4.4.12") ->
+ ["Trust Anchor Root CRL", "pre2000 CRL nextUpdate CA CRL"];
+crl_names("4.4.13") ->
+ ["Trust Anchor Root CRL", "GeneralizedTime CRL nextUpdate CA CRL"];
+crl_names(Chap) when Chap == "4.4.14";
+ Chap == "4.4.15"->
+ ["Trust Anchor Root CRL", "Negative Serial Number CA CRL"];
+crl_names(Chap) when Chap == "4.4.16";
+ Chap == "4.4.17";
+ Chap == "4.4.18" ->
+ ["Trust Anchor Root CRL", "Long Serial Number CA CRL"];
+crl_names(Chap)when Chap == "4.4.19";
+ Chap == "4.4.20" ->
+ ["Trust Anchor Root CRL", "Separate Certificate and CRL Keys CRL"];
+crl_names("4.4.21") ->
+ ["Trust Anchor Root CRL", "Separate Certificate and CRL Keys CA2 CRL"];
+crl_names(Chap) when Chap == "4.5.1";
+ Chap == "4.5.2"->
+ ["Trust Anchor Root CRL", "Basic Self-Issued New Key CA CRL"];
+crl_names(Chap) when Chap == "4.5.3";
+ Chap == "4.5.4";
+ Chap == "4.5.5" ->
+ ["Trust Anchor Root CRL", "Basic Self-Issued Old Key Self-Issued Cert CRL",
+ "Basic Self-Issued Old Key CA CRL"];
+crl_names(Chap) when Chap == "4.5.6";
+ Chap == "4.5.7";
+ Chap == "4.5.8" ->
+ ["Trust Anchor Root CRL", "Basic Self-Issued CRL Signing Key CRL Cert CRL",
+ "Basic Self-Issued CRL Signing Key CA CRL"
+ ];
+crl_names("4.7.4") ->
+ ["Trust Anchor Root CRL", "keyUsage Critical cRLSign False CA CRL"];
+crl_names("4.7.5") ->
+ ["Trust Anchor Root CRL", "keyUsage Not Critical cRLSign False CA CRL"];
+crl_names(Chap) when Chap == "4.14.1";
+ Chap == "4.14.2";
+ Chap == "4.14.3";
+ Chap == "4.14.4" ->
+ ["Trust Anchor Root CRL", "distributionPoint1 CA CRL"];
+crl_names(Chap) when Chap == "4.14.5";
+ Chap == "4.14.6";
+ Chap == "4.14.7";
+ Chap == "4.14.8";
+ Chap == "4.14.9" ->
+ ["Trust Anchor Root CRL", "distributionPoint2 CA CRL"];
+crl_names("4.14.10") ->
+ ["Trust Anchor Root CRL", "No issuingDistributionPoint CA CRL"];
+crl_names("4.14.11") ->
+ ["Trust Anchor Root CRL", "onlyContainsUserCerts CA CRL"];
+crl_names(Chap) when Chap == "4.14.12";
+ Chap == "4.14.13" ->
+ ["Trust Anchor Root CRL", "onlyContainsCACerts CA CRL"];
+crl_names("4.14.14") ->
+ ["Trust Anchor Root CRL", "onlyContainsAttributeCerts CA CRL"];
+crl_names(Chap) when Chap == "4.14.15";
+ Chap == "4.14.16" ->
+ ["Trust Anchor Root CRL", "onlySomeReasons CA1 compromise CRL",
+ "onlySomeReasons CA1 other reasons CRL"];
+crl_names("4.14.17") ->
+ ["Trust Anchor Root CRL",
+ "onlySomeReasons CA2 CRL1", "onlySomeReasons CA2 CRL2"];
+crl_names("4.14.18") ->
+ ["Trust Anchor Root CRL",
+ "onlySomeReasons CA3 compromise CRL", "onlySomeReasons CA3 other reasons CRL"];
+crl_names(Chap) when Chap == "4.14.19";
+ Chap == "4.14.20";
+ Chap == "4.14.21" ->
+ ["Trust Anchor Root CRL", "onlySomeReasons CA4 compromise CRL",
+ "onlySomeReasons CA4 other reasons CRL"];
+crl_names(Chap) when Chap == "4.14.22";
+ Chap == "4.14.23";
+ Chap == "4.14.24";
+ Chap == "4.14.25";
+ Chap == "4.14.26" ->
+ ["Trust Anchor Root CRL", "indirectCRL CA1 CRL"];
+crl_names("4.14.27") ->
+ ["Trust Anchor Root CRL", "Good CA CRL"];
+
+crl_names(Chap) when Chap == "4.14.28";
+ Chap == "4.14.29" ->
+ ["Trust Anchor Root CRL", "indirectCRL CA3 CRL", "indirectCRL CA3 cRLIssuer CRL"];
+crl_names("4.14.30") ->
+ ["Trust Anchor Root CRL", "indirectCRL CA4 cRLIssuer CRL"];
+crl_names(Chap) when Chap == "4.14.31";
+ Chap == "4.14.32";
+ Chap == "4.14.33";
+ Chap == "4.14.34";
+ Chap == "4.14.35" ->
+ ["Trust Anchor Root CRL", "indirectCRL CA5 CRL"];
+crl_names("4.15.1") ->
+ ["Trust Anchor Root CRL", "deltaCRLIndicator No Base CA CRL"];
+crl_names(Chap) when Chap == "4.15.2";
+ Chap == "4.15.3";
+ Chap == "4.15.4";
+ Chap == "4.15.5";
+ Chap == "4.15.6";
+ Chap == "4.15.7" ->
+ ["Trust Anchor Root CRL", "deltaCRL CA1 CRL", "deltaCRL CA1 deltaCRL"];
+crl_names(Chap) when Chap == "4.15.8";
+ Chap == "4.15.9" ->
+ ["Trust Anchor Root CRL", "deltaCRL CA2 CRL", "deltaCRL CA2 deltaCRL"];
+crl_names("4.15.10") ->
+ ["Trust Anchor Root CRL", "deltaCRL CA3 CRL", "deltaCRL CA3 deltaCRL"].
+
+crl_root_cert() ->
+ "Trust Anchor Root Certificate".
+
+crl_path("Trust Anchor Root CRL") ->
+ []; %% Signed directly by crl_root_cert
+crl_path("Revoked subCA CRL") ->
+ ["Good CA Cert", "Revoked subCA Cert"];
+crl_path("indirectCRL CA3 cRLIssuer CRL") ->
+ ["indirectCRL CA3 Cert", "indirectCRL CA3 cRLIssuer Cert"];
+crl_path("Two CRLs CA Good CRL") ->
+ ["Two CRLs CA Cert"];
+crl_path("Two CRLs CA Bad CRL") ->
+ ["Two CRLs CA Cert"];
+crl_path("Separate Certificate and CRL Keys CRL") ->
+ ["Separate Certificate and CRL Keys CRL Signing Cert"];
+crl_path("Separate Certificate and CRL Keys CA2 CRL") ->
+ ["Separate Certificate and CRL Keys CA2 CRL Signing Cert"];
+crl_path("Basic Self-Issued Old Key Self-Issued Cert CRL") ->
+ ["Basic Self-Issued Old Key CA Cert"];
+crl_path("Basic Self-Issued Old Key CA CRL") ->
+ ["Basic Self-Issued Old Key CA Cert", "Basic Self-Issued Old Key NewWithOld CA Cert"];
+
+crl_path("Basic Self-Issued CRL Signing Key CRL Cert CRL") ->
+ ["Basic Self-Issued CRL Signing Key CA Cert"];
+crl_path("Basic Self-Issued CRL Signing Key CA CRL") ->
+ ["Basic Self-Issued CRL Signing Key CA Cert", "Basic Self-Issued CRL Signing Key CRL Cert"];
+
+crl_path("onlySomeReasons CA1 compromise CRL") ->
+ ["onlySomeReasons CA1 Cert"];
+crl_path("onlySomeReasons CA1 other reasons CRL") ->
+ ["onlySomeReasons CA1 Cert"];
+crl_path("onlySomeReasons CA3 other reasons CRL") ->
+ ["onlySomeReasons CA3 Cert"];
+crl_path("onlySomeReasons CA3 compromise CRL") ->
+ ["onlySomeReasons CA3 Cert"];
+crl_path("onlySomeReasons CA4 compromise CRL") ->
+ ["onlySomeReasons CA4 Cert"];
+crl_path("onlySomeReasons CA4 other reasons CRL") ->
+ ["onlySomeReasons CA4 Cert"];
+crl_path("Basic Self-Issued New Key CA CRL") ->
+ ["Basic Self-Issued New Key CA Cert"];
+crl_path("deltaCRL CA1 deltaCRL") ->
+ crl_path("deltaCRL CA2 CRL");
+crl_path("deltaCRL CA2 deltaCRL") ->
+ crl_path("deltaCRL CA2 CRL");
+crl_path("deltaCRL CA3 deltaCRL") ->
+ crl_path("deltaCRL CA3 CRL");
+crl_path(CRL) when CRL == "onlySomeReasons CA2 CRL1";
+ CRL == "onlySomeReasons CA2 CRL2" ->
+ ["onlySomeReasons CA2 Cert"];
+
+crl_path(CRL) ->
+ L = length(CRL),
+ Base = string:sub_string(CRL, 1, L -3),
+ [Base ++ "Cert"].
+
+crls(CRLS) ->
+ lists:foldl(fun([], Acc) ->
+ Acc;
+ (CRLFile, Acc) ->
+ [CRL] = read_crls(CRLFile),
+ [CRL | Acc]
+ end, [], CRLS).
+
+
+%% TODO: If we implement policy support
%% Certificate policy tests need special handling. They can have several
%% sub tests and we need to check the outputs are correct.
-certificate_policies() ->
+certificate_policies_tests() ->
%%{ "4.8", "Certificate Policies" },
[{"4.8.1.1", "All Certificates Same Policy Test1", "-policy anyPolicy -explicit_policy", "True", ?NIST1, ?NIST1, 0},
- {"4.8.1.2", "All Certificates Same Policy Test1", "-policy ?NIST1 -explicit_policy", "True", ?NIST1, ?NIST1, 0},
+ {"4.8.1.2", "All Certificates Same Policy Test1", "-policy ?NIST1BasicSelfIssuedCRLSigningKeyCACert.pem -explicit_policy", "True", ?NIST1, ?NIST1, 0},
{"4.8.1.3", "All Certificates Same Policy Test1", "-policy ?NIST2 -explicit_policy", "True", ?NIST1, "<empty>", 43},
{"4.8.1.4", "All Certificates Same Policy Test1", "-policy ?NIST1 -policy ?NIST2 -explicit_policy", "True", ?NIST1, ?NIST1, 0},
{"4.8.2.1", "All Certificates No Policies Test2", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
@@ -1443,7 +1537,7 @@ certificate_policies() ->
{"4.8.18.2", "User Notice Qualifier Test18", "-policy ?NIST2", "True", "?NIST1:?NIST2", "?NIST2", 0},
{"4.8.19", "User Notice Qualifier Test19", "-policy anyPolicy", "False", "?NIST1", "?NIST1", 0},
{"4.8.20", "CPS Pointer Qualifier Test20", "-policy anyPolicy -explicit_policy", "True", "?NIST1", "?NIST1", 0}].
-require_explicit_policy() ->
+require_explicit_policy_tests() ->
%%{ "4.9", "Require Explicit Policy" },
[{"4.9.1", "Valid RequireExplicitPolicy Test1", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
{"4.9.2", "Valid RequireExplicitPolicy Test2", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
@@ -1453,7 +1547,7 @@ require_explicit_policy() ->
{"4.9.6", "Valid Self-Issued requireExplicitPolicy Test6", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
{"4.9.7", "Invalid Self-Issued requireExplicitPolicy Test7", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
{"4.9.8", "Invalid Self-Issued requireExplicitPolicy Test8", "-policy anyPolicy", "True", "<empty>", "<empty>", 43}].
-policy_mappings() ->
+policy_mappings_tests() ->
%%{ "4.10", "Policy Mappings" },
[{"4.10.1.1", "Valid Policy Mapping Test1", "-policy ?NIST1", "True", "?NIST1", "?NIST1", 0},
{"4.10.1.2", "Valid Policy Mapping Test1", "-policy ?NIST2", "True", "?NIST1", "<empty>", 43},
@@ -1483,7 +1577,7 @@ policy_mappings() ->
%% TODO: check notice display
{"4.10.14", "Valid Policy Mapping Test14", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0}].
-inhibit_policy_mapping() ->
+inhibit_policy_mapping_tests() ->
%%{ "4.11", "Inhibit Policy Mapping" },
[{"4.11.1", "Invalid inhibitPolicyMapping Test1", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
{"4.11.2", "Valid inhibitPolicyMapping Test2", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
@@ -1496,7 +1590,7 @@ inhibit_policy_mapping() ->
{"4.11.9", "Invalid Self-Issued inhibitPolicyMapping Test9", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
{"4.11.10", "Invalid Self-Issued inhibitPolicyMapping Test10", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
{"4.11.11", "Invalid Self-Issued inhibitPolicyMapping Test11", "-policy anyPolicy", "True", "<empty>", "<empty>", 43}].
-inhibit_any_policy() ->
+inhibit_any_policy_tests() ->
%%{ "4.12", "Inhibit Any Policy" },
[{"4.12.1", "Invalid inhibitAnyPolicy Test1", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
{"4.12.2", "Valid inhibitAnyPolicy Test2", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
@@ -1509,12 +1603,3 @@ inhibit_any_policy() ->
{"4.12.8", "Invalid Self-Issued inhibitAnyPolicy Test8", 43 },
{"4.12.9", "Valid Self-Issued inhibitAnyPolicy Test9", ok},
{"4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10", 43 }].
-
-crypto_support_check(Config) ->
- try crypto:sha256(<<"Test">>) of
- _ ->
- Config
- catch error:notsup ->
- crypto:stop(),
- {skip, "To old version of openssl"}
- end.
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLIssuerNameCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLIssuerNameCACRL.pem
new file mode 100644
index 0000000000..a4cf643928
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLIssuerNameCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZSW5jb3JyZWN0IENS
+TCBJc3N1ZXIgTmFtZRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUEXLyNV0E1Q5KIAcHQSj9lHAAHHEwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAIIk/+6+dqID/yKmKYDaVgXh/yLWZO4uV1m6OYRSrdfa
+8aqYcgwChIaIIX465VDCpGO2LMOXV1Z/COerJguUNRGaiSQCSrsIpNGGZTQE+HNN
+C5mabMfPuSVaBgBMzQZTY3ggLNr6x1G7dXlm+Fpo+q/fSznBVsGFHCgtp53FJHBi
+Xcd3LTBFyZLiyhITqm2xvTwyzl/URcDYBp+tWTmn7ZxADdoThK7OkY2U13O0vxKj
+/haiS1NuVbX2QkS+eH399jGQHAHiBOFlRPs8FGdshTWOJxmLMMTIuS7cIEH3Oz8t
+b1Go7j4qHIYr/b2uKHb9RBMFNRKsZfqVKEQ+1J8TPNc=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLSignatureCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLSignatureCACRL.pem
new file mode 100644
index 0000000000..e17fac1f20
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadCRLSignatureCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUQmFkIENSTCBTaWdu
+YXR1cmUgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFDGLNY2eRGEwFN7nCy4UGUgk2/m9MAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQFsPfAbIcqMI+lzJmY396TIwn2ubAkQgm95U712CIuw00auDjGM
+iebAOLbNLgSktivN23rc5rPxSOqeWsNfgVxwCPKvBv7v4PsLQhzK2OyonV5Cmdl1
+biEymv88bEUcEnibvH3O0Lg3RySMNjPYqZgPfwF9b0iTYeb2JYk+lX+m3WGr5UPg
+M9nuC6sychRxGgF1AQOd/N6spvgSAazEyNqCWhcwdrOeM+HEDPAFOOFAhmCp+jjh
+Fgh2E2Gq1vbxGSzzKlRBDrO1hovT9XhvEa2SjopbWMbfOR/wPTjxEImIQDWw69RL
+KnTL/OdnUXifoSNJIJK3ffPTSG5AEHFUm6j+
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadSignedCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadSignedCACRL.pem
new file mode 100644
index 0000000000..58c89f81c6
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadSignedCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwDCBqQIBATANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEWMBQGA1UEAxMNQmFkIFNpZ25lZCBD
+QRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAU
+e90QO0rgyN1EhU6IPFqLzZkik68wCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQAD
+ggEBAEBt9Jji+aprAMfoXE8zclIPjs520FFAXSPqsJt77l8vTA50oUbD0sILCDfA
+raU16Pm3lIT3wuEAUmM7luTzG5Kg5qbgyv9cLm3rSJOADZCw6oahFAEbZyqOsgfP
+QYRy9EOeg8TUc6EPrlZhTrZzf2kgmDeL6WxTz2Len415oFf6JsDNMLcHSQkDzmdi
+OxYXDA2w5khPrzX0cxbMpmZVJiQksdKJg/RGGCqNJVcZwTqAZFNzSldJvx7fqQPI
+SkcKznfT/cczC37Q2uCupIyG4cntiRdIztkHiKQFRkiUxIMQA3ky3t+ib3lZDnl2
+VwGLcmmYuu4ScsqL+OP0ZjpzZKM=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotAfterDateCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotAfterDateCACRL.pem
new file mode 100644
index 0000000000..3c952437ce
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotAfterDateCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUQmFkIG5vdEFmdGVy
+IERhdGUgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFCwO/ffuPPOkZuznBZ+Is+LPdEbYMAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQBcYZ4ucABlH6Z0XtJMAmcrX6txzEawWpikzfzapuRe0YBL6IHm
+LRqW+vpBfR5vSQ2PBLXFJA9eVpJjjBieF9USt58DsvTF1nuPMJCk1WhxfDrE/hWy
+vR3tnLW38c6e4+omJN9fotQilw+sq32j1yQjnR4KU+VxMs6sgs1W2XmmWpTP+fQw
+W9ukAXGzwQNmBb4mbOjLDVv3fXxzVI5gK8bhcxh83cfmHMkI+dp1g4nAxQ5gRTaw
+2ypGWph9170Z1Y/W6eznbNGA40YreXqqZeq8ujpjYlksC6tpQkOp8lBJGwi7fKaI
+IxV4vXSSbExz7A4CFQ1zYx1ciciCGWcyOyqx
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotBeforeDateCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotBeforeDateCACRL.pem
new file mode 100644
index 0000000000..fb4bf11a7c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BadnotBeforeDateCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByDCBsQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEeMBwGA1UEAxMVQmFkIG5vdEJlZm9y
+ZSBEYXRlIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNV
+HSMEGDAWgBRjPrwanvuh8lmhL0uV/ubeVriGQDAKBgNVHRQEAwIBATANBgkqhkiG
+9w0BAQsFAAOCAQEAnN6H352YCy4U82Ndz+iFkIxTLVmwiMi00RViqbziNXLSYbbX
+MpJsCPn93wGhEOokDcJBoWq6/2QeHHmEs9rN758+loP1P1R27wgicrcPIEbT0+BT
+st0TYtZExQoXWVe5QtyTa4cNR7Wz88ga1xf3GyngnjFAHmAWrU4IOpxhKvs2FOS1
+zPaxzdgvNZyxvltIUt6zujlAxDf3wJK9qWyZSt7ORob8RVaAJR12UA60qyVbA2HX
+BdAavTzVJatY2AjtnIiFWAmtI3s/jIvLLNX5yUVVDSEDCI3zWY5YR/URyf4uViEk
+qyy8PQ83mVkpTjaWRxjFrcIvwlUvmRlHTvp2NQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCACRL.pem
new file mode 100644
index 0000000000..9a34f8a612
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB+zCB5AIBATANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEtMCsGA1UEAxMkQmFzaWMgU2VsZi1J
+c3N1ZWQgQ1JMIFNpZ25pbmcgS2V5IENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEw
+ODMwMDBaMCIwIAIBAxcNMTAwMTAxMDgzMDAwWjAMMAoGA1UdFQQDCgEBoC8wLTAf
+BgNVHSMEGDAWgBQkwVVx+p7hIYUq8K1hpxW51U1DFzAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAE4g/85gXzIM9TYVxAXxgc8KwavltVn6wFCluy5zwxGRz
+lpJXjJWctmJ+Z1qPVlL/K8aOW+YW+keL5zcINUYHxipyQLt+W7qeFDivq5ABgK62
+qpZ6tpwTa02IXkUDixs2QVXM7vXLrHlYacLGjIti+LUP3R7y3fLSjg3BMZcvwA17
+0N1YhfYZrNVwfwqv2H58HIdo5+SSCcUGZe9sbkqRINta3/OKnlS5e7Y4KW5I65oT
+2eX4iPmPNR6NqNv6D+mMXxt6uJGw8NRA2NqO8MS8UqkA6bmZldcdkefcJ5ETJu8r
+xewaq22gblqFL2vdcM/JJ61rcuPVZTqChfDyaQu/rg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCRLCertCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCRLCertCRL.pem
new file mode 100644
index 0000000000..447b7ec511
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedCRLSigningKeyCRLCertCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICZjCCAU4CAQEwDQYJKoZIhvcNAQELBQAwXTELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExLTArBgNVBAMTJEJhc2ljIFNlbGYt
+SXNzdWVkIENSTCBTaWduaW5nIEtleSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMx
+MDgzMDAwWqCBvDCBuTAfBgNVHSMEGDAWgBQpmkUuNpWd7PJeVJwT1dn2RJEsEzCB
+iQYDVR0cAQH/BH8wfaB7oHmkdzB1MQswCQYDVQQGEwJVUzEfMB0GA1UEChMWVGVz
+dCBDZXJ0aWZpY2F0ZXMgMjAxMTFFMEMGA1UEAxM8U2VsZi1Jc3N1ZWQgQ2VydCBE
+UCBmb3IgQmFzaWMgU2VsZi1Jc3N1ZWQgQ1JMIFNpZ25pbmcgS2V5IENBMAoGA1Ud
+FAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQAnpcVORfH/FTHsCl1sjvHIvPQTdrMI
+73pWCshHQB8/eCwDmTg+xFk7n4KCYSRgbN6ingc4wzbnLkb1WPmw80aXbqd4Tg+/
+U9T0ANxSewLBeW0zUFFcW5LjqrxCJVV4IMDXh+D6F+M8uEWE8/UGzpz3qkIBfW/a
+KHQszpVl7i9x0MhjHFAXkJbCuB7ymXntYfbSQNHvMWwbPW+nt0HadbJqjJy4FH4V
+kaSg/tkFa1StClKjm3T+GDhISPpDWthGUmS4n9cmj4QnPSd6E57d+ix0hb5oqQAg
+DYeL9/xaN7fOIzuGknzE3+p19OT8vNhvp7mRoMpZpzPtm0so48EXagMx
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedNewKeyCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedNewKeyCACRL.pem
new file mode 100644
index 0000000000..9c3d7d42ab
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedNewKeyCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB8zCB3AIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMcQmFzaWMgU2VsZi1J
+c3N1ZWQgTmV3IEtleSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAi
+MCACAQMXDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaAvMC0wHwYDVR0jBBgw
+FoAUoPzALOtV7pIGbKke6V9fop9iI5UwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEL
+BQADggEBAHAue0P1w9Vgt/mvhideeiLl2unmfJC0JKCIBeeWXl0CYW5jcSrshCwZ
+dHRM5uhs8RQCNRnJIrhwuRUvh9SaDsZGFWqAlOdYbkaXdzbX1cyTigQ0tCNTN+aD
+FxGTm+CWxi6awN2a2ZcOzZ3KuB8D7q0b1mVtnMFsvV7JEMyxZRWFm5/8yJAliOKc
+8wrWtDfbpkU6c1P0l2bPzvmDirISAKwj2IwibkbQimbISwt1b/jijPOQgiArom5S
+sHzZh2DI9xdDBXLImkJveUGF1d8zIngbvyn19Iz7bT8mJVANx2K0U6kC3ODgov8b
+ARv87w9CDE+nCZz505ZS1f/pVtswcPg=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeyCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeyCACRL.pem
new file mode 100644
index 0000000000..3f330c715a
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeyCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB8zCB3AIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMcQmFzaWMgU2VsZi1J
+c3N1ZWQgT2xkIEtleSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAi
+MCACAQQXDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaAvMC0wHwYDVR0jBBgw
+FoAUiF++PzU5ZprrTcImGyaxKie1CCowCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEL
+BQADggEBALJPjOBcvrNJea5bTdcDaUR+3rWdWzwAFlIFN29RBQgnnwGyoPnMhBaI
+MBMMxrzPQiqc908w+4E82FSbeVKbutPPjs4izG8wE3jwPk5GmWPKozrZZ3Eliqd1
+9Kx1he6yCDnPpHZ6D4qm6qyy/xmspL7X3W40Dz56ldxu3DECDIrDACjdnu9PERDu
+acqDQPFKbcaZeCY9QX9/vsG+vrWH+HxEkzA/S9tyojYSLfVLvYubBd0OAWhTqqR6
+5h2Gx6z7DH6/1vtctb0HGg2VY7bVjpL0YhwXoTjZZXbWlLH1l7N+fP2cH5eqDwwF
+DRhIRhasjSucbUzOFXoc3dmBrOKwtjM=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeySelfIssuedCertCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeySelfIssuedCertCRL.pem
new file mode 100644
index 0000000000..8fa388cd45
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/BasicSelfIssuedOldKeySelfIssuedCertCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICVjCCAT4CAQEwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExJTAjBgNVBAMTHEJhc2ljIFNlbGYt
+SXNzdWVkIE9sZCBLZXkgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqg
+gbQwgbEwHwYDVR0jBBgwFoAU3Q11jVNoEsTLFUDAFIYUFjChvq8wgYEGA1UdHAEB
+/wR3MHWgc6BxpG8wbTELMAkGA1UEBhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlm
+aWNhdGVzIDIwMTExPTA7BgNVBAMTNFNlbGYtSXNzdWVkIENlcnQgRFAgZm9yIEJh
+c2ljIFNlbGYtSXNzdWVkIE9sZCBLZXkgQ0EwCgYDVR0UBAMCAQEwDQYJKoZIhvcN
+AQELBQADggEBAMCggIi2OzR9WO+bNMEVT0PdVnX9lNyjIAmJZj6g/SECKy85ZQp/
+Xs5YY43xxXswtJ+70cQGunzXIXd22a5xTlGlcM0orE2WIbDaoJskD3D5HKPCb6MR
+C0XwhV6KGmB+H/rb77EnHEHTHQ6SwKfSaVSVrVkaGD4HYHAKiOqOzkInultUR04p
+jTJ3watfZyB+L9Xmfj+Bz/GvTCDdYOQfs9uXhWH+C7HQPe8uXD1C1tSDD9+XnUHo
+rScJkZkZpExsGvF8ngtjp+0SUmCTM7VejHtKWD2l4KO+TkjEM9PG0+Hf75iOq9eO
+UdA7iu/ozw7EbowpmABJmeVSiWD9S4/deBc=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/DSACACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/DSACACRL.pem
new file mode 100644
index 0000000000..7d1d13a767
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/DSACACRL.pem
@@ -0,0 +1,7 @@
+-----BEGIN X509 CRL-----
+MIHeMIGeAgEBMAkGByqGSM44BAMwPzELMAkGA1UEBhMCVVMxHzAdBgNVBAoTFlRl
+c3QgQ2VydGlmaWNhdGVzIDIwMTExDzANBgNVBAMTBkRTQSBDQRcNMTAwMTAxMDgz
+MDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUj5DGjHToewzIWcd9
+PFtUWWAlC7EwCgYDVR0UBAMCAQEwCQYHKoZIzjgEAwMwADAtAhQCMhWXnJJuf+2W
+pXCHP72o0SdqdAIVAMsLFa667x5ODKAkIlFPI/Ge57Hj
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/DSAParametersInheritedCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/DSAParametersInheritedCACRL.pem
new file mode 100644
index 0000000000..545293a0db
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/DSAParametersInheritedCACRL.pem
@@ -0,0 +1,8 @@
+-----BEGIN X509 CRL-----
+MIHyMIGzAgEBMAkGByqGSM44BAMwVDELMAkGA1UEBhMCVVMxHzAdBgNVBAoTFlRl
+c3QgQ2VydGlmaWNhdGVzIDIwMTExJDAiBgNVBAMTG0RTQSBQYXJhbWV0ZXJzIElu
+aGVyaXRlZCBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUZYGfcDqMrfZDHcjnj1WO6Evbh+IwCgYDVR0UBAMCAQEwCQYHKoZI
+zjgEAwMvADAsAhQ80F0tKnVM5ABE7rErqs6hgIc8gAIULN+1q3I9zEFZqSneZHjR
+yXC3FZQ=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/GeneralizedTimeCRLnextUpdateCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GeneralizedTimeCRLnextUpdateCACRL.pem
new file mode 100644
index 0000000000..cab3080a90
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GeneralizedTimeCRLnextUpdateCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1DCBvQIBATANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEoMCYGA1UEAxMfR2VuZXJpemVkVGlt
+ZSBDUkwgbmV4dFVwZGF0ZSBDQRcNMTAwMTAxMDgzMDAwWhgPMjA1MDAxMDExMjAx
+MDBaoC8wLTAfBgNVHSMEGDAWgBR+KnXvDDbHS+cg2X9hSEeOEoMaLDAKBgNVHRQE
+AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAkJf/F0AFe6ViIe9vaZwlRWs2cge1PnzK
+viLSchMF7AdYTAPq0hfWo34GTEw1e0k3KTIJlnj+fD3wpnhTA3qt3YzyS+wvdSZL
+e2Ogr4CvWKWbHi+5klCk5cJBkT5+SRZQErgATVyQYkcSYHYR8iPZ3izeSuoCPq8z
+KSBdZqgRqdJuPftmcbi4XI30zAJCDmMxuC++D3uTc8NHA6DrtAf4p2Iv0f33jtYo
+CsFBEVKpYd/0At1yxRDJ1MvKsiHZM3Pb2Ygoi5koy2gaNE34l128etEN6U0cZ7iy
+A5OYdxjNKkR1Xvk33eje3ixCOvsidtMSb7446sL6w2zQHQDJITAzcg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodCACRL.pem
new file mode 100644
index 0000000000..f482eae237
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIICADCB6QIBATANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEQMA4GA1UEAxMHR29vZCBDQRcNMTAw
+MTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjBEMCACAQ4XDTEwMDEwMTA4MzAwMFow
+DDAKBgNVHRUEAwoBATAgAgEPFw0xMDAxMDEwODMwMDFaMAwwCgYDVR0VBAMKAQGg
+LzAtMB8GA1UdIwQYMBaAFFgBhCQbvCtSlEo9pRByFFH1rzrJMAoGA1UdFAQDAgEB
+MA0GCSqGSIb3DQEBCwUAA4IBAQA9vPMLiinD8G7FaoTsu8T2jUrTi1OLPHxKnrlB
+rAP/eHa+VQV1HJfY5Gjq1dpNgzZqDIgQM5QHPm0aSgMN7Ultx+XzbxRswLnwgQrZ
+7f76Tlky1I+jz7/p3AEynrNR72v64SZt46UhpSuWBHoF1uEVtgirTZNfOEaGUJTN
+OaTA5U55/iw9BKjHN0e/Vd7OGnrk5h6FsgWOiasGn6/tym9teDt/L2hlOdsZsvX1
+KPc0ExUHVjJIUBYTooqyy/CuTzFHla6RYVYvJuRF5qYCxa0GTZK3ImCtJ3XfsGdf
+LEJDZ7T17xBQHucMvIVLm6vY44WUy7PqQhZJskhJMEvj01ZE
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCACRL.pem
new file mode 100644
index 0000000000..04790063da
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBvTCBpgIBATANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTETMBEGA1UEAxMKR29vZCBzdWJDQRcN
+MTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUMgcs
+nnRdLV0pu7F6jTsVUrR9QngwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEB
+AEbJGAG0MzgAYBNHSm7qI/hQO0cVg2FSkzuKdKB4zp0Jl2hvgjJKAEnU1QMkCyW1
+7B1srXRhjyLp8lvBZPWtXtev7QSkNV9ysUiNDdg+FThP9WVsf+zPu2+UuYn57A0U
+0NeWGv0DeoZG1mzRq5DcvLk98o3ErZug8ABzaUlprx8yGvzqw5abyj7AgeXvp5fs
+0Jo+ya4e8aFrBx/8k2gPvGTv5AOaa2+tLFQsVOm4PUQk1ANklm+CIlOz5hvvZgTp
+UXaiY/BrYCSV+N7MFXNH/75HUm4PPLFr5LgI/whOgR6bFC3e/5kTdQpVBwGBNvNy
+OEp8bA7ViIqbseokJI3q29w=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCAPanyPolicyMapping1to2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCAPanyPolicyMapping1to2CACRL.pem
new file mode 100644
index 0000000000..ed9ac1744d
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/GoodsubCAPanyPolicyMapping1to2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1TCBvgIBATANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTErMCkGA1UEAxMiR29vZCBzdWJDQSBQ
+YW55UG9saWN5IE1hcHBpbmcgMXRvMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgz
+MDAwWqAvMC0wHwYDVR0jBBgwFoAUW3N5meOuBtOKpjNOFHjkoB2x5MkwCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAKKfTLLrhhr5sQTxYh0/59xGeCAPDiAb
+hZVIWXYrEy3HdaKVI786DjInVHDAHrpvO+pL52/unPqNZAFSpNpk8+4otR2/c9lu
+7EtForVhzkCVgO+bnGnLPqgYKq91tLD/NtB4OdfXlezP1LN4f4j8yHwmkJ9kv5bS
+op2gs30YZo4f5rgRFvDFzL0bYMzHcY/NVLqnHPp+8NqPsNAdyWl/90QjCG6Fj636
+8D7SQQpDY4Qrq0raGpsspyYkMeshUhLiEb8A2rnaen0dhrG8+5W2WP0zNoSQvKH8
+D2JLtZK+l75rRRZm5V9PNrza+ZfjbEABUmJjJ/LOkLiyNna789a2+9g=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/LongSerialNumberCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/LongSerialNumberCACRL.pem
new file mode 100644
index 0000000000..d0d3787427
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/LongSerialNumberCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB/zCB6AIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEeMBwGA1UEAxMVTG9uZyBTZXJpYWwg
+TnVtYmVyIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMDUwMwIUfwEC
+AwQFBgcICQoLDA0ODxAREhMXDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaAv
+MC0wHwYDVR0jBBgwFoAUC2O3R67CBzIbf2/jOrjqC//XZKQwCgYDVR0UBAMCAQEw
+DQYJKoZIhvcNAQELBQADggEBAAT3AsJOgrvo4ohLomVgQey2sS6xh4bvK/qZmx4v
+czM1U9QpS7uO1QDgIkdxd7nGEtPqhzhjm5Uyw/M5FJwW0pOu5sRG9I/QvYgaTTbe
+u6CCwpL4fxJ42EjKicKdWvZ8+iQONDhcmHzIsvJJcg4vSkWc0S7CYwcrdbAn/KnW
+ru/Jnh4lGUxoj6GDYrroSCrPQqXk9rCTxq+wH5Ck8WQ3UyXLkVzuxWdBrNQ0Gwag
+dAh4u1o+3e+ta5V/WtQTZaSb71A0GvLqZpynu/pWDCQ8fkguvKbP55CuQLCnnukw
+nFs7zIlDlBQCYOgqvjswdzwZDSRliZD035oLDHPgSIeiWY0=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/Mapping1to2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/Mapping1to2CACRL.pem
new file mode 100644
index 0000000000..5aa18e1b89
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/Mapping1to2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwjCBqwIBATANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEYMBYGA1UEAxMPTWFwcGluZyAxdG8y
+IENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAW
+gBSZxXhpyz0zdsKZrETlsA7+ufTbxzAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsF
+AAOCAQEAHDBNYlKeVrvQoU9wdLhmD2iI+pNFkNB0O/BJXY59wp/DFV+gyygyE1sC
+qnwOPMiKR+u9zypXr3+YbG/L0YeZuzzaFbHrm4ZYPcCRzaz0YVm7ZhbI+ea+moVW
+R5BgVfFUkfCiGNYQ5nxKif7WeYcCK+Aiy1eQ7e4munvJ5jzDrRiiZiBPRfY29FPh
+0qkp9TRqPLpY4oYwaGxe9UMKqvVdohBYqUUfdB2tgjeVlDct+MokpYL7wpnrQBTy
+yzgYpZ+GELYzhhn1Oc6PkIrYxc1h3O+tIg85uII/qFOC9qOslH0qPiVqEzwckAhZ
+HX8PPcXxLhO62X4BdaMgJhgHdUrW0g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingFromanyPolicyCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingFromanyPolicyCACRL.pem
new file mode 100644
index 0000000000..4d6c9d0aaa
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingFromanyPolicyCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZTWFwcGluZyBGcm9t
+IGFueVBvbGljeSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUaHMU4As0z3JA2pSW1hWreqRvLowwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAKZyiDbM1h05WJkyjY/Ri6vJfUyXeHPdkeLm2K+DuxVs
+VOreMcdvbKCDm+VjAud129+ou9CUFZUn2vPwhZ5+W6Z7ohzUoo8QeWGoWkvlY/yU
+/Hf4qR6QOxUATGr/f9u3ptsbVjBKEhD66Q/OvXgiBFNzOdZOqKuuI/x/rnXyOSo4
+pYJ/RecUb1m9WaVjO1eKQCGImMbrHTnIOziAg47/IdCztubxtWwtV8jmd/zi5E+0
+FO/lBnFyyghqNjPnML0LHQUM8Lr1EnFU9Lg2m/QFg2rWghrWadYKoa6lroPKhdMn
+hTL+BnTZkrwlJ7OtCI1wQD1NHIJmiL6lDBFT6TMH1P0=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingToanyPolicyCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingToanyPolicyCACRL.pem
new file mode 100644
index 0000000000..a4a369c179
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/MappingToanyPolicyCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXTWFwcGluZyBUbyBh
+bnlQb2xpY3kgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFBQs7ZPxHhpwFZSLLZO0mNK3BQisMAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQAMdZWbfYwoDdwrkj0e1LjvvPiIXbBMwxuNhXG1LAaqazMF
+B3SM4/6IQ5kqLD4mXL6VTe1W3Ovu5L8DjbkXHckkq585B2s73Mwl9Ymlx7/MFahd
+taFST1d8AEQqxgBjcQ6imlEPtgJNboJqcbNS3/R/xau8OMXmY/kuSyTiMqeVq0jl
+ePVLDFrrLYaovKT0nG+7mN/afE+kyQxXaRk722ypf+38K4HHUAZwadRKPa8exyKz
+KNS8wFYjlrrua93qbpkDzmZ02gjkUJByCeBTqvkEbabUqLGfFhPJ8w/LFJiubwlI
+CmoYEAKpfR4393Uizsg6T+mHAaJmeIocAsoZBWvR
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/MissingbasicConstraintsCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/MissingbasicConstraintsCACRL.pem
new file mode 100644
index 0000000000..e84c210970
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/MissingbasicConstraintsCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbTWlzc2luZyBiYXNp
+Y0NvbnN0cmFpbnRzIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBQwVrwVEY1PxibGtZyhcJLS+U8NeTAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEADdJ1BXt1/rZ+Je0fEAOWJOx/zAciiWeBWaa5WMnq
+H4fvy//4+r57ZLVCN87f0fnxBSGk2bs2qZA7tkLMtVyRU12cjYsTXzqIA7w+lMGx
+Tsel+hDHGdJjAL5X7xDMOX3kfX/I5lruE+nKCxaGXWV3peJkaVdfw/qzkR7/3Woz
+aa5B7soNJv8sGyflwJCMUgAfaHZa6LopIRZ2GpmDhDYiXtujZC4NoLhKaq3LgQgF
+Y8gjpJtW7dEs7HQo33OeC4s2u8Q6T0pJkG6Xi7rGArplXTklb0MFjrEN6quGlYNC
+00HSsvG4Pf+2IPKUf4P6I0QW2CAnZqfprIPGok3Sy6tfJw==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/NameOrderCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NameOrderCACRL.pem
new file mode 100644
index 0000000000..9aab5ae9dd
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NameOrderCACRL.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICDjCB9wIBATANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExIzAhBgNVBAsTGk9yZ2FuaXphdGlv
+bmFsIFVuaXQgTmFtZSAxMSMwIQYDVQQLExpPcmdhbml6YXRpb25hbCBVbml0IE5h
+bWUgMjEZMBcGA1UEAxMQTmFtZSBPcmRlcmluZyBDQRcNMTAwMTAxMDgzMDAwWhcN
+MzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUv0qLgZtNjBQxjFvpzN0v6HkS
+UVAwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBABkyacQyoBQE5YZL2K2Q
+0f637287irENIuJeWpv9MsXXsZZfN//UeOfwIdnhAMQCx1GeEbCdAPAKkBxI3Jn2
+AVtxqytV8F7xqUiUpYRw6g2B0jjsJoaFP4AoY+BGk5/4oLwj2MzNyNcYFb/KPPgc
+Pwq4T0IR7qMz60d2lZzLhWWz50jOmvwvyxFbOcYwh1RmLB7KKcwAaPeSwlCxThQS
+sugsqHuq3K+pi7KTShAV2UWRupDOGlVyPYAuo3n4G2LmwPmwmYmnG3+KS1Azyj8B
+ywYDiAPQyG10rufsDF3GEpJzIOPt7VHv8z2SthTPmVfDFrkwshOQsb+PrltGP9bC
+V/s=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/NegativeSerialNumberCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NegativeSerialNumberCACRL.pem
new file mode 100644
index 0000000000..62dbbc8db4
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NegativeSerialNumberCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB8DCB2QIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZTmVnYXRpdmUgU2Vy
+aWFsIE51bWJlciBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAiMCAC
+Af8XDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaAvMC0wHwYDVR0jBBgwFoAU
+YuQuNcYPxeiR0AvBjd62r9qI2T8wCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQAD
+ggEBABjkQVYJziJmvShgFK3XecyOCYDlSPShr+vgrGFBQpyi/FePWU0yot93064/
+lRSHgzS8B9yvXPJBygOGT/hbmNG/88Evu2Z1LoEOLTzq+Sbf6LahfqDpkvdf6SjM
+wy4udr0g7dVOjHQg9DM+HDij7tc150o6P0e9++0CgpXuRNQKYKRq3qn4KjBq9Yph
+S/MpUEY70hgZaL+XTbyvti83Y8nPqrVIz3VRcG7GLHAmYb3cGwf/8zNL8lpOhzOU
+MoTwN+TcRWvMlYWYoyfaaGxA+Ak3wcPsIHhHLxTyXucXGQPjrmiGqK9H6BOUZT4q
+HupHV4TbUwMoW+FXISGPVvz3ECA=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/NoPoliciesCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NoPoliciesCACRL.pem
new file mode 100644
index 0000000000..42ee928471
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NoPoliciesCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwTCBqgIBATANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEXMBUGA1UEAxMOTm8gUG9saWNpZXMg
+Q0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaA
+FEIkA+2lS3acl5hcdOoFOhv8NeScMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUA
+A4IBAQBuELGhtxMeER+HyzT997rCWtWbXV9HT6zgfU9AUTX2pDoNFn9iGfFkLaJm
+rSkQro17ogzl9xrF2EvdgMSSw6YxRU7MbMMmF2lXC+IbScdtAGgdURnGF/C3Omao
+dGbXXI+3gUM5YSlPqGToDB2j7tBAC+THt8Knxq1NLeRt9cXpztX/UF+B4u62ylHo
+q6jV4KLlWksRGwtEF9w/2iiQv08zz92ySgL4Z/CbBMQfX73iq6SjPFOJm1CpA0BR
+QFN33H1OC8WMHaoV8M7DBGpudcWzHZpuq9ikjLdlCmDuGEyJgceneOe6e7vsupe2
+DGRGvgwmJbJI/XbCbLnwSW3Xdsp2
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/NoissuingDistributionPointCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NoissuingDistributionPointCACRL.pem
new file mode 100644
index 0000000000..789099d061
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/NoissuingDistributionPointCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0TCBugIBATANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEnMCUGA1UECxMeTm8gaXNzdWluZ0Rp
+c3RyaWJ1dGlvblBvaW50IENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBa
+oC8wLTAfBgNVHSMEGDAWgBSzy1S/ap38n8cxDpIMp0drmQCfMTAKBgNVHRQEAwIB
+ATANBgkqhkiG9w0BAQsFAAOCAQEAqnXhjxLsCflfSGLvYk06S6AP9+nEuFtbqXDP
++T4URhv2PZ583f7hg0jEd1/SZqyNxrZk6cNNMR2DYPCX8XsP3c0lKf1wVoielyl1
+bSPCTifm0z8pJr9ORD7XHDZ4F8s/nv08f+GJmYUaE036Nw++wNMqi016tw+TrHa1
+s9jSwUvlzjg/om6n0EMTWnWTnEHngdrGkV63kuo+4yymlsEALlgmIUp41bOiWzFo
+aYxsFd2k+ZAGvv5mB1Qimcp8C1ssInLczcDQ5Un329OAz83nrgdCZcYkFBAR1A46
+p+16zuw55BiQp3gByK1NVTssEcBOkDm/M1DgS+CtE8xkfKnR6g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/OldCRLnextUpdateCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/OldCRLnextUpdateCACRL.pem
new file mode 100644
index 0000000000..d9591e5cf1
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/OldCRLnextUpdateCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByDCBsQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEeMBwGA1UEAxMVT2xkIENSTCBuZXh0
+VXBkYXRlIENBFw0xMDAxMDEwODMwMDBaFw0xMDAxMDIwODMwMDBaoC8wLTAfBgNV
+HSMEGDAWgBTO2h/aWsyOl/ogFSlPrJaNKs14EzAKBgNVHRQEAwIBATANBgkqhkiG
+9w0BAQsFAAOCAQEANLTjtSL1Q3Ya29eHHAMhRdlEtcNF5CMpIUxvS3eQjTH0RxIR
+EWfDguJmX5gAeyHgegi0W4E1e5qArzpestM9nXMZypQ0GuOLEqQ8QfV4UTp5B3Ng
+gdgrxRTIdlpkEG43G93gZBmZ7u+HHbBtoBM270gFtluBXTnLbs6cHsZRn3p5jOCc
+Ll/YQBCO42iRjmww2mYKy5dB18geb0YZHlKL3FbZ1JhfZlvmHilBvBSx9uy5qZgZ
+HwlONqnePLkbK+0PyLaooa5NJXmusGVuZVC9x5gzwO+ZHun8fZ8aHIDDO9RtOv5U
+6r2J4kRp8Nw6zM4yWeQOD0GfRFlsq/OM3lHgPg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3CACRL.pem
new file mode 100644
index 0000000000..f590198a12
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxjCBrwIBATANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UEAxMTUDEyIE1hcHBpbmcg
+MXRvMyBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0j
+BBgwFoAU/PSNYTMygHx9NYfeX1L7afEdwRIwCgYDVR0UBAMCAQEwDQYJKoZIhvcN
+AQELBQADggEBADWFF9y8VCunmgrr/9sJCD19KF6FofJOEV4U6zjPju5N/4b3Txoc
+LiClRWHYyRqHjOlLvAOik0mopqcUhwGqQG3MpU56R8LEKScgQQiacPuSeRSflRRo
+nxGs/90yJrq9s59EN5oZH+AnhJ07R2kq1PFLMGR6MY6B4A4MZony01/BPG4EfpRn
+W270ehb6FEYIc514vHyJ65s8KfUx01BsMSTwS75LJFEmnM6pRLzZzbESQEo/5/BN
+ttRRwrNt7TlwY7zs+oSDjUEpQ4K7tbfuQtIqiGm2VsY1O8kZWYmg+eUTUplcLoEZ
+LuAkicZCYw+YPcorZ+m9nL8FbxnrPm2LjJM=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subCACRL.pem
new file mode 100644
index 0000000000..acc5cde185
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWUDEyIE1hcHBpbmcg
+MXRvMyBzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUvnsTk6Hkm8UnPDBT16XJ5lqWejQwCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBALLR4At4E9ny2pPCIb4rLKvVRs10lszGrH8NVo1jhuugSyMS
+wMYPWuZbUw+rpN/YwFFkM5R256ITwtEttgHkWoa3CetBBRYF6UPIMyZp0KRDQAZC
+SwPU89QvP5H8KHuB3Zg4bg1wrXZTP9vjTjxf65UQhc2S3zj1M+TBv94h5J5cHSY+
+Q9Nz5iRoxEJv55/TWa7UQYBwaDbPxdb+twKEhdocjTZRYub2LhKRlY9nmTTiM/J5
+wE0RYNQsPiUkZuNELh7ZxPCp9Gk5KqbE0qUSO7KYiPEUj5mK4F+j2Mwb6nsoT9gt
+lrN/kqlyXJMhf1wRux12aUXN9Ia92lW6WrI7iH4=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subsubCACRL.pem
new file mode 100644
index 0000000000..d000a06282
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P12Mapping1to3subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZUDEyIE1hcHBpbmcg
+MXRvMyBzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUAF05Pg/lqipeLfauaCqtM5s9m3MwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBABqrLgpbtj/1buUK3kRN35sQe3KtFggWeg1MO7BkQtue
+zRD3ajIwDOBbemqCmEj8w4TdlDzTiEVpaa4k4UqlcTINMdlc8AbSzs4IjZvg2Mxu
+RcGm6+Kr8YfltOSeJk1zdQve5V9ft76TSGOZqK0Q4rTYRuuTipe3EnwJUdvyTR0u
+gmPO5XTMHnyecCJoUAHFmqEy5EAjgANJ9t0DwPzK+BIPDn76PmjKd0zhd5rAhQzm
+FhgGSyUAZMLAnPrpYTJtTW+QM92qJPxOMWvDAMVTJxUrZmfaDSEOFUnoTi6yADaR
+Mu8MWB8W9CRmxNShdUht4CGu5R03u6DGBoT70fkbn2g=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234CACRL.pem
new file mode 100644
index 0000000000..376de8c6e4
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUUDEgTWFwcGluZyAx
+dG8yMzQgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFJULAalJeKp22n8JDayIFPn190eSMAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQCqaCGQVcOhNGIvLyAEZ6u7CZSlusbOFE1T7cL10Z0XpNwHIU2e
+dzV4pmt0Y3tAJyR0FIXlqZbxq6fm/S5U4cWoM62jk4PzFGu9HaocJNNOIK0Opfuk
+TwwMOpYN/6IH74iy22lb2Wdgike7G9bCWl7nvMVZw5I7OIGyy/oqkhqjtWFLC9nD
+fYRIwfG3HPD8Kc2GMVc/iTalLDe3OUcsSGTrqCg0OwGckH+CdiXQk5MfV61bwICQ
+RxURNAqzCqYhNSrDH/qcGId/3mN/LzpoBr4SVRMZhMw0MpUWSTGwe1wnarhxaSoD
+VRHuoceqwHtU+s3AzFxHRXDbv/0xHECrkNjX
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234subCACRL.pem
new file mode 100644
index 0000000000..316b5ba594
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1Mapping1to234subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXUDEgTWFwcGluZyAx
+dG8yMzQgc3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFAMX5ZUA/So5eK/LRvZAmGUKAu27MAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQDCUm9OtS/rVGX56aFpRteKjEE8VKLOCXIecUda5ewyHw6a
+JRpUhGBguzOjY60yM8isBHYefdfjM4usLfZniy6NtfJ2S7yProWY7P4IYUsWgrMn
+2tXBp0LnyyWarx1f2NSeBJbsQKiw8fXLsygMnd8ISb6eA1AGKfZfxmeC4PM2Hl4/
+KbKdvxs7UWT4jD0WolZyOpjr/Ffh/uAKZB/TVks8j7ZENODT2lUc5KxmDbMCHEUp
+pd5GyRrXKJjdMMMUK/VUxOr1K22eW1FgBmx1zUiT9Uhen/bS5WXtfhVGqm1q468F
+jrPVC+/FBoFjuHU5tcxtNup3cLH6Vm4Y/v5+u2u+
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1anyPolicyMapping1to2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1anyPolicyMapping1to2CACRL.pem
new file mode 100644
index 0000000000..709a1368ac
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/P1anyPolicyMapping1to2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbUDFhbnlQb2xpY3kg
+TWFwcGluZyAxdG8yIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBQfAigoMo5KhPi4i0HxXXvoJVJrhjAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEABhVsmwrFO9I1+fkjbJM7OfRp8BbNFRh0Mhb/ky6K
+g4U6YuwlEQP6KzM3QyOyQPIh7CAljCBxJpJkXrfm29RJY3OqS4THg+FfEmIcU+MV
+1TrRd8CI6ufBCdoG0SUUsS2W1CZFjbQNEl/xAfMUkuJi2T0lbCCsb1y0lpGrFW1l
+k2HLwq3qbikjZyWhoD/k6ho1yIEg4uT03GyJUm/n7Ij4DThK7mJP5vu9VD8rGwU3
+XXsoD62oMo2duCLrH4Uj5U+k/RbYb3zdbq+6xb4WLkt9MC3zWK3NtiVWIr9Q3XjV
+3uz8fErny04GW1dGGQQn+U50ZLjCA3bG78hbyCxv07zp6g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PanyPolicyMapping1to2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PanyPolicyMapping1to2CACRL.pem
new file mode 100644
index 0000000000..c039b47889
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PanyPolicyMapping1to2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMaUGFueVBvbGljeSBN
+YXBwaW5nIDF0bzIgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFEcDJy9DPcUv2ZKsx9J20DPG+Xe7MAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQBQVc02PPmQX4EhnPqxh12Tk5NseAryd0o8bmViilep
+uCpk+roAUOXLvKHg43alw0d+OsPA435KTBLKs5hR1lrEjEqE0AW56jqYbdCmei19
+XbaaGc7hrBbraDuFqAeobbZ2jwDxN2MQqIOT5omzfyyVLUzVKNyNsxvOVCoke+ya
+n29eMlOzv61ZesITDJlkrqTEyjwaRHUQtfthv4TB0sPIP5NmLq9ThYqhaVjsEtK5
+4bS6XP6xsVw4uyPrwStEgPPAbrYZyyRVNrNJigAyEKw59Kl5GQPefAm+mAo+x5D9
+aZDC+5MDbHU4CcjPPzbX5iocBgz3rEazHL1CJbIflrlh
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234CACRL.pem
new file mode 100644
index 0000000000..ef2c47424e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxDCBrQIBATANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEaMBgGA1UEAxMRUG9saWNpZXMgUDEy
+MzQgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQY
+MBaAFPb9qYwmLLTP1tPr1B6tkmoduyRQMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEB
+CwUAA4IBAQDVVwwWNj9cO5+4t4+7LgMKvD8IGEKTakoiouH5na732HehNDO/mHzA
+cEKjj5MgEdx2JLghyLAtDsD4LTzdCANAftXnGeZJVcATUbjSecgPg5wFLLp9/mg4
+Fb5mIQeTUkYcrswC6Wa/P3vLJfu7L0vJwg6tPwnkFHw9NqsuzFqmQvrlrRtzLaDQ
+zlvg6BZkDCXSK+7gqQ84F4WJZCV9laVkymfM1ih0wXWby0VWlvAZK8SoWc6W7rep
+6dePGKx1V/lgJkYbxvMROoRKmoXSoHdxPktChC9KL0LievdasDF5/HZ5UgKNcE3n
+65jwDBq9nnOQfhhPm2WeLNlVbzY1Mzjg
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subCAP123CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subCAP123CRL.pem
new file mode 100644
index 0000000000..5cb4f07fdf
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subCAP123CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYUG9saWNpZXMgUDEy
+MzQgc3ViQ0FQMTIzFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBS5qlCBpjRmUWidQu4piGrsHMh89zAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAfV2uyHCfgiXrwk21BBpCMPiQmJ5erAU2QRfYd/IzoTgx
+sMGttr8QexaLY7rfY8K9Ju7t428gmoFYScIB8AITUCh+Z9l+wx3egQxCC9twjgRt
+zS/1ys8I2nK9CmA26ClY7TAL2ztIjFDcS+S1/tZlJxi26il6EpTjDkb4altMcwYD
+0dy7EW8Y/JAvFGBkziG9FiDThEdYK/hyDtceBEGDcWJP2s4CBOIigzdEkllFJe33
+ugx2AhLvGvHPzpyOzUPxlbKkkkoBjtU5WUl0v1PSiAa/OqXxXjOb1uuMUsHutbdM
+51I6VkQkncKEKN03OTkCgwthFM4GN5rurT02zD0KBw==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subsubCAP123P12CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subsubCAP123P12CRL.pem
new file mode 100644
index 0000000000..4f33bf88f8
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP1234subsubCAP123P12CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0TCBugIBATANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEnMCUGA1UEAxMeUG9saWNpZXMgUDEy
+MzQgc3Vic3ViQ0FQMTIzUDEyFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBa
+oC8wLTAfBgNVHSMEGDAWgBRO9F6h+Qgwe2WsksARCyzTtJYHHjAKBgNVHRQEAwIB
+ATANBgkqhkiG9w0BAQsFAAOCAQEAO3mUa/hz4u9id4j6HNSVrunOClJfxtxgVK//
+BhUHRP7DLt9PfridxGqVOENl4KKUp3Is8JDXhsQLfalp+SXUEjUNIW9tK1XGT8RM
+KuyPXfYNvK0ki8RLZBrOObwuz1bwCIr8suJnlbuO2PizZiYkd9JkPpmI4Ql7wvKQ
+qtZG/D9gMSKw8YYU0BBD38C1DBcx9zX8Juq1of2wA1bRO4+1r7d1caiauSNDICLM
+6K+5veVzXPbdi9AiCym0q2DafSijAO/tyVI7viGFriA1XXPyW4IgJTlYwj6C7bNE
+spPxDeHZOYGjSRYwnOVwl5FetLBZeXPnb+oCUueETTdCap53mg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123CACRL.pem
new file mode 100644
index 0000000000..9badaf1180
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwzCBrAIBATANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEZMBcGA1UEAxMQUG9saWNpZXMgUDEy
+MyBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgw
+FoAUjCgK2g0JFGLuPT2WuHGTEonq6GMwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEL
+BQADggEBAF+cFlwOZpoC7aoNCsV8ISlb/o86hb45QuGdajlLv/vTDAstyF6123qR
+3dE5/YuJ4FTgjZqNt6iBOMIaauFE9nTeQ/G7WhB6yGOtna9QrTIIWQfi3kyuONC5
+1+YUr/dj9wBJgHXQhO1ugdweVdstePbTe0iRl1ZGG+Hs/xT5r7wji24hhtjyXoAJ
+J9A2NQoLt7wD4OBOKQUHarYY24xpnVcWryWxfS2HGdsiWfyrdVMSTzoZnIqI3kzW
+VvbVj99ShHKFmIQMqBuZZGQCrXlts5G6mknQK9TNCHCJZwX41S5Tw/dd5X+Ujdyz
+knTDjuehdwjtDecV5Dh0q0nORth5X+s=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subCAP12CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subCAP12CRL.pem
new file mode 100644
index 0000000000..bfa6e83f6c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subCAP12CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWUG9saWNpZXMgUDEy
+MyBzdWJDQVAxMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUzgDa/aqTQPjAoHmtwXjOHdcn9p4wCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBAEBeDNTliwQBVeWRQ3NDLEUH3xNSHfAr8itMFr1gMI8YaS7e
+qYMtIZnedQ7o1A10abrH6X4li/8UDL+7o98CTcd02D2Hrvc+QXT++nIJ5oFbt0qJ
+iOVXGQ5ZXVxSaNif729zjcAmgGKcHtVtxPvf9CgmnQ78hA6mx0ugFHs4QSmecsMt
+umd0V1AsscRGzTjvN0YCVBPpZPy/oxLU6pYp6XAmqC1UHPv8Ny1/unMz7cYoam/0
+83KZJHp8I4FSzkdhrFyLjKaaVxwWioLyQUTwrzR/qzaU1Eyk+KipzKVh470kuItM
+cDnV0OXOPuJR1XA3yhdLZU0aMtwd28WZ1Y4myPQ=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP12P1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP12P1CRL.pem
new file mode 100644
index 0000000000..f8a920a1be
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP12P1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbUG9saWNpZXMgUDEy
+MyBzdWJzdWJDQVAxMlAxFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBTkGz5Gt+bIqdjt0TN/BeHxXRIkwjAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEAZg1qheMvRGkd/jBrdaoWnRb0iEuPZw9Ij5k64ZeI
+JUmMeWjKKFnLBsC0MIrEtR3NPqMU6tfZH3mmeCzJ6pjo0IozkN1OnMYFqwxrfn1T
++d/yM4fYBb12oesd7n1+c36hlHKd7dxi1xUAwCIABnX/17odaOCD9ikA2sq5XfqS
+p4Z7IUPd+i/8dF3Pkfm+cpPJaNdpdd2sxx4mmbsGcL9+2xIwhfiVavawZe0MZYxw
+kPhNVL8zL6kYUCRvB7J2hEwu1MWH3paED9MIkKyS0zVdzfg4DojApNP/nwL3JHIf
+DVscEQo6mY+6hhhOYApDNF6y81BRqasImFItcLp/fgE4tQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP2P2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP2P2CRL.pem
new file mode 100644
index 0000000000..cbbe9d03b1
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubCAP2P2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbUG9saWNpZXMgUDEy
+MyBzdWJzdWJDQVAxMlAyFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBTp/LZeVhROBh3RMv2IYGsQ+AUbaTAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEAYcCBk7Si8nv8UU/B0/YbctjIyBk8VOtKhIFbRunt
+alE+/Vc/c77r0Y1CfVII/DOAFcB872KtQuWyl5p8uVlVwmDlL1BKmz35mD2PS10i
+NsuofkZTp97xrRZbA1k+zqMshOzmEXReNrR/qliJpTPlH1YMNV5IN02HNYZ8+6mn
+BzAs4e8/xS2cO9ktya0ZwAqwH3ksD+etLL/MIj/3BAL9HRMOC+RcKktWkVZKqYq/
+AAzn3HlvnTUZi2OW81ABtFl2hYSJEyBcKjrSoDuZ4Utk5AuxOsLwa0hH4da+/4nx
+OreMrYjymG9FpLVq+RhVYMdJSzp8c2CU7rgN0Pap7sQY/A==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubsubCAP12P2P1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubsubCAP12P2P1CRL.pem
new file mode 100644
index 0000000000..2a6a21b33b
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP123subsubsubCAP12P2P1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0zCBvAIBATANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEpMCcGA1UEAxMgUG9saWNpZXMgUDEy
+MyBzdWJzdWJzdWJDQVAxMlAyUDEXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAw
+MFqgLzAtMB8GA1UdIwQYMBaAFIkgF4T7rLsJ195eXp5o9jlQH0CIMAoGA1UdFAQD
+AgEBMA0GCSqGSIb3DQEBCwUAA4IBAQAVS+qKdu5cTu1Y/7f1Yci/ULGAtX4oYox6
+0LYSSXpOl1BzTNMxUCp30N382djQEYODR8vROlVXDyEaHwMC8Dyn+YreG+1eHODk
+Mq/Hc59ckRW17LDJpyBew1535EVQa6LtC6bD72AQ1Fd+hzH90WNNQCMb4xQ6eOnF
+T1pSoKoopsA2NH3zTBVrtq1n6K7FOojGqKdO7oYqill+bRdMoYSNKQx1lskS9E1b
+lQftEmE8AAlU+Q1zV5IiiSpoEXe8/nbyTwSbYvaUHmmBgwCOdgnpJiG6TvwjcFh/
+zIQiGotG9zQszNrO7GPpvc9wQ+o2uN1Luilv1P0FRw0PBHMwmwUJ
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12CACRL.pem
new file mode 100644
index 0000000000..1af85735f5
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwjCBqwIBATANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEYMBYGA1UEAxMPUG9saWNpZXMgUDEy
+IENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAW
+gBTYXzXimsE3KibOg8xzDnAVKjriMTAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsF
+AAOCAQEAUiAHin1qZsRcAQcRXu9l1qnbsNYeC32w7Y8SR7o7SLMBjrLfpzTt3u31
+UGBH/9CfynTV2n3wVuJoCCFTdkgRn08X+Oc2sK/8g+oKvTwmoLQv0lktEsFvOFC0
+4/5wB94qkPysqGKKPj0ADujY5GBWb64Z9V6ehvxACTzKhPCNc7auvTLZEymtWW2H
+4C6nZGjUuuoZbd1Y20d0u5/18MySt5HCfKyoIfA75dsnuL7RJVFvrjcXxH40cXs8
++xizlf66wdIVeWCAr8RV4bPFmlC7fAF3UjC4MoE1RQqbWuYig79F7RS29s6XNWiq
+A0W7puTYGKoCpIUETmzBSDOsNpcfIg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subCAP1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subCAP1CRL.pem
new file mode 100644
index 0000000000..c96f12103b
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subCAP1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUUG9saWNpZXMgUDEy
+IHN1YkNBUDEXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFCKe1w64SM4JDjpdvtZNWCNWjcvWMAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQCPniPRTYwvNO1eFZjaR7nnHYFDRh7cAd2EsYgmh9W7kjeafaZt
+vLCnzQv82LN47Ki1z/2KWraLSRduP8qnY4wGOdRsahnrl/ss2wjMB6UiFp+Un6IA
+AKEM5MLgZwvjsadAADqJXonGzB1Eh2xmHGqZloU5V5FDewbjem/scf3yufvahMvr
+ZSjBsSUMCBfIewJq7JRkwSgyip4K/t9UBJBbsfkOOR5/rEgaZyyfI86nGhg0GawS
+FHw1fAPcG6vEKnsyyHU9JhzjtQYUi3JiZO2BamFAXfJkDOhCWfkR4ywhRUP5bqAE
+q4GAriFrKPKYB3Fp4nAhbLi4bhV4kUS+lWoT
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subsubCAP1P2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subsubCAP1P2CRL.pem
new file mode 100644
index 0000000000..4dd0f2fca0
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP12subsubCAP1P2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZUG9saWNpZXMgUDEy
+IHN1YnN1YkNBUDFQMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUx6U3p9D6JOV839vyXWnb7sr2me4wCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAKWuXLxMM7H4MkbAsQLa1RgeuDYC5FLy5mzt/UsidYqx
+rSK7vX19l658Lz1NEcq25gXzJlfOG8ZIAUkO/SXwi1IwqOU2QVkn6nJnXYP0J0c8
+QEzxYlYEC/DHDTEUltH2ZoIuOoozIT6NHw8+2/XBBjatS1nL10bhwvzRXirGFKGN
+BtASLRZeHaU0y/n2KkBuusn3HFyErzRskNRLPOTk3Lt0/RB8nbrRxUUZJXAaZJIr
+4Kj4LcatDgdgXCZ2MEC/mCByKwFiwh5RgMQqPPLMhGBRSPfPD5hVKVL2iGu8qSxK
+kkLZkwrGL9U/1mXtcajUpz+r28iLP4uJnCxt9ZBVIcg=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCA2CRL.pem
new file mode 100644
index 0000000000..d2e6b8d3db
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxTCBrgIBATANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEbMBkGA1UEAxMSUG9saWNpZXMgUDIg
+c3ViQ0EyFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSME
+GDAWgBQXLOoDuAd3gT1lpb8zH8x60pj8vjAKBgNVHRQEAwIBATANBgkqhkiG9w0B
+AQsFAAOCAQEASUNpb/KK0iBuFV/Y7HRxjqNfJAhSRjOxNrEMtuql/YucrqQKFs2f
+AcbNwEWPPdW7KEd2bhyUBlJJ1g0mWCPu+bHNv9IND3bsioXiStlDblymVm/ShJ0i
+f3VWT47L0Lb6Ppye2r+A486Q468clSbDv2pj+vAPqFqUaSr5iN+Y/WTxUtAs34Dx
+qDRWP9lye1OzlLnMJSf/ZVYHdS/KmnsR9YIIeI7pNqtPf9ilDBe6Va51tpVfHnp3
+OLQersoyyDApH5KCQQv0/+4EPqZjmAcO+ALDg4Q92vfzbULImJW6rMD6dlEtITlu
+iful4K0ey6Jngy/6qFTtI/jJgzNmxsR6Zw==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCACRL.pem
new file mode 100644
index 0000000000..02c8fa43d4
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP2subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxDCBrQIBATANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEaMBgGA1UEAxMRUG9saWNpZXMgUDIg
+c3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQY
+MBaAFF48hHOeMHBycZiugTYZ2yIOfK8DMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEB
+CwUAA4IBAQAIgjc4iT1LVOUqEO9SLZgx9MpR4Vt3gTa3JciJH+czDui7YgsT688m
+8/dqZXCxTkt9JYPQGABYYhwxsQC2oyjG2jercknnJ+XHk4JV2wN/XO9ItNhI+OvA
+rnKtzk6Rpf7pS3SSjeU3XR5UIOiMM2JoWGvtUhwq7b5RaLk36Z0gGp9x/3LaGDBA
+FTred1LnWgYQCO7jTGWfDT4xIJr0FqA1RNLb+xvkmA1lmhjZ20lw8HXHgFsfvb4L
+ADFkLzFQ6p/zuleXBDe8U5lusCqjls0cTaiNCdpPXuJ1I4hkPYu0raquxjC7VoM8
+LWcIpRna9gUu8sSD7k7N+NDdQSM+Op+P
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP3CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP3CACRL.pem
new file mode 100644
index 0000000000..0eac63d37a
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/PoliciesP3CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwTCBqgIBATANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEXMBUGA1UEAxMOUG9saWNpZXMgUDMg
+Q0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaA
+FNgFqyygi8OS3Mataj+/88aY5dz9MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUA
+A4IBAQCwxaqJWjJraTqw0xo+dvcx3uD3LYUe9aJqKvZTbNqLT23k7U62qcWUz59N
+Rprnl0q9aemI80Mk/Vk4WAr9weTsOytXrNML4Rgk4Sb+WjU4OSlUZbBka1YS41Y4
+xiZzhQYrL391uyDD/FLsehWJmkO9JqeydLT1A1lAuX9m3f59PJ6waXJMMwySszDI
+T2e56JR6Vt3659YRpNScJmDKWc3wdHagNvmtn4Z/c+TtO+JN11doMwx/92uV+nic
+GVVPJQqKZDvNfK/hLxBo3nKBpXJUrU4AyYCbpe4idc6CxYMAy95UqUlFV72pnndm
+E5RRfI4x2a+BTvs8HNSX3LpruISg
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280MandatoryAttributeTypesCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280MandatoryAttributeTypesCACRL.pem
new file mode 100644
index 0000000000..49582a3282
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280MandatoryAttributeTypesCACRL.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICDjCB9wIBATANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExEzARBgoJkiaJk/IsZAEZFgNnb3Yx
+IDAeBgoJkiaJk/IsZAEZFhB0ZXN0Y2VydGlmaWNhdGVzMREwDwYDVQQIEwhNYXJ5
+bGFuZDEMMAoGA1UEBRMDMzQ1MQswCQYDVQQuEwJDQRcNMTAwMTAxMDgzMDAwWhcN
+MzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAU8FEYYu/OQce3sGd0awK8Mgoz
+meswCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAFqTS/IzHJiqF28DiO+F
+v++AFZ/b8cYN6B5eoSoZYBg2C7pV+5UEL0+hQlper2e6TUIEkMpSU7Y6VWc2okpS
+YR+2bNCsIDX/RB2DYzyEGgqwoBmbeTCE/bIbcxjoSUOP7YlI4wD4XgOISwVOBZoK
+Mc+341k1iHhwI0OFHv3XVHqwegy5RVcgYhWcq/H9ARUvD3+a5HDdBGTCP4r8aCcD
+46zDEsBRYVJNPsyk4cnBsR/8nh8Bufy8PWuArb+s1ZSQ0PMgtwfrvqPCM+wnl/+Z
+gN3UiKvlBG2lSrTxhOelPGvoNZrr6Z8Uw8rl1EXcLvPTJsqR17snRwWCWLR6ewAc
+XbI=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280OptionalAttributeTypesCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280OptionalAttributeTypesCACRL.pem
new file mode 100644
index 0000000000..106a0215db
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RFC3280OptionalAttributeTypesCACRL.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICGzCCAQMCAQEwDQYJKoZIhvcNAQELBQAwgZ8xCzAJBgNVBAYTAlVTMR8wHQYD
+VQQKExZUZXN0IENlcnRpZmljYXRlcyAyMDExMRUwEwYDVQQHEwxHYWl0aGVyc2J1
+cmcxDTALBgNVBCoTBEpvaG4xCjAIBgNVBCsTAVExEzARBgNVBEETCkZpY3RpdGlv
+dXMxCzAJBgNVBAQTAkNBMQwwCgYDVQQsEwNJSUkxDTALBgNVBAwTBE0uRC4XDTEw
+MDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaAFJtubz+K
+p/TntYwxW86ZS5EcfHy9MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBB
+32Yrko9n8ahvFVhspRmxscM7BMFLDBPKByEzJomnbztKvfw1bn4lsO39UIuBQgbS
+u+w1ZEnc3FcTvU0KjPNUA8e3eiuRzhct1XtqCPo7OmtFZDP7HQaCC0M7bxLiD56K
+00ww0RoiC8Vx0TI8+A+dZIQH1g19xShQ2WGquQLC26Wcf4FeXCTS/aaPeCGurbKD
+RBpShJHmZ2zFUZy0Wyu/FG+LMQpJf/ypy5dzYO94rHYMOdjfk4q17d9rLbtzyIZl
+GIOuZHdlBJi1uVKKOWFJHc1KIEbf2dc3AOfRAcZnvWZ9cBJpm51VC3FNPjqBtxVm
+OSHxymJkNoLCs4Rr1cCL
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/RevokedsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RevokedsubCACRL.pem
new file mode 100644
index 0000000000..f07d7b88bf
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RevokedsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwDCBqQIBATANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEWMBQGA1UEAxMNUmV2b2tlZCBzdWJD
+QRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAU
+lm+SmaDpdnS7X9T4+xnZzx0FoO8wCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQAD
+ggEBAB+FPq0gPzR/ldksUu2y1NFGBtliXqr8+2YkuC3znY6aUv+jZG4MgXN/m30I
+hs7lxydqbF2ubdw6Er9PhmvJcnH92BREyAAUHt3zzHbCK8WKmwdofIK/tFrXr0XO
+eGPfmfmm8oHJREcNQ2ftaCvq7eTy61KqVno+p4KNKLPxWvR2uahuhFxgIXZlJVQF
+lSIPCEPGT+t+tSxFQ7RevCv9jl9KFIf8hEWpLxjxY44uucZlQaLFV0oRiiuB7Cq3
+xYM0xa8uZ5/xuBu9MJ1TKg+LWqp6dwd3BRo4BxbBHOwNeUJ+PtaR23AAoiL7s5mt
+bsFxXB0TfszCLEmLmFFfkuB6m6k=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/RolloverfromPrintableStringtoUTF8StringCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RolloverfromPrintableStringtoUTF8StringCACRL.pem
new file mode 100644
index 0000000000..912b6c8b8f
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/RolloverfromPrintableStringtoUTF8StringCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB4TCBygIBATANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJVUzEfMB0GA1UE
+CgwWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTE3MDUGA1UEAwwuUm9sbG92ZXIgZnJv
+bSBQcmludGFibGVTdHJpbmcgdG8gVVRGOFN0cmluZyBDQRcNMTAwMTAxMDgzMDAw
+WhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUtW1PKD/Hu7GYpKml0Khb
+Xkp0s+cwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAFPDLO8fJtAH7E7z
+iHWXjzFLzoHGbLXSioC2TDR+Fm3hAOwdSphltknYwSxA0SyKeru8c8RVOu0fd7dS
+CaXmFaYL9CE4HREg1zFtuSPsElkhuZgi5N2cijO4oXUgdJsssFe3O/jWTBixJONF
+ZoAu4pjxi1mcNYDK5jn45jB25RNnjvhTm84I0o5/RQOp9vzpT5V60F3npWI8m7PQ
+UswjVucpjvslv2rPZEN5DldNgg+/W/qElgRFa+loYjeJyYRftsknzt8F1g2fzC7i
+k7fJTv0ZgFOk3tdUZhFHC3DNcwb6uscyTEdodNzaPhqoNHgUBdCqbUq0zZQXsIz4
+Sfp0ZJk=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCA2CRL.pem
new file mode 100644
index 0000000000..e3b1f68960
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEuMCwGA1UEAxMlU2VwYXJhdGUgQ2Vy
+dGlmaWNhdGUgYW5kIENSTCBLZXlzIENBMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMx
+MDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUE4Q9hI8eqnyBd18x3c1g85eX2bEwCgYD
+VR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAKN55WtVRJBOZvbUAlZXukKilUzr
+4Z8lHcq4fiql8hc6UUhmYAc/7MdfDa3NqgbUoVg7aUngm52yLgXubmnMztA5Vqum
+CXiNSmJ5AVWh7GCs8pdMHFLpFqnh1y4RTpt4AjYFC+xc18gSrsyDKWv7YEYVyQG7
+GHA9JEMm3SpSgh3B872L+neVTTMrO/bHKl54QGGp1tasaLdTkRVB/002yGBraVvE
+zfC7szqOc5v0tl4e3VrUBcNfn4QTDvl5PfrovZdPJP3Ys7139K38+kT/2YwCJ6M4
+EOAhyfzVSTgvuFoB+UlYIt10c5GA7J7pDJr4PCGTzR1K7XesSFuZCbD5Ddo=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCRL.pem
new file mode 100644
index 0000000000..9e3ca350cc
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/SeparateCertificateandCRLKeysCRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB/DCB5QIBATANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEuMCwGA1UEAxMlU2VwYXJhdGUgQ2Vy
+dGlmaWNhdGUgYW5kIENSTCBLZXlzIENBMRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMx
+MDgzMDAwWjAiMCACAQIXDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaAvMC0w
+HwYDVR0jBBgwFoAUcopDCwRbPT3EVeGDxp/fkMrq914wCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBADQCnzJmc0jLQFb6EQ2iJDMcxrSuJftSikSCoKvuRTTH
++4cqd+xjh+kkZ1FCCmG6mY/hlnLTlKYqJlrJuu/vhHZP6XYwqkrtyx23ORmAOyq7
+SAuTvPBOPRo9HyvVWWHITgAKA90A0XUK+/zg1MRKgqqslTOaNXCqhu+nvshCtLx6
+MLsCYH5LVs3GimWfsT7wSpF4cqI4QyfZLJDtGz++9M7s03LvH6QNfQ0qrSaOdCfk
+hsdtNEzNFOOy34JejUZIDie83zj7Vgr1v6Gx+c5xkoDemggV/wzLYi7Si45JQBrJ
+trqjdLNOoS7QFadH/Vw7zL06Fahe2uUOOsXac76NQl4=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/TrustAnchorRootCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/TrustAnchorRootCRL.pem
new file mode 100644
index 0000000000..114e6e1cbf
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/TrustAnchorRootCRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB4zCBzAIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMVHJ1c3QgQW5jaG9y
+Fw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMCIwIAIBaBcNMTAwMTAxMDgz
+MDAwWjAMMAoGA1UdFQQDCgEBoC8wLTAfBgNVHSMEGDAWgBTkfV/RXJWGCCwFrr51
+tmWn2V2oZjAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAqxkdtbsha7bh
+TM3wtzeelTjR1IGQgK4R8Psc2fw2NOydlq8PeSc3qitHV6m4dqHzchQlytYprOK4
+dRitEh+RYY4UKUNu+OQQ5VFLSvuC0Wv3xn2w29VqpQtavBFfJ8Lst9520pece6x8
+6fB9L6VP4YNGIrLc+7hEjEDALJs+ttPoxNNXGMApQQi5xyZEksXQAo60ZdH/r95l
+dVCa7U2OVXO1MCuZlWQRlql0Bi3CzE26cW1jccEdU6yQ0ONKNuROR+6NsXZ2Qm2C
+lHEGWFJAZ/CWB7NjQ9maNkoioZb4IB2AKPKBcb0mT3TYspgT8zcZSP5DLC8iVOrc
+x2SLSvd35g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCABadCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCABadCRL.pem
new file mode 100644
index 0000000000..526eb1f6e1
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCABadCRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB7jCB1wIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXQmFkIENSTCBmb3Ig
+VHdvIENSTHMgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowIjAgAgEB
+Fw0xMDAxMDEwODMwMDBaMAwwCgYDVR0VBAMKAQGgLzAtMB8GA1UdIwQYMBaAFBCh
+AdaZnYDjbf3n7ndLX/FJ2TxTMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IB
+AQB+8PsN24d0Zz4YP749N8IiCoLpju5Z7O2yP6C4n3XwSRKExXK5ROwg9adTW556
+L44a0aChbR1b7Mnz/du0vx67O0D6hMRhS7ICuiI+pkpovJsVnT2QdObWBlls2Bic
+e+iSX+eIlXHcURQc0ZkhvKiiDYgxeSo4RvxknjaauHKdIA1DQC1G2IFU+Izjg7j0
+pS5yeLaGtz7azDmrChRrP+XRCDjsSuihtS9dtDRTyUwRYjhU6plkHjjwvXaFh3EW
+ZQWN0LVL7m7M2MtXUPlKYlEG8SpcrfBS25aBg4tRLRo8w/iWY0Z3HcRYYj9HiZhU
+3Yo0R0Z2apWmbVVmxNJQy+jA
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCAGoodCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCAGoodCRL.pem
new file mode 100644
index 0000000000..7bffa1d5cd
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/TwoCRLsCAGoodCRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBvjCBpwIBATANBgkqhkiG9w0BAQsFADBEMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEUMBIGA1UEAxMLVHdvIENSTHMgQ0EX
+DTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaAFBCh
+AdaZnYDjbf3n7ndLX/FJ2TxTMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IB
+AQAWgigQQEvB+tF9ELpYI007J23N+XwGsg5vz8wIxMsi5Sa3NDkUCZ8ByXClFLRp
+zIM650GcrIDpZCHPhfgT9bU2b2LX/4vVdSy/aI7tC+nd70UPKeH4SU7sVwAJmKQD
+NRnWLJp7VXl79yR51SEMKrwNpgoFmblJHKcLyNr8NrwmLmS/5mpGaeri0bEh53cy
+Zv9dvJI6Nvh30wbYtcEtURtCSHWYlIYs8cQML4IsYcQbWSX8uS4XqSnaUVwYKtFT
+HdUX46XIkuGdKeExJKbWXb9R9JJcCG85Qn+mfX+Z0XatgOxGpmuzJ/JbEqxPS+w0
+25GOIJTaYjoDxoOmVIpJZGcZ
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/UIDCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UIDCACRL.pem
new file mode 100644
index 0000000000..c94eb68a11
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UIDCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBuTCBogIBATANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEPMA0GA1UEAxMGVUlEIENBFw0xMDAx
+MDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAWgBQQP8UEMPHY
+QzaFeVyMjYud7i8cqTAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEARJT8
+6342NMtFGT+8uvbJJ26LNypeqnke2LqSnfunR258riLofJj2E5r1NS7Ew5YjWdZH
+3BiwowR/IRuFqlj1l7gDB6L9YFVbNuJrC41UxIBzGMa2zHtTXxe610TC987XcbbT
+O4ccPzvQ3MEfiY7odLNkOpKfOHUTgOvPfpo/8X/jofZp0kBTH7q31S4XKH1XHBab
+H2kyudXTJmNkSXOdXlclPdZ1wdtt5hi/i5mYMQYnwVgQoburqiAt1LurPrOi6zgK
+JmfT7ELdKocAa0nRCBMMTZLknEAVubFfI1ViKGMGwolmVIQjlJrI7h6RMh4bUEVI
+eDsOknaIs9a+DRxKNA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringCaseInsensitiveMatchCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringCaseInsensitiveMatchCACRL.pem
new file mode 100644
index 0000000000..a6c2055e8e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringCaseInsensitiveMatchCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1zCBwAIBATANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJVUzEfMB0GA1UE
+CgwWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEtMCsGA1UEAwwkVVRGOFN0cmluZyBD
+YXNlIEluc2Vuc2l0aXZlIE1hdGNoIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEw
+ODMwMDBaoC8wLTAfBgNVHSMEGDAWgBRg3xjRyqlQkhEXIUTSd/Vqraa+eDAKBgNV
+HRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAfnKj08ZVDYA3KZCzOUW4VvkN0rgV
+qYukj5p80KK3oRJtQjiMB7M+BrG/Nu2ReWIrB2vSyryurZD2QeTcJOr68b0I/VLV
+uz4/b1/AlXgvUywrMiaXKrW/dApifr70HDghgvyCwQ1SDST/jFNBmrC//H61A3NG
+PenyRN+GkvTzlOIoJcqZ4PRX7J28D9lesW4m8Z+k7o/mF0c2F2lBMG+yzTh9ZB5W
+eaqvmY63gKTu3GRUHET6/SE2HI1fgioVFPDutr5b1uh9ACA60X+Lkg6MBhPqPGdY
+UQXKBt92Nd1aHg18VydBY9+6yBEvlQfpZyaQ/Sx7TL0SSwzKlcGDwXvVXA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringEncodedNamesCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringEncodedNamesCACRL.pem
new file mode 100644
index 0000000000..2bfdb97dcc
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UTF8StringEncodedNamesCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBwDCBqQIBATANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJVUzEfMB0GA1UE
+CgwWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEWMBQGA1UEAwwNVVRGOFN0cmluZyBD
+QRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAU
+O2dbRPINp0h9cymMk5/VJOMSYCYwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQAD
+ggEBAE2uI86u6pYfkenx+nHcN7B8ymkICJpPJlIqNfjteDVjwz9D2ra89nHKdXRE
+83ftELk0cXxN4qEuylBI+2V/WUNjll1VsTqvRSGDFu6KhjZHEjbdGHu2Z+tT7E9a
+72X3hxYJEDycSTlaR4OvFUWeKksPaKXt6HdhV7AQUHT9KbewgLDekpPKj1O1tjzs
+/NN2mt0mBqbm9dzi4oL2PezZLfEOpa1BXQR9r37HWKmDxO4SixOGNaOd+jplpzhy
+PDqftcMmgRZnKesEvKcXul1GRxreqhaF+dlvluKwzRgC9Z0x8iS8HyoqlCzdGy8x
+OuRJvqqfg0aPDn/waUA0pF7Qfwo=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLEntryExtensionCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLEntryExtensionCACRL.pem
new file mode 100644
index 0000000000..dfee3b2056
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLEntryExtensionCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIICCjCB8wIBATANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEnMCUGA1UEAxMeVW5rbm93biBDUkwg
+RW50cnkgRXh0ZW5zaW9uIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBa
+MDcwNQIBARcNMTAwMTAxMDgzMDAwWjAhMAoGA1UdFQQDCgEBMBMGCWCGSAFlAgEM
+AgEB/wQDAgEAoC8wLTAfBgNVHSMEGDAWgBQAphnLoS1NKC8i89JMN8//TDDN6jAK
+BgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAIGIA0Yful35UcVgnqPFFJiLX
+VB8WXGbleSexbAb9EgxCCpffOaMuaq51McJ+Rjspyjmn0SEnbnpeKmNbmYtnQjn0
+OxNp/Yy5ZwjufitxKb9JgFLBhfpJ2BU9H5MgPEmXA+aZf5ojGPh/2afwJKE/9H22
+wemiZlYlpA5aN7PYqWHfEPE2bd4Ey7RHleuCRpfDHx2EgumLSRYjm9q++THgGOgu
+C59aDH3vvuAItfh9eVHTYxxjRm9kjIC/RCrCvQRclRGN/SoPDBys9RQxv1iklvN2
+rLH+Os+0BB3L67GMsAFQhWXCFU6U9Yubm/mErDVFOwsmuMNNKgojKkuqAhxZzQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLExtensionCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLExtensionCACRL.pem
new file mode 100644
index 0000000000..8d7158e411
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/UnknownCRLExtensionCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYVW5rbm93biBDUkwg
+RXh0ZW5zaW9uIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMCIwIAIB
+ARcNMTAwMTAxMDgzMDAwWjAMMAoGA1UdFQQDCgEBoEQwQjAfBgNVHSMEGDAWgBT9
+//4ZTdsMncWi2IJW67DZEGHjMTATBglghkgBZQIBDAIBAf8EAwIBADAKBgNVHRQE
+AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAsguh6rQBEGU98+Fqtl5R79QDu51NuNZF
+H2otyBt8ZPFJkif8J/pquv09GgIMFsMbAtMGkVPNYEjnQ6MHSWYE2SxTYeIfOnQb
+JiED6NtncdUGsoXt2g+9gJTDdVPjl8z9p1j1QEdp6c/XEj2gEVGDkM2iAy/3QImN
+kqrG1n1QtiAOUQ1oZoIk6NnGfAvRQ5/eNZafTa7vm805Q11tE6mT8XwbUX9Cs/lL
+X5h3h7DATdVfDPYwac9NZ8rrof7FQ/jXB4p2P5PM/U2vqEM8YTuRhW2w+jGzBFY6
+ef7bd7LrSoWExjczcmVuIZDqrxYsdAc4TJbQUm8B28FkdM4NzVo2Bg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/WrongCRLCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/WrongCRLCACRL.pem
new file mode 100644
index 0000000000..114e6e1cbf
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/WrongCRLCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB4zCBzAIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMVHJ1c3QgQW5jaG9y
+Fw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMCIwIAIBaBcNMTAwMTAxMDgz
+MDAwWjAMMAoGA1UdFQQDCgEBoC8wLTAfBgNVHSMEGDAWgBTkfV/RXJWGCCwFrr51
+tmWn2V2oZjAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAqxkdtbsha7bh
+TM3wtzeelTjR1IGQgK4R8Psc2fw2NOydlq8PeSc3qitHV6m4dqHzchQlytYprOK4
+dRitEh+RYY4UKUNu+OQQ5VFLSvuC0Wv3xn2w29VqpQtavBFfJ8Lst9520pece6x8
+6fB9L6VP4YNGIrLc+7hEjEDALJs+ttPoxNNXGMApQQi5xyZEksXQAo60ZdH/r95l
+dVCa7U2OVXO1MCuZlWQRlql0Bi3CzE26cW1jccEdU6yQ0ONKNuROR+6NsXZ2Qm2C
+lHEGWFJAZ/CWB7NjQ9maNkoioZb4IB2AKPKBcb0mT3TYspgT8zcZSP5DLC8iVOrc
+x2SLSvd35g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/anyPolicyCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/anyPolicyCACRL.pem
new file mode 100644
index 0000000000..d8cd6550ee
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/anyPolicyCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBvzCBqAIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMYW55UG9saWN5IENB
+Fw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAWgBS7
+yd7IHJXnQuKQoo6uA1yrJGB+hTAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOC
+AQEAW7i6zdMI6ytGpku8kYKf2WVx9tqIMFh+vvcagsWR/9oPNp1kXgdfv/tfRS9F
+JRQ3RVYaKY2bWDVc8ISsrwZpBMe3RjfDEdqAyuNcy4B/C+O7OAtyNinAvtsYASAU
+gfDoW3s1V53iLbLDfY1uRCq7F78dHwjuuIob+tpHFR9EVUx3MgkPAyq8oLrbDdaV
+FAsq2XTgry00qj82bR0rSY7UdNMOhDy32qeoH4ZEEh0XHdBEM3xuMjwn6x6J2SiV
+96FDpO+UNcTr/VeV9sx0xJAJOqmSU+e8nL8FKCGhm02fI9CIZBV4TOICDgacRgOn
++aSLkS+XcWlyrkZL2FakdOWiXQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsCriticalcAFalseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsCriticalcAFalseCACRL.pem
new file mode 100644
index 0000000000..b5726c158e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsCriticalcAFalseCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEuMCwGA1UEAxMlYmFzaWNDb25zdHJh
+aW50cyBDcml0aWNhbCBjQSBGYWxzZSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMx
+MDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUcN9ELwOZHBdzGPI2PBQ00AnR8u0wCgYD
+VR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAFaK4KYhrGo/o9KPU/OnZGglN4vq
+uuAH6a9XjvSUA/de1oHyAxw6rgxrjBo1pgtdLgSqXuYXMeqyVjZV5ew58wd7f0vG
+u06a6f3TOX3ScNZYY9/u1VRsX8/y3kKUg2+EQdr7vYCjhSIc2SLqpAnku150OwB9
+GZG7y/NRjqX9AyecyCJm16G/w9fA4+tndtvBvvDIwYn+LGrse5cgka4iR+CWzsIj
+cA17nCnhg3n88NSXrIsre1LI1YBKEHrIqbTpDglDxtJcdTtF+5/new5L+vftj0Rv
+8bR8NQPo5DBNJ5C9GnCjQgVSyMnQNhD3+LUDDScGs0QVg981FI6tusPFZpE=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalCACRL.pem
new file mode 100644
index 0000000000..3dfeb7ca4c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0zCBvAIBATANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEpMCcGA1UEAxMgYmFzaWNDb25zdHJh
+aW50cyBOb3QgQ3JpdGljYWwgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAw
+MFqgLzAtMB8GA1UdIwQYMBaAFAqkuTBDrEPINAITz+9V6L9wn0avMAoGA1UdFAQD
+AgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBY/ZWklRmCU6F7pRzO8mrG3iaF2gp4Qyse
+QLf/yzlYy5XdbwzhwiClQ7EwxA9jaGD8EKopJL9sMh53QBZFivrXUP+O09cHRlMI
+SCyonmbdvnOUDwoky9YY4KrC0YI+mhbOpe6LQJcRgj2ge5C1i+UsQmUZapOUvXaI
+f5rc1TlLg4mlxYSQT9jnLV3aAwt4i6cwitTkpbYPolvjsHqfRQ2/aLLd59SNnIlv
+pdso7IaAW3aoo38dJ8ZyJZBwNAwR3dmi4oIOivHX6FwDgxNdhVIN5X/VsMeNbRu/
+mD1HePYlexWjcMfsVRx9oVsIVoT0i8dAXEnefM7n1XOadWnaW8Di
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalcAFalseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalcAFalseCACRL.pem
new file mode 100644
index 0000000000..36b9df8549
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/basicConstraintsNotCriticalcAFalseCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB3DCBxQIBATANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEyMDAGA1UEAxMpYmFzaWNDb25zdHJh
+aW50cyBOb3QgQ3JpdGljYWwgY0EgRmFsc2UgQ0EXDTEwMDEwMTA4MzAwMFoXDTMw
+MTIzMTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaAFDnQm7dPKTe+07CKdupqns3vRr5Y
+MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQB5jwS9LsJUqzevwbstTFfJ
+TrsCQBjg8kn30zn2Yi0+ff92y1zfpzK3MSFfq9olKCKSpoKdwgLTZVXiHsO44X4d
+cIzo03knrnXX6wAQH0b/GXlbvQ9fEZaylTxMV7mO38UgIs9cWXdqjlsgAy37qOBT
+L5Dn2xUp2u/+QcbwyLOGP7/shriabGHlepclCQI6BxIor8gJz2zCxtovV90j7WL0
+8nF8wMwVv89hu38b92uORIQDamYDRTigiOYS5FPTirqoReA9lUdQ+hd3KaS1S/YE
+w7fmNEbkdCMg4hHAYnR0xW54Bp9bea2ANRJmdwUCz930q3XqPS8OJt/PZgOAmdYa
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1CRL.pem
new file mode 100644
index 0000000000..338d64cd37
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1CRL.pem
@@ -0,0 +1,16 @@
+-----BEGIN X509 CRL-----
+MIIChDCCAWwCAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNVBAMTDGRlbHRhQ1JMIENB
+MRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjBmMCACAQIXDTEwMDEwMTA4
+MzAwMFowDDAKBgNVHRUEAwoBATAgAgEEFw0xMDAxMDEwODMwMDBaMAwwCgYDVR0V
+BAMKAQYwIAIBBRcNMTAwMTAxMDgzMDAwWjAMMAoGA1UdFQQDCgEGoIGKMIGHMB8G
+A1UdIwQYMBaAFHcYI+V2hMgUlD+C0IHqdLHgpC8zMFgGA1UdLgRRME8wTaBLoEmk
+RzBFMQswCQYDVQQGEwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAx
+MTEVMBMGA1UEAxMMZGVsdGFDUkwgQ0ExMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEB
+CwUAA4IBAQCEUqY7TzVnZWYlyrtBszCIhhTKhr7tH5UHvoZkNs8lzeBMqtUDZvd6
+o0mB7WSv5R+t8tGleNhn4isudltqLAWZxxZNnht04o3YZTwKS/NRNAinBoQfZnmw
+abMmledsFuF2JrA3XYOZ5NWdlah8/MPUAKRoI0Dw7qxmLL/exsz5OAKh3qjXlzwJ
+Bdm4CYCO3DH58BQk6oJKVlqCY3ZsCuvtvjNHnLpkXAKRQ+t/OsHWssYkEVX5FizE
+WE6G6XMMcQtb2gN0QwzO8o3xyFGYyy1gkEuB+yzmqHqLYTlRZd5IvRxYYoqHbrce
+x7ROIMJEsNFw5k+b7qWYLo703GOsCxD0
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1deltaCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1deltaCRL.pem
new file mode 100644
index 0000000000..4c306accba
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA1deltaCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICWjCCAUICAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNVBAMTDGRlbHRhQ1JMIENB
+MRcNMTEwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjCBiDAgAgEDFw0xMDA2MDEw
+ODMwMDBaMAwwCgYDVR0VBAMKAQEwIAIBBBcNMTAwNjAxMDgzMDAwWjAMMAoGA1Ud
+FQQDCgEIMCACAQUXDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBATAgAgEGFw0x
+MDA2MDEwODMwMDBaMAwwCgYDVR0VBAMKAQigPjA8MB8GA1UdIwQYMBaAFHcYI+V2
+hMgUlD+C0IHqdLHgpC8zMA0GA1UdGwEB/wQDAgEBMAoGA1UdFAQDAgEFMA0GCSqG
+SIb3DQEBCwUAA4IBAQAFVo99MjLWWcc8kdu/qveAAPZgvgHBAQqOygCNbu4J704l
+Ab9wHTJoNvghxK7iGsCGd2O7l1ODdooPWNcY3NVkY2soZmevk5F19MQX7fr4HrLp
+Dtcdfbby1PG2TX0MttfwpGDh8yfO1SFjkclmoP8f1f8mrmulJcy/sXK+H478JHO1
+lycEzMsvgGj2HCZvRziR+g3nH2AVMra4r6u+oo1ctwcWWGRkhfuyeBBJWDMh3T61
+gIbdB+Atjs3QBscvjPdU+F5XyuaBLbwEBYJOoTeSKTxfDVeYnPFghHyenItJsmII
+5IPocdTk/6/RB0wtDlMQwjNUXxe0/3WoHVy8bUQZ
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2CRL.pem
new file mode 100644
index 0000000000..b4090dfee4
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2CRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICQDCCASgCAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNVBAMTDGRlbHRhQ1JMIENB
+MhcNMTAwNjAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAiMCACAQIXDTEwMDEwMTA4
+MzAwMFowDDAKBgNVHRUEAwoBAaCBijCBhzAfBgNVHSMEGDAWgBR82Pa+A0zOz7c/
+oRm7M6u11437xDBYBgNVHS4EUTBPME2gS6BJpEcwRTELMAkGA1UEBhMCVVMxHzAd
+BgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNVBAMTDGRlbHRhQ1JM
+IENBMjAKBgNVHRQEAwIBAjANBgkqhkiG9w0BAQsFAAOCAQEA57Gy4XXEzOgR+KG2
+Yc4w8HgmX79ERY3s082LNYuSwFrA3D7hoCa+tX8tuXbF6Kgb+wocIFROzk7r+ZIp
+PegSzJQcKWoVCQiuHUfBt3MVZLojeM4n8ThfMbPOnf+Si+V4YgEcBGcgKt/pxEnZ
+d1dJu+rB+TSyUk4QuJ5X2DJn4ne+2Wf6mzoZKakJp61aDD5QxysbN/52R9QR/wdg
+awyL5mtu/8U342t+4sFbLm7X/pyDcPkp9on2ORsKGIBGGr3QoHItIAZn2ghPsT6a
+5YYcJOUm/pZwBeKoZyQ+s9Lhon5HOWs5aE3KwFdS5vo1zpB2Ps9Sv4ud2+O135oG
+tuFQTA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2deltaCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2deltaCRL.pem
new file mode 100644
index 0000000000..d305bae0ab
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA2deltaCRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB8jCB2wIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMZGVsdGFDUkwgQ0Ey
+Fw0xMTAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMCIwIAIBAhcNMTAwMTAxMDgz
+MDAwWjAMMAoGA1UdFQQDCgEBoD4wPDAfBgNVHSMEGDAWgBR82Pa+A0zOz7c/oRm7
+M6u11437xDANBgNVHRsBAf8EAwIBATAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsF
+AAOCAQEAWX5v6H6qmSiro3ZgYkvIi4WDhAzCpjMNElzQ7rs+mPh/1B/2CSAv+B9Q
+RXHJvMYS0XEwfvTy3N5vAhY6QMNhPKJcepJHVmng0NMOBn3DMJJ7nobJKAA95ls8
+/BP+nNjVHoq7RnLivTxvXOijGGCJACg3st64CByuwcbNcJdEJkI0usFnLEoA8W9Z
+G47VSzeORnf3EmA4IZERhS7NY3+91CDRb8R0CO0u8sVVPPWMltdN0WYSnQA9D4oV
+hOEunai3vsrn7DVSsoTrIWz7zxgIgxk+6sfaWhGIKVLW34lIdA2geMWt446/maWg
+E/O9OWirLi1qY7bp8BcCUe9UL/cfOQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3CRL.pem
new file mode 100644
index 0000000000..084e49127f
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3CRL.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICHDCCAQQCAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNVBAMTDGRlbHRhQ1JMIENB
+MxcNMTAwMTAxMDgzMDAwWhcNMTAwNjAxMDgzMDAwWqCBijCBhzAfBgNVHSMEGDAW
+gBTvY9OoTrH532HiDcMFo5gY0pOZ5zBYBgNVHS4EUTBPME2gS6BJpEcwRTELMAkG
+A1UEBhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNV
+BAMTDGRlbHRhQ1JMIENBMzAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEA
+XB3lEAs1DWFKrU3BzflSTtmiCa5KzMZrXpDmqHt7+kWNjEMUS17TsvkrfGWOcEFJ
+9MzmGUqAuD9Z0q5kxVVNRuZhG8K9U+biCmMVFtKzxFGbz/vJkcKaroB/ukiqNQlv
+DTSKebUJJm5g0rc06LVGic+YgK2pcCwm4BsdmcCEYV3mlIhUOUA48Ww0WemFKPTw
+9A1V3URGpOzrMJYJOJff0IOVjdyGwSc+xHCtbJG4xV+/Qe1/9yYn+RqHQXUo0C7D
+GJNSr+OcpXX8urZQp4ZVQRz3OTs4eb2xRK1ZPj9Xhiv98iZwo38GaFGvMhOHv7gv
+C13eDAq4KnlQgz/wpxmHog==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3deltaCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3deltaCRL.pem
new file mode 100644
index 0000000000..db02c94369
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLCA3deltaCRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMZGVsdGFDUkwgQ0Ez
+Fw0xMDA2MDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoD4wPDAfBgNVHSMEGDAWgBTv
+Y9OoTrH532HiDcMFo5gY0pOZ5zANBgNVHRsBAf8EAwIBAjAKBgNVHRQEAwIBAzAN
+BgkqhkiG9w0BAQsFAAOCAQEAy7ylas55kqoznlqWS9cO6Q/EC7dPiZKF4Szp326L
+qCs4kd16Vbi3mhz7BP2iHSjO0AlaMnmGSYOlnzQEtuD6NlQB1RhuWH1kCWAaQPXU
+4K4nMJduHuGjopkIxnN8BGPfXGbeOJfl0FDQM84vkRCJ4Owq233JvEIDCEhdkYsO
+wQr+dUqPNkR1lz7fGtskqpe3aotkQ3DrS/1wuBRuTmXLKDZy63IdAe+TTp8yugnl
+9QEdYEXvMgLChLe57ZaOFVCE8349rkhikvnFWIfc1st2EsBrOaOwqFUrZReVg6qx
+wxDSf2FoINaLIX7ECkEBBmQh9SyEz8BXwaboI8z08ovRzg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLIndicatorNoBaseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLIndicatorNoBaseCACRL.pem
new file mode 100644
index 0000000000..781db0a18d
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/deltaCRLIndicatorNoBaseCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB3jCBxwIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMcZGVsdGFDUkxJbmRp
+Y2F0b3IgTm8gQmFzZSBDQRcNMTAwNTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqA+
+MDwwHwYDVR0jBBgwFoAU9Dh2Jauk4xzAyHWMjRNrYyO2ioEwDQYDVR0bAQH/BAMC
+AQEwCgYDVR0UBAMCAQUwDQYJKoZIhvcNAQELBQADggEBAJOY+1gmjxVv2D6HNyPt
+vKA7Gk7seNkgnSPoPR24Ao0znff3gjJGgz6r0TY7IIF+ddgjmu4l6BpkS2fN2Uow
+BCFEAD/0lK0RPtuyUCdbFiSHtNQlbpbxEK0iwDAw2YoYQZBP6qobz3IIjxIZjQou
+XlOIRoXE8Lg0QHFHQF58+Bs7Exk5kU8bwCalEL36OcGihMb9wXuuJTvSuXypU5v6
+kDwwrvxx06w9O2WYC8dqriObG8Uz04+Xt6alCmcj/sU2rop6BZMheZ8bKSHXCPWB
+FWIubsW25os4rHlxDz+DmXAcRCyIyrQxz9ERTDjPhKhAUPXz+baG38/oqA3bVMn4
+HKo=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint1CACRL.pem
new file mode 100644
index 0000000000..dc27f6b6fd
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint1CACRL.pem
@@ -0,0 +1,16 @@
+-----BEGIN X509 CRL-----
+MIICfTCCAWUCAQEwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHjAcBgNVBAsTFWRpc3RyaWJ1dGlv
+blBvaW50MSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAiMCACAQIX
+DTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaCBvjCBuzAfBgNVHSMEGDAWgBQR
+MHO9jXAogtJvz9I37c3rI5Hb7zCBiwYDVR0cAQH/BIGAMH6gfKB6pHgwdjELMAkG
+A1UEBhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHjAcBgNV
+BAsTFWRpc3RyaWJ1dGlvblBvaW50MSBDQTEmMCQGA1UEAxMdQ1JMMSBvZiBkaXN0
+cmlidXRpb25Qb2ludDEgQ0EwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEB
+ACrxG+l579by89QJva16Yro3XPJ9lXu/l8cgQpoaHZifIG9TnaWxb4WFwSBIbOqp
+rbQW7N580RJBH2SqiiUmCu6Acg2ryKfywGULkFFd0ZYMBrhtHQe7T0SJq0NFtMlZ
+A9Vgia3Tqhiam3c1oJeZnETcn35b5qLAmr+EaRpXDT4Mflqwub0kgwal6p9wmuH5
+vs4dc98l/Ub+J+ve8yVmMVq/0YSGv5Z2IjX2V9iWdjcZPnAC3BaOMvm40zy5cOWJ
+FaXii7M41MgR4d8ZMQn/UQGb2CMypm207QW3yNbuI7+/0y0vxJDo2k84ktw6sAda
+dQBSIAUmYp0Rsdtg9TwZE00=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint2CACRL.pem
new file mode 100644
index 0000000000..1ebde75c29
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/distributionPoint2CACRL.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICJTCCAQ0CAQEwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHjAcBgNVBAsTFWRpc3RyaWJ1dGlv
+blBvaW50MiBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAiMCACAQIX
+DTEwMDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaBnMGUwHwYDVR0jBBgwFoAURGzu
+229/605Jf3j+zeUYoOy7YGswNgYDVR0cAQH/BCwwKqAooSYwJAYDVQQDEx1DUkwx
+IG9mIGRpc3RyaWJ1dGlvblBvaW50MiBDQTAKBgNVHRQEAwIBATANBgkqhkiG9w0B
+AQsFAAOCAQEAD560RltKzGwM+LefEKN9n+UE6uNAoPwiNSYPGe9Qcu9WXsG11CqZ
+O1saNKTu0+bMx11WU3qRDyGpWZidaW0/x60RcSMR/X/RGoZw2hlixluvHpIBQwYf
+H2V2PE+OjNIeXBF9uEAV5KuBRb/Yre7GlCoXJM1j9WZRCHKwVYZ2xNog9R8STNs5
+fw4kynvydxQ6U8KjUxJeBmb6PiAf64Mcf9AXUCjakwAKJgw2zptKV75QrEEwpnVj
+sv7A5HqoMS7mLwPV2dznH+rHn/0IJp1FuS9YNs4L7oTyKZYlriy7U5pmsHHajGIc
+6g5+w/GiX51Emsi7RXjAvfpu/9MisG29PQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA1CRL.pem
new file mode 100644
index 0000000000..c9de28ecb9
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA1CRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB9zCB4AIBATANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEYMBYGA1UEAxMPaW5kaXJlY3RDUkwg
+Q0ExFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMCIwIAIBAhcNMTAwMTAx
+MDgzMDAwWjAMMAoGA1UdFQQDCgEBoEAwPjAfBgNVHSMEGDAWgBQl+K/8r7apGht5
+S9vLZCyLS7EVzTAPBgNVHRwBAf8EBTADhAH/MAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQALqiVAlWG4BlkRVLdCVDqUtfpcaK8JLzEqoQUm4fS+Y+mdf9uA
+Q8+l8aQmcGeh/Gkufzp4bwsxkkxL81qTvuvDm4UV5q4TYz3aaWtzE/ewNWzLyLjA
+FQafw0u0ZTdXs5Z7R03DlwrGH27ZmMqjue8uV060HNTVUzWJjnSwxZ2FZ1gY6Rbe
+F0cmOk3ym2/1h61sWgBZRLG5vIGZkJe/An/pJyGL68bKTnyaPeYdKm0knt/yGGbo
+24bdwhzVLbzPIq6n8JCNWhO5r9pcmhR+XdrgddIpS341f9S41j82WGfwLCnc0pBX
+6PxVxMdDQ1qLQAbzCU3OCE98HtTv7IpDCUdi
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3CRL.pem
new file mode 100644
index 0000000000..607f7bf989
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3CRL.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICMjCCARoCAQEwDQYJKoZIhvcNAQELBQAwSDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExGDAWBgNVBAsTD2luZGlyZWN0Q1JM
+IENBMxcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqCBnTCBmjAfBgNVHSME
+GDAWgBRIk1R9xG0w/y1XRXEk30wFn0oALTBrBgNVHRwBAf8EYTBfoF2gW6RZMFcx
+CzAJBgNVBAYTAlVTMR8wHQYDVQQKExZUZXN0IENlcnRpZmljYXRlcyAyMDExMRgw
+FgYDVQQLEw9pbmRpcmVjdENSTCBDQTMxDTALBgNVBAMTBENSTDEwCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBACvzWPSm982N1bxs5RW+yTNbWoZ1NBGEvAUX
+B80kE0PTfchM1HbkPh4SkkVarj2/alnN4E7cMWzlq1qhc76WR4ApjPZmCW4zlw1e
+a229Eh3s15IX+CZcBEza5mQIHc5mnn2v80MPJCS7W53lvPlrD3T85bv3w3uX8UZi
+AkR4wCC12Rbnm4fEtgkIxuB7FrKb0SWf6ygBn+Tcv27CGSF9YBhVsXEyGAA8qt9N
+1eBJrRGBu1xG6rYEuW5OQgGhZgV3QhxEqUxhatPtYT8bcR07S3PrGx9Y+Mh+o9Mw
+LuHM6OiDiRdd2nRUmWWpZGOgdTKEJ0eFrqOnxHPPF3bhhiJs0hE=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3cRLIssuerCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3cRLIssuerCRL.pem
new file mode 100644
index 0000000000..a366a243ba
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA3cRLIssuerCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICajCCAVICAQEwDQYJKoZIhvcNAQELBQAwUjELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExIjAgBgNVBAsTGWluZGlyZWN0Q1JM
+IENBMyBjUkxJc3N1ZXIXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqggcsw
+gcgwHwYDVR0jBBgwFoAUkdE5mMnvT1RlihhSLXwSEgpsd40wgZgGA1UdHAEB/wSB
+jTCBiqCBhKCBgaR/MH0xCzAJBgNVBAYTAlVTMR8wHQYDVQQKExZUZXN0IENlcnRp
+ZmljYXRlcyAyMDExMSIwIAYDVQQLExlpbmRpcmVjdENSTCBDQTMgY1JMSXNzdWVy
+MSkwJwYDVQQDEyBpbmRpcmVjdCBDUkwgZm9yIGluZGlyZWN0Q1JMIENBM4QB/zAK
+BgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEANA7Z476bqcNnf7wWi2LE7Gws
+3Nz3U+G05Yp4xMLc4gYoKj/W+mjvsbXzJ2sjU8D2e3qHu3p0lIsFP+ZXXhvi4CEv
+3lIMQQE8/pPGxtqGDSnKRstdZPq2JvqisZFieChKH469G7yrHNMKD6C4MkQs27gj
+3cybk3G5fEGmpE5xVwHb1m2P/wD3vzkQVU6+T+RD8FPlZbqJRZEdIg/RSBQNXjbY
+ZIvKCkfl6w63f39NgMYSsfUM2g4jiv8PAoAR/RmDHgvylCoc8E2KDWiTFss/502e
+hhNTwMhEGS+Aze381vRThygIpqw29m4My844a8XVX2jZ8y6GGoiwqdby8U4wwg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA4cRLIssuerCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA4cRLIssuerCRL.pem
new file mode 100644
index 0000000000..596762cdbb
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA4cRLIssuerCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICajCCAVICAQEwDQYJKoZIhvcNAQELBQAwUjELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExIjAgBgNVBAsTGWluZGlyZWN0Q1JM
+IENBNCBjUkxJc3N1ZXIXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqggcsw
+gcgwHwYDVR0jBBgwFoAU8wjrbbnFoBCk2gRF/696R68RwLkwgZgGA1UdHAEB/wSB
+jTCBiqCBhKCBgaR/MH0xCzAJBgNVBAYTAlVTMR8wHQYDVQQKExZUZXN0IENlcnRp
+ZmljYXRlcyAyMDExMSIwIAYDVQQLExlpbmRpcmVjdENSTCBDQTQgY1JMSXNzdWVy
+MSkwJwYDVQQDEyBpbmRpcmVjdCBDUkwgZm9yIGluZGlyZWN0Q1JMIENBNIQB/zAK
+BgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAKRPyrIpC9HqbA9TytL4xuspW
+lO0Ihz0TyIs8bWEMPSanD0tdGsO8v1QQrv/XSVeAPiDcPvwFtX47TpbPJxJQBV5/
+AfGEAJ/o5Jl9ah2yuA3Qd1UZkL85V/XJgnqxpqJeLRQoQ3PeT0rlnQUM2fru3LrF
+AZn9lpxyqfqPsNbcDwwf0dbtGOvwUC2KTkXueizW0VEFgxRmRcielTglQXSV+Y1Y
+/MLqly+BHpWOko7BnfR6Ukfod6O8vyPwhUm0VW7AxPNH/qbqcpJjMnwCN8Bzp5LL
+UfQ6pkmCRWESbba14wXPuhoPM3OhzBzpGrBMeRpml96Tf3Q6xho0V/QmOaAs8g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA5CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA5CRL.pem
new file mode 100644
index 0000000000..fdab0bd2f1
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/indirectCRLCA5CRL.pem
@@ -0,0 +1,35 @@
+-----BEGIN X509 CRL-----
+MIIGJTCCBQ0CAQEwDQYJKoZIhvcNAQELBQAwSDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExGDAWBgNVBAsTD2luZGlyZWN0Q1JM
+IENBNRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjCCAt4wIAIBARcNMTAw
+MTAxMDgzMDAwWjAMMAoGA1UdFQQDCgEBMHoCAQIXDTEwMDEwMTA4MzAwMFowZjAK
+BgNVHRUEAwoBATBYBgNVHR0BAf8ETjBMpEowSDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExGDAWBgNVBAMTD2luZGlyZWN0Q1JM
+IENBNjAgAgEDFw0xMDAxMDEwODMwMDBaMAwwCgYDVR0VBAMKAQEwIAIBBBcNMTAw
+MTAxMDgzMDAwWjAMMAoGA1UdFQQDCgEBMHoCAQUXDTEwMDEwMTA4MzAwMFowZjAK
+BgNVHRUEAwoBATBYBgNVHR0BAf8ETjBMpEowSDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExGDAWBgNVBAMTD2luZGlyZWN0Q1JM
+IENBNzAgAgEGFw0xMDAxMDEwODMwMDBaMAwwCgYDVR0VBAMKAQEwIAIBBxcNMTAw
+MTAxMDgzMDAwWjAMMAoGA1UdFQQDCgEBMHoCAQgXDTEwMDEwMTA4MzAwMFowZjAK
+BgNVHRUEAwoBATBYBgNVHR0BAf8ETjBMpEowSDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExGDAWBgNVBAMTD2luZGlyZWN0Q1JM
+IENBNjAgAgEJFw0xMDAxMDEwODMwMDBaMAwwCgYDVR0VBAMKAQEwegIBChcNMTAw
+MTAxMDgzMDAwWjBmMAoGA1UdFQQDCgEBMFgGA1UdHQEB/wROMEykSjBIMQswCQYD
+VQQGEwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEYMBYGA1UE
+AxMPaW5kaXJlY3RDUkwgQ0E1MCACAQsXDTEwMDEwMTA4MzAwMFowDDAKBgNVHRUE
+AwoBAaCCAa0wggGpMB8GA1UdIwQYMBaAFIH3qr1IdVmAsM/fIxid2JNGghazMIIB
+eAYDVR0cAQH/BIIBbDCCAWigggFhoIIBXaR1MHMxCzAJBgNVBAYTAlVTMR8wHQYD
+VQQKExZUZXN0IENlcnRpZmljYXRlcyAyMDExMRgwFgYDVQQLEw9pbmRpcmVjdENS
+TCBDQTUxKTAnBgNVBAMTIGluZGlyZWN0IENSTCBmb3IgaW5kaXJlY3RDUkwgQ0E2
+pHUwczELMAkGA1UEBhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIw
+MTExGDAWBgNVBAsTD2luZGlyZWN0Q1JMIENBNTEpMCcGA1UEAxMgaW5kaXJlY3Qg
+Q1JMIGZvciBpbmRpcmVjdENSTCBDQTekbTBrMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEYMBYGA1UECxMPaW5kaXJlY3RDUkwg
+Q0E1MSEwHwYDVQQDExhDUkwxIGZvciBpbmRpcmVjdENSTCBDQTWEAf8wCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAD511WYLf3F/LVZg+HVRImOIHZrYvfUb
+QGXr1qzVVk86bLrZqrPNXo6+dCj/pZJrP35VxvrcapftonBK2FucTiMzWyg5WXI0
+lh3i/7BOlopDezS1m0T/vPhEYJM4ymyhbEY7vjLQWeTWEvcQIW0QGfVRpFzMzkwe
+FcIq6QleFY3hfOWT72oAdZHiweeNPc3/XMPFFkZ/3Tp52Mt1OOq49Xk8HneV/F06
+tZGefG3DrvQbkqBHF3p2qjWrwtNUHlqxJ5uCYf0UKMtwKp3KLTJgphrCOApaPapD
+Dixk3loTgU9P/PO5XAP8s+tTdwjYlYPDan/Uxi1PpwdxUZ/ghuFaW9Q=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy0CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy0CACRL.pem
new file mode 100644
index 0000000000..f6f50228e7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy0CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUaW5oaWJpdEFueVBv
+bGljeTAgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFBigoHpq/2qdhYIkzcMmhfi/ijcGMAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQB+ePMn32XQoMZZJrXrnElaigAgYnqRtRguHjnlJXmaftw3lk++
+PSQPSKUxKtuvbuczbt+jMJhTngohIIfbPfEYrSEe6kolUODSJK4Vdp+ja2jfD9ba
+VrmoHNH5JOLCm4HqaV6Cba3rKH8F+0rlw49q6YTS7otMBaaPgfVPMtketW2okiNK
+YBVOVSdC4XuxuZQZE3rz8u+T9QcOm12eMNJU/pXhFjOaagtqU1xtqEBO3LOsbMym
+uTRGJO8VoWdYNxe/jedXiAMASJlx4BQo0hJDm16wlubz4S0Ac9gHYNrFD6laVDph
+B5eNCGxHDSJkxhNtbW9ztHgQcT18pxOV4mHy
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1CACRL.pem
new file mode 100644
index 0000000000..ad1941263c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUaW5oaWJpdEFueVBv
+bGljeTEgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFNimnieXEcOO1Bkh1yC8nO2he/LTMAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQBM2rRjH0dKX4Ay7xIJONSV1tyQoFaznksb2FKUgatoMTtF/Tbx
+WqANV/RsKCYjHc7wAlyn0LCfxyIvIGSLQTUk3+Dyk0yESy/Cz0R93eCeI2y+MZ7j
+BHz+jCEgOeV4ilL0Y2hTmHOQGBkrFfa/tWA2tAejAZmnozFhgQcfenUMXWc5uU3N
+CMS7n67+hUUE3kQ5qw5L3GtxUytXOdG4CUa96yPcMKJgJ1W4fk7FkAAGt2IM4lDM
++c3gS0+TfewBtGFPfu0kDt+0gLX/SdGGJhBnYCuoAicXhshNmhOjchP3Auo6pZHP
+0uto4/XnOnHKUanX+Cg7D++JqCa1FzShSjUn
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA1CRL.pem
new file mode 100644
index 0000000000..cc49e37c54
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYaW5oaWJpdEFueVBv
+bGljeTEgc3ViQ0ExFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBR0oNVY2StT0iuwzV1xxqG/Q6fIFTAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAcdszKmraUaBp3w473eShNoALBZ1aj31fBfibxZPvtlwG
+BECryi8bmOwXZwKUE8Pr1MeQVtHYgDJhBscq9F8scmBwbmp/kRnBdN9Dgq7fe9Yd
+lke45ULwXOLkX+MdbWcNMX0OILkySpw+zpIDX1HCNeL0QKz+bXwouqgAnpj1IIFL
+yx56Vl/AGQ7S0jkR1emdZJudenGiCKkDqImjORjteSO852f04/83n6iNYDLcDzki
+uxyd+n00PMhqjiG44a5o+rAfOiJBbxv3eDMNQo7mhnTHUZnAq+3bSSQcJqCQBTNC
+zLna0kwa38h1WeQWbekOJGO2kiFd1pTss+mPmvpCBA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA2CRL.pem
new file mode 100644
index 0000000000..846500d7af
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYaW5oaWJpdEFueVBv
+bGljeTEgc3ViQ0EyFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBSMBdzffmTbYr7bS1FkjGpm2FyjozAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAsrP3R/bTvBLXn8NE+Qcr0Cr7ETparxT+Grm80Py+H77E
+UR6eT9/tvIJYTNYzpw7zEUB4vYeVqMJCZoPtP26Lkv30BLAkWEQ/kaM9720aG1pH
+sGUCpSwpnZkZeEhUW//IvCb9Ubf/aMAE+NpvLnYHBB2hQdckW8hCrMubc6jfQL2K
+DTEhwuFs8p81I2OXuA//qk9PrQlnI0dsFenmRCbSpZj3CzIjwuPbv4J2JKthNgb9
+xuFT97kzKFYa77JP+Skcicva4o0A94WVkCtcAv8FrHPNNapflzcE6edP5Y5R97SK
+yflBco+Kk8eEzkWleh3wLh04+CEoj9JYMEA+1ICv8w==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCAIAP5CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCAIAP5CRL.pem
new file mode 100644
index 0000000000..7ebae31c23
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subCAIAP5CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbaW5oaWJpdEFueVBv
+bGljeTEgc3ViQ0FJQVA1Fw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBSJBFR0BmCz9wBuoGGOFfu+UgIGJjAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEAGOaiustpHjlRoLea0ROpIk9v5o+dhhyD281DHP68
+cahcHEEDBsFZ+08KXnho7vLW55E2mnOZpjD+YAw5M1UpuZmKHgHTg14FfZhrZjco
+LjkcUC8hlCOc2ZfIpv23+Sh4dtR/iglXo5KqDiBbii0VPndtZ0M0XgTfLe+3vp1l
+ofMF2I3jkMfQSgyFMihCzguRCgjr2g8TAcX1KxaRyQD5NtelpY3f7juQo7RD3AdF
+hiZdjnCY6qtgQ/9ju/6dkWl2vNOVWQBLJ1aieo2o1UT5PiJXoMlKBbuYZpecyNRa
+bdRFkCoSybqi+qAZ0S39CBZQGuU7Une7xne9cXK+M05J8w==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subsubCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subsubCA2CRL.pem
new file mode 100644
index 0000000000..669df318fe
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy1subsubCA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbaW5oaWJpdEFueVBv
+bGljeTEgc3Vic3ViQ0EyFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBQRfcCcinb5STP3pIFLjjB1lTvoiDAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEArE0ESZ1xjjGSyPpJ2Ru9aEVl6UtjKC1vctLfDCZD
+eLTLipnD0R6vsDscUna4h22okIeP9AEeLEOvpX5Oi0bVNhU0w6O2xP0Tc/Cfuole
+HgH4ZUJcKob6/2DpXLSayUNNL1zY8I/OS+lfsetIqOhp78xLiR0ghyeOagnkH99r
+a9eT9iCCUe/XO/N0gMOjsPkh5qOGC6gg9/XwsECc1BYf3HGzU10IC/C4rrxgrwQx
+YmpA+WDMQpEmDFXxect/9gARsgny4irJ0++2rFI1WdWKFEmMkO/l9B6GRYCjNQJX
+cS0JH8PWhv3DjvUoEeBIFDDJJwquskVZWwP6TbkfEqut+A==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5CACRL.pem
new file mode 100644
index 0000000000..7c053d1c8a
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBxzCBsAIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEdMBsGA1UEAxMUaW5oaWJpdEFueVBv
+bGljeTUgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8GA1Ud
+IwQYMBaAFMAmgedp1p188L3VnapTDmX5nMsKMAoGA1UdFAQDAgEBMA0GCSqGSIb3
+DQEBCwUAA4IBAQCXIcfQLBFOcgt5m7Q9laH1FvfjTwZ1s2tC3d3NzBGRJRqo4lFB
+sb3PvwFL96EwopImZofRByNNmtdA1E6FS5dyiaDjOD8u9f02ZnL3PpAkuTTMyA+l
+iGSo7ZEvwYMPjWdtiN0SGLlpoVbTbAcUx4zjHOby1H6TiZcexSrf6ndRtYzR9I/0
+3jzFnqPcSIVQeB/gSrSWMj9j1gYO/UQGf6H8/YXadnYzoh7+C2lbwk27mpb0d8sc
+EkGJPa0iimLbKCmprPG5iHE0y6yUltjSia8fsubGfzNkMaJWsFepd/HMoXWC68hS
+0fI5vvDTIzHqFMAF6cZ8ddHMNbFA4XDD24FW
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subCACRL.pem
new file mode 100644
index 0000000000..5c6e19906c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXaW5oaWJpdEFueVBv
+bGljeTUgc3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFGyZqbYF675wSTZMWJoi6BSIhS/bMAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQCfcJ8e+tup8Fr+n+Wg9FB/0V86blpBUsRvV6juNBKzuyuz
+b4iY4BZM1flYt9OF043DVHi7xN7BcQ7YGBal/day/v9GisD3Ia8qYdtyRCb0y70V
+6jiVJ1FVolO5New51aMcNAzmdCvmqvsj2KBm5y1zJmBwF+MeKrOk23kL4jOpX06y
+Yjfbs1xCbub01wBmE/t+rL/FZdFamC+uh3XfBUw6vCrDNvdtN31n522EV8I3ifru
+ByIJ7RgtjgeIDfCOND3TZ3i+OTEcn4XrMW+Y3BYiRKhLEpxrHkxNdgOK1ouC0HuI
+QlE/DkaDnw9rj6NnI9wlZTMCbmsSkn28VrkArw7y
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subsubCACRL.pem
new file mode 100644
index 0000000000..793cf1291a
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitAnyPolicy5subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMaaW5oaWJpdEFueVBv
+bGljeTUgc3Vic3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFDHhP/xiboBlzal5EAArbola6AXDMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQBBNQhxoz5IzMcomKNxeSnmWdgwCCbynAR5YVIt4vqS
+zbN+H6DPt7UbaqhpgJTAedphGYOiVm+LYOehKXMYp6ZF2iHFC7yZ4/tbozh3hqY5
+5G1Zf2c2cXsCI9cI+uXB3jk0h1RgxaBRoAST6PS8HQJvUXM0T3QyApj2ELLjlvHx
++OrJ7XfsmOzliH8pfVdnKGzp2piSiJhdiiV/egX23AXvvQq5k3Tb0oUWo54BAso3
+2eXyypSbPTbxQXVqq4bjsVs/F7h0xgFRlwK4YPbmcpZqM1TXl0f8l/KqnFV+ZOmL
+aXghz7oTvQoFmJodMyzgWtvR4LRWnVj2v53K6AO/Jvrx
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0CACRL.pem
new file mode 100644
index 0000000000..c709a56df7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYaW5oaWJpdFBvbGlj
+eU1hcHBpbmcwIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBRYNyYHkYRgrO72QD6lK/z/lx2d2zAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAvS17Fvl0x0lQNKsr9O7mk57ThTYOMkhSLLVLYCrox6vO
+B/wLW2wLJKrJ//n/VFqEGncKHNgwyF0tiBNhm9qEGp+LSbKwN/NT/ZffUmuer74d
+iUIQr7fvQYATGGY8f8a3GlQ451Wnw4LTOpfTfIOdH611ql5bQg9zsZsoamXa0WZ+
+Q9WLA9rT2AAQDWE+6jhD6PfhMZlfrOwfQ0oZJX+EDkiQ0N1BAhURxMxzflrWeedF
+nRHOyZrlIzqZ9rqaIaTcPkn3Q90fxREys2AgX59Fyp76iT3lsYpPWUytnt7e0NpY
+sZTGdW5W8/vh1jYAMhuBJNzTfk0Ilf71Le+qxQVFQA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0subCACRL.pem
new file mode 100644
index 0000000000..50f92f4a14
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping0subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbaW5oaWJpdFBvbGlj
+eU1hcHBpbmcwIHN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBT/tHNiUo1cljpakK4avLg8eYFjHjAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEArr+kgBiRhrD9A0eGhC60oEuT+oe4x7jNWNet8W+g
+U6eESV36XCGgh37RfZtL6k40uiXm+WNM5Tir3iLaoUVR675FIWTn8deelq410jkk
+RTbEz8ikqYH/MGilEhLEfaYteQu8kqGETlDmFbmcjriRWulMGVOc7yKMIrKGRKWY
+oZXN+MB4zjkepwlJtef6ZtwNa+QkYENfLSu0fNu+MU+aqnwyLqsqNqV6paPViltB
+c47TqfXNtm18NtKDYjXdPgiLfmk0qZ+WSQK9mz2v2NSsHq7G8IeOYJ5BuaXDs3df
+fyZrzQxOFaaRNLor0m5T8HKIM4HtHVuLGioqQRGLyX5zUA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12CACRL.pem
new file mode 100644
index 0000000000..ec32a575b2
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMcaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxMiBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAv
+MC0wHwYDVR0jBBgwFoAUTWd+jd05Ga/oJt4OATR4sXUQ2qQwCgYDVR0UBAMCAQEw
+DQYJKoZIhvcNAQELBQADggEBAOTAmNbgjGjQ7urj0qwWnSMCHeyF9To1md3H2IWh
+CNZaepq/e7ALmIDr7viy2FfyNnmBi0SWz4b/3ddI+NhylyuhBX7b+hHIBcAbyuym
+ZprJeuNjk53T2KoUGrOUnRGAoUKY8I1mNrXb2oQ5+keKUevF1G4OYsjoH2i/YU/p
+xf9xMwd4fKjRZuIS62MMJBXOQgWPXu3q1K2U12M1EHJ+Uzm0vgYf54vL35Zczo1T
+42ue5Wkt2tFgiQlN5betiQhuXPSNoEcX54l3oRfo/QS2cFKzaQEYFrS4Khdy590X
+16eGQeXouMpeCARjGbBeUoVWa/qFm+40nOXtBftQOtUuGJc=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCACRL.pem
new file mode 100644
index 0000000000..8313d770c7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0jCBuwIBATANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEoMCYGA1UEAxMfaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxMiBzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAw
+WqAvMC0wHwYDVR0jBBgwFoAUqiaUHWQPfgW8XWCNB1f8cJVmbOcwCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBAGhzR1y9MeY8/io6ssFZCHWXI8r8OoPogUgA
++Zmv2YJAGwg2FY/ID9nYmyntsT1bsAfzPubQJJGsg6+izEwcjNGaq9S8W2doUJ/5
+LQVpPBYydzpRm9CkW+YlpxTdYxlXLJOlZOxQbAob7dUdViUgbu3bVQq0oMlgjz3z
+uMwHv4yp4xOD45CQbwALHVAoVkayZ6ESltquwQBSOaRATkbTRl7BdNcssrh9TTMS
+YYhcnWHQd4e1KWdJLb8ZSgYpAAoLLV+4QSR3B64O4vy95xwcG71puEs/RLDgW7MY
+pEnbOsL1TDq7ZjYfAHyxFXZKe7XEFknnu7A5cNjoSr65szamIn0=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCAIPM5CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCAIPM5CRL.pem
new file mode 100644
index 0000000000..3d86355fa7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subCAIPM5CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1jCBvwIBATANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEsMCoGA1UEAxMjaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxMiBzdWJDQUlQTTUXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4
+MzAwMFqgLzAtMB8GA1UdIwQYMBaAFB0Ez3YnB48iO8L0gi7u5t0TgHtTMAoGA1Ud
+FAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQCT97ZZ9/3xeVKS7ylodjmyfxLqZ+7V
+iezI4cQFmH7cWThgfMefgj1664LrHOuiY/4bhvk1LHQj1c5pFbUYLc5hprEiv3dn
+OJejWo7PxTY47hkXIntlElUyYb/mxUPxiklQ7FEbE7RFSOTi5MZNrHgd+JITUa6x
+jPfDI0z/GO/Jo4RPZos2Iu1hVLN++sU8iMVMe7/sIoOrNw/lwudUfo+cZEKWi7xv
++1ICLtnK0XoPBTxNzb/i8cOZrjggiKole9mFEAZrs5P5dfytRTVFje+d4Aj6lYr6
+4smUCABSDWhLcyI2OLIt5taw1BigwfOsGvjMsRVgRuF/3U3LRHf+8o1M
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCACRL.pem
new file mode 100644
index 0000000000..4c8450f3b7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1TCBvgIBATANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTErMCkGA1UEAxMiaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxMiBzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgz
+MDAwWqAvMC0wHwYDVR0jBBgwFoAU14BcE4uOQXa6CrVzceijQIB0DtEwCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAB8d26fH9sOi6DPVWkJSNU1UltmljVsq
+Z9FBaQQxT+XSQDuAxW3VxeL55+/62jWO/O8/xvfw4egnAoTjtDfOrHFCEk7AlIgX
+vdGeXe7l4sHgbaq6l/z4EDsQU7SoukhtrjUVUTz7ksLjJwraVbBc8Kun/Umpj2sc
+ZEFrn/PMyibfXkeJ5aWTosLuEyKBag/Ln7hhl4nN6LDnafj+sxvhIlPGKKE1B66S
+h+wbhxZ6QvqOGfdYlcjRwXpdRPiF2/DJApIjF3eV7CkMM8tMo0myD+xQWwjPkNPw
+29n2FmWxfSmGBhbRkJ/nPGid50jCG/1UOrtN9+pQpRS3Tpky/zFtkvo=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCAIPM5CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCAIPM5CRL.pem
new file mode 100644
index 0000000000..2ed760a1e5
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P12subsubCAIPM5CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2TCBwgIBATANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEvMC0GA1UEAxMmaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxMiBzdWJzdWJDQUlQTTUXDTEwMDEwMTA4MzAwMFoXDTMwMTIz
+MTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaAFBKHGzVn8LyhoDa6FagpGe0am1twMAoG
+A1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBRQeh+mh86ONreRF9oNGE+z0lr
+y1ZYBiri/f8kk7y1GbwNB6LG+M8Fve7pe8pvtawSMfGnEbaHqdOf1jzSeOQXvSBb
+htuZ+DO9kOVDRyysBLNDWTSgA7BC/MI0JwrHnUMq6twutmQ0aPe0hHZu3DdydeRt
+ncUQ6qa+dNiZ2RJCpcXwKcGPLJnafDpICui8VPRJKgj4bcdtpFICoCmnB3iqbLKe
+9s2XyNtHxfJPOW4HSASB82rWcTzNA6Px0FwXm+8TKpkopS1dlZ6cd/nYhJCj1i26
+wxRDAx634CAzhWoGaYtrE2P5epcOEnh4G49ybfPmua8RWxTyi5CvhBhtrtXp
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1CACRL.pem
new file mode 100644
index 0000000000..f231fe784a
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBS+tp29KX8aodmL4aSAaIMorUrwATAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEAUv+vJlKK7TKlyO/T/yrf26BwpHa6dJHReqjLh6e/
+iXSXPSDXvuDrj+uNAIL4o8s8X5y7h5+ivYEDyZi2lnrCsj75+IuJIBfeHnfdeCo5
+rsa2Hml6bhJX0OuZRkMlg1qDMYlN3EEqcpobXWd/TfL3RB+vw/V7WwC/F5vx5UkT
+mH0jpI0glDOOIaQIDhgXerdEMuZ4FpSdAiUtj6icPYmbaGMY+We8X07ztyv2RQsK
+frTxkyAHRM8fC79LlQzzCvTPcV9wkwKteKMY6ZzWsOfp1B9DAyK6wq2Lp+TqbJqh
+pyL/lPhKASzGVegUqAOczdo0rvNDCVIPu0gCk5PgjcpieA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subCACRL.pem
new file mode 100644
index 0000000000..3730e7c738
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0TCBugIBATANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEnMCUGA1UEAxMeaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxIHN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBa
+oC8wLTAfBgNVHSMEGDAWgBTzzQc/gzDTxwJi2ubKbAGlsbaAyzAKBgNVHRQEAwIB
+ATANBgkqhkiG9w0BAQsFAAOCAQEAAuGpcOqakKHpoO5Y+E7QAQnB1fmAm4smN7eu
+RNXIdrZaVd24C1BbFzYAnjdewBVYT4adCdnslaNe4tqpq3Chh/YtmUe152/GTiXF
+MVbo5FRZhjSvK8VTVEzvSZ21b3oiqIv5d4P47XmhVfo0GtTv7Rg+x+ay8dGUgni1
+D153LEBh9beouesqqxn/8uFfxYpqmxFrS8vLdL9kxpeaFX32bM0eSOhA3lg4oCfm
+j28x6yL57beJMHjFZMN5vAXTZHZKeJS1QXak2Dt21G3VKPyq3v7iY0GDgLqQGsIp
+vPsv+nuvwdTjcQPwsMIQjZBrq2woAYvlF5hx8ofqoLNW6/oV1g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subsubCACRL.pem
new file mode 100644
index 0000000000..6bb1b2a960
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping1P1subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1DCBvQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEqMCgGA1UEAxMhaW5oaWJpdFBvbGlj
+eU1hcHBpbmcxIFAxIHN1YnN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMw
+MDBaoC8wLTAfBgNVHSMEGDAWgBQ+RXSii9LxVoxGAWZ4cCTGIsEDnjAKBgNVHRQE
+AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAdMziQBhDzdFRF40rOtd55OD5MPOXWPRb
+5i6KUQcwxrHZ6xZibEhM/eHGtHW89pL4Jjzrwbp+SXz/OzJ6yU9Cf3PQsP3a7l87
+J/EY+KL++6g5V58wlaXZYOvO8v5WTSFGP6NUvg8Nq2SChq3KqVvKxp/MrFSckP74
+gd2jepabJyTeXajSMManT+wxxTKG8WKMQtiQdXclZmEgaVYgxKVgIJudF46yLEh6
+gVwhKAR8xdIBr/mztrcM+aQKvdxtz3aHuKNwm+lo0tSjxB7UojZvIMdd7fuc0V1E
+PEVJDd2+Eej5s071zlgMeaahFbVeBNgaQy5rURdHxtyMZukFdCW5aQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5CACRL.pem
new file mode 100644
index 0000000000..68d33d924f
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYaW5oaWJpdFBvbGlj
+eU1hcHBpbmc1IENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBTbgAe5YizFw/3zQ+JmUSW72/QczTAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEANZI64pJVPbGyUy9hrPD2bO0EkxlY3aJHxDko6PaPdQ86
+dFjmX8tTCD0vmm8Hox4bI8fZHbjMDqhWxLU8NtjNJLSZX5IY7SJaaacDGaRd6laP
+05hB5MTLcEKBxH5FIetoK93e8mf+rMVRG4kCmn/UX4notzBcX0x0qKoWd2v9v2QH
+Gx7Gr6Ouae8wubYiu7aR9fCYRIcllEZVFRQ9f0bB5o4NANAUM4uq7ZrrqSRauqN/
+iNxCEeKSVnItuZnAZXpazNmXwSCdWPiRSl/77tThqoBhGKsgOvNbwJaTKJIuJ8HX
+5HgiQiSaz6Y5GySbA6rFemmW6X6o49/CiJr8cI+fKA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subCACRL.pem
new file mode 100644
index 0000000000..7925d0d1f2
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEkMCIGA1UEAxMbaW5oaWJpdFBvbGlj
+eU1hcHBpbmc1IHN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8w
+LTAfBgNVHSMEGDAWgBTY7G2+t2/KE2PKJ8ycW6JpNrbyaDAKBgNVHRQEAwIBATAN
+BgkqhkiG9w0BAQsFAAOCAQEAOYCNoa/mt1m/IQNy9kCVeCItblOzMyiCcng/IMCd
+RQ9q7kAa/nPj/zINqGAM4GUY4yB5wHm5zVKPL/AxC4adae2Xg5o2XqJ9rRI9bSgJ
+s48iHWbFp8mU2H5Wbn/hVKSWWCi6XzP1N9QwsFJa/5nsgRDzp73VHarqIPUBahtA
+mYLPo0bIg77oHPsXYmEI+aufY88+IMtVr4iFIW3ifEQu/XbmfwNjQLopIHBn3E0+
+gyD5XDJeF5f5C3FG9vQ/3DSgrdN2DLzWHr3/dWNIkRWhVxqimffMjYUkuxi4bKQ0
++30q3zclNs0lOr240CPBkg6Y39n0Zo7ihxBoS5INvbTi4g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubCACRL.pem
new file mode 100644
index 0000000000..2fb83ef408
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0TCBugIBATANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEnMCUGA1UEAxMeaW5oaWJpdFBvbGlj
+eU1hcHBpbmc1IHN1YnN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBa
+oC8wLTAfBgNVHSMEGDAWgBQ1p9ThS3ROVahxtEJ/Mv4EGskBuDAKBgNVHRQEAwIB
+ATANBgkqhkiG9w0BAQsFAAOCAQEAbayhlH01G0sqNxiiUyC8qPsdhUF3mHVEhoqz
+2SOwTTDzqCTLyqftFnZPAJ9fbG/FN3Denqr2ouh1Rl2mPEG3KmBA/w6gRrTzxmS0
+pC8UsBWdRvRebGZ29WJEjgslUz/r9BbSlwabF1dsAssvmv9xPxFBql4uNrLOEfap
+M9Ldo4y1eiBWd5xNTYp2zu+oBOAgywJggc7xepoUhwcPCTSrcAqmsQNLBoMYcf84
+nzm8rJ89cTqyPvpLxKjjgLdquVevhCcIG9HSCmAbb1z8SKhWaaBjRSoLmAo7845M
+VoDabAd0zNq9DEwb9WHB0zZldJ+u4LJtAAEpdl1nc2KqMADUnA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubsubCACRL.pem
new file mode 100644
index 0000000000..ade3f19453
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/inhibitPolicyMapping5subsubsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1DCBvQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEqMCgGA1UEAxMhaW5oaWJpdFBvbGlj
+eU1hcHBpbmc1IHN1YnN1YnN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMw
+MDBaoC8wLTAfBgNVHSMEGDAWgBSuY8vX4sNx4/TObvw19JvSTT7cFzAKBgNVHRQE
+AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAj0qjzBDkME3FgINy8gUWHlUGBpgreUMF
+1IqXG918JUeFy1vfkDdhwmg9ln2GjMquqb6J26L5mgH0EN4qUsfRZtcLHTEnMXt+
+MSKI8xOWJrid//uFlitbPPNdppvovBNSAZroq+uZLd+jDxKfiPOVlrIkbbTQvv44
+YAGrkkdsmrxSxWwrtXdLIURmW/D9J5uRkRqpMVvikD5aMLGQEangg5MO7ZLsGUBL
++mdA7YDq+RMG5F0TVoKOOlhOZhAxcgs+RMCZdJKWxJd6/gu5opHeEuOy5KShVzUW
+ABXNyqZXT4tjAjYW0Z26urTv8FeBoRoJC2Kyozm7+IR4m/H4/GaJMQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalcRLSignFalseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalcRLSignFalseCACRL.pem
new file mode 100644
index 0000000000..4993db248d
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalcRLSignFalseCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1TCBvgIBATANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTErMCkGA1UEAxMia2V5VXNhZ2UgQ3Jp
+dGljYWwgY1JMU2lnbiBGYWxzZSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgz
+MDAwWqAvMC0wHwYDVR0jBBgwFoAUwspp9bSvEy30nPIRVcsqMLPSWkkwCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAJk/UxyWvcm6kbidRgW52BKoSxXcHpfW
+896BFKl4iGUzmYA8GanMvM9EkEoeqjrHdTABcPE1Mv0lREGRYZv9H+gD6iAnKctc
+8G74C8eYkvcdocWAixuvDMyZ+D+TxSCOo04ppe+HraHgEQRy2sgobIYdqEY6XcyS
+X0areuyMQPjqbTdOMFsTrvtSew034Q0zSoKsPZhxfMQ6zcx7JKqna8HzCO9LCZag
+r5+47Bk470ve2Xy5FrPk6sWJQal0/YHOAKKnnXoXitqst2A3cYiWgRAqpDMz2yMH
+zdtJKbBsIieZGgQiedwXDs7aKWzN5o5sh0ALyj17bbHyMrs7gvyiGvA=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalkeyCertSignFalseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalkeyCertSignFalseCACRL.pem
new file mode 100644
index 0000000000..8a9a50b563
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageCriticalkeyCertSignFalseCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2TCBwgIBATANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEvMC0GA1UEAxMma2V5VXNhZ2UgQ3Jp
+dGljYWwga2V5Q2VydFNpZ24gRmFsc2UgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIz
+MTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaAFDRVC2f8HLHcwnIKFPBj6dSb8GP5MAoG
+A1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQB3bfisM1UBugxKYYdxZkYgpRvs
+rh8UEjPVD8z0t29+yeyiPm4bFmTZI64VNvQlcl/Jj0YdcqkWGEKdH7RS79lSQhBs
+piAcYQcdS9WzaZ1tFNG/Fvxo+MkksrQ+Z95rb0vvB+7YuTIVWqbHcJamCgZ4h+Pl
+XTUQgHedNzpPKisiLF9y32JbDJ/nnrec9wEpMn7z2Yhb2vDWhdtQoYMTk4LrMOSk
+74Cqfpuy6JEaymDfdmrIIx4JZOfmo9mQcgeN2WoV/4YYaGGL3T3Sk8FqUaTTdM9Z
+iRiqzBSTOfl4VF4e3S1ZTDv5JH0U/HrJexLhgdi3xEpE4EQIZvXVsZX6I8rn
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalCACRL.pem
new file mode 100644
index 0000000000..844a745e39
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYa2V5VXNhZ2UgTm90
+IENyaXRpY2FsIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBTBkBFK2bQrxXB+zow7Yljlu5crczAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAgK5IxkJ3u7pRpg/BKAlwCJPgj4SrjTrLeu875hsUvEfv
+mMzLN50lGQpwuuH2oaQ15Da+PGpzng6Ao5MhMt3vTqU+Yp5VQEnBIsGED0lTJDHj
+pDyQpS2d4nhdYyPrHQHJWwLoGaTBPglYqc/vASXq862RiNKywdVX4QFj9IXXUrwI
+wQ7d5uKirZUEkInjJCdVH8ryJfo9fLRD4kb3OkbO62e/HHSJO2DstQadNweLoLCM
+hhJlw5KkDXIBfQvq5pPrI76dHY9VatsnqKRkt1CUE4MVk0fOIqci2Nz77LdTsFre
+Pfe0WNoqSJpoGv4SfIr7v8Uw83bmO3Yy/enh3p9J9g==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalcRLSignFalseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalcRLSignFalseCACRL.pem
new file mode 100644
index 0000000000..e0fd7bfd8f
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalcRLSignFalseCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2TCBwgIBATANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEvMC0GA1UEAxMma2V5VXNhZ2UgTm90
+IENyaXRpY2FsIGNSTFNpZ24gRmFsc2UgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIz
+MTA4MzAwMFqgLzAtMB8GA1UdIwQYMBaAFPl+UqB5ZgQIRAhleRAO3ZDmQ/HYMAoG
+A1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQCa3FLqxtdS2NeSwWMvuticdJwe
+M+xS0ZRf30G+WsPtmoRnb753WkhlJZZcglilAExrCN9BIMSEpO/UgyXpjDj7GUri
+F9QHfTdIT8QGKcZMbx/nq29ge/fdjOIkhXnBktQy5BfB8lGkYwNs20NuFpL3FaUx
+IvruMRR2AyivlndK+xcz6s2j2v1WYXlvZlFNAAHVmXR8+67zbU7t0WIN7VlkTyTa
+0mxanuASRP5FmlT+Czr6N6OERlBTp1wnvlq9BHeTGDXQp1oXu8B8sTsQHTMbuGWH
+FqGDZpZJL1BsCMuXkBk40b6b57/C5CvIy7SfX9xnvKmJs81C6910qBITMcZI
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalkeyCertSignFalseCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalkeyCertSignFalseCACRL.pem
new file mode 100644
index 0000000000..d7877a9b68
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/keyUsageNotCriticalkeyCertSignFalseCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB3TCBxgIBATANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEzMDEGA1UEAxMqa2V5VXNhZ2UgTm90
+IENyaXRpY2FsIGtleUNlcnRTaWduIEZhbHNlIENBFw0xMDAxMDEwODMwMDBaFw0z
+MDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAWgBSyJdIoMNBVaG5MtcJI88qbFfJA
+RTAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAtIeKFZV9BB4OBq63soXU
+rgYDlsozbj5cYoU86vXpmHddbTowwaGtFlqbfg9deTqT6r9IpdIClfZtJVT3s3Lm
+PFb/areGyQblwYuOD6Mldtdty0FH5A9uMMMCEk1iZD0Z8WApxo1bomtY/EI+ZHAF
+N9+xTE7DZtHIOSZ0nyz64fHMPDYQPDGtkK2QQ6nFNX+ljnPOCRBfwwAsndlumWRP
+SlthF8gU3A8008ytHdpkNEsUhf81ntUy4o2pftmjQOnMJT0C97CXykxZBc8f49A9
+QKsI6ql/dt1XO9hNmVp7qamXA7+yhBwfWAKnhXRQn5D64/ZqVxE9lYL7PvJrr1tM
++w==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1CACRL.pem
new file mode 100644
index 0000000000..c999bf8b23
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWbmFtZUNvbnN0cmFp
+bnRzIEROMSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUQXhCRs1OqILn4Tnf96kWwAr874YwCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBAFtcX7FztYXgApU6J1ska8lB9xinzLv+LkatWBtqZuRZ8yYU
+LLgGDlzgHX8d51lkdXrlTe3iW6aNmKTFznTRqxPGLNA8VikBmBhNLYGgk0u3HTQD
+hZzWtyLOa4FB26lrREAgvEC7P5TB0Xd1p72E4IwKf1ZV7KOiTpw7EmHLsSWYGcDr
+96mwtkUK6g//vxJnIa+k7C9jjQboCmOyH0HSluB0KQYqislhXHO3BSBxiXVhHec5
+3ToVLhmo/v+3fgl8wkEO2RH9MRcx29+JiRrqLr5xYZy3sKKBX/7e5jT0PQsKFOqI
+CKt6oFNRwz2qzEcbHFMyoDR2+5R8zA8OHCDYf54=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA1CRL.pem
new file mode 100644
index 0000000000..3884626320
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA1CRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB6TCB0gIBATANBgkqhkiG9w0BAQsFADBvMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEaMBgGA1UECxMRcGVybWl0dGVkU3Vi
+dHJlZTExIzAhBgNVBAMTGm5hbWVDb25zdHJhaW50cyBETjEgc3ViQ0ExFw0xMDAx
+MDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAWgBThOA4UGBRD
+XM7nS2LHGsGS9maC6jAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAL1Mn
+Ok+7QkFamOzoQfdBznGodtPDmg30Cgk3VHY7mAwg0VzRhhTaUHjMrmZzpyKuNNU5
+of9K/maIKludVfLuV9NPmt4pTZWW8l02umkRg/vbAIfPGWpUhev5X3V6f+Bn5bbg
+UQvEiuFQvJzutxukSCkNzijr698Qa5qEu1HzILhO1gQxPhufrfjHqQ5qxAnJiVkm
+uOFSP/OBfuuDg7HS8kCAkzfHrtweRwrrtGf6AYzVZO/+pc7OMOyUW+kh0oXHY60n
+snh7NPi/PNGb4RANJBcQhNKHMVY23eCcwylCnfp7FfuNLSAj55aRvxvG3Pn+WQ+t
+UqzAs79/UBMKcj1IWg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA2CRL.pem
new file mode 100644
index 0000000000..a39dd31a35
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA2CRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB6TCB0gIBATANBgkqhkiG9w0BAQsFADBvMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEaMBgGA1UECxMRcGVybWl0dGVkU3Vi
+dHJlZTExIzAhBgNVBAMTGm5hbWVDb25zdHJhaW50cyBETjEgc3ViQ0EyFw0xMDAx
+MDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAWgBSiL1iDW0yV
+l7fu9oe0lw7gf+CXFTAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAyDcs
+pkncHaUX9Ebs68OGd6Vbz7PAjZ/cnQXN6ZzCf1HVx8vtldilw0xP7L6LA1z4/sKe
+5AglNKS18TrC9jvMcs5MPI8g9jNPpmzn4tVGJiISlft8SqKPL9dvgUCODtIj+Vqv
+x5ELHuMRwAsj7vXY6FrgTwM4eTwEbRhYCxM1r05VPj8t/fl5XoNR/4vaCmDYR9uf
+JscXoSlBsXJkPrkxHnrreTiSNtP1iAiX6CXOBctSfPzhrZknzWq76UYq4LnQrqNo
+gyZ1pc46+f7RqxgGOgn/Nb6AqBy+N2vpYXabMKmNpIBmpOGq/qonbtPF/zJbj+fc
+Bafk7fSWIrCNZg0pFw==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA3CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA3CRL.pem
new file mode 100644
index 0000000000..7dc7ee7fd4
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN1subCA3CRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB6TCB0gIBATANBgkqhkiG9w0BAQsFADBvMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEaMBgGA1UECxMRcGVybWl0dGVkU3Vi
+dHJlZTExIzAhBgNVBAMTGm5hbWVDb25zdHJhaW50cyBETjEgc3ViQ0EzFw0xMDAx
+MDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNVHSMEGDAWgBQnSeQE2UX6
+bJiUbPztDcMkUm1VRDAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAuEeu
+G7nwSvVr9BxS9bMPB12xdegiBpg5U2K0vTD1JSSOR+RQ2LvwpJlkNy2oFt8+sbAi
+oTCOgifKXzi0tszHRH8vYcKy+DJ/RE8mX214KIg5Lj3DEpOlzPE19/z+eUl41Pbw
+sgnQTE+ccm2h4GlUefprR8PSZdOIcqxbDbapLHC9vz1Dy1YdM5iySa7YJ7Xk4uDe
+NtysCgwKtANPKF/qtbYQgcZxGPYArrWprgK2xyMBeux7WTQp+9xaSOU2gUmAKwzj
+bt0iV6KEkoU08FmUwzXTxX1bBsjLyIeRFPm58XbJ0MxgGdJPmMn7m2W4PPeMJpGD
+vH1qhNYwy4NsWosCfQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN2CACRL.pem
new file mode 100644
index 0000000000..d32449cf89
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWbmFtZUNvbnN0cmFp
+bnRzIEROMiBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUo1fZW10Rs2D2AGuJUSuCwwlzqHswCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBAAky6btWTahA//H8vhr8u8hbW8h/OWD8skXuVJHLv0LdS2cI
+zzk3f1u8vwWaohmjsIdNllFU2hd3GH62mJdoXJflLxxVDm47FWdzmmlyUsxFXojL
+HI+tjwBFmSzzzd/t7GeF5mKc11PrUz9oqoSJEZVCcYQX2px2xJIzmqOkc4VWGrGo
+rIvTE8SETRWTYcE/IDOxc1lSs4KyH/MGIwMeN6Mu3p3d/H8ygXKEzf7gYR0riFW7
+ps5wlQRxDC7ICktp4f2bN8l7pw5TwjCfNmzqDbW9IlDFaRr1VUV6hpPwORT9qWVQ
+7ZbDXVLZwaWxGmp8vYh7weNKgrmfibuz/DcHqPg=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3CACRL.pem
new file mode 100644
index 0000000000..a72350793c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWbmFtZUNvbnN0cmFp
+bnRzIEROMyBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUBtxbvscSN1mkikB0fAmdRTxKodswCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBAItPJiJOtxXyscdSk4LVnHx2Ge6LLKaoPE6qXi5JRs2t4LjU
+DJAh0bKPehBDlbvqpV6/e8pqaJP3T1DH28vZTr2gGY/Ar4BcVSzrKO0jH7j2PJU1
+Kzq68kP2/tr90XnUOuz5589ORJ9aryewWxJ5g1w5GqD4dC8NV5aDWPWAdnxVw0Dn
+DVvJl11dzlFqaZSwuDIj0IjzssosDmCrPDUjLDLn37f35XRIX7/GB3ghSrUJLsId
+TrU+ROvpQ4iO9zAVMDfQOePSnUeNpO4Sr/as3lHaFptwj0tY1PIeLcyfv8ZNZYN5
+7Q8+aKRQMPg2ZHGeF0d9ADvGLZTZ2vMCK/hHfL4=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA1CRL.pem
new file mode 100644
index 0000000000..c179e730e0
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMabmFtZUNvbnN0cmFp
+bnRzIEROMyBzdWJDQTEXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFIC8xy73jhp/8Th79DXr3elYxjxQMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQDKBu+BE4WjUUs1+SbDPdTUvtI61Eo5D0f55tSFFzqY
+3mjQN51xcisMQIFvf9dPdD7/MOUjS2GeSG7CgPObXBVkhjsNzNhgUdk7obAAuQNo
+7pj0c+Kp36GKHgSzMmOvzXOpe0OcS0iEJTqOss/+GD+a0kPUQBTQptEFJwPyDdKZ
+yIpuXbmhEtaXJVEq/fIkQLtHDv6VqsOCPDyyca/NP1J2Ed4zEHcP7w4wTcxhCkq1
+duWazm3Bnc3Qu4lIOHUP1VGum+Q4cLzFzNlWCOIaWqCVwQvywAADhy4E/mxHtGAF
+8s55z3PAJfeRKySqkJJtPI5qRgllB+n9b/HxD7DskHy/
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA2CRL.pem
new file mode 100644
index 0000000000..4f416b3ab6
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN3subCA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMabmFtZUNvbnN0cmFp
+bnRzIEROMyBzdWJDQTIXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFMwE7WooHX7eZOoAiCrsdRG/pS5nMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQBSQba9PCeM3gDcJ5/15bCZXzS1J88gi1mSM00AHLmm
+cvaM3zC1dupZ3+nUGrGuJeSy9gJvKmRvCGQJVVScbWaJSBCLsE2OTLQZosIbktpA
+SMDnJNCgEQMqL3S8I0U71qD4gw/f8DoxBloqVyzuwIynWZl+V9agP5UCWweDpo3n
+zqfqm4zYF2gZYgVz53l9/zYpxr8e0d6o/Y2sqk6ykbzR1e+Yw8Jr5AKs8awilABf
+Lu5pl0DO/pFtT1cX7MEtd1aoxZqQxssOS0JlosEF66VMeOKgUw4uvovkbjP9zfUr
+GfwYbvUJZ4XSDy6p68jsQKRpG7/v6V6Xy4LcZ+4I+ATD
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN4CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN4CACRL.pem
new file mode 100644
index 0000000000..bd4472556c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN4CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWbmFtZUNvbnN0cmFp
+bnRzIERONCBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUbEk2rS5YiRI2UUE7VFImJADTynUwCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBAH6NXW4G6VFh6lalxV0HfwwV4W70J+q058P1U/nVsOOg7s46
+v+bhzKwJrIovS+fGE+WmDCMbeeIzvmMnkF7ZSGmZarmGDzNGsxghmiNHW9eP2Wk2
+7QjyePG/cAff8ILOqzCHw1WZMtIgyVM3tQY492xqKPRTBac5P5DN6COtBGzKsk7O
+mtOvhcqtwMt5ejXil9ibRhAKHcgoNtzOoZoaQOvTajOP0vdFYnHHkF+bFDd+lxUE
+IHgX9IOmk1xGFgdEcSpQL+6mvV0aKk9iavdbVBQCeWzul24GRr21EVO2emR3oceI
+vBeEL509yRgDMZoosPcUPzU3MCre4KHexkxNGKg=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN5CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN5CACRL.pem
new file mode 100644
index 0000000000..bdb12dbf59
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDN5CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByTCBsgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWbmFtZUNvbnN0cmFp
+bnRzIERONSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0wHwYD
+VR0jBBgwFoAUup8JypA5nE53Wuv7EJWs06dKXScwCgYDVR0UBAMCAQEwDQYJKoZI
+hvcNAQELBQADggEBAITmZi9ly086wq/MHAGjaUYsma31grAeyveTU+oJ7olEb42/
+ALSN0DXoO4UjV1bj/wiIPtErg0EjHWqVW4M9ID8ZdfDuXBLNBQ2NP14gJLjVTk2H
+6iHx4QK9QiB1gVdfKbj5+lTCt+7YWZtOWovr5SIlPtbNqszR1gpTLaLyIkT1FRg0
+txRaU4qTZmOIYCuWGEWeh0F9xHAZ4d30j1KcBSdHzOL28ibTjgDsYQF1680ChYu6
+TMUWY6q/ufziFDezkXkrLrtNWAwYZvS4sRynpbrhKUL+CldFK/u96ZZwL6T9Nkkn
+aY1gGgepUvLKlQt20+jmOu/L8Va7xcXK+AtuQQI=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS1CACRL.pem
new file mode 100644
index 0000000000..33e2aa1407
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS1CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXbmFtZUNvbnN0cmFp
+bnRzIEROUzEgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFLGqF/Djz8zSp4mmgwfd/27aB+NJMAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQA16Gsjfh0eCk00xbqXxGjwPJCTmNcQ5BQRATn1KHZNDm0l
+HSuZNQELk9z/M1jw8rEArioWWkLQEKdVQ8WtjFYYYcj7VTo8aho763/UhY1WBQQF
+ISHqASE4ygCUcwSKus12Ksk+NXvvARlv5EG/UqoSAMx+6t0VLuPteV5JtXaAgABC
+xXScnAJvH0BZJWDXh8x9TCocXxmH9SsZhgXM4WEZxRch1Z3bxLd3NrxztPXe8h7H
+9Lvp/TOEvTdjtbBn0kwomw1DCVeJd9DBNXFO5YvXyDBU3usNmHNMk0wri1roJzUg
+UrnYLYox1O/52yeQdQiSAkQ3grctmcBcJW8WaIWu
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS2CACRL.pem
new file mode 100644
index 0000000000..02b8226a6d
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsDNS2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXbmFtZUNvbnN0cmFp
+bnRzIEROUzIgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFEZInEIJjl1TcNgWHuDByRgVNQoGMAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQAmhkWLOOzNQKAS8uW774Ig/r2A1dpM2sBujFbCeg9blw2k
+/qRHoInFtwM22vgIBInC6EZW8qPqzPeJpjIluu02T25EjxRFGiameUbHQ02XAejf
+thhUnDw6lWF+N/sIKYXCkN6TuiKC9m4LPvlmI1JC1RqGWmZIsl59ae4zV1G0iyMy
+ol7WhsPhzsQj8pRACFdznwq0ehd3L8UO43BHl8+rXVzS6f++filZ2WZHPFCR5Nq8
+l9KaNhNCE7VeBQv7dElPeknvANPEGomeXFIIPwCx7Ra2mc3mjG5qYwmX1JYjPxe4
+siLRqgKc8s5vwYGwwPqtoInJckVUxfkZ8YAu5vTI
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA1CRL.pem
new file mode 100644
index 0000000000..4b594be896
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMabmFtZUNvbnN0cmFp
+bnRzIFJGQzgyMiBDQTEXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFMhqjrEPS6qliLinj5Hb6jNK6NXiMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQAEHhqk9qr1vH2Svec33ko0nUKpbgipddl8h6FtsAXi
+ewGnaaUK55/3Eu4FsbORjB+jSKWvYyaXnMPecX8zseOKgDWEiPZY6i+0/16Dz/NI
+2aOEVA3hxBmSToyka2FOki/KzcWfeKpebdihmZ/pyKk2qo5ygfASyV+/3fyroafe
+0FwfIRz0EHXamVhpTBVK/nsmtk2KxccIP0QjPkCu95nAAzeXJVTbzOUAbz9ZDpnM
+puACGthyjzpNfQmx1LHF1juFUdywoQSm/c/FOoPnU2KH2Ae/x0Z+tKQ3O36c72EV
+IU8WWZP82htw8qMDi5U5gymAIdQJjsyKbg53DpbkEwom
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA2CRL.pem
new file mode 100644
index 0000000000..6aa93849c0
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMabmFtZUNvbnN0cmFp
+bnRzIFJGQzgyMiBDQTIXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFFGAzfpJckg87Q5OC87OH0BlEnCgMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQAw8GlFDmo7lahPoMQ4ha8PN7CTyiVN52wVziP3qO0H
+uFi2H7EZV3VuYHNfJlzeeRtXGjpxBDiYkJJIg/n4ibxdyNtRnCjWTDb0BKbnQuUb
+QxoDRWuzc6G2pJ29H3Dp6DHQ7TLZwCfPfayn3AfOJBtYQpLk6c7ejrgXWv0T1ZSv
+H871UQpCF57JNU3zco9nXYN+I2IVnfgG08JXxGJsw3PMg1xa4v3awSYQ00/8v66G
+lBekAv9no926ub3Hp2DwYwcfE7iLaOdLtnBFPjdFLuZTPIGGJeeIve6NaEAwPqWO
+ZNUKSZipydOKeYsvEVEFUxVApV4TZbcSREvjGXQlYuH9
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA3CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA3CRL.pem
new file mode 100644
index 0000000000..b2cec3d3fa
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsRFC822CA3CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMabmFtZUNvbnN0cmFp
+bnRzIFJGQzgyMiBDQTMXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFJq6OU3aIXWv6kHDPGxR2KhFqX+jMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQAAhq4g3DB1Yb6DUVC11zrj0kzA3Lbth5HDupuy0okk
+5Do0LQZeiwCI37JhQceiRGxtD5riXbo3LyL2g+XqV1OCTXAbJrRAe+5sHmwrH8pO
+PZobXV32KSzzqzPbUNn4QmQDxfQLZgGAz/aPtMDuBIm22oI5iP93csW6p0lHcu34
+Z78RF06bdhO5nd8PbU8BQ+weHoWq8h8iykRzkvxL2d+vk0rS9AbEu0Hs/tqnw/pD
+1l+cuy9gmD5MFpfoMDZ9seQAKJOt5VkKW4rphhX9b3rm2cxceIqlvqQgJip+RM/I
+v3o2PYMSOePzWfRA63LYY8B5sY79W0v/miCl08vsjte9
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI1CACRL.pem
new file mode 100644
index 0000000000..67688e4aa4
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI1CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXbmFtZUNvbnN0cmFp
+bnRzIFVSSTEgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFPoorUEW3ipoF8gPHCM/JgPeAhQCMAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQAr3EikSVaRZA2v0/ARpi/8rC3nZprCYF4pOzM5aC96Hooz
+oEfd6+gFBJWGGPyyQuztWCg4AYXJqqotuSL0rGteXeA7S09i58Vi0rMZEYiaw1HV
+EYvt4LDShzMpeTXstjWCfMlhWnBVII+6ga0LwGD1SWtci91T6zgYlXczH33esi9i
+ras/1f4p1SQDAyo1gHulaaBRJvqQrjE/MaL8q3Ts0kQMM57aI6UeqpydIttGUcl3
+pwNujq4V8yChxN9nB1wQauRsi9xCaqTJwLDqxouZIxdUeFWEQvRAIur8NHdhZrE0
+gvLGaebETdYzvDYEkFdVMsYNWPEmd2fZ+F8dJKYB
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI2CACRL.pem
new file mode 100644
index 0000000000..fa5a247617
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/nameConstraintsURI2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByjCBswIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEgMB4GA1UEAxMXbmFtZUNvbnN0cmFp
+bnRzIFVSSTIgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAtMB8G
+A1UdIwQYMBaAFE3riXHf8AQBsvp2OlixumDdjNPDMAoGA1UdFAQDAgEBMA0GCSqG
+SIb3DQEBCwUAA4IBAQBk9OEGWwvZ0lgWzqgJL4OZ9j0+fjAMdi78QuVFSmvPPOi3
+kLfoOrPjMNmwi42SIz4BEyDt0iVxlq+eYqrIN5q/NqFdjl1w0UvNivcuPMjYtkdg
+4XPJXcfGCfnKbZ1voHnuDlmj6+lpUsXRA0YjgRhmGz4T26ReJO1FQy6+DDqO27+V
+CZ3JM83sNDNlcMeZZk9f46HtFq/kwvqFpTHmqWvvti1hLal0aRetSyckf01vmHQa
+14FbJwEqs6hrwxhLN6Fwd/b6lN3+vLbgucxKkFvRL0JUbPuY2VtFlJk8WOllxXMc
+MYhV7lqBnaFyCO+gWQaEIE5dDbKQTNVpmVRqbT+8
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsAttributeCertsCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsAttributeCertsCACRL.pem
new file mode 100644
index 0000000000..0c5aa4a18c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsAttributeCertsCACRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB4TCBygIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEmMCQGA1UEAxMdb25seUNvbnRhaW5z
+QXR0cmlidXRlQ2VydHMgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqg
+QDA+MB8GA1UdIwQYMBaAFE0H/vYtvLUZGlBN35kEem0zcJBOMA8GA1UdHAEB/wQF
+MAOFAf8wCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAILLUDuBlm16hFFX
+7mKimuJxRJIqqqi7YTYNnUkkt1ZjNwD+Zb+YdPhJrJJMboHIGRErVjSDGwHJs0HF
+HveDuGTcBDgqyJeG0C55xjRlSkPABS4jtWVVROYX/GkccJOjCGEs8A0vMVWUrsP9
+Otao6UOKDtn4wNkaItZ1Mv8Bbk1han+DsqJIdjCc3T8RV6xZcyQ9o0uO7THeyATG
+mPT6keQhjiAbT7NtvSL7pdd+F3U+68etzFFxjwqFr7/wSJxVWzF4vtrwW6tqPcCF
+SXNG3adV0JgEG4luWVHRC2GODHTh8DeygWMtEkKtkRouQMFoZGv7MvgoqlewMTfB
+1YnOC+M=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsCACertsCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsCACertsCACRL.pem
new file mode 100644
index 0000000000..23ab0ba052
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsCACertsCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2jCBwwIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEfMB0GA1UEAxMWb25seUNvbnRhaW5z
+Q0FDZXJ0cyBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqBAMD4wHwYD
+VR0jBBgwFoAUJTjDrsotdXpbTdTAA5KIEyLHbFQwDwYDVR0cAQH/BAUwA4IB/zAK
+BgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAMHmB5cF8VCL97/Gfo/Dpi3SC
+hi1rnJSgDEUQFwICI2Jlyewhfxs6F/EC7F0YYnPPfiA8ajXpGp5ccAvVUIoQUBgX
+iUdjp/RBmalZoyzPw8ZkGQMyy6ehymfyMnH/wKrivmAnxtPm8SGuWVJouu0T5+7n
+8G/vJg4q42RHYQQ7ripuh6wiI+Lf9wNHAzmmGsT6vG0Yrpg0hAcQzhof9xOK88h1
+xyJPReiXKjJx8Uvp/jIRjarGdjh19va1ysYLfMypqeF3C3Lb3J9vuxLS31FdX93s
+wLY919ormQApL+COmVhzilgTKI6ZfgxFhlF3nRNMQDdGc/r3tdezNoMznqBbBA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsUserCertsCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsUserCertsCACRL.pem
new file mode 100644
index 0000000000..e99752a506
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlyContainsUserCertsCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB3DCBxQIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYb25seUNvbnRhaW5z
+VXNlckNlcnRzIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoEAwPjAf
+BgNVHSMEGDAWgBSdvACp3AHN/h2WiH21nk+Z3iTSBTAPBgNVHRwBAf8EBTADgQH/
+MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQCHCFuxTPvpn0fp83f2Az3x
+GKcDG6BSg4w2lISlNPpcuzAOfsNrNNvWBc8jiwdsgKpMr2rFH7HdpvG9k+A5EqT4
+B978vmdJe6d+HJ0a6RINKrDeQ3BWUeZVyzXzKJvJNEtP6+l67BA/PV1O7t93prcA
+sUdgfm074/h81yKVQJKfsE+H9yCXo4XxlvN9/37Du9lNWtlU13tvD1Hc7FjO3pB2
++YJQwmKhlXrt+7K96k9DdPJMXGzJmpICBFxHz8KkC3f0vmYau2h8FzDZV3P0trhO
+azIpQl9N2nqKsYQ57hLeTBRQ3B9tlKm8MH3lzfYUf8Iktufhg/HGuFg35gfeZWUd
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1compromiseCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1compromiseCRL.pem
new file mode 100644
index 0000000000..8aeb421af8
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1compromiseCRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB/DCB5QIBATANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UEAxMTb25seVNvbWVSZWFz
+b25zIENBMRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWjAiMCACAQEXDTEw
+MDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBAaBBMD8wHwYDVR0jBBgwFoAUUGjRCUEn
+h+cKTrd4VvsXju4EB3EwEAYDVR0cAQH/BAYwBIMCBWAwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAGGC6QC55Xv0YiF5ILhvWpoLo4gexHND0T8vTNw6fKSa
+g9Re5ty4c1tDwJkRQ3RRY36O82BLImIyx+NltDfnu21/0zLv9XbZxHUraT+5Ch2v
+smfGOTG/zm7a0Ht0QtM6q/br1RJPbxG0c7RUyV4hooP9WDV2UIz/9ba6XfbIf6Ts
+SaDhRmu6P2hbGTuAvKwsMR+DgDRvCQ8OUdc639W2hiVXaf5+kHyQz25BDTDEOptA
+cwgpFmaZiGKgltA63nn4Fl797/VmQbQYg8pmRPsEPeF5kw6n5lbXEo7wLXG4dc4N
+GiqeRO8oi8zU8rI/ddx+zr9jUeJZQldzM9VBsOq2c8c=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1otherreasonsCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1otherreasonsCRL.pem
new file mode 100644
index 0000000000..49f7456ffa
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA1otherreasonsCRL.pem
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB/TCB5gIBATANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UEAxMTb25seVNvbWVSZWFz
+b25zIENBMRcNMTAwMTAxMDgzMDAxWhcNMzAxMjMxMDgzMDAwWjAiMCACAQIXDTEw
+MDEwMTA4MzAwMFowDDAKBgNVHRUEAwoBBqBCMEAwHwYDVR0jBBgwFoAUUGjRCUEn
+h+cKTrd4VvsXju4EB3EwEQYDVR0cAQH/BAcwBYMDB5+AMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQASB9/TxIVbi32C3VcEK5Q9oKUrzWbOmzDBEI3G1S0k
+Y451pdZaFfBVzikVlcBVTw5gikTy4TUK6sEoysiEvRlpTzYuBxqKQgXwacRlVNUG
+mzZqYmHQycTyrlZfv4PyVPrz6E9ToTvz9/DymSkswVyBm/GKZ3Rq31G8niu4xHT2
+EBz0BEW3/GN9sUC/Y4dGPcTNJc3OkcrL7t1YKfz9H+dFdXqpTW9wdt6DkyEI/Ync
+3pxo6Qnj8Wwk8U2aiDvKqQh6z/b8Mlt1CullIhKM3SqGzTqGnv7SntdZwTv/1oeY
+dbpJ6VGFTMqXxUkgDnR4ba+Tn9iMkAUakQvbjnN5/mgW
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL1.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL1.pem
new file mode 100644
index 0000000000..2d585f4780
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL1.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UEAxMTb25seVNvbWVSZWFz
+b25zIENBMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqBBMD8wHwYDVR0j
+BBgwFoAUYGPf0iOkKdZBpKzKhnmYpmUBSK4wEAYDVR0cAQH/BAYwBIMCAxgwCgYD
+VR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAE7Yv0ls2R1n277KQK1TR+2NXC1y
+pY4ZorshYnrshNO+Uy23PtVCJzy0390E1CsDzIZdmz+/rXEDsQOSwCYDWrCSo6hK
+BCyTlWBfqZcNTQJnRgYV95e3yHaqY0mEgY6l+az1gDR7hC5UBwFPnFGNnY0s9JSD
+bu4LOdl+bT8QmTw02+hfMA4Q/I+ytJOkWkLs+5pLg6vyQreprf8MjJDdGxG0oKk5
+Q+vPpYQQmsyBosaz7mNSuZ799BAqRAl0ATMmT5FGldFo7whlDhyYwCnT6djdR3nd
+nsBhSdbf3LXqnKk6i79U1H+Yzx0XagnJA7wGGmHf5oIRRVDaMmQOzaf/sl0=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL2.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL2.pem
new file mode 100644
index 0000000000..657f0999fa
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA2CRL2.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UEAxMTb25seVNvbWVSZWFz
+b25zIENBMhcNMTAwMTAxMDgzMDAxWhcNMzAxMjMxMDgzMDAwWqBBMD8wHwYDVR0j
+BBgwFoAUYGPf0iOkKdZBpKzKhnmYpmUBSK4wEAYDVR0cAQH/BAYwBIMCAQYwCgYD
+VR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAI78t4QP3CIEpYKHa9TIyjr1Z+lq
+HE7UgiKd4HbsKK5gPDAme9A/DK/klDZoufxmSUnjJ+KO5yE5YiQITW9k2CvZL17g
+Wo8miQcf7HFp9dEEnwd6yHE10ZmqqIJrujTaa9P76KhaovCCoWlJUAyCOSF9DDyj
+5fJyJYUKxXo4FwkcViwsJgp4NK3m+YB3BYFRy/p4PQKPFYYrDMI1yx8B/lOp16UH
+rhYzMC5sohfnCpryHxNTgBu1Cy9XzITBvUniXOtMO+hY/axGojkm/IOQSlzYAahL
+AOc1qr6BEK/tkWxUJanBWTpPh5d5Rojto/uu4fOG4XbQLS4PllRZlCKQTyY=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3compromiseCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3compromiseCRL.pem
new file mode 100644
index 0000000000..acac31a59e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3compromiseCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICPTCCASUCAQEwDQYJKoZIhvcNAQELBQAwTDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHDAaBgNVBAsTE29ubHlTb21lUmVh
+c29ucyBDQTMXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqggaQwgaEwHwYD
+VR0jBBgwFoAULSS3l4cs7tocvt6XhBuvoBUWvmswcgYDVR0cAQH/BGgwZqBgoF6k
+XDBaMQswCQYDVQQGEwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAx
+MTEcMBoGA1UECxMTb25seVNvbWVSZWFzb25zIENBMzEMMAoGA1UEAxMDQ1JMgwIF
+YDAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAdQRa9rY2kA/f5hPXwMzB
+IiCNKdlFB5gAcrElHOAFq8MP3BQ6LtE0dH+RoAudtqh92aydcFza5EsMVAQq99AM
+jBjlm535dj9hxo79uqC2ZReofJBNgLL5H8cktqZPCsnyeGgDWDxHGtSE7PThveN3
+4VD9Kstk04qFpJ/8TK3BPca6zEtTb0k8LkpRojumPy+KGNs936HEkGwRBQaFkn4v
+i0gosO557Q4wXMI4AQfuY5jGCavXjUkXoR1BlS0CrQqMFC69J8hOrpK7tOdDPefa
+NpCf+3pMgASPMhuc3W9/bQIQTQL/dFwdfQZCmJUrxu3e04URw13J+rDXaZKgYXb9
+cg==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3otherreasonsCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3otherreasonsCRL.pem
new file mode 100644
index 0000000000..3d20df2931
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA3otherreasonsCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICPjCCASYCAQEwDQYJKoZIhvcNAQELBQAwTDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHDAaBgNVBAsTE29ubHlTb21lUmVh
+c29ucyBDQTMXDTEwMDEwMTA4MzAwMVoXDTMwMTIzMTA4MzAwMFqggaUwgaIwHwYD
+VR0jBBgwFoAULSS3l4cs7tocvt6XhBuvoBUWvmswcwYDVR0cAQH/BGkwZ6BgoF6k
+XDBaMQswCQYDVQQGEwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAx
+MTEcMBoGA1UECxMTb25seVNvbWVSZWFzb25zIENBMzEMMAoGA1UEAxMDQ1JMgwMH
+n4AwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAE32bsFUkG2yqjakiO6C
+h4PUu/ZdW+ec4ZPUt/0Aw5pN/yGw2DJp2nBjHbLEn8qoxZbVX7CM4Kl44520B2Mm
+rn/e/dmOMzfKLV5SxreIg2gzl0Y/mg4JqmGza4sTA8nDExWiRyqQbf7wIgK6pQEU
+sEjvc2RsJrzvIt6QryEMYAJaAe9FaMP++SnKSKisBKzcirBgTz0nrPrNkUcI2o6P
+GHW3ZwPfyDsUhx1z2sbtT3y/svye0Ksgh+2wZc3tU5zsvRAKN6fokw4ADhlporgF
+3WZLQJcywJElK3w7mPc8YL9JKieuAiul/E1dbpnm8dA9Sj5oDyooynxUav/o4HCl
+WDw=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4compromiseCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4compromiseCRL.pem
new file mode 100644
index 0000000000..3b60898d4d
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4compromiseCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICYjCCAUoCAQEwDQYJKoZIhvcNAQELBQAwTDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHDAaBgNVBAsTE29ubHlTb21lUmVh
+c29ucyBDQTQXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowIjAgAgECFw0x
+MDAxMDEwODMwMDBaMAwwCgYDVR0VBAMKAQGggaUwgaIwHwYDVR0jBBgwFoAUvmbc
+HgwGO/bTiDSRUyaBDWgXbskwcwYDVR0cAQH/BGkwZ6BhoF+kXTBbMQswCQYDVQQG
+EwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UECxMT
+b25seVNvbWVSZWFzb25zIENBNDENMAsGA1UEAxMEQ1JMMYMCBWAwCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBAAJIN0tHbsczxcPvHunvZEwHCJR0fVLav9lF
+XrsjWM5Qsaj0eOddNDav/I/ELvHUL2JCVu0UKLtwlNZlAIPgOKi3wEhf6qSV2WY8
+NW+zQ8Zdk+zuIsE/to9477C7VJfd95fqPhxFRzrfo3R1TCwEskmOVhvwIcsuYOfM
+fNl1ObbutpSkauLcUTJaHkdo0/QO6vSMEEVbmVbqXUOVq/Bbv4QFypTl9tEGCAeS
+SXhy9KG1XxdDJRL8nExHIqzvaBxRg0IJAHGi1ERrL3mlUyq/0AkHnT2kqrNaVzxL
+aDF48Wb41H/JPZjU73gRqAm4HHQcEIR/ZMgCQy2ZqMFxubBzw6U=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4otherreasonsCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4otherreasonsCRL.pem
new file mode 100644
index 0000000000..189002c25d
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/onlySomeReasonsCA4otherreasonsCRL.pem
@@ -0,0 +1,15 @@
+-----BEGIN X509 CRL-----
+MIICYzCCAUsCAQEwDQYJKoZIhvcNAQELBQAwTDELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHDAaBgNVBAsTE29ubHlTb21lUmVh
+c29ucyBDQTQXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowIjAgAgEDFw0x
+MDAxMDEwODMwMDBaMAwwCgYDVR0VBAMKAQOggaYwgaMwHwYDVR0jBBgwFoAUvmbc
+HgwGO/bTiDSRUyaBDWgXbskwdAYDVR0cAQH/BGowaKBhoF+kXTBbMQswCQYDVQQG
+EwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEcMBoGA1UECxMT
+b25seVNvbWVSZWFzb25zIENBNDENMAsGA1UEAxMEQ1JMMoMDB5+AMAoGA1UdFAQD
+AgEBMA0GCSqGSIb3DQEBCwUAA4IBAQA6VO6zbrPramIZ5tc+d2wb1qV2eX230xjC
+Z+k9zK/PWUvG47ZOYUDccUWhVUgH99nRvoqdhVZrF69HIqdJx8a1+kvi45meJsHN
+faOVtyb2cXnYduYiSrcVZtimnSItAc9LIKt5NvRKVbsD/ZX4Nf+fnCaQEmd1Vx89
+dWq+5Pt3iqORg89D6HzU1GFVE/ES60t7rUbYkxKdfnZhsauX6Mm7ZBIDZK6I14LD
+6qm0UicAFZzpn15jKZWD6h3s3ZGgpFBIR1CkQH5pyTLQK/jPma1mq6ktz3hHjAfR
++BFDWpDxlfjcvBm8TPB8kmPYF9zl7fj8VkpDW/g2jwvDYNwyuYq9
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0CACRL.pem
new file mode 100644
index 0000000000..c1142fd5f2
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByDCBsQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEeMBwGA1UEAxMVcGF0aExlbkNvbnN0
+cmFpbnQwIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNV
+HSMEGDAWgBSbK7JKPJDFblABySK9Y84J8Yw9+jAKBgNVHRQEAwIBATANBgkqhkiG
+9w0BAQsFAAOCAQEACbNqHOyNhLoyqsp302Qhh2DQ5xn50BIJt8FHPQoxzjgcSxkV
+vSWc3F7o93x2Gy3t90APobAPMq7lgkvI9rUyIdg3jn+mkAyaGOaZNoocBVIGwEmI
+ITL2DEhUSGag4wZgXgxAqkcvasDMihLpVudYujuqQ3sU4FLxr1jwXtdtwmXrYHSx
+W3CFNk07BfXdrjETCFJVP2fmElf1s3xOJJaw82NqWBAU7OGk/CTI0XQwxPHAqnao
+Pywh9giLL8cjIqi77qOQk3qSmPvygMXfsMQv1LkdL1UpSNta0D4NurcyLXUojN9p
+qwk5NGs5KwY5CNr3lncwUfuSkuySGB+KmoSzQA==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCA2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCA2CRL.pem
new file mode 100644
index 0000000000..34b51bd784
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCA2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcGF0aExlbkNvbnN0
+cmFpbnQwIHN1YkNBMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUxgkqG/u46T5oYHrHl86zWFF7dt4wCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAJqExyZTBoPDB2CCe0jcRtIcGgoQJSMase7HfvYA2gVB
+zQ+2yRT8qyeoK/ybY8kBRGQ8pSfv7R4ARlwK2vvAfx70U512ssjSDWpmAXK3EuDU
+JVvVfrmHO66z6LhZ1BUx3ngzk1tnEZnvfCWqMGkRFh3dXT142l/0uWGdEBpr/lyy
+zhhJZ+AvGuhEWpeuAI5GL4Gw7p/YBaMoioEvVVMJ16Jp9k7dwaFF7hSPLf31GCtn
+Rm/6rENr/P+vdFLRET/FG84eGMBsLtlW4y6q2boQImMqZZ6uC5hIfK1Ke4vLfEZS
+/6Qs392dyBadvH2ifTb/L95kG7zGC7fHAx2e+tECzCo=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCACRL.pem
new file mode 100644
index 0000000000..1c2c371782
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint0subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYcGF0aExlbkNvbnN0
+cmFpbnQwIHN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBQUYmcQfdI3xXIG0N5/tRYdyqNzXjAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAFpwGZEbWR35NljL/Cqg+hxRkUXPsz9aZL5+OrEpCBF/F
+AvtTISr5emDzeNbc+DWdsPAIYIOZ/1kx31aA+0e9Hc5Bac7O246yIwM/kyODPfM+
+36CTCsUCHdIlEm2tDNOhn7gHV9y+tJkT49rRp952zeTwloKyMADiR5amnqhcoOXp
++uY55zW2wQLkADXqukppj4bP13g/R9fIZvhkTFLD1FGArjGt9HH1Hfe3n3MjI0TV
+AaD5TOm4Jogz8RsrFDz3EFMUxCb06jcGz+B3Oe5etjJ0aSpbG8d5ETgGAW3ucXbP
+eVlTs9xMJlm4s34hxYOI3Xnu2ksQ3YiHccWpFcNo8Q==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1CACRL.pem
new file mode 100644
index 0000000000..c0dedb88c7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByDCBsQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEeMBwGA1UEAxMVcGF0aExlbkNvbnN0
+cmFpbnQxIENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNV
+HSMEGDAWgBTz5HFg/xcU3o0mhTN+HPzBR2f6wTAKBgNVHRQEAwIBATANBgkqhkiG
+9w0BAQsFAAOCAQEAYUHA3NQZQRmqjqAh2cWof7Fkl+YK2qY4pF/Yo6L2+ASqcQaE
+6+YCwPVUcjJsNzrF76KKHib7UbodnAH9cBBig1d5a00OFN9n4B81Ha7C0UxKtphU
+gm7wVEBlsHY8KAcV9y+VX11UX9qJ2GEAN1pa/Kio6w42wMcW/oDrAO7UKZtzJv3M
+peqQexGUQYQMbyIh2TTz4TOk2uZovikXa2+1FiUqFPNZfHkZ4eRnQBUQBxFJT1pj
+m0QtotM8+yChkTGrP52ilV/GI3kaLuyIbZVl7adUHiIxUkrEmmkOl7OHhsKwrrTU
+9RkZtL1XF075smmMW8iNRRVEDA3HqJxv2GN0iQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1subCACRL.pem
new file mode 100644
index 0000000000..fd43b9187b
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint1subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEhMB8GA1UEAxMYcGF0aExlbkNvbnN0
+cmFpbnQxIHN1YkNBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAf
+BgNVHSMEGDAWgBTlmZa1x31VQq2Bjscl9hjNrJ2QeTAKBgNVHRQEAwIBATANBgkq
+hkiG9w0BAQsFAAOCAQEAE0X1RyeBmz4sK6l9ognWRz3YK1XFln2WRcvR6Rnj5+hD
+paYtOhh2FRMNL11CqqpiG2IC1JPGKA36hx7UcF6LyhcqtDS0YEI9kXz/C5Hk60bc
+wKuIyVOZYgXOnNvsewa2LvGhi8ZUCI4L6DGdV7+OcJ/7PX3Jth+01Np7T15jo/gv
+cCCkFx3fmd9ysx2xcO2Cyd5vtqiEOK7DIoNZ6WguHlYdZb9/kDoRoWf5Qq7rmKXQ
+agJhrU6jWsCfQqY6e1oYlafSRPemgJj4kD1vtTW1D8OZc+iUFy0Fd3EZ6HT8xOAP
+9e0WFDsqL0+K31KZk5tFm3KZOrjJIxvcmLu+a1mELw==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6CACRL.pem
new file mode 100644
index 0000000000..a4bb7e3ab2
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIByDCBsQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEeMBwGA1UEAxMVcGF0aExlbkNvbnN0
+cmFpbnQ2IENBFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaoC8wLTAfBgNV
+HSMEGDAWgBSvvIWu/kyu4Y2XI4jIpbFgC7pO2DAKBgNVHRQEAwIBATANBgkqhkiG
+9w0BAQsFAAOCAQEAmHcSluSxj/t6JAD/aFB0G2KneIGVwM+c+dhxzVgL8/onCq0v
+KLB3BafsI5LQYRb5peAT1mCROTnVIHW0n6bE0RCQIxGty7Zh/kcjRtdL9cv5JX91
+ovjJVm7snc3XR5wUe4+8pRO3HeWurcXj/NvUOmaZg+hEnv8zgICjxndiqtPlQPjq
+/BIIDOT7FSuYwFIB5bcPBvyEjRSR7hi2UDzR9bxjiHBULC8nCbNhk5Qff0815fLK
+TQozMgMeB3D9psl8cDfO2owL77bsQx0um2QjJWW/ByMnYndkzGRt/9SkxRGHKtmV
+2rp5wMZKEQcVOm8v6KmfkdWtMBf5GCXLvjf0RQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA0CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA0CRL.pem
new file mode 100644
index 0000000000..a06b0839cf
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA0CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YkNBMBcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUz3Z2g3OQJMeNo21nfOtSwNTU7UgwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAFyoC4W//fvuVDNbyQCjkcD+eWvMUc48a7gacH/9yFzM
+auBjPEdjd4HWqUjEH7AH75ZgRXnf1n1pL9wh9mIJmVV4hLHfnDcryOMH71gfDrft
+d72DZcCBNZv7jXSMuIjCDn4TtlF8DgldJHQ5uA1f/a+qt1nOV7OCgHStr8PsP45+
+Cf/UGN/hqLWdlvaMB7PF7Qbfm639AE4UWs5NyKQC9PaDpFw12fAUJSO6PRXnSEMT
+9xx74LAC4aZIO5CtnUE/MPIvGgJFdUneXVkGDmsg/jsXbCVhKH7fUWun9IPvehE/
+OW6kYzC+6v943J3NelQUzcWzzF0CH8DwMGEY/GcmIwI=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA1CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA1CRL.pem
new file mode 100644
index 0000000000..5aff3ab9e6
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA1CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YkNBMRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUPJqVnpNeVmLpWziQbJo6bpLb9wswCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAJEL4fmSZTA+fF23RGynu2YEOWQ+YFNJzfYPg8EdimTL
+8AAXERJlbKKh+51nygXhYhUEonLIVmJyK83n7rIbEaOlrfXu2M4CtSi0zPZyTNL6
+hntIw1oK90JumjJhqxc0T9viI+cCoKz5b1Y0VZ5UNrno5fHmhw784TwN8bKxTig1
+DC4mjrk38QAAEV/5xQdS0i4nXP7Tz1PO81ueqMz8kgdp+QHjFKxDOoadq1gt+7Ly
+GRuY2SlF7pKZ6e4SdGF3rJ/sSzmO0wMLkMU4074RRg0BOo7J8ow/WuMVmwi+alQJ
+l5xRRlX1d4F30oa5AuJWrOSDw87HKTfRwPvCF/U6hPY=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA4CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA4CRL.pem
new file mode 100644
index 0000000000..1cc5a4506e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subCA4CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YkNBNBcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUSYXbS/sRY9mZAii0C3qeExdaFXcwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBALcHlK8kwUx4MZCo/sdlhk02Cf/n4mMvGAzXzjTDFoO1
++Nvo1HL5xmZ9KKCTSYmfBHc/qhMAmH31I6UJAVlOdtUcq2VCRRej8OlOGLImThkt
+oClLD6mmtW1YuB6bJtsuFj+GIPvLZfkpOgKg0fDmcQRVL5DO5ajMN/BH/xJtHuiV
+n5DjNZPhJls11DOd57TzFhGVq17PhOrMvL+8nCMs4Zl7DtNKw3EJuTDGTGAB+OYx
+5FJBmick+Mnkf2ElfidE3yBiOlg0Oj/fXjb5cqCa4uR+sAqYOl9BBjM6RfVbOrhJ
+7FuBGqYEmCr0D/FT8EusGdWFDBqfDsWtXVV7LHxcm6c=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA00CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA00CRL.pem
new file mode 100644
index 0000000000..6b19bdf4f3
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA00CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0DCBuQIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEmMCQGA1UEAxMdcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YnN1YkNBMDAXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqg
+LzAtMB8GA1UdIwQYMBaAFLq54oj31FkliuMp30+gBjjdcXSCMAoGA1UdFAQDAgEB
+MA0GCSqGSIb3DQEBCwUAA4IBAQC9tjk91ybiFjv2eYZsjGMKc+y1kd1xc1xIXSdD
+dM5JR+GglRm79uK4gDZ3gTLIQpDVgYPXV+ereJ9Kg9DOl79O3h/nxtS45azUxvdb
+uk/DW7PpSZSOK4d6hW/VgZG2Giv+ZucWNnUGjsXCs4/Hhi+IZvAI/Fhtcbi5cwHQ
+RG1hqJYGsqzQ1V4iBshQnZeyjp0KFz95dIifHNsL1YJJy7ODiCE6RLGaXs064DII
+g3XyZdz7hZOFbGTR7GwkYtSyIHLm4iD/xJeCU6cA6FNd+Xb5Fs4SSteCUd0lurH1
+JQLnUF/Xjt2IowuQFnfQ7z2jq+8BRrIgkvCQp5lzteSqPE1i
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA11CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA11CRL.pem
new file mode 100644
index 0000000000..f85921377f
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA11CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0DCBuQIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEmMCQGA1UEAxMdcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YnN1YkNBMTEXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqg
+LzAtMB8GA1UdIwQYMBaAFNOmRV4CnWcWfZSAD3O5hMZbtTG+MAoGA1UdFAQDAgEB
+MA0GCSqGSIb3DQEBCwUAA4IBAQChBEJUKVtETDiFUgxBvxOrmaOjI5NxDTsqyM7m
+HrkP330mh+ij8w4DJ/kOhHxC0c4EBgD7m4oUbkClmqY0LVRNaUlFHdNvftGJMg8k
+Z6Vveak9+Z3q5J7QlE8hdLCGsnQXL3gWoOjH28j3I72fW5tabTdyq7qPjNKkt0xh
+6Sv9jLxHbAWimSvj6xQ3JxO4UweFvDl72eQb+tFhrJpouhlUv13eF6eaQoVKf4to
+KRjRXWEErBEkb1fEXzUISEvQH8gbzVi8raKG/CWbUfFCkBWiqd3Ahr+w0xtmVV9W
+wk0SlM+XlKRQZ4chc+93RMQQBCC6LwN2rBmyaLUPAtzUOTA2
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA41CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA41CRL.pem
new file mode 100644
index 0000000000..744befe8d2
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubCA41CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0DCBuQIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEmMCQGA1UEAxMdcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YnN1YkNBNDEXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqg
+LzAtMB8GA1UdIwQYMBaAFERapgfP9vPIx0bvZKH1W8E/grxXMAoGA1UdFAQDAgEB
+MA0GCSqGSIb3DQEBCwUAA4IBAQBC2N5Gdl473M+niHqbKh49ObjDXcF0Vbam4NyC
+e5V+1D6PZLlZQDNh0ORk/MnIOYWxchUhXpUnpNfcqReFdP/kIhwlc/Nm3xveO86n
+zWuRP3NrN0N8SRz9YmLkoZvDNL5gagKCwLzeGTTi6lMKqhZnmcDH3ko7k3TOlCO7
+I7f6jEp6ECAHUbDE7UyJC93lYu98YpaM5SV4L8i58/GBpCwGsGirSxws7Xhrgr4L
+Q5UUt5v3GDNW5YiRBEuG1kMlBC4T4gX/TNsdu/8G4RT2hO+SIDOtMNfA4D4TIiY0
+OzDtVVto9DYarCyKlQKHzb6RrFL8sYZJc213B/1O4qRNeJCj
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA11XCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA11XCRL.pem
new file mode 100644
index 0000000000..20392a29a6
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA11XCRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1DCBvQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEqMCgGA1UEAxMhcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YnN1YnN1YkNBMTFYFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMw
+MDBaoC8wLTAfBgNVHSMEGDAWgBSD2ri1xp3Iiwh8iz/tGnIl4q8b6jAKBgNVHRQE
+AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAmKydWhVC5ytcp4DjzRPCIZ1myP9MGW97
+diaTIZaFdYYz52k2GD6uHBEL1rALDG6e2DiU+YbmfVJHE5RbehxwtimoWsHOtGLO
+NPTMBPwGoGHIUyR2Ex40oozOrprl5tY3y8uticLLyQQ4meUTrquM7aAEaHHYGwU/
+FziX56TGzO9Tm6ci+jlTrOwHy/uj/AVkkQS9RHk1ytgrG54WSwh/diP9qJrNGvBe
+a8Ditg8ijMjGU9J7NeDJn33G0U8/R08ZOfo0kNqD6mG8Np5meREfiCt5UGfwBOV1
+EVMpK/Liv20yc7PcJT2lKGl1eXZmiZ7TLGV0KJWUWRNy1o4cv6a1ng==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA41XCRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA41XCRL.pem
new file mode 100644
index 0000000000..8674072d00
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pathLenConstraint6subsubsubCA41XCRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1DCBvQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEqMCgGA1UEAxMhcGF0aExlbkNvbnN0
+cmFpbnQ2IHN1YnN1YnN1YkNBNDFYFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMw
+MDBaoC8wLTAfBgNVHSMEGDAWgBSh7aLzNVSln7xj5kdqUyRsSgxyLDAKBgNVHRQE
+AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAB9m9d1A5cqTJSbdKDkv4KfjAJDsKOqyf
+l1QLXj28Mq43YlLbcoaivW0yL+44zumb02ZKr4v1qd7tP5QLPvv+Ew1pQwC3I8cp
+Hq33iO6VX/ZLVT+vD8wguU/Lwq+oZGFDHMatgq2CGtZ2lJbZ8/I11wR/otTBa9Ne
+krQ+n79avPaAagJoyz+1HKSerOyuyFQ9GP/v64sS3YKy5LJZ/VXC9PlpzU523ENu
+ncwldAgVmNTgxa+kPmdIzUkWLHuuggVltFtRbVsiKyJINgNcmooZhDIHCk6LsXYY
+fBMmxX4xFLGzi1p4sobgJgBkY8YBDiB2xEslOFkwKIgpRfX01T4IZQ==
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/pre2000CRLnextUpdateCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pre2000CRLnextUpdateCACRL.pem
new file mode 100644
index 0000000000..57afdac2b5
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/pre2000CRLnextUpdateCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcHJlMjAwMCBDUkwg
+bmV4dFVwZGF0ZSBDQRcNOTgwMTAxMTIwMTAwWhcNOTkwMTAxMTIwMTAwWqAvMC0w
+HwYDVR0jBBgwFoAUHqhHnGGAaCixQpopjOYoAymSA8wwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAF6aXbwxymxr0Q8xGFXYqmr5vzuVUREiNHYZMX6N6pqI
+noDmGZN1FgX3FSkcKlsiVYWPRp8VygdNPt2sctjy5OV3J8kAKXzoll7/cHVPWj3b
+uGP8B0Y3sk7oCupwlI/lPwu4Yf5hHcUofyGV4yeOCNn0BHGtOzcfStxbO/K2sG10
+ny8KKkH/+horhqSur2p6z02jq1hcHsQLt293tPfaG6skObtvWgrajbE8rPKYLHiS
+mkh+9Lxtzv/+WOR7YeBgjfg7Eu+gLC+2rrA4C/UiQT27baIzEJkaz3qarL8p4qWR
+BctCVbNVbcrgSA7pT3kavp4Te5NHLg1vRfmkHka1ESk=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0CACRL.pem
new file mode 100644
index 0000000000..faecb30bdc
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MCBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUuezfulIiuLi+aveiEtUnINZnBDUwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAErZavnEyTgHh/ez0LB7FgIfWGuiJB+NDDOQBT31adQW
+nPq1ylOQnG5ALE9askbusXrsw8VHIffm8bBd6JRdFXD9p7S2SzFE5skbRHVs71qr
+ytTzQhoQgYMaWRIYBx5Yg9J0+HSp7rip8FPRoPA34LRoPFmtvGyESnFQCZQMj6Ar
+DrRhaj9MFsicWAObMlIWNOsISnNkDd1s4XeRTMbZ6NgvyZ9Oo6K4S9YsPJypmaWD
+rAtkwSqyyH9yT/Ip7jNFdYfin5oE2i+dN4FCWzQXyr+z0l6dWdw/sjiDWRHVQTkA
+G/F4Ro+qR6bVtq9wt/H1qbauMxOqI+OILjfZARtV/mY=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subCACRL.pem
new file mode 100644
index 0000000000..6aa182da50
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMccmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MCBzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAv
+MC0wHwYDVR0jBBgwFoAUvmJ4/Tu9bpwLM/I7MqpBCPPliVowCgYDVR0UBAMCAQEw
+DQYJKoZIhvcNAQELBQADggEBABmiY4GL9Z4TINu3A3r2ReqPCf6NBrK838gjCy5y
+yomt33rwH0sDWcdU1YtKMk1iAWpBBon3nBrfylsFDAacz9oqvHBnCSYnO/b3WWLv
+rv80IaJoV6IeZC1CF7vXFcUWt0VnUgVxNzhLWOn0GEu/R/W3HIPUUvpg/0+RVG6c
+WSPwCUAidFY88P195evwDEXaKykQw6LzAlnWMvrL0lviPl4Px/GDUOBp+aZaDz+t
+ktuljb5StVBqdQ4XzemwS12ZkAGw//synft8xDg7c1Pq7csftQ1SFuEvkRaobXYp
+mSWUqhhm5pkRQBxPySvpDiYCOiQbsiTyAAnYkydIeAkX1Ps=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubCACRL.pem
new file mode 100644
index 0000000000..58a10374de
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0jCBuwIBATANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEoMCYGA1UEAxMfcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MCBzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAw
+WqAvMC0wHwYDVR0jBBgwFoAU69iXen96IzUZ5M+XJCcizGenVkkwCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBADaIskgZjnU/+X04sIHx4MxEDo7nCtfaRe6U
+sgYqAEr8u9JCuba3tJgEud2meu8XRkQjagttBmG52vxS4rMiu6Xq79DPWLrdKc3x
++1Tx/wF0iACCp7B0aNfFnrF+Cg/XCQqeVlthn8EP51HmFl+Fu/0szwhHS3N4Nh67
+C7QGGL61vSUqK3V9tRSn7ubAJBJp+BFbG0uLvOlEUbs4iil1f+VlWlXr7WFfKw0F
+k9prVeYBcnyV7X4uLEpQZGk26Qo1X63H+aMUhSehqg9v+M5A8/pq5MKCRwD6S3Ej
+h8DoK5dmqjOrjfBGsS8Z1az1WsVDlC7EO/BFgTXM349j406Rpe4=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubsubCACRL.pem
new file mode 100644
index 0000000000..34265b943c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy0subsubsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1TCBvgIBATANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTErMCkGA1UEAxMicmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MCBzdWJzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgz
+MDAwWqAvMC0wHwYDVR0jBBgwFoAUtdsE1sggCC9aQcd4o0SJ2s4ua7owCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAChXnVu5rzda6+f2NZ1nWf5qyFfBR3qb
+IwWmBIAATlpil8e/RfSjzkNP2SrKhGi7KDseMn7F6MsHlGp8McNb7ryQcd0+PSUV
+m9hELQcBosZrU/XTdctfTx2/k5mfixlK+UYqz3k7rFfG7RhdkhUexaCQFSCgBgxQ
+RhHlXyP8xpSytC0T6w8gIXxUQjK5jEBwr8uVYhadcCsQnx4I35MXmNUb52BohF3s
+p3pOdgGiCn5CmgcqBa1ybBK5qtKKHav8H6dBzNLeuG9giZC/ALpFhzB0fgkGXXFr
+52zZxy2Z8dN7OWAMTski7B2c363+TwXI7Y/Vuq3qIYLxdcFWix3zefY=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10CACRL.pem
new file mode 100644
index 0000000000..efb8976e4e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEjMCEGA1UEAxMacmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MTAgQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqgLzAt
+MB8GA1UdIwQYMBaAFBnzTATRX9WAR/P4NCwRgeSYz2ufMAoGA1UdFAQDAgEBMA0G
+CSqGSIb3DQEBCwUAA4IBAQALMOPr5blCX12/wmoUiyjhE3KtwudCyjTFeRfWdh1y
+i74p1lKaCtLS2Ccqelr0fuD98PSUvKa37UrWDtj9fXTCgbe0dB2upF/hfkaCEq9b
+vO5HAuBB/hBwR/F1IsQ7qHwDkQA8WhXRfYsrneWfygUtQUzrji/nz0yF5l+GnWWX
+iMID56whZjh/ch6Uvb9qYJO2p4R1KMFJ7G+xKJQm+TsTx6iYIDP2Q8uedSstLasu
++d68KWDFkf8pAXDDgpp4ldUflWbW7Wa7tSHodxE9D9cee4Db7jmXyV7BqQUxYUwF
+9qj1mjdivXtpeTsNKhX0ASsm4jHKmSjKOYvkEALiALq/
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subCACRL.pem
new file mode 100644
index 0000000000..125c24847c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0DCBuQIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEmMCQGA1UEAxMdcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MTAgc3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFqg
+LzAtMB8GA1UdIwQYMBaAFG4YpmEkD2jbLgYRliY3r8l4KVYGMAoGA1UdFAQDAgEB
+MA0GCSqGSIb3DQEBCwUAA4IBAQCZ/4QYxzZaC5BIcXVOv0Pa0KrQdGUx6Ae7knJP
+df/x+IrPcwEHZeD8dQUYnWT7EOvcJBRS3HaI8xD0+n3IFR1+ayaQuV2UCQSu2WbA
+FXx+HRApe5lWOVZsG9vg7V2ccF+8u4qIaLxxTlfOGL3m1FyK8/YXhDfNeOwRukNG
+JxHdfhaqHFtofV3Spa2HcUwKbNAEtu4SAcW55ZV0q/W1tbOBeYwBMNoNMKEVPf8B
+FhJh0ID0xyoFdFIDsj0uNkvNRazAjnUGtz0m7/PZE22qvPH2Bt9gII5UEIbWY4Nv
++Kz6TiXfjZZkl5vR4DHy6qOfQxVDbEuehfRxsBLngKLXzW3r
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubCACRL.pem
new file mode 100644
index 0000000000..7754862b2e
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0zCBvAIBATANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEpMCcGA1UEAxMgcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MTAgc3Vic3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAw
+MFqgLzAtMB8GA1UdIwQYMBaAFFhQTw7y/nIkpNB3P6CWLHe1JOghMAoGA1UdFAQD
+AgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBc9QUsQJu8eEkhD/bB2k137z1Tw2E+SOGM
+InCgU/5FjqgVS8frk2POJXSyTdZonYpJvj3fEuXLp/eViZ0+V3oe31vnFtzeQ9qv
+//rOvJd0b3yOtLFAB58oF5yms/4Zj2ekeWU38HUrQ8lVrT3p0nj7V49ENlaiXwVD
+vhsaTShUxHnVPb5W4nX/uvl6PUWXZLwzWvr3foaAbf0rgV3eWhpjspPlE0ajF0Tk
+ButtK76M4AJocWeWr1AupATbtGU+vvi+I5D7YrBGn7qxF9BvzMiq65H4YHnNfiiF
+iVtgU+GXZxft7+hmVYgX5eQKcDhSQdKKB05U8r2Q5ZRFq8o+b/Vr
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubsubCACRL.pem
new file mode 100644
index 0000000000..caac766953
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy10subsubsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1jCBvwIBATANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEsMCoGA1UEAxMjcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MTAgc3Vic3Vic3ViQ0EXDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4
+MzAwMFqgLzAtMB8GA1UdIwQYMBaAFJaMcfwVqDvO2cT4w9BfaXF86ABLMAoGA1Ud
+FAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBzlq+27lis3jgVun42HmkOAJ9zzdIt
+iyptjiWBCLV5lLA3gbiuroQbr6cKYWhP/qQ91g7MgSzvq/cVwCudSeqIOCJZUwRu
+Kpu6AKkK77GfWA2/GC4ZtIhsHIyA0P0MTa2ygmtxIn0ufluNzgEognWxF4Kdd0F6
+g1sJL547W8byiNlD6KtZ8Oe9PQOr1tevTWvWgSRj2bitAfcwrEBSsyG1eu/Yyeun
+opopG2H28TuBcitgZA7mjicFqzibabUUA+hqZ/X5cL+JiR+84VWc3o5fPFwpdAWr
+09gYI6qG+5O4q7tIyb8d8dIVO+FcKV+mkbZDpFu+3VWRFY4GkBjq98uJ
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2CACRL.pem
new file mode 100644
index 0000000000..acf0e69c78
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MiBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUNqnZ+6o4L6D3TDvZhZ2aFaMtqccwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAD8YETFOSpFWhTbHdjwH+oNciH7CRTbs6UkICQVsnIN4
+xt8m4Pvho9VeU9KNeIvmcaKaJk8HrxbhKlluWFUS/IMk+U6SQ3QSdnxLtJdvC0JT
+iARR9dKR5YX/G0JHJaAO3ULSu8Gaj093TFfQPs2ALcfg5G6BbQmxJ6qCwp/IZ61T
+x71148Lqbb0k2JVZgnnPkhe1k/7no2rjmvu4Zp0BuFkQIwceN908LGSZmuVf09R9
+6FUkYhY5s6tM0rHLLS0JGgCuYyl6RTeD/OemNh4QfA6z6N+WmvAUwzbRWtm/gDOx
+hQq+8Qcc+HErYcZfSg9cgJqRGb1J8KGGd+92uK1wHmo=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2subCACRL.pem
new file mode 100644
index 0000000000..426415e452
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy2subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMccmVxdWlyZUV4cGxp
+Y2l0UG9saWN5MiBzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAv
+MC0wHwYDVR0jBBgwFoAUIHf+TDCN4rNRHY+w9xx/HYOYDkcwCgYDVR0UBAMCAQEw
+DQYJKoZIhvcNAQELBQADggEBAHnk7z+QEkfo+N/q7+bAHDhYCm1ax7Vg1PSs/3WE
+OvoTOp65ghyIX7UdKdmUTpefa89C2PRORNB06xIYzQSeCkCoq7bpTW0hzMfPweY3
+MwlEqnllWldcWgczSOxsomOjJ6os81onh9ZyICGbIZLPL+HZtfPpXKdyw7riGAm3
+h3V0pHznhgcm4XEpe6iHovoFbdmWs73G0vSjLnTyDmSBVjAiEVnZLut10BGyjCRq
+ZQjLcXfXtF1aFymk1p/eN5QLMaNZ59uoGNgsjRQmod7H1Lezp0r53yA1bg9P7yXU
+RsY/pvoiI9j5t3svgZWKC5wuTmJ7nMTwlqaZDS2nWAw3/TE=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4CACRL.pem
new file mode 100644
index 0000000000..c96cbf6314
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NCBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUzdHczNQxYwcsXTaxD42edb5LXmMwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBACOdVMcZUqu3gJlw13ZK7/NcOtSAuvEOVHfjChSXRFkp
+gVhiUJqPQYg0fs6eORxMRc/EyKUTNeKQE/08Q0pN69TSShhHJgrbI0qL+z+1l+OA
+615L/Z658Nv7uKLt0nk/RkguMQw2xIlUEKvC1S/MQAcJAiBKPnSA7fCb93ph053o
+ZOVorML758OWTjvXGykpiJMbxgdS1MQpSRrU3FGST+auQhI4Qet5QpMlA9nfHwgB
+l4lUkF73iHwV8LNHI8t/Pnd5LkKd6XWiDrQRAzhrh/UhmcspUJyFlLIxthO2Az6n
+/FIQMAHm0mvyrgmmZSsw8HCseOgTNCnQEEnWLodqabI=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subCACRL.pem
new file mode 100644
index 0000000000..332b2ec9e5
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMccmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NCBzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAv
+MC0wHwYDVR0jBBgwFoAUfe8OlBe79qeX5tgiSENIrLPuuo0wCgYDVR0UBAMCAQEw
+DQYJKoZIhvcNAQELBQADggEBALIg2yo0C0OaDGoUWWB1PeKkFzO29Zrz7os0w6Ta
+c4W0ufJ/V7W6GTWtNjN2zoVhWe1DJzAivJejwI89ES8kpKJvQ0FIqSmeKk6v7qM6
+gZuhVsvemsw7mb2LVd7t6ismBYCbYTBnoHc/dW+zgHLXNsjHA7aIq3zEzeiJPxgy
+qf4a48BXm8WKQVFLAJv28l/B3nanW2+rYMnEMUBlI7ytGE/gcZ5WB3x8i/NxQAa1
+mBBrHVFyNLJX1pxCmg1myP9dXj1ljlSwRHVgxfYhVcfl5H72cJg/zTQNELpqjlqO
+kM8wXuKpxsFsJpGBOfl3zjeCeFmjOyucmB/CZT3L9h+H9sY=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubCACRL.pem
new file mode 100644
index 0000000000..ab40c50e73
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0jCBuwIBATANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEoMCYGA1UEAxMfcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NCBzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAw
+WqAvMC0wHwYDVR0jBBgwFoAUqerm056wCZev5/4eLhAyoRBnTIYwCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBAD08KCdOiCGTM5PYyFE+HRlYaBd1VnGIFiAb
+fCdTAlEmK+/NxqlrBGqz1zx6O09X4u/XsmvwI5Pi9ujsyxN/aHR16/JBWfUEPKDg
+2a7XOoAyKWO623Z78xWD4DbfQo32vsyDpe2ydCnYiX7qPf3muC7KNROeHMt1QwK0
+/T89l2NJmPBE5+sSCMMZ+8tY1GQgVTeNczO8zzoYcG5XZrKs503sfLvISvcCpre+
+l/LeByAhkJpr+/wlR8+eTrUMpZIhnB8x9uk9hi0YBBbdKmAR8Sqc4U/2yUPFp6ue
+FyF/txO3HXmTNYLFSYo0+G8uEkQCOFQn7BHJOybYH6ertxgKhdQ=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubsubCACRL.pem
new file mode 100644
index 0000000000..986abff429
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy4subsubsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1TCBvgIBATANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTErMCkGA1UEAxMicmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NCBzdWJzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgz
+MDAwWqAvMC0wHwYDVR0jBBgwFoAUFLvRJvSegTyLDhLP2XsVsizcoyEwCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAC0JNUPn/JJeMGuu1cv0PUV36H5zZk3z
+KXq6TT6CRatXHsIRl7bwvsJ2wnkkT4QUM0xeVl8Q50Thm/P81vxVb48w3ahA/mm8
+QtxJwkPK9VPV+jkfAW5vcTVzJZlr9EWhuYgfqC0KdUUiE2omtydtinQhGdI0ooey
+U5XP6voQwf8BKCYOgXxQNJtRE1+W96SifSUQr07fN7gXUp2MgZYwp8QPjFZrX5dH
+FqgmhSv6rdjO9knE/guw21FzA0F5rM6HjNuxre3qont7vlzpI9sx7VzrR4J87meb
+DhRujiMvn1Ge6qwNPGgSnd8P/LsA8kltmewk93W94u74GqfwQCtFtxk=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5CACRL.pem
new file mode 100644
index 0000000000..6b45ed261f
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NSBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUu5GDq66u3lzY4PKQPFz6ny7hOWgwCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAMz51cm+tJdOQUKRaISFOoTqH2PSV3W1i/VLNoo60huI
+wSIOg0YNxG2wXxFH5UdH+SdRacD3qHlAKKyTsWgvhqZgdgbgieS4Nc1CpGnyxeXk
+FCdGt4OJ6mEToXFqJayWwR25ckoJp8k7gpseERoqgDCTPvKjp+1yrznlX8VWTKya
+dgVr+LgSLzCHY8HYekoKcQRbFWbnMBw5K7VE06CLJJIx9kHgDOU+Zqxjy+cilIIb
+HxMmsrxCwKW+ARA/LBiLpn26m9SC/fHstIopRML+1zkbXCoad2VwB9GyvLwzAoqn
+MwJuDzT0G/MZCB4n/s5J/urXFkYBVCQpivlfX9tNUU0=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subCACRL.pem
new file mode 100644
index 0000000000..29a2c67261
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTElMCMGA1UEAxMccmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NSBzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAv
+MC0wHwYDVR0jBBgwFoAUN9O/3txQx6/IiuiSsMRIYfA6BAEwCgYDVR0UBAMCAQEw
+DQYJKoZIhvcNAQELBQADggEBANAIgl9rVP+LLEYRL1+oori60bQTlB1+1LBFItkp
+7BfodwaAGRmWO4GV6phJzxjpi1aKVGuCg7vlwzS+/ns0mlAaghPxpelwd/KACsv1
+AnrbnVR7AW9z6/ipRID0K1V+8EJmjUdD05BjXoyDKP5Jg2v1joSB306Lv7EDGqBh
+babIXd9ZVrMJBFhW8Zp9A/c/P72LrfRkDBi5rhxI8lJeDUPTfQVUGn0nh2MHx2LQ
+vDd++QtcVY+4tPwkiNJiVNBu5dec8DBuGwNcxcZ2FnpExVglJuFf9AXlXPlXs1Ri
+6+WLqQ6sFjS8R0NhYyILqm/JtXO9mKzXAwa53nCXPytwtPk=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubCACRL.pem
new file mode 100644
index 0000000000..9370cde1bf
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0jCBuwIBATANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEoMCYGA1UEAxMfcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NSBzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAw
+WqAvMC0wHwYDVR0jBBgwFoAU+IIvef+0fggC21uvMp3kNWG1bBswCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBABWp0q1/e5b14+ebJrBOiLc2iTt8KlT0ycPq
+EjyoPsQAO6krSC8L+PdSOSv4if2Udf9Xrgrk5zvDIBkVrv7+QlR0A/5kBRukZimS
+L0Q5lCJjpBmvgZRu/c5bYm32iIfJtwwEgXN4fNh3QESi+KGB+IopD9+/TxV8nAWn
+bTqJ3YPGM/tlmkpLHQD7lt7PAHe/ofrkJc8L6ircKUzmZ4vce3HQtQ79rlbyOLxW
+bN7O9mfUymz4SN/gsnll4HpJKrSBTeINssUcCUwpZ6p1IJ0/tmZHpF39HZo1W0ts
+ZB6DWqnOL5lWsw3x/QiKVgvfPjKA1mvqsXVhy/xvNFGT3kyNcC8=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubsubCACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubsubCACRL.pem
new file mode 100644
index 0000000000..db6c01924b
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy5subsubsubCACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB1TCBvgIBATANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTErMCkGA1UEAxMicmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NSBzdWJzdWJzdWJDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgz
+MDAwWqAvMC0wHwYDVR0jBBgwFoAU+mK6vX5eX98fuge+H3k3gtz8EygwCgYDVR0U
+BAMCAQEwDQYJKoZIhvcNAQELBQADggEBAGQii0uxuUm9ok8RNEseRwlN5+lK2R2A
+VZUJ+vZ/O+4ye3x1RIcZ38oWF8zrGZqp6Afos6JbZLSUAGRrbmYowxXCT3vV3yA5
+SBdIoXsByE2Kh6dyeNbB/jDFRNP5rbKcwJJGqXrfnRbHXOOizHPMmWTBscj9lit6
+HIzQhlURn1bHP2GcQ17uBGSYpSVhVV247dlt4+HgReog9NC8D26xPVdnaodtBYvp
+oknWHAcjehSi5kjt4/DJ0Fym3yHGbwpkKWT0A7RXK6cCRWfvJDnGu5vrIKigQo7q
+z4ZIKE1aO2tXJ98dc8M6Z6u1MZDnn3n/9JUAhZPtZ9Gb4eEUU+qgrRk=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7CACRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7CACRL.pem
new file mode 100644
index 0000000000..99d47f5020
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7CACRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIBzDCBtQIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEiMCAGA1UEAxMZcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NyBDQRcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAwWqAvMC0w
+HwYDVR0jBBgwFoAUbDGXATUg3ts15QppWFmIZMwhzkowCgYDVR0UBAMCAQEwDQYJ
+KoZIhvcNAQELBQADggEBAHC+EDnf6+cnW0GTLMwWoISAn/jJ++FGGwmSv7O8st49
+YmlngcgSQdE1CmcLFM8Lsv390rQwtm57E89aLHSpSbVXvAS/ZvyS5yRgoxGJLw5r
+ulwKqAmjzrXPB/0A7mjLwXVxLBZTAqJgnIFW+qE679S4SKLWOsc66HRFsdQmFbwe
+BiF1/V5PbM83sNyN+boyBm1w5YrasEIWLajc+s+gF1dbQTKuDziD52azMegWvfIO
+xqixHCdK+CpIFObodAnW2gPHWTicXYH+ZwagtqQbI2EM7SdnbvQQe68frsfqK1k/
+SGXl0LfQl3/GmYynOg46FDf53/oRxz0bwsEa8XBpXpY=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subCARE2CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subCARE2CRL.pem
new file mode 100644
index 0000000000..dd8aaf35a7
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subCARE2CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB0jCBuwIBATANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEoMCYGA1UEAxMfcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NyBzdWJDQVJFMhcNMTAwMTAxMDgzMDAwWhcNMzAxMjMxMDgzMDAw
+WqAvMC0wHwYDVR0jBBgwFoAU51wljn6qTHeDe8PqadbHojThNFkwCgYDVR0UBAMC
+AQEwDQYJKoZIhvcNAQELBQADggEBACgCaW8g9ZHgkL+vcByM70Ao9B8BhlunjYHK
+905EiAQQ3OqjJzEE5YRp0uhrbChY1xoHKAjE45VIhK1aADKyV5Wt+ugBAoFLAPcN
+9FQwvTEBjUwZPCQaV54hyt/PrDBh8GJxnTpLnEb/+gl/hu2P1tDD0Zqb4BPoOxur
+abZ0PpzSCPHJdQq75RX/KZCEkaOsa4wHslFHXJXlLLh5vRqvrM23NDsY9lsNb9+3
+3mSVngQWhqVJNdFsMJisyzq88Iv3cSmgzD4oowE05khNWWhpbgxtdMYGWVqN2qEg
+EDI3oExT5CeehzLWuI7dnhKZVJl7y68n1s7KHKJtMb9vnGsiNZ4=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubCARE2RE4CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubCARE2RE4CRL.pem
new file mode 100644
index 0000000000..cce599a5fb
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubCARE2RE4CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEuMCwGA1UEAxMlcmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NyBzdWJzdWJDQVJFMlJFNBcNMTAwMTAxMDgzMDAwWhcNMzAxMjMx
+MDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUbv+NCItm/pule/tkM2XqA5VIlJgwCgYD
+VR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBADsVgmLjUlCjkqyM30ho6gvaBfoZ
+3IEMbL01Z1YWCVL/M7dkcp2H98jCurGWlEQCqlx8gXZRrrO8u7rtpHKu0oUuCcrC
+6bxljOwBRgdv0TnNB3k+FrXcaBT7/SJtGhLwjh0smLC69eI42quLSEXXHhlpmYiJ
+1cOQwPCtd+KHbeDMoKi6j7HbFD3OR7jH+OsbnwMpWdlyhDeZlXXh5vbLXtN/j6VH
+9TWdi/Tt6z049i5YcCL2l5Kq9Mp/Y2DRpLQAycHpYL+/U8yOyUq3A3MYO/fdWo1k
+H0nSPreisWgBkSD/u11jR/hPbEH9SXv2nflBaRg/9kSoAbuDknlvrLGxwbQ=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubsubCARE2RE4CRL.pem b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubsubCARE2RE4CRL.pem
new file mode 100644
index 0000000000..bd1656505c
--- /dev/null
+++ b/lib/public_key/test/pkits_SUITE_data/pkits/crls/requireExplicitPolicy7subsubsubCARE2RE4CRL.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2zCBxAIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEfMB0GA1UE
+ChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTExMC8GA1UEAxMocmVxdWlyZUV4cGxp
+Y2l0UG9saWN5NyBzdWJzdWJzdWJDQVJFMlJFNBcNMTAwMTAxMDgzMDAwWhcNMzAx
+MjMxMDgzMDAwWqAvMC0wHwYDVR0jBBgwFoAUeyxRYTEVrawsa6m+OzsYGpKqf0Qw
+CgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADggEBAKC0+mcSVMrZw/Yabdg8xvnX
+VJrufKnwa2sdt5WXbKX73DCh2OvTm5gJg61AkjghRN4W1VfHpQqc6lsrWHlFK+6r
+GbsL/og+JwfDgiHr+xLf9hmxlS2Uu+TK1HYUVGw/VNLoLPqre1tq4ag4W7re2Z3g
+BBZ8OyS0aUcMYpI1rp9/+PWOYo/9cEDFK2zlsIazYl0Nk8Jz8xWVzFP4gf5RXb5i
+ejUZI578baWPUfUUnEQMSqiKJmHNxPyY6REVUEFkMDu5dOlCu0GfsLBw61am3hGQ
+XvILnAB1SRdyO5uNlJLkRh9EB5aUDRUC5HydfiaSTzb0gkzdKgCRjUUsUjovcPg=
+-----END X509 CRL-----
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 2b83bc0a5c..ea48479f0b 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -20,85 +20,19 @@
%%
-module(public_key_SUITE).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
%% Note: This directive should only be used in test suites.
-compile(export_all).
-%%-include_lib("common_test/include/ct.hrl").
--include_lib("test_server/include/test_server.hrl").
-
--include_lib("public_key/include/public_key.hrl").
-
-define(TIMEOUT, 120000). % 2 min
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% Function: init_per_suite(Config) -> Config
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Initialization before the whole suite
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- try crypto:start() of
- ok ->
- Config
- catch _:_ ->
- {skip, "Crypto did not start"}
- end.
-%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config) -> _
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after the whole suite
-%%--------------------------------------------------------------------
-end_per_suite(_Config) ->
- application:stop(crypto).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, Config) -> Config
-%% Case - atom()
-%% Name of the test case that is about to be run.
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%%
-%% Description: Initialization before each test case
-%%
-%% Note: This function is free to add any key/value pairs to the Config
-%% variable, but should NOT alter/remove any existing entries.
-%% Description: Initialization before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config0) ->
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = test_server:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, Config) -> _
-%% Case - atom()
-%% Name of the test case that is about to be run.
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after each test case
+%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-end_per_testcase(_TestCase, Config) ->
- Dog = ?config(watchdog, Config),
- case Dog of
- undefined ->
- ok;
- _ ->
- test_server:timetrap_cancel(Dog)
- end.
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
@@ -119,30 +53,46 @@ groups() ->
ssh_openssh_public_key_long_header]},
{sign_verify, [], [rsa_sign_verify, dsa_sign_verify]}
].
+%%-------------------------------------------------------------------
+init_per_suite(Config) ->
+ try crypto:start() of
+ ok ->
+ Config
+ 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(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ct:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
-%% Test cases starts here.
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-app(doc) ->
- "Test that the public_key app file is ok";
-app(suite) ->
- [];
+app() ->
+ [{doc, "Test that the public_key app file is ok"}].
app(Config) when is_list(Config) ->
- ok = test_server:app_test(public_key).
+ ok = ?t:app_test(public_key).
%%--------------------------------------------------------------------
-dsa_pem(doc) ->
- [""];
-dsa_pem(suite) ->
- [];
+dsa_pem() ->
+ [{doc, "DSA PEM-file decode/encode"}].
dsa_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -164,10 +114,8 @@ dsa_pem(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-rsa_pem(doc) ->
- [""];
-rsa_pem(suite) ->
- [];
+rsa_pem() ->
+ [{doc, "RSA PEM-file decode/encode"}].
rsa_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
[{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry0 ] =
@@ -201,10 +149,8 @@ rsa_pem(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-encrypted_pem(doc) ->
- [""];
-encrypted_pem(suite) ->
- [];
+encrypted_pem() ->
+ [{doc, "Encrypted PEM-file decode/encode"}].
encrypted_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -234,10 +180,8 @@ encrypted_pem(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-dh_pem(doc) ->
- [""];
-dh_pem(suite) ->
- [];
+dh_pem() ->
+ [{doc, "DH parametrs PEM-file decode/encode"}].
dh_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
[{'DHParameter', DerDH, not_encrypted} = Entry] =
@@ -252,10 +196,8 @@ dh_pem(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-pkcs10_pem(doc) ->
- [""];
-pkcs10_pem(suite) ->
- [];
+pkcs10_pem() ->
+ [{doc, "PKCS-10 PEM-file decode/encode"}].
pkcs10_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
[{'CertificationRequest', DerPKCS10, not_encrypted} = Entry] =
@@ -269,10 +211,8 @@ pkcs10_pem(Config) when is_list(Config) ->
Entry = public_key:pem_entry_encode('CertificationRequest', PKCS10).
%%--------------------------------------------------------------------
-pkcs7_pem(doc) ->
- [""];
-pkcs7_pem(suite) ->
- [];
+pkcs7_pem() ->
+ [{doc, "PKCS-7 PEM-file decode/encode"}].
pkcs7_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
[{'ContentInfo', DerPKCS7, not_encrypted} = Entry] =
@@ -286,10 +226,8 @@ pkcs7_pem(Config) when is_list(Config) ->
Entry = public_key:pem_entry_encode('ContentInfo', PKCS7).
%%--------------------------------------------------------------------
-cert_pem(doc) ->
- [""];
-cert_pem(suite) ->
- [];
+cert_pem() ->
+ [{doc, "Certificate PEM-file decode/encode"}].
cert_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -315,10 +253,8 @@ cert_pem(Config) when is_list(Config) ->
[Entry0] = erl_make_certs:pem_to_der(filename:join(Datadir, "wdsa.pem")).
%%--------------------------------------------------------------------
-ssh_rsa_public_key(doc) ->
- "";
-ssh_rsa_public_key(suite) ->
- [];
+ssh_rsa_public_key() ->
+ [{doc, "ssh rsa public key decode/encode"}].
ssh_rsa_public_key(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -343,10 +279,8 @@ ssh_rsa_public_key(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-ssh_dsa_public_key(doc) ->
- "";
-ssh_dsa_public_key(suite) ->
- [];
+ssh_dsa_public_key() ->
+ [{doc, "ssh dsa public key decode/encode"}].
ssh_dsa_public_key(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -370,10 +304,8 @@ ssh_dsa_public_key(Config) when is_list(Config) ->
public_key:ssh_decode(EncodedOpenSsh, public_key).
%%--------------------------------------------------------------------
-ssh_rfc4716_rsa_comment(doc) ->
- "Test comment header and rsa key";
-ssh_rfc4716_rsa_comment(suite) ->
- [];
+ssh_rfc4716_rsa_comment() ->
+ [{doc, "Test comment header and rsa key"}].
ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -388,10 +320,8 @@ ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
RSARawSsh2 = public_key:ssh_encode([{PubKey, Attributes}], rfc4716_public_key).
%%--------------------------------------------------------------------
-ssh_rfc4716_dsa_comment(doc) ->
- "Test comment header and dsa key";
-ssh_rfc4716_dsa_comment(suite) ->
- [];
+ssh_rfc4716_dsa_comment() ->
+ [{doc, "Test comment header and dsa key"}].
ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -410,10 +340,8 @@ ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
public_key:ssh_decode(Encoded, public_key).
%%--------------------------------------------------------------------
-ssh_rfc4716_rsa_subject(doc) ->
- "Test another header value than comment";
-ssh_rfc4716_rsa_subject(suite) ->
- [];
+ssh_rfc4716_rsa_subject() ->
+ [{doc, "Test another header value than comment"}].
ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -432,10 +360,8 @@ ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
public_key:ssh_decode(Encoded, public_key).
%%--------------------------------------------------------------------
-ssh_known_hosts(doc) ->
- "";
-ssh_known_hosts(suite) ->
- [];
+ssh_known_hosts() ->
+ [{doc, "ssh known hosts file encode/decode"}].
ssh_known_hosts(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -463,10 +389,8 @@ ssh_known_hosts(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-ssh1_known_hosts(doc) ->
- "";
-ssh1_known_hosts(suite) ->
- [];
+ssh1_known_hosts() ->
+ [{doc, "ssh (ver 1) known hosts file encode/decode"}].
ssh1_known_hosts(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -485,10 +409,8 @@ ssh1_known_hosts(Config) when is_list(Config) ->
Decoded = public_key:ssh_decode(Encoded, known_hosts).
%%--------------------------------------------------------------------
-ssh_auth_keys(doc) ->
- "";
-ssh_auth_keys(suite) ->
- [];
+ssh_auth_keys() ->
+ [{doc, "ssh authorized keys file encode/decode"}].
ssh_auth_keys(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -513,10 +435,8 @@ ssh_auth_keys(Config) when is_list(Config) ->
Decoded = public_key:ssh_decode(Encoded, auth_keys).
%%--------------------------------------------------------------------
-ssh1_auth_keys(doc) ->
- "";
-ssh1_auth_keys(suite) ->
- [];
+ssh1_auth_keys() ->
+ [{doc, "ssh (ver 1) authorized keys file encode/decode"}].
ssh1_auth_keys(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -543,10 +463,8 @@ ssh1_auth_keys(Config) when is_list(Config) ->
Decoded = public_key:ssh_decode(Encoded, auth_keys).
%%--------------------------------------------------------------------
-ssh_openssh_public_key_with_comment(doc) ->
- "Test that emty lines and lines starting with # are ignored";
-ssh_openssh_public_key_with_comment(suite) ->
- [];
+ssh_openssh_public_key_with_comment() ->
+ [{doc, "Test that emty lines and lines starting with # are ignored"}].
ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -554,10 +472,8 @@ ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
[{{_, #'Dss-Parms'{}}, _}] = public_key:ssh_decode(DSARawOpenSsh, openssh_public_key).
%%--------------------------------------------------------------------
-ssh_openssh_public_key_long_header(doc) ->
- "Test that long headers are handled";
-ssh_openssh_public_key_long_header(suite) ->
- [];
+ssh_openssh_public_key_long_header() ->
+ [{doc, "Test that long headers are handled"}].
ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
@@ -568,10 +484,8 @@ ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
Decoded = public_key:ssh_decode(Encoded, rfc4716_public_key).
%%--------------------------------------------------------------------
-encrypt_decrypt(doc) ->
- [""];
-encrypt_decrypt(suite) ->
- [];
+encrypt_decrypt() ->
+ [{doc, "Test public_key:encrypt_private and public_key:decrypt_public"}].
encrypt_decrypt(Config) when is_list(Config) ->
{PrivateKey, _DerKey} = erl_make_certs:gen_rsa(64),
#'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = PrivateKey,
@@ -588,10 +502,8 @@ encrypt_decrypt(Config) when is_list(Config) ->
ok.
%%--------------------------------------------------------------------
-rsa_sign_verify(doc) ->
- ["Checks that we can sign and verify rsa signatures."];
-rsa_sign_verify(suite) ->
- [];
+rsa_sign_verify() ->
+ [{doc, "Checks that we can sign and verify rsa signatures."}].
rsa_sign_verify(Config) when is_list(Config) ->
Ca = {_, CaKey} = erl_make_certs:make_cert([]),
{Cert1, _} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]),
@@ -611,10 +523,8 @@ rsa_sign_verify(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-dsa_sign_verify(doc) ->
- ["Checks that we can sign and verify dsa signatures."];
-dsa_sign_verify(suite) ->
- [];
+dsa_sign_verify() ->
+ [{doc, "Checks that we can sign and verify dsa signatures."}].
dsa_sign_verify(Config) when is_list(Config) ->
Ca = erl_make_certs:make_cert([]),
CertInfo = {_,CertKey1} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]),
@@ -650,10 +560,8 @@ dsa_sign_verify(Config) when is_list(Config) ->
{DSAPublicKey, DSAParams}).
%%--------------------------------------------------------------------
-pkix(doc) ->
- "Misc pkix tests not covered elsewhere";
-pkix(suite) ->
- [];
+pkix() ->
+ [{doc, "Misc pkix tests not covered elsewhere"}].
pkix(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
Certs0 = erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")),
@@ -691,17 +599,15 @@ pkix(Config) when is_list(Config) ->
[[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"ERLANGCA"}}],
[{'AttributeTypeAndValue', {2,5,4,3},{printableString," erlang ca "}}]]},
VerifyStr = {rdnSequence,
- [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlang ca"}}],
- [{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlangca"}}]]},
+ [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlangca"}}],
+ [{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlang ca"}}]]},
VerifyStr = public_key:pkix_normalize_name(TestStr),
ok.
%%--------------------------------------------------------------------
-pkix_countryname(doc) ->
- "Test workaround for certs that code x509countryname as utf8";
-pkix_countryname(suite) ->
- [];
+pkix_countryname() ->
+ [{doc, "Test workaround for certs that code x509countryname as utf8"}].
pkix_countryname(Config) when is_list(Config) ->
Cert = incorrect_pkix_cert(),
OTPCert = public_key:pkix_decode_cert(Cert, otp),
@@ -711,24 +617,9 @@ pkix_countryname(Config) when is_list(Config) ->
check_countryname(Issuer),
check_countryname(Subj).
-check_countryname({rdnSequence,DirName}) ->
- do_check_countryname(DirName).
-do_check_countryname([]) ->
- ok;
-do_check_countryname([#'AttributeTypeAndValue'{type = ?'id-at-countryName',
- value = "US"}|_]) ->
- ok;
-do_check_countryname([#'AttributeTypeAndValue'{type = ?'id-at-countryName',
- value = Value}|_]) ->
- test_server:fail({incorrect_cuntry_name, Value});
-do_check_countryname([_| Rest]) ->
- do_check_countryname(Rest).
-
%%--------------------------------------------------------------------
-pkix_path_validation(doc) ->
- "Misc pkix tests not covered elsewhere";
-pkix_path_validation(suite) ->
- [];
+pkix_path_validation() ->
+ [{doc, "Test PKIX path validation"}].
pkix_path_validation(Config) when is_list(Config) ->
CaK = {Trusted,_} =
erl_make_certs:make_cert([{key, dsa},
@@ -759,7 +650,8 @@ pkix_path_validation(Config) when is_list(Config) ->
CertK3 = {Cert3,_} = erl_make_certs:make_cert([{issuer, CertK1},
{extensions, [{basic_constraints, false}]}]),
- {Cert4,_} = erl_make_certs:make_cert([{issuer, CertK3}]),
+ {Cert4,_} = erl_make_certs:make_cert([{issuer, CertK3}, {extensions, [{key_usage, undefined}]}]),
+
{error, {bad_cert,missing_basic_constraint}} =
public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], []),
@@ -796,6 +688,21 @@ pkix_path_validation(Config) when is_list(Config) ->
public_key:pkix_path_validation(unknown_ca, [Cert1], [{verify_fun,
VerifyFunAndState1}]),
ok.
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+check_countryname({rdnSequence,DirName}) ->
+ do_check_countryname(DirName).
+do_check_countryname([]) ->
+ ok;
+do_check_countryname([#'AttributeTypeAndValue'{type = ?'id-at-countryName',
+ value = "US"}|_]) ->
+ ok;
+do_check_countryname([#'AttributeTypeAndValue'{type = ?'id-at-countryName',
+ value = Value}|_]) ->
+ ct:fail({incorrect_cuntry_name, Value});
+do_check_countryname([_| Rest]) ->
+ do_check_countryname(Rest).
check_entry_type(#'DSAPrivateKey'{}, 'DSAPrivateKey') ->
true;
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index b8af89d040..bd20a5546b 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 0.17
+PUBLIC_KEY_VSN = 0.18
diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile
index a7e34053f1..3c67bca1d6 100644
--- a/lib/reltool/src/Makefile
+++ b/lib/reltool/src/Makefile
@@ -57,7 +57,8 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
ERL_COMPILE_FLAGS += +'{parse_transform,sys_pre_attributes}' \
- +'{attribute,insert,app_vsn,$(APP_VSN)}'
+ +'{attribute,insert,app_vsn,$(APP_VSN)}' \
+ -Werror
# ----------------------------------------------------
# Targets
@@ -79,10 +80,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Dependencies
diff --git a/lib/runtime_tools/c_src/Makefile.in b/lib/runtime_tools/c_src/Makefile.in
index 586f649924..d315a90e18 100644
--- a/lib/runtime_tools/c_src/Makefile.in
+++ b/lib/runtime_tools/c_src/Makefile.in
@@ -111,11 +111,11 @@ debug opt valgrind: $(SOLIBS) $(OBJDIR) $(LIBDIR) $(NIF_LIB)
ifdef DTRACE_ENABLED
DTRACE_USER_HEADER=$(OBJDIR)/dtrace_user.h
$(OBJDIR)/dtrace_user.h: ./dtrace_user.d
- dtrace -h -C $(INCLUDES) \
+ $(dtrace_verbose)dtrace -h -C $(INCLUDES) \
-s ./dtrace_user.d \
-o ./dtrace_user.tmp
- sed -e '/^#define[ ]*ERLANG_[A-Z0-9_]*(.*)/y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' ./dtrace_user.tmp > $@
- rm ./dtrace_user.tmp
+ $(V_at)sed -e '/^#define[ ]*ERLANG_[A-Z0-9_]*(.*)/y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' ./dtrace_user.tmp > $@
+ $(V_at)rm ./dtrace_user.tmp
else
DTRACE_USER_HEADER=
endif
@@ -124,7 +124,7 @@ DTRACE_OBJS =
ifdef DTRACE_ENABLED_2STEP
DTRACE_OBJS += $(OBJDIR)/dtrace_user.o
$(OBJDIR)/dtrace_user.o: $(before_DTrace_OBJS) $(OBJDIR)/dtrace_user.h
- dtrace -G -C \
+ $(dtrace_verbose)dtrace -G -C \
-s ./dtrace_user.d \
-o $@ $(before_DTrace_OBJS)
endif
@@ -138,26 +138,26 @@ $(LIBDIR):
-@mkdir -p $(LIBDIR)
$(OBJDIR)/dyntrace$(TYPEMARKER).o: dyntrace.c $(DTRACE_USER_HEADER)
- $(INSTALL_DIR) $(OBJDIR)
- $(CC) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_at)$(INSTALL_DIR) $(OBJDIR)
+ $(V_CC) -c -o $@ $(ALL_CFLAGS) $<
$(NIF_LIB): $(DYNTRACE_OBJS)
- $(INSTALL_DIR) $(LIBDIR)
- $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+ $(V_at)$(INSTALL_DIR) $(LIBDIR)
+ $(V_LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(OBJDIR)/%.o: %.c
- $(CC) -c -o $@ $(ALL_CFLAGS) $<
+ $(V_CC) -c -o $@ $(ALL_CFLAGS) $<
$(LIBDIR)/trace_ip_drv.so: $(TRACE_IP_DRV_OBJS)
- $(LD) $(LDFLAGS) -o $@ $^ -lc $(LIBS)
+ $(V_LD) $(LDFLAGS) -o $@ $^ -lc $(LIBS)
$(LIBDIR)/trace_file_drv.so: $(TRACE_FILE_DRV_OBJS)
- $(LD) $(LDFLAGS) -o $@ $^ -lc $(LIBS)
+ $(V_LD) $(LDFLAGS) -o $@ $^ -lc $(LIBS)
$(LIBDIR)/trace_ip_drv.dll: $(TRACE_IP_DRV_OBJS)
- $(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
+ $(V_LD) $(LDFLAGS) -o $@ $^ $(LIBS)
$(LIBDIR)/trace_file_drv.dll: $(TRACE_FILE_DRV_OBJS)
- $(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
+ $(V_LD) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
rm -f $(SOLIBS) $(TRACE_IP_DRV_OBJS) $(TRACE_FILE_DRV_OBJS)
diff --git a/lib/runtime_tools/src/Makefile b/lib/runtime_tools/src/Makefile
index 4ca37ab0bf..9809004638 100644
--- a/lib/runtime_tools/src/Makefile
+++ b/lib/runtime_tools/src/Makefile
@@ -68,7 +68,8 @@ EXAMPLE_FILES= \
ERL_COMPILE_FLAGS += \
-I../include \
-I ../../et/include \
- -I ../../../libraries/et/include
+ -I ../../../libraries/et/include \
+ -Werror
# ----------------------------------------------------
# Targets
@@ -81,10 +82,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/runtime_tools/src/runtime_tools_sup.erl b/lib/runtime_tools/src/runtime_tools_sup.erl
index 264e172a3c..e8ea08ec97 100644
--- a/lib/runtime_tools/src/runtime_tools_sup.erl
+++ b/lib/runtime_tools/src/runtime_tools_sup.erl
@@ -34,7 +34,7 @@
%% The runtime tools top most supervisor starts:
%% -The ttb_autostart component. This is used for tracing at startup
%% using observer/ttb.
-init(AutoModArgs) ->
+init(_AutoModArgs) ->
Flags = {one_for_one, 0, 3600},
Children = [{ttb_autostart, {ttb_autostart, start_link, []},
temporary, 3000, worker, [ttb_autostart]}],
diff --git a/lib/sasl/src/Makefile b/lib/sasl/src/Makefile
index de0c45e6ae..4daa6e9861 100644
--- a/lib/sasl/src/Makefile
+++ b/lib/sasl/src/Makefile
@@ -60,7 +60,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I../../stdlib/include
+ERL_COMPILE_FLAGS += -I../../stdlib/include -Werror
# ----------------------------------------------------
@@ -80,10 +80,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index 94cffc988d..82b7a738bb 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -938,7 +938,7 @@ otp_9417(cleanup,_Conf) ->
%% OTP-9395 - performance problems when there are MANY processes
%% Test that the procedure of checking for old code before an upgrade
-%% can be started is "very much faster" when there is no old code in
+%% can be started is faster when there is no old code in
%% the system.
otp_9395_check_old_code(Conf) when is_list(Conf) ->
@@ -978,8 +978,8 @@ otp_9395_check_old_code(Conf) when is_list(Conf) ->
"\tAfter purge: ~.2f sec~n"
"\tT1/T2: ~.2f",
[NProcs,length(Modules),T1/1000000,T2/1000000,X]),
- if X < 1000 ->
- ct:fail({not_enough_improvement_after_purge,round(X)});
+ if X < 1 ->
+ ct:fail({no_improvement_after_purge,X});
true ->
ok
end;
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile
index 8820565124..6e55498669 100644
--- a/lib/snmp/doc/src/Makefile
+++ b/lib/snmp/doc/src/Makefile
@@ -118,7 +118,7 @@ clean clean_docs: clean_html clean_man clean_pdf
rm -f errs core *~
$(INDEX_TARGET): $(INDEX_SRC) ../../vsn.mk # Create top make file
- sed -e 's;%VSN%;$(VSN);' $< > $@ # inserting version number
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@ # inserting version number
man: man1 man3 man6 man7
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index b6b8751f6c..5b94dcb051 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2012</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -34,6 +34,86 @@
<section>
+ <title>SNMP Development Toolkit 4.23</title>
+<!--
+ <p>Version 4.23 supports code replacement in runtime from/to
+ version 4.22.1,
+ 4.22, 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and 4.21. </p>
+-->
+
+ <section>
+ <title>Improvements and new features</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>[manager] Polish return values of snmpm_user_default according
+ to snmpm_user doc.</p>
+ <p>Luca Favatella</p>
+ <p>Own Id: OTP-10671</p>
+ </item>
+
+ <item>
+ <p>[agent] Remove runtime warning in snmpa_agent because of
+ tuple fun usage. </p>
+ <p>Luca Favatella</p>
+ <p>Own Id: OTP-10672</p>
+ </item>
+
+ <item>
+ <p>[manager] SNMP manager performance optimization. </p>
+ <p>Ivan Dubovik</p>
+ <p>Own Id: OTP-10673</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+
+ <!--
+ <list type="bulleted">
+ <item>
+ <p>[agent] Simultaneous
+ <seealso marker="snmpa#backup">snmpa:backup/1,2</seealso>
+ calls can interfere.
+ The master agent did not check if a backup was already in
+ progress when a backup request was accepted. </p>
+ <p>Own Id: OTP-9884</p>
+ <p>Aux Id: Seq 11995</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> <!-- 4.23 -->
+
+
+ <section>
<title>SNMP Development Toolkit 4.22.1</title>
<p>Version 4.22.1 supports code replacement in runtime from/to
version 4.22, 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and
@@ -126,70 +206,6 @@
<section>
- <title>SNMP Development Toolkit 4.23</title>
- <p>Version 4.23 supports code replacement in runtime from/to
- version 4.22,
- 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and 4.21. </p>
-
- <section>
- <title>Improvements and new features</title>
- <p>-</p>
-
-<!--
- <list type="bulleted">
- <item>
- <p>[agent] Documenting previously existing but undocumented function,
- <seealso marker="snmp_generic#get_table_info">snmp_generic:get_table_info/2</seealso>. </p>
- <p>Own Id: OTP-9942</p>
- </item>
-
- </list>
--->
-
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <p>-</p>
-
- <!--
- <list type="bulleted">
- <item>
- <p>[agent] Simultaneous
- <seealso marker="snmpa#backup">snmpa:backup/1,2</seealso>
- calls can interfere.
- The master agent did not check if a backup was already in
- progress when a backup request was accepted. </p>
- <p>Own Id: OTP-9884</p>
- <p>Aux Id: Seq 11995</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> <!-- 4.23 -->
-
-
- <section>
<title>SNMP Development Toolkit 4.22</title>
<p>Version 4.22 supports code replacement in runtime from/to
version 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and 4.21. </p>
diff --git a/lib/snmp/mibs/Makefile.in b/lib/snmp/mibs/Makefile.in
index 5c1f855fad..e7ca540cc6 100644
--- a/lib/snmp/mibs/Makefile.in
+++ b/lib/snmp/mibs/Makefile.in
@@ -141,11 +141,11 @@ OTP_MIBDIR = $(shell if test -d ../../otp_mibs; then echo otp_mibs; \
debug opt: $(TARGET_FILES)
$(ERL_TOP)/lib/snmp/bin/snmp-v2tov1: $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1.src
- $(PERL) -p -e 's?%PERL%?$(PERL)? ' < $< > $@
- chmod 755 $@
+ $(gen_verbose)$(PERL) -p -e 's?%PERL%?$(PERL)? ' < $< > $@
+ $(V_at)chmod 755 $@
$(SNMP_BIN_TARGET_DIR)/OTP-REG.bin: $(ERL_TOP)/lib/$(OTP_MIBDIR)/mibs/OTP-REG.mib
- $(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
+ $(snmp_verbose)$(ERLC) -pa $(SNMP_TOOLKIT)/ebin -I $(SNMP_TOOLKIT)/priv/mibs $(SNMP_FLAGS) -o $(SNMP_BIN_TARGET_DIR) $<
# To support parallel make, we'll need explicit dependencies
# to ensure that an imported MIB has been compiled when it's needed.
@@ -214,7 +214,7 @@ info:
@echo "RELSYSDIR = "$(RELSYSDIR)""
v1/%.mib.v1: %.mib $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1
- $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $<
+ $(gen_verbose)$(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $<
# ----------------------------------------------------
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index 9d30e332f1..57846db13b 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-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -1134,7 +1134,7 @@ handle_call({get, Vars, Context}, _From, S) ->
"~n Vars: ~p"
"~n Context: ~p", [Vars, Context]),
put_pdu_data({undefined, undefined, undefined, undefined, Context}),
- case catch mapfoldl({?MODULE, tr_var}, [], 1, Vars) of
+ case catch mapfoldl(fun ?MODULE:tr_var/2, [], 1, Vars) of
{error, Reason} -> {reply, {error, Reason}, S};
{_, Varbinds} ->
?vdebug("Varbinds: ~p",[Varbinds]),
@@ -1155,7 +1155,7 @@ handle_call({get_next, Vars, Context}, _From, S) ->
"~n Vars: ~p"
"~n Context: ~p",[Vars, Context]),
put_pdu_data({undefined, undefined, undefined, undefined, Context}),
- case catch mapfoldl({?MODULE, tr_var}, [], 1, Vars) of
+ case catch mapfoldl(fun ?MODULE:tr_var/2, [], 1, Vars) of
{error, Reason} -> {reply, {error, Reason}, S};
{_, Varbinds} ->
?vdebug("Varbinds: ~p",[Varbinds]),
diff --git a/lib/snmp/src/app/Makefile b/lib/snmp/src/app/Makefile
index f7c311b663..716add8b9e 100644
--- a/lib/snmp/src/app/Makefile
+++ b/lib/snmp/src/app/Makefile
@@ -116,10 +116,10 @@ info:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 593ddd82bd..a6abf8439a 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -22,582 +22,12 @@
%% ----- U p g r a d e -------------------------------------------------------
[
- {"4.22",
- [
- {load_module, snmpm, soft_purge, soft_purge, []},
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}
- ]
- },
- {"4.21.7",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21.6",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21.5",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21.4",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21.3",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21.2",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, []},
- {load_module, snmpa_set_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21.1",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, []},
- {load_module, snmpa_set_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {update, snmp_note_store, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- },
- {"4.21",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, []},
- {load_module, snmpa_set_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {update, snmp_note_store, soft, soft_purge, soft_purge, []},
-
- {add_module, snmpm_net_if_mt}
- ]
- }
],
%% ------D o w n g r a d e ---------------------------------------------------
[
- {"4.22",
- [
- {load_module, snmpm, soft_purge, soft_purge, []},
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}
- ]
- },
- {"4.21.7",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21.6",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21.5",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21.4",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21.3",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21.2",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, []},
- {load_module, snmpa_set_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21.1",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, []},
- {load_module, snmpa_set_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {update, snmp_note_store, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- },
- {"4.21",
- [
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
-
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]},
-
- {load_module, snmp, soft_purge, soft_purge, [snmp_log]},
- {load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
- {load_module, snmpm_mpd, soft_purge, soft_purge, []},
-
- {load_module, snmpa, soft_purge, soft_purge, [snmp]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
- {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
-
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, []},
- {load_module, snmpa_set_lib, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge, []},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmp_conf, snmpa_mib_lib]},
- {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []},
- {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
- {update, snmpa_mib, soft, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {update, snmp_note_store, soft, soft_purge, soft_purge, []},
-
- {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
- ]
- }
]
+
}.
diff --git a/lib/snmp/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk
index 3ee8dc4bec..e6ba1ac810 100644
--- a/lib/snmp/src/compile/depend.mk
+++ b/lib/snmp/src/compile/depend.mk
@@ -45,5 +45,5 @@ $(EBIN)/snmpc_mib_gram.$(EMULATOR): \
snmpc_mib_gram.erl
$(BIN)/snmpc: snmpc.src ../../vsn.mk
- $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
- chmod 755 $@
+ $(vsn_verbose)$(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
+ $(V_at)chmod 755 $@
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 484954addb..61d22362cc 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-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2004-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
@@ -3163,17 +3163,16 @@ request_id() ->
%%----------------------------------------------------------------------
agent_data(TargetName, SendOpts) ->
- case snmpm_config:agent_info(TargetName, all) of
- {ok, Info} ->
- Version = agent_data_item(version, Info),
+ case snmpm_config:agent_info(TargetName, version) of
+ {ok, Version} ->
MsgData =
case Version of
v3 ->
- DefSecModel = agent_data_item(sec_model, Info),
- DefSecName = agent_data_item(sec_name, Info),
- DefSecLevel = agent_data_item(sec_level, Info),
+ DefSecModel = agent_data_item(sec_model, TargetName),
+ DefSecName = agent_data_item(sec_name, TargetName),
+ DefSecLevel = agent_data_item(sec_level, TargetName),
- EngineId = agent_data_item(engine_id, Info),
+ EngineId = agent_data_item(engine_id, TargetName),
CtxName = agent_data_item(context,
SendOpts,
?DEFAULT_CONTEXT),
@@ -3191,8 +3190,8 @@ agent_data(TargetName, SendOpts) ->
{SecModel, SecName, mk_sec_level_flag(SecLevel),
EngineId, CtxName, TargetName};
_ ->
- DefComm = agent_data_item(community, Info),
- DefSecModel = agent_data_item(sec_model, Info),
+ DefComm = agent_data_item(community, TargetName),
+ DefSecModel = agent_data_item(sec_model, TargetName),
Comm = agent_data_item(community,
SendOpts,
@@ -3203,21 +3202,21 @@ agent_data(TargetName, SendOpts) ->
{Comm, SecModel}
end,
- Domain = agent_data_item(tdomain, Info),
- Addr = agent_data_item(address, Info),
- Port = agent_data_item(port, Info),
- RegType = agent_data_item(reg_type, Info),
+ Domain = agent_data_item(tdomain, TargetName),
+ Addr = agent_data_item(address, TargetName),
+ Port = agent_data_item(port, TargetName),
+ RegType = agent_data_item(reg_type, TargetName),
{ok, RegType, Domain, Addr, Port, version(Version), MsgData};
Error ->
Error
end.
-agent_data_item(Item, Info) ->
- case lists:keysearch(Item, 1, Info) of
- {value, {_, Val}} ->
+agent_data_item(Item, TargetName) ->
+ case snmpm_config:agent_info(TargetName, Item) of
+ {ok, Val} ->
Val;
- false ->
- throw({error, {not_found, Item, Info}})
+ {error, not_found} ->
+ throw({error, {not_found, Item, TargetName}})
end.
agent_data_item(Item, Info, Default) ->
diff --git a/lib/snmp/src/manager/snmpm_user_default.erl b/lib/snmp/src/manager/snmpm_user_default.erl
index d90fc3f258..015198cb76 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-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-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
@@ -62,7 +62,7 @@ handle_trap(TargetName, SnmpTrap, UserData) ->
"~n SnmpTrap: ~p"
"~n UserData: ~p",
[TargetName, SnmpTrap, UserData]),
- ok.
+ ignore.
handle_inform(TargetName, SnmpInform, UserData) ->
@@ -80,7 +80,7 @@ handle_report(TargetName, SnmpReport, UserData) ->
"~n SnmpReport: ~p"
"~n UserData: ~p",
[TargetName, SnmpReport, UserData]),
- ok.
+ ignore.
info(F, A) ->
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index a0afb5056e..7f7d887d5e 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -188,6 +188,9 @@
<p>Provide, in bytes, when rekeying should be initiated,
defaults to one time each GB and one time per hour.</p>
</item>
+ <tag><c><![CDATA[{idle_time, integer()}]]></c></tag>
+ <item>
+ <p>Sets a timeout on connection when no channels are active, default is infinity</p></item>
</taglist>
</desc>
</func>
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 323f0af191..27e43a88ed 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -120,10 +120,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 826a11f1f4..cbd8166bb9 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,12 +19,14 @@
{"%VSN%",
[
+ {<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
{<<"2.1">>, [{restart_application, ssh}]},
{<<"2.0\\.*">>, [{restart_application, ssh}]},
{<<"1\\.*">>, [{restart_application, ssh}]}
],
[
+ {<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
{<<"2.1">>,[{restart_application, ssh}]},
{<<"2.0\\.*">>, [{restart_application, ssh}]},
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 3ef26b1678..193f877b98 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -31,11 +31,6 @@
stop_listener/1, stop_listener/2, stop_daemon/1, stop_daemon/2,
shell/1, shell/2, shell/3]).
--deprecated({sign_data, 2, next_major_release}).
--deprecated({verify_data, 3, next_major_release}).
-
--export([sign_data/2, verify_data/3]).
-
%%--------------------------------------------------------------------
%% Function: start([, Type]) -> ok
%%
@@ -278,7 +273,9 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
{ok, SysSup} ->
{ok, SysSup};
{error, {already_started, _}} ->
- {error, eaddrinuse}
+ {error, eaddrinuse};
+ {error, R} ->
+ {error, R}
catch
exit:{noproc, _} ->
{error, ssh_not_started}
@@ -392,8 +389,8 @@ handle_ssh_option({public_key_alg, Value} = Opt) when Value == 'ssh-rsa'; Value
Opt;
handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), length(Value) >= 1 ->
case handle_pref_algs(Value, []) of
- true ->
- Opt;
+ {true, NewOpts} ->
+ NewOpts;
_ ->
throw({error, {eoptions, Opt}})
end;
@@ -501,38 +498,3 @@ inetopt(false) ->
%%%
%% Deprecated
%%%
-
-%%--------------------------------------------------------------------
-%% Function: sign_data(Data, Algorithm) -> binary() |
-%% {error, Reason}
-%%
-%% Data = binary()
-%% Algorithm = "ssh-rsa"
-%%
-%% Description: Use SSH key to sign data.
-%%--------------------------------------------------------------------
-sign_data(Data, Algorithm) when is_binary(Data) ->
- case ssh_file:user_key(Algorithm,[]) of
- {ok, Key} when Algorithm == "ssh-rsa" ->
- public_key:sign(Data, sha, Key);
- Error ->
- Error
- end.
-
-%%--------------------------------------------------------------------
-%% Function: verify_data(Data, Signature, Algorithm) -> ok |
-%% {error, Reason}
-%%
-%% Data = binary()
-%% Signature = binary()
-%% Algorithm = "ssh-rsa"
-%%
-%% Description: Use SSH signature to verify data.
-%%--------------------------------------------------------------------
-verify_data(Data, Signature, Algorithm) when is_binary(Data), is_binary(Signature) ->
- case ssh_file:user_key(Algorithm, []) of
- {ok, #'RSAPrivateKey'{publicExponent = E, modulus = N}} when Algorithm == "ssh-rsa" ->
- public_key:verify(Data, sha, Signature, #'RSAPublicKey'{publicExponent = E, modulus = N});
- Error ->
- Error
- end.
diff --git a/lib/ssh/src/ssh_client_key_api.erl b/lib/ssh/src/ssh_client_key_api.erl
index eed0b85f47..58054a9fc5 100644
--- a/lib/ssh/src/ssh_client_key_api.erl
+++ b/lib/ssh/src/ssh_client_key_api.erl
@@ -26,7 +26,7 @@
Algorithm :: 'ssh-rsa'| 'ssh-dss'| atom(), ConnectOptions :: proplists:proplist()) ->
boolean().
--callback user_key(Algorithm :: 'ssh-rsa'| 'ssh-dss'| atom(), ConnectOptions :: proplists:proplists()) ->
+-callback user_key(Algorithm :: 'ssh-rsa'| 'ssh-dss'| atom(), ConnectOptions :: proplists:proplist()) ->
{ok, PrivateKey :: #'RSAPrivateKey'{}| #'DSAPrivateKey'{} | term()} | {error, string()}.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 88b45111ff..9378686242 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -422,11 +422,15 @@ userauth(#ssh_msg_userauth_failure{authentications = Methodes},
#state{ssh_params = #ssh{role = client,
userauth_methods = none} = Ssh0} = State) ->
AuthMethods = string:tokens(Methodes, ","),
- {Msg, Ssh} = ssh_auth:userauth_request_msg(
- Ssh0#ssh{userauth_methods = AuthMethods}),
- send_msg(Msg, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-
+ Ssh1 = Ssh0#ssh{userauth_methods = AuthMethods},
+ case ssh_auth:userauth_request_msg(Ssh1) of
+ {disconnect, DisconnectMsg, {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
+ {Msg, Ssh} ->
+ send_msg(Msg, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
%% The prefered authentication method failed try next method
userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 921ec2206a..71666a3179 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 2.1.2
+SSH_VSN = 2.1.3
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 49bbd5d27d..73cda03b2f 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2012</year>
+ <year>1999</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -22,10 +22,6 @@
</legalnotice>
<title>SSL Release Notes</title>
- <prepared>Peter H&ouml;gfeldt</prepared>
- <docno></docno>
- <date>2003-08-03</date>
- <rev>G</rev>
<file>notes.xml</file>
</header>
<p>This document describes the changes made to the SSL application.</p>
@@ -605,1285 +601,7 @@
</item>
</list>
</section>
-
- </section>
-
-
- <section><title>SSL 3.11.1</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fixed handling of several ssl/tls packets arriving at the
- same time. This was broken during a refactoring of the
- code.</p>
- <p>
- Own Id: OTP-8679</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Added missing checks for padding and Mac value. Removed
- code for export ciphers and DH certificates as we decided
- not to support them.</p>
- <p>
- Own Id: OTP-7047</p>
- </item>
- <item>
- <p>
- New ssl will no longer return esslerrssl to be backwards
- compatible with old ssl as this hids infomation from the
- user. format_error/1 has been updated to support new ssl.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-7049</p>
- </item>
- <item>
- <p>
- New ssl now supports secure renegotiation as described by
- RFC 5746.</p>
- <p>
- Own Id: OTP-8568</p>
- </item>
- <item>
- <p>
- Alert handling has been improved to better handle
- unexpected but valid messages and the implementation is
- also changed to avoid timing related issues that could
- cause different error messages depending on network
- latency. Packet handling was sort of broken but would
- mostly work as expected when socket was in binary mode.
- This has now been fixed.</p>
- <p>
- Own Id: OTP-8588</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.11</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fixes handling of the option fail_if_no_peer_cert and
- some undocumented options. Thanks to Rory Byrne.</p>
- <p>
- Own Id: OTP-8557</p>
- </item>
- </list>
- </section>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Support for Diffie-Hellman. ssl-3.11 requires
- public_key-0.6.</p>
- <p>
- Own Id: OTP-7046</p>
- </item>
- <item>
- <p>
- New ssl now properly handles ssl renegotiation, and
- initiates a renegotiation if ssl/ltls-sequence numbers
- comes close to the max value. However RFC-5746 is not yet
- supported, but will be in an upcoming release.</p>
- <p>
- Own Id: OTP-8517</p>
- </item>
- <item>
- <p>
- When gen_tcp is configured with the {packet,http} option,
- it automatically switches to expect HTTP Headers after a
- HTTP Request/Response line has been received. This update
- fixes ssl to behave in the same way. Thanks to Rory
- Byrne.</p>
- <p>
- Own Id: OTP-8545</p>
- </item>
- <item>
- <p>
- Ssl now correctly verifies the extended_key_usage
- extension and also allows the user to verify application
- specific extensions by supplying an appropriate fun.</p>
- <p>
- Own Id: OTP-8554 Aux Id: OTP-8553 </p>
- </item>
- <item>
- <p>
- Fixed ssl:transport_accept/2 to return properly when
- socket is closed. Thanks to Rory Byrne.</p>
- <p>
- Own Id: OTP-8560</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.9</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fixed a crash in the certificate certification part.</p>
- <p>
- Own Id: OTP-8510 Aux Id: seq11525 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.8</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p><c>ssl:send/2</c> ignored packet option, fix provided
- by YAMASHINA Hio.</p>
- <p>Fixed a file cache bug which caused problems when the
- same file was used for both cert and cacert.</p>
- <p>Allow <c>ssl:listen/2</c> to be called with option
- {ssl_imp, old}.</p>
- <p> Fixed ssl:setopts(Socket, binary) which didn't work
- for 'new' ssl.</p>.
- <p>
- Own Id: OTP-8441</p>
- </item>
- <item>
- <p>
- Do a controlled shutdown if a non ssl packet arrives as
- the first packet.</p>
- <p>
- Own Id: OTP-8459 Aux Id: seq11505 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Fixed session reuse (in new_ssl), thanks Wil Tan.</p>
- <p>Send CA list during Certificate Request (in new_ssl) ,
- thanks Wil Tan.</p> <p><c>NOTE</c>: SSL (new_ssl)
- requires public_key-0.5.</p>
- <p>
- Own Id: OTP-8372</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.7</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- A ticker process could potentially be blocked
- indefinitely trying to send a tick to a node not
- responding. If this happened, the connection would not be
- brought down as it should.</p>
- <p> This requires erts-5.7.4 and kernel-2.13.4 or later
- to be able to get the erlang distribution over ssl to work.</p>
- <p>
- Own Id: OTP-8218</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The documentation is now built with open source tools
- (xsltproc and fop) that exists on most platforms. One
- visible change is that the frames are removed.</p>
- <p>
- Own Id: OTP-8250</p>
- </item>
- <item>
- <p>
- Code cleanup from Kostis.</p>
- <p>
- Own Id: OTP-8260</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.6</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- The ssl:ssl_accept/3 issue was not properly fixed in the
- previous patch, see OTP-8244.</p>
- <p>
- Own Id: OTP-8275 Aux Id: seq11451 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.5</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Allow clients to not send certificates if option
- <c>fail_if_no_peer_cert</c> was not set.</p>
- <p>
- Own Id: OTP-8224</p>
- </item>
- <item>
- <p>An ssl:ssl_accept/3 could crash a connection if the
- timing was wrong.</p> <p>Removed info message if the
- socket closed without a proper disconnect from the ssl
- layer. </p> <p>ssl:send/2 is now blocking until the
- message is sent.</p>
- <p>
- Own Id: OTP-8244 Aux Id: seq11420 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.4</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- A client could avoid a certificate check if the client
- code didn't send the requested certificate.</p>
- <p>
- Own Id: OTP-8137</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SSL 3.10.3</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Packet handling was not implemented correctly.</p>
- <p>Inet option handling support have been improved.</p>
- <p>The <c>verify_fun</c> is now invoked even if
- verify_peer is used, that implies that by default
- {bad_cert,unknown_ca} is an accepted fault during the
- client connection phase. The check can still be done by
- suppling another verify_fun.</p>
- <p>
- Own Id: OTP-8011 Aux Id: seq11287 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-
-<section><title>SSL 3.10.2</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- A "new_ssl" socket was not closed if the controlling
- process died without calling ssl:close/1.</p>
- <p>
- Own Id: OTP-7963 Aux Id: seq11276 </p>
- </item>
- </list>
</section>
-
-</section>
-
-<section><title>SSL 3.10.1</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fixed bug that caused the ssl handshake finished message
- to be calculated wrongly under the circumstances that the
- server did not send the trusted cert and that the
- previous cert did not have the extension telling us the
- trusted certs name. This manifested it self as
- bad_record_mac alert from the server.</p>
- <p>
- Own Id: OTP-7878</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The cacertsfile option is now optional for ssl servers.</p>
- <p>
- Own Id: OTP-7656</p>
- </item>
- <item>
- <p>
- For the ssl client the options cacertfile, certfile and
- keyfile are now optional as they are not always needed
- depending on configuration of the client itself and the
- configuration of the server. Also as PEM-files may
- contain more than one entry the keyfile option will
- default to the same file as given by the certfile option.</p>
- <p>
- Own Id: OTP-7870</p>
- </item>
- <item>
- <p>
- Added new ssl client option verify_fun.</p>
- <p>
- Own Id: OTP-7871</p>
- </item>
- </list>
- </section>
-
-</section>
-
- <section><title>SSL 3.10</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Error log entries are now formatted correctly.</p>
- <p>
- Own Id: OTP-7258</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- All handling of X509-certificates and public keys have
- been moved to the new application public_key.</p>
- <p>
- Own Id: OTP-6894</p>
- </item>
- <item>
- <p>
- New ssl now supports SSL-3.0 and TLS-1.0</p>
- <p>
- Own Id: OTP-7037</p>
- </item>
- <item>
- <p>
- New ssl now supports all inet-packet types.</p>
- <p>
- Own Id: OTP-7039</p>
- </item>
- <item>
- <p>
- The new ssl-server is now able to send a certificate
- request to the client. However new options may be
- introduced later to fully support all features regarding
- certificate requests.</p>
- <p>
- Own Id: OTP-7150</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Known Bugs and Problems</title>
- <list>
- <item>
- <p>
- Running erlang distribution over ssl don't work as
- described in the documentation.</p>
- <p>
- Own Id: OTP-7536</p>
- </item>
- </list>
- </section>
-
- </section>
-
-
- <section><title>SSL 3.9</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- ssl_prim.erl was passing an FD rather than an #sslsocket
- to ssl_broker:ssl_accept_prim. This could cause problems
- in the deprecated accept function, this will not cause
- any more problems however this function is deprecated!</p>
- <p>
- Own Id: OTP-6926</p>
- </item>
- <item>
- <p>
- Erlang distribution over ssl was broken after R11B-0,
- this has now been fixed.</p>
- <p>
- Own Id: OTP-7004</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- All inet options are available in the new ssl
- implementation that is released as a alfa in ssl-3.9 and
- will replace the old implementation in ssl-4.0. This will
- not be fixed in the old implementation.</p>
- <p>
- Own Id: OTP-4677</p>
- </item>
- <item>
- <p>
- The new ssl implementation released as a alfa in this
- version supports upgrading of a tcp connection to an ssl
- connection so that http client and servers may implement
- RFC 2817.</p>
- <p>
- Own Id: OTP-5510</p>
- </item>
- <item>
- <p>A new implementation of ssl is released as a alfa
- version in ssl-3.9 it will later replace the old
- implementation in ssl-4.0. The new implementation can be
- accessed by providing the option {ssl_imp, new} to the
- ssl:connect and ssl:listen functions.</p>
- <p>The new implementation is Erlang based and all logic
- is in Erlang and only payload encryption calculations are
- done in C via the crypto application. The main reason for
- making a new implementation is that the old solution was
- very crippled as the control of the ssl-socket was deep
- down in openssl making it hard if not impossible to
- support all inet options, ipv6 and upgrade of a tcp
- connection to an ssl connection. The alfa version has a
- few limitations that will be removed before the ssl-4.0
- release. Main differences and limitations in the alfa are
- listed below.</p>
-
- <list type="bulleted"> <item>New ssl requires the crypto
- application.</item> <item>The option reuseaddr is
- supported and the default value is false as in gen_tcp.
- Old ssl is patched to accept that the option is set to
- true to provide a smoother migration between the
- versions. In old ssl the option is hard coded to
- true.</item> <item>ssl:version/0 is replaced by
- ssl:versions/0</item> <item>ssl:ciphers/0 is replaced by
- ssl:cipher_suites/0</item> <item>ssl:pid/1 is a
- meaningless function in new ssl and will be deprecated in
- ssl-4.0 until it is removed it will return a valid but
- meaningless pid.</item> <item>New API functions are
- ssl:shutdown/2, ssl:cipher_suites/[0,1] and
- ssl:versions/0</item> <item>Diffie-Hellman keyexchange is
- not supported.</item> <item>Not all inet packet types are
- supported.</item> <item>CRL and policy certificate
- extensions are not supported.</item> <item>In this alfa
- only sslv3 is enabled, although tlsv1 and tlsv1.1
- versions are implemented and will be supported in future
- versions.</item> <item>For security reasons sslv2 is not
- supported.</item> </list>
- <p>
- Own Id: OTP-6619</p>
- </item>
- <item>
- <p>
- New ssl implementation, released as alfa in ssl-3.9,
- supports ipv6. It will not be supported in the old
- implementation.</p>
- <p>
- Own Id: OTP-6637 Aux Id: OTP-6636 </p>
- </item>
- </list>
- </section>
-
- </section>
-
- <section>
- <title>SSL 3.1.1.1</title>
-
- <section>
- <title>Minor Makefile changes</title>
- <list type="bulleted">
- <item>
- <p>Removed use of <c>erl_flags</c> from Makefile.</p>
- <p>Own Id: OTP-6689</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.1.1</title>
-
- <section>
- <title>Crash on error in ssl_accept</title>
- <list type="bulleted">
- <item>
- <p>A bug in ssl_accept could cause all ssl
- connections to hang when a connection
- attempt was closed by the client while
- the server was in <c>ssl_accept</c>.</p>
- <p>Own Id: OTP-6612 Aux Id: seq10599</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>SSL now uses a two-phase accept, with a separate accept
- calls for the socket and the ssl protocol. This avoids
- timeouts when a client doesn't initiate ssl handshake.</p>
- <p>With the old implementation of accept, the server
- was locked by a client, if the client didn't do
- proper ssl handshake.</p>
- <p>Own Id: OTP-6418 Aux Id: seq10105</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.12</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>An integer array pointing to a struct pollfd array, is
- now reset before file descriptors are collected to be
- included in a call to poll(). This is to prevent file
- descriptors to be mixed up.</p>
- <p>Own Id: OTP-6084</p>
- </item>
- <item>
- <p>The generation of the module ssl_pkix_oid contained
- multiple identifiers, which made the mapping between
- atoms and identifiers not one-to-one.</p>
- <p>Own Id: OTP-6085</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.11</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The state of a connection in active mode could be in a
- restrictive state, so that an internal tcp_closed message
- was incorrectly considered illegal, resulting in a
- premature termination of the connection process.</p>
- <p>Own Id: OTP-5972 Aux Id: seq10188 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.10</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Erlang distribution over SSL was broken. Corrected.
- (Thanks to Fredrik Thulin.)</p>
- <p>Own Id: OTP-5863</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.9</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The port program for the ssl application could waste huge
- amounts of CPU time if a write could not be completed
- directly and was put in the write queue. (Only on platforms
- where poll() is used, such as Solaris and Linux.)</p>
- <p>Own Id: OTP-5784</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.8</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A process reading only a portion of a sufficiently large
- amount of data from an accepted socket, and then quering
- the ssl library (e.g. ssl:getpeername()), would cause a
- global deadlock in the esock port program.</p>
- <p>Own Id: OTP-5702</p>
- </item>
- <item>
- <p>A spelling error in the module <c>ssl_pkix</c> caused the
- call to <c>ssl:peercert/2</c> to fail when the option
- <c>subject</c> was used.</p>
- <p>Own Id: OTP-5708</p>
- </item>
- <item>
- <p>Because fopen() on Solaris 8 can't handle file
- descriptor numbers above 255, reading of certificate
- files would fail if all file descriptors below 256 were
- in use (typically, if many connections were open). This
- problem has been worked around.</p>
- <p>The ssl application's port program used to use
- select(), which meant that it could not handle more than
- FD_SETSIZE file descriptors (usually 1024). To eliminate
- that limitation, poll() is now used on all platforms that
- support it.</p>
- <p>Solaris/Sparc, 64-bit emulator: The SO_REUSEADDR
- option was not set for listen sockets, which essentially
- made the ssl application unusable. Corrected.</p>
- <p>The default listen queue size for ssl port program was
- changed to 128 (from 5).</p>
- <p>Own Id: OTP-5755 Aux Id: seq10068 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssl 3.0.7</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The R/W buffer length i esock.c was too small. It has
- been increased from 4k to 32k.</p>
- <p>Own Id: OTP-5620</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssl 3.0.6</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>A configuration option for choosing protocol versions has
- been added (<c>sslv2</c>, <c>sslv3</c>, and
- <c>tlsv1</c>).</p>
- <p>Own Id: OTP-5429 Aux Id: seq9755 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssl 3.0.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Linked in drivers in the crypto, and asn1 applications
- are now compiled with the -D_THREAD_SAFE and -D_REENTRANT
- switches on unix when the emulator has thread support
- enabled.</p>
- <p>Linked in drivers on MacOSX are not compiled with the
- undocumented -lbundle1.o switch anymore. Thanks to Sean
- Hinde who sent us a patch.</p>
- <p>Linked in driver in crypto, and port programs in ssl, now
- compiles on OSF1.</p>
- <p>Minor makefile improvements in runtime_tools.</p>
- <p>Own Id: OTP-5346</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssl 3.0.4</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p><c>ssl:recv/3</c> with finite timeout value, closed the
- connection at timeout.</p>
- <p>Own Id: OTP-4882</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssl 3.0.3</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When a file descriptor was marked for closing, and
- end-of-file condition had already been detected, the file
- descriptor was never closed.</p>
- <p>Own Id: OTP-5093 Aux Id: seq8806 </p>
- </item>
- <item>
- <p>When the number of open file descriptors reached
- FD_SETSIZE, the SSL port program entered a busy loop.</p>
- <p>Own Id: OTP-5094 Aux Id: seq8806 </p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The SSL application now supports SSL sessions for
- servers, which typically speeds up HTTP requests from
- browsers.</p>
- <p>Own Id: OTP-5095</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.2</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The UTF8String type is now defined in asn1-1.4.4.2 and
- later. Therefore the definitions of UTF8String has been
- removed from the ASN.1 modules PKIX1Explicit88.asn1 and
- PKIXAttributeCertificate.asn1. The SSL application can now
- only be built using asn-1.4.4.2 or later.</p>
- <p>OwnId: OTP-4971.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <p>See SSL-3.0.
- </p>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>An unexpected object identifier would crash <c>ssl:peercert</c>. </p>
- <p>OwnId: OTP-4771.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <p>See SSL-3.0.
- </p>
- </section>
- </section>
-
- <section>
- <title>SSL 3.0</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The <c>cache_timout</c> option was silently ignored. It had
- to do with SSL sessions, where multiple connections can occur.
- Since the Erlang SSL application does not support sessions the
- option is still ignored, and consequently the documentation
- about it has been removed.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>The Erlang SSL application is now based on OpenSSL version
- 0.9.7a. OpenSSL 0.9.6 should also work.</p>
- <p>OwnId: OTP-4002</p>
- </item>
- <item>
- <p>When connecting it is now possible to bind to a local address
- and local port. </p>
- <p>OwnId: OTP-4675</p>
- </item>
- <item>
- <p>The <c>ssl_esock</c> port program is now part of the
- distribution and thus does not have to be created
- explicitly. It is dynamically linked to OpenSSL
- libraries in a "standard" location (typically
- <c>/usr/local/lib</c> on UNIX; in the path on Win32).</p>
- <p>OwnId:
- OTP-4676</p>
- </item>
- <item>
- <p>The new functions <c>ssl:peercert/1/2</c> provide information
- from the certificate of a peer of a connection.</p>
- <p>OwnId: OTP-4680
- <br></br>
-Aux Id: seq7688</p>
- </item>
- <item>
- <p>The function <c>ssl:port/1</c> has been removed from the
- documentation, but not from the <c>ssl</c> interface module.
- The recommendation is to use <c>ssl:peername/1</c>
- instead, which provides both address and port of the peer.</p>
- <p>OwnId: OTP-4681 </p>
- </item>
- <item>
- <p>New User's Guide documentation has been added.</p>
- <p>OwnId: OTP-4682 </p>
- </item>
- <item>
- <p>The old <c>ssl_socket</c> interface has been removed and also
- the documentation of it. </p>
- <p>OwnId: OTP-4683 </p>
- </item>
- <item>
- <p>The use of ephemeral RSA keys is now supported. It is
- a global configuration option (see the ssl(6) manual page).</p>
- <p>OwnId: OTP-4691.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The option <c>cacertfile</c> is now in effect, and can
- therefore no longer be set with the OS environment
- variable SSL_CERT_FILE (which did set the same value for
- all connections). </p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>There was a synchronization error at closing of an SSL
- connection. </p>
- <p>OwnId: OTP-4435
- <br></br>
-Aux Id: seq7534</p>
- </item>
- <item>
- <p>C macros in <c>debuglog.c</c> were not ANSI C compliant.</p>
- <p>OwnId: OTP-4674</p>
- </item>
- <item>
- <p>The <c>binary</c> option was not properly handled.</p>
- <p>OwnId: OTP-4678</p>
- </item>
- <item>
- <p>The <c>ssl:format_error/1</c> did not consider <c>inet</c>
- error codes, nor did it have a catch all for unknown error
- codes.</p>
- <p>OwnId: OTP-4679</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <list type="bulleted">
- <item>
- <p>Change of controlling process in not OTP compliant. </p>
- <p>OwnId; OTP-4712</p>
- </item>
- <item>
- <p>There is still no way to restrict the cipher sizes. </p>
- <p>OwnId: OTP-4712</p>
- </item>
- <item>
- <p>The <c>keep_alive</c> and <c>reuse_addr</c> options will be
- added in a future release. </p>
- <p>OwnId: OTP-4677</p>
- </item>
- <item>
- <p>There is currently no way to restrict the SSL/TLS
- protocol versions to use. In a future release this will be
- supported as a configuration option, and as an option for
- each connection as well. </p>
- <p>OwnId: OTP-4711.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3.6</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>There was a synchronization error at closing, which could
- result in that an SSL socket was removed prematurely, resulting
- in that a user process referring to it received an unexpected
- exit.</p>
- <p>OwnId: OTP-4435
- <br></br>
-Aux Id: seq7600</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <p>See SSL 2.2 . </p>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Setting of the option `nodelay' caused the SSL port program
- to dump core.</p>
- <p>OwnId: OTP-4380
- <br></br>
-Aux Id: -</p>
- </item>
- <item>
- <p>Setting of the option '{active, once}' in <c>setopts</c> was
- wrong, causing a correct socket message to be regarded as
- erroneous. </p>
- <p>OwnId: OTP-4380
- <br></br>
-Aux Id: -</p>
- </item>
- <item>
- <p>A self-signed peer certificate was always rejected with the
- error `eselfsignedcert', irrespective of the `depth' value. </p>
- <p>OwnId: OTP-4374
- <br></br>
-Aux Id: seq7417</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <p>See SSL 2.2 . </p>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3.4</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>All TCP options allowed in gen_tcp, are now also allowed in
- SSL, except the option <c>{reuseaddr, Boolean}</c>. A new
- function <c>getopts</c> has been added to the SSL interface
- module <c>ssl</c>. </p>
- <p>OwnId: OTP-4305, OTP-4159</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3.3</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The roles of the SSLeay and OpenSSL packages has been
- clarified in the ssl(6) application manual page. Also
- the URLs from which to download SSLeay has been updated.</p>
- <p>OwnId: OTP-4002
- <br></br>
-Aux Id: seq5269</p>
- </item>
- <item>
- <p>A call to <c>ssl:listen(Port, Options)</c> with
- <c>Options = []</c> resulted in the cryptic <c>{error, ebadf}</c> return value. The return value has been changed
- to <c>{error, enooptions}</c>, and the behaviour has been
- documented in the <c>listen/2</c> function.</p>
- <p>OwnId: OTP-4016
- <br></br>
-Aux Id: seq7006</p>
- </item>
- <item>
- <p>Use of the option <c>{nodelay, boolean()}</c> crashed
- the <c>ssl_server</c>.</p>
- <p>OwnId: OTP-4070
- <br></br>
-Aux Id:</p>
- </item>
- <item>
- <p>A bug caused the Erlang distribution over ssl to fail.
- This bug has now been fixed.</p>
- <p>OwnId: OTP-4072
- <br></br>
-Aux Id:</p>
- </item>
- <item>
- <p>On Windows when the SSL port program encountered an
- error code not anticipated it crashed. </p>
- <p>OwnId: OTP-4132
- <br></br>
-Aux Id:</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3.2</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The <c>ssl:accept/1-2</c> function sometimes returned
- <c>{error, {What, Where}}</c> instead of <c>{error, What}</c>, where <c>What</c> is an atom. </p>
- <p>OwnId: OTP-3775
- <br></br>
-Aux Id: seq4991</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Sometimes the SSL portprogram would loop in an accept
- loop, without terminating even when the SSL application
- was stopped.. </p>
- <p>OwnId: OTP-3691</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.3</title>
- <p>Functions have been added to SSL to experimentally support
- Erlang distribution.
- </p>
- </section>
-
- <section>
- <title>SSL 2.2.1</title>
- <p>The 2.2.1 version of SSL provides code replacement in runtime
- by upgrading from, or downgrading to, versions 2.1 and 2.2.
- </p>
- </section>
-
- <section>
- <title>SSL 2.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The restriction that only the creator of an SSL socket can
- read from and write to the socket has been lifted.</p>
- <p>OwnId: OTP-3301</p>
- </item>
- <item>
- <p>The option <c>{packet, cdr}</c> for SSL sockets has been added,
- which means that SSL sockets also supports CDR encoded packets.</p>
- <p>OwnId: OTP-3302</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <list type="bulleted">
- <item>
- <p>Setting of a CA certificate file with the <c>cacertfile</c>
- option (in calls to <c>ssl:accept/1/2</c> or
- <c>ssl:connect/3/4</c>) does not work due to weaknesses
- in the SSLeay package. </p>
- <p>A work-around is to set the OS environment variable
- <c>SSL_CERT_FILE</c> before SSL is started. However, then
- the CA certificate file will be global for all connections.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>When changing controlling process of an SSL socket, a
- temporary process is started, which is not gen_server
- compliant.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>Although there is a <c>cache</c> timeout option, it is
- silently ignored.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>There is currently no way to restrict the cipher sizes.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The set of possible error reasons has been extended to
- contain diagnostics on erroneous certificates and failures
- to verify certificates.</p>
- <p>OwnId: OTP-3145</p>
- </item>
- <item>
- <p>The maximum number of simultaneous SSL connections on
- Windows has been increased from 31 to 127.</p>
- <p>OwnId: OTP-3145</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A dead-lock occurring when write queues are not empty has
- been removed. </p>
- <p>OwnId: OTP-3145</p>
- </item>
- <item>
- <p>Error reasons have been unified and changed.</p>
- <p>(** POTENTIAL INCOMPATIBILITY **)</p>
- <p>OwnId: OTP-3145</p>
- </item>
- <item>
- <p>On Windows a check of the existence of the environment
- variable <c>ERLSRV_SERVICE_NAME</c> has been added. If
- that variable is defined, the port program of the SSL
- application will not terminated when a user logs off.</p>
- <p>OwnId: OTP-3145</p>
- </item>
- <item>
- <p>An error in the setting of the <c>nodelay</c> option
- has been corrected.</p>
- <p>OwnId: OTP-3145</p>
- </item>
- <item>
- <p>The confounded notions of verify mode and verify depth has
- been corrected. The option <c>verifydepth</c> has been
- removed, and the two separate options <c>verify</c> and
- <c>depth</c> has been added.</p>
- <p>(** POTENTIAL INCOMPATIBILITY **)</p>
- <p>OwnId: OTP-3145</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known Bugs and Problems</title>
- <list type="bulleted">
- <item>
- <p>Setting of a CA certificate file with the <c>cacertfile</c>
- option (in calls to <c>ssl:accept/1/2</c> or
- <c>ssl:connect/3/4</c>) does not work due to weaknesses
- in the SSLeay package. </p>
- <p>A work-around is to set the OS environment variable
- <c>SSL_CERT_FILE</c> before SSL is started. However, then
- the CA certificate file will be global for all connections.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>When changing controlling process of an SSL socket, a
- temporary process is started, which is not gen_server
- compliant.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>Although there is a <c>cache</c> timeout option, it is
- silently ignored.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- <item>
- <p>There is currently no way to restrict the cipher sizes.</p>
- <p>OwnId: OTP-3146</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSL 2.0</title>
- <p>A complete new version of SSL with separate I/O channels
- for all connections with non-blocking I/O multiplexing.</p>
- </section>
</chapter>
diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile
index 6be8a1456e..043645be41 100644
--- a/lib/ssl/src/Makefile
+++ b/lib/ssl/src/Makefile
@@ -108,10 +108,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index 9b1227fa7f..76e14860ec 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,24 +1,13 @@
%% -*- erlang -*-
{"%VSN%",
[
- {"5.1.1", [{restart_application, ssl}]
- },
- {"5.1", [
- {load_module, ssl_connection, soft_purge, soft_purge, []}
- ]
- },
+ {<<"5.1\\*">>, [{restart_application, ssl}]},
{<<"5.0\\*">>, [{restart_application, ssl}]},
{<<"4\\.*">>, [{restart_application, ssl}]},
{<<"3\\.*">>, [{restart_application, ssl}]}
],
[
- {"5.1.1", [{restart_application, ssl}]
- },
- {"5.1", [
- {load_module, ssl_connection, soft_purge, soft_purge, []}
- ]
- },
- {"5.1", [{restart_application, ssl}]},
+ {<<"5.1\\*">>, [{restart_application, ssl}]},
{<<"5.0\\*">>, [{restart_application, ssl}]},
{<<"4\\.*">>, [{restart_application, ssl}]},
{<<"3\\.*">>, [{restart_application, ssl}]}
diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl
index 222b3f1ad7..f94a1136a0 100644
--- a/lib/ssl/src/ssl_alert.erl
+++ b/lib/ssl/src/ssl_alert.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-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
@@ -36,8 +36,7 @@
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
--spec reason_code(#alert{}, client | server) -> closed | esslconnect |
- esslaccept | string().
+-spec reason_code(#alert{}, client | server) -> closed | {essl, string()}.
%%
%% Description: Returns the error reason that will be returned to the
%% user.
@@ -45,12 +44,8 @@
reason_code(#alert{description = ?CLOSE_NOTIFY}, _) ->
closed;
-reason_code(#alert{description = ?HANDSHAKE_FAILURE}, client) ->
- esslconnect;
-reason_code(#alert{description = ?HANDSHAKE_FAILURE}, server) ->
- esslaccept;
reason_code(#alert{description = Description}, _) ->
- description_txt(Description).
+ {essl, description_txt(Description)}.
%%--------------------------------------------------------------------
-spec alert_txt(#alert{}) -> string().
diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl
index 67d00f0da7..ff36b5ee26 100644
--- a/lib/ssl/src/ssl_certificate_db.erl
+++ b/lib/ssl/src/ssl_certificate_db.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-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
@@ -18,10 +18,11 @@
%%
%%----------------------------------------------------------------------
-%% Purpose: Storage for trused certificats
+%% Purpose: Storage for trusted certificates
%%----------------------------------------------------------------------
-module(ssl_certificate_db).
+
-include("ssl_internal.hrl").
-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/file.hrl").
@@ -37,7 +38,7 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec create() -> [db_handle()].
+-spec create() -> [db_handle(),...].
%%
%% Description: Creates a new certificate db.
%% Note: lookup_trusted_cert/4 may be called from any process but only
@@ -54,7 +55,7 @@ create() ->
].
%%--------------------------------------------------------------------
--spec remove([db_handle()]) -> term().
+-spec remove([db_handle()]) -> ok.
%%
%% Description: Removes database db
%%--------------------------------------------------------------------
@@ -114,8 +115,8 @@ add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache] = Db) ->
new_trusted_cert_entry({MD5, File}, Db)
end.
%%--------------------------------------------------------------------
--spec cache_pem_file({binary(), binary()}, [db_handle()]) -> term().
--spec cache_pem_file(reference(), {binary(), binary()}, [db_handle()]) -> term().
+-spec cache_pem_file({binary(), binary()}, [db_handle()]) -> {ok, term()}.
+-spec cache_pem_file(reference(), {binary(), binary()}, [db_handle()]) -> {ok, term()}.
%%
%% Description: Cache file as binary in DB
%%--------------------------------------------------------------------
@@ -131,19 +132,25 @@ cache_pem_file(Ref, {MD5, File}, [_CertsDb, _RefDb, PemChache]) ->
insert(MD5, {Content, Ref}, PemChache),
{ok, Content}.
+%%--------------------------------------------------------------------
+-spec remove_trusted_certs(reference(), db_handle()) -> ok.
+%%
+%% Description: Removes all trusted certificates refernced by <Ref>.
+%%--------------------------------------------------------------------
remove_trusted_certs(Ref, CertsDb) ->
remove_certs(Ref, CertsDb).
%%--------------------------------------------------------------------
--spec remove(term(), db_handle()) -> term().
+-spec remove(term(), db_handle()) -> ok.
%%
%% Description: Removes an element in a <Db>.
%%--------------------------------------------------------------------
remove(Key, Db) ->
- _ = ets:delete(Db, Key).
+ ets:delete(Db, Key),
+ ok.
%%--------------------------------------------------------------------
--spec lookup(term(), db_handle()) -> term() | undefined.
+-spec lookup(term(), db_handle()) -> [term()] | undefined.
%%
%% Description: Looks up an element in a <Db>.
%%--------------------------------------------------------------------
@@ -158,7 +165,7 @@ lookup(Key, Db) ->
[Pick(Data) || Data <- Contents]
end.
%%--------------------------------------------------------------------
--spec foldl(fun(), term(), db_handle()) -> term().
+-spec foldl(fun((_,_) -> term()), term(), db_handle()) -> term().
%%
%% Description: Calls Fun(Elem, AccIn) on successive elements of the
%% cache, starting with AccIn == Acc0. Fun/2 must return a new
@@ -178,12 +185,13 @@ ref_count(Key, Db, N) ->
ets:update_counter(Db,Key,N).
%%--------------------------------------------------------------------
--spec clear(db_handle()) -> term().
+-spec clear(db_handle()) -> ok.
%%
%% Description: Clears the cache
%%--------------------------------------------------------------------
clear(Db) ->
- ets:delete_all_objects(Db).
+ true = ets:delete_all_objects(Db),
+ ok.
%%--------------------------------------------------------------------
-spec db_size(db_handle()) -> integer().
@@ -194,30 +202,35 @@ db_size(Db) ->
ets:info(Db, size).
%%--------------------------------------------------------------------
-%%-spec insert(Key::term(), Data::term(), Db::db_handle()) -> no_return().
+-spec insert(Key::term(), Data::term(), Db::db_handle()) -> ok.
%%
%% Description: Inserts data into <Db>
%%--------------------------------------------------------------------
insert(Key, Data, Db) ->
- true = ets:insert(Db, {Key, Data}).
+ true = ets:insert(Db, {Key, Data}),
+ ok.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
update_counter(Key, Count, Db) ->
- true = ets:insert(Db, {Key, Count}).
+ true = ets:insert(Db, {Key, Count}),
+ ok.
remove_certs(Ref, CertsDb) ->
- ets:match_delete(CertsDb, {{Ref, '_', '_'}, '_'}).
+ true = ets:match_delete(CertsDb, {{Ref, '_', '_'}, '_'}),
+ ok.
add_certs_from_der(DerList, Ref, CertsDb) ->
Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end,
- [Add(Cert) || Cert <- DerList].
+ [Add(Cert) || Cert <- DerList],
+ ok.
add_certs_from_pem(PemEntries, Ref, CertsDb) ->
Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end,
- [Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries].
-
+ [Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries],
+ ok.
+
add_certs(Cert, Ref, CertsDb) ->
try ErlCert = public_key:pkix_decode_cert(Cert, otp),
TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate,
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index cde13069b5..e5a6181a88 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-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
@@ -372,8 +372,7 @@ hello(#server_hello{cipher_suite = CipherSuite,
ssl_options = SslOptions} = State0) ->
case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
- handle_own_alert(Alert, ReqVersion, hello, State0),
- {stop, {shutdown, own_alert}, State0};
+ handle_own_alert(Alert, ReqVersion, hello, State0);
{Version, NewId, ConnectionStates, NextProtocol} ->
{KeyAlgorithm, _, _, _} =
ssl_cipher:suite_definition(CipherSuite),
@@ -1135,7 +1134,7 @@ init_certificates(#ssl_options{cacerts = CaCerts,
{ok, _, _, _, _, _} = ssl_manager:connection_init(Certs, Role)
catch
Error:Reason ->
- handle_file_error(?LINE, Error, Reason, CACertFile, ecacertfile,
+ handle_file_error(?LINE, Error, Reason, CACertFile, {ecacertfile, Reason},
erlang:get_stacktrace())
end,
init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CertFile, Role).
@@ -1157,7 +1156,7 @@ init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHan
{ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, OwnCert}
catch
Error:Reason ->
- handle_file_error(?LINE, Error, Reason, CertFile, ecertfile,
+ handle_file_error(?LINE, Error, Reason, CertFile, {ecertfile, Reason},
erlang:get_stacktrace())
end;
init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, _, _) ->
@@ -1176,7 +1175,7 @@ init_private_key(DbHandle, undefined, KeyFile, Password, _) ->
private_key(public_key:pem_entry_decode(PemEntry, Password))
catch
Error:Reason ->
- handle_file_error(?LINE, Error, Reason, KeyFile, ekeyfile,
+ handle_file_error(?LINE, Error, Reason, KeyFile, {ekeyfile, Reason},
erlang:get_stacktrace())
end;
@@ -1234,7 +1233,7 @@ init_diffie_hellman(DbHandle,_, DHParamFile, server) ->
catch
Error:Reason ->
handle_file_error(?LINE, Error, Reason,
- DHParamFile, edhfile, erlang:get_stacktrace())
+ DHParamFile, {edhfile, Reason}, erlang:get_stacktrace())
end.
sync_send_all_state_event(FsmPid, Event) ->
@@ -1628,78 +1627,49 @@ save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, abbrev
save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, abbreviated) ->
ssl_record:set_server_verify_data(current_write, Data, ConnectionStates).
-handle_server_key(#server_key_exchange{params =
- #server_dh_params{dh_p = P,
- dh_g = G,
- dh_y = ServerPublicDhKey},
- signed_params = <<>>},
- #state{key_algorithm = dh_anon} = State) ->
- dh_master_secret(P, G, ServerPublicDhKey, undefined, State);
-
-handle_server_key(
- #server_key_exchange{params =
- #server_dh_params{dh_p = P,
- dh_g = G,
- dh_y = ServerPublicDhKey},
- signed_params = Signed,
- hashsign = HashSign},
- #state{negotiated_version = Version,
- public_key_info = PubKeyInfo,
- connection_states = ConnectionStates} = State) ->
-
- PLen = size(P),
- GLen = size(G),
- YLen = size(ServerPublicDhKey),
- HashAlgo = connection_hash_algo(HashSign, State),
+handle_server_key(#server_key_exchange{exchange_keys = Keys},
+ #state{key_algorithm = KeyAlg,
+ negotiated_version = Version} = State) ->
+ Params = ssl_handshake:decode_server_key(Keys, KeyAlg, Version),
+ HashSign = connection_hashsign(Params#server_key_params.hashsign, State),
+ case HashSign of
+ {_, anon} ->
+ server_master_secret(Params#server_key_params.params, State);
+ _ ->
+ verify_server_key(Params, HashSign, State)
+ end.
- ConnectionState =
+verify_server_key(#server_key_params{params = Params,
+ params_bin = EncParams,
+ signature = Signature},
+ HashSign = {HashAlgo, _},
+ #state{negotiated_version = Version,
+ public_key_info = PubKeyInfo,
+ connection_states = ConnectionStates} = State) ->
+ ConnectionState =
ssl_record:pending_connection_state(ConnectionStates, read),
SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
Hash = ssl_handshake:server_key_exchange_hash(HashAlgo,
- <<ClientRandom/binary,
- ServerRandom/binary,
- ?UINT16(PLen), P/binary,
- ?UINT16(GLen), G/binary,
- ?UINT16(YLen),
- ServerPublicDhKey/binary>>),
-
- case verify_dh_params(Version, Signed, Hash, HashAlgo, PubKeyInfo) of
+ <<ClientRandom/binary,
+ ServerRandom/binary,
+ EncParams/binary>>),
+ case ssl_handshake:verify_signature(Version, Hash, HashSign, Signature, PubKeyInfo) of
true ->
- dh_master_secret(P, G, ServerPublicDhKey, undefined, State);
+ server_master_secret(Params, State);
false ->
?ALERT_REC(?FATAL, ?DECRYPT_ERROR)
end.
-verify_dh_params({3, Minor}, Signed, Hashes, HashAlgo, {?rsaEncryption, PubKey, _PubKeyParams})
- when Minor >= 3 ->
- public_key:verify({digest, Hashes}, HashAlgo, Signed, PubKey);
-verify_dh_params(_Version, Signed, Hashes, _HashAlgo, {?rsaEncryption, PubKey, _PubKeyParams}) ->
- case public_key:decrypt_public(Signed, PubKey,
- [{rsa_pad, rsa_pkcs1_padding}]) of
- Hashes ->
- true;
- _ ->
- false
- end;
-verify_dh_params(_Version, Signed, Hash, HashAlgo, {?'id-dsa', PublicKey, PublicKeyParams}) ->
- public_key:verify({digest, Hash}, HashAlgo, Signed, {PublicKey, PublicKeyParams}).
-
-dh_master_secret(Prime, Base, PublicDhKey, undefined, State) ->
- PMpint = mpint_binary(Prime),
- GMpint = mpint_binary(Base),
- Keys = {_, PrivateDhKey} =
- crypto:dh_generate_key([PMpint,GMpint]),
- dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State#state{diffie_hellman_keys = Keys});
+server_master_secret(#server_dh_params{dh_p = P, dh_g = G, dh_y = ServerPublicDhKey},
+ State) ->
+ dh_master_secret(P, G, ServerPublicDhKey, undefined, State).
-dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey,
- #state{session = Session,
- negotiated_version = Version, role = Role,
- connection_states = ConnectionStates0} = State) ->
- PremasterSecret =
- crypto:dh_compute_key(mpint_binary(PublicDhKey), PrivateDhKey,
- [PMpint, GMpint]),
+master_from_premaster_secret(PremasterSecret,
+ #state{session = Session,
+ negotiated_version = Version, role = Role,
+ connection_states = ConnectionStates0} = State) ->
case ssl_handshake:master_secret(Version, PremasterSecret,
ConnectionStates0, Role) of
{MasterSecret, ConnectionStates} ->
@@ -1711,6 +1681,19 @@ dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey,
Alert
end.
+dh_master_secret(Prime, Base, PublicDhKey, undefined, State) ->
+ PMpint = mpint_binary(Prime),
+ GMpint = mpint_binary(Base),
+ Keys = {_, PrivateDhKey} =
+ crypto:dh_generate_key([PMpint,GMpint]),
+ dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State#state{diffie_hellman_keys = Keys});
+
+dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State) ->
+ PremasterSecret =
+ crypto:dh_compute_key(mpint_binary(PublicDhKey), PrivateDhKey,
+ [PMpint, GMpint]),
+ master_from_premaster_secret(PremasterSecret, State).
+
cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) ->
ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0),
next_state_connection(cipher, ack_connection(State#state{session = Session,
@@ -2485,10 +2468,10 @@ get_pending_connection_state_prf(CStates, Direction) ->
CS = ssl_record:pending_connection_state(CStates, Direction),
CS#connection_state.security_parameters#security_parameters.prf_algorithm.
-connection_hash_algo({HashAlgo, _}, _State) ->
- HashAlgo;
-connection_hash_algo(_, #state{hashsign_algorithm = {HashAlgo, _}}) ->
- HashAlgo.
+connection_hashsign(HashSign = {_, _}, _State) ->
+ HashSign;
+connection_hashsign(_, #state{hashsign_algorithm = HashSign}) ->
+ HashSign.
%% RFC 5246, Sect. 7.4.1.4.1. Signature Algorithms
%% If the client does not send the signature_algorithms extension, the
@@ -2526,12 +2509,13 @@ default_hashsign(_Version, KeyExchange)
start_or_recv_cancel_timer(infinity, _RecvFrom) ->
undefined;
start_or_recv_cancel_timer(Timeout, RecvFrom) ->
- erlang:send_after(Timeout, self(), {cancel_start_or_recv, RecvFrom}).
+ erlang:send_after(Timeout, self(), {cancel_start_or_recv, RecvFrom}).
cancel_timer(undefined) ->
ok;
cancel_timer(Timer) ->
- erlang:cancel_timer(Timer).
+ erlang:cancel_timer(Timer),
+ ok.
handle_unrecv_data(StateName, #state{socket = Socket, transport_cb = Transport} = State) ->
inet:setopts(Socket, [{active, false}]),
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index db21dac942..1929370991 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -32,10 +32,10 @@
-export([master_secret/4, client_hello/8, server_hello/5, hello/4,
hello_request/0, certify/7, certificate/4,
- client_certificate_verify/6, certificate_verify/6,
+ client_certificate_verify/6, certificate_verify/6, verify_signature/5,
certificate_request/3, key_exchange/3, server_key_exchange_hash/2,
finished/5, verify_connection/6, get_tls_handshake/3,
- decode_client_key/3, server_hello_done/0,
+ decode_client_key/3, decode_server_key/3, server_hello_done/0,
encode_handshake/2, init_handshake_history/0, update_handshake_history/2,
decrypt_premaster_secret/2, prf/5, next_protocol/1]).
@@ -320,25 +320,36 @@ client_certificate_verify(OwnCert, MasterSecret, Version,
%%
%% Description: Checks that the certificate_verify message is valid.
%%--------------------------------------------------------------------
-certificate_verify(Signature, {?'rsaEncryption', PublicKey, _}, Version,
- {HashAlgo, _SignAlgo}, MasterSecret, {_, Handshake}) ->
- Hashes = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake),
- case certificate_verify_rsa(Hashes, HashAlgo, Signature, PublicKey, Version) of
+certificate_verify(Signature, PublicKeyInfo, Version,
+ HashSign = {HashAlgo, _}, MasterSecret, {_, Handshake}) ->
+ Hash = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake),
+ case verify_signature(Version, Hash, HashSign, Signature, PublicKeyInfo) of
true ->
valid;
_ ->
- ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE)
- end;
-certificate_verify(Signature, {?'id-dsa', PublicKey, PublicKeyParams}, Version,
- {HashAlgo, _SignAlgo}, MasterSecret, {_, Handshake}) ->
- Hashes = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake),
- case public_key:verify({digest, Hashes}, sha, Signature, {PublicKey, PublicKeyParams}) of
- true ->
- valid;
- false ->
?ALERT_REC(?FATAL, ?BAD_CERTIFICATE)
end.
+%%--------------------------------------------------------------------
+-spec verify_signature(tls_version(), binary(), {term(), term()}, binary(),
+ public_key_info()) -> true | false.
+%%
+%% Description: Checks that a public_key signature is valid.
+%%--------------------------------------------------------------------
+verify_signature(_Version, _Hash, {_HashAlgo, anon}, _Signature, _) ->
+ true;
+verify_signature({3, Minor}, Hash, {HashAlgo, rsa}, Signature, {?rsaEncryption, PubKey, _PubKeyParams})
+ when Minor >= 3 ->
+ public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey);
+verify_signature(_Version, Hash, _HashAlgo, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) ->
+ case public_key:decrypt_public(Signature, PubKey,
+ [{rsa_pad, rsa_pkcs1_padding}]) of
+ Hash -> true;
+ _ -> false
+ end;
+verify_signature(_Version, Hash, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) ->
+ public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}).
+
%%--------------------------------------------------------------------
-spec certificate_request(#connection_states{}, db_handle(), certdb_ref()) ->
@@ -382,31 +393,33 @@ key_exchange(client, _Version, {dh, <<?UINT32(Len), PublicKey:Len/binary>>}) ->
key_exchange(server, Version, {dh, {<<?UINT32(Len), PublicKey:Len/binary>>, _},
#'DHParameter'{prime = P, base = G},
- {HashAlgo, SignAlgo}, ClientRandom, ServerRandom, PrivateKey}) ->
+ HashSign, ClientRandom, ServerRandom, PrivateKey}) ->
<<?UINT32(_), PBin/binary>> = crypto:mpint(P),
<<?UINT32(_), GBin/binary>> = crypto:mpint(G),
- PLen = byte_size(PBin),
- GLen = byte_size(GBin),
- YLen = byte_size(PublicKey),
ServerDHParams = #server_dh_params{dh_p = PBin,
dh_g = GBin, dh_y = PublicKey},
+ enc_server_key_exchange(Version, ServerDHParams, HashSign,
+ ClientRandom, ServerRandom, PrivateKey).
+enc_server_key_exchange(Version, Params, {HashAlgo, SignAlgo},
+ ClientRandom, ServerRandom, PrivateKey) ->
+ EncParams = enc_server_key(Params),
case HashAlgo of
null ->
- #server_key_exchange{params = ServerDHParams,
- signed_params = <<>>,
- hashsign = {null, anon}};
+ #server_key_params{params = Params,
+ params_bin = EncParams,
+ hashsign = {null, anon},
+ signature = <<>>};
_ ->
Hash =
server_key_exchange_hash(HashAlgo, <<ClientRandom/binary,
- ServerRandom/binary,
- ?UINT16(PLen), PBin/binary,
- ?UINT16(GLen), GBin/binary,
- ?UINT16(YLen), PublicKey/binary>>),
- Signed = digitally_signed(Version, Hash, HashAlgo, PrivateKey),
- #server_key_exchange{params = ServerDHParams,
- signed_params = Signed,
- hashsign = {HashAlgo, SignAlgo}}
+ ServerRandom/binary,
+ EncParams/binary>>),
+ Signature = digitally_signed(Version, Hash, HashAlgo, PrivateKey),
+ #server_key_params{params = Params,
+ params_bin = EncParams,
+ hashsign = {HashAlgo, SignAlgo},
+ signature = Signature}
end.
%%--------------------------------------------------------------------
@@ -523,6 +536,15 @@ decode_client_key(ClientKey, Type, Version) ->
dec_client_key(ClientKey, key_exchange_alg(Type), Version).
%%--------------------------------------------------------------------
+-spec decode_server_key(binary(), key_algo(), tls_version()) ->
+ #server_key_params{}.
+%%
+%% Description: Decode server_key data and return appropriate type
+%%--------------------------------------------------------------------
+decode_server_key(ServerKey, Type, Version) ->
+ dec_server_key(ServerKey, key_exchange_alg(Type), Version).
+
+%%--------------------------------------------------------------------
-spec init_handshake_history() -> tls_handshake_history().
%%
@@ -975,31 +997,8 @@ dec_hs(_Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
next_protocol_negotiation = NextProtocolNegotiation};
dec_hs(_Version, ?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) ->
#certificate{asn1_certificates = certs_to_list(ASN1Certs)};
-
-dec_hs(_Version, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
- ?UINT16(GLen), G:GLen/binary,
- ?UINT16(YLen), Y:YLen/binary,
- ?UINT16(0)>>) -> %% May happen if key_algorithm is dh_anon
- #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
- dh_y = Y},
- signed_params = <<>>, hashsign = {null, anon}};
-dec_hs({Major, Minor}, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
- ?UINT16(GLen), G:GLen/binary,
- ?UINT16(YLen), Y:YLen/binary,
- ?BYTE(HashAlgo), ?BYTE(SignAlgo),
- ?UINT16(Len), Sig:Len/binary>>)
- when Major == 3, Minor >= 3 ->
- #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
- dh_y = Y},
- signed_params = Sig,
- hashsign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}};
-dec_hs(_Version, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
- ?UINT16(GLen), G:GLen/binary,
- ?UINT16(YLen), Y:YLen/binary,
- ?UINT16(Len), Sig:Len/binary>>) ->
- #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
- dh_y = Y},
- signed_params = Sig, hashsign = undefined};
+dec_hs(_Version, ?SERVER_KEY_EXCHANGE, Keys) ->
+ #server_key_exchange{exchange_keys = Keys};
dec_hs({Major, Minor}, ?CERTIFICATE_REQUEST,
<<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary,
?UINT16(HashSignsLen), HashSigns:HashSignsLen/binary,
@@ -1039,6 +1038,42 @@ dec_client_key(<<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>,
?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
#client_diffie_hellman_public{dh_public = DH_Y}.
+dec_ske_params(Len, Keys, Version) ->
+ <<Params:Len/bytes, Signature/binary>> = Keys,
+ dec_ske_signature(Params, Signature, Version).
+
+dec_ske_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo),
+ ?UINT16(0)>>, {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)},
+ {Params, HashSign, <<>>};
+dec_ske_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo),
+ ?UINT16(Len), Signature:Len/binary>>, {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)},
+ {Params, HashSign, Signature};
+dec_ske_signature(Params, <<>>, _) ->
+ {Params, {null, anon}, <<>>};
+dec_ske_signature(Params, <<?UINT16(0)>>, _) ->
+ {Params, {null, anon}, <<>>};
+dec_ske_signature(Params, <<?UINT16(Len), Signature:Len/binary>>, _) ->
+ {Params, undefined, Signature};
+dec_ske_signature(_, _, _) ->
+ throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)).
+
+dec_server_key(<<?UINT16(PLen), P:PLen/binary,
+ ?UINT16(GLen), G:GLen/binary,
+ ?UINT16(YLen), Y:YLen/binary, _/binary>> = KeyStruct,
+ ?KEY_EXCHANGE_DIFFIE_HELLMAN, Version) ->
+ Params = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y},
+ {BinMsg, HashSign, Signature} = dec_ske_params(PLen + GLen + YLen + 6, KeyStruct, Version),
+ #server_key_params{params = Params,
+ params_bin = BinMsg,
+ hashsign = HashSign,
+ signature = Signature};
+dec_server_key(_, _, _) ->
+ throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)).
+
dec_hello_extensions(<<>>) ->
[];
dec_hello_extensions(<<?UINT16(ExtLen), Extensions:ExtLen/binary>>) ->
@@ -1156,18 +1191,12 @@ enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version) ->
ASN1Certs = certs_from_list(ASN1CertList),
ACLen = erlang:iolist_size(ASN1Certs),
{?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>};
-enc_hs(#server_key_exchange{params = #server_dh_params{
- dh_p = P, dh_g = G, dh_y = Y},
- signed_params = SignedParams, hashsign = HashSign}, Version) ->
- PLen = byte_size(P),
- GLen = byte_size(G),
- YLen = byte_size(Y),
- Signature = enc_sign(HashSign, SignedParams, Version),
- {?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P/binary,
- ?UINT16(GLen), G/binary,
- ?UINT16(YLen), Y/binary,
- Signature/binary>>
- };
+enc_hs(#server_key_exchange{exchange_keys = Keys}, _Version) ->
+ {?SERVER_KEY_EXCHANGE, Keys};
+enc_hs(#server_key_params{params_bin = Keys, hashsign = HashSign,
+ signature = Signature}, Version) ->
+ EncSign = enc_sign(HashSign, Signature, Version),
+ {?SERVER_KEY_EXCHANGE, <<Keys/binary, EncSign/binary>>};
enc_hs(#certificate_request{certificate_types = CertTypes,
hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSignAlgos},
certificate_authorities = CertAuths},
@@ -1211,6 +1240,14 @@ enc_cke(#client_diffie_hellman_public{dh_public = DHPublic}, _) ->
Len = byte_size(DHPublic),
<<?UINT16(Len), DHPublic/binary>>.
+enc_server_key(#server_dh_params{dh_p = P, dh_g = G, dh_y = Y}) ->
+ PLen = byte_size(P),
+ GLen = byte_size(G),
+ YLen = byte_size(Y),
+ <<?UINT16(PLen), P/binary, ?UINT16(GLen), G/binary, ?UINT16(YLen), Y/binary>>.
+
+enc_sign({_, anon}, _Sign, _Version) ->
+ <<>>;
enc_sign({HashAlg, SignAlg}, Signature, _Version = {Major, Minor})
when Major == 3, Minor >= 3->
SignLen = byte_size(Signature),
@@ -1328,8 +1365,8 @@ certificate_authorities_from_db(CertDbHandle, CertDbRef) ->
digitally_signed({3, Minor}, Hash, HashAlgo, Key) when Minor >= 3 ->
public_key:sign({digest, Hash}, HashAlgo, Key);
-digitally_signed(_Version, Hash, _HashAlgo, #'DSAPrivateKey'{} = Key) ->
- public_key:sign({digest, Hash}, sha, Key);
+digitally_signed(_Version, Hash, HashAlgo, #'DSAPrivateKey'{} = Key) ->
+ public_key:sign({digest, Hash}, HashAlgo, Key);
digitally_signed(_Version, Hash, _HashAlgo, #'RSAPrivateKey'{} = Key) ->
public_key:encrypt_private(Hash, Key,
[{rsa_pad, rsa_pkcs1_padding}]).
@@ -1378,19 +1415,6 @@ apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) ->
{unknown, {SslState, UserState}}
end.
-certificate_verify_rsa(Hashes, sha, Signature, PublicKey, {Major, Minor})
- when Major == 3, Minor >= 3 ->
- public_key:verify({digest, Hashes}, sha, Signature, PublicKey);
-certificate_verify_rsa(Hashes, HashAlgo, Signature, PublicKey, {Major, Minor})
- when Major == 3, Minor >= 3 ->
- public_key:verify({digest, Hashes}, HashAlgo, Signature, PublicKey);
-certificate_verify_rsa(Hashes, _HashAlgo, Signature, PublicKey, _Version) ->
- case public_key:decrypt_public(Signature, PublicKey,
- [{rsa_pad, rsa_pkcs1_padding}]) of
- Hashes -> true;
- _ -> false
- end.
-
-define(TLSEXT_SIGALG_RSA(MD), {MD, rsa}).
-define(TLSEXT_SIGALG_DSA(MD), {MD, dsa}).
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index 9af6511d68..2414d5b666 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -141,9 +141,14 @@
}).
-record(server_key_exchange, {
+ exchange_keys
+ }).
+
+-record(server_key_params, {
params, %% #server_rsa_params{} | #server_dh_params{}
- signed_params, %% #signature{}
- hashsign %% term(atom(), atom())
+ params_bin,
+ hashsign, %% term(atom(), atom())
+ signature %% #signature{}
}).
%% enum { anonymous, rsa, dsa } SignatureAlgorithm;
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 13689ce7d8..aa9da65bb8 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-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
@@ -142,8 +142,15 @@ lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) ->
new_session_id(Port) ->
call({new_session_id, Port}).
+%%--------------------------------------------------------------------
+-spec clean_cert_db(reference(), binary()) -> ok.
+%%
+%% Description: Send clean request of cert db to ssl_manager process should
+%% be called by ssl-connection processes.
+%%--------------------------------------------------------------------
clean_cert_db(Ref, File) ->
- erlang:send_after(?CLEAN_CERT_DB, self(), {clean_cert_db, Ref, File}).
+ erlang:send_after(?CLEAN_CERT_DB, get(ssl_manager), {clean_cert_db, Ref, File}),
+ ok.
%%--------------------------------------------------------------------
-spec register_session(inet:port_number(), #session{}) -> ok.
@@ -320,19 +327,12 @@ handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace]} = State) ->
handle_info({clean_cert_db, Ref, File},
#state{certificate_db = [CertDb,RefDb, PemCache]} = State) ->
- case ssl_certificate_db:ref_count(Ref, RefDb, 0) of
- 0 ->
- MD5 = crypto:md5(File),
- case ssl_certificate_db:lookup_cached_pem(PemCache, MD5) of
- [{Content, Ref}] ->
- ssl_certificate_db:insert(MD5, Content, PemCache);
- undefined ->
- ok
- end,
- ssl_certificate_db:remove(Ref, RefDb),
- ssl_certificate_db:remove_trusted_certs(Ref, CertDb);
+
+ case ssl_certificate_db:lookup(Ref, RefDb) of
+ undefined -> %% Alredy cleaned
+ ok;
_ ->
- ok
+ clean_cert_db(Ref, CertDb, RefDb, PemCache, File)
end,
{noreply, State};
@@ -345,7 +345,7 @@ handle_info(_Info, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
--spec terminate(reason(), #state{}) -> term().
+-spec terminate(reason(), #state{}) -> ok.
%%
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
@@ -464,3 +464,19 @@ new_id(Port, Tries, Cache, CacheCb) ->
_ ->
new_id(Port, Tries - 1, Cache, CacheCb)
end.
+
+clean_cert_db(Ref, CertDb, RefDb, PemCache, File) ->
+ case ssl_certificate_db:ref_count(Ref, RefDb, 0) of
+ 0 ->
+ MD5 = crypto:md5(File),
+ case ssl_certificate_db:lookup_cached_pem(PemCache, MD5) of
+ [{Content, Ref}] ->
+ ssl_certificate_db:insert(MD5, Content, PemCache);
+ _ ->
+ ok
+ end,
+ ssl_certificate_db:remove(Ref, RefDb),
+ ssl_certificate_db:remove_trusted_certs(Ref, CertDb);
+ _ ->
+ ok
+ end.
diff --git a/lib/ssl/src/ssl_tls_dist_proxy.erl b/lib/ssl/src/ssl_tls_dist_proxy.erl
index a8476b104f..a22af6b960 100644
--- a/lib/ssl/src/ssl_tls_dist_proxy.erl
+++ b/lib/ssl/src/ssl_tls_dist_proxy.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2011-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
@@ -89,7 +89,7 @@ handle_call({connect, Ip, Port}, {From, _}, State) ->
ok ->
flush_old_controller(From, Socket),
{reply, Res, State}
- end;
+ end;
{Pid, Error} ->
{reply, Error, State}
end;
@@ -115,13 +115,13 @@ code_change(_OldVsn, St, _Extra) ->
get_tcp_address(Socket) ->
case inet:sockname(Socket) of
{ok, Address} ->
- {ok, Host} = inet:gethostname(),
+ {ok, Host} = inet:gethostname(),
NetAddress = #net_address{
- address = Address,
- host = Host,
- protocol = proxy,
- family = inet
- },
+ address = Address,
+ host = Host,
+ protocol = proxy,
+ family = inet
+ },
{ok, NetAddress};
{error, _} = Error -> Error
end.
@@ -129,17 +129,17 @@ get_tcp_address(Socket) ->
accept_loop(Proxy, erts = Type, Listen, Extra) ->
process_flag(priority, max),
case gen_tcp:accept(Listen) of
- {ok, Socket} ->
- Extra ! {accept,self(),Socket,inet,proxy},
- receive
- {_Kernel, controller, Pid} ->
- ok = gen_tcp:controlling_process(Socket, Pid),
- flush_old_controller(Pid, Socket),
- Pid ! {self(), controller};
- {_Kernel, unsupported_protocol} ->
- exit(unsupported_protocol)
- end;
- Error ->
+ {ok, Socket} ->
+ Extra ! {accept,self(),Socket,inet,proxy},
+ receive
+ {_Kernel, controller, Pid} ->
+ ok = gen_tcp:controlling_process(Socket, Pid),
+ flush_old_controller(Pid, Socket),
+ Pid ! {self(), controller};
+ {_Kernel, unsupported_protocol} ->
+ exit(unsupported_protocol)
+ end;
+ Error ->
exit(Error)
end,
accept_loop(Proxy, Type, Listen, Extra);
@@ -242,7 +242,7 @@ loop_conn(World, Erts) ->
ssl:close(World);
{ssl_closed, World} ->
gen_tcp:close(Erts)
- end.
+ end.
get_ssl_options(Type) ->
case init:get_argument(ssl_dist_opt) of
@@ -255,7 +255,7 @@ get_ssl_options(Type) ->
ssl_options(_,[]) ->
[];
ssl_options(server, ["client_" ++ _, _Value |T]) ->
- ssl_options(server,T);
+ ssl_options(server,T);
ssl_options(client, ["server_" ++ _, _Value|T]) ->
ssl_options(client,T);
ssl_options(server, ["server_certfile", Value|T]) ->
@@ -265,7 +265,7 @@ ssl_options(client, ["client_certfile", Value | T]) ->
ssl_options(server, ["server_cacertfile", Value|T]) ->
[{cacertfile, Value} | ssl_options(server,T)];
ssl_options(client, ["client_cacertfile", Value|T]) ->
- [{cacertfile, Value} | ssl_options(client,T)];
+ [{cacertfile, Value} | ssl_options(client,T)];
ssl_options(server, ["server_keyfile", Value|T]) ->
[{keyfile, Value} | ssl_options(server,T)];
ssl_options(client, ["client_keyfile", Value|T]) ->
@@ -277,7 +277,7 @@ ssl_options(client, ["client_password", Value|T]) ->
ssl_options(server, ["server_verify", Value|T]) ->
[{verify, atomize(Value)} | ssl_options(server,T)];
ssl_options(client, ["client_verify", Value|T]) ->
- [{verify, atomize(Value)} | ssl_options(client,T)];
+ [{verify, atomize(Value)} | ssl_options(client,T)];
ssl_options(server, ["server_reuse_sessions", Value|T]) ->
[{reuse_sessions, atomize(Value)} | ssl_options(server,T)];
ssl_options(client, ["client_reuse_sessions", Value|T]) ->
@@ -295,11 +295,11 @@ ssl_options(server, ["server_hibernate_after", Value|T]) ->
ssl_options(client, ["client_hibernate_after", Value|T]) ->
[{hibernate_after, list_to_integer(Value)} | ssl_options(client,T)];
ssl_options(server, ["server_ciphers", Value|T]) ->
- [{ciphers, Value} | ssl_options(server,T)];
+ [{ciphers, Value} | ssl_options(server,T)];
ssl_options(client, ["client_ciphers", Value|T]) ->
[{ciphers, Value} | ssl_options(client,T)];
ssl_options(server, ["server_dhfile", Value|T]) ->
- [{dhfile, Value} | ssl_options(server,T)];
+ [{dhfile, Value} | ssl_options(server,T)];
ssl_options(server, ["server_fail_if_no_peer_cert", Value|T]) ->
[{fail_if_no_peer_cert, atomize(Value)} | ssl_options(server,T)];
ssl_options(_,_) ->
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 5ba71f9218..7067cd861d 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -84,7 +84,8 @@ basic_tests() ->
alerts,
send_close,
connect_twice,
- connect_dist
+ connect_dist,
+ clear_pem_cache
].
options_tests() ->
@@ -536,6 +537,33 @@ connect_dist(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+
+clear_pem_cache() ->
+ [{doc,"Test that internal reference tabel is cleaned properly even when "
+ " the PEM cache is cleared" }].
+clear_pem_cache(Config) when is_list(Config) ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ [_,FilRefDb, _] = element(5, State),
+ {Server, Client} = basic_verify_test_no_close(Config),
+ 2 = ets:info(FilRefDb, size),
+ ssl:clear_pem_cache(),
+ _ = sys:get_status(whereis(ssl_manager)),
+ {Server1, Client1} = basic_verify_test_no_close(Config),
+ 4 = ets:info(FilRefDb, size),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ct:sleep(5000),
+ _ = sys:get_status(whereis(ssl_manager)),
+ 2 = ets:info(FilRefDb, size),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1),
+ ct:sleep(5000),
+ _ = sys:get_status(whereis(ssl_manager)),
+ 0 = ets:info(FilRefDb, size).
+
+%%--------------------------------------------------------------------
peername() ->
[{doc,"Test API function peername/1"}].
@@ -1567,8 +1595,8 @@ default_reject_anonymous(Config) when is_list(Config) ->
[{ciphers,[Cipher]} |
ClientOpts]}]),
- ssl_test_lib:check_result(Server, {error, "insufficient security"},
- Client, {error, "insufficient security"}).
+ ssl_test_lib:check_result(Server, {error, {essl, "insufficient security"}},
+ Client, {error, {essl, "insufficient security"}}).
%%--------------------------------------------------------------------
reuse_session() ->
@@ -2641,6 +2669,26 @@ tcp_send_recv_result(Socket) ->
{ok,"Hello world"} = gen_tcp:recv(Socket, 11),
ok.
+basic_verify_test_no_close(Config) ->
+ ClientOpts = ?config(client_verification_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()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ {Server, Client}.
+
basic_test(Config) ->
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
@@ -2659,7 +2707,6 @@ basic_test(Config) ->
{options, ClientOpts}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
-
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
@@ -2908,7 +2955,7 @@ erlang_ssl_receive(Socket, Data) ->
erlang_ssl_receive(Socket, tl(Data));
Other ->
ct:fail({unexpected_message, Other})
- after ?SLEEP * 3 ->
+ after ?SLEEP * 3 * test_server:timetrap_scale_factor() ->
ct:fail({did_not_get, Data})
end.
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 9677d98c1b..86e1d47be7 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -252,8 +252,8 @@ server_require_peer_cert_fail(Config) when is_list(Config) ->
{from, self()},
{options, [{active, false} | BadClientOpts]}]),
- ssl_test_lib:check_result(Server, {error, esslaccept},
- Client, {error, esslconnect}).
+ ssl_test_lib:check_result(Server, {error, {essl, "handshake failure"}},
+ Client, {error, {essl, "handshake failure"}}).
%%--------------------------------------------------------------------
@@ -293,14 +293,14 @@ verify_fun_always_run_client(Config) when is_list(Config) ->
[{verify, verify_peer},
{verify_fun, FunAndState}
| ClientOpts]}]),
- %% Server error may be esslaccept or closed depending on timing
+ %% Server error may be {essl,"handshake failure"} or closed depending on timing
%% this is not a bug it is a circumstance of how tcp works!
receive
{Server, ServerError} ->
ct:print("Server Error ~p~n", [ServerError])
end,
- ssl_test_lib:check_result(Client, {error, esslconnect}).
+ ssl_test_lib:check_result(Client, {error, {essl, "handshake failure"}}).
%%--------------------------------------------------------------------
verify_fun_always_run_server() ->
@@ -342,14 +342,14 @@ verify_fun_always_run_server(Config) when is_list(Config) ->
[{verify, verify_peer}
| ClientOpts]}]),
- %% Client error may be esslconnect or closed depending on timing
+ %% Client error may be {essl, "handshake failure" } or closed depending on timing
%% this is not a bug it is a circumstance of how tcp works!
receive
{Client, ClientError} ->
ct:print("Client Error ~p~n", [ClientError])
end,
- ssl_test_lib:check_result(Server, {error, esslaccept}).
+ ssl_test_lib:check_result(Server, {error, {essl, "handshake failure"}}).
%%--------------------------------------------------------------------
@@ -380,7 +380,7 @@ client_verify_none_passive(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
cert_expired() ->
- [{doc,"Test server with invalid signature"}].
+ [{doc,"Test server with expired certificate"}].
cert_expired(Config) when is_list(Config) ->
ClientOpts = ?config(client_verification_opts, Config),
@@ -432,8 +432,8 @@ cert_expired(Config) when is_list(Config) ->
{from, self()},
{options, [{verify, verify_peer} | ClientOpts]}]),
- ssl_test_lib:check_result(Server, {error, "certificate expired"},
- Client, {error, "certificate expired"}).
+ ssl_test_lib:check_result(Server, {error, {essl, "certificate expired"}},
+ Client, {error, {essl, "certificate expired"}}).
two_digits_str(N) when N < 10 ->
lists:flatten(io_lib:format("0~p", [N]));
@@ -679,7 +679,7 @@ delete_authority_key_extension([Head | Rest], Acc) ->
%%--------------------------------------------------------------------
invalid_signature_server() ->
- [{doc,"Test server with invalid signature"}].
+ [{doc,"Test client with invalid signature"}].
invalid_signature_server(Config) when is_list(Config) ->
ClientOpts = ?config(client_verification_opts, Config),
@@ -710,8 +710,8 @@ invalid_signature_server(Config) when is_list(Config) ->
{from, self()},
{options, [{verify, verify_peer} | ClientOpts]}]),
- tcp_delivery_workaround(Server, {error, "bad certificate"},
- Client, {error,"bad certificate"}).
+ tcp_delivery_workaround(Server, {error, {essl, "bad certificate"}},
+ Client, {error, {essl, "bad certificate"}}).
%%--------------------------------------------------------------------
@@ -747,8 +747,8 @@ invalid_signature_client(Config) when is_list(Config) ->
{from, self()},
{options, NewClientOpts}]),
- tcp_delivery_workaround(Server, {error, "bad certificate"},
- Client, {error,"bad certificate"}).
+ tcp_delivery_workaround(Server, {error, {essl, "bad certificate"}},
+ Client, {error, {essl, "bad certificate"}}).
%%--------------------------------------------------------------------
@@ -829,8 +829,8 @@ unknown_server_ca_fail(Config) when is_list(Config) ->
{verify_fun, FunAndState}
| ClientOpts]}]),
- ssl_test_lib:check_result(Server, {error,"unknown ca"},
- Client, {error, "unknown ca"}).
+ ssl_test_lib:check_result(Server, {error, {essl, "unknown ca"}},
+ Client, {error, {essl, "unknown ca"}}).
%%--------------------------------------------------------------------
unknown_server_ca_accept_verify_none() ->
@@ -947,10 +947,6 @@ tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) ->
{Client, {error,closed}} ->
server_msg(Server, ServerMsg);
{Server, {error,closed}} ->
- client_msg(Client, ClientMsg);
- {Client, {error, esslconnect}} ->
- server_msg(Server, ServerMsg);
- {Server, {error, esslaccept}} ->
client_msg(Client, ClientMsg)
end.
@@ -961,8 +957,8 @@ client_msg(Client, ClientMsg) ->
{Client, {error,closed}} ->
ct:print("client got close"),
ok;
- {Client, {error, esslconnect}} ->
- ct:print("client got econnaborted"),
+ {Client, {error, Reason}} ->
+ ct:print("client got econnaborted: ~p", [Reason]),
ok;
Unexpected ->
ct:fail(Unexpected)
@@ -974,8 +970,8 @@ server_msg(Server, ServerMsg) ->
{Server, {error,closed}} ->
ct:print("server got close"),
ok;
- {Server, {error, esslaccept}} ->
- ct:print("server got econnaborted"),
+ {Server, {error, Reason}} ->
+ ct:print("server got econnaborted: ~p", [Reason]),
ok;
Unexpected ->
ct:fail(Unexpected)
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 76b302b1cb..8d96a70a6e 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -203,6 +203,67 @@ close(Pid) ->
ct:print("Pid: ~p down due to:~p ~n", [Pid, Reason])
end.
+
+check_result(Server, {error, SReason} = ServerMsg, Client, {error, closed} = ClientMsg) ->
+ receive
+ {Server, {error, {SReason, _}}} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {got, Unexpected}},
+ ct:fail(Reason)
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, {error, {SReason, _}}} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Server,{error, {SReason, 'term()'}}},
+ {got, Unexpected}}},
+ ct:fail(Reason)
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Server, ServerMsg, Client, ClientMsg);
+
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {expected, {Server, {error, {SReason, 'term()'}}}, {got, Unexpected}}},
+ ct:fail(Reason)
+ end;
+
+check_result(Server, {error, closed} = ServerMsg, Client, {error, CReson} = ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, {error, {CReson, _}}} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Client, {error, {CReson, 'term()'}}},
+ {got, Unexpected}}},
+ ct:fail(Reason)
+ end;
+ {Client, {error, {CReson, _}}} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Server, ServerMsg}},
+ {got, Unexpected}},
+ ct:fail(Reason)
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Server, ServerMsg, Client, ClientMsg);
+
+ Unexpected ->
+ Reason = {{expected, {Client, {error, {CReson, 'term()'}}},
+ {expected, {Server, ServerMsg}}, {got, Unexpected}}},
+ ct:fail(Reason)
+ end;
+
check_result(Server, ServerMsg, Client, ClientMsg) ->
receive
{Server, ServerMsg} ->
@@ -233,6 +294,22 @@ check_result(Server, ServerMsg, Client, ClientMsg) ->
ct:fail(Reason)
end.
+check_result(Pid, {error, Reason} = Err) when Reason == ecertfile;
+ Reason == ecacertfile;
+ Reason == ekeyfile;
+ Reason == edhfile ->
+ receive
+ {Pid, {error, {Reason, Str}}} when is_list(Str) ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Pid, Err);
+ Unexpected ->
+ Reason = {{expected, {Pid, {error, {Reason, "'appropriate error string'"}}}},
+ {got, Unexpected}},
+ ct:fail(Reason)
+ end;
+
check_result(Pid, Msg) ->
receive
{Pid, Msg} ->
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index d5e7d515fd..7c0c00bf36 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -902,7 +902,7 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
ok
end,
- ssl_test_lib:check_result(Server, {error,"protocol version"}),
+ ssl_test_lib:check_result(Server, {error, {essl, "protocol version"}}),
process_flag(trap_exit, false).
%%--------------------------------------------------------------------
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index adfb29e639..cb73e86ede 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 5.1.2
+SSL_VSN = 5.2
diff --git a/lib/stdlib/doc/src/base64.xml b/lib/stdlib/doc/src/base64.xml
index bfe8494a73..e4ce841a8a 100644
--- a/lib/stdlib/doc/src/base64.xml
+++ b/lib/stdlib/doc/src/base64.xml
@@ -37,6 +37,11 @@
<datatype>
<name name="ascii_string"/>
</datatype>
+ <datatype>
+ <name name="ascii_binary"/>
+ <desc><p>A <c>binary()</c> with ASCII characters in the range 1 to 255.</p>
+ </desc>
+ </datatype>
</datatypes>
<funcs>
<func>
diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml
index 3e8aba2e5f..df7bf883fc 100644
--- a/lib/stdlib/doc/src/epp.xml
+++ b/lib/stdlib/doc/src/epp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2012</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -109,7 +109,8 @@
<fsummary>Return a string representation of an encoding</fsummary>
<desc>
<p>Returns a string representation of an encoding. The string
- is recognized by <c>read_encoding/1,2</c> and
+ is recognized by <c>read_encoding/1,2</c>,
+ <c>read_encoding_from_binary/1,2</c>, and
<c>set_encoding/1</c> as a valid encoding.</p>
</desc>
</func>
@@ -128,6 +129,20 @@
</desc>
</func>
<func>
+ <name name="read_encoding_from_binary" arity="1"/>
+ <name name="read_encoding_from_binary" arity="2"/>
+ <fsummary>Read the encoding from a binary</fsummary>
+ <desc>
+ <p>Read the <seealso marker="#encoding">encoding</seealso> from
+ a binary. Returns the read encoding, or <c>none</c> if no
+ valid encoding was found.</p>
+ <p>The option <c>in_comment_only</c> is <c>true</c> by
+ default, which is correct for Erlang source files. If set to
+ <c>false</c> the encoding string does not necessarily have to
+ occur in a comment.</p>
+ </desc>
+ </func>
+ <func>
<name name="set_encoding" arity="1"/>
<fsummary>Read and set the encoding of an IO device</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index 22cd45a482..fa475804eb 100644
--- a/lib/stdlib/doc/src/io.xml
+++ b/lib/stdlib/doc/src/io.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2012</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -306,6 +306,11 @@
<item>
<p>The parsing failed.</p>
</item>
+ <tag><c>{error, <anno>ErrorDescription</anno>}</c></tag>
+ <item>
+ <p>Other (rare) error condition, for instance <c>{error, estale}</c>
+ if reading from an NFS file system.</p>
+ </item>
</taglist>
</desc>
</func>
@@ -333,6 +338,11 @@
<item>
<p>The parsing failed.</p>
</item>
+ <tag><c>{error, <anno>ErrorDescription</anno>}</c></tag>
+ <item>
+ <p>Other (rare) error condition, for instance <c>{error, estale}</c>
+ if reading from an NFS file system.</p>
+ </item>
</taglist>
</desc>
</func>
@@ -440,9 +450,12 @@ ok</pre>
</item>
<tag><c>s</c></tag>
<item>
- <p>Prints the argument with the <c>string</c> syntax. The
+ <p>Prints the argument with the string syntax. The
argument is, if no Unicode translation modifier is present, an
- iolist(), a binary, or an atom. If the Unicode translation modifier (<c>t</c>) is in effect, the argument is unicode:chardata(), meaning that binaries are in UTF-8. The characters
+ <c>iolist()</c>, a <c>binary()</c>, or an <c>atom()</c>.
+ If the Unicode translation modifier (<c>t</c>) is in effect,
+ the argument is <c>unicode:chardata()</c>, meaning that
+ binaries are in UTF-8. The characters
are printed without quotes. The string is first truncated
by the given precision and then padded and justified
to the given field width. The default precision is the field width.</p>
@@ -480,9 +493,8 @@ ok
<c>~w</c>, but breaks terms whose printed representation
is longer than one line into many lines and indents each
line sensibly. It also tries to detect lists of
- printable characters and to output these as strings. The
- Unicode translation modifier is used for determining
- what characters are printable. For example:</p>
+ printable characters and to output these as strings.
+ For example:</p>
<pre>
5> <input>T = [{attributes,[[{id,age,1.50000},{mode,explicit},</input>
<input>{typename,"INTEGER"}], [{id,cho},{mode,explicit},{typename,'Cho'}]]},</input>
@@ -521,19 +533,6 @@ Here T = [{attributes,[[{id,age,1.5},
{tag,{'PRIVATE',3}},
{mode,implicit}]
ok</pre>
- <p>Binaries that look like UTF-8 encoded strings will be
- output with the string syntax if the Unicode translation
- modifier is given:</p>
- <pre>
-9> <input>io:fwrite("~p~n",[[1024]]).</input>
-[1024]
-10> <input>io:fwrite("~tp~n",[[1024]]).</input>
-"\x{400}"
-11> <input>io:fwrite("~tp~n", [&lt;&lt;128,128&gt;&gt;]).</input>
-&lt;&lt;128,128&gt;&gt;
-12> <input>io:fwrite("~tp~n", [&lt;&lt;208,128&gt;&gt;]).</input>
-&lt;&lt;"\x{400}"/utf8&gt;&gt;
-ok</pre>
</item>
<tag><c>W</c></tag>
<item>
@@ -848,12 +847,21 @@ enter><input>:</input> <input>alan</input> <input>:</input> <input>joe</in
</item>
<tag><c>{eof, EndLocation}</c></tag>
<item>
- <p>End of file was encountered.</p>
+ <p>End of file was encountered by the tokenizer.</p>
+ </item>
+ <tag><c>eof</c></tag>
+ <item>
+ <p>End of file was encountered by the I/O-server.</p>
</item>
<tag><c>{error, ErrorInfo, ErrorLocation}</c></tag>
<item>
- <p>An error occurred.</p>
+ <p>An error occurred while tokenizing.</p>
</item>
+ <tag><c>{error, <anno>ErrorDescription</anno>}</c></tag>
+ <item>
+ <p>Other (rare) error condition, for instance <c>{error, estale}</c>
+ if reading from an NFS file system.</p>
+ </item>
</taglist>
<p>Example:</p>
<pre>
@@ -910,12 +918,21 @@ enter><input>1.0er.</input>
</item>
<tag><c>{eof, EndLocation}</c></tag>
<item>
- <p>End of file was encountered.</p>
+ <p>End of file was encountered by the tokenizer.</p>
+ </item>
+ <tag><c>eof</c></tag>
+ <item>
+ <p>End of file was encountered by the I/O-server.</p>
</item>
<tag><c>{error, ErrorInfo, ErrorLocation}</c></tag>
<item>
- <p>An error occurred.</p>
+ <p>An error occurred while tokenizing or parsing.</p>
</item>
+ <tag><c>{error, <anno>ErrorDescription</anno>}</c></tag>
+ <item>
+ <p>Other (rare) error condition, for instance <c>{error, estale}</c>
+ if reading from an NFS file system.</p>
+ </item>
</taglist>
<p>Example:</p>
<pre>
@@ -952,12 +969,21 @@ enter><input>abc("hey".</input>
</item>
<tag><c>{eof, EndLocation}</c></tag>
<item>
- <p>End of file was encountered.</p>
+ <p>End of file was encountered by the tokenizer.</p>
+ </item>
+ <tag><c>eof</c></tag>
+ <item>
+ <p>End of file was encountered by the I/O-server.</p>
</item>
<tag><c>{error, ErrorInfo, ErrorLocation}</c></tag>
<item>
- <p>An error occurred.</p>
+ <p>An error occurred while tokenizing or parsing.</p>
</item>
+ <tag><c>{error, <anno>ErrorDescription</anno>}</c></tag>
+ <item>
+ <p>Other (rare) error condition, for instance <c>{error, estale}</c>
+ if reading from an NFS file system.</p>
+ </item>
</taglist>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/io_lib.xml b/lib/stdlib/doc/src/io_lib.xml
index 617a6b74fc..001d34a7c2 100644
--- a/lib/stdlib/doc/src/io_lib.xml
+++ b/lib/stdlib/doc/src/io_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2012</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -43,12 +43,6 @@
<name name="chars"/>
</datatype>
<datatype>
- <name name="unicode_chars"/>
- </datatype>
- <datatype>
- <name name="unicode_string"/>
- </datatype>
- <datatype>
<name name="continuation"/>
<desc><p>A continuation as returned by <seealso marker="#fread/3"><c>fread/3</c></seealso>.</p>
</desc>
@@ -59,6 +53,9 @@
<datatype>
<name name="fread_error"/>
</datatype>
+ <datatype>
+ <name name="latin1_string"/>
+ </datatype>
</datatypes>
<funcs>
<func>
@@ -213,25 +210,25 @@
<name name="write_string" arity="1"/>
<fsummary>Write a string</fsummary>
<desc>
- <p>Returns the list of characters needed to print <c><anno>String</anno></c>
- as a string.</p>
+ <p>Returns the list of characters needed to print
+ <c><anno>String</anno></c> as a string.</p>
</desc>
</func>
<func>
- <name name="write_unicode_string" arity="1"/>
- <fsummary>Write a Unicode string</fsummary>
+ <name name="write_string_as_latin1" arity="1"/>
+ <fsummary>Write a string</fsummary>
<desc>
<p>Returns the list of characters needed to print
- <c><anno>UnicodeString</anno></c> as a string.</p>
+ <c><anno>String</anno></c> as a string. Non-Latin-1
+ characters are escaped.</p>
</desc>
</func>
<func>
- <name name="write_unicode_string_as_latin1" arity="1"/>
- <fsummary>Write a Unicode string</fsummary>
+ <name name="write_latin1_string" arity="1"/>
+ <fsummary>Write an ISO-latin-1 string</fsummary>
<desc>
<p>Returns the list of characters needed to print
- <c><anno>UnicodeString</anno></c> as a string. Non-Latin-1
- characters are escaped.</p>
+ <c><anno>Latin1String</anno></c> as a string.</p>
</desc>
</func>
<func>
@@ -239,24 +236,24 @@
<fsummary>Write a character</fsummary>
<desc>
<p>Returns the list of characters needed to print a character
- constant in the ISO-latin-1 character set.</p>
+ constant in the Unicode character set.</p>
</desc>
</func>
<func>
- <name name="write_unicode_char" arity="1"/>
- <fsummary>Write a Unicode character</fsummary>
+ <name name="write_char_as_latin1" arity="1"/>
+ <fsummary>Write a character</fsummary>
<desc>
<p>Returns the list of characters needed to print a character
- constant in the Unicode character set.</p>
+ constant in the Unicode character set. Non-Latin-1 characters
+ are escaped.</p>
</desc>
</func>
<func>
- <name name="write_unicode_char_as_latin1" arity="1"/>
- <fsummary>Write a Unicode character</fsummary>
+ <name name="write_latin1_char" arity="1"/>
+ <fsummary>Write an ISO-latin-1 character</fsummary>
<desc>
<p>Returns the list of characters needed to print a character
- constant in the Unicode character set. Non-Latin-1 characters
- are escaped.</p>
+ constant in the ISO-latin-1 character set.</p>
</desc>
</func>
<func>
@@ -272,15 +269,15 @@
<fsummary>Test for a list of characters</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a flat list of
- characters in the ISO-latin-1 range, otherwise it returns <c>false</c>.</p>
+ characters in the Unicode range, otherwise it returns <c>false</c>.</p>
</desc>
</func>
<func>
- <name name="unicode_char_list" arity="1"/>
- <fsummary>Test for a list of Unicode characters</fsummary>
+ <name name="latin1_char_list" arity="1"/>
+ <fsummary>Test for a list of ISO-latin-1 characters</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a flat list of
- characters in the Unicode range, otherwise it returns <c>false</c>.</p>
+ characters in the ISO-latin-1 range, otherwise it returns <c>false</c>.</p>
</desc>
</func>
<func>
@@ -288,31 +285,31 @@
<fsummary>Test for a deep list of characters</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a, possibly deep, list
- of characters in the ISO-latin-1 range, otherwise it returns <c>false</c>.</p>
+ of characters in the Unicode range, otherwise it returns <c>false</c>.</p>
</desc>
</func>
<func>
- <name name="deep_unicode_char_list" arity="1"/>
- <fsummary>Test for a deep list of Unicode characters</fsummary>
+ <name name="deep_latin1_char_list" arity="1"/>
+ <fsummary>Test for a deep list of characters</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a, possibly deep, list
- of characters in the Unicode range, otherwise it returns <c>false</c>.</p>
+ of characters in the ISO-latin-1 range, otherwise it returns <c>false</c>.</p>
</desc>
</func>
<func>
<name name="printable_list" arity="1"/>
- <fsummary>Test for a list of printable ISO-latin-1 characters</fsummary>
+ <fsummary>Test for a list of printable characters</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a flat list of
- printable ISO-latin-1 characters, otherwise it returns <c>false</c>.</p>
+ printable Unicode characters, otherwise it returns <c>false</c>.</p>
</desc>
</func>
<func>
- <name name="printable_unicode_list" arity="1"/>
- <fsummary>Test for a list of printable Unicode characters</fsummary>
+ <name name="printable_latin1_list" arity="1"/>
+ <fsummary>Test for a list of printable ISO-latin-1 characters</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a flat list of
- printable Unicode characters, otherwise it returns <c>false</c>.</p>
+ printable ISO-latin-1 characters, otherwise it returns <c>false</c>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/stdlib/doc/src/proc_lib.xml b/lib/stdlib/doc/src/proc_lib.xml
index abc17c4a91..b597074044 100644
--- a/lib/stdlib/doc/src/proc_lib.xml
+++ b/lib/stdlib/doc/src/proc_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2011</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -209,6 +209,13 @@ init(Parent) ->
<name name="format" arity="1"/>
<fsummary>Format a crash report.</fsummary>
<desc>
+ <p>Equivalent to <c>format(<anno>CrashReport</anno>, latin1)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="format" arity="2"/>
+ <fsummary>Format a crash report.</fsummary>
+ <desc>
<p>This function can be used by a user defined event handler to
format a crash report. The crash report is sent using
<c>error_logger:error_report(crash_report, <anno>CrashReport</anno>)</c>.
diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index d235f3e180..deba6adb11 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1996</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -52,19 +52,10 @@
</desc>
</datatype>
<datatype>
- <name name="unicode_char"/>
- <desc>
- <p>An <c>integer()</c> representing a valid Unicode codepoint.</p>
- </desc>
- </datatype>
- <datatype>
<name name="chardata"/>
</datatype>
<datatype>
<name name="charlist"/>
- <desc>
- <p>A <c>unicode_binary()</c> is allowed as the tail of the list.</p>
- </desc>
</datatype>
<datatype>
<name name="external_unicode_binary"/>
@@ -78,10 +69,6 @@
</datatype>
<datatype>
<name name="external_charlist"/>
- <desc>
- <p>An <c>external_unicode_binary()</c> is allowed as the tail
- of the list.</p>
- </desc>
</datatype>
<datatype>
<name name="latin1_binary"/>
@@ -96,11 +83,12 @@
</datatype>
<datatype>
<name name="latin1_chardata"/>
+ <desc><p>The same as <c>iodata()</c>.</p>
+ </desc>
</datatype>
<datatype>
<name name="latin1_charlist"/>
- <desc><p>A <c>latin1_binary()</c> is allowed as the tail of
- the list.</p>
+ <desc><p>The same as <c>iolist()</c>.</p>
</desc>
</datatype>
</datatypes>
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index 320b5b2e84..0a75fbeec0 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -163,10 +163,10 @@ Erlang R16B (erts-5.10) [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.10 (abort with ^G)
1> <input>lists:keyfind(encoding, 1, io:getopts()).</input>
{encoding,unicode}
-2> <input>"уницоде"</input>
-"уницоде"
+2> <input>"Юникод"</input>
+"Юникод"
3> <input>io:format("~ts~n", [v(2)]).</input>
-уницоде
+Юникод
ok
4> </pre>
<p>While strings can be input as Unicode characters, the language elements are still limited to the ISO-latin-1 character set. Only character constants and strings are allowed to be beyond that range:</p>
@@ -177,7 +177,7 @@ Erlang R16B (erts-5.10) [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.10 (abort with ^G)
1> <input>$ξ</input>
958
-2> <input>уницоде.</input>
+2> <input>Юникод.</input>
* 1: illegal character
2> </pre>
</section>
@@ -305,10 +305,10 @@ $ <input>erl</input>
Erlang R16B (erts-5.10) [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.10 (abort with ^G)
-1> <input>io_lib:format("~ts~n", ["θνιψοδε"]).</input>
-["θνιψοδε","\n"]
-2> <input>io:put_chars(io_lib:format("~ts~n", ["θνιψοδε"])).</input>
-θνιψοδε
+1> <input>io_lib:format("~ts~n", ["Γιούνικοντ"]).</input>
+["Γιούνικοντ","\n"]
+2> <input>io:put_chars(io_lib:format("~ts~n", ["Γιούνικοντ"])).</input>
+Γιούνικοντ
ok</pre>
<p>The Unicode string is returned as a Unicode list, which is recognized as such since the Erlang shell uses the Unicode encoding. The Unicode list is valid input to the <seealso marker="stdlib:io#put_chars/2">io:put_chars/2</seealso> function, so data can be output on any Unicode capable device. If the device is a terminal, characters will be output in the <c>\x{</c>H ...<c>}</c> format if encoding is <c>latin1</c> otherwise in UTF-8 (for the non-interactive terminal - "oldshell" or "noshell") or whatever is suitable to show the character properly (for an interactive terminal - the regular shell). The bottom line is that you can always send Unicode data to the <c>standard_io</c> device. Files will however only accept Unicode codepoints beyond ISO-latin-1 if <c>encoding</c> is set to something else than <c>latin1</c>.</p>
</section>
diff --git a/lib/stdlib/examples/erl_id_trans.erl b/lib/stdlib/examples/erl_id_trans.erl
index 34c6ecc394..51def8c8e1 100644
--- a/lib/stdlib/examples/erl_id_trans.erl
+++ b/lib/stdlib/examples/erl_id_trans.erl
@@ -153,7 +153,6 @@ pattern({record,Line,Name,Pfs0}) ->
pattern({record_index,Line,Name,Field0}) ->
Field1 = pattern(Field0),
{record_index,Line,Name,Field1};
-%% record_field occurs in query expressions
pattern({record_field,Line,Rec0,Name,Field0}) ->
Rec1 = expr(Rec0),
Field1 = expr(Field0),
@@ -431,10 +430,6 @@ expr({'catch',Line,E0}) ->
%% No new variables added.
E1 = expr(E0),
{'catch',Line,E1};
-expr({'query', Line, E0}) ->
- %% lc expression
- E = expr(E0),
- {'query', Line, E};
expr({match,Line,P0,E0}) ->
E1 = expr(E0),
P1 = pattern(P0),
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 575a5cbe4a..30bff3bf96 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -149,7 +149,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
endif
-ERL_COMPILE_FLAGS += -I../include -I../../kernel/include
+ERL_COMPILE_FLAGS += -I../include -I../../kernel/include -Werror
# ----------------------------------------------------
# Targets
@@ -175,24 +175,25 @@ primary_bootstrap_compiler: \
$(BOOTSTRAP_COMPILER)/ebin/otp_internal.beam
$(BOOTSTRAP_COMPILER)/ebin/erl_parse.beam: erl_parse.yrl
- $(ERLC) -o $(BOOTSTRAP_COMPILER)/egen erl_parse.yrl
- $(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(BOOTSTRAP_COMPILER)/egen/erl_parse.erl
+ $(gen_verbose)
+ $(V_at)$(ERLC) -o $(BOOTSTRAP_COMPILER)/egen erl_parse.yrl
+ $(V_at)$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(BOOTSTRAP_COMPILER)/egen/erl_parse.erl
$(BOOTSTRAP_TOP)/lib/stdlib/egen/erl_parse.erl: erl_parse.yrl
- $(ERLC) $(YRL_FLAGS) -o$(BOOTSTRAP_TOP)/lib/stdlib/egen erl_parse.yrl
+ $(yecc_verbose)$(ERLC) $(YRL_FLAGS) -o$(BOOTSTRAP_TOP)/lib/stdlib/egen erl_parse.yrl
$(BOOTSTRAP_COMPILER)/ebin/%.beam: %.erl
- $(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $<
+ $(V_ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $<
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl
index 5d800e87b8..7bf281bd8a 100644
--- a/lib/stdlib/src/base64.erl
+++ b/lib/stdlib/src/base64.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2007-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
@@ -29,6 +29,7 @@
%%-------------------------------------------------------------------------
-type ascii_string() :: [1..255].
+-type ascii_binary() :: binary().
%%-------------------------------------------------------------------------
%% encode_to_string(ASCII) -> Base64String
@@ -39,7 +40,7 @@
%%-------------------------------------------------------------------------
-spec encode_to_string(Data) -> Base64String when
- Data :: string() | binary(),
+ Data :: ascii_string() | ascii_binary(),
Base64String :: ascii_string().
encode_to_string(Bin) when is_binary(Bin) ->
@@ -56,15 +57,15 @@ encode_to_string(List) when is_list(List) ->
%%-------------------------------------------------------------------------
-spec encode(Data) -> Base64 when
- Data :: string() | binary(),
- Base64 :: binary().
+ Data :: ascii_string() | ascii_binary(),
+ Base64 :: ascii_binary().
encode(Bin) when is_binary(Bin) ->
encode_binary(Bin);
encode(List) when is_list(List) ->
list_to_binary(encode_l(List)).
--spec encode_l(string()) -> ascii_string().
+-spec encode_l(ascii_string()) -> ascii_string().
encode_l([]) ->
[];
@@ -107,8 +108,8 @@ encode_binary(Bin) ->
%%-------------------------------------------------------------------------
-spec decode(Base64) -> Data when
- Base64 :: string() | binary(),
- Data :: binary().
+ Base64 :: ascii_string() | ascii_binary(),
+ Data :: ascii_binary().
decode(Bin) when is_binary(Bin) ->
decode_binary(<<>>, Bin);
@@ -116,21 +117,21 @@ decode(List) when is_list(List) ->
list_to_binary(decode_l(List)).
-spec mime_decode(Base64) -> Data when
- Base64 :: string() | binary(),
- Data :: binary().
+ Base64 :: ascii_string() | ascii_binary(),
+ Data :: ascii_binary().
mime_decode(Bin) when is_binary(Bin) ->
mime_decode_binary(<<>>, Bin);
mime_decode(List) when is_list(List) ->
mime_decode(list_to_binary(List)).
--spec decode_l(string()) -> string().
+-spec decode_l(ascii_string()) -> ascii_string().
decode_l(List) ->
L = strip_spaces(List, []),
decode(L, []).
--spec mime_decode_l(string()) -> string().
+-spec mime_decode_l(ascii_string()) -> ascii_string().
mime_decode_l(List) ->
L = strip_illegal(List, [], 0),
@@ -148,8 +149,8 @@ mime_decode_l(List) ->
%%-------------------------------------------------------------------------
-spec decode_to_string(Base64) -> DataString when
- Base64 :: string() | binary(),
- DataString :: string().
+ Base64 :: ascii_string() | ascii_binary(),
+ DataString :: ascii_string().
decode_to_string(Bin) when is_binary(Bin) ->
decode_to_string(binary_to_list(Bin));
@@ -157,8 +158,8 @@ decode_to_string(List) when is_list(List) ->
decode_l(List).
-spec mime_decode_to_string(Base64) -> DataString when
- Base64 :: string() | binary(),
- DataString :: string().
+ Base64 :: ascii_string() | ascii_binary(),
+ DataString :: ascii_string().
mime_decode_to_string(Bin) when is_binary(Bin) ->
mime_decode_to_string(binary_to_list(Bin));
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index e9a5e6831e..742fda0815 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -240,21 +240,21 @@ format_error({error, Error}) ->
format_error({error, Module, Error}) ->
Module:format_error(Error);
format_error({unknown_chunk, File, ChunkName}) ->
- io_lib:format("~p: Cannot find chunk ~p~n", [File, ChunkName]);
+ io_lib:format("~tp: Cannot find chunk ~p~n", [File, ChunkName]);
format_error({invalid_chunk, File, ChunkId}) ->
- io_lib:format("~p: Invalid contents of chunk ~p~n", [File, ChunkId]);
+ io_lib:format("~tp: Invalid contents of chunk ~p~n", [File, ChunkId]);
format_error({not_a_beam_file, File}) ->
- io_lib:format("~p: Not a BEAM file~n", [File]);
+ io_lib:format("~tp: Not a BEAM file~n", [File]);
format_error({file_error, File, Reason}) ->
- io_lib:format("~p: ~p~n", [File, file:format_error(Reason)]);
+ io_lib:format("~tp: ~tp~n", [File, file:format_error(Reason)]);
format_error({missing_chunk, File, ChunkId}) ->
- io_lib:format("~p: Not a BEAM file: no IFF \"~s\" chunk~n",
+ io_lib:format("~tp: Not a BEAM file: no IFF \"~s\" chunk~n",
[File, ChunkId]);
format_error({invalid_beam_file, File, Pos}) ->
- io_lib:format("~p: Invalid format of BEAM file near byte number ~p~n",
+ io_lib:format("~tp: Invalid format of BEAM file near byte number ~p~n",
[File, Pos]);
format_error({chunk_too_big, File, ChunkId, Size, Len}) ->
- io_lib:format("~p: Size of chunk \"~s\" is ~p bytes, "
+ io_lib:format("~tp: Size of chunk \"~s\" is ~p bytes, "
"but only ~p bytes could be read~n",
[File, ChunkId, Size, Len]);
format_error({chunks_different, Id}) ->
@@ -265,16 +265,16 @@ format_error({modules_different, Module1, Module2}) ->
io_lib:format("Module names ~p and ~p differ in the two files~n",
[Module1, Module2]);
format_error({not_a_directory, Name}) ->
- io_lib:format("~p: Not a directory~n", [Name]);
+ io_lib:format("~tp: Not a directory~n", [Name]);
format_error({key_missing_or_invalid, File, abstract_code}) ->
- io_lib:format("~p: Cannot decrypt abstract code because key is missing or invalid",
+ io_lib:format("~tp: Cannot decrypt abstract code because key is missing or invalid",
[File]);
format_error(badfun) ->
"not a fun or the fun has the wrong arity";
format_error(exists) ->
"a fun has already been installed";
format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
%%
%% Exported functions for encrypted debug info.
@@ -324,13 +324,13 @@ diff_directories(Dir1, Dir2) ->
{OnlyDir1, OnlyDir2, Diff} = compare_dirs(Dir1, Dir2),
diff_only(Dir1, OnlyDir1),
diff_only(Dir2, OnlyDir2),
- foreach(fun(D) -> io:format("** different: ~p~n", [D]) end, Diff),
+ foreach(fun(D) -> io:format("** different: ~tp~n", [D]) end, Diff),
ok.
diff_only(_Dir, []) ->
ok;
diff_only(Dir, Only) ->
- io:format("Only in ~p: ~p~n", [Dir, Only]).
+ io:format("Only in ~tp: ~tp~n", [Dir, Only]).
%% -> {OnlyInDir1, OnlyInDir2, Different} | throw(Error)
compare_dirs(Dir1, Dir2) ->
@@ -1030,11 +1030,11 @@ f_p_s(P, F) ->
{error, enoent} ->
{error, enoent};
{error, {Line, _Mod, _Term}=E} ->
- error("file:path_script(~p,~p): error on line ~p: ~s~n",
+ error("file:path_script(~tp,~tp): error on line ~p: ~ts~n",
[P, F, Line, file:format_error(E)]),
ok;
{error, E} when is_atom(E) ->
- error("file:path_script(~p,~p): ~s~n",
+ error("file:path_script(~tp,~tp): ~ts~n",
[P, F, file:format_error(E)]),
ok;
Other ->
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index 4c1c0f904b..7ef2334106 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -122,7 +122,7 @@ machine_load(Mod, File, Opts) ->
code:purge(Mod),
check_load(code:load_abs(File2,Mod), Mod);
_OtherMod ->
- format("** Module name '~p' does not match file name '~p' **~n",
+ format("** Module name '~p' does not match file name '~tp' **~n",
[Mod,File]),
{error, badfile}
end;
@@ -203,11 +203,11 @@ make_term(Str) ->
case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
{ok, Term} -> Term;
{error, {_,_,Reason}} ->
- io:format("~s: ~s~n", [Reason, Str]),
+ io:format("~ts: ~ts~n", [Reason, Str]),
throw(error)
end;
{error, {_,_,Reason}, _} ->
- io:format("~s: ~s~n", [Reason, Str]),
+ io:format("~ts: ~ts~n", [Reason, Str]),
throw(error)
end.
@@ -475,11 +475,11 @@ f_p_e(P, F) ->
{error, enoent} = Enoent ->
Enoent;
{error, E={Line, _Mod, _Term}} ->
- error("file:path_eval(~p,~p): error on line ~p: ~s~n",
+ error("file:path_eval(~tp,~tp): error on line ~p: ~ts~n",
[P, F, Line, file:format_error(E)]),
ok;
{error, E} ->
- error("file:path_eval(~p,~p): ~s~n",
+ error("file:path_eval(~tp,~tp): ~ts~n",
[P, F, file:format_error(E)]),
ok;
Other ->
@@ -588,7 +588,12 @@ month(12) -> "December".
flush() ->
receive
X ->
- format("Shell got ~p~n",[X]),
+ case lists:keyfind(encoding, 1, io:getopts()) of
+ {encoding,unicode} ->
+ format("Shell got ~tp~n",[X]);
+ _ ->
+ format("Shell got ~p~n",[X])
+ end,
flush()
after 0 ->
ok
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 845fae4bf4..285a7bf587 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -2504,7 +2504,7 @@ fopen2(Fname, Tab) ->
end,
case Do of
{repair, Mess} ->
- io:format(user, "dets: file ~p~s~n", [Fname, Mess]),
+ io:format(user, "dets: file ~tp~s~n", [Fname, Mess]),
Version = default,
case fsck(Fd, Tab, Fname, FH, default, default, Version) of
ok ->
@@ -2599,7 +2599,7 @@ fopen_existing_file(Tab, OpenArgs) ->
_ when FH#fileheader.keypos =/= Kp ->
throw({error, {keypos_mismatch, Fname}});
{compact, SourceHead} ->
- io:format(user, "dets: file ~p is now compacted ...~n", [Fname]),
+ io:format(user, "dets: file ~tp is now compacted ...~n", [Fname]),
{ok, NewSourceHead} = open_final(SourceHead, Fname, read, false,
?DEFAULT_CACHE, Tab, Debug),
case catch compact(NewSourceHead) of
@@ -2609,14 +2609,14 @@ fopen_existing_file(Tab, OpenArgs) ->
_Err ->
_ = file:close(Fd),
dets_utils:stop_disk_map(),
- io:format(user, "dets: compaction of file ~p failed, "
+ io:format(user, "dets: compaction of file ~tp failed, "
"now repairing ...~n", [Fname]),
{ok, Fd2, _FH} = read_file_header(Fname, Acc, Ram),
do_repair(Fd2, Tab, Fname, FH, MinSlots, MaxSlots,
Version, OpenArgs)
end;
{repair, Mess} ->
- io:format(user, "dets: file ~p~s~n", [Fname, Mess]),
+ io:format(user, "dets: file ~tp~s~n", [Fname, Mess]),
do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots,
Version, OpenArgs);
_ when FH#fileheader.version =/= Version, Version =/= default ->
diff --git a/lib/stdlib/src/dets_utils.erl b/lib/stdlib/src/dets_utils.erl
index 5db2ad3049..aab7f934c3 100644
--- a/lib/stdlib/src/dets_utils.erl
+++ b/lib/stdlib/src/dets_utils.erl
@@ -395,7 +395,7 @@ corrupt_reason(Head, Reason0) ->
corrupt(Head, Error) ->
case get(verbose) of
yes ->
- error_logger:format("** dets: Corrupt table ~p: ~p\n",
+ error_logger:format("** dets: Corrupt table ~p: ~tp\n",
[Head#head.name, Error]);
_ -> ok
end,
diff --git a/lib/stdlib/src/dets_v8.erl b/lib/stdlib/src/dets_v8.erl
index 3e962a1c8b..44829211f7 100644
--- a/lib/stdlib/src/dets_v8.erl
+++ b/lib/stdlib/src/dets_v8.erl
@@ -1492,7 +1492,7 @@ scan_next_allocated(Bin, From0, _To, <<From:32, To:32, L/binary>>, Ts, R) ->
%% Read term from file at position Pos
prterm(Head, Pos, ReadAhead) ->
Res = dets_utils:pread(Head, Pos, ?OHDSZ, ReadAhead),
- ?DEBUGF("file:pread(~p, ~p, ?) -> ~p~n", [Head#head.filename, Pos, Res]),
+ ?DEBUGF("file:pread(~tp, ~p, ?) -> ~p~n", [Head#head.filename, Pos, Res]),
{ok, <<Next:32, Sz:32, _Status:32, Bin0/binary>>} = Res,
?DEBUGF("{Next, Sz} = ~p~n", [{Next, Sz}]),
Bin = case byte_size(Bin0) of
diff --git a/lib/stdlib/src/dets_v9.erl b/lib/stdlib/src/dets_v9.erl
index f577b4410f..6d44c3924e 100644
--- a/lib/stdlib/src/dets_v9.erl
+++ b/lib/stdlib/src/dets_v9.erl
@@ -2662,7 +2662,7 @@ v_segment(H, SegNo, SegPos, SegSlot) ->
{'EXIT', Reason} ->
dets_utils:vformat("** dets: Corrupt or truncated dets file~n",
[]),
- io:format("~nERROR ~p~n", [Reason]);
+ io:format("~nERROR ~tp~n", [Reason]);
[] -> %% don't print empty buckets
true;
{Size, CollP, Objects} ->
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index 1164ee49eb..3192879f09 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -22,10 +22,10 @@
%% A simple Emacs-like line editor.
%% About Latin-1 characters: see the beginning of erl_scan.erl.
--export([init/0,start/1,edit_line/2,prefix_arg/1]).
+-export([init/0,start/1,start/2,edit_line/2,prefix_arg/1]).
-export([erase_line/1,erase_inp/1,redraw_line/1]).
-export([length_before/1,length_after/1,prompt/1]).
--export([current_line/1]).
+-export([current_line/1, current_chars/1]).
%%-export([expand/1]).
-export([edit_line1/2]).
@@ -54,7 +54,12 @@ init() ->
%% {undefined,Char,Rest,Cont,Requests}
start(Pbs) ->
- {more_chars,{line,Pbs,{[],[]},none},[{put_chars,unicode,Pbs}]}.
+ start(Pbs, none).
+
+%% Only two modes used: 'none' and 'search'. Other modes can be
+%% handled inline through specific character handling.
+start(Pbs, Mode) ->
+ {more_chars,{line,Pbs,{[],[]},Mode},[{put_chars,unicode,Pbs}]}.
edit_line(Cs, {line,P,L,{blink,N}}) ->
edit(Cs, P, L, none, [{move_rel,N}]);
@@ -76,6 +81,10 @@ edit([C|Cs], P, {Bef,Aft}, Prefix, Rs0) ->
edit(Cs, P, {Bef,Aft}, meta, Rs0);
meta_left_sq_bracket ->
edit(Cs, P, {Bef,Aft}, meta_left_sq_bracket, Rs0);
+ search_meta ->
+ edit(Cs, P, {Bef,Aft}, search_meta, Rs0);
+ search_meta_left_sq_bracket ->
+ edit(Cs, P, {Bef,Aft}, search_meta_left_sq_bracket, Rs0);
ctlx ->
edit(Cs, P, {Bef,Aft}, ctlx, Rs0);
new_line ->
@@ -115,6 +124,8 @@ edit([C|Cs], P, {Bef,Aft}, Prefix, Rs0) ->
case do_op(Op, Bef, Aft, Rs0) of
{blink,N,Line,Rs} ->
edit(Cs, P, Line, {blink,N}, Rs);
+ {Line, Rs, Mode} -> % allow custom modes from do_op
+ edit(Cs, P, Line, Mode, Rs);
{Line,Rs} ->
edit(Cs, P, Line, none, Rs)
end
@@ -168,9 +179,15 @@ key_map($\^], none) -> auto_blink;
key_map($\^X, none) -> ctlx;
key_map($\^Y, none) -> yank;
key_map($\e, none) -> meta;
-key_map($), Prefix) when Prefix =/= meta -> {blink,$),$(};
-key_map($}, Prefix) when Prefix =/= meta -> {blink,$},${};
-key_map($], Prefix) when Prefix =/= meta -> {blink,$],$[};
+key_map($), Prefix) when Prefix =/= meta,
+ Prefix =/= search,
+ Prefix =/= search_meta -> {blink,$),$(};
+key_map($}, Prefix) when Prefix =/= meta,
+ Prefix =/= search,
+ Prefix =/= search_meta -> {blink,$},${};
+key_map($], Prefix) when Prefix =/= meta,
+ Prefix =/= search,
+ Prefix =/= search_meta -> {blink,$],$[};
key_map($B, meta) -> backward_word;
key_map($D, meta) -> kill_word;
key_map($F, meta) -> forward_word;
@@ -188,6 +205,32 @@ key_map($D, meta_left_sq_bracket) -> backward_char;
key_map($C, meta_left_sq_bracket) -> forward_char;
key_map(C, none) when C >= $\s ->
{insert,C};
+%% for search, we need smarter line handling and so
+%% we cheat a bit on the dispatching, and allow to
+%% return a mode.
+key_map($\^H, search) -> {search, backward_delete_char};
+key_map($\177, search) -> {search, backward_delete_char};
+key_map($\^R, search) -> {search, skip_up};
+key_map($\^S, search) -> {search, skip_down};
+key_map($\n, search) -> {search, search_found};
+key_map($\r, search) -> {search, search_found};
+key_map($\^A, search) -> {search, search_quit};
+key_map($\^B, search) -> {search, search_quit};
+key_map($\^D, search) -> {search, search_quit};
+key_map($\^E, search) -> {search, search_quit};
+key_map($\^F, search) -> {search, search_quit};
+key_map($\t, search) -> {search, search_quit};
+key_map($\^L, search) -> {search, search_quit};
+key_map($\^T, search) -> {search, search_quit};
+key_map($\^U, search) -> {search, search_quit};
+key_map($\^], search) -> {search, search_quit};
+key_map($\^X, search) -> {search, search_quit};
+key_map($\^Y, search) -> {search, search_quit};
+key_map($\e, search) -> search_meta;
+key_map($[, search_meta) -> search_meta_left_sq_bracket;
+key_map(_, search_meta) -> {search, search_quit};
+key_map(_C, search_meta_left_sq_bracket) -> {search, search_quit};
+key_map(C, search) -> {insert_search,C};
key_map(C, _) -> {undefined,C}.
%% do_op(Action, Before, After, Requests)
@@ -196,6 +239,57 @@ do_op({insert,C}, Bef, [], Rs) ->
{{[C|Bef],[]},[{put_chars, unicode,[C]}|Rs]};
do_op({insert,C}, Bef, Aft, Rs) ->
{{[C|Bef],Aft},[{insert_chars, unicode, [C]}|Rs]};
+%% Search mode prompt always looks like (search)`$TERMS': $RESULT.
+%% the {insert_search, _} handlings allow to share this implementation
+%% correctly with group.erl. This module provides $TERMS, and group.erl
+%% is in charge of providing $RESULT.
+%% This require a bit of trickery. Because search disables moving around
+%% on the line (left/right arrow keys and other shortcuts that just exit
+%% search mode), we can use the Bef and Aft variables to hold each
+%% part of the line. Bef takes charge of "(search)`$TERMS" and Aft
+%% takes charge of "': $RESULT".
+do_op({insert_search, C}, Bef, [], Rs) ->
+ Aft="': ",
+ {{[C|Bef],Aft},
+ [{insert_chars, unicode, [C]++Aft}, {delete_chars,-3} | Rs],
+ search};
+do_op({insert_search, C}, Bef, Aft, Rs) ->
+ Offset= length(Aft),
+ NAft = "': ",
+ {{[C|Bef],NAft},
+ [{insert_chars, unicode, [C]++NAft}, {delete_chars,-Offset} | Rs],
+ search};
+do_op({search, backward_delete_char}, [_|Bef], Aft, Rs) ->
+ Offset= length(Aft)+1,
+ NAft = "': ",
+ {{Bef,NAft},
+ [{insert_chars, unicode, NAft}, {delete_chars,-Offset}|Rs],
+ search};
+do_op({search, backward_delete_char}, [], _Aft, Rs) ->
+ Aft="': ",
+ {{[],Aft}, Rs, search};
+do_op({search, skip_up}, Bef, Aft, Rs) ->
+ Offset= length(Aft),
+ NAft = "': ",
+ {{[$\^R|Bef],NAft}, % we insert ^R as a flag to whoever called us
+ [{insert_chars, unicode, NAft}, {delete_chars,-Offset}|Rs],
+ search};
+do_op({search, skip_down}, Bef, Aft, Rs) ->
+ Offset= length(Aft),
+ NAft = "': ",
+ {{[$\^S|Bef],NAft}, % we insert ^S as a flag to whoever called us
+ [{insert_chars, unicode, NAft}, {delete_chars,-Offset}|Rs],
+ search};
+do_op({search, search_found}, _Bef, Aft, Rs) ->
+ "': "++NAft = Aft,
+ {{[],NAft},
+ [{put_chars, unicode, "\n"}, {move_rel,-length(Aft)} | Rs],
+ search_found};
+do_op({search, search_quit}, _Bef, Aft, Rs) ->
+ "': "++NAft = Aft,
+ {{[],NAft},
+ [{put_chars, unicode, "\n"}, {move_rel,-length(Aft)} | Rs],
+ search_quit};
%% do blink after $$
do_op({blink,C,M}, Bef=[$$,$$|_], Aft, Rs) ->
N = over_paren(Bef, C, M),
@@ -453,6 +547,9 @@ prompt({line,Pbs,_,_}) ->
current_line({line,_,{Bef, Aft},_}) ->
reverse(Bef, Aft ++ "\n").
+current_chars({line,_,{Bef,Aft},_}) ->
+ reverse(Bef, Aft).
+
%% %% expand(CurrentBefore) ->
%% %% {yes,Expansion} | no
%% %% Try to expand the word before as either a module name or a function
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index a0f7660ecf..afa39c3fb9 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -24,7 +24,8 @@
-export([scan_erl_form/1,parse_erl_form/1,macro_defs/1]).
-export([parse_file/1, parse_file/3]).
-export([default_encoding/0, encoding_to_string/1,
- read_encoding/1, read_encoding/2, set_encoding/1]).
+ read_encoding_from_binary/1, read_encoding_from_binary/2,
+ set_encoding/1, read_encoding/1, read_encoding/2]).
-export([interpret_file_attribute/1]).
-export([normalize_typed_record_fields/1,restore_typed_record_fields/1]).
@@ -265,13 +266,41 @@ set_encoding(File) ->
ok = io:setopts(File, [{encoding, Enc}]),
Encoding.
--spec read_encoding_from_file(File, InComment) -> source_encoding() | none when
- File :: io:device(),
- InComment :: boolean().
+-spec read_encoding_from_binary(Binary) -> source_encoding() | none when
+ Binary :: binary().
-define(ENC_CHUNK, 32).
-define(N_ENC_CHUNK, 16). % a total of 512 bytes
+read_encoding_from_binary(Binary) ->
+ read_encoding_from_binary(Binary, []).
+
+-spec read_encoding_from_binary(Binary, Options) ->
+ source_encoding() | none when
+ Binary :: binary(),
+ Options :: [Option],
+ Option :: {in_comment_only, boolean()}.
+
+read_encoding_from_binary(Binary, Options) ->
+ InComment = proplists:get_value(in_comment_only, Options, true),
+ try
+ com_nl(Binary, fake_reader(0), 0, InComment)
+ catch
+ throw:no ->
+ none
+ end.
+
+fake_reader(N) ->
+ fun() when N =:= ?N_ENC_CHUNK ->
+ throw(no);
+ () ->
+ {<<>>, fake_reader(N+1)}
+ end.
+
+-spec read_encoding_from_file(File, InComment) -> source_encoding() | none when
+ File :: io:device(),
+ InComment :: boolean().
+
read_encoding_from_file(File, InComment) ->
{ok, Pos0} = file:position(File, cur),
Opts = io:getopts(File),
@@ -1224,8 +1253,6 @@ macro_arg([{'try',Lr}|Toks], E, Arg) ->
macro_arg(Toks, ['end'|E], [{'try',Lr}|Arg]);
macro_arg([{'cond',Lr}|Toks], E, Arg) ->
macro_arg(Toks, ['end'|E], [{'cond',Lr}|Arg]);
-macro_arg([{'query',Lr}|Toks], E, Arg) ->
- macro_arg(Toks, ['end'|E], [{'query',Lr}|Arg]);
macro_arg([{Rb,Lrb}|Toks], [Rb|E], Arg) -> %Found matching close
macro_arg(Toks, E, [{Rb,Lrb}|Arg]);
macro_arg([T|Toks], E, Arg) ->
@@ -1278,9 +1305,9 @@ token_src({X, _}) when is_atom(X) ->
token_src({var, _, X}) ->
atom_to_list(X);
token_src({char,_,C}) ->
- io_lib:write_unicode_char(C);
+ io_lib:write_char(C);
token_src({string, _, X}) ->
- io_lib:write_unicode_string(X);
+ io_lib:write_string(X);
token_src({_, _, X}) ->
io_lib:format("~w", [X]).
diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl
index 81bec21a3f..ec106ecc9d 100644
--- a/lib/stdlib/src/erl_compile.erl
+++ b/lib/stdlib/src/erl_compile.erl
@@ -68,7 +68,7 @@ compile(List) ->
{'EXIT', Pid, {compiler_result, Result}} ->
Result;
{'EXIT', Pid, Reason} ->
- io:format("Runtime error: ~p~n", [Reason]),
+ io:format("Runtime error: ~tp~n", [Reason]),
error
end.
@@ -170,12 +170,12 @@ compile3([], _Cwd, _Options) -> ok.
%% Invokes the appropriate compiler, depending on the file extension.
compile_file("", Input, _Output, _Options) ->
- io:format("File has no extension: ~s~n", [Input]),
+ io:format("File has no extension: ~ts~n", [Input]),
error;
compile_file(Ext, Input, Output, Options) ->
case compiler(Ext) of
no ->
- io:format("Unknown extension: '~s'\n", [Ext]),
+ io:format("Unknown extension: '~ts'\n", [Ext]),
error;
{M, F} ->
case catch M:F(Input, Output, Options) of
@@ -215,10 +215,10 @@ make_term(Str) ->
case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
{ok, Term} -> Term;
{error, {_,_,Reason}} ->
- io:format("~s: ~s~n", [Reason, Str]),
+ io:format("~ts: ~ts~n", [Reason, Str]),
throw(error)
end;
{error, {_,_,Reason}, _} ->
- io:format("~s: ~s~n", [Reason, Str]),
+ io:format("~ts: ~ts~n", [Reason, Str]),
throw(error)
end.
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index 3063881890..bf2fffbd97 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -278,6 +278,7 @@ bif(exit, 1) -> true;
bif(exit, 2) -> true;
bif(float, 1) -> true;
bif(float_to_list, 1) -> true;
+bif(float_to_list, 2) -> true;
bif(garbage_collect, 0) -> true;
bif(garbage_collect, 1) -> true;
bif(get, 0) -> true;
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index d24e2fff44..dd5480838f 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -94,7 +94,6 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
%% the other function collections contain {Function, Arity}.
-record(lint, {state=start :: 'start' | 'attribute' | 'function',
module=[], %Module
- extends=[], %Extends
behaviour=[], %Behaviour
exports=gb_sets:empty() :: gb_set(), %Exports
imports=[], %Imports
@@ -112,7 +111,6 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
enabled_warnings=[], %All enabled warnings (ordset).
errors=[], %Current errors
warnings=[], %Current warnings
- global_vt=[], %The global VarTable
file = "" :: string(), %From last file attribute
recdef_top=false :: boolean(), %true in record initialisation
%outside any fun or lc
@@ -142,10 +140,8 @@ format_error({bad_module_name, M}) ->
io_lib:format("bad module name '~s'", [M]);
format_error(redefine_module) ->
"redefining module";
-format_error(redefine_extends) ->
- "redefining extends attribute";
-format_error(extends_self) ->
- "cannot extend from self";
+format_error(pmod_unsupported) ->
+ "parameterized modules are no longer supported";
%% format_error({redefine_mod_import, M, P}) ->
%% io_lib:format("module '~s' already imported from package '~s'", [M, P]);
@@ -166,10 +162,6 @@ format_error({bad_inline,{F,A}}) ->
io_lib:format("inlined function ~w/~w undefined", [F,A]);
format_error({invalid_deprecated,D}) ->
io_lib:format("badly formed deprecated attribute ~w", [D]);
-format_error(invalid_extends) ->
- "badly formed extends attribute";
-format_error(define_instance) ->
- "defining instance function not allowed in abstract module";
format_error({bad_deprecated,{F,A}}) ->
io_lib:format("deprecated function ~w/~w undefined or not exported", [F,A]);
format_error({bad_nowarn_unused_function,{F,A}}) ->
@@ -622,8 +614,6 @@ forms(Forms0, St0) ->
pre_scan([{function,_L,new,_A,_Cs} | Fs], St) ->
pre_scan(Fs, St#lint{new=true});
-pre_scan([{attribute,_L,extends,M} | Fs], St) when is_atom(M) ->
- pre_scan(Fs, St#lint{extends=true});
pre_scan([{attribute,L,compile,C} | Fs], St) ->
case is_warn_enabled(export_all, St) andalso
member(export_all, lists:flatten([C])) of
@@ -678,41 +668,15 @@ form(Form, #lint{state=State}=St) ->
%% start_state(Form, State) -> State'
-start_state({attribute,_,module,{M,Ps}}, St0) ->
- St1 = St0#lint{module=M},
- Arity = length(Ps),
- Ps1 = if is_atom(St1#lint.extends) ->
- ['BASE', 'THIS' | Ps];
- true ->
- ['THIS' | Ps]
- end,
- Vt = orddict:from_list([{V, {bound, used, []}} || V <- Ps1]),
- St2 = add_instance(Arity, St1),
- St3 = ensure_new(Arity, St2),
- St3#lint{state=attribute, extends=[], global_vt=Vt};
+start_state({attribute,Line,module,{_,_}}=Form, St0) ->
+ St1 = add_error(Line, pmod_unsupported, St0),
+ attribute_state(Form, St1#lint{state=attribute});
start_state({attribute,_,module,M}, St0) ->
St1 = St0#lint{module=M},
- St1#lint{state=attribute, extends=[]};
+ St1#lint{state=attribute};
start_state(Form, St) ->
St1 = add_error(element(2, Form), undefined_module, St),
- attribute_state(Form, St1#lint{state=attribute, extends=[]}).
-
-ensure_new(Arity, St) ->
- case St#lint.new of
- true ->
- St;
- false ->
- add_func(new, Arity, St)
- end.
-
-add_instance(Arity, St) ->
- A = Arity + (if is_atom(St#lint.extends) -> 1; true -> 0 end),
- add_func(instance, A, St).
-
-add_func(Name, Arity, St) ->
- F = {Name, Arity},
- St#lint{exports = gb_sets:add_element(F, St#lint.exports),
- defined = gb_sets:add_element(F, St#lint.defined)}.
+ attribute_state(Form, St1#lint{state=attribute}).
%% attribute_state(Form, State) ->
%% State'
@@ -721,15 +685,6 @@ attribute_state({attribute,_L,module,_M}, #lint{module=[]}=St) ->
St;
attribute_state({attribute,L,module,_M}, St) ->
add_error(L, redefine_module, St);
-attribute_state({attribute,L,extends,M}, #lint{module=M}=St) when is_atom(M) ->
- add_error(L, extends_self, St);
-attribute_state({attribute,_L,extends,M}, #lint{extends=[]}=St)
- when is_atom(M) ->
- St#lint{extends=M};
-attribute_state({attribute,L,extends,M}, St) when is_atom(M) ->
- add_error(L, redefine_extends, St);
-attribute_state({attribute,L,extends,_M}, St) ->
- add_error(L, invalid_extends, St);
attribute_state({attribute,L,export,Es}, St) ->
export(L, Es, St);
attribute_state({attribute,L,export_type,Es}, St) ->
@@ -1322,11 +1277,9 @@ call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func}=St) ->
%% function(Line, Name, Arity, Clauses, State) -> State.
-function(Line, instance, _Arity, _Cs, St) when St#lint.global_vt =/= [] ->
- add_error(Line, define_instance, St);
function(Line, Name, Arity, Cs, St0) ->
St1 = define_function(Line, Name, Arity, St0#lint{func={Name,Arity}}),
- clauses(Cs, St1#lint.global_vt, St1).
+ clauses(Cs, St1).
-spec define_function(line(), atom(), arity(), lint_state()) -> lint_state().
@@ -1349,15 +1302,16 @@ function_check_max_args(Line, Arity, St) when Arity > ?MAX_ARGUMENTS ->
add_error(Line, {too_many_arguments,Arity}, St);
function_check_max_args(_, _, St) -> St.
-%% clauses([Clause], VarTable, State) -> {VarTable, State}.
+%% clauses([Clause], State) -> {VarTable, State}.
-clauses(Cs, Vt, St) ->
+clauses(Cs, St) ->
foldl(fun (C, St0) ->
- {_,St1} = clause(C, Vt, St0),
+ {_,St1} = clause(C, St0),
St1
end, St, Cs).
-clause({clause,_Line,H,G,B}, Vt0, St0) ->
+clause({clause,_Line,H,G,B}, St0) ->
+ Vt0 = [],
{Hvt,Binvt,St1} = head(H, Vt0, St0),
%% Cannot ignore BinVt since "binsize variables" may have been used.
Vt1 = vtupdate(Hvt, vtupdate(Binvt, Vt0)),
@@ -2205,9 +2159,7 @@ expr({op,_Line,_Op,L,R}, Vt, St) ->
expr_list([L,R], Vt, St); %They see the same variables
%% The following are not allowed to occur anywhere!
expr({remote,Line,_M,_F}, _Vt, St) ->
- {[],add_error(Line, illegal_expr, St)};
-expr({'query',Line,_Q}, _Vt, St) ->
- {[],add_error(Line, {mnemosyne,"query"}, St)}.
+ {[],add_error(Line, illegal_expr, St)}.
%% expr_list(Expressions, Variables, State) ->
%% {UsedVarTable,State}
@@ -3484,7 +3436,7 @@ check_format_3(Fmt, As) ->
_Len -> {warn,1,"wrong number of arguments in format call",[]}
end;
{error,S} ->
- {warn,1,"format string invalid (~s)",[S]}
+ {warn,1,"format string invalid (~ts)",[S]}
end.
args_list({cons,_L,_H,T}) -> args_list(T);
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 002abc11e8..9ff25fcbc5 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -36,7 +36,7 @@ tuple
record_expr record_tuple record_field record_fields
if_expr if_clause if_clauses case_expr cr_clause cr_clauses receive_expr
fun_expr fun_clause fun_clauses atom_or_var integer_or_var
-try_expr try_catch try_clause try_clauses query_expr
+try_expr try_catch try_clause try_clauses
function_call argument_list
exprs guard
atomic strings
@@ -54,7 +54,7 @@ char integer float atom string var
'(' ')' ',' '->' ':-' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
'after' 'begin' 'case' 'try' 'catch' 'end' 'fun' 'if' 'of' 'receive' 'when'
-'andalso' 'orelse' 'query'
+'andalso' 'orelse'
'bnot' 'not'
'*' '/' 'div' 'rem' 'band' 'and'
'+' '-' 'bor' 'bxor' 'bsl' 'bsr' 'or' 'xor'
@@ -272,7 +272,6 @@ expr_max -> case_expr : '$1'.
expr_max -> receive_expr : '$1'.
expr_max -> fun_expr : '$1'.
expr_max -> try_expr : '$1'.
-expr_max -> query_expr : '$1'.
list -> '[' ']' : {nil,?line('$1')}.
@@ -432,9 +431,6 @@ try_clause -> var ':' expr clause_guard clause_body :
L = ?line('$1'),
{clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}.
-query_expr -> 'query' list_comprehension 'end' :
- {'query',?line('$1'),'$2'}.
-
argument_list -> '(' ')' : {[],?line('$1')}.
argument_list -> '(' exprs ')' : {'$2',?line('$1')}.
@@ -520,7 +516,7 @@ Erlang code.
-type abstract_form() :: term().
-type error_description() :: term().
-type error_info() :: {erl_scan:line(), module(), error_description()}.
--type token() :: {Tag :: atom(), Line :: erl_scan:line()}.
+-type token() :: erl_scan:token().
%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 0383ce6839..a868867a81 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -179,12 +179,12 @@ state(_Hook) ->
state().
state() ->
- #pp{string_fun = fun io_lib:write_unicode_string_as_latin1/1,
- char_fun = fun io_lib:write_unicode_char_as_latin1/1}.
+ #pp{string_fun = fun io_lib:write_string_as_latin1/1,
+ char_fun = fun io_lib:write_char_as_latin1/1}.
unicode_state() ->
- #pp{string_fun = fun io_lib:write_unicode_string/1,
- char_fun = fun io_lib:write_unicode_char/1}.
+ #pp{string_fun = fun io_lib:write_string/1,
+ char_fun = fun io_lib:write_char/1}.
encoding(Options) ->
case proplists:get_value(encoding, Options, epp:default_encoding()) of
@@ -510,8 +510,6 @@ lexpr({'fun',_,{clauses,Cs}}, _Prec, Opts) ->
lexpr({'fun',_,{clauses,Cs},Extra}, _Prec, Opts) ->
{force_nl,fun_info(Extra),
{list,[{first,'fun',fun_clauses(Cs, Opts)},'end']}};
-lexpr({'query',_,Lc}, _Prec, Opts) ->
- {list,[{step,leaf("query"),lexpr(Lc, 0, Opts)},'end']};
lexpr({call,_,{remote,_,{atom,_,M},{atom,_,F}=N}=Name,Args}, Prec, Opts) ->
case erl_internal:bif(M, F, length(Args)) of
true ->
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index e5bb287c45..26d5747ee7 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -64,6 +64,7 @@
location/0,
options/0,
return_cont/0,
+ token/0,
tokens_result/0]).
%%%
@@ -106,7 +107,7 @@
ws = false :: boolean(),
comment = false :: boolean(),
text = false :: boolean(),
- unicode = false :: boolean()}).
+ unicode = true :: boolean()}).
%%----------------------------------------------------------------------------
@@ -115,7 +116,7 @@
format_error({string,Quote,Head}) ->
lists:flatten(["unterminated " ++ string_thing(Quote) ++
" starting with " ++
- io_lib:write_unicode_string(Head, Quote)]);
+ io_lib:write_string(Head, Quote)]);
format_error({illegal,Type}) ->
lists:flatten(io_lib:fwrite("illegal ~w", [Type]));
format_error(char) -> "unterminated character";
@@ -349,14 +350,14 @@ string_thing(_) -> "string".
%% erl_scan:string("[98,2730,99]."). This is to protect the caller
%% from character codes greater than 255. Search for UNI to find code
%% implementing this "feature". The 'unicode' option is undocumented
-%% and will probably be removed later.
+%% and will be removed later.
-define(NO_UNICODE, 0).
-define(UNI255(C), (C =< 16#ff)).
options(Opts0) when is_list(Opts0) ->
Opts = lists:foldr(fun expand_opt/2, [], Opts0),
- [RW_fun] =
- case opts(Opts, [reserved_word_fun], []) of
+ [RW_fun, Unicode] =
+ case opts(Opts, [reserved_word_fun, unicode], []) of
badarg ->
erlang:error(badarg, [Opts0]);
R ->
@@ -365,7 +366,6 @@ options(Opts0) when is_list(Opts0) ->
Comment = proplists:get_bool(return_comments, Opts),
WS = proplists:get_bool(return_white_spaces, Opts),
Txt = proplists:get_bool(text, Opts),
- Unicode = proplists:get_bool(unicode, Opts),
#erl_scan{resword_fun = RW_fun,
comment = Comment,
ws = WS,
@@ -378,6 +378,8 @@ opts(Options, [Key|Keys], L) ->
V = case lists:keyfind(Key, 1, Options) of
{reserved_word_fun,F} when ?RESWORDFUN(F) ->
{ok,F};
+ {unicode, Bool} when is_boolean(Bool) ->
+ {ok,Bool};
{Key,_} ->
badarg;
false ->
@@ -393,7 +395,9 @@ opts(_Options, [], L) ->
lists:reverse(L).
default_option(reserved_word_fun) ->
- fun reserved_word/1.
+ fun reserved_word/1;
+default_option(unicode) ->
+ true.
expand_opt(return, Os) ->
[return_comments,return_white_spaces|Os];
@@ -1404,7 +1408,6 @@ reserved_word('fun') -> true;
reserved_word('if') -> true;
reserved_word('let') -> true;
reserved_word('of') -> true;
-reserved_word('query') -> true;
reserved_word('receive') -> true;
reserved_word('when') -> true;
reserved_word('bnot') -> true;
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index 306834e845..9d32e0ad8b 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -154,7 +154,7 @@ table(Name, Opts) ->
t(Name) ->
case table(Name) of
{ok, List} ->
- lists:foreach(fun(N) -> ok = io:format("~s\n", [N]) end, List);
+ lists:foreach(fun(N) -> ok = io:format("~ts\n", [N]) end, List);
Error ->
Error
end.
@@ -216,11 +216,11 @@ format_error(bad_header) -> "Bad directory header";
format_error(eof) -> "Unexpected end of file";
format_error(symbolic_link_too_long) -> "Symbolic link too long";
format_error({Name,Reason}) ->
- lists:flatten(io_lib:format("~s: ~s", [Name,format_error(Reason)]));
+ lists:flatten(io_lib:format("~ts: ~ts", [Name,format_error(Reason)]));
format_error(Atom) when is_atom(Atom) ->
file:format_error(Atom);
format_error(Term) ->
- lists:flatten(io_lib:format("~p", [Term])).
+ lists:flatten(io_lib:format("~tp", [Term])).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -325,13 +325,13 @@ add1(TarFile, Name, NameInArchive, Opts) ->
end.
add1(Tar, Name, Header, Bin, Options) ->
- add_verbose(Options, "a ~s~n", [Name]),
+ add_verbose(Options, "a ~ts~n", [Name]),
file:write(Tar, [Header, Bin, padding(byte_size(Bin), ?record_size)]).
add_directory(TarFile, DirName, NameInArchive, Info, Options) ->
case file:list_dir(DirName) of
{ok, []} ->
- add_verbose(Options, "a ~s~n", [DirName]),
+ add_verbose(Options, "a ~ts~n", [DirName]),
Header = create_header(NameInArchive, Info),
file:write(TarFile, Header);
{ok, Files} ->
@@ -731,7 +731,7 @@ write_extracted_element(Header, Bin, Opts) ->
symlink ->
create_symlink(Name, Header, Opts);
Other -> % Ignore.
- read_verbose(Opts, "x ~s - unsupported type ~p~n",
+ read_verbose(Opts, "x ~ts - unsupported type ~p~n",
[Name, Other]),
not_written
end,
@@ -757,7 +757,7 @@ create_symlink(Name, #tar_header{linkname=Linkname}=Header, Opts) ->
create_symlink(Name, Header, Opts);
{error,eexist} -> not_written;
{error,enotsup} ->
- read_verbose(Opts, "x ~s - symbolic links not supported~n", [Name]),
+ read_verbose(Opts, "x ~ts - symbolic links not supported~n", [Name]),
not_written;
{error,Reason} -> throw({error, Reason})
end.
@@ -774,10 +774,10 @@ write_extracted_file(Name, Bin, Opts) ->
end,
case Write of
true ->
- read_verbose(Opts, "x ~s~n", [Name]),
+ read_verbose(Opts, "x ~ts~n", [Name]),
write_file(Name, Bin);
false ->
- read_verbose(Opts, "x ~s - exists, not created~n", [Name]),
+ read_verbose(Opts, "x ~ts - exists, not created~n", [Name]),
not_written
end.
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 99a9d138ac..cab5973d0c 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -624,7 +624,7 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) ->
ok = file:close(Fd),
check_source(S3, CheckOnly);
{error, Reason} ->
- io:format("escript: ~p\n", [Reason]),
+ io:format("escript: ~tp\n", [Reason]),
fatal("Preprocessor error")
end.
@@ -694,7 +694,7 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
epp_parse_file(Epp, S2, [Form | Forms]);
true ->
Args = lists:flatten(io_lib:format("illegal mode attribute: ~p", [NewMode])),
- io:format("~s:~w ~s\n", [S#state.file,Ln,Args]),
+ io:format("~ts:~w ~s\n", [S#state.file,Ln,Args]),
Error = {error,{Ln,erl_parse,Args}},
Nerrs= S#state.n_errors + 1,
epp_parse_file(Epp, S2#state{n_errors = Nerrs}, [Error | Forms])
@@ -710,7 +710,7 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
epp_parse_file(Epp, S, [Form | Forms])
end;
{error,{Ln,Mod,Args}} = Form ->
- io:format("~s:~w: ~ts\n",
+ io:format("~ts:~w: ~ts\n",
[S#state.file,Ln,Mod:format_error(Args)]),
epp_parse_file(Epp, S#state{n_errors = S#state.n_errors + 1}, [Form | Forms]);
{eof, _LastLine} = Eof ->
@@ -780,10 +780,10 @@ report_errors(Errors) ->
Errors).
list_errors(F, [{Line,Mod,E}|Es]) ->
- io:fwrite("~s:~w: ~ts\n", [F,Line,Mod:format_error(E)]),
+ io:fwrite("~ts:~w: ~ts\n", [F,Line,Mod:format_error(E)]),
list_errors(F, Es);
list_errors(F, [{Mod,E}|Es]) ->
- io:fwrite("~s: ~ts\n", [F,Mod:format_error(E)]),
+ io:fwrite("~ts: ~ts\n", [F,Mod:format_error(E)]),
list_errors(F, Es);
list_errors(_F, []) -> ok.
@@ -795,10 +795,10 @@ report_warnings(Ws0) ->
lists:foreach(fun({_,Str}) -> io:put_chars(Str) end, Ws).
format_message(F, [{Line,Mod,E}|Es]) ->
- M = {{F,Line},io_lib:format("~s:~w: Warning: ~ts\n", [F,Line,Mod:format_error(E)])},
+ M = {{F,Line},io_lib:format("~ts:~w: Warning: ~ts\n", [F,Line,Mod:format_error(E)])},
[M|format_message(F, Es)];
format_message(F, [{Mod,E}|Es]) ->
- M = {none,io_lib:format("~s: Warning: ~ts\n", [F,Mod:format_error(E)])},
+ M = {none,io_lib:format("~ts: Warning: ~ts\n", [F,Mod:format_error(E)])},
[M|format_message(F, Es)];
format_message(_, []) -> [].
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 61bb038737..06f21c1d2c 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -501,7 +501,7 @@ fun2ms(ShellFun) when is_function(ShellFun) ->
case ms_transform:transform_from_shell(
?MODULE,Clauses,ImportList) of
{error,[{_,[{_,_,Code}|_]}|_],_} ->
- io:format("Error: ~s~n",
+ io:format("Error: ~ts~n",
[ms_transform:format_error(Code)]),
{error,transform_error};
Else ->
@@ -1586,7 +1586,7 @@ choice(Height, Width, P, Mode, Tab, Key, Turn, Opos) ->
{ok,Re} ->
re_search(Height, Width, Tab, ets:first(Tab), Re, 1, 1);
{error,{ErrorString,_Pos}} ->
- io:format("~s\n", [ErrorString]),
+ io:format("~ts\n", [ErrorString]),
choice(Height, Width, P, Mode, Tab, Key, Turn, Opos)
end;
_ ->
diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl
index 3f31852afc..83782834cc 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -633,7 +633,7 @@ last_merge(R, W) when length(R) =< W#w.no_files ->
case W#w.out of
Fun when is_function(Fun) ->
{Fs, W1} = init_merge(lists:reverse(R), 1, [], W),
- ?DEBUG("merging ~p~n", [lists:reverse(R)]),
+ ?DEBUG("merging ~tp~n", [lists:reverse(R)]),
W2 = merge_files(Fs, [], 0, nolast, W1),
NW = close_input(W2),
outfun(close, NW);
@@ -659,7 +659,7 @@ merge_runs([R, R1 | Rs], NRs0, W) ->
merge_files(R, W) ->
{W1, Temp} = next_temp(W),
- ?DEBUG("merging ~p~nto ~p~n", [lists:reverse(R), Temp]),
+ ?DEBUG("merging ~tp~nto ~tp~n", [lists:reverse(R), Temp]),
{Temp, merge_files(R, W1, Temp)}.
merge_files(R, W, FileName) ->
@@ -1501,7 +1501,7 @@ close_out(_) ->
close_file(Fd, W) ->
{Fd, FileName} = lists:keyfind(Fd, 1, W#w.temp),
- ?DEBUG("closing ~p~n", [FileName]),
+ ?DEBUG("closing ~tp~n", [FileName]),
file:close(Fd),
W#w{temp = [FileName | lists:keydelete(Fd, 1, W#w.temp)]}.
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index ecf2aeb375..3dddb0d6e7 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -127,7 +127,7 @@ rows(Io) ->
-spec get_chars(Prompt, Count) -> Data | server_no_data() when
Prompt :: prompt(),
Count :: non_neg_integer(),
- Data :: [unicode:unicode_char()] | unicode:unicode_binary().
+ Data :: string() | unicode:unicode_binary().
get_chars(Prompt, N) ->
get_chars(default_input(), Prompt, N).
@@ -136,14 +136,14 @@ get_chars(Prompt, N) ->
IoDevice :: device(),
Prompt :: prompt(),
Count :: non_neg_integer(),
- Data :: [unicode:unicode_char()] | unicode:unicode_binary().
+ Data :: string() | unicode:unicode_binary().
get_chars(Io, Prompt, N) when is_integer(N), N >= 0 ->
request(Io, {get_chars,unicode,Prompt,N}).
-spec get_line(Prompt) -> Data | server_no_data() when
Prompt :: prompt(),
- Data :: [unicode:unicode_char()] | unicode:unicode_binary().
+ Data :: string() | unicode:unicode_binary().
get_line(Prompt) ->
get_line(default_input(), Prompt).
@@ -151,7 +151,7 @@ get_line(Prompt) ->
-spec get_line(IoDevice, Prompt) -> Data | server_no_data() when
IoDevice :: device(),
Prompt :: prompt(),
- Data :: [unicode:unicode_char()] | unicode:unicode_binary().
+ Data :: string() | unicode:unicode_binary().
get_line(Io, Prompt) ->
request(Io, {get_line,unicode,Prompt}).
@@ -221,8 +221,6 @@ write(Io, Term) ->
| {'error', ErrorInfo},
ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
-% Read does not use get_until as erl_scan does not work with unicode
-% XXX:PaN fixme?
read(Prompt) ->
read(default_input(), Prompt).
@@ -331,7 +329,7 @@ fread(Prompt, Format) ->
Prompt :: prompt(),
Format :: format(),
Result :: {'ok', Terms :: [term()]}
- | {'error', FreadError :: io_lib:fread_error()}
+ | {'error', {'fread', FreadError :: io_lib:fread_error()}}
| server_no_data().
fread(Io, Prompt, Format) ->
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index 5ad505f683..b7ec848e1e 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -64,29 +64,31 @@
-export([print/1,print/4,indentation/2]).
-export([write/1,write/2,write/3,nl/0,format_prompt/1,format_prompt/2]).
--export([write_atom/1,write_string/1,write_string/2,write_unicode_string/1,
- write_unicode_string/2, write_char/1, write_unicode_char/1]).
+-export([write_atom/1,write_string/1,write_string/2,write_latin1_string/1,
+ write_latin1_string/2, write_char/1, write_latin1_char/1]).
--export([write_unicode_string_as_latin1/1, write_unicode_string_as_latin1/2,
- write_unicode_char_as_latin1/1]).
+-export([write_string_as_latin1/1, write_string_as_latin1/2,
+ write_char_as_latin1/1]).
--export([quote_atom/2, char_list/1, unicode_char_list/1,
- deep_char_list/1, deep_unicode_char_list/1,
- printable_list/1, printable_unicode_list/1]).
+-export([quote_atom/2, char_list/1, latin1_char_list/1,
+ deep_char_list/1, deep_latin1_char_list/1,
+ printable_list/1, printable_latin1_list/1]).
%% Utilities for collecting characters.
-export([collect_chars/3, collect_chars/4,
collect_line/2, collect_line/3, collect_line/4,
get_until/3, get_until/4]).
--export_type([chars/0, unicode_chars/0, unicode_string/0, continuation/0,
- fread_error/0]).
+%% The following functions were used by Yecc's include-file.
+-export([write_unicode_string/1, write_unicode_char/1,
+ deep_unicode_char_list/1]).
+
+-export_type([chars/0, latin1_string/0, continuation/0, fread_error/0]).
%%----------------------------------------------------------------------
-type chars() :: [char() | chars()].
--type unicode_chars() :: [unicode:unicode_char() | unicode_chars()].
--type unicode_string() :: [unicode:unicode_char()].
+-type latin1_string() :: [unicode:latin1_char()].
-type depth() :: -1 | non_neg_integer().
-opaque continuation() :: {Format :: string(),
@@ -108,10 +110,8 @@
%% Interface calls to sub-modules.
--spec fwrite(Format, Data) -> chars() | UnicodeList when
+-spec fwrite(Format, Data) -> chars() when
Format :: io:format(),
- Data :: [term()],
- UnicodeList :: [unicode:unicode_char()],
Data :: [term()].
fwrite(Format, Args) ->
@@ -124,7 +124,7 @@ fwrite(Format, Args) ->
| {'more', RestFormat :: string(),
Nchars :: non_neg_integer(),
InputStack :: chars()}
- | {'error', What :: fread_error()}.
+ | {'error', {'fread', What :: fread_error()}}.
fread(Chars, Format) ->
io_lib_fread:fread(Chars, Format).
@@ -137,15 +137,14 @@ fread(Chars, Format) ->
| {'done', Result, LeftOverChars :: string()},
Result :: {'ok', InputList :: [term()]}
| 'eof'
- | {'error', What :: fread_error()}.
+ | {'error', {'fread', What :: fread_error()}}.
fread(Cont, Chars, Format) ->
io_lib_fread:fread(Cont, Chars, Format).
--spec format(Format, Data) -> chars() | UnicodeList when
+-spec format(Format, Data) -> chars() when
Format :: io:format(),
- Data :: [term()],
- UnicodeList :: [unicode:unicode_char()].
+ Data :: [term()].
format(Format, Args) ->
case catch io_lib_format:fwrite(Format, Args) of
@@ -340,6 +339,11 @@ name_char($_) -> true;
name_char($@) -> true;
name_char(_) -> false.
+%%% There are two functions to write Unicode strings:
+%%% - they both escape control characters < 160;
+%%% - write_string() never escapes characters >= 160;
+%%% - write_string_as_latin1() also escapes characters >= 255.
+
%% write_string([Char]) -> [Char]
%% Generate the list of characters needed to print a string.
@@ -352,33 +356,32 @@ write_string(S) ->
-spec write_string(string(), char()) -> chars().
write_string(S, Q) ->
- [Q|write_string1(latin1, S, Q)].
+ [Q|write_string1(unicode_as_unicode, S, Q)].
-%%% There are two functions to write Unicode strings:
-%%% - they both escape control characters < 160;
-%%% - write_unicode_string() never escapes characters >= 160;
-%%% - write_unicode_string_as_latin1() also escapes characters >= 255.
+%% Backwards compatibility.
+write_unicode_string(S) ->
+ write_string(S).
--spec write_unicode_string(UnicodeString) -> unicode_string() when
- UnicodeString :: unicode_string().
+-spec write_latin1_string(Latin1String) -> latin1_string() when
+ Latin1String :: latin1_string().
-write_unicode_string(S) ->
- write_unicode_string(S, $"). %"
+write_latin1_string(S) ->
+ write_latin1_string(S, $"). %"
--spec write_unicode_string(unicode_string(), char()) -> unicode_string().
+-spec write_latin1_string(latin1_string(), char()) -> latin1_string().
-write_unicode_string(S, Q) ->
- [Q|write_string1(unicode_as_unicode, S, Q)].
+write_latin1_string(S, Q) ->
+ [Q|write_string1(latin1, S, Q)].
--spec write_unicode_string_as_latin1(UnicodeString) -> string() when
- UnicodeString :: unicode_string().
+-spec write_string_as_latin1(String) -> latin1_string() when
+ String :: string().
-write_unicode_string_as_latin1(S) ->
- write_unicode_string_as_latin1(S, $"). %"
+write_string_as_latin1(S) ->
+ write_string_as_latin1(S, $"). %"
--spec write_unicode_string_as_latin1(unicode_string(), char()) -> string().
+-spec write_string_as_latin1(string(), char()) -> latin1_string().
-write_unicode_string_as_latin1(S, Q) ->
+write_string_as_latin1(S, Q) ->
[Q|write_string1(unicode_as_latin1, S, Q)].
write_string1(_,[], Q) ->
@@ -412,6 +415,11 @@ string_char(_,C, _, Tail) when C < $\240-> %Other control characters.
C3 = (C band 7) + $0,
[$\\,C1,C2,C3|Tail].
+%%% There are two functions to write a Unicode character:
+%%% - they both escape control characters < 160;
+%%% - write_char() never escapes characters >= 160;
+%%% - write_char_as_latin1() also escapes characters >= 255.
+
%% write_char(Char) -> [char()].
%% Generate the list of characters needed to print a character constant.
%% Must special case SPACE, $\s, here.
@@ -420,48 +428,63 @@ string_char(_,C, _, Tail) when C < $\240-> %Other control characters.
Char :: char().
write_char($\s) -> "$\\s"; %Must special case this.
-write_char(C) when is_integer(C), C >= $\000, C =< $\377 ->
- [$$|string_char(latin1,C, -1, [])].
+write_char(C) when is_integer(C), C >= $\000 ->
+ [$$|string_char(unicode_as_unicode, C, -1, [])].
-%%% There are two functions to write a Unicode character:
-%%% - they both escape control characters < 160;
-%%% - write_unicode_char() never escapes characters >= 160;
-%%% - write_unicode_char_as_latin1() also escapes characters >= 255.
+%% Backwards compatibility.
+write_unicode_char(C) ->
+ write_char(C).
--spec write_unicode_char(UnicodeChar) -> unicode_string() when
- UnicodeChar :: unicode:unicode_char().
+-spec write_latin1_char(Latin1Char) -> latin1_string() when
+ Latin1Char :: unicode:latin1_char().
-write_unicode_char(Uni) when is_integer(Uni), Uni >= $\000 ->
- [$$|string_char(unicode_as_unicode,Uni, -1, [])].
+write_latin1_char(Lat1) when is_integer(Lat1), Lat1 >= $\000, Lat1 =< $\377 ->
+ [$$|string_char(latin1, Lat1, -1, [])].
--spec write_unicode_char_as_latin1(UnicodeChar) -> string() when
- UnicodeChar :: unicode:unicode_char().
+-spec write_char_as_latin1(Char) -> latin1_string() when
+ Char :: char().
-write_unicode_char_as_latin1(Uni) when is_integer(Uni), Uni >= $\000 ->
+write_char_as_latin1(Uni) when is_integer(Uni), Uni >= $\000 ->
[$$|string_char(unicode_as_latin1,Uni, -1, [])].
-%% char_list(CharList)
-%% deep_char_list(CharList)
-%% Return true if CharList is a (possibly deep) list of characters, else
-%% false.
+%% latin1_char_list(CharList)
+%% deep_latin1_char_list(CharList)
+%% Return true if CharList is a (possibly deep) list of Latin-1
+%% characters, else false.
+
+-spec latin1_char_list(Term) -> boolean() when
+ Term :: term().
+
+latin1_char_list([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
+ latin1_char_list(Cs);
+latin1_char_list([]) -> true;
+latin1_char_list(_) -> false. %Everything else is false
-spec char_list(Term) -> boolean() when
Term :: term().
-char_list([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
+char_list([C|Cs]) when is_integer(C), C >= 0, C < 16#D800;
+ is_integer(C), C > 16#DFFF, C < 16#FFFE;
+ is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
char_list(Cs);
char_list([]) -> true;
char_list(_) -> false. %Everything else is false
--spec unicode_char_list(Term) -> boolean() when
+-spec deep_latin1_char_list(Term) -> boolean() when
Term :: term().
-unicode_char_list([C|Cs]) when is_integer(C), C >= 0, C < 16#D800;
- is_integer(C), C > 16#DFFF, C < 16#FFFE;
- is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
- unicode_char_list(Cs);
-unicode_char_list([]) -> true;
-unicode_char_list(_) -> false. %Everything else is false
+deep_latin1_char_list(Cs) ->
+ deep_latin1_char_list(Cs, []).
+
+deep_latin1_char_list([C|Cs], More) when is_list(C) ->
+ deep_latin1_char_list(C, [Cs|More]);
+deep_latin1_char_list([C|Cs], More) when is_integer(C), C >= $\000, C =< $\377 ->
+ deep_latin1_char_list(Cs, More);
+deep_latin1_char_list([], [Cs|More]) ->
+ deep_latin1_char_list(Cs, More);
+deep_latin1_char_list([], []) -> true;
+deep_latin1_char_list(_, _More) -> %Everything else is false
+ false.
-spec deep_char_list(Term) -> boolean() when
Term :: term().
@@ -471,43 +494,56 @@ deep_char_list(Cs) ->
deep_char_list([C|Cs], More) when is_list(C) ->
deep_char_list(C, [Cs|More]);
-deep_char_list([C|Cs], More) when is_integer(C), C >= $\000, C =< $\377 ->
+deep_char_list([C|Cs], More)
+ when is_integer(C), C >= 0, C < 16#D800;
+ is_integer(C), C > 16#DFFF, C < 16#FFFE;
+ is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
deep_char_list(Cs, More);
deep_char_list([], [Cs|More]) ->
deep_char_list(Cs, More);
deep_char_list([], []) -> true;
-deep_char_list(_, _More) -> %Everything else is false
+deep_char_list(_, _More) -> %Everything else is false
false.
--spec deep_unicode_char_list(Term) -> boolean() when
- Term :: term().
+deep_unicode_char_list(Term) ->
+ deep_char_list(Term).
-deep_unicode_char_list(Cs) ->
- deep_unicode_char_list(Cs, []).
+%% printable_latin1_list([Char]) -> boolean()
+%% Return true if CharList is a list of printable Latin1 characters, else
+%% false.
-deep_unicode_char_list([C|Cs], More) when is_list(C) ->
- deep_unicode_char_list(C, [Cs|More]);
-deep_unicode_char_list([C|Cs], More)
- when is_integer(C), C >= 0, C < 16#D800;
- is_integer(C), C > 16#DFFF, C < 16#FFFE;
- is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
- deep_unicode_char_list(Cs, More);
-deep_unicode_char_list([], [Cs|More]) ->
- deep_unicode_char_list(Cs, More);
-deep_unicode_char_list([], []) -> true;
-deep_unicode_char_list(_, _More) -> %Everything else is false
- false.
+-spec printable_latin1_list(Term) -> boolean() when
+ Term :: term().
+
+printable_latin1_list([C|Cs]) when is_integer(C), C >= $\040, C =< $\176 ->
+ printable_latin1_list(Cs);
+printable_latin1_list([C|Cs]) when is_integer(C), C >= $\240, C =< $\377 ->
+ printable_latin1_list(Cs);
+printable_latin1_list([$\n|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([$\r|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([$\t|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([$\v|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([$\b|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([$\f|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([$\e|Cs]) -> printable_latin1_list(Cs);
+printable_latin1_list([]) -> true;
+printable_latin1_list(_) -> false. %Everything else is false
%% printable_list([Char]) -> boolean()
%% Return true if CharList is a list of printable characters, else
-%% false.
+%% false. The notion of printable in Unicode terms is somewhat floating.
+%% Everything that is not a control character and not invalid unicode
+%% will be considered printable.
-spec printable_list(Term) -> boolean() when
Term :: term().
printable_list([C|Cs]) when is_integer(C), C >= $\040, C =< $\176 ->
printable_list(Cs);
-printable_list([C|Cs]) when is_integer(C), C >= $\240, C =< $\377 ->
+printable_list([C|Cs])
+ when is_integer(C), C >= 16#A0, C < 16#D800;
+ is_integer(C), C > 16#DFFF, C < 16#FFFE;
+ is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
printable_list(Cs);
printable_list([$\n|Cs]) -> printable_list(Cs);
printable_list([$\r|Cs]) -> printable_list(Cs);
@@ -517,33 +553,7 @@ printable_list([$\b|Cs]) -> printable_list(Cs);
printable_list([$\f|Cs]) -> printable_list(Cs);
printable_list([$\e|Cs]) -> printable_list(Cs);
printable_list([]) -> true;
-printable_list(_) -> false. %Everything else is false
-
-%% printable_unicode_list([Char]) -> boolean()
-%% Return true if CharList is a list of printable characters, else
-%% false. The notion of printable in Unicode terms is somewhat floating.
-%% Everything that is not a control character and not invalid unicode
-%% will be considered printable.
-
--spec printable_unicode_list(Term) -> boolean() when
- Term :: term().
-
-printable_unicode_list([C|Cs]) when is_integer(C), C >= $\040, C =< $\176 ->
- printable_unicode_list(Cs);
-printable_unicode_list([C|Cs])
- when is_integer(C), C >= 16#A0, C < 16#D800;
- is_integer(C), C > 16#DFFF, C < 16#FFFE;
- is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
- printable_unicode_list(Cs);
-printable_unicode_list([$\n|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([$\r|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([$\t|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([$\v|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([$\b|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([$\f|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([$\e|Cs]) -> printable_unicode_list(Cs);
-printable_unicode_list([]) -> true;
-printable_unicode_list(_) -> false. %Everything else is false
+printable_list(_) -> false. %Everything else is false
%% List = nl()
%% Return a list of characters to generate a newline.
diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl
index 5680f83ab6..6a06d9448b 100644
--- a/lib/stdlib/src/io_lib_format.erl
+++ b/lib/stdlib/src/io_lib_format.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -22,7 +22,7 @@
-export([fwrite/2,fwrite_g/1,indentation/2]).
-%% fwrite(Format, ArgList) -> [unicode:unicode:char()].
+%% fwrite(Format, ArgList) -> string().
%% Format the arguments in ArgList after string Format. Just generate
%% an error if there is an error in the arguments.
%%
@@ -133,7 +133,7 @@ pcount([{$P,_As,_F,_Ad,_P,_Pad,_Enc}|Cs], Acc) -> pcount(Cs, Acc+1);
pcount([_|Cs], Acc) -> pcount(Cs, Acc);
pcount([], Acc) -> Acc.
-%% build([Control], Pc, Indentation) -> [unicode:unicode_char()].
+%% build([Control], Pc, Indentation) -> string().
%% Interpret the control structures. Count the number of print
%% remaining and only calculate indentation when necessary. Must also
%% be smart when calculating indentation for characters in format.
@@ -154,7 +154,7 @@ decr_pc($p, Pc) -> Pc - 1;
decr_pc($P, Pc) -> Pc - 1;
decr_pc(_, Pc) -> Pc.
-%% indentation([unicode:unicode_char()], Indentation) -> Indentation.
+%% indentation(String, Indentation) -> Indentation.
%% Calculate the indentation of the end of a string given its start
%% indentation. We assume tabs at 8 cols.
@@ -167,8 +167,7 @@ indentation([C|Cs], I) ->
indentation([], I) -> I.
%% control(FormatChar, [Argument], FieldWidth, Adjust, Precision, PadChar,
-%% Encoding, Indentation) ->
-%% [unicode:unicode_char()]
+%% Encoding, Indentation) -> String
%% This is the main dispatch function for the various formatting commands.
%% Field widths and precisions have already been calculated.
@@ -613,7 +612,7 @@ prefixed_integer(Int, F, Adj, Base, Pad, Prefix, Lowercase)
term([Prefix|S], F, Adj, none, Pad)
end.
-%% char(Char, Field, Adjust, Precision, PadChar) -> [unicode:unicode_char()].
+%% char(Char, Field, Adjust, Precision, PadChar) -> string().
char(C, none, _Adj, none, _Pad) -> [C];
char(C, F, _Adj, none, _Pad) -> chars(C, F);
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 84d4b8bba0..92a34995b8 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -22,7 +22,7 @@
-export([fread/2,fread/3]).
--import(lists, [reverse/1,reverse/2]).
+-import(lists, [reverse/1]).
-define(is_whitespace(C),
((C) =:= $\s orelse (C) =:= $\t
@@ -43,7 +43,7 @@
| {'done', Result, LeftOverChars :: string()},
Result :: {'ok', InputList :: io_lib:chars()}
| 'eof'
- | {'error', What :: io_lib:fread_error()}.
+ | {'error', {'read', What :: io_lib:fread_error()}}.
fread([], Chars, Format) ->
%%io:format("FREAD: ~w `~s'~n", [Format,Chars]),
diff --git a/lib/stdlib/src/io_lib_pretty.erl b/lib/stdlib/src/io_lib_pretty.erl
index 99ad281a9b..a8f610558a 100644
--- a/lib/stdlib/src/io_lib_pretty.erl
+++ b/lib/stdlib/src/io_lib_pretty.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -51,7 +51,6 @@ print(Term) ->
-type max_chars() :: integer().
-type chars() :: io_lib:chars().
--type unicode_chars() :: io_lib:unicode_chars().
-type option() :: {column, column()}
| {line_length, line_length()}
| {depth, depth()}
@@ -60,8 +59,8 @@ print(Term) ->
| {encoding, latin1 | utf8 | unicode}.
-type options() :: [option()].
--spec print(term(), rec_print_fun()) -> chars() | unicode_chars();
- (term(), options()) -> chars() | unicode_chars().
+-spec print(term(), rec_print_fun()) -> chars();
+ (term(), options()) -> chars().
print(Term, Options) when is_list(Options) ->
Col = proplists:get_value(column, Options, 1),
@@ -74,24 +73,23 @@ print(Term, Options) when is_list(Options) ->
print(Term, RecDefFun) ->
print(Term, -1, RecDefFun).
--spec print(term(), depth(), rec_print_fun()) -> chars() | unicode_chars().
+-spec print(term(), depth(), rec_print_fun()) -> chars().
print(Term, Depth, RecDefFun) ->
print(Term, 1, 80, Depth, RecDefFun).
--spec print(term(), column(), line_length(), depth()) ->
- chars() | unicode_chars().
+-spec print(term(), column(), line_length(), depth()) -> chars().
print(Term, Col, Ll, D) ->
print(Term, Col, Ll, D, _M=-1, no_fun, latin1).
-spec print(term(), column(), line_length(), depth(), rec_print_fun()) ->
- chars() | unicode_chars().
+ chars().
print(Term, Col, Ll, D, RecDefFun) ->
print(Term, Col, Ll, D, _M=-1, RecDefFun).
-spec print(term(), column(), line_length(), depth(), max_chars(),
- rec_print_fun()) -> chars() | unicode_chars().
+ rec_print_fun()) -> chars().
print(Term, Col, Ll, D, M, RecDefFun) ->
print(Term, Col, Ll, D, M, RecDefFun, latin1).
@@ -369,13 +367,13 @@ print_length(<<_/bitstring>>=Bin, D, _RF, Enc) ->
S = io_lib:write_string(List, $"), %"
{[$<,$<,S,$>,$>], 4 + length(S)};
{false, List} when is_list(List) ->
- S = io_lib:write_unicode_string(List, $"), %"
+ S = io_lib:write_string(List, $"), %"
{[$<,$<,S,"/utf8>>"], 9 + length(S)};
{true, true, Prefix} ->
S = io_lib:write_string(Prefix, $"), %"
{[$<,$<, S | "...>>"], 7 + length(S)};
{false, true, Prefix} ->
- S = io_lib:write_unicode_string(Prefix, $"), %"
+ S = io_lib:write_string(Prefix, $"), %"
{[$<,$<, S | "/utf8...>>"], 12 + length(S)};
false ->
S = io_lib:write(Bin, D),
@@ -387,7 +385,7 @@ print_length(<<_/bitstring>>=Bin, D, _RF, Enc) ->
end;
print_length(Term, _D, _RF, _Enc) ->
S = io_lib:write(Term),
- {S, iolist_size(S)}.
+ {S, lists:flatlength(S)}.
print_length_tuple(_Tuple, 1, _RF, _Enc) ->
{"{...}", 5};
@@ -451,9 +449,9 @@ list_length_tail({_, Len}, Acc) ->
printable_list(_L, 1, _Enc) ->
false;
printable_list(L, _D, latin1) ->
- io_lib:printable_list(L);
+ io_lib:printable_latin1_list(L);
printable_list(L, _D, _Uni) ->
- io_lib:printable_unicode_list(L).
+ io_lib:printable_list(L).
%% Truncated lists could break some existing code.
% printable_list(L, D, Enc) when D >= 0 ->
% Len = ?CHARS * (D - 1),
@@ -538,9 +536,9 @@ printable_unicode(Bin, I, L) ->
{I, Bin, lists:reverse(L)}.
write_string(S, latin1) ->
- io_lib:write_string(S, $"); %"
+ io_lib:write_latin1_string(S, $"); %"
write_string(S, _Uni) ->
- io_lib:write_unicode_string(S, $"). %"
+ io_lib:write_string(S, $"). %"
%% Throw 'no_good' if the indentation exceeds half the line length
%% unless there is room for M characters on the line.
diff --git a/lib/stdlib/src/lib.erl b/lib/stdlib/src/lib.erl
index b2ce2a5a8f..8351376691 100644
--- a/lib/stdlib/src/lib.erl
+++ b/lib/stdlib/src/lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -44,7 +44,7 @@ flush_receive() ->
Args :: [term()].
error_message(Format, Args) ->
- io:format(<<"** ~s **\n">>, [io_lib:format(Format, Args)]).
+ io:format(<<"** ~ts **\n">>, [io_lib:format(Format, Args)]).
%% Return the name of the script that starts (this) erlang
%%
@@ -84,10 +84,14 @@ sendw(To, Msg) ->
%% eval_str(InStr) -> {ok, OutStr} | {error, ErrStr'}
%% InStr must represent a body
+%% Note: If InStr is a binary it has to be a Latin-1 string.
+%% If you have a UTF-8 encoded binary you have to call
+%% unicode:characters_to_list/1 before the call to eval_str().
-define(result(F,D), lists:flatten(io_lib:format(F, D))).
--spec eval_str(string() | binary()) -> {'ok', string()} | {'error', string()}.
+-spec eval_str(string() | unicode:latin1_binary()) ->
+ {'ok', string()} | {'error', string()}.
eval_str(Str) when is_list(Str) ->
case erl_scan:tokens([], Str, 0) of
@@ -105,12 +109,12 @@ eval_str(Str) when is_list(Str) ->
{error, ?result("*** eval: ~p", [Other])}
end;
{error, {_Line, Mod, Args}} ->
- Msg = ?result("*** ~s",[Mod:format_error(Args)]),
+ Msg = ?result("*** ~ts",[Mod:format_error(Args)]),
{error, Msg}
end;
false ->
{error, ?result("Non-white space found after "
- "end-of-form :~s", [Rest])}
+ "end-of-form :~ts", [Rest])}
end
end;
eval_str(Bin) when is_binary(Bin) ->
@@ -426,9 +430,9 @@ brackets_to_parens(S, Enc) ->
[$(,R,$)].
printable_list(latin1, As) ->
- io_lib:printable_list(As);
+ io_lib:printable_latin1_list(As);
printable_list(_, As) ->
- io_lib:printable_unicode_list(As).
+ io_lib:printable_list(As).
mfa_to_string(M, F, A) ->
io_lib:fwrite(<<"~s/~w">>, [mf_to_string({M, F}, A), A]).
diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index 4389fd457c..4868024eed 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -100,7 +100,7 @@ format_error({?ERR_GUARDREMOTECALL, Module, Name, Arithy}) ->
[Module,Name,Arithy]));
format_error({?ERR_GUARDELEMENT, Str}) ->
lists:flatten(
- io_lib:format("the language element ~s (in guard) cannot be translated "
+ io_lib:format("the language element ~ts (in guard) cannot be translated "
"into match_spec", [Str]));
format_error({?ERR_GUARDBINCONSTRUCT, Var}) ->
lists:flatten(
@@ -126,7 +126,7 @@ format_error({?ERR_BODYREMOTECALL, Module, Name, Arithy}) ->
[Module,Name,Arithy]));
format_error({?ERR_BODYELEMENT, Str}) ->
lists:flatten(
- io_lib:format("the language element ~s (in body) cannot be translated "
+ io_lib:format("the language element ~ts (in body) cannot be translated "
"into match_spec", [Str]));
format_error({?ERR_BODYBINCONSTRUCT, Var}) ->
lists:flatten(
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 4bca4c1e6d..1eb6fc2e86 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -29,7 +29,8 @@
start/3, start/4, start/5, start_link/3, start_link/4, start_link/5,
hibernate/3,
init_ack/1, init_ack/2,
- init_p/3,init_p/5,format/1,initial_call/1,translate_initial_call/1]).
+ init_p/3,init_p/5,format/1,format/2,initial_call/1,
+ translate_initial_call/1]).
%% Internal exports.
-export([wake_up/3]).
@@ -692,34 +693,41 @@ check(Res) -> Res.
-spec format(CrashReport) -> string() when
CrashReport :: [term()].
-
-format([OwnReport,LinkReport]) ->
- OwnFormat = format_report(OwnReport),
- LinkFormat = format_report(LinkReport),
- S = io_lib:format(" crasher:~n~s neighbours:~n~s",[OwnFormat,LinkFormat]),
- lists:flatten(S).
-
-format_report(Rep) when is_list(Rep) ->
- format_rep(Rep);
-format_report(Rep) ->
- io_lib:format("~p~n", [Rep]).
-
-format_rep([{initial_call,InitialCall}|Rep]) ->
- [format_mfa(InitialCall)|format_rep(Rep)];
-format_rep([{error_info,{Class,Reason,StackTrace}}|Rep]) ->
- [format_exception(Class, Reason, StackTrace)|format_rep(Rep)];
-format_rep([{Tag,Data}|Rep]) ->
- [format_tag(Tag, Data)|format_rep(Rep)];
-format_rep(_) ->
+format(CrashReport) ->
+ format(CrashReport, latin1).
+
+-spec format(CrashReport, Encoding) -> string() when
+ CrashReport :: [term()],
+ Encoding :: latin1 | unicode | utf8.
+
+format([OwnReport,LinkReport], Encoding) ->
+ OwnFormat = format_report(OwnReport, Encoding),
+ LinkFormat = format_report(LinkReport, Encoding),
+ Str = io_lib:format(" crasher:~n~ts neighbours:~n~ts",
+ [OwnFormat, LinkFormat]),
+ lists:flatten(Str).
+
+format_report(Rep, Enc) when is_list(Rep) ->
+ format_rep(Rep,Enc);
+format_report(Rep, Enc) ->
+ io_lib:format("~"++modifier(Enc)++"p~n", [Rep]).
+
+format_rep([{initial_call,InitialCall}|Rep], Enc) ->
+ [format_mfa(InitialCall)|format_rep(Rep, Enc)];
+format_rep([{error_info,{Class,Reason,StackTrace}}|Rep], Enc) ->
+ [format_exception(Class, Reason, StackTrace, Enc)|format_rep(Rep, Enc)];
+format_rep([{Tag,Data}|Rep], Enc) ->
+ [format_tag(Tag, Data)|format_rep(Rep, Enc)];
+format_rep(_, _Enc) ->
[].
-format_exception(Class, Reason, StackTrace) ->
- PF = pp_fun(),
+format_exception(Class, Reason, StackTrace, Enc) ->
+ PF = pp_fun(Enc),
StackFun = fun(M, _F, _A) -> (M =:= erl_eval) or (M =:= ?MODULE) end,
%% EI = " exception: ",
EI = " ",
[EI, lib:format_exception(1+length(EI), Class, Reason,
- StackTrace, StackFun, PF), "\n"].
+ StackTrace, StackFun, PF, Enc), "\n"].
format_mfa({M,F,Args}=StartF) ->
try
@@ -731,10 +739,14 @@ format_mfa({M,F,Args}=StartF) ->
format_tag(initial_call, StartF)
end.
-pp_fun() ->
+pp_fun(Enc) ->
+ P = modifier(Enc) ++ "p",
fun(Term, I) ->
- io_lib:format("~." ++ integer_to_list(I) ++ "p", [Term])
+ io_lib:format("~." ++ integer_to_list(I) ++ P, [Term])
end.
format_tag(Tag, Data) ->
io_lib:format(" ~p: ~80.18p~n", [Tag, Data]).
+
+modifier(latin1) -> "";
+modifier(_) -> "t".
diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl
index 9b71d0edb8..9351674e00 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.erl
@@ -386,25 +386,25 @@ format_error(nomatch_pattern) ->
format_error(nomatch_filter) ->
io_lib:format("filter evaluates to 'false'", []);
format_error({Line, Mod, Reason}) when is_integer(Line) ->
- io_lib:format("~p: ~s~n",
+ io_lib:format("~p: ~ts~n",
[Line, lists:flatten(Mod:format_error(Reason))]);
%% file_sorter errors
format_error({bad_object, FileName}) ->
- io_lib:format("the temporary file \"~s\" holding answers is corrupt",
+ io_lib:format("the temporary file \"~ts\" holding answers is corrupt",
[FileName]);
format_error(bad_object) ->
io_lib:format("the keys could not be extracted from some term", []);
format_error({file_error, FileName, Reason}) ->
- io_lib:format("\"~s\": ~p~n",[FileName, file:format_error(Reason)]);
+ io_lib:format("\"~ts\": ~tp~n",[FileName, file:format_error(Reason)]);
format_error({premature_eof, FileName}) ->
- io_lib:format("\"~s\": end-of-file was encountered inside some binary term",
+ io_lib:format("\"~ts\": end-of-file was encountered inside some binary term",
[FileName]);
format_error({tmpdir_usage, Why}) ->
io_lib:format("temporary file was needed for ~w~n", [Why]);
format_error({error, Module, Reason}) ->
Module:format_error(Reason);
format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
-spec(info(QH) -> Info when
QH :: query_handle_or_list(),
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index d441f38e44..0744a5ffb9 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -214,7 +214,7 @@ compile_messages(Forms, FormsNoShadows, Options, State) ->
end,
{_,BGens} = qual_fold(BGenF, [], [], FormsNoShadows, State),
GenForm = used_genvar_check(FormsNoShadows, State),
- ?DEBUG("GenForm = ~s~n", [catch erl_pp:form(GenForm)]),
+ ?DEBUG("GenForm = ~ts~n", [catch erl_pp:form(GenForm)]),
WarnFun = fun(Id, LC, A) -> {tag_lines(LC, get_lcid_no(Id)), A} end,
{WForms,ok} = qlc_mapfold(WarnFun, ok, Forms, State),
{Es,Ws} = compile_forms(WForms ++ [GenForm], Options),
@@ -337,7 +337,7 @@ compile_errors(FormsNoShadows) ->
{[], _Warnings} ->
[];
{Errors, _Warnings} ->
- ?DEBUG("got errors ~p~n", [Errors]),
+ ?DEBUG("got errors ~tp~n", [Errors]),
lists:flatmap(fun({_File,Es}) -> Es end, Errors)
end.
@@ -2742,7 +2742,7 @@ family(L) ->
display_forms(Forms) ->
io:format("Forms ***~n"),
lists:foreach(fun(Form) ->
- io:format("~s~n", [catch erl_pp:form(Form)])
+ io:format("~ts~n", [catch erl_pp:form(Form)])
end, Forms),
io:format("End Forms ***~n").
-else.
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index afe917b151..bc1bd06534 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -472,22 +472,24 @@ init(Q) -> drop_r(Q).
-compile({inline, [{r2f,1},{f2r,1}]}).
-%% Move all but two from R to F, if there are at least three
+%% Move half of elements from R to F, if there are at least three
r2f([]) ->
{[],[]};
r2f([_]=R) ->
{[],R};
r2f([X,Y]) ->
{[X],[Y]};
-r2f([X,Y|R]) ->
- {[X,Y],lists:reverse(R, [])}.
+r2f(List) ->
+ {FF,RR} = lists:split(length(List) div 2 + 1, List),
+ {FF,lists:reverse(RR, [])}.
-%% Move all but two from F to R, if there are enough
+%% Move half of elements from F to R, if there are enough
f2r([]) ->
{[],[]};
f2r([_]=F) ->
{F,[]};
f2r([X,Y]) ->
{[Y],[X]};
-f2r([X,Y|F]) ->
- {lists:reverse(F, []),[X,Y]}.
+f2r(List) ->
+ {FF,RR} = lists:split(length(List) div 2 + 1, List),
+ {lists:reverse(RR, []),FF}.
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index 5c929d2f51..bb90353e76 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -273,7 +273,7 @@ get_command(Prompt, Eval, Bs, RT, Ds) ->
fun() ->
exit(
case
- io:scan_erl_exprs(group_leader(), Prompt, 1, [unicode])
+ io:scan_erl_exprs(group_leader(), Prompt, 1)
of
{ok,Toks,_EndPos} ->
erl_parse:parse_exprs(Toks);
diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl
index de0179da59..317d06a44b 100644
--- a/lib/stdlib/src/slave.erl
+++ b/lib/stdlib/src/slave.erl
@@ -229,7 +229,7 @@ wait_for_slave(Parent, Host, Name, Node, Args, LinkTo, Prog) ->
Waiter = register_unique_name(0),
case mk_cmd(Host, Name, Args, Waiter, Prog) of
{ok, Cmd} ->
-%% io:format("Command: ~s~n", [Cmd]),
+%% io:format("Command: ~ts~n", [Cmd]),
open_port({spawn, Cmd}, [stream]),
receive
{SlavePid, slave_started} ->
diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl
index 03f0a19f14..aeaf9cb5c1 100644
--- a/lib/stdlib/src/string.erl
+++ b/lib/stdlib/src/string.erl
@@ -484,8 +484,8 @@ to_upper_char(C) ->
C.
-spec to_lower(String) -> Result when
- String :: string(),
- Result :: string()
+ String :: io_lib:latin1_string(),
+ Result :: io_lib:latin1_string()
; (Char) -> CharResult when
Char :: char(),
CharResult :: char().
@@ -496,8 +496,8 @@ to_lower(C) when is_integer(C) ->
to_lower_char(C).
-spec to_upper(String) -> Result when
- String :: string(),
- Result :: string()
+ String :: io_lib:latin1_string(),
+ Result :: io_lib:latin1_string()
; (Char) -> CharResult when
Char :: char(),
CharResult :: char().
diff --git a/lib/stdlib/src/unicode.erl b/lib/stdlib/src/unicode.erl
index 8b9412fb1b..49529cffd4 100644
--- a/lib/stdlib/src/unicode.erl
+++ b/lib/stdlib/src/unicode.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -24,26 +24,33 @@
bom_to_encoding/1, encoding_to_bom/1]).
-export_type([chardata/0, charlist/0, encoding/0, external_chardata/0,
- external_charlist/0, latin1_chardata/0,
- latin1_charlist/0, unicode_binary/0, unicode_char/0]).
+ external_charlist/0, latin1_char/0, latin1_chardata/0,
+ latin1_charlist/0, latin1_binary/0, unicode_binary/0]).
-type encoding() :: 'latin1' | 'unicode' | 'utf8'
| 'utf16' | {'utf16', endian()}
| 'utf32' | {'utf32', endian()}.
-type endian() :: 'big' | 'little'.
-type unicode_binary() :: binary().
--type unicode_char() :: non_neg_integer().
--type charlist() :: [unicode_char() | unicode_binary() | charlist()].
+-type charlist() ::
+ maybe_improper_list(char() | unicode_binary() | charlist(),
+ unicode_binary() | nil()).
-type chardata() :: charlist() | unicode_binary().
-type external_unicode_binary() :: binary().
-type external_chardata() :: external_charlist() | external_unicode_binary().
--type external_charlist() :: [unicode_char() | external_unicode_binary()
- | external_charlist()].
+-type external_charlist() ::
+ maybe_improper_list(char() |
+ external_unicode_binary() |
+ external_charlist(),
+ external_unicode_binary() | nil()).
-type latin1_binary() :: binary().
-type latin1_char() :: byte().
-type latin1_chardata() :: latin1_charlist() | latin1_binary().
--type latin1_charlist() :: [latin1_char() | latin1_binary()
- | latin1_charlist()].
+-type latin1_charlist() ::
+ maybe_improper_list(latin1_char() |
+ latin1_binary() |
+ latin1_charlist(),
+ latin1_binary() | nil()).
%%% BIFs
%%%
diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl
index c383540db7..489406c023 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -610,9 +610,9 @@ get_zip_opt([Unknown | _Rest], _Opts) ->
%% feedback funs
silent(_) -> ok.
-verbose_unzip(FN) -> io:format("extracting: ~p\n", [FN]).
+verbose_unzip(FN) -> io:format("extracting: ~tp\n", [FN]).
-verbose_zip(FN) -> io:format("adding: ~p\n", [FN]).
+verbose_zip(FN) -> io:format("adding: ~tp\n", [FN]).
%% file filter funs
all(_) -> true.
@@ -943,7 +943,7 @@ raw_short_print_info_etc(EOCD, X, Comment, Y, Acc) when is_record(EOCD, eocd) ->
raw_long_print_info_etc(EOCD, X, Comment, Y, Acc).
print_file_name(FileName) ->
- io:format("~s\n", [FileName]).
+ io:format("~ts\n", [FileName]).
%% for printing directory (tt/1)
@@ -960,14 +960,14 @@ raw_long_print_info_etc(EOCD, _, Comment, _, Acc) when is_record(EOCD, eocd) ->
Acc.
print_header(CompSize, MTime, UncompSize, FileName, FileComment) ->
- io:format("~8w ~s ~8w ~2w% ~s ~s\n",
+ io:format("~8w ~s ~8w ~2w% ~ts ~ts\n",
[CompSize, time_to_string(MTime), UncompSize,
get_percent(CompSize, UncompSize), FileName, FileComment]).
print_comment("") ->
ok;
print_comment(Comment) ->
- io:format("Archive comment: ~s\n", [Comment]).
+ io:format("Archive comment: ~ts\n", [Comment]).
get_percent(_, 0) -> 100;
get_percent(CompSize, Size) -> round(CompSize * 100 / Size).
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 29b8e28d3a..6aa09d7bd0 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -23,7 +23,6 @@ MODULES= \
dummy_via \
edlin_expand_SUITE \
epp_SUITE \
- erl_eval_helper \
erl_eval_SUITE \
erl_expand_records_SUITE \
erl_internal_SUITE \
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 606bbbcbb2..041d521514 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -1342,6 +1342,8 @@ encoding(Enc, File) ->
E = encoding_nocom(Enc, File).
encoding_com(Enc, File) ->
+ B = list_to_binary(Enc),
+ E = epp:read_encoding_from_binary(B),
ok = file:write_file(File, Enc),
{ok, Fd} = file:open(File, [read]),
E = epp:set_encoding(Fd),
@@ -1349,10 +1351,13 @@ encoding_com(Enc, File) ->
E = epp:read_encoding(File).
encoding_nocom(Enc, File) ->
+ Options = [{in_comment_only, false}],
+ B = list_to_binary(Enc),
+ E = epp:read_encoding_from_binary(B, Options),
ok = file:write_file(File, Enc),
{ok, Fd} = file:open(File, [read]),
ok = file:close(Fd),
- epp:read_encoding(File, [{in_comment_only, false}]).
+ E = epp:read_encoding(File, Options).
check(Config, Tests) ->
eval_tests(Config, fun check_test/2, Tests).
diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index 47792d1052..04d49770cb 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -1160,24 +1160,6 @@ do_funs(LFH, EFH) ->
concat(["begin F = fun(F, N) -> [", M,
":count_down(F,N) || X <-[1]] end, F(F,2) end."]),
[[[0]]], ['F'], LFH, EFH),
-
- %% Tests for a bug found by the Dialyzer - used to crash.
- case test_server:is_native(erl_eval) of
- true ->
- %% Parameterized modules are not supported by HiPE.
- ok;
- false ->
- check(fun() -> Pmod = erl_eval_helper:new(42), Pmod:add(5) end,
- "begin Pmod = erl_eval_helper:new(42), Pmod:add(5) end.",
- 47,
- ['Pmod'], LFH, EFH),
- check(fun() -> Pmod = erl_eval_helper:new(42),
- B = Pmod:add(7), B end,
- "begin Pmod = erl_eval_helper:new(42), "
- "B = Pmod:add(7), B end.",
- 49,
- ['B','Pmod'], LFH, EFH)
- end,
ok.
count_down(F, N) when N > 0 ->
diff --git a/lib/stdlib/test/erl_expand_records_SUITE.erl b/lib/stdlib/test/erl_expand_records_SUITE.erl
index e51c05a22c..94b4397a9c 100644
--- a/lib/stdlib/test/erl_expand_records_SUITE.erl
+++ b/lib/stdlib/test/erl_expand_records_SUITE.erl
@@ -35,7 +35,7 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2, end_per_testcase/2]).
--export([abstract_module/1, attributes/1, expr/1, guard/1,
+-export([attributes/1, expr/1, guard/1,
init/1, pattern/1, strict/1, update/1,
otp_5915/1, otp_7931/1, otp_5990/1,
otp_7078/1, otp_7101/1]).
@@ -55,7 +55,7 @@ end_per_testcase(_Case, _Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [abstract_module, attributes, expr, guard, init,
+ [attributes, expr, guard, init,
pattern, strict, update, {group, tickets}].
groups() ->
@@ -75,33 +75,6 @@ end_per_group(_GroupName, Config) ->
Config.
-abstract_module(doc) ->
- "Compile an abstract module.";
-abstract_module(suite) -> [];
-abstract_module(Config) when is_list(Config) ->
- %% erl_expand_records does not handle abstract modules. But anyway...
- File = filename("param.erl", Config),
- Beam = filename("param.beam", Config),
- Test = <<"-module(param, [A, B]).
-
- -export([args/1]).
-
- args(C) ->
- X = local(C),
- Z = new(A, B),
- {X, Z}.
-
- local(C) ->
- module_info(C).
- ">>,
-
- ?line ok = file:write_file(File, Test),
- ?line {ok, param} = compile:file(File, [{outdir,?privdir}]),
-
- ?line ok = file:delete(File),
- ?line ok = file:delete(Beam),
- ok.
-
attributes(doc) ->
"Import module and functions.";
attributes(suite) -> [];
@@ -196,7 +169,7 @@ guard(suite) -> [];
guard(Config) when is_list(Config) ->
File = filename("guard.erl", Config),
Beam = filename("guard.beam", Config),
- Test = <<"-module(guard, [A, B]).
+ Test = <<"-module(guard).
-export([t/1]).
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 774229fca9..564f27a512 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -2187,27 +2187,9 @@ otp_5878(Config) when is_list(Config) ->
?line [] = run(Config, Ts),
Abstr = <<"-module(lint_test, [A, B]).
-
- -export([args/1]).
-
- -record(r, {a = A, b = THIS}). % A and THIS are unbound
-
- %% param:args(compile,param:new(1,2)).
-
- args(C) ->
- X = local(C),
- Z = new(A, B),
- F = fun(THIS) -> {x, A} end, % THIS unused and shadowed
- {X, Z, THIS, F, #r{}}.
-
- local(C) ->
- module_info(C).
">>,
- ?line {error,[{5,erl_lint,{unbound_var,'A'}},
- {5,erl_lint,{unbound_var,'THIS'}}],
- [{12,erl_lint,{unused_var,'THIS'}},
- {12,erl_lint,{shadowed_var,'THIS','fun'}}]}
- = run_test2(Config, Abstr, [warn_unused_record]),
+ {errors,[{1,erl_lint,pmod_unsupported}],[]} =
+ run_test2(Config, Abstr, [warn_unused_record]),
QLC1 = <<"-module(lint_test).
-include_lib(\"stdlib/include/qlc.hrl\").
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index db416b03b0..37be61d665 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -537,29 +537,9 @@ messages(Config) when is_list(Config) ->
?line true = "\n" =:= lists:flatten(erl_pp:form({eof,0})),
ok.
-old_mnemosyne_syntax(suite) ->
- [];
old_mnemosyne_syntax(Config) when is_list(Config) ->
- %% Since we have kept the 'query' syntax and ':-' token,
+ %% Since we have kept the ':-' token,
%% better test that we can pretty print it.
- Q = {'query',6,
- {lc,6,
- {var,6,'X'},
- [{generate,6,
- {var,6,'X'},
- {call,6,{atom,6,table},[{atom,6,tab}]}},
- {match,7,
- {record_field,7,{var,7,'X'},{atom,7,foo}},
- {atom,7,bar}}]}},
- ?line "query\n"
- " [ \n" % extra space...
- " X ||\n"
- " X <- table(tab),\n"
- " X.foo = bar\n"
- " ]\n"
- "end" =
- lists:flatten(erl_pp:expr(Q)),
-
R = {rule,12,sales,2,
[{clause,12,
[{var,12,'E'},{atom,12,employee}],
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index 34e1b99abe..3f77d40a2e 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -197,7 +197,7 @@ otp_7810(Config) when is_list(Config) ->
reserved_words() ->
L = ['after', 'begin', 'case', 'try', 'cond', 'catch',
'andalso', 'orelse', 'end', 'fun', 'if', 'let', 'of',
- 'query', 'receive', 'when', 'bnot', 'not', 'div',
+ 'receive', 'when', 'bnot', 'not', 'div',
'rem', 'band', 'and', 'bor', 'bxor', 'bsl', 'bsr',
'or', 'xor'],
[begin
@@ -809,45 +809,52 @@ white_spaces() ->
unicode() ->
?line {ok,[{char,1,83},{integer,1,45}],1} =
- erl_scan:string("$\\12345"), % not unicode
+ erl_scan:string("$\\12345", 1, [{unicode,false}]), % not unicode
?line {error,{1,erl_scan,{illegal,character}},1} =
- erl_scan:string([1089]),
+ erl_scan:string([1089], 1, [{unicode,false}]),
?line {error,{{1,1},erl_scan,{illegal,character}},{1,2}} =
- erl_scan:string([1089], {1,1}),
+ erl_scan:string([1089], {1,1}, [{unicode,false}]),
?line {error,{1,erl_scan,{illegal,character}},1} =
%% ?line {error,{1,erl_scan,{illegal,atom}},1} =
- erl_scan:string("'a"++[1089]++"b'"),
+ erl_scan:string("'a"++[1089]++"b'", 1, [{unicode,false}]),
?line {error,{{1,3},erl_scan,{illegal,character}},{1,4}} =
- erl_scan:string("'a"++[1089]++"b'", {1,1}),
+ erl_scan:string("'a"++[1089]++"b'", {1,1}, [{unicode,false}]),
?line test("\"a"++[1089]++"b\""),
- ?line {ok,[{char,1,1}],1} = erl_scan:string([$$,$\\,$^,1089]),
+ ?line {ok,[{char,1,1}],1} =
+ erl_scan:string([$$,$\\,$^,1089], 1, [{unicode,false}]),
- ?line {error,{1,erl_scan,Error},1} = erl_scan:string("\"qa\x{aaa}"),
+ ?line {error,{1,erl_scan,Error},1} =
+ erl_scan:string("\"qa\x{aaa}", 1, [{unicode,false}]),
?line "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}),
+ erl_scan:string("\"qa\\x{aaa}",{1,1}, [{unicode,false}]),
?line {error,{{1,4},erl_scan,{illegal,character}},{1,11}} =
- erl_scan:string("'qa\\x{aaa}'",{1,1}),
+ erl_scan:string("'qa\\x{aaa}'",{1,1}, [{unicode,false}]),
Tags = [category, column, length, line, symbol, text],
%% Workaround. No character codes greater than 255! To be changed.
%% Note: don't remove these tests, just modify them!
- ?line {ok,[{integer,1,1089}],1} = erl_scan:string([$$,1089]),
- ?line {ok,[{integer,1,1089}],1} = erl_scan:string([$$,$\\,1089]),
+ ?line {ok,[{integer,1,1089}],1} =
+ erl_scan:string([$$,1089], 1, [{unicode,false}]),
+ ?line {ok,[{integer,1,1089}],1} =
+ erl_scan:string([$$,$\\,1089], 1, [{unicode,false}]),
Qs = "$\\x{aaa}",
- ?line {ok,[{integer,1,16#aaa}],1} = erl_scan:string(Qs),
- ?line {ok,[Q2],{1,9}} = erl_scan:string("$\\x{aaa}", {1,1}, text),
+ ?line {ok,[{integer,1,16#aaa}],1} =
+ erl_scan:string(Qs, 1, [{unicode,false}]),
+ ?line {ok,[Q2],{1,9}} =
+ erl_scan:string("$\\x{aaa}", {1,1}, [text,{unicode,false}]),
?line [{category,integer},{column,1},{length,8},
{line,1},{symbol,16#aaa},{text,Qs}] =
erl_scan:token_info(Q2),
U1 = "\"\\x{aaa}\"",
- ?line {ok,[T1,T2,T3],{1,10}} = erl_scan:string(U1, {1,1}, text),
+ ?line {ok,[T1,T2,T3],{1,10}} =
+ erl_scan:string(U1, {1,1}, [text,{unicode,false}]),
?line [{category,'['},{column,1},{length,1},{line,1},
{symbol,'['},{text,"\""}] = erl_scan:token_info(T1, Tags),
?line [{category,integer},{column,2},{length,7},
@@ -856,21 +863,23 @@ unicode() ->
?line [{category,']'},{column,9},{length,1},{line,1},
{symbol,']'},{text,"\""}] = erl_scan:token_info(T3, Tags),
?line {ok,[{'[',1},{integer,1,16#aaa},{']',1}],1} =
- erl_scan:string(U1, 1),
+ erl_scan:string(U1, 1, [{unicode,false}]),
U2 = "\"\\x41\\x{fff}\\x42\"",
?line {ok,[{'[',1},{char,1,16#41},{',',1},{integer,1,16#fff},
- {',',1},{char,1,16#42},{']',1}],1} = erl_scan:string(U2, 1),
+ {',',1},{char,1,16#42},{']',1}],1} =
+ erl_scan:string(U2, 1, [{unicode,false}]),
U3 = "\"a\n\\x{fff}\n\"",
?line {ok,[{'[',1},{char,1,$a},{',',1},{char,1,$\n},
{',',2},{integer,2,16#fff},{',',2},{char,2,$\n},
{']',3}],3} =
- erl_scan:string(U3, 1),
+ erl_scan:string(U3, 1, [{unicode,false}]),
U4 = "\"\\^\n\\x{aaa}\\^\n\"",
?line {ok,[{'[',1},{char,1,$\n},{',',2},{integer,2,16#aaa},
- {',',2},{char,2,$\n},{']',3}],3} = erl_scan:string(U4, 1),
+ {',',2},{char,2,$\n},{']',3}],3} =
+ erl_scan:string(U4, 1, [{unicode,false}]),
%% Keep these tests:
?line test(Qs),
@@ -882,17 +891,19 @@ unicode() ->
Str1 = "\"ab" ++ [1089] ++ "cd\"",
?line {ok,[{'[',1},{char,1,$a},{',',1},{char,1,$b},{',',1},
{integer,1,1089},{',',1},{char,1,$c},{',',1},
- {char,1,$d},{']',1}],1} = erl_scan:string(Str1),
+ {char,1,$d},{']',1}],1} =
+ erl_scan:string(Str1, 1, [{unicode,false}]),
?line {ok,[{'[',_},{char,_,$a},{',',_},{char,_,$b},{',',_},
{integer,_,1089},{',',_},{char,_,$c},{',',_},
- {char,_,$d},{']',_}],{1,8}} = erl_scan:string(Str1, {1,1}),
+ {char,_,$d},{']',_}],{1,8}} =
+ erl_scan:string(Str1, {1,1}, [{unicode,false}]),
?line test(Str1),
Comment = "%% "++[1089],
%% Returned a comment In R15B03:
{error,{1,erl_scan,{illegal,character}},1} =
- erl_scan:string(Comment, 1, return),
+ erl_scan:string(Comment, 1, [return,{unicode,false}]),
{error,{{1,1},erl_scan,{illegal,character}},{1,5}} =
- erl_scan:string(Comment, {1,1}, return),
+ erl_scan:string(Comment, {1,1}, [return,{unicode,false}]),
ok.
more_chars() ->
@@ -967,16 +978,16 @@ otp_10302(suite) ->
otp_10302(Config) when is_list(Config) ->
%% From unicode():
{error,{1,erl_scan,{illegal,atom}},1} =
- erl_scan:string("'a"++[1089]++"b'", 1, unicode),
+ erl_scan:string("'a"++[1089]++"b'", 1),
{error,{{1,1},erl_scan,{illegal,atom}},{1,12}} =
- erl_scan:string("'qa\\x{aaa}'",{1,1},unicode),
+ erl_scan:string("'qa\\x{aaa}'",{1,1}),
- {ok,[{char,1,1089}],1} = erl_scan:string([$$,1089], 1, unicode),
- {ok,[{char,1,1089}],1} = erl_scan:string([$$,$\\,1089],1,unicode),
+ {ok,[{char,1,1089}],1} = erl_scan:string([$$,1089], 1),
+ {ok,[{char,1,1089}],1} = erl_scan:string([$$,$\\,1089],1),
Qs = "$\\x{aaa}",
- {ok,[{char,1,2730}],1} = erl_scan:string(Qs,1,unicode),
- {ok,[Q2],{1,9}} = erl_scan:string(Qs,{1,1},[unicode,text]),
+ {ok,[{char,1,2730}],1} = erl_scan:string(Qs,1),
+ {ok,[Q2],{1,9}} = erl_scan:string(Qs,{1,1},[text]),
[{category,char},{column,1},{length,8},
{line,1},{symbol,16#aaa},{text,Qs}] =
erl_scan:token_info(Q2),
@@ -984,24 +995,24 @@ otp_10302(Config) when is_list(Config) ->
Tags = [category, column, length, line, symbol, text],
U1 = "\"\\x{aaa}\"",
- {ok,[T1],{1,10}} = erl_scan:string(U1, {1,1}, [unicode,text]),
+ {ok,[T1],{1,10}} = erl_scan:string(U1, {1,1}, [text]),
[{category,string},{column,1},{length,9},{line,1},
{symbol,[16#aaa]},{text,U1}] = erl_scan:token_info(T1, Tags),
U2 = "\"\\x41\\x{fff}\\x42\"",
- {ok,[{string,1,[65,4095,66]}],1} = erl_scan:string(U2, 1, unicode),
+ {ok,[{string,1,[65,4095,66]}],1} = erl_scan:string(U2, 1),
U3 = "\"a\n\\x{fff}\n\"",
- {ok,[{string,1,[97,10,4095,10]}],3} = erl_scan:string(U3, 1,unicode),
+ {ok,[{string,1,[97,10,4095,10]}],3} = erl_scan:string(U3, 1),
U4 = "\"\\^\n\\x{aaa}\\^\n\"",
- {ok,[{string,1,[10,2730,10]}],3} = erl_scan:string(U4, 1,[unicode]),
+ {ok,[{string,1,[10,2730,10]}],3} = erl_scan:string(U4, 1,[]),
Str1 = "\"ab" ++ [1089] ++ "cd\"",
{ok,[{string,1,[97,98,1089,99,100]}],1} =
- erl_scan:string(Str1,1,unicode),
+ erl_scan:string(Str1,1),
{ok,[{string,{1,1},[97,98,1089,99,100]}],{1,8}} =
- erl_scan:string(Str1, {1,1},unicode),
+ erl_scan:string(Str1, {1,1}),
OK1 = 16#D800-1,
OK2 = 16#DFFF+1,
@@ -1016,55 +1027,55 @@ otp_10302(Config) when is_list(Config) ->
IllegalL = [Illegal1,Illegal2,Illegal3,Illegal4],
[{ok,[{comment,1,[$%,$%,$\s,OK]}],1} =
- erl_scan:string("%% "++[OK], 1, [unicode,return]) ||
+ erl_scan:string("%% "++[OK], 1, [return]) ||
OK <- OKL],
{ok,[{comment,_,[$%,$%,$\s,OK1]}],{1,5}} =
- erl_scan:string("%% "++[OK1], {1,1}, [unicode,return]),
+ erl_scan:string("%% "++[OK1], {1,1}, [return]),
[{error,{1,erl_scan,{illegal,character}},1} =
- erl_scan:string("%% "++[Illegal], 1, [unicode,return]) ||
+ erl_scan:string("%% "++[Illegal], 1, [return]) ||
Illegal <- IllegalL],
{error,{{1,1},erl_scan,{illegal,character}},{1,5}} =
- erl_scan:string("%% "++[Illegal1], {1,1}, [unicode,return]),
+ erl_scan:string("%% "++[Illegal1], {1,1}, [return]),
- [{ok,[],1} = erl_scan:string("%% "++[OK], 1, [unicode]) ||
+ [{ok,[],1} = erl_scan:string("%% "++[OK], 1, []) ||
OK <- OKL],
- {ok,[],{1,5}} = erl_scan:string("%% "++[OK1], {1,1}, [unicode]),
+ {ok,[],{1,5}} = erl_scan:string("%% "++[OK1], {1,1}, []),
[{error,{1,erl_scan,{illegal,character}},1} =
- erl_scan:string("%% "++[Illegal], 1, [unicode]) ||
+ erl_scan:string("%% "++[Illegal], 1, []) ||
Illegal <- IllegalL],
{error,{{1,1},erl_scan,{illegal,character}},{1,5}} =
- erl_scan:string("%% "++[Illegal1], {1,1}, [unicode]),
+ erl_scan:string("%% "++[Illegal1], {1,1}, []),
[{ok,[{string,{1,1},[OK]}],{1,4}} =
- erl_scan:string("\""++[OK]++"\"",{1,1},unicode) ||
+ erl_scan:string("\""++[OK]++"\"",{1,1}) ||
OK <- OKL],
[{error,{{1,2},erl_scan,{illegal,character}},{1,3}} =
- erl_scan:string("\""++[OK]++"\"",{1,1},unicode) ||
+ erl_scan:string("\""++[OK]++"\"",{1,1}) ||
OK <- IllegalL],
[{error,{{1,1},erl_scan,{illegal,character}},{1,2}} =
- erl_scan:string([Illegal],{1,1},unicode) ||
+ erl_scan:string([Illegal],{1,1}) ||
Illegal <- IllegalL],
{ok,[{char,{1,1},OK1}],{1,3}} =
- erl_scan:string([$$,OK1],{1,1},unicode),
+ erl_scan:string([$$,OK1],{1,1}),
{error,{{1,1},erl_scan,{illegal,character}},{1,2}} =
- erl_scan:string([$$,Illegal1],{1,1},unicode),
+ erl_scan:string([$$,Illegal1],{1,1}),
{ok,[{char,{1,1},OK1}],{1,4}} =
- erl_scan:string([$$,$\\,OK1],{1,1},unicode),
+ erl_scan:string([$$,$\\,OK1],{1,1}),
{error,{{1,1},erl_scan,{illegal,character}},{1,4}} =
- erl_scan:string([$$,$\\,Illegal1],{1,1},unicode),
+ erl_scan:string([$$,$\\,Illegal1],{1,1}),
{ok,[{string,{1,1},[55295]}],{1,5}} =
- erl_scan:string("\"\\"++[OK1]++"\"",{1,1},unicode),
+ erl_scan:string("\"\\"++[OK1]++"\"",{1,1}),
{error,{{1,2},erl_scan,{illegal,character}},{1,4}} =
- erl_scan:string("\"\\"++[Illegal1]++"\"",{1,1},unicode),
+ erl_scan:string("\"\\"++[Illegal1]++"\"",{1,1}),
{ok,[{char,{1,1},OK1}],{1,10}} =
- erl_scan:string("$\\x{D7FF}",{1,1},unicode),
+ erl_scan:string("$\\x{D7FF}",{1,1}),
{error,{{1,1},erl_scan,{illegal,character}},{1,10}} =
- erl_scan:string("$\\x{D800}",{1,1},unicode),
+ erl_scan:string("$\\x{D800}",{1,1}),
%% Not erl_scan, but erl_parse.
{integer,0,1} = erl_parse:abstract(1),
diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl
index 7634c21a17..3749d594f2 100644
--- a/lib/stdlib/test/escript_SUITE.erl
+++ b/lib/stdlib/test/escript_SUITE.erl
@@ -26,6 +26,7 @@
errors/1,
strange_name/1,
emulator_flags/1,
+ emulator_flags_no_shebang/1,
module_script/1,
beam_script/1,
archive_script/1,
@@ -45,6 +46,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic, errors, strange_name, emulator_flags,
+ emulator_flags_no_shebang,
module_script, beam_script, archive_script, epp,
create_and_extract, foldl, overflow,
archive_script_file_access, unicode].
@@ -150,6 +152,21 @@ emulator_flags(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+emulator_flags_no_shebang(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ %% Need run_with_opts, to always use "escript" explicitly
+ ?line run_with_opts(Dir, "", "emulator_flags_no_shebang -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[{nostick,[]}]\n"
+ "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Pick the source code from the emulator_flags script
%% Generate a new escript with a module header
diff --git a/lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang b/lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang
new file mode 100644
index 0000000000..47d843ebe1
--- /dev/null
+++ b/lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang
@@ -0,0 +1,10 @@
+%% -*- erlang -*-
+%%! -nostick -mnesia dir a/directory -mnesia debug verbose
+
+main(MainArgs) ->
+ io:format("main:~p\n",[MainArgs]),
+ ErlArgs = init:get_arguments(),
+ io:format("nostick:~p\n",[[E || E <- ErlArgs, element(1, E) =:= nostick]]),
+ io:format("mnesia:~p\n", [[E || E <- ErlArgs, element(1, E) =:= mnesia]]),
+ io:format("ERL_FLAGS=~p\n", [os:getenv("ERL_FLAGS")]),
+ io:format("unknown:~p\n",[[E || E <- ErlArgs, element(1, E) =:= unknown]]).
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 521d7255ea..4d2b53b265 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -2051,15 +2051,15 @@ otp_10302(Suite) when is_list(Suite) ->
"<<228,...>>" = fmt("~tP", [<<"äppl">>, 2]),
Chars = lists:seq(0, 512), % just a few...
- [] = [C || C <- Chars, S <- io_lib:write_unicode_char_as_latin1(C),
+ [] = [C || C <- Chars, S <- io_lib:write_char_as_latin1(C),
not is_latin1(S)],
- L1 = [S || C <- Chars, S <- io_lib:write_unicode_char(C),
+ L1 = [S || C <- Chars, S <- io_lib:write_char(C),
not is_latin1(S)],
L1 = lists:seq(256, 512),
- [] = [C || C <- Chars, S <- io_lib:write_unicode_string_as_latin1([C]),
+ [] = [C || C <- Chars, S <- io_lib:write_string_as_latin1([C]),
not is_latin1(S)],
- L2 = [S || C <- Chars, S <- io_lib:write_unicode_string([C]),
+ L2 = [S || C <- Chars, S <- io_lib:write_string([C]),
not is_latin1(S)],
L2 = lists:seq(256, 512),
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index cac8309bd9..a9ea78a58b 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-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
@@ -6663,7 +6663,7 @@ otp_7714(Config) when is_list(Config) ->
{A,I1} <- ets:table(E1),
{B,I2} <- ets:table(E2),
I1 =:= I2],{join,merge}),
- [{a,1},{a,2},{a,3}] = qlc:e(Q),
+ [{a,1},{a,2},{a,3}] = lists:sort(qlc:e(Q)),
ets:delete(E1),
ets:delete(E2)">>],
?line run(Config, Ts).
@@ -6728,7 +6728,7 @@ otp_6674(Config) when is_list(Config) ->
[{join,lookup}]}}],
[]} = qlc:info(Q, {format,debug}),
{0,1,0,0} = join_info(Q),
- [{1.0,1},{2,2}] = qlc:e(Q),
+ [{1.0,1},{2,2}] = lists:sort(qlc:e(Q)),
ets:delete(E1),
ets:delete(E2)">>,
<<"E1 = ets:new(join, [ordered_set]),
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index a32f846bd2..f22df96697 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -28,7 +28,7 @@
refman_bit_syntax/1,
progex_bit_syntax/1, progex_records/1,
progex_lc/1, progex_funs/1,
- otp_5990/1, otp_6166/1, otp_6554/1, otp_6785/1,
+ otp_5990/1, otp_6166/1, otp_6554/1,
otp_7184/1, otp_7232/1, otp_8393/1, otp_10302/1]).
-export([ start_restricted_from_shell/1,
@@ -92,7 +92,7 @@ groups() ->
[progex_bit_syntax, progex_records, progex_lc,
progex_funs]},
{tickets, [],
- [otp_5990, otp_6166, otp_6554, otp_6785, otp_7184,
+ [otp_5990, otp_6166, otp_6554, otp_7184,
otp_7232, otp_8393, otp_10302]}].
init_per_suite(Config) ->
@@ -2543,19 +2543,6 @@ otp_6554(Config) when is_list(Config) ->
ok.
-otp_6785(doc) ->
- "OTP-6785. Parameterized modules.";
-otp_6785(suite) -> [];
-otp_6785(Config) when is_list(Config) ->
- MFile = filename:join(?config(priv_dir, Config), "parameterized.erl"),
- Contents = <<"-module(parameterized, [A]). "
- "-export([test/0]). "
- "test() -> A. ">>,
- ?line ok = compile_file(Config, MFile, Contents, []),
- ?line (parameterized:new(adsf)):test(),
- file:delete(MFile),
- ok.
-
otp_7184(doc) ->
"OTP-7184. Propagate exit signals from dying evaluator process.";
otp_7184(suite) -> [];
diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile
index dca5e78be9..c9fbad8f9a 100644
--- a/lib/syntax_tools/src/Makefile
+++ b/lib/syntax_tools/src/Makefile
@@ -26,7 +26,7 @@ EBIN = ../ebin
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
endif
-ERL_COMPILE_FLAGS += +warn_unused_vars +nowarn_shadow_vars +warn_unused_import # +warn_missing_spec +warn_untyped_record
+ERL_COMPILE_FLAGS += +nowarn_shadow_vars +warn_unused_import -Werror # +warn_missing_spec +warn_untyped_record
SOURCES=erl_syntax.erl erl_prettypr.erl erl_syntax_lib.erl \
erl_comment_scan.erl erl_recomment.erl erl_tidy.erl \
@@ -62,17 +62,17 @@ distclean: clean
realclean: clean
$(EBIN)/%.$(EMULATOR):%.erl
- erlc -W $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index 1a55a5e71c..1ffcf31134 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -813,13 +813,6 @@ lay_2(Node, Ctxt) ->
reset_prec(Ctxt)),
lay_parentheses(D, Ctxt);
- query_expr ->
- Ctxt1 = reset_prec(Ctxt),
- D = lay(erl_syntax:query_expr_body(Node), Ctxt1),
- sep([text("query"),
- nest(Ctxt1#ctxt.sub_indent, D),
- text("end")]);
-
receive_expr ->
Ctxt1 = reset_prec(Ctxt),
D1 = lay_clauses(erl_syntax:receive_expr_clauses(Node),
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index f7420030c3..bdb2b5bcd7 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -235,8 +235,6 @@
prefix_expr/2,
prefix_expr_argument/1,
prefix_expr_operator/1,
- query_expr/1,
- query_expr_body/1,
receive_expr/1,
receive_expr/3,
receive_expr_action/1,
@@ -449,7 +447,6 @@
%% <td>parentheses</td>
%% <td>prefix_expr</td>
%% </tr><tr>
-%% <td>query_expr</td>
%% <td>receive_expr</td>
%% <td>record_access</td>
%% </tr><tr>
@@ -513,7 +510,6 @@
%% @see operator/1
%% @see parentheses/1
%% @see prefix_expr/2
-%% @see query_expr/1
%% @see receive_expr/3
%% @see record_access/3
%% @see record_expr/2
@@ -578,7 +574,6 @@ type(Node) ->
{match, _, _, _} -> match_expr;
{op, _, _, _, _} -> infix_expr;
{op, _, _, _} -> prefix_expr;
- {'query', _, _} -> query_expr;
{record, _, _, _, _} -> record_expr;
{record, _, _, _} -> record_expr;
{record_field, _, _, _, _} -> record_access;
@@ -1705,11 +1700,11 @@ char_literal(Node) ->
-spec char_literal(syntaxTree(), encoding()) -> nonempty_string().
char_literal(Node, unicode) ->
- io_lib:write_unicode_char(char_value(Node));
+ io_lib:write_char(char_value(Node));
char_literal(Node, utf8) ->
- io_lib:write_unicode_char(char_value(Node));
+ io_lib:write_char(char_value(Node));
char_literal(Node, latin1) ->
- io_lib:write_unicode_char_as_latin1(char_value(Node)).
+ io_lib:write_char_as_latin1(char_value(Node)).
%% =====================================================================
@@ -1806,11 +1801,11 @@ string_literal(Node) ->
-spec string_literal(syntaxTree(), encoding()) -> nonempty_string().
string_literal(Node, utf8) ->
- io_lib:write_unicode_string(string_value(Node));
+ io_lib:write_string(string_value(Node));
string_literal(Node, unicode) ->
- io_lib:write_unicode_string(string_value(Node));
+ io_lib:write_string(string_value(Node));
string_literal(Node, latin1) ->
- io_lib:write_unicode_string_as_latin1(string_value(Node)).
+ io_lib:write_string_as_latin1(string_value(Node)).
%% =====================================================================
@@ -4097,7 +4092,6 @@ record_access(Argument, Field) ->
%% @see record_access_type/1
%% @see record_access_field/1
%% @see record_expr/3
-%% @see query_expr/1
-record(record_access, {argument :: syntaxTree(),
type :: 'none' | syntaxTree(),
@@ -4574,50 +4568,6 @@ binary_comp_body(Node) ->
%% =====================================================================
-%% @doc Creates an abstract Mnemosyne query expression. The result
-%% represents "<code>query <em>Body</em> end</code>".
-%%
-%% @see query_expr_body/1
-%% @see record_access/2
-%% @see rule/2
-
-%% type(Node) = query_expr
-%% data(Node) = syntaxTree()
-%%
-%% `erl_parse' representation:
-%%
-%% {'query', Pos, Body}
-%%
-%% Body = erl_parse()
-
--spec query_expr(syntaxTree()) -> syntaxTree().
-
-query_expr(Body) ->
- tree(query_expr, Body).
-
-revert_query_expr(Node) ->
- Pos = get_pos(Node),
- Body = list_comp_body(Node),
- {'query', Pos, Body}.
-
-
-%% =====================================================================
-%% @doc Returns the body subtree of a `query_expr' node.
-%%
-%% @see query_expr/1
-
--spec query_expr_body(syntaxTree()) -> syntaxTree().
-
-query_expr_body(Node) ->
- case unwrap(Node) of
- {'query', _, Body} ->
- Body;
- Node1 ->
- data(Node1)
- end.
-
-
-%% =====================================================================
%% @doc Creates an abstract Mnemosyne rule. If `Clauses' is
%% `[C1, ..., Cn]', the results represents
%% "<code><em>Name</em> <em>C1</em>; ...; <em>Name</em>
@@ -6041,8 +5991,6 @@ revert_root(Node) ->
revert_parentheses(Node);
prefix_expr ->
revert_prefix_expr(Node);
- query_expr ->
- revert_query_expr(Node);
receive_expr ->
revert_receive_expr(Node);
record_access ->
@@ -6283,8 +6231,6 @@ subtrees(T) ->
prefix_expr ->
[[prefix_expr_operator(T)],
[prefix_expr_argument(T)]];
- query_expr ->
- [[query_expr_body(T)]];
receive_expr ->
case receive_expr_timeout(T) of
none ->
@@ -6413,7 +6359,6 @@ make_tree(match_expr, [[P], [E]]) -> match_expr(P, E);
make_tree(module_qualifier, [[M], [N]]) -> module_qualifier(M, N);
make_tree(parentheses, [[E]]) -> parentheses(E);
make_tree(prefix_expr, [[F], [A]]) -> prefix_expr(F, A);
-make_tree(query_expr, [[B]]) -> query_expr(B);
make_tree(receive_expr, [C]) -> receive_expr(C);
make_tree(receive_expr, [C, [E], A]) -> receive_expr(C, E, A);
make_tree(record_access, [[E], [F]]) ->
diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile
index 3261936472..7251acd20b 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -91,7 +91,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I../include
+ERL_COMPILE_FLAGS += -I../include -Werror
# ----------------------------------------------------
# Targets
@@ -112,10 +112,10 @@ configure: configure.in
# Special Build Targets
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl
index d9a699ca9f..c0200ab67c 100644
--- a/lib/test_server/src/ts_lib.erl
+++ b/lib/test_server/src/ts_lib.erl
@@ -143,7 +143,6 @@ suite_order(inets) -> 28;
suite_order(asn1) -> 30;
suite_order(os_mon) -> 32;
suite_order(snmp) -> 38;
-suite_order(mnemosyne) -> 40;
suite_order(mnesia_session) -> 42;
suite_order(mnesia) -> 44;
suite_order(system) -> 999; %% IMPORTANT: system SHOULD always be last!
diff --git a/lib/test_server/test/erl2html2_SUITE.erl b/lib/test_server/test/erl2html2_SUITE.erl
index 96175413a1..37c2b74d8e 100644
--- a/lib/test_server/test/erl2html2_SUITE.erl
+++ b/lib/test_server/test/erl2html2_SUITE.erl
@@ -1,11 +1,21 @@
-%%%-------------------------------------------------------------------
-%%% @author Siri Hansen <[email protected]>
-%%% @copyright (C) 2012, Siri Hansen
-%%% @doc
-%%%
-%%% @end
-%%% Created : 15 Nov 2012 by Siri Hansen <[email protected]>
-%%%-------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(erl2html2_SUITE).
-compile(export_all).
diff --git a/lib/toolbar/src/Makefile b/lib/toolbar/src/Makefile
index 102970a59a..a24846976b 100644
--- a/lib/toolbar/src/Makefile
+++ b/lib/toolbar/src/Makefile
@@ -71,10 +71,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in
index 0382d3228d..aea5686ae9 100644
--- a/lib/tools/c_src/Makefile.in
+++ b/lib/tools/c_src/Makefile.in
@@ -17,6 +17,7 @@
# %CopyrightEnd%
#
+include $(ERL_TOP)/make/output.mk
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/erts/include/internal/$(TARGET)/ethread.mk
@@ -150,7 +151,7 @@ _create_dirs := $(shell mkdir -p $(CREATE_DIRS))
all: $(PROGS) $(DRIVERS)
$(ERTS_LIB):
- cd $(ERL_TOP)/erts/lib_src && $(MAKE) $(TYPE)
+ $(make_verbose)cd $(ERL_TOP)/erts/lib_src && $(MAKE) $(TYPE)
docs:
@@ -167,7 +168,7 @@ clean:
#
$(EMEM_OBJ_DIR)/%.o: %.c
- $(CC) $(EMEM_CFLAGS) -o $@ -c $<
+ $(V_CC) $(EMEM_CFLAGS) -o $@ -c $<
#
# Driver targets
@@ -178,7 +179,7 @@ $(EMEM_OBJ_DIR)/%.o: %.c
#
$(BIN_DIR)/emem$(TYPEMARKER)@EXEEXT@: $(EMEM_OBJS) $(ERTS_LIB)
- $(PRE_LD) $(LD) $(EMEM_LDFLAGS) -o $@ $(EMEM_OBJS) $(EMEM_LIBS)
+ $(ld_verbose)$(PRE_LD) $(LD) $(EMEM_LDFLAGS) -o $@ $(EMEM_OBJS) $(EMEM_LIBS)
#
# Release targets
@@ -221,7 +222,8 @@ SED_DEPEND=sed '$(SED_REPL_OBJ_DIR);$(SED_REPL_TT_DIR);$(SED_REPL_TARGET);$(SED_
DEPEND_MK=depend.mk
dep depend:
- @echo "Generating dependency file $(DEPEND_MK)..."
+ [ $(v_p) == 0 ] && echo " GEN "$(DEPEND_MK)
+ $(V_colon)@echo "Generating dependency file $(DEPEND_MK)..."
@echo "# Generated dependency rules." > $(DEPEND_MK);
@echo "# Do *not* edit this file; instead, run 'make depend'." \
>> $(DEPEND_MK);
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 2967acf310..21615f4cd9 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -723,9 +723,6 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defvar erlang-int-bifs
'("abs"
- "adler32"
- "adler32_combine"
- "alive"
"apply"
"atom_to_binary"
"atom_to_list"
@@ -733,19 +730,20 @@ resulting regexp is surrounded by \\_< and \\_>."
"binary_to_existing_atom"
"binary_to_list"
"binary_to_term"
+ "binary_part"
"bit_size"
+ "bitsize"
"bitstring_to_list"
"byte_size"
+ "check_old_code"
"check_process_code"
- "contact_binary"
- "crc32"
- "crc32_combine"
"date"
- "decode_packet"
"delete_module"
+ "demonitor"
"disconnect_node"
"element"
"erase"
+ "error"
"exit"
"float"
"float_to_list"
@@ -756,7 +754,6 @@ resulting regexp is surrounded by \\_< and \\_>."
"halt"
"hd"
"integer_to_list"
- "internal_bif"
"iolist_size"
"iolist_to_binary"
"is_alive"
@@ -787,13 +784,13 @@ resulting regexp is surrounded by \\_< and \\_>."
"list_to_tuple"
"load_module"
"make_ref"
+ "max"
+ "min"
"module_loaded"
+ "monitor"
"monitor_node"
"node"
- "node_link"
- "node_unlink"
"nodes"
- "notalive"
"now"
"open_port"
"pid_to_list"
@@ -837,48 +834,102 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defvar erlang-ext-bifs
- '("append_element"
+ '("adler32"
+ "adler32_combine"
+ "alloc_info"
+ "alloc_sizes"
+ "append"
+ "append_element"
+ "await_proc_exit"
+ "await_sched_wall_time_modifications"
+ "bitstr_to_list"
"bump_reductions"
+ "call_on_load_function"
"cancel_timer"
- "demonitor"
+ "crasher"
+ "crc32"
+ "crc32_combine"
+ "decode_packet"
+ "delay_trap"
+ "delete_element"
+ "dexit"
+ "dgroup_leader"
"display"
+ "display_nl"
+ "display_string"
+ "dist_exit"
+ "dlink"
+ "dmonitor_node"
+ "dmonitor_p"
+ "dsend"
+ "dt_append_vm_tag_data"
+ "dt_get_tag"
+ "dt_get_tag_data"
+ "dt_prepend_vm_tag_data"
+ "dt_put_tag"
+ "dt_restore_tag"
+ "dt_spread_tag"
+ "dunlink"
+ "external_size"
+ "finish_after_on_load"
+ "finish_loading"
+ "flush_monitor_message"
+ "format_cpu_topology"
"fun_info"
"fun_to_list"
"function_exported"
+ "garbage_collect_message_area"
+ "gather_sched_wall_time_result"
"get_cookie"
+ "get_module_info"
"get_stacktrace"
"hash"
- "integer_to_list"
+ "hibernate"
+ "insert_element"
"is_builtin"
- "list_to_integer"
+ "list_to_bitstr"
+ "load_nif"
"loaded"
"localtime"
"localtime_to_universaltime"
+ "make_fun"
"make_tuple"
- "max"
+ "match_spec_test"
"md5"
"md5_final"
"md5_init"
"md5_update"
"memory"
- "min"
- "monitor"
+ "module_info"
"monitor_node"
+ "nif_error"
"phash"
"phash2"
"port_call"
+ "port_get_data"
"port_info"
+ "port_set_data"
"port_to_list"
"ports"
+ "posixtime_to_universaltime"
+ "prepare_loading"
"process_display"
+ "raise"
"read_timer"
"ref_to_list"
"resume_process"
"send"
"send_after"
"send_nosuspend"
+ "seq_trace"
+ "seq_trace_info"
+ "seq_trace_print"
"set_cookie"
+ "set_cpu_topology"
+ "setnode"
+ "spawn_opt"
"start_timer"
+ "subtract"
"suspend_process"
"system_flag"
"system_info"
@@ -890,6 +941,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"trace_pattern"
"universaltime"
"universaltime_to_localtime"
+ "universaltime_to_posixtime"
"yield")
"Erlang built-in functions (BIFs) that needs erlang: prefix"))
@@ -1518,9 +1570,9 @@ Other commands:
. (("\\(?:^\\|[^$]\\)\"\\(?:[^\"\n]\\|\\\\\"\\)*\\(\\$\\)\"" 1 "w")
;; Likewise for atoms
("\\(?:^\\|[^$]\\)'\\(?:[^'\n]\\|\\\\'\\)*\\(\\$\\)'" 1 "w")
- ;; And the dollar sign in $\" escapes two characters, not
- ;; just one.
- ("\\(\\$\\)\\\\\\\"" 1 "'"))))))
+ ;; And the dollar sign in $\" or $\' escapes two
+ ;; characters, not just one.
+ ("\\(\\$\\)\\\\[\"']" 1 "'"))))))
diff --git a/lib/tools/src/Makefile b/lib/tools/src/Makefile
index abe1389771..f11589d82b 100644
--- a/lib/tools/src/Makefile
+++ b/lib/tools/src/Makefile
@@ -75,7 +75,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS += -Werror
# ----------------------------------------------------
# Targets
@@ -94,10 +94,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index ab29d156aa..468225dc13 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2001-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
@@ -824,7 +824,7 @@ main_process_loop(State) ->
main_process_loop(State);
get_status ->
- io:format("~p~n",[State]),
+ io:format("~tp~n",[State]),
main_process_loop(State)
end.
@@ -889,7 +889,7 @@ remote_process_loop(State) ->
remote_process_loop(State);
get_status ->
- io:format("~p~n",[State]),
+ io:format("~tp~n",[State]),
remote_process_loop(State);
M ->
@@ -1007,7 +1007,7 @@ do_start_nodes(Nodes, State) ->
erlang:monitor(process,{?SERVER,Node}),
[Node|Acc];
Error ->
- io:format("Could not start cover on ~w: ~p\n",
+ io:format("Could not start cover on ~w: ~tp\n",
[Node,Error]),
Acc
end
@@ -1223,7 +1223,7 @@ do_get_all_importfiles([],Acc) ->
imported_info(Text,Module,Imported) ->
case lists:keysearch(Module,1,Imported) of
{value,{Module,_File,ImportFiles}} ->
- io:format("~s includes data from imported files\n~p\n",
+ io:format("~ts includes data from imported files\n~tp\n",
[Text,ImportFiles]);
false ->
ok
@@ -1237,7 +1237,7 @@ add_imported(Module, File, ImportFile, Imported) ->
add_imported(M, F1, ImportFile, [{M,_F2,ImportFiles}|Imported], Acc) ->
case lists:member(ImportFile,ImportFiles) of
true ->
- io:fwrite("WARNING: Module ~w already imported from ~p~n"
+ io:fwrite("WARNING: Module ~w already imported from ~tp~n"
"Not importing again!~n",[M,ImportFile]),
dont_import;
false ->
@@ -1255,7 +1255,7 @@ remove_imported(Module,Imported) ->
case lists:keysearch(Module,1,Imported) of
{value,{Module,_,ImportFiles}} ->
io:fwrite("WARNING: Deleting data for module ~w imported from~n"
- "~p~n",[Module,ImportFiles]),
+ "~tp~n",[Module,ImportFiles]),
lists:keydelete(Module,1,Imported);
false ->
Imported
@@ -1519,12 +1519,6 @@ aux_var(Vars, N) ->
%% This way we will be able to exclude functions defined in include files.
munge({function,0,module_info,_Arity,_Clauses},_Vars,_MainFile,_Switch) ->
ignore; % module_info will be added again when the forms are recompiled
-munge(Form={function,_,'MNEMOSYNE QUERY',_,_},Vars,_MainFile,Switch) ->
- {Form,Vars,Switch}; % No bumps in Mnemosyne code.
-munge(Form={function,_,'MNEMOSYNE RULE',_,_},Vars,_MainFile,Switch) ->
- {Form,Vars,Switch};
-munge(Form={function,_,'MNEMOSYNE RECFUNDEF',_,_},Vars,_MainFile,Switch) ->
- {Form,Vars,Switch};
munge({function,Line,Function,Arity,Clauses},Vars,_MainFile,on) ->
Vars2 = Vars#vars{function=Function,
arity=Arity,
diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl
index 70d62307c8..0694a47318 100644
--- a/lib/tools/src/lcnt.erl
+++ b/lib/tools/src/lcnt.erl
@@ -272,7 +272,7 @@ handle_call({locations, InOpts}, _From, #state{ locks = Locks } = State) when is
Opts = options(InOpts, Default),
Printables = filter_print([#print{
name = string_names(Names),
- entry = term2string("~p:~p", [Stats#stats.file, Stats#stats.line]),
+ entry = term2string("~tp:~p", [Stats#stats.file, Stats#stats.line]),
colls = Stats#stats.colls,
tries = Stats#stats.tries,
cr = percent(Stats#stats.colls, Stats#stats.tries),
@@ -567,7 +567,7 @@ stats2print(Stats, Duration) ->
lists:map(fun
(S) ->
#print{
- entry = term2string("~p:~p", [S#stats.file, S#stats.line]),
+ 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),
@@ -798,20 +798,20 @@ options1([{Key, Value}|Opts], Defaults) ->
%%% AUX STRING FORMATTING
-print(String) -> io:format("~s~n", [String]).
+print(String) -> io:format("~ts~n", [String]).
kv(Key, Value) -> kv(Key, Value, 20).
kv(Key, Value, Offset) -> term2string(term2string("~~~ps : ~~s", [Offset]),[Key, Value]).
s(T) when is_float(T) -> term2string("~.4f", [T]);
-s(T) when is_list(T) -> term2string("~s", [T]);
+s(T) when is_list(T) -> term2string("~ts", [T]);
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([{format, Format, S} | Ss], Out) -> strings(Ss, Out ++ term2string(Format, [S]));
-strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~s", [S])).
+strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~ts", [S])).
term2string({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) -> term2string("~p:~p/~p", [M,F,A]);
diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl
index 5cc8d47faa..3b4f7fcc36 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.erl
@@ -90,7 +90,7 @@ read_emakefile(Emakefile,Opts) ->
Mods = [filename:rootname(F) || F <- filelib:wildcard("*.erl")],
[{Mods, Opts}];
{error,Other} ->
- io:format("make: Trouble reading 'Emakefile':~n~p~n",[Other]),
+ io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]),
error
end.
@@ -145,7 +145,7 @@ get_opts_from_emakefile(Mods,Emakefile,Opts) ->
{error,enoent} ->
[{Mods, Opts}];
{error,Other} ->
- io:format("make: Trouble reading 'Emakefile':~n~p~n",[Other]),
+ io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]),
error
end.
@@ -253,15 +253,15 @@ include_opt([]) ->
%% Where load can be netload | load | noload
recompile(File, true, _Load, _Opts) ->
- io:format("Out of date: ~s\n",[File]);
+ io:format("Out of date: ~ts\n",[File]);
recompile(File, false, noload, Opts) ->
- io:format("Recompile: ~s\n",[File]),
+ io:format("Recompile: ~ts\n",[File]),
compile:file(File, [report_errors, report_warnings, error_summary |Opts]);
recompile(File, false, load, Opts) ->
- io:format("Recompile: ~s\n",[File]),
+ io:format("Recompile: ~ts\n",[File]),
c:c(File, Opts);
recompile(File, false, netload, Opts) ->
- io:format("Recompile: ~s\n",[File]),
+ io:format("Recompile: ~ts\n",[File]),
c:nc(File, Opts).
exists(File) ->
diff --git a/lib/tools/src/tags.erl b/lib/tools/src/tags.erl
index e740d38c91..6ce35e4f05 100644
--- a/lib/tools/src/tags.erl
+++ b/lib/tools/src/tags.erl
@@ -157,7 +157,7 @@ files_loop([F | Fs], Os) ->
ok ->
ok;
error ->
- %% io:format("Could not open ~s~n", [F]),
+ %% io:format("Could not open ~ts~n", [F]),
error
end,
files_loop(Fs, Os).
@@ -315,11 +315,11 @@ close_out(Os) ->
pfnote(Str, {LineNo, CharNo}) ->
- io_lib:format("~s\177~w,~w~n", [flatrev(Str), LineNo, CharNo]).
+ io_lib:format("~ts\177~w,~w~n", [flatrev(Str), LineNo, CharNo]).
genout(Os, Name, Entries) ->
- io:format(Os, "\^l~n~s,~w~n", [Name, reclength(Entries)]),
+ io:format(Os, "\^l~n~ts,~w~n", [Name, reclength(Entries)]),
io:put_chars(Os, lists:reverse(Entries)).
diff --git a/lib/tools/src/xref.erl b/lib/tools/src/xref.erl
index 0693bec019..912c320857 100644
--- a/lib/tools/src/xref.erl
+++ b/lib/tools/src/xref.erl
@@ -297,7 +297,7 @@ set_default(Name, Option, Value) ->
format_error({error, Module, Error}) ->
Module:format_error(Error);
format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
%%%----------------------------------------------------------------------
%%%Callback functions from gen_server
diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl
index 93f0e9c0c8..af063f3971 100644
--- a/lib/tools/src/xref_base.erl
+++ b/lib/tools/src/xref_base.erl
@@ -480,43 +480,43 @@ set_default(State, Options) ->
format_error({error, Module, Error}) ->
Module:format_error(Error);
format_error({invalid_options, Options}) ->
- io_lib:format("Unknown option(s) or invalid option value(s): ~p~n",
+ io_lib:format("Unknown option(s) or invalid option value(s): ~tp~n",
[Options]);
format_error({invalid_filename, Term}) ->
- io_lib:format("A file name (a string) was expected: ~p~n", [Term]);
+ io_lib:format("A file name (a string) was expected: ~tp~n", [Term]);
format_error({no_debug_info, FileName}) ->
- io_lib:format("The BEAM file ~p has no debug info~n", [FileName]);
+ io_lib:format("The BEAM file ~tp has no debug info~n", [FileName]);
format_error({invalid_path, Term}) ->
- io_lib:format("A path (a list of strings) was expected: ~p~n", [Term]);
+ io_lib:format("A path (a list of strings) was expected: ~tp~n", [Term]);
format_error({invalid_query, Term}) ->
- io_lib:format("A query (a string or an atom) was expected: ~p~n", [Term]);
+ io_lib:format("A query (a string or an atom) was expected: ~tp~n", [Term]);
format_error({not_user_variable, Variable}) ->
- io_lib:format("~p is not a user variable~n", [Variable]);
+ io_lib:format("~tp is not a user variable~n", [Variable]);
format_error({unknown_analysis, Term}) ->
- io_lib:format("~p is not a predefined analysis~n", [Term]);
+ io_lib:format("~tp is not a predefined analysis~n", [Term]);
format_error({module_mismatch, Module, ReadModule}) ->
- io_lib:format("Name of read module ~p does not match analyzed module ~p~n",
+ io_lib:format("Name of read module ~tp does not match analyzed module ~tp~n",
[ReadModule, Module]);
format_error({release_clash, {Release, Dir, OldDir}}) ->
- io_lib:format("The release ~p read from ~p clashes with release "
- "already read from ~p~n", [Release, Dir, OldDir]);
+ io_lib:format("The release ~tp read from ~tp clashes with release "
+ "already read from ~tp~n", [Release, Dir, OldDir]);
format_error({application_clash, {Application, Dir, OldDir}}) ->
- io_lib:format("The application ~p read from ~p clashes with application "
- "already read from ~p~n", [Application, Dir, OldDir]);
+ io_lib:format("The application ~tp read from ~tp clashes with application "
+ "already read from ~tp~n", [Application, Dir, OldDir]);
format_error({module_clash, {Module, Dir, OldDir}}) ->
- io_lib:format("The module ~p read from ~p clashes with module "
- "already read from ~p~n", [Module, Dir, OldDir]);
+ io_lib:format("The module ~tp read from ~tp clashes with module "
+ "already read from ~tp~n", [Module, Dir, OldDir]);
format_error({no_such_release, Name}) ->
- io_lib:format("There is no analyzed release ~p~n", [Name]);
+ io_lib:format("There is no analyzed release ~tp~n", [Name]);
format_error({no_such_application, Name}) ->
- io_lib:format("There is no analyzed application ~p~n", [Name]);
+ io_lib:format("There is no analyzed application ~tp~n", [Name]);
format_error({no_such_module, Name}) ->
- io_lib:format("There is no analyzed module ~p~n", [Name]);
+ io_lib:format("There is no analyzed module ~tp~n", [Name]);
format_error({no_such_info, Term}) ->
- io_lib:format("~p is not one of 'modules', 'applications', "
+ io_lib:format("~tp is not one of 'modules', 'applications', "
"'releases' and 'libraries'~n", [Term]);
format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
%%
%% Local functions
@@ -1506,7 +1506,7 @@ do_variables(State) ->
_Else -> {[Name | P], U}
end;
({{tmp, V}, _}, A) ->
- io:format("Bug in ~p: temporary ~p~n", [?MODULE, V]), A;
+ io:format("Bug in ~tp: temporary ~tp~n", [?MODULE, V]), A;
(_V, A) -> A
end,
{U,P} = foldl(Fun, {[],[]}, dict:to_list(State#xref.variables)),
@@ -1766,23 +1766,23 @@ tpack(T, I, L) ->
message(true, What, Arg) ->
case What of
reading_beam ->
- io:format("~s... ", Arg);
+ io:format("~ts... ", Arg);
skipped_beam ->
io:format("skipped (no debug information)~n", Arg);
no_debug_info ->
- io:format("Skipping ~s (no debug information)~n", Arg);
+ io:format("Skipping ~ts (no debug information)~n", Arg);
unresolved_summary1 ->
- io:format("~p: 1 unresolved call~n", Arg);
+ io:format("~tp: 1 unresolved call~n", Arg);
unresolved_summary ->
- io:format("~p: ~p unresolved calls~n", Arg);
+ io:format("~tp: ~tp unresolved calls~n", Arg);
jam ->
- io:format("Skipping ~s (probably JAM file)~n", [Arg]);
+ io:format("Skipping ~ts (probably JAM file)~n", [Arg]);
unreadable ->
- io:format("Skipping ~s (unreadable)~n", [Arg]);
+ io:format("Skipping ~ts (unreadable)~n", [Arg]);
xref_attr ->
- io:format("~s: Skipping 'xref' attribute ~w~n", Arg);
+ io:format("~ts: Skipping 'xref' attribute ~w~n", Arg);
depr_attr ->
- io:format("~s: Skipping 'deprecated' attribute ~w~n", Arg);
+ io:format("~ts: Skipping 'deprecated' attribute ~w~n", Arg);
lib_search ->
io:format("Scanning library path for BEAM files... ", []);
lib_check ->
@@ -1794,7 +1794,7 @@ message(true, What, Arg) ->
error ->
io:format("error~n", Arg);
Else ->
- io:format("~p~n", [{Else,Arg}])
+ io:format("~tp~n", [{Else,Arg}])
end;
message(_, _, _) ->
true.
diff --git a/lib/tools/src/xref_compiler.erl b/lib/tools/src/xref_compiler.erl
index 22312c6754..303132d53f 100644
--- a/lib/tools/src/xref_compiler.erl
+++ b/lib/tools/src/xref_compiler.erl
@@ -83,19 +83,19 @@ format_error({error, Module, Error}) ->
format_error({parse_error, Line, Error}) ->
format_parse_error(Error, format_line(Line));
format_error({variable_reassigned, Expr}) ->
- io_lib:format("Variable assigned more than once: ~s~n", [Expr]);
+ io_lib:format("Variable assigned more than once: ~ts~n", [Expr]);
format_error({unknown_variable, Name}) ->
- io_lib:format("Variable ~p used before set~n", [Name]);
+ io_lib:format("Variable ~tp used before set~n", [Name]);
format_error({type_error, Expr}) ->
io_lib:format("Operator applied to argument(s) of different or "
- "invalid type(s): ~s~n", [Expr]);
+ "invalid type(s): ~ts~n", [Expr]);
format_error({type_mismatch, Expr1, Expr2}) ->
- io_lib:format("Constants of different types: ~s, ~s~n",
+ io_lib:format("Constants of different types: ~ts, ~ts~n",
[Expr1, Expr2]);
format_error({unknown_constant, Constant}) ->
- io_lib:format("Unknown constant ~s~n", [Constant]);
+ io_lib:format("Unknown constant ~ts~n", [Constant]);
format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
%%
%% Local functions
@@ -908,21 +908,21 @@ fetch_value(V, D) ->
Value.
format_parse_error(["invalid_regexp", String, Error], Line) ->
- io_lib:format("Invalid regular expression \"~s\"~s: ~s~n",
+ io_lib:format("Invalid regular expression \"~ts\"~s: ~ts~n",
[String, Line, lists:flatten(Error)]);
format_parse_error(["invalid_regexp_variable", Var], Line) ->
- io_lib:format("Invalid wildcard variable ~p~s "
+ io_lib:format("Invalid wildcard variable ~tp~s "
"(only '_' is allowed)~n", [Var, Line]);
format_parse_error(["missing_type", Expr], Line) ->
- io_lib:format("Missing type of regular expression ~s~s~n",
+ io_lib:format("Missing type of regular expression ~ts~s~n",
[Expr, Line]);
format_parse_error(["type_mismatch", Expr], Line) ->
- io_lib:format("Type does not match structure of constant~s: ~s~n",
+ io_lib:format("Type does not match structure of constant~s: ~ts~n",
[Line, Expr]);
format_parse_error(["invalid_operator", Op], Line) ->
- io_lib:format("Invalid operator ~p~s~n", [Op, Line]);
+ io_lib:format("Invalid operator ~tp~s~n", [Op, Line]);
format_parse_error(Error, Line) ->
- io_lib:format("Parse error~s: ~s~n", [Line, lists:flatten(Error)]).
+ io_lib:format("Parse error~s: ~ts~n", [Line, lists:flatten(Error)]).
format_line(-1) ->
" at end of string";
diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl
index 92f0c45c7b..2fcc2c503c 100644
--- a/lib/tools/src/xref_reader.erl
+++ b/lib/tools/src/xref_reader.erl
@@ -80,12 +80,6 @@ form({attribute, Line, xref, Calls}, S) -> % experimental
attr(Calls, Line, M, Fun, L, X, B, S);
form({attribute, _Line, _Attr, _Val}, S) ->
S;
-form({function, 0, 'MNEMOSYNE RULE', 1, _Clauses}, S) ->
- S;
-form({function, 0, 'MNEMOSYNE QUERY', 2, _Clauses}, S) ->
- S;
-form({function, 0, 'MNEMOSYNE RECFUNDEF', 1, _Clauses}, S) ->
- S;
form({function, 0, module_info, 0, _Clauses}, S) ->
S;
form({function, 0, module_info, 1, _Clauses}, S) ->
@@ -331,9 +325,6 @@ handle_call(Locality, Module, Name, Arity, Line, S) ->
handle_call(Locality, To, Line, S, false)
end.
-handle_call(_Locality, {_, 'MNEMOSYNE RULE',1}, _Line, S, _) -> S;
-handle_call(_Locality, {_, 'MNEMOSYNE QUERY', 2}, _Line, S, _) -> S;
-handle_call(_Locality, {_, 'MNEMOSYNE RECFUNDEF',1}, _Line, S, _) -> S;
handle_call(Locality, To0, Line, S, IsUnres) ->
From = S#xrefr.function,
To = adjust_arity(S, To0),
diff --git a/lib/tools/src/xref_utils.erl b/lib/tools/src/xref_utils.erl
index 680563e9df..184b81402d 100644
--- a/lib/tools/src/xref_utils.erl
+++ b/lib/tools/src/xref_utils.erl
@@ -517,16 +517,16 @@ subprocess(Fun, Opts) ->
format_error({error, Module, Error}) ->
Module:format_error(Error);
format_error({file_error, FileName, Reason}) ->
- io_lib:format("~s: ~p~n", [FileName, file:format_error(Reason)]);
+ io_lib:format("~ts: ~tp~n", [FileName, file:format_error(Reason)]);
format_error({unrecognized_file, FileName}) ->
- io_lib:format("~p is neither a regular file nor a directory~n",
+ io_lib:format("~tp is neither a regular file nor a directory~n",
[FileName]);
format_error({no_such_module, Module}) ->
- io_lib:format("Cannot find module ~p using the code path~n", [Module]);
+ io_lib:format("Cannot find module ~tp using the code path~n", [Module]);
format_error({interpreted, Module}) ->
- io_lib:format("Cannot use BEAM code of interpreted module ~p~n", [Module]);
+ io_lib:format("Cannot use BEAM code of interpreted module ~tp~n", [Module]);
format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
%%
%% Local functions
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
index 86c81217b6..484cfdf53f 100644
--- a/lib/tools/test/Makefile
+++ b/lib/tools/test/Makefile
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
MODULES = \
cover_SUITE \
eprof_SUITE \
+ emacs_SUITE \
emem_SUITE \
fprof_SUITE \
cprof_SUITE \
diff --git a/lib/tools/test/emacs_SUITE.erl b/lib/tools/test/emacs_SUITE.erl
new file mode 100644
index 0000000000..369b8c3ab5
--- /dev/null
+++ b/lib/tools/test/emacs_SUITE.erl
@@ -0,0 +1,76 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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%
+%%
+-module(emacs_SUITE).
+
+%%-define(line_trace, 1).
+
+-export([all/0, init_per_testcase/2, end_per_testcase/2]).
+
+-export([bif_highlight/1]).
+
+all() ->
+ [bif_highlight].
+
+init_per_testcase(_Case, Config) ->
+ ErlangEl = filename:join([code:lib_dir(tools),"emacs","erlang.el"]),
+ case file:read_file_info(ErlangEl) of
+ {ok, _} ->
+ [{el, ErlangEl}|Config];
+ _ ->
+ {skip, "Could not find erlang.el"}
+ end.
+
+end_per_testcase(_Case, _Config) ->
+ ok.
+
+bif_highlight(Config) ->
+ ErlangEl = proplists:get_value(el,Config),
+ {ok, Bin} = file:read_file(ErlangEl),
+
+ %% All auto-imported bifs
+ IntBifs = lists:usort(
+ [F || {F,A} <- erlang:module_info(exports),
+ erl_internal:bif(F,A)]),
+
+ %% all bif which need erlang: prefix and are not operands
+ ExtBifs = lists:usort(
+ [F || {F,A} <- erlang:module_info(exports),
+ not erl_internal:bif(F,A) andalso
+ not is_atom(catch erl_internal:op_type(F,A))]),
+
+ check_bif_highlight(Bin, <<"erlang-int-bifs">>, IntBifs),
+ check_bif_highlight(Bin, <<"erlang-ext-bifs">>, ExtBifs).
+
+
+check_bif_highlight(Bin, Tag, Compare) ->
+ [_H,IntMatch,_T] =
+ re:split(Bin,<<"defvar ",Tag/binary,
+ "[^(]*\\(([^)]*)">>,[]),
+ EmacsIntBifs = [list_to_atom(S) ||
+ S <- string:tokens(binary_to_list(IntMatch)," '\"\n")],
+
+ ct:log("Emacs ~p",[EmacsIntBifs]),
+ ct:log("Int ~p",[Compare]),
+
+ ct:log("Diff1 ~p",[Compare -- EmacsIntBifs]),
+ ct:log("Diff2 ~p",[EmacsIntBifs -- Compare]),
+ [] = Compare -- EmacsIntBifs,
+ [] = EmacsIntBifs -- Compare.
+
+
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index cf49526156..dc06678b8e 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -47,7 +47,7 @@
-export([
add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1,
replace/1, update/1, deprecated/1, trycatch/1,
- abstract_modules/1, fun_mfa/1, fun_mfa_r14/1,
+ fun_mfa/1, fun_mfa_r14/1,
fun_mfa_vars/1, qlc/1]).
-export([
@@ -83,7 +83,7 @@ groups() ->
modules]},
{files, [],
[add, default, info, lib, read, read2, remove, replace,
- update, deprecated, trycatch, abstract_modules, fun_mfa,
+ update, deprecated, trycatch, fun_mfa,
fun_mfa_r14, fun_mfa_vars, qlc]},
{analyses, [],
[analyze, basic, md, q, variables, unused_locals]},
@@ -1669,64 +1669,6 @@ trycatch(Conf) when is_list(Conf) ->
ok.
-abstract_modules(suite) -> [];
-abstract_modules(doc) -> ["OTP-5520: Abstract (parameterized) modules."];
-abstract_modules(Conf) when is_list(Conf) ->
- Dir = ?copydir,
- File = fname(Dir, "absmod.erl"),
- MFile = fname(Dir, "absmod"),
- Beam = fname(Dir, "absmod.beam"),
- Test = <<"-module(param, [A, B]).
-
- -export([args/1]).
-
- args(C) ->
- X = local(C),
- Y = THIS:new(), % undef
- Z = new(A, B),
- {X, Y, Z}.
-
- local(C) ->
- module_info(C).
- ">>,
-
- ?line ok = file:write_file(File, Test),
-
- %% The compiler will no longer allow us to have a mismatch between
- %% the module name and the output file, so we must use a trick.
- ?line {ok, param, BeamCode} = compile:file(File, [binary,debug_info]),
- ?line ok = file:write_file(Beam, BeamCode),
-
- ?line {ok, _} = xref:start(s),
- ?line {ok, param} = xref:add_module(s, MFile, {warnings,false}),
- A = param,
- ?line {ok, [{{{A,args,1},{'$M_EXPR',new,0}},[7]},
- {{{A,args,1},{A,local,1}},[6]},
- {{{A,args,1},{A,new,2}},[8]},
- {{{A,local,1},{A,module_info,1}},[12]},
- {{{param,new,2},{param,instance,2}},[0]}]} =
- xref:q(s, "(Lin) E"),
- ?line {ok,[{param,args,1},
- {param,instance,2},
- {param,local,1},
- {param,module_info,1},
- {param,new,2}]} = xref:q(s, "F"),
-
- ?line ok = check_state(s),
- ?line xref:stop(s),
-
- ?line {ok, _} = xref:start(s, {xref_mode, modules}),
- ?line {ok, param} = xref:add_module(s, MFile),
- ?line {ok,[{param,args,1},
- {param,instance,2},
- {param,new,2}]} = xref:q(s, "X"),
- ?line ok = check_state(s),
- ?line xref:stop(s),
-
- ?line ok = file:delete(File),
- ?line ok = file:delete(Beam),
- ok.
-
fun_mfa(suite) -> [];
fun_mfa(doc) -> ["OTP-5653: fun M:F/A."];
fun_mfa(Conf) when is_list(Conf) ->
diff --git a/lib/tv/src/Makefile b/lib/tv/src/Makefile
index da1713e156..3d680c1eaf 100644
--- a/lib/tv/src/Makefile
+++ b/lib/tv/src/Makefile
@@ -109,10 +109,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/tv/src/tv_main.hrl b/lib/tv/src/tv_main.hrl
index 28329ca83c..06b405ac1f 100644
--- a/lib/tv/src/tv_main.hrl
+++ b/lib/tv/src/tv_main.hrl
@@ -131,7 +131,6 @@
ir_WstringDef,
lmcounter,
locks,
- mnemosyne_tmp,
pg2_table,
queue,
snmp_agent_table,
diff --git a/lib/typer/src/Makefile b/lib/typer/src/Makefile
index 1f94d8fdc8..13af466755 100644
--- a/lib/typer/src/Makefile
+++ b/lib/typer/src/Makefile
@@ -82,13 +82,13 @@ clean:
# ----------------------------------------------------
$(EBIN)/typer.$(EMULATOR): typer.erl ../vsn.mk Makefile
- erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) typer.erl
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) typer.erl
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ---------------------------------------------------------------------
# dependencies
diff --git a/lib/webtool/src/Makefile b/lib/webtool/src/Makefile
index 783ffad79a..f28c777240 100644
--- a/lib/webtool/src/Makefile
+++ b/lib/webtool/src/Makefile
@@ -76,10 +76,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Release Target
diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4
index 5d555a5123..918e30a886 100644
--- a/lib/wx/aclocal.m4
+++ b/lib/wx/aclocal.m4
@@ -1861,17 +1861,16 @@ 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 CFLAGS])
+ AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)])
saved_CFLAGS=$CFLAGS;
- CFLAGS="$1 $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 $CFLAGS")
+ AS_VAR_SET($2, "$1 $$2")
else
AC_MSG_RESULT([no])
- AS_VAR_SET($2, "$CFLAGS")
fi
])
diff --git a/lib/wx/api_gen/wx_extra/bugs.h b/lib/wx/api_gen/wx_extra/bugs.h
index b8f3dfcb00..e3a4fa200b 100644
--- a/lib/wx/api_gen/wx_extra/bugs.h
+++ b/lib/wx/api_gen/wx_extra/bugs.h
@@ -34,3 +34,9 @@ class WXDLLIMPEXP_ADV wxGridCellNumberRenderer : public wxGridCellStringRenderer
wxGridCellNumberRenderer();
};
+// Enable test for valid wxTreeItemId's
+class WXDLLIMPEXP_ADV wxTreeCtrlBase : public wxControl
+{
+ public:
+ static bool IsTreeItemIdOk(wxTreeItemId id);
+}
diff --git a/lib/stdlib/test/erl_eval_helper.erl b/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
index 6863b40108..50dca4e2bb 100644
--- a/lib/stdlib/test/erl_eval_helper.erl
+++ b/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
@@ -1,28 +1,28 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 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%
%%
--module(erl_eval_helper, [Base]).
-
--export([add/1]).
-
-add(Arg) ->
- Base+Arg.
-
-
+<<wxTreeCtrl_IsTreeItemIdOk
+case ~s: { // wxTreeCtrl::IsTreeItemIdOk
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ bool Result = item.IsOk();
+ rt.addBool(Result);
+ break;
+}
+wxTreeCtrl_IsTreeItemIdOk>>
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
index a999a869e6..2e1a0d617a 100644
--- a/lib/wx/api_gen/wx_gen_erl.erl
+++ b/lib/wx/api_gen/wx_gen_erl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -218,33 +218,37 @@ check_class(#type{base={class,Name},xml=Xml}) ->
gen_export(#class{name=Class,abstract=Abs},Ms0) ->
RemoveC = fun(#method{where=merged_c}) -> false;(_Other) -> true end,
Res = filter(RemoveC, Ms0),
+ GetF = fun(M=#method{method_type=constructor,where=W,params=Ps}) ->
+ {Args,Opts} = split_optional(Ps),
+ OptLen = case Opts of
+ [] -> 0;
+ _ when W =:= erl_no_opt -> 0;
+ _ -> 1
+ end,
+ deprecated(M, "new" ++ "/" ++ integer_to_list(length(Args)+OptLen));
+ (M=#method{method_type=destructor}) ->
+ case Abs of
+ true -> [];
+ _ -> deprecated(M, "destroy/1")
+ end;
+ (M=#method{name=N,alias=A,where=W, params=Ps}) ->
+ {Args,Opts} = split_optional(Ps),
+ OptLen = case Opts of
+ [] -> 0;
+ _ when W =:= erl_no_opt -> 0;
+ _ -> 1
+ end,
+ deprecated(M, erl_func_name(N,A) ++ "/" ++ integer_to_list(length(Args) + OptLen))
+ end,
case Res of
[] -> [];
[M=#method{where=taylormade}|_] ->
- [deprecated(M, taylormade_export(Class, M))];
+ try
+ [deprecated(M, taylormade_export(Class, M))]
+ catch error:{badmatch, {error, enoent}} ->
+ lists:map(GetF, Res)
+ end;
Ms ->
- GetF = fun(M=#method{method_type=constructor,where=W,params=Ps}) ->
- {Args,Opts} = split_optional(Ps),
- OptLen = case Opts of
- [] -> 0;
- _ when W =:= erl_no_opt -> 0;
- _ -> 1
- end,
- deprecated(M, "new" ++ "/" ++ integer_to_list(length(Args)+OptLen));
- (M=#method{method_type=destructor}) ->
- case Abs of
- true -> [];
- _ -> deprecated(M, "destroy/1")
- end;
- (M=#method{name=N,alias=A,where=W, params=Ps}) ->
- {Args,Opts} = split_optional(Ps),
- OptLen = case Opts of
- [] -> 0;
- _ when W =:= erl_no_opt -> 0;
- _ -> 1
- end,
- deprecated(M, erl_func_name(N,A) ++ "/" ++ integer_to_list(length(Args) + OptLen))
- end,
lists:map(GetF, Ms)
end.
@@ -262,7 +266,12 @@ gen_method(Class,Ms0) ->
case Res of
[] -> Ms0;
[#method{where=taylormade}|_] ->
- taylormade_func(Class, Res),
+ try
+ taylormade_func(Class, Res)
+ catch error:{badmatch, {error, enoent}} ->
+ gen_doc(Class,Res),
+ gen_method1(Res)
+ end,
Ms0;
Ms ->
gen_doc(Class,Ms),
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index 94142ff6ba..81f2a389ab 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -975,7 +975,7 @@
'AssignImageList','AssignStateImageList','Collapse','CollapseAndReset',
'Create','Delete','DeleteAllItems','DeleteChildren',
{'EditLabel', [{"textCtrlClass", [nowhere]}]}, %'EndEditLabel',
- 'EnsureVisible','Expand','GetBoundingRect',
+ 'EnsureVisible','Expand',{'GetBoundingRect', [{"rect", [out]}]},
'GetChildrenCount','GetCount','GetEditControl',
{'GetFirstChild',[{"cookie", out}]}, {'GetNextChild',[{"cookie", [both]}]},
'GetFirstVisibleItem',{'GetImageList',0},'GetIndent',
@@ -984,9 +984,10 @@
'GetNextSibling','GetNextVisible','GetItemParent',%'GetParent',
'GetPrevSibling','GetPrevVisible','GetRootItem',
'GetSelection',{'GetSelections', [{return, nowhere},{"val",out}]},
- 'GetStateImageList',{'HitTest', 1},
+ 'GetStateImageList', {{'HitTest', 2}, [{"flags", out}]},
{'InsertItem',[{"insertAfter", skip_member}]},
'IsBold','IsExpanded','IsSelected','IsVisible','ItemHasChildren',
+ {'IsTreeItemIdOk', [{where, taylormade}]},
%%'OnCompareItems',
'PrependItem','ScrollTo','SelectItem',
'SetIndent',{'SetImageList',1},'SetItemBackgroundColour',
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index 5fbe8a2a9e..2d55f34346 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2008-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
@@ -18687,15 +18687,11 @@ case wxTreeCtrl_Expand: { // wxTreeCtrl::Expand
break;
}
case wxTreeCtrl_GetBoundingRect: { // wxTreeCtrl::GetBoundingRect
+ wxRect rect;
bool textOnly=false;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
- int * rectX = (int *) bp; bp += 4;
- int * rectY = (int *) bp; bp += 4;
- int * rectW = (int *) bp; bp += 4;
- int * rectH = (int *) bp; bp += 4;
- wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
textOnly = *(bool *) bp; bp += 4;
@@ -18704,6 +18700,8 @@ case wxTreeCtrl_GetBoundingRect: { // wxTreeCtrl::GetBoundingRect
if(!This) throw wxe_badarg(0);
bool Result = This->GetBoundingRect(item,rect,textOnly);
rt.addBool(Result);
+ rt.add(rect);
+ rt.addTupleCount(2);
break;
}
case wxTreeCtrl_GetChildrenCount: { // wxTreeCtrl::GetChildrenCount
@@ -18937,13 +18935,16 @@ case wxTreeCtrl_GetStateImageList: { // wxTreeCtrl::GetStateImageList
break;
}
case wxTreeCtrl_HitTest: { // wxTreeCtrl::HitTest
+ int flags;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
int * pointX = (int *) bp; bp += 4;
int * pointY = (int *) bp; bp += 4;
wxPoint point = wxPoint(*pointX,*pointY);
if(!This) throw wxe_badarg(0);
- wxTreeItemId Result = This->HitTest(point);
+ wxTreeItemId Result = This->HitTest(point,flags);
rt.add((wxUIntPtr *) Result.m_pItem);
+ rt.addInt(flags);
+ rt.addTupleCount(2);
break;
}
case wxTreeCtrl_InsertItem: { // wxTreeCtrl::InsertItem
@@ -19019,6 +19020,13 @@ case wxTreeCtrl_ItemHasChildren: { // wxTreeCtrl::ItemHasChildren
rt.addBool(Result);
break;
}
+
+case wxTreeCtrl_IsTreeItemIdOk: { // wxTreeCtrl::IsTreeItemIdOk
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ bool Result = item.IsOk();
+ rt.addBool(Result);
+ break;
+}
case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
int image=-1;
int selectedImage=-1;
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index 4b87c2340e..c341825d8d 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2008-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
@@ -1931,1424 +1931,1425 @@
#define wxTreeCtrl_IsSelected 2058
#define wxTreeCtrl_IsVisible 2059
#define wxTreeCtrl_ItemHasChildren 2060
-#define wxTreeCtrl_PrependItem 2061
-#define wxTreeCtrl_ScrollTo 2062
-#define wxTreeCtrl_SelectItem_1 2063
-#define wxTreeCtrl_SelectItem_2 2064
-#define wxTreeCtrl_SetIndent 2065
-#define wxTreeCtrl_SetImageList 2066
-#define wxTreeCtrl_SetItemBackgroundColour 2067
-#define wxTreeCtrl_SetItemBold 2068
-#define wxTreeCtrl_SetItemData 2069
-#define wxTreeCtrl_SetItemDropHighlight 2070
-#define wxTreeCtrl_SetItemFont 2071
-#define wxTreeCtrl_SetItemHasChildren 2072
-#define wxTreeCtrl_SetItemImage_2 2073
-#define wxTreeCtrl_SetItemImage_3 2074
-#define wxTreeCtrl_SetItemText 2075
-#define wxTreeCtrl_SetItemTextColour 2076
-#define wxTreeCtrl_SetStateImageList 2077
-#define wxTreeCtrl_SetWindowStyle 2078
-#define wxTreeCtrl_SortChildren 2079
-#define wxTreeCtrl_Toggle 2080
-#define wxTreeCtrl_ToggleItemSelection 2081
-#define wxTreeCtrl_Unselect 2082
-#define wxTreeCtrl_UnselectAll 2083
-#define wxTreeCtrl_UnselectItem 2084
-#define wxScrollBar_new_0 2085
-#define wxScrollBar_new_3 2086
-#define wxScrollBar_destruct 2087
-#define wxScrollBar_Create 2088
-#define wxScrollBar_GetRange 2089
-#define wxScrollBar_GetPageSize 2090
-#define wxScrollBar_GetThumbPosition 2091
-#define wxScrollBar_GetThumbSize 2092
-#define wxScrollBar_SetThumbPosition 2093
-#define wxScrollBar_SetScrollbar 2094
-#define wxSpinButton_new_2 2096
-#define wxSpinButton_new_0 2097
-#define wxSpinButton_Create 2098
-#define wxSpinButton_GetMax 2099
-#define wxSpinButton_GetMin 2100
-#define wxSpinButton_GetValue 2101
-#define wxSpinButton_SetRange 2102
-#define wxSpinButton_SetValue 2103
-#define wxSpinButton_destroy 2104
-#define wxSpinCtrl_new_0 2105
-#define wxSpinCtrl_new_2 2106
-#define wxSpinCtrl_Create 2108
-#define wxSpinCtrl_SetValue_1_1 2111
-#define wxSpinCtrl_SetValue_1_0 2112
-#define wxSpinCtrl_GetValue 2114
-#define wxSpinCtrl_SetRange 2116
-#define wxSpinCtrl_SetSelection 2117
-#define wxSpinCtrl_GetMin 2119
-#define wxSpinCtrl_GetMax 2121
-#define wxSpinCtrl_destroy 2122
-#define wxStaticText_new_0 2123
-#define wxStaticText_new_4 2124
-#define wxStaticText_Create 2125
-#define wxStaticText_GetLabel 2126
-#define wxStaticText_SetLabel 2127
-#define wxStaticText_Wrap 2128
-#define wxStaticText_destroy 2129
-#define wxStaticBitmap_new_0 2130
-#define wxStaticBitmap_new_4 2131
-#define wxStaticBitmap_Create 2132
-#define wxStaticBitmap_GetBitmap 2133
-#define wxStaticBitmap_SetBitmap 2134
-#define wxStaticBitmap_destroy 2135
-#define wxRadioBox_new 2136
-#define wxRadioBox_destruct 2138
-#define wxRadioBox_Create 2139
-#define wxRadioBox_Enable_2 2140
-#define wxRadioBox_Enable_1 2141
-#define wxRadioBox_GetSelection 2142
-#define wxRadioBox_GetString 2143
-#define wxRadioBox_SetSelection 2144
-#define wxRadioBox_Show_2 2145
-#define wxRadioBox_Show_1 2146
-#define wxRadioBox_GetColumnCount 2147
-#define wxRadioBox_GetItemHelpText 2148
-#define wxRadioBox_GetItemToolTip 2149
-#define wxRadioBox_GetItemFromPoint 2151
-#define wxRadioBox_GetRowCount 2152
-#define wxRadioBox_IsItemEnabled 2153
-#define wxRadioBox_IsItemShown 2154
-#define wxRadioBox_SetItemHelpText 2155
-#define wxRadioBox_SetItemToolTip 2156
-#define wxRadioButton_new_0 2157
-#define wxRadioButton_new_4 2158
-#define wxRadioButton_Create 2159
-#define wxRadioButton_GetValue 2160
-#define wxRadioButton_SetValue 2161
-#define wxRadioButton_destroy 2162
-#define wxSlider_new_6 2164
-#define wxSlider_new_0 2165
-#define wxSlider_Create 2166
-#define wxSlider_GetLineSize 2167
-#define wxSlider_GetMax 2168
-#define wxSlider_GetMin 2169
-#define wxSlider_GetPageSize 2170
-#define wxSlider_GetThumbLength 2171
-#define wxSlider_GetValue 2172
-#define wxSlider_SetLineSize 2173
-#define wxSlider_SetPageSize 2174
-#define wxSlider_SetRange 2175
-#define wxSlider_SetThumbLength 2176
-#define wxSlider_SetValue 2177
-#define wxSlider_destroy 2178
-#define wxDialog_new_4 2180
-#define wxDialog_new_0 2181
-#define wxDialog_destruct 2183
-#define wxDialog_Create 2184
-#define wxDialog_CreateButtonSizer 2185
-#define wxDialog_CreateStdDialogButtonSizer 2186
-#define wxDialog_EndModal 2187
-#define wxDialog_GetAffirmativeId 2188
-#define wxDialog_GetReturnCode 2189
-#define wxDialog_IsModal 2190
-#define wxDialog_SetAffirmativeId 2191
-#define wxDialog_SetReturnCode 2192
-#define wxDialog_Show 2193
-#define wxDialog_ShowModal 2194
-#define wxColourDialog_new_0 2195
-#define wxColourDialog_new_2 2196
-#define wxColourDialog_destruct 2197
-#define wxColourDialog_Create 2198
-#define wxColourDialog_GetColourData 2199
-#define wxColourData_new_0 2200
-#define wxColourData_new_1 2201
-#define wxColourData_destruct 2202
-#define wxColourData_GetChooseFull 2203
-#define wxColourData_GetColour 2204
-#define wxColourData_GetCustomColour 2206
-#define wxColourData_SetChooseFull 2207
-#define wxColourData_SetColour 2208
-#define wxColourData_SetCustomColour 2209
-#define wxPalette_new_0 2210
-#define wxPalette_new_4 2211
-#define wxPalette_destruct 2213
-#define wxPalette_Create 2214
-#define wxPalette_GetColoursCount 2215
-#define wxPalette_GetPixel 2216
-#define wxPalette_GetRGB 2217
-#define wxPalette_IsOk 2218
-#define wxDirDialog_new 2222
-#define wxDirDialog_destruct 2223
-#define wxDirDialog_GetPath 2224
-#define wxDirDialog_GetMessage 2225
-#define wxDirDialog_SetMessage 2226
-#define wxDirDialog_SetPath 2227
-#define wxFileDialog_new 2231
-#define wxFileDialog_destruct 2232
-#define wxFileDialog_GetDirectory 2233
-#define wxFileDialog_GetFilename 2234
-#define wxFileDialog_GetFilenames 2235
-#define wxFileDialog_GetFilterIndex 2236
-#define wxFileDialog_GetMessage 2237
-#define wxFileDialog_GetPath 2238
-#define wxFileDialog_GetPaths 2239
-#define wxFileDialog_GetWildcard 2240
-#define wxFileDialog_SetDirectory 2241
-#define wxFileDialog_SetFilename 2242
-#define wxFileDialog_SetFilterIndex 2243
-#define wxFileDialog_SetMessage 2244
-#define wxFileDialog_SetPath 2245
-#define wxFileDialog_SetWildcard 2246
-#define wxPickerBase_SetInternalMargin 2247
-#define wxPickerBase_GetInternalMargin 2248
-#define wxPickerBase_SetTextCtrlProportion 2249
-#define wxPickerBase_SetPickerCtrlProportion 2250
-#define wxPickerBase_GetTextCtrlProportion 2251
-#define wxPickerBase_GetPickerCtrlProportion 2252
-#define wxPickerBase_HasTextCtrl 2253
-#define wxPickerBase_GetTextCtrl 2254
-#define wxPickerBase_IsTextCtrlGrowable 2255
-#define wxPickerBase_SetPickerCtrlGrowable 2256
-#define wxPickerBase_SetTextCtrlGrowable 2257
-#define wxPickerBase_IsPickerCtrlGrowable 2258
-#define wxFilePickerCtrl_new_0 2259
-#define wxFilePickerCtrl_new_3 2260
-#define wxFilePickerCtrl_Create 2261
-#define wxFilePickerCtrl_GetPath 2262
-#define wxFilePickerCtrl_SetPath 2263
-#define wxFilePickerCtrl_destroy 2264
-#define wxDirPickerCtrl_new_0 2265
-#define wxDirPickerCtrl_new_3 2266
-#define wxDirPickerCtrl_Create 2267
-#define wxDirPickerCtrl_GetPath 2268
-#define wxDirPickerCtrl_SetPath 2269
-#define wxDirPickerCtrl_destroy 2270
-#define wxColourPickerCtrl_new_0 2271
-#define wxColourPickerCtrl_new_3 2272
-#define wxColourPickerCtrl_Create 2273
-#define wxColourPickerCtrl_GetColour 2274
-#define wxColourPickerCtrl_SetColour_1_1 2275
-#define wxColourPickerCtrl_SetColour_1_0 2276
-#define wxColourPickerCtrl_destroy 2277
-#define wxDatePickerCtrl_new_0 2278
-#define wxDatePickerCtrl_new_3 2279
-#define wxDatePickerCtrl_GetRange 2280
-#define wxDatePickerCtrl_GetValue 2281
-#define wxDatePickerCtrl_SetRange 2282
-#define wxDatePickerCtrl_SetValue 2283
-#define wxDatePickerCtrl_destroy 2284
-#define wxFontPickerCtrl_new_0 2285
-#define wxFontPickerCtrl_new_3 2286
-#define wxFontPickerCtrl_Create 2287
-#define wxFontPickerCtrl_GetSelectedFont 2288
-#define wxFontPickerCtrl_SetSelectedFont 2289
-#define wxFontPickerCtrl_GetMaxPointSize 2290
-#define wxFontPickerCtrl_SetMaxPointSize 2291
-#define wxFontPickerCtrl_destroy 2292
-#define wxFindReplaceDialog_new_0 2295
-#define wxFindReplaceDialog_new_4 2296
-#define wxFindReplaceDialog_destruct 2297
-#define wxFindReplaceDialog_Create 2298
-#define wxFindReplaceDialog_GetData 2299
-#define wxFindReplaceData_new_0 2300
-#define wxFindReplaceData_new_1 2301
-#define wxFindReplaceData_GetFindString 2302
-#define wxFindReplaceData_GetReplaceString 2303
-#define wxFindReplaceData_GetFlags 2304
-#define wxFindReplaceData_SetFlags 2305
-#define wxFindReplaceData_SetFindString 2306
-#define wxFindReplaceData_SetReplaceString 2307
-#define wxFindReplaceData_destroy 2308
-#define wxMultiChoiceDialog_new_0 2309
-#define wxMultiChoiceDialog_new_5 2311
-#define wxMultiChoiceDialog_GetSelections 2312
-#define wxMultiChoiceDialog_SetSelections 2313
-#define wxMultiChoiceDialog_destroy 2314
-#define wxSingleChoiceDialog_new_0 2315
-#define wxSingleChoiceDialog_new_5 2317
-#define wxSingleChoiceDialog_GetSelection 2318
-#define wxSingleChoiceDialog_GetStringSelection 2319
-#define wxSingleChoiceDialog_SetSelection 2320
-#define wxSingleChoiceDialog_destroy 2321
-#define wxTextEntryDialog_new 2322
-#define wxTextEntryDialog_GetValue 2323
-#define wxTextEntryDialog_SetValue 2324
-#define wxTextEntryDialog_destroy 2325
-#define wxPasswordEntryDialog_new 2326
-#define wxPasswordEntryDialog_destroy 2327
-#define wxFontData_new_0 2328
-#define wxFontData_new_1 2329
-#define wxFontData_destruct 2330
-#define wxFontData_EnableEffects 2331
-#define wxFontData_GetAllowSymbols 2332
-#define wxFontData_GetColour 2333
-#define wxFontData_GetChosenFont 2334
-#define wxFontData_GetEnableEffects 2335
-#define wxFontData_GetInitialFont 2336
-#define wxFontData_GetShowHelp 2337
-#define wxFontData_SetAllowSymbols 2338
-#define wxFontData_SetChosenFont 2339
-#define wxFontData_SetColour 2340
-#define wxFontData_SetInitialFont 2341
-#define wxFontData_SetRange 2342
-#define wxFontData_SetShowHelp 2343
-#define wxFontDialog_new_0 2347
-#define wxFontDialog_new_2 2349
-#define wxFontDialog_Create 2351
-#define wxFontDialog_GetFontData 2352
-#define wxFontDialog_destroy 2354
-#define wxProgressDialog_new 2355
-#define wxProgressDialog_destruct 2356
-#define wxProgressDialog_Resume 2357
-#define wxProgressDialog_Update_2 2358
-#define wxProgressDialog_Update_0 2359
-#define wxMessageDialog_new 2360
-#define wxMessageDialog_destruct 2361
-#define wxPageSetupDialog_new 2362
-#define wxPageSetupDialog_destruct 2363
-#define wxPageSetupDialog_GetPageSetupData 2364
-#define wxPageSetupDialog_ShowModal 2365
-#define wxPageSetupDialogData_new_0 2366
-#define wxPageSetupDialogData_new_1_0 2367
-#define wxPageSetupDialogData_new_1_1 2368
-#define wxPageSetupDialogData_destruct 2369
-#define wxPageSetupDialogData_EnableHelp 2370
-#define wxPageSetupDialogData_EnableMargins 2371
-#define wxPageSetupDialogData_EnableOrientation 2372
-#define wxPageSetupDialogData_EnablePaper 2373
-#define wxPageSetupDialogData_EnablePrinter 2374
-#define wxPageSetupDialogData_GetDefaultMinMargins 2375
-#define wxPageSetupDialogData_GetEnableMargins 2376
-#define wxPageSetupDialogData_GetEnableOrientation 2377
-#define wxPageSetupDialogData_GetEnablePaper 2378
-#define wxPageSetupDialogData_GetEnablePrinter 2379
-#define wxPageSetupDialogData_GetEnableHelp 2380
-#define wxPageSetupDialogData_GetDefaultInfo 2381
-#define wxPageSetupDialogData_GetMarginTopLeft 2382
-#define wxPageSetupDialogData_GetMarginBottomRight 2383
-#define wxPageSetupDialogData_GetMinMarginTopLeft 2384
-#define wxPageSetupDialogData_GetMinMarginBottomRight 2385
-#define wxPageSetupDialogData_GetPaperId 2386
-#define wxPageSetupDialogData_GetPaperSize 2387
-#define wxPageSetupDialogData_GetPrintData 2389
-#define wxPageSetupDialogData_IsOk 2390
-#define wxPageSetupDialogData_SetDefaultInfo 2391
-#define wxPageSetupDialogData_SetDefaultMinMargins 2392
-#define wxPageSetupDialogData_SetMarginTopLeft 2393
-#define wxPageSetupDialogData_SetMarginBottomRight 2394
-#define wxPageSetupDialogData_SetMinMarginTopLeft 2395
-#define wxPageSetupDialogData_SetMinMarginBottomRight 2396
-#define wxPageSetupDialogData_SetPaperId 2397
-#define wxPageSetupDialogData_SetPaperSize_1_1 2398
-#define wxPageSetupDialogData_SetPaperSize_1_0 2399
-#define wxPageSetupDialogData_SetPrintData 2400
-#define wxPrintDialog_new_2_0 2401
-#define wxPrintDialog_new_2_1 2402
-#define wxPrintDialog_destruct 2403
-#define wxPrintDialog_GetPrintDialogData 2404
-#define wxPrintDialog_GetPrintDC 2405
-#define wxPrintDialogData_new_0 2406
-#define wxPrintDialogData_new_1_1 2407
-#define wxPrintDialogData_new_1_0 2408
-#define wxPrintDialogData_destruct 2409
-#define wxPrintDialogData_EnableHelp 2410
-#define wxPrintDialogData_EnablePageNumbers 2411
-#define wxPrintDialogData_EnablePrintToFile 2412
-#define wxPrintDialogData_EnableSelection 2413
-#define wxPrintDialogData_GetAllPages 2414
-#define wxPrintDialogData_GetCollate 2415
-#define wxPrintDialogData_GetFromPage 2416
-#define wxPrintDialogData_GetMaxPage 2417
-#define wxPrintDialogData_GetMinPage 2418
-#define wxPrintDialogData_GetNoCopies 2419
-#define wxPrintDialogData_GetPrintData 2420
-#define wxPrintDialogData_GetPrintToFile 2421
-#define wxPrintDialogData_GetSelection 2422
-#define wxPrintDialogData_GetToPage 2423
-#define wxPrintDialogData_IsOk 2424
-#define wxPrintDialogData_SetCollate 2425
-#define wxPrintDialogData_SetFromPage 2426
-#define wxPrintDialogData_SetMaxPage 2427
-#define wxPrintDialogData_SetMinPage 2428
-#define wxPrintDialogData_SetNoCopies 2429
-#define wxPrintDialogData_SetPrintData 2430
-#define wxPrintDialogData_SetPrintToFile 2431
-#define wxPrintDialogData_SetSelection 2432
-#define wxPrintDialogData_SetToPage 2433
-#define wxPrintData_new_0 2434
-#define wxPrintData_new_1 2435
-#define wxPrintData_destruct 2436
-#define wxPrintData_GetCollate 2437
-#define wxPrintData_GetBin 2438
-#define wxPrintData_GetColour 2439
-#define wxPrintData_GetDuplex 2440
-#define wxPrintData_GetNoCopies 2441
-#define wxPrintData_GetOrientation 2442
-#define wxPrintData_GetPaperId 2443
-#define wxPrintData_GetPrinterName 2444
-#define wxPrintData_GetQuality 2445
-#define wxPrintData_IsOk 2446
-#define wxPrintData_SetBin 2447
-#define wxPrintData_SetCollate 2448
-#define wxPrintData_SetColour 2449
-#define wxPrintData_SetDuplex 2450
-#define wxPrintData_SetNoCopies 2451
-#define wxPrintData_SetOrientation 2452
-#define wxPrintData_SetPaperId 2453
-#define wxPrintData_SetPrinterName 2454
-#define wxPrintData_SetQuality 2455
-#define wxPrintPreview_new_2 2458
-#define wxPrintPreview_new_3 2459
-#define wxPrintPreview_destruct 2461
-#define wxPrintPreview_GetCanvas 2462
-#define wxPrintPreview_GetCurrentPage 2463
-#define wxPrintPreview_GetFrame 2464
-#define wxPrintPreview_GetMaxPage 2465
-#define wxPrintPreview_GetMinPage 2466
-#define wxPrintPreview_GetPrintout 2467
-#define wxPrintPreview_GetPrintoutForPrinting 2468
-#define wxPrintPreview_IsOk 2469
-#define wxPrintPreview_PaintPage 2470
-#define wxPrintPreview_Print 2471
-#define wxPrintPreview_RenderPage 2472
-#define wxPrintPreview_SetCanvas 2473
-#define wxPrintPreview_SetCurrentPage 2474
-#define wxPrintPreview_SetFrame 2475
-#define wxPrintPreview_SetPrintout 2476
-#define wxPrintPreview_SetZoom 2477
-#define wxPreviewFrame_new 2478
-#define wxPreviewFrame_destruct 2479
-#define wxPreviewFrame_CreateControlBar 2480
-#define wxPreviewFrame_CreateCanvas 2481
-#define wxPreviewFrame_Initialize 2482
-#define wxPreviewFrame_OnCloseWindow 2483
-#define wxPreviewControlBar_new 2484
-#define wxPreviewControlBar_destruct 2485
-#define wxPreviewControlBar_CreateButtons 2486
-#define wxPreviewControlBar_GetPrintPreview 2487
-#define wxPreviewControlBar_GetZoomControl 2488
-#define wxPreviewControlBar_SetZoomControl 2489
-#define wxPrinter_new 2491
-#define wxPrinter_CreateAbortWindow 2492
-#define wxPrinter_GetAbort 2493
-#define wxPrinter_GetLastError 2494
-#define wxPrinter_GetPrintDialogData 2495
-#define wxPrinter_Print 2496
-#define wxPrinter_PrintDialog 2497
-#define wxPrinter_ReportError 2498
-#define wxPrinter_Setup 2499
-#define wxPrinter_destroy 2500
-#define wxXmlResource_new_1 2501
-#define wxXmlResource_new_2 2502
-#define wxXmlResource_destruct 2503
-#define wxXmlResource_AttachUnknownControl 2504
-#define wxXmlResource_ClearHandlers 2505
-#define wxXmlResource_CompareVersion 2506
-#define wxXmlResource_Get 2507
-#define wxXmlResource_GetFlags 2508
-#define wxXmlResource_GetVersion 2509
-#define wxXmlResource_GetXRCID 2510
-#define wxXmlResource_InitAllHandlers 2511
-#define wxXmlResource_Load 2512
-#define wxXmlResource_LoadBitmap 2513
-#define wxXmlResource_LoadDialog_2 2514
-#define wxXmlResource_LoadDialog_3 2515
-#define wxXmlResource_LoadFrame_2 2516
-#define wxXmlResource_LoadFrame_3 2517
-#define wxXmlResource_LoadIcon 2518
-#define wxXmlResource_LoadMenu 2519
-#define wxXmlResource_LoadMenuBar_2 2520
-#define wxXmlResource_LoadMenuBar_1 2521
-#define wxXmlResource_LoadPanel_2 2522
-#define wxXmlResource_LoadPanel_3 2523
-#define wxXmlResource_LoadToolBar 2524
-#define wxXmlResource_Set 2525
-#define wxXmlResource_SetFlags 2526
-#define wxXmlResource_Unload 2527
-#define wxXmlResource_xrcctrl 2528
-#define wxHtmlEasyPrinting_new 2529
-#define wxHtmlEasyPrinting_destruct 2530
-#define wxHtmlEasyPrinting_GetPrintData 2531
-#define wxHtmlEasyPrinting_GetPageSetupData 2532
-#define wxHtmlEasyPrinting_PreviewFile 2533
-#define wxHtmlEasyPrinting_PreviewText 2534
-#define wxHtmlEasyPrinting_PrintFile 2535
-#define wxHtmlEasyPrinting_PrintText 2536
-#define wxHtmlEasyPrinting_PageSetup 2537
-#define wxHtmlEasyPrinting_SetFonts 2538
-#define wxHtmlEasyPrinting_SetHeader 2539
-#define wxHtmlEasyPrinting_SetFooter 2540
-#define wxGLCanvas_new_2 2542
-#define wxGLCanvas_new_3_1 2543
-#define wxGLCanvas_new_3_0 2544
-#define wxGLCanvas_GetContext 2545
-#define wxGLCanvas_SetCurrent 2547
-#define wxGLCanvas_SwapBuffers 2548
-#define wxGLCanvas_destroy 2549
-#define wxAuiManager_new 2550
-#define wxAuiManager_destruct 2551
-#define wxAuiManager_AddPane_2_1 2552
-#define wxAuiManager_AddPane_3 2553
-#define wxAuiManager_AddPane_2_0 2554
-#define wxAuiManager_DetachPane 2555
-#define wxAuiManager_GetAllPanes 2556
-#define wxAuiManager_GetArtProvider 2557
-#define wxAuiManager_GetDockSizeConstraint 2558
-#define wxAuiManager_GetFlags 2559
-#define wxAuiManager_GetManagedWindow 2560
-#define wxAuiManager_GetManager 2561
-#define wxAuiManager_GetPane_1_1 2562
-#define wxAuiManager_GetPane_1_0 2563
-#define wxAuiManager_HideHint 2564
-#define wxAuiManager_InsertPane 2565
-#define wxAuiManager_LoadPaneInfo 2566
-#define wxAuiManager_LoadPerspective 2567
-#define wxAuiManager_SavePaneInfo 2568
-#define wxAuiManager_SavePerspective 2569
-#define wxAuiManager_SetArtProvider 2570
-#define wxAuiManager_SetDockSizeConstraint 2571
-#define wxAuiManager_SetFlags 2572
-#define wxAuiManager_SetManagedWindow 2573
-#define wxAuiManager_ShowHint 2574
-#define wxAuiManager_UnInit 2575
-#define wxAuiManager_Update 2576
-#define wxAuiPaneInfo_new_0 2577
-#define wxAuiPaneInfo_new_1 2578
-#define wxAuiPaneInfo_destruct 2579
-#define wxAuiPaneInfo_BestSize_1 2580
-#define wxAuiPaneInfo_BestSize_2 2581
-#define wxAuiPaneInfo_Bottom 2582
-#define wxAuiPaneInfo_BottomDockable 2583
-#define wxAuiPaneInfo_Caption 2584
-#define wxAuiPaneInfo_CaptionVisible 2585
-#define wxAuiPaneInfo_Centre 2586
-#define wxAuiPaneInfo_CentrePane 2587
-#define wxAuiPaneInfo_CloseButton 2588
-#define wxAuiPaneInfo_DefaultPane 2589
-#define wxAuiPaneInfo_DestroyOnClose 2590
-#define wxAuiPaneInfo_Direction 2591
-#define wxAuiPaneInfo_Dock 2592
-#define wxAuiPaneInfo_Dockable 2593
-#define wxAuiPaneInfo_Fixed 2594
-#define wxAuiPaneInfo_Float 2595
-#define wxAuiPaneInfo_Floatable 2596
-#define wxAuiPaneInfo_FloatingPosition_1 2597
-#define wxAuiPaneInfo_FloatingPosition_2 2598
-#define wxAuiPaneInfo_FloatingSize_1 2599
-#define wxAuiPaneInfo_FloatingSize_2 2600
-#define wxAuiPaneInfo_Gripper 2601
-#define wxAuiPaneInfo_GripperTop 2602
-#define wxAuiPaneInfo_HasBorder 2603
-#define wxAuiPaneInfo_HasCaption 2604
-#define wxAuiPaneInfo_HasCloseButton 2605
-#define wxAuiPaneInfo_HasFlag 2606
-#define wxAuiPaneInfo_HasGripper 2607
-#define wxAuiPaneInfo_HasGripperTop 2608
-#define wxAuiPaneInfo_HasMaximizeButton 2609
-#define wxAuiPaneInfo_HasMinimizeButton 2610
-#define wxAuiPaneInfo_HasPinButton 2611
-#define wxAuiPaneInfo_Hide 2612
-#define wxAuiPaneInfo_IsBottomDockable 2613
-#define wxAuiPaneInfo_IsDocked 2614
-#define wxAuiPaneInfo_IsFixed 2615
-#define wxAuiPaneInfo_IsFloatable 2616
-#define wxAuiPaneInfo_IsFloating 2617
-#define wxAuiPaneInfo_IsLeftDockable 2618
-#define wxAuiPaneInfo_IsMovable 2619
-#define wxAuiPaneInfo_IsOk 2620
-#define wxAuiPaneInfo_IsResizable 2621
-#define wxAuiPaneInfo_IsRightDockable 2622
-#define wxAuiPaneInfo_IsShown 2623
-#define wxAuiPaneInfo_IsToolbar 2624
-#define wxAuiPaneInfo_IsTopDockable 2625
-#define wxAuiPaneInfo_Layer 2626
-#define wxAuiPaneInfo_Left 2627
-#define wxAuiPaneInfo_LeftDockable 2628
-#define wxAuiPaneInfo_MaxSize_1 2629
-#define wxAuiPaneInfo_MaxSize_2 2630
-#define wxAuiPaneInfo_MaximizeButton 2631
-#define wxAuiPaneInfo_MinSize_1 2632
-#define wxAuiPaneInfo_MinSize_2 2633
-#define wxAuiPaneInfo_MinimizeButton 2634
-#define wxAuiPaneInfo_Movable 2635
-#define wxAuiPaneInfo_Name 2636
-#define wxAuiPaneInfo_PaneBorder 2637
-#define wxAuiPaneInfo_PinButton 2638
-#define wxAuiPaneInfo_Position 2639
-#define wxAuiPaneInfo_Resizable 2640
-#define wxAuiPaneInfo_Right 2641
-#define wxAuiPaneInfo_RightDockable 2642
-#define wxAuiPaneInfo_Row 2643
-#define wxAuiPaneInfo_SafeSet 2644
-#define wxAuiPaneInfo_SetFlag 2645
-#define wxAuiPaneInfo_Show 2646
-#define wxAuiPaneInfo_ToolbarPane 2647
-#define wxAuiPaneInfo_Top 2648
-#define wxAuiPaneInfo_TopDockable 2649
-#define wxAuiPaneInfo_Window 2650
-#define wxAuiNotebook_new_0 2651
-#define wxAuiNotebook_new_2 2652
-#define wxAuiNotebook_AddPage 2653
-#define wxAuiNotebook_Create 2654
-#define wxAuiNotebook_DeletePage 2655
-#define wxAuiNotebook_GetArtProvider 2656
-#define wxAuiNotebook_GetPage 2657
-#define wxAuiNotebook_GetPageBitmap 2658
-#define wxAuiNotebook_GetPageCount 2659
-#define wxAuiNotebook_GetPageIndex 2660
-#define wxAuiNotebook_GetPageText 2661
-#define wxAuiNotebook_GetSelection 2662
-#define wxAuiNotebook_InsertPage 2663
-#define wxAuiNotebook_RemovePage 2664
-#define wxAuiNotebook_SetArtProvider 2665
-#define wxAuiNotebook_SetFont 2666
-#define wxAuiNotebook_SetPageBitmap 2667
-#define wxAuiNotebook_SetPageText 2668
-#define wxAuiNotebook_SetSelection 2669
-#define wxAuiNotebook_SetTabCtrlHeight 2670
-#define wxAuiNotebook_SetUniformBitmapSize 2671
-#define wxAuiNotebook_destroy 2672
-#define wxMDIParentFrame_new_0 2673
-#define wxMDIParentFrame_new_4 2674
-#define wxMDIParentFrame_destruct 2675
-#define wxMDIParentFrame_ActivateNext 2676
-#define wxMDIParentFrame_ActivatePrevious 2677
-#define wxMDIParentFrame_ArrangeIcons 2678
-#define wxMDIParentFrame_Cascade 2679
-#define wxMDIParentFrame_Create 2680
-#define wxMDIParentFrame_GetActiveChild 2681
-#define wxMDIParentFrame_GetClientWindow 2682
-#define wxMDIParentFrame_Tile 2683
-#define wxMDIChildFrame_new_0 2684
-#define wxMDIChildFrame_new_4 2685
-#define wxMDIChildFrame_destruct 2686
-#define wxMDIChildFrame_Activate 2687
-#define wxMDIChildFrame_Create 2688
-#define wxMDIChildFrame_Maximize 2689
-#define wxMDIChildFrame_Restore 2690
-#define wxMDIClientWindow_new_0 2691
-#define wxMDIClientWindow_new_2 2692
-#define wxMDIClientWindow_destruct 2693
-#define wxMDIClientWindow_CreateClient 2694
-#define wxLayoutAlgorithm_new 2695
-#define wxLayoutAlgorithm_LayoutFrame 2696
-#define wxLayoutAlgorithm_LayoutMDIFrame 2697
-#define wxLayoutAlgorithm_LayoutWindow 2698
-#define wxLayoutAlgorithm_destroy 2699
-#define wxEvent_GetId 2700
-#define wxEvent_GetSkipped 2701
-#define wxEvent_GetTimestamp 2702
-#define wxEvent_IsCommandEvent 2703
-#define wxEvent_ResumePropagation 2704
-#define wxEvent_ShouldPropagate 2705
-#define wxEvent_Skip 2706
-#define wxEvent_StopPropagation 2707
-#define wxCommandEvent_getClientData 2708
-#define wxCommandEvent_GetExtraLong 2709
-#define wxCommandEvent_GetInt 2710
-#define wxCommandEvent_GetSelection 2711
-#define wxCommandEvent_GetString 2712
-#define wxCommandEvent_IsChecked 2713
-#define wxCommandEvent_IsSelection 2714
-#define wxCommandEvent_SetInt 2715
-#define wxCommandEvent_SetString 2716
-#define wxScrollEvent_GetOrientation 2717
-#define wxScrollEvent_GetPosition 2718
-#define wxScrollWinEvent_GetOrientation 2719
-#define wxScrollWinEvent_GetPosition 2720
-#define wxMouseEvent_AltDown 2721
-#define wxMouseEvent_Button 2722
-#define wxMouseEvent_ButtonDClick 2723
-#define wxMouseEvent_ButtonDown 2724
-#define wxMouseEvent_ButtonUp 2725
-#define wxMouseEvent_CmdDown 2726
-#define wxMouseEvent_ControlDown 2727
-#define wxMouseEvent_Dragging 2728
-#define wxMouseEvent_Entering 2729
-#define wxMouseEvent_GetButton 2730
-#define wxMouseEvent_GetPosition 2733
-#define wxMouseEvent_GetLogicalPosition 2734
-#define wxMouseEvent_GetLinesPerAction 2735
-#define wxMouseEvent_GetWheelRotation 2736
-#define wxMouseEvent_GetWheelDelta 2737
-#define wxMouseEvent_GetX 2738
-#define wxMouseEvent_GetY 2739
-#define wxMouseEvent_IsButton 2740
-#define wxMouseEvent_IsPageScroll 2741
-#define wxMouseEvent_Leaving 2742
-#define wxMouseEvent_LeftDClick 2743
-#define wxMouseEvent_LeftDown 2744
-#define wxMouseEvent_LeftIsDown 2745
-#define wxMouseEvent_LeftUp 2746
-#define wxMouseEvent_MetaDown 2747
-#define wxMouseEvent_MiddleDClick 2748
-#define wxMouseEvent_MiddleDown 2749
-#define wxMouseEvent_MiddleIsDown 2750
-#define wxMouseEvent_MiddleUp 2751
-#define wxMouseEvent_Moving 2752
-#define wxMouseEvent_RightDClick 2753
-#define wxMouseEvent_RightDown 2754
-#define wxMouseEvent_RightIsDown 2755
-#define wxMouseEvent_RightUp 2756
-#define wxMouseEvent_ShiftDown 2757
-#define wxSetCursorEvent_GetCursor 2758
-#define wxSetCursorEvent_GetX 2759
-#define wxSetCursorEvent_GetY 2760
-#define wxSetCursorEvent_HasCursor 2761
-#define wxSetCursorEvent_SetCursor 2762
-#define wxKeyEvent_AltDown 2763
-#define wxKeyEvent_CmdDown 2764
-#define wxKeyEvent_ControlDown 2765
-#define wxKeyEvent_GetKeyCode 2766
-#define wxKeyEvent_GetModifiers 2767
-#define wxKeyEvent_GetPosition 2770
-#define wxKeyEvent_GetRawKeyCode 2771
-#define wxKeyEvent_GetRawKeyFlags 2772
-#define wxKeyEvent_GetUnicodeKey 2773
-#define wxKeyEvent_GetX 2774
-#define wxKeyEvent_GetY 2775
-#define wxKeyEvent_HasModifiers 2776
-#define wxKeyEvent_MetaDown 2777
-#define wxKeyEvent_ShiftDown 2778
-#define wxSizeEvent_GetSize 2779
-#define wxMoveEvent_GetPosition 2780
-#define wxEraseEvent_GetDC 2781
-#define wxFocusEvent_GetWindow 2782
-#define wxChildFocusEvent_GetWindow 2783
-#define wxMenuEvent_GetMenu 2784
-#define wxMenuEvent_GetMenuId 2785
-#define wxMenuEvent_IsPopup 2786
-#define wxCloseEvent_CanVeto 2787
-#define wxCloseEvent_GetLoggingOff 2788
-#define wxCloseEvent_SetCanVeto 2789
-#define wxCloseEvent_SetLoggingOff 2790
-#define wxCloseEvent_Veto 2791
-#define wxShowEvent_SetShow 2792
-#define wxShowEvent_GetShow 2793
-#define wxIconizeEvent_Iconized 2794
-#define wxJoystickEvent_ButtonDown 2795
-#define wxJoystickEvent_ButtonIsDown 2796
-#define wxJoystickEvent_ButtonUp 2797
-#define wxJoystickEvent_GetButtonChange 2798
-#define wxJoystickEvent_GetButtonState 2799
-#define wxJoystickEvent_GetJoystick 2800
-#define wxJoystickEvent_GetPosition 2801
-#define wxJoystickEvent_GetZPosition 2802
-#define wxJoystickEvent_IsButton 2803
-#define wxJoystickEvent_IsMove 2804
-#define wxJoystickEvent_IsZMove 2805
-#define wxUpdateUIEvent_CanUpdate 2806
-#define wxUpdateUIEvent_Check 2807
-#define wxUpdateUIEvent_Enable 2808
-#define wxUpdateUIEvent_Show 2809
-#define wxUpdateUIEvent_GetChecked 2810
-#define wxUpdateUIEvent_GetEnabled 2811
-#define wxUpdateUIEvent_GetShown 2812
-#define wxUpdateUIEvent_GetSetChecked 2813
-#define wxUpdateUIEvent_GetSetEnabled 2814
-#define wxUpdateUIEvent_GetSetShown 2815
-#define wxUpdateUIEvent_GetSetText 2816
-#define wxUpdateUIEvent_GetText 2817
-#define wxUpdateUIEvent_GetMode 2818
-#define wxUpdateUIEvent_GetUpdateInterval 2819
-#define wxUpdateUIEvent_ResetUpdateTime 2820
-#define wxUpdateUIEvent_SetMode 2821
-#define wxUpdateUIEvent_SetText 2822
-#define wxUpdateUIEvent_SetUpdateInterval 2823
-#define wxMouseCaptureChangedEvent_GetCapturedWindow 2824
-#define wxPaletteChangedEvent_SetChangedWindow 2825
-#define wxPaletteChangedEvent_GetChangedWindow 2826
-#define wxQueryNewPaletteEvent_SetPaletteRealized 2827
-#define wxQueryNewPaletteEvent_GetPaletteRealized 2828
-#define wxNavigationKeyEvent_GetDirection 2829
-#define wxNavigationKeyEvent_SetDirection 2830
-#define wxNavigationKeyEvent_IsWindowChange 2831
-#define wxNavigationKeyEvent_SetWindowChange 2832
-#define wxNavigationKeyEvent_IsFromTab 2833
-#define wxNavigationKeyEvent_SetFromTab 2834
-#define wxNavigationKeyEvent_GetCurrentFocus 2835
-#define wxNavigationKeyEvent_SetCurrentFocus 2836
-#define wxHelpEvent_GetOrigin 2837
-#define wxHelpEvent_GetPosition 2838
-#define wxHelpEvent_SetOrigin 2839
-#define wxHelpEvent_SetPosition 2840
-#define wxContextMenuEvent_GetPosition 2841
-#define wxContextMenuEvent_SetPosition 2842
-#define wxIdleEvent_CanSend 2843
-#define wxIdleEvent_GetMode 2844
-#define wxIdleEvent_RequestMore 2845
-#define wxIdleEvent_MoreRequested 2846
-#define wxIdleEvent_SetMode 2847
-#define wxGridEvent_AltDown 2848
-#define wxGridEvent_ControlDown 2849
-#define wxGridEvent_GetCol 2850
-#define wxGridEvent_GetPosition 2851
-#define wxGridEvent_GetRow 2852
-#define wxGridEvent_MetaDown 2853
-#define wxGridEvent_Selecting 2854
-#define wxGridEvent_ShiftDown 2855
-#define wxNotifyEvent_Allow 2856
-#define wxNotifyEvent_IsAllowed 2857
-#define wxNotifyEvent_Veto 2858
-#define wxSashEvent_GetEdge 2859
-#define wxSashEvent_GetDragRect 2860
-#define wxSashEvent_GetDragStatus 2861
-#define wxListEvent_GetCacheFrom 2862
-#define wxListEvent_GetCacheTo 2863
-#define wxListEvent_GetKeyCode 2864
-#define wxListEvent_GetIndex 2865
-#define wxListEvent_GetColumn 2866
-#define wxListEvent_GetPoint 2867
-#define wxListEvent_GetLabel 2868
-#define wxListEvent_GetText 2869
-#define wxListEvent_GetImage 2870
-#define wxListEvent_GetData 2871
-#define wxListEvent_GetMask 2872
-#define wxListEvent_GetItem 2873
-#define wxListEvent_IsEditCancelled 2874
-#define wxDateEvent_GetDate 2875
-#define wxCalendarEvent_GetWeekDay 2876
-#define wxFileDirPickerEvent_GetPath 2877
-#define wxColourPickerEvent_GetColour 2878
-#define wxFontPickerEvent_GetFont 2879
-#define wxStyledTextEvent_GetPosition 2880
-#define wxStyledTextEvent_GetKey 2881
-#define wxStyledTextEvent_GetModifiers 2882
-#define wxStyledTextEvent_GetModificationType 2883
-#define wxStyledTextEvent_GetText 2884
-#define wxStyledTextEvent_GetLength 2885
-#define wxStyledTextEvent_GetLinesAdded 2886
-#define wxStyledTextEvent_GetLine 2887
-#define wxStyledTextEvent_GetFoldLevelNow 2888
-#define wxStyledTextEvent_GetFoldLevelPrev 2889
-#define wxStyledTextEvent_GetMargin 2890
-#define wxStyledTextEvent_GetMessage 2891
-#define wxStyledTextEvent_GetWParam 2892
-#define wxStyledTextEvent_GetLParam 2893
-#define wxStyledTextEvent_GetListType 2894
-#define wxStyledTextEvent_GetX 2895
-#define wxStyledTextEvent_GetY 2896
-#define wxStyledTextEvent_GetDragText 2897
-#define wxStyledTextEvent_GetDragAllowMove 2898
-#define wxStyledTextEvent_GetDragResult 2899
-#define wxStyledTextEvent_GetShift 2900
-#define wxStyledTextEvent_GetControl 2901
-#define wxStyledTextEvent_GetAlt 2902
-#define utils_wxGetKeyState 2903
-#define utils_wxGetMousePosition 2904
-#define utils_wxGetMouseState 2905
-#define utils_wxSetDetectableAutoRepeat 2906
-#define utils_wxBell 2907
-#define utils_wxFindMenuItemId 2908
-#define utils_wxGenericFindWindowAtPoint 2909
-#define utils_wxFindWindowAtPoint 2910
-#define utils_wxBeginBusyCursor 2911
-#define utils_wxEndBusyCursor 2912
-#define utils_wxIsBusy 2913
-#define utils_wxShutdown 2914
-#define utils_wxShell 2915
-#define utils_wxLaunchDefaultBrowser 2916
-#define utils_wxGetEmailAddress 2917
-#define utils_wxGetUserId 2918
-#define utils_wxGetHomeDir 2919
-#define utils_wxNewId 2920
-#define utils_wxRegisterId 2921
-#define utils_wxGetCurrentId 2922
-#define utils_wxGetOsDescription 2923
-#define utils_wxIsPlatformLittleEndian 2924
-#define utils_wxIsPlatform64Bit 2925
-#define wxPrintout_new 2926
-#define wxPrintout_destruct 2927
-#define wxPrintout_GetDC 2928
-#define wxPrintout_GetPageSizeMM 2929
-#define wxPrintout_GetPageSizePixels 2930
-#define wxPrintout_GetPaperRectPixels 2931
-#define wxPrintout_GetPPIPrinter 2932
-#define wxPrintout_GetPPIScreen 2933
-#define wxPrintout_GetTitle 2934
-#define wxPrintout_IsPreview 2935
-#define wxPrintout_FitThisSizeToPaper 2936
-#define wxPrintout_FitThisSizeToPage 2937
-#define wxPrintout_FitThisSizeToPageMargins 2938
-#define wxPrintout_MapScreenSizeToPaper 2939
-#define wxPrintout_MapScreenSizeToPage 2940
-#define wxPrintout_MapScreenSizeToPageMargins 2941
-#define wxPrintout_MapScreenSizeToDevice 2942
-#define wxPrintout_GetLogicalPaperRect 2943
-#define wxPrintout_GetLogicalPageRect 2944
-#define wxPrintout_GetLogicalPageMarginsRect 2945
-#define wxPrintout_SetLogicalOrigin 2946
-#define wxPrintout_OffsetLogicalOrigin 2947
-#define wxStyledTextCtrl_new_2 2948
-#define wxStyledTextCtrl_new_0 2949
-#define wxStyledTextCtrl_destruct 2950
-#define wxStyledTextCtrl_Create 2951
-#define wxStyledTextCtrl_AddText 2952
-#define wxStyledTextCtrl_AddStyledText 2953
-#define wxStyledTextCtrl_InsertText 2954
-#define wxStyledTextCtrl_ClearAll 2955
-#define wxStyledTextCtrl_ClearDocumentStyle 2956
-#define wxStyledTextCtrl_GetLength 2957
-#define wxStyledTextCtrl_GetCharAt 2958
-#define wxStyledTextCtrl_GetCurrentPos 2959
-#define wxStyledTextCtrl_GetAnchor 2960
-#define wxStyledTextCtrl_GetStyleAt 2961
-#define wxStyledTextCtrl_Redo 2962
-#define wxStyledTextCtrl_SetUndoCollection 2963
-#define wxStyledTextCtrl_SelectAll 2964
-#define wxStyledTextCtrl_SetSavePoint 2965
-#define wxStyledTextCtrl_GetStyledText 2966
-#define wxStyledTextCtrl_CanRedo 2967
-#define wxStyledTextCtrl_MarkerLineFromHandle 2968
-#define wxStyledTextCtrl_MarkerDeleteHandle 2969
-#define wxStyledTextCtrl_GetUndoCollection 2970
-#define wxStyledTextCtrl_GetViewWhiteSpace 2971
-#define wxStyledTextCtrl_SetViewWhiteSpace 2972
-#define wxStyledTextCtrl_PositionFromPoint 2973
-#define wxStyledTextCtrl_PositionFromPointClose 2974
-#define wxStyledTextCtrl_GotoLine 2975
-#define wxStyledTextCtrl_GotoPos 2976
-#define wxStyledTextCtrl_SetAnchor 2977
-#define wxStyledTextCtrl_GetCurLine 2978
-#define wxStyledTextCtrl_GetEndStyled 2979
-#define wxStyledTextCtrl_ConvertEOLs 2980
-#define wxStyledTextCtrl_GetEOLMode 2981
-#define wxStyledTextCtrl_SetEOLMode 2982
-#define wxStyledTextCtrl_StartStyling 2983
-#define wxStyledTextCtrl_SetStyling 2984
-#define wxStyledTextCtrl_GetBufferedDraw 2985
-#define wxStyledTextCtrl_SetBufferedDraw 2986
-#define wxStyledTextCtrl_SetTabWidth 2987
-#define wxStyledTextCtrl_GetTabWidth 2988
-#define wxStyledTextCtrl_SetCodePage 2989
-#define wxStyledTextCtrl_MarkerDefine 2990
-#define wxStyledTextCtrl_MarkerSetForeground 2991
-#define wxStyledTextCtrl_MarkerSetBackground 2992
-#define wxStyledTextCtrl_MarkerAdd 2993
-#define wxStyledTextCtrl_MarkerDelete 2994
-#define wxStyledTextCtrl_MarkerDeleteAll 2995
-#define wxStyledTextCtrl_MarkerGet 2996
-#define wxStyledTextCtrl_MarkerNext 2997
-#define wxStyledTextCtrl_MarkerPrevious 2998
-#define wxStyledTextCtrl_MarkerDefineBitmap 2999
-#define wxStyledTextCtrl_MarkerAddSet 3000
-#define wxStyledTextCtrl_MarkerSetAlpha 3001
-#define wxStyledTextCtrl_SetMarginType 3002
-#define wxStyledTextCtrl_GetMarginType 3003
-#define wxStyledTextCtrl_SetMarginWidth 3004
-#define wxStyledTextCtrl_GetMarginWidth 3005
-#define wxStyledTextCtrl_SetMarginMask 3006
-#define wxStyledTextCtrl_GetMarginMask 3007
-#define wxStyledTextCtrl_SetMarginSensitive 3008
-#define wxStyledTextCtrl_GetMarginSensitive 3009
-#define wxStyledTextCtrl_StyleClearAll 3010
-#define wxStyledTextCtrl_StyleSetForeground 3011
-#define wxStyledTextCtrl_StyleSetBackground 3012
-#define wxStyledTextCtrl_StyleSetBold 3013
-#define wxStyledTextCtrl_StyleSetItalic 3014
-#define wxStyledTextCtrl_StyleSetSize 3015
-#define wxStyledTextCtrl_StyleSetFaceName 3016
-#define wxStyledTextCtrl_StyleSetEOLFilled 3017
-#define wxStyledTextCtrl_StyleResetDefault 3018
-#define wxStyledTextCtrl_StyleSetUnderline 3019
-#define wxStyledTextCtrl_StyleSetCase 3020
-#define wxStyledTextCtrl_StyleSetHotSpot 3021
-#define wxStyledTextCtrl_SetSelForeground 3022
-#define wxStyledTextCtrl_SetSelBackground 3023
-#define wxStyledTextCtrl_GetSelAlpha 3024
-#define wxStyledTextCtrl_SetSelAlpha 3025
-#define wxStyledTextCtrl_SetCaretForeground 3026
-#define wxStyledTextCtrl_CmdKeyAssign 3027
-#define wxStyledTextCtrl_CmdKeyClear 3028
-#define wxStyledTextCtrl_CmdKeyClearAll 3029
-#define wxStyledTextCtrl_SetStyleBytes 3030
-#define wxStyledTextCtrl_StyleSetVisible 3031
-#define wxStyledTextCtrl_GetCaretPeriod 3032
-#define wxStyledTextCtrl_SetCaretPeriod 3033
-#define wxStyledTextCtrl_SetWordChars 3034
-#define wxStyledTextCtrl_BeginUndoAction 3035
-#define wxStyledTextCtrl_EndUndoAction 3036
-#define wxStyledTextCtrl_IndicatorSetStyle 3037
-#define wxStyledTextCtrl_IndicatorGetStyle 3038
-#define wxStyledTextCtrl_IndicatorSetForeground 3039
-#define wxStyledTextCtrl_IndicatorGetForeground 3040
-#define wxStyledTextCtrl_SetWhitespaceForeground 3041
-#define wxStyledTextCtrl_SetWhitespaceBackground 3042
-#define wxStyledTextCtrl_GetStyleBits 3043
-#define wxStyledTextCtrl_SetLineState 3044
-#define wxStyledTextCtrl_GetLineState 3045
-#define wxStyledTextCtrl_GetMaxLineState 3046
-#define wxStyledTextCtrl_GetCaretLineVisible 3047
-#define wxStyledTextCtrl_SetCaretLineVisible 3048
-#define wxStyledTextCtrl_GetCaretLineBackground 3049
-#define wxStyledTextCtrl_SetCaretLineBackground 3050
-#define wxStyledTextCtrl_AutoCompShow 3051
-#define wxStyledTextCtrl_AutoCompCancel 3052
-#define wxStyledTextCtrl_AutoCompActive 3053
-#define wxStyledTextCtrl_AutoCompPosStart 3054
-#define wxStyledTextCtrl_AutoCompComplete 3055
-#define wxStyledTextCtrl_AutoCompStops 3056
-#define wxStyledTextCtrl_AutoCompSetSeparator 3057
-#define wxStyledTextCtrl_AutoCompGetSeparator 3058
-#define wxStyledTextCtrl_AutoCompSelect 3059
-#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3060
-#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3061
-#define wxStyledTextCtrl_AutoCompSetFillUps 3062
-#define wxStyledTextCtrl_AutoCompSetChooseSingle 3063
-#define wxStyledTextCtrl_AutoCompGetChooseSingle 3064
-#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3065
-#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3066
-#define wxStyledTextCtrl_UserListShow 3067
-#define wxStyledTextCtrl_AutoCompSetAutoHide 3068
-#define wxStyledTextCtrl_AutoCompGetAutoHide 3069
-#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3070
-#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3071
-#define wxStyledTextCtrl_RegisterImage 3072
-#define wxStyledTextCtrl_ClearRegisteredImages 3073
-#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3074
-#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3075
-#define wxStyledTextCtrl_AutoCompSetMaxWidth 3076
-#define wxStyledTextCtrl_AutoCompGetMaxWidth 3077
-#define wxStyledTextCtrl_AutoCompSetMaxHeight 3078
-#define wxStyledTextCtrl_AutoCompGetMaxHeight 3079
-#define wxStyledTextCtrl_SetIndent 3080
-#define wxStyledTextCtrl_GetIndent 3081
-#define wxStyledTextCtrl_SetUseTabs 3082
-#define wxStyledTextCtrl_GetUseTabs 3083
-#define wxStyledTextCtrl_SetLineIndentation 3084
-#define wxStyledTextCtrl_GetLineIndentation 3085
-#define wxStyledTextCtrl_GetLineIndentPosition 3086
-#define wxStyledTextCtrl_GetColumn 3087
-#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3088
-#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3089
-#define wxStyledTextCtrl_SetIndentationGuides 3090
-#define wxStyledTextCtrl_GetIndentationGuides 3091
-#define wxStyledTextCtrl_SetHighlightGuide 3092
-#define wxStyledTextCtrl_GetHighlightGuide 3093
-#define wxStyledTextCtrl_GetLineEndPosition 3094
-#define wxStyledTextCtrl_GetCodePage 3095
-#define wxStyledTextCtrl_GetCaretForeground 3096
-#define wxStyledTextCtrl_GetReadOnly 3097
-#define wxStyledTextCtrl_SetCurrentPos 3098
-#define wxStyledTextCtrl_SetSelectionStart 3099
-#define wxStyledTextCtrl_GetSelectionStart 3100
-#define wxStyledTextCtrl_SetSelectionEnd 3101
-#define wxStyledTextCtrl_GetSelectionEnd 3102
-#define wxStyledTextCtrl_SetPrintMagnification 3103
-#define wxStyledTextCtrl_GetPrintMagnification 3104
-#define wxStyledTextCtrl_SetPrintColourMode 3105
-#define wxStyledTextCtrl_GetPrintColourMode 3106
-#define wxStyledTextCtrl_FindText 3107
-#define wxStyledTextCtrl_FormatRange 3108
-#define wxStyledTextCtrl_GetFirstVisibleLine 3109
-#define wxStyledTextCtrl_GetLine 3110
-#define wxStyledTextCtrl_GetLineCount 3111
-#define wxStyledTextCtrl_SetMarginLeft 3112
-#define wxStyledTextCtrl_GetMarginLeft 3113
-#define wxStyledTextCtrl_SetMarginRight 3114
-#define wxStyledTextCtrl_GetMarginRight 3115
-#define wxStyledTextCtrl_GetModify 3116
-#define wxStyledTextCtrl_SetSelection 3117
-#define wxStyledTextCtrl_GetSelectedText 3118
-#define wxStyledTextCtrl_GetTextRange 3119
-#define wxStyledTextCtrl_HideSelection 3120
-#define wxStyledTextCtrl_LineFromPosition 3121
-#define wxStyledTextCtrl_PositionFromLine 3122
-#define wxStyledTextCtrl_LineScroll 3123
-#define wxStyledTextCtrl_EnsureCaretVisible 3124
-#define wxStyledTextCtrl_ReplaceSelection 3125
-#define wxStyledTextCtrl_SetReadOnly 3126
-#define wxStyledTextCtrl_CanPaste 3127
-#define wxStyledTextCtrl_CanUndo 3128
-#define wxStyledTextCtrl_EmptyUndoBuffer 3129
-#define wxStyledTextCtrl_Undo 3130
-#define wxStyledTextCtrl_Cut 3131
-#define wxStyledTextCtrl_Copy 3132
-#define wxStyledTextCtrl_Paste 3133
-#define wxStyledTextCtrl_Clear 3134
-#define wxStyledTextCtrl_SetText 3135
-#define wxStyledTextCtrl_GetText 3136
-#define wxStyledTextCtrl_GetTextLength 3137
-#define wxStyledTextCtrl_GetOvertype 3138
-#define wxStyledTextCtrl_SetCaretWidth 3139
-#define wxStyledTextCtrl_GetCaretWidth 3140
-#define wxStyledTextCtrl_SetTargetStart 3141
-#define wxStyledTextCtrl_GetTargetStart 3142
-#define wxStyledTextCtrl_SetTargetEnd 3143
-#define wxStyledTextCtrl_GetTargetEnd 3144
-#define wxStyledTextCtrl_ReplaceTarget 3145
-#define wxStyledTextCtrl_SearchInTarget 3146
-#define wxStyledTextCtrl_SetSearchFlags 3147
-#define wxStyledTextCtrl_GetSearchFlags 3148
-#define wxStyledTextCtrl_CallTipShow 3149
-#define wxStyledTextCtrl_CallTipCancel 3150
-#define wxStyledTextCtrl_CallTipActive 3151
-#define wxStyledTextCtrl_CallTipPosAtStart 3152
-#define wxStyledTextCtrl_CallTipSetHighlight 3153
-#define wxStyledTextCtrl_CallTipSetBackground 3154
-#define wxStyledTextCtrl_CallTipSetForeground 3155
-#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3156
-#define wxStyledTextCtrl_CallTipUseStyle 3157
-#define wxStyledTextCtrl_VisibleFromDocLine 3158
-#define wxStyledTextCtrl_DocLineFromVisible 3159
-#define wxStyledTextCtrl_WrapCount 3160
-#define wxStyledTextCtrl_SetFoldLevel 3161
-#define wxStyledTextCtrl_GetFoldLevel 3162
-#define wxStyledTextCtrl_GetLastChild 3163
-#define wxStyledTextCtrl_GetFoldParent 3164
-#define wxStyledTextCtrl_ShowLines 3165
-#define wxStyledTextCtrl_HideLines 3166
-#define wxStyledTextCtrl_GetLineVisible 3167
-#define wxStyledTextCtrl_SetFoldExpanded 3168
-#define wxStyledTextCtrl_GetFoldExpanded 3169
-#define wxStyledTextCtrl_ToggleFold 3170
-#define wxStyledTextCtrl_EnsureVisible 3171
-#define wxStyledTextCtrl_SetFoldFlags 3172
-#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3173
-#define wxStyledTextCtrl_SetTabIndents 3174
-#define wxStyledTextCtrl_GetTabIndents 3175
-#define wxStyledTextCtrl_SetBackSpaceUnIndents 3176
-#define wxStyledTextCtrl_GetBackSpaceUnIndents 3177
-#define wxStyledTextCtrl_SetMouseDwellTime 3178
-#define wxStyledTextCtrl_GetMouseDwellTime 3179
-#define wxStyledTextCtrl_WordStartPosition 3180
-#define wxStyledTextCtrl_WordEndPosition 3181
-#define wxStyledTextCtrl_SetWrapMode 3182
-#define wxStyledTextCtrl_GetWrapMode 3183
-#define wxStyledTextCtrl_SetWrapVisualFlags 3184
-#define wxStyledTextCtrl_GetWrapVisualFlags 3185
-#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3186
-#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3187
-#define wxStyledTextCtrl_SetWrapStartIndent 3188
-#define wxStyledTextCtrl_GetWrapStartIndent 3189
-#define wxStyledTextCtrl_SetLayoutCache 3190
-#define wxStyledTextCtrl_GetLayoutCache 3191
-#define wxStyledTextCtrl_SetScrollWidth 3192
-#define wxStyledTextCtrl_GetScrollWidth 3193
-#define wxStyledTextCtrl_TextWidth 3194
-#define wxStyledTextCtrl_GetEndAtLastLine 3195
-#define wxStyledTextCtrl_TextHeight 3196
-#define wxStyledTextCtrl_SetUseVerticalScrollBar 3197
-#define wxStyledTextCtrl_GetUseVerticalScrollBar 3198
-#define wxStyledTextCtrl_AppendText 3199
-#define wxStyledTextCtrl_GetTwoPhaseDraw 3200
-#define wxStyledTextCtrl_SetTwoPhaseDraw 3201
-#define wxStyledTextCtrl_TargetFromSelection 3202
-#define wxStyledTextCtrl_LinesJoin 3203
-#define wxStyledTextCtrl_LinesSplit 3204
-#define wxStyledTextCtrl_SetFoldMarginColour 3205
-#define wxStyledTextCtrl_SetFoldMarginHiColour 3206
-#define wxStyledTextCtrl_LineDown 3207
-#define wxStyledTextCtrl_LineDownExtend 3208
-#define wxStyledTextCtrl_LineUp 3209
-#define wxStyledTextCtrl_LineUpExtend 3210
-#define wxStyledTextCtrl_CharLeft 3211
-#define wxStyledTextCtrl_CharLeftExtend 3212
-#define wxStyledTextCtrl_CharRight 3213
-#define wxStyledTextCtrl_CharRightExtend 3214
-#define wxStyledTextCtrl_WordLeft 3215
-#define wxStyledTextCtrl_WordLeftExtend 3216
-#define wxStyledTextCtrl_WordRight 3217
-#define wxStyledTextCtrl_WordRightExtend 3218
-#define wxStyledTextCtrl_Home 3219
-#define wxStyledTextCtrl_HomeExtend 3220
-#define wxStyledTextCtrl_LineEnd 3221
-#define wxStyledTextCtrl_LineEndExtend 3222
-#define wxStyledTextCtrl_DocumentStart 3223
-#define wxStyledTextCtrl_DocumentStartExtend 3224
-#define wxStyledTextCtrl_DocumentEnd 3225
-#define wxStyledTextCtrl_DocumentEndExtend 3226
-#define wxStyledTextCtrl_PageUp 3227
-#define wxStyledTextCtrl_PageUpExtend 3228
-#define wxStyledTextCtrl_PageDown 3229
-#define wxStyledTextCtrl_PageDownExtend 3230
-#define wxStyledTextCtrl_EditToggleOvertype 3231
-#define wxStyledTextCtrl_Cancel 3232
-#define wxStyledTextCtrl_DeleteBack 3233
-#define wxStyledTextCtrl_Tab 3234
-#define wxStyledTextCtrl_BackTab 3235
-#define wxStyledTextCtrl_NewLine 3236
-#define wxStyledTextCtrl_FormFeed 3237
-#define wxStyledTextCtrl_VCHome 3238
-#define wxStyledTextCtrl_VCHomeExtend 3239
-#define wxStyledTextCtrl_ZoomIn 3240
-#define wxStyledTextCtrl_ZoomOut 3241
-#define wxStyledTextCtrl_DelWordLeft 3242
-#define wxStyledTextCtrl_DelWordRight 3243
-#define wxStyledTextCtrl_LineCut 3244
-#define wxStyledTextCtrl_LineDelete 3245
-#define wxStyledTextCtrl_LineTranspose 3246
-#define wxStyledTextCtrl_LineDuplicate 3247
-#define wxStyledTextCtrl_LowerCase 3248
-#define wxStyledTextCtrl_UpperCase 3249
-#define wxStyledTextCtrl_LineScrollDown 3250
-#define wxStyledTextCtrl_LineScrollUp 3251
-#define wxStyledTextCtrl_DeleteBackNotLine 3252
-#define wxStyledTextCtrl_HomeDisplay 3253
-#define wxStyledTextCtrl_HomeDisplayExtend 3254
-#define wxStyledTextCtrl_LineEndDisplay 3255
-#define wxStyledTextCtrl_LineEndDisplayExtend 3256
-#define wxStyledTextCtrl_HomeWrapExtend 3257
-#define wxStyledTextCtrl_LineEndWrap 3258
-#define wxStyledTextCtrl_LineEndWrapExtend 3259
-#define wxStyledTextCtrl_VCHomeWrap 3260
-#define wxStyledTextCtrl_VCHomeWrapExtend 3261
-#define wxStyledTextCtrl_LineCopy 3262
-#define wxStyledTextCtrl_MoveCaretInsideView 3263
-#define wxStyledTextCtrl_LineLength 3264
-#define wxStyledTextCtrl_BraceHighlight 3265
-#define wxStyledTextCtrl_BraceBadLight 3266
-#define wxStyledTextCtrl_BraceMatch 3267
-#define wxStyledTextCtrl_GetViewEOL 3268
-#define wxStyledTextCtrl_SetViewEOL 3269
-#define wxStyledTextCtrl_SetModEventMask 3270
-#define wxStyledTextCtrl_GetEdgeColumn 3271
-#define wxStyledTextCtrl_SetEdgeColumn 3272
-#define wxStyledTextCtrl_SetEdgeMode 3273
-#define wxStyledTextCtrl_GetEdgeMode 3274
-#define wxStyledTextCtrl_GetEdgeColour 3275
-#define wxStyledTextCtrl_SetEdgeColour 3276
-#define wxStyledTextCtrl_SearchAnchor 3277
-#define wxStyledTextCtrl_SearchNext 3278
-#define wxStyledTextCtrl_SearchPrev 3279
-#define wxStyledTextCtrl_LinesOnScreen 3280
-#define wxStyledTextCtrl_UsePopUp 3281
-#define wxStyledTextCtrl_SelectionIsRectangle 3282
-#define wxStyledTextCtrl_SetZoom 3283
-#define wxStyledTextCtrl_GetZoom 3284
-#define wxStyledTextCtrl_GetModEventMask 3285
-#define wxStyledTextCtrl_SetSTCFocus 3286
-#define wxStyledTextCtrl_GetSTCFocus 3287
-#define wxStyledTextCtrl_SetStatus 3288
-#define wxStyledTextCtrl_GetStatus 3289
-#define wxStyledTextCtrl_SetMouseDownCaptures 3290
-#define wxStyledTextCtrl_GetMouseDownCaptures 3291
-#define wxStyledTextCtrl_SetSTCCursor 3292
-#define wxStyledTextCtrl_GetSTCCursor 3293
-#define wxStyledTextCtrl_SetControlCharSymbol 3294
-#define wxStyledTextCtrl_GetControlCharSymbol 3295
-#define wxStyledTextCtrl_WordPartLeft 3296
-#define wxStyledTextCtrl_WordPartLeftExtend 3297
-#define wxStyledTextCtrl_WordPartRight 3298
-#define wxStyledTextCtrl_WordPartRightExtend 3299
-#define wxStyledTextCtrl_SetVisiblePolicy 3300
-#define wxStyledTextCtrl_DelLineLeft 3301
-#define wxStyledTextCtrl_DelLineRight 3302
-#define wxStyledTextCtrl_GetXOffset 3303
-#define wxStyledTextCtrl_ChooseCaretX 3304
-#define wxStyledTextCtrl_SetXCaretPolicy 3305
-#define wxStyledTextCtrl_SetYCaretPolicy 3306
-#define wxStyledTextCtrl_GetPrintWrapMode 3307
-#define wxStyledTextCtrl_SetHotspotActiveForeground 3308
-#define wxStyledTextCtrl_SetHotspotActiveBackground 3309
-#define wxStyledTextCtrl_SetHotspotActiveUnderline 3310
-#define wxStyledTextCtrl_SetHotspotSingleLine 3311
-#define wxStyledTextCtrl_ParaDownExtend 3312
-#define wxStyledTextCtrl_ParaUp 3313
-#define wxStyledTextCtrl_ParaUpExtend 3314
-#define wxStyledTextCtrl_PositionBefore 3315
-#define wxStyledTextCtrl_PositionAfter 3316
-#define wxStyledTextCtrl_CopyRange 3317
-#define wxStyledTextCtrl_CopyText 3318
-#define wxStyledTextCtrl_SetSelectionMode 3319
-#define wxStyledTextCtrl_GetSelectionMode 3320
-#define wxStyledTextCtrl_LineDownRectExtend 3321
-#define wxStyledTextCtrl_LineUpRectExtend 3322
-#define wxStyledTextCtrl_CharLeftRectExtend 3323
-#define wxStyledTextCtrl_CharRightRectExtend 3324
-#define wxStyledTextCtrl_HomeRectExtend 3325
-#define wxStyledTextCtrl_VCHomeRectExtend 3326
-#define wxStyledTextCtrl_LineEndRectExtend 3327
-#define wxStyledTextCtrl_PageUpRectExtend 3328
-#define wxStyledTextCtrl_PageDownRectExtend 3329
-#define wxStyledTextCtrl_StutteredPageUp 3330
-#define wxStyledTextCtrl_StutteredPageUpExtend 3331
-#define wxStyledTextCtrl_StutteredPageDown 3332
-#define wxStyledTextCtrl_StutteredPageDownExtend 3333
-#define wxStyledTextCtrl_WordLeftEnd 3334
-#define wxStyledTextCtrl_WordLeftEndExtend 3335
-#define wxStyledTextCtrl_WordRightEnd 3336
-#define wxStyledTextCtrl_WordRightEndExtend 3337
-#define wxStyledTextCtrl_SetWhitespaceChars 3338
-#define wxStyledTextCtrl_SetCharsDefault 3339
-#define wxStyledTextCtrl_AutoCompGetCurrent 3340
-#define wxStyledTextCtrl_Allocate 3341
-#define wxStyledTextCtrl_FindColumn 3342
-#define wxStyledTextCtrl_GetCaretSticky 3343
-#define wxStyledTextCtrl_SetCaretSticky 3344
-#define wxStyledTextCtrl_ToggleCaretSticky 3345
-#define wxStyledTextCtrl_SetPasteConvertEndings 3346
-#define wxStyledTextCtrl_GetPasteConvertEndings 3347
-#define wxStyledTextCtrl_SelectionDuplicate 3348
-#define wxStyledTextCtrl_SetCaretLineBackAlpha 3349
-#define wxStyledTextCtrl_GetCaretLineBackAlpha 3350
-#define wxStyledTextCtrl_StartRecord 3351
-#define wxStyledTextCtrl_StopRecord 3352
-#define wxStyledTextCtrl_SetLexer 3353
-#define wxStyledTextCtrl_GetLexer 3354
-#define wxStyledTextCtrl_Colourise 3355
-#define wxStyledTextCtrl_SetProperty 3356
-#define wxStyledTextCtrl_SetKeyWords 3357
-#define wxStyledTextCtrl_SetLexerLanguage 3358
-#define wxStyledTextCtrl_GetProperty 3359
-#define wxStyledTextCtrl_GetStyleBitsNeeded 3360
-#define wxStyledTextCtrl_GetCurrentLine 3361
-#define wxStyledTextCtrl_StyleSetSpec 3362
-#define wxStyledTextCtrl_StyleSetFont 3363
-#define wxStyledTextCtrl_StyleSetFontAttr 3364
-#define wxStyledTextCtrl_StyleSetCharacterSet 3365
-#define wxStyledTextCtrl_StyleSetFontEncoding 3366
-#define wxStyledTextCtrl_CmdKeyExecute 3367
-#define wxStyledTextCtrl_SetMargins 3368
-#define wxStyledTextCtrl_GetSelection 3369
-#define wxStyledTextCtrl_PointFromPosition 3370
-#define wxStyledTextCtrl_ScrollToLine 3371
-#define wxStyledTextCtrl_ScrollToColumn 3372
-#define wxStyledTextCtrl_SetVScrollBar 3373
-#define wxStyledTextCtrl_SetHScrollBar 3374
-#define wxStyledTextCtrl_GetLastKeydownProcessed 3375
-#define wxStyledTextCtrl_SetLastKeydownProcessed 3376
-#define wxStyledTextCtrl_SaveFile 3377
-#define wxStyledTextCtrl_LoadFile 3378
-#define wxStyledTextCtrl_DoDragOver 3379
-#define wxStyledTextCtrl_DoDropText 3380
-#define wxStyledTextCtrl_GetUseAntiAliasing 3381
-#define wxStyledTextCtrl_AddTextRaw 3382
-#define wxStyledTextCtrl_InsertTextRaw 3383
-#define wxStyledTextCtrl_GetCurLineRaw 3384
-#define wxStyledTextCtrl_GetLineRaw 3385
-#define wxStyledTextCtrl_GetSelectedTextRaw 3386
-#define wxStyledTextCtrl_GetTextRangeRaw 3387
-#define wxStyledTextCtrl_SetTextRaw 3388
-#define wxStyledTextCtrl_GetTextRaw 3389
-#define wxStyledTextCtrl_AppendTextRaw 3390
-#define wxArtProvider_GetBitmap 3391
-#define wxArtProvider_GetIcon 3392
-#define wxTreeEvent_GetKeyCode 3393
-#define wxTreeEvent_GetItem 3394
-#define wxTreeEvent_GetKeyEvent 3395
-#define wxTreeEvent_GetLabel 3396
-#define wxTreeEvent_GetOldItem 3397
-#define wxTreeEvent_GetPoint 3398
-#define wxTreeEvent_IsEditCancelled 3399
-#define wxTreeEvent_SetToolTip 3400
-#define wxNotebookEvent_GetOldSelection 3401
-#define wxNotebookEvent_GetSelection 3402
-#define wxNotebookEvent_SetOldSelection 3403
-#define wxNotebookEvent_SetSelection 3404
-#define wxFileDataObject_new 3405
-#define wxFileDataObject_AddFile 3406
-#define wxFileDataObject_GetFilenames 3407
-#define wxFileDataObject_destroy 3408
-#define wxTextDataObject_new 3409
-#define wxTextDataObject_GetTextLength 3410
-#define wxTextDataObject_GetText 3411
-#define wxTextDataObject_SetText 3412
-#define wxTextDataObject_destroy 3413
-#define wxBitmapDataObject_new_1_1 3414
-#define wxBitmapDataObject_new_1_0 3415
-#define wxBitmapDataObject_GetBitmap 3416
-#define wxBitmapDataObject_SetBitmap 3417
-#define wxBitmapDataObject_destroy 3418
-#define wxClipboard_new 3420
-#define wxClipboard_destruct 3421
-#define wxClipboard_AddData 3422
-#define wxClipboard_Clear 3423
-#define wxClipboard_Close 3424
-#define wxClipboard_Flush 3425
-#define wxClipboard_GetData 3426
-#define wxClipboard_IsOpened 3427
-#define wxClipboard_Open 3428
-#define wxClipboard_SetData 3429
-#define wxClipboard_UsePrimarySelection 3431
-#define wxClipboard_IsSupported 3432
-#define wxClipboard_Get 3433
-#define wxSpinEvent_GetPosition 3434
-#define wxSpinEvent_SetPosition 3435
-#define wxSplitterWindow_new_0 3436
-#define wxSplitterWindow_new_2 3437
-#define wxSplitterWindow_destruct 3438
-#define wxSplitterWindow_Create 3439
-#define wxSplitterWindow_GetMinimumPaneSize 3440
-#define wxSplitterWindow_GetSashGravity 3441
-#define wxSplitterWindow_GetSashPosition 3442
-#define wxSplitterWindow_GetSplitMode 3443
-#define wxSplitterWindow_GetWindow1 3444
-#define wxSplitterWindow_GetWindow2 3445
-#define wxSplitterWindow_Initialize 3446
-#define wxSplitterWindow_IsSplit 3447
-#define wxSplitterWindow_ReplaceWindow 3448
-#define wxSplitterWindow_SetSashGravity 3449
-#define wxSplitterWindow_SetSashPosition 3450
-#define wxSplitterWindow_SetSashSize 3451
-#define wxSplitterWindow_SetMinimumPaneSize 3452
-#define wxSplitterWindow_SetSplitMode 3453
-#define wxSplitterWindow_SplitHorizontally 3454
-#define wxSplitterWindow_SplitVertically 3455
-#define wxSplitterWindow_Unsplit 3456
-#define wxSplitterWindow_UpdateSize 3457
-#define wxSplitterEvent_GetSashPosition 3458
-#define wxSplitterEvent_GetX 3459
-#define wxSplitterEvent_GetY 3460
-#define wxSplitterEvent_GetWindowBeingRemoved 3461
-#define wxSplitterEvent_SetSashPosition 3462
-#define wxHtmlWindow_new_0 3463
-#define wxHtmlWindow_new_2 3464
-#define wxHtmlWindow_AppendToPage 3465
-#define wxHtmlWindow_GetOpenedAnchor 3466
-#define wxHtmlWindow_GetOpenedPage 3467
-#define wxHtmlWindow_GetOpenedPageTitle 3468
-#define wxHtmlWindow_GetRelatedFrame 3469
-#define wxHtmlWindow_HistoryBack 3470
-#define wxHtmlWindow_HistoryCanBack 3471
-#define wxHtmlWindow_HistoryCanForward 3472
-#define wxHtmlWindow_HistoryClear 3473
-#define wxHtmlWindow_HistoryForward 3474
-#define wxHtmlWindow_LoadFile 3475
-#define wxHtmlWindow_LoadPage 3476
-#define wxHtmlWindow_SelectAll 3477
-#define wxHtmlWindow_SelectionToText 3478
-#define wxHtmlWindow_SelectLine 3479
-#define wxHtmlWindow_SelectWord 3480
-#define wxHtmlWindow_SetBorders 3481
-#define wxHtmlWindow_SetFonts 3482
-#define wxHtmlWindow_SetPage 3483
-#define wxHtmlWindow_SetRelatedFrame 3484
-#define wxHtmlWindow_SetRelatedStatusBar 3485
-#define wxHtmlWindow_ToText 3486
-#define wxHtmlWindow_destroy 3487
-#define wxHtmlLinkEvent_GetLinkInfo 3488
-#define wxSystemSettings_GetColour 3489
-#define wxSystemSettings_GetFont 3490
-#define wxSystemSettings_GetMetric 3491
-#define wxSystemSettings_GetScreenType 3492
-#define wxSystemOptions_GetOption 3493
-#define wxSystemOptions_GetOptionInt 3494
-#define wxSystemOptions_HasOption 3495
-#define wxSystemOptions_IsFalse 3496
-#define wxSystemOptions_SetOption_2_1 3497
-#define wxSystemOptions_SetOption_2_0 3498
-#define wxAuiNotebookEvent_SetSelection 3499
-#define wxAuiNotebookEvent_GetSelection 3500
-#define wxAuiNotebookEvent_SetOldSelection 3501
-#define wxAuiNotebookEvent_GetOldSelection 3502
-#define wxAuiNotebookEvent_SetDragSource 3503
-#define wxAuiNotebookEvent_GetDragSource 3504
-#define wxAuiManagerEvent_SetManager 3505
-#define wxAuiManagerEvent_GetManager 3506
-#define wxAuiManagerEvent_SetPane 3507
-#define wxAuiManagerEvent_GetPane 3508
-#define wxAuiManagerEvent_SetButton 3509
-#define wxAuiManagerEvent_GetButton 3510
-#define wxAuiManagerEvent_SetDC 3511
-#define wxAuiManagerEvent_GetDC 3512
-#define wxAuiManagerEvent_Veto 3513
-#define wxAuiManagerEvent_GetVeto 3514
-#define wxAuiManagerEvent_SetCanVeto 3515
-#define wxAuiManagerEvent_CanVeto 3516
-#define wxLogNull_new 3517
-#define wxLogNull_destroy 3518
-#define wxTaskBarIcon_new 3519
-#define wxTaskBarIcon_destruct 3520
-#define wxTaskBarIcon_PopupMenu 3521
-#define wxTaskBarIcon_RemoveIcon 3522
-#define wxTaskBarIcon_SetIcon 3523
+#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 wxPrintout_new 2927
+#define wxPrintout_destruct 2928
+#define wxPrintout_GetDC 2929
+#define wxPrintout_GetPageSizeMM 2930
+#define wxPrintout_GetPageSizePixels 2931
+#define wxPrintout_GetPaperRectPixels 2932
+#define wxPrintout_GetPPIPrinter 2933
+#define wxPrintout_GetPPIScreen 2934
+#define wxPrintout_GetTitle 2935
+#define wxPrintout_IsPreview 2936
+#define wxPrintout_FitThisSizeToPaper 2937
+#define wxPrintout_FitThisSizeToPage 2938
+#define wxPrintout_FitThisSizeToPageMargins 2939
+#define wxPrintout_MapScreenSizeToPaper 2940
+#define wxPrintout_MapScreenSizeToPage 2941
+#define wxPrintout_MapScreenSizeToPageMargins 2942
+#define wxPrintout_MapScreenSizeToDevice 2943
+#define wxPrintout_GetLogicalPaperRect 2944
+#define wxPrintout_GetLogicalPageRect 2945
+#define wxPrintout_GetLogicalPageMarginsRect 2946
+#define wxPrintout_SetLogicalOrigin 2947
+#define wxPrintout_OffsetLogicalOrigin 2948
+#define wxStyledTextCtrl_new_2 2949
+#define wxStyledTextCtrl_new_0 2950
+#define wxStyledTextCtrl_destruct 2951
+#define wxStyledTextCtrl_Create 2952
+#define wxStyledTextCtrl_AddText 2953
+#define wxStyledTextCtrl_AddStyledText 2954
+#define wxStyledTextCtrl_InsertText 2955
+#define wxStyledTextCtrl_ClearAll 2956
+#define wxStyledTextCtrl_ClearDocumentStyle 2957
+#define wxStyledTextCtrl_GetLength 2958
+#define wxStyledTextCtrl_GetCharAt 2959
+#define wxStyledTextCtrl_GetCurrentPos 2960
+#define wxStyledTextCtrl_GetAnchor 2961
+#define wxStyledTextCtrl_GetStyleAt 2962
+#define wxStyledTextCtrl_Redo 2963
+#define wxStyledTextCtrl_SetUndoCollection 2964
+#define wxStyledTextCtrl_SelectAll 2965
+#define wxStyledTextCtrl_SetSavePoint 2966
+#define wxStyledTextCtrl_GetStyledText 2967
+#define wxStyledTextCtrl_CanRedo 2968
+#define wxStyledTextCtrl_MarkerLineFromHandle 2969
+#define wxStyledTextCtrl_MarkerDeleteHandle 2970
+#define wxStyledTextCtrl_GetUndoCollection 2971
+#define wxStyledTextCtrl_GetViewWhiteSpace 2972
+#define wxStyledTextCtrl_SetViewWhiteSpace 2973
+#define wxStyledTextCtrl_PositionFromPoint 2974
+#define wxStyledTextCtrl_PositionFromPointClose 2975
+#define wxStyledTextCtrl_GotoLine 2976
+#define wxStyledTextCtrl_GotoPos 2977
+#define wxStyledTextCtrl_SetAnchor 2978
+#define wxStyledTextCtrl_GetCurLine 2979
+#define wxStyledTextCtrl_GetEndStyled 2980
+#define wxStyledTextCtrl_ConvertEOLs 2981
+#define wxStyledTextCtrl_GetEOLMode 2982
+#define wxStyledTextCtrl_SetEOLMode 2983
+#define wxStyledTextCtrl_StartStyling 2984
+#define wxStyledTextCtrl_SetStyling 2985
+#define wxStyledTextCtrl_GetBufferedDraw 2986
+#define wxStyledTextCtrl_SetBufferedDraw 2987
+#define wxStyledTextCtrl_SetTabWidth 2988
+#define wxStyledTextCtrl_GetTabWidth 2989
+#define wxStyledTextCtrl_SetCodePage 2990
+#define wxStyledTextCtrl_MarkerDefine 2991
+#define wxStyledTextCtrl_MarkerSetForeground 2992
+#define wxStyledTextCtrl_MarkerSetBackground 2993
+#define wxStyledTextCtrl_MarkerAdd 2994
+#define wxStyledTextCtrl_MarkerDelete 2995
+#define wxStyledTextCtrl_MarkerDeleteAll 2996
+#define wxStyledTextCtrl_MarkerGet 2997
+#define wxStyledTextCtrl_MarkerNext 2998
+#define wxStyledTextCtrl_MarkerPrevious 2999
+#define wxStyledTextCtrl_MarkerDefineBitmap 3000
+#define wxStyledTextCtrl_MarkerAddSet 3001
+#define wxStyledTextCtrl_MarkerSetAlpha 3002
+#define wxStyledTextCtrl_SetMarginType 3003
+#define wxStyledTextCtrl_GetMarginType 3004
+#define wxStyledTextCtrl_SetMarginWidth 3005
+#define wxStyledTextCtrl_GetMarginWidth 3006
+#define wxStyledTextCtrl_SetMarginMask 3007
+#define wxStyledTextCtrl_GetMarginMask 3008
+#define wxStyledTextCtrl_SetMarginSensitive 3009
+#define wxStyledTextCtrl_GetMarginSensitive 3010
+#define wxStyledTextCtrl_StyleClearAll 3011
+#define wxStyledTextCtrl_StyleSetForeground 3012
+#define wxStyledTextCtrl_StyleSetBackground 3013
+#define wxStyledTextCtrl_StyleSetBold 3014
+#define wxStyledTextCtrl_StyleSetItalic 3015
+#define wxStyledTextCtrl_StyleSetSize 3016
+#define wxStyledTextCtrl_StyleSetFaceName 3017
+#define wxStyledTextCtrl_StyleSetEOLFilled 3018
+#define wxStyledTextCtrl_StyleResetDefault 3019
+#define wxStyledTextCtrl_StyleSetUnderline 3020
+#define wxStyledTextCtrl_StyleSetCase 3021
+#define wxStyledTextCtrl_StyleSetHotSpot 3022
+#define wxStyledTextCtrl_SetSelForeground 3023
+#define wxStyledTextCtrl_SetSelBackground 3024
+#define wxStyledTextCtrl_GetSelAlpha 3025
+#define wxStyledTextCtrl_SetSelAlpha 3026
+#define wxStyledTextCtrl_SetCaretForeground 3027
+#define wxStyledTextCtrl_CmdKeyAssign 3028
+#define wxStyledTextCtrl_CmdKeyClear 3029
+#define wxStyledTextCtrl_CmdKeyClearAll 3030
+#define wxStyledTextCtrl_SetStyleBytes 3031
+#define wxStyledTextCtrl_StyleSetVisible 3032
+#define wxStyledTextCtrl_GetCaretPeriod 3033
+#define wxStyledTextCtrl_SetCaretPeriod 3034
+#define wxStyledTextCtrl_SetWordChars 3035
+#define wxStyledTextCtrl_BeginUndoAction 3036
+#define wxStyledTextCtrl_EndUndoAction 3037
+#define wxStyledTextCtrl_IndicatorSetStyle 3038
+#define wxStyledTextCtrl_IndicatorGetStyle 3039
+#define wxStyledTextCtrl_IndicatorSetForeground 3040
+#define wxStyledTextCtrl_IndicatorGetForeground 3041
+#define wxStyledTextCtrl_SetWhitespaceForeground 3042
+#define wxStyledTextCtrl_SetWhitespaceBackground 3043
+#define wxStyledTextCtrl_GetStyleBits 3044
+#define wxStyledTextCtrl_SetLineState 3045
+#define wxStyledTextCtrl_GetLineState 3046
+#define wxStyledTextCtrl_GetMaxLineState 3047
+#define wxStyledTextCtrl_GetCaretLineVisible 3048
+#define wxStyledTextCtrl_SetCaretLineVisible 3049
+#define wxStyledTextCtrl_GetCaretLineBackground 3050
+#define wxStyledTextCtrl_SetCaretLineBackground 3051
+#define wxStyledTextCtrl_AutoCompShow 3052
+#define wxStyledTextCtrl_AutoCompCancel 3053
+#define wxStyledTextCtrl_AutoCompActive 3054
+#define wxStyledTextCtrl_AutoCompPosStart 3055
+#define wxStyledTextCtrl_AutoCompComplete 3056
+#define wxStyledTextCtrl_AutoCompStops 3057
+#define wxStyledTextCtrl_AutoCompSetSeparator 3058
+#define wxStyledTextCtrl_AutoCompGetSeparator 3059
+#define wxStyledTextCtrl_AutoCompSelect 3060
+#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3061
+#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3062
+#define wxStyledTextCtrl_AutoCompSetFillUps 3063
+#define wxStyledTextCtrl_AutoCompSetChooseSingle 3064
+#define wxStyledTextCtrl_AutoCompGetChooseSingle 3065
+#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3066
+#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3067
+#define wxStyledTextCtrl_UserListShow 3068
+#define wxStyledTextCtrl_AutoCompSetAutoHide 3069
+#define wxStyledTextCtrl_AutoCompGetAutoHide 3070
+#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3071
+#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3072
+#define wxStyledTextCtrl_RegisterImage 3073
+#define wxStyledTextCtrl_ClearRegisteredImages 3074
+#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3075
+#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3076
+#define wxStyledTextCtrl_AutoCompSetMaxWidth 3077
+#define wxStyledTextCtrl_AutoCompGetMaxWidth 3078
+#define wxStyledTextCtrl_AutoCompSetMaxHeight 3079
+#define wxStyledTextCtrl_AutoCompGetMaxHeight 3080
+#define wxStyledTextCtrl_SetIndent 3081
+#define wxStyledTextCtrl_GetIndent 3082
+#define wxStyledTextCtrl_SetUseTabs 3083
+#define wxStyledTextCtrl_GetUseTabs 3084
+#define wxStyledTextCtrl_SetLineIndentation 3085
+#define wxStyledTextCtrl_GetLineIndentation 3086
+#define wxStyledTextCtrl_GetLineIndentPosition 3087
+#define wxStyledTextCtrl_GetColumn 3088
+#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3089
+#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3090
+#define wxStyledTextCtrl_SetIndentationGuides 3091
+#define wxStyledTextCtrl_GetIndentationGuides 3092
+#define wxStyledTextCtrl_SetHighlightGuide 3093
+#define wxStyledTextCtrl_GetHighlightGuide 3094
+#define wxStyledTextCtrl_GetLineEndPosition 3095
+#define wxStyledTextCtrl_GetCodePage 3096
+#define wxStyledTextCtrl_GetCaretForeground 3097
+#define wxStyledTextCtrl_GetReadOnly 3098
+#define wxStyledTextCtrl_SetCurrentPos 3099
+#define wxStyledTextCtrl_SetSelectionStart 3100
+#define wxStyledTextCtrl_GetSelectionStart 3101
+#define wxStyledTextCtrl_SetSelectionEnd 3102
+#define wxStyledTextCtrl_GetSelectionEnd 3103
+#define wxStyledTextCtrl_SetPrintMagnification 3104
+#define wxStyledTextCtrl_GetPrintMagnification 3105
+#define wxStyledTextCtrl_SetPrintColourMode 3106
+#define wxStyledTextCtrl_GetPrintColourMode 3107
+#define wxStyledTextCtrl_FindText 3108
+#define wxStyledTextCtrl_FormatRange 3109
+#define wxStyledTextCtrl_GetFirstVisibleLine 3110
+#define wxStyledTextCtrl_GetLine 3111
+#define wxStyledTextCtrl_GetLineCount 3112
+#define wxStyledTextCtrl_SetMarginLeft 3113
+#define wxStyledTextCtrl_GetMarginLeft 3114
+#define wxStyledTextCtrl_SetMarginRight 3115
+#define wxStyledTextCtrl_GetMarginRight 3116
+#define wxStyledTextCtrl_GetModify 3117
+#define wxStyledTextCtrl_SetSelection 3118
+#define wxStyledTextCtrl_GetSelectedText 3119
+#define wxStyledTextCtrl_GetTextRange 3120
+#define wxStyledTextCtrl_HideSelection 3121
+#define wxStyledTextCtrl_LineFromPosition 3122
+#define wxStyledTextCtrl_PositionFromLine 3123
+#define wxStyledTextCtrl_LineScroll 3124
+#define wxStyledTextCtrl_EnsureCaretVisible 3125
+#define wxStyledTextCtrl_ReplaceSelection 3126
+#define wxStyledTextCtrl_SetReadOnly 3127
+#define wxStyledTextCtrl_CanPaste 3128
+#define wxStyledTextCtrl_CanUndo 3129
+#define wxStyledTextCtrl_EmptyUndoBuffer 3130
+#define wxStyledTextCtrl_Undo 3131
+#define wxStyledTextCtrl_Cut 3132
+#define wxStyledTextCtrl_Copy 3133
+#define wxStyledTextCtrl_Paste 3134
+#define wxStyledTextCtrl_Clear 3135
+#define wxStyledTextCtrl_SetText 3136
+#define wxStyledTextCtrl_GetText 3137
+#define wxStyledTextCtrl_GetTextLength 3138
+#define wxStyledTextCtrl_GetOvertype 3139
+#define wxStyledTextCtrl_SetCaretWidth 3140
+#define wxStyledTextCtrl_GetCaretWidth 3141
+#define wxStyledTextCtrl_SetTargetStart 3142
+#define wxStyledTextCtrl_GetTargetStart 3143
+#define wxStyledTextCtrl_SetTargetEnd 3144
+#define wxStyledTextCtrl_GetTargetEnd 3145
+#define wxStyledTextCtrl_ReplaceTarget 3146
+#define wxStyledTextCtrl_SearchInTarget 3147
+#define wxStyledTextCtrl_SetSearchFlags 3148
+#define wxStyledTextCtrl_GetSearchFlags 3149
+#define wxStyledTextCtrl_CallTipShow 3150
+#define wxStyledTextCtrl_CallTipCancel 3151
+#define wxStyledTextCtrl_CallTipActive 3152
+#define wxStyledTextCtrl_CallTipPosAtStart 3153
+#define wxStyledTextCtrl_CallTipSetHighlight 3154
+#define wxStyledTextCtrl_CallTipSetBackground 3155
+#define wxStyledTextCtrl_CallTipSetForeground 3156
+#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3157
+#define wxStyledTextCtrl_CallTipUseStyle 3158
+#define wxStyledTextCtrl_VisibleFromDocLine 3159
+#define wxStyledTextCtrl_DocLineFromVisible 3160
+#define wxStyledTextCtrl_WrapCount 3161
+#define wxStyledTextCtrl_SetFoldLevel 3162
+#define wxStyledTextCtrl_GetFoldLevel 3163
+#define wxStyledTextCtrl_GetLastChild 3164
+#define wxStyledTextCtrl_GetFoldParent 3165
+#define wxStyledTextCtrl_ShowLines 3166
+#define wxStyledTextCtrl_HideLines 3167
+#define wxStyledTextCtrl_GetLineVisible 3168
+#define wxStyledTextCtrl_SetFoldExpanded 3169
+#define wxStyledTextCtrl_GetFoldExpanded 3170
+#define wxStyledTextCtrl_ToggleFold 3171
+#define wxStyledTextCtrl_EnsureVisible 3172
+#define wxStyledTextCtrl_SetFoldFlags 3173
+#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3174
+#define wxStyledTextCtrl_SetTabIndents 3175
+#define wxStyledTextCtrl_GetTabIndents 3176
+#define wxStyledTextCtrl_SetBackSpaceUnIndents 3177
+#define wxStyledTextCtrl_GetBackSpaceUnIndents 3178
+#define wxStyledTextCtrl_SetMouseDwellTime 3179
+#define wxStyledTextCtrl_GetMouseDwellTime 3180
+#define wxStyledTextCtrl_WordStartPosition 3181
+#define wxStyledTextCtrl_WordEndPosition 3182
+#define wxStyledTextCtrl_SetWrapMode 3183
+#define wxStyledTextCtrl_GetWrapMode 3184
+#define wxStyledTextCtrl_SetWrapVisualFlags 3185
+#define wxStyledTextCtrl_GetWrapVisualFlags 3186
+#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3187
+#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3188
+#define wxStyledTextCtrl_SetWrapStartIndent 3189
+#define wxStyledTextCtrl_GetWrapStartIndent 3190
+#define wxStyledTextCtrl_SetLayoutCache 3191
+#define wxStyledTextCtrl_GetLayoutCache 3192
+#define wxStyledTextCtrl_SetScrollWidth 3193
+#define wxStyledTextCtrl_GetScrollWidth 3194
+#define wxStyledTextCtrl_TextWidth 3195
+#define wxStyledTextCtrl_GetEndAtLastLine 3196
+#define wxStyledTextCtrl_TextHeight 3197
+#define wxStyledTextCtrl_SetUseVerticalScrollBar 3198
+#define wxStyledTextCtrl_GetUseVerticalScrollBar 3199
+#define wxStyledTextCtrl_AppendText 3200
+#define wxStyledTextCtrl_GetTwoPhaseDraw 3201
+#define wxStyledTextCtrl_SetTwoPhaseDraw 3202
+#define wxStyledTextCtrl_TargetFromSelection 3203
+#define wxStyledTextCtrl_LinesJoin 3204
+#define wxStyledTextCtrl_LinesSplit 3205
+#define wxStyledTextCtrl_SetFoldMarginColour 3206
+#define wxStyledTextCtrl_SetFoldMarginHiColour 3207
+#define wxStyledTextCtrl_LineDown 3208
+#define wxStyledTextCtrl_LineDownExtend 3209
+#define wxStyledTextCtrl_LineUp 3210
+#define wxStyledTextCtrl_LineUpExtend 3211
+#define wxStyledTextCtrl_CharLeft 3212
+#define wxStyledTextCtrl_CharLeftExtend 3213
+#define wxStyledTextCtrl_CharRight 3214
+#define wxStyledTextCtrl_CharRightExtend 3215
+#define wxStyledTextCtrl_WordLeft 3216
+#define wxStyledTextCtrl_WordLeftExtend 3217
+#define wxStyledTextCtrl_WordRight 3218
+#define wxStyledTextCtrl_WordRightExtend 3219
+#define wxStyledTextCtrl_Home 3220
+#define wxStyledTextCtrl_HomeExtend 3221
+#define wxStyledTextCtrl_LineEnd 3222
+#define wxStyledTextCtrl_LineEndExtend 3223
+#define wxStyledTextCtrl_DocumentStart 3224
+#define wxStyledTextCtrl_DocumentStartExtend 3225
+#define wxStyledTextCtrl_DocumentEnd 3226
+#define wxStyledTextCtrl_DocumentEndExtend 3227
+#define wxStyledTextCtrl_PageUp 3228
+#define wxStyledTextCtrl_PageUpExtend 3229
+#define wxStyledTextCtrl_PageDown 3230
+#define wxStyledTextCtrl_PageDownExtend 3231
+#define wxStyledTextCtrl_EditToggleOvertype 3232
+#define wxStyledTextCtrl_Cancel 3233
+#define wxStyledTextCtrl_DeleteBack 3234
+#define wxStyledTextCtrl_Tab 3235
+#define wxStyledTextCtrl_BackTab 3236
+#define wxStyledTextCtrl_NewLine 3237
+#define wxStyledTextCtrl_FormFeed 3238
+#define wxStyledTextCtrl_VCHome 3239
+#define wxStyledTextCtrl_VCHomeExtend 3240
+#define wxStyledTextCtrl_ZoomIn 3241
+#define wxStyledTextCtrl_ZoomOut 3242
+#define wxStyledTextCtrl_DelWordLeft 3243
+#define wxStyledTextCtrl_DelWordRight 3244
+#define wxStyledTextCtrl_LineCut 3245
+#define wxStyledTextCtrl_LineDelete 3246
+#define wxStyledTextCtrl_LineTranspose 3247
+#define wxStyledTextCtrl_LineDuplicate 3248
+#define wxStyledTextCtrl_LowerCase 3249
+#define wxStyledTextCtrl_UpperCase 3250
+#define wxStyledTextCtrl_LineScrollDown 3251
+#define wxStyledTextCtrl_LineScrollUp 3252
+#define wxStyledTextCtrl_DeleteBackNotLine 3253
+#define wxStyledTextCtrl_HomeDisplay 3254
+#define wxStyledTextCtrl_HomeDisplayExtend 3255
+#define wxStyledTextCtrl_LineEndDisplay 3256
+#define wxStyledTextCtrl_LineEndDisplayExtend 3257
+#define wxStyledTextCtrl_HomeWrapExtend 3258
+#define wxStyledTextCtrl_LineEndWrap 3259
+#define wxStyledTextCtrl_LineEndWrapExtend 3260
+#define wxStyledTextCtrl_VCHomeWrap 3261
+#define wxStyledTextCtrl_VCHomeWrapExtend 3262
+#define wxStyledTextCtrl_LineCopy 3263
+#define wxStyledTextCtrl_MoveCaretInsideView 3264
+#define wxStyledTextCtrl_LineLength 3265
+#define wxStyledTextCtrl_BraceHighlight 3266
+#define wxStyledTextCtrl_BraceBadLight 3267
+#define wxStyledTextCtrl_BraceMatch 3268
+#define wxStyledTextCtrl_GetViewEOL 3269
+#define wxStyledTextCtrl_SetViewEOL 3270
+#define wxStyledTextCtrl_SetModEventMask 3271
+#define wxStyledTextCtrl_GetEdgeColumn 3272
+#define wxStyledTextCtrl_SetEdgeColumn 3273
+#define wxStyledTextCtrl_SetEdgeMode 3274
+#define wxStyledTextCtrl_GetEdgeMode 3275
+#define wxStyledTextCtrl_GetEdgeColour 3276
+#define wxStyledTextCtrl_SetEdgeColour 3277
+#define wxStyledTextCtrl_SearchAnchor 3278
+#define wxStyledTextCtrl_SearchNext 3279
+#define wxStyledTextCtrl_SearchPrev 3280
+#define wxStyledTextCtrl_LinesOnScreen 3281
+#define wxStyledTextCtrl_UsePopUp 3282
+#define wxStyledTextCtrl_SelectionIsRectangle 3283
+#define wxStyledTextCtrl_SetZoom 3284
+#define wxStyledTextCtrl_GetZoom 3285
+#define wxStyledTextCtrl_GetModEventMask 3286
+#define wxStyledTextCtrl_SetSTCFocus 3287
+#define wxStyledTextCtrl_GetSTCFocus 3288
+#define wxStyledTextCtrl_SetStatus 3289
+#define wxStyledTextCtrl_GetStatus 3290
+#define wxStyledTextCtrl_SetMouseDownCaptures 3291
+#define wxStyledTextCtrl_GetMouseDownCaptures 3292
+#define wxStyledTextCtrl_SetSTCCursor 3293
+#define wxStyledTextCtrl_GetSTCCursor 3294
+#define wxStyledTextCtrl_SetControlCharSymbol 3295
+#define wxStyledTextCtrl_GetControlCharSymbol 3296
+#define wxStyledTextCtrl_WordPartLeft 3297
+#define wxStyledTextCtrl_WordPartLeftExtend 3298
+#define wxStyledTextCtrl_WordPartRight 3299
+#define wxStyledTextCtrl_WordPartRightExtend 3300
+#define wxStyledTextCtrl_SetVisiblePolicy 3301
+#define wxStyledTextCtrl_DelLineLeft 3302
+#define wxStyledTextCtrl_DelLineRight 3303
+#define wxStyledTextCtrl_GetXOffset 3304
+#define wxStyledTextCtrl_ChooseCaretX 3305
+#define wxStyledTextCtrl_SetXCaretPolicy 3306
+#define wxStyledTextCtrl_SetYCaretPolicy 3307
+#define wxStyledTextCtrl_GetPrintWrapMode 3308
+#define wxStyledTextCtrl_SetHotspotActiveForeground 3309
+#define wxStyledTextCtrl_SetHotspotActiveBackground 3310
+#define wxStyledTextCtrl_SetHotspotActiveUnderline 3311
+#define wxStyledTextCtrl_SetHotspotSingleLine 3312
+#define wxStyledTextCtrl_ParaDownExtend 3313
+#define wxStyledTextCtrl_ParaUp 3314
+#define wxStyledTextCtrl_ParaUpExtend 3315
+#define wxStyledTextCtrl_PositionBefore 3316
+#define wxStyledTextCtrl_PositionAfter 3317
+#define wxStyledTextCtrl_CopyRange 3318
+#define wxStyledTextCtrl_CopyText 3319
+#define wxStyledTextCtrl_SetSelectionMode 3320
+#define wxStyledTextCtrl_GetSelectionMode 3321
+#define wxStyledTextCtrl_LineDownRectExtend 3322
+#define wxStyledTextCtrl_LineUpRectExtend 3323
+#define wxStyledTextCtrl_CharLeftRectExtend 3324
+#define wxStyledTextCtrl_CharRightRectExtend 3325
+#define wxStyledTextCtrl_HomeRectExtend 3326
+#define wxStyledTextCtrl_VCHomeRectExtend 3327
+#define wxStyledTextCtrl_LineEndRectExtend 3328
+#define wxStyledTextCtrl_PageUpRectExtend 3329
+#define wxStyledTextCtrl_PageDownRectExtend 3330
+#define wxStyledTextCtrl_StutteredPageUp 3331
+#define wxStyledTextCtrl_StutteredPageUpExtend 3332
+#define wxStyledTextCtrl_StutteredPageDown 3333
+#define wxStyledTextCtrl_StutteredPageDownExtend 3334
+#define wxStyledTextCtrl_WordLeftEnd 3335
+#define wxStyledTextCtrl_WordLeftEndExtend 3336
+#define wxStyledTextCtrl_WordRightEnd 3337
+#define wxStyledTextCtrl_WordRightEndExtend 3338
+#define wxStyledTextCtrl_SetWhitespaceChars 3339
+#define wxStyledTextCtrl_SetCharsDefault 3340
+#define wxStyledTextCtrl_AutoCompGetCurrent 3341
+#define wxStyledTextCtrl_Allocate 3342
+#define wxStyledTextCtrl_FindColumn 3343
+#define wxStyledTextCtrl_GetCaretSticky 3344
+#define wxStyledTextCtrl_SetCaretSticky 3345
+#define wxStyledTextCtrl_ToggleCaretSticky 3346
+#define wxStyledTextCtrl_SetPasteConvertEndings 3347
+#define wxStyledTextCtrl_GetPasteConvertEndings 3348
+#define wxStyledTextCtrl_SelectionDuplicate 3349
+#define wxStyledTextCtrl_SetCaretLineBackAlpha 3350
+#define wxStyledTextCtrl_GetCaretLineBackAlpha 3351
+#define wxStyledTextCtrl_StartRecord 3352
+#define wxStyledTextCtrl_StopRecord 3353
+#define wxStyledTextCtrl_SetLexer 3354
+#define wxStyledTextCtrl_GetLexer 3355
+#define wxStyledTextCtrl_Colourise 3356
+#define wxStyledTextCtrl_SetProperty 3357
+#define wxStyledTextCtrl_SetKeyWords 3358
+#define wxStyledTextCtrl_SetLexerLanguage 3359
+#define wxStyledTextCtrl_GetProperty 3360
+#define wxStyledTextCtrl_GetStyleBitsNeeded 3361
+#define wxStyledTextCtrl_GetCurrentLine 3362
+#define wxStyledTextCtrl_StyleSetSpec 3363
+#define wxStyledTextCtrl_StyleSetFont 3364
+#define wxStyledTextCtrl_StyleSetFontAttr 3365
+#define wxStyledTextCtrl_StyleSetCharacterSet 3366
+#define wxStyledTextCtrl_StyleSetFontEncoding 3367
+#define wxStyledTextCtrl_CmdKeyExecute 3368
+#define wxStyledTextCtrl_SetMargins 3369
+#define wxStyledTextCtrl_GetSelection 3370
+#define wxStyledTextCtrl_PointFromPosition 3371
+#define wxStyledTextCtrl_ScrollToLine 3372
+#define wxStyledTextCtrl_ScrollToColumn 3373
+#define wxStyledTextCtrl_SetVScrollBar 3374
+#define wxStyledTextCtrl_SetHScrollBar 3375
+#define wxStyledTextCtrl_GetLastKeydownProcessed 3376
+#define wxStyledTextCtrl_SetLastKeydownProcessed 3377
+#define wxStyledTextCtrl_SaveFile 3378
+#define wxStyledTextCtrl_LoadFile 3379
+#define wxStyledTextCtrl_DoDragOver 3380
+#define wxStyledTextCtrl_DoDropText 3381
+#define wxStyledTextCtrl_GetUseAntiAliasing 3382
+#define wxStyledTextCtrl_AddTextRaw 3383
+#define wxStyledTextCtrl_InsertTextRaw 3384
+#define wxStyledTextCtrl_GetCurLineRaw 3385
+#define wxStyledTextCtrl_GetLineRaw 3386
+#define wxStyledTextCtrl_GetSelectedTextRaw 3387
+#define wxStyledTextCtrl_GetTextRangeRaw 3388
+#define wxStyledTextCtrl_SetTextRaw 3389
+#define wxStyledTextCtrl_GetTextRaw 3390
+#define wxStyledTextCtrl_AppendTextRaw 3391
+#define wxArtProvider_GetBitmap 3392
+#define wxArtProvider_GetIcon 3393
+#define wxTreeEvent_GetKeyCode 3394
+#define wxTreeEvent_GetItem 3395
+#define wxTreeEvent_GetKeyEvent 3396
+#define wxTreeEvent_GetLabel 3397
+#define wxTreeEvent_GetOldItem 3398
+#define wxTreeEvent_GetPoint 3399
+#define wxTreeEvent_IsEditCancelled 3400
+#define wxTreeEvent_SetToolTip 3401
+#define wxNotebookEvent_GetOldSelection 3402
+#define wxNotebookEvent_GetSelection 3403
+#define wxNotebookEvent_SetOldSelection 3404
+#define wxNotebookEvent_SetSelection 3405
+#define wxFileDataObject_new 3406
+#define wxFileDataObject_AddFile 3407
+#define wxFileDataObject_GetFilenames 3408
+#define wxFileDataObject_destroy 3409
+#define wxTextDataObject_new 3410
+#define wxTextDataObject_GetTextLength 3411
+#define wxTextDataObject_GetText 3412
+#define wxTextDataObject_SetText 3413
+#define wxTextDataObject_destroy 3414
+#define wxBitmapDataObject_new_1_1 3415
+#define wxBitmapDataObject_new_1_0 3416
+#define wxBitmapDataObject_GetBitmap 3417
+#define wxBitmapDataObject_SetBitmap 3418
+#define wxBitmapDataObject_destroy 3419
+#define wxClipboard_new 3421
+#define wxClipboard_destruct 3422
+#define wxClipboard_AddData 3423
+#define wxClipboard_Clear 3424
+#define wxClipboard_Close 3425
+#define wxClipboard_Flush 3426
+#define wxClipboard_GetData 3427
+#define wxClipboard_IsOpened 3428
+#define wxClipboard_Open 3429
+#define wxClipboard_SetData 3430
+#define wxClipboard_UsePrimarySelection 3432
+#define wxClipboard_IsSupported 3433
+#define wxClipboard_Get 3434
+#define wxSpinEvent_GetPosition 3435
+#define wxSpinEvent_SetPosition 3436
+#define wxSplitterWindow_new_0 3437
+#define wxSplitterWindow_new_2 3438
+#define wxSplitterWindow_destruct 3439
+#define wxSplitterWindow_Create 3440
+#define wxSplitterWindow_GetMinimumPaneSize 3441
+#define wxSplitterWindow_GetSashGravity 3442
+#define wxSplitterWindow_GetSashPosition 3443
+#define wxSplitterWindow_GetSplitMode 3444
+#define wxSplitterWindow_GetWindow1 3445
+#define wxSplitterWindow_GetWindow2 3446
+#define wxSplitterWindow_Initialize 3447
+#define wxSplitterWindow_IsSplit 3448
+#define wxSplitterWindow_ReplaceWindow 3449
+#define wxSplitterWindow_SetSashGravity 3450
+#define wxSplitterWindow_SetSashPosition 3451
+#define wxSplitterWindow_SetSashSize 3452
+#define wxSplitterWindow_SetMinimumPaneSize 3453
+#define wxSplitterWindow_SetSplitMode 3454
+#define wxSplitterWindow_SplitHorizontally 3455
+#define wxSplitterWindow_SplitVertically 3456
+#define wxSplitterWindow_Unsplit 3457
+#define wxSplitterWindow_UpdateSize 3458
+#define wxSplitterEvent_GetSashPosition 3459
+#define wxSplitterEvent_GetX 3460
+#define wxSplitterEvent_GetY 3461
+#define wxSplitterEvent_GetWindowBeingRemoved 3462
+#define wxSplitterEvent_SetSashPosition 3463
+#define wxHtmlWindow_new_0 3464
+#define wxHtmlWindow_new_2 3465
+#define wxHtmlWindow_AppendToPage 3466
+#define wxHtmlWindow_GetOpenedAnchor 3467
+#define wxHtmlWindow_GetOpenedPage 3468
+#define wxHtmlWindow_GetOpenedPageTitle 3469
+#define wxHtmlWindow_GetRelatedFrame 3470
+#define wxHtmlWindow_HistoryBack 3471
+#define wxHtmlWindow_HistoryCanBack 3472
+#define wxHtmlWindow_HistoryCanForward 3473
+#define wxHtmlWindow_HistoryClear 3474
+#define wxHtmlWindow_HistoryForward 3475
+#define wxHtmlWindow_LoadFile 3476
+#define wxHtmlWindow_LoadPage 3477
+#define wxHtmlWindow_SelectAll 3478
+#define wxHtmlWindow_SelectionToText 3479
+#define wxHtmlWindow_SelectLine 3480
+#define wxHtmlWindow_SelectWord 3481
+#define wxHtmlWindow_SetBorders 3482
+#define wxHtmlWindow_SetFonts 3483
+#define wxHtmlWindow_SetPage 3484
+#define wxHtmlWindow_SetRelatedFrame 3485
+#define wxHtmlWindow_SetRelatedStatusBar 3486
+#define wxHtmlWindow_ToText 3487
+#define wxHtmlWindow_destroy 3488
+#define wxHtmlLinkEvent_GetLinkInfo 3489
+#define wxSystemSettings_GetColour 3490
+#define wxSystemSettings_GetFont 3491
+#define wxSystemSettings_GetMetric 3492
+#define wxSystemSettings_GetScreenType 3493
+#define wxSystemOptions_GetOption 3494
+#define wxSystemOptions_GetOptionInt 3495
+#define wxSystemOptions_HasOption 3496
+#define wxSystemOptions_IsFalse 3497
+#define wxSystemOptions_SetOption_2_1 3498
+#define wxSystemOptions_SetOption_2_0 3499
+#define wxAuiNotebookEvent_SetSelection 3500
+#define wxAuiNotebookEvent_GetSelection 3501
+#define wxAuiNotebookEvent_SetOldSelection 3502
+#define wxAuiNotebookEvent_GetOldSelection 3503
+#define wxAuiNotebookEvent_SetDragSource 3504
+#define wxAuiNotebookEvent_GetDragSource 3505
+#define wxAuiManagerEvent_SetManager 3506
+#define wxAuiManagerEvent_GetManager 3507
+#define wxAuiManagerEvent_SetPane 3508
+#define wxAuiManagerEvent_GetPane 3509
+#define wxAuiManagerEvent_SetButton 3510
+#define wxAuiManagerEvent_GetButton 3511
+#define wxAuiManagerEvent_SetDC 3512
+#define wxAuiManagerEvent_GetDC 3513
+#define wxAuiManagerEvent_Veto 3514
+#define wxAuiManagerEvent_GetVeto 3515
+#define wxAuiManagerEvent_SetCanVeto 3516
+#define wxAuiManagerEvent_CanVeto 3517
+#define wxLogNull_new 3518
+#define wxLogNull_destroy 3519
+#define wxTaskBarIcon_new 3520
+#define wxTaskBarIcon_destruct 3521
+#define wxTaskBarIcon_PopupMenu 3522
+#define wxTaskBarIcon_RemoveIcon 3523
+#define wxTaskBarIcon_SetIcon 3524
diff --git a/lib/wx/examples/demo/demo_html_tagger.erl b/lib/wx/examples/demo/demo_html_tagger.erl
index 243e5d659f..46bfe73676 100644
--- a/lib/wx/examples/demo/demo_html_tagger.erl
+++ b/lib/wx/examples/demo/demo_html_tagger.erl
@@ -485,7 +485,6 @@ is_keyword('not') -> true;
is_keyword('of' ) -> true;
is_keyword('or' ) -> true;
is_keyword('orelse' ) -> true;
-is_keyword('query' ) -> true;
is_keyword('receive' ) -> true;
is_keyword('rem' ) -> true;
is_keyword('spec') -> true;
diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile
index 777fb7d998..26574ed86f 100644
--- a/lib/wx/src/Makefile
+++ b/lib/wx/src/Makefile
@@ -101,19 +101,19 @@ archive: opt
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk Makefile
- sed -e 's;%GEN_MODS%;$(GEN_MODS);' $< > [email protected]
- sed -e 's;%VSN%;$(VSN);' [email protected] > $@
+ $(gen_verbose)sed -e 's;%GEN_MODS%;$(GEN_MODS);' $< > [email protected]
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' [email protected] > $@
+ $(V_at)rm [email protected]
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk Makefile
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# Rules
$(EBIN)/%.beam: $(ESRC)/%.erl $(HEADER_FILES)
- $(ERLC) -W -bbeam $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+ $(V_ERLC) -W -bbeam $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
$(EBIN)/%.beam: $(EGEN)/%.erl $(HEADER_FILES)
- $(ERLC) -W -bbeam $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+ $(V_ERLC) -W -bbeam $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
# ----------------------------------------------------
# Release Target
diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl
index dfa9e691ce..df2b9bed39 100644
--- a/lib/wx/src/gen/wxTreeCtrl.erl
+++ b/lib/wx/src/gen/wxTreeCtrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -35,21 +35,22 @@
-include("wxe.hrl").
-export([addRoot/2,addRoot/3,appendItem/3,appendItem/4,assignImageList/2,assignStateImageList/2,
collapse/2,collapseAndReset/2,create/2,create/3,delete/2,deleteAllItems/1,
- deleteChildren/2,destroy/1,editLabel/2,ensureVisible/2,expand/2,getBoundingRect/3,
- getBoundingRect/4,getChildrenCount/2,getChildrenCount/3,getCount/1,
+ deleteChildren/2,destroy/1,editLabel/2,ensureVisible/2,expand/2,getBoundingRect/2,
+ getBoundingRect/3,getChildrenCount/2,getChildrenCount/3,getCount/1,
getEditControl/1,getFirstChild/2,getFirstVisibleItem/1,getImageList/1,
getIndent/1,getItemBackgroundColour/2,getItemData/2,getItemFont/2,
getItemImage/2,getItemImage/3,getItemParent/2,getItemText/2,getItemTextColour/2,
getLastChild/2,getNextChild/3,getNextSibling/2,getNextVisible/2,getPrevSibling/2,
getPrevVisible/2,getRootItem/1,getSelection/1,getSelections/1,getStateImageList/1,
hitTest/2,insertItem/4,insertItem/5,isBold/2,isExpanded/2,isSelected/2,
- isVisible/2,itemHasChildren/2,new/0,new/1,new/2,prependItem/3,prependItem/4,
- scrollTo/2,selectItem/2,selectItem/3,setImageList/2,setIndent/2,setItemBackgroundColour/3,
- setItemBold/2,setItemBold/3,setItemData/3,setItemDropHighlight/2,
- setItemDropHighlight/3,setItemFont/3,setItemHasChildren/2,setItemHasChildren/3,
- setItemImage/3,setItemImage/4,setItemText/3,setItemTextColour/3,setStateImageList/2,
- setWindowStyle/2,sortChildren/2,toggle/2,toggleItemSelection/2,unselect/1,
- unselectAll/1,unselectItem/2]).
+ isTreeItemIdOk/1,isVisible/2,itemHasChildren/2,new/0,new/1,new/2,prependItem/3,
+ prependItem/4,scrollTo/2,selectItem/2,selectItem/3,setImageList/2,
+ setIndent/2,setItemBackgroundColour/3,setItemBold/2,setItemBold/3,
+ setItemData/3,setItemDropHighlight/2,setItemDropHighlight/3,setItemFont/3,
+ setItemHasChildren/2,setItemHasChildren/3,setItemImage/3,setItemImage/4,
+ setItemText/3,setItemTextColour/3,setStateImageList/2,setWindowStyle/2,
+ sortChildren/2,toggle/2,toggleItemSelection/2,unselect/1,unselectAll/1,
+ unselectItem/2]).
%% inherited exports
-export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1,
@@ -303,26 +304,28 @@ expand(#wx_ref{type=ThisT,ref=ThisRef},Item)
wxe_util:cast(?wxTreeCtrl_Expand,
<<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @equiv getBoundingRect(This,Item,Rect, [])
--spec getBoundingRect(This, Item, Rect) -> boolean() when
- This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}.
+%% @equiv getBoundingRect(This,Item, [])
+-spec getBoundingRect(This, Item) -> Result when
+ Result ::{Res ::boolean(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}},
+ This::wxTreeCtrl(), Item::integer().
-getBoundingRect(This,Item,Rect={RectX,RectY,RectW,RectH})
- when is_record(This, wx_ref),is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
- getBoundingRect(This,Item,Rect, []).
+getBoundingRect(This,Item)
+ when is_record(This, wx_ref),is_integer(Item) ->
+ getBoundingRect(This,Item, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetboundingrect">external documentation</a>.
--spec getBoundingRect(This, Item, Rect, [Option]) -> boolean() when
- This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()},
+-spec getBoundingRect(This, Item, [Option]) -> Result when
+ Result :: {Res ::boolean(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}},
+ This::wxTreeCtrl(), Item::integer(),
Option :: {textOnly, boolean()}.
-getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},Item,{RectX,RectY,RectW,RectH}, Options)
- when is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
+getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({textOnly, TextOnly}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(TextOnly)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetBoundingRect,
- <<ThisRef:32/?UI,0:32,Item:64/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
%% @equiv getChildrenCount(This,Item, [])
-spec getChildrenCount(This, Item) -> integer() when
@@ -561,7 +564,8 @@ getStateImageList(#wx_ref{type=ThisT,ref=ThisRef}) ->
<<ThisRef:32/?UI>>).
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlhittest">external documentation</a>.
--spec hitTest(This, Point) -> integer() when
+-spec hitTest(This, Point) -> Result when
+ Result ::{Res ::integer(), Flags::integer()},
This::wxTreeCtrl(), Point::{X::integer(), Y::integer()}.
hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
when is_integer(PointX),is_integer(PointY) ->
@@ -640,6 +644,14 @@ itemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
wxe_util:call(?wxTreeCtrl_ItemHasChildren,
<<ThisRef:32/?UI,0:32,Item:64/?UI>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlistreeitemidok">external documentation</a>.
+-spec isTreeItemIdOk(Id) -> boolean() when
+ Id::integer().
+isTreeItemIdOk(Id)
+ when is_integer(Id) ->
+ wxe_util:call(?wxTreeCtrl_IsTreeItemIdOk,
+ <<Id:64/?UI>>).
+
%% @equiv prependItem(This,Parent,Text, [])
-spec prependItem(This, Parent, Text) -> integer() when
This::wxTreeCtrl(), Parent::integer(), Text::unicode:chardata().
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index 6f4fa3fe34..29cb2b05e6 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -1877,1432 +1877,1433 @@ wxdebug_table() ->
{2050, {wxTreeCtrl, getSelection, 0}},
{2051, {wxTreeCtrl, getSelections, 1}},
{2052, {wxTreeCtrl, getStateImageList, 0}},
- {2053, {wxTreeCtrl, hitTest, 1}},
+ {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, prependItem, 3}},
- {2062, {wxTreeCtrl, scrollTo, 1}},
- {2063, {wxTreeCtrl, selectItem_1, 1}},
- {2064, {wxTreeCtrl, selectItem_2, 2}},
- {2065, {wxTreeCtrl, setIndent, 1}},
- {2066, {wxTreeCtrl, setImageList, 1}},
- {2067, {wxTreeCtrl, setItemBackgroundColour, 2}},
- {2068, {wxTreeCtrl, setItemBold, 2}},
- {2069, {wxTreeCtrl, setItemData, 2}},
- {2070, {wxTreeCtrl, setItemDropHighlight, 2}},
- {2071, {wxTreeCtrl, setItemFont, 2}},
- {2072, {wxTreeCtrl, setItemHasChildren, 2}},
- {2073, {wxTreeCtrl, setItemImage_2, 2}},
- {2074, {wxTreeCtrl, setItemImage_3, 3}},
- {2075, {wxTreeCtrl, setItemText, 2}},
- {2076, {wxTreeCtrl, setItemTextColour, 2}},
- {2077, {wxTreeCtrl, setStateImageList, 1}},
- {2078, {wxTreeCtrl, setWindowStyle, 1}},
- {2079, {wxTreeCtrl, sortChildren, 1}},
- {2080, {wxTreeCtrl, toggle, 1}},
- {2081, {wxTreeCtrl, toggleItemSelection, 1}},
- {2082, {wxTreeCtrl, unselect, 0}},
- {2083, {wxTreeCtrl, unselectAll, 0}},
- {2084, {wxTreeCtrl, unselectItem, 1}},
- {2085, {wxScrollBar, new_0, 0}},
- {2086, {wxScrollBar, new_3, 3}},
- {2087, {wxScrollBar, destruct, 0}},
- {2088, {wxScrollBar, create, 3}},
- {2089, {wxScrollBar, getRange, 0}},
- {2090, {wxScrollBar, getPageSize, 0}},
- {2091, {wxScrollBar, getThumbPosition, 0}},
- {2092, {wxScrollBar, getThumbSize, 0}},
- {2093, {wxScrollBar, setThumbPosition, 1}},
- {2094, {wxScrollBar, setScrollbar, 5}},
- {2096, {wxSpinButton, new_2, 2}},
- {2097, {wxSpinButton, new_0, 0}},
- {2098, {wxSpinButton, create, 2}},
- {2099, {wxSpinButton, getMax, 0}},
- {2100, {wxSpinButton, getMin, 0}},
- {2101, {wxSpinButton, getValue, 0}},
- {2102, {wxSpinButton, setRange, 2}},
- {2103, {wxSpinButton, setValue, 1}},
- {2104, {wxSpinButton, 'Destroy', undefined}},
- {2105, {wxSpinCtrl, new_0, 0}},
- {2106, {wxSpinCtrl, new_2, 2}},
- {2108, {wxSpinCtrl, create, 2}},
- {2111, {wxSpinCtrl, setValue_1_1, 1}},
- {2112, {wxSpinCtrl, setValue_1_0, 1}},
- {2114, {wxSpinCtrl, getValue, 0}},
- {2116, {wxSpinCtrl, setRange, 2}},
- {2117, {wxSpinCtrl, setSelection, 2}},
- {2119, {wxSpinCtrl, getMin, 0}},
- {2121, {wxSpinCtrl, getMax, 0}},
- {2122, {wxSpinCtrl, 'Destroy', undefined}},
- {2123, {wxStaticText, new_0, 0}},
- {2124, {wxStaticText, new_4, 4}},
- {2125, {wxStaticText, create, 4}},
- {2126, {wxStaticText, getLabel, 0}},
- {2127, {wxStaticText, setLabel, 1}},
- {2128, {wxStaticText, wrap, 1}},
- {2129, {wxStaticText, 'Destroy', undefined}},
- {2130, {wxStaticBitmap, new_0, 0}},
- {2131, {wxStaticBitmap, new_4, 4}},
- {2132, {wxStaticBitmap, create, 4}},
- {2133, {wxStaticBitmap, getBitmap, 0}},
- {2134, {wxStaticBitmap, setBitmap, 1}},
- {2135, {wxStaticBitmap, 'Destroy', undefined}},
- {2136, {wxRadioBox, new, 7}},
- {2138, {wxRadioBox, destruct, 0}},
- {2139, {wxRadioBox, create, 7}},
- {2140, {wxRadioBox, enable_2, 2}},
- {2141, {wxRadioBox, enable_1, 1}},
- {2142, {wxRadioBox, getSelection, 0}},
- {2143, {wxRadioBox, getString, 1}},
- {2144, {wxRadioBox, setSelection, 1}},
- {2145, {wxRadioBox, show_2, 2}},
- {2146, {wxRadioBox, show_1, 1}},
- {2147, {wxRadioBox, getColumnCount, 0}},
- {2148, {wxRadioBox, getItemHelpText, 1}},
- {2149, {wxRadioBox, getItemToolTip, 1}},
- {2151, {wxRadioBox, getItemFromPoint, 1}},
- {2152, {wxRadioBox, getRowCount, 0}},
- {2153, {wxRadioBox, isItemEnabled, 1}},
- {2154, {wxRadioBox, isItemShown, 1}},
- {2155, {wxRadioBox, setItemHelpText, 2}},
- {2156, {wxRadioBox, setItemToolTip, 2}},
- {2157, {wxRadioButton, new_0, 0}},
- {2158, {wxRadioButton, new_4, 4}},
- {2159, {wxRadioButton, create, 4}},
- {2160, {wxRadioButton, getValue, 0}},
- {2161, {wxRadioButton, setValue, 1}},
- {2162, {wxRadioButton, 'Destroy', undefined}},
- {2164, {wxSlider, new_6, 6}},
- {2165, {wxSlider, new_0, 0}},
- {2166, {wxSlider, create, 6}},
- {2167, {wxSlider, getLineSize, 0}},
- {2168, {wxSlider, getMax, 0}},
- {2169, {wxSlider, getMin, 0}},
- {2170, {wxSlider, getPageSize, 0}},
- {2171, {wxSlider, getThumbLength, 0}},
- {2172, {wxSlider, getValue, 0}},
- {2173, {wxSlider, setLineSize, 1}},
- {2174, {wxSlider, setPageSize, 1}},
- {2175, {wxSlider, setRange, 2}},
- {2176, {wxSlider, setThumbLength, 1}},
- {2177, {wxSlider, setValue, 1}},
- {2178, {wxSlider, 'Destroy', undefined}},
- {2180, {wxDialog, new_4, 4}},
- {2181, {wxDialog, new_0, 0}},
- {2183, {wxDialog, destruct, 0}},
- {2184, {wxDialog, create, 4}},
- {2185, {wxDialog, createButtonSizer, 1}},
- {2186, {wxDialog, createStdDialogButtonSizer, 1}},
- {2187, {wxDialog, endModal, 1}},
- {2188, {wxDialog, getAffirmativeId, 0}},
- {2189, {wxDialog, getReturnCode, 0}},
- {2190, {wxDialog, isModal, 0}},
- {2191, {wxDialog, setAffirmativeId, 1}},
- {2192, {wxDialog, setReturnCode, 1}},
- {2193, {wxDialog, show, 1}},
- {2194, {wxDialog, showModal, 0}},
- {2195, {wxColourDialog, new_0, 0}},
- {2196, {wxColourDialog, new_2, 2}},
- {2197, {wxColourDialog, destruct, 0}},
- {2198, {wxColourDialog, create, 2}},
- {2199, {wxColourDialog, getColourData, 0}},
- {2200, {wxColourData, new_0, 0}},
- {2201, {wxColourData, new_1, 1}},
- {2202, {wxColourData, destruct, 0}},
- {2203, {wxColourData, getChooseFull, 0}},
- {2204, {wxColourData, getColour, 0}},
- {2206, {wxColourData, getCustomColour, 1}},
- {2207, {wxColourData, setChooseFull, 1}},
- {2208, {wxColourData, setColour, 1}},
- {2209, {wxColourData, setCustomColour, 2}},
- {2210, {wxPalette, new_0, 0}},
- {2211, {wxPalette, new_4, 4}},
- {2213, {wxPalette, destruct, 0}},
- {2214, {wxPalette, create, 4}},
- {2215, {wxPalette, getColoursCount, 0}},
- {2216, {wxPalette, getPixel, 3}},
- {2217, {wxPalette, getRGB, 4}},
- {2218, {wxPalette, isOk, 0}},
- {2222, {wxDirDialog, new, 2}},
- {2223, {wxDirDialog, destruct, 0}},
- {2224, {wxDirDialog, getPath, 0}},
- {2225, {wxDirDialog, getMessage, 0}},
- {2226, {wxDirDialog, setMessage, 1}},
- {2227, {wxDirDialog, setPath, 1}},
- {2231, {wxFileDialog, new, 2}},
- {2232, {wxFileDialog, destruct, 0}},
- {2233, {wxFileDialog, getDirectory, 0}},
- {2234, {wxFileDialog, getFilename, 0}},
- {2235, {wxFileDialog, getFilenames, 1}},
- {2236, {wxFileDialog, getFilterIndex, 0}},
- {2237, {wxFileDialog, getMessage, 0}},
- {2238, {wxFileDialog, getPath, 0}},
- {2239, {wxFileDialog, getPaths, 1}},
- {2240, {wxFileDialog, getWildcard, 0}},
- {2241, {wxFileDialog, setDirectory, 1}},
- {2242, {wxFileDialog, setFilename, 1}},
- {2243, {wxFileDialog, setFilterIndex, 1}},
- {2244, {wxFileDialog, setMessage, 1}},
- {2245, {wxFileDialog, setPath, 1}},
- {2246, {wxFileDialog, setWildcard, 1}},
- {2247, {wxPickerBase, setInternalMargin, 1}},
- {2248, {wxPickerBase, getInternalMargin, 0}},
- {2249, {wxPickerBase, setTextCtrlProportion, 1}},
- {2250, {wxPickerBase, setPickerCtrlProportion, 1}},
- {2251, {wxPickerBase, getTextCtrlProportion, 0}},
- {2252, {wxPickerBase, getPickerCtrlProportion, 0}},
- {2253, {wxPickerBase, hasTextCtrl, 0}},
- {2254, {wxPickerBase, getTextCtrl, 0}},
- {2255, {wxPickerBase, isTextCtrlGrowable, 0}},
- {2256, {wxPickerBase, setPickerCtrlGrowable, 1}},
- {2257, {wxPickerBase, setTextCtrlGrowable, 1}},
- {2258, {wxPickerBase, isPickerCtrlGrowable, 0}},
- {2259, {wxFilePickerCtrl, new_0, 0}},
- {2260, {wxFilePickerCtrl, new_3, 3}},
- {2261, {wxFilePickerCtrl, create, 3}},
- {2262, {wxFilePickerCtrl, getPath, 0}},
- {2263, {wxFilePickerCtrl, setPath, 1}},
- {2264, {wxFilePickerCtrl, 'Destroy', undefined}},
- {2265, {wxDirPickerCtrl, new_0, 0}},
- {2266, {wxDirPickerCtrl, new_3, 3}},
- {2267, {wxDirPickerCtrl, create, 3}},
- {2268, {wxDirPickerCtrl, getPath, 0}},
- {2269, {wxDirPickerCtrl, setPath, 1}},
- {2270, {wxDirPickerCtrl, 'Destroy', undefined}},
- {2271, {wxColourPickerCtrl, new_0, 0}},
- {2272, {wxColourPickerCtrl, new_3, 3}},
- {2273, {wxColourPickerCtrl, create, 3}},
- {2274, {wxColourPickerCtrl, getColour, 0}},
- {2275, {wxColourPickerCtrl, setColour_1_1, 1}},
- {2276, {wxColourPickerCtrl, setColour_1_0, 1}},
- {2277, {wxColourPickerCtrl, 'Destroy', undefined}},
- {2278, {wxDatePickerCtrl, new_0, 0}},
- {2279, {wxDatePickerCtrl, new_3, 3}},
- {2280, {wxDatePickerCtrl, getRange, 2}},
- {2281, {wxDatePickerCtrl, getValue, 0}},
- {2282, {wxDatePickerCtrl, setRange, 2}},
- {2283, {wxDatePickerCtrl, setValue, 1}},
- {2284, {wxDatePickerCtrl, 'Destroy', undefined}},
- {2285, {wxFontPickerCtrl, new_0, 0}},
- {2286, {wxFontPickerCtrl, new_3, 3}},
- {2287, {wxFontPickerCtrl, create, 3}},
- {2288, {wxFontPickerCtrl, getSelectedFont, 0}},
- {2289, {wxFontPickerCtrl, setSelectedFont, 1}},
- {2290, {wxFontPickerCtrl, getMaxPointSize, 0}},
- {2291, {wxFontPickerCtrl, setMaxPointSize, 1}},
- {2292, {wxFontPickerCtrl, 'Destroy', undefined}},
- {2295, {wxFindReplaceDialog, new_0, 0}},
- {2296, {wxFindReplaceDialog, new_4, 4}},
- {2297, {wxFindReplaceDialog, destruct, 0}},
- {2298, {wxFindReplaceDialog, create, 4}},
- {2299, {wxFindReplaceDialog, getData, 0}},
- {2300, {wxFindReplaceData, new_0, 0}},
- {2301, {wxFindReplaceData, new_1, 1}},
- {2302, {wxFindReplaceData, getFindString, 0}},
- {2303, {wxFindReplaceData, getReplaceString, 0}},
- {2304, {wxFindReplaceData, getFlags, 0}},
- {2305, {wxFindReplaceData, setFlags, 1}},
- {2306, {wxFindReplaceData, setFindString, 1}},
- {2307, {wxFindReplaceData, setReplaceString, 1}},
- {2308, {wxFindReplaceData, 'Destroy', undefined}},
- {2309, {wxMultiChoiceDialog, new_0, 0}},
- {2311, {wxMultiChoiceDialog, new_5, 5}},
- {2312, {wxMultiChoiceDialog, getSelections, 0}},
- {2313, {wxMultiChoiceDialog, setSelections, 1}},
- {2314, {wxMultiChoiceDialog, 'Destroy', undefined}},
- {2315, {wxSingleChoiceDialog, new_0, 0}},
- {2317, {wxSingleChoiceDialog, new_5, 5}},
- {2318, {wxSingleChoiceDialog, getSelection, 0}},
- {2319, {wxSingleChoiceDialog, getStringSelection, 0}},
- {2320, {wxSingleChoiceDialog, setSelection, 1}},
- {2321, {wxSingleChoiceDialog, 'Destroy', undefined}},
- {2322, {wxTextEntryDialog, new, 3}},
- {2323, {wxTextEntryDialog, getValue, 0}},
- {2324, {wxTextEntryDialog, setValue, 1}},
- {2325, {wxTextEntryDialog, 'Destroy', undefined}},
- {2326, {wxPasswordEntryDialog, new, 3}},
- {2327, {wxPasswordEntryDialog, 'Destroy', undefined}},
- {2328, {wxFontData, new_0, 0}},
- {2329, {wxFontData, new_1, 1}},
- {2330, {wxFontData, destruct, 0}},
- {2331, {wxFontData, enableEffects, 1}},
- {2332, {wxFontData, getAllowSymbols, 0}},
- {2333, {wxFontData, getColour, 0}},
- {2334, {wxFontData, getChosenFont, 0}},
- {2335, {wxFontData, getEnableEffects, 0}},
- {2336, {wxFontData, getInitialFont, 0}},
- {2337, {wxFontData, getShowHelp, 0}},
- {2338, {wxFontData, setAllowSymbols, 1}},
- {2339, {wxFontData, setChosenFont, 1}},
- {2340, {wxFontData, setColour, 1}},
- {2341, {wxFontData, setInitialFont, 1}},
- {2342, {wxFontData, setRange, 2}},
- {2343, {wxFontData, setShowHelp, 1}},
- {2347, {wxFontDialog, new_0, 0}},
- {2349, {wxFontDialog, new_2, 2}},
- {2351, {wxFontDialog, create, 2}},
- {2352, {wxFontDialog, getFontData, 0}},
- {2354, {wxFontDialog, 'Destroy', undefined}},
- {2355, {wxProgressDialog, new, 3}},
- {2356, {wxProgressDialog, destruct, 0}},
- {2357, {wxProgressDialog, resume, 0}},
- {2358, {wxProgressDialog, update_2, 2}},
- {2359, {wxProgressDialog, update_0, 0}},
- {2360, {wxMessageDialog, new, 3}},
- {2361, {wxMessageDialog, destruct, 0}},
- {2362, {wxPageSetupDialog, new, 2}},
- {2363, {wxPageSetupDialog, destruct, 0}},
- {2364, {wxPageSetupDialog, getPageSetupData, 0}},
- {2365, {wxPageSetupDialog, showModal, 0}},
- {2366, {wxPageSetupDialogData, new_0, 0}},
- {2367, {wxPageSetupDialogData, new_1_0, 1}},
- {2368, {wxPageSetupDialogData, new_1_1, 1}},
- {2369, {wxPageSetupDialogData, destruct, 0}},
- {2370, {wxPageSetupDialogData, enableHelp, 1}},
- {2371, {wxPageSetupDialogData, enableMargins, 1}},
- {2372, {wxPageSetupDialogData, enableOrientation, 1}},
- {2373, {wxPageSetupDialogData, enablePaper, 1}},
- {2374, {wxPageSetupDialogData, enablePrinter, 1}},
- {2375, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
- {2376, {wxPageSetupDialogData, getEnableMargins, 0}},
- {2377, {wxPageSetupDialogData, getEnableOrientation, 0}},
- {2378, {wxPageSetupDialogData, getEnablePaper, 0}},
- {2379, {wxPageSetupDialogData, getEnablePrinter, 0}},
- {2380, {wxPageSetupDialogData, getEnableHelp, 0}},
- {2381, {wxPageSetupDialogData, getDefaultInfo, 0}},
- {2382, {wxPageSetupDialogData, getMarginTopLeft, 0}},
- {2383, {wxPageSetupDialogData, getMarginBottomRight, 0}},
- {2384, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
- {2385, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
- {2386, {wxPageSetupDialogData, getPaperId, 0}},
- {2387, {wxPageSetupDialogData, getPaperSize, 0}},
- {2389, {wxPageSetupDialogData, getPrintData, 0}},
- {2390, {wxPageSetupDialogData, isOk, 0}},
- {2391, {wxPageSetupDialogData, setDefaultInfo, 1}},
- {2392, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
- {2393, {wxPageSetupDialogData, setMarginTopLeft, 1}},
- {2394, {wxPageSetupDialogData, setMarginBottomRight, 1}},
- {2395, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
- {2396, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
- {2397, {wxPageSetupDialogData, setPaperId, 1}},
- {2398, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
- {2399, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
- {2400, {wxPageSetupDialogData, setPrintData, 1}},
- {2401, {wxPrintDialog, new_2_0, 2}},
- {2402, {wxPrintDialog, new_2_1, 2}},
- {2403, {wxPrintDialog, destruct, 0}},
- {2404, {wxPrintDialog, getPrintDialogData, 0}},
- {2405, {wxPrintDialog, getPrintDC, 0}},
- {2406, {wxPrintDialogData, new_0, 0}},
- {2407, {wxPrintDialogData, new_1_1, 1}},
- {2408, {wxPrintDialogData, new_1_0, 1}},
- {2409, {wxPrintDialogData, destruct, 0}},
- {2410, {wxPrintDialogData, enableHelp, 1}},
- {2411, {wxPrintDialogData, enablePageNumbers, 1}},
- {2412, {wxPrintDialogData, enablePrintToFile, 1}},
- {2413, {wxPrintDialogData, enableSelection, 1}},
- {2414, {wxPrintDialogData, getAllPages, 0}},
- {2415, {wxPrintDialogData, getCollate, 0}},
- {2416, {wxPrintDialogData, getFromPage, 0}},
- {2417, {wxPrintDialogData, getMaxPage, 0}},
- {2418, {wxPrintDialogData, getMinPage, 0}},
- {2419, {wxPrintDialogData, getNoCopies, 0}},
- {2420, {wxPrintDialogData, getPrintData, 0}},
- {2421, {wxPrintDialogData, getPrintToFile, 0}},
- {2422, {wxPrintDialogData, getSelection, 0}},
- {2423, {wxPrintDialogData, getToPage, 0}},
- {2424, {wxPrintDialogData, isOk, 0}},
- {2425, {wxPrintDialogData, setCollate, 1}},
- {2426, {wxPrintDialogData, setFromPage, 1}},
- {2427, {wxPrintDialogData, setMaxPage, 1}},
- {2428, {wxPrintDialogData, setMinPage, 1}},
- {2429, {wxPrintDialogData, setNoCopies, 1}},
- {2430, {wxPrintDialogData, setPrintData, 1}},
- {2431, {wxPrintDialogData, setPrintToFile, 1}},
- {2432, {wxPrintDialogData, setSelection, 1}},
- {2433, {wxPrintDialogData, setToPage, 1}},
- {2434, {wxPrintData, new_0, 0}},
- {2435, {wxPrintData, new_1, 1}},
- {2436, {wxPrintData, destruct, 0}},
- {2437, {wxPrintData, getCollate, 0}},
- {2438, {wxPrintData, getBin, 0}},
- {2439, {wxPrintData, getColour, 0}},
- {2440, {wxPrintData, getDuplex, 0}},
- {2441, {wxPrintData, getNoCopies, 0}},
- {2442, {wxPrintData, getOrientation, 0}},
- {2443, {wxPrintData, getPaperId, 0}},
- {2444, {wxPrintData, getPrinterName, 0}},
- {2445, {wxPrintData, getQuality, 0}},
- {2446, {wxPrintData, isOk, 0}},
- {2447, {wxPrintData, setBin, 1}},
- {2448, {wxPrintData, setCollate, 1}},
- {2449, {wxPrintData, setColour, 1}},
- {2450, {wxPrintData, setDuplex, 1}},
- {2451, {wxPrintData, setNoCopies, 1}},
- {2452, {wxPrintData, setOrientation, 1}},
- {2453, {wxPrintData, setPaperId, 1}},
- {2454, {wxPrintData, setPrinterName, 1}},
- {2455, {wxPrintData, setQuality, 1}},
- {2458, {wxPrintPreview, new_2, 2}},
- {2459, {wxPrintPreview, new_3, 3}},
- {2461, {wxPrintPreview, destruct, 0}},
- {2462, {wxPrintPreview, getCanvas, 0}},
- {2463, {wxPrintPreview, getCurrentPage, 0}},
- {2464, {wxPrintPreview, getFrame, 0}},
- {2465, {wxPrintPreview, getMaxPage, 0}},
- {2466, {wxPrintPreview, getMinPage, 0}},
- {2467, {wxPrintPreview, getPrintout, 0}},
- {2468, {wxPrintPreview, getPrintoutForPrinting, 0}},
- {2469, {wxPrintPreview, isOk, 0}},
- {2470, {wxPrintPreview, paintPage, 2}},
- {2471, {wxPrintPreview, print, 1}},
- {2472, {wxPrintPreview, renderPage, 1}},
- {2473, {wxPrintPreview, setCanvas, 1}},
- {2474, {wxPrintPreview, setCurrentPage, 1}},
- {2475, {wxPrintPreview, setFrame, 1}},
- {2476, {wxPrintPreview, setPrintout, 1}},
- {2477, {wxPrintPreview, setZoom, 1}},
- {2478, {wxPreviewFrame, new, 3}},
- {2479, {wxPreviewFrame, destruct, 0}},
- {2480, {wxPreviewFrame, createControlBar, 0}},
- {2481, {wxPreviewFrame, createCanvas, 0}},
- {2482, {wxPreviewFrame, initialize, 0}},
- {2483, {wxPreviewFrame, onCloseWindow, 1}},
- {2484, {wxPreviewControlBar, new, 4}},
- {2485, {wxPreviewControlBar, destruct, 0}},
- {2486, {wxPreviewControlBar, createButtons, 0}},
- {2487, {wxPreviewControlBar, getPrintPreview, 0}},
- {2488, {wxPreviewControlBar, getZoomControl, 0}},
- {2489, {wxPreviewControlBar, setZoomControl, 1}},
- {2491, {wxPrinter, new, 1}},
- {2492, {wxPrinter, createAbortWindow, 2}},
- {2493, {wxPrinter, getAbort, 0}},
- {2494, {wxPrinter, getLastError, 0}},
- {2495, {wxPrinter, getPrintDialogData, 0}},
- {2496, {wxPrinter, print, 3}},
- {2497, {wxPrinter, printDialog, 1}},
- {2498, {wxPrinter, reportError, 3}},
- {2499, {wxPrinter, setup, 1}},
- {2500, {wxPrinter, 'Destroy', undefined}},
- {2501, {wxXmlResource, new_1, 1}},
- {2502, {wxXmlResource, new_2, 2}},
- {2503, {wxXmlResource, destruct, 0}},
- {2504, {wxXmlResource, attachUnknownControl, 3}},
- {2505, {wxXmlResource, clearHandlers, 0}},
- {2506, {wxXmlResource, compareVersion, 4}},
- {2507, {wxXmlResource, get, 0}},
- {2508, {wxXmlResource, getFlags, 0}},
- {2509, {wxXmlResource, getVersion, 0}},
- {2510, {wxXmlResource, getXRCID, 2}},
- {2511, {wxXmlResource, initAllHandlers, 0}},
- {2512, {wxXmlResource, load, 1}},
- {2513, {wxXmlResource, loadBitmap, 1}},
- {2514, {wxXmlResource, loadDialog_2, 2}},
- {2515, {wxXmlResource, loadDialog_3, 3}},
- {2516, {wxXmlResource, loadFrame_2, 2}},
- {2517, {wxXmlResource, loadFrame_3, 3}},
- {2518, {wxXmlResource, loadIcon, 1}},
- {2519, {wxXmlResource, loadMenu, 1}},
- {2520, {wxXmlResource, loadMenuBar_2, 2}},
- {2521, {wxXmlResource, loadMenuBar_1, 1}},
- {2522, {wxXmlResource, loadPanel_2, 2}},
- {2523, {wxXmlResource, loadPanel_3, 3}},
- {2524, {wxXmlResource, loadToolBar, 2}},
- {2525, {wxXmlResource, set, 1}},
- {2526, {wxXmlResource, setFlags, 1}},
- {2527, {wxXmlResource, unload, 1}},
- {2528, {wxXmlResource, xrcctrl, 3}},
- {2529, {wxHtmlEasyPrinting, new, 1}},
- {2530, {wxHtmlEasyPrinting, destruct, 0}},
- {2531, {wxHtmlEasyPrinting, getPrintData, 0}},
- {2532, {wxHtmlEasyPrinting, getPageSetupData, 0}},
- {2533, {wxHtmlEasyPrinting, previewFile, 1}},
- {2534, {wxHtmlEasyPrinting, previewText, 2}},
- {2535, {wxHtmlEasyPrinting, printFile, 1}},
- {2536, {wxHtmlEasyPrinting, printText, 2}},
- {2537, {wxHtmlEasyPrinting, pageSetup, 0}},
- {2538, {wxHtmlEasyPrinting, setFonts, 3}},
- {2539, {wxHtmlEasyPrinting, setHeader, 2}},
- {2540, {wxHtmlEasyPrinting, setFooter, 2}},
- {2542, {wxGLCanvas, new_2, 2}},
- {2543, {wxGLCanvas, new_3_1, 3}},
- {2544, {wxGLCanvas, new_3_0, 3}},
- {2545, {wxGLCanvas, getContext, 0}},
- {2547, {wxGLCanvas, setCurrent, 0}},
- {2548, {wxGLCanvas, swapBuffers, 0}},
- {2549, {wxGLCanvas, 'Destroy', undefined}},
- {2550, {wxAuiManager, new, 1}},
- {2551, {wxAuiManager, destruct, 0}},
- {2552, {wxAuiManager, addPane_2_1, 2}},
- {2553, {wxAuiManager, addPane_3, 3}},
- {2554, {wxAuiManager, addPane_2_0, 2}},
- {2555, {wxAuiManager, detachPane, 1}},
- {2556, {wxAuiManager, getAllPanes, 0}},
- {2557, {wxAuiManager, getArtProvider, 0}},
- {2558, {wxAuiManager, getDockSizeConstraint, 2}},
- {2559, {wxAuiManager, getFlags, 0}},
- {2560, {wxAuiManager, getManagedWindow, 0}},
- {2561, {wxAuiManager, getManager, 1}},
- {2562, {wxAuiManager, getPane_1_1, 1}},
- {2563, {wxAuiManager, getPane_1_0, 1}},
- {2564, {wxAuiManager, hideHint, 0}},
- {2565, {wxAuiManager, insertPane, 3}},
- {2566, {wxAuiManager, loadPaneInfo, 2}},
- {2567, {wxAuiManager, loadPerspective, 2}},
- {2568, {wxAuiManager, savePaneInfo, 1}},
- {2569, {wxAuiManager, savePerspective, 0}},
- {2570, {wxAuiManager, setArtProvider, 1}},
- {2571, {wxAuiManager, setDockSizeConstraint, 2}},
- {2572, {wxAuiManager, setFlags, 1}},
- {2573, {wxAuiManager, setManagedWindow, 1}},
- {2574, {wxAuiManager, showHint, 1}},
- {2575, {wxAuiManager, unInit, 0}},
- {2576, {wxAuiManager, update, 0}},
- {2577, {wxAuiPaneInfo, new_0, 0}},
- {2578, {wxAuiPaneInfo, new_1, 1}},
- {2579, {wxAuiPaneInfo, destruct, 0}},
- {2580, {wxAuiPaneInfo, bestSize_1, 1}},
- {2581, {wxAuiPaneInfo, bestSize_2, 2}},
- {2582, {wxAuiPaneInfo, bottom, 0}},
- {2583, {wxAuiPaneInfo, bottomDockable, 1}},
- {2584, {wxAuiPaneInfo, caption, 1}},
- {2585, {wxAuiPaneInfo, captionVisible, 1}},
- {2586, {wxAuiPaneInfo, centre, 0}},
- {2587, {wxAuiPaneInfo, centrePane, 0}},
- {2588, {wxAuiPaneInfo, closeButton, 1}},
- {2589, {wxAuiPaneInfo, defaultPane, 0}},
- {2590, {wxAuiPaneInfo, destroyOnClose, 1}},
- {2591, {wxAuiPaneInfo, direction, 1}},
- {2592, {wxAuiPaneInfo, dock, 0}},
- {2593, {wxAuiPaneInfo, dockable, 1}},
- {2594, {wxAuiPaneInfo, fixed, 0}},
- {2595, {wxAuiPaneInfo, float, 0}},
- {2596, {wxAuiPaneInfo, floatable, 1}},
- {2597, {wxAuiPaneInfo, floatingPosition_1, 1}},
- {2598, {wxAuiPaneInfo, floatingPosition_2, 2}},
- {2599, {wxAuiPaneInfo, floatingSize_1, 1}},
- {2600, {wxAuiPaneInfo, floatingSize_2, 2}},
- {2601, {wxAuiPaneInfo, gripper, 1}},
- {2602, {wxAuiPaneInfo, gripperTop, 1}},
- {2603, {wxAuiPaneInfo, hasBorder, 0}},
- {2604, {wxAuiPaneInfo, hasCaption, 0}},
- {2605, {wxAuiPaneInfo, hasCloseButton, 0}},
- {2606, {wxAuiPaneInfo, hasFlag, 1}},
- {2607, {wxAuiPaneInfo, hasGripper, 0}},
- {2608, {wxAuiPaneInfo, hasGripperTop, 0}},
- {2609, {wxAuiPaneInfo, hasMaximizeButton, 0}},
- {2610, {wxAuiPaneInfo, hasMinimizeButton, 0}},
- {2611, {wxAuiPaneInfo, hasPinButton, 0}},
- {2612, {wxAuiPaneInfo, hide, 0}},
- {2613, {wxAuiPaneInfo, isBottomDockable, 0}},
- {2614, {wxAuiPaneInfo, isDocked, 0}},
- {2615, {wxAuiPaneInfo, isFixed, 0}},
- {2616, {wxAuiPaneInfo, isFloatable, 0}},
- {2617, {wxAuiPaneInfo, isFloating, 0}},
- {2618, {wxAuiPaneInfo, isLeftDockable, 0}},
- {2619, {wxAuiPaneInfo, isMovable, 0}},
- {2620, {wxAuiPaneInfo, isOk, 0}},
- {2621, {wxAuiPaneInfo, isResizable, 0}},
- {2622, {wxAuiPaneInfo, isRightDockable, 0}},
- {2623, {wxAuiPaneInfo, isShown, 0}},
- {2624, {wxAuiPaneInfo, isToolbar, 0}},
- {2625, {wxAuiPaneInfo, isTopDockable, 0}},
- {2626, {wxAuiPaneInfo, layer, 1}},
- {2627, {wxAuiPaneInfo, left, 0}},
- {2628, {wxAuiPaneInfo, leftDockable, 1}},
- {2629, {wxAuiPaneInfo, maxSize_1, 1}},
- {2630, {wxAuiPaneInfo, maxSize_2, 2}},
- {2631, {wxAuiPaneInfo, maximizeButton, 1}},
- {2632, {wxAuiPaneInfo, minSize_1, 1}},
- {2633, {wxAuiPaneInfo, minSize_2, 2}},
- {2634, {wxAuiPaneInfo, minimizeButton, 1}},
- {2635, {wxAuiPaneInfo, movable, 1}},
- {2636, {wxAuiPaneInfo, name, 1}},
- {2637, {wxAuiPaneInfo, paneBorder, 1}},
- {2638, {wxAuiPaneInfo, pinButton, 1}},
- {2639, {wxAuiPaneInfo, position, 1}},
- {2640, {wxAuiPaneInfo, resizable, 1}},
- {2641, {wxAuiPaneInfo, right, 0}},
- {2642, {wxAuiPaneInfo, rightDockable, 1}},
- {2643, {wxAuiPaneInfo, row, 1}},
- {2644, {wxAuiPaneInfo, safeSet, 1}},
- {2645, {wxAuiPaneInfo, setFlag, 2}},
- {2646, {wxAuiPaneInfo, show, 1}},
- {2647, {wxAuiPaneInfo, toolbarPane, 0}},
- {2648, {wxAuiPaneInfo, top, 0}},
- {2649, {wxAuiPaneInfo, topDockable, 1}},
- {2650, {wxAuiPaneInfo, window, 1}},
- {2651, {wxAuiNotebook, new_0, 0}},
- {2652, {wxAuiNotebook, new_2, 2}},
- {2653, {wxAuiNotebook, addPage, 3}},
- {2654, {wxAuiNotebook, create, 2}},
- {2655, {wxAuiNotebook, deletePage, 1}},
- {2656, {wxAuiNotebook, getArtProvider, 0}},
- {2657, {wxAuiNotebook, getPage, 1}},
- {2658, {wxAuiNotebook, getPageBitmap, 1}},
- {2659, {wxAuiNotebook, getPageCount, 0}},
- {2660, {wxAuiNotebook, getPageIndex, 1}},
- {2661, {wxAuiNotebook, getPageText, 1}},
- {2662, {wxAuiNotebook, getSelection, 0}},
- {2663, {wxAuiNotebook, insertPage, 4}},
- {2664, {wxAuiNotebook, removePage, 1}},
- {2665, {wxAuiNotebook, setArtProvider, 1}},
- {2666, {wxAuiNotebook, setFont, 1}},
- {2667, {wxAuiNotebook, setPageBitmap, 2}},
- {2668, {wxAuiNotebook, setPageText, 2}},
- {2669, {wxAuiNotebook, setSelection, 1}},
- {2670, {wxAuiNotebook, setTabCtrlHeight, 1}},
- {2671, {wxAuiNotebook, setUniformBitmapSize, 1}},
- {2672, {wxAuiNotebook, 'Destroy', undefined}},
- {2673, {wxMDIParentFrame, new_0, 0}},
- {2674, {wxMDIParentFrame, new_4, 4}},
- {2675, {wxMDIParentFrame, destruct, 0}},
- {2676, {wxMDIParentFrame, activateNext, 0}},
- {2677, {wxMDIParentFrame, activatePrevious, 0}},
- {2678, {wxMDIParentFrame, arrangeIcons, 0}},
- {2679, {wxMDIParentFrame, cascade, 0}},
- {2680, {wxMDIParentFrame, create, 4}},
- {2681, {wxMDIParentFrame, getActiveChild, 0}},
- {2682, {wxMDIParentFrame, getClientWindow, 0}},
- {2683, {wxMDIParentFrame, tile, 1}},
- {2684, {wxMDIChildFrame, new_0, 0}},
- {2685, {wxMDIChildFrame, new_4, 4}},
- {2686, {wxMDIChildFrame, destruct, 0}},
- {2687, {wxMDIChildFrame, activate, 0}},
- {2688, {wxMDIChildFrame, create, 4}},
- {2689, {wxMDIChildFrame, maximize, 1}},
- {2690, {wxMDIChildFrame, restore, 0}},
- {2691, {wxMDIClientWindow, new_0, 0}},
- {2692, {wxMDIClientWindow, new_2, 2}},
- {2693, {wxMDIClientWindow, destruct, 0}},
- {2694, {wxMDIClientWindow, createClient, 2}},
- {2695, {wxLayoutAlgorithm, new, 0}},
- {2696, {wxLayoutAlgorithm, layoutFrame, 2}},
- {2697, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
- {2698, {wxLayoutAlgorithm, layoutWindow, 2}},
- {2699, {wxLayoutAlgorithm, 'Destroy', undefined}},
- {2700, {wxEvent, getId, 0}},
- {2701, {wxEvent, getSkipped, 0}},
- {2702, {wxEvent, getTimestamp, 0}},
- {2703, {wxEvent, isCommandEvent, 0}},
- {2704, {wxEvent, resumePropagation, 1}},
- {2705, {wxEvent, shouldPropagate, 0}},
- {2706, {wxEvent, skip, 1}},
- {2707, {wxEvent, stopPropagation, 0}},
- {2708, {wxCommandEvent, getClientData, 0}},
- {2709, {wxCommandEvent, getExtraLong, 0}},
- {2710, {wxCommandEvent, getInt, 0}},
- {2711, {wxCommandEvent, getSelection, 0}},
- {2712, {wxCommandEvent, getString, 0}},
- {2713, {wxCommandEvent, isChecked, 0}},
- {2714, {wxCommandEvent, isSelection, 0}},
- {2715, {wxCommandEvent, setInt, 1}},
- {2716, {wxCommandEvent, setString, 1}},
- {2717, {wxScrollEvent, getOrientation, 0}},
- {2718, {wxScrollEvent, getPosition, 0}},
- {2719, {wxScrollWinEvent, getOrientation, 0}},
- {2720, {wxScrollWinEvent, getPosition, 0}},
- {2721, {wxMouseEvent, altDown, 0}},
- {2722, {wxMouseEvent, button, 1}},
- {2723, {wxMouseEvent, buttonDClick, 1}},
- {2724, {wxMouseEvent, buttonDown, 1}},
- {2725, {wxMouseEvent, buttonUp, 1}},
- {2726, {wxMouseEvent, cmdDown, 0}},
- {2727, {wxMouseEvent, controlDown, 0}},
- {2728, {wxMouseEvent, dragging, 0}},
- {2729, {wxMouseEvent, entering, 0}},
- {2730, {wxMouseEvent, getButton, 0}},
- {2733, {wxMouseEvent, getPosition, 0}},
- {2734, {wxMouseEvent, getLogicalPosition, 1}},
- {2735, {wxMouseEvent, getLinesPerAction, 0}},
- {2736, {wxMouseEvent, getWheelRotation, 0}},
- {2737, {wxMouseEvent, getWheelDelta, 0}},
- {2738, {wxMouseEvent, getX, 0}},
- {2739, {wxMouseEvent, getY, 0}},
- {2740, {wxMouseEvent, isButton, 0}},
- {2741, {wxMouseEvent, isPageScroll, 0}},
- {2742, {wxMouseEvent, leaving, 0}},
- {2743, {wxMouseEvent, leftDClick, 0}},
- {2744, {wxMouseEvent, leftDown, 0}},
- {2745, {wxMouseEvent, leftIsDown, 0}},
- {2746, {wxMouseEvent, leftUp, 0}},
- {2747, {wxMouseEvent, metaDown, 0}},
- {2748, {wxMouseEvent, middleDClick, 0}},
- {2749, {wxMouseEvent, middleDown, 0}},
- {2750, {wxMouseEvent, middleIsDown, 0}},
- {2751, {wxMouseEvent, middleUp, 0}},
- {2752, {wxMouseEvent, moving, 0}},
- {2753, {wxMouseEvent, rightDClick, 0}},
- {2754, {wxMouseEvent, rightDown, 0}},
- {2755, {wxMouseEvent, rightIsDown, 0}},
- {2756, {wxMouseEvent, rightUp, 0}},
- {2757, {wxMouseEvent, shiftDown, 0}},
- {2758, {wxSetCursorEvent, getCursor, 0}},
- {2759, {wxSetCursorEvent, getX, 0}},
- {2760, {wxSetCursorEvent, getY, 0}},
- {2761, {wxSetCursorEvent, hasCursor, 0}},
- {2762, {wxSetCursorEvent, setCursor, 1}},
- {2763, {wxKeyEvent, altDown, 0}},
- {2764, {wxKeyEvent, cmdDown, 0}},
- {2765, {wxKeyEvent, controlDown, 0}},
- {2766, {wxKeyEvent, getKeyCode, 0}},
- {2767, {wxKeyEvent, getModifiers, 0}},
- {2770, {wxKeyEvent, getPosition, 0}},
- {2771, {wxKeyEvent, getRawKeyCode, 0}},
- {2772, {wxKeyEvent, getRawKeyFlags, 0}},
- {2773, {wxKeyEvent, getUnicodeKey, 0}},
- {2774, {wxKeyEvent, getX, 0}},
- {2775, {wxKeyEvent, getY, 0}},
- {2776, {wxKeyEvent, hasModifiers, 0}},
- {2777, {wxKeyEvent, metaDown, 0}},
- {2778, {wxKeyEvent, shiftDown, 0}},
- {2779, {wxSizeEvent, getSize, 0}},
- {2780, {wxMoveEvent, getPosition, 0}},
- {2781, {wxEraseEvent, getDC, 0}},
- {2782, {wxFocusEvent, getWindow, 0}},
- {2783, {wxChildFocusEvent, getWindow, 0}},
- {2784, {wxMenuEvent, getMenu, 0}},
- {2785, {wxMenuEvent, getMenuId, 0}},
- {2786, {wxMenuEvent, isPopup, 0}},
- {2787, {wxCloseEvent, canVeto, 0}},
- {2788, {wxCloseEvent, getLoggingOff, 0}},
- {2789, {wxCloseEvent, setCanVeto, 1}},
- {2790, {wxCloseEvent, setLoggingOff, 1}},
- {2791, {wxCloseEvent, veto, 1}},
- {2792, {wxShowEvent, setShow, 1}},
- {2793, {wxShowEvent, getShow, 0}},
- {2794, {wxIconizeEvent, iconized, 0}},
- {2795, {wxJoystickEvent, buttonDown, 1}},
- {2796, {wxJoystickEvent, buttonIsDown, 1}},
- {2797, {wxJoystickEvent, buttonUp, 1}},
- {2798, {wxJoystickEvent, getButtonChange, 0}},
- {2799, {wxJoystickEvent, getButtonState, 0}},
- {2800, {wxJoystickEvent, getJoystick, 0}},
- {2801, {wxJoystickEvent, getPosition, 0}},
- {2802, {wxJoystickEvent, getZPosition, 0}},
- {2803, {wxJoystickEvent, isButton, 0}},
- {2804, {wxJoystickEvent, isMove, 0}},
- {2805, {wxJoystickEvent, isZMove, 0}},
- {2806, {wxUpdateUIEvent, canUpdate, 1}},
- {2807, {wxUpdateUIEvent, check, 1}},
- {2808, {wxUpdateUIEvent, enable, 1}},
- {2809, {wxUpdateUIEvent, show, 1}},
- {2810, {wxUpdateUIEvent, getChecked, 0}},
- {2811, {wxUpdateUIEvent, getEnabled, 0}},
- {2812, {wxUpdateUIEvent, getShown, 0}},
- {2813, {wxUpdateUIEvent, getSetChecked, 0}},
- {2814, {wxUpdateUIEvent, getSetEnabled, 0}},
- {2815, {wxUpdateUIEvent, getSetShown, 0}},
- {2816, {wxUpdateUIEvent, getSetText, 0}},
- {2817, {wxUpdateUIEvent, getText, 0}},
- {2818, {wxUpdateUIEvent, getMode, 0}},
- {2819, {wxUpdateUIEvent, getUpdateInterval, 0}},
- {2820, {wxUpdateUIEvent, resetUpdateTime, 0}},
- {2821, {wxUpdateUIEvent, setMode, 1}},
- {2822, {wxUpdateUIEvent, setText, 1}},
- {2823, {wxUpdateUIEvent, setUpdateInterval, 1}},
- {2824, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
- {2825, {wxPaletteChangedEvent, setChangedWindow, 1}},
- {2826, {wxPaletteChangedEvent, getChangedWindow, 0}},
- {2827, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
- {2828, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
- {2829, {wxNavigationKeyEvent, getDirection, 0}},
- {2830, {wxNavigationKeyEvent, setDirection, 1}},
- {2831, {wxNavigationKeyEvent, isWindowChange, 0}},
- {2832, {wxNavigationKeyEvent, setWindowChange, 1}},
- {2833, {wxNavigationKeyEvent, isFromTab, 0}},
- {2834, {wxNavigationKeyEvent, setFromTab, 1}},
- {2835, {wxNavigationKeyEvent, getCurrentFocus, 0}},
- {2836, {wxNavigationKeyEvent, setCurrentFocus, 1}},
- {2837, {wxHelpEvent, getOrigin, 0}},
- {2838, {wxHelpEvent, getPosition, 0}},
- {2839, {wxHelpEvent, setOrigin, 1}},
- {2840, {wxHelpEvent, setPosition, 1}},
- {2841, {wxContextMenuEvent, getPosition, 0}},
- {2842, {wxContextMenuEvent, setPosition, 1}},
- {2843, {wxIdleEvent, canSend, 1}},
- {2844, {wxIdleEvent, getMode, 0}},
- {2845, {wxIdleEvent, requestMore, 1}},
- {2846, {wxIdleEvent, moreRequested, 0}},
- {2847, {wxIdleEvent, setMode, 1}},
- {2848, {wxGridEvent, altDown, 0}},
- {2849, {wxGridEvent, controlDown, 0}},
- {2850, {wxGridEvent, getCol, 0}},
- {2851, {wxGridEvent, getPosition, 0}},
- {2852, {wxGridEvent, getRow, 0}},
- {2853, {wxGridEvent, metaDown, 0}},
- {2854, {wxGridEvent, selecting, 0}},
- {2855, {wxGridEvent, shiftDown, 0}},
- {2856, {wxNotifyEvent, allow, 0}},
- {2857, {wxNotifyEvent, isAllowed, 0}},
- {2858, {wxNotifyEvent, veto, 0}},
- {2859, {wxSashEvent, getEdge, 0}},
- {2860, {wxSashEvent, getDragRect, 0}},
- {2861, {wxSashEvent, getDragStatus, 0}},
- {2862, {wxListEvent, getCacheFrom, 0}},
- {2863, {wxListEvent, getCacheTo, 0}},
- {2864, {wxListEvent, getKeyCode, 0}},
- {2865, {wxListEvent, getIndex, 0}},
- {2866, {wxListEvent, getColumn, 0}},
- {2867, {wxListEvent, getPoint, 0}},
- {2868, {wxListEvent, getLabel, 0}},
- {2869, {wxListEvent, getText, 0}},
- {2870, {wxListEvent, getImage, 0}},
- {2871, {wxListEvent, getData, 0}},
- {2872, {wxListEvent, getMask, 0}},
- {2873, {wxListEvent, getItem, 0}},
- {2874, {wxListEvent, isEditCancelled, 0}},
- {2875, {wxDateEvent, getDate, 0}},
- {2876, {wxCalendarEvent, getWeekDay, 0}},
- {2877, {wxFileDirPickerEvent, getPath, 0}},
- {2878, {wxColourPickerEvent, getColour, 0}},
- {2879, {wxFontPickerEvent, getFont, 0}},
- {2880, {wxStyledTextEvent, getPosition, 0}},
- {2881, {wxStyledTextEvent, getKey, 0}},
- {2882, {wxStyledTextEvent, getModifiers, 0}},
- {2883, {wxStyledTextEvent, getModificationType, 0}},
- {2884, {wxStyledTextEvent, getText, 0}},
- {2885, {wxStyledTextEvent, getLength, 0}},
- {2886, {wxStyledTextEvent, getLinesAdded, 0}},
- {2887, {wxStyledTextEvent, getLine, 0}},
- {2888, {wxStyledTextEvent, getFoldLevelNow, 0}},
- {2889, {wxStyledTextEvent, getFoldLevelPrev, 0}},
- {2890, {wxStyledTextEvent, getMargin, 0}},
- {2891, {wxStyledTextEvent, getMessage, 0}},
- {2892, {wxStyledTextEvent, getWParam, 0}},
- {2893, {wxStyledTextEvent, getLParam, 0}},
- {2894, {wxStyledTextEvent, getListType, 0}},
- {2895, {wxStyledTextEvent, getX, 0}},
- {2896, {wxStyledTextEvent, getY, 0}},
- {2897, {wxStyledTextEvent, getDragText, 0}},
- {2898, {wxStyledTextEvent, getDragAllowMove, 0}},
- {2899, {wxStyledTextEvent, getDragResult, 0}},
- {2900, {wxStyledTextEvent, getShift, 0}},
- {2901, {wxStyledTextEvent, getControl, 0}},
- {2902, {wxStyledTextEvent, getAlt, 0}},
- {2903, {utils, getKeyState, 1}},
- {2904, {utils, getMousePosition, 2}},
- {2905, {utils, getMouseState, 0}},
- {2906, {utils, setDetectableAutoRepeat, 1}},
- {2907, {utils, bell, 0}},
- {2908, {utils, findMenuItemId, 3}},
- {2909, {utils, genericFindWindowAtPoint, 1}},
- {2910, {utils, findWindowAtPoint, 1}},
- {2911, {utils, beginBusyCursor, 1}},
- {2912, {utils, endBusyCursor, 0}},
- {2913, {utils, isBusy, 0}},
- {2914, {utils, shutdown, 1}},
- {2915, {utils, shell, 1}},
- {2916, {utils, launchDefaultBrowser, 2}},
- {2917, {utils, getEmailAddress, 0}},
- {2918, {utils, getUserId, 0}},
- {2919, {utils, getHomeDir, 0}},
- {2920, {utils, newId, 0}},
- {2921, {utils, registerId, 1}},
- {2922, {utils, getCurrentId, 0}},
- {2923, {utils, getOsDescription, 0}},
- {2924, {utils, isPlatformLittleEndian, 0}},
- {2925, {utils, isPlatform64Bit, 0}},
- {2926, {wxPrintout, new, 1}},
- {2927, {wxPrintout, destruct, 0}},
- {2928, {wxPrintout, getDC, 0}},
- {2929, {wxPrintout, getPageSizeMM, 2}},
- {2930, {wxPrintout, getPageSizePixels, 2}},
- {2931, {wxPrintout, getPaperRectPixels, 0}},
- {2932, {wxPrintout, getPPIPrinter, 2}},
- {2933, {wxPrintout, getPPIScreen, 2}},
- {2934, {wxPrintout, getTitle, 0}},
- {2935, {wxPrintout, isPreview, 0}},
- {2936, {wxPrintout, fitThisSizeToPaper, 1}},
- {2937, {wxPrintout, fitThisSizeToPage, 1}},
- {2938, {wxPrintout, fitThisSizeToPageMargins, 2}},
- {2939, {wxPrintout, mapScreenSizeToPaper, 0}},
- {2940, {wxPrintout, mapScreenSizeToPage, 0}},
- {2941, {wxPrintout, mapScreenSizeToPageMargins, 1}},
- {2942, {wxPrintout, mapScreenSizeToDevice, 0}},
- {2943, {wxPrintout, getLogicalPaperRect, 0}},
- {2944, {wxPrintout, getLogicalPageRect, 0}},
- {2945, {wxPrintout, getLogicalPageMarginsRect, 1}},
- {2946, {wxPrintout, setLogicalOrigin, 2}},
- {2947, {wxPrintout, offsetLogicalOrigin, 2}},
- {2948, {wxStyledTextCtrl, new_2, 2}},
- {2949, {wxStyledTextCtrl, new_0, 0}},
- {2950, {wxStyledTextCtrl, destruct, 0}},
- {2951, {wxStyledTextCtrl, create, 2}},
- {2952, {wxStyledTextCtrl, addText, 1}},
- {2953, {wxStyledTextCtrl, addStyledText, 1}},
- {2954, {wxStyledTextCtrl, insertText, 2}},
- {2955, {wxStyledTextCtrl, clearAll, 0}},
- {2956, {wxStyledTextCtrl, clearDocumentStyle, 0}},
- {2957, {wxStyledTextCtrl, getLength, 0}},
- {2958, {wxStyledTextCtrl, getCharAt, 1}},
- {2959, {wxStyledTextCtrl, getCurrentPos, 0}},
- {2960, {wxStyledTextCtrl, getAnchor, 0}},
- {2961, {wxStyledTextCtrl, getStyleAt, 1}},
- {2962, {wxStyledTextCtrl, redo, 0}},
- {2963, {wxStyledTextCtrl, setUndoCollection, 1}},
- {2964, {wxStyledTextCtrl, selectAll, 0}},
- {2965, {wxStyledTextCtrl, setSavePoint, 0}},
- {2966, {wxStyledTextCtrl, getStyledText, 2}},
- {2967, {wxStyledTextCtrl, canRedo, 0}},
- {2968, {wxStyledTextCtrl, markerLineFromHandle, 1}},
- {2969, {wxStyledTextCtrl, markerDeleteHandle, 1}},
- {2970, {wxStyledTextCtrl, getUndoCollection, 0}},
- {2971, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
- {2972, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
- {2973, {wxStyledTextCtrl, positionFromPoint, 1}},
- {2974, {wxStyledTextCtrl, positionFromPointClose, 2}},
- {2975, {wxStyledTextCtrl, gotoLine, 1}},
- {2976, {wxStyledTextCtrl, gotoPos, 1}},
- {2977, {wxStyledTextCtrl, setAnchor, 1}},
- {2978, {wxStyledTextCtrl, getCurLine, 1}},
- {2979, {wxStyledTextCtrl, getEndStyled, 0}},
- {2980, {wxStyledTextCtrl, convertEOLs, 1}},
- {2981, {wxStyledTextCtrl, getEOLMode, 0}},
- {2982, {wxStyledTextCtrl, setEOLMode, 1}},
- {2983, {wxStyledTextCtrl, startStyling, 2}},
- {2984, {wxStyledTextCtrl, setStyling, 2}},
- {2985, {wxStyledTextCtrl, getBufferedDraw, 0}},
- {2986, {wxStyledTextCtrl, setBufferedDraw, 1}},
- {2987, {wxStyledTextCtrl, setTabWidth, 1}},
- {2988, {wxStyledTextCtrl, getTabWidth, 0}},
- {2989, {wxStyledTextCtrl, setCodePage, 1}},
- {2990, {wxStyledTextCtrl, markerDefine, 3}},
- {2991, {wxStyledTextCtrl, markerSetForeground, 2}},
- {2992, {wxStyledTextCtrl, markerSetBackground, 2}},
- {2993, {wxStyledTextCtrl, markerAdd, 2}},
- {2994, {wxStyledTextCtrl, markerDelete, 2}},
- {2995, {wxStyledTextCtrl, markerDeleteAll, 1}},
- {2996, {wxStyledTextCtrl, markerGet, 1}},
- {2997, {wxStyledTextCtrl, markerNext, 2}},
- {2998, {wxStyledTextCtrl, markerPrevious, 2}},
- {2999, {wxStyledTextCtrl, markerDefineBitmap, 2}},
- {3000, {wxStyledTextCtrl, markerAddSet, 2}},
- {3001, {wxStyledTextCtrl, markerSetAlpha, 2}},
- {3002, {wxStyledTextCtrl, setMarginType, 2}},
- {3003, {wxStyledTextCtrl, getMarginType, 1}},
- {3004, {wxStyledTextCtrl, setMarginWidth, 2}},
- {3005, {wxStyledTextCtrl, getMarginWidth, 1}},
- {3006, {wxStyledTextCtrl, setMarginMask, 2}},
- {3007, {wxStyledTextCtrl, getMarginMask, 1}},
- {3008, {wxStyledTextCtrl, setMarginSensitive, 2}},
- {3009, {wxStyledTextCtrl, getMarginSensitive, 1}},
- {3010, {wxStyledTextCtrl, styleClearAll, 0}},
- {3011, {wxStyledTextCtrl, styleSetForeground, 2}},
- {3012, {wxStyledTextCtrl, styleSetBackground, 2}},
- {3013, {wxStyledTextCtrl, styleSetBold, 2}},
- {3014, {wxStyledTextCtrl, styleSetItalic, 2}},
- {3015, {wxStyledTextCtrl, styleSetSize, 2}},
- {3016, {wxStyledTextCtrl, styleSetFaceName, 2}},
- {3017, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
- {3018, {wxStyledTextCtrl, styleResetDefault, 0}},
- {3019, {wxStyledTextCtrl, styleSetUnderline, 2}},
- {3020, {wxStyledTextCtrl, styleSetCase, 2}},
- {3021, {wxStyledTextCtrl, styleSetHotSpot, 2}},
- {3022, {wxStyledTextCtrl, setSelForeground, 2}},
- {3023, {wxStyledTextCtrl, setSelBackground, 2}},
- {3024, {wxStyledTextCtrl, getSelAlpha, 0}},
- {3025, {wxStyledTextCtrl, setSelAlpha, 1}},
- {3026, {wxStyledTextCtrl, setCaretForeground, 1}},
- {3027, {wxStyledTextCtrl, cmdKeyAssign, 3}},
- {3028, {wxStyledTextCtrl, cmdKeyClear, 2}},
- {3029, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
- {3030, {wxStyledTextCtrl, setStyleBytes, 2}},
- {3031, {wxStyledTextCtrl, styleSetVisible, 2}},
- {3032, {wxStyledTextCtrl, getCaretPeriod, 0}},
- {3033, {wxStyledTextCtrl, setCaretPeriod, 1}},
- {3034, {wxStyledTextCtrl, setWordChars, 1}},
- {3035, {wxStyledTextCtrl, beginUndoAction, 0}},
- {3036, {wxStyledTextCtrl, endUndoAction, 0}},
- {3037, {wxStyledTextCtrl, indicatorSetStyle, 2}},
- {3038, {wxStyledTextCtrl, indicatorGetStyle, 1}},
- {3039, {wxStyledTextCtrl, indicatorSetForeground, 2}},
- {3040, {wxStyledTextCtrl, indicatorGetForeground, 1}},
- {3041, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
- {3042, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
- {3043, {wxStyledTextCtrl, getStyleBits, 0}},
- {3044, {wxStyledTextCtrl, setLineState, 2}},
- {3045, {wxStyledTextCtrl, getLineState, 1}},
- {3046, {wxStyledTextCtrl, getMaxLineState, 0}},
- {3047, {wxStyledTextCtrl, getCaretLineVisible, 0}},
- {3048, {wxStyledTextCtrl, setCaretLineVisible, 1}},
- {3049, {wxStyledTextCtrl, getCaretLineBackground, 0}},
- {3050, {wxStyledTextCtrl, setCaretLineBackground, 1}},
- {3051, {wxStyledTextCtrl, autoCompShow, 2}},
- {3052, {wxStyledTextCtrl, autoCompCancel, 0}},
- {3053, {wxStyledTextCtrl, autoCompActive, 0}},
- {3054, {wxStyledTextCtrl, autoCompPosStart, 0}},
- {3055, {wxStyledTextCtrl, autoCompComplete, 0}},
- {3056, {wxStyledTextCtrl, autoCompStops, 1}},
- {3057, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
- {3058, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
- {3059, {wxStyledTextCtrl, autoCompSelect, 1}},
- {3060, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
- {3061, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
- {3062, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
- {3063, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
- {3064, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
- {3065, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
- {3066, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
- {3067, {wxStyledTextCtrl, userListShow, 2}},
- {3068, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
- {3069, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
- {3070, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
- {3071, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
- {3072, {wxStyledTextCtrl, registerImage, 2}},
- {3073, {wxStyledTextCtrl, clearRegisteredImages, 0}},
- {3074, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
- {3075, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
- {3076, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
- {3077, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
- {3078, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
- {3079, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
- {3080, {wxStyledTextCtrl, setIndent, 1}},
- {3081, {wxStyledTextCtrl, getIndent, 0}},
- {3082, {wxStyledTextCtrl, setUseTabs, 1}},
- {3083, {wxStyledTextCtrl, getUseTabs, 0}},
- {3084, {wxStyledTextCtrl, setLineIndentation, 2}},
- {3085, {wxStyledTextCtrl, getLineIndentation, 1}},
- {3086, {wxStyledTextCtrl, getLineIndentPosition, 1}},
- {3087, {wxStyledTextCtrl, getColumn, 1}},
- {3088, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
- {3089, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
- {3090, {wxStyledTextCtrl, setIndentationGuides, 1}},
- {3091, {wxStyledTextCtrl, getIndentationGuides, 0}},
- {3092, {wxStyledTextCtrl, setHighlightGuide, 1}},
- {3093, {wxStyledTextCtrl, getHighlightGuide, 0}},
- {3094, {wxStyledTextCtrl, getLineEndPosition, 1}},
- {3095, {wxStyledTextCtrl, getCodePage, 0}},
- {3096, {wxStyledTextCtrl, getCaretForeground, 0}},
- {3097, {wxStyledTextCtrl, getReadOnly, 0}},
- {3098, {wxStyledTextCtrl, setCurrentPos, 1}},
- {3099, {wxStyledTextCtrl, setSelectionStart, 1}},
- {3100, {wxStyledTextCtrl, getSelectionStart, 0}},
- {3101, {wxStyledTextCtrl, setSelectionEnd, 1}},
- {3102, {wxStyledTextCtrl, getSelectionEnd, 0}},
- {3103, {wxStyledTextCtrl, setPrintMagnification, 1}},
- {3104, {wxStyledTextCtrl, getPrintMagnification, 0}},
- {3105, {wxStyledTextCtrl, setPrintColourMode, 1}},
- {3106, {wxStyledTextCtrl, getPrintColourMode, 0}},
- {3107, {wxStyledTextCtrl, findText, 4}},
- {3108, {wxStyledTextCtrl, formatRange, 7}},
- {3109, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
- {3110, {wxStyledTextCtrl, getLine, 1}},
- {3111, {wxStyledTextCtrl, getLineCount, 0}},
- {3112, {wxStyledTextCtrl, setMarginLeft, 1}},
- {3113, {wxStyledTextCtrl, getMarginLeft, 0}},
- {3114, {wxStyledTextCtrl, setMarginRight, 1}},
- {3115, {wxStyledTextCtrl, getMarginRight, 0}},
- {3116, {wxStyledTextCtrl, getModify, 0}},
- {3117, {wxStyledTextCtrl, setSelection, 2}},
- {3118, {wxStyledTextCtrl, getSelectedText, 0}},
- {3119, {wxStyledTextCtrl, getTextRange, 2}},
- {3120, {wxStyledTextCtrl, hideSelection, 1}},
- {3121, {wxStyledTextCtrl, lineFromPosition, 1}},
- {3122, {wxStyledTextCtrl, positionFromLine, 1}},
- {3123, {wxStyledTextCtrl, lineScroll, 2}},
- {3124, {wxStyledTextCtrl, ensureCaretVisible, 0}},
- {3125, {wxStyledTextCtrl, replaceSelection, 1}},
- {3126, {wxStyledTextCtrl, setReadOnly, 1}},
- {3127, {wxStyledTextCtrl, canPaste, 0}},
- {3128, {wxStyledTextCtrl, canUndo, 0}},
- {3129, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
- {3130, {wxStyledTextCtrl, undo, 0}},
- {3131, {wxStyledTextCtrl, cut, 0}},
- {3132, {wxStyledTextCtrl, copy, 0}},
- {3133, {wxStyledTextCtrl, paste, 0}},
- {3134, {wxStyledTextCtrl, clear, 0}},
- {3135, {wxStyledTextCtrl, setText, 1}},
- {3136, {wxStyledTextCtrl, getText, 0}},
- {3137, {wxStyledTextCtrl, getTextLength, 0}},
- {3138, {wxStyledTextCtrl, getOvertype, 0}},
- {3139, {wxStyledTextCtrl, setCaretWidth, 1}},
- {3140, {wxStyledTextCtrl, getCaretWidth, 0}},
- {3141, {wxStyledTextCtrl, setTargetStart, 1}},
- {3142, {wxStyledTextCtrl, getTargetStart, 0}},
- {3143, {wxStyledTextCtrl, setTargetEnd, 1}},
- {3144, {wxStyledTextCtrl, getTargetEnd, 0}},
- {3145, {wxStyledTextCtrl, replaceTarget, 1}},
- {3146, {wxStyledTextCtrl, searchInTarget, 1}},
- {3147, {wxStyledTextCtrl, setSearchFlags, 1}},
- {3148, {wxStyledTextCtrl, getSearchFlags, 0}},
- {3149, {wxStyledTextCtrl, callTipShow, 2}},
- {3150, {wxStyledTextCtrl, callTipCancel, 0}},
- {3151, {wxStyledTextCtrl, callTipActive, 0}},
- {3152, {wxStyledTextCtrl, callTipPosAtStart, 0}},
- {3153, {wxStyledTextCtrl, callTipSetHighlight, 2}},
- {3154, {wxStyledTextCtrl, callTipSetBackground, 1}},
- {3155, {wxStyledTextCtrl, callTipSetForeground, 1}},
- {3156, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
- {3157, {wxStyledTextCtrl, callTipUseStyle, 1}},
- {3158, {wxStyledTextCtrl, visibleFromDocLine, 1}},
- {3159, {wxStyledTextCtrl, docLineFromVisible, 1}},
- {3160, {wxStyledTextCtrl, wrapCount, 1}},
- {3161, {wxStyledTextCtrl, setFoldLevel, 2}},
- {3162, {wxStyledTextCtrl, getFoldLevel, 1}},
- {3163, {wxStyledTextCtrl, getLastChild, 2}},
- {3164, {wxStyledTextCtrl, getFoldParent, 1}},
- {3165, {wxStyledTextCtrl, showLines, 2}},
- {3166, {wxStyledTextCtrl, hideLines, 2}},
- {3167, {wxStyledTextCtrl, getLineVisible, 1}},
- {3168, {wxStyledTextCtrl, setFoldExpanded, 2}},
- {3169, {wxStyledTextCtrl, getFoldExpanded, 1}},
- {3170, {wxStyledTextCtrl, toggleFold, 1}},
- {3171, {wxStyledTextCtrl, ensureVisible, 1}},
- {3172, {wxStyledTextCtrl, setFoldFlags, 1}},
- {3173, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
- {3174, {wxStyledTextCtrl, setTabIndents, 1}},
- {3175, {wxStyledTextCtrl, getTabIndents, 0}},
- {3176, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
- {3177, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
- {3178, {wxStyledTextCtrl, setMouseDwellTime, 1}},
- {3179, {wxStyledTextCtrl, getMouseDwellTime, 0}},
- {3180, {wxStyledTextCtrl, wordStartPosition, 2}},
- {3181, {wxStyledTextCtrl, wordEndPosition, 2}},
- {3182, {wxStyledTextCtrl, setWrapMode, 1}},
- {3183, {wxStyledTextCtrl, getWrapMode, 0}},
- {3184, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
- {3185, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
- {3186, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
- {3187, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
- {3188, {wxStyledTextCtrl, setWrapStartIndent, 1}},
- {3189, {wxStyledTextCtrl, getWrapStartIndent, 0}},
- {3190, {wxStyledTextCtrl, setLayoutCache, 1}},
- {3191, {wxStyledTextCtrl, getLayoutCache, 0}},
- {3192, {wxStyledTextCtrl, setScrollWidth, 1}},
- {3193, {wxStyledTextCtrl, getScrollWidth, 0}},
- {3194, {wxStyledTextCtrl, textWidth, 2}},
- {3195, {wxStyledTextCtrl, getEndAtLastLine, 0}},
- {3196, {wxStyledTextCtrl, textHeight, 1}},
- {3197, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
- {3198, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
- {3199, {wxStyledTextCtrl, appendText, 1}},
- {3200, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
- {3201, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
- {3202, {wxStyledTextCtrl, targetFromSelection, 0}},
- {3203, {wxStyledTextCtrl, linesJoin, 0}},
- {3204, {wxStyledTextCtrl, linesSplit, 1}},
- {3205, {wxStyledTextCtrl, setFoldMarginColour, 2}},
- {3206, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
- {3207, {wxStyledTextCtrl, lineDown, 0}},
- {3208, {wxStyledTextCtrl, lineDownExtend, 0}},
- {3209, {wxStyledTextCtrl, lineUp, 0}},
- {3210, {wxStyledTextCtrl, lineUpExtend, 0}},
- {3211, {wxStyledTextCtrl, charLeft, 0}},
- {3212, {wxStyledTextCtrl, charLeftExtend, 0}},
- {3213, {wxStyledTextCtrl, charRight, 0}},
- {3214, {wxStyledTextCtrl, charRightExtend, 0}},
- {3215, {wxStyledTextCtrl, wordLeft, 0}},
- {3216, {wxStyledTextCtrl, wordLeftExtend, 0}},
- {3217, {wxStyledTextCtrl, wordRight, 0}},
- {3218, {wxStyledTextCtrl, wordRightExtend, 0}},
- {3219, {wxStyledTextCtrl, home, 0}},
- {3220, {wxStyledTextCtrl, homeExtend, 0}},
- {3221, {wxStyledTextCtrl, lineEnd, 0}},
- {3222, {wxStyledTextCtrl, lineEndExtend, 0}},
- {3223, {wxStyledTextCtrl, documentStart, 0}},
- {3224, {wxStyledTextCtrl, documentStartExtend, 0}},
- {3225, {wxStyledTextCtrl, documentEnd, 0}},
- {3226, {wxStyledTextCtrl, documentEndExtend, 0}},
- {3227, {wxStyledTextCtrl, pageUp, 0}},
- {3228, {wxStyledTextCtrl, pageUpExtend, 0}},
- {3229, {wxStyledTextCtrl, pageDown, 0}},
- {3230, {wxStyledTextCtrl, pageDownExtend, 0}},
- {3231, {wxStyledTextCtrl, editToggleOvertype, 0}},
- {3232, {wxStyledTextCtrl, cancel, 0}},
- {3233, {wxStyledTextCtrl, deleteBack, 0}},
- {3234, {wxStyledTextCtrl, tab, 0}},
- {3235, {wxStyledTextCtrl, backTab, 0}},
- {3236, {wxStyledTextCtrl, newLine, 0}},
- {3237, {wxStyledTextCtrl, formFeed, 0}},
- {3238, {wxStyledTextCtrl, vCHome, 0}},
- {3239, {wxStyledTextCtrl, vCHomeExtend, 0}},
- {3240, {wxStyledTextCtrl, zoomIn, 0}},
- {3241, {wxStyledTextCtrl, zoomOut, 0}},
- {3242, {wxStyledTextCtrl, delWordLeft, 0}},
- {3243, {wxStyledTextCtrl, delWordRight, 0}},
- {3244, {wxStyledTextCtrl, lineCut, 0}},
- {3245, {wxStyledTextCtrl, lineDelete, 0}},
- {3246, {wxStyledTextCtrl, lineTranspose, 0}},
- {3247, {wxStyledTextCtrl, lineDuplicate, 0}},
- {3248, {wxStyledTextCtrl, lowerCase, 0}},
- {3249, {wxStyledTextCtrl, upperCase, 0}},
- {3250, {wxStyledTextCtrl, lineScrollDown, 0}},
- {3251, {wxStyledTextCtrl, lineScrollUp, 0}},
- {3252, {wxStyledTextCtrl, deleteBackNotLine, 0}},
- {3253, {wxStyledTextCtrl, homeDisplay, 0}},
- {3254, {wxStyledTextCtrl, homeDisplayExtend, 0}},
- {3255, {wxStyledTextCtrl, lineEndDisplay, 0}},
- {3256, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
- {3257, {wxStyledTextCtrl, homeWrapExtend, 0}},
- {3258, {wxStyledTextCtrl, lineEndWrap, 0}},
- {3259, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
- {3260, {wxStyledTextCtrl, vCHomeWrap, 0}},
- {3261, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
- {3262, {wxStyledTextCtrl, lineCopy, 0}},
- {3263, {wxStyledTextCtrl, moveCaretInsideView, 0}},
- {3264, {wxStyledTextCtrl, lineLength, 1}},
- {3265, {wxStyledTextCtrl, braceHighlight, 2}},
- {3266, {wxStyledTextCtrl, braceBadLight, 1}},
- {3267, {wxStyledTextCtrl, braceMatch, 1}},
- {3268, {wxStyledTextCtrl, getViewEOL, 0}},
- {3269, {wxStyledTextCtrl, setViewEOL, 1}},
- {3270, {wxStyledTextCtrl, setModEventMask, 1}},
- {3271, {wxStyledTextCtrl, getEdgeColumn, 0}},
- {3272, {wxStyledTextCtrl, setEdgeColumn, 1}},
- {3273, {wxStyledTextCtrl, setEdgeMode, 1}},
- {3274, {wxStyledTextCtrl, getEdgeMode, 0}},
- {3275, {wxStyledTextCtrl, getEdgeColour, 0}},
- {3276, {wxStyledTextCtrl, setEdgeColour, 1}},
- {3277, {wxStyledTextCtrl, searchAnchor, 0}},
- {3278, {wxStyledTextCtrl, searchNext, 2}},
- {3279, {wxStyledTextCtrl, searchPrev, 2}},
- {3280, {wxStyledTextCtrl, linesOnScreen, 0}},
- {3281, {wxStyledTextCtrl, usePopUp, 1}},
- {3282, {wxStyledTextCtrl, selectionIsRectangle, 0}},
- {3283, {wxStyledTextCtrl, setZoom, 1}},
- {3284, {wxStyledTextCtrl, getZoom, 0}},
- {3285, {wxStyledTextCtrl, getModEventMask, 0}},
- {3286, {wxStyledTextCtrl, setSTCFocus, 1}},
- {3287, {wxStyledTextCtrl, getSTCFocus, 0}},
- {3288, {wxStyledTextCtrl, setStatus, 1}},
- {3289, {wxStyledTextCtrl, getStatus, 0}},
- {3290, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
- {3291, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
- {3292, {wxStyledTextCtrl, setSTCCursor, 1}},
- {3293, {wxStyledTextCtrl, getSTCCursor, 0}},
- {3294, {wxStyledTextCtrl, setControlCharSymbol, 1}},
- {3295, {wxStyledTextCtrl, getControlCharSymbol, 0}},
- {3296, {wxStyledTextCtrl, wordPartLeft, 0}},
- {3297, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
- {3298, {wxStyledTextCtrl, wordPartRight, 0}},
- {3299, {wxStyledTextCtrl, wordPartRightExtend, 0}},
- {3300, {wxStyledTextCtrl, setVisiblePolicy, 2}},
- {3301, {wxStyledTextCtrl, delLineLeft, 0}},
- {3302, {wxStyledTextCtrl, delLineRight, 0}},
- {3303, {wxStyledTextCtrl, getXOffset, 0}},
- {3304, {wxStyledTextCtrl, chooseCaretX, 0}},
- {3305, {wxStyledTextCtrl, setXCaretPolicy, 2}},
- {3306, {wxStyledTextCtrl, setYCaretPolicy, 2}},
- {3307, {wxStyledTextCtrl, getPrintWrapMode, 0}},
- {3308, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
- {3309, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
- {3310, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
- {3311, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
- {3312, {wxStyledTextCtrl, paraDownExtend, 0}},
- {3313, {wxStyledTextCtrl, paraUp, 0}},
- {3314, {wxStyledTextCtrl, paraUpExtend, 0}},
- {3315, {wxStyledTextCtrl, positionBefore, 1}},
- {3316, {wxStyledTextCtrl, positionAfter, 1}},
- {3317, {wxStyledTextCtrl, copyRange, 2}},
- {3318, {wxStyledTextCtrl, copyText, 2}},
- {3319, {wxStyledTextCtrl, setSelectionMode, 1}},
- {3320, {wxStyledTextCtrl, getSelectionMode, 0}},
- {3321, {wxStyledTextCtrl, lineDownRectExtend, 0}},
- {3322, {wxStyledTextCtrl, lineUpRectExtend, 0}},
- {3323, {wxStyledTextCtrl, charLeftRectExtend, 0}},
- {3324, {wxStyledTextCtrl, charRightRectExtend, 0}},
- {3325, {wxStyledTextCtrl, homeRectExtend, 0}},
- {3326, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
- {3327, {wxStyledTextCtrl, lineEndRectExtend, 0}},
- {3328, {wxStyledTextCtrl, pageUpRectExtend, 0}},
- {3329, {wxStyledTextCtrl, pageDownRectExtend, 0}},
- {3330, {wxStyledTextCtrl, stutteredPageUp, 0}},
- {3331, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
- {3332, {wxStyledTextCtrl, stutteredPageDown, 0}},
- {3333, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
- {3334, {wxStyledTextCtrl, wordLeftEnd, 0}},
- {3335, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
- {3336, {wxStyledTextCtrl, wordRightEnd, 0}},
- {3337, {wxStyledTextCtrl, wordRightEndExtend, 0}},
- {3338, {wxStyledTextCtrl, setWhitespaceChars, 1}},
- {3339, {wxStyledTextCtrl, setCharsDefault, 0}},
- {3340, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
- {3341, {wxStyledTextCtrl, allocate, 1}},
- {3342, {wxStyledTextCtrl, findColumn, 2}},
- {3343, {wxStyledTextCtrl, getCaretSticky, 0}},
- {3344, {wxStyledTextCtrl, setCaretSticky, 1}},
- {3345, {wxStyledTextCtrl, toggleCaretSticky, 0}},
- {3346, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
- {3347, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
- {3348, {wxStyledTextCtrl, selectionDuplicate, 0}},
- {3349, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
- {3350, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
- {3351, {wxStyledTextCtrl, startRecord, 0}},
- {3352, {wxStyledTextCtrl, stopRecord, 0}},
- {3353, {wxStyledTextCtrl, setLexer, 1}},
- {3354, {wxStyledTextCtrl, getLexer, 0}},
- {3355, {wxStyledTextCtrl, colourise, 2}},
- {3356, {wxStyledTextCtrl, setProperty, 2}},
- {3357, {wxStyledTextCtrl, setKeyWords, 2}},
- {3358, {wxStyledTextCtrl, setLexerLanguage, 1}},
- {3359, {wxStyledTextCtrl, getProperty, 1}},
- {3360, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
- {3361, {wxStyledTextCtrl, getCurrentLine, 0}},
- {3362, {wxStyledTextCtrl, styleSetSpec, 2}},
- {3363, {wxStyledTextCtrl, styleSetFont, 2}},
- {3364, {wxStyledTextCtrl, styleSetFontAttr, 7}},
- {3365, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
- {3366, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
- {3367, {wxStyledTextCtrl, cmdKeyExecute, 1}},
- {3368, {wxStyledTextCtrl, setMargins, 2}},
- {3369, {wxStyledTextCtrl, getSelection, 2}},
- {3370, {wxStyledTextCtrl, pointFromPosition, 1}},
- {3371, {wxStyledTextCtrl, scrollToLine, 1}},
- {3372, {wxStyledTextCtrl, scrollToColumn, 1}},
- {3373, {wxStyledTextCtrl, setVScrollBar, 1}},
- {3374, {wxStyledTextCtrl, setHScrollBar, 1}},
- {3375, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
- {3376, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
- {3377, {wxStyledTextCtrl, saveFile, 1}},
- {3378, {wxStyledTextCtrl, loadFile, 1}},
- {3379, {wxStyledTextCtrl, doDragOver, 3}},
- {3380, {wxStyledTextCtrl, doDropText, 3}},
- {3381, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
- {3382, {wxStyledTextCtrl, addTextRaw, 1}},
- {3383, {wxStyledTextCtrl, insertTextRaw, 2}},
- {3384, {wxStyledTextCtrl, getCurLineRaw, 1}},
- {3385, {wxStyledTextCtrl, getLineRaw, 1}},
- {3386, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
- {3387, {wxStyledTextCtrl, getTextRangeRaw, 2}},
- {3388, {wxStyledTextCtrl, setTextRaw, 1}},
- {3389, {wxStyledTextCtrl, getTextRaw, 0}},
- {3390, {wxStyledTextCtrl, appendTextRaw, 1}},
- {3391, {wxArtProvider, getBitmap, 2}},
- {3392, {wxArtProvider, getIcon, 2}},
- {3393, {wxTreeEvent, getKeyCode, 0}},
- {3394, {wxTreeEvent, getItem, 0}},
- {3395, {wxTreeEvent, getKeyEvent, 0}},
- {3396, {wxTreeEvent, getLabel, 0}},
- {3397, {wxTreeEvent, getOldItem, 0}},
- {3398, {wxTreeEvent, getPoint, 0}},
- {3399, {wxTreeEvent, isEditCancelled, 0}},
- {3400, {wxTreeEvent, setToolTip, 1}},
- {3401, {wxNotebookEvent, getOldSelection, 0}},
- {3402, {wxNotebookEvent, getSelection, 0}},
- {3403, {wxNotebookEvent, setOldSelection, 1}},
- {3404, {wxNotebookEvent, setSelection, 1}},
- {3405, {wxFileDataObject, new, 0}},
- {3406, {wxFileDataObject, addFile, 1}},
- {3407, {wxFileDataObject, getFilenames, 0}},
- {3408, {wxFileDataObject, 'Destroy', undefined}},
- {3409, {wxTextDataObject, new, 1}},
- {3410, {wxTextDataObject, getTextLength, 0}},
- {3411, {wxTextDataObject, getText, 0}},
- {3412, {wxTextDataObject, setText, 1}},
- {3413, {wxTextDataObject, 'Destroy', undefined}},
- {3414, {wxBitmapDataObject, new_1_1, 1}},
- {3415, {wxBitmapDataObject, new_1_0, 1}},
- {3416, {wxBitmapDataObject, getBitmap, 0}},
- {3417, {wxBitmapDataObject, setBitmap, 1}},
- {3418, {wxBitmapDataObject, 'Destroy', undefined}},
- {3420, {wxClipboard, new, 0}},
- {3421, {wxClipboard, destruct, 0}},
- {3422, {wxClipboard, addData, 1}},
- {3423, {wxClipboard, clear, 0}},
- {3424, {wxClipboard, close, 0}},
- {3425, {wxClipboard, flush, 0}},
- {3426, {wxClipboard, getData, 1}},
- {3427, {wxClipboard, isOpened, 0}},
- {3428, {wxClipboard, open, 0}},
- {3429, {wxClipboard, setData, 1}},
- {3431, {wxClipboard, usePrimarySelection, 1}},
- {3432, {wxClipboard, isSupported, 1}},
- {3433, {wxClipboard, get, 0}},
- {3434, {wxSpinEvent, getPosition, 0}},
- {3435, {wxSpinEvent, setPosition, 1}},
- {3436, {wxSplitterWindow, new_0, 0}},
- {3437, {wxSplitterWindow, new_2, 2}},
- {3438, {wxSplitterWindow, destruct, 0}},
- {3439, {wxSplitterWindow, create, 2}},
- {3440, {wxSplitterWindow, getMinimumPaneSize, 0}},
- {3441, {wxSplitterWindow, getSashGravity, 0}},
- {3442, {wxSplitterWindow, getSashPosition, 0}},
- {3443, {wxSplitterWindow, getSplitMode, 0}},
- {3444, {wxSplitterWindow, getWindow1, 0}},
- {3445, {wxSplitterWindow, getWindow2, 0}},
- {3446, {wxSplitterWindow, initialize, 1}},
- {3447, {wxSplitterWindow, isSplit, 0}},
- {3448, {wxSplitterWindow, replaceWindow, 2}},
- {3449, {wxSplitterWindow, setSashGravity, 1}},
- {3450, {wxSplitterWindow, setSashPosition, 2}},
- {3451, {wxSplitterWindow, setSashSize, 1}},
- {3452, {wxSplitterWindow, setMinimumPaneSize, 1}},
- {3453, {wxSplitterWindow, setSplitMode, 1}},
- {3454, {wxSplitterWindow, splitHorizontally, 3}},
- {3455, {wxSplitterWindow, splitVertically, 3}},
- {3456, {wxSplitterWindow, unsplit, 1}},
- {3457, {wxSplitterWindow, updateSize, 0}},
- {3458, {wxSplitterEvent, getSashPosition, 0}},
- {3459, {wxSplitterEvent, getX, 0}},
- {3460, {wxSplitterEvent, getY, 0}},
- {3461, {wxSplitterEvent, getWindowBeingRemoved, 0}},
- {3462, {wxSplitterEvent, setSashPosition, 1}},
- {3463, {wxHtmlWindow, new_0, 0}},
- {3464, {wxHtmlWindow, new_2, 2}},
- {3465, {wxHtmlWindow, appendToPage, 1}},
- {3466, {wxHtmlWindow, getOpenedAnchor, 0}},
- {3467, {wxHtmlWindow, getOpenedPage, 0}},
- {3468, {wxHtmlWindow, getOpenedPageTitle, 0}},
- {3469, {wxHtmlWindow, getRelatedFrame, 0}},
- {3470, {wxHtmlWindow, historyBack, 0}},
- {3471, {wxHtmlWindow, historyCanBack, 0}},
- {3472, {wxHtmlWindow, historyCanForward, 0}},
- {3473, {wxHtmlWindow, historyClear, 0}},
- {3474, {wxHtmlWindow, historyForward, 0}},
- {3475, {wxHtmlWindow, loadFile, 1}},
- {3476, {wxHtmlWindow, loadPage, 1}},
- {3477, {wxHtmlWindow, selectAll, 0}},
- {3478, {wxHtmlWindow, selectionToText, 0}},
- {3479, {wxHtmlWindow, selectLine, 1}},
- {3480, {wxHtmlWindow, selectWord, 1}},
- {3481, {wxHtmlWindow, setBorders, 1}},
- {3482, {wxHtmlWindow, setFonts, 3}},
- {3483, {wxHtmlWindow, setPage, 1}},
- {3484, {wxHtmlWindow, setRelatedFrame, 2}},
- {3485, {wxHtmlWindow, setRelatedStatusBar, 1}},
- {3486, {wxHtmlWindow, toText, 0}},
- {3487, {wxHtmlWindow, 'Destroy', undefined}},
- {3488, {wxHtmlLinkEvent, getLinkInfo, 0}},
- {3489, {wxSystemSettings, getColour, 1}},
- {3490, {wxSystemSettings, getFont, 1}},
- {3491, {wxSystemSettings, getMetric, 2}},
- {3492, {wxSystemSettings, getScreenType, 0}},
- {3493, {wxSystemOptions, getOption, 1}},
- {3494, {wxSystemOptions, getOptionInt, 1}},
- {3495, {wxSystemOptions, hasOption, 1}},
- {3496, {wxSystemOptions, isFalse, 1}},
- {3497, {wxSystemOptions, setOption_2_1, 2}},
- {3498, {wxSystemOptions, setOption_2_0, 2}},
- {3499, {wxAuiNotebookEvent, setSelection, 1}},
- {3500, {wxAuiNotebookEvent, getSelection, 0}},
- {3501, {wxAuiNotebookEvent, setOldSelection, 1}},
- {3502, {wxAuiNotebookEvent, getOldSelection, 0}},
- {3503, {wxAuiNotebookEvent, setDragSource, 1}},
- {3504, {wxAuiNotebookEvent, getDragSource, 0}},
- {3505, {wxAuiManagerEvent, setManager, 1}},
- {3506, {wxAuiManagerEvent, getManager, 0}},
- {3507, {wxAuiManagerEvent, setPane, 1}},
- {3508, {wxAuiManagerEvent, getPane, 0}},
- {3509, {wxAuiManagerEvent, setButton, 1}},
- {3510, {wxAuiManagerEvent, getButton, 0}},
- {3511, {wxAuiManagerEvent, setDC, 1}},
- {3512, {wxAuiManagerEvent, getDC, 0}},
- {3513, {wxAuiManagerEvent, veto, 1}},
- {3514, {wxAuiManagerEvent, getVeto, 0}},
- {3515, {wxAuiManagerEvent, setCanVeto, 1}},
- {3516, {wxAuiManagerEvent, canVeto, 0}},
- {3517, {wxLogNull, new, 0}},
- {3518, {wxLogNull, 'Destroy', undefined}},
- {3519, {wxTaskBarIcon, new, 0}},
- {3520, {wxTaskBarIcon, destruct, 0}},
- {3521, {wxTaskBarIcon, popupMenu, 1}},
- {3522, {wxTaskBarIcon, removeIcon, 0}},
- {3523, {wxTaskBarIcon, setIcon, 2}},
+ {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, {wxPrintout, new, 1}},
+ {2928, {wxPrintout, destruct, 0}},
+ {2929, {wxPrintout, getDC, 0}},
+ {2930, {wxPrintout, getPageSizeMM, 2}},
+ {2931, {wxPrintout, getPageSizePixels, 2}},
+ {2932, {wxPrintout, getPaperRectPixels, 0}},
+ {2933, {wxPrintout, getPPIPrinter, 2}},
+ {2934, {wxPrintout, getPPIScreen, 2}},
+ {2935, {wxPrintout, getTitle, 0}},
+ {2936, {wxPrintout, isPreview, 0}},
+ {2937, {wxPrintout, fitThisSizeToPaper, 1}},
+ {2938, {wxPrintout, fitThisSizeToPage, 1}},
+ {2939, {wxPrintout, fitThisSizeToPageMargins, 2}},
+ {2940, {wxPrintout, mapScreenSizeToPaper, 0}},
+ {2941, {wxPrintout, mapScreenSizeToPage, 0}},
+ {2942, {wxPrintout, mapScreenSizeToPageMargins, 1}},
+ {2943, {wxPrintout, mapScreenSizeToDevice, 0}},
+ {2944, {wxPrintout, getLogicalPaperRect, 0}},
+ {2945, {wxPrintout, getLogicalPageRect, 0}},
+ {2946, {wxPrintout, getLogicalPageMarginsRect, 1}},
+ {2947, {wxPrintout, setLogicalOrigin, 2}},
+ {2948, {wxPrintout, offsetLogicalOrigin, 2}},
+ {2949, {wxStyledTextCtrl, new_2, 2}},
+ {2950, {wxStyledTextCtrl, new_0, 0}},
+ {2951, {wxStyledTextCtrl, destruct, 0}},
+ {2952, {wxStyledTextCtrl, create, 2}},
+ {2953, {wxStyledTextCtrl, addText, 1}},
+ {2954, {wxStyledTextCtrl, addStyledText, 1}},
+ {2955, {wxStyledTextCtrl, insertText, 2}},
+ {2956, {wxStyledTextCtrl, clearAll, 0}},
+ {2957, {wxStyledTextCtrl, clearDocumentStyle, 0}},
+ {2958, {wxStyledTextCtrl, getLength, 0}},
+ {2959, {wxStyledTextCtrl, getCharAt, 1}},
+ {2960, {wxStyledTextCtrl, getCurrentPos, 0}},
+ {2961, {wxStyledTextCtrl, getAnchor, 0}},
+ {2962, {wxStyledTextCtrl, getStyleAt, 1}},
+ {2963, {wxStyledTextCtrl, redo, 0}},
+ {2964, {wxStyledTextCtrl, setUndoCollection, 1}},
+ {2965, {wxStyledTextCtrl, selectAll, 0}},
+ {2966, {wxStyledTextCtrl, setSavePoint, 0}},
+ {2967, {wxStyledTextCtrl, getStyledText, 2}},
+ {2968, {wxStyledTextCtrl, canRedo, 0}},
+ {2969, {wxStyledTextCtrl, markerLineFromHandle, 1}},
+ {2970, {wxStyledTextCtrl, markerDeleteHandle, 1}},
+ {2971, {wxStyledTextCtrl, getUndoCollection, 0}},
+ {2972, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
+ {2973, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
+ {2974, {wxStyledTextCtrl, positionFromPoint, 1}},
+ {2975, {wxStyledTextCtrl, positionFromPointClose, 2}},
+ {2976, {wxStyledTextCtrl, gotoLine, 1}},
+ {2977, {wxStyledTextCtrl, gotoPos, 1}},
+ {2978, {wxStyledTextCtrl, setAnchor, 1}},
+ {2979, {wxStyledTextCtrl, getCurLine, 1}},
+ {2980, {wxStyledTextCtrl, getEndStyled, 0}},
+ {2981, {wxStyledTextCtrl, convertEOLs, 1}},
+ {2982, {wxStyledTextCtrl, getEOLMode, 0}},
+ {2983, {wxStyledTextCtrl, setEOLMode, 1}},
+ {2984, {wxStyledTextCtrl, startStyling, 2}},
+ {2985, {wxStyledTextCtrl, setStyling, 2}},
+ {2986, {wxStyledTextCtrl, getBufferedDraw, 0}},
+ {2987, {wxStyledTextCtrl, setBufferedDraw, 1}},
+ {2988, {wxStyledTextCtrl, setTabWidth, 1}},
+ {2989, {wxStyledTextCtrl, getTabWidth, 0}},
+ {2990, {wxStyledTextCtrl, setCodePage, 1}},
+ {2991, {wxStyledTextCtrl, markerDefine, 3}},
+ {2992, {wxStyledTextCtrl, markerSetForeground, 2}},
+ {2993, {wxStyledTextCtrl, markerSetBackground, 2}},
+ {2994, {wxStyledTextCtrl, markerAdd, 2}},
+ {2995, {wxStyledTextCtrl, markerDelete, 2}},
+ {2996, {wxStyledTextCtrl, markerDeleteAll, 1}},
+ {2997, {wxStyledTextCtrl, markerGet, 1}},
+ {2998, {wxStyledTextCtrl, markerNext, 2}},
+ {2999, {wxStyledTextCtrl, markerPrevious, 2}},
+ {3000, {wxStyledTextCtrl, markerDefineBitmap, 2}},
+ {3001, {wxStyledTextCtrl, markerAddSet, 2}},
+ {3002, {wxStyledTextCtrl, markerSetAlpha, 2}},
+ {3003, {wxStyledTextCtrl, setMarginType, 2}},
+ {3004, {wxStyledTextCtrl, getMarginType, 1}},
+ {3005, {wxStyledTextCtrl, setMarginWidth, 2}},
+ {3006, {wxStyledTextCtrl, getMarginWidth, 1}},
+ {3007, {wxStyledTextCtrl, setMarginMask, 2}},
+ {3008, {wxStyledTextCtrl, getMarginMask, 1}},
+ {3009, {wxStyledTextCtrl, setMarginSensitive, 2}},
+ {3010, {wxStyledTextCtrl, getMarginSensitive, 1}},
+ {3011, {wxStyledTextCtrl, styleClearAll, 0}},
+ {3012, {wxStyledTextCtrl, styleSetForeground, 2}},
+ {3013, {wxStyledTextCtrl, styleSetBackground, 2}},
+ {3014, {wxStyledTextCtrl, styleSetBold, 2}},
+ {3015, {wxStyledTextCtrl, styleSetItalic, 2}},
+ {3016, {wxStyledTextCtrl, styleSetSize, 2}},
+ {3017, {wxStyledTextCtrl, styleSetFaceName, 2}},
+ {3018, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
+ {3019, {wxStyledTextCtrl, styleResetDefault, 0}},
+ {3020, {wxStyledTextCtrl, styleSetUnderline, 2}},
+ {3021, {wxStyledTextCtrl, styleSetCase, 2}},
+ {3022, {wxStyledTextCtrl, styleSetHotSpot, 2}},
+ {3023, {wxStyledTextCtrl, setSelForeground, 2}},
+ {3024, {wxStyledTextCtrl, setSelBackground, 2}},
+ {3025, {wxStyledTextCtrl, getSelAlpha, 0}},
+ {3026, {wxStyledTextCtrl, setSelAlpha, 1}},
+ {3027, {wxStyledTextCtrl, setCaretForeground, 1}},
+ {3028, {wxStyledTextCtrl, cmdKeyAssign, 3}},
+ {3029, {wxStyledTextCtrl, cmdKeyClear, 2}},
+ {3030, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
+ {3031, {wxStyledTextCtrl, setStyleBytes, 2}},
+ {3032, {wxStyledTextCtrl, styleSetVisible, 2}},
+ {3033, {wxStyledTextCtrl, getCaretPeriod, 0}},
+ {3034, {wxStyledTextCtrl, setCaretPeriod, 1}},
+ {3035, {wxStyledTextCtrl, setWordChars, 1}},
+ {3036, {wxStyledTextCtrl, beginUndoAction, 0}},
+ {3037, {wxStyledTextCtrl, endUndoAction, 0}},
+ {3038, {wxStyledTextCtrl, indicatorSetStyle, 2}},
+ {3039, {wxStyledTextCtrl, indicatorGetStyle, 1}},
+ {3040, {wxStyledTextCtrl, indicatorSetForeground, 2}},
+ {3041, {wxStyledTextCtrl, indicatorGetForeground, 1}},
+ {3042, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
+ {3043, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
+ {3044, {wxStyledTextCtrl, getStyleBits, 0}},
+ {3045, {wxStyledTextCtrl, setLineState, 2}},
+ {3046, {wxStyledTextCtrl, getLineState, 1}},
+ {3047, {wxStyledTextCtrl, getMaxLineState, 0}},
+ {3048, {wxStyledTextCtrl, getCaretLineVisible, 0}},
+ {3049, {wxStyledTextCtrl, setCaretLineVisible, 1}},
+ {3050, {wxStyledTextCtrl, getCaretLineBackground, 0}},
+ {3051, {wxStyledTextCtrl, setCaretLineBackground, 1}},
+ {3052, {wxStyledTextCtrl, autoCompShow, 2}},
+ {3053, {wxStyledTextCtrl, autoCompCancel, 0}},
+ {3054, {wxStyledTextCtrl, autoCompActive, 0}},
+ {3055, {wxStyledTextCtrl, autoCompPosStart, 0}},
+ {3056, {wxStyledTextCtrl, autoCompComplete, 0}},
+ {3057, {wxStyledTextCtrl, autoCompStops, 1}},
+ {3058, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
+ {3059, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
+ {3060, {wxStyledTextCtrl, autoCompSelect, 1}},
+ {3061, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
+ {3062, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
+ {3063, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
+ {3064, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
+ {3065, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
+ {3066, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
+ {3067, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
+ {3068, {wxStyledTextCtrl, userListShow, 2}},
+ {3069, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
+ {3070, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
+ {3071, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
+ {3072, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
+ {3073, {wxStyledTextCtrl, registerImage, 2}},
+ {3074, {wxStyledTextCtrl, clearRegisteredImages, 0}},
+ {3075, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
+ {3076, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
+ {3077, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
+ {3078, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
+ {3079, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
+ {3080, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
+ {3081, {wxStyledTextCtrl, setIndent, 1}},
+ {3082, {wxStyledTextCtrl, getIndent, 0}},
+ {3083, {wxStyledTextCtrl, setUseTabs, 1}},
+ {3084, {wxStyledTextCtrl, getUseTabs, 0}},
+ {3085, {wxStyledTextCtrl, setLineIndentation, 2}},
+ {3086, {wxStyledTextCtrl, getLineIndentation, 1}},
+ {3087, {wxStyledTextCtrl, getLineIndentPosition, 1}},
+ {3088, {wxStyledTextCtrl, getColumn, 1}},
+ {3089, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
+ {3090, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
+ {3091, {wxStyledTextCtrl, setIndentationGuides, 1}},
+ {3092, {wxStyledTextCtrl, getIndentationGuides, 0}},
+ {3093, {wxStyledTextCtrl, setHighlightGuide, 1}},
+ {3094, {wxStyledTextCtrl, getHighlightGuide, 0}},
+ {3095, {wxStyledTextCtrl, getLineEndPosition, 1}},
+ {3096, {wxStyledTextCtrl, getCodePage, 0}},
+ {3097, {wxStyledTextCtrl, getCaretForeground, 0}},
+ {3098, {wxStyledTextCtrl, getReadOnly, 0}},
+ {3099, {wxStyledTextCtrl, setCurrentPos, 1}},
+ {3100, {wxStyledTextCtrl, setSelectionStart, 1}},
+ {3101, {wxStyledTextCtrl, getSelectionStart, 0}},
+ {3102, {wxStyledTextCtrl, setSelectionEnd, 1}},
+ {3103, {wxStyledTextCtrl, getSelectionEnd, 0}},
+ {3104, {wxStyledTextCtrl, setPrintMagnification, 1}},
+ {3105, {wxStyledTextCtrl, getPrintMagnification, 0}},
+ {3106, {wxStyledTextCtrl, setPrintColourMode, 1}},
+ {3107, {wxStyledTextCtrl, getPrintColourMode, 0}},
+ {3108, {wxStyledTextCtrl, findText, 4}},
+ {3109, {wxStyledTextCtrl, formatRange, 7}},
+ {3110, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
+ {3111, {wxStyledTextCtrl, getLine, 1}},
+ {3112, {wxStyledTextCtrl, getLineCount, 0}},
+ {3113, {wxStyledTextCtrl, setMarginLeft, 1}},
+ {3114, {wxStyledTextCtrl, getMarginLeft, 0}},
+ {3115, {wxStyledTextCtrl, setMarginRight, 1}},
+ {3116, {wxStyledTextCtrl, getMarginRight, 0}},
+ {3117, {wxStyledTextCtrl, getModify, 0}},
+ {3118, {wxStyledTextCtrl, setSelection, 2}},
+ {3119, {wxStyledTextCtrl, getSelectedText, 0}},
+ {3120, {wxStyledTextCtrl, getTextRange, 2}},
+ {3121, {wxStyledTextCtrl, hideSelection, 1}},
+ {3122, {wxStyledTextCtrl, lineFromPosition, 1}},
+ {3123, {wxStyledTextCtrl, positionFromLine, 1}},
+ {3124, {wxStyledTextCtrl, lineScroll, 2}},
+ {3125, {wxStyledTextCtrl, ensureCaretVisible, 0}},
+ {3126, {wxStyledTextCtrl, replaceSelection, 1}},
+ {3127, {wxStyledTextCtrl, setReadOnly, 1}},
+ {3128, {wxStyledTextCtrl, canPaste, 0}},
+ {3129, {wxStyledTextCtrl, canUndo, 0}},
+ {3130, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
+ {3131, {wxStyledTextCtrl, undo, 0}},
+ {3132, {wxStyledTextCtrl, cut, 0}},
+ {3133, {wxStyledTextCtrl, copy, 0}},
+ {3134, {wxStyledTextCtrl, paste, 0}},
+ {3135, {wxStyledTextCtrl, clear, 0}},
+ {3136, {wxStyledTextCtrl, setText, 1}},
+ {3137, {wxStyledTextCtrl, getText, 0}},
+ {3138, {wxStyledTextCtrl, getTextLength, 0}},
+ {3139, {wxStyledTextCtrl, getOvertype, 0}},
+ {3140, {wxStyledTextCtrl, setCaretWidth, 1}},
+ {3141, {wxStyledTextCtrl, getCaretWidth, 0}},
+ {3142, {wxStyledTextCtrl, setTargetStart, 1}},
+ {3143, {wxStyledTextCtrl, getTargetStart, 0}},
+ {3144, {wxStyledTextCtrl, setTargetEnd, 1}},
+ {3145, {wxStyledTextCtrl, getTargetEnd, 0}},
+ {3146, {wxStyledTextCtrl, replaceTarget, 1}},
+ {3147, {wxStyledTextCtrl, searchInTarget, 1}},
+ {3148, {wxStyledTextCtrl, setSearchFlags, 1}},
+ {3149, {wxStyledTextCtrl, getSearchFlags, 0}},
+ {3150, {wxStyledTextCtrl, callTipShow, 2}},
+ {3151, {wxStyledTextCtrl, callTipCancel, 0}},
+ {3152, {wxStyledTextCtrl, callTipActive, 0}},
+ {3153, {wxStyledTextCtrl, callTipPosAtStart, 0}},
+ {3154, {wxStyledTextCtrl, callTipSetHighlight, 2}},
+ {3155, {wxStyledTextCtrl, callTipSetBackground, 1}},
+ {3156, {wxStyledTextCtrl, callTipSetForeground, 1}},
+ {3157, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
+ {3158, {wxStyledTextCtrl, callTipUseStyle, 1}},
+ {3159, {wxStyledTextCtrl, visibleFromDocLine, 1}},
+ {3160, {wxStyledTextCtrl, docLineFromVisible, 1}},
+ {3161, {wxStyledTextCtrl, wrapCount, 1}},
+ {3162, {wxStyledTextCtrl, setFoldLevel, 2}},
+ {3163, {wxStyledTextCtrl, getFoldLevel, 1}},
+ {3164, {wxStyledTextCtrl, getLastChild, 2}},
+ {3165, {wxStyledTextCtrl, getFoldParent, 1}},
+ {3166, {wxStyledTextCtrl, showLines, 2}},
+ {3167, {wxStyledTextCtrl, hideLines, 2}},
+ {3168, {wxStyledTextCtrl, getLineVisible, 1}},
+ {3169, {wxStyledTextCtrl, setFoldExpanded, 2}},
+ {3170, {wxStyledTextCtrl, getFoldExpanded, 1}},
+ {3171, {wxStyledTextCtrl, toggleFold, 1}},
+ {3172, {wxStyledTextCtrl, ensureVisible, 1}},
+ {3173, {wxStyledTextCtrl, setFoldFlags, 1}},
+ {3174, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
+ {3175, {wxStyledTextCtrl, setTabIndents, 1}},
+ {3176, {wxStyledTextCtrl, getTabIndents, 0}},
+ {3177, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
+ {3178, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
+ {3179, {wxStyledTextCtrl, setMouseDwellTime, 1}},
+ {3180, {wxStyledTextCtrl, getMouseDwellTime, 0}},
+ {3181, {wxStyledTextCtrl, wordStartPosition, 2}},
+ {3182, {wxStyledTextCtrl, wordEndPosition, 2}},
+ {3183, {wxStyledTextCtrl, setWrapMode, 1}},
+ {3184, {wxStyledTextCtrl, getWrapMode, 0}},
+ {3185, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
+ {3186, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
+ {3187, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
+ {3188, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
+ {3189, {wxStyledTextCtrl, setWrapStartIndent, 1}},
+ {3190, {wxStyledTextCtrl, getWrapStartIndent, 0}},
+ {3191, {wxStyledTextCtrl, setLayoutCache, 1}},
+ {3192, {wxStyledTextCtrl, getLayoutCache, 0}},
+ {3193, {wxStyledTextCtrl, setScrollWidth, 1}},
+ {3194, {wxStyledTextCtrl, getScrollWidth, 0}},
+ {3195, {wxStyledTextCtrl, textWidth, 2}},
+ {3196, {wxStyledTextCtrl, getEndAtLastLine, 0}},
+ {3197, {wxStyledTextCtrl, textHeight, 1}},
+ {3198, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
+ {3199, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
+ {3200, {wxStyledTextCtrl, appendText, 1}},
+ {3201, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
+ {3202, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
+ {3203, {wxStyledTextCtrl, targetFromSelection, 0}},
+ {3204, {wxStyledTextCtrl, linesJoin, 0}},
+ {3205, {wxStyledTextCtrl, linesSplit, 1}},
+ {3206, {wxStyledTextCtrl, setFoldMarginColour, 2}},
+ {3207, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
+ {3208, {wxStyledTextCtrl, lineDown, 0}},
+ {3209, {wxStyledTextCtrl, lineDownExtend, 0}},
+ {3210, {wxStyledTextCtrl, lineUp, 0}},
+ {3211, {wxStyledTextCtrl, lineUpExtend, 0}},
+ {3212, {wxStyledTextCtrl, charLeft, 0}},
+ {3213, {wxStyledTextCtrl, charLeftExtend, 0}},
+ {3214, {wxStyledTextCtrl, charRight, 0}},
+ {3215, {wxStyledTextCtrl, charRightExtend, 0}},
+ {3216, {wxStyledTextCtrl, wordLeft, 0}},
+ {3217, {wxStyledTextCtrl, wordLeftExtend, 0}},
+ {3218, {wxStyledTextCtrl, wordRight, 0}},
+ {3219, {wxStyledTextCtrl, wordRightExtend, 0}},
+ {3220, {wxStyledTextCtrl, home, 0}},
+ {3221, {wxStyledTextCtrl, homeExtend, 0}},
+ {3222, {wxStyledTextCtrl, lineEnd, 0}},
+ {3223, {wxStyledTextCtrl, lineEndExtend, 0}},
+ {3224, {wxStyledTextCtrl, documentStart, 0}},
+ {3225, {wxStyledTextCtrl, documentStartExtend, 0}},
+ {3226, {wxStyledTextCtrl, documentEnd, 0}},
+ {3227, {wxStyledTextCtrl, documentEndExtend, 0}},
+ {3228, {wxStyledTextCtrl, pageUp, 0}},
+ {3229, {wxStyledTextCtrl, pageUpExtend, 0}},
+ {3230, {wxStyledTextCtrl, pageDown, 0}},
+ {3231, {wxStyledTextCtrl, pageDownExtend, 0}},
+ {3232, {wxStyledTextCtrl, editToggleOvertype, 0}},
+ {3233, {wxStyledTextCtrl, cancel, 0}},
+ {3234, {wxStyledTextCtrl, deleteBack, 0}},
+ {3235, {wxStyledTextCtrl, tab, 0}},
+ {3236, {wxStyledTextCtrl, backTab, 0}},
+ {3237, {wxStyledTextCtrl, newLine, 0}},
+ {3238, {wxStyledTextCtrl, formFeed, 0}},
+ {3239, {wxStyledTextCtrl, vCHome, 0}},
+ {3240, {wxStyledTextCtrl, vCHomeExtend, 0}},
+ {3241, {wxStyledTextCtrl, zoomIn, 0}},
+ {3242, {wxStyledTextCtrl, zoomOut, 0}},
+ {3243, {wxStyledTextCtrl, delWordLeft, 0}},
+ {3244, {wxStyledTextCtrl, delWordRight, 0}},
+ {3245, {wxStyledTextCtrl, lineCut, 0}},
+ {3246, {wxStyledTextCtrl, lineDelete, 0}},
+ {3247, {wxStyledTextCtrl, lineTranspose, 0}},
+ {3248, {wxStyledTextCtrl, lineDuplicate, 0}},
+ {3249, {wxStyledTextCtrl, lowerCase, 0}},
+ {3250, {wxStyledTextCtrl, upperCase, 0}},
+ {3251, {wxStyledTextCtrl, lineScrollDown, 0}},
+ {3252, {wxStyledTextCtrl, lineScrollUp, 0}},
+ {3253, {wxStyledTextCtrl, deleteBackNotLine, 0}},
+ {3254, {wxStyledTextCtrl, homeDisplay, 0}},
+ {3255, {wxStyledTextCtrl, homeDisplayExtend, 0}},
+ {3256, {wxStyledTextCtrl, lineEndDisplay, 0}},
+ {3257, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
+ {3258, {wxStyledTextCtrl, homeWrapExtend, 0}},
+ {3259, {wxStyledTextCtrl, lineEndWrap, 0}},
+ {3260, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
+ {3261, {wxStyledTextCtrl, vCHomeWrap, 0}},
+ {3262, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
+ {3263, {wxStyledTextCtrl, lineCopy, 0}},
+ {3264, {wxStyledTextCtrl, moveCaretInsideView, 0}},
+ {3265, {wxStyledTextCtrl, lineLength, 1}},
+ {3266, {wxStyledTextCtrl, braceHighlight, 2}},
+ {3267, {wxStyledTextCtrl, braceBadLight, 1}},
+ {3268, {wxStyledTextCtrl, braceMatch, 1}},
+ {3269, {wxStyledTextCtrl, getViewEOL, 0}},
+ {3270, {wxStyledTextCtrl, setViewEOL, 1}},
+ {3271, {wxStyledTextCtrl, setModEventMask, 1}},
+ {3272, {wxStyledTextCtrl, getEdgeColumn, 0}},
+ {3273, {wxStyledTextCtrl, setEdgeColumn, 1}},
+ {3274, {wxStyledTextCtrl, setEdgeMode, 1}},
+ {3275, {wxStyledTextCtrl, getEdgeMode, 0}},
+ {3276, {wxStyledTextCtrl, getEdgeColour, 0}},
+ {3277, {wxStyledTextCtrl, setEdgeColour, 1}},
+ {3278, {wxStyledTextCtrl, searchAnchor, 0}},
+ {3279, {wxStyledTextCtrl, searchNext, 2}},
+ {3280, {wxStyledTextCtrl, searchPrev, 2}},
+ {3281, {wxStyledTextCtrl, linesOnScreen, 0}},
+ {3282, {wxStyledTextCtrl, usePopUp, 1}},
+ {3283, {wxStyledTextCtrl, selectionIsRectangle, 0}},
+ {3284, {wxStyledTextCtrl, setZoom, 1}},
+ {3285, {wxStyledTextCtrl, getZoom, 0}},
+ {3286, {wxStyledTextCtrl, getModEventMask, 0}},
+ {3287, {wxStyledTextCtrl, setSTCFocus, 1}},
+ {3288, {wxStyledTextCtrl, getSTCFocus, 0}},
+ {3289, {wxStyledTextCtrl, setStatus, 1}},
+ {3290, {wxStyledTextCtrl, getStatus, 0}},
+ {3291, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
+ {3292, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
+ {3293, {wxStyledTextCtrl, setSTCCursor, 1}},
+ {3294, {wxStyledTextCtrl, getSTCCursor, 0}},
+ {3295, {wxStyledTextCtrl, setControlCharSymbol, 1}},
+ {3296, {wxStyledTextCtrl, getControlCharSymbol, 0}},
+ {3297, {wxStyledTextCtrl, wordPartLeft, 0}},
+ {3298, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
+ {3299, {wxStyledTextCtrl, wordPartRight, 0}},
+ {3300, {wxStyledTextCtrl, wordPartRightExtend, 0}},
+ {3301, {wxStyledTextCtrl, setVisiblePolicy, 2}},
+ {3302, {wxStyledTextCtrl, delLineLeft, 0}},
+ {3303, {wxStyledTextCtrl, delLineRight, 0}},
+ {3304, {wxStyledTextCtrl, getXOffset, 0}},
+ {3305, {wxStyledTextCtrl, chooseCaretX, 0}},
+ {3306, {wxStyledTextCtrl, setXCaretPolicy, 2}},
+ {3307, {wxStyledTextCtrl, setYCaretPolicy, 2}},
+ {3308, {wxStyledTextCtrl, getPrintWrapMode, 0}},
+ {3309, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
+ {3310, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
+ {3311, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
+ {3312, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
+ {3313, {wxStyledTextCtrl, paraDownExtend, 0}},
+ {3314, {wxStyledTextCtrl, paraUp, 0}},
+ {3315, {wxStyledTextCtrl, paraUpExtend, 0}},
+ {3316, {wxStyledTextCtrl, positionBefore, 1}},
+ {3317, {wxStyledTextCtrl, positionAfter, 1}},
+ {3318, {wxStyledTextCtrl, copyRange, 2}},
+ {3319, {wxStyledTextCtrl, copyText, 2}},
+ {3320, {wxStyledTextCtrl, setSelectionMode, 1}},
+ {3321, {wxStyledTextCtrl, getSelectionMode, 0}},
+ {3322, {wxStyledTextCtrl, lineDownRectExtend, 0}},
+ {3323, {wxStyledTextCtrl, lineUpRectExtend, 0}},
+ {3324, {wxStyledTextCtrl, charLeftRectExtend, 0}},
+ {3325, {wxStyledTextCtrl, charRightRectExtend, 0}},
+ {3326, {wxStyledTextCtrl, homeRectExtend, 0}},
+ {3327, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
+ {3328, {wxStyledTextCtrl, lineEndRectExtend, 0}},
+ {3329, {wxStyledTextCtrl, pageUpRectExtend, 0}},
+ {3330, {wxStyledTextCtrl, pageDownRectExtend, 0}},
+ {3331, {wxStyledTextCtrl, stutteredPageUp, 0}},
+ {3332, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
+ {3333, {wxStyledTextCtrl, stutteredPageDown, 0}},
+ {3334, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
+ {3335, {wxStyledTextCtrl, wordLeftEnd, 0}},
+ {3336, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
+ {3337, {wxStyledTextCtrl, wordRightEnd, 0}},
+ {3338, {wxStyledTextCtrl, wordRightEndExtend, 0}},
+ {3339, {wxStyledTextCtrl, setWhitespaceChars, 1}},
+ {3340, {wxStyledTextCtrl, setCharsDefault, 0}},
+ {3341, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
+ {3342, {wxStyledTextCtrl, allocate, 1}},
+ {3343, {wxStyledTextCtrl, findColumn, 2}},
+ {3344, {wxStyledTextCtrl, getCaretSticky, 0}},
+ {3345, {wxStyledTextCtrl, setCaretSticky, 1}},
+ {3346, {wxStyledTextCtrl, toggleCaretSticky, 0}},
+ {3347, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
+ {3348, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
+ {3349, {wxStyledTextCtrl, selectionDuplicate, 0}},
+ {3350, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
+ {3351, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
+ {3352, {wxStyledTextCtrl, startRecord, 0}},
+ {3353, {wxStyledTextCtrl, stopRecord, 0}},
+ {3354, {wxStyledTextCtrl, setLexer, 1}},
+ {3355, {wxStyledTextCtrl, getLexer, 0}},
+ {3356, {wxStyledTextCtrl, colourise, 2}},
+ {3357, {wxStyledTextCtrl, setProperty, 2}},
+ {3358, {wxStyledTextCtrl, setKeyWords, 2}},
+ {3359, {wxStyledTextCtrl, setLexerLanguage, 1}},
+ {3360, {wxStyledTextCtrl, getProperty, 1}},
+ {3361, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
+ {3362, {wxStyledTextCtrl, getCurrentLine, 0}},
+ {3363, {wxStyledTextCtrl, styleSetSpec, 2}},
+ {3364, {wxStyledTextCtrl, styleSetFont, 2}},
+ {3365, {wxStyledTextCtrl, styleSetFontAttr, 7}},
+ {3366, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
+ {3367, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
+ {3368, {wxStyledTextCtrl, cmdKeyExecute, 1}},
+ {3369, {wxStyledTextCtrl, setMargins, 2}},
+ {3370, {wxStyledTextCtrl, getSelection, 2}},
+ {3371, {wxStyledTextCtrl, pointFromPosition, 1}},
+ {3372, {wxStyledTextCtrl, scrollToLine, 1}},
+ {3373, {wxStyledTextCtrl, scrollToColumn, 1}},
+ {3374, {wxStyledTextCtrl, setVScrollBar, 1}},
+ {3375, {wxStyledTextCtrl, setHScrollBar, 1}},
+ {3376, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
+ {3377, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
+ {3378, {wxStyledTextCtrl, saveFile, 1}},
+ {3379, {wxStyledTextCtrl, loadFile, 1}},
+ {3380, {wxStyledTextCtrl, doDragOver, 3}},
+ {3381, {wxStyledTextCtrl, doDropText, 3}},
+ {3382, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
+ {3383, {wxStyledTextCtrl, addTextRaw, 1}},
+ {3384, {wxStyledTextCtrl, insertTextRaw, 2}},
+ {3385, {wxStyledTextCtrl, getCurLineRaw, 1}},
+ {3386, {wxStyledTextCtrl, getLineRaw, 1}},
+ {3387, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
+ {3388, {wxStyledTextCtrl, getTextRangeRaw, 2}},
+ {3389, {wxStyledTextCtrl, setTextRaw, 1}},
+ {3390, {wxStyledTextCtrl, getTextRaw, 0}},
+ {3391, {wxStyledTextCtrl, appendTextRaw, 1}},
+ {3392, {wxArtProvider, getBitmap, 2}},
+ {3393, {wxArtProvider, getIcon, 2}},
+ {3394, {wxTreeEvent, getKeyCode, 0}},
+ {3395, {wxTreeEvent, getItem, 0}},
+ {3396, {wxTreeEvent, getKeyEvent, 0}},
+ {3397, {wxTreeEvent, getLabel, 0}},
+ {3398, {wxTreeEvent, getOldItem, 0}},
+ {3399, {wxTreeEvent, getPoint, 0}},
+ {3400, {wxTreeEvent, isEditCancelled, 0}},
+ {3401, {wxTreeEvent, setToolTip, 1}},
+ {3402, {wxNotebookEvent, getOldSelection, 0}},
+ {3403, {wxNotebookEvent, getSelection, 0}},
+ {3404, {wxNotebookEvent, setOldSelection, 1}},
+ {3405, {wxNotebookEvent, setSelection, 1}},
+ {3406, {wxFileDataObject, new, 0}},
+ {3407, {wxFileDataObject, addFile, 1}},
+ {3408, {wxFileDataObject, getFilenames, 0}},
+ {3409, {wxFileDataObject, 'Destroy', undefined}},
+ {3410, {wxTextDataObject, new, 1}},
+ {3411, {wxTextDataObject, getTextLength, 0}},
+ {3412, {wxTextDataObject, getText, 0}},
+ {3413, {wxTextDataObject, setText, 1}},
+ {3414, {wxTextDataObject, 'Destroy', undefined}},
+ {3415, {wxBitmapDataObject, new_1_1, 1}},
+ {3416, {wxBitmapDataObject, new_1_0, 1}},
+ {3417, {wxBitmapDataObject, getBitmap, 0}},
+ {3418, {wxBitmapDataObject, setBitmap, 1}},
+ {3419, {wxBitmapDataObject, 'Destroy', undefined}},
+ {3421, {wxClipboard, new, 0}},
+ {3422, {wxClipboard, destruct, 0}},
+ {3423, {wxClipboard, addData, 1}},
+ {3424, {wxClipboard, clear, 0}},
+ {3425, {wxClipboard, close, 0}},
+ {3426, {wxClipboard, flush, 0}},
+ {3427, {wxClipboard, getData, 1}},
+ {3428, {wxClipboard, isOpened, 0}},
+ {3429, {wxClipboard, open, 0}},
+ {3430, {wxClipboard, setData, 1}},
+ {3432, {wxClipboard, usePrimarySelection, 1}},
+ {3433, {wxClipboard, isSupported, 1}},
+ {3434, {wxClipboard, get, 0}},
+ {3435, {wxSpinEvent, getPosition, 0}},
+ {3436, {wxSpinEvent, setPosition, 1}},
+ {3437, {wxSplitterWindow, new_0, 0}},
+ {3438, {wxSplitterWindow, new_2, 2}},
+ {3439, {wxSplitterWindow, destruct, 0}},
+ {3440, {wxSplitterWindow, create, 2}},
+ {3441, {wxSplitterWindow, getMinimumPaneSize, 0}},
+ {3442, {wxSplitterWindow, getSashGravity, 0}},
+ {3443, {wxSplitterWindow, getSashPosition, 0}},
+ {3444, {wxSplitterWindow, getSplitMode, 0}},
+ {3445, {wxSplitterWindow, getWindow1, 0}},
+ {3446, {wxSplitterWindow, getWindow2, 0}},
+ {3447, {wxSplitterWindow, initialize, 1}},
+ {3448, {wxSplitterWindow, isSplit, 0}},
+ {3449, {wxSplitterWindow, replaceWindow, 2}},
+ {3450, {wxSplitterWindow, setSashGravity, 1}},
+ {3451, {wxSplitterWindow, setSashPosition, 2}},
+ {3452, {wxSplitterWindow, setSashSize, 1}},
+ {3453, {wxSplitterWindow, setMinimumPaneSize, 1}},
+ {3454, {wxSplitterWindow, setSplitMode, 1}},
+ {3455, {wxSplitterWindow, splitHorizontally, 3}},
+ {3456, {wxSplitterWindow, splitVertically, 3}},
+ {3457, {wxSplitterWindow, unsplit, 1}},
+ {3458, {wxSplitterWindow, updateSize, 0}},
+ {3459, {wxSplitterEvent, getSashPosition, 0}},
+ {3460, {wxSplitterEvent, getX, 0}},
+ {3461, {wxSplitterEvent, getY, 0}},
+ {3462, {wxSplitterEvent, getWindowBeingRemoved, 0}},
+ {3463, {wxSplitterEvent, setSashPosition, 1}},
+ {3464, {wxHtmlWindow, new_0, 0}},
+ {3465, {wxHtmlWindow, new_2, 2}},
+ {3466, {wxHtmlWindow, appendToPage, 1}},
+ {3467, {wxHtmlWindow, getOpenedAnchor, 0}},
+ {3468, {wxHtmlWindow, getOpenedPage, 0}},
+ {3469, {wxHtmlWindow, getOpenedPageTitle, 0}},
+ {3470, {wxHtmlWindow, getRelatedFrame, 0}},
+ {3471, {wxHtmlWindow, historyBack, 0}},
+ {3472, {wxHtmlWindow, historyCanBack, 0}},
+ {3473, {wxHtmlWindow, historyCanForward, 0}},
+ {3474, {wxHtmlWindow, historyClear, 0}},
+ {3475, {wxHtmlWindow, historyForward, 0}},
+ {3476, {wxHtmlWindow, loadFile, 1}},
+ {3477, {wxHtmlWindow, loadPage, 1}},
+ {3478, {wxHtmlWindow, selectAll, 0}},
+ {3479, {wxHtmlWindow, selectionToText, 0}},
+ {3480, {wxHtmlWindow, selectLine, 1}},
+ {3481, {wxHtmlWindow, selectWord, 1}},
+ {3482, {wxHtmlWindow, setBorders, 1}},
+ {3483, {wxHtmlWindow, setFonts, 3}},
+ {3484, {wxHtmlWindow, setPage, 1}},
+ {3485, {wxHtmlWindow, setRelatedFrame, 2}},
+ {3486, {wxHtmlWindow, setRelatedStatusBar, 1}},
+ {3487, {wxHtmlWindow, toText, 0}},
+ {3488, {wxHtmlWindow, 'Destroy', undefined}},
+ {3489, {wxHtmlLinkEvent, getLinkInfo, 0}},
+ {3490, {wxSystemSettings, getColour, 1}},
+ {3491, {wxSystemSettings, getFont, 1}},
+ {3492, {wxSystemSettings, getMetric, 2}},
+ {3493, {wxSystemSettings, getScreenType, 0}},
+ {3494, {wxSystemOptions, getOption, 1}},
+ {3495, {wxSystemOptions, getOptionInt, 1}},
+ {3496, {wxSystemOptions, hasOption, 1}},
+ {3497, {wxSystemOptions, isFalse, 1}},
+ {3498, {wxSystemOptions, setOption_2_1, 2}},
+ {3499, {wxSystemOptions, setOption_2_0, 2}},
+ {3500, {wxAuiNotebookEvent, setSelection, 1}},
+ {3501, {wxAuiNotebookEvent, getSelection, 0}},
+ {3502, {wxAuiNotebookEvent, setOldSelection, 1}},
+ {3503, {wxAuiNotebookEvent, getOldSelection, 0}},
+ {3504, {wxAuiNotebookEvent, setDragSource, 1}},
+ {3505, {wxAuiNotebookEvent, getDragSource, 0}},
+ {3506, {wxAuiManagerEvent, setManager, 1}},
+ {3507, {wxAuiManagerEvent, getManager, 0}},
+ {3508, {wxAuiManagerEvent, setPane, 1}},
+ {3509, {wxAuiManagerEvent, getPane, 0}},
+ {3510, {wxAuiManagerEvent, setButton, 1}},
+ {3511, {wxAuiManagerEvent, getButton, 0}},
+ {3512, {wxAuiManagerEvent, setDC, 1}},
+ {3513, {wxAuiManagerEvent, getDC, 0}},
+ {3514, {wxAuiManagerEvent, veto, 1}},
+ {3515, {wxAuiManagerEvent, getVeto, 0}},
+ {3516, {wxAuiManagerEvent, setCanVeto, 1}},
+ {3517, {wxAuiManagerEvent, canVeto, 0}},
+ {3518, {wxLogNull, new, 0}},
+ {3519, {wxLogNull, 'Destroy', undefined}},
+ {3520, {wxTaskBarIcon, new, 0}},
+ {3521, {wxTaskBarIcon, destruct, 0}},
+ {3522, {wxTaskBarIcon, popupMenu, 1}},
+ {3523, {wxTaskBarIcon, removeIcon, 0}},
+ {3524, {wxTaskBarIcon, setIcon, 2}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index e6aced6e09..b6e507b11d 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -1881,1422 +1881,1423 @@
-define(wxTreeCtrl_IsSelected, 2058).
-define(wxTreeCtrl_IsVisible, 2059).
-define(wxTreeCtrl_ItemHasChildren, 2060).
--define(wxTreeCtrl_PrependItem, 2061).
--define(wxTreeCtrl_ScrollTo, 2062).
--define(wxTreeCtrl_SelectItem_1, 2063).
--define(wxTreeCtrl_SelectItem_2, 2064).
--define(wxTreeCtrl_SetIndent, 2065).
--define(wxTreeCtrl_SetImageList, 2066).
--define(wxTreeCtrl_SetItemBackgroundColour, 2067).
--define(wxTreeCtrl_SetItemBold, 2068).
--define(wxTreeCtrl_SetItemData, 2069).
--define(wxTreeCtrl_SetItemDropHighlight, 2070).
--define(wxTreeCtrl_SetItemFont, 2071).
--define(wxTreeCtrl_SetItemHasChildren, 2072).
--define(wxTreeCtrl_SetItemImage_2, 2073).
--define(wxTreeCtrl_SetItemImage_3, 2074).
--define(wxTreeCtrl_SetItemText, 2075).
--define(wxTreeCtrl_SetItemTextColour, 2076).
--define(wxTreeCtrl_SetStateImageList, 2077).
--define(wxTreeCtrl_SetWindowStyle, 2078).
--define(wxTreeCtrl_SortChildren, 2079).
--define(wxTreeCtrl_Toggle, 2080).
--define(wxTreeCtrl_ToggleItemSelection, 2081).
--define(wxTreeCtrl_Unselect, 2082).
--define(wxTreeCtrl_UnselectAll, 2083).
--define(wxTreeCtrl_UnselectItem, 2084).
--define(wxScrollBar_new_0, 2085).
--define(wxScrollBar_new_3, 2086).
--define(wxScrollBar_destruct, 2087).
--define(wxScrollBar_Create, 2088).
--define(wxScrollBar_GetRange, 2089).
--define(wxScrollBar_GetPageSize, 2090).
--define(wxScrollBar_GetThumbPosition, 2091).
--define(wxScrollBar_GetThumbSize, 2092).
--define(wxScrollBar_SetThumbPosition, 2093).
--define(wxScrollBar_SetScrollbar, 2094).
--define(wxSpinButton_new_2, 2096).
--define(wxSpinButton_new_0, 2097).
--define(wxSpinButton_Create, 2098).
--define(wxSpinButton_GetMax, 2099).
--define(wxSpinButton_GetMin, 2100).
--define(wxSpinButton_GetValue, 2101).
--define(wxSpinButton_SetRange, 2102).
--define(wxSpinButton_SetValue, 2103).
--define(wxSpinButton_destroy, 2104).
--define(wxSpinCtrl_new_0, 2105).
--define(wxSpinCtrl_new_2, 2106).
--define(wxSpinCtrl_Create, 2108).
--define(wxSpinCtrl_SetValue_1_1, 2111).
--define(wxSpinCtrl_SetValue_1_0, 2112).
--define(wxSpinCtrl_GetValue, 2114).
--define(wxSpinCtrl_SetRange, 2116).
--define(wxSpinCtrl_SetSelection, 2117).
--define(wxSpinCtrl_GetMin, 2119).
--define(wxSpinCtrl_GetMax, 2121).
--define(wxSpinCtrl_destroy, 2122).
--define(wxStaticText_new_0, 2123).
--define(wxStaticText_new_4, 2124).
--define(wxStaticText_Create, 2125).
--define(wxStaticText_GetLabel, 2126).
--define(wxStaticText_SetLabel, 2127).
--define(wxStaticText_Wrap, 2128).
--define(wxStaticText_destroy, 2129).
--define(wxStaticBitmap_new_0, 2130).
--define(wxStaticBitmap_new_4, 2131).
--define(wxStaticBitmap_Create, 2132).
--define(wxStaticBitmap_GetBitmap, 2133).
--define(wxStaticBitmap_SetBitmap, 2134).
--define(wxStaticBitmap_destroy, 2135).
--define(wxRadioBox_new, 2136).
--define(wxRadioBox_destruct, 2138).
--define(wxRadioBox_Create, 2139).
--define(wxRadioBox_Enable_2, 2140).
--define(wxRadioBox_Enable_1, 2141).
--define(wxRadioBox_GetSelection, 2142).
--define(wxRadioBox_GetString, 2143).
--define(wxRadioBox_SetSelection, 2144).
--define(wxRadioBox_Show_2, 2145).
--define(wxRadioBox_Show_1, 2146).
--define(wxRadioBox_GetColumnCount, 2147).
--define(wxRadioBox_GetItemHelpText, 2148).
--define(wxRadioBox_GetItemToolTip, 2149).
--define(wxRadioBox_GetItemFromPoint, 2151).
--define(wxRadioBox_GetRowCount, 2152).
--define(wxRadioBox_IsItemEnabled, 2153).
--define(wxRadioBox_IsItemShown, 2154).
--define(wxRadioBox_SetItemHelpText, 2155).
--define(wxRadioBox_SetItemToolTip, 2156).
--define(wxRadioButton_new_0, 2157).
--define(wxRadioButton_new_4, 2158).
--define(wxRadioButton_Create, 2159).
--define(wxRadioButton_GetValue, 2160).
--define(wxRadioButton_SetValue, 2161).
--define(wxRadioButton_destroy, 2162).
--define(wxSlider_new_6, 2164).
--define(wxSlider_new_0, 2165).
--define(wxSlider_Create, 2166).
--define(wxSlider_GetLineSize, 2167).
--define(wxSlider_GetMax, 2168).
--define(wxSlider_GetMin, 2169).
--define(wxSlider_GetPageSize, 2170).
--define(wxSlider_GetThumbLength, 2171).
--define(wxSlider_GetValue, 2172).
--define(wxSlider_SetLineSize, 2173).
--define(wxSlider_SetPageSize, 2174).
--define(wxSlider_SetRange, 2175).
--define(wxSlider_SetThumbLength, 2176).
--define(wxSlider_SetValue, 2177).
--define(wxSlider_destroy, 2178).
--define(wxDialog_new_4, 2180).
--define(wxDialog_new_0, 2181).
--define(wxDialog_destruct, 2183).
--define(wxDialog_Create, 2184).
--define(wxDialog_CreateButtonSizer, 2185).
--define(wxDialog_CreateStdDialogButtonSizer, 2186).
--define(wxDialog_EndModal, 2187).
--define(wxDialog_GetAffirmativeId, 2188).
--define(wxDialog_GetReturnCode, 2189).
--define(wxDialog_IsModal, 2190).
--define(wxDialog_SetAffirmativeId, 2191).
--define(wxDialog_SetReturnCode, 2192).
--define(wxDialog_Show, 2193).
--define(wxDialog_ShowModal, 2194).
--define(wxColourDialog_new_0, 2195).
--define(wxColourDialog_new_2, 2196).
--define(wxColourDialog_destruct, 2197).
--define(wxColourDialog_Create, 2198).
--define(wxColourDialog_GetColourData, 2199).
--define(wxColourData_new_0, 2200).
--define(wxColourData_new_1, 2201).
--define(wxColourData_destruct, 2202).
--define(wxColourData_GetChooseFull, 2203).
--define(wxColourData_GetColour, 2204).
--define(wxColourData_GetCustomColour, 2206).
--define(wxColourData_SetChooseFull, 2207).
--define(wxColourData_SetColour, 2208).
--define(wxColourData_SetCustomColour, 2209).
--define(wxPalette_new_0, 2210).
--define(wxPalette_new_4, 2211).
--define(wxPalette_destruct, 2213).
--define(wxPalette_Create, 2214).
--define(wxPalette_GetColoursCount, 2215).
--define(wxPalette_GetPixel, 2216).
--define(wxPalette_GetRGB, 2217).
--define(wxPalette_IsOk, 2218).
--define(wxDirDialog_new, 2222).
--define(wxDirDialog_destruct, 2223).
--define(wxDirDialog_GetPath, 2224).
--define(wxDirDialog_GetMessage, 2225).
--define(wxDirDialog_SetMessage, 2226).
--define(wxDirDialog_SetPath, 2227).
--define(wxFileDialog_new, 2231).
--define(wxFileDialog_destruct, 2232).
--define(wxFileDialog_GetDirectory, 2233).
--define(wxFileDialog_GetFilename, 2234).
--define(wxFileDialog_GetFilenames, 2235).
--define(wxFileDialog_GetFilterIndex, 2236).
--define(wxFileDialog_GetMessage, 2237).
--define(wxFileDialog_GetPath, 2238).
--define(wxFileDialog_GetPaths, 2239).
--define(wxFileDialog_GetWildcard, 2240).
--define(wxFileDialog_SetDirectory, 2241).
--define(wxFileDialog_SetFilename, 2242).
--define(wxFileDialog_SetFilterIndex, 2243).
--define(wxFileDialog_SetMessage, 2244).
--define(wxFileDialog_SetPath, 2245).
--define(wxFileDialog_SetWildcard, 2246).
--define(wxPickerBase_SetInternalMargin, 2247).
--define(wxPickerBase_GetInternalMargin, 2248).
--define(wxPickerBase_SetTextCtrlProportion, 2249).
--define(wxPickerBase_SetPickerCtrlProportion, 2250).
--define(wxPickerBase_GetTextCtrlProportion, 2251).
--define(wxPickerBase_GetPickerCtrlProportion, 2252).
--define(wxPickerBase_HasTextCtrl, 2253).
--define(wxPickerBase_GetTextCtrl, 2254).
--define(wxPickerBase_IsTextCtrlGrowable, 2255).
--define(wxPickerBase_SetPickerCtrlGrowable, 2256).
--define(wxPickerBase_SetTextCtrlGrowable, 2257).
--define(wxPickerBase_IsPickerCtrlGrowable, 2258).
--define(wxFilePickerCtrl_new_0, 2259).
--define(wxFilePickerCtrl_new_3, 2260).
--define(wxFilePickerCtrl_Create, 2261).
--define(wxFilePickerCtrl_GetPath, 2262).
--define(wxFilePickerCtrl_SetPath, 2263).
--define(wxFilePickerCtrl_destroy, 2264).
--define(wxDirPickerCtrl_new_0, 2265).
--define(wxDirPickerCtrl_new_3, 2266).
--define(wxDirPickerCtrl_Create, 2267).
--define(wxDirPickerCtrl_GetPath, 2268).
--define(wxDirPickerCtrl_SetPath, 2269).
--define(wxDirPickerCtrl_destroy, 2270).
--define(wxColourPickerCtrl_new_0, 2271).
--define(wxColourPickerCtrl_new_3, 2272).
--define(wxColourPickerCtrl_Create, 2273).
--define(wxColourPickerCtrl_GetColour, 2274).
--define(wxColourPickerCtrl_SetColour_1_1, 2275).
--define(wxColourPickerCtrl_SetColour_1_0, 2276).
--define(wxColourPickerCtrl_destroy, 2277).
--define(wxDatePickerCtrl_new_0, 2278).
--define(wxDatePickerCtrl_new_3, 2279).
--define(wxDatePickerCtrl_GetRange, 2280).
--define(wxDatePickerCtrl_GetValue, 2281).
--define(wxDatePickerCtrl_SetRange, 2282).
--define(wxDatePickerCtrl_SetValue, 2283).
--define(wxDatePickerCtrl_destroy, 2284).
--define(wxFontPickerCtrl_new_0, 2285).
--define(wxFontPickerCtrl_new_3, 2286).
--define(wxFontPickerCtrl_Create, 2287).
--define(wxFontPickerCtrl_GetSelectedFont, 2288).
--define(wxFontPickerCtrl_SetSelectedFont, 2289).
--define(wxFontPickerCtrl_GetMaxPointSize, 2290).
--define(wxFontPickerCtrl_SetMaxPointSize, 2291).
--define(wxFontPickerCtrl_destroy, 2292).
--define(wxFindReplaceDialog_new_0, 2295).
--define(wxFindReplaceDialog_new_4, 2296).
--define(wxFindReplaceDialog_destruct, 2297).
--define(wxFindReplaceDialog_Create, 2298).
--define(wxFindReplaceDialog_GetData, 2299).
--define(wxFindReplaceData_new_0, 2300).
--define(wxFindReplaceData_new_1, 2301).
--define(wxFindReplaceData_GetFindString, 2302).
--define(wxFindReplaceData_GetReplaceString, 2303).
--define(wxFindReplaceData_GetFlags, 2304).
--define(wxFindReplaceData_SetFlags, 2305).
--define(wxFindReplaceData_SetFindString, 2306).
--define(wxFindReplaceData_SetReplaceString, 2307).
--define(wxFindReplaceData_destroy, 2308).
--define(wxMultiChoiceDialog_new_0, 2309).
--define(wxMultiChoiceDialog_new_5, 2311).
--define(wxMultiChoiceDialog_GetSelections, 2312).
--define(wxMultiChoiceDialog_SetSelections, 2313).
--define(wxMultiChoiceDialog_destroy, 2314).
--define(wxSingleChoiceDialog_new_0, 2315).
--define(wxSingleChoiceDialog_new_5, 2317).
--define(wxSingleChoiceDialog_GetSelection, 2318).
--define(wxSingleChoiceDialog_GetStringSelection, 2319).
--define(wxSingleChoiceDialog_SetSelection, 2320).
--define(wxSingleChoiceDialog_destroy, 2321).
--define(wxTextEntryDialog_new, 2322).
--define(wxTextEntryDialog_GetValue, 2323).
--define(wxTextEntryDialog_SetValue, 2324).
--define(wxTextEntryDialog_destroy, 2325).
--define(wxPasswordEntryDialog_new, 2326).
--define(wxPasswordEntryDialog_destroy, 2327).
--define(wxFontData_new_0, 2328).
--define(wxFontData_new_1, 2329).
--define(wxFontData_destruct, 2330).
--define(wxFontData_EnableEffects, 2331).
--define(wxFontData_GetAllowSymbols, 2332).
--define(wxFontData_GetColour, 2333).
--define(wxFontData_GetChosenFont, 2334).
--define(wxFontData_GetEnableEffects, 2335).
--define(wxFontData_GetInitialFont, 2336).
--define(wxFontData_GetShowHelp, 2337).
--define(wxFontData_SetAllowSymbols, 2338).
--define(wxFontData_SetChosenFont, 2339).
--define(wxFontData_SetColour, 2340).
--define(wxFontData_SetInitialFont, 2341).
--define(wxFontData_SetRange, 2342).
--define(wxFontData_SetShowHelp, 2343).
--define(wxFontDialog_new_0, 2347).
--define(wxFontDialog_new_2, 2349).
--define(wxFontDialog_Create, 2351).
--define(wxFontDialog_GetFontData, 2352).
--define(wxFontDialog_destroy, 2354).
--define(wxProgressDialog_new, 2355).
--define(wxProgressDialog_destruct, 2356).
--define(wxProgressDialog_Resume, 2357).
--define(wxProgressDialog_Update_2, 2358).
--define(wxProgressDialog_Update_0, 2359).
--define(wxMessageDialog_new, 2360).
--define(wxMessageDialog_destruct, 2361).
--define(wxPageSetupDialog_new, 2362).
--define(wxPageSetupDialog_destruct, 2363).
--define(wxPageSetupDialog_GetPageSetupData, 2364).
--define(wxPageSetupDialog_ShowModal, 2365).
--define(wxPageSetupDialogData_new_0, 2366).
--define(wxPageSetupDialogData_new_1_0, 2367).
--define(wxPageSetupDialogData_new_1_1, 2368).
--define(wxPageSetupDialogData_destruct, 2369).
--define(wxPageSetupDialogData_EnableHelp, 2370).
--define(wxPageSetupDialogData_EnableMargins, 2371).
--define(wxPageSetupDialogData_EnableOrientation, 2372).
--define(wxPageSetupDialogData_EnablePaper, 2373).
--define(wxPageSetupDialogData_EnablePrinter, 2374).
--define(wxPageSetupDialogData_GetDefaultMinMargins, 2375).
--define(wxPageSetupDialogData_GetEnableMargins, 2376).
--define(wxPageSetupDialogData_GetEnableOrientation, 2377).
--define(wxPageSetupDialogData_GetEnablePaper, 2378).
--define(wxPageSetupDialogData_GetEnablePrinter, 2379).
--define(wxPageSetupDialogData_GetEnableHelp, 2380).
--define(wxPageSetupDialogData_GetDefaultInfo, 2381).
--define(wxPageSetupDialogData_GetMarginTopLeft, 2382).
--define(wxPageSetupDialogData_GetMarginBottomRight, 2383).
--define(wxPageSetupDialogData_GetMinMarginTopLeft, 2384).
--define(wxPageSetupDialogData_GetMinMarginBottomRight, 2385).
--define(wxPageSetupDialogData_GetPaperId, 2386).
--define(wxPageSetupDialogData_GetPaperSize, 2387).
--define(wxPageSetupDialogData_GetPrintData, 2389).
--define(wxPageSetupDialogData_IsOk, 2390).
--define(wxPageSetupDialogData_SetDefaultInfo, 2391).
--define(wxPageSetupDialogData_SetDefaultMinMargins, 2392).
--define(wxPageSetupDialogData_SetMarginTopLeft, 2393).
--define(wxPageSetupDialogData_SetMarginBottomRight, 2394).
--define(wxPageSetupDialogData_SetMinMarginTopLeft, 2395).
--define(wxPageSetupDialogData_SetMinMarginBottomRight, 2396).
--define(wxPageSetupDialogData_SetPaperId, 2397).
--define(wxPageSetupDialogData_SetPaperSize_1_1, 2398).
--define(wxPageSetupDialogData_SetPaperSize_1_0, 2399).
--define(wxPageSetupDialogData_SetPrintData, 2400).
--define(wxPrintDialog_new_2_0, 2401).
--define(wxPrintDialog_new_2_1, 2402).
--define(wxPrintDialog_destruct, 2403).
--define(wxPrintDialog_GetPrintDialogData, 2404).
--define(wxPrintDialog_GetPrintDC, 2405).
--define(wxPrintDialogData_new_0, 2406).
--define(wxPrintDialogData_new_1_1, 2407).
--define(wxPrintDialogData_new_1_0, 2408).
--define(wxPrintDialogData_destruct, 2409).
--define(wxPrintDialogData_EnableHelp, 2410).
--define(wxPrintDialogData_EnablePageNumbers, 2411).
--define(wxPrintDialogData_EnablePrintToFile, 2412).
--define(wxPrintDialogData_EnableSelection, 2413).
--define(wxPrintDialogData_GetAllPages, 2414).
--define(wxPrintDialogData_GetCollate, 2415).
--define(wxPrintDialogData_GetFromPage, 2416).
--define(wxPrintDialogData_GetMaxPage, 2417).
--define(wxPrintDialogData_GetMinPage, 2418).
--define(wxPrintDialogData_GetNoCopies, 2419).
--define(wxPrintDialogData_GetPrintData, 2420).
--define(wxPrintDialogData_GetPrintToFile, 2421).
--define(wxPrintDialogData_GetSelection, 2422).
--define(wxPrintDialogData_GetToPage, 2423).
--define(wxPrintDialogData_IsOk, 2424).
--define(wxPrintDialogData_SetCollate, 2425).
--define(wxPrintDialogData_SetFromPage, 2426).
--define(wxPrintDialogData_SetMaxPage, 2427).
--define(wxPrintDialogData_SetMinPage, 2428).
--define(wxPrintDialogData_SetNoCopies, 2429).
--define(wxPrintDialogData_SetPrintData, 2430).
--define(wxPrintDialogData_SetPrintToFile, 2431).
--define(wxPrintDialogData_SetSelection, 2432).
--define(wxPrintDialogData_SetToPage, 2433).
--define(wxPrintData_new_0, 2434).
--define(wxPrintData_new_1, 2435).
--define(wxPrintData_destruct, 2436).
--define(wxPrintData_GetCollate, 2437).
--define(wxPrintData_GetBin, 2438).
--define(wxPrintData_GetColour, 2439).
--define(wxPrintData_GetDuplex, 2440).
--define(wxPrintData_GetNoCopies, 2441).
--define(wxPrintData_GetOrientation, 2442).
--define(wxPrintData_GetPaperId, 2443).
--define(wxPrintData_GetPrinterName, 2444).
--define(wxPrintData_GetQuality, 2445).
--define(wxPrintData_IsOk, 2446).
--define(wxPrintData_SetBin, 2447).
--define(wxPrintData_SetCollate, 2448).
--define(wxPrintData_SetColour, 2449).
--define(wxPrintData_SetDuplex, 2450).
--define(wxPrintData_SetNoCopies, 2451).
--define(wxPrintData_SetOrientation, 2452).
--define(wxPrintData_SetPaperId, 2453).
--define(wxPrintData_SetPrinterName, 2454).
--define(wxPrintData_SetQuality, 2455).
--define(wxPrintPreview_new_2, 2458).
--define(wxPrintPreview_new_3, 2459).
--define(wxPrintPreview_destruct, 2461).
--define(wxPrintPreview_GetCanvas, 2462).
--define(wxPrintPreview_GetCurrentPage, 2463).
--define(wxPrintPreview_GetFrame, 2464).
--define(wxPrintPreview_GetMaxPage, 2465).
--define(wxPrintPreview_GetMinPage, 2466).
--define(wxPrintPreview_GetPrintout, 2467).
--define(wxPrintPreview_GetPrintoutForPrinting, 2468).
--define(wxPrintPreview_IsOk, 2469).
--define(wxPrintPreview_PaintPage, 2470).
--define(wxPrintPreview_Print, 2471).
--define(wxPrintPreview_RenderPage, 2472).
--define(wxPrintPreview_SetCanvas, 2473).
--define(wxPrintPreview_SetCurrentPage, 2474).
--define(wxPrintPreview_SetFrame, 2475).
--define(wxPrintPreview_SetPrintout, 2476).
--define(wxPrintPreview_SetZoom, 2477).
--define(wxPreviewFrame_new, 2478).
--define(wxPreviewFrame_destruct, 2479).
--define(wxPreviewFrame_CreateControlBar, 2480).
--define(wxPreviewFrame_CreateCanvas, 2481).
--define(wxPreviewFrame_Initialize, 2482).
--define(wxPreviewFrame_OnCloseWindow, 2483).
--define(wxPreviewControlBar_new, 2484).
--define(wxPreviewControlBar_destruct, 2485).
--define(wxPreviewControlBar_CreateButtons, 2486).
--define(wxPreviewControlBar_GetPrintPreview, 2487).
--define(wxPreviewControlBar_GetZoomControl, 2488).
--define(wxPreviewControlBar_SetZoomControl, 2489).
--define(wxPrinter_new, 2491).
--define(wxPrinter_CreateAbortWindow, 2492).
--define(wxPrinter_GetAbort, 2493).
--define(wxPrinter_GetLastError, 2494).
--define(wxPrinter_GetPrintDialogData, 2495).
--define(wxPrinter_Print, 2496).
--define(wxPrinter_PrintDialog, 2497).
--define(wxPrinter_ReportError, 2498).
--define(wxPrinter_Setup, 2499).
--define(wxPrinter_destroy, 2500).
--define(wxXmlResource_new_1, 2501).
--define(wxXmlResource_new_2, 2502).
--define(wxXmlResource_destruct, 2503).
--define(wxXmlResource_AttachUnknownControl, 2504).
--define(wxXmlResource_ClearHandlers, 2505).
--define(wxXmlResource_CompareVersion, 2506).
--define(wxXmlResource_Get, 2507).
--define(wxXmlResource_GetFlags, 2508).
--define(wxXmlResource_GetVersion, 2509).
--define(wxXmlResource_GetXRCID, 2510).
--define(wxXmlResource_InitAllHandlers, 2511).
--define(wxXmlResource_Load, 2512).
--define(wxXmlResource_LoadBitmap, 2513).
--define(wxXmlResource_LoadDialog_2, 2514).
--define(wxXmlResource_LoadDialog_3, 2515).
--define(wxXmlResource_LoadFrame_2, 2516).
--define(wxXmlResource_LoadFrame_3, 2517).
--define(wxXmlResource_LoadIcon, 2518).
--define(wxXmlResource_LoadMenu, 2519).
--define(wxXmlResource_LoadMenuBar_2, 2520).
--define(wxXmlResource_LoadMenuBar_1, 2521).
--define(wxXmlResource_LoadPanel_2, 2522).
--define(wxXmlResource_LoadPanel_3, 2523).
--define(wxXmlResource_LoadToolBar, 2524).
--define(wxXmlResource_Set, 2525).
--define(wxXmlResource_SetFlags, 2526).
--define(wxXmlResource_Unload, 2527).
--define(wxXmlResource_xrcctrl, 2528).
--define(wxHtmlEasyPrinting_new, 2529).
--define(wxHtmlEasyPrinting_destruct, 2530).
--define(wxHtmlEasyPrinting_GetPrintData, 2531).
--define(wxHtmlEasyPrinting_GetPageSetupData, 2532).
--define(wxHtmlEasyPrinting_PreviewFile, 2533).
--define(wxHtmlEasyPrinting_PreviewText, 2534).
--define(wxHtmlEasyPrinting_PrintFile, 2535).
--define(wxHtmlEasyPrinting_PrintText, 2536).
--define(wxHtmlEasyPrinting_PageSetup, 2537).
--define(wxHtmlEasyPrinting_SetFonts, 2538).
--define(wxHtmlEasyPrinting_SetHeader, 2539).
--define(wxHtmlEasyPrinting_SetFooter, 2540).
--define(wxGLCanvas_new_2, 2542).
--define(wxGLCanvas_new_3_1, 2543).
--define(wxGLCanvas_new_3_0, 2544).
--define(wxGLCanvas_GetContext, 2545).
--define(wxGLCanvas_SetCurrent, 2547).
--define(wxGLCanvas_SwapBuffers, 2548).
--define(wxGLCanvas_destroy, 2549).
--define(wxAuiManager_new, 2550).
--define(wxAuiManager_destruct, 2551).
--define(wxAuiManager_AddPane_2_1, 2552).
--define(wxAuiManager_AddPane_3, 2553).
--define(wxAuiManager_AddPane_2_0, 2554).
--define(wxAuiManager_DetachPane, 2555).
--define(wxAuiManager_GetAllPanes, 2556).
--define(wxAuiManager_GetArtProvider, 2557).
--define(wxAuiManager_GetDockSizeConstraint, 2558).
--define(wxAuiManager_GetFlags, 2559).
--define(wxAuiManager_GetManagedWindow, 2560).
--define(wxAuiManager_GetManager, 2561).
--define(wxAuiManager_GetPane_1_1, 2562).
--define(wxAuiManager_GetPane_1_0, 2563).
--define(wxAuiManager_HideHint, 2564).
--define(wxAuiManager_InsertPane, 2565).
--define(wxAuiManager_LoadPaneInfo, 2566).
--define(wxAuiManager_LoadPerspective, 2567).
--define(wxAuiManager_SavePaneInfo, 2568).
--define(wxAuiManager_SavePerspective, 2569).
--define(wxAuiManager_SetArtProvider, 2570).
--define(wxAuiManager_SetDockSizeConstraint, 2571).
--define(wxAuiManager_SetFlags, 2572).
--define(wxAuiManager_SetManagedWindow, 2573).
--define(wxAuiManager_ShowHint, 2574).
--define(wxAuiManager_UnInit, 2575).
--define(wxAuiManager_Update, 2576).
--define(wxAuiPaneInfo_new_0, 2577).
--define(wxAuiPaneInfo_new_1, 2578).
--define(wxAuiPaneInfo_destruct, 2579).
--define(wxAuiPaneInfo_BestSize_1, 2580).
--define(wxAuiPaneInfo_BestSize_2, 2581).
--define(wxAuiPaneInfo_Bottom, 2582).
--define(wxAuiPaneInfo_BottomDockable, 2583).
--define(wxAuiPaneInfo_Caption, 2584).
--define(wxAuiPaneInfo_CaptionVisible, 2585).
--define(wxAuiPaneInfo_Centre, 2586).
--define(wxAuiPaneInfo_CentrePane, 2587).
--define(wxAuiPaneInfo_CloseButton, 2588).
--define(wxAuiPaneInfo_DefaultPane, 2589).
--define(wxAuiPaneInfo_DestroyOnClose, 2590).
--define(wxAuiPaneInfo_Direction, 2591).
--define(wxAuiPaneInfo_Dock, 2592).
--define(wxAuiPaneInfo_Dockable, 2593).
--define(wxAuiPaneInfo_Fixed, 2594).
--define(wxAuiPaneInfo_Float, 2595).
--define(wxAuiPaneInfo_Floatable, 2596).
--define(wxAuiPaneInfo_FloatingPosition_1, 2597).
--define(wxAuiPaneInfo_FloatingPosition_2, 2598).
--define(wxAuiPaneInfo_FloatingSize_1, 2599).
--define(wxAuiPaneInfo_FloatingSize_2, 2600).
--define(wxAuiPaneInfo_Gripper, 2601).
--define(wxAuiPaneInfo_GripperTop, 2602).
--define(wxAuiPaneInfo_HasBorder, 2603).
--define(wxAuiPaneInfo_HasCaption, 2604).
--define(wxAuiPaneInfo_HasCloseButton, 2605).
--define(wxAuiPaneInfo_HasFlag, 2606).
--define(wxAuiPaneInfo_HasGripper, 2607).
--define(wxAuiPaneInfo_HasGripperTop, 2608).
--define(wxAuiPaneInfo_HasMaximizeButton, 2609).
--define(wxAuiPaneInfo_HasMinimizeButton, 2610).
--define(wxAuiPaneInfo_HasPinButton, 2611).
--define(wxAuiPaneInfo_Hide, 2612).
--define(wxAuiPaneInfo_IsBottomDockable, 2613).
--define(wxAuiPaneInfo_IsDocked, 2614).
--define(wxAuiPaneInfo_IsFixed, 2615).
--define(wxAuiPaneInfo_IsFloatable, 2616).
--define(wxAuiPaneInfo_IsFloating, 2617).
--define(wxAuiPaneInfo_IsLeftDockable, 2618).
--define(wxAuiPaneInfo_IsMovable, 2619).
--define(wxAuiPaneInfo_IsOk, 2620).
--define(wxAuiPaneInfo_IsResizable, 2621).
--define(wxAuiPaneInfo_IsRightDockable, 2622).
--define(wxAuiPaneInfo_IsShown, 2623).
--define(wxAuiPaneInfo_IsToolbar, 2624).
--define(wxAuiPaneInfo_IsTopDockable, 2625).
--define(wxAuiPaneInfo_Layer, 2626).
--define(wxAuiPaneInfo_Left, 2627).
--define(wxAuiPaneInfo_LeftDockable, 2628).
--define(wxAuiPaneInfo_MaxSize_1, 2629).
--define(wxAuiPaneInfo_MaxSize_2, 2630).
--define(wxAuiPaneInfo_MaximizeButton, 2631).
--define(wxAuiPaneInfo_MinSize_1, 2632).
--define(wxAuiPaneInfo_MinSize_2, 2633).
--define(wxAuiPaneInfo_MinimizeButton, 2634).
--define(wxAuiPaneInfo_Movable, 2635).
--define(wxAuiPaneInfo_Name, 2636).
--define(wxAuiPaneInfo_PaneBorder, 2637).
--define(wxAuiPaneInfo_PinButton, 2638).
--define(wxAuiPaneInfo_Position, 2639).
--define(wxAuiPaneInfo_Resizable, 2640).
--define(wxAuiPaneInfo_Right, 2641).
--define(wxAuiPaneInfo_RightDockable, 2642).
--define(wxAuiPaneInfo_Row, 2643).
--define(wxAuiPaneInfo_SafeSet, 2644).
--define(wxAuiPaneInfo_SetFlag, 2645).
--define(wxAuiPaneInfo_Show, 2646).
--define(wxAuiPaneInfo_ToolbarPane, 2647).
--define(wxAuiPaneInfo_Top, 2648).
--define(wxAuiPaneInfo_TopDockable, 2649).
--define(wxAuiPaneInfo_Window, 2650).
--define(wxAuiNotebook_new_0, 2651).
--define(wxAuiNotebook_new_2, 2652).
--define(wxAuiNotebook_AddPage, 2653).
--define(wxAuiNotebook_Create, 2654).
--define(wxAuiNotebook_DeletePage, 2655).
--define(wxAuiNotebook_GetArtProvider, 2656).
--define(wxAuiNotebook_GetPage, 2657).
--define(wxAuiNotebook_GetPageBitmap, 2658).
--define(wxAuiNotebook_GetPageCount, 2659).
--define(wxAuiNotebook_GetPageIndex, 2660).
--define(wxAuiNotebook_GetPageText, 2661).
--define(wxAuiNotebook_GetSelection, 2662).
--define(wxAuiNotebook_InsertPage, 2663).
--define(wxAuiNotebook_RemovePage, 2664).
--define(wxAuiNotebook_SetArtProvider, 2665).
--define(wxAuiNotebook_SetFont, 2666).
--define(wxAuiNotebook_SetPageBitmap, 2667).
--define(wxAuiNotebook_SetPageText, 2668).
--define(wxAuiNotebook_SetSelection, 2669).
--define(wxAuiNotebook_SetTabCtrlHeight, 2670).
--define(wxAuiNotebook_SetUniformBitmapSize, 2671).
--define(wxAuiNotebook_destroy, 2672).
--define(wxMDIParentFrame_new_0, 2673).
--define(wxMDIParentFrame_new_4, 2674).
--define(wxMDIParentFrame_destruct, 2675).
--define(wxMDIParentFrame_ActivateNext, 2676).
--define(wxMDIParentFrame_ActivatePrevious, 2677).
--define(wxMDIParentFrame_ArrangeIcons, 2678).
--define(wxMDIParentFrame_Cascade, 2679).
--define(wxMDIParentFrame_Create, 2680).
--define(wxMDIParentFrame_GetActiveChild, 2681).
--define(wxMDIParentFrame_GetClientWindow, 2682).
--define(wxMDIParentFrame_Tile, 2683).
--define(wxMDIChildFrame_new_0, 2684).
--define(wxMDIChildFrame_new_4, 2685).
--define(wxMDIChildFrame_destruct, 2686).
--define(wxMDIChildFrame_Activate, 2687).
--define(wxMDIChildFrame_Create, 2688).
--define(wxMDIChildFrame_Maximize, 2689).
--define(wxMDIChildFrame_Restore, 2690).
--define(wxMDIClientWindow_new_0, 2691).
--define(wxMDIClientWindow_new_2, 2692).
--define(wxMDIClientWindow_destruct, 2693).
--define(wxMDIClientWindow_CreateClient, 2694).
--define(wxLayoutAlgorithm_new, 2695).
--define(wxLayoutAlgorithm_LayoutFrame, 2696).
--define(wxLayoutAlgorithm_LayoutMDIFrame, 2697).
--define(wxLayoutAlgorithm_LayoutWindow, 2698).
--define(wxLayoutAlgorithm_destroy, 2699).
--define(wxEvent_GetId, 2700).
--define(wxEvent_GetSkipped, 2701).
--define(wxEvent_GetTimestamp, 2702).
--define(wxEvent_IsCommandEvent, 2703).
--define(wxEvent_ResumePropagation, 2704).
--define(wxEvent_ShouldPropagate, 2705).
--define(wxEvent_Skip, 2706).
--define(wxEvent_StopPropagation, 2707).
--define(wxCommandEvent_getClientData, 2708).
--define(wxCommandEvent_GetExtraLong, 2709).
--define(wxCommandEvent_GetInt, 2710).
--define(wxCommandEvent_GetSelection, 2711).
--define(wxCommandEvent_GetString, 2712).
--define(wxCommandEvent_IsChecked, 2713).
--define(wxCommandEvent_IsSelection, 2714).
--define(wxCommandEvent_SetInt, 2715).
--define(wxCommandEvent_SetString, 2716).
--define(wxScrollEvent_GetOrientation, 2717).
--define(wxScrollEvent_GetPosition, 2718).
--define(wxScrollWinEvent_GetOrientation, 2719).
--define(wxScrollWinEvent_GetPosition, 2720).
--define(wxMouseEvent_AltDown, 2721).
--define(wxMouseEvent_Button, 2722).
--define(wxMouseEvent_ButtonDClick, 2723).
--define(wxMouseEvent_ButtonDown, 2724).
--define(wxMouseEvent_ButtonUp, 2725).
--define(wxMouseEvent_CmdDown, 2726).
--define(wxMouseEvent_ControlDown, 2727).
--define(wxMouseEvent_Dragging, 2728).
--define(wxMouseEvent_Entering, 2729).
--define(wxMouseEvent_GetButton, 2730).
--define(wxMouseEvent_GetPosition, 2733).
--define(wxMouseEvent_GetLogicalPosition, 2734).
--define(wxMouseEvent_GetLinesPerAction, 2735).
--define(wxMouseEvent_GetWheelRotation, 2736).
--define(wxMouseEvent_GetWheelDelta, 2737).
--define(wxMouseEvent_GetX, 2738).
--define(wxMouseEvent_GetY, 2739).
--define(wxMouseEvent_IsButton, 2740).
--define(wxMouseEvent_IsPageScroll, 2741).
--define(wxMouseEvent_Leaving, 2742).
--define(wxMouseEvent_LeftDClick, 2743).
--define(wxMouseEvent_LeftDown, 2744).
--define(wxMouseEvent_LeftIsDown, 2745).
--define(wxMouseEvent_LeftUp, 2746).
--define(wxMouseEvent_MetaDown, 2747).
--define(wxMouseEvent_MiddleDClick, 2748).
--define(wxMouseEvent_MiddleDown, 2749).
--define(wxMouseEvent_MiddleIsDown, 2750).
--define(wxMouseEvent_MiddleUp, 2751).
--define(wxMouseEvent_Moving, 2752).
--define(wxMouseEvent_RightDClick, 2753).
--define(wxMouseEvent_RightDown, 2754).
--define(wxMouseEvent_RightIsDown, 2755).
--define(wxMouseEvent_RightUp, 2756).
--define(wxMouseEvent_ShiftDown, 2757).
--define(wxSetCursorEvent_GetCursor, 2758).
--define(wxSetCursorEvent_GetX, 2759).
--define(wxSetCursorEvent_GetY, 2760).
--define(wxSetCursorEvent_HasCursor, 2761).
--define(wxSetCursorEvent_SetCursor, 2762).
--define(wxKeyEvent_AltDown, 2763).
--define(wxKeyEvent_CmdDown, 2764).
--define(wxKeyEvent_ControlDown, 2765).
--define(wxKeyEvent_GetKeyCode, 2766).
--define(wxKeyEvent_GetModifiers, 2767).
--define(wxKeyEvent_GetPosition, 2770).
--define(wxKeyEvent_GetRawKeyCode, 2771).
--define(wxKeyEvent_GetRawKeyFlags, 2772).
--define(wxKeyEvent_GetUnicodeKey, 2773).
--define(wxKeyEvent_GetX, 2774).
--define(wxKeyEvent_GetY, 2775).
--define(wxKeyEvent_HasModifiers, 2776).
--define(wxKeyEvent_MetaDown, 2777).
--define(wxKeyEvent_ShiftDown, 2778).
--define(wxSizeEvent_GetSize, 2779).
--define(wxMoveEvent_GetPosition, 2780).
--define(wxEraseEvent_GetDC, 2781).
--define(wxFocusEvent_GetWindow, 2782).
--define(wxChildFocusEvent_GetWindow, 2783).
--define(wxMenuEvent_GetMenu, 2784).
--define(wxMenuEvent_GetMenuId, 2785).
--define(wxMenuEvent_IsPopup, 2786).
--define(wxCloseEvent_CanVeto, 2787).
--define(wxCloseEvent_GetLoggingOff, 2788).
--define(wxCloseEvent_SetCanVeto, 2789).
--define(wxCloseEvent_SetLoggingOff, 2790).
--define(wxCloseEvent_Veto, 2791).
--define(wxShowEvent_SetShow, 2792).
--define(wxShowEvent_GetShow, 2793).
--define(wxIconizeEvent_Iconized, 2794).
--define(wxJoystickEvent_ButtonDown, 2795).
--define(wxJoystickEvent_ButtonIsDown, 2796).
--define(wxJoystickEvent_ButtonUp, 2797).
--define(wxJoystickEvent_GetButtonChange, 2798).
--define(wxJoystickEvent_GetButtonState, 2799).
--define(wxJoystickEvent_GetJoystick, 2800).
--define(wxJoystickEvent_GetPosition, 2801).
--define(wxJoystickEvent_GetZPosition, 2802).
--define(wxJoystickEvent_IsButton, 2803).
--define(wxJoystickEvent_IsMove, 2804).
--define(wxJoystickEvent_IsZMove, 2805).
--define(wxUpdateUIEvent_CanUpdate, 2806).
--define(wxUpdateUIEvent_Check, 2807).
--define(wxUpdateUIEvent_Enable, 2808).
--define(wxUpdateUIEvent_Show, 2809).
--define(wxUpdateUIEvent_GetChecked, 2810).
--define(wxUpdateUIEvent_GetEnabled, 2811).
--define(wxUpdateUIEvent_GetShown, 2812).
--define(wxUpdateUIEvent_GetSetChecked, 2813).
--define(wxUpdateUIEvent_GetSetEnabled, 2814).
--define(wxUpdateUIEvent_GetSetShown, 2815).
--define(wxUpdateUIEvent_GetSetText, 2816).
--define(wxUpdateUIEvent_GetText, 2817).
--define(wxUpdateUIEvent_GetMode, 2818).
--define(wxUpdateUIEvent_GetUpdateInterval, 2819).
--define(wxUpdateUIEvent_ResetUpdateTime, 2820).
--define(wxUpdateUIEvent_SetMode, 2821).
--define(wxUpdateUIEvent_SetText, 2822).
--define(wxUpdateUIEvent_SetUpdateInterval, 2823).
--define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2824).
--define(wxPaletteChangedEvent_SetChangedWindow, 2825).
--define(wxPaletteChangedEvent_GetChangedWindow, 2826).
--define(wxQueryNewPaletteEvent_SetPaletteRealized, 2827).
--define(wxQueryNewPaletteEvent_GetPaletteRealized, 2828).
--define(wxNavigationKeyEvent_GetDirection, 2829).
--define(wxNavigationKeyEvent_SetDirection, 2830).
--define(wxNavigationKeyEvent_IsWindowChange, 2831).
--define(wxNavigationKeyEvent_SetWindowChange, 2832).
--define(wxNavigationKeyEvent_IsFromTab, 2833).
--define(wxNavigationKeyEvent_SetFromTab, 2834).
--define(wxNavigationKeyEvent_GetCurrentFocus, 2835).
--define(wxNavigationKeyEvent_SetCurrentFocus, 2836).
--define(wxHelpEvent_GetOrigin, 2837).
--define(wxHelpEvent_GetPosition, 2838).
--define(wxHelpEvent_SetOrigin, 2839).
--define(wxHelpEvent_SetPosition, 2840).
--define(wxContextMenuEvent_GetPosition, 2841).
--define(wxContextMenuEvent_SetPosition, 2842).
--define(wxIdleEvent_CanSend, 2843).
--define(wxIdleEvent_GetMode, 2844).
--define(wxIdleEvent_RequestMore, 2845).
--define(wxIdleEvent_MoreRequested, 2846).
--define(wxIdleEvent_SetMode, 2847).
--define(wxGridEvent_AltDown, 2848).
--define(wxGridEvent_ControlDown, 2849).
--define(wxGridEvent_GetCol, 2850).
--define(wxGridEvent_GetPosition, 2851).
--define(wxGridEvent_GetRow, 2852).
--define(wxGridEvent_MetaDown, 2853).
--define(wxGridEvent_Selecting, 2854).
--define(wxGridEvent_ShiftDown, 2855).
--define(wxNotifyEvent_Allow, 2856).
--define(wxNotifyEvent_IsAllowed, 2857).
--define(wxNotifyEvent_Veto, 2858).
--define(wxSashEvent_GetEdge, 2859).
--define(wxSashEvent_GetDragRect, 2860).
--define(wxSashEvent_GetDragStatus, 2861).
--define(wxListEvent_GetCacheFrom, 2862).
--define(wxListEvent_GetCacheTo, 2863).
--define(wxListEvent_GetKeyCode, 2864).
--define(wxListEvent_GetIndex, 2865).
--define(wxListEvent_GetColumn, 2866).
--define(wxListEvent_GetPoint, 2867).
--define(wxListEvent_GetLabel, 2868).
--define(wxListEvent_GetText, 2869).
--define(wxListEvent_GetImage, 2870).
--define(wxListEvent_GetData, 2871).
--define(wxListEvent_GetMask, 2872).
--define(wxListEvent_GetItem, 2873).
--define(wxListEvent_IsEditCancelled, 2874).
--define(wxDateEvent_GetDate, 2875).
--define(wxCalendarEvent_GetWeekDay, 2876).
--define(wxFileDirPickerEvent_GetPath, 2877).
--define(wxColourPickerEvent_GetColour, 2878).
--define(wxFontPickerEvent_GetFont, 2879).
--define(wxStyledTextEvent_GetPosition, 2880).
--define(wxStyledTextEvent_GetKey, 2881).
--define(wxStyledTextEvent_GetModifiers, 2882).
--define(wxStyledTextEvent_GetModificationType, 2883).
--define(wxStyledTextEvent_GetText, 2884).
--define(wxStyledTextEvent_GetLength, 2885).
--define(wxStyledTextEvent_GetLinesAdded, 2886).
--define(wxStyledTextEvent_GetLine, 2887).
--define(wxStyledTextEvent_GetFoldLevelNow, 2888).
--define(wxStyledTextEvent_GetFoldLevelPrev, 2889).
--define(wxStyledTextEvent_GetMargin, 2890).
--define(wxStyledTextEvent_GetMessage, 2891).
--define(wxStyledTextEvent_GetWParam, 2892).
--define(wxStyledTextEvent_GetLParam, 2893).
--define(wxStyledTextEvent_GetListType, 2894).
--define(wxStyledTextEvent_GetX, 2895).
--define(wxStyledTextEvent_GetY, 2896).
--define(wxStyledTextEvent_GetDragText, 2897).
--define(wxStyledTextEvent_GetDragAllowMove, 2898).
--define(wxStyledTextEvent_GetDragResult, 2899).
--define(wxStyledTextEvent_GetShift, 2900).
--define(wxStyledTextEvent_GetControl, 2901).
--define(wxStyledTextEvent_GetAlt, 2902).
--define(utils_wxGetKeyState, 2903).
--define(utils_wxGetMousePosition, 2904).
--define(utils_wxGetMouseState, 2905).
--define(utils_wxSetDetectableAutoRepeat, 2906).
--define(utils_wxBell, 2907).
--define(utils_wxFindMenuItemId, 2908).
--define(utils_wxGenericFindWindowAtPoint, 2909).
--define(utils_wxFindWindowAtPoint, 2910).
--define(utils_wxBeginBusyCursor, 2911).
--define(utils_wxEndBusyCursor, 2912).
--define(utils_wxIsBusy, 2913).
--define(utils_wxShutdown, 2914).
--define(utils_wxShell, 2915).
--define(utils_wxLaunchDefaultBrowser, 2916).
--define(utils_wxGetEmailAddress, 2917).
--define(utils_wxGetUserId, 2918).
--define(utils_wxGetHomeDir, 2919).
--define(utils_wxNewId, 2920).
--define(utils_wxRegisterId, 2921).
--define(utils_wxGetCurrentId, 2922).
--define(utils_wxGetOsDescription, 2923).
--define(utils_wxIsPlatformLittleEndian, 2924).
--define(utils_wxIsPlatform64Bit, 2925).
--define(wxPrintout_new, 2926).
--define(wxPrintout_destruct, 2927).
--define(wxPrintout_GetDC, 2928).
--define(wxPrintout_GetPageSizeMM, 2929).
--define(wxPrintout_GetPageSizePixels, 2930).
--define(wxPrintout_GetPaperRectPixels, 2931).
--define(wxPrintout_GetPPIPrinter, 2932).
--define(wxPrintout_GetPPIScreen, 2933).
--define(wxPrintout_GetTitle, 2934).
--define(wxPrintout_IsPreview, 2935).
--define(wxPrintout_FitThisSizeToPaper, 2936).
--define(wxPrintout_FitThisSizeToPage, 2937).
--define(wxPrintout_FitThisSizeToPageMargins, 2938).
--define(wxPrintout_MapScreenSizeToPaper, 2939).
--define(wxPrintout_MapScreenSizeToPage, 2940).
--define(wxPrintout_MapScreenSizeToPageMargins, 2941).
--define(wxPrintout_MapScreenSizeToDevice, 2942).
--define(wxPrintout_GetLogicalPaperRect, 2943).
--define(wxPrintout_GetLogicalPageRect, 2944).
--define(wxPrintout_GetLogicalPageMarginsRect, 2945).
--define(wxPrintout_SetLogicalOrigin, 2946).
--define(wxPrintout_OffsetLogicalOrigin, 2947).
--define(wxStyledTextCtrl_new_2, 2948).
--define(wxStyledTextCtrl_new_0, 2949).
--define(wxStyledTextCtrl_destruct, 2950).
--define(wxStyledTextCtrl_Create, 2951).
--define(wxStyledTextCtrl_AddText, 2952).
--define(wxStyledTextCtrl_AddStyledText, 2953).
--define(wxStyledTextCtrl_InsertText, 2954).
--define(wxStyledTextCtrl_ClearAll, 2955).
--define(wxStyledTextCtrl_ClearDocumentStyle, 2956).
--define(wxStyledTextCtrl_GetLength, 2957).
--define(wxStyledTextCtrl_GetCharAt, 2958).
--define(wxStyledTextCtrl_GetCurrentPos, 2959).
--define(wxStyledTextCtrl_GetAnchor, 2960).
--define(wxStyledTextCtrl_GetStyleAt, 2961).
--define(wxStyledTextCtrl_Redo, 2962).
--define(wxStyledTextCtrl_SetUndoCollection, 2963).
--define(wxStyledTextCtrl_SelectAll, 2964).
--define(wxStyledTextCtrl_SetSavePoint, 2965).
--define(wxStyledTextCtrl_GetStyledText, 2966).
--define(wxStyledTextCtrl_CanRedo, 2967).
--define(wxStyledTextCtrl_MarkerLineFromHandle, 2968).
--define(wxStyledTextCtrl_MarkerDeleteHandle, 2969).
--define(wxStyledTextCtrl_GetUndoCollection, 2970).
--define(wxStyledTextCtrl_GetViewWhiteSpace, 2971).
--define(wxStyledTextCtrl_SetViewWhiteSpace, 2972).
--define(wxStyledTextCtrl_PositionFromPoint, 2973).
--define(wxStyledTextCtrl_PositionFromPointClose, 2974).
--define(wxStyledTextCtrl_GotoLine, 2975).
--define(wxStyledTextCtrl_GotoPos, 2976).
--define(wxStyledTextCtrl_SetAnchor, 2977).
--define(wxStyledTextCtrl_GetCurLine, 2978).
--define(wxStyledTextCtrl_GetEndStyled, 2979).
--define(wxStyledTextCtrl_ConvertEOLs, 2980).
--define(wxStyledTextCtrl_GetEOLMode, 2981).
--define(wxStyledTextCtrl_SetEOLMode, 2982).
--define(wxStyledTextCtrl_StartStyling, 2983).
--define(wxStyledTextCtrl_SetStyling, 2984).
--define(wxStyledTextCtrl_GetBufferedDraw, 2985).
--define(wxStyledTextCtrl_SetBufferedDraw, 2986).
--define(wxStyledTextCtrl_SetTabWidth, 2987).
--define(wxStyledTextCtrl_GetTabWidth, 2988).
--define(wxStyledTextCtrl_SetCodePage, 2989).
--define(wxStyledTextCtrl_MarkerDefine, 2990).
--define(wxStyledTextCtrl_MarkerSetForeground, 2991).
--define(wxStyledTextCtrl_MarkerSetBackground, 2992).
--define(wxStyledTextCtrl_MarkerAdd, 2993).
--define(wxStyledTextCtrl_MarkerDelete, 2994).
--define(wxStyledTextCtrl_MarkerDeleteAll, 2995).
--define(wxStyledTextCtrl_MarkerGet, 2996).
--define(wxStyledTextCtrl_MarkerNext, 2997).
--define(wxStyledTextCtrl_MarkerPrevious, 2998).
--define(wxStyledTextCtrl_MarkerDefineBitmap, 2999).
--define(wxStyledTextCtrl_MarkerAddSet, 3000).
--define(wxStyledTextCtrl_MarkerSetAlpha, 3001).
--define(wxStyledTextCtrl_SetMarginType, 3002).
--define(wxStyledTextCtrl_GetMarginType, 3003).
--define(wxStyledTextCtrl_SetMarginWidth, 3004).
--define(wxStyledTextCtrl_GetMarginWidth, 3005).
--define(wxStyledTextCtrl_SetMarginMask, 3006).
--define(wxStyledTextCtrl_GetMarginMask, 3007).
--define(wxStyledTextCtrl_SetMarginSensitive, 3008).
--define(wxStyledTextCtrl_GetMarginSensitive, 3009).
--define(wxStyledTextCtrl_StyleClearAll, 3010).
--define(wxStyledTextCtrl_StyleSetForeground, 3011).
--define(wxStyledTextCtrl_StyleSetBackground, 3012).
--define(wxStyledTextCtrl_StyleSetBold, 3013).
--define(wxStyledTextCtrl_StyleSetItalic, 3014).
--define(wxStyledTextCtrl_StyleSetSize, 3015).
--define(wxStyledTextCtrl_StyleSetFaceName, 3016).
--define(wxStyledTextCtrl_StyleSetEOLFilled, 3017).
--define(wxStyledTextCtrl_StyleResetDefault, 3018).
--define(wxStyledTextCtrl_StyleSetUnderline, 3019).
--define(wxStyledTextCtrl_StyleSetCase, 3020).
--define(wxStyledTextCtrl_StyleSetHotSpot, 3021).
--define(wxStyledTextCtrl_SetSelForeground, 3022).
--define(wxStyledTextCtrl_SetSelBackground, 3023).
--define(wxStyledTextCtrl_GetSelAlpha, 3024).
--define(wxStyledTextCtrl_SetSelAlpha, 3025).
--define(wxStyledTextCtrl_SetCaretForeground, 3026).
--define(wxStyledTextCtrl_CmdKeyAssign, 3027).
--define(wxStyledTextCtrl_CmdKeyClear, 3028).
--define(wxStyledTextCtrl_CmdKeyClearAll, 3029).
--define(wxStyledTextCtrl_SetStyleBytes, 3030).
--define(wxStyledTextCtrl_StyleSetVisible, 3031).
--define(wxStyledTextCtrl_GetCaretPeriod, 3032).
--define(wxStyledTextCtrl_SetCaretPeriod, 3033).
--define(wxStyledTextCtrl_SetWordChars, 3034).
--define(wxStyledTextCtrl_BeginUndoAction, 3035).
--define(wxStyledTextCtrl_EndUndoAction, 3036).
--define(wxStyledTextCtrl_IndicatorSetStyle, 3037).
--define(wxStyledTextCtrl_IndicatorGetStyle, 3038).
--define(wxStyledTextCtrl_IndicatorSetForeground, 3039).
--define(wxStyledTextCtrl_IndicatorGetForeground, 3040).
--define(wxStyledTextCtrl_SetWhitespaceForeground, 3041).
--define(wxStyledTextCtrl_SetWhitespaceBackground, 3042).
--define(wxStyledTextCtrl_GetStyleBits, 3043).
--define(wxStyledTextCtrl_SetLineState, 3044).
--define(wxStyledTextCtrl_GetLineState, 3045).
--define(wxStyledTextCtrl_GetMaxLineState, 3046).
--define(wxStyledTextCtrl_GetCaretLineVisible, 3047).
--define(wxStyledTextCtrl_SetCaretLineVisible, 3048).
--define(wxStyledTextCtrl_GetCaretLineBackground, 3049).
--define(wxStyledTextCtrl_SetCaretLineBackground, 3050).
--define(wxStyledTextCtrl_AutoCompShow, 3051).
--define(wxStyledTextCtrl_AutoCompCancel, 3052).
--define(wxStyledTextCtrl_AutoCompActive, 3053).
--define(wxStyledTextCtrl_AutoCompPosStart, 3054).
--define(wxStyledTextCtrl_AutoCompComplete, 3055).
--define(wxStyledTextCtrl_AutoCompStops, 3056).
--define(wxStyledTextCtrl_AutoCompSetSeparator, 3057).
--define(wxStyledTextCtrl_AutoCompGetSeparator, 3058).
--define(wxStyledTextCtrl_AutoCompSelect, 3059).
--define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3060).
--define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3061).
--define(wxStyledTextCtrl_AutoCompSetFillUps, 3062).
--define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3063).
--define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3064).
--define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3065).
--define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3066).
--define(wxStyledTextCtrl_UserListShow, 3067).
--define(wxStyledTextCtrl_AutoCompSetAutoHide, 3068).
--define(wxStyledTextCtrl_AutoCompGetAutoHide, 3069).
--define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3070).
--define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3071).
--define(wxStyledTextCtrl_RegisterImage, 3072).
--define(wxStyledTextCtrl_ClearRegisteredImages, 3073).
--define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3074).
--define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3075).
--define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3076).
--define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3077).
--define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3078).
--define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3079).
--define(wxStyledTextCtrl_SetIndent, 3080).
--define(wxStyledTextCtrl_GetIndent, 3081).
--define(wxStyledTextCtrl_SetUseTabs, 3082).
--define(wxStyledTextCtrl_GetUseTabs, 3083).
--define(wxStyledTextCtrl_SetLineIndentation, 3084).
--define(wxStyledTextCtrl_GetLineIndentation, 3085).
--define(wxStyledTextCtrl_GetLineIndentPosition, 3086).
--define(wxStyledTextCtrl_GetColumn, 3087).
--define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3088).
--define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3089).
--define(wxStyledTextCtrl_SetIndentationGuides, 3090).
--define(wxStyledTextCtrl_GetIndentationGuides, 3091).
--define(wxStyledTextCtrl_SetHighlightGuide, 3092).
--define(wxStyledTextCtrl_GetHighlightGuide, 3093).
--define(wxStyledTextCtrl_GetLineEndPosition, 3094).
--define(wxStyledTextCtrl_GetCodePage, 3095).
--define(wxStyledTextCtrl_GetCaretForeground, 3096).
--define(wxStyledTextCtrl_GetReadOnly, 3097).
--define(wxStyledTextCtrl_SetCurrentPos, 3098).
--define(wxStyledTextCtrl_SetSelectionStart, 3099).
--define(wxStyledTextCtrl_GetSelectionStart, 3100).
--define(wxStyledTextCtrl_SetSelectionEnd, 3101).
--define(wxStyledTextCtrl_GetSelectionEnd, 3102).
--define(wxStyledTextCtrl_SetPrintMagnification, 3103).
--define(wxStyledTextCtrl_GetPrintMagnification, 3104).
--define(wxStyledTextCtrl_SetPrintColourMode, 3105).
--define(wxStyledTextCtrl_GetPrintColourMode, 3106).
--define(wxStyledTextCtrl_FindText, 3107).
--define(wxStyledTextCtrl_FormatRange, 3108).
--define(wxStyledTextCtrl_GetFirstVisibleLine, 3109).
--define(wxStyledTextCtrl_GetLine, 3110).
--define(wxStyledTextCtrl_GetLineCount, 3111).
--define(wxStyledTextCtrl_SetMarginLeft, 3112).
--define(wxStyledTextCtrl_GetMarginLeft, 3113).
--define(wxStyledTextCtrl_SetMarginRight, 3114).
--define(wxStyledTextCtrl_GetMarginRight, 3115).
--define(wxStyledTextCtrl_GetModify, 3116).
--define(wxStyledTextCtrl_SetSelection, 3117).
--define(wxStyledTextCtrl_GetSelectedText, 3118).
--define(wxStyledTextCtrl_GetTextRange, 3119).
--define(wxStyledTextCtrl_HideSelection, 3120).
--define(wxStyledTextCtrl_LineFromPosition, 3121).
--define(wxStyledTextCtrl_PositionFromLine, 3122).
--define(wxStyledTextCtrl_LineScroll, 3123).
--define(wxStyledTextCtrl_EnsureCaretVisible, 3124).
--define(wxStyledTextCtrl_ReplaceSelection, 3125).
--define(wxStyledTextCtrl_SetReadOnly, 3126).
--define(wxStyledTextCtrl_CanPaste, 3127).
--define(wxStyledTextCtrl_CanUndo, 3128).
--define(wxStyledTextCtrl_EmptyUndoBuffer, 3129).
--define(wxStyledTextCtrl_Undo, 3130).
--define(wxStyledTextCtrl_Cut, 3131).
--define(wxStyledTextCtrl_Copy, 3132).
--define(wxStyledTextCtrl_Paste, 3133).
--define(wxStyledTextCtrl_Clear, 3134).
--define(wxStyledTextCtrl_SetText, 3135).
--define(wxStyledTextCtrl_GetText, 3136).
--define(wxStyledTextCtrl_GetTextLength, 3137).
--define(wxStyledTextCtrl_GetOvertype, 3138).
--define(wxStyledTextCtrl_SetCaretWidth, 3139).
--define(wxStyledTextCtrl_GetCaretWidth, 3140).
--define(wxStyledTextCtrl_SetTargetStart, 3141).
--define(wxStyledTextCtrl_GetTargetStart, 3142).
--define(wxStyledTextCtrl_SetTargetEnd, 3143).
--define(wxStyledTextCtrl_GetTargetEnd, 3144).
--define(wxStyledTextCtrl_ReplaceTarget, 3145).
--define(wxStyledTextCtrl_SearchInTarget, 3146).
--define(wxStyledTextCtrl_SetSearchFlags, 3147).
--define(wxStyledTextCtrl_GetSearchFlags, 3148).
--define(wxStyledTextCtrl_CallTipShow, 3149).
--define(wxStyledTextCtrl_CallTipCancel, 3150).
--define(wxStyledTextCtrl_CallTipActive, 3151).
--define(wxStyledTextCtrl_CallTipPosAtStart, 3152).
--define(wxStyledTextCtrl_CallTipSetHighlight, 3153).
--define(wxStyledTextCtrl_CallTipSetBackground, 3154).
--define(wxStyledTextCtrl_CallTipSetForeground, 3155).
--define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3156).
--define(wxStyledTextCtrl_CallTipUseStyle, 3157).
--define(wxStyledTextCtrl_VisibleFromDocLine, 3158).
--define(wxStyledTextCtrl_DocLineFromVisible, 3159).
--define(wxStyledTextCtrl_WrapCount, 3160).
--define(wxStyledTextCtrl_SetFoldLevel, 3161).
--define(wxStyledTextCtrl_GetFoldLevel, 3162).
--define(wxStyledTextCtrl_GetLastChild, 3163).
--define(wxStyledTextCtrl_GetFoldParent, 3164).
--define(wxStyledTextCtrl_ShowLines, 3165).
--define(wxStyledTextCtrl_HideLines, 3166).
--define(wxStyledTextCtrl_GetLineVisible, 3167).
--define(wxStyledTextCtrl_SetFoldExpanded, 3168).
--define(wxStyledTextCtrl_GetFoldExpanded, 3169).
--define(wxStyledTextCtrl_ToggleFold, 3170).
--define(wxStyledTextCtrl_EnsureVisible, 3171).
--define(wxStyledTextCtrl_SetFoldFlags, 3172).
--define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3173).
--define(wxStyledTextCtrl_SetTabIndents, 3174).
--define(wxStyledTextCtrl_GetTabIndents, 3175).
--define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3176).
--define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3177).
--define(wxStyledTextCtrl_SetMouseDwellTime, 3178).
--define(wxStyledTextCtrl_GetMouseDwellTime, 3179).
--define(wxStyledTextCtrl_WordStartPosition, 3180).
--define(wxStyledTextCtrl_WordEndPosition, 3181).
--define(wxStyledTextCtrl_SetWrapMode, 3182).
--define(wxStyledTextCtrl_GetWrapMode, 3183).
--define(wxStyledTextCtrl_SetWrapVisualFlags, 3184).
--define(wxStyledTextCtrl_GetWrapVisualFlags, 3185).
--define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3186).
--define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3187).
--define(wxStyledTextCtrl_SetWrapStartIndent, 3188).
--define(wxStyledTextCtrl_GetWrapStartIndent, 3189).
--define(wxStyledTextCtrl_SetLayoutCache, 3190).
--define(wxStyledTextCtrl_GetLayoutCache, 3191).
--define(wxStyledTextCtrl_SetScrollWidth, 3192).
--define(wxStyledTextCtrl_GetScrollWidth, 3193).
--define(wxStyledTextCtrl_TextWidth, 3194).
--define(wxStyledTextCtrl_GetEndAtLastLine, 3195).
--define(wxStyledTextCtrl_TextHeight, 3196).
--define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3197).
--define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3198).
--define(wxStyledTextCtrl_AppendText, 3199).
--define(wxStyledTextCtrl_GetTwoPhaseDraw, 3200).
--define(wxStyledTextCtrl_SetTwoPhaseDraw, 3201).
--define(wxStyledTextCtrl_TargetFromSelection, 3202).
--define(wxStyledTextCtrl_LinesJoin, 3203).
--define(wxStyledTextCtrl_LinesSplit, 3204).
--define(wxStyledTextCtrl_SetFoldMarginColour, 3205).
--define(wxStyledTextCtrl_SetFoldMarginHiColour, 3206).
--define(wxStyledTextCtrl_LineDown, 3207).
--define(wxStyledTextCtrl_LineDownExtend, 3208).
--define(wxStyledTextCtrl_LineUp, 3209).
--define(wxStyledTextCtrl_LineUpExtend, 3210).
--define(wxStyledTextCtrl_CharLeft, 3211).
--define(wxStyledTextCtrl_CharLeftExtend, 3212).
--define(wxStyledTextCtrl_CharRight, 3213).
--define(wxStyledTextCtrl_CharRightExtend, 3214).
--define(wxStyledTextCtrl_WordLeft, 3215).
--define(wxStyledTextCtrl_WordLeftExtend, 3216).
--define(wxStyledTextCtrl_WordRight, 3217).
--define(wxStyledTextCtrl_WordRightExtend, 3218).
--define(wxStyledTextCtrl_Home, 3219).
--define(wxStyledTextCtrl_HomeExtend, 3220).
--define(wxStyledTextCtrl_LineEnd, 3221).
--define(wxStyledTextCtrl_LineEndExtend, 3222).
--define(wxStyledTextCtrl_DocumentStart, 3223).
--define(wxStyledTextCtrl_DocumentStartExtend, 3224).
--define(wxStyledTextCtrl_DocumentEnd, 3225).
--define(wxStyledTextCtrl_DocumentEndExtend, 3226).
--define(wxStyledTextCtrl_PageUp, 3227).
--define(wxStyledTextCtrl_PageUpExtend, 3228).
--define(wxStyledTextCtrl_PageDown, 3229).
--define(wxStyledTextCtrl_PageDownExtend, 3230).
--define(wxStyledTextCtrl_EditToggleOvertype, 3231).
--define(wxStyledTextCtrl_Cancel, 3232).
--define(wxStyledTextCtrl_DeleteBack, 3233).
--define(wxStyledTextCtrl_Tab, 3234).
--define(wxStyledTextCtrl_BackTab, 3235).
--define(wxStyledTextCtrl_NewLine, 3236).
--define(wxStyledTextCtrl_FormFeed, 3237).
--define(wxStyledTextCtrl_VCHome, 3238).
--define(wxStyledTextCtrl_VCHomeExtend, 3239).
--define(wxStyledTextCtrl_ZoomIn, 3240).
--define(wxStyledTextCtrl_ZoomOut, 3241).
--define(wxStyledTextCtrl_DelWordLeft, 3242).
--define(wxStyledTextCtrl_DelWordRight, 3243).
--define(wxStyledTextCtrl_LineCut, 3244).
--define(wxStyledTextCtrl_LineDelete, 3245).
--define(wxStyledTextCtrl_LineTranspose, 3246).
--define(wxStyledTextCtrl_LineDuplicate, 3247).
--define(wxStyledTextCtrl_LowerCase, 3248).
--define(wxStyledTextCtrl_UpperCase, 3249).
--define(wxStyledTextCtrl_LineScrollDown, 3250).
--define(wxStyledTextCtrl_LineScrollUp, 3251).
--define(wxStyledTextCtrl_DeleteBackNotLine, 3252).
--define(wxStyledTextCtrl_HomeDisplay, 3253).
--define(wxStyledTextCtrl_HomeDisplayExtend, 3254).
--define(wxStyledTextCtrl_LineEndDisplay, 3255).
--define(wxStyledTextCtrl_LineEndDisplayExtend, 3256).
--define(wxStyledTextCtrl_HomeWrapExtend, 3257).
--define(wxStyledTextCtrl_LineEndWrap, 3258).
--define(wxStyledTextCtrl_LineEndWrapExtend, 3259).
--define(wxStyledTextCtrl_VCHomeWrap, 3260).
--define(wxStyledTextCtrl_VCHomeWrapExtend, 3261).
--define(wxStyledTextCtrl_LineCopy, 3262).
--define(wxStyledTextCtrl_MoveCaretInsideView, 3263).
--define(wxStyledTextCtrl_LineLength, 3264).
--define(wxStyledTextCtrl_BraceHighlight, 3265).
--define(wxStyledTextCtrl_BraceBadLight, 3266).
--define(wxStyledTextCtrl_BraceMatch, 3267).
--define(wxStyledTextCtrl_GetViewEOL, 3268).
--define(wxStyledTextCtrl_SetViewEOL, 3269).
--define(wxStyledTextCtrl_SetModEventMask, 3270).
--define(wxStyledTextCtrl_GetEdgeColumn, 3271).
--define(wxStyledTextCtrl_SetEdgeColumn, 3272).
--define(wxStyledTextCtrl_SetEdgeMode, 3273).
--define(wxStyledTextCtrl_GetEdgeMode, 3274).
--define(wxStyledTextCtrl_GetEdgeColour, 3275).
--define(wxStyledTextCtrl_SetEdgeColour, 3276).
--define(wxStyledTextCtrl_SearchAnchor, 3277).
--define(wxStyledTextCtrl_SearchNext, 3278).
--define(wxStyledTextCtrl_SearchPrev, 3279).
--define(wxStyledTextCtrl_LinesOnScreen, 3280).
--define(wxStyledTextCtrl_UsePopUp, 3281).
--define(wxStyledTextCtrl_SelectionIsRectangle, 3282).
--define(wxStyledTextCtrl_SetZoom, 3283).
--define(wxStyledTextCtrl_GetZoom, 3284).
--define(wxStyledTextCtrl_GetModEventMask, 3285).
--define(wxStyledTextCtrl_SetSTCFocus, 3286).
--define(wxStyledTextCtrl_GetSTCFocus, 3287).
--define(wxStyledTextCtrl_SetStatus, 3288).
--define(wxStyledTextCtrl_GetStatus, 3289).
--define(wxStyledTextCtrl_SetMouseDownCaptures, 3290).
--define(wxStyledTextCtrl_GetMouseDownCaptures, 3291).
--define(wxStyledTextCtrl_SetSTCCursor, 3292).
--define(wxStyledTextCtrl_GetSTCCursor, 3293).
--define(wxStyledTextCtrl_SetControlCharSymbol, 3294).
--define(wxStyledTextCtrl_GetControlCharSymbol, 3295).
--define(wxStyledTextCtrl_WordPartLeft, 3296).
--define(wxStyledTextCtrl_WordPartLeftExtend, 3297).
--define(wxStyledTextCtrl_WordPartRight, 3298).
--define(wxStyledTextCtrl_WordPartRightExtend, 3299).
--define(wxStyledTextCtrl_SetVisiblePolicy, 3300).
--define(wxStyledTextCtrl_DelLineLeft, 3301).
--define(wxStyledTextCtrl_DelLineRight, 3302).
--define(wxStyledTextCtrl_GetXOffset, 3303).
--define(wxStyledTextCtrl_ChooseCaretX, 3304).
--define(wxStyledTextCtrl_SetXCaretPolicy, 3305).
--define(wxStyledTextCtrl_SetYCaretPolicy, 3306).
--define(wxStyledTextCtrl_GetPrintWrapMode, 3307).
--define(wxStyledTextCtrl_SetHotspotActiveForeground, 3308).
--define(wxStyledTextCtrl_SetHotspotActiveBackground, 3309).
--define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3310).
--define(wxStyledTextCtrl_SetHotspotSingleLine, 3311).
--define(wxStyledTextCtrl_ParaDownExtend, 3312).
--define(wxStyledTextCtrl_ParaUp, 3313).
--define(wxStyledTextCtrl_ParaUpExtend, 3314).
--define(wxStyledTextCtrl_PositionBefore, 3315).
--define(wxStyledTextCtrl_PositionAfter, 3316).
--define(wxStyledTextCtrl_CopyRange, 3317).
--define(wxStyledTextCtrl_CopyText, 3318).
--define(wxStyledTextCtrl_SetSelectionMode, 3319).
--define(wxStyledTextCtrl_GetSelectionMode, 3320).
--define(wxStyledTextCtrl_LineDownRectExtend, 3321).
--define(wxStyledTextCtrl_LineUpRectExtend, 3322).
--define(wxStyledTextCtrl_CharLeftRectExtend, 3323).
--define(wxStyledTextCtrl_CharRightRectExtend, 3324).
--define(wxStyledTextCtrl_HomeRectExtend, 3325).
--define(wxStyledTextCtrl_VCHomeRectExtend, 3326).
--define(wxStyledTextCtrl_LineEndRectExtend, 3327).
--define(wxStyledTextCtrl_PageUpRectExtend, 3328).
--define(wxStyledTextCtrl_PageDownRectExtend, 3329).
--define(wxStyledTextCtrl_StutteredPageUp, 3330).
--define(wxStyledTextCtrl_StutteredPageUpExtend, 3331).
--define(wxStyledTextCtrl_StutteredPageDown, 3332).
--define(wxStyledTextCtrl_StutteredPageDownExtend, 3333).
--define(wxStyledTextCtrl_WordLeftEnd, 3334).
--define(wxStyledTextCtrl_WordLeftEndExtend, 3335).
--define(wxStyledTextCtrl_WordRightEnd, 3336).
--define(wxStyledTextCtrl_WordRightEndExtend, 3337).
--define(wxStyledTextCtrl_SetWhitespaceChars, 3338).
--define(wxStyledTextCtrl_SetCharsDefault, 3339).
--define(wxStyledTextCtrl_AutoCompGetCurrent, 3340).
--define(wxStyledTextCtrl_Allocate, 3341).
--define(wxStyledTextCtrl_FindColumn, 3342).
--define(wxStyledTextCtrl_GetCaretSticky, 3343).
--define(wxStyledTextCtrl_SetCaretSticky, 3344).
--define(wxStyledTextCtrl_ToggleCaretSticky, 3345).
--define(wxStyledTextCtrl_SetPasteConvertEndings, 3346).
--define(wxStyledTextCtrl_GetPasteConvertEndings, 3347).
--define(wxStyledTextCtrl_SelectionDuplicate, 3348).
--define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3349).
--define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3350).
--define(wxStyledTextCtrl_StartRecord, 3351).
--define(wxStyledTextCtrl_StopRecord, 3352).
--define(wxStyledTextCtrl_SetLexer, 3353).
--define(wxStyledTextCtrl_GetLexer, 3354).
--define(wxStyledTextCtrl_Colourise, 3355).
--define(wxStyledTextCtrl_SetProperty, 3356).
--define(wxStyledTextCtrl_SetKeyWords, 3357).
--define(wxStyledTextCtrl_SetLexerLanguage, 3358).
--define(wxStyledTextCtrl_GetProperty, 3359).
--define(wxStyledTextCtrl_GetStyleBitsNeeded, 3360).
--define(wxStyledTextCtrl_GetCurrentLine, 3361).
--define(wxStyledTextCtrl_StyleSetSpec, 3362).
--define(wxStyledTextCtrl_StyleSetFont, 3363).
--define(wxStyledTextCtrl_StyleSetFontAttr, 3364).
--define(wxStyledTextCtrl_StyleSetCharacterSet, 3365).
--define(wxStyledTextCtrl_StyleSetFontEncoding, 3366).
--define(wxStyledTextCtrl_CmdKeyExecute, 3367).
--define(wxStyledTextCtrl_SetMargins, 3368).
--define(wxStyledTextCtrl_GetSelection, 3369).
--define(wxStyledTextCtrl_PointFromPosition, 3370).
--define(wxStyledTextCtrl_ScrollToLine, 3371).
--define(wxStyledTextCtrl_ScrollToColumn, 3372).
--define(wxStyledTextCtrl_SetVScrollBar, 3373).
--define(wxStyledTextCtrl_SetHScrollBar, 3374).
--define(wxStyledTextCtrl_GetLastKeydownProcessed, 3375).
--define(wxStyledTextCtrl_SetLastKeydownProcessed, 3376).
--define(wxStyledTextCtrl_SaveFile, 3377).
--define(wxStyledTextCtrl_LoadFile, 3378).
--define(wxStyledTextCtrl_DoDragOver, 3379).
--define(wxStyledTextCtrl_DoDropText, 3380).
--define(wxStyledTextCtrl_GetUseAntiAliasing, 3381).
--define(wxStyledTextCtrl_AddTextRaw, 3382).
--define(wxStyledTextCtrl_InsertTextRaw, 3383).
--define(wxStyledTextCtrl_GetCurLineRaw, 3384).
--define(wxStyledTextCtrl_GetLineRaw, 3385).
--define(wxStyledTextCtrl_GetSelectedTextRaw, 3386).
--define(wxStyledTextCtrl_GetTextRangeRaw, 3387).
--define(wxStyledTextCtrl_SetTextRaw, 3388).
--define(wxStyledTextCtrl_GetTextRaw, 3389).
--define(wxStyledTextCtrl_AppendTextRaw, 3390).
--define(wxArtProvider_GetBitmap, 3391).
--define(wxArtProvider_GetIcon, 3392).
--define(wxTreeEvent_GetKeyCode, 3393).
--define(wxTreeEvent_GetItem, 3394).
--define(wxTreeEvent_GetKeyEvent, 3395).
--define(wxTreeEvent_GetLabel, 3396).
--define(wxTreeEvent_GetOldItem, 3397).
--define(wxTreeEvent_GetPoint, 3398).
--define(wxTreeEvent_IsEditCancelled, 3399).
--define(wxTreeEvent_SetToolTip, 3400).
--define(wxNotebookEvent_GetOldSelection, 3401).
--define(wxNotebookEvent_GetSelection, 3402).
--define(wxNotebookEvent_SetOldSelection, 3403).
--define(wxNotebookEvent_SetSelection, 3404).
--define(wxFileDataObject_new, 3405).
--define(wxFileDataObject_AddFile, 3406).
--define(wxFileDataObject_GetFilenames, 3407).
--define(wxFileDataObject_destroy, 3408).
--define(wxTextDataObject_new, 3409).
--define(wxTextDataObject_GetTextLength, 3410).
--define(wxTextDataObject_GetText, 3411).
--define(wxTextDataObject_SetText, 3412).
--define(wxTextDataObject_destroy, 3413).
--define(wxBitmapDataObject_new_1_1, 3414).
--define(wxBitmapDataObject_new_1_0, 3415).
--define(wxBitmapDataObject_GetBitmap, 3416).
--define(wxBitmapDataObject_SetBitmap, 3417).
--define(wxBitmapDataObject_destroy, 3418).
--define(wxClipboard_new, 3420).
--define(wxClipboard_destruct, 3421).
--define(wxClipboard_AddData, 3422).
--define(wxClipboard_Clear, 3423).
--define(wxClipboard_Close, 3424).
--define(wxClipboard_Flush, 3425).
--define(wxClipboard_GetData, 3426).
--define(wxClipboard_IsOpened, 3427).
--define(wxClipboard_Open, 3428).
--define(wxClipboard_SetData, 3429).
--define(wxClipboard_UsePrimarySelection, 3431).
--define(wxClipboard_IsSupported, 3432).
--define(wxClipboard_Get, 3433).
--define(wxSpinEvent_GetPosition, 3434).
--define(wxSpinEvent_SetPosition, 3435).
--define(wxSplitterWindow_new_0, 3436).
--define(wxSplitterWindow_new_2, 3437).
--define(wxSplitterWindow_destruct, 3438).
--define(wxSplitterWindow_Create, 3439).
--define(wxSplitterWindow_GetMinimumPaneSize, 3440).
--define(wxSplitterWindow_GetSashGravity, 3441).
--define(wxSplitterWindow_GetSashPosition, 3442).
--define(wxSplitterWindow_GetSplitMode, 3443).
--define(wxSplitterWindow_GetWindow1, 3444).
--define(wxSplitterWindow_GetWindow2, 3445).
--define(wxSplitterWindow_Initialize, 3446).
--define(wxSplitterWindow_IsSplit, 3447).
--define(wxSplitterWindow_ReplaceWindow, 3448).
--define(wxSplitterWindow_SetSashGravity, 3449).
--define(wxSplitterWindow_SetSashPosition, 3450).
--define(wxSplitterWindow_SetSashSize, 3451).
--define(wxSplitterWindow_SetMinimumPaneSize, 3452).
--define(wxSplitterWindow_SetSplitMode, 3453).
--define(wxSplitterWindow_SplitHorizontally, 3454).
--define(wxSplitterWindow_SplitVertically, 3455).
--define(wxSplitterWindow_Unsplit, 3456).
--define(wxSplitterWindow_UpdateSize, 3457).
--define(wxSplitterEvent_GetSashPosition, 3458).
--define(wxSplitterEvent_GetX, 3459).
--define(wxSplitterEvent_GetY, 3460).
--define(wxSplitterEvent_GetWindowBeingRemoved, 3461).
--define(wxSplitterEvent_SetSashPosition, 3462).
--define(wxHtmlWindow_new_0, 3463).
--define(wxHtmlWindow_new_2, 3464).
--define(wxHtmlWindow_AppendToPage, 3465).
--define(wxHtmlWindow_GetOpenedAnchor, 3466).
--define(wxHtmlWindow_GetOpenedPage, 3467).
--define(wxHtmlWindow_GetOpenedPageTitle, 3468).
--define(wxHtmlWindow_GetRelatedFrame, 3469).
--define(wxHtmlWindow_HistoryBack, 3470).
--define(wxHtmlWindow_HistoryCanBack, 3471).
--define(wxHtmlWindow_HistoryCanForward, 3472).
--define(wxHtmlWindow_HistoryClear, 3473).
--define(wxHtmlWindow_HistoryForward, 3474).
--define(wxHtmlWindow_LoadFile, 3475).
--define(wxHtmlWindow_LoadPage, 3476).
--define(wxHtmlWindow_SelectAll, 3477).
--define(wxHtmlWindow_SelectionToText, 3478).
--define(wxHtmlWindow_SelectLine, 3479).
--define(wxHtmlWindow_SelectWord, 3480).
--define(wxHtmlWindow_SetBorders, 3481).
--define(wxHtmlWindow_SetFonts, 3482).
--define(wxHtmlWindow_SetPage, 3483).
--define(wxHtmlWindow_SetRelatedFrame, 3484).
--define(wxHtmlWindow_SetRelatedStatusBar, 3485).
--define(wxHtmlWindow_ToText, 3486).
--define(wxHtmlWindow_destroy, 3487).
--define(wxHtmlLinkEvent_GetLinkInfo, 3488).
--define(wxSystemSettings_GetColour, 3489).
--define(wxSystemSettings_GetFont, 3490).
--define(wxSystemSettings_GetMetric, 3491).
--define(wxSystemSettings_GetScreenType, 3492).
--define(wxSystemOptions_GetOption, 3493).
--define(wxSystemOptions_GetOptionInt, 3494).
--define(wxSystemOptions_HasOption, 3495).
--define(wxSystemOptions_IsFalse, 3496).
--define(wxSystemOptions_SetOption_2_1, 3497).
--define(wxSystemOptions_SetOption_2_0, 3498).
--define(wxAuiNotebookEvent_SetSelection, 3499).
--define(wxAuiNotebookEvent_GetSelection, 3500).
--define(wxAuiNotebookEvent_SetOldSelection, 3501).
--define(wxAuiNotebookEvent_GetOldSelection, 3502).
--define(wxAuiNotebookEvent_SetDragSource, 3503).
--define(wxAuiNotebookEvent_GetDragSource, 3504).
--define(wxAuiManagerEvent_SetManager, 3505).
--define(wxAuiManagerEvent_GetManager, 3506).
--define(wxAuiManagerEvent_SetPane, 3507).
--define(wxAuiManagerEvent_GetPane, 3508).
--define(wxAuiManagerEvent_SetButton, 3509).
--define(wxAuiManagerEvent_GetButton, 3510).
--define(wxAuiManagerEvent_SetDC, 3511).
--define(wxAuiManagerEvent_GetDC, 3512).
--define(wxAuiManagerEvent_Veto, 3513).
--define(wxAuiManagerEvent_GetVeto, 3514).
--define(wxAuiManagerEvent_SetCanVeto, 3515).
--define(wxAuiManagerEvent_CanVeto, 3516).
--define(wxLogNull_new, 3517).
--define(wxLogNull_destroy, 3518).
--define(wxTaskBarIcon_new, 3519).
--define(wxTaskBarIcon_destruct, 3520).
--define(wxTaskBarIcon_PopupMenu, 3521).
--define(wxTaskBarIcon_RemoveIcon, 3522).
--define(wxTaskBarIcon_SetIcon, 3523).
+-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(wxPrintout_new, 2927).
+-define(wxPrintout_destruct, 2928).
+-define(wxPrintout_GetDC, 2929).
+-define(wxPrintout_GetPageSizeMM, 2930).
+-define(wxPrintout_GetPageSizePixels, 2931).
+-define(wxPrintout_GetPaperRectPixels, 2932).
+-define(wxPrintout_GetPPIPrinter, 2933).
+-define(wxPrintout_GetPPIScreen, 2934).
+-define(wxPrintout_GetTitle, 2935).
+-define(wxPrintout_IsPreview, 2936).
+-define(wxPrintout_FitThisSizeToPaper, 2937).
+-define(wxPrintout_FitThisSizeToPage, 2938).
+-define(wxPrintout_FitThisSizeToPageMargins, 2939).
+-define(wxPrintout_MapScreenSizeToPaper, 2940).
+-define(wxPrintout_MapScreenSizeToPage, 2941).
+-define(wxPrintout_MapScreenSizeToPageMargins, 2942).
+-define(wxPrintout_MapScreenSizeToDevice, 2943).
+-define(wxPrintout_GetLogicalPaperRect, 2944).
+-define(wxPrintout_GetLogicalPageRect, 2945).
+-define(wxPrintout_GetLogicalPageMarginsRect, 2946).
+-define(wxPrintout_SetLogicalOrigin, 2947).
+-define(wxPrintout_OffsetLogicalOrigin, 2948).
+-define(wxStyledTextCtrl_new_2, 2949).
+-define(wxStyledTextCtrl_new_0, 2950).
+-define(wxStyledTextCtrl_destruct, 2951).
+-define(wxStyledTextCtrl_Create, 2952).
+-define(wxStyledTextCtrl_AddText, 2953).
+-define(wxStyledTextCtrl_AddStyledText, 2954).
+-define(wxStyledTextCtrl_InsertText, 2955).
+-define(wxStyledTextCtrl_ClearAll, 2956).
+-define(wxStyledTextCtrl_ClearDocumentStyle, 2957).
+-define(wxStyledTextCtrl_GetLength, 2958).
+-define(wxStyledTextCtrl_GetCharAt, 2959).
+-define(wxStyledTextCtrl_GetCurrentPos, 2960).
+-define(wxStyledTextCtrl_GetAnchor, 2961).
+-define(wxStyledTextCtrl_GetStyleAt, 2962).
+-define(wxStyledTextCtrl_Redo, 2963).
+-define(wxStyledTextCtrl_SetUndoCollection, 2964).
+-define(wxStyledTextCtrl_SelectAll, 2965).
+-define(wxStyledTextCtrl_SetSavePoint, 2966).
+-define(wxStyledTextCtrl_GetStyledText, 2967).
+-define(wxStyledTextCtrl_CanRedo, 2968).
+-define(wxStyledTextCtrl_MarkerLineFromHandle, 2969).
+-define(wxStyledTextCtrl_MarkerDeleteHandle, 2970).
+-define(wxStyledTextCtrl_GetUndoCollection, 2971).
+-define(wxStyledTextCtrl_GetViewWhiteSpace, 2972).
+-define(wxStyledTextCtrl_SetViewWhiteSpace, 2973).
+-define(wxStyledTextCtrl_PositionFromPoint, 2974).
+-define(wxStyledTextCtrl_PositionFromPointClose, 2975).
+-define(wxStyledTextCtrl_GotoLine, 2976).
+-define(wxStyledTextCtrl_GotoPos, 2977).
+-define(wxStyledTextCtrl_SetAnchor, 2978).
+-define(wxStyledTextCtrl_GetCurLine, 2979).
+-define(wxStyledTextCtrl_GetEndStyled, 2980).
+-define(wxStyledTextCtrl_ConvertEOLs, 2981).
+-define(wxStyledTextCtrl_GetEOLMode, 2982).
+-define(wxStyledTextCtrl_SetEOLMode, 2983).
+-define(wxStyledTextCtrl_StartStyling, 2984).
+-define(wxStyledTextCtrl_SetStyling, 2985).
+-define(wxStyledTextCtrl_GetBufferedDraw, 2986).
+-define(wxStyledTextCtrl_SetBufferedDraw, 2987).
+-define(wxStyledTextCtrl_SetTabWidth, 2988).
+-define(wxStyledTextCtrl_GetTabWidth, 2989).
+-define(wxStyledTextCtrl_SetCodePage, 2990).
+-define(wxStyledTextCtrl_MarkerDefine, 2991).
+-define(wxStyledTextCtrl_MarkerSetForeground, 2992).
+-define(wxStyledTextCtrl_MarkerSetBackground, 2993).
+-define(wxStyledTextCtrl_MarkerAdd, 2994).
+-define(wxStyledTextCtrl_MarkerDelete, 2995).
+-define(wxStyledTextCtrl_MarkerDeleteAll, 2996).
+-define(wxStyledTextCtrl_MarkerGet, 2997).
+-define(wxStyledTextCtrl_MarkerNext, 2998).
+-define(wxStyledTextCtrl_MarkerPrevious, 2999).
+-define(wxStyledTextCtrl_MarkerDefineBitmap, 3000).
+-define(wxStyledTextCtrl_MarkerAddSet, 3001).
+-define(wxStyledTextCtrl_MarkerSetAlpha, 3002).
+-define(wxStyledTextCtrl_SetMarginType, 3003).
+-define(wxStyledTextCtrl_GetMarginType, 3004).
+-define(wxStyledTextCtrl_SetMarginWidth, 3005).
+-define(wxStyledTextCtrl_GetMarginWidth, 3006).
+-define(wxStyledTextCtrl_SetMarginMask, 3007).
+-define(wxStyledTextCtrl_GetMarginMask, 3008).
+-define(wxStyledTextCtrl_SetMarginSensitive, 3009).
+-define(wxStyledTextCtrl_GetMarginSensitive, 3010).
+-define(wxStyledTextCtrl_StyleClearAll, 3011).
+-define(wxStyledTextCtrl_StyleSetForeground, 3012).
+-define(wxStyledTextCtrl_StyleSetBackground, 3013).
+-define(wxStyledTextCtrl_StyleSetBold, 3014).
+-define(wxStyledTextCtrl_StyleSetItalic, 3015).
+-define(wxStyledTextCtrl_StyleSetSize, 3016).
+-define(wxStyledTextCtrl_StyleSetFaceName, 3017).
+-define(wxStyledTextCtrl_StyleSetEOLFilled, 3018).
+-define(wxStyledTextCtrl_StyleResetDefault, 3019).
+-define(wxStyledTextCtrl_StyleSetUnderline, 3020).
+-define(wxStyledTextCtrl_StyleSetCase, 3021).
+-define(wxStyledTextCtrl_StyleSetHotSpot, 3022).
+-define(wxStyledTextCtrl_SetSelForeground, 3023).
+-define(wxStyledTextCtrl_SetSelBackground, 3024).
+-define(wxStyledTextCtrl_GetSelAlpha, 3025).
+-define(wxStyledTextCtrl_SetSelAlpha, 3026).
+-define(wxStyledTextCtrl_SetCaretForeground, 3027).
+-define(wxStyledTextCtrl_CmdKeyAssign, 3028).
+-define(wxStyledTextCtrl_CmdKeyClear, 3029).
+-define(wxStyledTextCtrl_CmdKeyClearAll, 3030).
+-define(wxStyledTextCtrl_SetStyleBytes, 3031).
+-define(wxStyledTextCtrl_StyleSetVisible, 3032).
+-define(wxStyledTextCtrl_GetCaretPeriod, 3033).
+-define(wxStyledTextCtrl_SetCaretPeriod, 3034).
+-define(wxStyledTextCtrl_SetWordChars, 3035).
+-define(wxStyledTextCtrl_BeginUndoAction, 3036).
+-define(wxStyledTextCtrl_EndUndoAction, 3037).
+-define(wxStyledTextCtrl_IndicatorSetStyle, 3038).
+-define(wxStyledTextCtrl_IndicatorGetStyle, 3039).
+-define(wxStyledTextCtrl_IndicatorSetForeground, 3040).
+-define(wxStyledTextCtrl_IndicatorGetForeground, 3041).
+-define(wxStyledTextCtrl_SetWhitespaceForeground, 3042).
+-define(wxStyledTextCtrl_SetWhitespaceBackground, 3043).
+-define(wxStyledTextCtrl_GetStyleBits, 3044).
+-define(wxStyledTextCtrl_SetLineState, 3045).
+-define(wxStyledTextCtrl_GetLineState, 3046).
+-define(wxStyledTextCtrl_GetMaxLineState, 3047).
+-define(wxStyledTextCtrl_GetCaretLineVisible, 3048).
+-define(wxStyledTextCtrl_SetCaretLineVisible, 3049).
+-define(wxStyledTextCtrl_GetCaretLineBackground, 3050).
+-define(wxStyledTextCtrl_SetCaretLineBackground, 3051).
+-define(wxStyledTextCtrl_AutoCompShow, 3052).
+-define(wxStyledTextCtrl_AutoCompCancel, 3053).
+-define(wxStyledTextCtrl_AutoCompActive, 3054).
+-define(wxStyledTextCtrl_AutoCompPosStart, 3055).
+-define(wxStyledTextCtrl_AutoCompComplete, 3056).
+-define(wxStyledTextCtrl_AutoCompStops, 3057).
+-define(wxStyledTextCtrl_AutoCompSetSeparator, 3058).
+-define(wxStyledTextCtrl_AutoCompGetSeparator, 3059).
+-define(wxStyledTextCtrl_AutoCompSelect, 3060).
+-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3061).
+-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3062).
+-define(wxStyledTextCtrl_AutoCompSetFillUps, 3063).
+-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3064).
+-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3065).
+-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3066).
+-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3067).
+-define(wxStyledTextCtrl_UserListShow, 3068).
+-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3069).
+-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3070).
+-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3071).
+-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3072).
+-define(wxStyledTextCtrl_RegisterImage, 3073).
+-define(wxStyledTextCtrl_ClearRegisteredImages, 3074).
+-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3075).
+-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3076).
+-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3077).
+-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3078).
+-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3079).
+-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3080).
+-define(wxStyledTextCtrl_SetIndent, 3081).
+-define(wxStyledTextCtrl_GetIndent, 3082).
+-define(wxStyledTextCtrl_SetUseTabs, 3083).
+-define(wxStyledTextCtrl_GetUseTabs, 3084).
+-define(wxStyledTextCtrl_SetLineIndentation, 3085).
+-define(wxStyledTextCtrl_GetLineIndentation, 3086).
+-define(wxStyledTextCtrl_GetLineIndentPosition, 3087).
+-define(wxStyledTextCtrl_GetColumn, 3088).
+-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3089).
+-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3090).
+-define(wxStyledTextCtrl_SetIndentationGuides, 3091).
+-define(wxStyledTextCtrl_GetIndentationGuides, 3092).
+-define(wxStyledTextCtrl_SetHighlightGuide, 3093).
+-define(wxStyledTextCtrl_GetHighlightGuide, 3094).
+-define(wxStyledTextCtrl_GetLineEndPosition, 3095).
+-define(wxStyledTextCtrl_GetCodePage, 3096).
+-define(wxStyledTextCtrl_GetCaretForeground, 3097).
+-define(wxStyledTextCtrl_GetReadOnly, 3098).
+-define(wxStyledTextCtrl_SetCurrentPos, 3099).
+-define(wxStyledTextCtrl_SetSelectionStart, 3100).
+-define(wxStyledTextCtrl_GetSelectionStart, 3101).
+-define(wxStyledTextCtrl_SetSelectionEnd, 3102).
+-define(wxStyledTextCtrl_GetSelectionEnd, 3103).
+-define(wxStyledTextCtrl_SetPrintMagnification, 3104).
+-define(wxStyledTextCtrl_GetPrintMagnification, 3105).
+-define(wxStyledTextCtrl_SetPrintColourMode, 3106).
+-define(wxStyledTextCtrl_GetPrintColourMode, 3107).
+-define(wxStyledTextCtrl_FindText, 3108).
+-define(wxStyledTextCtrl_FormatRange, 3109).
+-define(wxStyledTextCtrl_GetFirstVisibleLine, 3110).
+-define(wxStyledTextCtrl_GetLine, 3111).
+-define(wxStyledTextCtrl_GetLineCount, 3112).
+-define(wxStyledTextCtrl_SetMarginLeft, 3113).
+-define(wxStyledTextCtrl_GetMarginLeft, 3114).
+-define(wxStyledTextCtrl_SetMarginRight, 3115).
+-define(wxStyledTextCtrl_GetMarginRight, 3116).
+-define(wxStyledTextCtrl_GetModify, 3117).
+-define(wxStyledTextCtrl_SetSelection, 3118).
+-define(wxStyledTextCtrl_GetSelectedText, 3119).
+-define(wxStyledTextCtrl_GetTextRange, 3120).
+-define(wxStyledTextCtrl_HideSelection, 3121).
+-define(wxStyledTextCtrl_LineFromPosition, 3122).
+-define(wxStyledTextCtrl_PositionFromLine, 3123).
+-define(wxStyledTextCtrl_LineScroll, 3124).
+-define(wxStyledTextCtrl_EnsureCaretVisible, 3125).
+-define(wxStyledTextCtrl_ReplaceSelection, 3126).
+-define(wxStyledTextCtrl_SetReadOnly, 3127).
+-define(wxStyledTextCtrl_CanPaste, 3128).
+-define(wxStyledTextCtrl_CanUndo, 3129).
+-define(wxStyledTextCtrl_EmptyUndoBuffer, 3130).
+-define(wxStyledTextCtrl_Undo, 3131).
+-define(wxStyledTextCtrl_Cut, 3132).
+-define(wxStyledTextCtrl_Copy, 3133).
+-define(wxStyledTextCtrl_Paste, 3134).
+-define(wxStyledTextCtrl_Clear, 3135).
+-define(wxStyledTextCtrl_SetText, 3136).
+-define(wxStyledTextCtrl_GetText, 3137).
+-define(wxStyledTextCtrl_GetTextLength, 3138).
+-define(wxStyledTextCtrl_GetOvertype, 3139).
+-define(wxStyledTextCtrl_SetCaretWidth, 3140).
+-define(wxStyledTextCtrl_GetCaretWidth, 3141).
+-define(wxStyledTextCtrl_SetTargetStart, 3142).
+-define(wxStyledTextCtrl_GetTargetStart, 3143).
+-define(wxStyledTextCtrl_SetTargetEnd, 3144).
+-define(wxStyledTextCtrl_GetTargetEnd, 3145).
+-define(wxStyledTextCtrl_ReplaceTarget, 3146).
+-define(wxStyledTextCtrl_SearchInTarget, 3147).
+-define(wxStyledTextCtrl_SetSearchFlags, 3148).
+-define(wxStyledTextCtrl_GetSearchFlags, 3149).
+-define(wxStyledTextCtrl_CallTipShow, 3150).
+-define(wxStyledTextCtrl_CallTipCancel, 3151).
+-define(wxStyledTextCtrl_CallTipActive, 3152).
+-define(wxStyledTextCtrl_CallTipPosAtStart, 3153).
+-define(wxStyledTextCtrl_CallTipSetHighlight, 3154).
+-define(wxStyledTextCtrl_CallTipSetBackground, 3155).
+-define(wxStyledTextCtrl_CallTipSetForeground, 3156).
+-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3157).
+-define(wxStyledTextCtrl_CallTipUseStyle, 3158).
+-define(wxStyledTextCtrl_VisibleFromDocLine, 3159).
+-define(wxStyledTextCtrl_DocLineFromVisible, 3160).
+-define(wxStyledTextCtrl_WrapCount, 3161).
+-define(wxStyledTextCtrl_SetFoldLevel, 3162).
+-define(wxStyledTextCtrl_GetFoldLevel, 3163).
+-define(wxStyledTextCtrl_GetLastChild, 3164).
+-define(wxStyledTextCtrl_GetFoldParent, 3165).
+-define(wxStyledTextCtrl_ShowLines, 3166).
+-define(wxStyledTextCtrl_HideLines, 3167).
+-define(wxStyledTextCtrl_GetLineVisible, 3168).
+-define(wxStyledTextCtrl_SetFoldExpanded, 3169).
+-define(wxStyledTextCtrl_GetFoldExpanded, 3170).
+-define(wxStyledTextCtrl_ToggleFold, 3171).
+-define(wxStyledTextCtrl_EnsureVisible, 3172).
+-define(wxStyledTextCtrl_SetFoldFlags, 3173).
+-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3174).
+-define(wxStyledTextCtrl_SetTabIndents, 3175).
+-define(wxStyledTextCtrl_GetTabIndents, 3176).
+-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3177).
+-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3178).
+-define(wxStyledTextCtrl_SetMouseDwellTime, 3179).
+-define(wxStyledTextCtrl_GetMouseDwellTime, 3180).
+-define(wxStyledTextCtrl_WordStartPosition, 3181).
+-define(wxStyledTextCtrl_WordEndPosition, 3182).
+-define(wxStyledTextCtrl_SetWrapMode, 3183).
+-define(wxStyledTextCtrl_GetWrapMode, 3184).
+-define(wxStyledTextCtrl_SetWrapVisualFlags, 3185).
+-define(wxStyledTextCtrl_GetWrapVisualFlags, 3186).
+-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3187).
+-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3188).
+-define(wxStyledTextCtrl_SetWrapStartIndent, 3189).
+-define(wxStyledTextCtrl_GetWrapStartIndent, 3190).
+-define(wxStyledTextCtrl_SetLayoutCache, 3191).
+-define(wxStyledTextCtrl_GetLayoutCache, 3192).
+-define(wxStyledTextCtrl_SetScrollWidth, 3193).
+-define(wxStyledTextCtrl_GetScrollWidth, 3194).
+-define(wxStyledTextCtrl_TextWidth, 3195).
+-define(wxStyledTextCtrl_GetEndAtLastLine, 3196).
+-define(wxStyledTextCtrl_TextHeight, 3197).
+-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3198).
+-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3199).
+-define(wxStyledTextCtrl_AppendText, 3200).
+-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3201).
+-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3202).
+-define(wxStyledTextCtrl_TargetFromSelection, 3203).
+-define(wxStyledTextCtrl_LinesJoin, 3204).
+-define(wxStyledTextCtrl_LinesSplit, 3205).
+-define(wxStyledTextCtrl_SetFoldMarginColour, 3206).
+-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3207).
+-define(wxStyledTextCtrl_LineDown, 3208).
+-define(wxStyledTextCtrl_LineDownExtend, 3209).
+-define(wxStyledTextCtrl_LineUp, 3210).
+-define(wxStyledTextCtrl_LineUpExtend, 3211).
+-define(wxStyledTextCtrl_CharLeft, 3212).
+-define(wxStyledTextCtrl_CharLeftExtend, 3213).
+-define(wxStyledTextCtrl_CharRight, 3214).
+-define(wxStyledTextCtrl_CharRightExtend, 3215).
+-define(wxStyledTextCtrl_WordLeft, 3216).
+-define(wxStyledTextCtrl_WordLeftExtend, 3217).
+-define(wxStyledTextCtrl_WordRight, 3218).
+-define(wxStyledTextCtrl_WordRightExtend, 3219).
+-define(wxStyledTextCtrl_Home, 3220).
+-define(wxStyledTextCtrl_HomeExtend, 3221).
+-define(wxStyledTextCtrl_LineEnd, 3222).
+-define(wxStyledTextCtrl_LineEndExtend, 3223).
+-define(wxStyledTextCtrl_DocumentStart, 3224).
+-define(wxStyledTextCtrl_DocumentStartExtend, 3225).
+-define(wxStyledTextCtrl_DocumentEnd, 3226).
+-define(wxStyledTextCtrl_DocumentEndExtend, 3227).
+-define(wxStyledTextCtrl_PageUp, 3228).
+-define(wxStyledTextCtrl_PageUpExtend, 3229).
+-define(wxStyledTextCtrl_PageDown, 3230).
+-define(wxStyledTextCtrl_PageDownExtend, 3231).
+-define(wxStyledTextCtrl_EditToggleOvertype, 3232).
+-define(wxStyledTextCtrl_Cancel, 3233).
+-define(wxStyledTextCtrl_DeleteBack, 3234).
+-define(wxStyledTextCtrl_Tab, 3235).
+-define(wxStyledTextCtrl_BackTab, 3236).
+-define(wxStyledTextCtrl_NewLine, 3237).
+-define(wxStyledTextCtrl_FormFeed, 3238).
+-define(wxStyledTextCtrl_VCHome, 3239).
+-define(wxStyledTextCtrl_VCHomeExtend, 3240).
+-define(wxStyledTextCtrl_ZoomIn, 3241).
+-define(wxStyledTextCtrl_ZoomOut, 3242).
+-define(wxStyledTextCtrl_DelWordLeft, 3243).
+-define(wxStyledTextCtrl_DelWordRight, 3244).
+-define(wxStyledTextCtrl_LineCut, 3245).
+-define(wxStyledTextCtrl_LineDelete, 3246).
+-define(wxStyledTextCtrl_LineTranspose, 3247).
+-define(wxStyledTextCtrl_LineDuplicate, 3248).
+-define(wxStyledTextCtrl_LowerCase, 3249).
+-define(wxStyledTextCtrl_UpperCase, 3250).
+-define(wxStyledTextCtrl_LineScrollDown, 3251).
+-define(wxStyledTextCtrl_LineScrollUp, 3252).
+-define(wxStyledTextCtrl_DeleteBackNotLine, 3253).
+-define(wxStyledTextCtrl_HomeDisplay, 3254).
+-define(wxStyledTextCtrl_HomeDisplayExtend, 3255).
+-define(wxStyledTextCtrl_LineEndDisplay, 3256).
+-define(wxStyledTextCtrl_LineEndDisplayExtend, 3257).
+-define(wxStyledTextCtrl_HomeWrapExtend, 3258).
+-define(wxStyledTextCtrl_LineEndWrap, 3259).
+-define(wxStyledTextCtrl_LineEndWrapExtend, 3260).
+-define(wxStyledTextCtrl_VCHomeWrap, 3261).
+-define(wxStyledTextCtrl_VCHomeWrapExtend, 3262).
+-define(wxStyledTextCtrl_LineCopy, 3263).
+-define(wxStyledTextCtrl_MoveCaretInsideView, 3264).
+-define(wxStyledTextCtrl_LineLength, 3265).
+-define(wxStyledTextCtrl_BraceHighlight, 3266).
+-define(wxStyledTextCtrl_BraceBadLight, 3267).
+-define(wxStyledTextCtrl_BraceMatch, 3268).
+-define(wxStyledTextCtrl_GetViewEOL, 3269).
+-define(wxStyledTextCtrl_SetViewEOL, 3270).
+-define(wxStyledTextCtrl_SetModEventMask, 3271).
+-define(wxStyledTextCtrl_GetEdgeColumn, 3272).
+-define(wxStyledTextCtrl_SetEdgeColumn, 3273).
+-define(wxStyledTextCtrl_SetEdgeMode, 3274).
+-define(wxStyledTextCtrl_GetEdgeMode, 3275).
+-define(wxStyledTextCtrl_GetEdgeColour, 3276).
+-define(wxStyledTextCtrl_SetEdgeColour, 3277).
+-define(wxStyledTextCtrl_SearchAnchor, 3278).
+-define(wxStyledTextCtrl_SearchNext, 3279).
+-define(wxStyledTextCtrl_SearchPrev, 3280).
+-define(wxStyledTextCtrl_LinesOnScreen, 3281).
+-define(wxStyledTextCtrl_UsePopUp, 3282).
+-define(wxStyledTextCtrl_SelectionIsRectangle, 3283).
+-define(wxStyledTextCtrl_SetZoom, 3284).
+-define(wxStyledTextCtrl_GetZoom, 3285).
+-define(wxStyledTextCtrl_GetModEventMask, 3286).
+-define(wxStyledTextCtrl_SetSTCFocus, 3287).
+-define(wxStyledTextCtrl_GetSTCFocus, 3288).
+-define(wxStyledTextCtrl_SetStatus, 3289).
+-define(wxStyledTextCtrl_GetStatus, 3290).
+-define(wxStyledTextCtrl_SetMouseDownCaptures, 3291).
+-define(wxStyledTextCtrl_GetMouseDownCaptures, 3292).
+-define(wxStyledTextCtrl_SetSTCCursor, 3293).
+-define(wxStyledTextCtrl_GetSTCCursor, 3294).
+-define(wxStyledTextCtrl_SetControlCharSymbol, 3295).
+-define(wxStyledTextCtrl_GetControlCharSymbol, 3296).
+-define(wxStyledTextCtrl_WordPartLeft, 3297).
+-define(wxStyledTextCtrl_WordPartLeftExtend, 3298).
+-define(wxStyledTextCtrl_WordPartRight, 3299).
+-define(wxStyledTextCtrl_WordPartRightExtend, 3300).
+-define(wxStyledTextCtrl_SetVisiblePolicy, 3301).
+-define(wxStyledTextCtrl_DelLineLeft, 3302).
+-define(wxStyledTextCtrl_DelLineRight, 3303).
+-define(wxStyledTextCtrl_GetXOffset, 3304).
+-define(wxStyledTextCtrl_ChooseCaretX, 3305).
+-define(wxStyledTextCtrl_SetXCaretPolicy, 3306).
+-define(wxStyledTextCtrl_SetYCaretPolicy, 3307).
+-define(wxStyledTextCtrl_GetPrintWrapMode, 3308).
+-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3309).
+-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3310).
+-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3311).
+-define(wxStyledTextCtrl_SetHotspotSingleLine, 3312).
+-define(wxStyledTextCtrl_ParaDownExtend, 3313).
+-define(wxStyledTextCtrl_ParaUp, 3314).
+-define(wxStyledTextCtrl_ParaUpExtend, 3315).
+-define(wxStyledTextCtrl_PositionBefore, 3316).
+-define(wxStyledTextCtrl_PositionAfter, 3317).
+-define(wxStyledTextCtrl_CopyRange, 3318).
+-define(wxStyledTextCtrl_CopyText, 3319).
+-define(wxStyledTextCtrl_SetSelectionMode, 3320).
+-define(wxStyledTextCtrl_GetSelectionMode, 3321).
+-define(wxStyledTextCtrl_LineDownRectExtend, 3322).
+-define(wxStyledTextCtrl_LineUpRectExtend, 3323).
+-define(wxStyledTextCtrl_CharLeftRectExtend, 3324).
+-define(wxStyledTextCtrl_CharRightRectExtend, 3325).
+-define(wxStyledTextCtrl_HomeRectExtend, 3326).
+-define(wxStyledTextCtrl_VCHomeRectExtend, 3327).
+-define(wxStyledTextCtrl_LineEndRectExtend, 3328).
+-define(wxStyledTextCtrl_PageUpRectExtend, 3329).
+-define(wxStyledTextCtrl_PageDownRectExtend, 3330).
+-define(wxStyledTextCtrl_StutteredPageUp, 3331).
+-define(wxStyledTextCtrl_StutteredPageUpExtend, 3332).
+-define(wxStyledTextCtrl_StutteredPageDown, 3333).
+-define(wxStyledTextCtrl_StutteredPageDownExtend, 3334).
+-define(wxStyledTextCtrl_WordLeftEnd, 3335).
+-define(wxStyledTextCtrl_WordLeftEndExtend, 3336).
+-define(wxStyledTextCtrl_WordRightEnd, 3337).
+-define(wxStyledTextCtrl_WordRightEndExtend, 3338).
+-define(wxStyledTextCtrl_SetWhitespaceChars, 3339).
+-define(wxStyledTextCtrl_SetCharsDefault, 3340).
+-define(wxStyledTextCtrl_AutoCompGetCurrent, 3341).
+-define(wxStyledTextCtrl_Allocate, 3342).
+-define(wxStyledTextCtrl_FindColumn, 3343).
+-define(wxStyledTextCtrl_GetCaretSticky, 3344).
+-define(wxStyledTextCtrl_SetCaretSticky, 3345).
+-define(wxStyledTextCtrl_ToggleCaretSticky, 3346).
+-define(wxStyledTextCtrl_SetPasteConvertEndings, 3347).
+-define(wxStyledTextCtrl_GetPasteConvertEndings, 3348).
+-define(wxStyledTextCtrl_SelectionDuplicate, 3349).
+-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3350).
+-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3351).
+-define(wxStyledTextCtrl_StartRecord, 3352).
+-define(wxStyledTextCtrl_StopRecord, 3353).
+-define(wxStyledTextCtrl_SetLexer, 3354).
+-define(wxStyledTextCtrl_GetLexer, 3355).
+-define(wxStyledTextCtrl_Colourise, 3356).
+-define(wxStyledTextCtrl_SetProperty, 3357).
+-define(wxStyledTextCtrl_SetKeyWords, 3358).
+-define(wxStyledTextCtrl_SetLexerLanguage, 3359).
+-define(wxStyledTextCtrl_GetProperty, 3360).
+-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3361).
+-define(wxStyledTextCtrl_GetCurrentLine, 3362).
+-define(wxStyledTextCtrl_StyleSetSpec, 3363).
+-define(wxStyledTextCtrl_StyleSetFont, 3364).
+-define(wxStyledTextCtrl_StyleSetFontAttr, 3365).
+-define(wxStyledTextCtrl_StyleSetCharacterSet, 3366).
+-define(wxStyledTextCtrl_StyleSetFontEncoding, 3367).
+-define(wxStyledTextCtrl_CmdKeyExecute, 3368).
+-define(wxStyledTextCtrl_SetMargins, 3369).
+-define(wxStyledTextCtrl_GetSelection, 3370).
+-define(wxStyledTextCtrl_PointFromPosition, 3371).
+-define(wxStyledTextCtrl_ScrollToLine, 3372).
+-define(wxStyledTextCtrl_ScrollToColumn, 3373).
+-define(wxStyledTextCtrl_SetVScrollBar, 3374).
+-define(wxStyledTextCtrl_SetHScrollBar, 3375).
+-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3376).
+-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3377).
+-define(wxStyledTextCtrl_SaveFile, 3378).
+-define(wxStyledTextCtrl_LoadFile, 3379).
+-define(wxStyledTextCtrl_DoDragOver, 3380).
+-define(wxStyledTextCtrl_DoDropText, 3381).
+-define(wxStyledTextCtrl_GetUseAntiAliasing, 3382).
+-define(wxStyledTextCtrl_AddTextRaw, 3383).
+-define(wxStyledTextCtrl_InsertTextRaw, 3384).
+-define(wxStyledTextCtrl_GetCurLineRaw, 3385).
+-define(wxStyledTextCtrl_GetLineRaw, 3386).
+-define(wxStyledTextCtrl_GetSelectedTextRaw, 3387).
+-define(wxStyledTextCtrl_GetTextRangeRaw, 3388).
+-define(wxStyledTextCtrl_SetTextRaw, 3389).
+-define(wxStyledTextCtrl_GetTextRaw, 3390).
+-define(wxStyledTextCtrl_AppendTextRaw, 3391).
+-define(wxArtProvider_GetBitmap, 3392).
+-define(wxArtProvider_GetIcon, 3393).
+-define(wxTreeEvent_GetKeyCode, 3394).
+-define(wxTreeEvent_GetItem, 3395).
+-define(wxTreeEvent_GetKeyEvent, 3396).
+-define(wxTreeEvent_GetLabel, 3397).
+-define(wxTreeEvent_GetOldItem, 3398).
+-define(wxTreeEvent_GetPoint, 3399).
+-define(wxTreeEvent_IsEditCancelled, 3400).
+-define(wxTreeEvent_SetToolTip, 3401).
+-define(wxNotebookEvent_GetOldSelection, 3402).
+-define(wxNotebookEvent_GetSelection, 3403).
+-define(wxNotebookEvent_SetOldSelection, 3404).
+-define(wxNotebookEvent_SetSelection, 3405).
+-define(wxFileDataObject_new, 3406).
+-define(wxFileDataObject_AddFile, 3407).
+-define(wxFileDataObject_GetFilenames, 3408).
+-define(wxFileDataObject_destroy, 3409).
+-define(wxTextDataObject_new, 3410).
+-define(wxTextDataObject_GetTextLength, 3411).
+-define(wxTextDataObject_GetText, 3412).
+-define(wxTextDataObject_SetText, 3413).
+-define(wxTextDataObject_destroy, 3414).
+-define(wxBitmapDataObject_new_1_1, 3415).
+-define(wxBitmapDataObject_new_1_0, 3416).
+-define(wxBitmapDataObject_GetBitmap, 3417).
+-define(wxBitmapDataObject_SetBitmap, 3418).
+-define(wxBitmapDataObject_destroy, 3419).
+-define(wxClipboard_new, 3421).
+-define(wxClipboard_destruct, 3422).
+-define(wxClipboard_AddData, 3423).
+-define(wxClipboard_Clear, 3424).
+-define(wxClipboard_Close, 3425).
+-define(wxClipboard_Flush, 3426).
+-define(wxClipboard_GetData, 3427).
+-define(wxClipboard_IsOpened, 3428).
+-define(wxClipboard_Open, 3429).
+-define(wxClipboard_SetData, 3430).
+-define(wxClipboard_UsePrimarySelection, 3432).
+-define(wxClipboard_IsSupported, 3433).
+-define(wxClipboard_Get, 3434).
+-define(wxSpinEvent_GetPosition, 3435).
+-define(wxSpinEvent_SetPosition, 3436).
+-define(wxSplitterWindow_new_0, 3437).
+-define(wxSplitterWindow_new_2, 3438).
+-define(wxSplitterWindow_destruct, 3439).
+-define(wxSplitterWindow_Create, 3440).
+-define(wxSplitterWindow_GetMinimumPaneSize, 3441).
+-define(wxSplitterWindow_GetSashGravity, 3442).
+-define(wxSplitterWindow_GetSashPosition, 3443).
+-define(wxSplitterWindow_GetSplitMode, 3444).
+-define(wxSplitterWindow_GetWindow1, 3445).
+-define(wxSplitterWindow_GetWindow2, 3446).
+-define(wxSplitterWindow_Initialize, 3447).
+-define(wxSplitterWindow_IsSplit, 3448).
+-define(wxSplitterWindow_ReplaceWindow, 3449).
+-define(wxSplitterWindow_SetSashGravity, 3450).
+-define(wxSplitterWindow_SetSashPosition, 3451).
+-define(wxSplitterWindow_SetSashSize, 3452).
+-define(wxSplitterWindow_SetMinimumPaneSize, 3453).
+-define(wxSplitterWindow_SetSplitMode, 3454).
+-define(wxSplitterWindow_SplitHorizontally, 3455).
+-define(wxSplitterWindow_SplitVertically, 3456).
+-define(wxSplitterWindow_Unsplit, 3457).
+-define(wxSplitterWindow_UpdateSize, 3458).
+-define(wxSplitterEvent_GetSashPosition, 3459).
+-define(wxSplitterEvent_GetX, 3460).
+-define(wxSplitterEvent_GetY, 3461).
+-define(wxSplitterEvent_GetWindowBeingRemoved, 3462).
+-define(wxSplitterEvent_SetSashPosition, 3463).
+-define(wxHtmlWindow_new_0, 3464).
+-define(wxHtmlWindow_new_2, 3465).
+-define(wxHtmlWindow_AppendToPage, 3466).
+-define(wxHtmlWindow_GetOpenedAnchor, 3467).
+-define(wxHtmlWindow_GetOpenedPage, 3468).
+-define(wxHtmlWindow_GetOpenedPageTitle, 3469).
+-define(wxHtmlWindow_GetRelatedFrame, 3470).
+-define(wxHtmlWindow_HistoryBack, 3471).
+-define(wxHtmlWindow_HistoryCanBack, 3472).
+-define(wxHtmlWindow_HistoryCanForward, 3473).
+-define(wxHtmlWindow_HistoryClear, 3474).
+-define(wxHtmlWindow_HistoryForward, 3475).
+-define(wxHtmlWindow_LoadFile, 3476).
+-define(wxHtmlWindow_LoadPage, 3477).
+-define(wxHtmlWindow_SelectAll, 3478).
+-define(wxHtmlWindow_SelectionToText, 3479).
+-define(wxHtmlWindow_SelectLine, 3480).
+-define(wxHtmlWindow_SelectWord, 3481).
+-define(wxHtmlWindow_SetBorders, 3482).
+-define(wxHtmlWindow_SetFonts, 3483).
+-define(wxHtmlWindow_SetPage, 3484).
+-define(wxHtmlWindow_SetRelatedFrame, 3485).
+-define(wxHtmlWindow_SetRelatedStatusBar, 3486).
+-define(wxHtmlWindow_ToText, 3487).
+-define(wxHtmlWindow_destroy, 3488).
+-define(wxHtmlLinkEvent_GetLinkInfo, 3489).
+-define(wxSystemSettings_GetColour, 3490).
+-define(wxSystemSettings_GetFont, 3491).
+-define(wxSystemSettings_GetMetric, 3492).
+-define(wxSystemSettings_GetScreenType, 3493).
+-define(wxSystemOptions_GetOption, 3494).
+-define(wxSystemOptions_GetOptionInt, 3495).
+-define(wxSystemOptions_HasOption, 3496).
+-define(wxSystemOptions_IsFalse, 3497).
+-define(wxSystemOptions_SetOption_2_1, 3498).
+-define(wxSystemOptions_SetOption_2_0, 3499).
+-define(wxAuiNotebookEvent_SetSelection, 3500).
+-define(wxAuiNotebookEvent_GetSelection, 3501).
+-define(wxAuiNotebookEvent_SetOldSelection, 3502).
+-define(wxAuiNotebookEvent_GetOldSelection, 3503).
+-define(wxAuiNotebookEvent_SetDragSource, 3504).
+-define(wxAuiNotebookEvent_GetDragSource, 3505).
+-define(wxAuiManagerEvent_SetManager, 3506).
+-define(wxAuiManagerEvent_GetManager, 3507).
+-define(wxAuiManagerEvent_SetPane, 3508).
+-define(wxAuiManagerEvent_GetPane, 3509).
+-define(wxAuiManagerEvent_SetButton, 3510).
+-define(wxAuiManagerEvent_GetButton, 3511).
+-define(wxAuiManagerEvent_SetDC, 3512).
+-define(wxAuiManagerEvent_GetDC, 3513).
+-define(wxAuiManagerEvent_Veto, 3514).
+-define(wxAuiManagerEvent_GetVeto, 3515).
+-define(wxAuiManagerEvent_SetCanVeto, 3516).
+-define(wxAuiManagerEvent_CanVeto, 3517).
+-define(wxLogNull_new, 3518).
+-define(wxLogNull_destroy, 3519).
+-define(wxTaskBarIcon_new, 3520).
+-define(wxTaskBarIcon_destruct, 3521).
+-define(wxTaskBarIcon_PopupMenu, 3522).
+-define(wxTaskBarIcon_RemoveIcon, 3523).
+-define(wxTaskBarIcon_SetIcon, 3524).
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index 22bfa53e0a..4186d73c88 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-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
@@ -130,11 +130,19 @@ treeCtrl(Config) ->
wxWindow:setSizerAndFit(Panel, Sizer),
wxFrame:show(Frame),
+ ok = wxTreeCtrl:expand(Tree, Root),
?m([], wxTreeCtrl:getItemData(Tree, Root)),
?m({data,item1}, wxTreeCtrl:getItemData(Tree, Item1)),
?m({data,item2}, wxTreeCtrl:getItemData(Tree, Item2)),
?m({data,item3}, wxTreeCtrl:getItemData(Tree, Item3)),
+ {true, {X0,Y0,W0,H0}} = ?m({_,_},wxTreeCtrl:getBoundingRect(Tree, Item1, [{textOnly, true}])),
+ ?m({true, {_,Y1,_,_}} when Y1 > Y0, wxTreeCtrl:getBoundingRect(Tree, Item2)),
+ ?m({Item1, _}, wxTreeCtrl:hitTest(Tree, {X0+W0 div 2, Y0+H0 div 2})),
+ ?m(true, wxTreeCtrl:isTreeItemIdOk(Item1)),
+ ?m({0, _}, wxTreeCtrl:hitTest(Tree, {X0+W0 div 2, Y0+H0+H0})),
+ ?m(false, wxTreeCtrl:isTreeItemIdOk(0)),
+
wxFrame:connect(Tree, command_tree_item_expanded),
wxFrame:connect(Tree, command_tree_item_collapsed),
wxFrame:connect(Frame, close_window),
diff --git a/lib/xmerl/src/Makefile b/lib/xmerl/src/Makefile
index ce1aa11fba..d5ce3fe6ff 100644
--- a/lib/xmerl/src/Makefile
+++ b/lib/xmerl/src/Makefile
@@ -166,34 +166,34 @@ EDOC_PATHS = \
-pa $(EDOC_APP)/ebin -pa $(XMERL_APP)/ebin -pa $(SYNTAX_TOOLS_APP)/ebin
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
xmerl_xpath_parse.erl: xmerl_xpath_parse.yrl
- $(ERLC) -o $(ESRC) $<
+ $(yecc_verbose)$(ERLC) -o $(ESRC) $<
xmerl_b64Bin.erl: xmerl_b64Bin.yrl
- $(ERLC) -o $(ESRC) $<
+ $(yecc_verbose)$(ERLC) -o $(ESRC) $<
xmerl_sax_parser_list.erl: xmerl_sax_parser_list.erlsrc xmerl_sax_parser_base.erlsrc
- cat xmerl_sax_parser_list.erlsrc xmerl_sax_parser_base.erlsrc >$@
+ $(gen_verbose)cat xmerl_sax_parser_list.erlsrc xmerl_sax_parser_base.erlsrc >$@
xmerl_sax_parser_latin1.erl: xmerl_sax_parser_latin1.erlsrc xmerl_sax_parser_base.erlsrc
- cat xmerl_sax_parser_latin1.erlsrc xmerl_sax_parser_base.erlsrc >$@
+ $(gen_verbose)cat xmerl_sax_parser_latin1.erlsrc xmerl_sax_parser_base.erlsrc >$@
xmerl_sax_parser_utf8.erl: xmerl_sax_parser_utf8.erlsrc xmerl_sax_parser_base.erlsrc
- cat xmerl_sax_parser_utf8.erlsrc xmerl_sax_parser_base.erlsrc >$@
+ $(gen_verbose)cat xmerl_sax_parser_utf8.erlsrc xmerl_sax_parser_base.erlsrc >$@
xmerl_sax_parser_utf16be.erl: xmerl_sax_parser_utf16be.erlsrc xmerl_sax_parser_base.erlsrc
- cat xmerl_sax_parser_utf16be.erlsrc xmerl_sax_parser_base.erlsrc >$@
+ $(gen_verbose)cat xmerl_sax_parser_utf16be.erlsrc xmerl_sax_parser_base.erlsrc >$@
xmerl_sax_parser_utf16le.erl: xmerl_sax_parser_utf16le.erlsrc xmerl_sax_parser_base.erlsrc
- cat xmerl_sax_parser_utf16le.erlsrc xmerl_sax_parser_base.erlsrc >$@
+ $(gen_verbose)cat xmerl_sax_parser_utf16le.erlsrc xmerl_sax_parser_base.erlsrc >$@
$(EBIN)/%.beam: %.erl
- $(ERLC) $(ERL_COMPILE_FLAGS) -o $(EBIN) $<
+ $(V_ERLC) $(ERL_COMPILE_FLAGS) -o $(EBIN) $<
$(DOCDIR)/%.html: %.erl
$(ERL) -noshell $(EDOC_PATHS) \