aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HOWTO/INSTALL-CROSS.md2
-rw-r--r--HOWTO/INSTALL.md69
-rw-r--r--HOWTO/MARKDOWN.md2
-rw-r--r--aclocal.m42
-rw-r--r--bootstrap/bin/start.bootbin5242 -> 5242 bytes
-rw-r--r--bootstrap/bin/start_clean.bootbin5242 -> 5242 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_block.beambin14340 -> 14424 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bool.beambin16256 -> 16480 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dead.beambin10176 -> 10212 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dict.beambin5740 -> 5360 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_jump.beambin8408 -> 8524 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin13108 -> 13220 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_validator.beambin34356 -> 34356 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin35644 -> 37560 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app2
-rw-r--r--bootstrap/lib/compiler/ebin/core_lib.beambin5344 -> 5460 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_parse.beambin37688 -> 37664 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin10896 -> 12064 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold.beambin46668 -> 47060 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_inline.beambin4168 -> 4208 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin50652 -> 51060 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin43392 -> 43196 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel_pp.beambin10596 -> 11780 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_controller.beambin30848 -> 31208 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/auth.beambin6472 -> 6472 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin6916 -> 6916 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin26148 -> 26188 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin37096 -> 37112 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin24908 -> 24908 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin10512 -> 10512 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin14608 -> 14624 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin32136 -> 32324 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin11720 -> 13532 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp_dist.beambin6208 -> 6248 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_config.beambin7468 -> 7736 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin25956 -> 26408 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin12776 -> 12936 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp_dist.beambin6496 -> 6532 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app2
-rw-r--r--bootstrap/lib/kernel/ebin/kernel_config.beambin2708 -> 2708 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin22712 -> 22764 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/os.beambin5276 -> 5276 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user.beambin12384 -> 11572 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_drv.beambin10308 -> 10308 bytes
-rw-r--r--bootstrap/lib/kernel/include/dist.hrl3
-rw-r--r--bootstrap/lib/kernel/include/file.hrl59
-rw-r--r--bootstrap/lib/stdlib/ebin/beam_lib.beambin18044 -> 18052 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin13904 -> 14028 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin53412 -> 53452 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_utils.beambin28736 -> 28824 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin50008 -> 50008 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6348 -> 6796 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin.beambin7912 -> 9260 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin27204 -> 27480 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_compile.beambin4876 -> 4880 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_internal.beambin5016 -> 5036 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin82112 -> 82492 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin69912 -> 69016 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin23800 -> 24488 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin31120 -> 33168 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_tar.beambin15228 -> 15336 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/escript.beambin17264 -> 17268 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin21660 -> 21692 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin17520 -> 17560 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_fsm.beambin15136 -> 15360 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin16896 -> 17264 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib.beambin9200 -> 9332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_pretty.beambin13212 -> 13228 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin9624 -> 9620 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lists.beambin29524 -> 29556 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ms_transform.beambin20068 -> 20068 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pool.beambin3816 -> 3848 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proc_lib.beambin9776 -> 9968 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin69144 -> 69148 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin70944 -> 71084 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/queue.beambin5900 -> 6184 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin30320 -> 29700 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin40500 -> 40756 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin7292 -> 7332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/unicode.beambin10928 -> 11584 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/zip.beambin25212 -> 26752 bytes
-rw-r--r--erts/aclocal.m42
-rw-r--r--erts/configure.in8
-rw-r--r--erts/doc/src/absform.xml9
-rw-r--r--erts/doc/src/erl.xml37
-rw-r--r--erts/doc/src/erl_dist_protocol.xml290
-rw-r--r--erts/doc/src/erl_driver.xml6
-rw-r--r--erts/doc/src/erl_ext_dist.xml123
-rw-r--r--erts/doc/src/erlang.xml59
-rw-r--r--erts/doc/src/erts_alloc.xml2
-rw-r--r--erts/doc/src/notes.xml2
-rw-r--r--erts/doc/src/part.xml2
-rw-r--r--erts/doc/src/ref_man.xml2
-rw-r--r--erts/emulator/beam/atom.c171
-rw-r--r--erts/emulator/beam/atom.h64
-rw-r--r--erts/emulator/beam/atom.names7
-rw-r--r--erts/emulator/beam/beam_bif_load.c8
-rw-r--r--erts/emulator/beam/beam_bp.c2
-rw-r--r--erts/emulator/beam/beam_bp.h2
-rw-r--r--erts/emulator/beam/beam_catches.c2
-rw-r--r--erts/emulator/beam/beam_catches.h2
-rw-r--r--erts/emulator/beam/beam_debug.c2
-rw-r--r--erts/emulator/beam/beam_load.c10
-rw-r--r--erts/emulator/beam/beam_load.h2
-rw-r--r--erts/emulator/beam/bif.c111
-rw-r--r--erts/emulator/beam/bif.h4
-rw-r--r--erts/emulator/beam/bif.tab3
-rw-r--r--erts/emulator/beam/binary.c2
-rw-r--r--erts/emulator/beam/code_ix.h5
-rw-r--r--erts/emulator/beam/dist.c16
-rw-r--r--erts/emulator/beam/dist.h5
-rw-r--r--erts/emulator/beam/erl_afit_alloc.c2
-rw-r--r--erts/emulator/beam/erl_afit_alloc.h2
-rw-r--r--erts/emulator/beam/erl_alloc.c8
-rw-r--r--erts/emulator/beam/erl_alloc.types4
-rw-r--r--erts/emulator/beam/erl_alloc_util.c6
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.c2
-rw-r--r--erts/emulator/beam/erl_bestfit_alloc.c2
-rw-r--r--erts/emulator/beam/erl_bif_binary.c2
-rw-r--r--erts/emulator/beam/erl_bif_chksum.c2
-rw-r--r--erts/emulator/beam/erl_bif_ddll.c7
-rwxr-xr-xerts/emulator/beam/erl_bif_info.c28
-rw-r--r--erts/emulator/beam/erl_bif_op.c2
-rw-r--r--erts/emulator/beam/erl_bif_port.c4
-rw-r--r--erts/emulator/beam/erl_bif_re.c5
-rw-r--r--erts/emulator/beam/erl_bif_trace.c2
-rw-r--r--erts/emulator/beam/erl_cpu_topology.c40
-rw-r--r--erts/emulator/beam/erl_cpu_topology.h4
-rw-r--r--erts/emulator/beam/erl_db.c4
-rw-r--r--erts/emulator/beam/erl_db.h2
-rw-r--r--erts/emulator/beam/erl_db_hash.h2
-rw-r--r--erts/emulator/beam/erl_db_tree.c2
-rw-r--r--erts/emulator/beam/erl_db_util.c5
-rw-r--r--erts/emulator/beam/erl_db_util.h2
-rw-r--r--erts/emulator/beam/erl_driver.h2
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.c2
-rw-r--r--erts/emulator/beam/erl_init.c30
-rw-r--r--erts/emulator/beam/erl_instrument.c4
-rw-r--r--erts/emulator/beam/erl_monitors.c2
-rw-r--r--erts/emulator/beam/erl_monitors.h2
-rw-r--r--erts/emulator/beam/erl_mtrace.c2
-rw-r--r--erts/emulator/beam/erl_nif.c34
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h2
-rw-r--r--erts/emulator/beam/erl_node_container_utils.h2
-rw-r--r--erts/emulator/beam/erl_port.h39
-rw-r--r--erts/emulator/beam/erl_port_task.c28
-rw-r--r--erts/emulator/beam/erl_process.c39
-rw-r--r--erts/emulator/beam/erl_process_dict.c2
-rw-r--r--erts/emulator/beam/erl_process_dump.c2
-rw-r--r--erts/emulator/beam/erl_sys_driver.h2
-rw-r--r--erts/emulator/beam/erl_term.c2
-rw-r--r--erts/emulator/beam/erl_term.h2
-rw-r--r--erts/emulator/beam/erl_unicode.c230
-rw-r--r--erts/emulator/beam/export.c9
-rw-r--r--erts/emulator/beam/export.h2
-rw-r--r--erts/emulator/beam/external.c296
-rw-r--r--erts/emulator/beam/external.h9
-rwxr-xr-xerts/emulator/beam/global.h9
-rw-r--r--erts/emulator/beam/index.h2
-rw-r--r--erts/emulator/beam/io.c68
-rw-r--r--erts/emulator/beam/module.c2
-rw-r--r--erts/emulator/beam/module.h2
-rw-r--r--erts/emulator/beam/packet_parser.c6
-rw-r--r--erts/emulator/beam/register.c2
-rw-r--r--erts/emulator/beam/sys.h5
-rw-r--r--erts/emulator/beam/time.c26
-rw-r--r--erts/emulator/beam/utils.c4
-rw-r--r--erts/emulator/drivers/common/efile_drv.c95
-rw-r--r--erts/emulator/drivers/common/gzio.c5
-rw-r--r--erts/emulator/drivers/common/inet_drv.c66
-rw-r--r--erts/emulator/drivers/unix/ttsl_drv.c2
-rw-r--r--erts/emulator/drivers/win32/registry_drv.c2
-rw-r--r--erts/emulator/drivers/win32/win_efile.c10
-rw-r--r--erts/emulator/hipe/hipe_debug.c2
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c2
-rw-r--r--erts/emulator/hipe/hipe_x86.c2
-rw-r--r--erts/emulator/hipe/hipe_x86_gc.h4
-rw-r--r--erts/emulator/sys/common/erl_mseg.c2
-rw-r--r--erts/emulator/sys/common/erl_mseg.h2
-rw-r--r--erts/emulator/sys/common/erl_poll.h2
-rw-r--r--erts/emulator/sys/common/erl_sys_common_misc.c153
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys_ddll.c2
-rw-r--r--erts/emulator/sys/unix/sys_float.c11
-rw-r--r--erts/emulator/sys/win32/erl_win32_sys_ddll.c2
-rw-r--r--erts/emulator/sys/win32/erl_win_dyn_driver.h2
-rw-r--r--erts/emulator/sys/win32/sys_float.c11
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.c10
-rw-r--r--erts/emulator/test/beam_SUITE.erl2
-rw-r--r--erts/emulator/test/bif_SUITE.erl4
-rw-r--r--erts/emulator/test/busy_port_SUITE.erl306
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/Makefile.src5
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c6
-rw-r--r--erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c190
-rw-r--r--erts/emulator/test/ddll_SUITE.erl2
-rw-r--r--erts/emulator/test/distribution_SUITE.erl327
-rw-r--r--erts/emulator/test/driver_SUITE.erl2
-rw-r--r--erts/emulator/test/driver_SUITE_data/async_blast_drv.c10
-rw-r--r--erts/emulator/test/driver_SUITE_data/caller_drv.c4
-rw-r--r--erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c2
-rw-r--r--erts/emulator/test/driver_SUITE_data/monitor_drv.c2
-rw-r--r--erts/emulator/test/driver_SUITE_data/otp_9302_drv.c6
-rw-r--r--erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c11
-rw-r--r--erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c4
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c10
-rw-r--r--erts/emulator/test/estone_SUITE.erl2
-rw-r--r--erts/emulator/test/gc_SUITE.erl2
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl2
-rw-r--r--erts/emulator/test/mtx_SUITE.erl8
-rw-r--r--erts/emulator/test/mtx_SUITE_data/Makefile.src2
-rw-r--r--erts/emulator/test/nofrag_SUITE.erl2
-rw-r--r--erts/emulator/test/num_bif_SUITE.erl47
-rw-r--r--erts/emulator/test/port_SUITE_data/dead_port.c2
-rw-r--r--erts/emulator/test/process_SUITE.erl2
-rw-r--r--erts/emulator/test/save_calls_SUITE.erl2
-rw-r--r--erts/emulator/test/send_term_SUITE_data/send_term_drv.c8
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl2
-rw-r--r--erts/emulator/test/trace_local_SUITE.erl4
-rw-r--r--erts/emulator/test/tuple_SUITE.erl2
-rwxr-xr-xerts/emulator/utils/make_tables2
-rw-r--r--erts/epmd/src/epmd.c2
-rw-r--r--erts/epmd/src/epmd_cli.c15
-rw-r--r--erts/epmd/src/epmd_int.h22
-rw-r--r--erts/epmd/src/epmd_srv.c217
-rw-r--r--erts/epmd/test/epmd_SUITE.erl49
-rw-r--r--erts/etc/common/erlexec.c11
-rw-r--r--erts/etc/common/escript.c2
-rw-r--r--erts/etc/common/inet_gethost.c9
-rwxr-xr-xerts/etc/win32/nsis/dll_version_helper.sh2
-rw-r--r--erts/lib_src/Makefile.in4
-rw-r--r--erts/lib_src/common/erl_misc_utils.c2
-rw-r--r--erts/lib_src/common/erl_printf_format.c2
-rw-r--r--erts/lib_src/common/ethr_mutex.c8
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin54136 -> 54120 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin92756 -> 92996 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin3616 -> 3616 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin48556 -> 48568 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1448 -> 1448 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin41176 -> 41128 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin70016 -> 70012 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin23408 -> 23408 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin12784 -> 12784 bytes
-rw-r--r--erts/preloaded/src/erlang.erl17
-rw-r--r--erts/preloaded/src/init.erl16
-rw-r--r--erts/preloaded/src/prim_file.erl7
-rw-r--r--erts/vsn.mk4
-rw-r--r--lib/appmon/src/Makefile2
-rw-r--r--lib/asn1/c_src/asn1_erl_nif.c56
-rw-r--r--lib/asn1/doc/src/asn1_ug.xml122
-rw-r--r--lib/asn1/doc/src/asn1ct.xml57
-rw-r--r--lib/asn1/doc/src/asn1rt.xml2
-rw-r--r--lib/asn1/src/.gitignore2
-rw-r--r--lib/asn1/src/Makefile63
-rw-r--r--lib/asn1/src/asn1.app.src5
-rw-r--r--lib/asn1/src/asn1_records.hrl8
-rw-r--r--lib/asn1/src/asn1ct.erl152
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl98
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl133
-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.erl145
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl394
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl394
-rw-r--r--lib/asn1/src/asn1ct_gen_per_rt2ct.erl316
-rw-r--r--lib/asn1/src/asn1ct_imm.erl162
-rw-r--r--lib/asn1/src/asn1ct_value.erl47
-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.erl27
-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.erl80
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn2
-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.erl4
-rw-r--r--lib/asn1/test/asn1_SUITE_data/testobj.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/asn1_wrapper.erl2
-rw-r--r--lib/asn1/test/ber_decode_error.erl45
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl54
-rw-r--r--lib/asn1/test/testDoubleEllipses.erl10
-rw-r--r--lib/asn1/test/testNBAPsystem.erl5
-rw-r--r--lib/asn1/test/testParamBasic.erl10
-rw-r--r--lib/asn1/test/testPrimStrings.erl293
-rw-r--r--lib/asn1/test/testSSLspecs.erl23
-rw-r--r--lib/asn1/test/testSeqSetDefaultVal.erl6
-rw-r--r--lib/asn1/test/testTypeValueNotation.erl4
-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/ct_run.xml1
-rw-r--r--lib/common_test/doc/src/notes.xml2
-rw-r--r--lib/common_test/doc/src/run_test_chapter.xml817
-rw-r--r--lib/common_test/src/Makefile4
-rw-r--r--lib/common_test/src/ct.erl8
-rw-r--r--lib/common_test/src/ct_config.erl13
-rw-r--r--lib/common_test/src/ct_config_plain.erl4
-rw-r--r--lib/common_test/src/ct_conn_log_h.erl33
-rw-r--r--lib/common_test/src/ct_event.erl4
-rw-r--r--lib/common_test/src/ct_framework.erl27
-rw-r--r--lib/common_test/src/ct_gen_conn.erl4
-rw-r--r--lib/common_test/src/ct_groups.erl4
-rw-r--r--lib/common_test/src/ct_hooks.erl6
-rw-r--r--lib/common_test/src/ct_logs.erl145
-rw-r--r--lib/common_test/src/ct_make.erl8
-rw-r--r--lib/common_test/src/ct_master.erl183
-rw-r--r--lib/common_test/src/ct_master_event.erl6
-rw-r--r--lib/common_test/src/ct_master_logs.erl24
-rw-r--r--lib/common_test/src/ct_master_status.erl4
-rw-r--r--lib/common_test/src/ct_netconfc.erl40
-rw-r--r--lib/common_test/src/ct_run.erl552
-rw-r--r--lib/common_test/src/ct_telnet.erl32
-rw-r--r--lib/common_test/src/ct_telnet_client.erl4
-rw-r--r--lib/common_test/src/ct_testspec.erl369
-rw-r--r--lib/common_test/src/ct_util.erl10
-rw-r--r--lib/common_test/src/cth_conn_log.erl7
-rw-r--r--lib/common_test/src/cth_surefire.erl4
-rw-r--r--lib/common_test/src/unix_telnet.erl4
-rw-r--r--lib/common_test/test/Makefile1
-rw-r--r--lib/common_test/test/ct_error_SUITE.erl65
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl175
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl239
-rw-r--r--lib/common_test/test/ct_hooks_SUITE.erl2
-rw-r--r--lib/common_test/test/ct_master_SUITE.erl17
-rw-r--r--lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl2
-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_netconfc_SUITE_data/ns.erl21
-rw-r--r--lib/common_test/test/ct_surefire_SUITE.erl77
-rw-r--r--lib/common_test/test/ct_test_support.erl8
-rw-r--r--lib/common_test/test/ct_testspec_2_SUITE.erl41
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE.erl745
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg111
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg121
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg131
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/config2/cfg211
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/flat_spec14
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join12
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join_sep15
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep12
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep_join12
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both12
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both_join16
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_join11
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_sep13
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/flat_spec25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join_sep25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep_join25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both24
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both_join29
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_join25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_sep25
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl175
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl175
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl174
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl177
-rw-r--r--lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl158
-rw-r--r--lib/compiler/src/Makefile4
-rw-r--r--lib/compiler/src/beam_block.erl2
-rw-r--r--lib/compiler/src/beam_bool.erl2
-rw-r--r--lib/compiler/src/beam_bsm.erl2
-rw-r--r--lib/compiler/src/beam_clean.erl2
-rw-r--r--lib/compiler/src/beam_dead.erl2
-rw-r--r--lib/compiler/src/beam_dict.erl20
-rw-r--r--lib/compiler/src/beam_except.erl2
-rw-r--r--lib/compiler/src/beam_flatten.erl2
-rw-r--r--lib/compiler/src/beam_jump.erl2
-rw-r--r--lib/compiler/src/beam_peep.erl2
-rw-r--r--lib/compiler/src/beam_receive.erl2
-rw-r--r--lib/compiler/src/beam_trim.erl2
-rw-r--r--lib/compiler/src/beam_validator.erl4
-rw-r--r--lib/compiler/src/compile.erl42
-rw-r--r--lib/compiler/src/compiler.app.src2
-rw-r--r--lib/compiler/src/core_lint.erl2
-rw-r--r--lib/compiler/src/sys_core_fold.erl39
-rw-r--r--lib/compiler/src/v3_kernel.erl33
-rw-r--r--lib/compiler/test/andor_SUITE.erl2
-rw-r--r--lib/compiler/test/beam_except_SUITE.erl2
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl2
-rw-r--r--lib/compiler/test/bs_bit_binaries_SUITE.erl2
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl50
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl2
-rw-r--r--lib/compiler/test/guard_SUITE.erl2
-rw-r--r--lib/compiler/test/inline_SUITE.erl2
-rw-r--r--lib/compiler/test/match_SUITE.erl2
-rw-r--r--lib/compiler/test/receive_SUITE.erl2
-rw-r--r--lib/compiler/test/record_SUITE.erl2
-rw-r--r--lib/compiler/test/test_lib.erl2
-rw-r--r--lib/compiler/test/warnings_SUITE.erl2
-rw-r--r--lib/cosFileTransfer/test/fileTransfer_SUITE.erl2
-rwxr-xr-xlib/crypto/doc/src/crypto.xml2
-rw-r--r--lib/crypto/doc/src/crypto_app.xml2
-rw-r--r--lib/crypto/src/Makefile4
-rw-r--r--lib/crypto/src/crypto.erl2
-rw-r--r--lib/crypto/test/crypto_SUITE.erl2
-rw-r--r--lib/debugger/src/Makefile4
-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_settings.erl2
-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/debugger/test/erl_eval_SUITE.erl2
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl2
-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/diameter.xml68
-rw-r--r--lib/diameter/doc/src/diameter_tcp.xml7
-rw-r--r--lib/diameter/doc/src/notes.xml2
-rw-r--r--lib/diameter/doc/src/seealso.ent1
-rw-r--r--lib/diameter/src/Makefile12
-rw-r--r--lib/diameter/src/base/diameter.app.src4
-rw-r--r--lib/diameter/src/base/diameter.appup.src6
-rw-r--r--lib/diameter/src/base/diameter_peer.erl13
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl47
-rw-r--r--lib/diameter/src/base/diameter_service.erl80
-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/vsn.mk7
-rw-r--r--lib/eldap/doc/src/eldap.xml4
-rw-r--r--lib/eldap/src/Makefile4
-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.xsl14
-rw-r--r--lib/erl_docgen/vsn.mk3
-rw-r--r--lib/erl_interface/aclocal.m42
-rw-r--r--lib/erl_interface/doc/src/ei.xml66
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml20
-rw-r--r--lib/erl_interface/include/ei.h42
-rw-r--r--lib/erl_interface/include/erl_interface.h42
-rw-r--r--lib/erl_interface/src/Makefile2
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c9
-rw-r--r--lib/erl_interface/src/connect/ei_connect_int.h4
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.c2
-rw-r--r--lib/erl_interface/src/connect/eirecv.c14
-rw-r--r--lib/erl_interface/src/decode/decode_atom.c161
-rw-r--r--lib/erl_interface/src/decode/decode_boolean.c38
-rw-r--r--lib/erl_interface/src/decode/decode_fun.c8
-rw-r--r--lib/erl_interface/src/decode/decode_pid.c16
-rw-r--r--lib/erl_interface/src/decode/decode_port.c15
-rw-r--r--lib/erl_interface/src/decode/decode_ref.c30
-rw-r--r--lib/erl_interface/src/encode/encode_atom.c157
-rw-r--r--lib/erl_interface/src/encode/encode_fun.c6
-rw-r--r--lib/erl_interface/src/encode/encode_pid.c26
-rw-r--r--lib/erl_interface/src/encode/encode_port.c25
-rw-r--r--lib/erl_interface/src/encode/encode_ref.c26
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c20
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.c160
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.h6
-rw-r--r--lib/erl_interface/src/legacy/erl_format.c22
-rw-r--r--lib/erl_interface/src/legacy/erl_malloc.c22
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c415
-rw-r--r--lib/erl_interface/src/legacy/global_whereis.c13
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.c42
-rw-r--r--lib/erl_interface/src/misc/ei_format.c6
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c9
-rw-r--r--lib/erl_interface/src/misc/ei_x_encode.c72
-rw-r--r--lib/erl_interface/src/misc/get_type.c81
-rw-r--r--lib/erl_interface/src/misc/putget.h9
-rw-r--r--lib/erl_interface/src/misc/show_msg.c16
-rw-r--r--lib/erl_interface/src/prog/ei_fake_prog.c8
-rw-r--r--lib/erl_interface/test/all_SUITE_data/init_tc.erl2
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl78
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c154
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE.erl123
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c398
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl39
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c244
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl5
-rw-r--r--lib/hipe/cerl/erl_types.erl40
-rw-r--r--lib/ic/c_src/ic.c1
-rw-r--r--lib/ic/examples/all-against-all/client.c3
-rw-r--r--lib/ic/examples/c-client/client.c3
-rw-r--r--lib/ic/examples/c-server/client.c3
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Any.java2
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Environment.java4
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/Term.java5
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java2
-rw-r--r--lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java7
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_client.c8
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c8
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c8
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c5
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c5
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src12
-rw-r--r--lib/inets/src/http_client/httpc_response.erl7
-rw-r--r--lib/inets/src/inets_app/inets.appup.src111
-rw-r--r--lib/inets/test/erl_make_certs.erl2
-rw-r--r--lib/inets/test/ftp_suite_lib.erl2
-rw-r--r--lib/inets/test/httpc_SUITE.erl36
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl2
-rw-r--r--lib/inets/test/inets_SUITE.erl2
-rw-r--r--lib/inets/test/inets_appup_test.erl15
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl2
-rw-r--r--lib/inets/vsn.mk4
-rw-r--r--lib/jinterface/java_src/Makefile2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java6
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java8
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java66
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java62
-rw-r--r--lib/jinterface/test/nc_SUITE.erl148
-rw-r--r--lib/kernel/doc/src/application.xml2
-rw-r--r--lib/kernel/doc/src/error_handler.xml15
-rw-r--r--lib/kernel/doc/src/file.xml53
-rw-r--r--lib/kernel/doc/src/global.xml2
-rw-r--r--lib/kernel/doc/src/inet.xml2
-rw-r--r--lib/kernel/doc/src/ref_man.xml2
-rw-r--r--lib/kernel/include/dist.hrl3
-rw-r--r--lib/kernel/include/file.hrl59
-rw-r--r--lib/kernel/internal_doc/distribution_handshake.txt216
-rw-r--r--lib/kernel/src/Makefile4
-rw-r--r--lib/kernel/src/application.erl2
-rw-r--r--lib/kernel/src/application_controller.erl71
-rw-r--r--lib/kernel/src/auth.erl4
-rw-r--r--lib/kernel/src/code.erl6
-rw-r--r--lib/kernel/src/code_server.erl6
-rw-r--r--lib/kernel/src/disk_log.erl48
-rw-r--r--lib/kernel/src/disk_log_1.erl8
-rw-r--r--lib/kernel/src/dist_util.erl5
-rw-r--r--lib/kernel/src/error_handler.erl2
-rw-r--r--lib/kernel/src/file.erl8
-rw-r--r--lib/kernel/src/group.erl147
-rw-r--r--lib/kernel/src/inet_config.erl37
-rw-r--r--lib/kernel/src/inet_parse.erl4
-rw-r--r--lib/kernel/src/kernel.app.src2
-rw-r--r--lib/kernel/src/kernel_config.erl4
-rw-r--r--lib/kernel/src/net_kernel.erl10
-rw-r--r--lib/kernel/src/os.erl4
-rw-r--r--lib/kernel/src/user.erl172
-rw-r--r--lib/kernel/src/user_drv.erl4
-rw-r--r--lib/kernel/test/Makefile2
-rw-r--r--lib/kernel/test/application_SUITE.erl2
-rw-r--r--lib/kernel/test/file_SUITE.erl61
-rw-r--r--lib/kernel/test/gen_tcp_echo_SUITE.erl2
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl82
-rw-r--r--lib/kernel/test/ignore_cores.erl2
-rw-r--r--lib/kernel/test/inet_SUITE.erl2
-rw-r--r--lib/kernel/test/os_SUITE.erl2
-rw-r--r--lib/kernel/test/pdict_SUITE.erl2
-rw-r--r--lib/megaco/aclocal.m42
-rw-r--r--lib/megaco/configure.in2
-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/doc/src/megaco_encode.xml2
-rw-r--r--lib/megaco/examples/meas/megaco_codec_meas.erl2
-rw-r--r--lib/megaco/examples/meas/megaco_codec_transform.erl2
-rw-r--r--lib/megaco/src/app/megaco.app.src2
-rw-r--r--lib/megaco/src/binary/depend.mk2
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder.erl2
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder_lib.erl2
-rw-r--r--lib/megaco/src/binary/modules.mk2
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src12
-rw-r--r--lib/megaco/src/rules.mk2
-rw-r--r--lib/megaco/test/megaco_actions_test.erl2
-rw-r--r--lib/megaco/test/megaco_call_flow_test.erl2
-rw-r--r--lib/megaco/test/megaco_mib_test.erl2
-rw-r--r--lib/megaco/test/megaco_test_mg.erl2
-rw-r--r--lib/megaco/test/megaco_test_mgc.erl2
-rw-r--r--lib/mnesia/examples/mnesia_tpcb.erl2
-rw-r--r--lib/mnesia/include/mnemosyne.hrl18
-rw-r--r--lib/mnesia/src/Makefile7
-rw-r--r--lib/mnesia/src/mnesia.erl4
-rw-r--r--lib/mnesia/src/mnesia_controller.erl2
-rw-r--r--lib/mnesia/src/mnesia_event.erl2
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl6
-rw-r--r--lib/mnesia/src/mnesia_recover.erl2
-rw-r--r--lib/mnesia/src/mnesia_sup.erl15
-rw-r--r--lib/mnesia/src/mnesia_tm.erl2
-rw-r--r--lib/mnesia/test/mnesia.spec3
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl3
-rw-r--r--lib/mnesia/test/mnesia_config_test.erl44
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl5
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl2
-rw-r--r--lib/observer/src/Makefile5
-rw-r--r--lib/odbc/aclocal.m42
-rw-r--r--lib/odbc/c_src/odbcserver.c52
-rw-r--r--lib/odbc/c_src/odbcserver.h2
-rw-r--r--lib/odbc/configure.in2
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl2
-rw-r--r--lib/orber/src/orber_ifr_exceptiondef.erl22
-rw-r--r--lib/orber/test/csiv2_SUITE.erl2
-rw-r--r--lib/os_mon/src/Makefile4
-rw-r--r--lib/os_mon/src/os_mon.erl2
-rw-r--r--lib/parsetools/include/yeccpre.hrl8
-rw-r--r--lib/parsetools/src/Makefile5
-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/doc/src/notes.xml2
-rw-r--r--lib/public_key/asn1/Makefile2
-rw-r--r--lib/public_key/asn1/PKCS-10.asn126
-rw-r--r--lib/public_key/doc/src/cert_records.xml9
-rw-r--r--lib/public_key/src/Makefile2
-rw-r--r--lib/public_key/src/public_key.erl2
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/src/Makefile5
-rw-r--r--lib/runtime_tools/doc/src/book.xml2
-rw-r--r--lib/runtime_tools/src/Makefile5
-rw-r--r--lib/runtime_tools/src/appmon_info.erl2
-rw-r--r--lib/runtime_tools/src/dbg.erl2
-rw-r--r--lib/runtime_tools/src/runtime_tools_sup.erl4
-rw-r--r--lib/sasl/src/Makefile4
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl6
-rw-r--r--lib/snmp/src/compile/depend.mk2
-rw-r--r--lib/snmp/test/snmp_manager_user_old.erl2
-rw-r--r--lib/snmp/test/snmp_manager_user_test.erl2
-rw-r--r--lib/snmp/test/snmp_test_manager.erl2
-rw-r--r--lib/ssh/doc/src/introduction.xml3
-rw-r--r--lib/ssh/doc/src/ssh.xml2
-rw-r--r--lib/ssh/doc/src/ssh_channel.xml39
-rw-r--r--lib/ssh/doc/src/ssh_client_key_api.xml9
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml26
-rw-r--r--lib/ssh/doc/src/ssh_server_key_api.xml5
-rw-r--r--lib/ssh/doc/src/ssh_sftpd.xml4
-rw-r--r--lib/ssh/doc/src/using_ssh.xml11
-rw-r--r--lib/ssh/src/Makefile4
-rw-r--r--lib/ssh/src/ssh.app.src2
-rw-r--r--lib/ssh/src/ssh.appup.src4
-rw-r--r--lib/ssh/src/ssh.erl46
-rw-r--r--lib/ssh/src/ssh_channel.erl7
-rw-r--r--lib/ssh/src/ssh_cli.erl4
-rw-r--r--lib/ssh/src/ssh_client_key_api.erl4
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl2
-rw-r--r--lib/ssh/src/ssh_daemon_channel.erl (renamed from lib/ssh/src/ssh_subsystem.erl)31
-rw-r--r--lib/ssh/src/ssh_sftp.erl10
-rw-r--r--lib/ssh/src/ssh_sftpd.erl7
-rw-r--r--lib/ssh/src/ssh_shell.erl8
-rw-r--r--lib/ssh/src/ssh_xfer.hrl2
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl2
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml1284
-rw-r--r--lib/ssl/doc/src/ssl_app.xml2
-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.erl18
-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/erl_make_certs.erl2
-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.xml7
-rw-r--r--lib/stdlib/doc/src/epp.xml19
-rw-r--r--lib/stdlib/doc/src/ets.xml10
-rw-r--r--lib/stdlib/doc/src/filelib.xml2
-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/proplists.xml2
-rw-r--r--lib/stdlib/doc/src/unicode.xml20
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml18
-rw-r--r--lib/stdlib/doc/src/zip.xml2
-rw-r--r--lib/stdlib/examples/erl_id_trans.erl5
-rw-r--r--lib/stdlib/src/Makefile4
-rw-r--r--lib/stdlib/src/base64.erl31
-rw-r--r--lib/stdlib/src/beam_lib.erl30
-rw-r--r--lib/stdlib/src/c.erl19
-rw-r--r--lib/stdlib/src/dets.erl10
-rw-r--r--lib/stdlib/src/dets_utils.erl4
-rw-r--r--lib/stdlib/src/dets_v8.erl4
-rw-r--r--lib/stdlib/src/dets_v9.erl4
-rw-r--r--lib/stdlib/src/edlin.erl109
-rw-r--r--lib/stdlib/src/epp.erl45
-rw-r--r--lib/stdlib/src/erl_compile.erl12
-rw-r--r--lib/stdlib/src/erl_eval.erl2
-rw-r--r--lib/stdlib/src/erl_internal.erl3
-rw-r--r--lib/stdlib/src/erl_lint.erl12
-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.erl20
-rw-r--r--lib/stdlib/src/escript.erl16
-rw-r--r--lib/stdlib/src/ets.erl6
-rw-r--r--lib/stdlib/src/file_sorter.erl8
-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.erl6
-rw-r--r--lib/stdlib/src/proc_lib.erl64
-rw-r--r--lib/stdlib/src/proplists.erl2
-rw-r--r--lib/stdlib/src/qlc.erl12
-rw-r--r--lib/stdlib/src/qlc_pt.erl8
-rw-r--r--lib/stdlib/src/queue.erl16
-rw-r--r--lib/stdlib/src/shell.erl35
-rw-r--r--lib/stdlib/src/slave.erl4
-rw-r--r--lib/stdlib/src/string.erl10
-rw-r--r--lib/stdlib/src/unicode.erl25
-rw-r--r--lib/stdlib/src/zip.erl12
-rw-r--r--lib/stdlib/test/dict_SUITE.erl2
-rw-r--r--lib/stdlib/test/dict_test_lib.erl2
-rw-r--r--lib/stdlib/test/epp_SUITE.erl9
-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.erl2
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl2
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl2
-rw-r--r--lib/stdlib/test/io_SUITE.erl8
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl6
-rw-r--r--lib/stdlib/test/sets_SUITE.erl2
-rw-r--r--lib/stdlib/test/sets_test_lib.erl2
-rw-r--r--lib/stdlib/test/sys_SUITE.erl2
-rw-r--r--lib/stdlib/test/timer_SUITE.erl2
-rw-r--r--lib/syntax_tools/src/Makefile2
-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/Makefile4
-rw-r--r--lib/test_server/src/erl2html2.erl68
-rw-r--r--lib/test_server/src/test_server.app.src2
-rw-r--r--lib/test_server/src/test_server.erl82
-rw-r--r--lib/test_server/src/test_server_ctrl.erl582
-rw-r--r--lib/test_server/src/test_server_gl.erl16
-rw-r--r--lib/test_server/src/test_server_h.erl6
-rw-r--r--lib/test_server/src/test_server_internal.hrl2
-rw-r--r--lib/test_server/src/test_server_io.erl12
-rw-r--r--lib/test_server/src/test_server_node.erl14
-rw-r--r--lib/test_server/src/test_server_sup.erl35
-rw-r--r--lib/test_server/src/ts.erl2
-rw-r--r--lib/test_server/src/ts_install.erl13
-rw-r--r--lib/test_server/src/ts_lib.erl16
-rw-r--r--lib/test_server/test/erl2html2_SUITE.erl26
-rw-r--r--lib/test_server/test/test_server_SUITE.erl227
-rw-r--r--lib/test_server/test/test_server_SUITE_data/Makefile.src3
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl82
-rw-r--r--lib/test_server/test/test_server_test_lib.erl66
-rw-r--r--lib/tools/doc/src/xref.xml2
-rw-r--r--lib/tools/emacs/erlang.el96
-rw-r--r--lib/tools/src/Makefile4
-rw-r--r--lib/tools/src/cover.erl20
-rw-r--r--lib/tools/src/lcnt.erl12
-rw-r--r--lib/tools/src/make.erl14
-rw-r--r--lib/tools/src/tags.erl8
-rw-r--r--lib/tools/src/xref.erl4
-rw-r--r--lib/tools/src/xref_base.erl60
-rw-r--r--lib/tools/src/xref_compiler.erl26
-rw-r--r--lib/tools/src/xref_reader.erl11
-rw-r--r--lib/tools/src/xref_utils.erl12
-rw-r--r--lib/tools/test/Makefile1
-rw-r--r--lib/tools/test/cprof_SUITE.erl18
-rw-r--r--lib/tools/test/emacs_SUITE.erl76
-rw-r--r--lib/tv/src/tv_main.hrl3
-rw-r--r--lib/wx/aclocal.m42
-rw-r--r--lib/wx/api_gen/wx_extra/bugs.h6
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.c_src4
-rw-r--r--lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src28
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl6
-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/egl_impl.cpp135
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h4
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp6
-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/c_src/wxePrintout.cpp6
-rw-r--r--lib/wx/c_src/wxe_driver.c22
-rw-r--r--lib/wx/c_src/wxe_driver.h10
-rw-r--r--lib/wx/c_src/wxe_events.h6
-rw-r--r--lib/wx/c_src/wxe_gl.cpp6
-rw-r--r--lib/wx/c_src/wxe_impl.cpp20
-rw-r--r--lib/wx/c_src/wxe_impl.h24
-rw-r--r--lib/wx/c_src/wxe_ps_init.c2
-rw-r--r--lib/wx/c_src/wxe_return.cpp10
-rw-r--r--lib/wx/c_src/wxe_return.h10
-rwxr-xr-xlib/wx/configure.in30
-rw-r--r--lib/wx/examples/demo/demo_html_tagger.erl3
-rw-r--r--lib/wx/examples/demo/ex_button.erl2
-rw-r--r--lib/wx/examples/demo/ex_canvas.erl2
-rw-r--r--lib/wx/examples/demo/ex_choices.erl2
-rw-r--r--lib/wx/examples/demo/ex_cursor.erl2
-rw-r--r--lib/wx/examples/demo/ex_dialogs.erl2
-rw-r--r--lib/wx/examples/demo/ex_frame_utils.erl2
-rw-r--r--lib/wx/examples/demo/ex_gauge.erl2
-rw-r--r--lib/wx/examples/demo/ex_grid.erl2
-rw-r--r--lib/wx/examples/demo/ex_htmlWindow.erl2
-rw-r--r--lib/wx/examples/demo/ex_listCtrl.erl2
-rw-r--r--lib/wx/examples/demo/ex_notebook.erl2
-rw-r--r--lib/wx/examples/demo/ex_pickers.erl2
-rw-r--r--lib/wx/examples/demo/ex_popupMenu.erl2
-rw-r--r--lib/wx/examples/demo/ex_radioBox.erl2
-rw-r--r--lib/wx/examples/demo/ex_sashWindow.erl2
-rw-r--r--lib/wx/examples/demo/ex_sizers.erl2
-rw-r--r--lib/wx/examples/demo/ex_slider.erl2
-rw-r--r--lib/wx/examples/demo/ex_splitterWindow.erl2
-rw-r--r--lib/wx/examples/demo/ex_static.erl2
-rw-r--r--lib/wx/examples/demo/ex_treeCtrl.erl2
-rw-r--r--lib/wx/src/gen/wxNcPaintEvent.erl64
-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/src/wxe_server.erl2
-rw-r--r--lib/wx/test/wx_class_SUITE.erl10
-rw-r--r--make/emd2exml.in2
-rwxr-xr-xmake/fakefop118
-rw-r--r--make/otp.mk.in3
-rw-r--r--make/otp_ded.mk.in2
-rw-r--r--make/otp_release_targets.mk5
-rw-r--r--make/output.mk.in29
-rw-r--r--system/README4
-rw-r--r--system/doc/efficiency_guide/advanced.xml2
-rw-r--r--system/doc/efficiency_guide/drivers.xml2
-rw-r--r--system/doc/embedded/part.xml2
-rw-r--r--system/doc/embedded/xmlfiles.mk2
-rw-r--r--system/doc/installation_guide/part.xml2
-rw-r--r--system/doc/installation_guide/xmlfiles.mk2
-rw-r--r--system/doc/reference_manual/ports.xml2
-rw-r--r--system/doc/reference_manual/typespec.xml4
851 files changed, 22854 insertions, 20163 deletions
diff --git a/HOWTO/INSTALL-CROSS.md b/HOWTO/INSTALL-CROSS.md
index 8a2b1bc8ad..fbcb5f83c6 100644
--- a/HOWTO/INSTALL-CROSS.md
+++ b/HOWTO/INSTALL-CROSS.md
@@ -527,7 +527,7 @@ Copyright and License
%CopyrightBegin%
-Copyright Ericsson AB 2009-2010. All Rights Reserved.
+Copyright Ericsson AB 2009-2013. All Rights Reserved.
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md
index 4f7c317a47..8051bc4393 100644
--- a/HOWTO/INSTALL.md
+++ b/HOWTO/INSTALL.md
@@ -656,40 +656,6 @@ suffix.
Use the `--enable-darwin-64bit` configure flag to build a 64-bit
binaries on Mac OS X.
-Building universal binaries on Mac OS X (obsolete information)
---------------------------------------------------------------
-
-(This information was written when Mac OS X Leopard was the current
-release. It may no longer work.)
-
-Universal 32bit binaries can be built on an Intel Mac using the
-`--enable-darwin-universal` configure option. There still may occur
-problems with certain applications using this option, but the base
-system should run smoothly.
-
-When building universal binaries on a PowerPC Mac (at least on Tiger),
-you must point out a suitable SDK that contains universal binaries.
-For instance, to build universal binaries for Tiger (10.4):
-
- $ CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" \
- LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" \
- ./configure --enable-darwin-universal
-
-Also, if you run Leopard, but want to build for Tiger, you must do by
-setting the `MACOSX_DEPLOYMENT_TARGET` environmental variable.
-
- $ export MACOSX_DEPLOYMENT_TARGET=10.4
-
-Experimental support for 64bit x86 darwin binaries can be enabled
-using the `--enable-darwin-64bit` configure flag. The 64bit binaries are
-best built and run on Leopard, but most of the system also works on
-Tiger (Tiger's 64bit libraries are, however, limited; therefore e.g. `odbc`,
-`crypto`, `ssl` etc. are not supported in Tiger). 64bit PPC binaries are not
-supported and we have no plans to add such support (no machines to
-test on).
-
-Universal binaries and 64bit binaries are mutually exclusive options.
-
Building a fast Erlang VM on Mac OS Lion
----------------------------------------
@@ -722,39 +688,36 @@ Install MacPorts (<http://www.macports.org/>). Then:
### Building with wxErlang ###
-If you want to build the `wx` application, you will need to get wxMac-2.8.12
-(`wxMac-2.8.12.tar.gz` from
-<http://sourceforge.net/projects/wxwindows/files/2.8.12/>) and install it.
+If you want to build the `wx` application, you will need to get wxWidgets-2.9.4 (or later)
+(`wxWidgets-2.9.4.tar.bz2` from <http://sourceforge.net/projects/wxwindows/files/2.9.4/>)
+or get it from github:
+ $ git clone [email protected]:wxWidgets/wxWidgets.git
-Export the path for MacOSX10.6.sdk:
+Be aware that the wxWidgets-2.9 branch is a development branch of wxWidgets and the MacOsX
+port still lags behind the other ports.
- $ export SDK=/Developer/SDKs/MacOSX10.6.sdk
+Configure and build wxMac:
-In Xcode 4.3 the path has changed so use the following instead,
-
- $ export SDK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk
-
-Then configure and build wxMac:
-
- $ arch_flags="-arch i386" ./configure CFLAGS="$arch_flags" CXXFLAGS="$arch_flags" CPPFLAGS="$arch_flags" LDFLAGS="$arch_flags" OBJCFLAGS="$arch_flags" OBJCXXFLAGS="$arch_flags" --prefix=/usr/local --with-macosx-sdk="$SDK" --with-macosx-version-min=10.6 --enable-unicode --with-opengl --disable-shared
+ $ ./configure --with-cocoa --prefix=/usr/local
$ make
$ sudo make install
+ $ export PATH=/usr/local/bin:$PATH
-To link wx properly you will also need to build and install `wxStyledTextCtrl`:
+Check that you got the correct wx-config
- $ cd contrib/src/stc
- $ make
- $ sudo make install
+ $ which wx-config
### Finish up ###
Build Erlang with the MacPorts GCC as the main compiler (using `clang`
for the Objective-C Cocoa code in the `wx` application):
- $ PATH=/usr/local/bin:$PATH CC=/opt/local/bin/gcc-mp-4.5 CXX=/opt/local/bin/g++-mp-4.5 ./configure --enable-m32-build make
+ $ export PATH=/usr/local/bin:$PATH
+ $ cd $ERL_TOP
+ $ CC=/opt/local/bin/gcc-mp-4.5 CXX=/opt/local/bin/g++-mp-4.5 ./configure --enable-darwin-64bit
+ $ make
$ sudo make install
-
How to Build a Debug Enabled Erlang RunTime System
--------------------------------------------------
@@ -801,7 +764,7 @@ Copyright and License
%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
diff --git a/HOWTO/MARKDOWN.md b/HOWTO/MARKDOWN.md
index 42045fb10c..c9ad09a1be 100644
--- a/HOWTO/MARKDOWN.md
+++ b/HOWTO/MARKDOWN.md
@@ -241,7 +241,7 @@ Copyright and License
%CopyrightBegin%
-Copyright Ericsson AB 2010. 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
diff --git a/aclocal.m4 b/aclocal.m4
index 918e30a886..25f40944e7 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index a98b0eda7d..f1eb1a8818 100644
--- a/bootstrap/bin/start.boot
+++ b/bootstrap/bin/start.boot
Binary files differ
diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot
index a98b0eda7d..f1eb1a8818 100644
--- a/bootstrap/bin/start_clean.boot
+++ b/bootstrap/bin/start_clean.boot
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_block.beam b/bootstrap/lib/compiler/ebin/beam_block.beam
index 7c287dc773..72cce89b9d 100644
--- a/bootstrap/lib/compiler/ebin/beam_block.beam
+++ b/bootstrap/lib/compiler/ebin/beam_block.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam
index 0324c7743f..18eb174687 100644
--- a/bootstrap/lib/compiler/ebin/beam_bool.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bool.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dead.beam b/bootstrap/lib/compiler/ebin/beam_dead.beam
index e80f8913a4..b664286f0f 100644
--- a/bootstrap/lib/compiler/ebin/beam_dead.beam
+++ b/bootstrap/lib/compiler/ebin/beam_dead.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dict.beam b/bootstrap/lib/compiler/ebin/beam_dict.beam
index 30777e45b8..50771f4e90 100644
--- a/bootstrap/lib/compiler/ebin/beam_dict.beam
+++ b/bootstrap/lib/compiler/ebin/beam_dict.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_jump.beam b/bootstrap/lib/compiler/ebin/beam_jump.beam
index d15e27f507..c296bdd18d 100644
--- a/bootstrap/lib/compiler/ebin/beam_jump.beam
+++ b/bootstrap/lib/compiler/ebin/beam_jump.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam
index abd69e31fe..1aa160b998 100644
--- a/bootstrap/lib/compiler/ebin/beam_utils.beam
+++ b/bootstrap/lib/compiler/ebin/beam_utils.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam
index d13cbe1944..f67076fa93 100644
--- a/bootstrap/lib/compiler/ebin/beam_validator.beam
+++ b/bootstrap/lib/compiler/ebin/beam_validator.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam
index 9767c2b2cf..2eaae61431 100644
--- a/bootstrap/lib/compiler/ebin/compile.beam
+++ b/bootstrap/lib/compiler/ebin/compile.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app
index 733120aa9e..b6d060167e 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %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
diff --git a/bootstrap/lib/compiler/ebin/core_lib.beam b/bootstrap/lib/compiler/ebin/core_lib.beam
index bbf9d34115..d03dfe646c 100644
--- a/bootstrap/lib/compiler/ebin/core_lib.beam
+++ b/bootstrap/lib/compiler/ebin/core_lib.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_parse.beam b/bootstrap/lib/compiler/ebin/core_parse.beam
index ac2a161ced..80820731c1 100644
--- a/bootstrap/lib/compiler/ebin/core_parse.beam
+++ b/bootstrap/lib/compiler/ebin/core_parse.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_pp.beam b/bootstrap/lib/compiler/ebin/core_pp.beam
index 934d718214..e96e4bc654 100644
--- a/bootstrap/lib/compiler/ebin/core_pp.beam
+++ b/bootstrap/lib/compiler/ebin/core_pp.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
index 2d812b9922..a4529cdd39 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_inline.beam b/bootstrap/lib/compiler/ebin/sys_core_inline.beam
index fa5ed774cd..b2762781e7 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_inline.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_inline.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam
index 5e29ac196e..a51af4dd43 100644
--- a/bootstrap/lib/compiler/ebin/v3_core.beam
+++ b/bootstrap/lib/compiler/ebin/v3_core.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel.beam b/bootstrap/lib/compiler/ebin/v3_kernel.beam
index ce71dd37bb..97a9a79260 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
index d263343393..8f18f5ff25 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam
index 28512de9f1..15c9afae26 100644
--- a/bootstrap/lib/kernel/ebin/application_controller.beam
+++ b/bootstrap/lib/kernel/ebin/application_controller.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/auth.beam b/bootstrap/lib/kernel/ebin/auth.beam
index 0f0eb3437e..049f4056ae 100644
--- a/bootstrap/lib/kernel/ebin/auth.beam
+++ b/bootstrap/lib/kernel/ebin/auth.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam
index 04150eee56..4c847698bd 100644
--- a/bootstrap/lib/kernel/ebin/code.beam
+++ b/bootstrap/lib/kernel/ebin/code.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code_server.beam b/bootstrap/lib/kernel/ebin/code_server.beam
index f142832816..3503784efa 100644
--- a/bootstrap/lib/kernel/ebin/code_server.beam
+++ b/bootstrap/lib/kernel/ebin/code_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam
index 6573609386..96f63b364c 100644
--- a/bootstrap/lib/kernel/ebin/disk_log.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log_1.beam b/bootstrap/lib/kernel/ebin/disk_log_1.beam
index d851460d38..3e69311b53 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_1.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_1.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam
index 8e07296a49..84738305f7 100644
--- a/bootstrap/lib/kernel/ebin/dist_util.beam
+++ b/bootstrap/lib/kernel/ebin/dist_util.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam
index b66197b778..0c161534f9 100644
--- a/bootstrap/lib/kernel/ebin/file.beam
+++ b/bootstrap/lib/kernel/ebin/file.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index 4a90e37aac..e9f463867e 100644
--- a/bootstrap/lib/kernel/ebin/global.beam
+++ b/bootstrap/lib/kernel/ebin/global.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam
index 2a7e46faf5..c34d495e04 100644
--- a/bootstrap/lib/kernel/ebin/group.beam
+++ b/bootstrap/lib/kernel/ebin/group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
index 148a74fe49..dd2d62b8a0 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_config.beam b/bootstrap/lib/kernel/ebin/inet_config.beam
index 9479212ed0..52076f809f 100644
--- a/bootstrap/lib/kernel/ebin/inet_config.beam
+++ b/bootstrap/lib/kernel/ebin/inet_config.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_db.beam b/bootstrap/lib/kernel/ebin/inet_db.beam
index a3081261a2..4fd0b25503 100644
--- a/bootstrap/lib/kernel/ebin/inet_db.beam
+++ b/bootstrap/lib/kernel/ebin/inet_db.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index c5a2398824..1b92542df2 100644
--- a/bootstrap/lib/kernel/ebin/inet_parse.beam
+++ b/bootstrap/lib/kernel/ebin/inet_parse.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
index e794a5e94c..39389454f9 100644
--- a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index ca2dc4f7c5..c6f75faea9 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. 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
diff --git a/bootstrap/lib/kernel/ebin/kernel_config.beam b/bootstrap/lib/kernel/ebin/kernel_config.beam
index 848401eacf..ce8077390c 100644
--- a/bootstrap/lib/kernel/ebin/kernel_config.beam
+++ b/bootstrap/lib/kernel/ebin/kernel_config.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam
index f27b82d841..f7b38ff234 100644
--- a/bootstrap/lib/kernel/ebin/net_kernel.beam
+++ b/bootstrap/lib/kernel/ebin/net_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/os.beam b/bootstrap/lib/kernel/ebin/os.beam
index 8e13b88768..3972fe7b91 100644
--- a/bootstrap/lib/kernel/ebin/os.beam
+++ b/bootstrap/lib/kernel/ebin/os.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user.beam b/bootstrap/lib/kernel/ebin/user.beam
index 7b761283a0..2a72398b7c 100644
--- a/bootstrap/lib/kernel/ebin/user.beam
+++ b/bootstrap/lib/kernel/ebin/user.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user_drv.beam b/bootstrap/lib/kernel/ebin/user_drv.beam
index 15b09a5f93..723343519d 100644
--- a/bootstrap/lib/kernel/ebin/user_drv.beam
+++ b/bootstrap/lib/kernel/ebin/user_drv.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/include/dist.hrl b/bootstrap/lib/kernel/include/dist.hrl
index 5b52f6f294..e32c112e63 100644
--- a/bootstrap/lib/kernel/include/dist.hrl
+++ b/bootstrap/lib/kernel/include/dist.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
@@ -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/bootstrap/lib/kernel/include/file.hrl b/bootstrap/lib/kernel/include/file.hrl
index bf97173122..69aec1ee36 100644
--- a/bootstrap/lib/kernel/include/file.hrl
+++ b/bootstrap/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/bootstrap/lib/stdlib/ebin/beam_lib.beam b/bootstrap/lib/stdlib/ebin/beam_lib.beam
index c7ebc3b440..8e7991754a 100644
--- a/bootstrap/lib/stdlib/ebin/beam_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/beam_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index d919fa0a2d..7221d02754 100644
--- a/bootstrap/lib/stdlib/ebin/c.beam
+++ b/bootstrap/lib/stdlib/ebin/c.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam
index 19f589980f..4178980970 100644
--- a/bootstrap/lib/stdlib/ebin/dets.beam
+++ b/bootstrap/lib/stdlib/ebin/dets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam
index f9b99f574c..2895659a45 100644
--- a/bootstrap/lib/stdlib/ebin/dets_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam
index 4d383902cd..0b3195a8b0 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v9.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph_utils.beam b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
index a5957fc9ce..9bab801654 100644
--- a/bootstrap/lib/stdlib/ebin/digraph_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/edlin.beam b/bootstrap/lib/stdlib/ebin/edlin.beam
index 3eac2b2000..bb586c5f6a 100644
--- a/bootstrap/lib/stdlib/ebin/edlin.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index a3a86afce9..7cf872d5aa 100644
--- a/bootstrap/lib/stdlib/ebin/epp.beam
+++ b/bootstrap/lib/stdlib/ebin/epp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_compile.beam b/bootstrap/lib/stdlib/ebin/erl_compile.beam
index c2757faf82..1311018a7f 100644
--- a/bootstrap/lib/stdlib/ebin/erl_compile.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_compile.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_internal.beam b/bootstrap/lib/stdlib/ebin/erl_internal.beam
index d557c6c5d7..641888643b 100644
--- a/bootstrap/lib/stdlib/ebin/erl_internal.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_internal.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index 20b6d9cd44..1b9a0409d1 100644
--- a/bootstrap/lib/stdlib/ebin/erl_lint.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam
index 0b274c9630..0b88268da2 100644
--- a/bootstrap/lib/stdlib/ebin/erl_parse.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam
index 9c5c72af30..e1eddee136 100644
--- a/bootstrap/lib/stdlib/ebin/erl_pp.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_pp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam
index ef47d3a06c..d0369866d3 100644
--- a/bootstrap/lib/stdlib/ebin/erl_scan.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_tar.beam b/bootstrap/lib/stdlib/ebin/erl_tar.beam
index 4cb833bb30..80e49621dd 100644
--- a/bootstrap/lib/stdlib/ebin/erl_tar.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_tar.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/escript.beam b/bootstrap/lib/stdlib/ebin/escript.beam
index f8f3145066..fcf50be158 100644
--- a/bootstrap/lib/stdlib/ebin/escript.beam
+++ b/bootstrap/lib/stdlib/ebin/escript.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam
index e255819b70..ccc36c6676 100644
--- a/bootstrap/lib/stdlib/ebin/ets.beam
+++ b/bootstrap/lib/stdlib/ebin/ets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam
index be35e0124e..37b6753300 100644
--- a/bootstrap/lib/stdlib/ebin/gen_event.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_event.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_fsm.beam b/bootstrap/lib/stdlib/ebin/gen_fsm.beam
index 06782fbf91..1fcabac0d7 100644
--- a/bootstrap/lib/stdlib/ebin/gen_fsm.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_fsm.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam
index 0ccd003b0b..f0fa4f03a9 100644
--- a/bootstrap/lib/stdlib/ebin/gen_server.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_server.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib.beam b/bootstrap/lib/stdlib/ebin/io_lib.beam
index 9420ea0f53..9bb33a2248 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
index b14eb23e7c..bc3b5ec877 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lib.beam b/bootstrap/lib/stdlib/ebin/lib.beam
index 668ea7eb29..546abc7a9d 100644
--- a/bootstrap/lib/stdlib/ebin/lib.beam
+++ b/bootstrap/lib/stdlib/ebin/lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lists.beam b/bootstrap/lib/stdlib/ebin/lists.beam
index 68b6d0da56..948af8d1be 100644
--- a/bootstrap/lib/stdlib/ebin/lists.beam
+++ b/bootstrap/lib/stdlib/ebin/lists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam
index 6031052e4c..c57225cf1c 100644
--- a/bootstrap/lib/stdlib/ebin/ms_transform.beam
+++ b/bootstrap/lib/stdlib/ebin/ms_transform.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/pool.beam b/bootstrap/lib/stdlib/ebin/pool.beam
index 9a9bfa4e2f..8ad59de20d 100644
--- a/bootstrap/lib/stdlib/ebin/pool.beam
+++ b/bootstrap/lib/stdlib/ebin/pool.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/proc_lib.beam b/bootstrap/lib/stdlib/ebin/proc_lib.beam
index e22b3ad758..a297dff09c 100644
--- a/bootstrap/lib/stdlib/ebin/proc_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/proc_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam
index 302dda040f..56c7e7ffe2 100644
--- a/bootstrap/lib/stdlib/ebin/qlc.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
index eb098b31ae..458684586b 100644
--- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/queue.beam b/bootstrap/lib/stdlib/ebin/queue.beam
index 688c411798..8907a03b57 100644
--- a/bootstrap/lib/stdlib/ebin/queue.beam
+++ b/bootstrap/lib/stdlib/ebin/queue.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index 5614d31ac8..587446dcc6 100644
--- a/bootstrap/lib/stdlib/ebin/shell.beam
+++ b/bootstrap/lib/stdlib/ebin/shell.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index 5a7ddd5f56..d8d65c5521 100644
--- a/bootstrap/lib/stdlib/ebin/sofs.beam
+++ b/bootstrap/lib/stdlib/ebin/sofs.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index e06badfec4..841874f1f5 100644
--- a/bootstrap/lib/stdlib/ebin/sys.beam
+++ b/bootstrap/lib/stdlib/ebin/sys.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/unicode.beam b/bootstrap/lib/stdlib/ebin/unicode.beam
index 9869d4862b..572cb2b6fa 100644
--- a/bootstrap/lib/stdlib/ebin/unicode.beam
+++ b/bootstrap/lib/stdlib/ebin/unicode.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam
index 41386df3f0..9a4d3b5cd3 100644
--- a/bootstrap/lib/stdlib/ebin/zip.beam
+++ b/bootstrap/lib/stdlib/ebin/zip.beam
Binary files differ
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 918e30a886..25f40944e7 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/configure.in b/erts/configure.in
index 30bc1ef000..1e3a607a6f 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1997-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1997-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
@@ -827,6 +827,12 @@ if test -z "$FOP"; then
AC_MSG_WARN([No 'fop' command found: going to generate placeholder PDF files])
fi
+AC_CHECK_PROGS(XMLLINT, xmllint)
+if test -z "$XMLLINT"; then
+ echo "xmllint" >> doc/CONF_INFO
+ AC_MSG_WARN([No 'xmllint' command found: can't run the xmllint target for the documentation])
+fi
+
dnl
dnl We can live with Solaris /usr/ucb/install
dnl
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
index 4455d0ac92..e512c19e05 100644
--- a/erts/doc/src/absform.xml
+++ b/erts/doc/src/absform.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2011</year>
+ <year>2001</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -290,13 +290,6 @@
<item>If E is <c><![CDATA[fun Fc_1 ; ... ; Fc_k end]]></c>
where each <c><![CDATA[Fc_i]]></c> is a function clause then Rep(E) =
<c><![CDATA[{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}]]></c>.</item>
- <item>If E is <c><![CDATA[query [E_0 || W_1, ..., W_k] end]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{'query',LINE,{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}}]]></c>.
- For Rep(W), see below.</item>
- <item>If E is <c><![CDATA[E_0.Field]]></c>, a Mnesia record access
- inside a query, then
- Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Rep(Field)}]]></c>.</item>
<item>If E is <c><![CDATA[( E_0 )]]></c>, then
Rep(E) = <c><![CDATA[Rep(E_0)]]></c>,
i.e., parenthesized expressions cannot be distinguished from their bodies.</item>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index a79a2d5c48..f354d68d45 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2012</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -582,7 +582,7 @@
<seealso marker="erts_alloc">erts_alloc(3)</seealso> for
further information.</p>
</item>
- <tag><c><![CDATA[+n Behavior]]></c></tag>
+ <tag><marker id="+n"/><c><![CDATA[+n Behavior]]></c></tag>
<item>
<p>Control behavior of signals to ports.</p>
<p>As of OTP-R16 signals to ports are truly asynchronously
@@ -615,7 +615,7 @@
debugging.</item>
</taglist>
</item>
- <tag><marker id="max_processes"><c><![CDATA[+P Number]]></c></marker></tag>
+ <tag><marker id="+P"/><marker id="max_processes"><c><![CDATA[+P Number]]></c></marker></tag>
<item>
<p>Sets the maximum number of simultaneously existing processes for this
system. Valid range for <c>Number</c> is <c>[1024-134217727]</c></p>
@@ -627,7 +627,7 @@
<seealso marker="erlang#system_info_process_limit">erlang:system_info(process_limit)</seealso>.</p>
<p>The default value is <c>262144</c></p>
</item>
- <tag><marker id="max_ports"><c><![CDATA[+Q Number]]></c></marker></tag>
+ <tag><marker id="+Q"/><marker id="max_ports"><c><![CDATA[+Q Number]]></c></marker></tag>
<item>
<p>Sets the maximum number of simultaneously existing ports for this
system. Valid range for <c>Number</c> is <c>[1024-134217727]</c></p>
@@ -672,7 +672,7 @@
<item>
<p>Limits the amount of reader groups used by read/write locks
optimized for read operations in the Erlang runtime system. By
- default the reader groups limit equals 8.</p>
+ default the reader groups limit equals 64.</p>
<p>When the amount of schedulers is less than or equal to the reader
groups limit, each scheduler has its own reader group. When the
amount of schedulers is larger than the reader groups limit,
@@ -710,7 +710,24 @@
<taglist>
<tag><marker id="+sbt"><c>+sbt BindType</c></marker></tag>
<item>
- <p>Set scheduler bind type. Currently valid <c>BindType</c>s:
+ <p>Set scheduler bind type.</p>
+ <p>Schedulers can also be bound using the
+ <seealso marker="#+stbt">+stbt</seealso> flag. The only difference
+ between these two flags is how the following errors are handled:</p>
+ <list>
+ <item>Binding of schedulers is not supported on the specific
+ platform.</item>
+ <item>No available CPU topology. That is the runtime system
+ was not able to automatically detected the CPU topology, and
+ no <seealso marker="#+sct">user defined CPU topology</seealso>
+ was set.</item>
+ </list>
+ <p>If any of these errors occur when <c>+sbt</c> has been passed,
+ the runtime system will print an error message, and refuse to
+ start. If any of these errors occur when <c>+stbt</c> has been
+ passed, the runtime system will silently ignore the error, and
+ start up using unbound schedulers.</p>
+ <p>Currently valid <c>BindType</c>s:
</p>
<taglist>
<tag><c>u</c></tag>
@@ -960,6 +977,14 @@
<p>For more information, see
<seealso marker="erlang#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>.</p>
</item>
+ <tag><marker id="+stbt"><c>+stbt BindType</c></marker></tag>
+ <item>
+ <p>Try to set scheduler bind type. The same as the
+ <seealso marker="#+sbt">+sbt</seealso> flag with the exception of
+ how some errors are handled. For more information, see the
+ documentation of the <seealso marker="#+sbt">+sbt</seealso> flag.
+ </p>
+ </item>
<tag><marker id="+sws"><c>+sws default|legacy|proposal</c></marker></tag>
<item>
<p>Set scheduler wakeup strategy. Default is <c>legacy</c> (has been
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
index 6c725fc82d..4cff4956a2 100644
--- a/erts/doc/src/erl_dist_protocol.xml
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -547,13 +547,289 @@ If Result > 0, the packet only consists of [119, Result].
-->
</section>
-
+ <marker id="distribution_handshake"/>
<section>
- <title>Handshake</title>
- <p>
- The handshake is discussed in detail in the internal documentation for
- the kernel (Erlang) application.
- </p>
+ <title>Distribution Handshake</title>
+ <p>
+ This section describes the distribution handshake protocol
+ introduced in the OTP-R6 release of Erlang/OTP. This
+ description was previously located in
+ <c>$ERL_TOP/lib/kernel/internal_doc/distribution_handshake.txt</c>,
+ and has more or less been copied and "formatted" here. It has been
+ more or less unchanged since the year 1999, but the handshake
+ should not have changed much since then either.
+ </p>
+ <section>
+ <title>General</title>
+ <p>
+ 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.
+ </p>
+ <p>
+ This is not entirely safe, as it is vulnerable against takeover
+ attacks, but it is a tradeoff between fair safety and performance.
+ </p>
+ <p>
+ 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.
+ </p>
+ </section>
+ <section>
+ <title>Definitions</title>
+ <p>
+ A challenge is a 32 bit integer number in big endian order. Below the function
+ <c>gen_challenge()</c> returns a random 32 bit integer used as a challenge.
+ </p>
+ <p>
+ A digest is a (16 bytes) MD5 hash of the Challenge (as text) concatenated
+ with the cookie (as text). Below, the function <c>gen_digest(Challenge, Cookie)</c>
+ generates a digest as described above.
+ </p>
+ <p>
+ 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 <em>NOT</em>
+ be the same. Below the function <c>out_cookie(Node)</c> returns the current
+ node's out_cookie for <c>Node</c>.
+ </p>
+ <p>
+ 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 <c>in_cookie(Node)</c> returns the current
+ node's <c>in_cookie</c> for <c>Node</c>.
+ </p>
+ <p>
+ The cookies are text strings that can be viewed as passwords.
+ </p>
+ <p>
+ 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 <c>gen_tcp</c> option <c>{packet, 2}</c>. Note that after
+ the handshake, the distribution switches to 4 byte packet headers.
+ </p>
+
+ </section>
+ <section>
+ <title>The Handshake in Detail</title>
+ <p>
+ Imagine two nodes, node A, which initiates the handshake and node B, which
+ accepts the connection.
+ </p>
+ <taglist>
+ <tag>1) connect/accept</tag>
+ <item><p>A connects to B via TCP/IP and B accepts the connection.</p></item>
+ <tag>2) send_name/receive_name</tag>
+ <item><p>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):
+ </p>
+<pre>
++---+--------+--------+-----+-----+-----+-----+-----+-----+-...-+-----+
+|'n'|Version0|Version1|Flag0|Flag1|Flag2|Flag3|Name0|Name1| ... |NameN|
++---+--------+--------+-----+-----+-----+-----+-----+-----+-... +-----+
+</pre>
+ <p>
+ The 'n' is just a message tag.
+ Version0 and 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
+ <c>$ERL_TOP/lib/kernel/include/dist.hrl</c>.
+ (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).
+ </p></item>
+ <tag>3) recv_status/send_status</tag>
+ <item><p>B sends a status message to A, which indicates
+ if the connection is allowed. The following status codes are defined:</p>
+ <taglist>
+ <tag><c>ok</c></tag>
+ <item>The handshake will continue.</item>
+ <tag><c>ok_simultaneous</c></tag>
+ <item>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).</item>
+ <tag><c>nok</c></tag>
+ <item>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).</item>
+ <tag><c>not_allowed</c></tag>
+ <item>The connection is disallowed for some (unspecified) security
+ reason.</item>
+ <tag><c>alive</c></tag>
+ <item>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.</item>
+ </taglist>
+ <p>This is the format of the status message:</p>
+<pre>
++---+-------+-------+-...-+-------+
+|'s'|Status0|Status1| ... |StatusN|
++---+-------+-------+-...-+-------+
+</pre>
+ <p>
+ 's' is the message tag Status0 ... StatusN is the status as a string (not terminated)
+ </p>
+ </item>
+ <tag>3B) send_status/recv_status</tag>
+ <item><p>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
+ <c>'false'</c>, which simply means that the connection should be closed, the
+ connection attempt was a mistake.</p></item>
+ <tag>4) recv_challenge/send_challenge</tag>
+ <item><p>If the status was <c>ok</c> or <c>ok_simultaneous</c>,
+ 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:</p>
+<pre>
++---+--------+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-...-+-----+
+|'n'|Version0|Version1|Flag0|Flag1|Flag2|Flag3|Chal0|Chal1|Chal2|Chal3|Name0|Name1| ... |NameN|
++---+--------+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-... +-----+
+</pre>
+ <p>
+ 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.
+ </p></item>
+ <tag>5) send_challenge_reply/recv_challenge_reply</tag>
+ <item><p>Now A has generated a digest and its own challenge. Those are
+ sent together in a package to B:</p>
+<pre>
++---+-----+-----+-----+-----+-----+-----+-----+-----+-...-+------+
+|'r'|Chal0|Chal1|Chal2|Chal3|Dige0|Dige1|Dige2|Dige3| ... |Dige15|
++---+-----+-----+-----+-----+-----+-----+-----+-----+-...-+------+
+</pre>
+ <p>
+ 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.
+ </p></item>
+ <tag>6) recv_challenge_ack/send_challenge_ack</tag>
+ <item><p>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:</p>
+<pre>
++---+-----+-----+-----+-----+-...-+------+
+|'a'|Dige0|Dige1|Dige2|Dige3| ... |Dige15|
++---+-----+-----+-----+-----+-...-+------+
+</pre>
+ <p>
+ Where 'a' is the tag and Dige0 ... Dige15 is the digest calculated by B
+ for A's challenge.</p></item>
+ <tag>7)</tag>
+ <item><p>A checks the digest from B and the connection is up.</p></item>
+ </taglist>
+ </section>
+ <section>
+ <title>Semigraphic View</title>
+<pre>
+A (initiator) B (acceptor)
+
+TCP connect -----------------------------------------&gt;
+ TCP accept
+
+send_name -----------------------------------------&gt;
+ recv_name
+
+ &lt;---------------------------------------- send_status
+recv_status
+(if status was 'alive'
+ send_status - - - - - - - - - - - - - - - - - - - -&gt;
+ recv_status)
+ ChB = gen_challenge()
+ (ChB)
+ &lt;---------------------------------------- send_challenge
+recv_challenge
+
+ChA = gen_challenge(),
+OCA = out_cookie(B),
+DiA = gen_digest(ChB,OCA)
+ (ChA, DiA)
+send_challenge_reply --------------------------------&gt;
+ 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)
+ &lt;----------------------------------------- send_challenge_ack
+recv_challenge_ack DONE
+ICA = in_cookie(B), - else
+check: CLOSE
+DiB == gen_digest(ChA,ICA) ?
+- if OK
+ DONE
+- else
+ CLOSE
+</pre>
+ </section>
+ <marker id="dflags"/>
+ <section>
+ <title>The Currently Defined Distribution Flags</title>
+ <p>
+ Currently (OTP-R16) the following capability flags are defined:
+ </p>
+<pre>
+%% The node should be published and part of the global namespace
+-define(DFLAG_PUBLISHED,1).
+
+%% The node implements an atom cache (obsolete)
+-define(DFLAG_ATOM_CACHE,2).
+
+%% The node implements extended (3 * 32 bits) references. This is
+%% required today. If not present connection will be refused.
+-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#10).
+
+%% The node implements distributed named process monitoring.
+-define(DFLAG_DIST_MONITOR_NAME,16#20).
+
+%% The (hidden) node implements atom cache (obsolete)
+-define(DFLAG_HIDDEN_ATOM_CACHE,16#40).
+
+%% The node understand new fun-tags
+-define(DFLAG_NEW_FUN_TAGS,16#80).
+
+%% The node is capable of handling extended pids and ports. This is
+%% required today. If not present connection will be refused.
+-define(DFLAG_EXTENDED_PIDS_PORTS,16#100).
+
+%%
+-define(DFLAG_EXPORT_PTR_TAG,16#200).
+
+%%
+-define(DFLAG_BIT_BINARIES,16#400).
+
+%% The node understands new float format
+-define(DFLAG_NEW_FLOATS,16#800).
+
+%%
+-define(DFLAG_UNICODE_IO,16#1000).
+
+%% The node implements atom cache in distribution header.
+-define(DFLAG_DIST_HDR_ATOM_CACHE,16#2000).
+
+%% The node understand the SMALL_ATOM_EXT tag
+-define(DFLAG_SMALL_ATOM_TAGS, 16#4000).
+
+%% The node understand UTF-8 encoded atoms
+-define(DFLAG_UTF8_ATOMS, 16#10000).
+
+</pre>
+ </section>
</section>
<section>
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 13f42a74a7..1212c34586 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -317,9 +317,9 @@
minor version used by the driver is greater than the one used
by the runtime system.</p>
<p>The emulator will refuse to load a driver that does not use
- the extended driver interface since,
+ the extended driver interface,
to allow for 64-bit capable drivers,
- incompatible type changes for the callbacks
+ since incompatible type changes for the callbacks
<seealso marker="driver_entry#output">output</seealso>,
<seealso marker="driver_entry#control">control</seealso> and
<seealso marker="driver_entry#call">call</seealso>
@@ -1560,7 +1560,7 @@ typedef struct ErlIOVec {
<c>[ERL_DRV_BUSY_MSGQ_LIM_MIN, ERL_DRV_BUSY_MSGQ_LIM_MAX]</c>.
Limits will be automatically adjusted to be sane. That is,
the system will adjust values so that the low limit used is
- lower or equal to the high limit used. By default the high
+ lower than or equal to the high limit used. By default the high
limit will be 8 kB and the low limit will be 4 kB.</p>
<p>By passing a pointer to an integer variable containing
diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml
index fd2da2cfe3..c6849f3326 100644
--- a/erts/doc/src/erl_ext_dist.xml
+++ b/erts/doc/src/erl_ext_dist.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -119,10 +119,39 @@
<cell align="center">Data</cell>
</row>
<tcaption></tcaption></table>
+ <marker id="utf8_atoms"/>
+ <note>
+ <p>As of ERTS version 5.10 (OTP-R16) support
+ for UTF-8 encoded atoms has been introduced in the external format.
+ However, only characters that can be encoded using Latin1 (ISO-8859-1)
+ are currently supported in atoms. The support for UTF-8 encoded atoms
+ in the external format has been implemented in order to be able to support
+ all Unicode characters in atoms in <em>some future release</em>. Full
+ support for Unicode atoms will not happen before OTP-R18, and might
+ be introduced even later than that. Until full Unicode support for
+ atoms has been introduced, it is an <em>error</em> to pass atoms containing
+ characters that cannot be encoded in Latin1, and <em>the behavior is
+ undefined</em>.</p>
+ <p>When the
+ <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_UTF8_ATOMS</c></seealso>
+ distribution flag has been exchanged between both nodes in the
+ <seealso marker="erl_dist_protocol#distribution_handshake">distribution handshake</seealso>,
+ all atoms in the distribution header will be encoded in UTF-8; otherwise,
+ all atoms in the distribution header will be encoded in Latin1. The two
+ new tags <seealso marker="#ATOM_UTF8_EXT">ATOM_UTF8_EXT</seealso>, and
+ <seealso marker="#SMALL_ATOM_UTF8_EXT">SMALL_ATOM_UTF8_EXT</seealso>
+ will only be used if the <c>DFLAG_UTF8_ATOMS</c> distribution flag has
+ been exchanged between nodes, or if an atom containing characters
+ that cannot be encoded in Latin1 is encountered.
+ </p>
+ <p>The maximum number of allowed characters in an atom is 255. In the
+ UTF-8 case each character may need 4 bytes to be encoded.
+ </p>
+ </note>
</section>
- <section>
- <marker id="distribution_header"/>
+ <marker id="distribution_header"/>
+ <section>
<title>Distribution header</title>
<p>
As of erts version 5.7.2 the old atom cache protocol was
@@ -219,8 +248,7 @@
<p>
The least significant bit in that half byte is the <c>LongAtoms</c>
flag. If it is set, 2 bytes are used for atom lengths instead of
- 1 byte in the distribution header. However, the current emulator
- cannot handle long atoms, so it will currently always be 0.
+ 1 byte in the distribution header.
</p>
<p>
After the <c>Flags</c> field follow the <c>AtomCacheRefs</c>. The
@@ -247,16 +275,26 @@
<p>
<c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c>
completely identify the location of an atom cache entry in the
- atom cache. <c>Length</c> is number of one byte characters that
- the atom text consists of. Length is a two byte big endian integer
+ atom cache. <c>Length</c> is number of bytes that <c>AtomText</c>
+ consists of. Length is a two byte big endian integer
if the <c>LongAtoms</c> flag has been set, otherwise a one byte
- integer. Subsequent <c>CachedAtomRef</c>s with the same
+ integer. When the
+ <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_UTF8_ATOMS</c></seealso>
+ distribution flag has been exchanged between both nodes in the
+ <seealso marker="erl_dist_protocol#distribution_handshake">distribution handshake</seealso>,
+ characters in <c>AtomText</c> is encoded in UTF-8; otherwise,
+ encoded in Latin1. Subsequent <c>CachedAtomRef</c>s with the same
<c>SegmentIndex</c> and <c>InternalSegmentIndex</c> as this
<c>NewAtomCacheRef</c> will refer to this atom until a new
<c>NewAtomCacheRef</c> with the same <c>SegmentIndex</c>
and <c>InternalSegmentIndex</c> appear.
</p>
<p>
+ For more information on encoding of atoms, see
+ <seealso marker="#utf8_atoms">note on UTF-8 encoded atoms</seealso>
+ in the beginning of this document.
+ </p>
+ <p>
If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c>
has not been set, a <c>CachedAtomRef</c> on the following format
will follow:
@@ -383,9 +421,9 @@
<tcaption></tcaption></table>
<p>
An atom is stored with a 2 byte unsigned length in big-endian order,
- followed by <c>Len</c> numbers of 8 bit characters that forms the
- <c>AtomName</c>.
- Note: The maximum allowed value for <c>Len</c> is 255.
+ followed by <c>Len</c> numbers of 8 bit Latin1 characters that forms
+ the <c>AtomName</c>.
+ <em>Note</em>: The maximum allowed value for <c>Len</c> is 255.
</p>
</section>
@@ -754,12 +792,14 @@
<tcaption></tcaption></table>
<p>
An atom is stored with a 1 byte unsigned length,
- followed by <c>Len</c> numbers of 8 bit characters that
+ followed by <c>Len</c> numbers of 8 bit Latin1 characters that
forms the <c>AtomName</c>. Longer atoms can be represented
by <seealso marker="#ATOM_EXT">ATOM_EXT</seealso>. <em>Note</em>
the <c>SMALL_ATOM_EXT</c> was introduced in erts version 5.7.2 and
- require a small atom distribution flag exchanged in the distribution
- handshake.
+ require an exchange of the
+ <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_SMALL_ATOM_TAGS</c></seealso>
+ distribution flag in the
+ <seealso marker="erl_dist_protocol#distribution_handshake">distribution handshake</seealso>.
</p>
</section>
@@ -1007,7 +1047,62 @@
This term is used in minor version 1 of the external format.
</p>
</section>
+ <section>
+ <marker id="ATOM_UTF8_EXT"/>
+ <title>ATOM_UTF8_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center"><c>118</c></cell>
+ <cell align="center"><c>Len</c></cell>
+ <cell align="center"><c>AtomName</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ An atom is stored with a 2 byte unsigned length in big-endian order,
+ followed by <c>Len</c> bytes containing the <c>AtomName</c> encoded
+ in UTF-8.
+ </p>
+ <p>
+ For more information on encoding of atoms, see
+ <seealso marker="#utf8_atoms">note on UTF-8 encoded atoms</seealso>
+ in the beginning of this document.
+ </p>
+ </section>
+ <section>
+ <marker id="SMALL_ATOM_UTF8_EXT"/>
+ <title>SMALL_ATOM_UTF8_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center"><c>119</c></cell>
+ <cell align="center"><c>Len</c></cell>
+ <cell align="center"><c>AtomName</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ An atom is stored with a 1 byte unsigned length,
+ followed by <c>Len</c> bytes containing the <c>AtomName</c> encoded
+ in UTF-8. Longer atoms encoded in UTF-8 can be represented using
+ <seealso marker="#ATOM_UTF8_EXT">ATOM_UTF8_EXT</seealso>.
+ </p>
+ <p>
+ For more information on encoding of atoms, see
+ <seealso marker="#utf8_atoms">note on UTF-8 encoded atoms</seealso>
+ in the beginning of this document.
+ </p>
+ </section>
</chapter>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 1d67be2e52..b336a135e7 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.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>
@@ -277,7 +277,9 @@
the binary contains Unicode characters greater than 16#FF.
In a future release, such Unicode characters might be allowed
and <c>binary_to_atom(<anno>Binary</anno>, utf8)</c>
- will not fail in that case.</p></note>
+ will not fail in that case. For more information on Unicode support in atoms
+ see <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8 encoded atoms</seealso>
+ in the chapter about the external term format in the ERTS User's Guide.</p></note>
<pre>
> <input>binary_to_atom(&lt;&lt;"Erlang"&gt;&gt;, latin1).</input>
@@ -968,6 +970,37 @@ true
</desc>
</func>
<func>
+ <name>float_to_list(Float, Options) -> string()</name>
+ <fsummary>Text representation of a float formatted using given options</fsummary>
+ <type>
+ <v>Float = float()</v>
+ <v>Options = [Option]</v>
+ <v>Option = {decimals, Decimals::0..249} |
+ {scientific, Decimals::0..249} |
+ compact</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Float</c> using fixed decimal point formatting.
+ When <c>decimals</c> option is specified
+ the returned value will contain at most <c>Decimals</c> number of
+ digits past the decimal point. If the number doesn't fit in the
+ internal static buffer of 256 bytes, the function throws <c>badarg</c>.
+ When <c>compact</c> option is provided
+ the trailing zeros at the end of the list are truncated (this option is
+ only meaningful together with the <c>decimals</c> option). When
+ <c>scientific</c> option is provided, the float will be formatted using
+ scientific notation with <c>Decimals</c> digits of precision. If
+ <c>Options</c> is <c>[]</c> the function behaves like <c>float_to_list/1</c>.
+ </p>
+ <pre>
+> <input>float_to_list(7.12, [{decimals, 4}]).</input>
+"7.1200"
+> <input>float_to_list(7.12, [{decimals, 4}, compact]).</input>
+"7.12"</pre>
+ </desc>
+ </func>
+ <func>
<name name="fun_info" arity="1"/>
<fsummary>Information about a fun</fsummary>
<desc>
@@ -1681,9 +1714,11 @@ os_prompt% </pre>
<desc>
<p>Returns the atom whose text representation is <c><anno>String</anno></c>.</p>
<p><c><anno>String</anno></c> may only contain ISO-latin-1
- characterns (i.e. numbers below 256) as the current
+ characters (i.e. numbers below 256) as the current
implementation does not allow unicode characters >= 256 in
- atoms.</p>
+ atoms. For more information on Unicode support in atoms
+ see <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8 encoded atoms</seealso>
+ in the chapter about the external term format in the ERTS User's Guide.</p>
<pre>
> <input>list_to_atom("Erlang").</input>
'Erlang'</pre>
@@ -5679,35 +5714,35 @@ ok
For more information see the
<seealso marker="erl#+spp">+spp</seealso> command line argument
of <seealso marker="erl">erl(1)</seealso>.</p></item>
- <tag><c>process_count</c></tag>
+ <tag><marker id="system_info_port_count"/><c>port_count</c></tag>
<item>
<p>Returns the number of ports currently existing at
the local node as an integer. The same value as
- <c>length(erlang:ports())</c> returns.</p>
+ <c>length(erlang:ports())</c> returns, but more efficient.</p>
</item>
<tag><marker id="system_info_port_limit"><c>port_limit</c></marker></tag>
<item>
<p>Returns the maximum number of simultaneously existing
ports at the local node as an integer. This limit
can be configured at startup by using the
- <seealso marker="erl#max_ports"><c>+Q</c></seealso>
+ <seealso marker="erl#+Q">+Q</seealso>
command line flag of
- <seealso marker="erl"><c>erl(1)</c></seealso>.</p>
+ <seealso marker="erl">erl(1)</seealso>.</p>
</item>
- <tag><c>process_count</c></tag>
+ <tag><marker id="system_info_process_count"/><c>process_count</c></tag>
<item>
<p>Returns the number of processes currently existing at
the local node as an integer. The same value as
- <c>length(processes())</c> returns.</p>
+ <c>length(processes())</c> returns, but more efficient.</p>
</item>
<tag><marker id="system_info_process_limit"><c>process_limit</c></marker></tag>
<item>
<p>Returns the maximum number of simultaneously existing
processes at the local node as an integer. This limit
can be configured at startup by using the
- <seealso marker="erl#max_processes"><c>+P</c></seealso>
+ <seealso marker="erl#+P">+P</seealso>
command line flag of
- <seealso marker="erl"><c>erl(1)</c></seealso>.</p>
+ <seealso marker="erl">erl(1)</seealso>.</p>
</item>
<tag><c>procs</c></tag>
<item>
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 87d6682328..f0bde600ad 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2002</year><year>2011</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index de6696671b..7ac66906ee 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2012</year>
+ <year>2004</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml
index 2c178556d4..fa50329cad 100644
--- a/erts/doc/src/part.xml
+++ b/erts/doc/src/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml
index 5c9938075c..e55923c344 100644
--- a/erts/doc/src/ref_man.xml
+++ b/erts/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index d7c7f117cf..b69f979397 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -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
@@ -111,7 +111,7 @@ atom_text_alloc(int bytes)
{
byte *res;
- ASSERT(bytes <= MAX_ATOM_LENGTH);
+ ASSERT(bytes <= MAX_ATOM_SZ_LIMIT);
if (atom_text_pos + bytes >= atom_text_end) {
more_atom_space();
}
@@ -162,6 +162,7 @@ atom_alloc(Atom* tmpl)
obj->name = atom_text_alloc(tmpl->len);
sys_memcpy(obj->name, tmpl->name, tmpl->len);
obj->len = tmpl->len;
+ obj->latin1_chars = tmpl->latin1_chars;
obj->slot.index = -1;
/*
@@ -192,44 +193,146 @@ atom_free(Atom* obj)
erts_free(ERTS_ALC_T_ATOM, (void*) obj);
}
+static void latin1_to_utf8(byte* conv_buf, const byte** srcp, int* lenp)
+{
+ byte* dst;
+ const byte* src = *srcp;
+ int i, len = *lenp;
+
+ for (i=0 ; i < len; ++i) {
+ if (src[i] & 0x80) {
+ goto need_convertion;
+ }
+ }
+ return;
+
+need_convertion:
+ sys_memcpy(conv_buf, src, i);
+ dst = conv_buf + i;
+ for ( ; i < len; ++i) {
+ unsigned char chr = src[i];
+ if (!(chr & 0x80)) {
+ *dst++ = chr;
+ }
+ else {
+ *dst++ = 0xC0 | (chr >> 6);
+ *dst++ = 0x80 | (chr & 0x3F);
+ }
+ }
+ *srcp = conv_buf;
+ *lenp = dst - conv_buf;
+}
+
+/*
+ * erts_atom_put() may fail. If it fails THE_NON_VALUE is returned!
+ */
Eterm
-am_atom_put(const char* name, int len)
+erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
{
+ byte utf8_copy[MAX_ATOM_SZ_FROM_LATIN1];
+ const byte *text = name;
+ int tlen = len;
+ Sint no_latin1_chars;
Atom a;
- Eterm ret;
int aix;
- /*
- * Silently truncate the atom if it is too long. Overlong atoms
- * could occur in situations where we have no good way to return
- * an error, such as in the I/O system. (Unfortunately, many
- * drivers don't check for errors.)
- *
- * If an error should be produced for overlong atoms (such in
- * list_to_atom/1), the caller should check the length before
- * calling this function.
- */
- if (len > MAX_ATOM_LENGTH) {
- len = MAX_ATOM_LENGTH;
- }
#ifdef ERTS_ATOM_PUT_OPS_STAT
erts_smp_atomic_inc_nob(&atom_put_ops);
#endif
- a.len = len;
- a.name = (byte*)name;
+
+ if (tlen < 0) {
+ if (trunc)
+ tlen = 0;
+ else
+ return THE_NON_VALUE;
+ }
+
+ switch (enc) {
+ case ERTS_ATOM_ENC_7BIT_ASCII:
+ if (tlen > MAX_ATOM_CHARACTERS) {
+ if (trunc)
+ tlen = MAX_ATOM_CHARACTERS;
+ else
+ return THE_NON_VALUE;
+ }
+#ifdef DEBUG
+ for (aix = 0; aix < len; aix++) {
+ ASSERT((name[aix] & 0x80) == 0);
+ }
+#endif
+ no_latin1_chars = tlen;
+ break;
+ case ERTS_ATOM_ENC_LATIN1:
+ if (tlen > MAX_ATOM_CHARACTERS) {
+ if (trunc)
+ tlen = MAX_ATOM_CHARACTERS;
+ else
+ return THE_NON_VALUE;
+ }
+ no_latin1_chars = tlen;
+ latin1_to_utf8(utf8_copy, &text, &tlen);
+ break;
+ case ERTS_ATOM_ENC_UTF8:
+ /* First sanity check; need to verify later */
+ if (tlen > MAX_ATOM_SZ_LIMIT && !trunc)
+ return THE_NON_VALUE;
+ break;
+ }
+
+ a.len = tlen;
+ a.name = (byte *) text;
atom_read_lock();
aix = index_get(&erts_atom_table, (void*) &a);
atom_read_unlock();
- if (aix >= 0)
- ret = make_atom(aix);
- else {
- atom_write_lock();
- ret = make_atom(index_put(&erts_atom_table, (void*) &a));
- atom_write_unlock();
+ if (aix >= 0) {
+ /* Already in table no need to verify it */
+ return make_atom(aix);
}
- return ret;
+
+ if (enc == ERTS_ATOM_ENC_UTF8) {
+ /* Need to verify encoding and length */
+ byte *err_pos;
+ Uint no_chars;
+ switch (erts_analyze_utf8_x((byte *) text,
+ (Uint) tlen,
+ &err_pos,
+ &no_chars, NULL,
+ &no_latin1_chars,
+ MAX_ATOM_CHARACTERS)) {
+ case ERTS_UTF8_OK:
+ ASSERT(no_chars <= MAX_ATOM_CHARACTERS);
+ break;
+ case ERTS_UTF8_OK_MAX_CHARS:
+ /* Truncated... */
+ if (!trunc)
+ return THE_NON_VALUE;
+ ASSERT(no_chars == MAX_ATOM_CHARACTERS);
+ tlen = err_pos - text;
+ break;
+ default:
+ /* Bad utf8... */
+ return THE_NON_VALUE;
+ }
+ }
+
+ ASSERT(tlen <= MAX_ATOM_SZ_LIMIT);
+ ASSERT(-1 <= no_latin1_chars && no_latin1_chars <= MAX_ATOM_CHARACTERS);
+
+ a.len = tlen;
+ a.latin1_chars = (Sint16) no_latin1_chars;
+ a.name = (byte *) text;
+ atom_write_lock();
+ aix = index_put(&erts_atom_table, (void*) &a);
+ atom_write_unlock();
+ return make_atom(aix);
}
+Eterm
+am_atom_put(const char* name, int len)
+{
+ /* Assumes 7-bit ascii; use erts_atom_put() for other encodings... */
+ return erts_atom_put((byte *) name, len, ERTS_ATOM_ENC_7BIT_ASCII, 1);
+}
int atom_table_size(void)
{
@@ -264,14 +367,19 @@ int atom_table_sz(void)
}
int
-erts_atom_get(const char *name, int len, Eterm* ap)
+erts_atom_get(const char *name, int len, Eterm* ap, ErtsAtomEncoding enc)
{
+ byte utf8_copy[MAX_ATOM_SZ_FROM_LATIN1];
Atom a;
int i;
int res;
- a.len = len;
+ a.len = (Sint16) len;
a.name = (byte *)name;
+ if (enc == ERTS_ATOM_ENC_LATIN1) {
+ latin1_to_utf8(utf8_copy, (const byte**)&a.name, &len);
+ a.len = (Sint16) len;
+ }
atom_read_lock();
i = index_get(&erts_atom_table, (void*) &a);
res = i < 0 ? 0 : (*ap = make_atom(i), 1);
@@ -333,8 +441,15 @@ init_atom_table(void)
for (i = 0; erl_atom_names[i] != 0; i++) {
int ix;
a.len = strlen(erl_atom_names[i]);
+ a.latin1_chars = a.len;
a.name = (byte*)erl_atom_names[i];
a.slot.index = i;
+#ifdef DEBUG
+ /* Verify 7-bit ascii */
+ for (ix = 0; ix < a.len; ix++) {
+ ASSERT((a.name[ix] & 0x80) == 0);
+ }
+#endif
ix = index_put(&erts_atom_table, (void*) &a);
atom_text_pos -= a.len;
atom_space -= a.len;
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index fd9c04d3d0..5904ae0f7e 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -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
@@ -26,7 +26,9 @@
#include "erl_atom_table.h"
-#define MAX_ATOM_LENGTH 255
+#define MAX_ATOM_CHARACTERS 255
+#define MAX_ATOM_SZ_FROM_LATIN1 (2*MAX_ATOM_CHARACTERS)
+#define MAX_ATOM_SZ_LIMIT (4*MAX_ATOM_CHARACTERS) /* theoretical byte limit */
#define ATOM_LIMIT (1024*1024)
#define MIN_ATOM_TABLE_SIZE 8192
@@ -45,7 +47,8 @@
*/
typedef struct atom {
IndexSlot slot; /* MUST BE LOCATED AT TOP OF STRUCT!!! */
- int len; /* length of atom name */
+ Sint16 len; /* length of atom name (UTF-8 encoded) */
+ Sint16 latin1_chars; /* 0-255 if atom can be encoded in latin1; otherwise, -1 */
int ord0; /* ordinal value of first 3 bytes + 7 bits */
byte* name; /* name of atom */
} Atom;
@@ -53,8 +56,8 @@ typedef struct atom {
extern IndexTable erts_atom_table;
ERTS_GLB_INLINE Atom* atom_tab(Uint i);
-ERTS_GLB_INLINE int erts_is_atom_bytes(byte *text, size_t len, Eterm term);
-ERTS_GLB_INLINE int erts_is_atom_str(char *str, Eterm term);
+ERTS_GLB_INLINE int erts_is_atom_utf8_bytes(byte *text, size_t len, Eterm term);
+ERTS_GLB_INLINE int erts_is_atom_str(const char *str, Eterm term, int is_latin1);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
ERTS_GLB_INLINE Atom*
@@ -63,7 +66,7 @@ atom_tab(Uint i)
return (Atom *) erts_index_lookup(&erts_atom_table, i);
}
-ERTS_GLB_INLINE int erts_is_atom_bytes(byte *text, size_t len, Eterm term)
+ERTS_GLB_INLINE int erts_is_atom_utf8_bytes(byte *text, size_t len, Eterm term)
{
Atom *a;
if (!is_atom(term))
@@ -73,43 +76,70 @@ ERTS_GLB_INLINE int erts_is_atom_bytes(byte *text, size_t len, Eterm term)
&& sys_memcmp((void *) a->name, (void *) text, len) == 0);
}
-ERTS_GLB_INLINE int erts_is_atom_str(char *str, Eterm term)
+ERTS_GLB_INLINE int erts_is_atom_str(const char *str, Eterm term, int is_latin1)
{
Atom *a;
int i, len;
- char *aname;
+ const byte* aname;
+ const byte* s = (const byte*) str;
+
if (!is_atom(term))
return 0;
a = atom_tab(atom_val(term));
len = a->len;
- aname = (char *) a->name;
- for (i = 0; i < len; i++)
- if (aname[i] != str[i] || str[i] == '\0')
- return 0;
- return str[len] == '\0';
+ aname = a->name;
+ if (is_latin1) {
+ for (i = 0; i < len; s++) {
+ if (aname[i] < 0x80) {
+ if (aname[i] != *s || *s == '\0')
+ return 0;
+ i++;
+ }
+ else {
+ if (aname[i] != (0xC0 | (*s >> 6)) ||
+ aname[i+1] != (0x80 | (*s & 0x3F))) {
+ return 0;
+ }
+ i += 2;
+ }
+ }
+ }
+ else {
+ for (i = 0; i < len; i++, s++)
+ if (aname[i] != *s || *s == '\0')
+ return 0;
+ }
+ return *s == '\0';
}
#endif
+typedef enum {
+ ERTS_ATOM_ENC_7BIT_ASCII,
+ ERTS_ATOM_ENC_LATIN1,
+ ERTS_ATOM_ENC_UTF8
+} ErtsAtomEncoding;
+
/*
* Note, ERTS_IS_ATOM_STR() expects the first argument to be a
- * string literal.
+ * 7-bit ASCII string literal.
*/
#define ERTS_IS_ATOM_STR(LSTR, TERM) \
- (erts_is_atom_bytes((byte *) LSTR, sizeof(LSTR) - 1, (TERM)))
+ (erts_is_atom_utf8_bytes((byte *) LSTR, sizeof(LSTR) - 1, (TERM)))
#define ERTS_DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
#define ERTS_INIT_AM(S) AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
int atom_table_size(void); /* number of elements */
int atom_table_sz(void); /* table size in bytes, excluding stored objects */
-Eterm am_atom_put(const char*, int); /* most callers pass plain char*'s */
+Eterm am_atom_put(const char*, int); /* ONLY 7-bit ascii! */
+Eterm erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc);
int atom_erase(byte*, int);
int atom_static_put(byte*, int);
void init_atom_table(void);
void atom_info(int, void *);
void dump_atoms(int, void *);
-int erts_atom_get(const char* name, int len, Eterm* ap);
+int erts_atom_get(const char* name, int len, Eterm* ap, ErtsAtomEncoding enc);
void erts_atom_get_text_space_sizes(Uint *reserved, Uint *used);
#endif
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index c47a608215..f138324e1f 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -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
@@ -18,6 +18,8 @@
#
#
+# IMPORTANT! All atoms defined here *need* to be in 7-bit ascii!
+#
# File format:
#
# Lines starting with '#' are ignored.
@@ -144,6 +146,7 @@ atom close
atom closed
atom code
atom command
+atom compact
atom compat_rel
atom compile
atom compressed
@@ -165,6 +168,7 @@ atom current_location
atom current_stacktrace
atom data
atom debug_flags
+atom decimals
atom delay_trap
atom dexit
atom depth
@@ -480,6 +484,7 @@ atom scheduler
atom scheduler_id
atom schedulers_online
atom scheme
+atom scientific
atom scope
atom sensitive
atom sequential_tracer
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index e0a4f86d2d..73264214ce 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -389,16 +389,16 @@ static void smp_code_ix_commiter(void* null)
Process* p = commiter_state.stager;
erts_commit_staging_code_ix();
+#ifdef DEBUG
+ commiter_state.stager = NULL;
+#endif
+ erts_release_code_write_permission();
erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS);
if (!ERTS_PROC_IS_EXITING(p)) {
erts_resume(p, ERTS_PROC_LOCK_STATUS);
}
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
erts_smp_proc_dec_refc(p);
-#ifdef DEBUG
- commiter_state.stager = NULL;
-#endif
- erts_release_code_write_permission();
}
#endif /* ERTS_SMP */
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c
index c1e11f6448..9b17de34ec 100644
--- a/erts/emulator/beam/beam_bp.c
+++ b/erts/emulator/beam/beam_bp.c
@@ -969,7 +969,7 @@ erts_trace_time_call(Process* c_p, BeamInstr* I, BpDataTime* bdt)
if (pbt == 0) {
/* First call of process to instrumented function */
pbt = Alloc(sizeof(process_breakpoint_time_t));
- (void *) ERTS_PROC_SET_CALL_TIME(c_p, ERTS_PROC_LOCK_MAIN, pbt);
+ (void) ERTS_PROC_SET_CALL_TIME(c_p, ERTS_PROC_LOCK_MAIN, pbt);
} else {
ASSERT(pbt->pc);
/* add time to previous code */
diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h
index 28aaaa462a..b061401863 100644
--- a/erts/emulator/beam/beam_bp.h
+++ b/erts/emulator/beam/beam_bp.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
diff --git a/erts/emulator/beam/beam_catches.c b/erts/emulator/beam/beam_catches.c
index 92f7ffe5a2..7c92408eea 100644
--- a/erts/emulator/beam/beam_catches.c
+++ b/erts/emulator/beam/beam_catches.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
diff --git a/erts/emulator/beam/beam_catches.h b/erts/emulator/beam/beam_catches.h
index b2bd2351a5..51ef463b2f 100644
--- a/erts/emulator/beam/beam_catches.h
+++ b/erts/emulator/beam/beam_catches.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index a609ed8c71..e36ec2a93e 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -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
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index b51f076a5d..f57fa2bfbb 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -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
@@ -1230,7 +1230,7 @@ load_atom_table(LoaderState* stp)
GetByte(stp, n);
GetString(stp, atom, n);
- stp->atom[i] = am_atom_put((char*)atom, n);
+ stp->atom[i] = erts_atom_put(atom, n, ERTS_ATOM_ENC_LATIN1, 1);
}
/*
@@ -1240,7 +1240,7 @@ load_atom_table(LoaderState* stp)
if (is_nil(stp->module)) {
stp->module = stp->atom[1];
} else if (stp->atom[1] != stp->module) {
- char sbuf[256];
+ char sbuf[MAX_ATOM_SZ_FROM_LATIN1];
Atom* ap;
ap = atom_tab(atom_val(stp->atom[1]));
@@ -1620,7 +1620,7 @@ read_line_table(LoaderState* stp)
GetInt(stp, 2, n);
GetString(stp, fname, n);
- stp->fname[i] = am_atom_put((char*)fname, n);
+ stp->fname[i] = erts_atom_put(fname, n, ERTS_ATOM_ENC_LATIN1, 1);
}
}
@@ -5904,7 +5904,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
Eterm* tp;
Eterm func;
Eterm arity_term;
- Uint arity;
+ Sint arity;
Uint native_address;
Eterm op;
diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h
index 1048f258a5..65a8f26d7c 100644
--- a/erts/emulator/beam/beam_load.h
+++ b/erts/emulator/beam/beam_load.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2011. 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
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 97c8114437..46f76624a5 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -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
@@ -359,8 +359,7 @@ remote_demonitor(Process *c_p, DistEntry *dep, Eterm ref, Eterm to)
break;
default:
ASSERT(! "Invalid dsig prepare result");
- res = ERTS_DEMONITOR_INTERNAL_ERROR;
- break;
+ return ERTS_DEMONITOR_INTERNAL_ERROR;
}
#ifndef ERTS_SMP
@@ -2604,9 +2603,13 @@ BIF_RETTYPE delete_element_2(BIF_ALIST_3)
BIF_RETTYPE atom_to_list_1(BIF_ALIST_1)
{
- Uint need;
- Eterm* hp;
Atom* ap;
+ Uint num_chars, num_built, num_eaten;
+ byte* err_pos;
+ Eterm res;
+#ifdef DEBUG
+ int ares;
+#endif
if (is_not_atom(BIF_ARG_1))
BIF_ERROR(BIF_P, BADARG);
@@ -2615,9 +2618,18 @@ BIF_RETTYPE atom_to_list_1(BIF_ALIST_1)
ap = atom_tab(atom_val(BIF_ARG_1));
if (ap->len == 0)
BIF_RET(NIL); /* the empty atom */
- need = ap->len*2;
- hp = HAlloc(BIF_P, need);
- BIF_RET(buf_to_intlist(&hp,(char*)ap->name,ap->len, NIL));
+
+#ifdef DEBUG
+ ares =
+#endif
+ erts_analyze_utf8(ap->name, ap->len, &err_pos, &num_chars, NULL);
+ ASSERT(ares == ERTS_UTF8_OK);
+
+ res = erts_utf8_to_list(BIF_P, num_chars, ap->name, ap->len, ap->len,
+ &num_built, &num_eaten, NIL);
+ ASSERT(num_built == num_chars);
+ ASSERT(num_eaten == ap->len);
+ BIF_RET(res);
}
/**********************************************************************/
@@ -2627,18 +2639,19 @@ BIF_RETTYPE atom_to_list_1(BIF_ALIST_1)
BIF_RETTYPE list_to_atom_1(BIF_ALIST_1)
{
Eterm res;
- char *buf = (char *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_LENGTH);
- int i = intlist_to_buf(BIF_ARG_1, buf, MAX_ATOM_LENGTH);
+ char *buf = (char *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_CHARACTERS);
+ int i = intlist_to_buf(BIF_ARG_1, buf, MAX_ATOM_CHARACTERS);
if (i < 0) {
erts_free(ERTS_ALC_T_TMP, (void *) buf);
i = list_length(BIF_ARG_1);
- if (i > MAX_ATOM_LENGTH) {
+ if (i > MAX_ATOM_CHARACTERS) {
BIF_ERROR(BIF_P, SYSTEM_LIMIT);
}
BIF_ERROR(BIF_P, BADARG);
}
- res = am_atom_put(buf, i);
+ res = erts_atom_put((byte *) buf, i, ERTS_ATOM_ENC_LATIN1, 1);
+ ASSERT(is_atom(res));
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_RET(res);
}
@@ -2648,16 +2661,16 @@ BIF_RETTYPE list_to_atom_1(BIF_ALIST_1)
BIF_RETTYPE list_to_existing_atom_1(BIF_ALIST_1)
{
int i;
- char *buf = (char *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_LENGTH);
+ char *buf = (char *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_CHARACTERS);
- if ((i = intlist_to_buf(BIF_ARG_1, buf, MAX_ATOM_LENGTH)) < 0) {
+ if ((i = intlist_to_buf(BIF_ARG_1, buf, MAX_ATOM_CHARACTERS)) < 0) {
error:
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_ERROR(BIF_P, BADARG);
} else {
Eterm a;
- if (erts_atom_get(buf, i, &a)) {
+ if (erts_atom_get(buf, i, &a, ERTS_ATOM_ENC_LATIN1)) {
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_RET(a);
} else {
@@ -2917,7 +2930,73 @@ BIF_RETTYPE float_to_list_1(BIF_ALIST_1)
need = i*2;
hp = HAlloc(BIF_P, need);
BIF_RET(buf_to_intlist(&hp, fbuf, i, NIL));
- }
+}
+
+BIF_RETTYPE float_to_list_2(BIF_ALIST_2)
+{
+ const static int arity_two = make_arityval(2);
+ int decimals = SYS_DEFAULT_FLOAT_DECIMALS;
+ int compact = 0;
+ enum fmt_type_ {
+ FMT_LEGACY,
+ FMT_FIXED,
+ FMT_SCIENTIFIC
+ } fmt_type = FMT_LEGACY;
+ Eterm list = BIF_ARG_2;
+ Eterm arg;
+ int i;
+ Uint need;
+ Eterm* hp;
+ FloatDef f;
+ char fbuf[256];
+
+ /* check the arguments */
+ if (is_not_float(BIF_ARG_1))
+ goto badarg;
+
+ for(; is_list(list); list = CDR(list_val(list))) {
+ arg = CAR(list_val(list));
+ if (arg == am_compact) {
+ compact = 1;
+ continue;
+ } else if (is_tuple(arg)) {
+ Eterm* tp = tuple_val(arg);
+ if (*tp == arity_two && is_small(tp[2])) {
+ decimals = signed_val(tp[2]);
+ if (decimals > 0 && decimals < sizeof(fbuf) - 6 /* "X." ++ "e+YY" */)
+ switch (tp[1]) {
+ case am_decimals:
+ fmt_type = FMT_FIXED;
+ continue;
+ case am_scientific:
+ fmt_type = FMT_SCIENTIFIC;
+ continue;
+ }
+ }
+ }
+ goto badarg;
+ }
+ if (is_not_nil(list)) {
+ goto badarg;
+ }
+
+ GET_DOUBLE(BIF_ARG_1, f);
+
+ if (fmt_type == FMT_FIXED) {
+ if ((i = sys_double_to_chars_fast(f.fd, fbuf, sizeof(fbuf),
+ decimals, compact)) <= 0)
+ goto badarg;
+ } else {
+ if ((i = sys_double_to_chars_ext(f.fd, fbuf, sizeof(fbuf), decimals)) <= 0)
+ goto badarg;
+ }
+
+ need = i*2;
+ hp = HAlloc(BIF_P, need);
+ BIF_RET(buf_to_intlist(&hp, fbuf, i, NIL));
+badarg:
+ BIF_ERROR(BIF_P, BADARG);
+}
/**********************************************************************/
diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h
index 71f232035d..ceaf747875 100644
--- a/erts/emulator/beam/bif.h
+++ b/erts/emulator/beam/bif.h
@@ -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
@@ -59,6 +59,8 @@ do { \
} while(0)
#define BUMP_REDS(p, gc) do { \
+ ASSERT(p); \
+ ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));\
(p)->fcalls -= (gc); \
if ((p)->fcalls < 0) { \
if (!ERTS_PROC_GET_SAVED_CALLS_BUF((p))) \
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 59a91cd40c..4aaf466008 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -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
@@ -64,6 +64,7 @@ bif erlang:external_size/1
bif erlang:external_size/2
ubif erlang:float/1
bif erlang:float_to_list/1
+bif erlang:float_to_list/2
bif erlang:fun_info/2
bif erlang:garbage_collect/0
bif erlang:garbage_collect/1
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index 4441dab181..dad13f1067 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -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
diff --git a/erts/emulator/beam/code_ix.h b/erts/emulator/beam/code_ix.h
index e2bd0da112..3f4f9776a4 100644
--- a/erts/emulator/beam/code_ix.h
+++ b/erts/emulator/beam/code_ix.h
@@ -76,7 +76,7 @@ ErtsCodeIndex erts_active_code_ix(void);
/* Return staging code ix.
* Only used by a process performing code loading/upgrading/deleting/purging.
- * code_ix must be locked.
+ * Code write permission must be seized.
*/
ERTS_GLB_INLINE
ErtsCodeIndex erts_staging_code_ix(void);
@@ -84,9 +84,10 @@ ErtsCodeIndex erts_staging_code_ix(void);
/* Try seize exclusive code write permission. Needed for code staging.
* Main process lock (only) must be held.
* System thread progress must not be blocked.
+ * Caller must not already hold the code write permission.
* Caller is suspended and *must* yield if 0 is returned.
*/
-int erts_try_seize_code_write_permission(struct process*);
+int erts_try_seize_code_write_permission(struct process* c_p);
/* Release code write permission.
* Will resume any suspended waiters.
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 64cd93a100..59fe7ea418 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -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
@@ -1729,7 +1729,7 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy)
data_size += erts_encode_dist_ext_size(ctl, flags, acmp);
if (is_value(msg))
data_size += erts_encode_dist_ext_size(msg, flags, acmp);
- erts_finalize_atom_cache_map(acmp);
+ erts_finalize_atom_cache_map(acmp, flags);
dhdr_ext_size = erts_encode_ext_dist_header_size(acmp);
data_size += dhdr_ext_size;
@@ -2073,7 +2073,8 @@ erts_dist_command(Port *prt, int reds_limit)
ASSERT(ob);
do {
ob->extp = erts_encode_ext_dist_header_finalize(ob->extp,
- dep->cache);
+ dep->cache,
+ flags);
if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
*--ob->extp = PASS_THROUGH; /* Old node; 'pass through'
needed */
@@ -2117,7 +2118,8 @@ erts_dist_command(Port *prt, int reds_limit)
Uint size;
oq.first->extp
= erts_encode_ext_dist_header_finalize(oq.first->extp,
- dep->cache);
+ dep->cache,
+ flags);
reds += ERTS_PORT_REDS_DIST_CMD_FINALIZE;
if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
*--oq.first->extp = PASS_THROUGH; /* Old node; 'pass through'
@@ -2548,9 +2550,9 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2)
/* By setting dist_entry==erts_this_dist_entry and DISTRIBUTION on
net_kernel do_net_exist will be called when net_kernel
is terminated !! */
- (void *) ERTS_PROC_SET_DIST_ENTRY(net_kernel,
- ERTS_PROC_LOCK_MAIN,
- erts_this_dist_entry);
+ (void) ERTS_PROC_SET_DIST_ENTRY(net_kernel,
+ ERTS_PROC_LOCK_MAIN,
+ erts_this_dist_entry);
erts_refc_inc(&erts_this_dist_entry->refc, 2);
net_kernel->flags |= F_DISTRIBUTION;
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index 2bc3d9c881..ff8f5e106f 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -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
@@ -38,7 +38,8 @@
#define DFLAG_UNICODE_IO 0x1000
#define DFLAG_DIST_HDR_ATOM_CACHE 0x2000
#define DFLAG_SMALL_ATOM_TAGS 0x4000
-#define DFLAGS_INTERNAL_TAGS 0x8000
+#define DFLAG_INTERNAL_TAGS 0x8000
+#define DFLAG_UTF8_ATOMS 0x10000
/* All flags that should be enabled when term_to_binary/1 is used. */
#define TERM_TO_BINARY_DFLAGS (DFLAG_EXTENDED_REFERENCES \
diff --git a/erts/emulator/beam/erl_afit_alloc.c b/erts/emulator/beam/erl_afit_alloc.c
index 306b32691c..5850f80843 100644
--- a/erts/emulator/beam/erl_afit_alloc.c
+++ b/erts/emulator/beam/erl_afit_alloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/beam/erl_afit_alloc.h b/erts/emulator/beam/erl_afit_alloc.h
index 87caccac20..cf7b99c463 100644
--- a/erts/emulator/beam/erl_afit_alloc.h
+++ b/erts/emulator/beam/erl_afit_alloc.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2009. 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
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 5da8c69c03..d748f86d75 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
@@ -3062,13 +3062,13 @@ erts_request_alloc_info(struct process *c_p,
Eterm alloc = CAR(consp);
for (ai = ERTS_ALC_A_MIN; ai <= ERTS_ALC_A_MAX; ai++)
- if (erts_is_atom_str((char *) erts_alc_a2ad[ai], alloc))
+ if (erts_is_atom_str(erts_alc_a2ad[ai], alloc, 0))
goto save_alloc;
- if (erts_is_atom_str("mseg_alloc", alloc)) {
+ if (erts_is_atom_str("mseg_alloc", alloc, 0)) {
ai = ERTS_ALC_INFO_A_MSEG_ALLOC;
goto save_alloc;
}
- if (erts_is_atom_str("alloc_util", alloc)) {
+ if (erts_is_atom_str("alloc_util", alloc, 0)) {
ai = ERTS_ALC_INFO_A_ALLOC_UTIL;
save_alloc:
if (req_ai[ai])
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index d4de0d076a..5e3615ccc2 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -1,7 +1,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
@@ -49,6 +49,8 @@
# true after a "+enable X" statement or if it has been passed as a
# command line argument to make_alloc_types. The variable X is false
# after a "+disable X" statement or if it has never been mentioned.
+#
+# IMPORTANT! Only use 7-bit ascii text in this file!
+if smp
+disable threads_no_smp
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 3d6761339b..187bc2b48b 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
@@ -2906,10 +2906,10 @@ make_name_atoms(Allctr_t *allctr)
char alloc[] = "alloc";
char realloc[] = "realloc";
char free[] = "free";
- char buf[MAX_ATOM_LENGTH];
+ char buf[MAX_ATOM_CHARACTERS];
size_t prefix_len = strlen(allctr->name_prefix);
- if (prefix_len > MAX_ATOM_LENGTH + sizeof(realloc) - 1)
+ if (prefix_len > MAX_ATOM_CHARACTERS + sizeof(realloc) - 1)
erl_exit(1,"Too long allocator name: %salloc\n",allctr->name_prefix);
memcpy((void *) buf, (void *) allctr->name_prefix, prefix_len);
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c
index 86b4696d8f..6ce209085c 100644
--- a/erts/emulator/beam/erl_ao_firstfit_alloc.c
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/beam/erl_bestfit_alloc.c b/erts/emulator/beam/erl_bestfit_alloc.c
index 743cbd93c9..5625622e3f 100644
--- a/erts/emulator/beam/erl_bestfit_alloc.c
+++ b/erts/emulator/beam/erl_bestfit_alloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index 474151d454..0db19a1ee6 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2011. 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
diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c
index ff5ce3cc7a..4302fe8f79 100644
--- a/erts/emulator/beam/erl_bif_chksum.c
+++ b/erts/emulator/beam/erl_bif_chksum.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. 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
diff --git a/erts/emulator/beam/erl_bif_ddll.c b/erts/emulator/beam/erl_bif_ddll.c
index 7cbea55eac..7cea0bc2eb 100644
--- a/erts/emulator/beam/erl_bif_ddll.c
+++ b/erts/emulator/beam/erl_bif_ddll.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2006-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
@@ -1835,7 +1835,10 @@ static Eterm build_load_error_hp(Eterm *hp, int code)
static Eterm mkatom(char *str)
{
- return am_atom_put(str, sys_strlen(str));
+ return erts_atom_put((byte *) str,
+ sys_strlen(str),
+ ERTS_ATOM_ENC_LATIN1,
+ 1);
}
static char *pick_list_or_atom(Eterm name_term)
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index fabddffc68..a601e4fb39 100755
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -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
@@ -2298,8 +2298,10 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
for (i = num_instructions-1; i >= 0; i--) {
res = erts_bld_cons(hpp, hszp,
erts_bld_tuple(hpp, hszp, 2,
- am_atom_put(opc[i].name,
- strlen(opc[i].name)),
+ erts_atom_put(opc[i].name,
+ strlen(opc[i].name),
+ ERTS_ATOM_ENC_LATIN1,
+ 1),
erts_bld_uint(hpp, hszp,
opc[i].count)),
res);
@@ -3286,7 +3288,7 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
else if (ERTS_IS_ATOM_STR("next_pid", BIF_ARG_1)
|| ERTS_IS_ATOM_STR("next_port", BIF_ARG_1)) {
/* Used by node_container_SUITE (emulator) */
- Eterm res;
+ Sint res;
if (ERTS_IS_ATOM_STR("next_pid", BIF_ARG_1))
res = erts_ptab_test_next_id(&erts_proc, 0, 0);
else
@@ -3644,7 +3646,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
Uint next;
if (term_to_Uint(BIF_ARG_2, &next) != 0) {
- Eterm res;
+ Sint res;
if (ERTS_IS_ATOM_STR("next_pid", BIF_ARG_1))
res = erts_ptab_test_next_id(&erts_proc, 1, next);
@@ -3873,7 +3875,7 @@ static Eterm lcnt_build_lock_stats_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_s
timer_ns = stats->timer.ns;
timer_n = stats->timer_n;
- af = am_atom_put(stats->file, strlen(stats->file));
+ af = erts_atom_put(stats->file, strlen(stats->file), ERTS_ATOM_ENC_LATIN1, 1);
uil = erts_bld_uint( hpp, szp, line);
tloc = erts_bld_tuple(hpp, szp, 2, af, uil);
@@ -3910,13 +3912,13 @@ static Eterm lcnt_build_lock_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_t *lock
ASSERT(ltype);
- type = am_atom_put(ltype, strlen(ltype));
- name = am_atom_put(lock->name, strlen(lock->name));
+ type = erts_atom_put(ltype, strlen(ltype), ERTS_ATOM_ENC_LATIN1, 1);
+ name = erts_atom_put(lock->name, strlen(lock->name), ERTS_ATOM_ENC_LATIN1, 1);
if (lock->flag & ERTS_LCNT_LT_ALLOC) {
/* use allocator types names as id's for allocator locks */
ltype = (char *) ERTS_ALC_A2AD(signed_val(lock->id));
- id = am_atom_put(ltype, strlen(ltype));
+ id = erts_atom_put(ltype, strlen(ltype), ERTS_ATOM_ENC_LATIN1, 1);
} else if (lock->flag & ERTS_LCNT_LT_PROCLOCK) {
/* use registered names as id's for process locks if available */
proc = erts_proc_lookup(lock->id);
@@ -3956,12 +3958,12 @@ static Eterm lcnt_build_result_term(Eterm **hpp, Uint *szp, erts_lcnt_data_t *da
dtns = erts_bld_uint( hpp, szp, data->duration.ns);
tdt = erts_bld_tuple(hpp, szp, 2, dts, dtns);
- adur = am_atom_put(str_duration, strlen(str_duration));
+ adur = erts_atom_put(str_duration, strlen(str_duration), ERTS_ATOM_ENC_LATIN1, 1);
tdur = erts_bld_tuple(hpp, szp, 2, adur, tdt);
/* lock tuple */
- aloc = am_atom_put(str_locks, strlen(str_locks));
+ aloc = erts_atom_put(str_locks, strlen(str_locks), ERTS_ATOM_ENC_LATIN1, 1);
for (lock = data->current_locks->head; lock != NULL ; lock = lock->next ) {
lloc = lcnt_build_lock_term(hpp, szp, lock, lloc);
@@ -4097,14 +4099,14 @@ BIF_RETTYPE erts_debug_lock_counters_1(BIF_ALIST_1)
static void os_info_init(void)
{
- Eterm type = am_atom_put(os_type, strlen(os_type));
+ Eterm type = erts_atom_put((byte *) os_type, strlen(os_type), ERTS_ATOM_ENC_LATIN1, 1);
Eterm flav;
int major, minor, build;
char* buf = erts_alloc(ERTS_ALC_T_TMP, 1024); /* More than enough */
Eterm* hp;
os_flavor(buf, 1024);
- flav = am_atom_put(buf, strlen(buf));
+ flav = erts_atom_put((byte *) buf, strlen(buf), ERTS_ATOM_ENC_LATIN1, 1);
erts_free(ERTS_ALC_T_TMP, (void *) buf);
hp = erts_alloc(ERTS_ALC_T_LL_TEMP_TERM, (3+4)*sizeof(Eterm));
os_type_tuple = TUPLE2(hp, type, flav);
diff --git a/erts/emulator/beam/erl_bif_op.c b/erts/emulator/beam/erl_bif_op.c
index d4cd9c89b3..adac0052d6 100644
--- a/erts/emulator/beam/erl_bif_op.c
+++ b/erts/emulator/beam/erl_bif_op.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2010. 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
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 81146e38d7..44fa41c7b6 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -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
@@ -66,7 +66,7 @@ BIF_RETTYPE open_port_2(BIF_ALIST_2)
} else {
str = "einval";
}
- BIF_P->fvalue = am_atom_put(str, strlen(str));
+ BIF_P->fvalue = erts_atom_put((byte *) str, strlen(str), ERTS_ATOM_ENC_LATIN1, 1);
BIF_ERROR(BIF_P, EXC_ERROR);
}
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index 88f980d19f..3d34c2a77f 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2011. 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
@@ -184,6 +184,7 @@ static Eterm make_signed_integer(int x, Process *p)
#define CAPSPEC_VALUES 0
#define CAPSPEC_TYPE 1
#define CAPSPEC_SIZE 2
+#define CAPSPEC_INIT {0,0}
static int /* 0 == ok, < 0 == error */
parse_options(Eterm listp, /* in */
@@ -864,7 +865,7 @@ re_run(Process *p, Eterm arg1, Eterm arg2, Eterm arg3)
size_t code_size;
Uint loop_limit_tmp;
unsigned long loop_count;
- Eterm capture[CAPSPEC_SIZE];
+ Eterm capture[CAPSPEC_SIZE] = CAPSPEC_INIT;
int is_list_cap;
if (parse_options(arg3,&comp_options,&options,&pflags,&startoffset,capture)
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index 99a4394666..69105b8f27 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -386,13 +386,13 @@ static void smp_bp_finisher(void* null)
#ifdef DEBUG
finish_bp.stager = NULL;
#endif
+ erts_release_code_write_permission();
erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS);
if (!ERTS_PROC_IS_EXITING(p)) {
erts_resume(p, ERTS_PROC_LOCK_STATUS);
}
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
erts_smp_proc_dec_refc(p);
- erts_release_code_write_permission();
}
}
#endif /* ERTS_SMP */
diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c
index 3f90f34736..88c6c34881 100644
--- a/erts/emulator/beam/erl_cpu_topology.c
+++ b/erts/emulator/beam/erl_cpu_topology.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2011. 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
@@ -34,7 +34,7 @@
#include "bif.h"
#include "erl_cpu_topology.h"
-#define ERTS_MAX_READER_GROUPS 8
+#define ERTS_MAX_READER_GROUPS 64
/*
* Cpu topology hierarchy.
@@ -620,30 +620,38 @@ write_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size)
int
erts_init_scheduler_bind_type_string(char *how)
{
+ ErtsCpuBindOrder order;
+
if (sys_strcmp(how, "u") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NONE;
- else if (erts_bind_to_cpu(cpuinfo, -1) == -ENOTSUP)
- return ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED;
- else if (!system_cpudata && !user_cpudata)
- return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY;
+ order = ERTS_CPU_BIND_NONE;
else if (sys_strcmp(how, "db") == 0)
- cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND;
+ order = ERTS_CPU_BIND_DEFAULT_BIND;
else if (sys_strcmp(how, "s") == 0)
- cpu_bind_order = ERTS_CPU_BIND_SPREAD;
+ order = ERTS_CPU_BIND_SPREAD;
else if (sys_strcmp(how, "ps") == 0)
- cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD;
+ order = ERTS_CPU_BIND_PROCESSOR_SPREAD;
else if (sys_strcmp(how, "ts") == 0)
- cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD;
+ order = ERTS_CPU_BIND_THREAD_SPREAD;
else if (sys_strcmp(how, "tnnps") == 0)
- cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD;
+ order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD;
else if (sys_strcmp(how, "nnps") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD;
+ order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD;
else if (sys_strcmp(how, "nnts") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
+ order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
else if (sys_strcmp(how, "ns") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
+ order = ERTS_CPU_BIND_NO_SPREAD;
else
- return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE;
+ return ERTS_INIT_SCHED_BIND_TYPE_ERROR_BAD_TYPE;
+
+ if (order != ERTS_CPU_BIND_NONE) {
+ if (erts_bind_to_cpu(cpuinfo, -1) == -ENOTSUP)
+ return ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED;
+ else if (!system_cpudata && !user_cpudata)
+ return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY;
+ }
+
+ cpu_bind_order = order;
+
return ERTS_INIT_SCHED_BIND_TYPE_SUCCESS;
}
diff --git a/erts/emulator/beam/erl_cpu_topology.h b/erts/emulator/beam/erl_cpu_topology.h
index c5a9520b61..b502258dae 100644
--- a/erts/emulator/beam/erl_cpu_topology.h
+++ b/erts/emulator/beam/erl_cpu_topology.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010. 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
@@ -40,7 +40,7 @@ void erts_init_cpu_topology(void);
#define ERTS_INIT_SCHED_BIND_TYPE_SUCCESS 0
#define ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED 1
#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY 2
-#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE 3
+#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_BAD_TYPE 3
int erts_init_scheduler_bind_type_string(char *how);
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 48a95cdf32..d0afc8ed8d 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -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
@@ -3830,7 +3830,7 @@ erts_ets_colliding_names(Process* p, Eterm name, Uint cnt)
while (index >= atom_table_size()) {
char tmp[20];
erts_snprintf(tmp, sizeof(tmp), "am%x", atom_table_size());
- am_atom_put(tmp,strlen(tmp));
+ erts_atom_put((byte *) tmp, strlen(tmp), ERTS_ATOM_ENC_LATIN1, 1);
}
list = CONS(hp, make_atom(index), list);
hp += 2;
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index e9a661efbc..6b62e10eb7 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -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
diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h
index cddd8dfadd..73c4078fc5 100644
--- a/erts/emulator/beam/erl_db_hash.h
+++ b/erts/emulator/beam/erl_db_hash.h
@@ -33,7 +33,7 @@ typedef struct hash_db_term {
DbTerm dbterm; /* The actual term */
} HashDbTerm;
-#define DB_HASH_LOCK_CNT 16
+#define DB_HASH_LOCK_CNT 64
typedef struct db_table_hash_fine_locks {
union {
erts_smp_rwmtx_t lck;
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index faa7f31d99..25029ba90f 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -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
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index bb08762b26..fc1c946c7d 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -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
@@ -4773,7 +4773,8 @@ static int match_compact(ErlHeapFragment *expr, DMCErrInfo *err_info)
ASSERT(j < x);
erts_snprintf(buff+1, sizeof(buff) - 1, "%u", (unsigned) j);
/* Yes, writing directly into terms, they ARE off heap */
- *p = am_atom_put(buff, strlen(buff));
+ *p = erts_atom_put((byte *) buff, strlen(buff),
+ ERTS_ATOM_ENC_LATIN1, 1);
}
++p;
}
diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h
index d8f6e40d2e..90b79e6044 100644
--- a/erts/emulator/beam/erl_db_util.h
+++ b/erts/emulator/beam/erl_db_util.h
@@ -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
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index d50ba364d0..a9a50a10bf 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2011. 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
diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c
index f98d377fd6..c2088929e9 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.c
+++ b/erts/emulator/beam/erl_goodfit_alloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 8db3c28378..223c9c4d7e 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2012. 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
@@ -358,7 +358,7 @@ erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char**
ErlSpawnOpts so;
Eterm env;
- start_mod = am_atom_put(modname, sys_strlen(modname));
+ start_mod = erts_atom_put((byte *) modname, sys_strlen(modname), ERTS_ATOM_ENC_LATIN1, 1);
if (erts_find_function(start_mod, am_start, 2,
erts_active_code_ix()) == NULL) {
erl_exit(5, "No function %s:start/2\n", modname);
@@ -455,7 +455,7 @@ load_preloaded(void)
i = 0;
while ((name = preload_p[i].name) != NULL) {
length = preload_p[i].size;
- module_name = am_atom_put(name, sys_strlen(name));
+ module_name = erts_atom_put((byte *) name, sys_strlen(name), ERTS_ATOM_ENC_LATIN1, 1);
if ((code = sys_preload_begin(&preload_p[i])) == 0)
erl_exit(1, "Failed to find preloaded code for module %s\n",
name);
@@ -523,7 +523,7 @@ void erts_usage(void)
erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n");
erts_fprintf(stderr, "-rg amount set reader groups limit\n");
erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n");
- erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
+ erts_fprintf(stderr, "-stbt type u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
erts_fprintf(stderr, "-sbwt val set scheduler busy wait threshold, valid values are:\n");
erts_fprintf(stderr, " none|very_short|short|medium|long|very_long.\n");
erts_fprintf(stderr, "-scl bool enable/disable compaction of scheduler load,\n");
@@ -531,7 +531,7 @@ void erts_usage(void)
erts_fprintf(stderr, "-sct cput set cpu topology,\n");
erts_fprintf(stderr, " see the erl(1) documentation for more info.\n");
erts_fprintf(stderr, "-sws val set scheduler wakeup strategy, valid values are:\n");
- erts_fprintf(stderr, " default|legacy|proposal.\n");
+ erts_fprintf(stderr, " default|legacy.\n");
erts_fprintf(stderr, "-swt val set scheduler wakeup threshold, valid values are:\n");
erts_fprintf(stderr, " very_low|low|medium|high|very_high.\n");
erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n");
@@ -1240,7 +1240,7 @@ erl_start(int argc, char **argv)
case ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY:
estr = "no cpu topology available";
break;
- case ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE:
+ case ERTS_INIT_SCHED_BIND_TYPE_ERROR_BAD_TYPE:
estr = "invalid type";
break;
default:
@@ -1335,6 +1335,16 @@ erl_start(int argc, char **argv)
}
else if (sys_strcmp("nsp", sub_param) == 0)
erts_use_sender_punish = 0;
+ else if (has_prefix("tbt", sub_param)) {
+ arg = get_arg(sub_param+3, argv[i+1], &i);
+ res = erts_init_scheduler_bind_type_string(arg);
+ if (res == ERTS_INIT_SCHED_BIND_TYPE_ERROR_BAD_TYPE) {
+ erts_fprintf(stderr,
+ "setting scheduler bind type '%s' failed: invalid type\n",
+ arg);
+ erts_usage();
+ }
+ }
else if (sys_strcmp("wt", sub_param) == 0) {
arg = get_arg(sub_param+2, argv[i+1], &i);
if (erts_sched_set_wakeup_other_thresold(arg) != 0) {
@@ -1522,6 +1532,14 @@ erl_start(int argc, char **argv)
i++;
}
+/* Output format on windows for sprintf defaults to three exponents.
+ * We use two-exponent to mimic normal sprintf behaviour.
+ */
+
+#if defined(__WIN32__) && defined(_TWO_DIGIT_EXPONENT)
+ _set_output_format(_TWO_DIGIT_EXPONENT);
+#endif
+
/* Restart will not reinstall the break handler */
#ifdef __WIN32__
if (ignore_break)
diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c
index 963c8b3c58..7f4349556c 100644
--- a/erts/emulator/beam/erl_instrument.c
+++ b/erts/emulator/beam/erl_instrument.c
@@ -775,8 +775,8 @@ Eterm erts_instr_get_memory_map(Process *proc)
ASSERT(hp + 3 == end_hp);
if (mem_anchor) {
- for (bp = mem_anchor; bp->next; bp = bp->next);
-
+ for (bp = mem_anchor; bp->next; bp = bp->next)
+ ;
ASSERT(org_mem_anchor);
org_mem_anchor->prev = bp;
bp->next = org_mem_anchor;
diff --git a/erts/emulator/beam/erl_monitors.c b/erts/emulator/beam/erl_monitors.c
index 63175c44d6..70e592cc5f 100644
--- a/erts/emulator/beam/erl_monitors.c
+++ b/erts/emulator/beam/erl_monitors.c
@@ -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
diff --git a/erts/emulator/beam/erl_monitors.h b/erts/emulator/beam/erl_monitors.h
index a7fa4e0145..6a360a2336 100644
--- a/erts/emulator/beam/erl_monitors.h
+++ b/erts/emulator/beam/erl_monitors.h
@@ -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
diff --git a/erts/emulator/beam/erl_mtrace.c b/erts/emulator/beam/erl_mtrace.c
index 5a6fb8589f..e538ba30c2 100644
--- a/erts/emulator/beam/erl_mtrace.c
+++ b/erts/emulator/beam/erl_mtrace.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 1bd2d933b2..068f904b76 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -743,16 +743,23 @@ int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len,
{
Atom* ap;
ASSERT(encoding == ERL_NIF_LATIN1);
- if (is_not_atom(atom)) {
+ if (is_not_atom(atom) || len==0) {
return 0;
}
ap = atom_tab(atom_val(atom));
- if (ap->len+1 > len) {
+
+ if (ap->latin1_chars < 0 || ap->latin1_chars >= len) {
return 0;
}
- sys_memcpy(buf, ap->name, ap->len);
- buf[ap->len] = '\0';
- return ap->len + 1;
+ if (ap->latin1_chars == ap->len) {
+ sys_memcpy(buf, ap->name, ap->len);
+ }
+ else {
+ int dlen = erts_utf8_to_latin1((byte*)buf, ap->name, ap->len);
+ ASSERT(dlen == ap->latin1_chars); (void)dlen;
+ }
+ buf[ap->latin1_chars] = '\0';
+ return ap->latin1_chars + 1;
}
int enif_get_int(ErlNifEnv* env, Eterm term, int* ip)
@@ -854,7 +861,10 @@ int enif_get_atom_length(ErlNifEnv* env, Eterm atom, unsigned* len,
ASSERT(enc == ERL_NIF_LATIN1);
if (is_not_atom(atom)) return 0;
ap = atom_tab(atom_val(atom));
- *len = ap->len;
+ if (ap->latin1_chars < 0) {
+ return 0;
+ }
+ *len = ap->latin1_chars;
return 1;
}
@@ -961,7 +971,7 @@ ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name)
ERL_NIF_TERM enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)
{
- return am_atom_put(name, len);
+ return erts_atom_put((byte*)name, len, ERTS_ATOM_ENC_LATIN1, 1);
}
int enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom,
@@ -974,7 +984,7 @@ int enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len,
ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)
{
ASSERT(encoding == ERL_NIF_LATIN1);
- return erts_atom_get(name, len, atom);
+ return erts_atom_get(name, len, atom, ERTS_ATOM_ENC_LATIN1);
}
ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
@@ -1633,7 +1643,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
"this vm variant (%s).",
entry->vm_variant, ERL_NIF_VM_VARIANT);
}
- else if (!erts_is_atom_str((char*)entry->name, mod_atom)) {
+ else if (!erts_is_atom_str((char*)entry->name, mod_atom, 1)) {
ret = load_nif_error(BIF_P, bad_lib, "Library module name '%s' does not"
" match calling module '%T'", entry->name, mod_atom);
}
@@ -1643,7 +1653,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
BeamInstr** code_pp;
ErlNifFunc* f = &entry->funcs[i];
- if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom)
+ if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom, ERTS_ATOM_ENC_LATIN1)
|| (code_pp = get_func_pp(mod->curr.code, f_atom, f->arity))==NULL) {
ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u",
mod_atom, f->name, f->arity);
@@ -1746,7 +1756,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs; i++)
{
BeamInstr* code_ptr;
- erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom);
+ erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom, ERTS_ATOM_ENC_LATIN1);
code_ptr = *get_func_pp(mod->curr.code, f_atom, entry->funcs[i].arity);
if (code_ptr[1] == 0) {
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 51ff1eaa48..af27573433 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/erl_node_container_utils.h b/erts/emulator/beam/erl_node_container_utils.h
index 667bda255b..0f93a3a9f0 100644
--- a/erts/emulator/beam/erl_node_container_utils.h
+++ b/erts/emulator/beam/erl_node_container_utils.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2011. 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
diff --git a/erts/emulator/beam/erl_port.h b/erts/emulator/beam/erl_port.h
index fb07f3d5bc..65b4cd0bfe 100644
--- a/erts/emulator/beam/erl_port.h
+++ b/erts/emulator/beam/erl_port.h
@@ -273,29 +273,28 @@ extern erts_smp_atomic_t erts_bytes_in; /* no bytes sent into the system */
(ERTS_PORT_SFLGS_INVALID_LOOKUP \
| ERTS_PORT_SFLG_DISTRIBUTION)
-
/*
* Costs in reductions for some port operations.
*/
-#define ERTS_PORT_REDS_EXECUTE 10
-#define ERTS_PORT_REDS_FREE 100
-#define ERTS_PORT_REDS_TIMEOUT 400
-#define ERTS_PORT_REDS_INPUT 400
-#define ERTS_PORT_REDS_OUTPUT 400
-#define ERTS_PORT_REDS_EVENT 400
-#define ERTS_PORT_REDS_CMD_OUTPUTV 400
-#define ERTS_PORT_REDS_CMD_OUTPUT 400
-#define ERTS_PORT_REDS_EXIT 300
-#define ERTS_PORT_REDS_CONNECT 40
-#define ERTS_PORT_REDS_UNLINK 40
-#define ERTS_PORT_REDS_LINK 40
-#define ERTS_PORT_REDS_BADSIG 40
-#define ERTS_PORT_REDS_CONTROL 400
-#define ERTS_PORT_REDS_CALL 400
-#define ERTS_PORT_REDS_INFO 100
-#define ERTS_PORT_REDS_SET_DATA 40
-#define ERTS_PORT_REDS_GET_DATA 40
-#define ERTS_PORT_REDS_TERMINATE 200
+#define ERTS_PORT_REDS_EXECUTE (CONTEXT_REDS/4)
+#define ERTS_PORT_REDS_FREE (CONTEXT_REDS/400)
+#define ERTS_PORT_REDS_TIMEOUT (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_INPUT (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_OUTPUT (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_EVENT (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_CMD_OUTPUTV (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_CMD_OUTPUT (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_EXIT (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_CONNECT (CONTEXT_REDS/200)
+#define ERTS_PORT_REDS_UNLINK (CONTEXT_REDS/200)
+#define ERTS_PORT_REDS_LINK (CONTEXT_REDS/200)
+#define ERTS_PORT_REDS_BADSIG (CONTEXT_REDS/200)
+#define ERTS_PORT_REDS_CONTROL (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_CALL (CONTEXT_REDS/50)
+#define ERTS_PORT_REDS_INFO (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_SET_DATA (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_GET_DATA (CONTEXT_REDS/100)
+#define ERTS_PORT_REDS_TERMINATE (CONTEXT_REDS/50)
void print_port_info(Port *, int, void *);
void erts_port_free(Port *);
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 8ceadcdb8c..dbc4a06c2d 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2006-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,6 +35,11 @@
#include "dtrace-wrapper.h"
#include <stdarg.h>
+/*
+ * ERTS_PORT_CALLBACK_VREDS: Limit the amount of callback calls we do...
+ */
+#define ERTS_PORT_CALLBACK_VREDS (CONTEXT_REDS/20)
+
#if defined(DEBUG) && 0
#define ERTS_HARD_DEBUG_TASK_QUEUES
#else
@@ -277,11 +282,16 @@ busy_wait_move_to_busy_queue(Port *pp, ErtsPortTask *ptp)
}
else {
int i;
+#ifdef DEBUG
erts_aint32_t flags;
-
+#endif
pp->sched.taskq.local.busy.first = ptp;
- flags = erts_smp_atomic32_read_bor_nob(&pp->sched.flags,
- ERTS_PTS_FLG_HAVE_BUSY_TASKS);
+
+#ifdef DEBUG
+ flags =
+#endif
+ erts_smp_atomic32_read_bor_nob(&pp->sched.flags,
+ ERTS_PTS_FLG_HAVE_BUSY_TASKS);
ASSERT(!(flags & ERTS_PTS_FLG_HAVE_BUSY_TASKS));
ASSERT(!tabp);
@@ -1215,15 +1225,14 @@ erts_port_task_abort(ErtsPortTaskHandle *pthp)
void
erts_port_task_abort_nosuspend_tasks(Port *pp)
{
- erts_aint32_t flags;
ErtsPortTaskHandleList *abort_list;
#ifdef ERTS_SMP
ErtsThrPrgrDelayHandle dhndl = ERTS_THR_PRGR_DHANDLE_INVALID;
#endif
erts_port_task_sched_lock(&pp->sched);
- flags = erts_smp_atomic32_read_band_nob(&pp->sched.flags,
- ~ERTS_PTS_FLG_HAVE_NS_TASKS);
+ erts_smp_atomic32_read_band_nob(&pp->sched.flags,
+ ~ERTS_PTS_FLG_HAVE_NS_TASKS);
abort_list = pp->sched.taskq.local.busy.nosuspend;
pp->sched.taskq.local.busy.nosuspend = NULL;
erts_port_task_sched_unlock(&pp->sched);
@@ -1544,6 +1553,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
ErtsPortTask *execq;
int processing_busy_q;
int res = 0;
+ int vreds = 0;
int reds = ERTS_PORT_REDS_EXECUTE;
erts_aint_t io_tasks_executed = 0;
int fpe_was_unmasked;
@@ -1688,6 +1698,9 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
break;
}
+ vreds += ERTS_PORT_CALLBACK_VREDS;
+ reds += ERTS_PORT_CALLBACK_VREDS;
+
if (reds >= CONTEXT_REDS)
break;
}
@@ -1757,6 +1770,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
res = (erts_smp_atomic_read_nob(&erts_port_task_outstanding_io_tasks)
!= (erts_aint_t) 0);
+ reds -= vreds;
runq->scheduler->reductions += reds;
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(runq));
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index aaca4b5f59..96af19fb83 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -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
@@ -4080,11 +4080,11 @@ typedef enum {
} ErtsSchedWakeupOtherThreshold;
typedef enum {
- ERTS_SCHED_WAKEUP_OTHER_TYPE_PROPOSAL,
+ ERTS_SCHED_WAKEUP_OTHER_TYPE_DEFAULT,
ERTS_SCHED_WAKEUP_OTHER_TYPE_LEGACY
} ErtsSchedWakeupOtherType;
-/* First proposal */
+/* Default */
#define ERTS_WAKEUP_OTHER_LIMIT_VERY_HIGH (200*CONTEXT_REDS)
#define ERTS_WAKEUP_OTHER_LIMIT_HIGH (50*CONTEXT_REDS)
@@ -4101,7 +4101,7 @@ typedef enum {
#define ERTS_WAKEUP_OTHER_DEC_SHIFT 2
#define ERTS_WAKEUP_OTHER_FIXED_INC (CONTEXT_REDS/10)
-/* To be legacy */
+/* Legacy */
#define ERTS_WAKEUP_OTHER_LIMIT_VERY_HIGH_LEGACY (200*CONTEXT_REDS)
#define ERTS_WAKEUP_OTHER_LIMIT_HIGH_LEGACY (50*CONTEXT_REDS)
@@ -4239,7 +4239,7 @@ static void
set_wakeup_other_data(void)
{
switch (wakeup_other.type) {
- case ERTS_SCHED_WAKEUP_OTHER_TYPE_PROPOSAL:
+ case ERTS_SCHED_WAKEUP_OTHER_TYPE_DEFAULT:
wakeup_other.check = wakeup_other_check;
wakeup_other_set_limit();
break;
@@ -4258,7 +4258,7 @@ erts_early_init_scheduling(int no_schedulers)
aux_work_timeout_early_init(no_schedulers);
#ifdef ERTS_SMP
wakeup_other.threshold = ERTS_SCHED_WAKEUP_OTHER_THRESHOLD_MEDIUM;
- wakeup_other.type = ERTS_SCHED_WAKEUP_OTHER_TYPE_LEGACY;
+ wakeup_other.type = ERTS_SCHED_WAKEUP_OTHER_TYPE_DEFAULT;
#endif
sched_busy_wait.sys_schedule = ERTS_SCHED_SYS_SLEEP_SPINCOUNT_MEDIUM;
sched_busy_wait.tse = (ERTS_SCHED_SYS_SLEEP_SPINCOUNT_MEDIUM
@@ -4270,6 +4270,7 @@ erts_early_init_scheduling(int no_schedulers)
int
erts_sched_set_wakeup_other_thresold(char *str)
{
+#ifdef ERTS_SMP
ErtsSchedWakeupOtherThreshold threshold;
if (sys_strcmp(str, "very_high") == 0)
threshold = ERTS_SCHED_WAKEUP_OTHER_THRESHOLD_VERY_HIGH;
@@ -4283,29 +4284,39 @@ erts_sched_set_wakeup_other_thresold(char *str)
threshold = ERTS_SCHED_WAKEUP_OTHER_THRESHOLD_VERY_LOW;
else
return EINVAL;
-#ifdef ERTS_SMP
wakeup_other.threshold = threshold;
set_wakeup_other_data();
-#endif
return 0;
+#else
+ if (sys_strcmp(str, "very_high") == 0 || sys_strcmp(str, "high") == 0 ||
+ sys_strcmp(str, "medium") == 0 || sys_strcmp(str, "low") == 0 ||
+ sys_strcmp(str, "very_low") == 0) {
+ return 0;
+ }
+ return EINVAL;
+#endif
}
int
erts_sched_set_wakeup_other_type(char *str)
{
+#ifdef ERTS_SMP
ErtsSchedWakeupOtherType type;
- if (sys_strcmp(str, "proposal") == 0)
- type = ERTS_SCHED_WAKEUP_OTHER_TYPE_PROPOSAL;
- else if (sys_strcmp(str, "default") == 0)
- type = ERTS_SCHED_WAKEUP_OTHER_TYPE_LEGACY;
+ if (sys_strcmp(str, "default") == 0)
+ type = ERTS_SCHED_WAKEUP_OTHER_TYPE_DEFAULT;
else if (sys_strcmp(str, "legacy") == 0)
type = ERTS_SCHED_WAKEUP_OTHER_TYPE_LEGACY;
else
return EINVAL;
-#ifdef ERTS_SMP
wakeup_other.type = type;
-#endif
return 0;
+#else
+ if (sys_strcmp(str, "proposal") == 0 || sys_strcmp(str, "default") == 0 ||
+ sys_strcmp(str, "legacy") == 0) {
+ return 0;
+ }
+ return EINVAL;
+#endif
}
int
diff --git a/erts/emulator/beam/erl_process_dict.c b/erts/emulator/beam/erl_process_dict.c
index bf384c66e1..a611b52af2 100644
--- a/erts/emulator/beam/erl_process_dict.c
+++ b/erts/emulator/beam/erl_process_dict.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2009. 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
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index ba74dfd6a1..a93229c473 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/beam/erl_sys_driver.h b/erts/emulator/beam/erl_sys_driver.h
index b991a2840c..dab4a94a9b 100644
--- a/erts/emulator/beam/erl_sys_driver.h
+++ b/erts/emulator/beam/erl_sys_driver.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. 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
diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c
index 4587cd84d1..2f206ffbec 100644
--- a/erts/emulator/beam/erl_term.c
+++ b/erts/emulator/beam/erl_term.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index fb3ef9cd6c..953edf79ea 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 51559aea1c..99108af937 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -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
@@ -1154,15 +1154,24 @@ BIF_RETTYPE unicode_characters_to_list_2(BIF_ALIST_2)
* When input to characters_to_list is a plain binary and the format is 'unicode', we do
* a faster analyze and size count with this function.
*/
-int erts_analyze_utf8(byte *source, Uint size,
- byte **err_pos, Uint *num_chars, int *left)
+static ERTS_INLINE int
+analyze_utf8(byte *source, Uint size, byte **err_pos, Uint *num_chars, int *left,
+ Sint *num_latin1_chars, Uint max_chars)
{
+ Uint latin1_count;
+ int is_latin1;
*err_pos = source;
+ if (num_latin1_chars) {
+ is_latin1 = 1;
+ latin1_count = 0;
+ }
*num_chars = 0;
while (size) {
if (((*source) & ((byte) 0x80)) == 0) {
source++;
- --size;
+ --size;
+ if (num_latin1_chars)
+ latin1_count++;
} else if (((*source) & ((byte) 0xE0)) == 0xC0) {
if (size < 2) {
return ERTS_UTF8_INCOMPLETE;
@@ -1171,6 +1180,11 @@ int erts_analyze_utf8(byte *source, Uint size,
((*source) < 0xC2) /* overlong */) {
return ERTS_UTF8_ERROR;
}
+ if (num_latin1_chars) {
+ latin1_count++;
+ if ((source[0] & ((byte) 0xFC)) != ((byte) 0xC0))
+ is_latin1 = 0;
+ }
source += 2;
size -= 2;
} else if (((*source) & ((byte) 0xF0)) == 0xE0) {
@@ -1188,6 +1202,8 @@ int erts_analyze_utf8(byte *source, Uint size,
}
source += 3;
size -= 3;
+ if (num_latin1_chars)
+ is_latin1 = 0;
} else if (((*source) & ((byte) 0xF8)) == 0xF0) {
if (size < 4) {
return ERTS_UTF8_INCOMPLETE;
@@ -1205,21 +1221,40 @@ int erts_analyze_utf8(byte *source, Uint size,
}
source += 4;
size -= 4;
+ if (num_latin1_chars)
+ is_latin1 = 0;
} else {
return ERTS_UTF8_ERROR;
}
++(*num_chars);
*err_pos = source;
- if (left && --(*left) <= 0) {
+ if (max_chars && size > 0 && *num_chars == max_chars)
+ return ERTS_UTF8_OK_MAX_CHARS;
+ if (left && --(*left) <= 0 && size) {
return ERTS_UTF8_ANALYZE_MORE;
}
}
+ if (num_latin1_chars)
+ *num_latin1_chars = is_latin1 ? latin1_count : -1;
return ERTS_UTF8_OK;
}
+int erts_analyze_utf8(byte *source, Uint size,
+ byte **err_pos, Uint *num_chars, int *left)
+{
+ return analyze_utf8(source, size, err_pos, num_chars, left, NULL, 0);
+}
+
+int erts_analyze_utf8_x(byte *source, Uint size,
+ byte **err_pos, Uint *num_chars, int *left,
+ Sint *num_latin1_chars, Uint max_chars)
+{
+ return analyze_utf8(source, size, err_pos, num_chars, left, num_latin1_chars, max_chars);
+}
+
/*
* No errors should be able to occur - no overlongs, no malformed, no nothing
- */
+ */
static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz,
Uint left,
Uint *num_built, Uint *num_eaten, Eterm tail)
@@ -1275,6 +1310,12 @@ static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz,
return ret;
}
+Eterm erts_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, Uint left,
+ Uint *num_built, Uint *num_eaten, Eterm tail)
+{
+ return do_utf8_to_list(p, num, bytes, sz, left, num_built, num_eaten, tail);
+}
+
static int is_candidate(Uint cp)
{
int index,pos;
@@ -1812,31 +1853,25 @@ BIF_RETTYPE atom_to_binary_2(BIF_ALIST_2)
ap = atom_tab(atom_val(BIF_ARG_1));
if (BIF_ARG_2 == am_latin1) {
- BIF_RET(new_binary(BIF_P, ap->name, ap->len));
- } else if (BIF_ARG_2 == am_utf8 || BIF_ARG_2 == am_unicode) {
- int bin_size = 0;
- int i;
Eterm bin_term;
- byte* bin_p;
- for (i = 0; i < ap->len; i++) {
- bin_size += (ap->name[i] >= 0x80) ? 2 : 1;
+ if (ap->latin1_chars < 0) {
+ goto error;
}
- if (bin_size == ap->len) {
- BIF_RET(new_binary(BIF_P, ap->name, ap->len));
+ if (ap->latin1_chars == ap->len) {
+ bin_term = new_binary(BIF_P, ap->name, ap->len);
}
- bin_term = new_binary(BIF_P, 0, bin_size);
- bin_p = binary_bytes(bin_term);
- for (i = 0; i < ap->len; i++) {
- byte b = ap->name[i];
- if (b < 0x80) {
- *bin_p++ = b;
- } else {
- *bin_p++ = 0xC0 | (b >> 6);
- *bin_p++ = 0x80 | (b & 0x3F);
- }
+ else {
+ byte* bin_p;
+ int dbg_sz;
+ bin_term = new_binary(BIF_P, 0, ap->latin1_chars);
+ bin_p = binary_bytes(bin_term);
+ dbg_sz = erts_utf8_to_latin1(bin_p, ap->name, ap->len);
+ ASSERT(dbg_sz == ap->latin1_chars); (void)dbg_sz;
}
BIF_RET(bin_term);
+ } else if (BIF_ARG_2 == am_utf8 || BIF_ARG_2 == am_unicode) {
+ BIF_RET(new_binary(BIF_P, ap->name, ap->len));
} else {
error:
BIF_ERROR(BIF_P, BADARG);
@@ -1844,118 +1879,78 @@ BIF_RETTYPE atom_to_binary_2(BIF_ALIST_2)
}
static BIF_RETTYPE
-binary_to_atom(Process* p, Eterm bin, Eterm enc, int must_exist)
+binary_to_atom(Process* proc, Eterm bin, Eterm enc, int must_exist)
{
byte* bytes;
byte *temp_alloc = NULL;
Uint bin_size;
if ((bytes = erts_get_aligned_binary_bytes(bin, &temp_alloc)) == 0) {
- BIF_ERROR(p, BADARG);
+ BIF_ERROR(proc, BADARG);
}
bin_size = binary_size(bin);
if (enc == am_latin1) {
Eterm a;
- if (bin_size > MAX_ATOM_LENGTH) {
+ if (bin_size > MAX_ATOM_CHARACTERS) {
system_limit:
erts_free_aligned_binary_bytes(temp_alloc);
- BIF_ERROR(p, SYSTEM_LIMIT);
+ BIF_ERROR(proc, SYSTEM_LIMIT);
}
if (!must_exist) {
- a = am_atom_put((char *)bytes, bin_size);
- erts_free_aligned_binary_bytes(temp_alloc);
+ a = erts_atom_put((byte *) bytes,
+ bin_size,
+ ERTS_ATOM_ENC_LATIN1,
+ 0);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ if (is_non_value(a))
+ goto badarg;
BIF_RET(a);
- } else if (erts_atom_get((char *)bytes, bin_size, &a)) {
+ } else if (erts_atom_get((char *)bytes, bin_size, &a, ERTS_ATOM_ENC_LATIN1)) {
erts_free_aligned_binary_bytes(temp_alloc);
BIF_RET(a);
} else {
goto badarg;
}
} else if (enc == am_utf8 || enc == am_unicode) {
- char *buf;
- char *dst;
- int i;
- int num_chars;
Eterm res;
+ Uint num_chars = 0;
+ const byte* p = bytes;
+ Uint left = bin_size;
- if (bin_size > 2*MAX_ATOM_LENGTH) {
- byte* err_pos;
- Uint n;
- int reds_left = bin_size+1; /* Number of reductions left. */
-
- if (erts_analyze_utf8(bytes, bin_size, &err_pos,
- &n, &reds_left) == ERTS_UTF8_OK) {
- /*
- * Correct UTF-8 encoding, but too many characters to
- * fit in an atom.
- */
+ while (left) {
+ if (++num_chars > MAX_ATOM_CHARACTERS) {
goto system_limit;
- } else {
- /*
- * Something wrong in the UTF-8 encoding or Unicode code
- * points > 255.
- */
- goto badarg;
}
- }
-
- /*
- * Allocate a temporary buffer the same size as the binary,
- * so that we don't need an extra overflow test.
- */
- buf = (char *) erts_alloc(ERTS_ALC_T_TMP, bin_size);
- dst = buf;
- for (i = 0; i < bin_size; i++) {
- int c = bytes[i];
- if (c < 0x80) {
- *dst++ = c;
- } else if (i < bin_size-1) {
- int c2;
- if ((c & 0xE0) != 0xC0) {
- goto free_badarg;
- }
- i++;
- c = (c & 0x3F) << 6;
- c2 = bytes[i];
- if ((c2 & 0xC0) != 0x80) {
- goto free_badarg;
- }
- c = c | (c2 & 0x3F);
- if (0x80 <= c && c < 256) {
- *dst++ = c;
- } else {
- goto free_badarg;
- }
- } else {
- free_badarg:
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- goto badarg;
+ if ((p[0] & 0x80) == 0) {
+ ++p;
+ --left;
}
+ else if (left >= 2
+ && (p[0] & 0xFE) == 0xC2 /* only allow latin1 subset */
+ && (p[1] & 0xC0) == 0x80) {
+ p += 2;
+ left -= 2;
+ }
+ else goto badarg;
}
- num_chars = dst - buf;
- if (num_chars > MAX_ATOM_LENGTH) {
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- goto system_limit;
- }
+
if (!must_exist) {
- res = am_atom_put(buf, num_chars);
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- erts_free_aligned_binary_bytes(temp_alloc);
- BIF_RET(res);
- } else {
- int exists = erts_atom_get(buf, num_chars, &res);
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- if (exists) {
- erts_free_aligned_binary_bytes(temp_alloc);
- BIF_RET(res);
- } else {
- goto badarg;
- }
+ res = erts_atom_put((byte *) bytes,
+ bin_size,
+ ERTS_ATOM_ENC_UTF8,
+ 0);
+ }
+ else if (!erts_atom_get((char*)bytes, bin_size, &res, ERTS_ATOM_ENC_UTF8)) {
+ goto badarg;
}
+ erts_free_aligned_binary_bytes(temp_alloc);
+ if (is_non_value(res))
+ goto badarg;
+ BIF_RET(res);
} else {
badarg:
erts_free_aligned_binary_bytes(temp_alloc);
- BIF_ERROR(p, BADARG);
+ BIF_ERROR(proc, BADARG);
}
}
@@ -2670,3 +2665,28 @@ BIF_RETTYPE file_native_name_encoding_0(BIF_ALIST_0)
}
}
+int erts_utf8_to_latin1(byte* dest, const byte* source, int slen)
+{
+ /*
+ * Assumes source contains valid utf8 that can be encoded as latin1,
+ * and that dest has enough room.
+ */
+ byte* dp = dest;
+
+ while (slen > 0) {
+ if ((source[0] & 0x80) == 0) {
+ *dp++ = *source++;
+ --slen;
+ }
+ else {
+ ASSERT(slen > 1);
+ ASSERT((source[0] & 0xFE) == 0xC2);
+ ASSERT((source[1] & 0xC0) == 0x80);
+ *dp++ = (char) ((source[0] << 6) | (source[1] & 0x3F));
+ source += 2;
+ slen -= 2;
+ }
+ }
+ return dp - dest;
+}
+
diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c
index 6b5121f917..b0f08d8245 100644
--- a/erts/emulator/beam/export.c
+++ b/erts/emulator/beam/export.c
@@ -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
@@ -383,7 +383,9 @@ void export_start_staging(void)
IndexTable* dst = &export_tables[dst_ix];
IndexTable* src = &export_tables[src_ix];
struct export_entry* src_entry;
+#ifdef DEBUG
struct export_entry* dst_entry;
+#endif
int i;
ASSERT(dst_ix != src_ix);
@@ -396,7 +398,10 @@ void export_start_staging(void)
for (i = 0; i < src->entries; i++) {
src_entry = (struct export_entry*) erts_index_lookup(src, i);
src_entry->ep->addressv[dst_ix] = src_entry->ep->addressv[src_ix];
- dst_entry = (struct export_entry*) index_put_entry(dst, src_entry);
+#ifdef DEBUG
+ dst_entry = (struct export_entry*)
+#endif
+ index_put_entry(dst, src_entry);
ASSERT(entry_to_blob(src_entry) == entry_to_blob(dst_entry));
}
export_staging_unlock();
diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h
index ee06e69aff..61a54de59f 100644
--- a/erts/emulator/beam/export.h
+++ b/erts/emulator/beam/export.h
@@ -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
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index ab1065aaa1..5ce0d97c74 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -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
@@ -142,6 +142,7 @@ erts_init_atom_cache_map(ErtsAtomCacheMap *acmp)
{
if (acmp) {
int ix;
+ acmp->long_atoms = 0;
for (ix = 0; ix < ERTS_ATOM_CACHE_SIZE; ix++)
acmp->cache[ix].iix = -1;
acmp->sz = 0;
@@ -154,6 +155,7 @@ erts_reset_atom_cache_map(ErtsAtomCacheMap *acmp)
{
if (acmp) {
int i;
+ acmp->long_atoms = 0;
for (i = 0; i < acmp->sz; i++) {
ASSERT(0 <= acmp->cix[i] && acmp->cix[i] < ERTS_ATOM_CACHE_SIZE);
acmp->cache[acmp->cix[i]].iix = -1;
@@ -175,9 +177,23 @@ erts_destroy_atom_cache_map(ErtsAtomCacheMap *acmp)
}
static ERTS_INLINE void
-insert_acache_map(ErtsAtomCacheMap *acmp, Eterm atom)
+insert_acache_map(ErtsAtomCacheMap *acmp, Eterm atom, Uint32 dflags)
{
- if (acmp && acmp->sz < ERTS_MAX_INTERNAL_ATOM_CACHE_ENTRIES) {
+ /*
+ * If the receiver do not understand utf8 atoms
+ * and this atom cannot be represented in latin1,
+ * we are not allowed to cache it.
+ *
+ * In this case all atoms are assumed to have
+ * latin1 encoding in the cache. By refusing it
+ * in the cache we will instead encode it using
+ * ATOM_UTF8_EXT/SMALL_ATOM_UTF8_EXT which the
+ * receiver do not recognize and tear down the
+ * connection.
+ */
+ if (acmp && acmp->sz < ERTS_MAX_INTERNAL_ATOM_CACHE_ENTRIES
+ && ((dflags & DFLAG_UTF8_ATOMS)
+ || atom_tab(atom_val(atom))->latin1_chars >= 0)) {
int ix;
ASSERT(acmp->hdr_sz < 0);
ix = atom2cix(atom);
@@ -190,7 +206,7 @@ insert_acache_map(ErtsAtomCacheMap *acmp, Eterm atom)
}
static ERTS_INLINE int
-get_iix_acache_map(ErtsAtomCacheMap *acmp, Eterm atom)
+get_iix_acache_map(ErtsAtomCacheMap *acmp, Eterm atom, Uint32 dflags)
{
if (!acmp)
return -1;
@@ -199,7 +215,9 @@ get_iix_acache_map(ErtsAtomCacheMap *acmp, Eterm atom)
ASSERT(is_atom(atom));
ix = atom2cix(atom);
if (acmp->cache[ix].iix < 0) {
- ASSERT(acmp->sz == ERTS_MAX_INTERNAL_ATOM_CACHE_ENTRIES);
+ ASSERT(acmp->sz == ERTS_MAX_INTERNAL_ATOM_CACHE_ENTRIES
+ || (!(dflags & DFLAG_UTF8_ATOMS)
+ && atom_tab(atom_val(atom))->latin1_chars < 0));
return -1;
}
else {
@@ -210,18 +228,17 @@ get_iix_acache_map(ErtsAtomCacheMap *acmp, Eterm atom)
}
void
-erts_finalize_atom_cache_map(ErtsAtomCacheMap *acmp)
+erts_finalize_atom_cache_map(ErtsAtomCacheMap *acmp, Uint32 dflags)
{
if (acmp) {
-#if MAX_ATOM_LENGTH > 255
-#error "This code is not complete; long_atoms info need to be passed to the following stages."
- int long_atoms = 0; /* !0 if one or more atoms are long than 255. */
-#endif
+ int utf8_atoms = (int) (dflags & DFLAG_UTF8_ATOMS);
+ int long_atoms = 0; /* !0 if one or more atoms are longer than 255. */
int i;
int sz;
int fix_sz
= 1 /* VERSION_MAGIC */
+ 1 /* DIST_HEADER */
+ + 1 /* dist header flags */
+ 1 /* number of internal cache entries */
;
int min_sz;
@@ -230,22 +247,23 @@ erts_finalize_atom_cache_map(ErtsAtomCacheMap *acmp)
min_sz = fix_sz+(2+4)*acmp->sz;
sz = fix_sz;
for (i = 0; i < acmp->sz; i++) {
+ Atom *a;
Eterm atom;
int len;
atom = acmp->cache[acmp->cix[i]].atom;
ASSERT(is_atom(atom));
- len = atom_tab(atom_val(atom))->len;
-#if MAX_ATOM_LENGTH > 255
+ a = atom_tab(atom_val(atom));
+ len = (int) (utf8_atoms ? a->len : a->latin1_chars);
+ ASSERT(len >= 0);
if (!long_atoms && len > 255)
long_atoms = 1;
-#endif
/* Enough for a new atom cache value */
sz += 1 /* cix */ + 1 /* length */ + len /* text */;
}
-#if MAX_ATOM_LENGTH > 255
- if (long_atoms)
+ if (long_atoms) {
+ acmp->long_atoms = 1;
sz += acmp->sz; /* we need 2 bytes per atom for length */
-#endif
+ }
/* Dynamically sized flag field */
sz += ERTS_DIST_HDR_ATOM_CACHE_FLAG_BYTES(acmp->sz);
if (sz < min_sz)
@@ -274,6 +292,7 @@ byte *erts_encode_ext_dist_header_setup(byte *ctl_ext, ErtsAtomCacheMap *acmp)
else {
int i;
byte *ep = ctl_ext;
+ byte dist_hdr_flags = acmp->long_atoms ? ERTS_DIST_HDR_LONG_ATOMS_FLG : 0;
ASSERT(acmp->hdr_sz >= 0);
/*
* Write cache update instructions. Note that this is a purely
@@ -296,28 +315,36 @@ byte *erts_encode_ext_dist_header_setup(byte *ctl_ext, ErtsAtomCacheMap *acmp)
}
--ep;
put_int8(acmp->sz, ep);
+ --ep;
+ put_int8(dist_hdr_flags, ep);
*--ep = DIST_HEADER;
*--ep = VERSION_MAGIC;
return ep;
}
}
-byte *erts_encode_ext_dist_header_finalize(byte *ext, ErtsAtomCache *cache)
+byte *erts_encode_ext_dist_header_finalize(byte *ext, ErtsAtomCache *cache, Uint32 dflags)
{
byte *ip;
byte instr_buf[(2+4)*ERTS_ATOM_CACHE_SIZE];
int ci, sz;
+ byte dist_hdr_flags;
+ int long_atoms;
+ int utf8_atoms = (int) (dflags & DFLAG_UTF8_ATOMS);
register byte *ep = ext;
ASSERT(ep[0] == VERSION_MAGIC);
if (ep[1] != DIST_HEADER)
return ext;
+ dist_hdr_flags = ep[2];
+ long_atoms = ERTS_DIST_HDR_LONG_ATOMS_FLG & ((int) dist_hdr_flags);
+
/*
* Update output atom cache and write the external version of
* the dist header. We write the header backwards just
* before the actual term(s).
*/
- ep += 2;
+ ep += 3;
ci = (int) get_int8(ep);
ASSERT(0 <= ci && ci < ERTS_ATOM_CACHE_SIZE);
ep += 1;
@@ -342,12 +369,7 @@ byte *erts_encode_ext_dist_header_finalize(byte *ext, ErtsAtomCache *cache)
flgs_bytes = ERTS_DIST_HDR_ATOM_CACHE_FLAG_BYTES(ci);
ASSERT(flgs_bytes <= sizeof(flgs_buf));
-#if MAX_ATOM_LENGTH > 255
- /* long_atoms info needs to be passed from previous stages */
- if (long_atoms)
- flgs |= ERTS_DIST_HDR_LONG_ATOMS_FLG;
-#endif
- flgs = 0;
+ flgs = (Uint32) dist_hdr_flags;
flgs_buf_ix = 0;
if ((ci & 1) == 0)
used_half_bytes = 2;
@@ -382,17 +404,22 @@ byte *erts_encode_ext_dist_header_finalize(byte *ext, ErtsAtomCache *cache)
Atom *a;
cache->out_arr[cix] = atom;
a = atom_tab(atom_val(atom));
- sz = a->len;
- ep -= sz;
- sys_memcpy((void *) ep, (void *) a->name, sz);
-#if MAX_ATOM_LENGTH > 255
+ if (utf8_atoms) {
+ sz = a->len;
+ ep -= sz;
+ sys_memcpy((void *) ep, (void *) a->name, sz);
+ }
+ else {
+ ASSERT(0 <= a->latin1_chars && a->latin1_chars <= MAX_ATOM_CHARACTERS);
+ ep -= a->latin1_chars;
+ sz = erts_utf8_to_latin1(ep, a->name, a->len);
+ ASSERT(a->latin1_chars == sz);
+ }
if (long_atoms) {
ep -= 2;
put_int16(sz, ep);
}
- else
-#endif
- {
+ else {
ASSERT(0 <= sz && sz <= 255);
--ep;
put_int8(sz, ep);
@@ -467,7 +494,7 @@ Uint erts_encode_ext_size_2(Eterm term, unsigned dflags)
Uint erts_encode_ext_size_ets(Eterm term)
{
- return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS);
+ return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAG_INTERNAL_TAGS);
}
@@ -500,7 +527,7 @@ void erts_encode_ext(Eterm term, byte **ext)
byte* erts_encode_ext_ets(Eterm term, byte *ep, struct erl_off_heap_header** off_heap)
{
- return enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS,
+ return enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS|DFLAG_INTERNAL_TAGS,
off_heap);
}
@@ -553,6 +580,7 @@ erts_prepare_dist_ext(ErtsDistExternal *edep,
#endif
register byte *ep = ext;
+ int utf8_atoms = (int) (dep->flags & DFLAG_UTF8_ATOMS);
edep->heap_size = -1;
edep->ext_endp = ext+size;
@@ -611,9 +639,7 @@ erts_prepare_dist_ext(ErtsDistExternal *edep,
ERTS_EXT_HDR_FAIL;
ep++;
if (no_atoms) {
-#if MAX_ATOM_LENGTH > 255
int long_atoms = 0;
-#endif
#ifdef DEBUG
byte *flgs_buf = ep;
#endif
@@ -632,14 +658,8 @@ erts_prepare_dist_ext(ErtsDistExternal *edep,
*/
byte_ix = ERTS_DIST_HDR_ATOM_CACHE_FLAG_BYTE_IX(no_atoms);
bit_ix = ERTS_DIST_HDR_ATOM_CACHE_FLAG_BIT_IX(no_atoms);
- if (flgsp[byte_ix] & (((byte) ERTS_DIST_HDR_LONG_ATOMS_FLG)
- << bit_ix)) {
-#if MAX_ATOM_LENGTH > 255
+ if (flgsp[byte_ix] & (((byte) ERTS_DIST_HDR_LONG_ATOMS_FLG) << bit_ix))
long_atoms = 1;
-#else
- ERTS_EXT_HDR_FAIL; /* Long atoms not supported yet */
-#endif
- }
#ifdef DEBUG
byte_ix = 0;
@@ -707,23 +727,25 @@ erts_prepare_dist_ext(ErtsDistExternal *edep,
if (cix >= ERTS_ATOM_CACHE_SIZE)
ERTS_EXT_HDR_FAIL;
ep++;
-#if MAX_ATOM_LENGTH > 255
if (long_atoms) {
CHKSIZE(2);
len = get_int16(ep);
ep += 2;
}
- else
-#endif
- {
+ else {
CHKSIZE(1);
len = get_int8(ep);
ep++;
}
- if (len > MAX_ATOM_LENGTH)
- ERTS_EXT_HDR_FAIL; /* Too long atom */
CHKSIZE(len);
- atom = am_atom_put((char *) ep, len);
+ atom = erts_atom_put((byte *) ep,
+ len,
+ (utf8_atoms
+ ? ERTS_ATOM_ENC_UTF8
+ : ERTS_ATOM_ENC_LATIN1),
+ 0);
+ if (is_non_value(atom))
+ ERTS_EXT_HDR_FAIL;
ep += len;
cache->in_arr[cix] = atom;
edep->attab.atom[tix] = atom;
@@ -926,7 +948,7 @@ BIF_RETTYPE erts_debug_dist_ext_to_term_2(BIF_ALIST_2)
Eterm res;
Eterm *hp;
Eterm *hendp;
- Uint hsz;
+ Sint hsz;
ErtsDistExternal ede;
Eterm *tp;
Eterm real_bin;
@@ -972,7 +994,7 @@ BIF_RETTYPE erts_debug_dist_ext_to_term_2(BIF_ALIST_2)
if (hsz < 0)
goto badarg;
- hp = HAlloc(BIF_P, hsz);
+ hp = HAlloc(BIF_P, (Uint) hsz);
hendp = hp + hsz;
res = erts_decode_dist_ext(&hp, &MSO(BIF_P), &ede);
@@ -1404,11 +1426,12 @@ static byte*
enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
{
int iix;
- int i, j;
+ int len;
+ int utf8_atoms = (int) (dflags & DFLAG_UTF8_ATOMS);
ASSERT(is_atom(atom));
- if (dflags & DFLAGS_INTERNAL_TAGS) {
+ if (dflags & DFLAG_INTERNAL_TAGS) {
Uint aval = atom_val(atom);
ASSERT(aval < (1<<24));
if (aval >= (1 << 16)) {
@@ -1423,27 +1446,56 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
}
return ep;
}
+
/*
* term_to_binary/1,2 and the initial distribution message
* don't use the cache.
*/
- iix = get_iix_acache_map(acmp, atom);
- if (iix < 0) {
- i = atom_val(atom);
- j = atom_tab(i)->len;
- if ((MAX_ATOM_LENGTH <= 255 || j <= 255)
- && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
- *ep++ = SMALL_ATOM_EXT;
- put_int8(j, ep);
- ep++;
+
+ iix = get_iix_acache_map(acmp, atom, dflags);
+ if (iix < 0) {
+ Atom *a = atom_tab(atom_val(atom));
+ len = a->len;
+ if (utf8_atoms || a->latin1_chars < 0) {
+ if (len > 255) {
+ *ep++ = ATOM_UTF8_EXT;
+ put_int16(len, ep);
+ ep += 2;
+ }
+ else {
+ *ep++ = SMALL_ATOM_UTF8_EXT;
+ put_int8(len, ep);
+ ep += 1;
+ }
+ sys_memcpy((char *) ep, (char *) a->name, len);
}
else {
- *ep++ = ATOM_EXT;
- put_int16(j, ep);
- ep += 2;
+ if (a->latin1_chars <= 255 && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
+ *ep++ = SMALL_ATOM_EXT;
+ if (len == a->latin1_chars) {
+ sys_memcpy(ep+1, a->name, len);
+ }
+ else {
+ len = erts_utf8_to_latin1(ep+1, a->name, len);
+ ASSERT(len == a->latin1_chars);
+ }
+ put_int8(len, ep);
+ ep++;
+ }
+ else {
+ *ep++ = ATOM_EXT;
+ if (len == a->latin1_chars) {
+ sys_memcpy(ep+2, a->name, len);
+ }
+ else {
+ len = erts_utf8_to_latin1(ep+2, a->name, len);
+ ASSERT(len == a->latin1_chars);
+ }
+ put_int16(len, ep);
+ ep += 2;
+ }
}
- sys_memcpy((char *) ep, (char*)atom_tab(i)->name, (int) j);
- ep += j;
+ ep += len;
return ep;
}
@@ -1472,7 +1524,7 @@ enc_pid(ErtsAtomCacheMap *acmp, Eterm pid, byte* ep, Uint32 dflags)
ep += 4;
put_int32(os, ep);
ep += 4;
- *ep++ = (is_internal_pid(pid) && (dflags & DFLAGS_INTERNAL_TAGS)) ?
+ *ep++ = (is_internal_pid(pid) && (dflags & DFLAG_INTERNAL_TAGS)) ?
INTERNAL_CREATION : pid_creation(pid);
return ep;
}
@@ -1483,6 +1535,7 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
{
Uint len;
int n;
+ ErtsAtomEncoding char_enc;
switch (*ep++) {
case ATOM_CACHE_REF:
@@ -1498,17 +1551,32 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
case ATOM_EXT:
len = get_int16(ep),
ep += 2;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
goto dec_atom_common;
case SMALL_ATOM_EXT:
len = get_int8(ep);
ep++;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
+ goto dec_atom_common;
+ case ATOM_UTF8_EXT:
+ len = get_int16(ep),
+ ep += 2;
+ char_enc = ERTS_ATOM_ENC_UTF8;
+ goto dec_atom_common;
+ case SMALL_ATOM_UTF8_EXT:
+ len = get_int8(ep),
+ ep++;
+ char_enc = ERTS_ATOM_ENC_UTF8;
dec_atom_common:
if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
- if (!erts_atom_get((char*)ep, len, objp)) {
+ if (!erts_atom_get((char*)ep, len, objp, char_enc)) {
goto error;
}
} else {
- *objp = am_atom_put((char*)ep, len);
+ Eterm atom = erts_atom_put(ep, len, char_enc, 0);
+ if (is_non_value(atom))
+ goto error;
+ *objp = atom;
}
ep += len;
break;
@@ -1770,7 +1838,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags,
put_int16(i, ep);
ep += 2;
ep = enc_atom(acmp,ref_node_name(obj),ep,dflags);
- *ep++ = ((dflags & DFLAGS_INTERNAL_TAGS) && is_internal_ref(obj)) ?
+ *ep++ = ((dflags & DFLAG_INTERNAL_TAGS) && is_internal_ref(obj)) ?
INTERNAL_CREATION : ref_creation(obj);
ref_num = ref_numbers(obj);
for (j = 0; j < i; j++) {
@@ -1787,7 +1855,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags,
j = port_number(obj);
put_int32(j, ep);
ep += 4;
- *ep++ = ((dflags & DFLAGS_INTERNAL_TAGS) && is_internal_port(obj)) ?
+ *ep++ = ((dflags & DFLAG_INTERNAL_TAGS) && is_internal_port(obj)) ?
INTERNAL_CREATION : port_creation(obj);
break;
@@ -1868,7 +1936,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags,
byte* bytes;
ERTS_GET_BINARY_BYTES(obj, bytes, bitoffs, bitsize);
- if (dflags & DFLAGS_INTERNAL_TAGS) {
+ if (dflags & DFLAG_INTERNAL_TAGS) {
ProcBin* pb = (ProcBin*) binary_val(obj);
Uint bytesize = pb->size;
if (pb->thing_word == HEADER_SUB_BIN) {
@@ -2114,6 +2182,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
{
Eterm* hp_saved = *hpp;
int n;
+ ErtsAtomEncoding char_enc;
register Eterm* hp = *hpp; /* Please don't take the address of hp */
Eterm* next = objp;
@@ -2199,17 +2268,32 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
case ATOM_EXT:
n = get_int16(ep);
ep += 2;
- goto dec_term_atom_common;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
+ goto dec_term_atom_common;
case SMALL_ATOM_EXT:
n = get_int8(ep);
ep++;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
+ goto dec_term_atom_common;
+ case ATOM_UTF8_EXT:
+ n = get_int16(ep);
+ ep += 2;
+ char_enc = ERTS_ATOM_ENC_UTF8;
+ goto dec_term_atom_common;
+ case SMALL_ATOM_UTF8_EXT:
+ n = get_int8(ep);
+ ep++;
+ char_enc = ERTS_ATOM_ENC_UTF8;
dec_term_atom_common:
if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
- if (!erts_atom_get((char*)ep, n, objp)) {
+ if (!erts_atom_get((char*)ep, n, objp, char_enc)) {
goto error;
}
} else {
- *objp = am_atom_put((char*)ep, n);
+ Eterm atom = erts_atom_put(ep, n, char_enc, 0);
+ if (is_non_value(atom))
+ goto error;
+ *objp = atom;
}
ep += n;
break;
@@ -2869,7 +2953,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
result++;
break;
case ATOM_DEF:
- if (dflags & DFLAGS_INTERNAL_TAGS) {
+ if (dflags & DFLAG_INTERNAL_TAGS) {
if (atom_val(obj) >= (1<<16)) {
result += 1 + 3;
}
@@ -2878,17 +2962,22 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
}
}
else {
- int alen = atom_tab(atom_val(obj))->len;
- if ((MAX_ATOM_LENGTH <= 255 || alen <= 255)
- && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
- /* Make sure a SMALL_ATOM_EXT fits: SMALL_ATOM_EXT l t1 t2... */
- result += 1 + 1 + alen;
+ Atom *a = atom_tab(atom_val(obj));
+ int alen;
+ if ((dflags & DFLAG_UTF8_ATOMS) || a->latin1_chars < 0) {
+ alen = a->len;
+ result += 1 + 1 + alen;
+ if (alen > 255) {
+ result++; /* ATOM_UTF8_EXT (not small) */
+ }
}
else {
- /* Make sure an ATOM_EXT fits: ATOM_EXT l1 l0 t1 t2... */
- result += 1 + 2 + alen;
+ alen = a->latin1_chars;
+ result += 1 + 1 + alen;
+ if (alen > 255 || !(dflags & DFLAG_SMALL_ATOM_TAGS))
+ result++; /* ATOM_EXT (not small) */
}
- insert_acache_map(acmp, obj);
+ insert_acache_map(acmp, obj, dflags);
}
break;
case SMALL_DEF:
@@ -2969,7 +3058,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
}
break;
case BINARY_DEF:
- if (dflags & DFLAGS_INTERNAL_TAGS) {
+ if (dflags & DFLAG_INTERNAL_TAGS) {
ProcBin* pb = (ProcBin*) binary_val(obj);
Uint sub_extra = 0;
Uint tot_bytes = pb->size;
@@ -3058,6 +3147,17 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
return result;
}
+static int is_valid_utf8_atom(byte* bytes, Uint nbytes)
+{
+ byte* err_pos;
+ Uint num_chars;
+
+ /*SVERK Do we really need to validate correct utf8? */
+ return nbytes <= MAX_ATOM_SZ_LIMIT
+ && erts_analyze_utf8(bytes, nbytes, &err_pos, &num_chars, NULL) == ERTS_UTF8_OK
+ && num_chars <= MAX_ATOM_CHARACTERS;
+}
+
static Sint
decoded_size(byte *ep, byte* endp, int internal_tags)
{
@@ -3125,21 +3225,41 @@ decoded_size(byte *ep, byte* endp, int internal_tags)
case ATOM_EXT:
CHKSIZE(2);
n = get_int16(ep);
- if (n > MAX_ATOM_LENGTH) {
+ if (n > MAX_ATOM_CHARACTERS) {
return -1;
}
SKIP(n+2+atom_extra_skip);
atom_extra_skip = 0;
break;
+ case ATOM_UTF8_EXT:
+ CHKSIZE(2);
+ n = get_int16(ep);
+ ep += 2;
+ if (!is_valid_utf8_atom(ep, n)) {
+ return -1;
+ }
+ SKIP(n+atom_extra_skip);
+ atom_extra_skip = 0;
+ break;
case SMALL_ATOM_EXT:
CHKSIZE(1);
n = get_int8(ep);
- if (n > MAX_ATOM_LENGTH) {
+ if (n > MAX_ATOM_CHARACTERS) {
return -1;
}
SKIP(n+1+atom_extra_skip);
atom_extra_skip = 0;
break;
+ case SMALL_ATOM_UTF8_EXT:
+ CHKSIZE(1);
+ n = get_int8(ep);
+ ep++;
+ if (!is_valid_utf8_atom(ep, n)) {
+ return -1;
+ }
+ SKIP(n+atom_extra_skip);
+ atom_extra_skip = 0;
+ break;
case ATOM_CACHE_REF:
SKIP(1+atom_extra_skip);
atom_extra_skip = 0;
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index eddd4571dd..e37d47919e 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -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
@@ -51,6 +51,8 @@
#define NEW_FUN_EXT 'p'
#define EXPORT_EXT 'q'
#define FUN_EXT 'u'
+#define ATOM_UTF8_EXT 'v'
+#define SMALL_ATOM_UTF8_EXT 'w'
#define DIST_HEADER 'D'
#define ATOM_CACHE_REF 'R'
@@ -90,6 +92,7 @@ typedef struct cache {
typedef struct {
int hdr_sz;
int sz;
+ int long_atoms;
int cix[ERTS_ATOM_CACHE_SIZE];
struct {
Eterm atom;
@@ -150,12 +153,12 @@ typedef struct {
void erts_init_atom_cache_map(ErtsAtomCacheMap *);
void erts_reset_atom_cache_map(ErtsAtomCacheMap *);
void erts_destroy_atom_cache_map(ErtsAtomCacheMap *);
-void erts_finalize_atom_cache_map(ErtsAtomCacheMap *);
+void erts_finalize_atom_cache_map(ErtsAtomCacheMap *, Uint32);
Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *);
Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *);
byte *erts_encode_ext_dist_header_setup(byte *, ErtsAtomCacheMap *);
-byte *erts_encode_ext_dist_header_finalize(byte *, ErtsAtomCache *);
+byte *erts_encode_ext_dist_header_finalize(byte *, ErtsAtomCache *, Uint32);
Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *);
void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 298241618f..012c1c7e6a 100755
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -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
@@ -786,16 +786,23 @@ Sint erts_native_filename_need(Eterm ioterm, int encoding);
void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars);
int erts_analyze_utf8(byte *source, Uint size,
byte **err_pos, Uint *num_chars, int *left);
+int erts_analyze_utf8_x(byte *source, Uint size,
+ byte **err_pos, Uint *num_chars, int *left,
+ Sint *num_latin1_chars, Uint max_chars);
char *erts_convert_filename_to_native(Eterm name, char *statbuf,
size_t statbuf_size,
ErtsAlcType_t alloc_type,
int allow_empty, int allow_atom,
Sint *used /* out */);
Eterm erts_convert_native_to_filename(Process *p, byte *bytes);
+Eterm erts_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, Uint left,
+ Uint *num_built, Uint *num_eaten, Eterm tail);
+int erts_utf8_to_latin1(byte* dest, const byte* source, int slen);
#define ERTS_UTF8_OK 0
#define ERTS_UTF8_INCOMPLETE 1
#define ERTS_UTF8_ERROR 2
#define ERTS_UTF8_ANALYZE_MORE 3
+#define ERTS_UTF8_OK_MAX_CHARS 4
void bin_write(int, void*, byte*, size_t);
int intlist_to_buf(Eterm, char*, int); /* most callers pass plain char*'s */
diff --git a/erts/emulator/beam/index.h b/erts/emulator/beam/index.h
index 3afe48d007..537bc11056 100644
--- a/erts/emulator/beam/index.h
+++ b/erts/emulator/beam/index.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. 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
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index e466f0e299..3ea4b24848 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -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
@@ -663,8 +663,11 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */
if (IS_TRACED_FL(port, F_TRACE_PORTS)) {
trace_port_open(port,
- pid,
- am_atom_put(port->name, strlen(port->name)));
+ pid,
+ erts_atom_put((byte *) port->name,
+ strlen(port->name),
+ ERTS_ATOM_ENC_LATIN1,
+ 1));
}
error_number = error_type = 0;
@@ -1573,6 +1576,8 @@ bad_port_signal(Process *c_p,
try_call_state.state,
flags & ERTS_PORT_SIG_FLG_BAD_OUTPUT);
finalize_imm_drv_call(&try_call_state);
+ if (c_p)
+ BUMP_REDS(c_p, ERTS_PORT_REDS_BADSIG);
return ERTS_PORT_OP_BADARG;
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
return ERTS_PORT_OP_DROPPED;
@@ -1950,10 +1955,11 @@ erts_port_output(Process *c_p,
driver_free_binary(cbin);
if (evp != &ev)
erts_free(ERTS_ALC_T_TMP, evp);
- if (try_call_res == ERTS_TRY_IMM_DRV_CALL_OK)
- return ERTS_PORT_OP_DONE;
- else
+ if (try_call_res != ERTS_TRY_IMM_DRV_CALL_OK)
return ERTS_PORT_OP_DROPPED;
+ if (c_p)
+ BUMP_REDS(c_p, ERTS_PORT_REDS_CMD_OUTPUTV);
+ return ERTS_PORT_OP_DONE;
case ERTS_TRY_IMM_DRV_CALL_INVALID_SCHED_FLAGS:
sched_flags = try_call_state.sched_flags;
case ERTS_TRY_IMM_DRV_CALL_BUSY_LOCK:
@@ -2096,10 +2102,11 @@ erts_port_output(Process *c_p,
/* Fall through... */
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
erts_free(ERTS_ALC_T_TMP, buf);
- if (try_call_res == ERTS_TRY_IMM_DRV_CALL_OK)
- return ERTS_PORT_OP_DONE;
- else
+ if (try_call_res != ERTS_TRY_IMM_DRV_CALL_OK)
return ERTS_PORT_OP_DROPPED;
+ if (c_p)
+ BUMP_REDS(c_p, ERTS_PORT_REDS_CMD_OUTPUT);
+ return ERTS_PORT_OP_DONE;
case ERTS_TRY_IMM_DRV_CALL_INVALID_SCHED_FLAGS:
sched_flags = try_call_state.sched_flags;
case ERTS_TRY_IMM_DRV_CALL_BUSY_LOCK:
@@ -2267,6 +2274,8 @@ erts_port_exit(Process *c_p,
reason,
flags & ERTS_PORT_SIG_FLG_BROKEN_LINK);
finalize_imm_drv_call(&try_call_state);
+ if (res == ERTS_PORT_OP_DONE && c_p)
+ BUMP_REDS(c_p, ERTS_PORT_REDS_EXIT);
return res;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
@@ -2434,6 +2443,8 @@ erts_port_connect(Process *c_p,
try_call_state.state,
connect_id);
finalize_imm_drv_call(&try_call_state);
+ if (res == ERTS_PORT_OP_DONE)
+ BUMP_REDS(c_p, ERTS_PORT_REDS_CONNECT);
return res;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
@@ -2492,6 +2503,7 @@ erts_port_unlink(Process *c_p, Port *prt, Eterm from, Eterm *refp)
case ERTS_TRY_IMM_DRV_CALL_OK:
port_unlink(prt, from);
finalize_imm_drv_call(&try_call_state);
+ BUMP_REDS(c_p, ERTS_PORT_REDS_UNLINK);
return ERTS_PORT_OP_DONE;
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
return ERTS_PORT_OP_DROPPED;
@@ -2579,6 +2591,7 @@ erts_port_link(Process *c_p, Port *prt, Eterm to, Eterm *refp)
case ERTS_TRY_IMM_DRV_CALL_OK:
port_link(prt, try_call_state.state, to);
finalize_imm_drv_call(&try_call_state);
+ BUMP_REDS(c_p, ERTS_PORT_REDS_LINK);
return ERTS_PORT_OP_DONE;
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
return ERTS_PORT_OP_BADARG;
@@ -2667,8 +2680,11 @@ static ERTS_INLINE void lcnt_enable_drv_lock_count(erts_driver_t *dp, int enable
erts_lcnt_init_lock_x(&dp->lock->lcnt,
"driver_lock",
ERTS_LCNT_LT_MUTEX,
- am_atom_put(dp->name,
- sys_strlen(dp->name)));
+ erts_atom_put((byte*)dp->name,
+ sys_strlen(dp->name),
+ ERTS_ATOM_ENC_LATIN1,
+ 1));
+
else
erts_lcnt_destroy_lock(&dp->lock->lcnt);
@@ -3944,6 +3960,7 @@ erts_port_control(Process* c_p,
&hp,
NULL,
&c_p->off_heap);
+ BUMP_REDS(c_p, ERTS_PORT_REDS_CONTROL);
return ERTS_PORT_OP_DONE;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
@@ -4241,9 +4258,10 @@ erts_port_call(Process* c_p,
*retvalp = TUPLE2(hp, am_ok, term);
hp += 3;
HRelease(c_p, hp_end, hp);
- if (resp_buf != &resp_buf[0]
+ if (resp_bufp != &resp_buf[0]
&& !(ret_flags & DRIVER_CALL_KEEP_BUFFER))
- driver_free(resp_buf);
+ driver_free(resp_bufp);
+ BUMP_REDS(c_p, ERTS_PORT_REDS_CALL);
return ERTS_PORT_OP_DONE;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
@@ -4423,6 +4441,7 @@ erts_port_info(Process* c_p,
*retvalp = copy_struct(value, used_h_size, &hp, &MSO(c_p));
free_message_buffer(bp);
}
+ BUMP_REDS(c_p, ERTS_PORT_REDS_INFO);
return ERTS_PORT_OP_DONE;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
@@ -4509,6 +4528,7 @@ erts_port_set_data(Process* c_p,
prt->bp = bp;
prt->data = set_data;
finalize_imm_drv_call(&try_call_state);
+ BUMP_REDS(c_p, ERTS_PORT_REDS_SET_DATA);
return ERTS_PORT_OP_DONE;
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
return ERTS_PORT_OP_DROPPED;
@@ -4641,6 +4661,7 @@ erts_port_get_data(Process* c_p,
free_message_buffer(bp);
}
*retvalp = TUPLE2(hp, am_ok, data);
+ BUMP_REDS(c_p, ERTS_PORT_REDS_GET_DATA);
return ERTS_PORT_OP_DONE;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
@@ -7028,7 +7049,8 @@ int driver_exit(ErlDrvPort ix, int err)
return driver_failure_term(ix, am_normal, 0);
else {
char* err_str = erl_errno_id(err);
- Eterm am_err = am_atom_put(err_str, sys_strlen(err_str));
+ Eterm am_err = erts_atom_put((byte *) err_str, sys_strlen(err_str),
+ ERTS_ATOM_ENC_LATIN1, 1);
return driver_failure_term(ix, am_err, 0);
}
}
@@ -7041,8 +7063,12 @@ int driver_failure(ErlDrvPort ix, int code)
int driver_failure_atom(ErlDrvPort ix, char* string)
{
- Eterm am = am_atom_put(string, strlen(string));
- return driver_failure_term(ix, am, 0);
+ return driver_failure_term(ix,
+ erts_atom_put((byte *) string,
+ strlen(string),
+ ERTS_ATOM_ENC_LATIN1,
+ 1),
+ 0);
}
int driver_failure_posix(ErlDrvPort ix, int err)
@@ -7059,7 +7085,10 @@ int driver_failure_eof(ErlDrvPort ix)
ErlDrvTermData driver_mk_atom(char* string)
{
- Eterm am = am_atom_put(string, sys_strlen(string));
+ Eterm am = erts_atom_put((byte *) string,
+ sys_strlen(string),
+ ERTS_ATOM_ENC_LATIN1,
+ 1);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return (ErlDrvTermData) am;
}
@@ -7354,7 +7383,10 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle)
erts_mtx_init_x(drv->lock,
"driver_lock",
#if defined(ERTS_ENABLE_LOCK_CHECK) || defined(ERTS_ENABLE_LOCK_COUNT)
- am_atom_put(drv->name, sys_strlen(drv->name))
+ erts_atom_put((byte *) drv->name,
+ sys_strlen(drv->name),
+ ERTS_ATOM_ENC_LATIN1,
+ 1)
#else
NIL
#endif
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c
index 01856007ee..daa6e136c5 100644
--- a/erts/emulator/beam/module.c
+++ b/erts/emulator/beam/module.c
@@ -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
diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h
index 6e123a0ffe..5235528e98 100644
--- a/erts/emulator/beam/module.h
+++ b/erts/emulator/beam/module.h
@@ -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
diff --git a/erts/emulator/beam/packet_parser.c b/erts/emulator/beam/packet_parser.c
index f1cfa8df39..1e301e3593 100644
--- a/erts/emulator/beam/packet_parser.c
+++ b/erts/emulator/beam/packet_parser.c
@@ -460,11 +460,9 @@ int packet_get_length(enum PacketParseType htype,
hp = (struct tpkt_head*) ptr;
if (hp->vrsn == TPKT_VRSN) {
plen = get_int16(hp->packet_length) - hlen;
- if (plen < 0)
- goto error;
- }
- else
+ } else {
goto error;
+ }
goto remain;
}
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index 757e2800e6..c626cb2780 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -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
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 898a30b010..249a9c05c2 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -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
@@ -729,9 +729,12 @@ char * getenv_string(GETENV_STATE *);
void fini_getenv_state(GETENV_STATE *);
/* xxxP */
+#define SYS_DEFAULT_FLOAT_DECIMALS 20
void init_sys_float(void);
int sys_chars_to_double(char*, double*);
int sys_double_to_chars(double, char*, size_t);
+int sys_double_to_chars_ext(double, char*, size_t, size_t);
+int sys_double_to_chars_fast(double, char*, int, int, int);
void sys_get_pid(char *, size_t);
/* erts_sys_putenv() returns, 0 on success and a value != 0 on failure. */
diff --git a/erts/emulator/beam/time.c b/erts/emulator/beam/time.c
index 932d157cd8..2fd8e0cf00 100644
--- a/erts/emulator/beam/time.c
+++ b/erts/emulator/beam/time.c
@@ -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
@@ -105,7 +105,14 @@ static ErlTimer *tiw_min_ptr;
/* END tiw_lock protected variables */
/* Actual interval time chosen by sys_init_time() */
-static int itime; /* Constant after init */
+
+#if SYS_CLOCK_RESOLUTION == 1
+# define TIW_ITIME 1
+# define TIW_ITIME_IS_CONSTANT
+#else
+static int tiw_itime; /* Constant after init */
+# define TIW_ITIME tiw_itime
+#endif
erts_smp_atomic32_t do_time; /* set at clock interrupt */
static ERTS_INLINE erts_short_time_t do_time_read(void)
@@ -123,7 +130,7 @@ static ERTS_INLINE void do_time_init(void)
erts_smp_atomic32_init_nob(&do_time, 0);
}
-/* get the time (in units of itime) to the next timeout,
+/* get the time (in units of TIW_ITIME) to the next timeout,
or -1 if there are no timeouts */
static erts_short_time_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
@@ -305,11 +312,18 @@ erts_timer_wheel_memory_size(void)
void
erts_init_time(void)
{
- int i;
+ int i, itime;
/* system dependent init; must be done before do_time_init()
if timer thread is enabled */
itime = erts_init_time_sup();
+#ifdef TIW_ITIME_IS_CONSTANT
+ if (itime != TIW_ITIME) {
+ erl_exit(ERTS_ABORT_EXIT, "timer resolution mismatch %d != %d", itime, TIW_ITIME);
+ }
+#else
+ tiw_itime = itime;
+#endif
erts_smp_mtx_init(&tiw_lock, "timer_wheel");
@@ -340,7 +354,7 @@ insert_timer(ErlTimer* p, Uint t)
*
* (x + y - 1)/y is precisely the "number of bins" formula.
*/
- ticks = (t + itime - 1) / itime;
+ ticks = (t + (TIW_ITIME - 1)) / TIW_ITIME;
/*
* Ticks must be a Uint64, or the addition may overflow here,
@@ -455,7 +469,7 @@ erts_time_left(ErlTimer *p)
erts_smp_mtx_unlock(&tiw_lock);
- return (Uint) left * itime;
+ return (Uint) left * TIW_ITIME;
}
#ifdef DEBUG
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 5261effef9..a8f15fdc38 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -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
@@ -371,7 +371,7 @@ Eterm
erts_bld_atom(Uint **hpp, Uint *szp, char *str)
{
if (hpp)
- return am_atom_put(str, sys_strlen(str));
+ return erts_atom_put((byte *) str, sys_strlen(str), ERTS_ATOM_ENC_LATIN1, 1);
else
return THE_NON_VALUE;
}
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index 25b02db2c9..fda6cf2e53 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -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
@@ -57,7 +57,7 @@
#define FILE_FADVISE 31
#define FILE_SENDFILE 32
#define FILE_FALLOCATE 33
-
+#define FILE_CLOSE_ON_PORT_EXIT 34
/* Return codes */
#define FILE_RESP_OK 0
@@ -178,6 +178,7 @@ dt_private *get_dt_private(int);
#define MUTEX_LOCK(m) do { IF_THRDS { TRACE_DRIVER; driver_pdl_lock(m); } } while (0)
#define MUTEX_UNLOCK(m) do { IF_THRDS { TRACE_DRIVER; driver_pdl_unlock(m); } } while (0)
#else
+#define IF_THRDS if (0)
#define MUTEX_INIT(m, p)
#define MUTEX_LOCK(m)
#define MUTEX_UNLOCK(m)
@@ -429,6 +430,7 @@ struct t_data
int level;
void (*invoke)(void *);
void (*free)(void *);
+ void *data_to_free; /* used by FILE_CLOSE_ON_PORT_EXIT only */
int again;
int reply;
#ifdef USE_VM_PROBES
@@ -808,34 +810,25 @@ static void free_data(void *data)
{
struct t_data *d = (struct t_data *) data;
- if (d->command == FILE_OPEN && d->is_fd_unused && d->fd != FILE_FD_INVALID) {
- do_close(d->flags, d->fd);
+ switch (d->command) {
+ case FILE_OPEN:
+ if (d->is_fd_unused && d->fd != FILE_FD_INVALID) {
+ /* This is OK to do in scheduler thread because there can be no async op
+ ongoing for this fd here, as we exited during async open.
+ Ideally, this close should happen in an async thread too, but that would
+ require a substantial rewrite, as we are here because of a dead port and
+ cannot schedule async jobs for that port any more... */
+ do_close(d->flags, d->fd);
+ }
+ break;
+ case FILE_CLOSE_ON_PORT_EXIT:
+ EF_FREE(d->data_to_free);
+ break;
}
EF_FREE(data);
}
-/*********************************************************************
- * Driver entry point -> stop
- */
-static void
-file_stop(ErlDrvData e)
-{
- file_descriptor* desc = (file_descriptor*)e;
-
- TRACE_C('p');
-
- if (desc->fd != FILE_FD_INVALID) {
- do_close(desc->flags, desc->fd);
- desc->fd = FILE_FD_INVALID;
- desc->flags = 0;
- }
- if (desc->read_binp) {
- driver_free_binary(desc->read_binp);
- }
- EF_FREE(desc);
-}
-
/*
* Sends back an error reply to Erlang.
@@ -2242,6 +2235,47 @@ static int lseek_flush_read(file_descriptor *desc, int *errp
}
+/*********************************************************************
+ * Driver entry point -> stop
+ * The close has to be scheduled on async thread, so that currently active
+ * async operation does not suddenly have the ground disappearing under their feet...
+ */
+static void
+file_stop(ErlDrvData e)
+{
+ file_descriptor* desc = (file_descriptor*)e;
+
+ TRACE_C('p');
+
+ IF_THRDS {
+ flush_read(desc);
+ if (desc->fd != FILE_FD_INVALID) {
+ struct t_data *d = EF_SAFE_ALLOC(sizeof(struct t_data));
+ d->command = FILE_CLOSE_ON_PORT_EXIT;
+ d->reply = !0;
+ d->fd = desc->fd;
+ d->flags = desc->flags;
+ d->invoke = invoke_close;
+ d->free = free_data;
+ d->level = 2;
+ d->data_to_free = (void *) desc;
+ cq_enq(desc, d);
+ desc->fd = FILE_FD_INVALID;
+ desc->flags = 0;
+ cq_execute(desc);
+ }
+ } else {
+ if (desc->fd != FILE_FD_INVALID) {
+ do_close(desc->flags, desc->fd);
+ desc->fd = FILE_FD_INVALID;
+ desc->flags = 0;
+ }
+ if (desc->read_binp) {
+ driver_free_binary(desc->read_binp);
+ }
+ EF_FREE(desc);
+ }
+}
/*********************************************************************
* Driver entry point -> ready_async
@@ -2465,7 +2499,6 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
}
free_readdir(data);
break;
- /* See file_stop */
case FILE_CLOSE:
if (d->reply) {
TRACE_C('K');
@@ -2525,6 +2558,15 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
}
break;
#endif
+ case FILE_CLOSE_ON_PORT_EXIT:
+ /* See file_stop. However this is never invoked after the port is killed. */
+ free_data(data);
+ EF_FREE(desc);
+ desc = NULL;
+ /* This is it for this port, so just send dtrace and return, avoid doing anything to the freed data */
+ DTRACE6(efile_drv_return, sched_i1, sched_i2, sched_utag,
+ command, result_ok, posix_errno);
+ return;
default:
abort();
}
@@ -2535,6 +2577,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
driver_set_timer(desc->port, desc->write_delay);
}
cq_execute(desc);
+
}
diff --git a/erts/emulator/drivers/common/gzio.c b/erts/emulator/drivers/common/gzio.c
index ca6d25adb4..e085c262b0 100644
--- a/erts/emulator/drivers/common/gzio.c
+++ b/erts/emulator/drivers/common/gzio.c
@@ -13,6 +13,7 @@
# include "config.h"
#endif
#include <stdio.h>
+#include <string.h> /* ssize_t on Mac OS X */
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -314,7 +315,7 @@ local int get_byte(s)
if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) {
#ifdef UNIX
- size_t res;
+ ssize_t res;
errno = 0;
res = ERTS_GZREAD(s->file, s->inbuf, Z_BUFSIZE);
if (res == 0) {
@@ -487,7 +488,7 @@ erts_gzread(gzFile file, voidp buf, unsigned len)
}
if (s->stream.avail_in == 0 && !s->z_eof) {
#ifdef UNIX
- size_t res;
+ ssize_t res;
errno = 0;
res = ERTS_GZREAD(s->file, s->inbuf, Z_BUFSIZE);
if (res == 0) {
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 236b8710fb..f0c22e9ebe 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -933,12 +933,20 @@ typedef struct {
int bufsz; /* minimum buffer constraint */
unsigned int hsz; /* the list header size, -1 is large !!! */
/* statistics */
- unsigned long recv_oct[2]; /* number of received octets >= 64 bits */
+#ifdef ARCH_64
+ Uint64 recv_oct; /* number of received octets, 64 bits */
+#else
+ Uint32 recv_oct[2]; /* number of received octets, 64 bits */
+#endif
unsigned long recv_cnt; /* number of packets received */
unsigned long recv_max; /* maximum packet size received */
double recv_avg; /* average packet size received */
double recv_dvi; /* avarage deviation from avg_size */
- unsigned long send_oct[2]; /* number of octets sent >= 64 bits */
+#ifdef ARCH_64
+ Uint64 send_oct; /* number of octets sent, 64 bits */
+#else
+ Uint32 send_oct[2]; /* number of octets sent, 64 bits */
+#endif
unsigned long send_cnt; /* number of packets sent */
unsigned long send_max; /* maximum packet send */
double send_avg; /* average packet size sent */
@@ -7377,13 +7385,21 @@ static ErlDrvSSizeT inet_fill_stat(inet_descriptor* desc,
val = (unsigned long) driver_sizeq(desc->port);
break;
case INET_STAT_RECV_OCT:
+#ifdef ARCH_64
+ put_int64(desc->recv_oct, dst); /* write it all */
+#else
put_int32(desc->recv_oct[1], dst); /* write high 32bit */
put_int32(desc->recv_oct[0], dst+4); /* write low 32bit */
+#endif
dst += 8;
continue;
case INET_STAT_SEND_OCT:
+#ifdef ARCH_64
+ put_int64(desc->send_oct, dst); /* write it all */
+#else
put_int32(desc->send_oct[1], dst); /* write high 32bit */
put_int32(desc->send_oct[0], dst+4); /* write low 32bit */
+#endif
dst += 8;
continue;
default: return -1; /* invalid argument */
@@ -7491,12 +7507,20 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)
desc->peer_ptr = NULL;
desc->name_ptr = NULL;
+#ifdef ARCH_64
+ desc->recv_oct = 0;
+#else
desc->recv_oct[0] = desc->recv_oct[1] = 0;
+#endif
desc->recv_cnt = 0;
desc->recv_max = 0;
desc->recv_avg = 0.0;
desc->recv_dvi = 0.0;
+#ifdef ARCH_64
+ desc->send_oct = 0;
+#else
desc->send_oct[0] = desc->send_oct[1] = 0;
+#endif
desc->send_cnt = 0;
desc->send_max = 0;
desc->send_avg = 0.0;
@@ -7885,14 +7909,19 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
static void inet_output_count(inet_descriptor* desc, ErlDrvSizeT len)
{
unsigned long n = desc->send_cnt + 1;
- unsigned long t = desc->send_oct[0] + len;
+#ifndef ARCH_64
+ Uint32 t = desc->send_oct[0] + len;
int c = (t < desc->send_oct[0]);
+#endif
double avg = desc->send_avg;
- /* at least 64 bit octet count */
+#ifdef ARCH_64
+ desc->send_oct += len;
+#else
+ /* 64 bit octet count in 32 bit words */
desc->send_oct[0] = t;
desc->send_oct[1] += c;
-
+#endif
if (n == 0) /* WRAP, use old avg as input to a new sequence */
n = 1;
desc->send_avg += (len - avg) / n;
@@ -7905,14 +7934,20 @@ static void inet_output_count(inet_descriptor* desc, ErlDrvSizeT len)
static void inet_input_count(inet_descriptor* desc, ErlDrvSizeT len)
{
unsigned long n = desc->recv_cnt + 1;
- unsigned long t = desc->recv_oct[0] + len;
+#ifndef ARCH_64
+ Uint32 t = (desc->recv_oct[0] + len);
int c = (t < desc->recv_oct[0]);
+#endif
double avg = desc->recv_avg;
double dvi;
- /* at least 64 bit octet count */
+#ifdef ARCH_64
+ desc->recv_oct += len;
+#else
+ /* 64 bit octet count in 32 bit words */
desc->recv_oct[0] = t;
desc->recv_oct[1] += c;
+#endif
if (n == 0) /* WRAP */
n = 1;
@@ -9723,6 +9758,7 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
DEBUGF(("tcp_inet_output(%ld): s=%d, About to send %d items\r\n",
(long)desc->inet.port, desc->inet.s, vsize));
if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s, iov, vsize, &n, 0))) {
+ write_error:
if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) {
DEBUGF(("tcp_inet_output(%ld): sock_sendv(%d) errno = %d\r\n",
(long)desc->inet.port, vsize, sock_errno()));
@@ -9733,6 +9769,22 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
desc->inet.send_would_block = 1;
#endif
goto done;
+ } else if (n == 0) { /* Workaround for redhat/CentOS 6.3 returning
+ 0 when sending packets with
+ sizes > (max 32 bit signed int) */
+ size_t howmuch = 0x7FFFFFFF; /* max signed 32 bit */
+ int x;
+ for(x = 0; x < vsize && iov[x].iov_len == 0; ++x)
+ ;
+ if (x < vsize) {
+ if (howmuch > iov[x].iov_len) {
+ howmuch = iov[x].iov_len;
+ }
+ n = sock_send(desc->inet.s, iov[x].iov_base,howmuch,0);
+ if (IS_SOCKET_ERROR(n)) {
+ goto write_error;
+ }
+ }
}
if (driver_deq(ix, n) <= desc->low) {
if (IS_BUSY(INETP(desc))) {
diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c
index ab2abb88d1..8912d148a5 100644
--- a/erts/emulator/drivers/unix/ttsl_drv.c
+++ b/erts/emulator/drivers/unix/ttsl_drv.c
@@ -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
diff --git a/erts/emulator/drivers/win32/registry_drv.c b/erts/emulator/drivers/win32/registry_drv.c
index 5b200ebd32..e908c956ae 100644
--- a/erts/emulator/drivers/win32/registry_drv.c
+++ b/erts/emulator/drivers/win32/registry_drv.c
@@ -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
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index f5011d11a5..f2b0c8a843 100644
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.c
@@ -41,6 +41,8 @@
#define IS_DOT_OR_DOTDOT(s) \
((s)[0] == L'.' && ((s)[1] == L'\0' || ((s)[1] == L'.' && (s)[2] == L'\0')))
+#define FILE_SHARE_FLAGS (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
+
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD) 0xFFFFFFFF)
#endif
@@ -724,7 +726,7 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */
crFlags = CREATE_NEW;
}
fd = CreateFileW(wname, access,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_SHARE_FLAGS,
NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL);
/*
@@ -909,7 +911,7 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
{
HANDLE handle; /* Handle returned by CreateFile() */
BY_HANDLE_FILE_INFORMATION fileInfo; /* from CreateFile() */
- if (handle = CreateFileW(name, GENERIC_READ, 0,NULL,
+ if (handle = CreateFileW(name, GENERIC_READ, FILE_SHARE_FLAGS, NULL,
OPEN_EXISTING, 0, NULL)) {
GetFileInformationByHandle(handle, &fileInfo);
pInfo->links = fileInfo.nNumberOfLinks;
@@ -1021,7 +1023,7 @@ efile_write_info(Efile_error* errInfo,
}
fd = CreateFileW(wname, GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SHARE_FLAGS,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd != INVALID_HANDLE_VALUE) {
BOOL result = SetFileTime(fd, &CreationFileTime, &AccessFileTime, &ModifyFileTime);
@@ -1384,7 +1386,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)
DWORD fileAttributes = GetFileAttributesW(wname);
if ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
BOOLEAN success = 0;
- HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ HANDLE h = CreateFileW(wname, GENERIC_READ, FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
int len;
if(h != INVALID_HANDLE_VALUE) {
success = pGetFinalPathNameByHandle(h, wbuffer, size / sizeof(WCHAR),0);
diff --git a/erts/emulator/hipe/hipe_debug.c b/erts/emulator/hipe/hipe_debug.c
index f2e9d03607..bf25ba82af 100644
--- a/erts/emulator/hipe/hipe_debug.c
+++ b/erts/emulator/hipe/hipe_debug.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2011. 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
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index 3c782b2f56..adc8793469 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -2,7 +2,7 @@
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2011. 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
diff --git a/erts/emulator/hipe/hipe_x86.c b/erts/emulator/hipe/hipe_x86.c
index 4281730ae2..327c74e9aa 100644
--- a/erts/emulator/hipe/hipe_x86.c
+++ b/erts/emulator/hipe/hipe_x86.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/hipe/hipe_x86_gc.h b/erts/emulator/hipe/hipe_x86_gc.h
index aa4abb6f59..ccb0d2ffb8 100644
--- a/erts/emulator/hipe/hipe_x86_gc.h
+++ b/erts/emulator/hipe/hipe_x86_gc.h
@@ -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
@@ -71,7 +71,7 @@ nstack_walk_init_sdesc(const Process *p, struct nstack_walk_state *state)
state->sdesc0[0].livebits[0] = 0;
# ifdef DEBUG
state->sdesc0[0].dbg_M = 0;
- state->sdesc0[0].dbg_F = am_init;
+ state->sdesc0[0].dbg_F = am_undefined;
state->sdesc0[0].dbg_A = 0;
# endif
/* XXX: this appears to prevent a gcc-4.1.1 bug on x86 */
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index 94f9f76a20..538eea88d1 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index 6f373f13f9..3d0b0f0355 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h
index 502290e4bb..09ed9f41af 100644
--- a/erts/emulator/sys/common/erl_poll.h
+++ b/erts/emulator/sys/common/erl_poll.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2006-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
diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c
index 461e763f03..1bf5fa89f4 100644
--- a/erts/emulator/sys/common/erl_sys_common_misc.c
+++ b/erts/emulator/sys/common/erl_sys_common_misc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2006-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
@@ -105,3 +105,154 @@ int erts_get_native_filename_encoding(void)
{
return filename_encoding;
}
+
+/* For internal use by sys_double_to_chars_fast() */
+static char* float_first_trailing_zero(char* p)
+{
+ for (--p; *p == '0' && *(p-1) == '0'; --p);
+ if (*(p-1) == '.') ++p;
+ return p;
+}
+
+int
+sys_double_to_chars(double fp, char *buffer, size_t buffer_size)
+{
+ return sys_double_to_chars_ext(fp, buffer, buffer_size, SYS_DEFAULT_FLOAT_DECIMALS);
+}
+
+int
+sys_double_to_chars_fast(double f, char *outbuf, int maxlen, int decimals, int compact)
+{
+ enum {
+ FRAC_SIZE = 52
+ , EXP_SIZE = 11
+ , EXP_MASK = (1ll << EXP_SIZE) - 1
+ , FRAC_MASK = (1ll << FRAC_SIZE) - 1
+ , FRAC_MASK2 = (1ll << (FRAC_SIZE + 1)) - 1
+ , MAX_FLOAT = 1ll << (FRAC_SIZE+1)
+ };
+
+ long long mantissa, int_part, int_part2, frac_part;
+ short exp;
+ int sign, i, n, m, max;
+ double absf;
+ union { long long L; double F; } x;
+ char c, *p = outbuf;
+ int digit, roundup;
+
+ x.F = f;
+
+ exp = (x.L >> FRAC_SIZE) & EXP_MASK;
+ mantissa = x.L & FRAC_MASK;
+ sign = x.L >= 0 ? 1 : -1;
+ if (exp == EXP_MASK) {
+ if (mantissa == 0) {
+ if (sign == -1)
+ *p++ = '-';
+ *p++ = 'i';
+ *p++ = 'n';
+ *p++ = 'f';
+ } else {
+ *p++ = 'n';
+ *p++ = 'a';
+ *p++ = 'n';
+ }
+ *p = '\0';
+ return p - outbuf;
+ }
+
+ exp -= EXP_MASK >> 1;
+ mantissa |= (1ll << FRAC_SIZE);
+ frac_part = 0;
+ int_part = 0;
+ absf = f * sign;
+
+ /* Don't bother with optimizing too large numbers and decimals */
+ if (absf > MAX_FLOAT || decimals > maxlen-17) {
+ int len = erts_snprintf(outbuf, maxlen, "%.*f", decimals, f);
+ if (len >= maxlen)
+ return -1;
+ p = outbuf + len;
+ /* Delete trailing zeroes */
+ if (compact)
+ p = float_first_trailing_zero(outbuf + len);
+ *p = '\0';
+ return p - outbuf;
+ }
+
+ if (exp >= FRAC_SIZE)
+ int_part = mantissa << (exp - FRAC_SIZE);
+ else if (exp >= 0) {
+ int_part = mantissa >> (FRAC_SIZE - exp);
+ frac_part = (mantissa << (exp + 1)) & FRAC_MASK2;
+ }
+ else /* if (exp < 0) */
+ frac_part = (mantissa & FRAC_MASK2) >> -(exp + 1);
+
+ if (int_part == 0) {
+ if (sign == -1)
+ *p++ = '-';
+ *p++ = '0';
+ } else {
+ int ret;
+ while (int_part != 0) {
+ int_part2 = int_part / 10;
+ *p++ = (char)(int_part - ((int_part2 << 3) + (int_part2 << 1)) + '0');
+ int_part = int_part2;
+ }
+ if (sign == -1)
+ *p++ = '-';
+ /* Reverse string */
+ ret = p - outbuf;
+ for (i = 0, n = ret/2; i < n; i++) {
+ int j = ret - i - 1;
+ c = outbuf[i];
+ outbuf[i] = outbuf[j];
+ outbuf[j] = c;
+ }
+ }
+ if (decimals != 0)
+ *p++ = '.';
+
+ max = maxlen - (p - outbuf) - 1 /* leave room for trailing '\0' */;
+ if (max > decimals)
+ max = decimals;
+ for (m = 0; m < max; m++) {
+ /* frac_part *= 10; */
+ frac_part = (frac_part << 3) + (frac_part << 1);
+
+ *p++ = (char)((frac_part >> (FRAC_SIZE + 1)) + '0');
+ frac_part &= FRAC_MASK2;
+ }
+
+ roundup = 0;
+ /* Rounding - look at the next digit */
+ frac_part = (frac_part << 3) + (frac_part << 1);
+ digit = (frac_part >> (FRAC_SIZE + 1));
+ if (digit > 5)
+ roundup = 1;
+ else if (digit == 5) {
+ frac_part &= FRAC_MASK2;
+ if (frac_part != 0) roundup = 1;
+ }
+ if (roundup) {
+ char d;
+ int pos = p - outbuf - 1;
+ do {
+ d = outbuf[pos];
+ if (d == '-') break;
+ if (d == '.') continue;
+ if (++d != ':') {
+ outbuf[pos] = d;
+ break;
+ }
+ outbuf[pos] = '0';
+ } while (--pos);
+ }
+
+ /* Delete trailing zeroes */
+ if (compact && *(p - 1) == '0')
+ p = float_first_trailing_zero(--p);
+ *p = '\0';
+ return p - outbuf;
+}
diff --git a/erts/emulator/sys/unix/erl_unix_sys_ddll.c b/erts/emulator/sys/unix/erl_unix_sys_ddll.c
index a35aec560a..12c47d0088 100644
--- a/erts/emulator/sys/unix/erl_unix_sys_ddll.c
+++ b/erts/emulator/sys/unix/erl_unix_sys_ddll.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2006-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
diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c
index 3fcb4d88dc..f2f4de869d 100644
--- a/erts/emulator/sys/unix/sys_float.c
+++ b/erts/emulator/sys/unix/sys_float.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2011. 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
@@ -735,7 +735,7 @@ void erts_sys_unblock_fpe(int unmasked)
/*
** Convert a double to ascii format 0.dddde[+|-]ddd
- ** return number of characters converted
+ ** return number of characters converted or -1 if error.
**
** These two functions should maybe use localeconv() to pick up
** the current radix character, but since it is uncertain how
@@ -745,11 +745,12 @@ void erts_sys_unblock_fpe(int unmasked)
*/
int
-sys_double_to_chars(double fp, char *buffer, size_t buffer_size)
+sys_double_to_chars_ext(double fp, char *buffer, size_t buffer_size, size_t decimals)
{
char *s = buffer;
-
- (void) erts_snprintf(buffer, buffer_size, "%.20e", fp);
+
+ if (erts_snprintf(buffer, buffer_size, "%.*e", decimals, fp) >= buffer_size)
+ return -1;
/* Search upto decimal point */
if (*s == '+' || *s == '-') s++;
while (ISDIGIT(*s)) s++;
diff --git a/erts/emulator/sys/win32/erl_win32_sys_ddll.c b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
index 54991a610c..4c8d83ab16 100644
--- a/erts/emulator/sys/win32/erl_win32_sys_ddll.c
+++ b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2006-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
diff --git a/erts/emulator/sys/win32/erl_win_dyn_driver.h b/erts/emulator/sys/win32/erl_win_dyn_driver.h
index 8b6be2b2f1..ae3228ff28 100644
--- a/erts/emulator/sys/win32/erl_win_dyn_driver.h
+++ b/erts/emulator/sys/win32/erl_win_dyn_driver.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2011. 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
diff --git a/erts/emulator/sys/win32/sys_float.c b/erts/emulator/sys/win32/sys_float.c
index 09dad89140..fb1ffc3089 100644
--- a/erts/emulator/sys/win32/sys_float.c
+++ b/erts/emulator/sys/win32/sys_float.c
@@ -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
@@ -114,15 +114,16 @@ sys_chars_to_double(char *buf, double *fp)
/*
** Convert a double to ascii format 0.dddde[+|-]ddd
-** return number of characters converted
+** return number of characters converted or -1 if error.
*/
int
-sys_double_to_chars(double fp, char *buffer, size_t buffer_size)
+sys_double_to_chars_ext(double fp, char *buffer, size_t buffer_size, size_t decimals)
{
char *s = buffer;
-
- (void) erts_snprintf(buffer, buffer_size, "%.20e", fp);
+
+ if (erts_snprintf(buffer, buffer_size, "%.*e", decimals, fp) >= buffer_size)
+ return -1;
/* Search upto decimal point */
if (*s == '+' || *s == '-') s++;
while (isdigit(*s)) s++;
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
index 66971654a2..5c4b11454f 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
@@ -42,6 +42,7 @@
typedef struct {
TestCaseState_t visible;
ErlDrvPort port;
+ ErlDrvTermData port_id;
int result;
jmp_buf done_jmp_buf;
char *comment;
@@ -97,6 +98,7 @@ testcase_drv_start(ErlDrvPort port, char *command)
itcs->visible.testcase_name = testcase_name();
itcs->visible.extra = NULL;
itcs->port = port;
+ itcs->port_id = driver_mk_port(port);
itcs->result = TESTCASE_FAILED;
itcs->comment = "";
@@ -142,7 +144,7 @@ testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
msg[1] = (ErlDrvTermData) result_atom;
msg[2] = ERL_DRV_PORT;
- msg[3] = driver_mk_port(itcs->port);
+ msg[3] = itcs->port_id;
msg[4] = ERL_DRV_ATOM;
msg[5] = driver_mk_atom(itcs->visible.testcase_name);
@@ -154,7 +156,7 @@ testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
msg[9] = ERL_DRV_TUPLE;
msg[10] = (ErlDrvTermData) 4;
- driver_output_term(itcs->port, msg, 11);
+ erl_drv_output_term(itcs->port_id, msg, 11);
}
int
@@ -184,7 +186,7 @@ testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
msg[1] = (ErlDrvTermData) driver_mk_atom("print");
msg[2] = ERL_DRV_PORT;
- msg[3] = driver_mk_port(itcs->port);
+ msg[3] = itcs->port_id;
msg[4] = ERL_DRV_ATOM;
msg[5] = driver_mk_atom(itcs->visible.testcase_name);
@@ -196,7 +198,7 @@ testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
msg[9] = ERL_DRV_TUPLE;
msg[10] = (ErlDrvTermData) 4;
- driver_output_term(itcs->port, msg, 11);
+ erl_drv_output_term(itcs->port_id, msg, 11);
}
diff --git a/erts/emulator/test/beam_SUITE.erl b/erts/emulator/test/beam_SUITE.erl
index 3197a4c137..60339ea422 100644
--- a/erts/emulator/test/beam_SUITE.erl
+++ b/erts/emulator/test/beam_SUITE.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
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index e2442861c7..02c6de8cb1 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -481,8 +481,6 @@ binary_to_atom(Config) when is_list(Config) ->
%% Bad UTF8 sequences.
?line ?BADARG(binary_to_atom(id(<<255>>), utf8)),
?line ?BADARG(binary_to_atom(id(<<255,0>>), utf8)),
- ?line ?BADARG(binary_to_atom(id(<<0:512/unit:8,255>>), utf8)),
- ?line ?BADARG(binary_to_atom(id(<<0:512/unit:8,255,0>>), utf8)),
?line ?BADARG(binary_to_atom(id(<<16#C0,16#80>>), utf8)), %Overlong 0.
?line [?BADARG(binary_to_atom(<<C/utf8>>, utf8)) ||
C <- lists:seq(256, 16#D7FF)],
@@ -494,6 +492,8 @@ binary_to_atom(Config) when is_list(Config) ->
C <- lists:seq(16#90000, 16#10FFFF)],
%% system_limit failures.
+ ?line ?SYS_LIMIT(binary_to_atom(id(<<0:512/unit:8,255>>), utf8)),
+ ?line ?SYS_LIMIT(binary_to_atom(id(<<0:512/unit:8,255,0>>), utf8)),
?line ?SYS_LIMIT(binary_to_atom(<<0:256/unit:8>>, latin1)),
?line ?SYS_LIMIT(binary_to_atom(<<0:257/unit:8>>, latin1)),
?line ?SYS_LIMIT(binary_to_atom(<<0:512/unit:8>>, latin1)),
diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl
index 32e907ca69..2c63296b83 100644
--- a/erts/emulator/test/busy_port_SUITE.erl
+++ b/erts/emulator/test/busy_port_SUITE.erl
@@ -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
@@ -26,6 +26,8 @@
no_trap_exit_unlinked/1, trap_exit/1, multiple_writers/1,
hard_busy_driver/1, soft_busy_driver/1]).
+-compile(export_all).
+
-include_lib("test_server/include/test_server.hrl").
%% Internal exports.
@@ -36,7 +38,9 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[io_to_busy, message_order, send_3, system_monitor,
no_trap_exit, no_trap_exit_unlinked, trap_exit,
- multiple_writers, hard_busy_driver, soft_busy_driver].
+ multiple_writers, hard_busy_driver, soft_busy_driver,
+ scheduling_delay_busy,scheduling_delay_busy_nosuspend,
+ scheduling_busy_link].
groups() ->
[].
@@ -528,6 +532,304 @@ hs_busy_pcmd(Prt, Opts, StartFun, EndFun) ->
EndFun(P, Res, Time)
end.
+scheduling_delay_busy(Config) ->
+
+ Scenario =
+ [{1,{spawn,[{var,drvname},undefined]}},
+ {2,{call,[{var,1},open_port]}},
+ {3,{spawn,[{var,2},{var,1}]}},
+ {0,{ack,[{var,1},{busy,1,250}]}},
+ {0,{cast,[{var,3},{command,2}]}},
+ [{0,{cast,[{var,3},{command,I}]}}
+ || I <- lists:seq(3,50)],
+ {0,{cast,[{var,3},take_control]}},
+ {0,{cast,[{var,1},{new_owner,{var,3}}]}},
+ {0,{cast,[{var,3},close]}},
+ {0,{timer,sleep,[300]}},
+ {0,{erlang,port_command,[{var,2},<<$N>>,[force]]}},
+ [{0,{cast,[{var,1},{command,I}]}}
+ || I <- lists:seq(101,127)]
+ ,{10,{call,[{var,3},get_data]}}
+ ],
+
+ Validation = [{seq,10,lists:seq(1,50)}],
+
+ port_scheduling(Scenario,Validation,?config(data_dir,Config)).
+
+scheduling_delay_busy_nosuspend(Config) ->
+
+ Scenario =
+ [{1,{spawn,[{var,drvname},undefined]}},
+ {2,{call,[{var,1},open_port]}},
+ {0,{cast,[{var,1},{command,1,100}]}},
+ {0,{cast,[{var,1},{busy,2}]}},
+ {10,{call,[{var,1},{command,3,[nosuspend]}]}},
+ {0,{timer,sleep,[200]}},
+ {0,{erlang,port_command,[{var,2},<<$N>>,[force]]}},
+ {0,{cast,[{var,1},close]}},
+ {20,{call,[{var,1},get_data]}}
+ ],
+
+ Validation = [{eq,10,nosuspend},{seq,20,[1,2]}],
+
+ port_scheduling(Scenario,Validation,?config(data_dir,Config)).
+
+scheduling_busy_link(Config) ->
+
+ Scenario =
+ [{1,{spawn,[{var,drvname},undefined]}},
+ {2,{call,[{var,1},open_port]}},
+ {3,{spawn,[{var,2},{var,1}]}},
+ {0,{cast,[{var,1},unlink]}},
+ {0,{cast,[{var,1},{busy,1}]}},
+ {0,{cast,[{var,1},{command,2}]}},
+ {0,{cast,[{var,1},link]}},
+ {0,{timer,sleep,[1000]}},
+ {0,{ack,[{var,3},take_control]}},
+ {0,{cast,[{var,1},{new_owner,{var,3}}]}},
+ {0,{cast,[{var,3},close]}},
+ {10,{call,[{var,3},get_data]}},
+ {20,{call,[{var,1},get_exit]}}
+ ],
+
+ Validation = [{seq,10,[1]},
+ {seq,20,[{'EXIT',noproc}]}],
+
+ port_scheduling(Scenario,Validation,?config(data_dir,Config)).
+
+process_init(DrvName,Owner) ->
+ process_flag(trap_exit,true),
+ process_loop(DrvName,Owner, {[],[]}).
+
+process_loop(DrvName,undefined,Data) when is_list(DrvName) ->
+ process_loop(DrvName,[binary],Data);
+process_loop(DrvName,PortOpts,Data) when is_list(DrvName) ->
+ receive
+ {call,open_port,P} ->
+ Port = open_port({spawn, DrvName}, PortOpts),
+ send(P,Port),
+ process_loop(Port,self(),Data)
+ end;
+process_loop(Port,undefined,Data) ->
+ receive
+ {cast,{new_owner,Pid}} ->
+ pal("NewOwner: ~p",[Pid]),
+ process_loop(Port,Pid,Data)
+ end;
+process_loop(Port,Owner,{Data,Exit} = DE) ->
+ receive
+ {Port,connected} ->
+ pal("Connected",[]),
+ process_loop(Port,undefined,DE);
+ {Port,{data,NewData}} ->
+ pal("Got: ~p",[NewData]),
+ receive
+ {Port,closed} ->
+ process_loop(Port,Owner,{Data ++ [NewData],Exit})
+ after 2000 ->
+ exit(did_not_get_port_close)
+ end;
+ {'EXIT',Port,Reason} = Exit ->
+ pal("Exit: ~p",[Exit]),
+ process_loop(Port,Owner,{Data, Exit ++ [[{'EXIT',Reason}]]});
+ {'EXIT',_Port,_Reason} = Exit ->
+ pal("Exit: ~p",[Exit]);
+ {call,Msg,P} ->
+ case handle_msg(Msg,Port,Owner,DE) of
+ {Reply,NewOwner,NewData} ->
+ send(P,Reply),
+ process_loop(Port,NewOwner,NewData);
+ Reply ->
+ send(P,Reply),
+ process_loop(Port,Owner,DE)
+ end;
+ {ack,Msg,P} ->
+ send(P,ok),
+ case handle_msg(Msg,Port,Owner,DE) of
+ {_Reply,NewOwner,NewData} ->
+ process_loop(Port,NewOwner,NewData);
+ _Reply ->
+ process_loop(Port,Owner,DE)
+ end;
+ {cast,Msg} when is_atom(Msg) orelse element(1,Msg) /= new_owner ->
+ case handle_msg(Msg,Port,Owner,DE) of
+ {_Reply,NewOwner,NewData} ->
+ process_loop(Port,NewOwner,NewData);
+ _ ->
+ process_loop(Port,Owner,DE)
+ end
+ end.
+
+handle_msg({busy,Value,Delay},Port,Owner,_Data) ->
+ pal("Long busy: ~p",[Value]),
+ send(Port,{Owner,{command,<<$L,Value:32,(round(Delay/100))>>}});
+handle_msg({busy,Value},Port,Owner,_Data) ->
+ pal("Busy: ~p",[Value]),
+ send(Port,{Owner,{command,<<$B,Value:32>>}});
+handle_msg({command,Value},Port,Owner,_Data) ->
+ pal("Short: ~p",[Value]),
+ send(Port,{Owner,{command,<<$C,Value:32>>}});
+handle_msg({command,Value,Delay},Port,Owner,_Data) when is_integer(Delay) ->
+ pal("Long: ~p",[Value]),
+ send(Port,{Owner,{command,<<$D,Value:32,(round(Delay/100))>>}});
+handle_msg({command,Value,Opts},Port,Owner,_Data) ->
+ pal("Short Opt: ~p",[Value]),
+ send(Port,{Owner,{command,<<$C,Value:32>>}},Opts);
+handle_msg({command,Value,Opts,Delay},Port,Owner,_Data) ->
+ pal("Long Opt: ~p",[Value]),
+ send(Port,{Owner,{command,<<$D,Value:32,(round(Delay/100))>>}},Opts);
+handle_msg(take_control,Port,Owner,Data) ->
+ pal("Connect: ~p",[self()]),
+ send(Port,{Owner, {connect, self()}}),
+ {undefined,self(),Data};
+handle_msg(unlink,Port,_Owner,_Data) ->
+ pal("Unlink:",[]),
+ erlang:unlink(Port);
+handle_msg(link,Port,_Owner,_Data) ->
+ pal("Link:",[]),
+ erlang:link(Port);
+handle_msg(close,Port,Owner,_Data) ->
+ pal("Close",[]),
+ send(Port,{Owner,close});
+handle_msg(get_data,Port,_Owner,{[],_Exit}) ->
+ %% Wait for data if it has not arrived yet
+ receive
+ {Port,{data,Data}} ->
+ Data
+ after 2000 ->
+ pal("~p",[erlang:process_info(self())]),
+ exit(did_not_get_port_data)
+ end;
+handle_msg(get_data,_Port,Owner,{Data,Exit}) ->
+ pal("GetData",[]),
+ {hd(Data),Owner,{tl(Data),Exit}};
+handle_msg(get_exit,Port,_Owner,{_Data,[]}) ->
+ %% Wait for exit if it has not arrived yet
+ receive
+ {'EXIT',Port,Reason} ->
+ [{'EXIT',Reason}]
+ after 2000 ->
+ pal("~p",[erlang:process_info(self())]),
+ exit(did_not_get_port_exit)
+ end;
+handle_msg(get_exit,_Port,Owner,{Data,Exit}) ->
+ {hd(Exit),Owner,{Data,tl(Exit)}}.
+
+
+
+call(Pid,Msg) ->
+ pal("call(~p,~p)",[Pid,Msg]),
+ send(Pid,{call,Msg,self()}),
+ receive
+ Ret ->
+ Ret
+ end.
+ack(Pid,Msg) ->
+ pal("ack(~p,~p)",[Pid,Msg]),
+ send(Pid,{ack,Msg,self()}),
+ receive
+ Ret ->
+ Ret
+ end.
+
+cast(Pid,Msg) ->
+ pal("cast(~p,~p)",[Pid,Msg]),
+ send(Pid,{cast,Msg}).
+
+send(Pid,Msg) ->
+ erlang:send(Pid,Msg).
+send(Prt,Msg,Opts) ->
+ erlang:send(Prt,Msg,Opts).
+
+
+port_scheduling(Scenario,Validation,Path) ->
+ DrvName = "scheduling_drv",
+ erl_ddll:start(),
+ case erl_ddll:load_driver(Path, DrvName) of
+ ok -> ok;
+ {error, Error} ->
+ io:format("~s\n", [erl_ddll:format_error(Error)]),
+ ?line ?t:fail()
+ end,
+
+ Data = run_scenario(lists:flatten(Scenario),[{drvname,DrvName}]),
+ ok = validate_scenario(Data,Validation).
+
+
+run_scenario([{V,{Module,Cmd,Args}}|T],Vars) ->
+ Res = run_command(Module,Cmd,
+ replace_args(Args,Vars)),
+ run_scenario(T,[{V,Res}|Vars]);
+run_scenario([{V,{Cmd,Args}}|T],Vars) ->
+ run_scenario([{V,{?MODULE,Cmd,Args}}|T],Vars);
+run_scenario([],Vars) ->
+ Vars.
+
+run_command(_M,spawn,{Args,Opts}) ->
+ Pid = spawn_opt(fun() -> apply(?MODULE,process_init,Args) end,[link|Opts]),
+ pal("spawn(~p): ~p",[Args,Pid]),
+ Pid;
+run_command(M,spawn,Args) ->
+ run_command(M,spawn,{Args,[]});
+run_command(Mod,Func,Args) ->
+ erlang:display({{Mod,Func,Args},now()}),
+ apply(Mod,Func,Args).
+
+validate_scenario(Data,[{print,Var}|T]) ->
+ pal("Val: ~p",[proplists:get_value(Var,Data)]),
+ validate_scenario(Data,T);
+validate_scenario(Data,[{eq,Var,Value}|T]) ->
+ case proplists:get_value(Var,Data) of
+ Value ->
+ validate_scenario(Data,T);
+ Else ->
+ exit({eq_return,Value,Else})
+ end;
+validate_scenario(Data,[{neq,Var,Value}|T]) ->
+ case proplists:get_value(Var,Data) of
+ Value ->
+ exit({neq_return,Value});
+ _Else ->
+ validate_scenario(Data,T)
+ end;
+validate_scenario(Data,[{seq,Var,Seq}|T]) ->
+ try
+ validate_sequence(proplists:get_value(Var,Data),Seq)
+ catch _:{validate_sequence,NotFound} ->
+ exit({validate_sequence,NotFound,Data})
+ end,
+ validate_scenario(Data,T);
+validate_scenario(_,[]) ->
+ ok.
+
+validate_sequence(Data,Validation) when is_binary(Data) ->
+ validate_sequence(binary_to_list(Data),Validation);
+validate_sequence([H|R],[H|T]) ->
+ validate_sequence(R,T);
+validate_sequence([_|R],Seq) ->
+ validate_sequence(R,Seq);
+validate_sequence(_,[]) ->
+ ok;
+validate_sequence([],NotFound) ->
+ exit({validate_sequence,NotFound}).
+
+replace_args({var,Var},Vars) ->
+ proplists:get_value(Var,Vars);
+replace_args([H|T],Vars) ->
+ [replace_args(H,Vars)|replace_args(T,Vars)];
+replace_args([],_Vars) ->
+ [];
+replace_args(Tuple,Vars) when is_tuple(Tuple) ->
+ list_to_tuple(replace_args(tuple_to_list(Tuple),Vars));
+replace_args(Else,_Vars) ->
+ Else.
+
+pal(_F,_A) -> ok.
+%pal(Format,Args) ->
+% ct:pal("~p "++Format,[self()|Args]).
+% erlang:display(lists:flatten(io_lib:format("~p "++Format,[self()|Args]))).
+
+
%%% Utilities.
chk_range(Min, Val, Max) when Min =< Val, Val =< Max ->
diff --git a/erts/emulator/test/busy_port_SUITE_data/Makefile.src b/erts/emulator/test/busy_port_SUITE_data/Makefile.src
index 664909db71..f7937bc8d3 100644
--- a/erts/emulator/test/busy_port_SUITE_data/Makefile.src
+++ b/erts/emulator/test/busy_port_SUITE_data/Makefile.src
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. 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
@@ -17,9 +17,10 @@
# %CopyrightEnd%
#
-all: busy_drv@dll@ hard_busy_drv@dll@ soft_busy_drv@dll@
+all: busy_drv@dll@ hard_busy_drv@dll@ soft_busy_drv@dll@ scheduling_drv@dll@
@SHLIB_RULES@
hard_busy_drv@obj@: hard_busy_drv.c hs_busy_drv.c
soft_busy_drv@obj@: soft_busy_drv.c hs_busy_drv.c
+scheduling_drv@obj@: scheduling_drv.c
diff --git a/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c
index 9f6bd310c6..7807b47e3d 100644
--- a/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c
+++ b/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -71,9 +71,9 @@ void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
ERL_DRV_PID, driver_caller(port),
ERL_DRV_TUPLE, (ErlDrvTermData) 3
};
- res = driver_output_term(port, msg, sizeof(msg)/sizeof(ErlDrvTermData));
+ res = erl_drv_output_term(driver_mk_port(port), msg, sizeof(msg)/sizeof(ErlDrvTermData));
if (res <= 0)
- driver_failure_atom(port, "driver_output_term failed");
+ driver_failure_atom(port, "erl_drv_output_term failed");
}
ErlDrvSSizeT control(ErlDrvData drv_data, unsigned int command, char *buf,
diff --git a/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c b/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c
new file mode 100644
index 0000000000..2008b33a72
--- /dev/null
+++ b/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c
@@ -0,0 +1,190 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef __WIN32__
+#include <windows.h>
+#else
+#include <sys/select.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include "erl_driver.h"
+
+#define get_int32(s) ((((unsigned char*) (s))[0] << 24) | \
+ (((unsigned char*) (s))[1] << 16) | \
+ (((unsigned char*) (s))[2] << 8) | \
+ (((unsigned char*) (s))[3]))
+
+#define ERTS_TEST_SCHEDULING_DRV_NAME "scheduling_drv"
+#define ERTS_TEST_SCHEDULING_DRV_FLAGS \
+ ERL_DRV_FLAG_USE_PORT_LOCKING | ERL_DRV_FLAG_SOFT_BUSY
+
+ErlDrvData start(ErlDrvPort port, char *command);
+void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
+ErlDrvSSizeT control(ErlDrvData drv_data, unsigned int command, char *buf,
+ ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen);
+void stop(ErlDrvData drv_data);
+void timeout(ErlDrvData drv_data);
+
+static void delay(unsigned ms);
+
+static ErlDrvEntry busy_drv_entry = {
+ NULL /* init */,
+ start,
+ stop,
+ output,
+ NULL /* ready_input */,
+ NULL /* ready_output */,
+ ERTS_TEST_SCHEDULING_DRV_NAME,
+ NULL /* finish */,
+ NULL /* handle */,
+ control,
+ timeout,
+ NULL /* outputv */,
+ NULL /* ready_async */,
+ NULL /* flush */,
+ NULL /* call */,
+ NULL /* event */,
+ ERL_DRV_EXTENDED_MARKER,
+ ERL_DRV_EXTENDED_MAJOR_VERSION,
+ ERL_DRV_EXTENDED_MINOR_VERSION,
+ ERTS_TEST_SCHEDULING_DRV_FLAGS,
+ NULL /* handle2 */,
+ NULL /* handle_monitor */,
+ NULL /* stop_select */
+};
+
+#define DBG(data,FMT)
+/* #define DBG(data,FMT) printf("0x%.8lx: %s",driver_caller(data->port),FMT); */
+
+typedef struct SchedDrvData {
+ ErlDrvPort port;
+ char data[255];
+ int curr;
+ int use_auto_busy;
+} SchedDrvData;
+
+DRIVER_INIT(busy_drv)
+{
+ return &busy_drv_entry;
+}
+
+ErlDrvData start(ErlDrvPort port, char *command)
+{
+ SchedDrvData *d = driver_alloc(sizeof(SchedDrvData));
+ d->port = port;
+ d->curr = 0;
+ d->use_auto_busy = 0;
+ DBG(d,"start\r\n");
+ return (ErlDrvData) d;
+}
+
+void stop(ErlDrvData drv_data) {
+ SchedDrvData *d = (SchedDrvData*)drv_data;
+ driver_output(d->port,d->data,d->curr);
+ DBG(d,"close\r\n");
+ driver_free(d);
+ return;
+}
+
+void timeout(ErlDrvData drv_data) {
+ SchedDrvData *d = (SchedDrvData*)drv_data;
+ set_busy_port(d->port, 0);
+ DBG(d,"timeout\r\n");
+}
+
+void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
+{
+ int res;
+ unsigned int command = *buf;
+ SchedDrvData *d = (SchedDrvData*)drv_data;
+
+ switch (command) {
+ case 'B': /* busy */
+ DBG(d,"busy: ");
+ set_busy_port(d->port, 1);
+ break;
+ case 'L': /* busy long call */
+ DBG(d,"long: ");
+ delay(buf[5]*100);
+ set_busy_port(d->port, 1);
+ break;
+ case 'D': /* delay call */
+ DBG(d,"delay: ");
+ delay(buf[5]*100);
+ break;
+ case 'N': /* not busy */
+ DBG(d,"not");
+ set_busy_port(d->port, 0);
+ goto done;
+ case 'C': /* change state */
+ DBG(d,"chang: ");
+ break;
+ case 'G': /* get state */
+ DBG(d,"get : ");
+ driver_output(d->port,d->data,d->curr);
+ return;
+ default:
+ driver_failure_posix((ErlDrvPort) drv_data, EINVAL);
+ break;
+ }
+ if (len > 1) {
+ unsigned int val = get_int32(buf+1);
+ fprintf(stderr,"%u",val);
+ d->data[d->curr++] = val;
+ }
+ done:
+ fprintf(stderr,"\r\n");
+}
+
+ErlDrvSSizeT control(ErlDrvData drv_data, unsigned int command, char *buf,
+ ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen)
+{
+ switch (command) {
+ case 'B': /* busy */
+ set_busy_port((ErlDrvPort) drv_data, 1);
+ break;
+ case 'N': /* not busy */
+ set_busy_port((ErlDrvPort) drv_data, 0);
+ break;
+ default:
+ driver_failure_posix((ErlDrvPort) drv_data, EINVAL);
+ break;
+ }
+ return 0;
+}
+
+
+/*
+ * Delays (sleeps) the given number of milli-seconds.
+ */
+
+static void delay(unsigned ms)
+{
+ fprintf(stderr,"delay(%u)",ms);
+#ifdef __WIN32__
+ Sleep(ms);
+#else
+ struct timeval t;
+ t.tv_sec = ms/1000;
+ t.tv_usec = (ms % 1000) * 1000;
+
+ select(0, NULL, NULL, NULL, &t);
+#endif
+}
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl
index 4675cab15c..ffb68ed4ee 100644
--- a/erts/emulator/test/ddll_SUITE.erl
+++ b/erts/emulator/test/ddll_SUITE.erl
@@ -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
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index f3a177faf2..aa6cf2b881 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -18,7 +18,17 @@
%%
-module(distribution_SUITE).
--compile(r13).
+-compile(r15).
+
+-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).
%% Tests distribution and the tcp driver.
@@ -37,8 +47,10 @@
dist_auto_connect_never/1, dist_auto_connect_once/1,
dist_parallel_send/1,
atom_roundtrip/1,
- atom_roundtrip_r13b/1,
+ unicode_atom_roundtrip/1,
+ atom_roundtrip_r15b/1,
contended_atom_cache_entry/1,
+ contended_unicode_atom_cache_entry/1,
bad_dist_structure/1,
bad_dist_ext_receive/1,
bad_dist_ext_process_info/1,
@@ -62,8 +74,9 @@ all() ->
link_to_dead_new_node, applied_monitor_node,
ref_port_roundtrip, nil_roundtrip, stop_dist,
{group, trap_bif}, {group, dist_auto_connect},
- dist_parallel_send, atom_roundtrip, atom_roundtrip_r13b,
- contended_atom_cache_entry, bad_dist_structure, {group, bad_dist_ext}].
+ dist_parallel_send, atom_roundtrip, unicode_atom_roundtrip, atom_roundtrip_r15b,
+ contended_atom_cache_entry, contended_unicode_atom_cache_entry,
+ bad_dist_structure, {group, bad_dist_ext}].
groups() ->
[{bulk_send, [], [bulk_send_small, bulk_send_big, bulk_send_bigbig]},
@@ -1085,19 +1098,27 @@ atom_roundtrip(Config) when is_list(Config) ->
?line stop_node(Node),
?line ok.
-atom_roundtrip_r13b(Config) when is_list(Config) ->
- case ?t:is_release_available("r13b") of
+atom_roundtrip_r15b(Config) when is_list(Config) ->
+ case ?t:is_release_available("r15b") of
true ->
?line AtomData = atom_data(),
?line verify_atom_data(AtomData),
- ?line {ok, Node} = start_node(Config, [], "r13b"),
+ ?line {ok, Node} = start_node(Config, [], "r15b"),
?line do_atom_roundtrip(Node, AtomData),
?line stop_node(Node),
?line ok;
false ->
- ?line {skip,"No OTP R13B available"}
+ ?line {skip,"No OTP R15B available"}
end.
+unicode_atom_roundtrip(Config) when is_list(Config) ->
+ ?line AtomData = unicode_atom_data(),
+ ?line verify_atom_data(AtomData),
+ ?line {ok, Node} = start_node(Config),
+ ?line do_atom_roundtrip(Node, AtomData),
+ ?line stop_node(Node),
+ ?line ok.
+
do_atom_roundtrip(Node, AtomData) ->
?line Parent = self(),
?line Proc = spawn_link(Node, fun () -> verify_atom_data_loop(Parent) end),
@@ -1128,12 +1149,76 @@ atom_data() ->
lists:seq(1, 2000)).
verify_atom_data(AtomData) ->
- lists:foreach(fun ({Atom, AtomTxt}) ->
- AtomTxt = atom_to_list(Atom)
+ lists:foreach(fun ({Atom, AtomTxt}) when is_atom(Atom) ->
+ AtomTxt = atom_to_list(Atom);
+ ({PPR, AtomTxt}) ->
+ % Pid, Port, or Ref
+ AtomTxt = atom_to_list(node(PPR))
end,
AtomData).
+uc_atom_tup(ATxt) ->
+ Atom = string_to_atom(ATxt),
+ ATxt = atom_to_list(Atom),
+ {Atom, ATxt}.
+
+uc_pid_tup(ATxt) ->
+ ATxtExt = string_to_atom_ext(ATxt),
+ Pid = mk_pid({ATxtExt, 1}, 4711,17),
+ true = is_pid(Pid),
+ Atom = node(Pid),
+ true = is_atom(Atom),
+ ATxt = atom_to_list(Atom),
+ {Pid, ATxt}.
+
+uc_port_tup(ATxt) ->
+ ATxtExt = string_to_atom_ext(ATxt),
+ Port = mk_port({ATxtExt, 2}, 4711),
+ true = is_port(Port),
+ Atom = node(Port),
+ true = is_atom(Atom),
+ ATxt = atom_to_list(Atom),
+ {Port, ATxt}.
+
+uc_ref_tup(ATxt) ->
+ ATxtExt = string_to_atom_ext(ATxt),
+ Ref = mk_ref({ATxtExt, 3}, [4711,17, 4711]),
+ true = is_reference(Ref),
+ Atom = node(Ref),
+ true = is_atom(Atom),
+ ATxt = atom_to_list(Atom),
+ {Ref, ATxt}.
+
+
+unicode_atom_data() ->
+ [uc_pid_tup(lists:seq(16#1f600, 16#1f600+249) ++ "@host"),
+ uc_pid_tup(lists:seq(16#1f600, 16#1f600+30) ++ "@host"),
+ uc_port_tup(lists:seq(16#1f600, 16#1f600+249) ++ "@host"),
+ uc_port_tup(lists:seq(16#1f600, 16#1f600+30) ++ "@host"),
+ uc_ref_tup(lists:seq(16#1f600, 16#1f600+249) ++ "@host"),
+ uc_ref_tup(lists:seq(16#1f600, 16#1f600+30) ++ "@host"),
+ uc_atom_tup(lists:seq(16#1f600, 16#1f600+254)),
+ uc_atom_tup(lists:seq(16#1f600, 16#1f600+63)),
+ uc_atom_tup(lists:seq(0, 254)),
+ uc_atom_tup(lists:seq(100, 163)),
+ uc_atom_tup(lists:seq(200, 354)),
+ uc_atom_tup(lists:seq(200, 263)),
+ uc_atom_tup(lists:seq(2000, 2254)),
+ uc_atom_tup(lists:seq(2000, 2063)),
+ uc_atom_tup(lists:seq(65500, 65754)),
+ uc_atom_tup(lists:seq(65500, 65563))
+ | lists:map(fun (N) ->
+ uc_atom_tup(lists:seq(64000+N, 64254+N))
+ end,
+ lists:seq(1, 2000))].
+
contended_atom_cache_entry(Config) when is_list(Config) ->
+ contended_atom_cache_entry_test(Config, latin1).
+
+contended_unicode_atom_cache_entry(Config) when is_list(Config) ->
+ contended_atom_cache_entry_test(Config, unicode).
+
+contended_atom_cache_entry_test(Config, Type) ->
?line TestServer = self(),
?line ProcessPairs = 10,
?line Msgs = 100000,
@@ -1147,9 +1232,16 @@ contended_atom_cache_entry(Config) when is_list(Config) ->
true),
Master = self(),
CIX = get_cix(),
- TestAtoms = get_conflicting_atoms(CIX, ProcessPairs),
+ TestAtoms = case Type of
+ latin1 ->
+ get_conflicting_atoms(CIX,
+ ProcessPairs);
+ unicode ->
+ get_conflicting_unicode_atoms(CIX,
+ ProcessPairs)
+ end,
io:format("Testing with the following atoms all using "
- "cache index ~p:~n ~p~n",
+ "cache index ~p:~n ~w~n",
[CIX, TestAtoms]),
Ps = lists:map(
fun (A) ->
@@ -1159,8 +1251,12 @@ contended_atom_cache_entry(Config) when is_list(Config) ->
fun () ->
Atom = receive
{Ref, txt, ATxt} ->
- list_to_atom(
- ATxt)
+ case Type of
+ latin1 ->
+ list_to_atom(ATxt);
+ unicode ->
+ string_to_atom(ATxt)
+ end
end,
receive_ref_atom(Ref,
Atom,
@@ -1252,6 +1348,20 @@ get_conflicting_atoms(CIX, N) ->
get_conflicting_atoms(CIX, N)
end.
+get_conflicting_unicode_atoms(_CIX, 0) ->
+ [];
+get_conflicting_unicode_atoms(CIX, N) ->
+ {A, B, C} = now(),
+ Atom = string_to_atom([16#1f608] ++ "atom" ++ integer_to_list(A*1000000000000
+ + B*1000000
+ + C)),
+ case erts_debug:get_internal_state({atom_out_cache_index, Atom}) of
+ CIX ->
+ [Atom|get_conflicting_unicode_atoms(CIX, N-1)];
+ _ ->
+ get_conflicting_unicode_atoms(CIX, N)
+ end.
+
-define(COOKIE, '').
-define(DOP_LINK, 1).
-define(DOP_SEND, 2).
@@ -2131,3 +2241,190 @@ repeat(_Fun, 0) ->
repeat(Fun, N) ->
Fun(),
repeat(Fun, N-1).
+
+string_to_atom_ext(String) ->
+ Utf8List = string_to_utf8_list(String),
+ Len = length(Utf8List),
+ case Len < 256 of
+ true ->
+ [?SMALL_ATOM_UTF8_EXT, Len | Utf8List];
+ false ->
+ [?ATOM_UTF8_EXT, Len bsr 8, Len band 16#ff | Utf8List]
+ end.
+
+string_to_atom(String) ->
+ binary_to_term(list_to_binary([?VERSION_MAGIC
+ | string_to_atom_ext(String)])).
+
+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)].
+
+utf8_list_to_string([]) ->
+ [];
+utf8_list_to_string([B|Bs]) when is_integer(B),
+ 0 =< B,
+ B =< 16#7F ->
+ [B | utf8_list_to_string(Bs)];
+utf8_list_to_string([B0, B1 | Bs]) when is_integer(B0),
+ 16#C0 =< B0,
+ B0 =< 16#DF,
+ is_integer(B1),
+ 16#80 =< B1,
+ B1 =< 16#BF ->
+ [(((B0 band 16#1F) bsl 6)
+ bor (B1 band 16#3F))
+ | utf8_list_to_string(Bs)];
+utf8_list_to_string([B0, B1, B2 | Bs]) when is_integer(B0),
+ 16#E0 =< B0,
+ B0 =< 16#EF,
+ is_integer(B1),
+ 16#80 =< B1,
+ B1 =< 16#BF,
+ is_integer(B2),
+ 16#80 =< B2,
+ B2 =< 16#BF ->
+ [(((B0 band 16#F) bsl 12)
+ bor ((B1 band 16#3F) bsl 6)
+ bor (B2 band 16#3F))
+ | utf8_list_to_string(Bs)];
+utf8_list_to_string([B0, B1, B2, B3 | Bs]) when is_integer(B0),
+ 16#F0 =< B0,
+ B0 =< 16#F7,
+ is_integer(B1),
+ 16#80 =< B1,
+ B1 =< 16#BF,
+ is_integer(B2),
+ 16#80 =< B2,
+ B2 =< 16#BF,
+ is_integer(B3),
+ 16#80 =< B3,
+ B3 =< 16#BF ->
+ [(((B0 band 16#7) bsl 18)
+ bor ((B1 band 16#3F) bsl 12)
+ bor ((B2 band 16#3F) bsl 6)
+ bor (B3 band 16#3F))
+ | utf8_list_to_string(Bs)].
+
+mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) ->
+ <<?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,
+ NodeNameExt,
+ uint32_be(Number),
+ uint32_be(Serial),
+ uint8(Creation)])) of
+ Pid when is_pid(Pid) ->
+ Pid;
+ {'EXIT', {badarg, _}} ->
+ 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) ->
+ <<?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,
+ NodeNameExt,
+ uint32_be(Number),
+ uint8(Creation)])) of
+ Port when is_port(Port) ->
+ Port;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_port, [{NodeNameExt, Creation}, Number]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end.
+
+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,
+ NodeNameExt,
+ uint32_be(Number),
+ uint8(Creation)])) of
+ Ref when is_reference(Ref) ->
+ Ref;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_ref, [{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) ->
+ <<?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)),
+ NodeNameExt,
+ uint8(Creation),
+ lists:map(fun (N) ->
+ uint32_be(N)
+ end,
+ Numbers)])) of
+ Ref when is_reference(Ref) ->
+ Ref;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_ref, [{NodeNameExt, Creation}, Numbers]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end.
+
+
+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,
+ (Uint bsr 8) band 16#ff,
+ Uint band 16#ff];
+uint32_be(Uint) ->
+ exit({badarg, uint32_be, [Uint]}).
+
+
+uint16_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 16 ->
+ [(Uint bsr 8) band 16#ff,
+ Uint band 16#ff];
+uint16_be(Uint) ->
+ exit({badarg, uint16_be, [Uint]}).
+
+uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 ->
+ Uint band 16#ff;
+uint8(Uint) ->
+ exit({badarg, uint8, [Uint]}).
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 13f18b4563..dae36fed8f 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -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
diff --git a/erts/emulator/test/driver_SUITE_data/async_blast_drv.c b/erts/emulator/test/driver_SUITE_data/async_blast_drv.c
index c2086c5860..72be107168 100644
--- a/erts/emulator/test/driver_SUITE_data/async_blast_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/async_blast_drv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2011. 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
@@ -56,6 +56,7 @@ static ErlDrvEntry async_blast_drv_entry = {
typedef struct {
ErlDrvPort port;
+ ErlDrvTermData port_id;
ErlDrvTermData caller;
int counter;
} async_blast_data_t;
@@ -81,6 +82,7 @@ static ErlDrvData start(ErlDrvPort port,
return ERL_DRV_ERROR_GENERAL;
abd->port = port;
+ abd->port_id = driver_mk_port(port);
abd->counter = 0;
return (ErlDrvData) abd;
}
@@ -97,12 +99,12 @@ static void ready_async(ErlDrvData drv_data,
async_blast_data_t *abd = (async_blast_data_t *) drv_data;
if (--abd->counter == 0) {
ErlDrvTermData spec[] = {
- ERL_DRV_PORT, driver_mk_port(abd->port),
+ ERL_DRV_PORT, abd->port_id,
ERL_DRV_ATOM, driver_mk_atom("done"),
ERL_DRV_TUPLE, 2
};
- driver_send_term(abd->port, abd->caller,
- spec, sizeof(spec)/sizeof(spec[0]));
+ erl_drv_send_term(abd->port_id, abd->caller,
+ spec, sizeof(spec)/sizeof(spec[0]));
}
}
diff --git a/erts/emulator/test/driver_SUITE_data/caller_drv.c b/erts/emulator/test/driver_SUITE_data/caller_drv.c
index 1ed20b0638..2731f9b317 100644
--- a/erts/emulator/test/driver_SUITE_data/caller_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/caller_drv.c
@@ -85,9 +85,9 @@ send_caller(ErlDrvData drv_data, char *func)
ERL_DRV_PID, driver_caller(port),
ERL_DRV_TUPLE, (ErlDrvTermData) 4
};
- res = driver_output_term(port, msg, sizeof(msg)/sizeof(ErlDrvTermData));
+ res = erl_drv_output_term(driver_mk_port(port), msg, sizeof(msg)/sizeof(ErlDrvTermData));
if (res <= 0)
- driver_failure_atom(port, "driver_output_term failed");
+ driver_failure_atom(port, "erl_drv_output_term failed");
}
static ErlDrvData
diff --git a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
index d174771629..9d8bbac231 100644
--- a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
@@ -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
diff --git a/erts/emulator/test/driver_SUITE_data/monitor_drv.c b/erts/emulator/test/driver_SUITE_data/monitor_drv.c
index 3da067fd09..81dfb65191 100644
--- a/erts/emulator/test/driver_SUITE_data/monitor_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/monitor_drv.c
@@ -117,7 +117,7 @@ static void handle_monitor(ErlDrvData drv_data, ErlDrvMonitor *monitor)
o->next = p->next;
}
driver_free(p);
- driver_send_term(data->port, data->ipid, spec, sizeof(spec)/sizeof(ErlDrvTermData));
+ erl_drv_send_term(driver_mk_port(data->port), data->ipid, spec, sizeof(spec)/sizeof(ErlDrvTermData));
}
return;
diff --git a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
index 221fd0ce51..88df73f696 100644
--- a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2011. 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
@@ -134,8 +134,8 @@ static void send_reply(Otp9302AsyncData *adata)
ERL_DRV_ATOM, adata->term_data.msg,
ERL_DRV_TUPLE, 2
};
- driver_send_term(adata->port, adata->term_data.receiver,
- spec, sizeof(spec)/sizeof(spec[0]));
+ erl_drv_send_term(adata->term_data.port, adata->term_data.receiver,
+ spec, sizeof(spec)/sizeof(spec[0]));
}
static void enqueue_reply(Otp9302AsyncData *adata)
diff --git a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
index 0c86a26604..cbee1c3dce 100644
--- a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
@@ -177,15 +177,16 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data)
{
PeekNonXQDrvData *dp = (PeekNonXQDrvData *) drv_data;
if (dp->cmd == PEEK_NONXQ_WAIT) {
+ ErlDrvTermData port_id = driver_mk_port(dp->port);
ErlDrvTermData spec[] = {
- ERL_DRV_PORT, driver_mk_port(dp->port),
+ ERL_DRV_PORT, port_id,
ERL_DRV_ATOM, driver_mk_atom("test_successful"),
ERL_DRV_TUPLE, 2
};
- driver_send_term(dp->port,
- dp->caller,
- spec,
- sizeof(spec) / sizeof(spec[0]));
+ erl_drv_send_term(port_id,
+ dp->caller,
+ spec,
+ sizeof(spec) / sizeof(spec[0]));
}
if (thread_data)
driver_free(thread_data);
diff --git a/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c b/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c
index 1070678d7b..5a9112afa3 100644
--- a/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c
@@ -168,8 +168,8 @@ static void *thread(void *varg)
for (s = 0; s < THR_MSG_BLAST_NO_SENDS_PER_PROC; s++) {
for (p = 0; p < THR_MSG_BLAST_NO_PROCS; p++) {
- int res = driver_send_term(tmbd->port, tmbd->proc[p],
- spec, sizeof(spec)/sizeof(spec[0]));
+ int res = erl_drv_send_term(tmbd->td_port, tmbd->proc[p],
+ spec, sizeof(spec)/sizeof(spec[0]));
if (p == 0 && res <= 0)
abort(); /* Could not send to creator */
}
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c b/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c
index b4542f3e36..2cd3209231 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/testcase_driver.c
@@ -42,6 +42,7 @@
typedef struct {
TestCaseState_t visible;
ErlDrvPort port;
+ ErlDrvTermData port_id;
int result;
jmp_buf done_jmp_buf;
char *comment;
@@ -98,6 +99,7 @@ testcase_drv_start(ErlDrvPort port, char *command)
itcs->visible.testcase_name = testcase_name();
itcs->visible.extra = NULL;
itcs->port = port;
+ itcs->port_id = driver_mk_port(port);
itcs->result = TESTCASE_FAILED;
itcs->comment = "";
@@ -143,7 +145,7 @@ testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
msg[1] = (ErlDrvTermData) result_atom;
msg[2] = ERL_DRV_PORT;
- msg[3] = driver_mk_port(itcs->port);
+ msg[3] = itcs->port_id;
msg[4] = ERL_DRV_ATOM;
msg[5] = driver_mk_atom(itcs->visible.testcase_name);
@@ -155,7 +157,7 @@ testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
msg[9] = ERL_DRV_TUPLE;
msg[10] = (ErlDrvTermData) 4;
- driver_output_term(itcs->port, msg, 11);
+ erl_drv_output_term(itcs->port_id, msg, 11);
}
int
@@ -185,7 +187,7 @@ testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
msg[1] = (ErlDrvTermData) driver_mk_atom("print");
msg[2] = ERL_DRV_PORT;
- msg[3] = driver_mk_port(itcs->port);
+ msg[3] = itcs->port_id;
msg[4] = ERL_DRV_ATOM;
msg[5] = driver_mk_atom(itcs->visible.testcase_name);
@@ -197,7 +199,7 @@ testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
msg[9] = ERL_DRV_TUPLE;
msg[10] = (ErlDrvTermData) 4;
- driver_output_term(itcs->port, msg, 11);
+ erl_drv_output_term(itcs->port_id, msg, 11);
}
diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl
index 21834bfa62..1de6d6fb56 100644
--- a/erts/emulator/test/estone_SUITE.erl
+++ b/erts/emulator/test/estone_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 19fa433a53..36889b6c36 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -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
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index d5cb4ee1b7..8dbc6b6538 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
diff --git a/erts/emulator/test/mtx_SUITE.erl b/erts/emulator/test/mtx_SUITE.erl
index 024c3456a8..22da84c808 100644
--- a/erts/emulator/test/mtx_SUITE.erl
+++ b/erts/emulator/test/mtx_SUITE.erl
@@ -58,8 +58,12 @@
init_per_suite(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
Lib = filename:join([DataDir, atom_to_list(?MODULE)]),
- ok = erlang:load_nif(Lib, none),
- Config.
+ case {erlang:load_nif(Lib, none),erlang:system_info(threads)} of
+ {{error,_},false} ->
+ {skip, "No thread support"};
+ _ ->
+ Config
+ end.
end_per_suite(Config) when is_list(Config) ->
catch erts_debug:set_internal_state(available_internal_state, false),
diff --git a/erts/emulator/test/mtx_SUITE_data/Makefile.src b/erts/emulator/test/mtx_SUITE_data/Makefile.src
index 37eb1daa72..e65d99e968 100644
--- a/erts/emulator/test/mtx_SUITE_data/Makefile.src
+++ b/erts/emulator/test/mtx_SUITE_data/Makefile.src
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. 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
diff --git a/erts/emulator/test/nofrag_SUITE.erl b/erts/emulator/test/nofrag_SUITE.erl
index 71567ed0cb..57eec87e63 100644
--- a/erts/emulator/test/nofrag_SUITE.erl
+++ b/erts/emulator/test/nofrag_SUITE.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
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
index 4459732257..bf33c337ee 100644
--- a/erts/emulator/test/num_bif_SUITE.erl
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -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
@@ -25,6 +25,7 @@
%% abs/1
%% float/1
%% float_to_list/1
+%% float_to_list/2
%% integer_to_list/1
%% list_to_float/1
%% list_to_integer/1
@@ -114,14 +115,46 @@ t_float(Config) when is_list(Config) ->
ok.
-%% Tests float_to_list/1.
+%% Tests float_to_list/1, float_to_list/2.
t_float_to_list(Config) when is_list(Config) ->
- ?line test_ftl("0.0e+0", 0.0),
- ?line test_ftl("2.5e+1", 25.0),
- ?line test_ftl("2.5e+0", 2.5),
- ?line test_ftl("2.5e-1", 0.25),
- ?line test_ftl("-3.5e+17", -350.0e15),
+ test_ftl("0.0e+0", 0.0),
+ test_ftl("2.5e+1", 25.0),
+ test_ftl("2.5e+0", 2.5),
+ test_ftl("2.5e-1", 0.25),
+ test_ftl("-3.5e+17", -350.0e15),
+ "1.00000000000000000000e+00" = float_to_list(1.0),
+ "1.00000000000000000000e+00" = float_to_list(1.0, []),
+ "-1.00000000000000000000e+00" = float_to_list(-1.0, []),
+ "-1.00000000000000000000" = float_to_list(-1.0, [{decimals, 20}]),
+ {'EXIT', {badarg, _}} = (catch float_to_list(1.0, [{decimals, -1}])),
+ {'EXIT', {badarg, _}} = (catch float_to_list(1.0, [{decimals, 250}])),
+ {'EXIT', {badarg, _}} = (catch float_to_list(1.0e+300, [{decimals, 1}])),
+ "1.0e+300" = float_to_list(1.0e+300, [{scientific, 1}]),
+ "1.0" = float_to_list(1.0, [{decimals, 249}, compact]),
+ Expected = "1." ++ string:copies("0", 249) ++ "e+00",
+ Expected = float_to_list(1.0, [{scientific, 249}, compact]),
+
+ X1 = float_to_list(1.0),
+ X2 = float_to_list(1.0, [{scientific, 20}]),
+ X1 = X2,
+ "1.000e+00" = float_to_list(1.0, [{scientific, 3}]),
+ "1.000" = float_to_list(1.0, [{decimals, 3}]),
+ "1.0" = float_to_list(1.0, [{decimals, 3}, compact]),
+ "1.12" = float_to_list(1.123, [{decimals, 2}]),
+ "1.123" = float_to_list(1.123, [{decimals, 3}]),
+ "1.123" = float_to_list(1.123, [{decimals, 3}, compact]),
+ "1.1230" = float_to_list(1.123, [{decimals, 4}]),
+ "1.12300" = float_to_list(1.123, [{decimals, 5}]),
+ "1.123" = float_to_list(1.123, [{decimals, 5}, compact]),
+ "1.1234" = float_to_list(1.1234,[{decimals, 6}, compact]),
+ "2.333333" = erlang:float_to_list(7/3, [{decimals, 6}, compact]),
+ "2.333333" = erlang:float_to_list(7/3, [{decimals, 6}]),
+ "0.00000000000000000000e+00" = float_to_list(0.0, [compact]),
+ "0.0" = float_to_list(0.0, [{decimals, 10}, compact]),
+ "123000000000000000000.0" = float_to_list(1.23e20, [{decimals, 10}, compact]),
+ "1.2300000000e+20" = float_to_list(1.23e20, [{scientific, 10}, compact]),
+ "1.23000000000000000000e+20" = float_to_list(1.23e20, []),
ok.
test_ftl(Expect, Float) ->
diff --git a/erts/emulator/test/port_SUITE_data/dead_port.c b/erts/emulator/test/port_SUITE_data/dead_port.c
index 4dd9ee4cc2..ea91546b0c 100644
--- a/erts/emulator/test/port_SUITE_data/dead_port.c
+++ b/erts/emulator/test/port_SUITE_data/dead_port.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. 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
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 11dd88413f..863cd2d654 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -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
diff --git a/erts/emulator/test/save_calls_SUITE.erl b/erts/emulator/test/save_calls_SUITE.erl
index 26ac4f2f7f..ddf8b2d919 100644
--- a/erts/emulator/test/save_calls_SUITE.erl
+++ b/erts/emulator/test/save_calls_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
diff --git a/erts/emulator/test/send_term_SUITE_data/send_term_drv.c b/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
index b3feca79f0..f8613487b0 100644
--- a/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
+++ b/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
@@ -664,7 +664,7 @@ static void send_term_drv_run(ErlDrvData port, char *buf, ErlDrvSizeT count)
/* Signal end of test case */
msg[0] = ERL_DRV_NIL;
- driver_output_term(erlang_port, msg, 1);
+ erl_drv_output_term(driver_mk_port(erlang_port), msg, 1);
return;
}
break;
@@ -687,14 +687,14 @@ static void send_term_drv_run(ErlDrvData port, char *buf, ErlDrvSizeT count)
static void output_term(ErlDrvTermData* msg, int len)
{
- if (driver_output_term(erlang_port, msg, len) <= 0) {
- driver_failure_atom(erlang_port, "driver_output_term_failed");
+ if (erl_drv_output_term(driver_mk_port(erlang_port), msg, len) <= 0) {
+ driver_failure_atom(erlang_port, "erl_drv_output_term_failed");
}
}
static void fail_term(ErlDrvTermData* msg, int len, int line)
{
- int status = driver_output_term(erlang_port, msg, len);
+ int status = erl_drv_output_term(driver_mk_port(erlang_port), msg, len);
if (status == 1) {
char buf[1024];
diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl
index c9533d0748..c28224729d 100644
--- a/erts/emulator/test/timer_bif_SUITE.erl
+++ b/erts/emulator/test/timer_bif_SUITE.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
diff --git a/erts/emulator/test/trace_local_SUITE.erl b/erts/emulator/test/trace_local_SUITE.erl
index b89a8c4a0e..1bed49aad2 100644
--- a/erts/emulator/test/trace_local_SUITE.erl
+++ b/erts/emulator/test/trace_local_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
@@ -874,7 +874,7 @@ exception_test(Opts, Func0, Args0) ->
%% wrap them in wrappers...
?line {Func1,Args1} =
case Function of
- true -> {fun (F, As) -> exc(F, As) end,[Func0,Args0]};
+ true -> {fun exc/2,[Func0,Args0]};
false -> {Func0,Args0}
end,
diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl
index a3b2764a5d..46ece41096 100644
--- a/erts/emulator/test/tuple_SUITE.erl
+++ b/erts/emulator/test/tuple_SUITE.erl
@@ -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
diff --git a/erts/emulator/utils/make_tables b/erts/emulator/utils/make_tables
index a841f26d6a..597a201e5a 100755
--- a/erts/emulator/utils/make_tables
+++ b/erts/emulator/utils/make_tables
@@ -2,7 +2,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2010. 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
diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c
index 3577abf6ba..94bb74c876 100644
--- a/erts/epmd/src/epmd.c
+++ b/erts/epmd/src/epmd.c
@@ -2,7 +2,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
diff --git a/erts/epmd/src/epmd_cli.c b/erts/epmd/src/epmd_cli.c
index 74408e3ebe..8817bde8d7 100644
--- a/erts/epmd/src/epmd_cli.c
+++ b/erts/epmd/src/epmd_cli.c
@@ -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
@@ -22,6 +22,7 @@
#endif
#include "epmd.h" /* Renamed from 'epmd_r4.h' */
#include "epmd_int.h"
+#include "erl_printf.h" /* erts_snprintf */
/* forward declarations */
@@ -114,16 +115,18 @@ void epmd_call(EpmdVars *g,int what)
epmd_cleanup_exit(g,1);
}
j = ntohl(i);
- if (!g->silent)
- printf("epmd: up and running on port %d with data:\n", j);
+ if (!g->silent) {
+ rval = erts_snprintf(buf, OUTBUF_SIZE,
+ "epmd: up and running on port %d with data:\n", j);
+ write(1, buf, rval);
+ }
while(1) {
- if ((rval = read(fd,buf,1)) <= 0) {
+ if ((rval = read(fd,buf,OUTBUF_SIZE)) <= 0) {
close(fd);
epmd_cleanup_exit(g,0);
}
- buf[rval] = '\0';
if (!g->silent)
- printf("%s",buf);
+ write(1, buf, rval); /* Potentially UTF-8 encoded */
}
}
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index 14d05c3f19..ac354dcc78 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -2,7 +2,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
@@ -226,13 +226,25 @@
#define MAX_UNREG_COUNT 1000
#define DEBUG_MAX_UNREG_COUNT 5
-/* Maximum length of a node name == atom name */
-#define MAXSYMLEN 255
+/*
+ * Maximum length of a node name == atom name
+ * 255 characters; UTF-8 encoded -> max 255*4
+ */
+#define MAXSYMLEN (255*4)
#define MAX_LISTEN_SOCKETS 16
-#define INBUF_SIZE 1024
-#define OUTBUF_SIZE 1024
+/*
+ * Largest request: ALIVE2_REQ
+ * 2 + 13 + 2*MAXSYMLEN
+ * Largest response: PORT2_RESP
+ * 2 + 14 + 2*MAXSYMLEN
+ *
+ * That is, 3*MAXSYMLEN should be large enough
+ */
+
+#define INBUF_SIZE (3*MAXSYMLEN)
+#define OUTBUF_SIZE (3*MAXSYMLEN)
#define get_int16(s) ((((unsigned char*) (s))[0] << 8) | \
(((unsigned char*) (s))[1]))
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 36565b7438..90df7cc25a 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -2,7 +2,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
@@ -73,7 +73,7 @@ static int conn_open(EpmdVars*,int);
static int conn_close_fd(EpmdVars*,int);
static void node_init(EpmdVars*);
-static Node *node_reg2(EpmdVars*,char*, int, int, unsigned char, unsigned char, int, int, int, char*);
+static Node *node_reg2(EpmdVars*, int, char*, int, int, unsigned char, unsigned char, int, int, int, char*);
static int node_unreg(EpmdVars*,char*);
static int node_unreg_sock(EpmdVars*,int);
@@ -81,6 +81,113 @@ static int reply(EpmdVars*,int,char *,int);
static void dbg_print_buf(EpmdVars*,char *,int);
static void print_names(EpmdVars*);
+static int is_same_str(char *x, char *y)
+{
+ int i = 0;
+ /*
+ * Using strcmp() == 0 is probably ok, but just to be sure,
+ * since we got UTF-8 strings, we do it ourselves.
+ *
+ * We assume null-terminated correctly encoded UTF-8.
+ */
+ while (x[i] == y[i]) {
+ if (x[i] == '\0')
+ return 1;
+ i++;
+ }
+ return 0;
+}
+
+static int copy_str(char *x, char *y)
+{
+ int i = 0;
+ /*
+ * Using strcpy() is probably ok, but just to be sure,
+ * since we got UTF-8 strings, we do it ourselves.
+ *
+ * We assume null-terminated correctly encoded UTF-8.
+ */
+ while (1) {
+ x[i] = y[i];
+ if (y[i] == '\0')
+ return i;
+ i++;
+ }
+}
+
+static int length_str(char *x)
+{
+ int i = 0;
+ /*
+ * Using strlen is probably ok, but just to be sure,
+ * since we got UTF-8 strings, we do it ourselves.
+ *
+ * We assume null-terminated correctly encoded UTF-8.
+ */
+ while (x[i])
+ i++;
+ return i;
+}
+
+static int verify_utf8(const char *src, int sz, int null_term)
+{
+ unsigned char *source = (unsigned char *) src;
+ int size = sz;
+ int num_chars = 0;
+ while (size) {
+ if (null_term && (*source) == 0)
+ return num_chars;
+ if (((*source) & ((unsigned char) 0x80)) == 0) {
+ source++;
+ --size;
+ } else if (((*source) & ((unsigned char) 0xE0)) == 0xC0) {
+ if (size < 2)
+ return -1;
+ if (((source[1] & ((unsigned char) 0xC0)) != 0x80) ||
+ ((*source) < 0xC2) /* overlong */) {
+ return -1;
+ }
+ source += 2;
+ size -= 2;
+ } else if (((*source) & ((unsigned char) 0xF0)) == 0xE0) {
+ if (size < 3)
+ return -1;
+ if (((source[1] & ((unsigned char) 0xC0)) != 0x80) ||
+ ((source[2] & ((unsigned char) 0xC0)) != 0x80) ||
+ (((*source) == 0xE0) && (source[1] < 0xA0)) /* overlong */ ) {
+ return -1;
+ }
+ if ((((*source) & ((unsigned char) 0xF)) == 0xD) &&
+ ((source[1] & 0x20) != 0)) {
+ return -1;
+ }
+ source += 3;
+ size -= 3;
+ } else if (((*source) & ((unsigned char) 0xF8)) == 0xF0) {
+ if (size < 4)
+ return -1;
+ if (((source[1] & ((unsigned char) 0xC0)) != 0x80) ||
+ ((source[2] & ((unsigned char) 0xC0)) != 0x80) ||
+ ((source[3] & ((unsigned char) 0xC0)) != 0x80) ||
+ (((*source) == 0xF0) && (source[1] < 0x90)) /* overlong */) {
+ return -1;
+ }
+ if ((((*source) & ((unsigned char)0x7)) > 0x4U) ||
+ ((((*source) & ((unsigned char)0x7)) == 0x4U) &&
+ ((source[1] & ((unsigned char)0x3F)) > 0xFU))) {
+ return -1;
+ }
+ source += 4;
+ size -= 4;
+ } else {
+ return -1;
+ }
+ ++num_chars;
+ }
+ return num_chars;
+}
+
+
static EPMD_INLINE void select_fd_set(EpmdVars* g, int fd)
{
FD_SET(fd, &g->orig_read_mask);
@@ -525,10 +632,11 @@ static void do_request(g, fd, s, buf, bsize)
}
name = &buf[11];
name[namelen]='\000';
+
extra = &buf[11+namelen+2];
extra[extralen]='\000';
wbuf[0] = EPMD_ALIVE2_RESP;
- if ((node = node_reg2(g, name, fd, eport, nodetype, protocol,
+ if ((node = node_reg2(g, namelen, name, fd, eport, nodetype, protocol,
highvsn, lowvsn, extralen, extra)) == NULL) {
wbuf[1] = 1; /* error */
put_int16(99, wbuf+2);
@@ -573,22 +681,28 @@ static void do_request(g, fd, s, buf, bsize)
{
char *name = &buf[1]; /* Points to node name */
+ int nsz;
Node *node;
-
+
+ nsz = verify_utf8(name, bsize, 0);
+ if (nsz < 1 || 255 < nsz) {
+ dbg_printf(g,0,"invalid node name in PORT2_REQ");
+ return;
+ }
+
wbuf[0] = EPMD_PORT2_RESP;
for (node = g->nodes.reg; node; node = node->next) {
int offset;
- if (strcmp(node->symname, name) == 0) {
+ if (is_same_str(node->symname, name)) {
wbuf[1] = 0; /* ok */
put_int16(node->port,wbuf+2);
wbuf[4] = node->nodetype;
wbuf[5] = node->protocol;
put_int16(node->highvsn,wbuf+6);
put_int16(node->lowvsn,wbuf+8);
- put_int16(strlen(node->symname),wbuf+10);
+ put_int16(length_str(node->symname),wbuf+10);
offset = 12;
- strcpy(wbuf + offset,node->symname);
- offset += strlen(node->symname);
+ offset += copy_str(wbuf + offset,node->symname);
put_int16(node->extralen,wbuf + offset);
offset += 2;
memcpy(wbuf + offset,node->extra,node->extralen);
@@ -629,15 +743,22 @@ static void do_request(g, fd, s, buf, bsize)
for (node = g->nodes.reg; node; node = node->next)
{
- int len;
+ int len = 0;
+ int r;
/* CAREFUL!!! These are parsed by "erl_epmd.erl" so a slight
change in syntax will break < OTP R3A */
- erts_snprintf(wbuf, sizeof(wbuf), "name %s at port %d\n",node->symname, node->port);
- len = strlen(wbuf);
+ len += copy_str(&wbuf[len], "name ");
+ len += copy_str(&wbuf[len], node->symname);
+ r = erts_snprintf(&wbuf[len], sizeof(wbuf)-len,
+ " at port %d\n", node->port);
+ if (r < 0)
+ goto failed_names_resp;
+ len += r;
if (reply(g, fd, wbuf, len) != len)
{
+ failed_names_resp:
dbg_tty_printf(g,1,"failed to send NAMES_RESP");
return;
}
@@ -665,16 +786,22 @@ static void do_request(g, fd, s, buf, bsize)
for (node = g->nodes.reg; node; node = node->next)
{
- int len;
+ int len = 0, r;
/* CAREFUL!!! These are parsed by "erl_epmd.erl" so a slight
change in syntax will break < OTP R3A */
- erts_snprintf(wbuf, sizeof(wbuf), "active name <%s> at port %d, fd = %d\n",
- node->symname, node->port, node->fd);
- len = strlen(wbuf) + 1;
- if (reply(g, fd,wbuf,len) != len)
+ len += copy_str(&wbuf[len], "active name <");
+ len += copy_str(&wbuf[len], node->symname);
+ r = erts_snprintf(&wbuf[len], sizeof(wbuf)-len,
+ "> at port %d, fd = %d\n",
+ node->port, node->fd);
+ if (r < 0)
+ goto failed_dump_resp;
+ len += r + 1;
+ if (reply(g, fd,wbuf,len) != len)
{
+ failed_dump_resp:
dbg_tty_printf(g,1,"failed to send DUMP_RESP");
return;
}
@@ -682,16 +809,22 @@ static void do_request(g, fd, s, buf, bsize)
for (node = g->nodes.unreg; node; node = node->next)
{
- int len;
+ int len = 0, r;
/* CAREFUL!!! These are parsed by "erl_epmd.erl" so a slight
change in syntax will break < OTP R3A */
- erts_snprintf(wbuf, sizeof(wbuf), "old/unused name <%s>, port = %d, fd = %d \n",
- node->symname,node->port, node->fd);
- len = strlen(wbuf) + 1;
- if (reply(g, fd,wbuf,len) != len)
+ len += copy_str(&wbuf[len], "old/unused name <");
+ len += copy_str(&wbuf[len], node->symname);
+ r = erts_snprintf(&wbuf[len], sizeof(wbuf)-len,
+ ">, port = %d, fd = %d \n",
+ node->port, node->fd);
+ if (r < 0)
+ goto failed_dump_resp2;
+ len += r + 1;
+ if (reply(g, fd,wbuf,len) != len)
{
+ failed_dump_resp2:
dbg_tty_printf(g,1,"failed to send DUMP_RESP");
return;
}
@@ -933,7 +1066,7 @@ static int node_unreg(EpmdVars *g,char *name)
Node *node = g->nodes.reg; /* Point to first node */
for (; node; prev = &node->next, node = node->next)
- if (strcmp(node->symname, name) == 0)
+ if (is_same_str(node->symname, name))
{
dbg_tty_printf(g,1,"unregistering '%s:%d', port %d",
node->symname, node->creation, node->port);
@@ -1013,6 +1146,7 @@ static int node_unreg_sock(EpmdVars *g,int fd)
*/
static Node *node_reg2(EpmdVars *g,
+ int namelen,
char* name,
int fd,
int port,
@@ -1025,6 +1159,7 @@ static Node *node_reg2(EpmdVars *g,
{
Node *prev; /* Point to previous node or NULL */
Node *node; /* Point to first node */
+ int sz;
/* Can be NULL; means old style */
if (extra == NULL)
@@ -1032,21 +1167,47 @@ static Node *node_reg2(EpmdVars *g,
/* Fail if node name is too long */
- if (strlen(name) > MAXSYMLEN)
+
+ if (namelen > MAXSYMLEN)
{
- dbg_printf(g,0,"node name is too long (%d) %s", strlen(name), name);
+ too_long_name:
+ dbg_printf(g,0,"node name is too long (%d) %s", namelen, name);
return NULL;
}
+
+ sz = verify_utf8(name, namelen, 0);
+ if (sz > 255)
+ goto too_long_name;
+
+ if (sz < 0) {
+ dbg_printf(g,0,"invalid node name encoding");
+ return NULL;
+ }
+
if (extralen > MAXSYMLEN)
{
- dbg_printf(g,0,"extra data is too long (%d) %s", strlen(name), name);
+#if 0
+ too_long_extra:
+#endif
+ dbg_printf(g,0,"extra data is too long (%d) %s", extralen, extra);
return NULL;
}
+#if 0 /* Should we require valid utf8 here? */
+ sz = verify_utf8(extra, extralen, 0);
+ if (sz > 255)
+ goto too_long_extra;
+
+ if (sz < 0) {
+ dbg_printf(g,0,"invalid extra data encoding");
+ return NULL;
+ }
+#endif
+
/* Fail if it is already registered */
for (node = g->nodes.reg; node; node = node->next)
- if (strcmp(node->symname, name) == 0)
+ if (is_same_str(node->symname, name))
{
dbg_printf(g,0,"node name already occupied %s", name);
return NULL;
@@ -1058,7 +1219,7 @@ static Node *node_reg2(EpmdVars *g,
prev = NULL;
for (node = g->nodes.unreg; node; prev = node, node = node->next)
- if (strcmp(node->symname, name) == 0)
+ if (is_same_str(node->symname, name))
{
dbg_tty_printf(g,1,"reusing slot with same name '%s'", node->symname);
@@ -1126,7 +1287,7 @@ static Node *node_reg2(EpmdVars *g,
node->lowvsn = lowvsn;
node->extralen = extralen;
memcpy(node->extra,extra,extralen);
- strcpy(node->symname,name);
+ copy_str(node->symname,name);
select_fd_set(g, fd);
if (highvsn == 0) {
diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl
index fd9969ae2b..cc24a556a3 100644
--- a/erts/epmd/test/epmd_SUITE.erl
+++ b/erts/epmd/test/epmd_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
@@ -45,6 +45,8 @@
register_names_1/1,
register_names_2/1,
register_duplicate_name/1,
+ unicode_name/1,
+ long_unicode_name/1,
get_port_nr/1,
slow_get_port_nr/1,
unregister_others_name_1/1,
@@ -107,7 +109,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[register_name, register_names_1, register_names_2,
- register_duplicate_name, get_port_nr, slow_get_port_nr,
+ register_duplicate_name, unicode_name, long_unicode_name,
+ get_port_nr, slow_get_port_nr,
unregister_others_name_1, unregister_others_name_2,
register_overflow, name_with_null_inside,
name_null_terminated, stupid_names_req, no_data,
@@ -197,6 +200,37 @@ register_duplicate_name(Config) when is_list(Config) ->
?line ok = close(Sock), % Unregister
ok.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+unicode_name(doc) ->
+ ["Check that we can register and lookup a unicode name"];
+unicode_name(suite) ->
+ [];
+unicode_name(Config) when is_list(Config) ->
+ ok = epmdrun(),
+ NodeName = [16#1f608],
+ {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, NodeName, []),
+ {ok,NodeInfo} = port_please_v2(NodeName),
+ NodeName = NodeInfo#node_info.node_name,
+ ok = close(Sock),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+long_unicode_name(doc) ->
+ ["Check that we can register and lookup a long unicode name"];
+long_unicode_name(suite) ->
+ [];
+long_unicode_name(Config) when is_list(Config) ->
+ ok = epmdrun(),
+ BaseChar = 16#1f600,
+ NodeName = lists:seq(BaseChar, BaseChar+200), % will be 800 bytes long
+ {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, NodeName, []),
+ {ok,NodeInfo} = port_please_v2(NodeName),
+ NodeName = NodeInfo#node_info.node_name,
+ ok = close(Sock),
+ ok.
+
% Internal function to register a node name, no close, i.e. unregister
register_node(Name) ->
@@ -205,9 +239,10 @@ register_node(Name,Port) ->
register_node_v2(Port,$M,0,5,5,Name,"").
register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
+ Utf8Name = unicode:characters_to_binary(Name),
Req = [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot,
put16(HVsn), put16(LVsn),
- size16(Name), Name,
+ put16(size(Utf8Name)), binary_to_list(Utf8Name),
size16(Extra), Extra],
case send_req(Req) of
{ok,Sock} ->
@@ -226,7 +261,8 @@ register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
% Internal function to fetch information about a node
port_please_v2(Name) ->
- case send_req([?EPMD_PORT_PLEASE2_REQ, Name]) of
+ case send_req([?EPMD_PORT_PLEASE2_REQ,
+ binary_to_list(unicode:characters_to_binary(Name))]) of
{ok,Sock} ->
case recv_until_sock_closes(Sock) of
{ok, Resp} ->
@@ -247,7 +283,7 @@ parse_port2_resp(Resp) ->
ELen:16,Extra:ELen/binary>> when Res =:= 0 ->
{ok, #node_info{port=Port,node_type=NodeType,prot=Prot,
hvsn=HVsn,lvsn=LVsn,
- node_name=binary_to_list(NodeName),
+ node_name=unicode:characters_to_list(NodeName),
extra=binary_to_list(Extra)}};
_Other ->
test_server:format("invalid port2 resp: ~p~n",
@@ -737,7 +773,7 @@ buffer_overrun_2(doc) ->
["Test security vulnerability in fake extra lengths in alive2_req"];
buffer_overrun_2(Config) when is_list(Config) ->
?line ok = epmdrun(),
- ?line [false | Rest] = [hostile2(N) || N <- lists:seq(255,10000)],
+ ?line [false | Rest] = [hostile2(N) || N <- lists:seq(255*4,10000)],
?line true = alltrue(Rest),
ok.
hostile(N) ->
@@ -880,6 +916,7 @@ no_live_killing(Config) when is_list(Config) ->
?line close(Sock3),
ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Terminate all tests with killing epmd.
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 50c61f50eb..577554c43d 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -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
@@ -124,6 +124,7 @@ static char *pluss_val_switches[] = {
"bwt",
"cl",
"ct",
+ "tbt",
"wt",
"ws",
"ss",
@@ -183,7 +184,6 @@ void error(char* format, ...);
#if !defined(ERTS_HAVE_SMP_EMU)
static void usage_notsup(const char *switchname);
#endif
-static void usage_msg(const char *msg);
static char **build_args_from_env(char *env_var);
static char **build_args_from_string(char *env_var);
static void initial_argv_massage(int *argc, char ***argv);
@@ -1131,13 +1131,6 @@ usage_notsup(const char *switchname)
#endif
static void
-usage_msg(const char *msg)
-{
- fprintf(stderr, "%s\n", msg);
- usage_aux();
-}
-
-static void
usage_format(char *format, ...)
{
va_list args;
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 3566406bf3..118bc6ef90 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -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
diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c
index b9a0e6bde3..bef97862a3 100644
--- a/erts/etc/common/inet_gethost.c
+++ b/erts/etc/common/inet_gethost.c
@@ -2562,7 +2562,8 @@ static void debugf(char *format, ...)
}
#else
/* suppress warning with 'if' */
- if(write(2,buff,strlen(buff)));
+ if(write(2,buff,strlen(buff)))
+ ;
#endif
va_end(ap);
}
@@ -2585,7 +2586,8 @@ static void warning(char *format, ...)
}
#else
/* suppress warning with 'if' */
- if(write(2,buff,strlen(buff)));
+ if(write(2,buff,strlen(buff)))
+ ;
#endif
va_end(ap);
}
@@ -2608,7 +2610,8 @@ static void fatal(char *format, ...)
}
#else
/* suppress warning with 'if' */
- if(write(2,buff,strlen(buff)));
+ if(write(2,buff,strlen(buff)))
+ ;
#endif
va_end(ap);
#ifndef WIN32
diff --git a/erts/etc/win32/nsis/dll_version_helper.sh b/erts/etc/win32/nsis/dll_version_helper.sh
index 0d9ba4248d..e75edf3738 100755
--- a/erts/etc/win32/nsis/dll_version_helper.sh
+++ b/erts/etc/win32/nsis/dll_version_helper.sh
@@ -2,7 +2,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
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index 88083bfe7d..0fc3ac6efc 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -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
@@ -579,7 +579,7 @@ ifeq ($(USING_VC),yes)
| $(SED_MDd_DEPEND) >> $(DEPEND_MK)
else
$(V_at)$(DEP_CC) -MM $(THR_DEFS) $(DEP_FLAGS) $(ETHREAD_LIB_SRC) \
- | $(SED_r_DEPEND) >$(V_at)> $(DEPEND_MK)
+ | $(SED_r_DEPEND) >> $(DEPEND_MK)
endif
endif
ifneq ($(strip $(ERTS_INTERNAL_LIB_SRCS)),)
diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c
index 1b49f69581..11e2c56f61 100644
--- a/erts/lib_src/common/erl_misc_utils.c
+++ b/erts/lib_src/common/erl_misc_utils.c
@@ -28,6 +28,8 @@
#include "erl_misc_utils.h"
#if defined(__WIN32__)
+#elif defined(VXWORKS)
+# include <selectLib.h>
#else /* UNIX */
# include <stdio.h>
# include <sys/types.h>
diff --git a/erts/lib_src/common/erl_printf_format.c b/erts/lib_src/common/erl_printf_format.c
index fd25cce7ed..384b1b1ad7 100644
--- a/erts/lib_src/common/erl_printf_format.c
+++ b/erts/lib_src/common/erl_printf_format.c
@@ -339,7 +339,7 @@ static int fmt_double(fmtfn_t fn,void*arg,double val,
double dexp;
int exp;
size_t max_size = 1;
- size_t size;
+ int size;
int new_fmt = fmt;
int fpe_was_unmasked;
diff --git a/erts/lib_src/common/ethr_mutex.c b/erts/lib_src/common/ethr_mutex.c
index e363279f2e..d8cd691e9d 100644
--- a/erts/lib_src/common/ethr_mutex.c
+++ b/erts/lib_src/common/ethr_mutex.c
@@ -692,7 +692,7 @@ write_lock_wait(struct ethr_mutex_base_ *mtxb,
goto chk_spin;
if (--until_yield == 0) {
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
- ETHR_YIELD();
+ (void) ETHR_YIELD();
}
}
@@ -711,7 +711,7 @@ write_lock_wait(struct ethr_mutex_base_ *mtxb,
ETHR_SPIN_BODY;
if (--until_yield == 0) {
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
- ETHR_YIELD();
+ (void) ETHR_YIELD();
}
act = ethr_atomic32_read(&mtxb->flgs);
scnt--;
@@ -2161,7 +2161,7 @@ rwmutex_normal_rlock_wait(ethr_rwmutex *rwmtx, ethr_sint32_t initial)
ETHR_SPIN_BODY;
if (--until_yield == 0) {
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
- ETHR_YIELD();
+ (void) ETHR_YIELD();
}
act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
scnt--;
@@ -2288,7 +2288,7 @@ rwmutex_freqread_rlock_wait(ethr_rwmutex *rwmtx,
ETHR_SPIN_BODY;
if (--until_yield == 0) {
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
- ETHR_YIELD();
+ (void) ETHR_YIELD();
}
act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
scnt--;
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 344fa3ecc0..f8c2df3a5a 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index bea586b11c..5b288ecc5c 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index af06c2a1cb..5b74dd6320 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 9710204552..6ee3dde07a 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 0ba1cb8f73..e499a2494f 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index b8f71b0c1e..ca93edbe25 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index a1aca09d1d..fb0a97fe09 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index bec1f2cc21..85492898d9 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 1ac89dd42a..9442134195 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 061db72dd8..115e1b03c4 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.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
@@ -84,7 +84,8 @@
-export([display_nl/0, display_string/1, dist_exit/3, erase/0, erase/1]).
-export([error/1, error/2, exit/1, exit/2, external_size/1]).
-export([external_size/2, finish_after_on_load/2, finish_loading/1, float/1]).
--export([float_to_list/1, fun_info/2, fun_to_list/1, function_exported/3]).
+-export([float_to_list/1, float_to_list/2]).
+-export([fun_info/2, fun_to_list/1, function_exported/3]).
-export([garbage_collect/0, garbage_collect/1]).
-export([garbage_collect_message_area/0, get/0, get/1, get_keys/1]).
-export([get_module_info/1, get_stacktrace/0, group_leader/0]).
@@ -711,6 +712,16 @@ float(_Number) ->
float_to_list(_Float) ->
erlang:nif_error(undefined).
+%% float_to_list/2
+-spec float_to_list(Float, Options) -> string() when
+ Float :: float(),
+ Options :: [Option],
+ Option :: {decimals, non_neg_integer()} |
+ {scientific, non_neg_integer()} |
+ compact.
+float_to_list(_Float, _Options) ->
+ erlang:nif_error(undefined).
+
%% fun_info/2
-spec erlang:fun_info(Fun, Item) -> {Item, Info} when
Fun :: function(),
@@ -2057,6 +2068,8 @@ tuple_to_list(_Tuple) ->
(multi_scheduling) -> disabled | blocked | enabled;
(multi_scheduling_blockers) -> [PID :: pid()];
(otp_release) -> string();
+ (port_count) -> non_neg_integer();
+ (port_limit) -> pos_integer();
(process_count) -> pos_integer();
(process_limit) -> pos_integer();
(procs) -> binary();
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index 1d1087c7f2..61d8df2428 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.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
@@ -184,12 +184,16 @@ prepare_run_args({run, [M,F|Args]}) ->
[b2a(M), b2a(F) | bs2ss(Args)].
b2a(Bin) when is_binary(Bin) ->
- list_to_atom(binary_to_list(Bin));
+ list_to_atom(b2s(Bin));
b2a(A) when is_atom(A) ->
A.
b2s(Bin) when is_binary(Bin) ->
- binary_to_list(Bin);
+ try
+ unicode:characters_to_list(Bin,file:native_name_encoding())
+ catch
+ _:_ -> binary_to_list(Bin)
+ end;
b2s(L) when is_list(L) ->
L.
@@ -1260,11 +1264,7 @@ get_arguments([]) ->
[].
to_strings([H|T]) when is_atom(H) -> [atom_to_list(H)|to_strings(T)];
-to_strings([H|T]) when is_binary(H) -> [try
- unicode:characters_to_list(H,file:native_name_encoding())
- catch
- _:_ -> binary_to_list(H)
- end|to_strings(T)];
+to_strings([H|T]) when is_binary(H) -> [b2s(H)|to_strings(T)];
to_strings([]) -> [].
get_argument(Arg,Flags) ->
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index c412b7faf2..50adf9c89d 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
@@ -154,8 +154,7 @@
internal_native2name/1,
internal_normalize_utf8/1]).
--type unicode_string() :: [unicode:unicode_char()].
--type prim_file_name() :: unicode_string() | unicode:unicode_binary().
+-type prim_file_name() :: string() | unicode:unicode_binary().
-spec internal_name2native(prim_file_name()) -> binary().
@@ -167,7 +166,7 @@ internal_name2native(_) ->
internal_native2name(_) ->
erlang:nif_error(undefined).
--spec internal_normalize_utf8(unicode:unicode_binary()) -> unicode_string().
+-spec internal_normalize_utf8(unicode:unicode_binary()) -> string().
internal_normalize_utf8(_) ->
erlang:nif_error(undefined).
diff --git a/erts/vsn.mk b/erts/vsn.mk
index a420781e9f..53638f435c 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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
@@ -18,7 +18,7 @@
#
VSN = 5.10
-SYSTEM_VSN = R16B
+SYSTEM_VSN = R16A
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/appmon/src/Makefile b/lib/appmon/src/Makefile
index c42ce068b4..c1620bc37a 100644
--- a/lib/appmon/src/Makefile
+++ b/lib/appmon/src/Makefile
@@ -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
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c
index dbff14f9b3..e7e5f5f2f5 100644
--- a/lib/asn1/c_src/asn1_erl_nif.c
+++ b/lib/asn1/c_src/asn1_erl_nif.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
@@ -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..362ca9330f 100644
--- a/lib/asn1/doc/src/asn1_ug.xml
+++ b/lib/asn1/doc/src/asn1_ug.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2011</year>
+ <year>1997</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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..f04bac9fec 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2012</year>
+ <year>1997</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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/doc/src/asn1rt.xml b/lib/asn1/doc/src/asn1rt.xml
index f2cac0c9e7..2b1b108ab1 100644
--- a/lib/asn1/doc/src/asn1rt.xml
+++ b/lib/asn1/doc/src/asn1rt.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2011</year>
+ <year>1997</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
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 03e18c565b..9607799401 100644
--- a/lib/asn1/src/Makefile
+++ b/lib/asn1/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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
@@ -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 =
@@ -138,6 +133,13 @@ info:
$(EBIN)/asn1ct.$(EMULATOR):asn1ct.erl
$(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
$(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..16d14c2e7b 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. 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
@@ -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..770b92cbc3 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..e82212f0d8 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -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..aa5ee18c80 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..ebc52df1d9 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..f3a2486565 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -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..0d6620667f 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..5a409295fb 100644
--- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
+++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -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..869bda5d52 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.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
@@ -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..764555c4d2 100644
--- a/lib/asn1/src/asn1ct_value.erl
+++ b/lib/asn1/src/asn1ct_value.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..c1879e3dcf 100644
--- a/lib/asn1/src/asn1rt_nif.erl
+++ b/lib/asn1/src/asn1rt_nif.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -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..88292aca99
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -0,0 +1,1561 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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..46adb2007d
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_ext.erl
@@ -0,0 +1,72 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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..d02f4f548e
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_per.erl
@@ -0,0 +1,976 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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..e7edc2b65f
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -0,0 +1,126 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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..ad0678f3c3
--- /dev/null
+++ b/lib/asn1/src/asn1rtt_uper.erl
@@ -0,0 +1,1042 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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..644cba8c3c 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.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
@@ -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/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
index b7cc74ab07..b07dcd8baa 100644
--- a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
+++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
@@ -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
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..d46560979d 100644
--- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -7,7 +7,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. 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
@@ -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_SUITE_data/testobj.erl b/lib/asn1/test/asn1_SUITE_data/testobj.erl
index d9f60ca8a3..8d34a473ae 100644
--- a/lib/asn1/test/asn1_SUITE_data/testobj.erl
+++ b/lib/asn1/test/asn1_SUITE_data/testobj.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. 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
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/asn1_wrapper.erl b/lib/asn1/test/asn1_wrapper.erl
index e764d8b4ca..ac194fe38b 100644
--- a/lib/asn1/test/asn1_wrapper.erl
+++ b/lib/asn1/test/asn1_wrapper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. 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
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
index ff6e386a88..1c4b4c6894 100644
--- a/lib/asn1/test/ber_decode_error.erl
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -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
@@ -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..40dbe25015 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.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
@@ -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..1032156b91 100644
--- a/lib/asn1/test/testDoubleEllipses.erl
+++ b/lib/asn1/test/testDoubleEllipses.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
@@ -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..0f4459f5b2 100644
--- a/lib/asn1/test/testNBAPsystem.erl
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -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..a10468d592 100644
--- a/lib/asn1/test/testParamBasic.erl
+++ b/lib/asn1/test/testParamBasic.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
@@ -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..f8b0c5b05a 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..bd6c9428e2 100644
--- a/lib/asn1/test/testSeqSetDefaultVal.erl
+++ b/lib/asn1/test/testSeqSetDefaultVal.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
@@ -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..61d69edd0e 100644
--- a/lib/asn1/test/testTypeValueNotation.erl
+++ b/lib/asn1/test/testTypeValueNotation.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -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/ct_run.xml b/lib/common_test/doc/src/ct_run.xml
index 0750f560b3..198290c1be 100644
--- a/lib/common_test/doc/src/ct_run.xml
+++ b/lib/common_test/doc/src/ct_run.xml
@@ -126,6 +126,7 @@
<title>Run tests using test specification</title>
<pre>
ct_run -spec TestSpec1 TestSpec2 .. TestSpecN
+ [-join_specs]
[-config ConfigFile1 ConfigFile2 .. ConfigFileN]
[-userconfig CallbackModule1 ConfigString1 and CallbackModule2
ConfigString2 and .. and CallbackModuleN ConfigStringN]
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 0345fab8e8..030de2efa9 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2012</year>
+ <year>2004</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml
index d5f5d89e05..35f89153d3 100644
--- a/lib/common_test/doc/src/run_test_chapter.xml
+++ b/lib/common_test/doc/src/run_test_chapter.xml
@@ -530,374 +530,469 @@
<marker id="test_specifications"></marker>
<section>
<title>Test Specifications</title>
-
- <p>The most flexible way to specify what to test, is to use a so
- called test specification. A test specification is a sequence of
- Erlang terms. The terms are normally declared in a text file (see
- <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>), but
- may also be passed to Common Test on the form of a list (see
- <c><seealso marker="ct#run_testspec-1">ct:run_testspec/1</seealso></c>).
- There are two general types of terms: configuration terms and test
- specification terms.</p>
- <p>With configuration terms it is possible to e.g. label the test
- run (similar to <c>ct_run -label</c>), evaluate arbitrary expressions
- before starting the test, import configuration data (similar to
- <c>ct_run -config/-userconfig</c>), specify the top level HTML log
- directory (similar to <c>ct_run -logdir</c>), enable code coverage
- analysis (similar to <c>ct_run -cover</c>), install Common Test Hooks
- (similar to <c>ct_run -ch_hooks</c>), install event_handler plugins
- (similar to <c>ct_run -event_handler</c>), specify include directories
- that should be passed to the compiler for automatic compilation
- (similar to <c>ct_run -include</c>), disable the auto compilation
- feature (similar to <c>ct_run -no_auto_compile</c>), set verbosity
- levels (similar to <c>ct_run -verbosity</c>), and more.</p>
- <p>Configuration terms can be combined with <c>ct_run</c> start flags,
- or <c>ct:run_test/1</c> options. The result will for some flags/options
- and terms be that the values are merged (e.g. configuration files,
- include directories, verbosity levels, silent connections), and for
- others that the start flags/options override the test specification
- terms (e.g. log directory, label, style sheet, auto compilation).</p>
- <p>With test specification terms it is possible to state exactly
- which tests should run and in which order. A test term specifies
- either one or more suites, one or more test case groups (possibly nested),
- or one or more test cases in a group (or in multiple groups) or in a suite.</p>
- <p>An arbitrary number of test terms may be declared in sequence.
- Common Test will by default compile the terms into one or more tests
- to be performed in one resulting test run. Note that a term that
- specifies a set of test cases will "swallow" one that only
- specifies a subset of these cases. E.g. the result of merging
- one term that specifies that all cases in suite S should be
- executed, with another term specifying only test case X and Y in
- S, is a test of all cases in S. However, if a term specifying
- test case X and Y in S is merged with a term specifying case Z
- in S, the result is a test of X, Y and Z in S. To disable this
- behaviour, i.e. to instead perform each test sequentially in a "script-like"
- manner, the term <c>merge_tests</c> can be set to <c>false</c> in
- the test specification.</p>
- <p>A test term can also specify one or more test suites, groups,
- or test cases to be skipped. Skipped suites, groups and cases
- are not executed and show up in the HTML log files as
- SKIPPED.</p>
- <p>When a test case group is specified, the resulting test
- executes the <c>init_per_group</c> function, followed by all test
- cases and sub groups (including their configuration functions), and
- finally the <c>end_per_group</c> function. Also if particular
- test cases in a group are specified, <c>init_per_group</c>
- and <c>end_per_group</c> for the group in question are
- called. If a group which is defined (in <c>Suite:group/0</c>) to
- be a sub group of another group, is specified (or if particular test
- cases of a sub group are), Common Test will call the configuration
- functions for the top level groups as well as for the sub group
- in question (making it possible to pass configuration data all
- the way from <c>init_per_suite</c> down to the test cases in the
- sub group).</p>
- <p>The test specification utilizes the same mechanism for specifying
- test case groups by means of names and paths, as explained in the
- <seealso marker="run_test_chapter#group_execution">Group Execution</seealso>
- section above, with the addition of the <c>GroupSpec</c> element
- described next.</p>
- <p>The <c>GroupSpec</c> element makes it possible to specify
- group execution properties that will override those in the
- group definition (i.e. in <c>groups/0</c>). Execution properties for
- sub-groups may be overridden as well. This feature makes it possible to
- change properties of groups at the time of execution,
- without even having to edit the test suite. The very same
- feature is available for <c>group</c> elements in the <c>Suite:all/0</c>
- list. Therefore, more detailed documentation, and examples, can be
- found in the <seealso marker="write_test_chapter#test_case_groups">
- Test case groups</seealso> chapter.</p>
-
- <p>Below is the test specification syntax. Test specifications can
- be used to run tests both in a single test host environment and
- in a distributed Common Test environment (Large Scale
- Testing). The node parameters in the <c>init</c> term are only
- relevant in the latter (see the
- <seealso marker="ct_master_chapter#test_specifications">Large
- Scale Testing</seealso> chapter for information). For more information
- about the various terms, please see the corresponding sections in the
- User's Guide, such as e.g. the
- <seealso marker="run_test_chapter#ct_run"><c>ct_run</c>
- program</seealso> for an overview of available start flags
- (since most flags have a corresponding configuration term), and
- more detailed explanation of e.g.
- <seealso marker="write_test_chapter#logging">Logging</seealso>
- (for the <c>verbosity</c>, <c>stylesheet</c> and <c>basic_html</c> terms),
- <seealso marker="config_file_chapter#top">External Configuration Data</seealso>
- (for the <c>config</c> and <c>userconfig</c> terms),
- <seealso marker="event_handler_chapter#event_handling">Event
- Handling</seealso> (for the <c>event_handler</c> term),
- <seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso>
- (for the <c>ct_hooks</c> term), etc.</p>
- <p>Config terms:</p>
- <pre>
- {merge_tests, Bool}.
-
- {define, Constant, Value}.
-
- {node, NodeAlias, Node}.
-
- {init, InitOptions}.
- {init, [NodeAlias], InitOptions}.
-
- {label, Label}.
- {label, NodeRefs, Label}.
-
- {verbosity, VerbosityLevels}.
- {verbosity, NodeRefs, VerbosityLevels}.
-
- {stylesheet, CSSFile}.
- {stylesheet, NodeRefs, CSSFile}.
-
- {silent_connections, ConnTypes}.
- {silent_connections, NodeRefs, ConnTypes}.
-
- {multiply_timetraps, N}.
- {multiply_timetraps, NodeRefs, N}.
-
- {scale_timetraps, Bool}.
- {scale_timetraps, NodeRefs, Bool}.
-
- {cover, CoverSpecFile}.
- {cover, NodeRefs, CoverSpecFile}.
-
- {cover_stop, Bool}.
- {cover_stop, NodeRefs, Bool}.
-
- {include, IncludeDirs}.
- {include, NodeRefs, IncludeDirs}.
-
- {auto_compile, Bool},
- {auto_compile, NodeRefs, Bool},
-
- {config, ConfigFiles}.
- {config, ConfigDir, ConfigBaseNames}.
- {config, NodeRefs, ConfigFiles}.
- {config, NodeRefs, ConfigDir, ConfigBaseNames}.
-
- {userconfig, {CallbackModule, ConfigStrings}}.
- {userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
-
- {logdir, LogDir}.
- {logdir, NodeRefs, LogDir}.
-
- {logopts, LogOpts}.
- {logopts, NodeRefs, LogOpts}.
-
- {create_priv_dir, PrivDirOption}.
- {create_priv_dir, NodeRefs, PrivDirOption}.
-
- {event_handler, EventHandlers}.
- {event_handler, NodeRefs, EventHandlers}.
- {event_handler, EventHandlers, InitArgs}.
- {event_handler, NodeRefs, EventHandlers, InitArgs}.
-
- {ct_hooks, CTHModules}.
- {ct_hooks, NodeRefs, CTHModules}.
-
- {enable_builtin_hooks, Bool}.
-
- {basic_html, Bool}.
- {basic_html, NodeRefs, Bool}.
+ <section>
+ <title>General description</title>
+ <p>The most flexible way to specify what to test, is to use a so
+ called test specification. A test specification is a sequence of
+ Erlang terms. The terms are normally declared in one or more text files
+ (see <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>), but
+ may also be passed to Common Test on the form of a list (see
+ <c><seealso marker="ct#run_testspec-1">ct:run_testspec/1</seealso></c>).
+ There are two general types of terms: configuration terms and test
+ specification terms.</p>
+ <p>With configuration terms it is possible to e.g. label the test
+ run (similar to <c>ct_run -label</c>), evaluate arbitrary expressions
+ before starting the test, import configuration data (similar to
+ <c>ct_run -config/-userconfig</c>), specify the top level HTML log
+ directory (similar to <c>ct_run -logdir</c>), enable code coverage
+ analysis (similar to <c>ct_run -cover</c>), install Common Test Hooks
+ (similar to <c>ct_run -ch_hooks</c>), install event_handler plugins
+ (similar to <c>ct_run -event_handler</c>), specify include directories
+ that should be passed to the compiler for automatic compilation
+ (similar to <c>ct_run -include</c>), disable the auto compilation
+ feature (similar to <c>ct_run -no_auto_compile</c>), set verbosity
+ levels (similar to <c>ct_run -verbosity</c>), and more.</p>
+ <p>Configuration terms can be combined with <c>ct_run</c> start flags,
+ or <c>ct:run_test/1</c> options. The result will for some flags/options
+ and terms be that the values are merged (e.g. configuration files,
+ include directories, verbosity levels, silent connections), and for
+ others that the start flags/options override the test specification
+ terms (e.g. log directory, label, style sheet, auto compilation).</p>
+ <p>With test specification terms it is possible to state exactly
+ which tests should run and in which order. A test term specifies
+ either one or more suites, one or more test case groups (possibly nested),
+ or one or more test cases in a group (or in multiple groups) or in a suite.</p>
+ <p>An arbitrary number of test terms may be declared in sequence.
+ Common Test will by default compile the terms into one or more tests
+ to be performed in one resulting test run. Note that a term that
+ specifies a set of test cases will "swallow" one that only
+ specifies a subset of these cases. E.g. the result of merging
+ one term that specifies that all cases in suite S should be
+ executed, with another term specifying only test case X and Y in
+ S, is a test of all cases in S. However, if a term specifying
+ test case X and Y in S is merged with a term specifying case Z
+ in S, the result is a test of X, Y and Z in S. To disable this
+ behaviour, i.e. to instead perform each test sequentially in a "script-like"
+ manner, the term <c>merge_tests</c> can be set to <c>false</c> in
+ the test specification.</p>
+ <p>A test term can also specify one or more test suites, groups,
+ or test cases to be skipped. Skipped suites, groups and cases
+ are not executed and show up in the HTML log files as
+ SKIPPED.</p>
+ </section>
+ <section>
+ <title>Using multiple test specification files</title>
+
+ <p>When multiple test specification files are given at startup (either
+ with <c>ct_run -spec file1 file2 ...</c> or
+ <c>ct:run_test([{spec, [File1,File2,...]}])</c>),
+ Common Test will either execute one test run per specification file, or
+ join the files and perform all tests within one single test run. The first
+ behaviour is the default one. The latter requires that the start
+ flag/option <c>join_suites</c> is provided, e.g.
+ <c>run_test -spec ./my_tests1.ts ./my_tests2.ts -join_suites</c>.</p>
+
+ <p>Joining a number of specifications, or running them separately, can
+ also be accomplished with (and may be combined with) test specification
+ file inclusion, described next.</p>
+ </section>
+ <section>
+ <title>Test specification file inclusion</title>
+ <p>With the <c>specs</c> term (see syntax below), it's possible to have
+ a test specification include other specifications. An included
+ specification may either be joined with the source specification,
+ or used to produce a separate test run (like with the <c>join_specs</c>
+ start flag/option above). Example:</p>
+ <pre>
+ %% In specification file "a.spec"
+ {specs, join, ["b.spec", "c.spec"]}.
+ {specs, separate, ["d.spec", "e.spec"]}.
+ %% Config and test terms follow
+ ...</pre>
+ <p>In this example, the test terms defined in files "b.spec" and "c.spec"
+ will be joined with the terms in the source specification "a.spec"
+ (if any). The inclusion of specifications "d.spec" and
+ "e.spec" will result in two separate, and independent, test runs (i.e.
+ one for each included specification).</p>
+ <p>Note that the <c>join</c> option does not imply that the test terms
+ will be merged (see <c>merge_tests</c> above), only that all tests are
+ executed in one single test run.</p>
+ <p>Joined specifications share common configuration settings, such as
+ the list of <c>config</c> files or <c>include</c> directories.
+ For configuration that can not be combined, such as settings for <c>logdir</c>
+ or <c>verbosity</c>, it is up to the user to ensure there are no clashes
+ when the test specifications are joined. Specifications included with
+ the <c>separate</c> option, do not share configuration settings with the
+ source specification. This is useful e.g. if there are clashing
+ configuration settings in included specifications, making it impossible
+ to join them.</p>
+ <p>If <c>{merge_tests,true}</c> is set in the source specification
+ (which is the default setting), terms in joined specifications will be
+ merged with terms in the source specification (according to the
+ description of <c>merge_tests</c> above).</p>
+ <p>Note that it is always the <c>merge_tests</c> setting in the source
+ specification that is used when joined with other specifications.
+ Say e.g. that a source specification A, with tests TA1 and TA2, has
+ <c>{merge_tests,false}</c> set, and it includes another specification,
+ B, with tests TB1 and TB2, that has <c>{merge_tests,true}</c> set.
+ The result will be that the test series: <c>TA1,TA2,merge(TB1,TB2)</c>,
+ is executed. The opposite <c>merge_tests</c> settings would result in the
+ following the test series: <c>merge(merge(TA1,TA2),TB1,TB2)</c>.</p>
+ <p>The <c>specs</c> term may of course be used to nest specifications,
+ i.e. have one specification include other specifications, which in turn
+ include others, etc.</p>
+ </section>
+ <section>
+ <title>Test case groups</title>
+
+ <p>When a test case group is specified, the resulting test
+ executes the <c>init_per_group</c> function, followed by all test
+ cases and sub groups (including their configuration functions), and
+ finally the <c>end_per_group</c> function. Also if particular
+ test cases in a group are specified, <c>init_per_group</c>
+ and <c>end_per_group</c> for the group in question are
+ called. If a group which is defined (in <c>Suite:group/0</c>) to
+ be a sub group of another group, is specified (or if particular test
+ cases of a sub group are), Common Test will call the configuration
+ functions for the top level groups as well as for the sub group
+ in question (making it possible to pass configuration data all
+ the way from <c>init_per_suite</c> down to the test cases in the
+ sub group).</p>
+ <p>The test specification utilizes the same mechanism for specifying
+ test case groups by means of names and paths, as explained in the
+ <seealso marker="run_test_chapter#group_execution">Group Execution</seealso>
+ section above, with the addition of the <c>GroupSpec</c> element
+ described next.</p>
+ <p>The <c>GroupSpec</c> element makes it possible to specify
+ group execution properties that will override those in the
+ group definition (i.e. in <c>groups/0</c>). Execution properties for
+ sub-groups may be overridden as well. This feature makes it possible to
+ change properties of groups at the time of execution,
+ without even having to edit the test suite. The very same
+ feature is available for <c>group</c> elements in the <c>Suite:all/0</c>
+ list. Therefore, more detailed documentation, and examples, can be
+ found in the <seealso marker="write_test_chapter#test_case_groups">
+ Test case groups</seealso> chapter.</p>
+ </section>
- {release_shell, Bool}.</pre>
+ <section>
+ <title>Test specification syntax</title>
+
+ <p>Below is the test specification syntax. Test specifications can
+ be used to run tests both in a single test host environment and
+ in a distributed Common Test environment (Large Scale
+ Testing). The node parameters in the <c>init</c> term are only
+ relevant in the latter (see the
+ <seealso marker="ct_master_chapter#test_specifications">Large
+ Scale Testing</seealso> chapter for information). For more information
+ about the various terms, please see the corresponding sections in the
+ User's Guide, such as e.g. the
+ <seealso marker="run_test_chapter#ct_run"><c>ct_run</c>
+ program</seealso> for an overview of available start flags
+ (since most flags have a corresponding configuration term), and
+ more detailed explanation of e.g.
+ <seealso marker="write_test_chapter#logging">Logging</seealso>
+ (for the <c>verbosity</c>, <c>stylesheet</c> and <c>basic_html</c> terms),
+ <seealso marker="config_file_chapter#top">External Configuration Data</seealso>
+ (for the <c>config</c> and <c>userconfig</c> terms),
+ <seealso marker="event_handler_chapter#event_handling">Event
+ Handling</seealso> (for the <c>event_handler</c> term),
+ <seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso>
+ (for the <c>ct_hooks</c> term), etc.</p>
+ </section>
+ <p>Config terms:</p>
+ <pre>
+ {merge_tests, Bool}.
+
+ {define, Constant, Value}.
+
+ {specs, InclSpecsOption, TestSpecs}.
+
+ {node, NodeAlias, Node}.
+
+ {init, InitOptions}.
+ {init, [NodeAlias], InitOptions}.
+
+ {label, Label}.
+ {label, NodeRefs, Label}.
+
+ {verbosity, VerbosityLevels}.
+ {verbosity, NodeRefs, VerbosityLevels}.
+
+ {stylesheet, CSSFile}.
+ {stylesheet, NodeRefs, CSSFile}.
+
+ {silent_connections, ConnTypes}.
+ {silent_connections, NodeRefs, ConnTypes}.
+
+ {multiply_timetraps, N}.
+ {multiply_timetraps, NodeRefs, N}.
+
+ {scale_timetraps, Bool}.
+ {scale_timetraps, NodeRefs, Bool}.
+
+ {cover, CoverSpecFile}.
+ {cover, NodeRefs, CoverSpecFile}.
+
+ {cover_stop, Bool}.
+ {cover_stop, NodeRefs, Bool}.
+
+ {include, IncludeDirs}.
+ {include, NodeRefs, IncludeDirs}.
+
+ {auto_compile, Bool},
+ {auto_compile, NodeRefs, Bool},
+
+ {config, ConfigFiles}.
+ {config, ConfigDir, ConfigBaseNames}.
+ {config, NodeRefs, ConfigFiles}.
+ {config, NodeRefs, ConfigDir, ConfigBaseNames}.
+
+ {userconfig, {CallbackModule, ConfigStrings}}.
+ {userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
+
+ {logdir, LogDir}.
+ {logdir, NodeRefs, LogDir}.
+
+ {logopts, LogOpts}.
+ {logopts, NodeRefs, LogOpts}.
+
+ {create_priv_dir, PrivDirOption}.
+ {create_priv_dir, NodeRefs, PrivDirOption}.
+
+ {event_handler, EventHandlers}.
+ {event_handler, NodeRefs, EventHandlers}.
+ {event_handler, EventHandlers, InitArgs}.
+ {event_handler, NodeRefs, EventHandlers, InitArgs}.
+
+ {ct_hooks, CTHModules}.
+ {ct_hooks, NodeRefs, CTHModules}.
+
+ {enable_builtin_hooks, Bool}.
+
+ {basic_html, Bool}.
+ {basic_html, NodeRefs, Bool}.
+
+ {release_shell, Bool}.</pre>
+
<p>Test terms:</p>
- <pre>
- {suites, Dir, Suites}.
- {suites, NodeRefs, Dir, Suites}.
-
- {groups, Dir, Suite, Groups}.
- {groups, NodeRefs, Dir, Suite, Groups}.
-
- {groups, Dir, Suite, Groups, {cases,Cases}}.
- {groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.
-
- {cases, Dir, Suite, Cases}.
- {cases, NodeRefs, Dir, Suite, Cases}.
-
- {skip_suites, Dir, Suites, Comment}.
- {skip_suites, NodeRefs, Dir, Suites, Comment}.
-
- {skip_groups, Dir, Suite, GroupNames, Comment}.
- {skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.
-
- {skip_cases, Dir, Suite, Cases, Comment}.
- {skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.</pre>
-
+ <pre>
+ {suites, Dir, Suites}.
+ {suites, NodeRefs, Dir, Suites}.
+
+ {groups, Dir, Suite, Groups}.
+ {groups, NodeRefs, Dir, Suite, Groups}.
+
+ {groups, Dir, Suite, Groups, {cases,Cases}}.
+ {groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.
+
+ {cases, Dir, Suite, Cases}.
+ {cases, NodeRefs, Dir, Suite, Cases}.
+
+ {skip_suites, Dir, Suites, Comment}.
+ {skip_suites, NodeRefs, Dir, Suites, Comment}.
+
+ {skip_groups, Dir, Suite, GroupNames, Comment}.
+ {skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.
+
+ {skip_cases, Dir, Suite, Cases, Comment}.
+ {skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.</pre>
+
<p>Types:</p>
- <pre>
- Bool = true | false
- Constant = atom()
- Value = term()
- NodeAlias = atom()
- Node = node()
- NodeRef = NodeAlias | Node | master
- NodeRefs = all_nodes | [NodeRef] | NodeRef
- InitOptions = term()
- Label = atom() | string()
- VerbosityLevels = integer() | [{Category,integer()}]
- Category = atom()
- CSSFile = string()
- ConnTypes = all | [atom()]
- N = integer()
- CoverSpecFile = string()
- IncludeDirs = string() | [string()]
- ConfigFiles = string() | [string()]
- ConfigDir = string()
- ConfigBaseNames = string() | [string()]
- CallbackModule = atom()
- ConfigStrings = string() | [string()]
- LogDir = string()
- LogOpts = [term()]
- PrivDirOption = auto_per_run | auto_per_tc | manual_per_tc
- EventHandlers = atom() | [atom()]
- InitArgs = [term()]
- CTHModules = [CTHModule |
- {CTHModule, CTHInitArgs} |
- {CTHModule, CTHInitArgs, CTHPriority}]
- CTHModule = atom()
- CTHInitArgs = term()
- Dir = string()
- Suites = atom() | [atom()] | all
- Suite = atom()
- Groups = GroupPath | [GroupPath] | GroupSpec | [GroupSpec] | all
- GroupPath = [GroupName]
- GroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,GroupSpec}
- GroupName = atom()
- GroupNames = GroupName | [GroupName]
- Cases = atom() | [atom()] | all
- Comment = string() | ""</pre>
-
- <p>The difference between the <c>config</c> terms above, is that with
- <c>ConfigDir</c>, <c>ConfigBaseNames</c> is a list of base names,
- i.e. without directory paths. <c>ConfigFiles</c> must be full names,
- including paths. E.g, these two terms have the same meaning:</p>
- <pre>
- {config, ["/home/testuser/tests/config/nodeA.cfg",
- "/home/testuser/tests/config/nodeB.cfg"]}.
-
- {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.</pre>
-
- <note><p>Any relative paths specified in the test specification, will be
- relative to the directory which contains the test specification file, if
- <c>ct_run -spec TestSpecFile ...</c> or
- <c>ct:run:test([{spec,TestSpecFile},...])</c>
- executes the test. The path will be relative to the top level log directory, if
- <c>ct:run:testspec(TestSpec)</c> executes the test.</p></note>
-
- <p>The <c>define</c> term introduces a constant, which is used to
- replace the name <c>Constant</c> with <c>Value</c>, wherever it's found in
- the test specification. This replacement happens during an initial iteration
- through the test specification. Constants may be used anywhere in the test
- specification, e.g. in arbitrary lists and tuples, and even in strings
- and inside the value part of other constant definitions! A constant can
- also be part of a node name, but that is the only place where a constant
- can be part of an atom.</p>
-
- <note><p>For the sake of readability, the name of the constant must always
- begin with an upper case letter, or a <c>$</c>, <c>?</c>, or <c>_</c>.
- This also means that it must always be single quoted (obviously, since
- the constant name is actually an atom, not text).</p></note>
-
- <p>The main benefit of constants is that they can be used to reduce the size
- (and avoid repetition) of long strings, such as file paths. Compare these
- terms:</p>
-
- <pre>
- %% 1a. no constant
- {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, "/home/testuser/tests/suites", all}.
-
- %% 1b. with constant
- {define, 'TESTDIR', "/home/testuser/tests"}.
- {config, "'TESTDIR'/config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, "'TESTDIR'/suites", all}.
-
- %% 2a. no constants
- {config, [testnode@host1, testnode@host2], "../config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, [testnode@host1, testnode@host2], "../suites", [x_SUITE, y_SUITE]}.
-
- %% 2b. with constants
- {define, 'NODE', testnode}.
- {define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.
- {config, 'NODES', "../config", ["nodeA.cfg","nodeB.cfg"]}.
- {suites, 'NODES', "../suites", [x_SUITE, y_SUITE]}.</pre>
-
- <p>Constants make the test specification term <c>alias</c>, in previous
- versions of Common Test, redundant. This term has been deprecated but will
- remain supported in upcoming Common Test releases. Replacing <c>alias</c>
- terms with <c>define</c> is strongly recommended though! Here's an example
- of such a replacement:</p>
+ <pre>
+ Bool = true | false
+ Constant = atom()
+ Value = term()
+ InclSpecsOption = join | separate
+ TestSpecs = string() | [string()]
+ NodeAlias = atom()
+ Node = node()
+ NodeRef = NodeAlias | Node | master
+ NodeRefs = all_nodes | [NodeRef] | NodeRef
+ InitOptions = term()
+ Label = atom() | string()
+ VerbosityLevels = integer() | [{Category,integer()}]
+ Category = atom()
+ CSSFile = string()
+ ConnTypes = all | [atom()]
+ N = integer()
+ CoverSpecFile = string()
+ IncludeDirs = string() | [string()]
+ ConfigFiles = string() | [string()]
+ ConfigDir = string()
+ ConfigBaseNames = string() | [string()]
+ CallbackModule = atom()
+ ConfigStrings = string() | [string()]
+ LogDir = string()
+ LogOpts = [term()]
+ PrivDirOption = auto_per_run | auto_per_tc | manual_per_tc
+ EventHandlers = atom() | [atom()]
+ InitArgs = [term()]
+ CTHModules = [CTHModule |
+ {CTHModule, CTHInitArgs} |
+ {CTHModule, CTHInitArgs, CTHPriority}]
+ CTHModule = atom()
+ CTHInitArgs = term()
+ Dir = string()
+ Suites = atom() | [atom()] | all
+ Suite = atom()
+ Groups = GroupPath | [GroupPath] | GroupSpec | [GroupSpec] | all
+ GroupPath = [GroupName]
+ GroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,GroupSpec}
+ GroupName = atom()
+ GroupNames = GroupName | [GroupName]
+ Cases = atom() | [atom()] | all
+ Comment = string() | ""</pre>
+
+ <section>
+ <p>The difference between the <c>config</c> terms above, is that with
+ <c>ConfigDir</c>, <c>ConfigBaseNames</c> is a list of base names,
+ i.e. without directory paths. <c>ConfigFiles</c> must be full names,
+ including paths. E.g, these two terms have the same meaning:</p>
+ <pre>
+ {config, ["/home/testuser/tests/config/nodeA.cfg",
+ "/home/testuser/tests/config/nodeB.cfg"]}.
+
+ {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.</pre>
+
+ <note><p>Any relative paths specified in the test specification, will be
+ relative to the directory which contains the test specification file, if
+ <c>ct_run -spec TestSpecFile ...</c> or
+ <c>ct:run:test([{spec,TestSpecFile},...])</c>
+ executes the test. The path will be relative to the top level log directory, if
+ <c>ct:run:testspec(TestSpec)</c> executes the test.</p></note>
+ </section>
- <pre>
- %% using the old alias term
- {config, "/home/testuser/tests/config/nodeA.cfg"}.
- {alias, suite_dir, "/home/testuser/tests/suites"}.
- {groups, suite_dir, x_SUITE, group1}.
-
- %% replacing with constants
- {define, 'TestDir', "/home/testuser/tests"}.
- {define, 'CfgDir', "'TestDir'/config"}.
- {define, 'SuiteDir', "'TestDir'/suites"}.
- {config, 'CfgDir', "nodeA.cfg"}.
- {groups, 'SuiteDir', x_SUITE, group1}.</pre>
-
- <p>Actually, constants could well replace the <c>node</c> term too, but
- this still has declarative value, mainly when used in combination
- with <c>NodeRefs == all_nodes</c> (see types above).</p>
-
- <p>Here follows a simple test specification example:</p>
- <pre>
- {define, 'Top', "/home/test"}.
- {define, 'T1', "'Top'/t1"}.
- {define, 'T2', "'Top'/t2"}.
- {define, 'T3', "'Top'/t3"}.
- {define, 'CfgFile', "config.cfg"}.
+ <section>
+ <title>Constants</title>
+
+ <p>The <c>define</c> term introduces a constant, which is used to
+ replace the name <c>Constant</c> with <c>Value</c>, wherever it's found in
+ the test specification. This replacement happens during an initial iteration
+ through the test specification. Constants may be used anywhere in the test
+ specification, e.g. in arbitrary lists and tuples, and even in strings
+ and inside the value part of other constant definitions! A constant can
+ also be part of a node name, but that is the only place where a constant
+ can be part of an atom.</p>
+
+ <note><p>For the sake of readability, the name of the constant must always
+ begin with an upper case letter, or a <c>$</c>, <c>?</c>, or <c>_</c>.
+ This also means that it must always be single quoted (obviously, since
+ the constant name is actually an atom, not text).</p></note>
+
+ <p>The main benefit of constants is that they can be used to reduce the size
+ (and avoid repetition) of long strings, such as file paths. Compare these
+ terms:</p>
+
+ <pre>
+ %% 1a. no constant
+ {config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, "/home/testuser/tests/suites", all}.
+
+ %% 1b. with constant
+ {define, 'TESTDIR', "/home/testuser/tests"}.
+ {config, "'TESTDIR'/config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, "'TESTDIR'/suites", all}.
+
+ %% 2a. no constants
+ {config, [testnode@host1, testnode@host2], "../config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, [testnode@host1, testnode@host2], "../suites", [x_SUITE, y_SUITE]}.
+
+ %% 2b. with constants
+ {define, 'NODE', testnode}.
+ {define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.
+ {config, 'NODES', "../config", ["nodeA.cfg","nodeB.cfg"]}.
+ {suites, 'NODES', "../suites", [x_SUITE, y_SUITE]}.</pre>
+
+ <p>Constants make the test specification term <c>alias</c>, in previous
+ versions of Common Test, redundant. This term has been deprecated but will
+ remain supported in upcoming Common Test releases. Replacing <c>alias</c>
+ terms with <c>define</c> is strongly recommended though! Here's an example
+ of such a replacement:</p>
+
+ <pre>
+ %% using the old alias term
+ {config, "/home/testuser/tests/config/nodeA.cfg"}.
+ {alias, suite_dir, "/home/testuser/tests/suites"}.
+ {groups, suite_dir, x_SUITE, group1}.
+
+ %% replacing with constants
+ {define, 'TestDir', "/home/testuser/tests"}.
+ {define, 'CfgDir', "'TestDir'/config"}.
+ {define, 'SuiteDir', "'TestDir'/suites"}.
+ {config, 'CfgDir', "nodeA.cfg"}.
+ {groups, 'SuiteDir', x_SUITE, group1}.</pre>
+
+ <p>Actually, constants could well replace the <c>node</c> term too, but
+ this still has declarative value, mainly when used in combination
+ with <c>NodeRefs == all_nodes</c> (see types above).</p>
+ </section>
- {logdir, "'Top'/logs"}.
-
- {config, ["'T1'/'CfgFile'", "'T2'/'CfgFile'", "'T3'/'CfgFile'"]}.
-
- {suites, 'T1', all}.
- {skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
- {skip_cases, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
- {skip_cases, 'T1', t1C_SUITE, [test1], "Ignore"}.
-
- {suites, 'T2', [t2B_SUITE,t2C_SUITE]}.
- {cases, 'T2', t2A_SUITE, [test4,test1,test7]}.
-
- {skip_suites, 'T3', all, "Not implemented"}.</pre>
+ <section>
+ <title>Example</title>
+
+ <p>Here follows a simple test specification example:</p>
+ <pre>
+ {define, 'Top', "/home/test"}.
+ {define, 'T1', "'Top'/t1"}.
+ {define, 'T2', "'Top'/t2"}.
+ {define, 'T3', "'Top'/t3"}.
+ {define, 'CfgFile', "config.cfg"}.
+
+ {logdir, "'Top'/logs"}.
+
+ {config, ["'T1'/'CfgFile'", "'T2'/'CfgFile'", "'T3'/'CfgFile'"]}.
+
+ {suites, 'T1', all}.
+ {skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
+ {skip_cases, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
+ {skip_cases, 'T1', t1C_SUITE, [test1], "Ignore"}.
+
+ {suites, 'T2', [t2B_SUITE,t2C_SUITE]}.
+ {cases, 'T2', t2A_SUITE, [test4,test1,test7]}.
+
+ {skip_suites, 'T3', all, "Not implemented"}.</pre>
+
+ <p>The example specifies the following:</p>
+ <list>
+ <item>The specified logdir directory will be used for storing
+ the HTML log files (in subdirectories tagged with node name,
+ date and time).</item>
+ <item>The variables in the specified test system config files will be
+ imported for the test.</item>
+ <item>The first test to run includes all suites for system t1. Excluded from
+ the test are however the t1B and t1D suites. Also test cases test3 and
+ test4 in t1A as well as the test1 case in t1C are excluded from
+ the test.</item>
+ <item>Secondly, the test for system t2 should run. The included suites are
+ t2B and t2C. Included are also test cases test4, test1 and test7 in suite
+ t2A. Note that the test cases will be executed in the specified order.</item>
+ <item>Lastly, all suites for systems t3 are to be completely skipped and this
+ should be explicitly noted in the log files.</item>
+ </list>
+ </section>
- <p>The example specifies the following:</p>
- <list>
- <item>The specified logdir directory will be used for storing
- the HTML log files (in subdirectories tagged with node name,
- date and time).</item>
- <item>The variables in the specified test system config files will be
- imported for the test.</item>
- <item>The first test to run includes all suites for system t1. Excluded from
- the test are however the t1B and t1D suites. Also test cases test3 and
- test4 in t1A as well as the test1 case in t1C are excluded from
- the test.</item>
- <item>Secondly, the test for system t2 should run. The included suites are
- t2B and t2C. Included are also test cases test4, test1 and test7 in suite
- t2A. Note that the test cases will be executed in the specified order.</item>
- <item>Lastly, all suites for systems t3 are to be completely skipped and this
- should be explicitly noted in the log files.</item>
- </list>
- <p>With the <c>init</c> term it's possible to specify initialization options
- for nodes defined in the test specification. Currently, there are options
- to start the node and/or to evaluate any function on the node.
- See the <seealso marker="ct_master_chapter#ct_slave">Automatic startup of
- the test target nodes</seealso> chapter for details.</p>
- <p>It is possible for the user to provide a test specification that
- includes (for Common Test) unrecognizable terms. If this is desired,
- the <c>-allow_user_terms</c> flag should be used when starting tests with
- <c>ct_run</c>. This forces Common Test to ignore unrecognizable terms.
- Note that in this mode, Common Test is not able to check the specification
- for errors as efficiently as if the scanner runs in default mode.
- If <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c> is used for starting the tests, the relaxed scanner
- mode is enabled by means of the tuple: <c>{allow_user_terms,true}</c></p>
+ <section>
+ <title>The init term</title>
+ <p>With the <c>init</c> term it's possible to specify initialization options
+ for nodes defined in the test specification. Currently, there are options
+ to start the node and/or to evaluate any function on the node.
+ See the <seealso marker="ct_master_chapter#ct_slave">Automatic startup of
+ the test target nodes</seealso> chapter for details.</p>
+ </section>
+ <section>
+ <title>User specific terms</title>
+ <p>It is possible for the user to provide a test specification that
+ includes (for Common Test) unrecognizable terms. If this is desired,
+ the <c>-allow_user_terms</c> flag should be used when starting tests with
+ <c>ct_run</c>. This forces Common Test to ignore unrecognizable terms.
+ Note that in this mode, Common Test is not able to check the specification
+ for errors as efficiently as if the scanner runs in default mode.
+ If <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c> is used
+ for starting the tests, the relaxed scanner
+ mode is enabled by means of the tuple: <c>{allow_user_terms,true}</c></p>
+ </section>
</section>
<section>
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index eb35a43d99..4600c0ad78 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -1,7 +1,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
@@ -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
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index 8eafdff29f..04a95a53fa 100644
--- a/lib/common_test/src/ct.erl
+++ b/lib/common_test/src/ct.erl
@@ -1,7 +1,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
@@ -144,8 +144,8 @@ run(TestDirs) ->
%%% @spec run_test(Opts) -> Result
%%% Opts = [OptTuples]
%%% OptTuples = {dir,TestDirs} | {suite,Suites} | {group,Groups} |
-%%% {testcase,Cases} | {spec,TestSpecs} | {label,Label} |
-%%% {config,CfgFiles} | {userconfig, UserConfig} |
+%%% {testcase,Cases} | {spec,TestSpecs} | {join_specs,Bool} |
+%%% {label,Label} | {config,CfgFiles} | {userconfig, UserConfig} |
%%% {allow_user_terms,Bool} | {logdir,LogDir} |
%%% {silent_connections,Conns} | {stylesheet,CSSFile} |
%%% {cover,CoverSpecFile} | {cover_stop,Bool} | {step,StepOpts} |
@@ -735,7 +735,7 @@ fail(Format, Args) ->
%%% overwrites the string set by this function.</p>
comment(Comment) when is_list(Comment) ->
Formatted =
- case (catch io_lib:format("~s",[Comment])) of
+ case (catch io_lib:format("~ts",[Comment])) of
{'EXIT',_} -> % it's a list not a string
io_lib:format("~p",[Comment]);
String ->
diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl
index b1d709bc75..c35cbd3c08 100644
--- a/lib/common_test/src/ct_config.erl
+++ b/lib/common_test/src/ct_config.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
@@ -266,7 +266,10 @@ read_config_files_int([{Callback, File}|Files], FunToSave) ->
read_config_files_int([], _FunToSave) ->
ok.
-store_config(Config, Callback, File) ->
+store_config(Config, Callback, File) when is_tuple(Config) ->
+ store_config([Config], Callback, File);
+
+store_config(Config, Callback, File) when is_list(Config) ->
[ets:insert(?attr_table,
#ct_conf{key=Key,
value=Val,
@@ -607,7 +610,7 @@ encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) ->
EncBin = crypto:des3_cbc_encrypt(K1, K2, K3, IVec, Bin2),
case file:write_file(EncryptFileName, EncBin) of
ok ->
- io:format("~s --(encrypt)--> ~s~n",
+ io:format("~ts --(encrypt)--> ~ts~n",
[SrcFileName,EncryptFileName]),
ok;
{error,Reason} ->
@@ -649,7 +652,7 @@ decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) ->
_ ->
case file:write_file(TargetFileName, SrcBin) of
ok ->
- io:format("~s --(decrypt)--> ~s~n",
+ io:format("~ts --(decrypt)--> ~ts~n",
[EncryptFileName,TargetFileName]),
ok;
{error,Reason} ->
@@ -700,7 +703,7 @@ get_crypt_key_from_file() ->
_ ->
case catch string:tokens(binary_to_list(Result), [$\n,$\r]) of
[Key] ->
- io:format("~nCrypt key file: ~s~n", [FullName]),
+ io:format("~nCrypt key file: ~ts~n", [FullName]),
Key;
_ ->
{error,{bad_crypt_file,FullName}}
diff --git a/lib/common_test/src/ct_config_plain.erl b/lib/common_test/src/ct_config_plain.erl
index 237df5c8f3..c6547f0a40 100644
--- a/lib/common_test/src/ct_config_plain.erl
+++ b/lib/common_test/src/ct_config_plain.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. 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
@@ -47,7 +47,7 @@ read_config(ConfigFile) ->
{error,no_crypt_file} ->
{error,{config_file_error,
lists:flatten(
- io_lib:format("~s",[file:format_error(Reason)]))}};
+ io_lib:format("~ts",[file:format_error(Reason)]))}};
{error,CryptError} ->
{error,{decrypt_file_error,CryptError}};
_ when is_list(Key) ->
diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl
index d7bd18606b..ac08a3e0ad 100644
--- a/lib/common_test/src/ct_conn_log_h.erl
+++ b/lib/common_test/src/ct_conn_log_h.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
@@ -52,7 +52,7 @@ open_files([],State) ->
do_open_files([{Tag,File}|Logs],Acc) ->
- case file:open(File, [write]) of
+ case file:open(File, [write,{encoding,utf8}]) of
{ok,Fd} ->
do_open_files(Logs,[{Tag,Fd}|Acc]);
{error,Reason} ->
@@ -98,9 +98,9 @@ terminate(_,#state{logs=Logs}) ->
%%% Writing reports
write_report(Time,#conn_log{module=ConnMod}=Info,Data,State) ->
{LogType,Fd} = get_log(Info,State),
- io:format(Fd,"~n~s~s~s",[format_head(ConnMod,LogType,Time),
- format_title(LogType,Info),
- format_data(ConnMod,LogType,Data)]).
+ io:format(Fd,"~n~ts~ts~ts",[format_head(ConnMod,LogType,Time),
+ format_title(LogType,Info),
+ format_data(ConnMod,LogType,Data)]).
write_error(Time,#conn_log{module=ConnMod}=Info,Report,State) ->
case get_log(Info,State) of
@@ -109,9 +109,10 @@ write_error(Time,#conn_log{module=ConnMod}=Info,Report,State) ->
%% sasl error handler, so don't write it again.
ok;
{LogType,Fd} ->
- io:format(Fd,"~n~s~s~s",[format_head(ConnMod,LogType,Time," ERROR"),
- format_title(LogType,Info),
- format_error(LogType,Report)])
+ io:format(Fd,"~n~ts~ts~ts",
+ [format_head(ConnMod,LogType,Time," ERROR"),
+ format_title(LogType,Info),
+ format_error(LogType,Report)])
end.
get_log(Info,State) ->
@@ -140,16 +141,16 @@ format_head(ConnMod,LogType,Time) ->
format_head(ConnMod,LogType,Time,"").
format_head(ConnMod,raw,Time,Text) ->
- io_lib:format("~n~p, ~p~s, ",[now_to_time(Time),ConnMod,Text]);
+ io_lib:format("~n~w, ~w~ts, ",[now_to_time(Time),ConnMod,Text]);
format_head(ConnMod,_,Time,Text) ->
Head = pad_char_end(?WIDTH,pretty_head(now_to_time(Time),ConnMod,Text),$=),
- io_lib:format("~n~s",[Head]).
+ io_lib:format("~n~ts",[Head]).
format_title(raw,#conn_log{client=Client}=Info) ->
- io_lib:format("Client ~p ~s ~s",[Client,actionstr(Info),serverstr(Info)]);
+ io_lib:format("Client ~w ~s ~ts",[Client,actionstr(Info),serverstr(Info)]);
format_title(_,Info) ->
Title = pad_char_end(?WIDTH,pretty_title(Info),$=),
- io_lib:format("~n~s", [Title]).
+ io_lib:format("~n~ts", [Title]).
format_data(_,_,NoData) when NoData == ""; NoData == <<>> ->
"";
@@ -162,8 +163,6 @@ format_error(pretty,Report) ->
[io_lib:format("~n ~p: ~p",[K,V]) || {K,V} <- Report].
-
-
%%%-----------------------------------------------------------------
%%% Helpers
conn_info(LoggingProc, #conn_log{client=undefined} = ConnInfo) ->
@@ -187,12 +186,12 @@ now_to_time({_,_,MicroS}=Now) ->
pretty_head({{{Y,Mo,D},{H,Mi,S}},MicroS},ConnMod,Text0) ->
Text = string:to_upper(atom_to_list(ConnMod) ++ Text0),
- io_lib:format("= ~s ==== ~s-~s-~p::~s:~s:~s,~s ",
+ io_lib:format("= ~s ==== ~s-~s-~w::~s:~s:~s,~s ",
[Text,t(D),month(Mo),Y,t(H),t(Mi),t(S),
micro2milli(MicroS)]).
pretty_title(#conn_log{client=Client}=Info) ->
- io_lib:format("= Client ~p ~s Server ~s ",
+ io_lib:format("= Client ~w ~s Server ~ts ",
[Client,actionstr(Info),serverstr(Info)]).
actionstr(#conn_log{action=send}) -> "----->";
@@ -204,7 +203,7 @@ actionstr(_) -> "<---->".
serverstr(#conn_log{name=undefined,address=Address}) ->
io_lib:format("~p",[Address]);
serverstr(#conn_log{name=Alias,address=Address}) ->
- io_lib:format("~p(~p)",[Alias,Address]).
+ io_lib:format("~w(~p)",[Alias,Address]).
month(1) -> "Jan";
month(2) -> "Feb";
diff --git a/lib/common_test/src/ct_event.erl b/lib/common_test/src/ct_event.erl
index 49e0635d79..c1c1d943b9 100644
--- a/lib/common_test/src/ct_event.erl
+++ b/lib/common_test/src/ct_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -150,7 +150,7 @@ init(RecvPids) ->
%%--------------------------------------------------------------------
handle_event(Event,State=#state{receivers=RecvPids}) ->
print("~n=== ~w ===~n", [?MODULE]),
- print("~p: ~p~n", [Event#event.name,Event#event.data]),
+ print("~w: ~w~n", [Event#event.name,Event#event.data]),
lists:foreach(fun(Recv) -> report_event(Recv,Event) end, RecvPids),
{ok,State}.
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index c1abf27e9f..5fe4eaf511 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.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
@@ -750,12 +750,12 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
Descr1 = lists:flatten(io_lib:format("~P",[Descr,10])),
if length(Descr1) > 50 ->
Descr2 = string:substr(Descr1,1,50),
- io_lib:format("{badmatch,~s...}",[Descr2]);
+ io_lib:format("{badmatch,~ts...}",[Descr2]);
true ->
- io_lib:format("{badmatch,~s}",[Descr1])
+ io_lib:format("{badmatch,~ts}",[Descr1])
end;
{test_case_failed,Reason} ->
- case (catch io_lib:format("{test_case_failed,~s}", [Reason])) of
+ case (catch io_lib:format("{test_case_failed,~ts}", [Reason])) of
{'EXIT',_} ->
io_lib:format("{test_case_failed,~p}", [Reason]);
Result -> Result
@@ -788,7 +788,7 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
"<font color=\"green\">" ++ "(" ++ "</font>"
++ Comment ++
"<font color=\"green\">" ++ ")" ++ "</font>",
- Str = io_lib:format("~s ~s", [ErrorHtml,CommentHtml]),
+ Str = io_lib:format("~ts ~ts", [ErrorHtml,CommentHtml]),
test_server:comment(Str)
end
end,
@@ -803,24 +803,24 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
end,
case Loc of
[{?MODULE,error_in_suite}] ->
- PrintErr("Error in suite detected: ~s", [ErrStr]);
+ PrintErr("Error in suite detected: ~ts", [ErrStr]);
R when R == unknown; R == undefined ->
- PrintErr("Error detected: ~s", [ErrStr]);
+ PrintErr("Error detected: ~ts", [ErrStr]);
%% if a function specified by all/0 does not exist, we
%% pick up undef here
[{LastMod,LastFunc}|_] when ErrStr == "undef" ->
- PrintErr("~w:~w could not be executed~nReason: ~s",
+ PrintErr("~w:~w could not be executed~nReason: ~ts",
[LastMod,LastFunc,ErrStr]);
[{LastMod,LastFunc}|_] ->
- PrintErr("~w:~w failed~nReason: ~s", [LastMod,LastFunc,ErrStr]);
+ PrintErr("~w:~w failed~nReason: ~ts", [LastMod,LastFunc,ErrStr]);
[{LastMod,LastFunc,LastLine}|_] ->
%% print error to console, we are only
%% interested in the last executed expression
- PrintErr("~w:~w failed on line ~w~nReason: ~s",
+ PrintErr("~w:~w failed on line ~w~nReason: ~ts",
[LastMod,LastFunc,LastLine,ErrStr]),
case ct_util:read_suite_data({seq,Mod,Func}) of
@@ -1184,7 +1184,7 @@ report(What,Data) ->
ok;
{error,Reason} ->
ct_logs:log("COVER INFO",
- "Importing cover data from: ~s fails! "
+ "Importing cover data from: ~ts fails! "
"Reason: ~p", [Imp,Reason])
end
end, Imps)
@@ -1349,4 +1349,7 @@ format_comment(Comment) ->
%%%-----------------------------------------------------------------
%%% @spec get_html_wrapper(TestName, PrintLabel, Cwd) -> Header
get_html_wrapper(TestName, PrintLabel, Cwd, TableCols) ->
- ct_logs:get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols).
+ get_html_wrapper(TestName, PrintLabel, Cwd, TableCols, utf8).
+
+get_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) ->
+ ct_logs:get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding).
diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl
index 1f01d84601..2d4b1d1f52 100644
--- a/lib/common_test/src/ct_gen_conn.erl
+++ b/lib/common_test/src/ct_gen_conn.erl
@@ -1,7 +1,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
@@ -272,7 +272,7 @@ call(Pid, Msg, Timeout) ->
after Timeout ->
erlang:demonitor(MRef, [flush]),
log("ct_gen_conn",
- "Connection process ~p not responding. Killing now!",
+ "Connection process ~w not responding. Killing now!",
[Pid]),
exit(Pid, kill),
{error,{process_down,Pid,forced_termination}}
diff --git a/lib/common_test/src/ct_groups.erl b/lib/common_test/src/ct_groups.erl
index 74ab5e5439..14a8aab881 100644
--- a/lib/common_test/src/ct_groups.erl
+++ b/lib/common_test/src/ct_groups.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
@@ -462,7 +462,7 @@ make_conf(Mod, Name, Props, TestSpec) ->
false ->
ct_logs:log("TEST INFO", "init_per_group/2 and "
"end_per_group/2 missing for group "
- "~p in ~p, using default.",
+ "~w in ~w, using default.",
[Name,Mod]),
{{ct_framework,init_per_group},
{ct_framework,end_per_group},
diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl
index 1bcc63738e..3d87a82e24 100644
--- a/lib/common_test/src/ct_hooks.erl
+++ b/lib/common_test/src/ct_hooks.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
@@ -362,11 +362,11 @@ catch_apply(M,F,A, Default) ->
[{M,F,A,_}|_] when Reason == undef ->
Default;
Trace ->
- ct_logs:log("Suite Hook","Call to CTH failed: ~p:~p",
+ ct_logs:log("Suite Hook","Call to CTH failed: ~w:~p",
[error,{Reason,Trace}]),
throw({error_in_cth_call,
lists:flatten(
- io_lib:format("~p:~p/~p CTH call failed",
+ io_lib:format("~w:~w/~w CTH call failed",
[M,F,length(A)]))})
end
end.
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index 0b7a8bb075..5924930072 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-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
@@ -35,9 +35,10 @@
-export([add_external_logs/1, add_link/3]).
-export([make_last_run_index/0]).
-export([make_all_suites_index/1,make_all_runs_index/1]).
--export([get_ts_html_wrapper/4]).
+-export([get_ts_html_wrapper/5]).
-export([xhtml/2, locate_priv_file/1, make_relative/1]).
-export([insert_javascript/1]).
+-export([uri/1]).
%% Logging stuff directly from testcase
-export([tc_log/3, tc_log/4, tc_log_async/3, tc_print/3, tc_print/4,
@@ -307,8 +308,8 @@ end_log() ->
%%% calling test suite.</p>
add_external_logs(Logs) ->
start_log("External Logs"),
- [cont_log("<a href=~p>~s</a>\n",
- [filename:join("log_private",Log),Log]) || Log <- Logs],
+ [cont_log("<a href=\"~ts\">~ts</a>\n",
+ [uri(filename:join("log_private",Log)),Log]) || Log <- Logs],
end_log().
%%%-----------------------------------------------------------------
@@ -320,8 +321,8 @@ add_external_logs(Logs) ->
%%% @doc Print a link to a given file stored in the priv_dir of the
%%% calling test suite.
add_link(Heading,File,Type) ->
- log(Heading,"<a href=~p type=~p>~s</a>\n",
- [filename:join("log_private",File),Type,File]).
+ log(Heading,"<a href=\"~ts\" type=~p>~ts</a>\n",
+ [uri(filename:join("log_private",File)),Type,File]).
%%%-----------------------------------------------------------------
@@ -469,7 +470,7 @@ ct_log(Category,Format,Args) ->
%%%=================================================================
%%% Internal functions
int_header() ->
- "<div class=\"ct_internal\"><b>*** CT ~s *** ~s</b>".
+ "<div class=\"ct_internal\"><b>*** CT ~s *** ~ts</b>".
int_footer() ->
"</div>".
@@ -692,7 +693,7 @@ logger_loop(State) ->
logger_loop(State);
{set_stylesheet,TC,SSFile} ->
Fd = State#logger_state.ct_log_fd,
- io:format(Fd, "~p loading external style sheet: ~s~n",
+ io:format(Fd, "~p loading external style sheet: ~ts~n",
[TC,SSFile]),
logger_loop(State#logger_state{stylesheet = SSFile});
{clear_stylesheet,_} when State#logger_state.stylesheet == undefined ->
@@ -752,7 +753,7 @@ print_to_log(sync, FromPid, TCGL, List, State) ->
IoProc = if FromPid /= TCGL -> TCGL;
true -> State#logger_state.ct_log_fd
end,
- io:format(IoProc, "~s", [lists:foldl(IoFun, [], List)]),
+ io:format(IoProc, "~ts", [lists:foldl(IoFun, [], List)]),
State;
print_to_log(async, FromPid, TCGL, List, State) ->
@@ -764,7 +765,7 @@ print_to_log(async, FromPid, TCGL, List, State) ->
end,
Printer = fun() ->
test_server:permit_io(IoProc, self()),
- io:format(IoProc, "~s", [lists:foldl(IoFun, [], List)])
+ io:format(IoProc, "~ts", [lists:foldl(IoFun, [], List)])
end,
case State#logger_state.async_print_jobs of
[] ->
@@ -868,7 +869,7 @@ set_evmgr_gl(GL) ->
end.
open_ctlog() ->
- {ok,Fd} = file:open(?ct_log_name,[write]),
+ {ok,Fd} = file:open(?ct_log_name,[write,{encoding,utf8}]),
io:format(Fd, header("Common Test Framework Log", {[],[1,2],[]}), []),
case file:consult(ct_run:variables_file_name("../")) of
{ok,Vars} ->
@@ -878,7 +879,7 @@ open_ctlog() ->
Dir = filename:dirname(Cwd),
Variables = ct_run:variables_file_name(Dir),
io:format(Fd,
- "Can not read the file \'~s\' Reason: ~w\n"
+ "Can not read the file \'~ts\' Reason: ~w\n"
"No configuration found for test!!\n",
[Variables,Reason])
end,
@@ -904,7 +905,7 @@ print_style(Fd,undefined) ->
print_style(Fd,StyleSheet) ->
case file:read_file(StyleSheet) of
{ok,Bin} ->
- Str = binary_to_list(Bin),
+ Str = b2s(Bin,encoding(StyleSheet)),
Pos0 = case string:str(Str,"<style>") of
0 -> string:str(Str,"<STYLE>");
N0 -> N0
@@ -919,9 +920,9 @@ print_style(Fd,StyleSheet) ->
print_style_error(Fd,StyleSheet,missing_style_end_tag);
Pos0 /= 0 ->
Style = string:sub_string(Str,Pos0,Pos1+7),
- io:format(Fd,"~s\n",[Style]);
+ io:format(Fd,"~ts\n",[Style]);
Pos0 == 0 ->
- io:format(Fd,"<style>~s</style>\n",[Str])
+ io:format(Fd,"<style>~ts</style>\n",[Str])
end;
{error,Reason} ->
print_style_error(Fd,StyleSheet,Reason)
@@ -934,7 +935,7 @@ print_style(Fd,StyleSheet) ->
%% [StyleSheet]).
print_style_error(Fd,StyleSheet,Reason) ->
- io:format(Fd,"\n<!-- Failed to load stylesheet ~s: ~p -->\n",
+ io:format(Fd,"\n<!-- Failed to load stylesheet ~ts: ~p -->\n",
[StyleSheet,Reason]),
print_style(Fd,undefined).
@@ -963,7 +964,7 @@ make_last_run_index(StartTime) ->
% io:put_chars("done\n"),
ok;
Err ->
- io:format("Unknown internal error while updating ~s. "
+ io:format("Unknown internal error while updating ~ts. "
"Please report.\n(Err: ~p, ID: 1)",
[AbsIndexName,Err]),
{error, Err}
@@ -1001,7 +1002,7 @@ make_last_run_index1(StartTime,IndexName) ->
%% write current Totals to file, later to be used in all_runs log
write_totals_file(?totals_name,Label,Logs1,Totals),
Index = [Index0|index_footer()],
- case force_write_file(IndexName, Index) of
+ case force_write_file(IndexName, unicode:characters_to_binary(Index)) of
ok ->
ok;
{error, Reason} ->
@@ -1085,7 +1086,7 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip,
CrashDumpName = SuiteName ++ "_erl_crash.dump",
case filelib:is_file(CrashDumpName) of
true ->
- ["&nbsp;<a href=\"", CrashDumpName,
+ ["&nbsp;<a href=\"", uri(CrashDumpName),
"\">(CrashDump)</a>"];
false ->
""
@@ -1115,10 +1116,10 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip,
[] -> "none";
_ -> "<a href=\""++?all_runs_name++"\">Old Runs</a>"
end,
- A = xhtml(["<td><font size=\"-1\"><a href=\"",CtLogFile,
+ A = xhtml(["<td><font size=\"-1\"><a href=\"",uri(CtLogFile),
"\">CT Log</a></font></td>\n",
"<td><font size=\"-1\">",OldRunsLink,"</font></td>\n"],
- ["<td><a href=\"",CtLogFile,"\">CT Log</a></td>\n",
+ ["<td><a href=\"",uri(CtLogFile),"\">CT Log</a></td>\n",
"<td>",OldRunsLink,"</td>\n"]),
{L,T,N,A};
false ->
@@ -1128,7 +1129,8 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip,
if NotBuilt == 0 ->
["<td align=right>",integer_to_list(NotBuilt),"</td>\n"];
true ->
- ["<td align=right><a href=\"",filename:join(CtRunDir,?ct_log_name),"\">",
+ ["<td align=right><a href=\"",
+ uri(filename:join(CtRunDir,?ct_log_name)),"\">",
integer_to_list(NotBuilt),"</a></td>\n"]
end,
FailStr =
@@ -1151,7 +1153,7 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip,
[xhtml("<tr valign=top>\n",
["<tr class=\"",odd_or_even(),"\">\n"]),
xhtml("<td><font size=\"-1\"><a href=\"", "<td><a href=\""),
- LogFile,"\">",SuiteName,"</a>", CrashDumpLink,
+ uri(LogFile),"\">",SuiteName,"</a>", CrashDumpLink,
xhtml("</font></td>\n", "</td>\n"),
Lbl, Timestamp,
"<td align=right>",integer_to_list(Success),"</td>\n",
@@ -1364,8 +1366,9 @@ header1(Title, SubTitle, TableCols) ->
"<head>\n",
"<title>" ++ Title ++ " " ++ SubTitle ++ "</title>\n",
"<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
xhtml("",
- ["<link rel=\"stylesheet\" href=\"",CSSFile,"\" type=\"text/css\">\n"]),
+ ["<link rel=\"stylesheet\" href=\"",uri(CSSFile),"\" type=\"text/css\">\n"]),
xhtml("",
["<script type=\"text/javascript\" src=\"",JQueryFile,
"\"></script>\n"]),
@@ -1462,7 +1465,7 @@ count_cases(Dir) ->
LogFile = filename:join(Dir, ?suitelog_name),
case file:read_file(LogFile) of
{ok, Bin} ->
- case count_cases1(binary_to_list(Bin),
+ case count_cases1(b2s(Bin),
{undefined,undefined,undefined,undefined}) of
{error,not_complete} ->
%% The test is not complete - dont write summary
@@ -1557,7 +1560,7 @@ config_table1([{Key,Value}|Vars]) ->
"<td><pre>",io_lib:format("~p",[Value]),"</pre></td></tr>\n"],
["<tr class=\"", odd_or_even(), "\">\n",
"<td>", atom_to_list(Key), "</td>\n",
- "<td>", io_lib:format("~p",[Value]), "</td>\n</tr>\n"]) |
+ "<td>", io_lib:format("~p",[Value]), "</td>\n</tr>\n"]) |
config_table1(Vars)];
config_table1([]) ->
["</tbody>\n</table>\n"].
@@ -1574,8 +1577,9 @@ make_all_runs_index(When) ->
DirsSorted = (catch sort_all_runs(Dirs)),
Header = all_runs_header(),
Index = [runentry(Dir) || Dir <- DirsSorted],
- Result = file:write_file(AbsName,Header++Index++
- all_runs_index_footer()),
+ Result = file:write_file(AbsName,
+ unicode:characters_to_binary(
+ Header++Index++all_runs_index_footer())),
if When == start -> ok;
true -> io:put_chars("done\n")
end,
@@ -1602,10 +1606,27 @@ sort_all_runs(Dirs) ->
interactive_link() ->
[Dir|_] = lists:reverse(filelib:wildcard(logdir_prefix()++"*.*")),
CtLog = filename:join(Dir,"ctlog.html"),
- Body = ["Log from last interactive run: <a href=\"",CtLog,"\">",
- timestamp(Dir),"</a>"],
- file:write_file("last_interactive.html",Body),
- io:format("~n~nUpdated ~s\n"
+ Body =
+ [xhtml(
+ ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n",
+ "<html>\n"],
+ ["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n",
+ "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n",
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"]),
+ "<!-- autogenerated by '"++atom_to_list(?MODULE)++"' -->\n",
+ "<head>\n",
+ "<title>Last interactive run</title>\n",
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
+ "</head>\n",
+ "<body>\n",
+ "Log from last interactive run: <a href=\"",uri(CtLog),"\">",
+ timestamp(Dir),"</a>",
+ "</body>\n",
+ "</html>\n"
+ ],
+ file:write_file("last_interactive.html",unicode:characters_to_binary(Body)),
+ io:format("~n~nUpdated ~ts\n"
"Any CT activities will be logged here\n",
[?abs("last_interactive.html")]).
@@ -1655,7 +1676,7 @@ runentry(Dir) ->
TestNames;
true ->
Trunc = Polish(string:substr(TestNames,1,?testname_width-3)),
- lists:flatten(io_lib:format("~s...",[Trunc]))
+ lists:flatten(io_lib:format("~ts...",[Trunc]))
end,
Total = TotSucc+TotFail+AllSkip,
A = xhtml(["<td align=center><font size=\"-1\">",Node,
@@ -1695,7 +1716,7 @@ runentry(Dir) ->
"<td align=right>?</td>\n"],
A++B++C
end,
- Index = filename:join(Dir,?index_name),
+ Index = uri(filename:join(Dir,?index_name)),
[xhtml("<tr>\n", ["<tr class=\"",odd_or_even(),"\">\n"]),
xhtml(["<td><font size=\"-1\"><a href=\"",Index,"\">",timestamp(Dir),"</a>",
TotalsStr,"</font></td>\n"],
@@ -1836,7 +1857,7 @@ make_all_suites_index(NewTestData = {_TestName,DirName}) ->
ok ->
ok;
Err ->
- io:format("Unknown internal error while updating ~s. "
+ io:format("Unknown internal error while updating ~ts. "
"Please report.\n(Err: ~p, ID: 1)",
[AbsIndexName,Err]),
{error, Err}
@@ -1900,7 +1921,7 @@ make_all_suites_index1(When, AbsIndexName, AllLogDirs) ->
ok
end;
Err ->
- io:format("Unknown internal error while updating ~s. "
+ io:format("Unknown internal error while updating ~ts. "
"Please report.\n(Err: ~p, ID: 1)",
[AbsIndexName,Err]),
{error, Err}
@@ -1912,7 +1933,7 @@ make_all_suites_index2(IndexName, AllTestLogDirs) ->
all_suites_index_header(),
0, 0, 0, 0, 0, [], []),
Index = [Index0|index_footer()],
- case force_write_file(IndexName, Index) of
+ case force_write_file(IndexName, unicode:characters_to_binary(Index)) of
ok ->
{ok,CacheData};
{error, Reason} ->
@@ -1970,7 +1991,7 @@ make_all_suites_ix_cached(AbsIndexName, NewTestData, Label, AllTestLogDirs) ->
all_suites_index_header(IndexDir),
0, 0, 0, 0, 0),
Index = [Index0|index_footer()],
- case force_write_file(AbsIndexName, Index) of
+ case force_write_file(AbsIndexName, unicode:characters_to_binary(Index)) of
ok ->
ok;
{error, Reason} ->
@@ -2116,7 +2137,7 @@ simulate_logger_loop() ->
receive
{log,_,_,_,_,_,List} ->
S = [[io_lib:format(Str,Args),io_lib:nl()] || {Str,Args} <- List],
- io:format("~s",[S]),
+ io:format("~ts",[S]),
simulate_logger_loop();
stop ->
ok
@@ -2273,11 +2294,12 @@ make_relative1(DirTs, CwdTs) ->
Ups ++ DirTs.
%%%-----------------------------------------------------------------
-%%% @spec get_ts_html_wrapper(TestName, PrintLabel, Cwd) -> {Mode,Header,Footer}
+%%% @spec get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding)
+%%% -> {Mode,Header,Footer}
%%%
%%% @doc
%%%
-get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols) ->
+get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) ->
TestName1 = if is_list(TestName) ->
lists:flatten(TestName);
true ->
@@ -2319,14 +2341,16 @@ get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols) ->
"<html>\n",
"<head><title>", TestName1, "</title>\n",
"<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=",
+ html_encoding(Encoding),"\">\n",
"</head>\n",
"<body", Bgr, " bgcolor=\"white\" text=\"black\" ",
"link=\"blue\" vlink=\"purple\" alink=\"red\">\n",
LabelStr, "\n"],
["<center>\n<br><hr><p>\n",
- "<a href=\"", AllRuns,
+ "<a href=\"", uri(AllRuns),
"\">Test run history\n</a> | ",
- "<a href=\"", TestIndex,
+ "<a href=\"", uri(TestIndex),
"\">Top level test index\n</a>\n</p>\n",
Copyright,"</center>\n</body>\n</html>\n"]};
_ ->
@@ -2363,14 +2387,15 @@ get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols) ->
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n",
"<head>\n<title>", TestName1, "</title>\n",
"<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
- "<link rel=\"stylesheet\" href=\"", CSSFile, "\" type=\"text/css\">\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
+ "<link rel=\"stylesheet\" href=\"", uri(CSSFile), "\" type=\"text/css\">\n",
"<script type=\"text/javascript\" src=\"", JQueryFile, "\"></script>\n",
"<script type=\"text/javascript\" src=\"", TableSorterFile, "\"></script>\n"] ++
TableSorterScript ++ ["</head>\n","<body>\n", LabelStr, "\n"],
["<center>\n<br /><hr /><p>\n",
- "<a href=\"", AllRuns,
+ "<a href=\"", uri(AllRuns),
"\">Test run history\n</a> | ",
- "<a href=\"", TestIndex,
+ "<a href=\"", uri(TestIndex),
"\">Top level test index\n</a>\n</p>\n",
Copyright,"</center>\n</body>\n</html>\n"]}
end.
@@ -2460,3 +2485,31 @@ insert_javascript({tablesorter,TableName,
" $(\"#",TableName,"\").trigger(\"update\");\n",
" $(\"#",TableName,"\").trigger(\"appendCache\");\n",
"});\n</script>\n"].
+
+uri("") ->
+ "";
+uri(Href) ->
+ test_server_ctrl:uri_encode(Href).
+
+%% Read magic comment to get encoding of text file.
+%% If no magic comment exists, assume default encoding
+encoding(File) ->
+ case epp:read_encoding(File) of
+ none ->
+ epp:default_encoding();
+ E ->
+ E
+ end.
+
+%% Convert binary to string using default encoding
+b2s(Bin) ->
+ b2s(Bin,epp:default_encoding()).
+
+%% Convert binary to string using given encoding
+b2s(Bin,Encoding) ->
+ unicode:characters_to_list(Bin,Encoding).
+
+html_encoding(latin1) ->
+ "iso-8859-1";
+html_encoding(utf8) ->
+ "utf-8".
diff --git a/lib/common_test/src/ct_make.erl b/lib/common_test/src/ct_make.erl
index 8ddb91d355..d4bd81e78d 100644
--- a/lib/common_test/src/ct_make.erl
+++ b/lib/common_test/src/ct_make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -280,13 +280,13 @@ recompile(File, NoExec, Load, Opts) ->
do_recompile(_File, true, _Load, _Opts) ->
out_of_date;
do_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]);
do_recompile(File, false, load, Opts) ->
- io:format("Recompile: ~s\n",[File]),
+ io:format("Recompile: ~ts\n",[File]),
c:c(File, Opts);
do_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/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl
index f29eba605c..e516f635d2 100644
--- a/lib/common_test/src/ct_master.erl
+++ b/lib/common_test/src/ct_master.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -82,39 +82,48 @@ run_test(NodeOptsList) when is_list(NodeOptsList) ->
%%% ExclNodes = [atom()]
%%%
%%% @doc Tests are spawned on the nodes as specified in <code>TestSpecs</code>.
-%%% Each specification in TestSpec will be handled separately. It is however possible
-%%% to also specify a list of specifications that should be merged into one before
-%%% the tests are executed. Any test without a particular node specification will
-%%% also be executed on the nodes in <code>InclNodes</code>. Nodes in the
-%%% <code>ExclNodes</code> list will be excluded from the test.
+%%% Each specification in TestSpec will be handled separately. It is however
+%%% possible to also specify a list of specifications that should be merged
+%%% into one before the tests are executed. Any test without a particular node
+%%% specification will also be executed on the nodes in <code>InclNodes</code>.
+%%% Nodes in the <code>ExclNodes</code> list will be excluded from the test.
run([TS|TestSpecs],AllowUserTerms,InclNodes,ExclNodes) when is_list(TS),
is_list(InclNodes),
is_list(ExclNodes) ->
- TS1 =
- case TS of
- List=[S|_] when is_list(S) -> List;
- Spec -> [Spec]
- end,
- Result =
- case catch ct_testspec:collect_tests_from_file(TS1,InclNodes,AllowUserTerms) of
- {error,Reason} ->
- {error,Reason};
- TSRec=#testspec{logdir=AllLogDirs,
- config=StdCfgFiles,
- userconfig=UserCfgFiles,
- include=AllIncludes,
- init=AllInitOpts,
- event_handler=AllEvHs} ->
- AllCfgFiles = {StdCfgFiles, UserCfgFiles},
- RunSkipPerNode = ct_testspec:prepare_tests(TSRec),
- RunSkipPerNode2 = exclude_nodes(ExclNodes,RunSkipPerNode),
- run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs,
- AllIncludes,[],[],AllInitOpts,TS1)
- end,
- [{TS,Result} | run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes)];
+ %% Note: [Spec] means run one test with Spec
+ %% [Spec1,Spec2] means run two tests separately
+ %% [[Spec1,Spec2]] means run one test, with the two specs merged
+ case catch ct_testspec:collect_tests_from_file([TS],InclNodes,
+ AllowUserTerms) of
+ {error,Reason} ->
+ [{error,Reason} | run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes)];
+ Tests ->
+ RunResult =
+ lists:map(
+ fun({Specs,TSRec=#testspec{logdir=AllLogDirs,
+ config=StdCfgFiles,
+ userconfig=UserCfgFiles,
+ include=AllIncludes,
+ init=AllInitOpts,
+ event_handler=AllEvHs}}) ->
+ AllCfgFiles =
+ {StdCfgFiles,UserCfgFiles},
+ RunSkipPerNode =
+ ct_testspec:prepare_tests(TSRec),
+ RunSkipPerNode2 =
+ exclude_nodes(ExclNodes,RunSkipPerNode),
+ TSList = if is_integer(hd(TS)) -> [TS];
+ true -> TS end,
+ {Specs,run_all(RunSkipPerNode2,AllLogDirs,
+ AllCfgFiles,AllEvHs,
+ AllIncludes,[],[],AllInitOpts,TSList)}
+ end, Tests),
+ RunResult ++ run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes)
+ end;
run([],_,_,_) ->
[];
-run(TS,AllowUserTerms,InclNodes,ExclNodes) when is_list(InclNodes), is_list(ExclNodes) ->
+run(TS,AllowUserTerms,InclNodes,ExclNodes) when is_list(InclNodes),
+ is_list(ExclNodes) ->
run([TS],AllowUserTerms,InclNodes,ExclNodes).
%%%-----------------------------------------------------------------
@@ -152,29 +161,32 @@ exclude_nodes([],RunSkipPerNode) ->
%%% AllowUserTerms = bool()
%%% Node = atom()
%%%
-%%% @doc Tests are spawned on <code>Node</code> according to <code>TestSpecs</code>.
+%%% @doc Tests are spawned on <code>Node</code> according to
+%%% <code>TestSpecs</code>.
run_on_node([TS|TestSpecs],AllowUserTerms,Node) when is_list(TS),is_atom(Node) ->
- TS1 =
- case TS of
- [List|_] when is_list(List) -> List;
- Spec -> [Spec]
- end,
- Result =
- case catch ct_testspec:collect_tests_from_file(TS1,[Node],AllowUserTerms) of
- {error,Reason} ->
- {error,Reason};
- TSRec=#testspec{logdir=AllLogDirs,
- config=StdCfgFiles,
- init=AllInitOpts,
- include=AllIncludes,
- userconfig=UserCfgFiles,
- event_handler=AllEvHs} ->
- AllCfgFiles = {StdCfgFiles, UserCfgFiles},
- {Run,Skip} = ct_testspec:prepare_tests(TSRec,Node),
- run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs,
- AllIncludes, [],[],AllInitOpts,TS1)
- end,
- [{TS,Result} | run_on_node(TestSpecs,AllowUserTerms,Node)];
+ case catch ct_testspec:collect_tests_from_file([TS],[Node],
+ AllowUserTerms) of
+ {error,Reason} ->
+ [{error,Reason} | run_on_node(TestSpecs,AllowUserTerms,Node)];
+ Tests ->
+ RunResult =
+ lists:map(
+ fun({Specs,TSRec=#testspec{logdir=AllLogDirs,
+ config=StdCfgFiles,
+ init=AllInitOpts,
+ include=AllIncludes,
+ userconfig=UserCfgFiles,
+ event_handler=AllEvHs}}) ->
+ AllCfgFiles = {StdCfgFiles,UserCfgFiles},
+ {Run,Skip} = ct_testspec:prepare_tests(TSRec,Node),
+ TSList = if is_integer(hd(TS)) -> [TS];
+ true -> TS end,
+ {Specs,run_all([{Node,Run,Skip}],AllLogDirs,
+ AllCfgFiles,AllEvHs,
+ AllIncludes, [],[],AllInitOpts,TSList)}
+ end, Tests),
+ RunResult ++ run_on_node(TestSpecs,AllowUserTerms,Node)
+ end;
run_on_node([],_,_) ->
[];
run_on_node(TS,AllowUserTerms,Node) when is_atom(Node) ->
@@ -244,8 +256,9 @@ run_all([],AllLogDirs,_,AllEvHs,_AllIncludes,
{value,{_,Dir}} -> Dir;
false -> "."
end,
- log(tty,"Master Logdir","~s",[MasterLogDir]),
- start_master(lists:reverse(NodeOpts),Handlers,MasterLogDir,LogDirs,InitOptions,Specs),
+ log(tty,"Master Logdir","~ts",[MasterLogDir]),
+ start_master(lists:reverse(NodeOpts),Handlers,MasterLogDir,
+ LogDirs,InitOptions,Specs),
ok.
@@ -297,13 +310,15 @@ start_master(NodeOptsList) ->
start_master(NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Specs) ->
Master = spawn_link(?MODULE,init_master,[self(),NodeOptsList,EvHandlers,
- MasterLogDir,LogDirs,InitOptions,Specs]),
+ MasterLogDir,LogDirs,
+ InitOptions,Specs]),
receive
{Master,Result} -> Result
end.
%%% @hidden
-init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Specs) ->
+init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,
+ InitOptions,Specs) ->
case whereis(ct_master) of
undefined ->
register(ct_master,self()),
@@ -325,13 +340,14 @@ init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Spec
{MLPid,_} = ct_master_logs:start(MasterLogDir,
[N || {N,_} <- NodeOptsList]),
log(all,"Master Logger process started","~w",[MLPid]),
+
case Specs of
[] -> ok;
_ ->
SpecsStr = lists:map(fun(Name) ->
Name ++ " "
end,Specs),
- ct_master_logs:log("Test Specification file(s)","~s",
+ ct_master_logs:log("Test Specification file(s)","~ts",
[lists:flatten(SpecsStr)])
end,
@@ -340,7 +356,7 @@ init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Spec
ct_master_event:add_handler(),
%% add user handlers for master event manager
Add = fun({H,Args}) ->
- log(all,"Adding Event Handler","~p",[H]),
+ log(all,"Adding Event Handler","~w",[H]),
case gen_event:add_handler(?CT_MEVMGR_REF,H,Args) of
ok -> ok;
{'EXIT',Why} -> exit(Why);
@@ -359,7 +375,8 @@ init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Spec
init_master1(Parent,NodeOptsList,InitOptions,LogDirs).
init_master1(Parent,NodeOptsList,InitOptions,LogDirs) ->
- {Inaccessible,NodeOptsList1,InitOptions1} = init_nodes(NodeOptsList,InitOptions),
+ {Inaccessible,NodeOptsList1,InitOptions1} = init_nodes(NodeOptsList,
+ InitOptions),
case Inaccessible of
[] ->
init_master2(Parent,NodeOptsList,LogDirs);
@@ -391,8 +408,9 @@ init_master2(Parent,NodeOptsList,LogDirs) ->
SpawnAndMon =
fun({Node,Opts}) ->
monitor_node(Node,true),
- log(all,"Test Info","Starting test(s) on ~p...",[Node]),
- {spawn_link(Node,?MODULE,init_node_ctrl,[self(),Cookie,Opts]),Node}
+ log(all,"Test Info","Starting test(s) on ~w...",[Node]),
+ {spawn_link(Node,?MODULE,init_node_ctrl,[self(),Cookie,Opts]),
+ Node}
end,
NodeCtrlPids = lists:map(SpawnAndMon,NodeOptsList),
Result = master_loop(#state{node_ctrl_pids=NodeCtrlPids,
@@ -404,7 +422,8 @@ master_loop(#state{node_ctrl_pids=[],
results=Finished}) ->
Str =
lists:map(fun({Node,Result}) ->
- io_lib:format("~-40.40.*s~p\n",[$_,atom_to_list(Node),Result])
+ io_lib:format("~-40.40.*ts~p\n",
+ [$_,atom_to_list(Node),Result])
end,lists:reverse(Finished)),
log(all,"TEST RESULTS",Str,[]),
log(all,"Info","Updating log files",[]),
@@ -437,18 +456,20 @@ master_loop(State=#state{node_ctrl_pids=NodeCtrlPids,
Bad
end,
log(all,"Test Info",
- "Test on node ~w failed! Reason: ~p",[Node,Error]),
+ "Test on node ~w failed! Reason: ~p",
+ [Node,Error]),
{Locks1,Blocked1} =
update_queue(exit,Node,Locks,Blocked),
master_loop(State#state{node_ctrl_pids=NodeCtrlPids1,
- results=[{Node,Error}|Results],
+ results=[{Node,
+ Error}|Results],
locks=Locks1,
blocked=Blocked1})
end;
undefined ->
%% ignore (but report) exit from master_logger etc
log(all,"Test Info",
- "Warning! Process ~p has terminated. Reason: ~p",
+ "Warning! Process ~w has terminated. Reason: ~p",
[Pid,Reason]),
master_loop(State)
end;
@@ -531,7 +552,7 @@ update_queue(take,Node,From,Lock={Op,Resource},Locks,Blocked) ->
%% Blocked: [{{Operation,Resource},Node,WaitingPid},...]
case lists:keysearch(Lock,1,Locks) of
{value,{_Lock,Owner}} -> % other node has lock
- log(html,"Lock Info","Node ~p blocked on ~w by ~w. Resource: ~p",
+ log(html,"Lock Info","Node ~w blocked on ~w by ~w. Resource: ~p",
[Node,Op,Owner,Resource]),
Blocked1 = Blocked ++ [{Lock,Node,From}],
{Locks,Blocked1};
@@ -546,7 +567,7 @@ update_queue(release,Node,_From,Lock={Op,Resource},Locks,Blocked) ->
case lists:keysearch(Lock,1,Blocked) of
{value,E={Lock,SomeNode,WaitingPid}} ->
Blocked1 = lists:delete(E,Blocked),
- log(html,"Lock Info","Node ~p proceeds with ~w. Resource: ~p",
+ log(html,"Lock Info","Node ~w proceeds with ~w. Resource: ~p",
[SomeNode,Op,Resource]),
reply(ok,WaitingPid), % waiting process may start
{Locks1,Blocked1};
@@ -625,7 +646,8 @@ refresh_logs([D|Dirs],Refreshed) ->
refresh_logs([],Refreshed) ->
Str =
lists:map(fun({D,Result}) ->
- io_lib:format("Refreshing logs in ~p... ~p",[D,Result])
+ io_lib:format("Refreshing logs in ~p... ~p",
+ [D,Result])
end,Refreshed),
log(all,"Info",Str,[]).
@@ -638,7 +660,7 @@ init_node_ctrl(MasterPid,Cookie,Opts) ->
process_flag(trap_exit, true),
MasterNode = node(MasterPid),
group_leader(whereis(user),self()),
- io:format("~n********** node_ctrl process ~p started on ~p **********~n",
+ io:format("~n********** node_ctrl process ~w started on ~w **********~n",
[self(),node()]),
%% initially this node must have the same cookie as the master node
%% but now we set it explicitly for the connection so that test suites
@@ -671,7 +693,7 @@ init_node_ctrl(MasterPid,Cookie,Opts) ->
pong ->
MasterPid ! {self(),{result,Result}};
pang ->
- io:format("Warning! Connection to master node ~p is lost. "
+ io:format("Warning! Connection to master node ~w is lost. "
"Can't report result!~n~n", [MasterNode])
end.
@@ -752,21 +774,25 @@ start_nodes(InitOptions)->
IsAlive = lists:member(NodeName, nodes()),
case {HasNodeStart, IsAlive} of
{false, false}->
- io:format("WARNING: Node ~p is not alive but has no node_start option~n", [NodeName]);
+ io:format("WARNING: Node ~w is not alive but has no "
+ "node_start option~n", [NodeName]);
{false, true}->
- io:format("Node ~p is alive~n", [NodeName]);
+ io:format("Node ~w is alive~n", [NodeName]);
{true, false}->
{node_start, NodeStart} = lists:keyfind(node_start, 1, Options),
{value, {callback_module, Callback}, NodeStart2}=
lists:keytake(callback_module, 1, NodeStart),
case Callback:start(Host, Node, NodeStart2) of
{ok, NodeName} ->
- io:format("Node ~p started successfully with callback ~p~n", [NodeName,Callback]);
+ io:format("Node ~w started successfully "
+ "with callback ~w~n", [NodeName,Callback]);
{error, Reason, _NodeName} ->
- io:format("Failed to start node ~p with callback ~p! Reason: ~p~n", [NodeName, Callback, Reason])
+ io:format("Failed to start node ~w with callback ~w! "
+ "Reason: ~p~n", [NodeName, Callback, Reason])
end;
{true, true}->
- io:format("WARNING: Node ~p is alive but has node_start option~n", [NodeName])
+ io:format("WARNING: Node ~w is alive but has node_start "
+ "option~n", [NodeName])
end
end,
InitOptions).
@@ -779,7 +805,8 @@ eval_on_nodes(InitOptions)->
{false,_}->
ok;
{true,false}->
- io:format("WARNING: Node ~p is not alive but has eval option ~n", [NodeName]);
+ io:format("WARNING: Node ~w is not alive but has eval "
+ "option~n", [NodeName]);
{true,true}->
{eval, MFAs} = lists:keyfind(eval, 1, Options),
evaluate(NodeName, MFAs)
@@ -790,9 +817,11 @@ eval_on_nodes(InitOptions)->
evaluate(Node, [{M,F,A}|MFAs])->
case rpc:call(Node, M, F, A) of
{badrpc,Reason}->
- io:format("WARNING: Failed to call ~p:~p/~p on node ~p due to ~p~n", [M,F,length(A),Node,Reason]);
+ io:format("WARNING: Failed to call ~w:~w/~w on node ~w "
+ "due to ~p~n", [M,F,length(A),Node,Reason]);
Result->
- io:format("Called ~p:~p/~p on node ~p, result: ~p~n", [M,F,length(A),Node,Result])
+ io:format("Called ~w:~w/~w on node ~w, result: ~p~n",
+ [M,F,length(A),Node,Result])
end,
evaluate(Node, MFAs);
evaluate(_Node, [])->
diff --git a/lib/common_test/src/ct_master_event.erl b/lib/common_test/src/ct_master_event.erl
index a70baefaaf..5877b7c6f2 100644
--- a/lib/common_test/src/ct_master_event.erl
+++ b/lib/common_test/src/ct_master_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -114,13 +114,13 @@ init(_) ->
%% each installed event handler to handle the event.
%%--------------------------------------------------------------------
handle_event(#event{name=start_logging,node=Node,data=RunDir},State) ->
- ct_master_logs:log("CT Master Event Handler","Got ~s from ~p",[RunDir,Node]),
+ ct_master_logs:log("CT Master Event Handler","Got ~ts from ~w",[RunDir,Node]),
ct_master_logs:nodedir(Node,RunDir),
{ok,State};
handle_event(#event{name=Name,node=Node,data=Data},State) ->
print("~n=== ~w ===~n", [?MODULE]),
- print("~p on ~p: ~p~n", [Name,Node,Data]),
+ print("~w on ~w: ~p~n", [Name,Node,Data]),
{ok,State}.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_master_logs.erl b/lib/common_test/src/ct_master_logs.erl
index 84f175c0a9..5393097f57 100644
--- a/lib/common_test/src/ct_master_logs.erl
+++ b/lib/common_test/src/ct_master_logs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -133,7 +133,7 @@ init(Parent,LogDir,Nodes) ->
end,Nodes)),
io:format(CtLogFd,int_header(),[log_timestamp(now()),"Test Nodes\n"]),
- io:format(CtLogFd,"~s\n",[NodeStr]),
+ io:format(CtLogFd,"~ts\n",[NodeStr]),
io:put_chars(CtLogFd,[int_footer(),"\n"]),
NodeDirIxFd = open_nodedir_index(RunDirAbs,Time),
@@ -201,7 +201,7 @@ loop(State) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
open_ct_master_log(Dir) ->
FullName = filename:join(Dir,?ct_master_log_name),
- {ok,Fd} = file:open(FullName,[write]),
+ {ok,Fd} = file:open(FullName,[write,{encoding,utf8}]),
io:put_chars(Fd,header("Common Test Master Log", {[],[1,2],[]})),
%% maybe add config info here later
io:put_chars(Fd,config_table([])),
@@ -235,7 +235,7 @@ config_table1([]) ->
["</tbody>\n</table>\n"].
int_header() ->
- "<div class=\"ct_internal\"><b>*** CT MASTER ~s *** ~s</b>".
+ "<div class=\"ct_internal\"><b>*** CT MASTER ~s *** ~ts</b>".
int_footer() ->
"</div>".
@@ -244,7 +244,7 @@ int_footer() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
open_nodedir_index(Dir,StartTime) ->
FullName = filename:join(Dir,?nodedir_index_name),
- {ok,Fd} = file:open(FullName,[write]),
+ {ok,Fd} = file:open(FullName,[write,{encoding,utf8}]),
io:put_chars(Fd,nodedir_index_header(StartTime)),
Fd.
@@ -253,7 +253,8 @@ print_nodedir(Node,RunDir,Fd) ->
io:put_chars(Fd,
["<tr>\n"
"<td align=center>",atom_to_list(Node),"</td>\n",
- "<td align=left><a href=\"",Index,"\">",Index,"</a></td>\n",
+ "<td align=left><a href=\"",ct_logs:uri(Index),"\">",Index,
+ "</a></td>\n",
"</tr>\n"]),
ok.
@@ -283,7 +284,9 @@ make_all_runs_index(LogDir) ->
DirsSorted = (catch sort_all_runs(Dirs)),
Header = all_runs_header(),
Index = [runentry(Dir) || Dir <- DirsSorted],
- Result = file:write_file(FullName,Header++Index++index_footer()),
+ Result = file:write_file(FullName,
+ unicode:characters_to_binary(
+ Header++Index++index_footer())),
Result.
sort_all_runs(Dirs) ->
@@ -323,7 +326,8 @@ runentry(Dir) ->
end,
Index = filename:join(Dir,?nodedir_index_name),
["<tr>\n"
- "<td align=center><a href=\"",Index,"\">",timestamp(Dir),"</a></td>\n",
+ "<td align=center><a href=\"",ct_logs:uri(Index),"\">",
+ timestamp(Dir),"</a></td>\n",
"<td align=center>",MasterStr,"</td>\n",
"<td align=center>",NodesStr,"</td>\n",
"</tr>\n"].
@@ -381,8 +385,10 @@ header(Title, TableCols) ->
"<head>\n",
"<title>" ++ Title ++ "</title>\n",
"<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n",
xhtml("",
- ["<link rel=\"stylesheet\" href=\"",CSSFile,"\" type=\"text/css\">"]),
+ ["<link rel=\"stylesheet\" href=\"",ct_logs:uri(CSSFile),
+ "\" type=\"text/css\">"]),
xhtml("",
["<script type=\"text/javascript\" src=\"",JQueryFile,
"\"></script>\n"]),
diff --git a/lib/common_test/src/ct_master_status.erl b/lib/common_test/src/ct_master_status.erl
index 76060fb7bb..f9f511ecca 100644
--- a/lib/common_test/src/ct_master_status.erl
+++ b/lib/common_test/src/ct_master_status.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -70,7 +70,7 @@ init(_) ->
%%
handle_event(#event{name=Name,node=Node,data=Data},State) ->
print("~n=== ~w ===~n", [?MODULE]),
- print("~p on ~p: ~p~n", [Name,Node,Data]),
+ print("~w on ~w: ~p~n", [Name,Node,Data]),
{ok,State}.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl
index 1ccbc86d8f..1339e53780 100644
--- a/lib/common_test/src/ct_netconfc.erl
+++ b/lib/common_test/src/ct_netconfc.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
@@ -1281,10 +1281,11 @@ do_send(Connection, SimpleXml) ->
to_xml_doc(Simple) ->
Prolog = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
- Xml = list_to_binary(xmerl:export_simple([Simple],
- xmerl_xml,
- [#xmlAttribute{name=prolog,
- value=Prolog}])),
+ Xml = unicode:characters_to_binary(
+ xmerl:export_simple([Simple],
+ xmerl_xml,
+ [#xmlAttribute{name=prolog,
+ value=Prolog}])),
<<Xml/binary,?END_TAG/binary>>.
%%%-----------------------------------------------------------------
@@ -1688,18 +1689,27 @@ log(#connection{host=Host,port=Port,name=Name},Action,Data) ->
%% Log callback - called from the error handler process
-format_data(raw,Data) ->
- io_lib:format("~n~s~n",[hide_password(Data)]);
-format_data(pretty,Data) ->
- io_lib:format("~n~s~n",[indent(Data)]);
-format_data(html,Data) ->
- io_lib:format("~n~s~n",[html_format(Data)]).
+format_data(How,Data) ->
+ %% Assuming that the data is encoded as UTF-8. If it is not, then
+ %% the printout might be wrong, but the format function will not
+ %% crash!
+ %% FIXME: should probably read encoding from the data and do
+ %% unicode:characters_to_binary(Data,InEncoding,utf8) when calling
+ %% log/3 instead of assuming utf8 in as done here!
+ do_format_data(How,unicode:characters_to_binary(Data)).
+
+do_format_data(raw,Data) ->
+ io_lib:format("~n~ts~n",[hide_password(Data)]);
+do_format_data(pretty,Data) ->
+ io_lib:format("~n~ts~n",[indent(Data)]);
+do_format_data(html,Data) ->
+ io_lib:format("~n~ts~n",[html_format(Data)]).
%%%-----------------------------------------------------------------
%%% Hide password elements from XML data
hide_password(Bin) ->
re:replace(Bin,<<"(<password[^>]*>)[^<]*(</password>)">>,<<"\\1*****\\2">>,
- [global,{return,binary}]).
+ [global,{return,binary},unicode]).
%%%-----------------------------------------------------------------
%%% HTML formatting
@@ -1717,13 +1727,13 @@ indent(Bin) ->
Part ->
indent1(lists:reverse(Part)++String,erase(indent))
end,
- list_to_binary(IndentedString).
+ unicode:characters_to_binary(IndentedString).
%% Normalizes the XML document by removing all space and newline
%% between two XML tags.
%% Returns a list, no matter if the input was a list or a binary.
-normalize(Str) ->
- re:replace(Str,<<">[ \r\n\t]+<">>,<<"><">>,[global,{return,list}]).
+normalize(Bin) ->
+ re:replace(Bin,<<">[ \r\n\t]+<">>,<<"><">>,[global,{return,list},unicode]).
indent1("<?"++Rest1,Indent1) ->
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index eb05c90ba8..c0bdbb2a09 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-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
@@ -148,7 +148,7 @@ script_start(Args) ->
_ -> ""
end
end,
- io:format("~nCommon Test~s starting (cwd is ~s)~n~n",
+ io:format("~nCommon Test~s starting (cwd is ~ts)~n~n",
[CTVsn,Cwd]),
Self = self(),
Pid = spawn_link(fun() -> script_start1(Self, Args) end),
@@ -330,33 +330,33 @@ script_start1(Parent, Args) ->
true
end,
- StartOpts = #opts{label = Label, profile = Profile,
- vts = Vts, shell = Shell,
- cover = Cover, cover_stop = CoverStop,
- logdir = LogDir, logopts = LogOpts,
- basic_html = BasicHtml,
- verbosity = Verbosity,
- event_handlers = EvHandlers,
- ct_hooks = CTHooks,
- enable_builtin_hooks = EnableBuiltinHooks,
- auto_compile = AutoCompile,
- include = IncludeDirs,
- silent_connections = SilentConns,
- stylesheet = Stylesheet,
- multiply_timetraps = MultTT,
- scale_timetraps = ScaleTT,
- create_priv_dir = CreatePrivDir,
- starter = script},
-
+ Opts = #opts{label = Label, profile = Profile,
+ vts = Vts, shell = Shell,
+ cover = Cover, cover_stop = CoverStop,
+ logdir = LogDir, logopts = LogOpts,
+ basic_html = BasicHtml,
+ verbosity = Verbosity,
+ event_handlers = EvHandlers,
+ ct_hooks = CTHooks,
+ enable_builtin_hooks = EnableBuiltinHooks,
+ auto_compile = AutoCompile,
+ include = IncludeDirs,
+ silent_connections = SilentConns,
+ stylesheet = Stylesheet,
+ multiply_timetraps = MultTT,
+ scale_timetraps = ScaleTT,
+ create_priv_dir = CreatePrivDir,
+ starter = script},
+
%% check if log files should be refreshed or go on to run tests...
- Result = run_or_refresh(StartOpts, Args),
+ Result = run_or_refresh(Opts, Args),
%% send final results to starting process waiting in script_start/0
Parent ! {self(), Result}.
-run_or_refresh(StartOpts = #opts{logdir = LogDir}, Args) ->
+run_or_refresh(Opts = #opts{logdir = LogDir}, Args) ->
case proplists:get_value(refresh_logs, Args) of
undefined ->
- script_start2(StartOpts, Args);
+ script_start2(Opts, Args);
Refresh ->
LogDir1 = case Refresh of
[] -> which(logdir,LogDir);
@@ -378,171 +378,203 @@ run_or_refresh(StartOpts = #opts{logdir = LogDir}, Args) ->
{error,{all_suites_index,ASReason}};
_ ->
file:set_cwd(Cwd),
- io:format("Logs in ~s refreshed!~n~n", [LogDir1]),
+ io:format("Logs in ~ts refreshed!~n~n",
+ [LogDir1]),
timer:sleep(500), % time to flush io before quitting
ok
end
end
end.
-script_start2(StartOpts = #opts{vts = undefined,
- shell = undefined}, Args) ->
- TestSpec = proplists:get_value(spec, Args),
- {Terms,Opts} =
- case TestSpec of
- Specs when Specs =/= [], Specs =/= undefined ->
- %% using testspec as input for test
- Relaxed = get_start_opt(allow_user_terms, true, false, Args),
- case catch ct_testspec:collect_tests_from_file(Specs, Relaxed) of
- {E,Reason} when E == error ; E == 'EXIT' ->
- {{error,Reason},StartOpts};
- TS ->
- SpecStartOpts = get_data_for_node(TS, node()),
-
- Label = choose_val(StartOpts#opts.label,
- SpecStartOpts#opts.label),
-
- Profile = choose_val(StartOpts#opts.profile,
- SpecStartOpts#opts.profile),
-
- LogDir = choose_val(StartOpts#opts.logdir,
- SpecStartOpts#opts.logdir),
-
- AllLogOpts = merge_vals([StartOpts#opts.logopts,
- SpecStartOpts#opts.logopts]),
- AllVerbosity =
- merge_keyvals([StartOpts#opts.verbosity,
- SpecStartOpts#opts.verbosity]),
- AllSilentConns =
- merge_vals([StartOpts#opts.silent_connections,
- SpecStartOpts#opts.silent_connections]),
- Cover =
- choose_val(StartOpts#opts.cover,
- SpecStartOpts#opts.cover),
- CoverStop =
- choose_val(StartOpts#opts.cover_stop,
- SpecStartOpts#opts.cover_stop),
- MultTT =
- choose_val(StartOpts#opts.multiply_timetraps,
- SpecStartOpts#opts.multiply_timetraps),
- ScaleTT =
- choose_val(StartOpts#opts.scale_timetraps,
- SpecStartOpts#opts.scale_timetraps),
-
- CreatePrivDir =
- choose_val(StartOpts#opts.create_priv_dir,
- SpecStartOpts#opts.create_priv_dir),
-
- AllEvHs =
- merge_vals([StartOpts#opts.event_handlers,
- SpecStartOpts#opts.event_handlers]),
-
- AllCTHooks = merge_vals(
- [StartOpts#opts.ct_hooks,
- SpecStartOpts#opts.ct_hooks]),
-
- EnableBuiltinHooks =
- choose_val(
- StartOpts#opts.enable_builtin_hooks,
- SpecStartOpts#opts.enable_builtin_hooks),
-
- Stylesheet =
- choose_val(StartOpts#opts.stylesheet,
- SpecStartOpts#opts.stylesheet),
-
- AllInclude = merge_vals([StartOpts#opts.include,
- SpecStartOpts#opts.include]),
- application:set_env(common_test, include, AllInclude),
-
- AutoCompile =
- case choose_val(StartOpts#opts.auto_compile,
- SpecStartOpts#opts.auto_compile) of
- undefined ->
- true;
- ACBool ->
- application:set_env(common_test,
- auto_compile,
- ACBool),
- ACBool
- end,
-
- BasicHtml =
- case choose_val(StartOpts#opts.basic_html,
- SpecStartOpts#opts.basic_html) of
- undefined ->
- false;
- BHBool ->
- application:set_env(common_test, basic_html,
- BHBool),
- BHBool
- end,
-
- {TS,StartOpts#opts{label = Label,
- profile = Profile,
- testspecs = Specs,
- cover = Cover,
- cover_stop = CoverStop,
- logdir = LogDir,
- logopts = AllLogOpts,
- basic_html = BasicHtml,
- verbosity = AllVerbosity,
- silent_connections = AllSilentConns,
- config = SpecStartOpts#opts.config,
- event_handlers = AllEvHs,
- ct_hooks = AllCTHooks,
- enable_builtin_hooks =
- EnableBuiltinHooks,
- stylesheet = Stylesheet,
- auto_compile = AutoCompile,
- include = AllInclude,
- multiply_timetraps = MultTT,
- scale_timetraps = ScaleTT,
- create_priv_dir = CreatePrivDir}}
- end;
- _ ->
- {undefined,StartOpts}
- end,
- %% read config/userconfig from start flags
- InitConfig = ct_config:prepare_config_list(Args),
- TheLogDir = which(logdir, Opts#opts.logdir),
- case {TestSpec,Terms} of
- {_,{error,_}=Error} ->
- Error;
- {[],_} ->
+script_start2(Opts = #opts{vts = undefined,
+ shell = undefined}, Args) ->
+ case proplists:get_value(spec, Args) of
+ Specs when Specs =/= [], Specs =/= undefined ->
+ Specs1 = get_start_opt(join_specs, [Specs], Specs, Args),
+ %% using testspec as input for test
+ Relaxed = get_start_opt(allow_user_terms, true, false, Args),
+ case catch ct_testspec:collect_tests_from_file(Specs1, Relaxed) of
+ {E,Reason} when E == error ; E == 'EXIT' ->
+ {error,Reason};
+ TestSpecData ->
+ execute_all_specs(TestSpecData, Opts, Args, [])
+ end;
+ [] ->
{error,no_testspec_specified};
- {undefined,_} -> % no testspec used
- case check_and_install_configfiles(InitConfig, TheLogDir, Opts) of
+ _ -> % no testspec used
+ %% read config/userconfig from start flags
+ InitConfig = ct_config:prepare_config_list(Args),
+ TheLogDir = which(logdir, Opts#opts.logdir),
+ case check_and_install_configfiles(InitConfig,
+ TheLogDir,
+ Opts) of
ok -> % go on read tests from start flags
script_start3(Opts#opts{config=InitConfig,
logdir=TheLogDir}, Args);
Error ->
Error
- end;
- {_,_} -> % testspec used
- %% merge config from start flags with config from testspec
- AllConfig = merge_vals([InitConfig, Opts#opts.config]),
- case check_and_install_configfiles(AllConfig, TheLogDir, Opts) of
- ok -> % read tests from spec
- {Run,Skip} = ct_testspec:prepare_tests(Terms, node()),
- do_run(Run, Skip, Opts#opts{config=AllConfig,
- logdir=TheLogDir}, Args);
- Error ->
- Error
end
end;
-script_start2(StartOpts, Args) ->
+script_start2(Opts, Args) ->
%% read config/userconfig from start flags
InitConfig = ct_config:prepare_config_list(Args),
- LogDir = which(logdir, StartOpts#opts.logdir),
- case check_and_install_configfiles(InitConfig, LogDir, StartOpts) of
+ LogDir = which(logdir, Opts#opts.logdir),
+ case check_and_install_configfiles(InitConfig, LogDir, Opts) of
ok -> % go on read tests from start flags
- script_start3(StartOpts#opts{config=InitConfig,
- logdir=LogDir}, Args);
+ script_start3(Opts#opts{config=InitConfig,
+ logdir=LogDir}, Args);
+ Error ->
+ Error
+ end.
+
+execute_all_specs([], _, _, Result) ->
+ Result1 = lists:reverse(Result),
+ case lists:keysearch('EXIT', 1, Result1) of
+ {value,{_,_,ExitReason}} ->
+ exit(ExitReason);
+ false ->
+ case lists:keysearch(error, 1, Result1) of
+ {value,Error} ->
+ Error;
+ false ->
+ lists:foldl(fun({Ok,Fail,{UserSkip,AutoSkip}},
+ {Ok1,Fail1,{UserSkip1,AutoSkip1}}) ->
+ {Ok1+Ok,Fail1+Fail,
+ {UserSkip1+UserSkip,
+ AutoSkip1+AutoSkip}}
+ end, {0,0,{0,0}}, Result1)
+ end
+ end;
+
+execute_all_specs([{Specs,TS} | TSs], Opts, Args, Result) ->
+ CombinedOpts = combine_test_opts(TS, Specs, Opts),
+ try execute_one_spec(TS, CombinedOpts, Args) of
+ ExecResult ->
+ execute_all_specs(TSs, Opts, Args, [ExecResult|Result])
+ catch
+ _ : ExitReason ->
+ execute_all_specs(TSs, Opts, Args,
+ [{'EXIT',self(),ExitReason}|Result])
+ end.
+
+execute_one_spec(TS, Opts, Args) ->
+ %% read config/userconfig from start flags
+ InitConfig = ct_config:prepare_config_list(Args),
+ TheLogDir = which(logdir, Opts#opts.logdir),
+ %% merge config from start flags with config from testspec
+ AllConfig = merge_vals([InitConfig, Opts#opts.config]),
+ case check_and_install_configfiles(AllConfig, TheLogDir, Opts) of
+ ok -> % read tests from spec
+ {Run,Skip} = ct_testspec:prepare_tests(TS, node()),
+ do_run(Run, Skip, Opts#opts{config=AllConfig,
+ logdir=TheLogDir}, Args);
Error ->
Error
end.
+combine_test_opts(TS, Specs, Opts) ->
+ TSOpts = get_data_for_node(TS, node()),
+
+ Label = choose_val(Opts#opts.label,
+ TSOpts#opts.label),
+
+ Profile = choose_val(Opts#opts.profile,
+ TSOpts#opts.profile),
+
+ LogDir = choose_val(Opts#opts.logdir,
+ TSOpts#opts.logdir),
+
+ AllLogOpts = merge_vals([Opts#opts.logopts,
+ TSOpts#opts.logopts]),
+ AllVerbosity =
+ merge_keyvals([Opts#opts.verbosity,
+ TSOpts#opts.verbosity]),
+ AllSilentConns =
+ merge_vals([Opts#opts.silent_connections,
+ TSOpts#opts.silent_connections]),
+ Cover =
+ choose_val(Opts#opts.cover,
+ TSOpts#opts.cover),
+ CoverStop =
+ choose_val(Opts#opts.cover_stop,
+ TSOpts#opts.cover_stop),
+ MultTT =
+ choose_val(Opts#opts.multiply_timetraps,
+ TSOpts#opts.multiply_timetraps),
+ ScaleTT =
+ choose_val(Opts#opts.scale_timetraps,
+ TSOpts#opts.scale_timetraps),
+
+ CreatePrivDir =
+ choose_val(Opts#opts.create_priv_dir,
+ TSOpts#opts.create_priv_dir),
+
+ AllEvHs =
+ merge_vals([Opts#opts.event_handlers,
+ TSOpts#opts.event_handlers]),
+
+ AllCTHooks = merge_vals(
+ [Opts#opts.ct_hooks,
+ TSOpts#opts.ct_hooks]),
+
+ EnableBuiltinHooks =
+ choose_val(
+ Opts#opts.enable_builtin_hooks,
+ TSOpts#opts.enable_builtin_hooks),
+
+ Stylesheet =
+ choose_val(Opts#opts.stylesheet,
+ TSOpts#opts.stylesheet),
+
+ AllInclude = merge_vals([Opts#opts.include,
+ TSOpts#opts.include]),
+ application:set_env(common_test, include, AllInclude),
+
+ AutoCompile =
+ case choose_val(Opts#opts.auto_compile,
+ TSOpts#opts.auto_compile) of
+ undefined ->
+ true;
+ ACBool ->
+ application:set_env(common_test,
+ auto_compile,
+ ACBool),
+ ACBool
+ end,
+
+ BasicHtml =
+ case choose_val(Opts#opts.basic_html,
+ TSOpts#opts.basic_html) of
+ undefined ->
+ false;
+ BHBool ->
+ application:set_env(common_test, basic_html,
+ BHBool),
+ BHBool
+ end,
+
+ Opts#opts{label = Label,
+ profile = Profile,
+ testspecs = Specs,
+ cover = Cover,
+ cover_stop = CoverStop,
+ logdir = which(logdir, LogDir),
+ logopts = AllLogOpts,
+ basic_html = BasicHtml,
+ verbosity = AllVerbosity,
+ silent_connections = AllSilentConns,
+ config = TSOpts#opts.config,
+ event_handlers = AllEvHs,
+ ct_hooks = AllCTHooks,
+ enable_builtin_hooks = EnableBuiltinHooks,
+ stylesheet = Stylesheet,
+ auto_compile = AutoCompile,
+ include = AllInclude,
+ multiply_timetraps = MultTT,
+ scale_timetraps = ScaleTT,
+ create_priv_dir = CreatePrivDir}.
+
check_and_install_configfiles(
Configs, LogDir, #opts{
event_handlers = EvHandlers,
@@ -562,12 +594,12 @@ check_and_install_configfiles(
{error,{cant_load_callback_module,Info}}
end.
-script_start3(StartOpts, Args) ->
- StartOpts1 = get_start_opt(step,
- fun(Step) ->
- StartOpts#opts{step = Step,
- cover = undefined}
- end, StartOpts, Args),
+script_start3(Opts, Args) ->
+ Opts1 = get_start_opt(step,
+ fun(Step) ->
+ Opts#opts{step = Step,
+ cover = undefined}
+ end, Opts, Args),
case {proplists:get_value(dir, Args),
proplists:get_value(suite, Args),
groups_and_cases(proplists:get_value(group, Args),
@@ -581,17 +613,17 @@ script_start3(StartOpts, Args) ->
{error,no_dir_specified};
{Dirs,undefined,[]} when is_list(Dirs) ->
- script_start4(StartOpts#opts{tests = tests(Dirs)}, Args);
+ script_start4(Opts#opts{tests = tests(Dirs)}, Args);
{undefined,Suites,[]} when is_list(Suites) ->
Ts = tests([suite_to_test(S) || S <- Suites]),
- script_start4(StartOpts1#opts{tests = Ts}, Args);
+ script_start4(Opts1#opts{tests = Ts}, Args);
{undefined,Suite,GsAndCs} when is_list(Suite) ->
case [suite_to_test(S) || S <- Suite] of
DirMods = [_] ->
Ts = tests(DirMods, GsAndCs),
- script_start4(StartOpts1#opts{tests = Ts}, Args);
+ script_start4(Opts1#opts{tests = Ts}, Args);
[_,_|_] ->
{error,multiple_suites_and_cases};
_ ->
@@ -605,10 +637,10 @@ script_start3(StartOpts, Args) ->
case [suite_to_test(Dir,S) || S <- Suite] of
DirMods when GsAndCs == [] ->
Ts = tests(DirMods),
- script_start4(StartOpts1#opts{tests = Ts}, Args);
+ script_start4(Opts1#opts{tests = Ts}, Args);
DirMods = [_] when GsAndCs /= [] ->
Ts = tests(DirMods, GsAndCs),
- script_start4(StartOpts1#opts{tests = Ts}, Args);
+ script_start4(Opts1#opts{tests = Ts}, Args);
[_,_|_] when GsAndCs /= [] ->
{error,multiple_suites_and_cases};
_ ->
@@ -619,8 +651,8 @@ script_start3(StartOpts, Args) ->
{error,incorrect_start_options};
{undefined,undefined,_} ->
- if StartOpts#opts.vts ; StartOpts#opts.shell ->
- script_start4(StartOpts#opts{tests = []}, Args);
+ if Opts#opts.vts ; Opts#opts.shell ->
+ script_start4(Opts#opts{tests = []}, Args);
true ->
script_usage(),
{error,missing_start_options}
@@ -750,6 +782,7 @@ script_usage() ->
"\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]"
"\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]"
"\n\t[-allow_user_terms]"
+ "\n\t[-join_specs]"
"\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]"
"\n\t[-stylesheet CSSFile]"
"\n\t[-cover CoverCfgFile]"
@@ -848,7 +881,7 @@ run_test1(StartOpts) when is_list(StartOpts) ->
undefined ->
Tracing = start_trace(StartOpts),
{ok,Cwd} = file:get_cwd(),
- io:format("~nCommon Test starting (cwd is ~s)~n~n", [Cwd]),
+ io:format("~nCommon Test starting (cwd is ~ts)~n~n", [Cwd]),
Res =
case ct_repeat:loop_test(func, StartOpts) of
false ->
@@ -1044,105 +1077,60 @@ run_test2(StartOpts) ->
end.
run_spec_file(Relaxed,
- Opts = #opts{testspecs = Specs, config = CfgFiles},
+ Opts = #opts{testspecs = Specs},
StartOpts) ->
Specs1 = case Specs of
[X|_] when is_integer(X) -> [Specs];
_ -> Specs
end,
AbsSpecs = lists:map(fun(SF) -> ?abs(SF) end, Specs1),
- log_ts_names(AbsSpecs),
- case catch ct_testspec:collect_tests_from_file(AbsSpecs, Relaxed) of
+ AbsSpecs1 = get_start_opt(join_specs, [AbsSpecs], AbsSpecs, StartOpts),
+ case catch ct_testspec:collect_tests_from_file(AbsSpecs1, Relaxed) of
{Error,CTReason} when Error == error ; Error == 'EXIT' ->
exit({error,CTReason});
- TS ->
- SpecOpts = get_data_for_node(TS, node()),
- Label = choose_val(Opts#opts.label,
- SpecOpts#opts.label),
- Profile = choose_val(Opts#opts.profile,
- SpecOpts#opts.profile),
- LogDir = choose_val(Opts#opts.logdir,
- SpecOpts#opts.logdir),
- AllLogOpts = merge_vals([Opts#opts.logopts,
- SpecOpts#opts.logopts]),
- Stylesheet = choose_val(Opts#opts.stylesheet,
- SpecOpts#opts.stylesheet),
- AllVerbosity = merge_keyvals([Opts#opts.verbosity,
- SpecOpts#opts.verbosity]),
- AllSilentConns = merge_vals([Opts#opts.silent_connections,
- SpecOpts#opts.silent_connections]),
- AllConfig = merge_vals([CfgFiles, SpecOpts#opts.config]),
- Cover = choose_val(Opts#opts.cover,
- SpecOpts#opts.cover),
- CoverStop = choose_val(Opts#opts.cover_stop,
- SpecOpts#opts.cover_stop),
- MultTT = choose_val(Opts#opts.multiply_timetraps,
- SpecOpts#opts.multiply_timetraps),
- ScaleTT = choose_val(Opts#opts.scale_timetraps,
- SpecOpts#opts.scale_timetraps),
- CreatePrivDir = choose_val(Opts#opts.create_priv_dir,
- SpecOpts#opts.create_priv_dir),
- AllEvHs = merge_vals([Opts#opts.event_handlers,
- SpecOpts#opts.event_handlers]),
- AllInclude = merge_vals([Opts#opts.include,
- SpecOpts#opts.include]),
- AllCTHooks = merge_vals([Opts#opts.ct_hooks,
- SpecOpts#opts.ct_hooks]),
- EnableBuiltinHooks = choose_val(Opts#opts.enable_builtin_hooks,
- SpecOpts#opts.enable_builtin_hooks),
-
- application:set_env(common_test, include, AllInclude),
-
- AutoCompile = case choose_val(Opts#opts.auto_compile,
- SpecOpts#opts.auto_compile) of
- undefined ->
- true;
- ACBool ->
- application:set_env(common_test, auto_compile,
- ACBool),
- ACBool
- end,
+ TestSpecData ->
+ run_all_specs(TestSpecData, Opts, StartOpts, [])
+ end.
- BasicHtml = case choose_val(Opts#opts.basic_html,
- SpecOpts#opts.basic_html) of
- undefined ->
- false;
- BHBool ->
- application:set_env(common_test, basic_html,
- BHBool),
- BHBool
- end,
-
- Opts1 = Opts#opts{label = Label,
- profile = Profile,
- cover = Cover,
- cover_stop = CoverStop,
- logdir = which(logdir, LogDir),
- logopts = AllLogOpts,
- stylesheet = Stylesheet,
- basic_html = BasicHtml,
- verbosity = AllVerbosity,
- silent_connections = AllSilentConns,
- config = AllConfig,
- event_handlers = AllEvHs,
- auto_compile = AutoCompile,
- include = AllInclude,
- testspecs = AbsSpecs,
- multiply_timetraps = MultTT,
- scale_timetraps = ScaleTT,
- create_priv_dir = CreatePrivDir,
- ct_hooks = AllCTHooks,
- enable_builtin_hooks = EnableBuiltinHooks
- },
-
- case check_and_install_configfiles(AllConfig,Opts1#opts.logdir,
- Opts1) of
- ok ->
- {Run,Skip} = ct_testspec:prepare_tests(TS, node()),
- reformat_result(catch do_run(Run, Skip, Opts1, StartOpts));
- {error,GCFReason} ->
- exit({error,GCFReason})
+run_all_specs([], _, _, TotResult) ->
+ TotResult1 = lists:reverse(TotResult),
+ case lists:keysearch('EXIT', 1, TotResult1) of
+ {value,{_,_,ExitReason}} ->
+ exit(ExitReason);
+ false ->
+ case lists:keysearch(error, 1, TotResult1) of
+ {value,Error} ->
+ Error;
+ false ->
+ lists:foldl(fun({Ok,Fail,{UserSkip,AutoSkip}},
+ {Ok1,Fail1,{UserSkip1,AutoSkip1}}) ->
+ {Ok1+Ok,Fail1+Fail,
+ {UserSkip1+UserSkip,
+ AutoSkip1+AutoSkip}}
+ end, {0,0,{0,0}}, TotResult1)
end
+ end;
+
+run_all_specs([{Specs,TS} | TSs], Opts, StartOpts, TotResult) ->
+ log_ts_names(Specs),
+ Combined = #opts{config = TSConfig} = combine_test_opts(TS, Specs, Opts),
+ AllConfig = merge_vals([Opts#opts.config, TSConfig]),
+ try run_one_spec(TS, Combined#opts{config = AllConfig}, StartOpts) of
+ Result ->
+ run_all_specs(TSs, Opts, StartOpts, [Result | TotResult])
+ catch
+ _ : Reason ->
+ run_all_specs(TSs, Opts, StartOpts, [{error,Reason} | TotResult])
+ end.
+
+run_one_spec(TS, CombinedOpts, StartOpts) ->
+ #opts{logdir = Logdir, config = Config} = CombinedOpts,
+ case check_and_install_configfiles(Config, Logdir, CombinedOpts) of
+ ok ->
+ {Run,Skip} = ct_testspec:prepare_tests(TS, node()),
+ reformat_result(catch do_run(Run, Skip, CombinedOpts, StartOpts));
+ Error ->
+ Error
end.
run_prepared(Run, Skip, Opts = #opts{logdir = LogDir,
@@ -1332,7 +1320,7 @@ run_testspec(TestSpec) ->
run_testspec1(TestSpec) ->
{ok,Cwd} = file:get_cwd(),
- io:format("~nCommon Test starting (cwd is ~s)~n~n", [Cwd]),
+ io:format("~nCommon Test starting (cwd is ~ts)~n~n", [Cwd]),
case catch run_testspec2(TestSpec) of
{'EXIT',Reason} ->
file:set_cwd(Cwd),
@@ -1469,7 +1457,7 @@ refresh_logs(LogDir) ->
{error,{all_runs_index,ARReason}};
_ ->
file:set_cwd(Cwd),
- io:format("Logs in ~s refreshed!~n",[LogDir]),
+ io:format("Logs in ~ts refreshed!~n",[LogDir]),
ok
end
end
@@ -1792,7 +1780,7 @@ possibly_spawn(true, Tests, Skip, Opts) ->
end,
unlink(CTUtilSrv),
SupPid = spawn(Supervisor),
- io:format(user, "~nTest control handed over to process ~p~n~n",
+ io:format(user, "~nTest control handed over to process ~w~n~n",
[SupPid]),
SupPid.
@@ -1880,7 +1868,7 @@ verify_suites(TestSuites) ->
Suite)),
io:format(user,
"Suite ~w not found"
- "in directory ~s~n",
+ "in directory ~ts~n",
[Suite,TestDir]),
{Found,[{DS,[Name]}|NotFound]}
end
@@ -1895,7 +1883,7 @@ verify_suites(TestSuites) ->
ActualDir = filename:dirname(SuiteFile),
{[{ActualDir,Suite}|Found],NotFound};
false ->
- io:format(user, "Directory ~s is "
+ io:format(user, "Directory ~ts is "
"invalid~n", [Dir]),
Name = filename:join(Dir, atom_to_list(Suite)),
{Found,[{DS,[Name]}|NotFound]}
@@ -2135,7 +2123,7 @@ do_run_test(Tests, Skip, Opts) ->
cross = CovCross,
src = _CovSrc}} ->
ct_logs:log("COVER INFO",
- "Using cover specification file: ~s~n"
+ "Using cover specification file: ~ts~n"
"App: ~w~n"
"Cross cover: ~w~n"
"Including ~w modules~n"
@@ -2150,7 +2138,7 @@ do_run_test(Tests, Skip, Opts) ->
DelResult = file:delete(CovExport),
ct_logs:log("COVER INFO",
"Warning! "
- "Export file ~s already exists. "
+ "Export file ~ts already exists. "
"Deleting with result: ~p",
[CovExport,DelResult]);
false ->
@@ -2632,7 +2620,7 @@ log_ts_names(Specs) ->
List = lists:map(fun(Name) ->
Name ++ " "
end, Specs),
- ct_logs:log("Test Specification file(s)", "~s",
+ ct_logs:log("Test Specification file(s)", "~ts",
[lists:flatten(List)]).
merge_arguments(Args) ->
@@ -2743,10 +2731,10 @@ event_handler_args2opts(Default, Args) ->
event_handler_init_args2opts(EHs)
end.
event_handler_init_args2opts([EH, Arg, "and" | EHs]) ->
- [{list_to_atom(EH),lists:flatten(io_lib:format("~s",[Arg]))} |
+ [{list_to_atom(EH),lists:flatten(io_lib:format("~ts",[Arg]))} |
event_handler_init_args2opts(EHs)];
event_handler_init_args2opts([EH, Arg]) ->
- [{list_to_atom(EH),lists:flatten(io_lib:format("~s",[Arg]))}];
+ [{list_to_atom(EH),lists:flatten(io_lib:format("~ts",[Arg]))}];
event_handler_init_args2opts([]) ->
[].
@@ -2896,6 +2884,10 @@ opts2args(EnvStartOpts) ->
[{allow_user_terms,[]}];
({allow_user_terms,false}) ->
[];
+ ({join_specs,true}) ->
+ [{join_specs,[]}];
+ ({join_specs,false}) ->
+ [];
({auto_compile,false}) ->
[{no_auto_compile,[]}];
({auto_compile,true}) ->
@@ -3064,7 +3056,7 @@ start_trace(Args) ->
false
end;
{_,Error} ->
- io:format("Warning! Tracing not started. Reason: ~s~n~n",
+ io:format("Warning! Tracing not started. Reason: ~ts~n~n",
[file:format_error(Error)]),
false
end;
diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl
index b13c050e32..02186864a5 100644
--- a/lib/common_test/src/ct_telnet.erl
+++ b/lib/common_test/src/ct_telnet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-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
@@ -201,7 +201,7 @@ open(KeyOrName,ConnType,TargetMod,Extra) ->
close(Connection) ->
case get_handle(Connection) of
{ok,Pid} ->
- log("ct_telnet:close","Handle: ~p",[Pid]),
+ log("ct_telnet:close","Handle: ~w",[Pid]),
case ct_gen_conn:stop(Pid) of
{error,{process_down,Pid,noproc}} ->
{error,already_closed};
@@ -558,7 +558,7 @@ reconnect(Ip,Port,N,State=#state{target_mod=TargetMod,
Error when N==0 ->
Error;
_Error ->
- log("Reconnect failed!","Retries left: ~p",[N]),
+ log("Reconnect failed!","Retries left: ~w",[N]),
timer:sleep(ReconnInt),
reconnect(Ip,Port,N-1,State)
end.
@@ -567,7 +567,7 @@ reconnect(Ip,Port,N,State=#state{target_mod=TargetMod,
%% @hidden
terminate(TelnPid,State) ->
log(heading(terminate,State#state.name),
- "Closing telnet connection.\nId: ~p",
+ "Closing telnet connection.\nId: ~w",
[TelnPid]),
ct_telnet_client:close(TelnPid).
@@ -899,7 +899,7 @@ one_expect(Data,Pattern,EO) ->
[Prompt] when Prompt==prompt; Prompt=={prompt,PromptType} ->
%% Only searching for prompt
log_lines(UptoPrompt),
- try_cont_log("<b>PROMPT:</b> ~s", [PromptType]),
+ try_cont_log("<b>PROMPT:</b> ~ts", [PromptType]),
{match,{prompt,PromptType},Rest};
[{prompt,_OtherPromptType}] ->
%% Only searching for one specific prompt, not thisone
@@ -969,7 +969,7 @@ seq_expect1(Data,[prompt|Patterns],Acc,Rest,EO) ->
{continue,[prompt|Patterns],Acc,LastLine};
PromptType ->
log_lines(Data),
- try_cont_log("<b>PROMPT:</b> ~s", [PromptType]),
+ try_cont_log("<b>PROMPT:</b> ~ts", [PromptType]),
seq_expect(Rest,Patterns,[{prompt,PromptType}|Acc],EO)
end;
seq_expect1(Data,[{prompt,PromptType}|Patterns],Acc,Rest,EO) ->
@@ -980,7 +980,7 @@ seq_expect1(Data,[{prompt,PromptType}|Patterns],Acc,Rest,EO) ->
{continue,[{prompt,PromptType}|Patterns],Acc,LastLine};
PromptType ->
log_lines(Data),
- try_cont_log("<b>PROMPT:</b> ~s", [PromptType]),
+ try_cont_log("<b>PROMPT:</b> ~ts", [PromptType]),
seq_expect(Rest,Patterns,[{prompt,PromptType}|Acc],EO);
_OtherPromptType ->
log_lines(Data),
@@ -1032,13 +1032,13 @@ match_line(Line,Patterns,FoundPrompt,EO) ->
match_line(Line,[prompt|Patterns],false,EO,RetTag) ->
match_line(Line,Patterns,false,EO,RetTag);
match_line(Line,[prompt|_Patterns],FoundPrompt,_EO,RetTag) ->
- try_cont_log(" ~s", [Line]),
- try_cont_log("<b>PROMPT:</b> ~s", [FoundPrompt]),
+ try_cont_log(" ~ts", [Line]),
+ try_cont_log("<b>PROMPT:</b> ~ts", [FoundPrompt]),
{RetTag,{prompt,FoundPrompt}};
match_line(Line,[{prompt,PromptType}|_Patterns],FoundPrompt,_EO,RetTag)
when PromptType==FoundPrompt ->
- try_cont_log(" ~s", [Line]),
- try_cont_log("<b>PROMPT:</b> ~s", [FoundPrompt]),
+ try_cont_log(" ~ts", [Line]),
+ try_cont_log("<b>PROMPT:</b> ~ts", [FoundPrompt]),
{RetTag,{prompt,FoundPrompt}};
match_line(Line,[{prompt,PromptType}|Patterns],FoundPrompt,EO,RetTag)
when PromptType=/=FoundPrompt ->
@@ -1048,7 +1048,7 @@ match_line(Line,[{Tag,Pattern}|Patterns],FoundPrompt,EO,RetTag) ->
nomatch ->
match_line(Line,Patterns,FoundPrompt,EO,RetTag);
{match,Match} ->
- try_cont_log("<b>MATCH:</b> ~s", [Line]),
+ try_cont_log("<b>MATCH:</b> ~ts", [Line]),
{RetTag,{Tag,Match}}
end;
match_line(Line,[Pattern|Patterns],FoundPrompt,EO,RetTag) ->
@@ -1056,13 +1056,13 @@ match_line(Line,[Pattern|Patterns],FoundPrompt,EO,RetTag) ->
nomatch ->
match_line(Line,Patterns,FoundPrompt,EO,RetTag);
{match,Match} ->
- try_cont_log("<b>MATCH:</b> ~s", [Line]),
+ try_cont_log("<b>MATCH:</b> ~ts", [Line]),
{RetTag,Match}
end;
match_line(Line,[],FoundPrompt,EO,match) ->
match_line(Line,EO#eo.haltpatterns,FoundPrompt,EO,halt);
match_line(Line,[],_FoundPrompt,_EO,halt) ->
- try_cont_log(" ~s", [Line]),
+ try_cont_log(" ~ts", [Line]),
nomatch.
one_line([$\n|Rest],Line) ->
@@ -1086,7 +1086,7 @@ log_lines(String) ->
[] ->
ok;
LastLine ->
- try_cont_log(" ~s", [LastLine])
+ try_cont_log(" ~ts", [LastLine])
end.
log_lines_not_last(String) ->
@@ -1094,7 +1094,7 @@ log_lines_not_last(String) ->
{[],LastLine} ->
LastLine;
{String1,LastLine} ->
- try_cont_log("~s",[String1]),
+ try_cont_log("~ts",[String1]),
LastLine
end.
diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl
index d703b39ac5..7329498ed6 100644
--- a/lib/common_test/src/ct_telnet_client.erl
+++ b/lib/common_test/src/ct_telnet_client.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. 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
@@ -308,7 +308,7 @@ cmd_dbg(_Cmd) ->
[Opt] -> Opt;
_ -> Opts
end,
- io:format("~s(~w): ~w\n", [CtrlStr,Ctrl,Opts1]);
+ io:format("~ts(~w): ~w\n", [CtrlStr,Ctrl,Opts1]);
Any ->
io:format("Unexpected in cmd_dbg:~n~w~n",[Any])
end.
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index 202d8f9373..e341391a91 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -28,7 +28,6 @@
collect_tests_from_file/2, collect_tests_from_file/3]).
-include("ct_util.hrl").
-
-define(testspec_fields, record_info(fields, testspec)).
%%%------------------------------------------------------------------
@@ -93,7 +92,7 @@ prepare_tests(TestSpec) when is_record(TestSpec,testspec) ->
%% run_per_node/2 takes the Run list as input and returns a list
%% of {Node,RunPerNode,[]} tuples where the tests have been sorted
%% on a per node basis.
-run_per_node([{{Node,Dir},Test}|Ts],Result, MergeTests) ->
+run_per_node([{{Node,Dir},Test}|Ts],Result,MergeTests) ->
{value,{Node,{Run,Skip}}} = lists:keysearch(Node,1,Result),
Run1 = case MergeTests of
false ->
@@ -190,7 +189,7 @@ prepare_suites(_Node,_Dir,[],Run,Skip) ->
prepare_cases(Node,Dir,Suite,Cases) ->
case get_skipped_cases(Node,Dir,Suite,Cases) of
- SkipAll=[{{Node,Dir},{Suite,_Cmt}}] -> % all cases to be skipped
+ SkipAll=[{{Node,Dir},{Suite,_Cmt}}] -> % all cases to be skipped
%% note: this adds an 'all' test even if only skip is specified
{[{{Node,Dir},{Suite,all}}],SkipAll};
Skipped ->
@@ -241,34 +240,147 @@ get_skipped_cases1(_,_,_,[]) ->
%%% collect_tests_from_file reads a testspec file and returns a record
%%% containing the data found.
-collect_tests_from_file(Specs, Relaxed) ->
+collect_tests_from_file(Specs,Relaxed) ->
collect_tests_from_file(Specs,[node()],Relaxed).
collect_tests_from_file(Specs,Nodes,Relaxed) when is_list(Nodes) ->
NodeRefs = lists:map(fun(N) -> {undefined,N} end, Nodes),
- catch collect_tests_from_file1(Specs,#testspec{nodes=NodeRefs},Relaxed).
+ %% [Spec1,Spec2,...] means create one testpec record per Spec file
+ %% [[Spec1,Spec2,...]] means merge all specs into one testspec record
+ {Join,Specs1} = if is_list(hd(hd(Specs))) -> {true,hd(Specs)};
+ true -> {false,Specs}
+ end,
+ Specs2 = [filename:absname(S) || S <- Specs1],
+ TS0 = #testspec{nodes=NodeRefs},
+
+ try create_specs(Specs2,TS0,Relaxed,Join) of
+ {{[],_},SeparateTestSpecs} ->
+ filter_and_convert(SeparateTestSpecs);
+ {{_,#testspec{tests=[]}},SeparateTestSpecs} ->
+ filter_and_convert(SeparateTestSpecs);
+ {Joined,SeparateTestSpecs} ->
+ [filter_and_convert(Joined) |
+ filter_and_convert(SeparateTestSpecs)]
+ catch
+ _:Error ->
+ Error
+ end.
+
+filter_and_convert(Joined) when is_tuple(Joined) ->
+ hd(filter_and_convert([Joined]));
+filter_and_convert([{_,#testspec{tests=[]}}|TSs]) ->
+ filter_and_convert(TSs);
+filter_and_convert([{[{SpecFile,MergeTests}|SMs],TestSpec}|TSs]) ->
+ #testspec{config = CfgFiles} = TestSpec,
+ TestSpec1 = TestSpec#testspec{config = delete_dups(CfgFiles),
+ merge_tests = MergeTests},
+ %% set the merge_tests value for the testspec to the value
+ %% of the first test spec in the set
+ [{[SpecFile | [SF || {SF,_} <- SMs]], TestSpec1} | filter_and_convert(TSs)];
+filter_and_convert([]) ->
+ [].
+
+delete_dups(Elems) ->
+ delete_dups1(lists:reverse(Elems),[]).
+
+delete_dups1([E|Es],Keep) ->
+ case lists:member(E,Es) of
+ true ->
+ delete_dups1(Es,Keep);
+ false ->
+ delete_dups1(Es,[E|Keep])
+ end;
+delete_dups1([],Keep) ->
+ Keep.
+
+create_specs(Specs,TestSpec,Relaxed,Join) ->
+ SpecsTree = create_spec_tree(Specs,TestSpec,Join,[]),
+ create_specs(SpecsTree,TestSpec,Relaxed).
-collect_tests_from_file1([Spec|Specs],TestSpec,Relaxed) ->
+create_spec_tree([Spec|Specs],TS,JoinWithNext,Known) ->
SpecDir = filename:dirname(filename:absname(Spec)),
- case file:consult(Spec) of
- {ok,Terms} ->
- case collect_tests(Terms,
- TestSpec#testspec{spec_dir=SpecDir},
- Relaxed) of
- TS = #testspec{tests=Tests, logdir=LogDirs} when Specs == [] ->
- LogDirs1 = lists:delete(".",LogDirs) ++ ["."],
- TS#testspec{tests=lists:flatten(Tests), logdir=LogDirs1};
- TS = #testspec{alias = As, nodes = Ns} ->
- TS1 = TS#testspec{alias = lists:reverse(As),
- nodes = lists:reverse(Ns)},
- collect_tests_from_file1(Specs,TS1,Relaxed)
- end;
- {error,Reason} ->
- ReasonStr =
- lists:flatten(io_lib:format("~s",
- [file:format_error(Reason)])),
- throw({error,{Spec,ReasonStr}})
- end.
+ TS1 = TS#testspec{spec_dir=SpecDir},
+ SpecAbsName = get_absfile(Spec,TS1),
+ case lists:member(SpecAbsName,Known) of
+ true ->
+ throw({error,{cyclic_reference,SpecAbsName}});
+ false ->
+ case file:consult(SpecAbsName) of
+ {ok,Terms} ->
+ Terms1 = replace_names(Terms),
+ {InclJoin,InclSep} = get_included_specs(Terms1,TS1),
+ {SpecAbsName,Terms1,
+ create_spec_tree(InclJoin,TS,true,[SpecAbsName|Known]),
+ create_spec_tree(InclSep,TS,false,[SpecAbsName|Known]),
+ JoinWithNext,
+ create_spec_tree(Specs,TS,JoinWithNext,Known)};
+ {error,Reason} ->
+ ReasonStr =
+ lists:flatten(io_lib:format("~s",
+ [file:format_error(Reason)])),
+ throw({error,{SpecAbsName,ReasonStr}})
+ end
+ end;
+create_spec_tree([],_TS,_JoinWithNext,_Known) ->
+ [].
+
+create_specs({Spec,Terms,InclJoin,InclSep,JoinWithNext,NextSpec},
+ TestSpec,Relaxed) ->
+ SpecDir = filename:dirname(filename:absname(Spec)),
+ TestSpec1 = create_spec(Terms,TestSpec#testspec{spec_dir=SpecDir},
+ JoinWithNext,Relaxed),
+
+ {{JoinSpecs1,JoinTS1},Separate1} = create_specs(InclJoin,TestSpec1,Relaxed),
+
+ {{JoinSpecs2,JoinTS2},Separate2} =
+ case JoinWithNext of
+ true ->
+ create_specs(NextSpec,JoinTS1,Relaxed);
+ false ->
+ {{[],JoinTS1},[]}
+ end,
+ {SepJoinSpecs,Separate3} = create_specs(InclSep,TestSpec,Relaxed),
+ {SepJoinSpecs1,Separate4} =
+ case JoinWithNext of
+ true ->
+ {{[],TestSpec},[]};
+ false ->
+ create_specs(NextSpec,TestSpec,Relaxed)
+ end,
+
+ SpecInfo = {Spec,TestSpec1#testspec.merge_tests},
+ AllSeparate =
+ [TSData || TSData = {Ss,_TS} <- Separate3++Separate1++
+ [SepJoinSpecs]++Separate2++
+ [SepJoinSpecs1]++Separate4,
+ Ss /= []],
+
+ case {JoinWithNext,JoinSpecs1} of
+ {true,_} ->
+ {{[SpecInfo|(JoinSpecs1++JoinSpecs2)],JoinTS2},
+ AllSeparate};
+ {false,[]} ->
+ {{[],TestSpec},
+ [{[SpecInfo],TestSpec1}|AllSeparate]};
+ {false,_} ->
+ {{[SpecInfo|(JoinSpecs1++JoinSpecs2)],JoinTS2},
+ AllSeparate}
+ end;
+create_specs([],TestSpec,_Relaxed) ->
+ {{[],TestSpec},[]}.
+
+create_spec(Terms,TestSpec,JoinedByPrev,Relaxed) ->
+ %% it's the "includer" that decides the value of merge_tests
+ Terms1 = if not JoinedByPrev ->
+ [{set_merge_tests,true}|Terms];
+ true ->
+ [{set_merge_tests,false}|Terms]
+ end,
+ TS = #testspec{tests=Tests, logdir=LogDirs} =
+ collect_tests({false,Terms1},TestSpec,Relaxed),
+ LogDirs1 = lists:delete(".",LogDirs) ++ ["."],
+ TS#testspec{tests=lists:flatten(Tests),
+ logdir=LogDirs1}.
collect_tests_from_list(Terms,Relaxed) ->
collect_tests_from_list(Terms,[node()],Relaxed).
@@ -276,8 +388,8 @@ collect_tests_from_list(Terms,Relaxed) ->
collect_tests_from_list(Terms,Nodes,Relaxed) when is_list(Nodes) ->
{ok,Cwd} = file:get_cwd(),
NodeRefs = lists:map(fun(N) -> {undefined,N} end, Nodes),
- case catch collect_tests(Terms,#testspec{nodes=NodeRefs,
- spec_dir=Cwd},
+ case catch collect_tests({true,Terms},#testspec{nodes=NodeRefs,
+ spec_dir=Cwd},
Relaxed) of
E = {error,_} ->
E;
@@ -287,13 +399,28 @@ collect_tests_from_list(Terms,Nodes,Relaxed) when is_list(Nodes) ->
TS#testspec{tests=lists:flatten(Tests), logdir=LogDirs1}
end.
-collect_tests(Terms,TestSpec,Relaxed) ->
+collect_tests({Replace,Terms},TestSpec=#testspec{alias=As,nodes=Ns},Relaxed) ->
put(relaxed,Relaxed),
- Terms1 = replace_names(Terms),
- TestSpec1 = get_global(Terms1,TestSpec),
- TestSpec2 = get_all_nodes(Terms1,TestSpec1),
- {Terms2, TestSpec3} = filter_init_terms(Terms1, [], TestSpec2),
- add_tests(Terms2,TestSpec3).
+ Terms1 = if Replace -> replace_names(Terms);
+ true -> Terms
+ end,
+ {MergeTestsDef,Terms2} =
+ case proplists:get_value(set_merge_tests,Terms1,true) of
+ false ->
+ %% disable merge_tests
+ {TestSpec#testspec.merge_tests,
+ proplists:delete(merge_tests,Terms1)};
+ true ->
+ {true,Terms1}
+ end,
+ %% reverse nodes and aliases initially to get the order of them right
+ %% in case this spec is being joined with a previous one
+ TestSpec1 = get_global(Terms2,TestSpec#testspec{alias = lists:reverse(As),
+ nodes = lists:reverse(Ns),
+ merge_tests = MergeTestsDef}),
+ TestSpec2 = get_all_nodes(Terms2,TestSpec1),
+ {Terms3, TestSpec3} = filter_init_terms(Terms2, [], TestSpec2),
+ add_tests(Terms3,TestSpec3).
%% replace names (atoms) in the testspec matching those in 'define' terms by
%% searching recursively through tuples and lists
@@ -420,9 +547,30 @@ replace_names_in_node1(NodeStr,Defs=[{Name,Replacement}|Ds]) ->
replace_names_in_node1(NodeStr,[]) ->
NodeStr.
+%% look for other specification files, either to join with the
+%% current spec, or execute as separate test runs
+get_included_specs(Terms,TestSpec) ->
+ get_included_specs(Terms,TestSpec,[],[]).
+
+get_included_specs([{specs,How,SpecOrSpecs}|Ts],TestSpec,Join,Sep) ->
+ Specs = case SpecOrSpecs of
+ [File|_] when is_list(File) ->
+ [get_absfile(Spec,TestSpec) || Spec <- SpecOrSpecs];
+ [Ch|_] when is_integer(Ch) ->
+ [get_absfile(SpecOrSpecs,TestSpec)]
+ end,
+ if How == join ->
+ get_included_specs(Ts,TestSpec,Join++Specs,Sep);
+ true ->
+ get_included_specs(Ts,TestSpec,Join,Sep++Specs)
+ end;
+get_included_specs([_|Ts],TestSpec,Join,Sep) ->
+ get_included_specs(Ts,TestSpec,Join,Sep);
+get_included_specs([],_,Join,Sep) ->
+ {Join,Sep}.
%% global terms that will be used for analysing all other terms in the spec
-get_global([{merge_tests,Bool} | Ts], Spec) ->
+get_global([{merge_tests,Bool}|Ts],Spec) ->
get_global(Ts,Spec#testspec{merge_tests=Bool});
%% the 'define' term replaces the 'alias' and 'node' terms, but we need to keep
@@ -588,7 +736,7 @@ add_option({Key,Value},Node,List,WarnIfExists) when is_list(Value) ->
NewOption = case lists:keyfind(Key,1,OldOptions) of
{Key,OldOption} when WarnIfExists,OldOption/=[]->
io:format("There is an option ~w=~w already "
- "defined for node ~p, skipping new ~w~n",
+ "defined for node ~w, skipping new ~w~n",
[Key,OldOption,Node,Value]),
OldOption;
{Key,OldOption}->
@@ -637,7 +785,7 @@ add_tests([{suites,all_nodes,Dir,Ss}|Ts],Spec) ->
add_tests([{suites,Dir,Ss}|Ts],Spec) ->
add_tests([{suites,all_nodes,Dir,Ss}|Ts],Spec);
add_tests([{suites,Nodes,Dir,Ss}|Ts],Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,suites,[Dir,Ss],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(Nodes,suites,[Dir,Ss],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{suites,Node,Dir,Ss}|Ts],Spec) ->
Tests = Spec#testspec.tests,
@@ -660,11 +808,11 @@ add_tests([{groups,Dir,Suite,Gs}|Ts],Spec) ->
add_tests([{groups,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec) ->
add_tests([{groups,all_nodes,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec);
add_tests([{groups,Nodes,Dir,Suite,Gs}|Ts],Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,groups,[Dir,Suite,Gs],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(Nodes,groups,[Dir,Suite,Gs],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{groups,Nodes,Dir,Suite,Gs,{cases,TCs}}|Ts],
Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,groups,[Dir,Suite,Gs,{cases,TCs}],Ts,
+ Ts1 = per_node(Nodes,groups,[Dir,Suite,Gs,{cases,TCs}],Ts,
Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{groups,Node,Dir,Suite,Gs}|Ts],Spec) ->
@@ -688,7 +836,7 @@ add_tests([{cases,all_nodes,Dir,Suite,Cs}|Ts],Spec) ->
add_tests([{cases,Dir,Suite,Cs}|Ts],Spec) ->
add_tests([{cases,all_nodes,Dir,Suite,Cs}|Ts],Spec);
add_tests([{cases,Nodes,Dir,Suite,Cs}|Ts],Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,cases,[Dir,Suite,Cs],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(Nodes,cases,[Dir,Suite,Cs],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{cases,Node,Dir,Suite,Cs}|Ts],Spec) ->
Tests = Spec#testspec.tests,
@@ -703,7 +851,7 @@ add_tests([{skip_suites,all_nodes,Dir,Ss,Cmt}|Ts],Spec) ->
add_tests([{skip_suites,Dir,Ss,Cmt}|Ts],Spec) ->
add_tests([{skip_suites,all_nodes,Dir,Ss,Cmt}|Ts],Spec);
add_tests([{skip_suites,Nodes,Dir,Ss,Cmt}|Ts],Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,skip_suites,[Dir,Ss,Cmt],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(Nodes,skip_suites,[Dir,Ss,Cmt],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{skip_suites,Node,Dir,Ss,Cmt}|Ts],Spec) ->
Tests = Spec#testspec.tests,
@@ -724,11 +872,11 @@ add_tests([{skip_groups,Dir,Suite,Gs,Cmt}|Ts],Spec) ->
add_tests([{skip_groups,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec) ->
add_tests([{skip_groups,all_nodes,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec);
add_tests([{skip_groups,Nodes,Dir,Suite,Gs,Cmt}|Ts],Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,skip_groups,[Dir,Suite,Gs,Cmt],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(Nodes,skip_groups,[Dir,Suite,Gs,Cmt],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{skip_groups,Nodes,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],
Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,skip_groups,[Dir,Suite,Gs,{cases,TCs},Cmt],Ts,
+ Ts1 = per_node(Nodes,skip_groups,[Dir,Suite,Gs,{cases,TCs},Cmt],Ts,
Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{skip_groups,Node,Dir,Suite,Gs,Cmt}|Ts],Spec) ->
@@ -752,7 +900,7 @@ add_tests([{skip_cases,all_nodes,Dir,Suite,Cs,Cmt}|Ts],Spec) ->
add_tests([{skip_cases,Dir,Suite,Cs,Cmt}|Ts],Spec) ->
add_tests([{skip_cases,all_nodes,Dir,Suite,Cs,Cmt}|Ts],Spec);
add_tests([{skip_cases,Nodes,Dir,Suite,Cs,Cmt}|Ts],Spec) when is_list(Nodes) ->
- Ts1 = separate(Nodes,skip_cases,[Dir,Suite,Cs,Cmt],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(Nodes,skip_cases,[Dir,Suite,Cs,Cmt],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{skip_cases,Node,Dir,Suite,Cs,Cmt}|Ts],Spec) ->
Tests = Spec#testspec.tests,
@@ -783,6 +931,9 @@ add_tests([{release_shell,Bool}|Ts],Spec) ->
add_tests(Ts, Spec#testspec{release_shell = Bool});
%% --- handled/errors ---
+add_tests([{set_merge_tests,_}|Ts],Spec) -> % internal
+ add_tests(Ts,Spec);
+
add_tests([{define,_,_}|Ts],Spec) -> % handled
add_tests(Ts,Spec);
@@ -792,7 +943,10 @@ add_tests([{alias,_,_}|Ts],Spec) -> % handled
add_tests([{node,_,_}|Ts],Spec) -> % handled
add_tests(Ts,Spec);
-add_tests([{merge_tests, _} | Ts], Spec) -> % handled
+add_tests([{merge_tests,_} | Ts], Spec) -> % handled
+ add_tests(Ts,Spec);
+
+add_tests([{specs,_,_} | Ts], Spec) -> % handled
add_tests(Ts,Spec);
%% --------------------------------------------------
@@ -821,7 +975,7 @@ add_tests([{Tag,NodesOrOther,Data}|Ts],Spec) when is_list(NodesOrOther) ->
case lists:all(fun(Test) -> is_node(Test,Spec#testspec.nodes)
end, NodesOrOther) of
true ->
- Ts1 = separate(NodesOrOther,Tag,[Data],Ts,Spec#testspec.nodes),
+ Ts1 = per_node(NodesOrOther,Tag,[Data],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
false ->
add_tests([{Tag,all_nodes,{NodesOrOther,Data}}|Ts],Spec)
@@ -866,7 +1020,18 @@ add_tests([],Spec) -> % done
%% check if it's a CT term that has bad format or if the user seems to
%% have added something of his/her own, which we'll let pass if relaxed
%% mode is enabled.
-check_term(Term) ->
+check_term(Atom) when is_atom(Atom) ->
+ Valid = valid_terms(),
+ case lists:member(Atom,Valid) of
+ true ->
+ valid;
+ false -> % ignore
+ case get(relaxed) of
+ true -> invalid;
+ false -> throw({error,{undefined_term_in_spec,Atom}})
+ end
+ end;
+check_term(Term) when is_tuple(Term) ->
Size = size(Term),
[Name|_] = tuple_to_list(Term),
Valid = valid_terms(),
@@ -894,7 +1059,9 @@ check_term(Term) ->
throw({error,{undefined_term_in_spec,Term}})
end
end
- end.
+ end;
+check_term(Other) ->
+ throw({error,{undefined_term_in_spec,Other}}).
%% specific data handling before saving in testspec record, e.g.
%% converting relative paths to absolute for directories and files
@@ -977,12 +1144,12 @@ update_recorded(Tag,Node,Spec) ->
end.
%% create one test term per node
-separate(Nodes,Tag,Data,Tests,Refs) ->
- Separated = separate(Nodes,Tag,Data,Refs),
+per_node(Nodes,Tag,Data,Tests,Refs) ->
+ Separated = per_node(Nodes,Tag,Data,Refs),
Separated ++ Tests.
-separate([N|Ns],Tag,Data,Refs) ->
- [list_to_tuple([Tag,ref2node(N,Refs)|Data])|separate(Ns,Tag,Data,Refs)];
-separate([],_,_,_) ->
+per_node([N|Ns],Tag,Data,Refs) ->
+ [list_to_tuple([Tag,ref2node(N,Refs)|Data])|per_node(Ns,Tag,Data,Refs)];
+per_node([],_,_,_) ->
[].
%% read the value for FieldName in record Rec#testspec
@@ -1039,14 +1206,21 @@ insert_groups(Node,Dir,Suite,Groups,Cases,Tests,true) when
{[Gr],Cases};
true ->
{Gr,Cases} end || Gr <- Groups],
- case lists:keysearch({Node,Dir},1,Tests) of
- {value,{{Node,Dir},[{all,_}]}} ->
- Tests;
- {value,{{Node,Dir},Suites0}} ->
- Suites1 = insert_groups1(Suite,Groups1,Suites0),
- insert_in_order({{Node,Dir},Suites1},Tests);
- false ->
- insert_in_order({{Node,Dir},[{Suite,Groups1}]},Tests)
+ {Tests1,Done} =
+ lists:foldr(fun(All={{N,D},[{all,_}]},{Replaced,_}) when N == Node,
+ D == Dir ->
+ {[All|Replaced],true};
+ ({{N,D},Suites0},{Replaced,_}) when N == Node,
+ D == Dir ->
+ Suites1 = insert_groups1(Suite,Groups1,Suites0),
+ {[{{N,D},Suites1}|Replaced],true};
+ (T,{Replaced,Match}) ->
+ {[T|Replaced],Match}
+ end, {[],false}, Tests),
+ if not Done ->
+ Tests ++ [{{Node,Dir},[{Suite,Groups1}]}];
+ true ->
+ Tests1
end;
insert_groups(Node,Dir,Suite,Groups,Case,Tests, MergeTests)
when is_atom(Case) ->
@@ -1084,14 +1258,21 @@ insert_groups2([],GrAndCases) ->
insert_cases(Node,Dir,Suite,Cases,Tests,false) when is_list(Cases) ->
append({{Node,Dir},[{Suite,Cases}]},Tests);
insert_cases(Node,Dir,Suite,Cases,Tests,true) when is_list(Cases) ->
- case lists:keysearch({Node,Dir},1,Tests) of
- {value,{{Node,Dir},[{all,_}]}} ->
- Tests;
- {value,{{Node,Dir},Suites0}} ->
- Suites1 = insert_cases1(Suite,Cases,Suites0),
- insert_in_order({{Node,Dir},Suites1},Tests);
- false ->
- insert_in_order({{Node,Dir},[{Suite,Cases}]},Tests)
+ {Tests1,Done} =
+ lists:foldr(fun(All={{N,D},[{all,_}]},{Replaced,_}) when N == Node,
+ D == Dir ->
+ {[All|Replaced],true};
+ ({{N,D},Suites0},{Replaced,_}) when N == Node,
+ D == Dir ->
+ Suites1 = insert_cases1(Suite,Cases,Suites0),
+ {[{{N,D},Suites1}|Replaced],true};
+ (T,{Replaced,Match}) ->
+ {[T|Replaced],Match}
+ end, {[],false}, Tests),
+ if not Done ->
+ Tests ++ [{{Node,Dir},[{Suite,Cases}]}];
+ true ->
+ Tests1
end;
insert_cases(Node,Dir,Suite,Case,Tests,MergeTests) when is_atom(Case) ->
insert_cases(Node,Dir,Suite,[Case],Tests,MergeTests).
@@ -1132,15 +1313,23 @@ skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests,false) when
append({{Node,Dir},Suites1},Tests);
skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests,true) when
((Cases == all) or is_list(Cases)) and is_list(Groups) ->
- Suites =
- case lists:keysearch({Node,Dir},1,Tests) of
- {value,{{Node,Dir},Suites0}} ->
- Suites0;
- false ->
- []
- end,
- Suites1 = skip_groups1(Suite,[{Gr,Cases} || Gr <- Groups],Cmt,Suites),
- insert_in_order({{Node,Dir},Suites1},Tests);
+ {Tests1,Done} =
+ lists:foldr(fun({{N,D},Suites0},{Replaced,_}) when N == Node,
+ D == Dir ->
+ Suites1 = skip_groups1(Suite,
+ [{Gr,Cases} || Gr <- Groups],
+ Cmt,Suites0),
+ {[{{N,D},Suites1}|Replaced],true};
+ (T,{Replaced,Match}) ->
+ {[T|Replaced],Match}
+ end, {[],false}, Tests),
+ if not Done ->
+ Tests ++ [{{Node,Dir},skip_groups1(Suite,
+ [{Gr,Cases} || Gr <- Groups],
+ Cmt,[])}];
+ true ->
+ Tests1
+ end;
skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests,MergeTests)
when is_atom(Case) ->
Cases = if Case == all -> all; true -> [Case] end,
@@ -1162,15 +1351,19 @@ skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,false) when is_list(Cases) ->
Suites1 = skip_cases1(Suite,Cases,Cmt,[]),
append({{Node,Dir},Suites1},Tests);
skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,true) when is_list(Cases) ->
- Suites =
- case lists:keysearch({Node,Dir},1,Tests) of
- {value,{{Node,Dir},Suites0}} ->
- Suites0;
- false ->
- []
- end,
- Suites1 = skip_cases1(Suite,Cases,Cmt,Suites),
- insert_in_order({{Node,Dir},Suites1},Tests);
+ {Tests1,Done} =
+ lists:foldr(fun({{N,D},Suites0},{Replaced,_}) when N == Node,
+ D == Dir ->
+ Suites1 = skip_cases1(Suite,Cases,Cmt,Suites0),
+ {[{{N,D},Suites1}|Replaced],true};
+ (T,{Replaced,Match}) ->
+ {[T|Replaced],Match}
+ end, {[],false}, Tests),
+ if not Done ->
+ Tests ++ [{{Node,Dir},skip_cases1(Suite,Cases,Cmt,[])}];
+ true ->
+ Tests1
+ end;
skip_cases(Node,Dir,Suite,Case,Cmt,Tests,MergeTests) when is_atom(Case) ->
skip_cases(Node,Dir,Suite,[Case],Cmt,Tests,MergeTests).
@@ -1260,7 +1453,9 @@ is_node([],_) ->
valid_terms() ->
[
+ {set_merge_tests,2},
{define,3},
+ {specs,3},
{node,3},
{cover,2},
{cover,3},
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index cf891ed043..0f2b2081d9 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -1,7 +1,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
@@ -396,14 +396,14 @@ loop(Mode,TestData,StartDir) ->
%% A connection crashed - remove the connection but don't die
ct_logs:tc_log_async(ct_error_notify,
"Connection process died: "
- "Pid: ~p, Address: ~p, Callback: ~p\n"
+ "Pid: ~w, Address: ~p, Callback: ~w\n"
"Reason: ~p\n\n",
[Pid,A,CB,Reason]),
catch CB:close(Pid),
loop(Mode,TestData,StartDir);
_ ->
%% Let process crash in case of error, this shouldn't happen!
- io:format("\n\nct_util_server got EXIT from ~p: ~p\n\n",
+ io:format("\n\nct_util_server got EXIT from ~w: ~p\n\n",
[Pid,Reason]),
file:set_cwd(StartDir),
exit(Reason)
@@ -956,7 +956,7 @@ open_url(iexplore, Args, URL) ->
Path = proplists:get_value(default, Paths),
[Cmd | _] = string:tokens(Path, "%"),
Cmd1 = Cmd ++ " " ++ Args ++ " " ++ URL,
- io:format(user, "~nOpening ~s with command:~n ~s~n", [URL,Cmd1]),
+ io:format(user, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd1]),
open_port({spawn,Cmd1}, []);
_ ->
io:format("~nNo path to iexplore.exe~n",[])
@@ -969,6 +969,6 @@ open_url(Prog, Args, URL) ->
is_list(Prog) -> Prog
end,
Cmd = ProgStr ++ " " ++ Args ++ " " ++ URL,
- io:format(user, "~nOpening ~s with command:~n ~s~n", [URL,Cmd]),
+ io:format(user, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd]),
open_port({spawn,Cmd},[]),
ok.
diff --git a/lib/common_test/src/cth_conn_log.erl b/lib/common_test/src/cth_conn_log.erl
index 255f3ec78a..644594e34d 100644
--- a/lib/common_test/src/cth_conn_log.erl
+++ b/lib/common_test/src/cth_conn_log.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
@@ -105,8 +105,9 @@ pre_init_per_testcase(TestCase,Config,CthState) ->
"<table borders=1>"
"<b>" ++ ConnModStr ++ " logs:</b>\n" ++
[io_lib:format(
- "<tr><td>~p</td><td><a href=~p>~s</a></td></tr>",
- [S,L,filename:basename(L)])
+ "<tr><td>~p</td><td><a href=\"~ts\">~ts</a>"
+ "</td></tr>",
+ [S,ct_logs:uri(L),filename:basename(L)])
|| {S,L} <- Ls] ++
"</table>",
io:format(Str,[]),
diff --git a/lib/common_test/src/cth_surefire.erl b/lib/common_test/src/cth_surefire.erl
index e6eaad8d48..1a38b6584b 100644
--- a/lib/common_test/src/cth_surefire.erl
+++ b/lib/common_test/src/cth_surefire.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
@@ -297,7 +297,7 @@ sanitize([]) ->
now_to_string(Now) ->
{{YY,MM,DD},{HH,Mi,SS}} = calendar:now_to_local_time(Now),
- io_lib:format("~p-~2..0B-~2..0BT~2..0B:~2..0B:~2..0B",[YY,MM,DD,HH,Mi,SS]).
+ io_lib:format("~w-~2..0B-~2..0BT~2..0B:~2..0B:~2..0B",[YY,MM,DD,HH,Mi,SS]).
make_url(undefined,_) ->
undefined;
diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl
index 25b9d4d5d2..99ce92e9f1 100644
--- a/lib/common_test/src/unix_telnet.erl
+++ b/lib/common_test/src/unix_telnet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. 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
@@ -110,7 +110,7 @@ connect1(Ip,Port,Timeout,KeepAlive,Username,Password) ->
case ct_telnet:silent_teln_expect(Pid,[],[prompt],?prx,[]) of
{ok,{prompt,?username},_} ->
ok = ct_telnet_client:send_data(Pid,Username),
- cont_log("Username: ~s",[Username]),
+ cont_log("Username: ~ts",[Username]),
case ct_telnet:silent_teln_expect(Pid,[],prompt,?prx,[]) of
{ok,{prompt,?password},_} ->
ok = ct_telnet_client:send_data(Pid,Password),
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index d469d03e04..760cc20410 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -40,6 +40,7 @@ MODULES= \
ct_repeat_1_SUITE \
ct_testspec_1_SUITE \
ct_testspec_2_SUITE \
+ ct_testspec_3_SUITE \
ct_skip_SUITE \
ct_error_SUITE \
ct_test_server_if_1_SUITE \
diff --git a/lib/common_test/test/ct_error_SUITE.erl b/lib/common_test/test/ct_error_SUITE.erl
index 6d90b29f41..86ec71c98e 100644
--- a/lib/common_test/test/ct_error_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE.erl
@@ -44,8 +44,12 @@
%% there will be clashes with logging processes etc).
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- Config1 = ct_test_support:init_per_suite(Config),
- Config1.
+ DataDir = ?config(data_dir, Config),
+ TestDir = filename:join(DataDir, "error/test/"),
+ CTH = filename:join(TestDir, "verify_config.erl"),
+ ct:pal("Compiling ~p: ~p",
+ [CTH,compile:file(CTH,[{outdir,TestDir},debug_info])]),
+ ct_test_support:init_per_suite([{path_dirs,[TestDir]} | Config]).
end_per_suite(Config) ->
ct_test_support:end_per_suite(Config).
@@ -61,7 +65,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[cfg_error, lib_error, no_compile, timetrap_end_conf,
timetrap_normal, timetrap_extended, timetrap_parallel,
- timetrap_fun, timetrap_fun_group, misc_errors].
+ timetrap_fun, timetrap_fun_group, misc_errors,
+ config_restored].
groups() ->
[].
@@ -285,6 +290,24 @@ misc_errors(Config) when is_list(Config) ->
TestEvents = events_to_check(misc_errors),
ok = ct_test_support:verify_events(TestEvents, Events, Config).
+%%%-----------------------------------------------------------------
+%%%
+config_restored(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suite = filename:join(DataDir, "error/test/config_restored_SUITE"),
+ {Opts,ERPid} = setup([{suite,Suite},
+ {ct_hooks,[verify_config]}],
+ Config),
+ ok = ct_test_support:run(Opts, Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(config_restored,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config),
+ Opts),
+
+ TestEvents = events_to_check(config_restored),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
@@ -1439,4 +1462,40 @@ test_events(misc_errors) ->
{?eh,test_stats,{2,7,{0,0}}},
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,stop_logging,[]}
+ ];
+
+test_events(config_restored) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,4}},
+ {?eh,tc_start,{config_restored_SUITE,init_per_suite}},
+ {?eh,tc_done,{config_restored_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{config_restored_SUITE,to_tc}},
+ {?eh,cth,{verify_config,post_end_per_testcase,{to_tc,diff_ok}}},
+ {?eh,tc_done,
+ {config_restored_SUITE,to_tc,{failed,{timetrap_timeout,1000}}}},
+ {?eh,test_stats,{0,1,{0,0}}},
+ {?eh,tc_start,{config_restored_SUITE,exit_tc}},
+ {?eh,cth,{verify_config,post_end_per_testcase,{exit_tc,diff_ok}}},
+ {?eh,tc_done,{config_restored_SUITE,exit_tc,
+ {failed,{error,{test_case_failed,"Goodbye!"}}}}},
+ {?eh,test_stats,{0,2,{0,0}}},
+ [{?eh,tc_start,{config_restored_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_start,{config_restored_SUITE,to_tc}},
+ {?eh,cth,{verify_config,post_end_per_testcase,{to_tc,diff_ok}}},
+ {?eh,tc_done,
+ {config_restored_SUITE,to_tc,{failed,{timetrap_timeout,1000}}}},
+ {?eh,test_stats,{0,3,{0,0}}},
+ {?eh,tc_start,{config_restored_SUITE,exit_tc}},
+ {?eh,cth,{verify_config,post_end_per_testcase,{exit_tc,diff_ok}}},
+ {?eh,tc_done,{config_restored_SUITE,exit_tc,
+ {failed,{error,{test_case_failed,"Goodbye!"}}}}},
+ {?eh,test_stats,{0,4,{0,0}}},
+ {?eh,tc_start,{config_restored_SUITE,{end_per_group,g1,[]}}},
+ {?eh,tc_done,{config_restored_SUITE,{end_per_group,g1,[]},ok}}],
+ {?eh,tc_start,{config_restored_SUITE,end_per_suite}},
+ {?eh,tc_done,{config_restored_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
].
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl
new file mode 100644
index 0000000000..fb47f2bcb9
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/config_restored_SUITE.erl
@@ -0,0 +1,175 @@
+%%
+%% %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(config_restored_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,1000}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = [{init_per_suite,?MODULE} | Config],
+ TabPid = spawn(fun() ->
+ ets:new(?MODULE, [named_table, set, public]),
+ receive _ -> ok end
+ end),
+ [{tab,TabPid} | Config1].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ets:delete(?MODULE),
+ exit(?config(tab, Config), kill),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(GroupName, Config) ->
+ [{init_per_group,GroupName} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(TC, Config) ->
+ Config1 = [{init_per_testcase,TC} | Config],
+ ets:insert(?MODULE, {config,Config}),
+ %% ct:pal("Config after init_per_testcase(~w) = ~p", [TC,Config1]),
+ Config1.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(TC, Config) ->
+ ct:pal("Config in end_per_testcase(~w) = ~p", [TC,Config]),
+ [{_,MemConfig}] = ets:lookup(?MODULE, config),
+ diff_config(Config, MemConfig, [tc_status]),
+ ?MODULE = proplists:get_value(init_per_suite, Config),
+ TC = proplists:get_value(init_per_testcase, Config),
+ case ?config(tc_group_properties, Config) of
+ undefined ->
+ ok;
+ Props ->
+ GName = proplists:get_value(name, Props),
+ GName = proplists:get_value(init_per_group, Config)
+ end,
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[to_tc, exit_tc]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [to_tc, exit_tc,
+ {group,g1}].
+
+
+to_tc(Config) ->
+ %% ct:pal("Config for to_tc = ~p", [Config]),
+ [{_,MemConfig}] = ets:lookup(?MODULE, config),
+ diff_config(Config, MemConfig, []),
+ ct:sleep(2000).
+
+exit_tc(Config) ->
+ %% ct:pal("Config for exit_tc = ~p", [Config]),
+ [{_,MemConfig}] = ets:lookup(?MODULE, config),
+ diff_config(Config, MemConfig, []),
+ ct:fail("Goodbye!").
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+
+diff_config(Cfg1, Cfg2, DiffKeys) ->
+ diff_config(Cfg1, Cfg2, DiffKeys, []).
+
+diff_config([{K,V} | Cfg1], Cfg2, DiffKeys, RemKeys) ->
+ case proplists:get_value(K, Cfg2) of
+ undefined ->
+ diff_config(Cfg1, Cfg2, proplists:delete(K, DiffKeys), RemKeys);
+ V ->
+ diff_config(Cfg1, proplists:delete(K, Cfg2), DiffKeys, RemKeys);
+ _Other ->
+ case proplists:is_defined(K, DiffKeys) of
+ true ->
+ diff_config(Cfg1, Cfg2, proplists:delete(K, DiffKeys), RemKeys);
+ false ->
+ diff_config(Cfg1, Cfg2, DiffKeys, [K | RemKeys])
+ end
+ end;
+diff_config([], [], [], []) ->
+ ct:pal("Diff ok!", []),
+ ok;
+diff_config([], Cfg2, DiffKeys, RemKeys) ->
+ Result = {diff_failed, {cfg2,Cfg2}, {diffkeys,DiffKeys}, {remkeys,RemKeys}},
+ ct:pal("Diff failed! Result = ~p", [Result]),
+ exit(Result).
+
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl
new file mode 100644
index 0000000000..40a54b9f99
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl
@@ -0,0 +1,239 @@
+%%
+%% %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%
+%%
+
+%%% @doc Common Test Example Suite Callback module.
+%%%
+%%% <p>This module gives an example of a common test CTH (Common Test Hook).
+%%% There are many ways to add a CTH to a test run, you can do it either in
+%%% the command line using -ct_hook, in a test spec using
+%%% {ct_hook,M} or in the suite it self by returning ct_hook
+%%% from either suite/0, init_per_suite/1, init_per_group/2 and
+%%% init_per_testcase/2. The scope of the CTH is determined by where is it
+%%% started. If it is started in the command line or test spec then it will
+%%% be stopped at the end of all tests. If it is started in init_per_suite,
+%%% it will be stopped after end_per_suite and so on. See terminate
+%%% documentation for a table describing the scoping machanics.
+%%%
+%%% All of callbacks except init/1 in a CTH are optional.</p>
+
+-module(verify_config).
+
+%% CT Hooks
+-export([id/1]).
+-export([init/2]).
+
+-export([pre_init_per_suite/3]).
+-export([post_init_per_suite/4]).
+-export([pre_end_per_suite/3]).
+-export([post_end_per_suite/4]).
+
+-export([pre_init_per_group/3]).
+-export([post_init_per_group/4]).
+-export([pre_end_per_group/3]).
+-export([post_end_per_group/4]).
+
+-export([pre_init_per_testcase/3]).
+-export([post_end_per_testcase/4]).
+
+-export([on_tc_fail/3]).
+-export([on_tc_skip/3]).
+
+-export([terminate/1]).
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-type config() :: proplists:proplist().
+-type reason() :: term().
+-type skip_or_fail() :: {skip, reason()} |
+ {auto_skip, reason()} |
+ {fail, reason()} |
+ {'EXIT',reason()}.
+
+-record(state, { id = ?MODULE :: term()}).
+
+%% @doc Always called before any other callback function. Use this to initiate
+%% any common state. It should return an state for this CTH.
+-spec init(Id :: term(), Opts :: proplists:proplist()) ->
+ {ok, State :: #state{}}.
+init(Id, Opts) ->
+ {ok,Opts}.
+
+%% @doc The ID is used to uniquly identify an CTH instance, if two CTH's
+%% return the same ID the seconds CTH is ignored. This function should NOT
+%% have any side effects as it might be called multiple times by common test.
+-spec id(Opts :: proplists:proplist()) ->
+ Id :: term().
+id(Opts) ->
+ now().
+
+%% @doc Called before init_per_suite is called. Note that this callback is
+%% only called if the CTH is added before init_per_suite is run (eg. in a test
+%% specification, suite/0 function etc).
+%% You can change the config in the this function.
+-spec pre_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_suite(Suite,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after init_per_suite.
+%% you can change the return value in this function.
+-spec post_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_suite(Suite,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before end_per_suite. The config/state can be changed here,
+%% though it will only affect the *end_per_suite function.
+-spec pre_end_per_suite(Suite :: atom(),
+ Config :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_suite(Suite,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after end_per_suite. Note that the config cannot be
+%% changed here, only the status of the suite.
+-spec post_end_per_suite(Suite :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_suite(Suite,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before each init_per_group.
+%% You can change the config in this function.
+-spec pre_init_per_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_group(Group,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after each init_per_group.
+%% You can change the return value in this function.
+-spec post_init_per_group(Group :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_group(Group,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called after each end_per_group. The config/state can be changed here,
+%% though it will only affect the *end_per_group functions.
+-spec pre_end_per_group(Group :: atom(),
+ Config :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_group(Group,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after each end_per_group. Note that the config cannot be
+%% changed here, only the status of the group.
+-spec post_end_per_group(Group :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_group(Group,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before each test case.
+%% You can change the config in this function.
+-spec pre_init_per_testcase(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_testcase(TC,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after each test case. Note that the config cannot be
+%% changed here, only the status of the test case.
+-spec post_end_per_testcase(TC :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_testcase(TC,Config,Return,State) ->
+ %% check that config has been restored
+ ct:pal("Config in verify_config:post_end_per_testcase(~w) = ~p",
+ [TC,Config]),
+ [{_,MemConfig}] = ets:lookup(config_restored_SUITE, config),
+ try config_restored_SUITE:diff_config(Config, MemConfig, [tc_status]) of
+ ok ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_end_per_testcase,
+ {TC,diff_ok}}})
+ catch
+ _:_ ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_end_per_testcase,
+ {TC,diff_failed}}})
+ end,
+ {Return, State}.
+
+%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
+%% post_end_per_group and post_end_per_tc if the suite, group or test case failed.
+%% This function should be used for extra cleanup which might be needed.
+%% It is not possible to modify the config or the status of the test run.
+-spec on_tc_fail(TC :: init_per_suite | end_per_suite |
+ init_per_group | end_per_group | atom(),
+ Reason :: term(), State :: #state{}) ->
+ NewState :: #state{}.
+on_tc_fail(TC, Reason, State) ->
+ State.
+
+%% @doc Called when a test case is skipped by either user action
+%% or due to an init function failing. Test case can be
+%% end_per_suite, init_per_group, end_per_group and the actual test cases.
+-spec on_tc_skip(TC :: end_per_suite |
+ init_per_group | end_per_group | atom(),
+ {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} |
+ {tc_user_skip, {skipped, Reason :: term()}},
+ State :: #state{}) ->
+ NewState :: #state{}.
+on_tc_skip(TC, Reason, State) ->
+ State.
+
+%% @doc Called when the scope of the CTH is done, this depends on
+%% when the CTH was specified. This translation table describes when this
+%% function is called.
+%%
+%% | Started in | terminate called |
+%% |---------------------|-------------------------|
+%% | command_line | after all tests are run |
+%% | test spec | after all tests are run |
+%% | suite/0 | after SUITE is done |
+%% | init_per_suite/1 | after SUITE is done |
+%% | init_per_group/2 | after group is done |
+%% |-----------------------------------------------|
+%%
+-spec terminate(State :: #state{}) ->
+ term().
+terminate(State) ->
+ ok.
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..0f336d2d79 100644
--- a/lib/common_test/test/ct_master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE.erl
@@ -109,7 +109,7 @@ ct_master_test(Config) when is_list(Config) ->
ERPid = ct_test_support:start_event_receiver(Config),
- [{TSFile,ok}] = run_test(ct_master_test, FileName, Config),
+ [{[TSFile],ok}] = run_test(ct_master_test, FileName, Config),
Events = ct_test_support:get_events(ERPid, Config),
@@ -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,[]}}]
}
@@ -192,12 +195,12 @@ get_log_dir(_,PrivDir,NodeName) ->
run_test(_Name, FileName, Config) ->
%% run the test twice, using different html versions
- [{FileName,ok}] = ct_test_support:run({ct_master,run,[FileName]},
- [{ct_master,basic_html,[true]}],
- Config),
- [{FileName,ok}] = ct_test_support:run({ct_master,run,[FileName]},
- [{ct_master,basic_html,[false]}],
- Config).
+ [{[FileName],ok}] = ct_test_support:run({ct_master,run,[FileName]},
+ [{ct_master,basic_html,[true]}],
+ Config),
+ [{[FileName],ok}] = ct_test_support:run({ct_master,run,[FileName]},
+ [{ct_master,basic_html,[false]}],
+ Config).
reformat(Events, EH) ->
ct_test_support:reformat(Events, EH).
diff --git a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
index 8a5009ad62..df54c4419c 100644
--- a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. 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
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_netconfc_SUITE_data/ns.erl b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
index 2427f37f52..09217f60a3 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/ns.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
@@ -426,7 +426,7 @@ reply(ConnRef,Reply) ->
send(ConnRef, make_msg(Reply)).
from_simple(Simple) ->
- list_to_binary(xmerl:export_simple_element(Simple,xmerl_xml)).
+ unicode_c2b(xmerl:export_simple_element(Simple,xmerl_xml)).
xml(Content) ->
<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
@@ -435,30 +435,30 @@ xml(Content) ->
rpc_reply(Content) when is_binary(Content) ->
MsgId = case erase(msg_id) of
undefined -> <<>>;
- Id -> list_to_binary([" message-id=\"",Id,"\""])
+ Id -> unicode_c2b([" message-id=\"",Id,"\""])
end,
<<"<rpc-reply xmlns=\"",?NETCONF_NAMESPACE,"\"",MsgId/binary,">\n",
Content/binary,"\n</rpc-reply>">>;
rpc_reply(Content) ->
- rpc_reply(list_to_binary(Content)).
+ rpc_reply(unicode_c2b(Content)).
session_id(no_session_id) ->
<<>>;
session_id(SessionId0) ->
- SessionId = list_to_binary(integer_to_list(SessionId0)),
+ SessionId = unicode_c2b(integer_to_list(SessionId0)),
<<"<session-id>",SessionId/binary,"</session-id>\n">>.
capabilities(undefined) ->
- CapsXml = list_to_binary([["<capability>",C,"</capability>\n"]
+ CapsXml = unicode_c2b([["<capability>",C,"</capability>\n"]
|| C <- ?CAPABILITIES]),
<<"<capabilities>\n",CapsXml/binary,"</capabilities>\n">>;
capabilities({base,Vsn}) ->
- CapsXml = list_to_binary([["<capability>",C,"</capability>\n"]
+ CapsXml = unicode_c2b([["<capability>",C,"</capability>\n"]
|| C <- ?CAPABILITIES_VSN(Vsn)]),
<<"<capabilities>\n",CapsXml/binary,"</capabilities>\n">>;
capabilities(no_base) ->
[_|Caps] = ?CAPABILITIES,
- CapsXml = list_to_binary([["<capability>",C,"</capability>\n"] || C <- Caps]),
+ CapsXml = unicode_c2b([["<capability>",C,"</capability>\n"] || C <- Caps]),
<<"<capabilities>\n",CapsXml/binary,"</capabilities>\n">>;
capabilities(no_caps) ->
<<>>.
@@ -553,3 +553,8 @@ make_msg(Xml) when is_binary(Xml) ->
xml(Xml);
make_msg(Simple) when is_tuple(Simple) ->
xml(from_simple(Simple)).
+
+%%%-----------------------------------------------------------------
+%%% Convert to unicode binary, since we use UTF-8 encoding in XML
+unicode_c2b(Characters) ->
+ unicode:characters_to_binary(Characters).
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..7c33fd404d 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.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
@@ -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,'_'}},
@@ -1132,6 +1132,8 @@ reformat([{_EH,#event{name=test_start,data=_}} | Events], EH) ->
[{EH,test_start,{'DEF',{'START_TIME','LOGDIR'}}} | reformat(Events, EH)];
reformat([{_EH,#event{name=test_done,data=_}} | Events], EH) ->
[{EH,test_done,{'DEF','STOP_TIME'}} | reformat(Events, EH)];
+reformat([{_EH,#event{name=tc_logfile,data=_}} | Events], EH) ->
+ reformat(Events, EH);
reformat([{_EH,#event{name=test_stats,data=Data}} | Events], EH) ->
[{EH,test_stats,Data} | reformat(Events, EH)];
%% use this to only print the last test_stats event:
diff --git a/lib/common_test/test/ct_testspec_2_SUITE.erl b/lib/common_test/test/ct_testspec_2_SUITE.erl
index 9d2dc84ad3..beaba0eaac 100644
--- a/lib/common_test/test/ct_testspec_2_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_2_SUITE.erl
@@ -479,7 +479,7 @@ multiple_specs(_Config) ->
"multiple_specs.1.spec"),
SpecFile2 = ct_test_support:write_testspec(Spec2,SpecDir,
"multiple_specs.2.spec"),
- FileResult = ct_testspec:collect_tests_from_file([SpecFile1,SpecFile2],
+ FileResult = ct_testspec:collect_tests_from_file([[SpecFile1,SpecFile2]],
false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
@@ -490,7 +490,7 @@ multiple_specs(_Config) ->
[{Node2,get_absdir(filename:join(SpecDir,CfgDir))} || CfgDir <- CfgDir2]],
LogDirV = get_absdir(filename:join(SpecDir,"../logs")),
- Verify = #testspec{merge_tests = false,
+ Verify = #testspec{merge_tests = true,
spec_dir = SpecDir,
nodes = [{undefined,Node},{n1,Node1},{n2,Node2}],
alias = [{to1,TO1V},{to2,TO2V}],
@@ -500,22 +500,13 @@ multiple_specs(_Config) ->
logdir = [{Node,LogDirV},{Node1,LogDirV},{Node2,LogDirV},"."],
config = CFGs,
tests = [{{Node1,TO1V},
- [{x_SUITE,[all]}]},
- {{Node1,TO1V},
- [{y_SUITE,[{g1,all},{g2,all}]}]},
- {{Node1,TO1V},
- [{y_SUITE,[tc1,tc2]}]},
- {{Node1,TO1V},
- [{z_SUITE,[{all,{skip,"skipped"}}]}]},
- {{Node2,TO2V},
- [{x_SUITE,[all]}]},
- {{Node2,TO2V},
- [{y_SUITE,[all]}]},
- {{Node2,TO2V},
- [{x_SUITE,[{{g1,all},{skip,"skipped"}},
- {{g2,all},{skip,"skipped"}}]}]},
+ [{x_SUITE,[all]},
+ {y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
+ {z_SUITE,[{all,{skip,"skipped"}}]}]},
{{Node2,TO2V},
- [{y_SUITE,[{tc1,{skip,"skipped"}},
+ [{x_SUITE,[all,{{g1,all},{skip,"skipped"}},
+ {{g2,all},{skip,"skipped"}}]},
+ {y_SUITE,[all,{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}]},
verify_result(Verify,FileResult,FileResult).
@@ -524,7 +515,7 @@ multiple_specs(_Config) ->
%%%
misc_config_terms(_Config) ->
CfgDir = "../cfgs/to1",
-
+ TODir = "../tests/to1",
Spec =
[{node,x,n1@h1},{node,y,n2@h2},
@@ -554,7 +545,9 @@ misc_config_terms(_Config) ->
{create_priv_dir,[auto_per_tc]},
{create_priv_dir,n1@h1,[manual_per_tc]},
- {create_priv_dir,n2@h2,[auto_per_run]}
+ {create_priv_dir,n2@h2,[auto_per_run]},
+
+ {suites,n1@h1,TODir,[x_SUITE]}
],
{ok,SpecDir} = file:get_cwd(),
@@ -599,7 +592,9 @@ misc_config_terms(_Config) ->
{n2@h2,CSS2}],
create_priv_dir = [{Node,[auto_per_tc]},
{n1@h1,[manual_per_tc]},
- {n2@h2,[auto_per_run]}]
+ {n2@h2,[auto_per_run]}],
+ tests = [{{n1@h1,get_absdir(filename:join(SpecDir,TODir))},
+ [{x_SUITE,[all]}]}]
},
verify_result(Verify,ListResult,FileResult).
@@ -688,10 +683,10 @@ define_names_1(_Config) ->
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
-verify_result(Verify,ListResult,FileResult) ->
+verify_result(VerificationRec,ListResult,FileResult) ->
{_,TSLTuples} = rec2proplist(ListResult),
{_,TSFTuples} = rec2proplist(FileResult),
- {_,VTuples} = rec2proplist(Verify),
+ {_,VTuples} = rec2proplist(VerificationRec),
VResult =
(catch lists:foldl(fun({Tag,Val},{[{Tag,Val}|TSL],[{Tag,Val}|TSF]}) ->
{TSL,TSF};
@@ -720,6 +715,8 @@ read_config(S) ->
rec2proplist(E={error,_What}) ->
exit({invalid_testspec_record,E});
+rec2proplist([{Specs,Rec}]) when is_list(Specs) ->
+ rec2proplist(Rec);
rec2proplist(Rec) ->
[RecName|RecList] = tuple_to_list(Rec),
FieldNames =
diff --git a/lib/common_test/test/ct_testspec_3_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE.erl
new file mode 100644
index 0000000000..e2f57c2c64
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE.erl
@@ -0,0 +1,745 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_testspec_1_SUITE
+%%%
+%%% Description:
+%%% Test test specifications
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_testspec_3_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Config1 = ct_test_support:init_per_suite(Config),
+ SpecsDir1 = filename:join(DataDir, "specs1"),
+ SpecsDir2 = filename:join(DataDir, "specs2"),
+ [{specs_dir1,SpecsDir1},{specs_dir2,SpecsDir2} | Config1].
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_separate,
+ start_join,
+ incl_separate1,
+ incl_separate2,
+ incl_join1,
+ incl_join2,
+ incl_both1,
+ incl_both2,
+ incl_both_and_join1,
+ incl_both_and_join2,
+ rec_incl_separate1,
+ rec_incl_separate2,
+ rec_incl_join1,
+ rec_incl_join2,
+ rec_incl_separate_join1,
+ rec_incl_separate_join2,
+ rec_incl_join_separate1,
+ rec_incl_join_separate2
+ ].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+
+start_separate(Config) ->
+ Specs = [fname(specs_dir1, "flat_spec1", Config),
+ fname(specs_dir2, "flat_spec2", Config)],
+ setup_and_execute(start_separate, Specs, [], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+start_join(Config) ->
+ Specs = [fname(specs_dir1, "flat_spec1", Config),
+ fname(specs_dir2, "flat_spec2", Config)],
+ setup_and_execute(start_join, Specs, [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+incl_separate1(Config) ->
+ Specs = [fname(specs_dir1, "spec_sep1", Config),
+ fname(specs_dir2, "spec_sep2", Config)],
+ setup_and_execute(incl_separate1, Specs, [], Config).
+
+incl_separate2(Config) ->
+ Specs = [fname(specs_dir1, "spec_sep1", Config),
+ fname(specs_dir2, "spec_sep2", Config)],
+ setup_and_execute(incl_separate2, Specs, [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+incl_join1(Config) ->
+ Specs = [fname(specs_dir1, "spec_join1", Config),
+ fname(specs_dir2, "spec_join2", Config)],
+ setup_and_execute(incl_join1, Specs, [], Config).
+
+incl_join2(Config) ->
+ Specs = [fname(specs_dir1, "spec_join1", Config),
+ fname(specs_dir2, "spec_join2", Config)],
+ setup_and_execute(incl_join2, Specs, [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+incl_both1(Config) ->
+ Specs = [fname(specs_dir1, "spec_both1", Config),
+ fname(specs_dir2, "spec_both2", Config)],
+ setup_and_execute(incl_both1, Specs, [], Config).
+
+incl_both2(Config) ->
+ Specs = [fname(specs_dir1, "spec_both1", Config),
+ fname(specs_dir2, "spec_both2", Config)],
+ setup_and_execute(incl_both2, Specs, [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+incl_both_and_join1(Config) ->
+ Specs = [fname(specs_dir1, "spec_both_join1", Config),
+ fname(specs_dir2, "spec_both_join2", Config)],
+ setup_and_execute(incl_both_and_join1, Specs, [], Config).
+
+incl_both_and_join2(Config) ->
+ Specs = [fname(specs_dir1, "spec_both_join1", Config),
+ fname(specs_dir2, "spec_both_join2", Config)],
+ setup_and_execute(incl_both_and_join2, Specs, [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+rec_incl_separate1(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_sep1", Config),
+ fname(specs_dir2, "rec_spec_sep2", Config)],
+ setup_and_execute(rec_incl_separate1, Specs, [], Config).
+
+rec_incl_separate2(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_sep1", Config),
+ fname(specs_dir2, "rec_spec_sep2", Config)],
+ setup_and_execute(rec_incl_separate2, Specs, [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+rec_incl_join1(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_join1", Config),
+ fname(specs_dir2, "rec_spec_join2", Config)],
+ setup_and_execute(rec_incl_join1, Specs, [], Config).
+
+rec_incl_join2(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_join1", Config),
+ fname(specs_dir2, "rec_spec_join2", Config)],
+ setup_and_execute(rec_incl_join2, Specs, [{join_specs,true}], Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+rec_incl_separate_join1(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_sep_join1", Config),
+ fname(specs_dir2, "rec_spec_sep_join2", Config)],
+ setup_and_execute(rec_incl_separate_join1, Specs, [], Config).
+
+rec_incl_separate_join2(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_sep_join1", Config),
+ fname(specs_dir2, "rec_spec_sep_join2", Config)],
+ setup_and_execute(rec_incl_separate_join2, Specs,
+ [{join_specs,true}], Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+rec_incl_join_separate1(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_join_sep1", Config),
+ fname(specs_dir2, "rec_spec_join_sep2", Config)],
+ setup_and_execute(rec_incl_join_separate1, Specs, [], Config).
+
+rec_incl_join_separate2(Config) ->
+ Specs = [fname(specs_dir1, "rec_spec_join_sep1", Config),
+ fname(specs_dir2, "rec_spec_join_sep2", Config)],
+ setup_and_execute(rec_incl_join_separate2, Specs,
+ [{join_specs,true}], Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+fname(Tag, File, Config) ->
+ filename:join(?config(Tag, Config), File).
+
+check_parameter(TCID) ->
+ {ok,{config,TCID}}.
+
+read_config(TCID) ->
+ {ok,[{tcname,list_to_atom(TCID)}]}.
+
+setup_and_execute(TCName, Specs, TestOpts, Config) ->
+
+ TestID = {userconfig,{?MODULE,atom_to_list(TCName)}},
+ TestTerms = [TestID,{spec,Specs},{label,TCName}] ++ TestOpts,
+
+ {Opts,ERPid} = setup(TestTerms, Config),
+
+ case ct_test_support:run(Opts, Config) of
+ ok ->
+ ok;
+ Error ->
+ ct:pal("Error executing with opts: ~p", [Opts]),
+ exit(Error)
+ end,
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(TCName,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config),
+ Opts),
+
+ TestEvents = events_to_check(TCName),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+setup(Test, Config) when is_tuple(Test) ->
+ setup([Test], Config);
+setup(Tests, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ Tests ++ [{event_handler,{?eh,EvHArgs}}],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+events_to_check(Test) ->
+ %% 2 tests (ct:run_test + script_start) is default
+ events_to_check(Test, 2).
+
+events_to_check(_, 0) ->
+ [];
+events_to_check(Test, N) ->
+ test_events(Test) ++ events_to_check(Test, N-1).
+
+test_events(start_separate) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(start_join) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{4,4,20}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{4,8,{4,4}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_separate1) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,5}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_separate2) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,5}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_join1) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{4,4,20}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{4,8,{4,4}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{4,4,20}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{4,8,{4,4}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_join2) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{4,4,20}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{4,8,{4,4}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_both1) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_both2) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{4,4,20}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,ok_tc}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{4,8,{4,4}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{3,2,15}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t12_SUITE,init_per_suite}},
+ {?eh,tc_done,{t12_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t12_SUITE,end_per_suite}},
+ {?eh,tc_done,{t12_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t22_SUITE,init_per_suite}},
+ {?eh,tc_done,{t22_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{3,6,{3,3}}},
+ {?eh,tc_start,{t22_SUITE,end_per_suite}},
+ {?eh,tc_done,{t22_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]},
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,10}},
+ {?eh,tc_start,{t11_SUITE,init_per_suite}},
+ {?eh,tc_done,{t11_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{1,2,{1,1}}},
+ {?eh,tc_start,{t11_SUITE,end_per_suite}},
+ {?eh,tc_done,{t11_SUITE,end_per_suite,ok}},
+ {?eh,tc_start,{t21_SUITE,init_per_suite}},
+ {?eh,tc_done,{t21_SUITE,init_per_suite,ok}},
+ {?eh,test_stats,{2,4,{2,2}}},
+ {?eh,tc_start,{t21_SUITE,end_per_suite}},
+ {?eh,tc_done,{t21_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(incl_both_and_join1) -> [];
+test_events(incl_both_and_join2) -> [];
+test_events(rec_incl_separate1) -> [];
+test_events(rec_incl_separate2) -> [];
+test_events(rec_incl_join1) -> [];
+test_events(rec_incl_join2) -> [];
+test_events(rec_incl_separate_join1) -> [];
+test_events(rec_incl_separate_join2) -> [];
+test_events(rec_incl_join_separate1) -> [];
+test_events(rec_incl_join_separate2) -> [];
+
+test_events(_) ->
+ [].
+
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg11 b/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg11
new file mode 100644
index 0000000000..bc672568da
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg11
@@ -0,0 +1 @@
+{file, cfg11}. \ No newline at end of file
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg12 b/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg12
new file mode 100644
index 0000000000..30f2cf6857
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg12
@@ -0,0 +1 @@
+{file, cfg12}. \ No newline at end of file
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg13 b/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg13
new file mode 100644
index 0000000000..1860ec78e5
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/config1/cfg13
@@ -0,0 +1 @@
+{file, cfg13}. \ No newline at end of file
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/config2/cfg21 b/lib/common_test/test/ct_testspec_3_SUITE_data/config2/cfg21
new file mode 100644
index 0000000000..b18d35443e
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/config2/cfg21
@@ -0,0 +1 @@
+{file, cfg21}. \ No newline at end of file
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/flat_spec1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/flat_spec1
new file mode 100644
index 0000000000..eff87222ea
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/flat_spec1
@@ -0,0 +1,4 @@
+{config, "../config1/cfg11"}.
+{suites, "../tests1", t11_SUITE}.
+{suites, "../tests1", t11_SUITE}.
+{suites, "../tests2", t21_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join1
new file mode 100644
index 0000000000..a3387f48a3
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join1
@@ -0,0 +1,2 @@
+{specs,join,"spec_join1"}.
+{specs,join,"../specs2/spec_join2"}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join_sep1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join_sep1
new file mode 100644
index 0000000000..fe127eb4b9
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_join_sep1
@@ -0,0 +1,5 @@
+{specs,join,"spec_sep1"}.
+{specs,join,"../specs2/spec_sep2"}.
+
+{config, "../config1/cfg13"}.
+{suites, "../tests2", t23_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep1
new file mode 100644
index 0000000000..c778aa68a6
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep1
@@ -0,0 +1,2 @@
+{specs,separate,"spec_sep1"}.
+{specs,separate,"../specs2/spec_sep2"}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep_join1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep_join1
new file mode 100644
index 0000000000..7cb5a05fff
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/rec_spec_sep_join1
@@ -0,0 +1,2 @@
+{specs,separate,"spec_join1"}.
+{specs,separate,"../specs2/spec_join2"}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both1
new file mode 100644
index 0000000000..46111614dc
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both1
@@ -0,0 +1,2 @@
+{specs, join, "../specs1/flat_spec1"}.
+{specs, separate, "../specs2/flat_spec2"}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both_join1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both_join1
new file mode 100644
index 0000000000..f52b3ed030
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_both_join1
@@ -0,0 +1,6 @@
+{specs, join, "../specs1/flat_spec1"}.
+{specs, separate, "../specs2/flat_spec2"}.
+{merge_tests,false}.
+{config, "../config1/cfg12"}.
+{suites, "../tests1", t11_SUITE}.
+{suites, "../tests2", t21_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_join1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_join1
new file mode 100644
index 0000000000..baaaf35be4
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_join1
@@ -0,0 +1 @@
+{specs, join, ["../specs2/flat_spec2", "flat_spec1"]}. \ No newline at end of file
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_sep1 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_sep1
new file mode 100644
index 0000000000..89456c35e0
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs1/spec_sep1
@@ -0,0 +1,3 @@
+{specs, separate, "../specs2/flat_spec2"}.
+{specs, separate, "flat_spec1"}.
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/flat_spec2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/flat_spec2
new file mode 100644
index 0000000000..758d1e2514
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/flat_spec2
@@ -0,0 +1,5 @@
+{merge_tests, false}.
+{config, "../config2/cfg21"}.
+{suites, "../tests1", t12_SUITE}.
+{suites, "../tests1", t12_SUITE}.
+{suites, "../tests2", t22_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join2
new file mode 100644
index 0000000000..19d3a3d8e2
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join2
@@ -0,0 +1,5 @@
+{specs,join,"spec_join2"}.
+{specs,join,"../specs1/spec_join1"}.
+
+{config, "../config1/cfg13"}.
+{suites, "../tests2", t23_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join_sep2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join_sep2
new file mode 100644
index 0000000000..930e68c847
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_join_sep2
@@ -0,0 +1,5 @@
+{specs,join,"spec_sep2"}.
+{specs,join,"../specs1/spec_sep1"}.
+
+{config, "../config1/cfg13"}.
+{suites, "../tests2", t23_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep2
new file mode 100644
index 0000000000..5026f329a7
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep2
@@ -0,0 +1,5 @@
+{specs,separate,"spec_sep2"}.
+{specs,separate,"../specs1/spec_sep1"}.
+
+{config, "../config1/cfg13"}.
+{suites, "../tests2", t23_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep_join2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep_join2
new file mode 100644
index 0000000000..17057088b4
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/rec_spec_sep_join2
@@ -0,0 +1,5 @@
+{specs,separate,"spec_join2"}.
+{specs,separate,"../specs1/spec_join1"}.
+
+{config, "../config1/cfg13"}.
+{suites, "../tests2", t23_SUITE}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both2
new file mode 100644
index 0000000000..4c83115d23
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both2
@@ -0,0 +1,4 @@
+{specs, separate, "../specs1/flat_spec1"}.
+{specs, join, "../specs2/flat_spec2"}.
+{config, "../config1/cfg12"}.
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both_join2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both_join2
new file mode 100644
index 0000000000..ad81bfb4cc
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_both_join2
@@ -0,0 +1,9 @@
+{merge_tests,true}.
+{config, "../config1/cfg12"}.
+{suites, "../tests1", t11_SUITE}.
+{suites, "../tests2", t21_SUITE}.
+{suites, "../tests1", t12_SUITE}.
+{suites, "../tests2", t22_SUITE}.
+
+{specs, separate, "../specs1/flat_spec1"}.
+{specs, join, "../specs2/flat_spec2"}.
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_join2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_join2
new file mode 100644
index 0000000000..d652dbd78f
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_join2
@@ -0,0 +1,5 @@
+{specs, join, ["../specs1/flat_spec1"]}.
+{specs, join, ["flat_spec2"]}.
+{config, "../config1/cfg12"}.
+{suites, "../tests2", t22_SUITE}.
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_sep2 b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_sep2
new file mode 100644
index 0000000000..8d37f508b8
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/specs2/spec_sep2
@@ -0,0 +1,5 @@
+{specs, separate, "../specs1/flat_spec1"}.
+{specs, separate, "flat_spec2"}.
+{config, "../config1/cfg12"}.
+{suites, "../tests2", t22_SUITE}.
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl
new file mode 100644
index 0000000000..bbe79ed3fe
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t11_SUITE.erl
@@ -0,0 +1,175 @@
+%%
+%% %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(t11_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% @spec suite() -> Info
+%% Info = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+suite() ->
+ [{require,file},
+ {require,tcname},
+ {timetrap,{seconds,1}}].
+
+%%--------------------------------------------------------------------
+%% @spec init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ %% verify that expected config file can be read
+ case {ct:get_config(tcname),ct:get_config(file,undefined,[all])} of
+ {start_separate,[cfg11]} -> ok;
+ {start_join,[cfg11,cfg21]} -> ok;
+ {incl_separate1,[cfg11]} -> ok;
+ {incl_separate2,[cfg11]} -> ok;
+ {incl_join1,[cfg21,cfg11]} -> ok;
+ {incl_join1,[cfg12,cfg11,cfg21]} -> ok;
+ {incl_join2,[cfg21,cfg11,cfg12]} -> ok;
+ {incl_both1,[cfg11]} -> ok;
+ {incl_both2,[cfg11,cfg12,cfg21]} -> ok;
+ {incl_both2,[cfg11]} -> ok;
+ _ -> ok
+
+ end,
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(autoskip_tc, Config) ->
+ exit(kaboom),
+ Config;
+
+init_per_testcase(userskip_tc, Config) ->
+ {skip,"user skipped"};
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%% @end
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% @spec all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [ok_tc, exit_tc, to_tc, autoskip_tc, userskip_tc].
+
+%%--------------------------------------------------------------------
+%% @spec TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%% @end
+%%--------------------------------------------------------------------
+ok_tc(_) ->
+ ok.
+
+exit_tc(_) ->
+ exit(kaboom),
+ ok.
+
+to_tc(_) ->
+ ct:timetrap(1),
+ ct:sleep(100),
+ ok.
+
+autoskip_tc(_) ->
+ ok.
+
+userskip_tc(_) ->
+ ok.
+
+
+
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl
new file mode 100644
index 0000000000..810298d348
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests1/t12_SUITE.erl
@@ -0,0 +1,175 @@
+%%
+%% %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(t12_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% @spec suite() -> Info
+%% Info = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+suite() ->
+ [{require,file},
+ {require,tcname},
+ {timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% @spec init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ %% verify that expected config file can be read
+ case {ct:get_config(tcname),ct:get_config(file,undefined,[all])} of
+ {start_separate,[cfg21]} -> ok;
+ {start_join,[cfg11,cfg21]} -> ok;
+ {incl_separate1,[cfg21]} -> ok;
+ {incl_separate2,[cfg21]} -> ok;
+ {incl_join1,[cfg21,cfg11]} -> ok;
+ {incl_join1,[cfg12,cfg11,cfg21]} -> ok;
+ {incl_join2,[cfg21,cfg11,cfg12]} -> ok;
+ {incl_both1,[cfg21]} -> ok;
+ {incl_both1,[cfg12,cfg21]} -> ok;
+ {incl_both2,[cfg11,cfg12,cfg21]} -> ok;
+ {incl_both2,[cfg21]} -> ok;
+ _ -> ok
+ end,
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(autoskip_tc, Config) ->
+ exit(kaboom),
+ Config;
+
+init_per_testcase(userskip_tc, Config) ->
+ {skip,"user skipped"};
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%% @end
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% @spec all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [ok_tc, exit_tc, to_tc, autoskip_tc, userskip_tc].
+
+%%--------------------------------------------------------------------
+%% @spec TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%% @end
+%%--------------------------------------------------------------------
+ok_tc(_) ->
+ ok.
+
+exit_tc(_) ->
+ exit(kaboom),
+ ok.
+
+to_tc(_) ->
+ ct:timetrap(1),
+ ct:sleep(100),
+ ok.
+
+autoskip_tc(_) ->
+ ok.
+
+userskip_tc(_) ->
+ ok.
+
+
+
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl
new file mode 100644
index 0000000000..9348cd8caf
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t21_SUITE.erl
@@ -0,0 +1,174 @@
+%%
+%% %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(t21_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% @spec suite() -> Info
+%% Info = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+suite() ->
+ [{require,file},
+ {require,tcname},
+ {timetrap,{seconds,1}}].
+
+%%--------------------------------------------------------------------
+%% @spec init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ %% verify that expected config file can be read
+ case {ct:get_config(tcname),ct:get_config(file,undefined,[all])} of
+ {start_separate,[cfg11]} -> ok;
+ {start_join,[cfg11,cfg21]} -> ok;
+ {incl_separate1,[cfg11]} -> ok;
+ {incl_separate2,[cfg11]} -> ok;
+ {incl_join1,[cfg21,cfg11]} -> ok;
+ {incl_join1,[cfg12,cfg11,cfg21]} -> ok;
+ {incl_join2,[cfg21,cfg11,cfg12]} -> ok;
+ {incl_both1,[cfg11]} -> ok;
+ {incl_both2,[cfg11,cfg12,cfg21]} -> ok;
+ {incl_both2,[cfg11]} -> ok;
+ _ -> ok
+ end,
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(autoskip_tc, Config) ->
+ exit(kaboom),
+ Config;
+
+init_per_testcase(userskip_tc, Config) ->
+ {skip,"user skipped"};
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%% @end
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% @spec all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [ok_tc, exit_tc, to_tc, autoskip_tc, userskip_tc].
+
+%%--------------------------------------------------------------------
+%% @spec TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%% @end
+%%--------------------------------------------------------------------
+ok_tc(_) ->
+ ok.
+
+exit_tc(_) ->
+ exit(kaboom),
+ ok.
+
+to_tc(_) ->
+ ct:timetrap(1),
+ ct:sleep(100),
+ ok.
+
+autoskip_tc(_) ->
+ ok.
+
+userskip_tc(_) ->
+ ok.
+
+
+
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl
new file mode 100644
index 0000000000..a92018ec70
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t22_SUITE.erl
@@ -0,0 +1,177 @@
+%%
+%% %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(t22_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% @spec suite() -> Info
+%% Info = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+suite() ->
+ [{require,file},
+ {require,tcname},
+ {timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% @spec init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ %% verify that expected config file can be read
+ case {ct:get_config(tcname),ct:get_config(file,undefined,[all])} of
+ {start_separate,[cfg21]} -> ok;
+ {start_join,[cfg11,cfg21]} -> ok;
+ {incl_separate1,[cfg12]} -> ok;
+ {incl_separate1,[cfg21]} -> ok;
+ {incl_separate2,[cfg12]} -> ok;
+ {incl_separate2,[cfg21]} -> ok;
+ {incl_join1,[cfg21,cfg11]} -> ok;
+ {incl_join1,[cfg12,cfg11,cfg21]} -> ok;
+ {incl_join2,[cfg21,cfg11,cfg12]} -> ok;
+ {incl_both1,[cfg21]} -> ok;
+ {incl_both1,[cfg12,cfg21]} -> ok;
+ {incl_both2,[cfg11,cfg12,cfg21]} -> ok;
+ {incl_both2,[cfg21]} -> ok;
+ _ -> ok
+ end,
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(autoskip_tc, Config) ->
+ exit(kaboom),
+ Config;
+
+init_per_testcase(userskip_tc, Config) ->
+ {skip,"user skipped"};
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%% @end
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% @spec all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [ok_tc, exit_tc, to_tc, autoskip_tc, userskip_tc].
+
+%%--------------------------------------------------------------------
+%% @spec TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%% @end
+%%--------------------------------------------------------------------
+ok_tc(_) ->
+ ok.
+
+exit_tc(_) ->
+ exit(kaboom),
+ ok.
+
+to_tc(_) ->
+ ct:timetrap(1),
+ ct:sleep(100),
+ ok.
+
+autoskip_tc(_) ->
+ ok.
+
+userskip_tc(_) ->
+ ok.
+
+
+
+
diff --git a/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl
new file mode 100644
index 0000000000..d01fac3144
--- /dev/null
+++ b/lib/common_test/test/ct_testspec_3_SUITE_data/tests2/t23_SUITE.erl
@@ -0,0 +1,158 @@
+%%
+%% %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(t23_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% @spec suite() -> Info
+%% Info = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% @spec init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% @end
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(autoskip_tc, Config) ->
+ exit(kaboom),
+ Config;
+
+init_per_testcase(userskip_tc, Config) ->
+ {skip,"user skipped"};
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @spec end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%% @end
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% @spec all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [ok_tc, exit_tc, to_tc, autoskip_tc, userskip_tc].
+
+%%--------------------------------------------------------------------
+%% @spec TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%% @end
+%%--------------------------------------------------------------------
+ok_tc(_) ->
+ ok.
+
+exit_tc(_) ->
+ exit(kaboom),
+ ok.
+
+to_tc(_) ->
+ ct:timetrap(1),
+ ct:sleep(100),
+ ok.
+
+autoskip_tc(_) ->
+ ok.
+
+userskip_tc(_) ->
+ ok.
+
+
+
+
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index 8d54dffd73..c6d09d85eb 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -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
@@ -122,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
# ----------------------------------------------------
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 3e0050382c..cf5244e1ce 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index 81be262d6d..cf5455dfde 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. 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
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index 02794a8e18..fdfcb08125 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.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
diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl
index 26ba93b91c..e208ffec1f 100644
--- a/lib/compiler/src/beam_clean.erl
+++ b/lib/compiler/src/beam_clean.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 92d8e5acb3..b15adfa889 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl
index ff6c7c11dc..212b9fb03a 100644
--- a/lib/compiler/src/beam_dict.erl
+++ b/lib/compiler/src/beam_dict.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
@@ -138,17 +138,7 @@ string(Str, Dict) when is_list(Str) ->
-spec lambda(label(), non_neg_integer(), bdict()) ->
{non_neg_integer(), bdict()}.
-lambda(Lbl, 0, #asm{lambdas=Lambdas0}=Dict) ->
- case lists:keyfind(Lbl, 1, Lambdas0) of
- {Lbl,{OldIndex,_,_,_,_}} ->
- {OldIndex,Dict};
- false ->
- new_lambda(Lbl, 0, Dict)
- end;
-lambda(Lbl, NumFree, Dict) ->
- new_lambda(Lbl, NumFree, Dict).
-
-new_lambda(Lbl, NumFree, #asm{lambdas=Lambdas0}=Dict) ->
+lambda(Lbl, NumFree, #asm{lambdas=Lambdas0}=Dict) ->
OldIndex = length(Lambdas0),
%% Set Index the same as OldIndex.
Index = OldIndex,
@@ -245,12 +235,10 @@ string_table(#asm{strings=Strings,string_offset=Size}) ->
-spec lambda_table(bdict()) -> {non_neg_integer(), [<<_:192>>]}.
-lambda_table(#asm{exports=Ext0,locals=Loc0,lambdas=Lambdas0}) ->
+lambda_table(#asm{locals=Loc0,lambdas=Lambdas0}) ->
Lambdas1 = sofs:relation(Lambdas0),
Loc = sofs:relation([{Lbl,{F,A}} || {F,A,Lbl} <- Loc0]),
- Ext = sofs:relation([{Lbl,{F,A}} || {F,A,Lbl} <- Ext0]),
- All = sofs:union(Loc, Ext),
- Lambdas2 = sofs:relative_product1(Lambdas1, All),
+ Lambdas2 = sofs:relative_product1(Lambdas1, Loc),
Lambdas = [<<F:32,A:32,Lbl:32,Index:32,NumFree:32,OldUniq:32>> ||
{{_,Lbl,Index,NumFree,OldUniq},{F,A}} <- sofs:to_external(Lambdas2)],
{length(Lambdas),Lambdas}.
diff --git a/lib/compiler/src/beam_except.erl b/lib/compiler/src/beam_except.erl
index 14e9943f88..eddb41a358 100644
--- a/lib/compiler/src/beam_except.erl
+++ b/lib/compiler/src/beam_except.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011. 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
diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl
index 04232d8fd2..25428c0c10 100644
--- a/lib/compiler/src/beam_flatten.erl
+++ b/lib/compiler/src/beam_flatten.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. 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
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index 636c299e47..b29a3565e4 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl
index a199aa50ed..97a8c7ba70 100644
--- a/lib/compiler/src/beam_peep.erl
+++ b/lib/compiler/src/beam_peep.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. 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
diff --git a/lib/compiler/src/beam_receive.erl b/lib/compiler/src/beam_receive.erl
index fe95a7e35b..0bb527aeb9 100644
--- a/lib/compiler/src/beam_receive.erl
+++ b/lib/compiler/src/beam_receive.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. 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
diff --git a/lib/compiler/src/beam_trim.erl b/lib/compiler/src/beam_trim.erl
index d95db1f681..fad9c42584 100644
--- a/lib/compiler/src/beam_trim.erl
+++ b/lib/compiler/src/beam_trim.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
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 29758b8fb4..58aba0b9cc 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.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
@@ -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 5f394f0b65..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,
@@ -1089,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);
@@ -1419,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 9a02121d8b..8775c84698 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.app.src
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %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
diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl
index 21296a8b66..8b688df830 100644
--- a/lib/compiler/src/core_lint.erl
+++ b/lib/compiler/src/core_lint.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. 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
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index f17b0bd130..d5fec0c869 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -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
@@ -2672,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).
@@ -2689,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.
@@ -2698,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.
@@ -2748,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;
@@ -2872,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/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index b1bff47f69..5f1c108f7c 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -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
@@ -235,8 +235,16 @@ gexpr_test_add(Ke, St0) ->
%% expr(Cexpr, Sub, State) -> {Kexpr,[PreKexpr],State}.
%% Convert a Core expression, flattening it at the same time.
-expr(#c_var{anno=A,name={Name,Arity}}, Sub, St) ->
- {#k_local{anno=A,name=get_fsub(Name, Arity, Sub),arity=Arity},[],St};
+expr(#c_var{anno=A,name={_Name,Arity}}=Fname, Sub, St) ->
+ %% A local in an expression.
+ %% For now, these are wrapped into a fun by reverse
+ %% etha-conversion, but really, there should be exactly one
+ %% such "lambda function" for each escaping local name,
+ %% instead of one for each occurrence as done now.
+ Vs = [#c_var{name=list_to_atom("V" ++ integer_to_list(V))} ||
+ V <- integers(1, Arity)],
+ Fun = #c_fun{anno=A,vars=Vs,body=#c_apply{anno=A,op=Fname,args=Vs}},
+ expr(Fun, Sub, St);
expr(#c_var{anno=A,name=V}, Sub, St) ->
{#k_var{anno=A,name=get_vsub(V, Sub)},[],St};
expr(#c_literal{anno=A,val=V}, _Sub, St) ->
@@ -1655,19 +1663,6 @@ uexpr(#ifun{anno=A,vars=Vs,body=B0}, {break,Rs}, St0) ->
#k_int{val=Index},#k_int{val=Uniq}|Fvs],
ret=Rs},
Free,add_local_function(Fun, St)};
-uexpr(#k_local{anno=A,name=Name,arity=Arity}, {break,Rs}, St) ->
- Fs = get_free(Name, Arity, St),
- FsCount = length(Fs),
- Free = lit_list_vars(Fs),
- %% Set dummy values for Index and Uniq -- the real values will
- %% be assigned by beam_asm.
- Index = Uniq = 0,
- Bif = #k_bif{anno=#k{us=Free,ns=lit_list_vars(Rs),a=A},
- op=#k_internal{name=make_fun,arity=FsCount+3},
- args=[#k_atom{val=Name},#k_int{val=FsCount+Arity},
- #k_int{val=Index},#k_int{val=Uniq}|Fs],
- ret=Rs},
- {Bif,Free,St};
uexpr(Lit, {break,Rs0}, St0) ->
%% Transform literals to puts here.
%%ok = io:fwrite("uexpr ~w:~p~n", [?LINE,Lit]),
@@ -1848,6 +1843,12 @@ make_list(Es) ->
#c_cons{hd=E,tl=Acc}
end, #c_literal{val=[]}, Es).
+%% List of integers in interval [N,M]. Empty list if N > M.
+
+integers(N, M) when N =< M ->
+ [N|integers(N + 1, M)];
+integers(_, _) -> [].
+
%% is_in_guard(State) -> true|false.
is_in_guard(#kern{guard_refc=Refc}) ->
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index fe69aeeb43..0d00769704 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. 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
diff --git a/lib/compiler/test/beam_except_SUITE.erl b/lib/compiler/test/beam_except_SUITE.erl
index 6b55224a42..bf67eedd5f 100644
--- a/lib/compiler/test/beam_except_SUITE.erl
+++ b/lib/compiler/test/beam_except_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011. 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
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index c84c83795a..bc1a9e2b3b 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.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
diff --git a/lib/compiler/test/bs_bit_binaries_SUITE.erl b/lib/compiler/test/bs_bit_binaries_SUITE.erl
index 897b4769f1..8609a490f5 100644
--- a/lib/compiler/test/bs_bit_binaries_SUITE.erl
+++ b/lib/compiler/test/bs_bit_binaries_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index d63d2235d7..9f15845d33 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -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/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 2adc71c237..53a65d8d17 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.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
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 66c0b9a295..5656d23090 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. 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
diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl
index 6dc7548437..d9b92766e4 100644
--- a/lib/compiler/test/inline_SUITE.erl
+++ b/lib/compiler/test/inline_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index de44926d81..ae7d764535 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.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
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 82c823b789..b91f2922fb 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.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
diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl
index 96f3712be9..c9f5a2053e 100644
--- a/lib/compiler/test/record_SUITE.erl
+++ b/lib/compiler/test/record_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2011. 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
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index 996c369705..a8befbecd9 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2011. 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
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index 9ce0df5ec4..f00bfe663b 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2011. 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
diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
index 18a591a7af..dfe6fabfab 100644
--- a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
+++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 14c77c873f..6b9b2ef207 100755
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2012</year>
+ <year>1999</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/crypto/doc/src/crypto_app.xml b/lib/crypto/doc/src/crypto_app.xml
index 6573a56f4c..8371db1ff2 100644
--- a/lib/crypto/doc/src/crypto_app.xml
+++ b/lib/crypto/doc/src/crypto_app.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile
index 5c200742ac..574c2076f2 100644
--- a/lib/crypto/src/Makefile
+++ b/lib/crypto/src/Makefile
@@ -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
@@ -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
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index aa89f6cc61..1328a95e87 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -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
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 142f06677a..6f2df0f07b 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -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
diff --git a/lib/debugger/src/Makefile b/lib/debugger/src/Makefile
index cadde8cd1b..85754da219 100644
--- a/lib/debugger/src/Makefile
+++ b/lib/debugger/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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
@@ -98,7 +98,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard
+ERL_COMPILE_FLAGS += +warn_obsolete_guard -Werror
# ----------------------------------------------------
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_settings.erl b/lib/debugger/src/dbg_wx_settings.erl
index 94ecc5781d..20aac74c3d 100644
--- a/lib/debugger/src/dbg_wx_settings.erl
+++ b/lib/debugger/src/dbg_wx_settings.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. 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
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/debugger/test/erl_eval_SUITE.erl b/lib/debugger/test/erl_eval_SUITE.erl
index c675f704b4..bb2669f450 100644
--- a/lib/debugger/test/erl_eval_SUITE.erl
+++ b/lib/debugger/test/erl_eval_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2011. 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
diff --git a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
index 0d7883f067..c5c6a56363 100644
--- a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
+++ b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
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..6f189099ed
--- /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 (_) -> [[{_,_}]]
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/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 d241e2bd19..1258e8e85d 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -11,7 +11,7 @@
<header>
<copyright>
<year>2011</year>
-<year>2012</year>
+<year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
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 60bb7e6a10..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) \
@@ -123,6 +123,12 @@ gen/diameter_gen_%.erl gen/diameter_gen_%.hrl: dict/%.dia
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
@@ -133,8 +139,10 @@ gen/$(DICT_YRL).erl: compiler/$(DICT_YRL).yrl
# Generate the app file.
$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk
$(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
@@ -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..ceefb9b398 100644
--- a/lib/diameter/src/base/diameter.app.src
+++ b/lib/diameter/src/base/diameter.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. 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
@@ -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 a04a387918..f6d772b534 100644
--- a/lib/diameter/src/base/diameter.appup.src
+++ b/lib/diameter/src/base/diameter.appup.src
@@ -26,7 +26,8 @@
{"1.1", [{restart_application, diameter}]},
{"1.2", [{restart_application, diameter}]},
{"1.2.1", [{restart_application, diameter}]},
- {"1.3", [{load_module, diameter_service}]}
+ {"1.3", [{restart_application, diameter}]},
+ {"1.3.1", [{restart_application, diameter}]}
],
[
{"0.9", [{restart_application, diameter}]},
@@ -35,6 +36,7 @@
{"1.1", [{restart_application, diameter}]},
{"1.2", [{restart_application, diameter}]},
{"1.2.1", [{restart_application, diameter}]},
- {"1.3", [{load_module, diameter_service}]}
+ {"1.3", [{restart_application, diameter}]},
+ {"1.3.1", [{restart_application, diameter}]}
]
}.
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 858870566f..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,
@@ -401,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) ->
@@ -508,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
@@ -585,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
@@ -1021,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 b5584ca0d0..d2a416166f 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -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)
%%% ---------------------------------------------------------------------------
@@ -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.
@@ -1819,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] ->
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/vsn.mk b/lib/diameter/vsn.mk
index 7b2208137b..74f4c57b70 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -18,8 +18,5 @@
# %CopyrightEnd%
APPLICATION = diameter
-DIAMETER_VSN = 1.3.1
-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/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index 04dad2eee7..30767abd7e 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2012</year>
+ <year>2012</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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 ad93e1087a..ebb7967e11 100644
--- a/lib/eldap/src/Makefile
+++ b/lib/eldap/src/Makefile
@@ -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
@@ -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
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..c15b16eb5b 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -3,7 +3,7 @@
#
# %CopyrightBegin%
#
- # Copyright Ericsson AB 2009-2012. All Rights Reserved.
+ # Copyright Ericsson AB 2009-2013. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -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/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 918e30a886..25f40944e7 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 539e16d837..03eea49224 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2011</year>
+ <year>2001</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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..a7921ea9d2 100644
--- a/lib/erl_interface/doc/src/erl_eterm.xml
+++ b/lib/erl_interface/doc/src/erl_eterm.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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..29d53ab3a2 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. 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
@@ -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..7f44cb83bd 100644
--- a/lib/erl_interface/include/erl_interface.h
+++ b/lib/erl_interface/include/erl_interface.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. 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
@@ -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 03e2ce14f0..a069aa07ab 100644
--- a/lib/erl_interface/src/Makefile
+++ b/lib/erl_interface/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2009. 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
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 34362b4b9f..c1361e169e 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
@@ -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..42ab9b58d7 100644
--- a/lib/erl_interface/src/connect/ei_connect_int.h
+++ b/lib/erl_interface/src/connect/ei_connect_int.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. 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
@@ -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/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c
index 79d259b92d..2545c5f3de 100644
--- a/lib/erl_interface/src/connect/ei_resolve.c
+++ b/lib/erl_interface/src/connect/ei_resolve.c
@@ -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
diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c
index 86852f947d..1821de3844 100644
--- a/lib/erl_interface/src/connect/eirecv.c
+++ b/lib/erl_interface/src/connect/eirecv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. 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
@@ -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..af4fc114d1 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -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
@@ -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..8c44a1ccfc 100644
--- a/lib/erl_interface/src/decode/decode_boolean.c
+++ b/lib/erl_interface/src/decode/decode_boolean.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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..c4667822e5 100644
--- a/lib/erl_interface/src/decode/decode_fun.c
+++ b/lib/erl_interface/src/decode/decode_fun.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. 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
@@ -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..67ce7e05f9 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -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
@@ -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..2d1b46e705 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -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
@@ -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..579371ed7d 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -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
@@ -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..32f5ae2af1 100644
--- a/lib/erl_interface/src/encode/encode_atom.c
+++ b/lib/erl_interface/src/encode/encode_atom.c
@@ -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
@@ -22,29 +22,112 @@
#include "eiext.h"
#include "putget.h"
+
+static int verify_ascii_atom(const char* src, int slen);
+static int verify_utf8_atom(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 (verify_ascii_atom(p, len) < 0) return -1;
+ memcpy(s+2, p, len);
+ 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;
+ } else if (from_enc == ERLANG_ASCII)
+ if (verify_ascii_atom(p, 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 (verify_ascii_atom(p, len) < 0) return -1;
+ if (buf) memcpy(s+offs,p,len);
+ break;
+ case ERLANG_UTF8:
+ if (len >= 256) offs++;
+ if (verify_utf8_atom(p, len) < 0) return -1;
+ if (buf) memcpy(s+offs,p,len);
+ 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 +136,55 @@ 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 verify_ascii_atom(const char* src, int slen)
+{
+ while (slen > 0) {
+ if ((src[0] & 0x80) != 0) return -1;
+ src++;
+ slen--;
+ }
+ return 0;
+}
+
+int verify_utf8_atom(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;
+ src++;
+ slen--;
+ }
+ else if ((src[0] & 0xF0) == 0xE0) {
+ if (slen < 3 || (src[1] & 0xC0) != 0x80 || (src[2] & 0xC0) != 0x80) return -1;
+ src += 2;
+ 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;
+ src += 3;
+ slen -= 3;
+ }
+ else return -1;
+ }
+ 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..455d8a5a94 100644
--- a/lib/erl_interface/src/encode/encode_fun.c
+++ b/lib/erl_interface/src/encode/encode_fun.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. 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
@@ -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..903c9cce00 100644
--- a/lib/erl_interface/src/encode/encode_pid.c
+++ b/lib/erl_interface/src/encode/encode_pid.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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..c729aeb4eb 100644
--- a/lib/erl_interface/src/encode/encode_port.c
+++ b/lib/erl_interface/src/encode/encode_port.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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..3511366bef 100644
--- a/lib/erl_interface/src/encode/encode_ref.c
+++ b/lib/erl_interface/src/encode/encode_ref.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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..eca16497dc 100644
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ b/lib/erl_interface/src/legacy/erl_connect.c
@@ -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
@@ -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..9e778a299e 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ b/lib/erl_interface/src/legacy/erl_eterm.c
@@ -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
@@ -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..ca4ec7925a 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.h
+++ b/lib/erl_interface/src/legacy/erl_eterm.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. 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
@@ -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..fda05cbdb8 100644
--- a/lib/erl_interface/src/legacy/erl_format.c
+++ b/lib/erl_interface/src/legacy/erl_format.c
@@ -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
@@ -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..c320a00bfe 100644
--- a/lib/erl_interface/src/legacy/erl_malloc.c
+++ b/lib/erl_interface/src/legacy/erl_malloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. 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
@@ -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..c051c3a597 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -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
@@ -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..589c9d17de 100644
--- a/lib/erl_interface/src/legacy/global_whereis.c
+++ b/lib/erl_interface/src/legacy/global_whereis.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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..1423ec7ed7 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2011. 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
@@ -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..07499213cd 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -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
@@ -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..95369db15a 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. 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
@@ -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..4e6f4a1d36 100644
--- a/lib/erl_interface/src/misc/ei_x_encode.c
+++ b/lib/erl_interface/src/misc/ei_x_encode.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. 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
@@ -99,7 +99,8 @@ 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 i = x->index;
- ei_encode_string_len(NULL, &i, s, len);
+ if (ei_encode_string_len(NULL, &i, s, len) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_string_len(x->buff, &x->index, s, len);
@@ -108,7 +109,8 @@ int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)
int ei_x_encode_binary(ei_x_buff* x, const void* p, int len)
{
int i = x->index;
- ei_encode_binary(NULL, &i, p, len);
+ if (ei_encode_binary(NULL, &i, p, len) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_binary(x->buff, &x->index, p, len);
@@ -117,7 +119,8 @@ int ei_x_encode_binary(ei_x_buff* x, const void* p, int len)
int ei_x_encode_long(ei_x_buff* x, long n)
{
int i = x->index;
- ei_encode_long(NULL, &i, n);
+ if (ei_encode_long(NULL, &i, n) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_long(x->buff, &x->index, n);
@@ -126,7 +129,8 @@ int ei_x_encode_long(ei_x_buff* x, long n)
int ei_x_encode_ulong(ei_x_buff* x, unsigned long n)
{
int i = x->index;
- ei_encode_ulong(NULL, &i, n);
+ if (ei_encode_ulong(NULL, &i, n) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_ulong(x->buff, &x->index, n);
@@ -135,7 +139,8 @@ int ei_x_encode_ulong(ei_x_buff* x, unsigned long n)
int ei_x_encode_char(ei_x_buff* x, char p)
{
int i = x->index;
- ei_encode_char(NULL, &i, p);
+ if (ei_encode_char(NULL, &i, p) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_char(x->buff, &x->index, p);
@@ -144,7 +149,8 @@ int ei_x_encode_char(ei_x_buff* x, char p)
int ei_x_encode_boolean(ei_x_buff* x, int p)
{
int i = x->index;
- ei_encode_boolean(NULL, &i, p);
+ if (ei_encode_boolean(NULL, &i, p) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_boolean(x->buff, &x->index, p);
@@ -153,7 +159,8 @@ int ei_x_encode_boolean(ei_x_buff* x, int p)
int ei_x_encode_double(ei_x_buff* x, double dbl)
{
int i = x->index;
- ei_encode_double(NULL, &i, dbl);
+ if (ei_encode_double(NULL, &i, dbl) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_double(x->buff, &x->index, dbl);
@@ -162,7 +169,8 @@ int ei_x_encode_double(ei_x_buff* x, double dbl)
int ei_x_encode_list_header(ei_x_buff* x, long n)
{
int i = x->index;
- ei_encode_list_header(NULL, &i, n);
+ if (ei_encode_list_header(NULL, &i, n) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_list_header(x->buff, &x->index, n);
@@ -171,7 +179,8 @@ int ei_x_encode_list_header(ei_x_buff* x, long n)
int ei_x_encode_empty_list(ei_x_buff* x)
{
int i = x->index;
- ei_encode_empty_list(NULL, &i);
+ if (ei_encode_empty_list(NULL, &i) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_empty_list(x->buff, &x->index);
@@ -180,7 +189,8 @@ int ei_x_encode_empty_list(ei_x_buff* x)
int ei_x_encode_version(ei_x_buff* x)
{
int i = x->index;
- ei_encode_version(NULL, &i);
+ if (ei_encode_version(NULL, &i) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_version(x->buff, &x->index);
@@ -189,7 +199,8 @@ int ei_x_encode_version(ei_x_buff* x)
int ei_x_encode_tuple_header(ei_x_buff* x, long n)
{
int i = x->index;
- ei_encode_tuple_header(NULL, &i, n);
+ if (ei_encode_tuple_header(NULL, &i, n) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_tuple_header(x->buff, &x->index, n);
@@ -197,22 +208,39 @@ 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);
+ if (ei_encode_atom_len_as(NULL, &i, s, len, from_enc, to_enc) == -1)
+ return -1;
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;
- ei_encode_pid(NULL, &i, pid);
+ if (ei_encode_pid(NULL, &i, pid) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_pid(x->buff, &x->index, pid);
@@ -221,7 +249,8 @@ int ei_x_encode_pid(ei_x_buff* x, const erlang_pid* pid)
int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)
{
int i = x->index;
- ei_encode_fun(NULL, &i, fun);
+ if (ei_encode_fun(NULL, &i, fun) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_fun(x->buff, &x->index, fun);
@@ -230,7 +259,8 @@ int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)
int ei_x_encode_ref(ei_x_buff* x, const erlang_ref* ref)
{
int i = x->index;
- ei_encode_ref(NULL, &i, ref);
+ if (ei_encode_ref(NULL, &i, ref) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_ref(x->buff, &x->index, ref);
@@ -239,7 +269,8 @@ int ei_x_encode_ref(ei_x_buff* x, const erlang_ref* ref)
int ei_x_encode_port(ei_x_buff* x, const erlang_port* port)
{
int i = x->index;
- ei_encode_port(NULL, &i, port);
+ if (ei_encode_port(NULL, &i, port) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_port(x->buff, &x->index, port);
@@ -248,7 +279,8 @@ int ei_x_encode_port(ei_x_buff* x, const erlang_port* port)
int ei_x_encode_trace(ei_x_buff* x, const erlang_trace* trace)
{
int i = x->index;
- ei_encode_trace(NULL, &i, trace);
+ if (ei_encode_trace(NULL, &i, trace) == -1)
+ return -1;
if (!x_fix_buff(x, i))
return -1;
return ei_encode_trace(x->buff, &x->index, trace);
diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c
index 2a680d0f94..2bd992bd56 100644
--- a/lib/erl_interface/src/misc/get_type.c
+++ b/lib/erl_interface/src/misc/get_type.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. 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
@@ -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..587bf1a0f8 100644
--- a/lib/erl_interface/src/misc/putget.h
+++ b/lib/erl_interface/src/misc/putget.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. 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
@@ -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..935a9a3287 100644
--- a/lib/erl_interface/src/misc/show_msg.c
+++ b/lib/erl_interface/src/misc/show_msg.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. 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
@@ -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..52a46fc341 100644
--- a/lib/erl_interface/src/prog/ei_fake_prog.c
+++ b/lib/erl_interface/src/prog/ei_fake_prog.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
@@ -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/all_SUITE_data/init_tc.erl b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
index 7e370c566a..0f2ac215f9 100644
--- a/lib/erl_interface/test/all_SUITE_data/init_tc.erl
+++ b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
@@ -40,7 +40,7 @@ run([]) ->
run1(Name) ->
CFile = Name ++ ".c",
{ok, Bin} = file:read_file(CFile),
- RE = "\nTESTCASE\\(([_a-zA-Z]*)\\)",
+ RE = "\nTESTCASE\\(([_a-zA-Z0-9]*)\\)",
{match, Cases0} = re:run(Bin, RE, [{capture,all_but_first,list},global]),
Cases = lists:concat(Cases0),
generate(Name, Cases).
diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl
index 2c4b6e5541..5a94994912 100644
--- a/lib/erl_interface/test/ei_decode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_SUITE.erl
@@ -27,14 +27,16 @@
-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_group/2,end_per_group/2, init_per_testcase/2,
+ end_per_testcase/2,
test_ei_decode_long/1,
test_ei_decode_ulong/1,
test_ei_decode_longlong/1,
test_ei_decode_ulonglong/1,
test_ei_decode_char/1,
test_ei_decode_nonoptimal/1,
- test_ei_decode_misc/1
+ test_ei_decode_misc/1,
+ test_ei_decode_utf8_atom/1
]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -43,7 +45,7 @@ all() ->
[test_ei_decode_long, test_ei_decode_ulong,
test_ei_decode_longlong, test_ei_decode_ulonglong,
test_ei_decode_char, test_ei_decode_nonoptimal,
- test_ei_decode_misc].
+ test_ei_decode_misc, test_ei_decode_utf8_atom].
groups() ->
[].
@@ -60,6 +62,11 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(_TC, Config) ->
+ Config.
+
+end_per_testcase(_RC, Config) ->
+ Config.
%% ---------------------------------------------------------------------------
@@ -221,6 +228,29 @@ test_ei_decode_misc(Config) when is_list(Config) ->
?line runner:recv_eot(P),
ok.
+%% ######################################################################## %%
+
+test_ei_decode_utf8_atom(Config) ->
+ ?line P = runner:start(?test_ei_decode_utf8_atom),
+
+ send_utf8_atom_as_binary(P,"å"),
+ send_utf8_atom_as_binary(P,"ä"),
+ send_term_as_binary(P,'ö'),
+ send_term_as_binary(P,'õ'),
+
+ ?line send_utf8_atom_as_binary(P,[1758]),
+ ?line send_utf8_atom_as_binary(P,[1758,1758]),
+ ?line send_utf8_atom_as_binary(P,[1758,1758,1758]),
+ ?line send_utf8_atom_as_binary(P,[1758,1758,1758,1758]),
+
+ send_utf8_atom_as_binary(P,"a"),
+ send_utf8_atom_as_binary(P,"b"),
+ send_term_as_binary(P,'c'),
+ send_term_as_binary(P,'d'),
+
+ ?line runner:recv_eot(P),
+ ok.
+
%% ######################################################################## %%
@@ -230,6 +260,8 @@ send_term_as_binary(Port, Term) when is_port(Port) ->
send_raw(Port, Bin) when is_port(Port) ->
Port ! {self(), {command, Bin}}.
+send_utf8_atom_as_binary(Port, String) ->
+ Port ! {self(), {command, term_to_binary(uc_atup(String))}}.
send_integers(P) ->
?line send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest
@@ -304,3 +336,43 @@ send_integers2(P) ->
?line send_term_as_binary(P, 16#ffffffffffffffff), % largest u64
?line send_term_as_binary(P, []), % illegal type
ok.
+
+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_SUITE_data/ei_decode_test.c b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
index b349138ae9..6db04aa676 100644
--- a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
@@ -17,6 +17,8 @@
* %CopyrightEnd%
*/
+#include <string.h>
+
#ifdef VXWORKS
#include "reclaim.h"
#endif
@@ -38,6 +40,22 @@
err, size1, SIZE, (EI_LONGLONG)p);
#endif
+struct my_atom {
+ enum erlang_char_encoding from;
+ enum erlang_char_encoding was_check;
+ enum erlang_char_encoding result_check;
+};
+
+/* Allow arrays constants to be part of macro arguments */
+#define P99(...) __VA_ARGS__
+
+int ei_decode_my_atom_as(const char *buf, int *index, char *to,
+ struct my_atom *atom);
+int ei_decode_my_atom(const char *buf, int *index, char *to,
+ struct my_atom *atom);
+int ei_decode_my_string(const char *buf, int *index, char *to,
+ struct my_atom *atom);
+
#define EI_DECODE_2(FUNC,SIZE,TYPE,VAL) \
{ \
TYPE p; \
@@ -129,17 +147,26 @@
} \
} \
-#define EI_DECODE_STRING(FUNC,SIZE,VAL) \
+#define dump(arr, num) { \
+ int i; \
+ message("Dumping " #arr ": "); \
+ for (i = 0; i < num; i++) message("%u, ",(unsigned char)arr[i]); \
+ message("\n"); \
+ }
+
+#define EI_DECODE_STRING_4(FUNC,SIZE,VAL,ATOM) \
{ \
char p[1024]; \
char *buf; \
+ unsigned char val[] = VAL; \
int size1 = 0; \
int size2 = 0; \
int err; \
- message("ei_" #FUNC " should be " #VAL); \
+ struct my_atom atom = ATOM; \
+ message("ei_" #FUNC " should be " #VAL "\n"); \
buf = read_packet(NULL); \
\
- err = ei_ ## FUNC(buf+1, &size1, NULL); \
+ err = ei_ ## FUNC(buf+1, &size1, NULL, &atom); \
message("err = %d, size = %d, expected size = %d\n",err,size1,SIZE); \
if (err != 0) { \
if (err != -1) { \
@@ -150,7 +177,7 @@
return; \
} \
\
- err = ei_ ## FUNC(buf+1, &size2, p); \
+ err = ei_ ## FUNC(buf+1, &size2, p, &atom); \
message("err = %d, size = %d, expected size = %d\n",err,size2,SIZE); \
if (err != 0) { \
if (err != -1) { \
@@ -161,7 +188,7 @@
return; \
} \
\
- if (strcmp(p,VAL) != 0) { \
+ if (strcmp(p,val) != 0) { \
fail("value is not correct"); \
return; \
} \
@@ -177,6 +204,51 @@
} \
} \
+#define EI_DECODE_STRING(FUNC,SIZE,VAL) \
+ EI_DECODE_STRING_4(FUNC,SIZE,VAL, \
+ P99({ERLANG_ANY,ERLANG_ANY,ERLANG_ANY}))
+
+#define EI_DECODE_STRING_FAIL(FUNC,ATOM) \
+ { \
+ char p[1024]; \
+ char *buf; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ struct my_atom atom = ATOM;\
+ message("ei_" #FUNC " should fail\n"); \
+ p[0] = 0; \
+ message("p[0] is %d\n",p[0]); \
+ buf = read_packet(NULL); \
+\
+ err = ei_ ## FUNC(buf+1, &size1, NULL, &atom); \
+ if (err != -1) { \
+ fail("should return -1 if NULL pointer"); \
+ return; \
+ } \
+\
+ err = ei_ ## FUNC(buf+1, &size2, p, &atom); \
+ if (err != -1) { \
+ fail("should return -1"); \
+ return; \
+ } \
+ if (p[0] != 0) { \
+ message("p[0] argument was modified to %u\n",(unsigned char)p[0]); \
+ } \
+\
+ if (size1 != 0) { \
+ fail("size of encoded data should be 0 if NULL"); \
+ return; \
+ } \
+\
+ if (size2 != 0) { \
+ fail("size of encoded data should be 0"); \
+ return; \
+ } \
+ } \
+
+//#define EI_DECODE_UTF8_STRING(FUNC,SIZE,VAL)
+
#define EI_DECODE_BIN(FUNC,SIZE,VAL,LEN) \
{ \
char p[1024]; \
@@ -536,13 +608,13 @@ TESTCASE(test_ei_decode_misc)
EI_DECODE_2(decode_boolean, 8, int, 0);
EI_DECODE_2(decode_boolean, 7, int, 1);
- EI_DECODE_STRING(decode_atom, 6, "foo");
- EI_DECODE_STRING(decode_atom, 3, "");
- EI_DECODE_STRING(decode_atom, 9, "������");
+ EI_DECODE_STRING(decode_my_atom, 6, "foo");
+ EI_DECODE_STRING(decode_my_atom, 3, "");
+ EI_DECODE_STRING(decode_my_atom, 9, "������");
- EI_DECODE_STRING(decode_string, 6, "foo");
- EI_DECODE_STRING(decode_string, 1, "");
- EI_DECODE_STRING(decode_string, 9, "������");
+ EI_DECODE_STRING(decode_my_string, 6, "foo");
+ EI_DECODE_STRING(decode_my_string, 1, "");
+ EI_DECODE_STRING(decode_my_string, 9, "������");
EI_DECODE_BIN(decode_binary, 8, "foo", 3);
EI_DECODE_BIN(decode_binary, 5, "", 0);
@@ -559,3 +631,63 @@ TESTCASE(test_ei_decode_misc)
/* ******************************************************************** */
+TESTCASE(test_ei_decode_utf8_atom)
+{
+
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({229,0}), /* LATIN1 "�" */
+ P99({ERLANG_ANY,ERLANG_LATIN1,ERLANG_LATIN1}));
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({195,164,0}), /* UTF8 "�" */
+ P99({ERLANG_UTF8,ERLANG_LATIN1,ERLANG_UTF8}));
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({246,0}), /* LATIN1 "�" */
+ P99({ERLANG_LATIN1,ERLANG_LATIN1,ERLANG_LATIN1}));
+ EI_DECODE_STRING_FAIL(decode_my_atom_as,
+ P99({ERLANG_ASCII,ERLANG_ANY,ERLANG_ANY}));
+
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({219,158,0}),
+ P99({ERLANG_ANY,ERLANG_UTF8,ERLANG_UTF8}));
+ EI_DECODE_STRING_4(decode_my_atom_as, 6, P99({219,158,219,158,0}),
+ P99({ERLANG_UTF8,ERLANG_UTF8,ERLANG_UTF8}));
+ EI_DECODE_STRING_FAIL(decode_my_atom_as,
+ P99({ERLANG_LATIN1,ERLANG_ANY,ERLANG_ANY}));
+ EI_DECODE_STRING_FAIL(decode_my_atom_as,
+ P99({ERLANG_ASCII,ERLANG_ANY,ERLANG_ANY}));
+
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, "a",
+ P99({ERLANG_ANY,ERLANG_LATIN1,ERLANG_ASCII}));
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, "b",
+ P99({ERLANG_UTF8,ERLANG_LATIN1,ERLANG_ASCII}));
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, "c",
+ P99({ERLANG_LATIN1,ERLANG_LATIN1,ERLANG_ASCII}));
+ EI_DECODE_STRING_4(decode_my_atom_as, 4, "d",
+ P99({ERLANG_ASCII,ERLANG_LATIN1,ERLANG_ASCII}));
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+int ei_decode_my_atom_as(const char *buf, int *index, char *to,
+ struct my_atom *atom) {
+ enum erlang_char_encoding was,result;
+ int res = ei_decode_atom_as(buf,index,to,1024,atom->from,&was,&result);
+ if (res != 0)
+ return res;
+ if (!(was & atom->was_check)) {
+ message("Original encoding was %d not %d\n",was,atom->was_check);
+ return -1;
+ } else if (!(result & atom->result_check)) {
+ message("Result encoding was %d not %d\n",result,atom->result_check);
+ return -1;
+ }
+ return res;
+}
+
+int ei_decode_my_atom(const char *buf, int *index, char *to,
+ struct my_atom *atom) {
+ return ei_decode_atom(buf, index, to);
+}
+
+int ei_decode_my_string(const char *buf, int *index, char *to,
+ struct my_atom *atom) {
+ return ei_decode_string(buf, index, to);
+}
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
index 85cb62239b..2271278291 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE.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
@@ -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..996d923ffc 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
@@ -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
@@ -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/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl
index 537e9cb01c..e0ac4c0637 100644
--- a/lib/erl_interface/test/ei_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_encode_SUITE.erl
@@ -34,7 +34,9 @@
test_ei_encode_ulonglong/1,
test_ei_encode_char/1,
test_ei_encode_misc/1,
- test_ei_encode_fails/1
+ test_ei_encode_fails/1,
+ test_ei_encode_utf8_atom/1,
+ test_ei_encode_utf8_atom_len/1
]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -43,7 +45,8 @@ all() ->
[test_ei_encode_long, test_ei_encode_ulong,
test_ei_encode_longlong, test_ei_encode_ulonglong,
test_ei_encode_char, test_ei_encode_misc,
- test_ei_encode_fails].
+ test_ei_encode_fails, test_ei_encode_utf8_atom,
+ test_ei_encode_utf8_atom_len].
groups() ->
[].
@@ -257,6 +260,38 @@ test_ei_encode_fails(Config) when is_list(Config) ->
%% ######################################################################## %%
+test_ei_encode_utf8_atom(Config) ->
+ ?line P = runner:start(?test_ei_encode_utf8_atom),
+
+ ?line {<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
+ ?line {<<100,0,1,197>>,'Å'} = get_buf_and_term(P),
+ ?line {<<100,0,1,197>>,'Å'} = get_buf_and_term(P),
+ ?line {<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
+
+ ?line {<<119,1,$A>>,'A'} = get_buf_and_term(P),
+ ?line {<<100,0,1,$A>>,'A'} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+%% ######################################################################## %%
+test_ei_encode_utf8_atom_len(Config) ->
+ ?line P = runner:start(?test_ei_encode_utf8_atom_len),
+
+ ?line {<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
+ ?line {<<100,0,2,197,196>>,'ÅÄ'} = get_buf_and_term(P),
+ ?line {<<100,0,1,197>>,'Å'} = get_buf_and_term(P),
+ ?line {<<119,4,195,133,195,132>>,'ÅÄ'} = get_buf_and_term(P),
+
+ ?line {<<119,1,$A>>,'A'} = get_buf_and_term(P),
+ ?line {<<100,0,2,$A,$B>>,'AB'} = get_buf_and_term(P),
+ ?line {<<100,0,255,_:(255*8)>>,_} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+%% ######################################################################## %%
+
% We read two packets for each test, the ei_encode and ei_x_encode version....
get_buf_and_term(P) ->
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
index c373658152..e904375e9e 100644
--- a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
@@ -208,6 +208,196 @@
ei_x_free(&arg); \
}
+#define EI_ENCODE_3(FUNC,ARG1,ARG2,ARG3) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1, ARG1, ARG2, ARG3); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("size calculation returned non zero but not -1"); \
+ return; \
+ } else { \
+ fail("size calculation returned non zero"); \
+ return; \
+ } \
+ } \
+ err = ei_ ## FUNC(buf, &size2, ARG1, ARG2, ARG3); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1"); \
+ } else { \
+ fail("returned non zero"); \
+ } \
+ return; \
+ } \
+ if (size1 != size2) { \
+ fail("size differs when arg is NULL or buf"); \
+ return; \
+ } \
+ if (size1 < 1) { \
+ fail("size is < 1"); \
+ return; \
+ } \
+ send_buffer(buf, size1); \
+ } \
+ { \
+ ei_x_buff arg; \
+ int err; \
+ message("ei_x_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg, ARG1, ARG2, ARG3); \
+ 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_ENCODE_3_FAIL(FUNC,ARG1,ARG2,ARG3) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1, ARG1, ARG2, ARG3); \
+ if (err != -1) { \
+ fail("size calculation returned non -1"); \
+ return; \
+ } \
+ err = ei_ ## FUNC(buf, &size2, ARG1, ARG2, ARG3); \
+ if (err != -1) { \
+ fail("returned non -1"); \
+ } \
+ if (size1 != size2) { \
+ fail("size differs when arg is NULL or buf"); \
+ return; \
+ } \
+ } \
+ { \
+ ei_x_buff arg; \
+ int err; \
+ message("ei_x_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg, ARG1, ARG2, ARG3); \
+ if (err != -1) { \
+ fail("returned non -1"); \
+ ei_x_free(&arg); \
+ return; \
+ } \
+ ei_x_free(&arg); \
+ }
+
+#define EI_ENCODE_4(FUNC,ARG1,ARG2,ARG3,ARG4) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " " #ARG4 " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1, ARG1, ARG2, ARG3, ARG4); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("size calculation returned non zero but not -1"); \
+ return; \
+ } else { \
+ fail("size calculation returned non zero"); \
+ return; \
+ } \
+ } \
+ err = ei_ ## FUNC(buf, &size2, ARG1, ARG2, ARG3, ARG4); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1"); \
+ } else { \
+ fail("returned non zero"); \
+ } \
+ return; \
+ } \
+ if (size1 != size2) { \
+ fail("size differs when arg is NULL or buf"); \
+ return; \
+ } \
+ if (size1 < 1) { \
+ fail("size is < 1"); \
+ return; \
+ } \
+ send_buffer(buf, size1); \
+ } \
+ { \
+ ei_x_buff arg; \
+ int err; \
+ message("ei_x_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " " #ARG4 " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg, ARG1, ARG2, ARG3, ARG4); \
+ 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_ENCODE_4_FAIL(FUNC,ARG1,ARG2,ARG3,ARG4) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " " #ARG4 " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1, ARG1, ARG2, ARG3, ARG4); \
+ if (err != -1) { \
+ fail("size calculation returned non -1"); \
+ return; \
+ } \
+ err = ei_ ## FUNC(buf, &size2, ARG1, ARG2, ARG3, ARG4); \
+ if (err != -1) { \
+ fail("returned non -1"); \
+ } \
+ if (size1 != size2) { \
+ fail("size differs when arg is NULL or buf"); \
+ return; \
+ } \
+ } \
+ { \
+ ei_x_buff arg; \
+ int err; \
+ message("ei_x_" #FUNC " " #ARG1 " " #ARG2 " " #ARG3 " " #ARG4 " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg, ARG1, ARG2, ARG3, ARG4); \
+ if (err != -1) { \
+ fail("returned non -1"); \
+ ei_x_free(&arg); \
+ return; \
+ } \
+ ei_x_free(&arg); \
+ }
+
/* ******************************************************************** */
TESTCASE(test_ei_encode_long)
@@ -464,3 +654,57 @@ TESTCASE(test_ei_encode_fails)
report(1);
}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_utf8_atom)
+{
+
+ EI_ENCODE_3(encode_atom_as, "�", ERLANG_LATIN1, ERLANG_UTF8);
+ EI_ENCODE_3(encode_atom_as, "�", ERLANG_LATIN1, ERLANG_LATIN1);
+ EI_ENCODE_3(encode_atom_as, "\303\205",
+ ERLANG_UTF8, ERLANG_LATIN1);
+ EI_ENCODE_3(encode_atom_as, "\303\205",
+ ERLANG_UTF8, ERLANG_UTF8);
+
+ EI_ENCODE_3(encode_atom_as, "A", ERLANG_ASCII, ERLANG_UTF8);
+ EI_ENCODE_3(encode_atom_as, "A", ERLANG_ASCII, ERLANG_LATIN1);
+
+ EI_ENCODE_3_FAIL(encode_atom_as, "�", ERLANG_UTF8, ERLANG_UTF8);
+ EI_ENCODE_3_FAIL(encode_atom_as, "�", ERLANG_UTF8, ERLANG_LATIN1);
+ EI_ENCODE_3_FAIL(encode_atom_as, "�", ERLANG_ASCII, ERLANG_UTF8);
+ EI_ENCODE_3_FAIL(encode_atom_as, "�", ERLANG_ASCII, ERLANG_LATIN1);
+
+ EI_ENCODE_3_FAIL(encode_atom_as, "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", ERLANG_ASCII, ERLANG_LATIN1);
+ EI_ENCODE_3_FAIL(encode_atom_as, "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", ERLANG_LATIN1, ERLANG_LATIN1);
+
+ EI_ENCODE_3_FAIL(encode_atom_as, "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", ERLANG_UTF8, ERLANG_LATIN1);
+
+ report(1);
+}
+
+TESTCASE(test_ei_encode_utf8_atom_len)
+{
+
+ EI_ENCODE_4(encode_atom_len_as, "���", 1, ERLANG_LATIN1, ERLANG_UTF8);
+ EI_ENCODE_4(encode_atom_len_as, "���", 2, ERLANG_LATIN1, ERLANG_LATIN1);
+ EI_ENCODE_4(encode_atom_len_as, "\303\205\303\204\303\226", 2,
+ ERLANG_UTF8, ERLANG_LATIN1);
+ EI_ENCODE_4(encode_atom_len_as, "\303\205\303\204\303\226", 4,
+ ERLANG_UTF8, ERLANG_UTF8);
+
+ EI_ENCODE_4(encode_atom_len_as, "ABC", 1, ERLANG_ASCII, ERLANG_UTF8);
+ EI_ENCODE_4(encode_atom_len_as, "ABC", 2, ERLANG_ASCII, ERLANG_LATIN1);
+
+ EI_ENCODE_4_FAIL(encode_atom_len_as, "���", 1, ERLANG_UTF8, ERLANG_UTF8);
+ EI_ENCODE_4_FAIL(encode_atom_len_as, "���", 2, ERLANG_UTF8, ERLANG_LATIN1);
+ EI_ENCODE_4_FAIL(encode_atom_len_as, "���", 3, ERLANG_ASCII, ERLANG_UTF8);
+ EI_ENCODE_4_FAIL(encode_atom_len_as, "���", 4, ERLANG_ASCII, ERLANG_LATIN1);
+
+ EI_ENCODE_4(encode_atom_len_as, "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", 255, ERLANG_ASCII, ERLANG_LATIN1);
+
+ EI_ENCODE_4_FAIL(encode_atom_len_as, "\303\205\303\204\303\226", 1,
+ ERLANG_UTF8, ERLANG_LATIN1);
+
+ report(1);
+}
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..532b2e43cd 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), ",") ++ ") -> "
@@ -3930,7 +3898,7 @@ t_form_to_string({type, _L, range, [From, To]} = Type) ->
case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
{{integer, _, FromVal}, {integer, _, ToVal}} ->
io_lib:format("~w..~w", [FromVal, ToVal]);
- _ -> io_lib:format("Bad formed type ~w",[Type])
+ _ -> io_lib:format("Badly formed type ~w",[Type])
end;
t_form_to_string({type, _L, record, [{atom, _, Name}]}) ->
io_lib:format("#~w{}", [Name]);
diff --git a/lib/ic/c_src/ic.c b/lib/ic/c_src/ic.c
index 1ace9ea1af..796842f4f8 100644
--- a/lib/ic/c_src/ic.c
+++ b/lib/ic/c_src/ic.c
@@ -149,6 +149,7 @@ void ic_init_ref(CORBA_Environment *env, erlang_ref *ref)
{
strcpy(ref->node, erl_thisnodename());
+ ref->node_org_enc = ERLANG_LATIN1;
ref->len = 3;
diff --git a/lib/ic/examples/all-against-all/client.c b/lib/ic/examples/all-against-all/client.c
index e0a52b142d..022b9fd1c0 100644
--- a/lib/ic/examples/all-against-all/client.c
+++ b/lib/ic/examples/all-against-all/client.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2009. 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
@@ -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..3e9678ae4d 100644
--- a/lib/ic/examples/c-client/client.c
+++ b/lib/ic/examples/c-client/client.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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..b6c7ef6bce 100644
--- a/lib/ic/examples/c-server/client.c
+++ b/lib/ic/examples/c-server/client.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. 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
@@ -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/java_src/com/ericsson/otp/ic/Any.java b/lib/ic/java_src/com/ericsson/otp/ic/Any.java
index 7337241908..c7ab6bad84 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Any.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Any.java
@@ -417,6 +417,8 @@ public class Any {
switch (__tag) {
case (com.ericsson.otp.erlang.OtpExternal.atomTag):
+ case (com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag):
+ case (com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag):
java.lang.String __elabel = _is.read_atom(); // Enumerant or Boolean
os.write_atom(__elabel);
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Environment.java b/lib/ic/java_src/com/ericsson/otp/ic/Environment.java
index f0c66f0726..4c5315ee98 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Environment.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Environment.java
@@ -334,6 +334,8 @@ public class Environment {
switch (tag) {
case com.ericsson.otp.erlang.OtpExternal.atomTag:
+ case com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag:
+ case com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag:
operation = is.read_atom();
break;
default:
@@ -344,6 +346,8 @@ public class Environment {
tag = is.peek();
switch (tag) {
case com.ericsson.otp.erlang.OtpExternal.atomTag:
+ case com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag:
+ case com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag:
operation = is.read_atom();
break;
default:
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Term.java b/lib/ic/java_src/com/ericsson/otp/ic/Term.java
index 9219cb7038..611f1f04d7 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/Term.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/Term.java
@@ -57,7 +57,10 @@ final public class Term extends Any {
public boolean isAtom() {
if (ObjV == null) {
- if (tag == com.ericsson.otp.erlang.OtpExternal.atomTag)
+ if (tag == com.ericsson.otp.erlang.OtpExternal.atomTag ||
+ tag == com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag ||
+ tag == com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag)
+
return true;
return false;
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java b/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java
index 437d38743b..5675eee706 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/TermHelper.java
@@ -69,6 +69,8 @@ public class TermHelper {
break;
case com.ericsson.otp.erlang.OtpExternal.atomTag:
+ case com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag:
+ case com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag:
_in.reset();
_value.atomV = _in.read_atom();
break;
diff --git a/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java b/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java
index 6d049f75f7..327864320f 100644
--- a/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java
+++ b/lib/ic/java_src/com/ericsson/otp/ic/TypeCode.java
@@ -723,6 +723,8 @@ public class TypeCode {
switch(__tag) {
case (com.ericsson.otp.erlang.OtpExternal.atomTag):
+ case (com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag):
+ case (com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag):
__kind = TypeCode.kind(_is.read_atom());
switch(__kind.value()) {
@@ -757,6 +759,8 @@ public class TypeCode {
switch(__tag) {
case (com.ericsson.otp.erlang.OtpExternal.atomTag):
+ case (com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag):
+ case (com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag):
__kind = TypeCode.kind(_is.read_atom());
_tc = new TypeCode();
@@ -814,6 +818,9 @@ public class TypeCode {
__label.insert_string(__enum);
break;
case (com.ericsson.otp.erlang.OtpExternal.atomTag):
+ case (com.ericsson.otp.erlang.OtpExternal.atomUtf8Tag):
+ case (com.ericsson.otp.erlang.OtpExternal.smallAtomUtf8Tag):
+
java.lang.String __default = _is.read_atom();
__label.insert_atom(__default);
break;
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
index e4f9cfdece..98fcdcc60f 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
@@ -390,6 +390,7 @@ int main(int argc, char **argv)
env->_from_pid = &pid;
strcpy(pid.node, this_node);
+ pid.node_org_enc = ERLANG_LATIN1;
pid.num = fd;
pid.serial = 0;
pid.creation = 0;
@@ -1006,7 +1007,7 @@ static int string4_test(IC_Env *env)
static int pid_test(IC_Env *env)
{
- erlang_pid pid = {"", 7, 0, 0}, pido, pidr;
+ erlang_pid pid = {"", ERLANG_LATIN1, 7, 0, 0}, pido, pidr;
strcpy(pid.node, this_node), /* this currently running node */
fprintf(stdout, "\n======== m_i_pid test ======\n\n");
@@ -1030,7 +1031,7 @@ static int pid_test(IC_Env *env)
static int port_test(IC_Env *env)
{
- erlang_port porti = {"node", 5, 1}, porto, portr;
+ erlang_port porti = {"node", ERLANG_LATIN1, 5, 1}, porto, portr;
fprintf(stdout, "\n======== m_i_port test ======\n\n");
portr = m_i_port_test(NULL, &porti, &porto, env);
@@ -1053,7 +1054,7 @@ static int port_test(IC_Env *env)
static int ref_test(IC_Env *env)
{
- erlang_ref refi = { "node1", 3, {1, 2, 3}, 1},
+ erlang_ref refi = { "node1", ERLANG_UTF8, 3, {1, 2, 3}, 1},
refo, refr;
fprintf(stdout, "\n======== m_i_ref test ======\n\n");
@@ -1111,6 +1112,7 @@ static int typedef_test(IC_Env *env)
long tl;
strcpy(mbi.node,"node");
+ mbi.node_org_enc = ERLANG_LATIN1;
mbi.id = 15;
mbi.creation = 1;
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
index f352b91fd5..4ced4fb5e5 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
@@ -393,6 +393,7 @@ int main(int argc, char **argv)
env->_from_pid = &pid;
strcpy(pid.node, this_node);
+ pid.node_org_enc = ERLANG_LATIN1;
pid.num = fd;
pid.serial = 0;
pid.creation = 0;
@@ -1009,7 +1010,7 @@ static int string4_test(IC_Env *env)
static int pid_test(IC_Env *env)
{
- erlang_pid pid = {"", 7, 0, 0}, pido, pidr;
+ erlang_pid pid = {"", ERLANG_LATIN1, 7, 0, 0}, pido, pidr;
strcpy(pid.node, this_node), /* this currently running node */
fprintf(stdout, "\n======== m_i_pid test ======\n\n");
@@ -1033,7 +1034,7 @@ static int pid_test(IC_Env *env)
static int port_test(IC_Env *env)
{
- erlang_port porti = {"node", 5, 1}, porto, portr;
+ erlang_port porti = {"node", ERLANG_LATIN1, 5, 1}, porto, portr;
fprintf(stdout, "\n======== m_i_port test ======\n\n");
portr = m_i_port_test(NULL, &porti, &porto, env);
@@ -1056,7 +1057,7 @@ static int port_test(IC_Env *env)
static int ref_test(IC_Env *env)
{
- erlang_ref refi = { "node1", 3, {1, 2, 3}, 1},
+ erlang_ref refi = { "node1", ERLANG_LATIN1, 3, {1, 2, 3}, 1},
refo, refr;
fprintf(stdout, "\n======== m_i_ref test ======\n\n");
@@ -1114,6 +1115,7 @@ static int typedef_test(IC_Env *env)
long tl;
strcpy(mbi.node,"node");
+ mbi.node_org_enc = ERLANG_LATIN1;
mbi.id = 15;
mbi.creation = 1;
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
index b2c5b0c836..7d5abcc376 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
@@ -393,6 +393,7 @@ int main(int argc, char **argv)
env->_from_pid = &pid;
strcpy(pid.node, this_node);
+ pid.node_org_enc = ERLANG_LATIN1;
pid.num = fd;
pid.serial = 0;
pid.creation = 0;
@@ -1009,7 +1010,7 @@ static int string4_test(IC_Env *env)
static int pid_test(IC_Env *env)
{
- erlang_pid pid = {"", 7, 0, 0}, pido, pidr;
+ erlang_pid pid = {"", ERLANG_LATIN1, 7, 0, 0}, pido, pidr;
strcpy(pid.node, this_node), /* this currently running node */
fprintf(stdout, "\n======== m_i_pid test ======\n\n");
@@ -1033,7 +1034,7 @@ static int pid_test(IC_Env *env)
static int port_test(IC_Env *env)
{
- erlang_port porti = {"node", 5, 1}, porto, portr;
+ erlang_port porti = {"node", ERLANG_LATIN1, 5, 1}, porto, portr;
fprintf(stdout, "\n======== m_i_port test ======\n\n");
portr = m_i_port_test(NULL, &porti, &porto, env);
@@ -1056,7 +1057,7 @@ static int port_test(IC_Env *env)
static int ref_test(IC_Env *env)
{
- erlang_ref refi = { "node1", 3, {1, 2, 3}, 1},
+ erlang_ref refi = { "node1", ERLANG_LATIN1, 3, {1, 2, 3}, 1},
refo, refr;
fprintf(stdout, "\n======== m_i_ref test ======\n\n");
@@ -1114,6 +1115,7 @@ static int typedef_test(IC_Env *env)
long tl;
strcpy(mbi.node,"node");
+ mbi.node_org_enc = ERLANG_LATIN1;
mbi.id = 15;
mbi.creation = 1;
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
index 305017ae85..ed21ba7baf 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
@@ -494,10 +494,12 @@ m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj,
m_i_port_test__rs* rs = NULL;
strcpy((*a).node,(*b).node);
+ a->node_org_enc = b->node_org_enc;
(*a).id = (*b).id;
(*a).creation = 0;
strcpy((*c).node,(*b).node);
+ c->node_org_enc = b->node_org_enc;
(*c).id = (*b).id;
(*c).creation = 0;
return rs;
@@ -514,6 +516,7 @@ m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj,
m_i_ref_test__rs* rs = NULL;
strcpy((*a).node,(*b).node);
+ a->node_org_enc = b->node_org_enc;
/*(*a).id = (*b).id;*/
(*a).len = (*b).len;
(*a).n[0] = (*b).n[0];
@@ -522,6 +525,7 @@ m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj,
(*a).creation = 0;
strcpy((*c).node,(*b).node);
+ c->node_org_enc = b->node_org_enc;
/*(*c).id = (*b).id;*/
(*c).len = (*b).len;
(*c).n[0] = (*b).n[0];
@@ -557,6 +561,7 @@ m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj,
*d = *b;
strcpy((*e).node,(*c).node);
+ e->node_org_enc = c->node_org_enc;
(*e).id = (*c).id;
(*e).creation = 0;
*a = 4711;
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
index c423a9e51c..d813cae45a 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
@@ -494,10 +494,12 @@ m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj,
m_i_port_test__rs* rs = NULL;
strcpy((*a).node,(*b).node);
+ a->node_org_enc = b->node_org_enc;
(*a).id = (*b).id;
(*a).creation = 0;
strcpy((*c).node,(*b).node);
+ c->node_org_enc = b->node_org_enc;
(*c).id = (*b).id;
(*c).creation = 0;
return rs;
@@ -514,6 +516,7 @@ m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj,
m_i_ref_test__rs* rs = NULL;
strcpy((*a).node,(*b).node);
+ a->node_org_enc = b->node_org_enc;
/*(*a).id = (*b).id;*/
(*a).len = (*b).len;
(*a).n[0] = (*b).n[0];
@@ -522,6 +525,7 @@ m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj,
(*a).creation = 0;
strcpy((*c).node,(*b).node);
+ c->node_org_enc = b->node_org_enc;
/*(*c).id = (*b).id;*/
(*c).len = (*b).len;
(*c).n[0] = (*b).n[0];
@@ -557,6 +561,7 @@ m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj,
*d = *b;
strcpy((*e).node,(*c).node);
+ e->node_org_enc = c->node_org_enc;
(*e).id = (*c).id;
(*e).creation = 0;
*a = 4711;
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 a2440adc92..3143ab427b 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
- $(gen_verbose)$(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl
- $(V_at)echo done > java_erl_test.built_java
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl
+ echo done > java_erl_test.built_java
$(CLASS_FILES) : $(JAVA_FILES)
- $(V_JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
+ $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
java_erl_test.built_erl: java_erl_test.idl
- $(gen_verbose)$(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl
- $(V_at)echo done > java_erl_test.built_erl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl
+ echo done > java_erl_test.built_erl
.erl.@EMULATOR@:
- $(V_ERLC) -I $(IC_INCLUDE_PATH) $<
+ $(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..f177aac8f2 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.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
@@ -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/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index ffd0ed622f..c63dcafa6c 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -1,7 +1,7 @@
%% This is an -*- erlang -*- file.
%% %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
@@ -18,109 +18,8 @@
{"%VSN%",
[
- {"5.9.1",
- [
- {load_module, httpd_request_handler, soft_purge, soft_purge, []}
- ]
- },
- {"5.9",
- [
- {load_module, httpd_request_handler, soft_purge, soft_purge, []},
- {load_module, tftp, soft_purge, soft_purge, [inets_service]},
- {load_module, inets_service, soft_purge, soft_purge, []},
- {load_module, httpc, soft_purge, soft_purge, [httpc_manager]},
- {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
- {update, httpc_manager, soft, soft_purge, soft_purge, []}
- ]
- },
- {"5.8.1",
- [
- {load_module, httpd_request_handler, soft_purge, soft_purge, []},
- {load_module, tftp, soft_purge, soft_purge, [inets_service]},
- {load_module, inets_service, soft_purge, soft_purge, []},
-
- {load_module, http_uri, soft_purge, soft_purge, []},
- {load_module, httpc_response, soft_purge, soft_purge, [http_uri]},
-
- {load_module, httpc, soft_purge, soft_purge,
- [http_uri, httpc_manager]},
-
- {load_module, inets_app, soft_purge, soft_purge, [inets_sup]},
- {update, inets_sup, soft, soft_purge, soft_purge, []},
-
- {load_module, httpd_conf, soft_purge, soft_purge, []},
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {load_module, httpd_script_env, soft_purge, soft_purge, []},
-
- {load_module, inets, soft_purge, soft_purge, [inets_trace]},
- {update, httpc_manager, soft, soft_purge, soft_purge, [http_uri]},
- {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
- {update, httpd_sup, soft, soft_purge, soft_purge, []},
- {add_module, inets_trace}
- ]
- },
- {"5.8",
- [
- {restart_application, inets}
- ]
- },
- {"5.7.2",
- [
- {restart_application, inets}
- ]
- }
- ],
+ {<<"5\\.*">>, [{restart_application, inets}]}
+ ],
[
- {"5.9.1",
- [
- {load_module, httpd_request_handler, soft_purge, soft_purge, []}
- ]
- },
- {"5.9",
- [
- {load_module, httpd_request_handler, soft_purge, soft_purge, []},
- {load_module, tftp, soft_purge, soft_purge, [inets_service]},
- {load_module, inets_service, soft_purge, soft_purge, []},
- {load_module, httpc, soft_purge, soft_purge, [httpc_manager]},
- {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
- {update, httpc_manager, soft, soft_purge, soft_purge, []}
- ]
- },
- {"5.8.1",
- [
- {load_module, httpd_request_handler, soft_purge, soft_purge, []},
- {load_module, tftp, soft_purge, soft_purge, [inets_service]},
- {load_module, inets_service, soft_purge, soft_purge, []},
-
- {load_module, http_uri, soft_purge, soft_purge, []},
- {load_module, httpc_response, soft_purge, soft_purge, [http_uri]},
-
- {load_module, httpc, soft_purge, soft_purge,
- [http_uri, httpc_manager]},
-
- {load_module, inets_app, soft_purge, soft_purge, [inets_sup]},
- {update, inets_sup, soft, soft_purge, soft_purge, []},
-
- {load_module, httpd_conf, soft_purge, soft_purge, []},
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {load_module, httpd_script_env, soft_purge, soft_purge, []},
-
- {load_module, inets, soft_purge, soft_purge, []},
- {update, httpc_manager, soft, soft_purge, soft_purge, [http_uri]},
- {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
- {update, httpd_sup, soft, soft_purge, soft_purge, []},
- {remove, {inets_trace, soft_purge, brutal_purge}}
- ]
- },
- {"5.8",
- [
- {restart_application, inets}
- ]
- },
- {"5.7.2",
- [
- {restart_application, inets}
- ]
- }
- ]
-}.
+ {<<"5\\.*">>, [{restart_application, inets}]}
+]}.
diff --git a/lib/inets/test/erl_make_certs.erl b/lib/inets/test/erl_make_certs.erl
index d6bdd05d01..5b92e551a5 100644
--- a/lib/inets/test/erl_make_certs.erl
+++ b/lib/inets/test/erl_make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011. 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
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
index 211c9b5bee..35f21cc74d 100644
--- a/lib/inets/test/ftp_suite_lib.erl
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 644b01120c..5a3bdaefcf 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_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
@@ -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/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
index 3862bf7a20..80f43ec236 100644
--- a/lib/inets/test/httpc_cookie_SUITE.erl
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index 069c68fa1e..6510c70d08 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -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
diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl
index 7ed237243e..648e373312 100644
--- a/lib/inets/test/inets_appup_test.erl
+++ b/lib/inets/test/inets_appup_test.erl
@@ -257,6 +257,21 @@ check_instruction(_, Instr, _AllInstr, _Modules) ->
check_version(V) when is_list(V) ->
ok;
+check_version(REBin) when is_binary(REBin) ->
+ try
+ begin
+ RE = binary_to_list(REBin),
+ case re:compile(RE) of
+ {ok, _} ->
+ ok;
+ {error, _} ->
+ error({bad_version, REBin})
+ end
+ end
+ catch
+ _T:_E ->
+ error({bad_version, REBin})
+ end;
check_version(V) ->
error({bad_version, V}).
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
index 65f0f0e09a..0ac940fd3e 100644
--- a/lib/inets/test/inets_sup_SUITE.erl
+++ b/lib/inets/test/inets_sup_SUITE.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
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 0c7cb5e7c2..394dccab48 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -2,7 +2,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
@@ -18,7 +18,7 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.9.2
+INETS_VSN = 5.9.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/java_src/Makefile b/lib/jinterface/java_src/Makefile
index 0aa9c09548..dafb634eac 100644
--- a/lib/jinterface/java_src/Makefile
+++ b/lib/jinterface/java_src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2000-2011. All Rights Reserved.
+# Copyright Ericsson AB 2000-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
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..cea5080607 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractNode.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
@@ -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/OtpEpmd.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
index b985f8aa50..1868dc7740 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
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..0371740b26 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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,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..45a82d6c94 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpExternal.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
@@ -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..9dc1728346 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
@@ -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..47ec3cc052 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2000-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
@@ -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..1f66366731 100644
--- a/lib/jinterface/test/nc_SUITE.erl
+++ b/lib/jinterface/test/nc_SUITE.erl
@@ -2,7 +2,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
@@ -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 9f19efc793..697de6681f 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.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>
diff --git a/lib/kernel/doc/src/error_handler.xml b/lib/kernel/doc/src/error_handler.xml
index 610b65f0a2..84ec3927c8 100644
--- a/lib/kernel/doc/src/error_handler.xml
+++ b/lib/kernel/doc/src/error_handler.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1996</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -62,6 +62,19 @@
<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>
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/global.xml b/lib/kernel/doc/src/global.xml
index 9c50049503..53958c47c2 100644
--- a/lib/kernel/doc/src/global.xml
+++ b/lib/kernel/doc/src/global.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>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index 3d929a772e..541500a300 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2012</year>
+ <year>1997</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
index 67d91ba585..96604a2fa2 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/kernel/include/dist.hrl b/lib/kernel/include/dist.hrl
index 5b52f6f294..e32c112e63 100644
--- a/lib/kernel/include/dist.hrl
+++ b/lib/kernel/include/dist.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
@@ -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 eaced4861a..cb3c0a49f4 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -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 @@ 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
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index 4e65883be7..6efc1b4499 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.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
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..1e12a647d7 100644
--- a/lib/kernel/src/auth.erl
+++ b/lib/kernel/src/auth.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
@@ -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..8a543abd6f 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.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
@@ -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..b770fce887 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.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
@@ -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..0c5af2857e 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..9d431bdd30 100644
--- a/lib/kernel/src/disk_log_1.erl
+++ b/lib/kernel/src/disk_log_1.erl
@@ -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
@@ -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..fc50ec6717 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. 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
@@ -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 a3aa1f1dcf..40aabba803 100644
--- a/lib/kernel/src/error_handler.erl
+++ b/lib/kernel/src/error_handler.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
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..2461f3ff25 100644
--- a/lib/kernel/src/inet_config.erl
+++ b/lib/kernel/src/inet_config.erl
@@ -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
@@ -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..619c78a6ca 100644
--- a/lib/kernel/src/inet_parse.erl
+++ b/lib/kernel/src/inet_parse.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. 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
@@ -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.app.src b/lib/kernel/src/kernel.app.src
index 9a20baf8d0..cb8c98ab06 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. 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
diff --git a/lib/kernel/src/kernel_config.erl b/lib/kernel/src/kernel_config.erl
index b1daf655c9..48141cfa03 100644
--- a/lib/kernel/src/kernel_config.erl
+++ b/lib/kernel/src/kernel_config.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
@@ -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..dd0071b914 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.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
@@ -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..742c000cc1 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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..bb654495d3 100644
--- a/lib/kernel/src/user_drv.erl
+++ b/lib/kernel/src/user_drv.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
@@ -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 8d2d55777b..cb11d4e899 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 2ca8840e1f..0452202467 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.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
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_echo_SUITE.erl b/lib/kernel/test/gen_tcp_echo_SUITE.erl
index 94f95798a0..9bc66dbae0 100644
--- a/lib/kernel/test/gen_tcp_echo_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_echo_SUITE.erl
@@ -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
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/ignore_cores.erl b/lib/kernel/test/ignore_cores.erl
index 8b1ac0fe6c..d4bb02df3f 100644
--- a/lib/kernel/test/ignore_cores.erl
+++ b/lib/kernel/test/ignore_cores.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. 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
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index e5e1794514..1f7724d0dc 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -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
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 3f2195b609..382fd6f6a9 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -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
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 60b818cbe3..98cff0222e 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4
index 918e30a886..25f40944e7 100644
--- a/lib/megaco/aclocal.m4
+++ b/lib/megaco/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/configure.in b/lib/megaco/configure.in
index 643267a154..64daa959b5 100644
--- a/lib/megaco/configure.in
+++ b/lib/megaco/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 2001-2011. All Rights Reserved.
+dnl Copyright Ericsson AB 2001-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
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/doc/src/megaco_encode.xml b/lib/megaco/doc/src/megaco_encode.xml
index 4a9d63c2e3..4b5adab262 100644
--- a/lib/megaco/doc/src/megaco_encode.xml
+++ b/lib/megaco/doc/src/megaco_encode.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/megaco/examples/meas/megaco_codec_meas.erl b/lib/megaco/examples/meas/megaco_codec_meas.erl
index 65b986ccd1..5af40eea7d 100644
--- a/lib/megaco/examples/meas/megaco_codec_meas.erl
+++ b/lib/megaco/examples/meas/megaco_codec_meas.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/lib/megaco/examples/meas/megaco_codec_transform.erl b/lib/megaco/examples/meas/megaco_codec_transform.erl
index 15db165566..7825e7856f 100644
--- a/lib/megaco/examples/meas/megaco_codec_transform.erl
+++ b/lib/megaco/examples/meas/megaco_codec_transform.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/lib/megaco/src/app/megaco.app.src b/lib/megaco/src/app/megaco.app.src
index 0ba2a866f9..40265166ae 100644
--- a/lib/megaco/src/app/megaco.app.src
+++ b/lib/megaco/src/app/megaco.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. 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
diff --git a/lib/megaco/src/binary/depend.mk b/lib/megaco/src/binary/depend.mk
index 2dce45981f..b9b86d3183 100644
--- a/lib/megaco/src/binary/depend.mk
+++ b/lib/megaco/src/binary/depend.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2011. 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
diff --git a/lib/megaco/src/binary/megaco_binary_encoder.erl b/lib/megaco/src/binary/megaco_binary_encoder.erl
index 51e167590d..abb496c173 100644
--- a/lib/megaco/src/binary/megaco_binary_encoder.erl
+++ b/lib/megaco/src/binary/megaco_binary_encoder.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
diff --git a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
index 262889db39..8a4f4e7509 100644
--- a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
+++ b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
diff --git a/lib/megaco/src/binary/modules.mk b/lib/megaco/src/binary/modules.mk
index bbaf087ceb..d0765b7a6b 100644
--- a/lib/megaco/src/binary/modules.mk
+++ b/lib/megaco/src/binary/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2009. 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
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..3914a81b8c 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
+++ b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2011. 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
@@ -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/megaco/src/rules.mk b/lib/megaco/src/rules.mk
index a59060032d..d9473af26e 100644
--- a/lib/megaco/src/rules.mk
+++ b/lib/megaco/src/rules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2009. 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
diff --git a/lib/megaco/test/megaco_actions_test.erl b/lib/megaco/test/megaco_actions_test.erl
index 6d0e80281d..cdf11f09cc 100644
--- a/lib/megaco/test/megaco_actions_test.erl
+++ b/lib/megaco/test/megaco_actions_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. 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
diff --git a/lib/megaco/test/megaco_call_flow_test.erl b/lib/megaco/test/megaco_call_flow_test.erl
index d5888018cd..8ad1cf6445 100644
--- a/lib/megaco/test/megaco_call_flow_test.erl
+++ b/lib/megaco/test/megaco_call_flow_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
diff --git a/lib/megaco/test/megaco_mib_test.erl b/lib/megaco/test/megaco_mib_test.erl
index ddc74ab741..96d7248726 100644
--- a/lib/megaco/test/megaco_mib_test.erl
+++ b/lib/megaco/test/megaco_mib_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/lib/megaco/test/megaco_test_mg.erl b/lib/megaco/test/megaco_test_mg.erl
index 947f0eebbb..cc1d2dd1b9 100644
--- a/lib/megaco/test/megaco_test_mg.erl
+++ b/lib/megaco/test/megaco_test_mg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. 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
diff --git a/lib/megaco/test/megaco_test_mgc.erl b/lib/megaco/test/megaco_test_mgc.erl
index a964983861..d9183f847e 100644
--- a/lib/megaco/test/megaco_test_mgc.erl
+++ b/lib/megaco/test/megaco_test_mgc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. 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
diff --git a/lib/mnesia/examples/mnesia_tpcb.erl b/lib/mnesia/examples/mnesia_tpcb.erl
index f36b43a495..07ae73f0bd 100644
--- a/lib/mnesia/examples/mnesia_tpcb.erl
+++ b/lib/mnesia/examples/mnesia_tpcb.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
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 53d327c11b..ac38fa05ef 100644
--- a/lib/mnesia/src/Makefile
+++ b/lib/mnesia/src/Makefile
@@ -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
@@ -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
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 3d30debc53..70466d10d7 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.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
@@ -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_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index ec67d9ec12..78f7bfa325 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.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
diff --git a/lib/mnesia/src/mnesia_event.erl b/lib/mnesia/src/mnesia_event.erl
index 9fd0342d31..35fe2d4035 100644
--- a/lib/mnesia/src/mnesia_event.erl
+++ b/lib/mnesia/src/mnesia_event.erl
@@ -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
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index c08bbc879f..7a788238fc 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.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
@@ -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_recover.erl b/lib/mnesia/src/mnesia_recover.erl
index b64f428f15..7aa03bda37 100644
--- a/lib/mnesia/src/mnesia_recover.erl
+++ b/lib/mnesia/src/mnesia_recover.erl
@@ -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
diff --git a/lib/mnesia/src/mnesia_sup.erl b/lib/mnesia/src/mnesia_sup.erl
index 9ee4086f50..8443fefe7f 100644
--- a/lib/mnesia/src/mnesia_sup.erl
+++ b/lib/mnesia/src/mnesia_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. 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,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/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index b5b14ac05b..e54e5c4e88 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.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
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..e0004ecb51 100644
--- a/lib/mnesia/test/mnesia_SUITE.erl
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -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
@@ -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..f0f3053ebf 100644
--- a/lib/mnesia/test/mnesia_config_test.erl
+++ b/lib/mnesia/test/mnesia_config_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. 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
@@ -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..8854854570 100644
--- a/lib/mnesia/test/mnesia_measure_test.erl
+++ b/lib/mnesia/test/mnesia_measure_test.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
@@ -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/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 57cbc61495..6a51aefdf0 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.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
diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile
index 877286033e..42f5c19935 100644
--- a/lib/observer/src/Makefile
+++ b/lib/observer/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2002-2012. All Rights Reserved.
+# Copyright Ericsson AB 2002-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
@@ -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
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
index 918e30a886..25f40944e7 100644
--- a/lib/odbc/aclocal.m4
+++ b/lib/odbc/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index 4a7a5224e5..a6b3de6e48 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2011. 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
@@ -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/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index 71760189e7..916a7cb31d 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2011. All Rights Reserved.
+ * Copyright Ericsson AB 2002-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
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index e6ba9f57f5..fd28830c0c 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 2005-2011. All Rights Reserved.
+dnl Copyright Ericsson AB 2005-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 7d732f20f7..b06384fc94 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/lib/orber/src/orber_ifr_exceptiondef.erl b/lib/orber/src/orber_ifr_exceptiondef.erl
index 7665d3d1bc..61b3051883 100644
--- a/lib/orber/src/orber_ifr_exceptiondef.erl
+++ b/lib/orber/src/orber_ifr_exceptiondef.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. 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
@@ -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/orber/test/csiv2_SUITE.erl b/lib/orber/test/csiv2_SUITE.erl
index b89bf0a56c..da8c0d3738 100644
--- a/lib/orber/test/csiv2_SUITE.erl
+++ b/lib/orber/test/csiv2_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
diff --git a/lib/os_mon/src/Makefile b/lib/os_mon/src/Makefile
index 9fc888e552..cd2dadec30 100644
--- a/lib/os_mon/src/Makefile
+++ b/lib/os_mon/src/Makefile
@@ -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
@@ -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
diff --git a/lib/os_mon/src/os_mon.erl b/lib/os_mon/src/os_mon.erl
index 19acae9f0e..b5f71f3eed 100644
--- a/lib/os_mon/src/os_mon.erl
+++ b/lib/os_mon/src/os_mon.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
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 7b63475231..2ee2285eb3 100644
--- a/lib/parsetools/src/Makefile
+++ b/lib/parsetools/src/Makefile
@@ -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
@@ -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
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/doc/src/notes.xml b/lib/percept/doc/src/notes.xml
index dd70cfe994..418c1e6cbc 100644
--- a/lib/percept/doc/src/notes.xml
+++ b/lib/percept/doc/src/notes.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile
index f765906b3b..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
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 f01f7dbaf5..ac4b4e4489 100644
--- a/lib/public_key/doc/src/cert_records.xml
+++ b/lib/public_key/doc/src/cert_records.xml
@@ -649,7 +649,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
version atom(),
subject {rdnSequence, [#AttributeTypeAndValue'{}]} ,
subjectPKInfo #'CertificationRequestInfo_subjectPKInfo'{},
- attributes [#AttributeTypeAndValue'{}]
+ attributes [#'AttributePKCS-10' {}]
}
#'CertificationRequestInfo_subjectPKInfo'{
@@ -665,7 +665,12 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
#'CertificationRequest_signatureAlgorithm'{
algorithm = oid(),
parameters = der_encoded()
- }
+ }
+
+#'AttributePKCS-10'{
+ type = oid(),
+ values = [der_encoded()]
+}
</code>
</section>
diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile
index b8ad68ecc7..09393e8e50 100644
--- a/lib/public_key/src/Makefile
+++ b/lib/public_key/src/Makefile
@@ -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
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 9b7d98728f..e753cf3867 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.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
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 74918f1d67..b8387fff96 100644
--- a/lib/reltool/src/Makefile
+++ b/lib/reltool/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2012. All Rights Reserved.
+# Copyright Ericsson AB 2009-2013. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -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
diff --git a/lib/runtime_tools/doc/src/book.xml b/lib/runtime_tools/doc/src/book.xml
index ad7d709644..62f145f0a5 100644
--- a/lib/runtime_tools/doc/src/book.xml
+++ b/lib/runtime_tools/doc/src/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/runtime_tools/src/Makefile b/lib/runtime_tools/src/Makefile
index 53b9ce34e4..2347986c53 100644
--- a/lib/runtime_tools/src/Makefile
+++ b/lib/runtime_tools/src/Makefile
@@ -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
@@ -68,7 +68,8 @@ EXAMPLE_FILES= \
ERL_COMPILE_FLAGS += \
-I../include \
-I ../../et/include \
- -I ../../../libraries/et/include
+ -I ../../../libraries/et/include \
+ -Werror
# ----------------------------------------------------
# Targets
diff --git a/lib/runtime_tools/src/appmon_info.erl b/lib/runtime_tools/src/appmon_info.erl
index 332140f69d..a728312c97 100644
--- a/lib/runtime_tools/src/appmon_info.erl
+++ b/lib/runtime_tools/src/appmon_info.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
diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl
index d35c8e781e..6e3bfe31c6 100644
--- a/lib/runtime_tools/src/dbg.erl
+++ b/lib/runtime_tools/src/dbg.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
diff --git a/lib/runtime_tools/src/runtime_tools_sup.erl b/lib/runtime_tools/src/runtime_tools_sup.erl
index 264e172a3c..ab9fa534d5 100644
--- a/lib/runtime_tools/src/runtime_tools_sup.erl
+++ b/lib/runtime_tools/src/runtime_tools_sup.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -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 c1ad8ca0bb..ab2d3a3ecd 100644
--- a/lib/sasl/src/Makefile
+++ b/lib/sasl/src/Makefile
@@ -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,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I../../stdlib/include
+ERL_COMPILE_FLAGS += -I../../stdlib/include -Werror
# ----------------------------------------------------
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/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk
index e6ba1ac810..2f8a07aba7 100644
--- a/lib/snmp/src/compile/depend.mk
+++ b/lib/snmp/src/compile/depend.mk
@@ -2,7 +2,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
diff --git a/lib/snmp/test/snmp_manager_user_old.erl b/lib/snmp/test/snmp_manager_user_old.erl
index 9f951bf64d..d5ffabee0b 100644
--- a/lib/snmp/test/snmp_manager_user_old.erl
+++ b/lib/snmp/test/snmp_manager_user_old.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. 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
diff --git a/lib/snmp/test/snmp_manager_user_test.erl b/lib/snmp/test/snmp_manager_user_test.erl
index 41d5c50b19..2633793bce 100644
--- a/lib/snmp/test/snmp_manager_user_test.erl
+++ b/lib/snmp/test/snmp_manager_user_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. 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
diff --git a/lib/snmp/test/snmp_test_manager.erl b/lib/snmp/test/snmp_test_manager.erl
index 0df2350d58..1f3383a7a8 100644
--- a/lib/snmp/test/snmp_test_manager.erl
+++ b/lib/snmp/test/snmp_test_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. 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
diff --git a/lib/ssh/doc/src/introduction.xml b/lib/ssh/doc/src/introduction.xml
index aac8de0f76..e76aa20d64 100644
--- a/lib/ssh/doc/src/introduction.xml
+++ b/lib/ssh/doc/src/introduction.xml
@@ -5,6 +5,7 @@
<header>
<copyright>
<year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -47,7 +48,7 @@
<section>
<title>Prerequisites</title>
- <p>It is assumed that the reader is familiar with the concepts of <seealso marker="doc/design_principals:users_guide">OTP</seealso>
+ <p>It is assumed that the reader is familiar with the concepts of <seealso marker="doc/design_principles:des_princ">OTP</seealso>
and has a basic understanding of <url href="http://en.wikipedia.org/wiki/Public-key_cryptography">public keys</url>.</p>
</section>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index 7f7d887d5e..f57ee13460 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2012</year>
+ <year>2004</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/ssh/doc/src/ssh_channel.xml b/lib/ssh/doc/src/ssh_channel.xml
index f0083ae8d1..66b3b8b656 100644
--- a/lib/ssh/doc/src/ssh_channel.xml
+++ b/lib/ssh/doc/src/ssh_channel.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -31,7 +31,7 @@
<p>SSH services (clients and servers) are implemented as channels
that are multiplexed over an SSH connection and communicates via
the <url href="http://www.ietf.org/rfc/rfc4254.txt"> SSH
- Connection Protocol </url>. This module provides a callback API
+ Connection Protocol</url>. This module provides a callback API
that takes care of generic channel aspects such as flow control
and close messages and lets the callback functions take care of
the service (application) specific parts. This behavior also ensures
@@ -41,12 +41,12 @@
the SSH applications supervisor tree.
</p>
- <note> When implementing a SSH subsystem use the
- <c>-behaviour(ssh_subsystem).</c> instead of <c>-behaviour(ssh_channel).</c>
+ <note> <p>When implementing a SSH subsystem use the
+ <c>-behaviour(ssh_daemon_channel).</c> instead of <c>-behaviour(ssh_channel).</c>
as the only relevant callback functions for subsystems are
- init/1, handle_ssh_msg/2, handle_msg/2 and terminate/2, so the ssh_subsystem
+ init/1, handle_ssh_msg/2, handle_msg/2 and terminate/2, so the ssh_daemon_channel
behaviour is limited version of the ssh_channel behaviour.
- </note>
+ </p> </note>
</description>
<section>
@@ -83,7 +83,7 @@
<desc>
<p>Makes a synchronous call to the channel process by sending
a message and waiting until a reply arrives or a timeout
- occurs. The channel will call <seealso mark =
+ occurs. The channel will call <seealso marker =
"#Module:handle_call-3">Module:handle_call/3</seealso>
to handle the message. If the channel process does not exist
<c>{error, closed}</c> is returned.
@@ -104,7 +104,7 @@
<p>Sends an asynchronous message to the channel process and
returns ok immediately, ignoring if the destination node or
channel process does not exist. The channel will call
- <seealso mark = "#Module:handle_cast-3">Module:handle_cast/2</seealso>
+ <seealso marker = "#Module:handle_cast-2">Module:handle_cast/2</seealso>
to handle the message.
</p>
</desc>
@@ -114,7 +114,7 @@
<name>enter_loop(State) -> _ </name>
<fsummary> Makes an existing process an ssh_channel process. </fsummary>
<type>
- <v> State = term() - as returned by <seealso mark = "#init-1">ssh_channel:init/1</seealso></v>
+ <v> State = term() - as returned by <seealso marker = "#init-1">ssh_channel:init/1</seealso></v>
</type>
<desc>
<p> Makes an existing process an <c>ssh_channel</c>
@@ -124,7 +124,7 @@
one of the start functions in proc_lib, see <seealso
marker="stdlib:proc_lib">proc_lib(3)</seealso>. The
user is responsible for any initialization of the process
- and needs to call <seealso mark = "#init-1">ssh_channel:init/1</seealso>
+ and needs to call <seealso marker = "#init-1">ssh_channel:init/1</seealso>
</p>
</desc>
</func>
@@ -155,7 +155,7 @@
marker="ssh#connect-3">ssh:connect/3</seealso></item>
<tag><c><![CDATA[{channel_id, channel_id()}]]></c></tag>
- <item> Id of the ssh channel.</item>
+ <item> Id of the SSH channel.</item>
</taglist>
@@ -222,8 +222,8 @@
<title> CALLBACK TIMEOUTS</title>
<p>The timeout values that may be returned by the callback functions
- has the same semantics as in a <seealso marker="stdlib#gen_server">gen_server</seealso>
- If the timeout occurs <seealso marker="#handle_msg">handle_msg/2</seealso>
+ has the same semantics as in a <seealso marker="stdlib:gen_server">gen_server</seealso>
+ If the timeout occurs <seealso marker="#Module:handle_msg-2">handle_msg/2</seealso>
will be called as <c>handle_msg(timeout, State). </c></p>
</section>
@@ -334,7 +334,6 @@
</p>
<p>For more detailed information on timeouts see the section
<seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
- <marker id="handle_msg"></marker>
</desc>
</func>
@@ -342,10 +341,11 @@
<name>Module:handle_msg(Msg, State) -> {ok, State} |
{stop, ChannelId, State}</name>
- <fsummary> Handle other messages than ssh connection protocol,
+ <fsummary> Handle other messages than SSH connection protocol,
call or cast messages sent to the channel.</fsummary>
<type>
<v>Msg = timeout | term()</v>
+ <v>ChannelId = ssh_channel_id()</v>
<v>State = term() </v>
</type>
<desc>
@@ -361,7 +361,7 @@
ssh_connection_ref()}]]></c></tag>
<item>This is the first messages that will be received by
the channel, it is sent just before the <seealso
- marker="#init-2">ssh_channel:init/1</seealso> function
+ marker="#init-1">ssh_channel:init/1</seealso> function
returns successfully. This is especially useful if the
server wants to send a message to the client without first
receiving a message from it. If the message is not
@@ -374,19 +374,20 @@
<func>
<name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop,
- ssh_channel_id(), State}</name>
+ ChannelId, State}</name>
<fsummary> Handles ssh connection protocol messages. </fsummary>
<type>
<v>Msg = <seealso marker="ssh_connection"> ssh_connection:event() </seealso> </v>
+ <v>ChannelId = ssh_channel_id()</v>
<v>State = term()</v>
</type>
<desc>
- <p> Handles ssh connection protocol messages that may need
+ <p> Handles SSH connection protocol messages that may need
service specific attention.
</p>
<p> The following message is completely taken care of by the
- ssh channel behavior</p>
+ SSH channel behavior</p>
<taglist>
<tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml
index abc1070e78..b9b1ec4efa 100644
--- a/lib/ssh/doc/src/ssh_client_key_api.xml
+++ b/lib/ssh/doc/src/ssh_client_key_api.xml
@@ -5,6 +5,7 @@
<header>
<copyright>
<year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -62,7 +63,7 @@
<d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
<v>ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#daemon">ssh:connect/[3,4]</seealso></d>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
<v>Reason = term() </v>
</type>
<desc>
@@ -85,7 +86,7 @@
can be handled.</d>
<v> ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#daemon">ssh:connect/[3,4]</seealso></d>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
<v> Result = boolean()</v>
</type>
@@ -104,7 +105,7 @@
can be handled.</d>
<v> ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#daemon">ssh:connect/[3,4]</seealso></d>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
<v> PrivateKey = private_key()</v>
<d> The private key of the user matching the <c>Algorithm</c></d>
@@ -114,7 +115,7 @@
<desc>
<p>Fetches the users "public key" matching the <c>Algorithm</c>.
- <note>The private key contains the public key</note>
+ <note><p>The private key contains the public key</p></note>
</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml
index c66622307f..efd4865a6f 100644
--- a/lib/ssh/doc/src/ssh_connection.xml
+++ b/lib/ssh/doc/src/ssh_connection.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -42,7 +42,7 @@
marker="ssh_channel">ssh_channel</seealso> behavior is used to
implement the channel process these will be handled by
<seealso
- marker="ssh_channel#CallbackModule:handled_ssh_msg-2">handle_ssh_msg/2 </seealso>.</p>
+ marker="ssh_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2 </seealso>.</p>
</description>
<section>
@@ -69,12 +69,12 @@
<taglist>
<tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}]]></c></tag>
<item> Data has arrived on the channel. This event is sent as
- result of calling <seealso marker="#send-3"> ssh_connection:send/[3,4,5] </seealso></item>
+ result of calling <seealso marker="ssh_connection#send-3"> ssh_connection:send/[3,4,5] </seealso></item>
<tag><c><![CDATA[{eof, ssh_channel_id()}]]></c></tag>
<item>Indicates that the other side will not send any more
data. This event is sent as result of calling <seealso
- marker="#send_eof-2"> ssh_connection:send_eof/2</seealso>
+ marker="ssh_connection#send_eof-2"> ssh_connection:send_eof/2</seealso>
</item>
</taglist>
</item>
@@ -104,12 +104,12 @@
following message can be sent to return the exit status of the
command. A zero 'exit_status' usually means that the command
terminated successfully. This event is sent as result of calling
- <seealso marker="#exit_status">
+ <seealso marker="ssh_connection#exit_status-3">
ssh_connection:exit_status/3</seealso></item>
<tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
<item> This event is sent as result of calling
- <seealso marker="#close">ssh_connection:close/2</seealso> Both the handling of this
+ <seealso marker="ssh_connection#close-2">ssh_connection:close/2</seealso> Both the handling of this
event and sending of it will be taken care of by the
<seealso marker="ssh_channel">ssh_channel</seealso> behavior.</item>
@@ -122,17 +122,17 @@
<p> Channels implementing a shell and command execution on the
server side should handle the following messages that may be sent by client channel processes. </p>
- <p><note>Events that includes a <c> WantReply</c> expects the event handling
- process to call <seealso marker="#reply_request">ssh_connection:reply_request/4</seealso>
+ <note> <p>Events that includes a <c> WantReply</c> expects the event handling
+ process to call <seealso marker="ssh_connection#reply_request-4">ssh_connection:reply_request/4</seealso>
with the boolean value of <c> WantReply</c> as the second
- argument. </note> </p>
+ argument. </p></note>
<taglist>
<tag><c><![CDATA[{env, ssh_channel_id(), boolean() = WantReply,
string() = Var, string() = Value}]]></c></tag>
<item> Environment variables may be passed to the shell/command
to be started later. This event is sent as result of calling <seealso
- marker="#setenv"> ssh_connection:setenv/5</seealso>
+ marker="ssh_connection#setenv-5"> ssh_connection:setenv/5</seealso>
</item>
<tag><c><![CDATA[{pty, ssh_channel_id(),
@@ -157,7 +157,7 @@
<tag><c><![CDATA[{shell, boolean() = WantReply}]]></c></tag>
<item> This message will request that the user's default shell
be started at the other end. This event is sent as result of calling <seealso
- marker="#shell"> ssh_connection:shell/2</seealso>
+ marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>
</item>
<tag><c><![CDATA[{window_change, ssh_channel_id(), integer() = CharWidth,
@@ -171,7 +171,7 @@
boolean() = WantReply, string() = Cmd}]]></c></tag>
<item> This message will request that the server starts
execution of the given command. This event is sent as result of calling <seealso
- marker="#exec">ssh_connection:exec/4 </seealso>
+ marker="ssh_connection#exec-4">ssh_connection:exec/4 </seealso>
</item>
</taglist>
</item>
@@ -194,7 +194,7 @@
<note><p>Channels implemented with the <seealso marker="ssh_channel"> ssh_channel
behavior</seealso> will normaly not need to call this function as flow control
will be handled by the behavior. The behavior will adjust the window every time
- the callback <seealso marker="ssh_channel#handled_ssh_msg-2">
+ the callback <seealso marker="ssh_channel#Module:handle_ssh_msg-2">
handle_ssh_msg/2 </seealso> has returned after processing channel data</p> </note>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_server_key_api.xml b/lib/ssh/doc/src/ssh_server_key_api.xml
index 78ff105387..c4562e1211 100644
--- a/lib/ssh/doc/src/ssh_server_key_api.xml
+++ b/lib/ssh/doc/src/ssh_server_key_api.xml
@@ -5,6 +5,7 @@
<header>
<copyright>
<year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -58,7 +59,7 @@
<d> Host key algorithm. Should support 'ssh-rsa'| 'ssh-dss' but additional algorithms
can be handled.</d>
<v> DaemonOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#daemon">ssh:daemon/[2,3]</seealso></d>
+ <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso></d>
<v> Key = private_key()</v>
<d> The private key of the host matching the <c>Algorithm</c></d>
<v>Reason = term() </v>
@@ -77,7 +78,7 @@
<v> User = string()</v>
<d> The user owning the public key</d>
<v> DaemonOptions = proplists:proplist() </v>
- <d> Options provided to <seealso marker="ssh#daemon">ssh:daemon/[2,3]</seealso></d>
+ <d> Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso></d>
<v> Result = boolean()</v>
</type>
<desc>
diff --git a/lib/ssh/doc/src/ssh_sftpd.xml b/lib/ssh/doc/src/ssh_sftpd.xml
index 3666bc7692..a73d6e52d4 100644
--- a/lib/ssh/doc/src/ssh_sftpd.xml
+++ b/lib/ssh/doc/src/ssh_sftpd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2012</year>
+ <year>2005</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -61,7 +61,7 @@
<item>
<p>Determines which module to call for accessing
the file server. The default value is <c>ssh_sftpd_file</c> that uses the
- <seealso marker="kernel#file">file</seealso> and <seealso marker="kernel#filelib">filelib</seealso> API:s to access the standard OTP file
+ <seealso marker="kernel:file">file</seealso> and <seealso marker="stdlib:filelib">filelib</seealso> API:s to access the standard OTP file
server. This option may be used to plug in
other file servers.</p>
</item>
diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml
index 87b811d591..c994c1c56c 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -29,7 +29,7 @@
<section>
<title> General information</title>
<p>The examples in the following sections use the utility function
- <seealso marker="ssh#start"> ssh:start/0 </seealso> that starts
+ <seealso marker="ssh#start-0"> ssh:start/0 </seealso> that starts
all needed applications (crypto, public_key and ssh). All examples
are run in an Erlang shell, or in a bash shell using openssh to
illustrate how the erlang ssh application can be used. The
@@ -70,7 +70,7 @@
<p> The option system_dir must be a directory containing a host
key file and it defaults to /etc/ssh. For details see section
Configuration Files in <seealso
- marker="ssh_app">ssh(6)</seealso>.
+ marker="SSH_app">ssh(6)</seealso>.
</p>
<note><p>Normally the /etc/ssh directory is only readable by root. </p>
@@ -137,12 +137,13 @@
<title>One Time Execution</title>
<p>In the following example the Erlang shell is the client process
- that receives the channel replies. <note> If you run this example
+ that receives the channel replies. </p>
+
+ <note><p> If you run this example
in your environment you may get fewer or more messages back as
this depends on the OS and shell on the machine running the ssh
daemon. See also <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>
- </note>
- </p>
+ </p></note>
<code type="erl" >
1> ssh:start().
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 27e43a88ed..93d0b54f57 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -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
@@ -41,7 +41,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/ssh-$(VSN)
BEHAVIOUR_MODULES= \
ssh_sftpd_file_api \
ssh_channel \
- ssh_subsystem \
+ ssh_daemon_channel \
ssh_client_key_api \
ssh_server_key_api
diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src
index a0ba7cf7d9..49707f3378 100644
--- a/lib/ssh/src/ssh.app.src
+++ b/lib/ssh/src/ssh.app.src
@@ -17,6 +17,7 @@
ssh_connection_handler,
ssh_connection_manager,
ssh_connection_sup,
+ ssh_daemon_channel,
ssh_shell,
sshc_sup,
sshd_sup,
@@ -29,7 +30,6 @@
ssh_sftpd,
ssh_sftpd_file,
ssh_sftpd_file_api,
- ssh_subsystem,
ssh_subsystem_sup,
ssh_sup,
ssh_system_sup,
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 826a11f1f4..5ba3742de7 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -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
@@ -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 b5a0aa2e05..3a7aa79d16 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.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
@@ -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
%%
@@ -394,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;
@@ -503,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_channel.erl b/lib/ssh/src/ssh_channel.erl
index 4e8f8538c2..062ed764ca 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.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
@@ -48,10 +48,7 @@
{ok, NewState :: term()} | {error, Reason :: term()}.
-callback handle_msg(Msg ::term(), State :: term()) ->
- {noreply, NewState :: term()} |
- {noreply, NewState :: term(), timeout() | hibernate} |
- {stop, Reason :: term(), NewState :: term()}.
-
+ {ok, State::term()} | {stop, ChannelId::integer(), State::term()}.
-callback handle_ssh_msg({ssh_cm, ConnectionRef::term(), SshMsg::term()},
State::term()) -> {ok, State::term()} |
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index c8c610f8ef..7232cc482c 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
@@ -24,7 +24,7 @@
-module(ssh_cli).
--behaviour(ssh_channel).
+-behaviour(ssh_daemon_channel).
-include("ssh.hrl").
-include("ssh_connect.hrl").
diff --git a/lib/ssh/src/ssh_client_key_api.erl b/lib/ssh/src/ssh_client_key_api.erl
index eed0b85f47..a17c7cbc77 100644
--- a/lib/ssh/src/ssh_client_key_api.erl
+++ b/lib/ssh/src/ssh_client_key_api.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
@@ -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 9378686242..787d82c4db 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-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
diff --git a/lib/ssh/src/ssh_subsystem.erl b/lib/ssh/src/ssh_daemon_channel.erl
index 5a9fa32668..ab3efbcaff 100644
--- a/lib/ssh/src/ssh_subsystem.erl
+++ b/lib/ssh/src/ssh_daemon_channel.erl
@@ -1,4 +1,28 @@
--module(ssh_subsystem).
+%%
+%% %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%
+%%
+
+%%
+%% Description: a gen_server implementing a simple
+%% terminal (using the group module) for a CLI
+%% over SSH
+
+-module(ssh_daemon_channel).
%% API to special server side channel that can be pluged into the erlang ssh daemeon
-callback init(Args :: term()) ->
@@ -11,10 +35,7 @@
term().
-callback handle_msg(Msg ::term(), State :: term()) ->
- {noreply, NewState :: term()} |
- {noreply, NewState :: term(), timeout() | hibernate} |
- {stop, Reason :: term(), NewState :: term()}.
-
+ {ok, State::term()} | {stop, ChannelId::integer(), State::term()}.
-callback handle_ssh_msg({ssh_cm, ConnectionRef::term(), SshMsg::term()},
State::term()) -> {ok, State::term()} |
{stop, ChannelId::integer(),
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index f000558100..f3afbe01bf 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
@@ -47,7 +47,7 @@
recv_window/2, list_dir/3, read_file/3, write_file/4]).
%% ssh_channel callbacks
--export([init/1, handle_call/3, handle_msg/2, handle_ssh_msg/2, terminate/2]).
+-export([init/1, handle_call/3, handle_cast/2, code_change/3, handle_msg/2, handle_ssh_msg/2, terminate/2]).
%% TODO: Should be placed elsewhere ssh_sftpd should not call functions in ssh_sftp!
-export([info_to_attr/1, attr_to_info/1]).
@@ -436,6 +436,12 @@ handle_call({{timeout, Timeout}, Msg}, From, #state{req_id = Id} = State) ->
timer:send_after(Timeout, {timeout, Id, From}),
do_handle_call(Msg, From, State).
+handle_cast(_,State) ->
+ {noreply, State}.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
do_handle_call({open, Async,FileName,Mode}, From, #state{xf = XF} = State) ->
{Access,Flags,Attrs} = open_mode(XF#ssh_xfer.vsn, Mode),
ReqID = State#state.req_id,
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index c7e8373840..3d469d3c6e 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -23,8 +23,7 @@
-module(ssh_sftpd).
-%%-behaviour(gen_server).
--behaviour(ssh_subsystem).
+-behaviour(ssh_daemon_channel).
-include_lib("kernel/include/file.hrl").
@@ -159,7 +158,7 @@ handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State) ->
{stop, ChannelId, State}.
%%--------------------------------------------------------------------
-%% Function: handle_ssh_msg(Args) -> {ok, State} | {stop, ChannelId, State}
+%% Function: handle_msg(Args) -> {ok, State} | {stop, ChannelId, State}
%%
%% Description: Handles other messages
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_shell.erl b/lib/ssh/src/ssh_shell.erl
index 6590486a4c..8031450617 100644
--- a/lib/ssh/src/ssh_shell.erl
+++ b/lib/ssh/src/ssh_shell.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,9 @@
-include("ssh_connect.hrl").
--behaviour(ssh_channel).
+%%% As this is an user interactive client it behaves like a daemon
+%%% channel inspite of it being a client.
+-behaviour(ssh_daemon_channel).
%% ssh_channel callbacks
-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]).
@@ -123,7 +125,7 @@ handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State) ->
{stop, ChannelId, State}.
%%--------------------------------------------------------------------
-%% Function: handle_ssh_msg(Args) -> {ok, State} | {stop, ChannelId, State}
+%% Function: handle_msg(Args) -> {ok, State} | {stop, ChannelId, State}
%%
%% Description: Handles other channel messages
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_xfer.hrl b/lib/ssh/src/ssh_xfer.hrl
index 0d85cf2094..8dc9a40f92 100644
--- a/lib/ssh/src/ssh_xfer.hrl
+++ b/lib/ssh/src/ssh_xfer.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
index 9f8a7c496c..8ad383d8c9 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. 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
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/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml
index 178bbcaebb..84ad483617 100644
--- a/lib/ssl/doc/src/ssl_app.xml
+++ b/lib/ssl/doc/src/ssl_app.xml
@@ -4,7 +4,7 @@
<appref>
<header>
<copyright>
- <year>1999</year><year>2010</year>
+ <year>1999</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
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 94f76e0606..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) ->
@@ -2510,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_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/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl
index d6bdd05d01..5b92e551a5 100644
--- a/lib/ssl/test/erl_make_certs.erl
+++ b/lib/ssl/test/erl_make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011. 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
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..f90a82187d 100644
--- a/lib/stdlib/doc/src/base64.xml
+++ b/lib/stdlib/doc/src/base64.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2011</year>
+ <year>2007</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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/ets.xml b/lib/stdlib/doc/src/ets.xml
index abaf64fb91..44c050a0d3 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -932,7 +932,8 @@ ets:select(Table,MatchSpec),</code>
If set to <c>true</c>, the table is optimized towards concurrent
write access. Different objects of the same table can be mutated
(and read) by concurrent processes. This is achieved to some degree
- at the expense of sequential access and concurrent reader performance.
+ at the expense of memory consumption and the performance of
+ sequential access and concurrent reading.
The <c>write_concurrency</c> option can be combined with the
<seealso marker="#new_2_read_concurrency">read_concurrency</seealso>
option. You typically want to combine these when large concurrent
@@ -944,8 +945,11 @@ ets:select(Table,MatchSpec),</code>
<seealso marker="#concurrency">atomicy and isolation</seealso>.
Functions that makes such promises over several objects (like
<c>insert/2</c>) will gain less (or nothing) from this option.</p>
- <p>Table type <c>ordered_set</c> is not affected by this option in current
- implementation.</p>
+ <p>In current implementation, table type <c>ordered_set</c> is not
+ affected by this option. Also, the memory consumption inflicted by
+ both <c>write_concurrency</c> and <c>read_concurrency</c> is a
+ constant overhead per table. This overhead can be especially large
+ when both options are combined.</p>
</item>
<item>
<marker id="new_2_read_concurrency"></marker>
diff --git a/lib/stdlib/doc/src/filelib.xml b/lib/stdlib/doc/src/filelib.xml
index cec20aee8e..ac67596f3c 100644
--- a/lib/stdlib/doc/src/filelib.xml
+++ b/lib/stdlib/doc/src/filelib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2003</year><year>2011</year>
+ <year>2003</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
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/proplists.xml b/lib/stdlib/doc/src/proplists.xml
index 8d64319344..a0063a58d3 100644
--- a/lib/stdlib/doc/src/proplists.xml
+++ b/lib/stdlib/doc/src/proplists.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2011</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
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/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml
index 61f49f5940..484bf0e080 100644
--- a/lib/stdlib/doc/src/zip.xml
+++ b/lib/stdlib/doc/src/zip.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2011</year>
+ <year>2006</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
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 2bab46b72a..f3387d669b 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -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
@@ -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
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..fe7e0f8e60 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
@@ -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..535f2d5174 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.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
@@ -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..ecb509f4b5 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.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
@@ -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..7bbb34dd15 100644
--- a/lib/stdlib/src/dets_utils.erl
+++ b/lib/stdlib/src/dets_utils.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. 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
@@ -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..24d6e06ec8 100644
--- a/lib/stdlib/src/dets_v8.erl
+++ b/lib/stdlib/src/dets_v8.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. 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
@@ -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..308f81c23b 100644
--- a/lib/stdlib/src/dets_v9.erl
+++ b/lib/stdlib/src/dets_v9.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. 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
@@ -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..8c3d59467b 100644
--- a/lib/stdlib/src/erl_compile.erl
+++ b/lib/stdlib/src/erl_compile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -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_eval.erl b/lib/stdlib/src/erl_eval.erl
index 8471ae6b64..1c3f91cbfc 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.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
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index 3063881890..254384e877 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.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
@@ -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 9a01e85006..deae9640f5 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.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
@@ -136,8 +136,6 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
format_error(undefined_module) ->
"no module definition";
-format_error({bad_module_name, M}) ->
- io_lib:format("bad module name '~s'", [M]);
format_error(redefine_module) ->
"redefining module";
format_error(pmod_unsupported) ->
@@ -238,8 +236,6 @@ format_error({illegal_guard_local_call, {F,A}}) ->
io_lib:format("call to local/imported function ~w/~w is illegal in guard",
[F,A]);
format_error(illegal_guard_expr) -> "illegal guard expression";
-format_error(deprecated_tuple_fun) ->
- "tuple funs are deprecated and will be removed in R16";
%% --- exports ---
format_error({explicit_export,F,A}) ->
io_lib:format("in this release, the call to ~w/~w must be written "
@@ -2159,9 +2155,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}
@@ -3438,7 +3432,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..4b654833ed 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -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
@@ -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..32742e419b 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.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
@@ -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..77c8029f59 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.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
@@ -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..2bf88959b7 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. 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
@@ -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..4e2ce39ec2 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -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/proplists.erl b/lib/stdlib/src/proplists.erl
index 204f8e128c..634724019f 100644
--- a/lib/stdlib/src/proplists.erl
+++ b/lib/stdlib/src/proplists.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. 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
diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl
index 9b71d0edb8..6a27cff589 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.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
@@ -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..26bc4d1bdf 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.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
@@ -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..4bbf5de8a5 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.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
@@ -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..203d2a4f76 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);
@@ -836,16 +836,6 @@ not_restricted(h, []) ->
true;
not_restricted(b, []) ->
true;
-not_restricted(which, [_]) ->
- true;
-not_restricted(import, [_]) ->
- true;
-not_restricted(import_all, [_]) ->
- true;
-not_restricted(use, [_]) ->
- true;
-not_restricted(use_all, [_]) ->
- true;
not_restricted(history, [_]) ->
true;
not_restricted(results, [_]) ->
@@ -1005,15 +995,6 @@ local_func(rr, [_,_]=As0, Bs0, _Shell, RT, Lf, Ef) ->
local_func(rr, [_,_,_]=As0, Bs0, _Shell, RT, Lf, Ef) ->
{[File,Sel,Options],Bs} = expr_list(As0, Bs0, Lf, Ef),
{value,read_and_add_records(File, Sel, Options, Bs, RT),Bs};
-local_func(which, [{atom,_,M}], Bs, _Shell, _RT, _Lf, _Ef) ->
- case erl_eval:binding({module,M}, Bs) of
- {value, M1} ->
- {value,M1,Bs};
- unbound ->
- {value,M,Bs}
- end;
-local_func(which, [_Other], _Bs, _Shell, _RT, _Lf, _Ef) ->
- erlang:raise(error, function_clause, [{shell,which,1}]);
local_func(history, [{integer,_,N}], Bs, _Shell, _RT, _Lf, _Ef) ->
{value,history(N),Bs};
local_func(history, [_Other], _Bs, _Shell, _RT, _Lf, _Ef) ->
@@ -1149,18 +1130,13 @@ listify(E) ->
[E].
check_command(Es, Bs) ->
- erl_eval:check_command(Es, strip_bindings(Bs)).
+ erl_eval:check_command(Es, Bs).
expr(E, Bs, Lf, Ef) ->
- erl_eval:expr(E, strip_bindings(Bs), Lf, Ef).
+ erl_eval:expr(E, Bs, Lf, Ef).
expr_list(Es, Bs, Lf, Ef) ->
- erl_eval:expr_list(Es, strip_bindings(Bs), Lf, Ef).
-
--spec strip_bindings(erl_eval:binding_struct()) -> erl_eval:binding_struct().
-
-strip_bindings(Bs) ->
- Bs -- [B || {{module,_},_}=B <- Bs].
+ erl_eval:expr_list(Es, Bs, Lf, Ef).
%% Note that a sequence number is used here to make sure that if a
%% record is used by another record, then the first record is parsed
@@ -1321,9 +1297,6 @@ list_commands([_D|Ds], RT) ->
list_commands(Ds, RT);
list_commands([], _RT) -> ok.
-list_bindings([{{module,M},Val}|Bs], RT) ->
- io:fwrite(<<"~w is ~w\n">>, [M,Val]),
- list_bindings(Bs, RT);
list_bindings([{Name,Val}|Bs], RT) ->
case erl_eval:fun_data(Val) of
{fun_data,_FBs,FCs0} ->
diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl
index de0179da59..9c74041f56 100644
--- a/lib/stdlib/src/slave.erl
+++ b/lib/stdlib/src/slave.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
@@ -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..4ed27ff4eb 100644
--- a/lib/stdlib/src/string.erl
+++ b/lib/stdlib/src/string.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
@@ -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..c40ce8e203 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -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/dict_SUITE.erl b/lib/stdlib/test/dict_SUITE.erl
index df9c769c67..0223240479 100644
--- a/lib/stdlib/test/dict_SUITE.erl
+++ b/lib/stdlib/test/dict_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. 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
diff --git a/lib/stdlib/test/dict_test_lib.erl b/lib/stdlib/test/dict_test_lib.erl
index 7167014310..e308fd0721 100644
--- a/lib/stdlib/test/dict_test_lib.erl
+++ b/lib/stdlib/test/dict_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. 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
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_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 3749d594f2..be8fb1b37a 100644
--- a/lib/stdlib/test/escript_SUITE.erl
+++ b/lib/stdlib/test/escript_SUITE.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
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index 1fd7518519..27078f0914 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. 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
diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index 22f66a6c14..a637a8543b 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-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
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/sets_SUITE.erl b/lib/stdlib/test/sets_SUITE.erl
index e2bcdd18ce..c0cf1fc7e8 100644
--- a/lib/stdlib/test/sets_SUITE.erl
+++ b/lib/stdlib/test/sets_SUITE.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
diff --git a/lib/stdlib/test/sets_test_lib.erl b/lib/stdlib/test/sets_test_lib.erl
index fd4ec2bac3..86f009a8f9 100644
--- a/lib/stdlib/test/sets_test_lib.erl
+++ b/lib/stdlib/test/sets_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. 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
diff --git a/lib/stdlib/test/sys_SUITE.erl b/lib/stdlib/test/sys_SUITE.erl
index b2e1d12b2a..c06ba545e7 100644
--- a/lib/stdlib/test/sys_SUITE.erl
+++ b/lib/stdlib/test/sys_SUITE.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
diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl
index 1110891ab8..bea2b3fb2a 100644
--- a/lib/stdlib/test/timer_SUITE.erl
+++ b/lib/stdlib/test/timer_SUITE.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
diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile
index 2aa6591c77..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 \
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 43a03f4e1d..ebc5f5b71b 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -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
@@ -91,7 +91,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I../include
+ERL_COMPILE_FLAGS += -I../include -Werror
# ----------------------------------------------------
# Targets
diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl
index 1729257809..9c0ca64173 100644
--- a/lib/test_server/src/erl2html2.erl
+++ b/lib/test_server/src/erl2html2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -34,16 +34,17 @@ convert(File, Dest) ->
%%
%% FIXME: The colours should *really* be set with
%% stylesheets...
+ %%
+ %% The html file is written with the same encoding as the input file.
Encoding = encoding(File),
Header = ["<!DOCTYPE HTML PUBLIC "
"\"-//W3C//DTD HTML 3.2 Final//EN\">\n"
- "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n"
+ "<!-- autogenerated by '",atom_to_list(?MODULE),"'. -->\n"
"<html>\n"
"<head>\n"
"<meta http-equiv=\"Content-Type\" content=\"text/html;"
- "charset=",
- Encoding,"\"/>\n"
- "<title>", File, "</title>\n"
+ "charset=",html_encoding(Encoding),"\"/>\n"
+ "<title>", to_raw_list(File,Encoding), "</title>\n"
"</head>\n\n"
"<body bgcolor=\"white\" text=\"black\""
" link=\"blue\" vlink=\"purple\" alink=\"red\">\n"],
@@ -61,7 +62,7 @@ convert(File, Dest, Header) ->
case file:open(Dest,[write,raw]) of
{ok,DFd} ->
file:write(DFd,[Header,"<pre>\n"]),
- _Lines = build_html(SFd,DFd,Functions),
+ _Lines = build_html(SFd,DFd,encoding(File),Functions),
file:write(DFd,["</pre>\n",footer(),
"</body>\n</html>\n"]),
%% {_, Time2} = statistics(runtime),
@@ -121,21 +122,21 @@ parse_file(Epp,File,InCorrectFile) ->
%%%-----------------------------------------------------------------
%%% Add a link target for each line and one for each function definition.
-build_html(SFd,DFd,Functions) ->
- build_html(SFd,DFd,file:read_line(SFd),1,Functions,false).
+build_html(SFd,DFd,Encoding,Functions) ->
+ build_html(SFd,DFd,Encoding,file:read_line(SFd),1,Functions,false).
-build_html(SFd,DFd,{ok,Str},L,[{F,A,L}|Functions],_IsFuncDef) ->
+build_html(SFd,DFd,Encoding,{ok,Str},L,[{F,A,L}|Functions],_IsFuncDef) ->
FALink = http_uri:encode(F++"-"++integer_to_list(A)),
- file:write(DFd,["<a name=\"",FALink,"\"/>"]),
- build_html(SFd,DFd,{ok,Str},L,Functions,true);
-build_html(SFd,DFd,{ok,Str},L,[{clause,L}|Functions],_IsFuncDef) ->
- build_html(SFd,DFd,{ok,Str},L,Functions,true);
-build_html(SFd,DFd,{ok,Str},L,Functions,IsFuncDef) ->
+ file:write(DFd,["<a name=\"",to_raw_list(FALink,Encoding),"\"/>"]),
+ build_html(SFd,DFd,Encoding,{ok,Str},L,Functions,true);
+build_html(SFd,DFd,Encoding,{ok,Str},L,[{clause,L}|Functions],_IsFuncDef) ->
+ build_html(SFd,DFd,Encoding,{ok,Str},L,Functions,true);
+build_html(SFd,DFd,Encoding,{ok,Str},L,Functions,IsFuncDef) ->
LStr = line_number(L),
Str1 = line(Str,IsFuncDef),
file:write(DFd,[LStr,Str1]),
- build_html(SFd,DFd,file:read_line(SFd),L+1,Functions,false);
-build_html(_SFd,_DFd,eof,L,_Functions,_IsFuncDef) ->
+ build_html(SFd,DFd,Encoding,file:read_line(SFd),L+1,Functions,false);
+build_html(_SFd,_DFd,_Encoding,eof,L,_Functions,_IsFuncDef) ->
L.
line_number(L) ->
@@ -190,16 +191,35 @@ footer() ->
%%%-----------------------------------------------------------------
%%% Read encoding from source file
encoding(File) ->
- Encoding =
- case epp:read_encoding(File) of
- none ->
- epp:default_encoding();
- E ->
- E
- end,
- html_encoding(Encoding).
+ case epp:read_encoding(File) of
+ none ->
+ epp:default_encoding();
+ E ->
+ E
+ end.
+%%%-----------------------------------------------------------------
+%%% Covert encoding atom to string for use in HTML header
html_encoding(latin1) ->
"iso-8859-1";
html_encoding(utf8) ->
"utf-8".
+
+%%%-----------------------------------------------------------------
+%%% Convert a string to a list of raw printable characters in the
+%%% given encoding. This is necessary since the files (source and
+%%% destination) are both opened in raw mode (default encoding). Byte
+%%% by byte is read from source and written to the destination. This
+%%% conversion is needed when printing data that is not first read
+%%% from the source.
+%%%
+%%% Example: if the encoding of the file is utf8, and we have a string
+%%% containing "�" = [229], then we need to convert this to [195,165]
+%%% before writing. Note that this conversion is only necessary
+%%% because the destination file is not (necessarily) opened with utf8
+%%% encoding - it is opened with default encoding in order to allow
+%%% raw file mode and byte by byte copying from source.
+to_raw_list(X,latin1) when is_list(X) ->
+ X;
+to_raw_list(X,utf8) when is_list(X) ->
+ binary_to_list(unicode:characters_to_binary(X)).
diff --git a/lib/test_server/src/test_server.app.src b/lib/test_server/src/test_server.app.src
index 26330f9695..163f370a47 100644
--- a/lib/test_server/src/test_server.app.src
+++ b/lib/test_server/src/test_server.app.src
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 37cd8fac99..43330d2c91 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.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
@@ -123,7 +123,7 @@ cover_compile({App,all,Include,Cross}) ->
io:format("\nWARNING: All modules in \'~w\' are excluded\n"
"Only cover compiling modules in include list "
"and the modules\nin the cross cover file:\n"
- "~p\n", [App,CompileMods]),
+ "~tp\n", [App,CompileMods]),
do_cover_compile(CompileMods),
io:fwrite("done\n\n",[]),
{ok,Include}
@@ -143,7 +143,7 @@ cover_compile({App,Exclude,Include,Cross}) ->
[App,length(CompileMods)]),
io:format("\nWARNING: Can't find lib_dir for \'~w\'\n"
"Only cover compiling modules in include list: "
- "~p\n", [App,Include]),
+ "~tp\n", [App,Include]),
do_cover_compile(CompileMods),
io:fwrite("done\n\n",[]),
{ok,Include}
@@ -186,7 +186,7 @@ do_cover_compile1([M|Rest]) ->
{ok,_} ->
ok;
Error ->
- io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n",
+ io:fwrite("\nWARNING: Could not cover compile ~w: ~tp\n",
[M,Error])
end,
code:stick_mod(M),
@@ -196,7 +196,7 @@ do_cover_compile1([M|Rest]) ->
{module,_} ->
do_cover_compile1([M|Rest]);
Error ->
- io:fwrite("\nWARNING: Could not load ~w: ~p\n",[M,Error]),
+ io:fwrite("\nWARNING: Could not load ~w: ~tp\n",[M,Error]),
do_cover_compile1(Rest)
end;
{false,_} ->
@@ -204,7 +204,7 @@ do_cover_compile1([M|Rest]) ->
{ok,_} ->
ok;
Error ->
- io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n",
+ io:fwrite("\nWARNING: Could not cover compile ~w: ~tp\n",
[M,Error])
end,
do_cover_compile1(Rest)
@@ -286,7 +286,7 @@ cover_analyse(Analyse,Modules,Stop) ->
{ok,{M,{Cov,NotCov}}} ->
{M,{Cov,NotCov,DetailsFun(M)}};
Err ->
- io:fwrite("WARNING: Analysis failed for ~w. Reason: ~p\n",
+ io:fwrite("WARNING: Analysis failed for ~w. Reason: ~tp\n",
[M,Err]),
{M,Err}
end
@@ -436,8 +436,8 @@ run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
_ ->
Args
end,
- print(minor, "Test case started with:\n~s:~s(~p)\n", [Mod,Func,Args2Print]),
- print(minor, "Current directory is ~p\n", [Cwd]),
+ print(minor, "Test case started with:\n~w:~w(~tp)\n", [Mod,Func,Args2Print]),
+ print(minor, "Current directory is ~tp\n", [Cwd]),
print_timestamp(minor,"Started at "),
print(minor, "", [], internal_raw),
TCCallback = get(test_server_testcase_callback),
@@ -498,7 +498,7 @@ run_test_case_msgloop(#st{ref=Ref,pid=Pid,end_conf_pid=EndConfPid0}=St0) ->
exit(Pid, kill),
%% here's the only place we know Reason, so we save
%% it as a comment, potentially replacing user data
- Error = lists:flatten(io_lib:format("Aborted: ~p",
+ Error = lists:flatten(io_lib:format("Aborted: ~tp",
[Reason])),
Error1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(Error,
@@ -742,8 +742,8 @@ call_end_conf(Mod,Func,TCPid,TCExitReason,Loc,Conf,TVal) ->
timer:sleep(1),
group_leader() ! {printout,12,
"WARNING! "
- "~p:end_per_testcase(~p, ~p)"
- " crashed!\n\tReason: ~p\n",
+ "~w:end_per_testcase(~w, ~tp)"
+ " crashed!\n\tReason: ~tp\n",
[Mod,Func,Conf,Why]};
_ ->
ok
@@ -756,8 +756,8 @@ call_end_conf(Mod,Func,TCPid,TCExitReason,Loc,Conf,TVal) ->
Starter ! {self(),{call_end_conf,Data,ok}};
{'EXIT',Pid,Reason} ->
group_leader() ! {printout,12,
- "WARNING! ~p:end_per_testcase(~p, ~p)"
- " failed!\n\tReason: ~p\n",
+ "WARNING! ~w:end_per_testcase(~w, ~tp)"
+ " failed!\n\tReason: ~tp\n",
[Mod,Func,Conf,Reason]},
Starter ! {self(),{call_end_conf,Data,{error,Reason}}};
{'EXIT',_OtherPid,Reason} ->
@@ -802,7 +802,7 @@ spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid,
{Result,E}
end,
group_leader() ! {printout,12,
- "WARNING! ~p:end_per_testcase(~p, ~p)"
+ "WARNING! ~w:end_per_testcase(~w, ~tp)"
" failed!\n\tReason: timetrap timeout"
" after ~w ms!\n", [Mod,Func,EndConf,TVal]},
FailLoc = proplists:get_value(tc_fail_loc, EndConf),
@@ -1180,7 +1180,7 @@ do_init_per_testcase(Mod, Args) ->
Bad ->
group_leader() ! {printout,12,
"ERROR! init_per_testcase has returned "
- "bad elements in Config: ~p\n",[Bad]},
+ "bad elements in Config: ~tp\n",[Bad]},
{skip,{failed,{Mod,init_per_testcase,bad_return}}}
end;
{fail,_Reason}=Res ->
@@ -1197,7 +1197,7 @@ do_init_per_testcase(Mod, Args) ->
FormattedLoc = test_server_sup:format_loc(Line),
group_leader() ! {printout,12,
"ERROR! init_per_testcase thrown!\n"
- "\tLocation: ~s\n\tReason: ~p\n",
+ "\tLocation: ~ts\n\tReason: ~tp\n",
[FormattedLoc, Other]},
{skip,{failed,{Mod,init_per_testcase,Other}}};
_:Reason0 ->
@@ -1208,7 +1208,7 @@ do_init_per_testcase(Mod, Args) ->
FormattedLoc = test_server_sup:format_loc(Line),
group_leader() ! {printout,12,
"ERROR! init_per_testcase crashed!\n"
- "\tLocation: ~s\n\tReason: ~p\n",
+ "\tLocation: ~ts\n\tReason: ~tp\n",
[FormattedLoc,Reason]},
{skip,{failed,{Mod,init_per_testcase,Reason}}}
end.
@@ -1244,13 +1244,13 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) ->
"<br />")
end,
set_loc(erlang:get_stacktrace()),
- comment(io_lib:format("~s<font color=\"red\">"
+ comment(io_lib:format("~ts<font color=\"red\">"
"WARNING: ~w thrown!"
"</font>\n",[Comment0,EndFunc])),
group_leader() ! {printout,12,
"WARNING: ~w thrown!\n"
- "Reason: ~p\n"
- "Line: ~s\n",
+ "Reason: ~tp\n"
+ "Line: ~ts\n",
[EndFunc, Other,
test_server_sup:format_loc(get_loc())]},
{failed,{Mod,end_per_testcase,Other}};
@@ -1266,13 +1266,13 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) ->
Cmt -> Cmt ++ test_server_ctrl:xhtml("<br>",
"<br />")
end,
- comment(io_lib:format("~s<font color=\"red\">"
+ comment(io_lib:format("~ts<font color=\"red\">"
"WARNING: ~w crashed!"
"</font>\n",[Comment0,EndFunc])),
group_leader() ! {printout,12,
"WARNING: ~w crashed!\n"
- "Reason: ~p\n"
- "Line: ~s\n",
+ "Reason: ~tp\n"
+ "Line: ~ts\n",
[EndFunc, Reason,
test_server_sup:format_loc(get_loc())]},
{failed,{Mod,end_per_testcase,Why}}
@@ -1351,7 +1351,7 @@ lookup_config(Key,Config) ->
{value,{Key,Val}} ->
Val;
_ ->
- io:format("Could not find element ~p in Config.~n",[Key]),
+ io:format("Could not find element ~tp in Config.~n",[Key]),
undefined
end.
@@ -1433,7 +1433,7 @@ format(Detail, Format, Args) ->
Str =
case catch io_lib:format(Format,Args) of
{'EXIT',_} ->
- io_lib:format("illegal format; ~p with args ~p.\n",
+ io_lib:format("illegal format; ~tp with args ~tp.\n",
[Format,Args]);
Valid -> Valid
end,
@@ -1564,7 +1564,7 @@ fail(Reason) ->
cast_to_list(X) when is_list(X) -> X;
cast_to_list(X) when is_atom(X) -> atom_to_list(X);
-cast_to_list(X) -> lists:flatten(io_lib:format("~p", [X])).
+cast_to_list(X) -> lists:flatten(io_lib:format("~tp", [X])).
@@ -1608,10 +1608,10 @@ break(CBM, TestCase, Comment) ->
end,
io:format(user,
"\n\n\n--- SEMIAUTOMATIC TESTING ---"
- "\nThe test case~s executes on process ~w"
- "\n\n\n~s"
+ "\nThe test case~ts executes on process ~w"
+ "\n\n\n~ts"
"\n\n\n-----------------------------\n\n"
- "Continue with --> ~w:continue(~s).\n",
+ "Continue with --> ~w:continue(~ts).\n",
[TCName,self(),Comment,CBM,CntArg]),
case whereis(PName) of
undefined ->
@@ -1735,7 +1735,7 @@ ensure_timetrap(Config) ->
Garbage ->
erase(test_server_default_timetrap),
format("=== WARNING: garbage in "
- "test_server_default_timetrap: ~p~n",
+ "test_server_default_timetrap: ~tp~n",
[Garbage])
end,
DTmo = case lists:keysearch(default_timeout,1,Config) of
@@ -1743,7 +1743,7 @@ ensure_timetrap(Config) ->
_ -> ?DEFAULT_TIMETRAP_SECS
end,
format("=== test_server setting default "
- "timetrap of ~p seconds~n",
+ "timetrap of ~tp seconds~n",
[DTmo]),
put(test_server_default_timetrap, timetrap(seconds(DTmo)))
end.
@@ -1764,7 +1764,7 @@ cancel_default_timetrap(true) ->
Garbage ->
erase(test_server_default_timetrap),
format("=== WARNING: garbage in "
- "test_server_default_timetrap: ~p~n",
+ "test_server_default_timetrap: ~tp~n",
[Garbage]),
error
end.
@@ -1773,7 +1773,7 @@ time_ms({hours,N}, _, _) -> hours(N);
time_ms({minutes,N}, _, _) -> minutes(N);
time_ms({seconds,N}, _, _) -> seconds(N);
time_ms({Other,_N}, _, _) ->
- format("=== ERROR: Invalid time specification: ~p. "
+ format("=== ERROR: Invalid time specification: ~tp. "
"Should be seconds, minutes, or hours.~n", [Other]),
exit({invalid_time_format,Other});
time_ms(Ms, _, _) when is_integer(Ms) -> Ms;
@@ -2266,14 +2266,14 @@ stop_node(Slave) ->
slave:stop(Slave),
receive
{nodedown, Slave} ->
- format(minor, "Stopped slave node: ~p", [Slave]),
- format(major, "=node_stop ~p", [Slave]),
+ format(minor, "Stopped slave node: ~w", [Slave]),
+ format(major, "=node_stop ~w", [Slave]),
if Cover -> do_cover_for_node(Slave,stop,false);
true -> ok
end,
true
after 30000 ->
- format("=== WARNING: Node ~p does not seem to terminate.",
+ format("=== WARNING: Node ~w does not seem to terminate.",
[Slave]),
erlang:monitor_node(Slave, false),
receive {nodedown, Slave} -> ok after 0 -> ok end,
@@ -2283,7 +2283,7 @@ stop_node(Slave) ->
%% Either, the node is already dead or it was started
%% with the {cleanup,false} option, or it was started
%% in some other way than test_server:start_node/3
- format("=== WARNING: Attempt to stop a nonexisting slavenode (~p)~n"
+ format("=== WARNING: Attempt to stop a nonexisting slavenode (~w)~n"
"=== Trying to kill it anyway!!!",
[Slave]),
case net_adm:ping(Slave)of
@@ -2292,14 +2292,14 @@ stop_node(Slave) ->
slave:stop(Slave),
receive
{nodedown, Slave} ->
- format(minor, "Stopped slave node: ~p", [Slave]),
- format(major, "=node_stop ~p", [Slave]),
+ format(minor, "Stopped slave node: ~w", [Slave]),
+ format(major, "=node_stop ~w", [Slave]),
if Cover -> do_cover_for_node(Slave,stop,false);
true -> ok
end,
true
after 30000 ->
- format("=== WARNING: Node ~p does not seem to terminate.",
+ format("=== WARNING: Node ~w does not seem to terminate.",
[Slave]),
erlang:monitor_node(Slave, false),
receive {nodedown, Slave} -> ok after 0 -> ok end,
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index c5c57426b4..e5d75e43c9 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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,6 @@
%% %CopyrightEnd%
%%
-module(test_server_ctrl).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
%% The Erlang Test Server %%
@@ -65,6 +64,7 @@
-export([get_target_info/0]).
-export([get_hosts/0]).
-export([node_started/1]).
+-export([uri_encode/1,uri_encode/2]).
%%% DEBUGGER INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([i/0, p/1, p/3, pi/2, pi/4, t/0, t/1]).
@@ -229,12 +229,12 @@ parse_cmd_line(['SPEC',Spec|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
parse_cmd_line(Cmds, TermList++SpecList, [Name|Names], Param,
Trc, Cov, TCCB);
{error,Reason} ->
- io:format("Can't open ~s: ~p\n",
- [cast_to_list(Spec), file:format_error(Reason)]),
+ io:format("Can't open ~w: ~tp\n",[Spec, file:format_error(Reason)]),
parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, TCCB)
end;
parse_cmd_line(['NAME',Name|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
- parse_cmd_line(Cmds, SpecList, [{name,Name}|Names], Param, Trc, Cov, TCCB);
+ parse_cmd_line(Cmds, SpecList, [{name,atom_to_list(Name)}|Names],
+ Param, Trc, Cov, TCCB);
parse_cmd_line(['SKIPMOD',Mod|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
parse_cmd_line(Cmds, [{skip,{Mod,"by command line"}}|SpecList], Names,
Param, Trc, Cov, TCCB);
@@ -242,14 +242,14 @@ parse_cmd_line(['SKIPCASE',Mod,Case|Cmds], SpecList, Names, Param, Trc, Cov, TCC
parse_cmd_line(Cmds, [{skip,{Mod,Case,"by command line"}}|SpecList], Names,
Param, Trc, Cov, TCCB);
parse_cmd_line(['DIR',Dir|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
- Name = cast_to_list(filename:basename(Dir)),
+ Name = filename:basename(Dir),
parse_cmd_line(Cmds, [{topcase,{dir,Name}}|SpecList], [Name|Names],
Param, Trc, Cov, TCCB);
parse_cmd_line(['MODULE',Mod|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
- parse_cmd_line(Cmds, [{topcase,{Mod,all}}|SpecList], [Mod|Names],
+ parse_cmd_line(Cmds,[{topcase,{Mod,all}}|SpecList],[atom_to_list(Mod)|Names],
Param, Trc, Cov, TCCB);
parse_cmd_line(['CASE',Mod,Case|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
- parse_cmd_line(Cmds, [{topcase,{Mod,Case}}|SpecList], [Mod|Names],
+ parse_cmd_line(Cmds,[{topcase,{Mod,Case}}|SpecList],[atom_to_list(Mod)|Names],
Param, Trc, Cov, TCCB);
parse_cmd_line(['PARAMETERS',Param|Cmds], SpecList, Names, _Param, Trc, Cov, TCCB) ->
parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, TCCB);
@@ -260,17 +260,17 @@ parse_cmd_line(['COVER',App,CF,Analyse|Cmds], SpecList, Names, Param, Trc, _Cov,
parse_cmd_line(['TESTCASE_CALLBACK',Mod,Func|Cmds], SpecList, Names, Param, Trc, Cov, _) ->
parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, {Mod,Func});
parse_cmd_line([Obj|_Cmds], _SpecList, _Names, _Param, _Trc, _Cov, _TCCB) ->
- io:format("~p: Bad argument: ~p\n", [?MODULE,Obj]),
+ io:format("~w: Bad argument: ~w\n", [?MODULE,Obj]),
io:format(" Use the `ts' module to start tests.\n", []),
io:format(" (If you ARE using `ts', there is a bug in `ts'.)\n", []),
halt(1);
parse_cmd_line([], SpecList, Names, Param, Trc, Cov, TCCB) ->
- NameList = lists:reverse(Names, [suite]),
+ NameList = lists:reverse(Names, ["suite"]),
Name = case lists:keysearch(name, 1, NameList) of
{value,{name,N}} -> N;
false -> hd(NameList)
end,
- {lists:reverse(SpecList), cast_to_list(Name), Param, Trc, Cov, TCCB}.
+ {lists:reverse(SpecList), Name, Param, Trc, Cov, TCCB}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% cast_to_list(X) -> string()
@@ -1011,9 +1011,9 @@ handle_info({'EXIT',Pid,Reason}, State) ->
normal ->
fine;
killed ->
- io:format("Suite ~s was killed\n", [Name]);
+ io:format("Suite ~ts was killed\n", [Name]);
_Other ->
- io:format("Suite ~s was killed with reason ~p\n",
+ io:format("Suite ~ts was killed with reason ~tp\n",
[Name,Reason])
end,
State2 = State#state{jobs=NewJobs},
@@ -1057,8 +1057,8 @@ handle_info({tcp,_MainSock,<<1,Request/binary>>}, State) ->
%% The local job proc will soon be killed by the closed socket or
%% because the job is finished. Then the above clause ('EXIT') will
%% handle the problem.
- io:format("Suite ~s was killed on remote target with reason"
- " ~p\n", [Name,Reason]);
+ io:format("Suite ~ts was killed on remote target with reason"
+ " ~tp\n", [Name,Reason]);
_ ->
ignore
end,
@@ -1192,10 +1192,10 @@ init_tester(Mod, Func, Args, Dir, Name, {_,_,MinLev}=Levels,
{'EXIT',test_suites_done} ->
ok;
{'EXIT',_Pid,Reason} ->
- print(1, "EXIT, reason ~p", [Reason]);
+ print(1, "EXIT, reason ~tp", [Reason]);
{'EXIT',Reason} ->
report_severe_error(Reason),
- print(1, "EXIT, reason ~p", [Reason])
+ print(1, "EXIT, reason ~tp", [Reason])
end,
Time = TimeMy/1000000,
SuccessStr =
@@ -1206,13 +1206,13 @@ init_tester(Mod, Func, Args, Dir, Name, {_,_,MinLev}=Levels,
{SkippedN,SkipStr} =
case get(test_server_skipped) of
{0,_} -> {0,""};
- {Skipped,_} -> {Skipped,io_lib:format(", ~p Skipped", [Skipped])}
+ {Skipped,_} -> {Skipped,io_lib:format(", ~w Skipped", [Skipped])}
end,
OkN = get(test_server_ok),
FailedN = get(test_server_failed),
print(html,"\n</tbody>\n<tfoot>\n"
"<tr><td></td><td><b>TOTAL</b></td><td></td><td></td><td></td>"
- "<td>~.3fs</td><td><b>~s</b></td><td>~p Ok, ~p Failed~s of ~p</td></tr>\n"
+ "<td>~.3fs</td><td><b>~ts</b></td><td>~w Ok, ~w Failed~ts of ~w</td></tr>\n"
"</tfoot>\n",
[Time,SuccessStr,OkN,FailedN,SkipStr,OkN+FailedN+SkippedN]),
test_server_io:stop().
@@ -1285,7 +1285,7 @@ do_spec(SpecName, TimetrapSpec) when is_list(SpecName) ->
{ok,TermList} ->
do_spec_list(TermList,TimetrapSpec);
{error,Reason} ->
- io:format("Can't open ~s: ~p\n", [SpecName,Reason]),
+ io:format("Can't open ~ts: ~tp\n", [SpecName,Reason]),
{error,{cant_open_spec,Reason}}
end.
@@ -1368,7 +1368,7 @@ do_spec_terms([{require_nodenames,NumNames}|Terms], TopCases, SkipList, Config)
do_spec_terms(Terms, TopCases, SkipList,
update_config(Config, {nodenames,NodeNames}));
do_spec_terms([Other|Terms], TopCases, SkipList, Config) ->
- io:format("** WARNING: Spec file contains unknown directive ~p\n",
+ io:format("** WARNING: Spec file contains unknown directive ~tp\n",
[Other]),
do_spec_terms(Terms, TopCases, SkipList, Config).
@@ -1387,7 +1387,7 @@ generate_nodenames(Num) ->
generate_nodenames2(0, _Hosts, Acc) ->
Acc;
generate_nodenames2(N, Hosts, Acc) ->
- Host=cast_to_list(lists:nth((N rem (length(Hosts)))+1, Hosts)),
+ Host=lists:nth((N rem (length(Hosts)))+1, Hosts),
Name=list_to_atom(temp_nodename("nod", []) ++ "@" ++ Host),
generate_nodenames2(N-1, Hosts, [Name|Acc]).
@@ -1507,7 +1507,7 @@ do_test_cases(TopCases, SkipCases,
FwMod = get_fw_mod(?MODULE),
case collect_all_cases(TopCases, SkipCases) of
{error,Why} ->
- print(1, "Error starting: ~p", [Why]),
+ print(1, "Error starting: ~tp", [Why]),
exit(test_suites_done);
TestSpec0 ->
N = case remove_conf(TestSpec0) of
@@ -1519,32 +1519,25 @@ do_test_cases(TopCases, SkipCases,
TestSpec =
add_init_and_end_per_suite(TestSpec0, undefined, undefined, FwMod),
TI = get_target_info(),
- print(1, "Starting test~s",
+ print(1, "Starting test~ts",
[print_if_known(N, {", ~w test cases",[N]},
{" (with repeated test cases)",[]})]),
Test = get(test_server_name),
TestName = if is_list(Test) ->
- lists:flatten(io_lib:format("~s", [Test]));
+ lists:flatten(io_lib:format("~ts", [Test]));
true ->
- lists:flatten(io_lib:format("~p", [Test]))
+ lists:flatten(io_lib:format("~tp", [Test]))
end,
TestDescr = "Test " ++ TestName ++ " results",
test_server_sup:framework_call(report, [tests_start,{Test,N}]),
{Header,Footer} =
- case test_server_sup:framework_call(get_html_wrapper,
+ case test_server_sup:framework_call(get_html_wrapper,
[TestDescr,true,TestDir,
{[],[2,3,4,7,8],[1,6]}], "") of
Empty when (Empty == "") ; (element(2,Empty) == "") ->
put(basic_html, true),
- {["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n",
- "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n",
- "<html>\n",
- "<head><title>", TestDescr, "</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
- "</head>\n",
- "<body bgcolor=\"white\" text=\"black\" ",
- "link=\"blue\" vlink=\"purple\" alink=\"red\">",
+ {[html_header(TestDescr),
"<h2>Results for test ", TestName, "</h2>\n"],
"\n</body>\n</html>\n"};
{basic_html,Html0,Html1} ->
@@ -1566,16 +1559,16 @@ do_test_cases(TopCases, SkipCases,
print(html, xhtml("\n<p><b>Host info:</b><br>\n",
"\n<p><b>Host info:</b><br />\n")),
print_who(test_server_sup:hoststr(), test_server_sup:get_username()),
- print(html, xhtml("<br>Used Erlang v~s in <tt>~s</tt></p>\n",
- "<br />Used Erlang v~s in \"~s\"</p>\n"),
+ print(html, xhtml("<br>Used Erlang v~ts in <tt>~ts</tt></p>\n",
+ "<br />Used Erlang v~ts in \"~ts\"</p>\n"),
[erlang:system_info(version), code:root_dir()]),
if FwMod == ?MODULE ->
print(html, xhtml("\n<p><b>Target Info:</b><br>\n",
"\n<p><b>Target Info:</b><br />\n")),
print_who(TI#target_info.host, TI#target_info.username),
- print(html, xhtml("<br>Used Erlang v~s in <tt>~s</tt></p>\n",
- "<br />Used Erlang v~s in \"~s\"</p>\n"),
+ print(html,xhtml("<br>Used Erlang v~ts in <tt>~ts</tt></p>\n",
+ "<br />Used Erlang v~ts in \"~ts\"</p>\n"),
[TI#target_info.version, TI#target_info.root_dir]);
true ->
case test_server_sup:framework_call(target_info, []) of
@@ -1583,7 +1576,7 @@ do_test_cases(TopCases, SkipCases,
length(TargetInfo) > 0 ->
print(html, xhtml("\n<p><b>Target info:</b><br>\n",
"\n<p><b>Target info:</b><br />\n")),
- print(html, "~s</p>\n", [TargetInfo]);
+ print(html, "~ts</p>\n", [TargetInfo]);
_ ->
ok
end
@@ -1591,39 +1584,39 @@ do_test_cases(TopCases, SkipCases,
print(html,
"<p><ul>\n"
- "<li><a href=\"~s\">Full textual log</a></li>\n"
- "<li><a href=\"~s\">Coverage log</a></li>\n"
- "<li><a href=\"~s\">Unexpected I/O log</a></li>\n</ul></p>\n",
+ "<li><a href=\"~ts\">Full textual log</a></li>\n"
+ "<li><a href=\"~ts\">Coverage log</a></li>\n"
+ "<li><a href=\"~ts\">Unexpected I/O log</a></li>\n</ul></p>\n",
[?suitelog_name,?coverlog_name,?unexpected_io_log]),
print(html,
- "<p>~s</p>\n" ++
+ "<p>~ts</p>\n" ++
xhtml("<table bgcolor=\"white\" border=\"3\" cellpadding=\"5\">",
["<table id=\"",?sortable_table_name,"\">\n",
"<thead>\n"]) ++
"<tr><th>Num</th><th>Module</th><th>Group</th>" ++
"<th>Case</th><th>Log</th><th>Time</th><th>Result</th>" ++
"<th>Comment</th></tr>\n</thead>\n<tbody>\n",
- [print_if_known(N, {"<i>Executing <b>~p</b> test cases...</i>" ++
- xhtml("\n<br>\n", "\n<br />\n"),[N]},
+ [print_if_known(N, {"<i>Executing <b>~w</b> test cases...</i>"
+ ++ xhtml("\n<br>\n", "\n<br />\n"),[N]},
{"",[]})]),
- print(major, "=cases ~p", [get(test_server_cases)]),
- print(major, "=user ~s", [TI#target_info.username]),
- print(major, "=host ~s", [TI#target_info.host]),
+ print(major, "=cases ~w", [get(test_server_cases)]),
+ print(major, "=user ~ts", [TI#target_info.username]),
+ print(major, "=host ~ts", [TI#target_info.host]),
%% If there are no hosts specified,use only the local host
case controller_call(get_hosts) of
[] ->
- print(major, "=hosts ~s", [TI#target_info.host]),
+ print(major, "=hosts ~ts", [TI#target_info.host]),
controller_call({set_hosts, [TI#target_info.host]});
Hosts ->
Str = lists:flatten(lists:map(fun(X) -> [X," "] end, Hosts)),
- print(major, "=hosts ~s", [Str])
+ print(major, "=hosts ~ts", [Str])
end,
- print(major, "=emulator_vsn ~s", [TI#target_info.version]),
- print(major, "=emulator ~s", [TI#target_info.emulator]),
- print(major, "=otp_release ~s", [TI#target_info.otp_release]),
- print(major, "=started ~s",
+ print(major, "=emulator_vsn ~ts", [TI#target_info.version]),
+ print(major, "=emulator ~ts", [TI#target_info.emulator]),
+ print(major, "=otp_release ~ts", [TI#target_info.otp_release]),
+ print(major, "=started ~ts",
[lists:flatten(timestamp_get(""))]),
put(test_server_html_footer, Footer),
@@ -1674,21 +1667,18 @@ start_log_file() ->
MkDirError2 ->
log_file_error(MkDirError2, TestDir)
end,
- ok = file:write_file(filename:join(Dir, ?last_file), TestDir1 ++ "\n"),
- ok = file:write_file(?last_file, TestDir1 ++ "\n"),
+ ok = write_file(filename:join(Dir, ?last_file), TestDir1 ++ "\n"),
+ ok = write_file(?last_file, TestDir1 ++ "\n"),
put(test_server_log_dir_base,TestDir1),
MajorName = filename:join(TestDir1, ?suitelog_name),
HtmlName = MajorName ++ ?html_ext,
UnexpectedName = filename:join(TestDir1, ?unexpected_io_log),
- {ok,Major} = file:open(MajorName, [write]),
- {ok,Html} = file:open(HtmlName, [write]),
- {ok,Unexpected} = file:open(UnexpectedName, [write]),
+ {ok,Major} = open_file(MajorName),
+ {ok,Html} = open_html_file(HtmlName),
+ {ok,Unexpected} = open_file(UnexpectedName),
test_server_io:set_fd(major, Major),
test_server_io:set_fd(html, Html),
test_server_io:set_fd(unexpected_io, Unexpected),
- put(test_server_major_fd,Major),
- put(test_server_html_fd,Html),
- put(test_server_unexpected_io, Unexpected),
make_html_link(filename:absname(?last_test ++ ?html_ext),
HtmlName, filename:basename(Dir)),
@@ -1714,21 +1704,15 @@ make_html_link(LinkName, Target, Explanation) ->
PwdL = filename:split(filename:dirname(LinkName)),
Href = case lists:prefix(PwdL, TargetL) of
true ->
- filename:join(lists:nthtail(length(PwdL), TargetL));
+ uri_encode(filename:join(lists:nthtail(length(PwdL),TargetL)));
false ->
- "file:" ++ Target
+ "file:" ++ uri_encode(Target)
end,
- H = io_lib:format("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
- "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n"
- "<html>\n"
- "<head><title>~s</title></head>\n"
- "<body bgcolor=\"white\" text=\"black\""
- " link=\"blue\" vlink=\"purple\" alink=\"red\">\n"
- "<h1>Last test</h1>\n"
- "<a href=\"~s\">~s</a>~n"
- "</body>\n</html>\n",
- [Explanation,Href,Explanation]),
- ok = file:write_file(LinkName, H).
+ H = [html_header(Explanation),
+ "<h1>Last test</h1>\n"
+ "<a href=\"",Href,"\">",Explanation,"</a>\n"
+ "</body>\n</html>\n"],
+ ok = write_html_file(LinkName, H).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% start_minor_log_file(Mod, Func) -> AbsName
@@ -1743,7 +1727,7 @@ make_html_link(LinkName, Target, Explanation) ->
start_minor_log_file(Mod, Func) ->
MFA = {Mod,Func,1},
LogDir = get(test_server_log_dir_base),
- Name0 = lists:flatten(io_lib:format("~s.~s~s", [Mod,Func,?html_ext])),
+ Name0 = lists:flatten(io_lib:format("~w.~w~ts", [Mod,Func,?html_ext])),
Name = downcase(Name0),
AbsName = filename:join(LogDir, Name),
case file:read_file_info(AbsName) of
@@ -1752,37 +1736,29 @@ start_minor_log_file(Mod, Func) ->
{ok,_} -> %% special case, duplicate names
{_,S,Us} = now(),
Name1_0 =
- lists:flatten(io_lib:format("~s.~s.~w.~w~s", [Mod,Func,S,
- trunc(Us/1000),
- ?html_ext])),
+ lists:flatten(io_lib:format("~w.~w.~w.~w~ts", [Mod,Func,S,
+ trunc(Us/1000),
+ ?html_ext])),
Name1 = downcase(Name1_0),
AbsName1 = filename:join(LogDir, Name1),
start_minor_log_file1(Mod, Func, LogDir, AbsName1, MFA)
end.
start_minor_log_file1(Mod, Func, LogDir, AbsName, MFA) ->
- {ok,Fd} = file:open(AbsName, [write]),
+ {ok,Fd} = open_html_file(AbsName),
Lev = get(test_server_minor_level)+1000, %% far down in the minor levels
put(test_server_minor_fd, Fd),
test_server_gl:set_minor_fd(group_leader(), Fd, MFA),
- TestDescr = io_lib:format("Test ~p:~p result", [Mod,Func]),
+ TestDescr = io_lib:format("Test ~w:~w result", [Mod,Func]),
{Header,Footer} =
- case test_server_sup:framework_call(get_html_wrapper,
+ case test_server_sup:framework_call(get_html_wrapper,
[TestDescr,false,
filename:dirname(AbsName),
undefined], "") of
Empty when (Empty == "") ; (element(2,Empty) == "") ->
put(basic_html, true),
- {["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n",
- "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n",
- "<html>\n",
- "<head><title>", TestDescr, "</title>\n",
- "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n",
- "</head>\n",
- "<body bgcolor=\"white\" text=\"black\" ",
- "link=\"blue\" vlink=\"purple\" alink=\"red\">\n"],
- "\n</body>\n</html>\n"};
+ {html_header(TestDescr), "\n</body>\n</html>\n"};
{basic_html,Html0,Html1} ->
put(basic_html, true),
{Html0,Html1};
@@ -1791,24 +1767,21 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName, MFA) ->
{Html0,Html1}
end,
put(test_server_minor_footer, Footer),
- io:fwrite(Fd, Header, []),
+ io:put_chars(Fd, Header),
- SrcListing = downcase(cast_to_list(Mod)) ++ ?src_listing_ext,
+ SrcListing = downcase(atom_to_list(Mod)) ++ ?src_listing_ext,
case {filelib:is_file(filename:join(LogDir, SrcListing)),
lists:member(no_src, get(test_server_logopts))} of
{true,false} ->
- print(Lev, "<a href=\"~s#~s\">source code for ~p:~p/1</a>\n",
- [SrcListing,atom_to_list(Func)++"-1",Mod,Func]);
- _ -> ok
+ print(Lev, "<a href=\"~ts#~ts\">source code for ~w:~w/1</a>\n",
+ [uri_encode(SrcListing),
+ uri_encode(atom_to_list(Func)++"-1",utf8),
+ Mod,Func]);
+ _ ->
+ ok
end,
- io:fwrite(Fd, "<pre>\n", []),
-
-% Stupid BUG!
-% case catch apply(Mod, Func, [doc]) of
-% {'EXIT', _Why} -> ok;
-% Comment -> print(Lev, "Comment: ~s~n<br>", [Comment])
-% end,
+ io:put_chars(Fd, "<pre>\n"),
AbsName.
@@ -1816,8 +1789,8 @@ stop_minor_log_file() ->
test_server_gl:unset_minor_fd(group_leader()),
Fd = get(test_server_minor_fd),
Footer = get(test_server_minor_footer),
- io:fwrite(Fd, "</pre>\n" ++ Footer, []),
- file:close(Fd),
+ io:put_chars(Fd, "</pre>\n" ++ Footer),
+ ok = file:close(Fd),
put(test_server_minor_fd, undefined).
downcase(S) -> downcase(S, []).
@@ -1899,25 +1872,15 @@ html_possibly_convert(Src, SrcInfo, Dest) ->
ok; % dest file up to date
_ ->
OutDir = get(test_server_log_dir_base),
- Header =
- case test_server_sup:framework_call(get_html_wrapper,
- ["Module "++Src,false,
- OutDir,undefined], "") of
- Empty when (Empty == "") ; (element(2,Empty) == "") ->
- ["<!DOCTYPE HTML PUBLIC",
- "\"-//W3C//DTD HTML 3.2 Final//EN\">\n",
- "<!-- autogenerated by 'erl2html2' -->\n",
- "<html>\n",
- "<head><title>Module ", Src, "</title>\n",
- "<meta http-equiv=\"cache-control\" ",
- "content=\"no-cache\">\n",
- "</head>\n",
- "<body bgcolor=\"white\" text=\"black\" ",
- "link=\"blue\" vlink=\"purple\" alink=\"red\">\n"];
- {_,Html,_} ->
- Html
- end,
- erl2html2:convert(Src, Dest, Header)
+ case test_server_sup:framework_call(get_html_wrapper,
+ ["Module "++Src,false,
+ OutDir,undefined,
+ encoding(Src)], "") of
+ Empty when (Empty == "") ; (element(2,Empty) == "") ->
+ erl2html2:convert(Src, Dest);
+ {_,Header,_} ->
+ erl2html2:convert(Src, Dest, Header)
+ end
end.
%% Copy all HTML files in InDir to OutDir.
@@ -1929,9 +1892,9 @@ copy_html_file(Src, DestDir) ->
Dest = filename:join(DestDir, filename:basename(Src)),
case file:read_file(Src) of
{ok,Bin} ->
- ok = file:write_file(Dest, Bin);
+ ok = write_file(Dest, Bin);
{error,_Reason} ->
- io:format("File ~p: read failed\n", [Src])
+ io:format("File ~tp: read failed\n", [Src])
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2106,15 +2069,15 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
end,
OkN = get(test_server_ok),
FailedN = get(test_server_failed),
- print(1, "TEST COMPLETE, ~w ok, ~w failed~s of ~w test cases\n",
+ print(1, "TEST COMPLETE, ~w ok, ~w failed~ts of ~w test cases\n",
[OkN,FailedN,SkipStr,OkN+FailedN+AllSkippedN]),
test_server_sup:framework_call(report, [tests_done,
{OkN,FailedN,{UserSkipN,AutoSkipN}}]),
- print(major, "=finished ~s", [lists:flatten(timestamp_get(""))]),
- print(major, "=failed ~p", [FailedN]),
- print(major, "=successful ~p", [OkN]),
- print(major, "=user_skipped ~p", [UserSkipN]),
- print(major, "=auto_skipped ~p", [AutoSkipN]),
+ print(major, "=finished ~ts", [lists:flatten(timestamp_get(""))]),
+ print(major, "=failed ~w", [FailedN]),
+ print(major, "=successful ~w", [OkN]),
+ print(major, "=user_skipped ~w", [UserSkipN]),
+ print(major, "=auto_skipped ~w", [AutoSkipN]),
exit(test_suites_done).
@@ -2645,7 +2608,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
run_test_cases_loop(Cases, [NewCfg|Config],
TimetrapData, Mode, Status2);
Bad ->
- print(minor, "~n*** ~p returned bad elements in Config: ~p.~n",
+ print(minor,
+ "~n*** ~w returned bad elements in Config: ~tp.~n",
[Func,Bad]),
Reason = {failed,{Mod,init_per_suite,bad_return}},
Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
@@ -2660,8 +2624,9 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
stop_minor_log_file(),
run_test_cases_loop(Cases, [NewCfg|Config], TimetrapData, Mode, Status2);
{_,{framework_error,{FwMod,FwFunc},Reason},_} ->
- print(minor, "~n*** ~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]),
- print(1, "~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]),
+ print(minor, "~n*** ~w failed in ~w. Reason: ~tp~n",
+ [FwMod,FwFunc,Reason]),
+ print(1, "~w failed in ~w. Reason: ~tp~n", [FwMod,FwFunc,Reason]),
exit(framework_error);
{_,Fail,_} when element(1,Fail) == 'EXIT';
element(1,Fail) == timetrap_timeout;
@@ -2670,7 +2635,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
{Cases2,Config1,Status3} =
if StartConf ->
ReportAbortRepeat(failed),
- print(minor, "~n*** ~p failed.~n"
+ print(minor, "~n*** ~w failed.~n"
" Skipping all cases.", [Func]),
Reason = {failed,{Mod,Func,Fail}},
{skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
@@ -2687,7 +2652,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
run_test_cases_loop(Cases2, Config1, TimetrapData, Mode, Status3);
{_,{Skip,Reason},_} when StartConf and ((Skip==skip) or (Skip==skipped)) ->
ReportAbortRepeat(skipped),
- print(minor, "~n*** ~p skipped.~n"
+ print(minor, "~n*** ~w skipped.~n"
" Skipping all cases.", [Func]),
set_io_buffering(IOHandler),
stop_minor_log_file(),
@@ -2696,7 +2661,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
delete_status(Ref, Status2));
{_,{skip_and_save,Reason,_SavedConfig},_} when StartConf ->
ReportAbortRepeat(skipped),
- print(minor, "~n*** ~p skipped.~n"
+ print(minor, "~n*** ~w skipped.~n"
" Skipping all cases.", [Func]),
set_io_buffering(IOHandler),
stop_minor_log_file(),
@@ -2757,7 +2722,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, TimetrapData, Mode, Status) ->
case run_test_case(Ref, 0, Mod, Func, Args, skip_init, TimetrapData) of
{_,Why={'EXIT',_},_} ->
- print(minor, "~n*** ~p failed.~n"
+ print(minor, "~n*** ~w failed.~n"
" Skipping all cases.", [Func]),
Reason = {failed,{Mod,Func,Why}},
Cases = skip_cases_upto(Ref, Cases0, Reason, conf, Mode),
@@ -2803,8 +2768,9 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
run_init, TimetrapData, Mode) of
%% callback to framework module failed, exit immediately
{_,{framework_error,{FwMod,FwFunc},Reason},_} ->
- print(minor, "~n*** ~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]),
- print(1, "~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]),
+ print(minor, "~n*** ~w failed in ~w. Reason: ~tp~n",
+ [FwMod,FwFunc,Reason]),
+ print(1, "~w failed in ~w. Reason: ~tp~n", [FwMod,FwFunc,Reason]),
stop_minor_log_file(),
exit(framework_error);
%% sequential execution of test case finished
@@ -2836,8 +2802,9 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
stop_minor_log_file(),
run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status1);
true -> % skip rest of cases in sequence
- print(minor, "~n*** ~p failed.~n"
- " Skipping all other cases in sequence.", [Func]),
+ print(minor, "~n*** ~w failed.~n"
+ " Skipping all other cases in sequence.",
+ [Func]),
Reason = {failed,{Mod,Func}},
Cases2 = skip_cases_upto(Ref, Cases, Reason, tc, Mode),
stop_minor_log_file(),
@@ -2953,7 +2920,7 @@ get_data_dir(Mod, Suite) ->
end,
case code:which(UseMod) of
non_existing ->
- print(12, "The module ~p is not loaded", [Mod]),
+ print(12, "The module ~w is not loaded", [Mod]),
[];
cover_compiled ->
MainCoverNode = cover:get_main_node(),
@@ -2964,7 +2931,7 @@ get_data_dir(Mod, Suite) ->
end.
do_get_data_dir(Mod,File) ->
- filename:dirname(File) ++ "/" ++ cast_to_list(Mod) ++ ?data_dir_suffix.
+ filename:dirname(File) ++ "/" ++ atom_to_list(Mod) ++ ?data_dir_suffix.
print_conf_time(0) ->
ok;
@@ -2975,8 +2942,8 @@ print_conf_time(ConfTime) ->
print_props(_, []) ->
ok;
print_props(true, Props) ->
- print(major, "=group_props ~p", [Props]),
- print(minor, "Group properties: ~p~n", [Props]);
+ print(major, "=group_props ~tp", [Props]),
+ print(minor, "Group properties: ~tp~n", [Props]);
print_props(_, _) ->
ok.
@@ -3126,24 +3093,24 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
Comment1 = reason_to_string(Comment),
- print(major, "~n=case ~p:~p", [Mod,Func]),
- print(major, "=started ~s", [lists:flatten(timestamp_get(""))]),
- print(major, "=result skipped: ~s", [Comment1]),
- print(2,"*** Skipping test case #~w ~p ***", [CaseNum,{Mod,Func}]),
+ print(major, "~n=case ~w:~w", [Mod,Func]),
+ print(major, "=started ~ts", [lists:flatten(timestamp_get(""))]),
+ print(major, "=result skipped: ~ts", [Comment1]),
+ print(2,"*** Skipping test case #~w ~w ***", [CaseNum,{Mod,Func}]),
TR = xhtml("<tr valign=\"top\">", ["<tr class=\"",odd_or_even(),"\">"]),
GroupName = case get_name(Mode) of
undefined -> "";
Name -> cast_to_list(Name)
end,
print(html,
- TR ++ "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>"
- "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>"
- "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>"
- "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>"
+ TR ++ "<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
+ "<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
+ "<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
+ "<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "< >" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "0.000s" ++ Col1 ++ "</td>"
- "<td><font color=\"~s\">SKIPPED</font></td>"
- "<td>~s</td></tr>\n",
+ "<td><font color=\"~ts\">SKIPPED</font></td>"
+ "<td>~ts</td></tr>\n",
[num2str(CaseNum),fw_name(Mod),GroupName,Func,ResultCol,Comment1]),
if CaseNum > 0 ->
{US,AS} = get(test_server_skipped),
@@ -3325,7 +3292,7 @@ wait_and_resend(Ref, [{_,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Skip,Fail) ->
{'EXIT',CurrPid,Reason} when Reason /= normal ->
%% unexpected termination of test case process
{value,{_,_,CaseNum,Mod,Func}} = lists:keysearch(CurrPid, 2, Cases),
- print(1, "Error! Process for test case #~p (~p:~p) died! Reason: ~p",
+ print(1, "Error! Process for test case #~w (~w:~w) died! Reason: ~tp",
[CaseNum, Mod, Func, Reason]),
exit({unexpected_termination,{CaseNum,Mod,Func},{CurrPid,Reason}})
end;
@@ -3464,7 +3431,7 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) ->
{'EXIT',TCPid,Reason} when Reason /= normal ->
test_server_io:print_buffered(CurrPid),
{value,{_,_,Num,M,F}} = lists:keysearch(TCPid, 2, Cases),
- print(1, "Error! Process for test case #~p (~p:~p) died! Reason: ~p",
+ print(1, "Error! Process for test case #~w (~w:~w) died! Reason: ~tp",
[Num, M, F, Reason]),
exit({unexpected_termination,{Num,M,F},{TCPid,Reason}})
end.
@@ -3540,11 +3507,11 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
end,
TSDir = get(test_server_dir),
- print(major, "=case ~p:~p", [Mod, Func]),
+ print(major, "=case ~w:~w", [Mod, Func]),
MinorName = start_minor_log_file(Mod, Func),
print(minor, "<a name=\"top\"></a>", [], internal_raw),
MinorBase = filename:basename(MinorName),
- print(major, "=logfile ~s", [filename:basename(MinorName)]),
+ print(major, "=logfile ~ts", [filename:basename(MinorName)]),
UpdatedArgs =
%% maybe create unique private directory for test case or config func
@@ -3552,14 +3519,13 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
auto_per_run ->
update_config(hd(Args), [{tc_logfile,MinorName}]);
PrivDirMode ->
+ %% create unique private directory for test case
RunDir = filename:dirname(MinorName),
Ext =
if Num == 0 ->
{_,S,Us} = now(),
lists:flatten(io_lib:format(".~w.~w", [S,Us]));
true ->
- %% create unique private directory for test case
- RunDir = filename:dirname(MinorName),
lists:flatten(io_lib:format(".~w", [Num]))
end,
PrivDir = filename:join(RunDir, ?priv_dir) ++ Ext,
@@ -3580,16 +3546,17 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
undefined -> "";
Name -> cast_to_list(Name)
end,
- print(major, "=started ~s", [lists:flatten(timestamp_get(""))]),
+ print(major, "=started ~ts", [lists:flatten(timestamp_get(""))]),
{{Col0,Col1},Style} = get_font_style((RunInit==run_init), Mode),
TR = xhtml("<tr valign=\"top\">", ["<tr class=\"",odd_or_even(),"\">"]),
- print(html, TR ++ "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>"
- "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>"
- "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>"
- "<td><a href=\"~s\">~p</a></td>"
- "<td><a href=\"~s#top\"><</a> <a href=\"~s#end\">></a></td>",
- [num2str(Num),fw_name(Mod),GroupName,MinorBase,Func,
- MinorBase,MinorBase]),
+ EncMinorBase = uri_encode(MinorBase),
+ print(html, TR ++ "<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
+ "<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
+ "<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
+ "<td><a href=\"~ts\">~w</a></td>"
+ "<td><a href=\"~ts#top\"><</a> <a href=\"~ts#end\">></a></td>",
+ [num2str(Num),fw_name(Mod),GroupName,EncMinorBase,Func,
+ EncMinorBase,EncMinorBase]),
do_unless_parallel(Main, fun erlang:yield/0),
@@ -3606,7 +3573,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
print(minor, "<a name=\"end\"></a>", [], internal_raw),
print(minor, "\n", [], internal_raw),
print_timestamp(minor, "Ended at "),
- print(major, "=ended ~s", [lists:flatten(timestamp_get(""))]),
+ print(major, "=ended ~ts", [lists:flatten(timestamp_get(""))]),
do_unless_parallel(Main, fun() -> file:set_cwd(filename:dirname(TSDir)) end),
@@ -3690,13 +3657,13 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
{'EXIT',_} = Exit ->
print(minor,
"WARNING: There might be slavenodes left in the"
- " system. I tried to kill them, but I failed: ~p\n",
+ " system. I tried to kill them, but I failed: ~tp\n",
[Exit]);
[] -> ok;
List ->
print(minor, "WARNING: ~w slave nodes in system after test"++
"case. Tried to killed them.~n"++
- " Names:~p",
+ " Names:~tp",
[length(List),List])
end;
false ->
@@ -3756,7 +3723,7 @@ progress(skip, CaseNum, Mod, Func, Loc, Reason, Time,
fun() -> {?auto_skip_color,auto_skip} end,
fun() -> {?user_skip_color,skip} end),
print(major, "=result skipped", []),
- print(1, "*** SKIPPED *** ~s",
+ print(1, "*** SKIPPED *** ~ts",
[get_info_str(Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,Func,
{skipped,Reason1}}]),
@@ -3775,24 +3742,24 @@ progress(skip, CaseNum, Mod, Func, Loc, Reason, Time,
end,
print(html,
"<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>"
- "<td><font color=\"~s\">SKIPPED</font></td>"
- "<td>~s~s</td></tr>\n",
+ "<td><font color=\"~ts\">SKIPPED</font></td>"
+ "<td>~ts~ts</td></tr>\n",
[Time,Color,ReasonStr2,Comment1]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~s", [FormatLoc]),
- print(minor, "=== reason = ~s", [ReasonStr1]),
+ print(minor, "=== location ~ts", [FormatLoc]),
+ print(minor, "=== reason = ~ts", [ReasonStr1]),
Ret;
progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T,
Comment0, {St0,St1}) ->
- print(major, "=result failed: timeout, ~p", [Loc]),
- print(1, "*** FAILED *** ~s",
+ print(major, "=result failed: timeout, ~tp", [Loc]),
+ print(1, "*** FAILED *** ~ts",
[get_info_str(Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report,
[tc_done,{Mod,Func,
{failed,timetrap_timeout}}]),
FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)),
- ErrorReason = io_lib:format("{timetrap_timeout,~s}", [FormatLastLoc]),
+ ErrorReason = io_lib:format("{timetrap_timeout,~ts}", [FormatLastLoc]),
Comment =
case Comment0 of
"" -> "<font color=\"red\">" ++ ErrorReason ++ "</font>";
@@ -3802,23 +3769,23 @@ progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T,
print(html,
"<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>"
"<td><font color=\"red\">FAILED</font></td>"
- "<td>~s</td></tr>\n",
+ "<td>~ts</td></tr>\n",
[T/1000,Comment]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~s", [FormatLoc]),
+ print(minor, "=== location ~ts", [FormatLoc]),
print(minor, "=== reason = timetrap timeout", []),
failed;
progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T,
Comment0, {St0,St1}) ->
- print(major, "=result failed: testcase_aborted, ~p", [Loc]),
- print(1, "*** FAILED *** ~s",
+ print(major, "=result failed: testcase_aborted, ~tp", [Loc]),
+ print(1, "*** FAILED *** ~ts",
[get_info_str(Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report,
[tc_done,{Mod,Func,
{failed,testcase_aborted}}]),
FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)),
- ErrorReason = io_lib:format("{testcase_aborted,~s}", [FormatLastLoc]),
+ ErrorReason = io_lib:format("{testcase_aborted,~ts}", [FormatLastLoc]),
Comment =
case Comment0 of
"" -> "<font color=\"red\">" ++ ErrorReason ++ "</font>";
@@ -3828,24 +3795,24 @@ progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T,
print(html,
"<td>" ++ St0 ++ "died" ++ St1 ++ "</td>"
"<td><font color=\"red\">FAILED</font></td>"
- "<td>~s</td></tr>\n",
+ "<td>~ts</td></tr>\n",
[Comment]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~s", [FormatLoc]),
- print(minor, "=== reason = {testcase_aborted,~p}", [Reason]),
+ print(minor, "=== location ~ts", [FormatLoc]),
+ print(minor, "=== reason = {testcase_aborted,~tp}", [Reason]),
failed;
progress(failed, CaseNum, Mod, Func, unknown, Reason, Time,
Comment0, {St0,St1}) ->
- print(major, "=result failed: ~p, ~p", [Reason,unknown]),
- print(1, "*** FAILED *** ~s",
+ print(major, "=result failed: ~tp, ~w", [Reason,unknown]),
+ print(1, "*** FAILED *** ~ts",
[get_info_str(Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,Func,
{failed,Reason}}]),
TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
true -> "~w"
end, [Time]),
- ErrorReason = lists:flatten(io_lib:format("~p", [Reason])),
+ ErrorReason = lists:flatten(io_lib:format("~tp", [Reason])),
ErrorReason1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(ErrorReason,[$\n])]),
ErrorReason2 =
@@ -3862,19 +3829,19 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time,
to_string(Comment0)
end,
print(html,
- "<td>" ++ St0 ++ "~s" ++ St1 ++ "</td>"
+ "<td>" ++ St0 ++ "~ts" ++ St1 ++ "</td>"
"<td><font color=\"red\">FAILED</font></td>"
- "<td>~s</td></tr>\n",
+ "<td>~ts</td></tr>\n",
[TimeStr,Comment]),
- print(minor, "=== location ~s", [unknown]),
+ print(minor, "=== location ~w", [unknown]),
{FStr,FormattedReason} = format_exception(Reason),
print(minor, "=== reason = " ++ FStr, [FormattedReason]),
failed;
progress(failed, CaseNum, Mod, Func, Loc, Reason, Time,
Comment0, {St0,St1}) ->
- print(major, "=result failed: ~p, ~p", [Reason,Loc]),
- print(1, "*** FAILED *** ~s",
+ print(major, "=result failed: ~tp, ~tp", [Reason,Loc]),
+ print(1, "*** FAILED *** ~ts",
[get_info_str(Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,Func,
{failed,Reason}}]),
@@ -3888,12 +3855,12 @@ progress(failed, CaseNum, Mod, Func, Loc, Reason, Time,
end,
FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)),
print(html,
- "<td>" ++ St0 ++ "~s" ++ St1 ++ "</td>"
+ "<td>" ++ St0 ++ "~ts" ++ St1 ++ "</td>"
"<td><font color=\"red\">FAILED</font></td>"
- "<td><font color=\"red\">~s</font>~s</td></tr>\n",
+ "<td><font color=\"red\">~ts</font>~ts</td></tr>\n",
[TimeStr,FormatLastLoc,Comment]),
FormatLoc = test_server_sup:format_loc(Loc),
- print(minor, "=== location ~s", [FormatLoc]),
+ print(minor, "=== location ~ts", [FormatLoc]),
{FStr,FormattedReason} = format_exception(Reason),
print(minor, "=== reason = " ++ FStr, [FormattedReason]),
failed;
@@ -3909,7 +3876,7 @@ progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time,
HtmlCmt = test_server_sup:framework_call(format_comment,
[String],
String),
- print(major, "=result ok: ~s", [String]),
+ print(major, "=result ok: ~ts", [String]),
"<td>" ++ HtmlCmt ++ "</td>";
_ ->
print(major, "=result ok", []),
@@ -3918,13 +3885,13 @@ progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time,
_ -> "<td>" ++ to_string(Comment0) ++ "</td>"
end
end,
- print(major, "=elapsed ~p", [Time]),
+ print(major, "=elapsed ~tp", [Time]),
print(html,
"<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>"
"<td><font color=\"green\">Ok</font></td>"
- "~s</tr>\n",
+ "~ts</tr>\n",
[Time,Comment]),
- print(minor, "=== returned value = ~p", [RetVal]),
+ print(minor, "=== returned value = ~tp", [RetVal]),
ok.
%%--------------------------------------------------------------------
@@ -4000,12 +3967,12 @@ print_if_known(Known, {SK,AK}, {SU,AU}) ->
io_lib:format(S, A).
to_string(Term) when is_list(Term) ->
- case (catch io_lib:format("~s", [Term])) of
- {'EXIT',_} -> io_lib:format("~p", [Term]);
+ case (catch io_lib:format("~ts", [Term])) of
+ {'EXIT',_} -> lists:flatten(io_lib:format("~tp", [Term]));
String -> lists:flatten(String)
end;
to_string(Term) ->
- lists:flatten(io_lib:format("~p", [Term])).
+ lists:flatten(io_lib:format("~tp", [Term])).
get_last_loc(Loc) when is_tuple(Loc) ->
Loc;
@@ -4077,14 +4044,14 @@ format_exception(Reason={_Error,Stack}) when is_list(Stack) ->
undefined ->
case application:get_env(test_server, format_exception) of
{ok,false} ->
- {"~p",Reason};
+ {"~tp",Reason};
_ ->
do_format_exception(Reason)
end;
FW ->
case application:get_env(FW, format_exception) of
{ok,false} ->
- {"~p",Reason};
+ {"~tp",Reason};
_ ->
do_format_exception(Reason)
end
@@ -4099,10 +4066,10 @@ do_format_exception(Reason={Error,Stack}) ->
end,
case catch lib:format_exception(1, error, Error, Stack, StackFun, PF) of
{'EXIT',_} ->
- {"~p",Reason};
+ {"~tp",Reason};
Formatted ->
Formatted1 = re:replace(Formatted, "exception error: ", "", [{return,list}]),
- {"~s",lists:flatten(Formatted1)}
+ {"~ts",lists:flatten(Formatted1)}
end.
@@ -4173,7 +4140,7 @@ print_who(Host, User) ->
"" -> "";
_ -> " by " ++ User
end,
- print(html, "Run~s on ~s", [UserStr,Host]).
+ print(html, "Run~ts on ~ts", [UserStr,Host]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% format(Format) -> IoLibReturn
@@ -4208,7 +4175,7 @@ format(Detail, Format, Args) ->
Str =
case catch io_lib:format(Format, Args) of
{'EXIT',_} ->
- io_lib:format("illegal format; ~p with args ~p.\n",
+ io_lib:format("illegal format; ~tp with args ~tp.\n",
[Format,Args]);
Valid -> Valid
end,
@@ -4244,7 +4211,7 @@ odd_or_even() ->
%% date and time. The resulting string is suitable as a filename.
timestamp_filename_get(Leader) ->
timestamp_get_internal(Leader,
- "~s~w-~2.2.0w-~2.2.0w_~2.2.0w.~2.2.0w.~2.2.0w").
+ "~ts~w-~2.2.0w-~2.2.0w_~2.2.0w.~2.2.0w.~2.2.0w").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% timestamp_get(Leader) -> string()
@@ -4254,7 +4221,7 @@ timestamp_filename_get(Leader) ->
%% date and time. The resulting string is suitable for display.
timestamp_get(Leader) ->
timestamp_get_internal(Leader,
- "~s~w-~2.2.0w-~2.2.0w ~2.2.0w:~2.2.0w:~2.2.0w").
+ "~ts~w-~2.2.0w-~2.2.0w ~2.2.0w:~2.2.0w:~2.2.0w").
timestamp_get_internal(Leader, Format) ->
{YY,MM,DD,H,M,S} = time_get(),
@@ -4588,14 +4555,18 @@ collect_files(Dir, Pattern, St) ->
Wc = filename:join([Dir1,Pattern++code:objfile_extension()]),
case catch filelib:wildcard(Wc) of
{'EXIT', Reason} ->
- io:format("Could not collect files: ~p~n", [Reason]),
+ io:format("Could not collect files: ~tp~n", [Reason]),
{error,{collect_fail,Dir,Pattern}};
Mods0 ->
Mods = [{path_to_module(Mod),all} || Mod <- lists:sort(Mods0)],
collect_cases(Mods, St)
end.
-path_to_module(Path) ->
+path_to_module(Path) when is_list(Path) ->
+ %% If this is called with a binary, then we are probably in +fnu
+ %% mode and have found a beam file with name encoded as latin1. We
+ %% will let this crash since it can not work to load such a module
+ %% anyway. It should be removed or renamed!
list_to_atom(filename:rootname(filename:basename(Path))).
collect_case_deny(Mod, Case, MFA, ReqList, SubCases, St) ->
@@ -4617,16 +4588,16 @@ check_deny([], _DenyList) -> granted;
check_deny(Req, DenyList) -> check_deny([Req], DenyList).
check_deny_req({Req,Val}, DenyList) ->
- %%io:format("ValCheck ~p=~p in ~p\n", [Req,Val,DenyList]),
+ %%io:format("ValCheck ~tp=~tp in ~tp\n", [Req,Val,DenyList]),
case lists:keysearch(Req, 1, DenyList) of
{value,{_Req,DenyVal}} when Val >= DenyVal ->
- {denied,io_lib:format("Requirement ~p=~p", [Req,Val])};
+ {denied,io_lib:format("Requirement ~tp=~tp", [Req,Val])};
_ ->
check_deny_req(Req, DenyList)
end;
check_deny_req(Req, DenyList) ->
case lists:member(Req, DenyList) of
- true -> {denied,io_lib:format("Requirement ~p", [Req])};
+ true -> {denied,io_lib:format("Requirement ~tp", [Req])};
false -> granted
end.
@@ -4727,14 +4698,14 @@ get_target_info() ->
start_node(Name, Type, Options) ->
T = 10 * ?ACCEPT_TIMEOUT * test_server:timetrap_scale_factor(),
- format(minor, "Attempt to start ~w node ~p with options ~p",
+ format(minor, "Attempt to start ~w node ~tp with options ~tp",
[Type, Name, Options]),
case controller_call({start_node,Name,Type,Options}, T) of
{{ok,Nodename}, Host, Cmd, Info, Warning} ->
format(minor,
- "Successfully started node ~p on ~p with command: ~p",
+ "Successfully started node ~w on ~tp with command: ~tp",
[Nodename, Host, Cmd]),
- format(major, "=node_start ~p", [Nodename]),
+ format(major, "=node_start ~w", [Nodename]),
case Info of
[] -> ok;
_ -> format(minor, Info)
@@ -4748,17 +4719,17 @@ start_node(Name, Type, Options) ->
{ok, Nodename};
{fail,{Ret, Host, Cmd}} ->
format(minor,
- "Failed to start node ~p on ~p with command: ~p~n"
- "Reason: ~p",
+ "Failed to start node ~tp on ~tp with command: ~tp~n"
+ "Reason: ~tp",
[Name, Host, Cmd, Ret]),
{fail,Ret};
{Ret, undefined, undefined} ->
- format(minor, "Failed to start node ~p: ~p", [Name,Ret]),
+ format(minor, "Failed to start node ~tp: ~tp", [Name,Ret]),
Ret;
{Ret, Host, Cmd} ->
format(minor,
- "Failed to start node ~p on ~p with command: ~p~n"
- "Reason: ~p",
+ "Failed to start node ~tp on ~tp with command: ~tp~n"
+ "Reason: ~tp",
[Name, Host, Cmd, Ret]),
Ret
end.
@@ -4972,11 +4943,11 @@ read_cover_file(CoverFile) ->
case check_cover_file(List, [], [], []) of
{ok,Exclude,Include,Cross} -> {Exclude,Include,Cross};
error ->
- io:fwrite("Faulty format of CoverFile ~p\n", [CoverFile]),
+ io:fwrite("Faulty format of CoverFile ~tp\n", [CoverFile]),
{[],[],[]}
end;
{error,Reason} ->
- io:fwrite("Can't read CoverFile ~p\nReason: ~p\n",
+ io:fwrite("Can't read CoverFile ~ts\nReason: ~tp\n",
[CoverFile,Reason]),
{[],[],[]}
end.
@@ -5029,11 +5000,11 @@ check_cross([]) ->
cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
write_default_cross_coverlog(TestDir),
- {ok,CoverLog} = file:open(filename:join(TestDir, ?coverlog_name), [write]),
+ {ok,CoverLog} = open_html_file(filename:join(TestDir, ?coverlog_name)),
write_coverlog_header(CoverLog),
io:fwrite(CoverLog, "<h1>Coverage for application '~w'</h1>\n", [App]),
io:fwrite(CoverLog,
- "<p><a href=\"~s\">Coverdata collected over all tests</a></p>",
+ "<p><a href=\"~ts\">Coverdata collected over all tests</a></p>",
[?cross_coverlog_name]),
{CoverFile,_Included,Excluded,Cross} =
@@ -5045,7 +5016,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
{Excl,Incl,Cr} = read_cover_file(File),
{File,Incl,Excl,Cr}
end,
- io:fwrite(CoverLog, "<p>CoverFile: <code>~p</code>\n", [CoverFile]),
+ io:fwrite(CoverLog, "<p>CoverFile: <code>~tp</code>\n", [CoverFile]),
write_cross_cover_info(TestDir,Cross),
case length(cover:imported_modules()) of
@@ -5056,11 +5027,11 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
ok
end,
- io:fwrite(CoverLog, "<p>Excluded module(s): <code>~p</code>\n", [Excluded]),
+ io:fwrite(CoverLog, "<p>Excluded module(s): <code>~tp</code>\n", [Excluded]),
Coverage = cover_analyse(Analyse, AnalyseMods, Stop),
- file:write_file(filename:join(TestDir,?raw_coverlog_name),
- term_to_binary(Coverage)),
+ write_file(filename:join(TestDir,?raw_coverlog_name),
+ term_to_binary(Coverage)),
case lists:filter(fun({_M,{_,_,_}}) -> false;
(_) -> true
@@ -5074,8 +5045,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
end,
TotPercent = write_cover_result_table(CoverLog, Coverage),
- file:write_file(filename:join(TestDir, ?cover_total),
- term_to_binary(TotPercent)).
+ write_file(filename:join(TestDir, ?cover_total),term_to_binary(TotPercent)).
cover_analyse(Analyse, AnalyseMods, Stop) ->
TestDir = get(test_server_log_dir_base),
@@ -5122,25 +5092,25 @@ cross_cover_analyse(Analyse, TagDirs0) ->
write_cross_cover_info(_Dir,[]) ->
ok;
write_cross_cover_info(Dir,Cross) ->
- {ok,Fd} = file:open(filename:join(Dir,?cross_cover_info),[write]),
- lists:foreach(fun(C) -> io:format(Fd,"~p.~n",[C]) end, Cross),
- file:close(Fd).
+ {ok,Fd} = open_file(filename:join(Dir,?cross_cover_info)),
+ lists:foreach(fun(C) -> io:format(Fd,"~tp.~n",[C]) end, Cross),
+ ok = file:close(Fd).
%% For each test from which there are cross cover analysed
%% modules, write a cross cover log (cross_cover.html).
write_cross_cover_logs([{Tag,Coverage}|T],TagDirMods) ->
case lists:keyfind(Tag,1,TagDirMods) of
{_,Dir,Mods} when Mods=/=[] ->
- file:write_file(filename:join(Dir,?raw_cross_coverlog_name),
- term_to_binary(Coverage)),
+ write_file(filename:join(Dir,?raw_cross_coverlog_name),
+ term_to_binary(Coverage)),
CoverLogName = filename:join(Dir,?cross_coverlog_name),
- {ok,CoverLog} = file:open(CoverLogName, [write]),
+ {ok,CoverLog} = open_html_file(CoverLogName),
write_coverlog_header(CoverLog),
io:fwrite(CoverLog,
"<h1>Coverage results for \'~w\' from all tests</h1>\n",
[Tag]),
write_cover_result_table(CoverLog, Coverage),
- io:fwrite("Written file ~p\n", [CoverLogName]);
+ io:fwrite("Written file ~tp\n", [CoverLogName]);
_ ->
ok
end,
@@ -5224,19 +5194,11 @@ analyse_modules(_Dir, [], _DetailsFun, Acc) ->
%% Support functions for writing the cover logs (both cross and normal)
write_coverlog_header(CoverLog) ->
- case catch
- io:fwrite(CoverLog,
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
- "<!-- autogenerated by '~w'. -->\n"
- "<html>\n"
- "<head><title>Coverage results</title></head>\n"
- "<body bgcolor=\"white\" text=\"black\" "
- "link=\"blue\" vlink=\"purple\" alink=\"red\">",
- [?MODULE]) of
+ case catch io:put_chars(CoverLog,html_header("Coverage results")) of
{'EXIT',Reason} ->
io:format("\n\nERROR: Could not write normal heading in coverlog.\n"
"CoverLog: ~w\n"
- "Reason: ~p\n",
+ "Reason: ~tp\n",
[CoverLog,Reason]),
io:format(CoverLog,"<html><body>\n", []);
_ ->
@@ -5251,20 +5213,22 @@ format_analyse(M,Cov,NotCov,undefined) ->
"<td align=right>~w</td></tr>\n",
[M,pc(Cov,NotCov),Cov,NotCov]);
format_analyse(M,Cov,NotCov,{file,File}) ->
- io_lib:fwrite("<tr><td><a href=\"~s\">~w</a></td>"
+ io_lib:fwrite("<tr><td><a href=\"~ts\">~w</a></td>"
"<td align=right>~w %</td>"
"<td align=right>~w</td>"
"<td align=right>~w</td></tr>\n",
- [filename:basename(File),M,pc(Cov,NotCov),Cov,NotCov]);
+ [uri_encode(filename:basename(File)),
+ M,pc(Cov,NotCov),Cov,NotCov]);
format_analyse(M,Cov,NotCov,{lines,Lines}) ->
CoverOutName = atom_to_list(M)++".COVER.html",
- {ok,CoverOut} = file:open(CoverOutName, [write]),
+ {ok,CoverOut} = open_html_file(CoverOutName),
write_not_covered(CoverOut,M,Lines),
- io_lib:fwrite("<tr><td><a href=\"~s\">~w</a></td>"
+ ok = file:close(CoverOut),
+ io_lib:fwrite("<tr><td><a href=\"~ts\">~w</a></td>"
"<td align=right>~w %</td>"
"<td align=right>~w</td>"
"<td align=right>~w</td></tr>\n",
- [CoverOutName,M,pc(Cov,NotCov),Cov,NotCov]);
+ [uri_encode(CoverOutName),M,pc(Cov,NotCov),Cov,NotCov]);
format_analyse(M,Cov,NotCov,{error,_}) ->
io_lib:fwrite("<tr><td>~w</td>"
"<td align=right>~w %</td>"
@@ -5280,8 +5244,8 @@ pc(Cov,NotCov) ->
write_not_covered(CoverOut,M,Lines) ->
+ io:put_chars(CoverOut,html_header("Coverage results for "++atom_to_list(M))),
io:fwrite(CoverOut,
- "<html>\n"
"The following lines in module ~w are not covered:\n"
"<table border=3 cellpadding=5>\n"
"<th>Line Number</th>\n",
@@ -5292,25 +5256,25 @@ write_not_covered(CoverOut,M,Lines) ->
ok
end,
Lines),
- io:fwrite(CoverOut,"</table>\n</html>\n", []).
+ io:put_chars(CoverOut,"</table>\n</body>\n</html>\n").
write_default_coverlog(TestDir) ->
- {ok,CoverLog} = file:open(filename:join(TestDir,?coverlog_name), [write]),
+ {ok,CoverLog} = open_html_file(filename:join(TestDir,?coverlog_name)),
write_coverlog_header(CoverLog),
- io:fwrite(CoverLog,"Cover tool is not used\n</body></html>\n", []),
- file:close(CoverLog).
+ io:put_chars(CoverLog,"Cover tool is not used\n</body></html>\n"),
+ ok = file:close(CoverLog).
write_default_cross_coverlog(TestDir) ->
{ok,CrossCoverLog} =
- file:open(filename:join(TestDir,?cross_coverlog_name), [write]),
+ open_html_file(filename:join(TestDir,?cross_coverlog_name)),
write_coverlog_header(CrossCoverLog),
io:put_chars(CrossCoverLog,
["No cross cover modules exist for this application,",
xhtml("<br>","<br />"),
"or cross cover analysis is not completed.\n"
"</body></html>\n"]),
- file:close(CrossCoverLog).
+ ok = file:close(CrossCoverLog).
write_cover_result_table(CoverLog,Coverage) ->
io:fwrite(CoverLog,
@@ -5321,7 +5285,7 @@ write_cover_result_table(CoverLog,Coverage) ->
{TotCov,TotNotCov} =
lists:foldl(fun({M,{Cov,NotCov,Details}},{AccCov,AccNotCov}) ->
Str = format_analyse(M,Cov,NotCov,Details),
- io:fwrite(CoverLog,"~s", [Str]),
+ io:fwrite(CoverLog,"~ts", [Str]),
{AccCov+Cov,AccNotCov+NotCov};
({_M,{error,_Reason}},{AccCov,AccNotCov}) ->
{AccCov,AccNotCov}
@@ -5336,5 +5300,81 @@ write_cover_result_table(CoverLog,Coverage) ->
"</body>\n"
"</html>\n",
[TotPercent,TotCov,TotNotCov]),
- file:close(CoverLog),
+ ok = file:close(CoverLog),
TotPercent.
+
+
+%%%-----------------------------------------------------------------
+%%% Support functions for writing files
+
+%% HTML files are always written with utf8 encoding
+html_header(Title) ->
+ ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
+ "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n"
+ "<html>\n"
+ "<head>\n"
+ "<title>", Title, "</title>\n"
+ "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n"
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
+ "</head>\n"
+ "<body bgcolor=\"white\" text=\"black\" "
+ "link=\"blue\" vlink=\"purple\" alink=\"red\">\n"].
+
+open_html_file(File) ->
+ file:open(File,[write,{encoding,utf8}]).
+
+write_html_file(File,Content) ->
+ file:write_file(File,unicode:characters_to_binary(Content)).
+
+
+%% Text files are written with default encoding
+open_file(File) ->
+ file:open(File,[write]).
+
+write_file(File,Content) ->
+ file:write_file(File,Content).
+
+%% Encoding of hyperlinks in HTML files
+uri_encode(File) ->
+ Encoding = file:native_name_encoding(),
+ uri_encode(File,Encoding).
+
+uri_encode(File,Encoding) ->
+ Components = filename:split(File),
+ filename:join([uri_encode_comp(C,Encoding) || C <- Components]).
+
+uri_encode_comp("/",_) ->
+ "/";
+uri_encode_comp(Chars,utf8) ->
+ http_uri:encode(Chars);
+uri_encode_comp(Chars,latin1) ->
+ do_uri_encode(Chars).
+
+%% Encode a file reference to a latin1 filename so it can be inserted
+%% in a utf8 encoded HTML file.
+%% This does the same as http_uri:encode/1, except it also encodes all
+%% characters >127 - i.e. latin1 but not ASCII.
+do_uri_encode([Char|Chars]) ->
+ case Char>127 orelse sets:is_element(Char, reserved()) of
+ true ->
+ [ $% | http_util:integer_to_hexlist(Char)] ++ do_uri_encode(Chars);
+ false ->
+ [Char | do_uri_encode(Chars)]
+ end;
+do_uri_encode([]) ->
+ [].
+
+%% Copied from http_uri.erl, but slightly modified
+%% (not converting @ and :)
+reserved() ->
+ sets:from_list([$;, $&, $=, $+, $,, $/, $?,
+ $#, $[, $], $<, $>, $\", ${, $}, $|,
+ $\\, $', $^, $%, $ ]).
+
+encoding(File) ->
+ case epp:read_encoding(File) of
+ none ->
+ epp:default_encoding();
+ E ->
+ E
+ end.
diff --git a/lib/test_server/src/test_server_gl.erl b/lib/test_server/src/test_server_gl.erl
index d32c7c07dc..0ab0d58040 100644
--- a/lib/test_server/src/test_server_gl.erl
+++ b/lib/test_server/src/test_server_gl.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
@@ -223,20 +223,12 @@ do_set_props([{reject_io_reqs,Bool}|Ps], St) ->
do_set_props([], St) -> St.
io_req({put_chars,Enc,Bytes}, _, _) when Enc =:= latin1; Enc =:= unicode ->
- to_latin1(Enc, Bytes);
+ unicode:characters_to_list(Bytes, Enc);
io_req({put_chars,Encoding,Mod,Func,[Format,Args]}, _, _) ->
Str = Mod:Func(Format, Args),
- to_latin1(Encoding, Str);
+ unicode:characters_to_list(Str, Encoding);
io_req(_, _, _) -> passthrough.
-to_latin1(unicode, Str) ->
- [if C > 255 ->
- io_lib:format("\\{~.8B}", [C]);
- true ->
- C
- end || C <- unicode:characters_to_list(Str, unicode)];
-to_latin1(latin1, Str) -> Str.
-
output(Level, Str, Sender, From, St) when is_integer(Level) ->
case selected_by_level(Level, stdout, St) of
true -> output(stdout, Str, Sender, From, St);
@@ -258,7 +250,7 @@ output(Level, Str, Sender, From, St) when is_atom(Level) ->
output_to_file(Level, dress_output(Str, Sender, St), From, St).
output_to_file(minor, Data0, From, #st{tc={M,F,A},minor=none}) ->
- Data = [io_lib:format("=== ~p:~p/~p\n", [M,F,A]),Data0],
+ Data = [io_lib:format("=== ~w:~w/~w\n", [M,F,A]),Data0],
test_server_io:print(From, unexpected_io, Data),
ok;
output_to_file(minor, Data, From, #st{minor=Fd}) ->
diff --git a/lib/test_server/src/test_server_h.erl b/lib/test_server/src/test_server_h.erl
index 78daba855d..c624947306 100644
--- a/lib/test_server/src/test_server_h.erl
+++ b/lib/test_server/src/test_server_h.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -140,9 +140,9 @@ report_receiver(info_report, _) -> kernel;
report_receiver(_, _) -> none.
tag({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) ->
- io:format(user, "~n=TESTCASE: ~p:~p/~p", [M,F,A]);
+ io:format(user, "~n=TESTCASE: ~w:~w/~w", [M,F,A]);
tag(Testcase) ->
- io:format(user, "~n=TESTCASE: ~p", [Testcase]).
+ io:format(user, "~n=TESTCASE: ~tp", [Testcase]).
tag_event(Event) ->
{calendar:local_time(), Event}.
diff --git a/lib/test_server/src/test_server_internal.hrl b/lib/test_server/src/test_server_internal.hrl
index d204c35293..9a11182725 100644
--- a/lib/test_server/src/test_server_internal.hrl
+++ b/lib/test_server/src/test_server_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
diff --git a/lib/test_server/src/test_server_io.erl b/lib/test_server/src/test_server_io.erl
index 777b377201..662ee11515 100644
--- a/lib/test_server/src/test_server_io.erl
+++ b/lib/test_server/src/test_server_io.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
@@ -235,7 +235,7 @@ handle_info(kill_group_leaders, #st{gls=Gls,stopping=From}=St) ->
gen_server:reply(From, ok),
{stop,normal,St};
handle_info(Other, St) ->
- io:format("Ignoring: ~p\n", [Other]),
+ io:format("Ignoring: ~tp\n", [Other]),
{noreply,St}.
terminate(_, _) ->
@@ -256,12 +256,12 @@ output(From, Tag, Str, #st{io_buffering=Buffered,buffered=Buf0}=St) ->
do_output(stdout, Str, #st{job_name=undefined}) ->
io:put_chars(Str);
do_output(stdout, Str0, #st{job_name=Name}) ->
- Str = io_lib:format("Testing ~s: ~s\n", [Name,Str0]),
+ Str = io_lib:format("Testing ~ts: ~ts\n", [Name,Str0]),
io:put_chars(Str);
do_output(Tag, Str, #st{fds=Fds}=St) ->
case gb_trees:lookup(Tag, Fds) of
none ->
- S = io_lib:format("\n*** ERROR: ~p, line ~p: No known '~p' log file\n",
+ S = io_lib:format("\n*** ERROR: ~w, line ~w: No known '~tp' log file\n",
[?MODULE,?LINE,Tag]),
do_output(stdout, [S,Str], St);
{value,Fd} ->
@@ -272,8 +272,8 @@ do_output(Tag, Str, #st{fds=Fds}=St) ->
_ -> ok
end
catch _:Error ->
- S = io_lib:format("\n*** ERROR: ~p, line ~p: Error writing to "
- "log file '~p': ~p\n",
+ S = io_lib:format("\n*** ERROR: ~w, line ~w: Error writing to "
+ "log file '~tp': ~tp\n",
[?MODULE,?LINE,Tag,Error]),
do_output(stdout, [S,Str], St)
end
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index b307d93c7d..62248af4db 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -249,7 +249,7 @@ print_trc(Out,{trace_ts,P,call,{M,F,A},C,Ts},N) ->
"~w: ~s~n"
"Process : ~w~n"
"Call : ~w:~w/~w~n"
- "Arguments : ~p~n"
+ "Arguments : ~tp~n"
"Caller : ~w~n~n",
[N,ts(Ts),P,M,F,length(A),A,C]);
print_trc(Out,{trace_ts,P,call,{M,F,A},Ts},N) ->
@@ -257,14 +257,14 @@ print_trc(Out,{trace_ts,P,call,{M,F,A},Ts},N) ->
"~w: ~s~n"
"Process : ~w~n"
"Call : ~w:~w/~w~n"
- "Arguments : ~p~n~n",
+ "Arguments : ~tp~n~n",
[N,ts(Ts),P,M,F,length(A),A]);
print_trc(Out,{trace_ts,P,return_from,{M,F,A},R,Ts},N) ->
io:format(Out,
"~w: ~s~n"
"Process : ~w~n"
"Return from : ~w:~w/~w~n"
- "Return value : ~p~n~n",
+ "Return value : ~tp~n~n",
[N,ts(Ts),P,M,F,A,R]);
print_trc(Out,{drop,X},N) ->
io:format(Out,
@@ -274,7 +274,7 @@ print_trc(Out,Trace,N) ->
Ts = element(size(Trace),Trace),
io:format(Out,
"~w: ~s~n"
- "Trace : ~p~n~n",
+ "Trace : ~tp~n~n",
[N,ts(Ts),Trace]).
ts({_, _, Micro} = Now) ->
{{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(Now),
@@ -465,8 +465,8 @@ handle_start_node_return(Version,VsnStr,{started, Node, OVersion, OVsnStr}) ->
Str = io_lib:format("WARNING: Started node "
"reports different system "
"version than current node! "
- "Current node version: ~p, ~p "
- "Started node version: ~p, ~p",
+ "Current node version: ~tp, ~tp "
+ "Started node version: ~tp, ~tp",
[Version, VsnStr,
OVersion, OVsnStr]),
Str1 = lists:flatten(Str),
diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl
index a6d426887e..cd96568970 100644
--- a/lib/test_server/src/test_server_sup.erl
+++ b/lib/test_server/src/test_server_sup.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
@@ -72,10 +72,10 @@ timetrap(Timeout0, ReportTVal, Scale, Pid) ->
after 10000 ->
%% Pid is probably trapping exits, hit it harder...
catch error_logger:warning_msg(
- "Testcase process ~p not "
+ "Testcase process ~w not "
"responding to timetrap "
"timeout:~n"
- " ~p.~n"
+ " ~tp.~n"
"Killing testcase...~n",
[Pid, Trap]),
exit(Pid, kill)
@@ -142,11 +142,11 @@ call_crash(Time,Crash,M,F,A) ->
{'EXIT',Pid,_Reason} when Crash==any ->
ok;
{'EXIT',Reason} ->
- test_server:format(12, "Wrong crash reason. Wanted ~p, got ~p.",
+ test_server:format(12, "Wrong crash reason. Wanted ~tp, got ~tp.",
[Crash, Reason]),
exit({wrong_crash_reason,Reason});
{'EXIT',Pid,Reason} ->
- test_server:format(12, "Wrong crash reason. Wanted ~p, got ~p.",
+ test_server:format(12, "Wrong crash reason. Wanted ~tp, got ~tp.",
[Crash, Reason]),
exit({wrong_crash_reason,Reason});
{'EXIT',OtherPid,Reason} when OldTrapExit == false ->
@@ -312,7 +312,7 @@ check_dict(Dict, Reason) ->
[] ->
1; % All ok.
List ->
- io:format("** ~s (~s) ->~n~p~n",[Reason, Dict, List]),
+ io:format("** ~ts (~ts) ->~n~tp~n",[Reason, Dict, List]),
0
end.
@@ -321,7 +321,7 @@ check_dict_tolerant(Dict, Reason, Mode) ->
[] ->
1; % All ok.
List ->
- io:format("** ~s (~s) ->~n~p~n",[Reason, Dict, List]),
+ io:format("** ~ts (~ts) ->~n~tp~n",[Reason, Dict, List]),
case Mode of
pedantic ->
0;
@@ -377,7 +377,7 @@ check_new_crash_dumps() ->
ok;
Num ->
test_server_ctrl:format(minor,
- "Found ~p crash dumps:~n", [Num]),
+ "Found ~w crash dumps:~n", [Num]),
append_files_to_logfile(Dumps),
delete_files(Dumps)
end.
@@ -385,7 +385,7 @@ check_new_crash_dumps() ->
append_files_to_logfile([]) -> ok;
append_files_to_logfile([File|Files]) ->
NodeName=from($., File),
- test_server_ctrl:format(minor, "Crash dump from node ~p:~n",[NodeName]),
+ test_server_ctrl:format(minor, "Crash dump from node ~tp:~n",[NodeName]),
Fd=get(test_server_minor_fd),
case file:read_file(File) of
{ok, Bin} ->
@@ -397,22 +397,22 @@ append_files_to_logfile([File|Files]) ->
%% fail, but in that case it will throw an exception so that
%% we will be aware of the problem.
io:format(Fd, "Unable to write the crash dump "
- "to this file: ~p~n", [file:format_error(Error)])
+ "to this file: ~tp~n", [file:format_error(Error)])
end;
_Error ->
- io:format(Fd, "Failed to read: ~s\n", [File])
+ io:format(Fd, "Failed to read: ~ts\n", [File])
end,
append_files_to_logfile(Files).
delete_files([]) -> ok;
delete_files([File|Files]) ->
- io:format("Deleting file: ~s~n", [File]),
+ io:format("Deleting file: ~ts~n", [File]),
case file:delete(File) of
{error, _} ->
case file:rename(File, File++".old") of
{error, Error} ->
io:format("Could neither delete nor rename file "
- "~s: ~s.~n", [File, Error]);
+ "~ts: ~ts.~n", [File, Error]);
_ ->
ok
end;
@@ -555,7 +555,7 @@ format_loc([{Mod,LineOrFunc}]) ->
format_loc({Mod,Func}) when is_atom(Func) ->
io_lib:format("{~w,~w}",[Mod,Func]);
format_loc(Loc) ->
- io_lib:format("~p",[Loc]).
+ io_lib:format("~tp",[Loc]).
format_loc1([{Mod,Func,Line}]) ->
[" ",format_loc1({Mod,Func,Line}),"]"];
@@ -566,9 +566,10 @@ format_loc1({Mod,Func,Line}) ->
case {lists:member(no_src, get(test_server_logopts)),
lists:reverse(ModStr)} of
{false,[$E,$T,$I,$U,$S,$_|_]} ->
- io_lib:format("{~w,~w,<a href=\"~s~s#~w\">~w</a>}",
- [Mod,Func,downcase(ModStr),?src_listing_ext,
- Line,Line]);
+ io_lib:format("{~w,~w,<a href=\"~ts~ts#~w\">~w</a>}",
+ [Mod,Func,
+ test_server_ctrl:uri_encode(downcase(ModStr)),
+ ?src_listing_ext,Line,Line]);
_ ->
io_lib:format("{~w,~w,~w}",[Mod,Func,Line])
end.
diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl
index cfd7161dbd..4e5dc1b759 100644
--- a/lib/test_server/src/ts.erl
+++ b/lib/test_server/src/ts.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl
index ba8952f10f..e9e559df5d 100644
--- a/lib/test_server/src/ts_install.erl
+++ b/lib/test_server/src/ts_install.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -93,7 +93,7 @@ autoconf1(_,_) ->
throw(cross_installation_failed).
autoconf2({ok, Bin}) ->
- get_vars(binary_to_list(Bin), name, [], []);
+ get_vars(ts_lib:b2s(Bin), name, [], []);
autoconf2(Error) ->
Error.
@@ -170,12 +170,12 @@ parse_xcomp_file(Filepath) ->
parse_xcomp_file([<<A:8,_/binary>> = Line|R],Envs,Flags)
when $A =< A, A =< $Z ->
[Var,Value] = binary:split(Line,<<"=">>),
- parse_xcomp_file(R,[{binary_to_list(Var),
- binary_to_list(Value)}|Envs],Flags);
+ parse_xcomp_file(R,[{ts_lib:b2s(Var),
+ ts_lib:b2s(Value)}|Envs],Flags);
parse_xcomp_file([<<"erl_xcomp_",Line/binary>>|R],Envs,Flags) ->
[Var,Value] = binary:split(Line,<<"=">>),
- parse_xcomp_file(R,Envs,[{binary_to_list(Var),
- binary_to_list(Value)}|Flags]);
+ parse_xcomp_file(R,Envs,[{ts_lib:b2s(Var),
+ ts_lib:b2s(Value)}|Flags]);
parse_xcomp_file([_|R],Envs,Flags) ->
parse_xcomp_file(R,Envs,Flags);
parse_xcomp_file([],Envs,Flags) ->
@@ -407,4 +407,3 @@ extra_platform_label() ->
[_|_]=Label -> "/" ++ Label;
false -> ""
end.
-
diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl
index d9a699ca9f..a00f607fc1 100644
--- a/lib/test_server/src/ts_lib.erl
+++ b/lib/test_server/src/ts_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. 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
@@ -29,7 +29,8 @@
specs/1, suites/2,
subst_file/3, subst/2, print_data/1,
make_non_erlang/2,
- maybe_atom_to_list/1, progress/4
+ maybe_atom_to_list/1, progress/4,
+ b2s/1
]).
error(Reason) ->
@@ -143,7 +144,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!
@@ -156,7 +156,7 @@ suite_order(_) -> 200.
subst_file(In, Out, Vars) ->
case file:read_file(In) of
{ok, Bin} ->
- Subst = subst(binary_to_list(Bin), Vars, []),
+ Subst = subst(b2s(Bin), Vars, []),
case file:write_file(Out, Subst) of
ok ->
ok;
@@ -335,3 +335,11 @@ make_non_erlang_do(DataDir, Variables) ->
after
timer:sleep(100) %% maybe unnecessary now when we don't do set_cwd anymore
end.
+
+b2s(Bin) ->
+ unicode:characters_to_list(Bin,default_encoding()).
+
+default_encoding() ->
+ try epp:default_encoding()
+ catch error:undef -> latin1
+ end.
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/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl
index fb82a87fd0..bea2c0dc49 100644
--- a/lib/test_server/test/test_server_SUITE.erl
+++ b/lib/test_server/test/test_server_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
@@ -31,6 +31,7 @@
-include_lib("common_test/include/ct.hrl").
-include("test_server_test_lib.hrl").
+-include_lib("kernel/include/file.hrl").
%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
@@ -68,6 +69,13 @@ init_per_testcase(_TestCase, Config) ->
%% @spec end_per_testcase(TestCase, Config0) ->
%% void() | {save_config,Config1} | {fail,Reason}
+end_per_testcase(test_server_unicode, _Config) ->
+ [_,Host] = string:tokens(atom_to_list(node()), "@"),
+ N1 = list_to_atom("test_server_tester_latin1" ++ "@" ++ Host),
+ N2 = list_to_atom("test_server_tester_utf8" ++ "@" ++ Host),
+ test_server:stop_node(N1),
+ test_server:stop_node(N2),
+ ok;
end_per_testcase(_TestCase, _Config) ->
ok.
@@ -80,7 +88,8 @@ all() ->
[test_server_SUITE, test_server_parallel01_SUITE,
test_server_conf02_SUITE, test_server_conf01_SUITE,
test_server_skip_SUITE, test_server_shuffle01_SUITE,
- test_server_break_SUITE, test_server_cover_SUITE].
+ test_server_break_SUITE, test_server_cover_SUITE,
+ test_server_unicode].
%%--------------------------------------------------------------------
@@ -171,7 +180,24 @@ test_server_cover_SUITE(Config) ->
ok
end.
+test_server_unicode(Config) ->
+ run_test_server_tests("test_server_unicode_SUITE", [],
+ 5, 0, 3, 3, 0, 0, 0, 0, 5, Config),
+
+ %% Create and run two test suites - one with filename and content
+ %% in latin1 (if the default filename mode is latin1) and one with
+ %% filename and content in utf8. Both have name and content
+ %% including letters ���. Check that all logs are generated with
+ %% utf8 encoded filenames.
+ case file:native_name_encoding() of
+ utf8 ->
+ ok;
+ latin1 ->
+ generate_and_run_unicode_test(Config,latin1)
+ end,
+ generate_and_run_unicode_test(Config,utf8).
+%%%-----------------------------------------------------------------
run_test_server_tests(SuiteName, Skip, NCases, NFail, NExpected, NSucc,
NUsrSkip, NAutoSkip,
NActualSkip, NActualFail, NActualSucc, Config) ->
@@ -182,12 +208,13 @@ run_test_server_tests(SuiteName, Skip, NCases, NFail, NExpected, NSucc,
run_test_server_tests(SuiteName, Skip, NCases, NFail, NExpected, NSucc,
NUsrSkip, NAutoSkip,
NActualSkip, NActualFail, NActualSucc, Cover, Config) ->
-
+ Node = proplists:get_value(node, Config),
+ Encoding = rpc:call(Node,file,native_name_encoding,[]),
WorkDir = proplists:get_value(work_dir, Config),
- ct:log("<a href=\"file://~s\">Test case log files</a>\n",
- [filename:join(WorkDir, SuiteName++".logs")]),
+ LogDir = filename:join(WorkDir, SuiteName++".logs"),
+ LogDirUri = test_server_ctrl:uri_encode(LogDir, Encoding),
+ ct:log("<a href=\"file://~s\">Test case log files</a>\n", [LogDirUri]),
- Node = proplists:get_value(node, Config),
{ok,_Pid} = rpc:call(Node,test_server_ctrl, start, []),
case Cover of
false ->
@@ -207,12 +234,10 @@ run_test_server_tests(SuiteName, Skip, NCases, NFail, NExpected, NSucc,
rpc:call(Node,test_server_ctrl, stop, []),
- {ok,Data} = test_server_test_lib:parse_suite(
- lists:last(
- lists:sort(
- filelib:wildcard(
- filename:join([WorkDir,SuiteName++".logs",
- "run*","suite.log"]))))),
+ LogDir1 = translate_filename(LogDir,Encoding),
+ LastRunDir = get_latest_run_dir(LogDir1),
+ LastSuiteLog = filename:join(LastRunDir,"suite.log"),
+ {ok,Data} = test_server_test_lib:parse_suite(LastSuiteLog),
check([{"Number of cases",NCases,Data#suite.n_cases},
{"Number failed",NFail,Data#suite.n_cases_failed},
{"Number expected",NExpected,Data#suite.n_cases_expected},
@@ -229,6 +254,47 @@ run_test_server_tests(SuiteName, Skip, NCases, NFail, NExpected, NSucc,
end,{0,0,0},Data#suite.cases),
Data.
+translate_filename(Filename,EncodingOnTestNode) ->
+ case {file:native_name_encoding(),EncodingOnTestNode} of
+ {X,X} -> Filename;
+ {utf8,latin1} -> list_to_binary(Filename);
+ {latin1,utf8} -> unicode:characters_to_binary(Filename)
+ end.
+
+get_latest_run_dir(Dir) ->
+ %% For the time being, filelib:wildcard can not take a binary
+ %% argument, so we avoid using this here.
+ case file:list_dir(Dir) of
+ {ok,Files} ->
+ {ok,RE} = re:compile(<<"^run.[1-2][-_\.0-9]*$">>),
+ RunDirs = lists:filter(
+ fun(F) ->
+ L = l(F),
+ case re:run(F,RE) of
+ {match,[{0,L}]} -> true;
+ _ -> false
+ end
+ end, Files),
+ case RunDirs of
+ [] ->
+ Dir;
+ [H|T] ->
+ filename:join(Dir,get_latest_dir(T,H))
+ end;
+ _ ->
+ Dir
+ end.
+
+l(X) when is_binary(X) -> size(X);
+l(X) when is_list(X) -> length(X).
+
+get_latest_dir([H|T],Latest) when H>Latest ->
+ get_latest_dir(T,H);
+get_latest_dir([_|T],Latest) ->
+ get_latest_dir(T,Latest);
+get_latest_dir([],Latest) ->
+ Latest.
+
check([{Str,Same,Same}|T], Status) ->
io:format("~s: ~p\n", [Str,Same]),
check(T, Status);
@@ -246,4 +312,139 @@ until(Fun) ->
timer:sleep(100),
until(Fun)
end.
-
+
+generate_and_run_unicode_test(Config0,Encoding) ->
+ DataDir = ?config(data_dir,Config0),
+ Suite = create_unicode_test_suite(DataDir,Encoding),
+
+ %% We can not run this test on default node since it must be
+ %% started with correct file name mode (+fnu/+fnl).
+ %% OBS: the node are stopped by end_per_testcase/2
+ Config1 = lists:keydelete(node,1,Config0),
+ Config2 = lists:keydelete(work_dir,1,Config1),
+ NodeName = list_to_atom("test_server_tester_" ++ atom_to_list(Encoding)),
+ ErtsSwitch = case Encoding of
+ latin1 -> "+fnl";
+ utf8 -> "+fnu"
+ end,
+ Config = start_node(Config2,NodeName,ErtsSwitch),
+
+ %% Compile the suite
+ Node = proplists:get_value(node,Config),
+ {ok,Mod} = rpc:call(Node,compile,file,[Suite,[{outdir,DataDir}]]),
+ ModStr = atom_to_list(Mod),
+
+ %% Clean logdir
+ LogDir0 = filename:join(DataDir,ModStr++".logs"),
+ LogDir = translate_filename(LogDir0,Encoding),
+ rm_dir(LogDir),
+
+ %% Run the test
+ run_test_server_tests(ModStr, [], 3, 0, 1, 1, 0, 0, 0, 0, 3, Config),
+
+ %% Check that all logs are created with utf8 encoded filenames
+ true = filelib:is_dir(LogDir),
+
+ RunDir = get_latest_run_dir(LogDir),
+ true = filelib:is_dir(RunDir),
+
+ LowerModStr = string:to_lower(ModStr),
+ SuiteHtml = translate_filename(LowerModStr++".src.html",Encoding),
+ true = filelib:is_regular(filename:join(RunDir,SuiteHtml)),
+
+ TCLog = translate_filename(LowerModStr++".tc_���.html",Encoding),
+ true = filelib:is_regular(filename:join(RunDir,TCLog)),
+ ok.
+
+%% Same as test_server_test_lib:start_slave, but starts a peer with
+%% additional arguments.
+%% The reason for this is that we need to start nodes with +fnu/+fnl,
+%% and that will not work well with a slave node since slave nodes run
+%% remote file system on master - i.e. they will use same file name
+%% mode as the master.
+start_node(Config,Name,Args) ->
+ [_,Host] = string:tokens(atom_to_list(node()), "@"),
+ ct:log("Trying to start ~w@~s~n",[Name,Host]),
+ case test_server:start_node(Name, peer, [{args,Args}]) of
+ {error,Reason} ->
+ test_server:fail(Reason);
+ {ok,Node} ->
+ ct:log("Node ~p started~n", [Node]),
+ test_server_test_lib:prepare_tester_node(Node,Config)
+ end.
+
+create_unicode_test_suite(Dir,Encoding) ->
+ ModStr = "test_server_"++atom_to_list(Encoding)++"_���_SUITE",
+ File = filename:join(Dir,ModStr++".erl"),
+ Suite =
+ ["%% -*- ",epp:encoding_to_string(Encoding)," -*-\n",
+ "-module(",ModStr,").\n"
+ "\n"
+ "-export([all/1, init_per_suite/1, end_per_suite/1]).\n"
+ "-export([init_per_testcase/2, end_per_testcase/2]).\n"
+ "-export([tc_���/1]).\n"
+ "\n"
+ "-include_lib(\"test_server/include/test_server.hrl\").\n"
+ "\n"
+ "all(suite) ->\n"
+ " [tc_���].\n"
+ "\n"
+ "init_per_suite(Config) ->\n"
+ " Config.\n"
+ "\n"
+ "end_per_suite(_Config) ->\n"
+ " ok.\n"
+ "\n"
+ "init_per_testcase(_Case,Config) ->\n"
+ " init_timetrap(500,Config).\n"
+ "\n"
+ "init_timetrap(T,Config) ->\n"
+ " Dog = ?t:timetrap(T),\n"
+ " [{watchdog, Dog}|Config].\n"
+ "\n"
+ "end_per_testcase(_Case,Config) ->\n"
+ " cancel_timetrap(Config).\n"
+ "\n"
+ "cancel_timetrap(Config) ->\n"
+ " Dog=?config(watchdog, Config),\n"
+ " ?t:timetrap_cancel(Dog),\n"
+ " ok.\n"
+ "\n"
+ "tc_���(Config) when is_list(Config) ->\n"
+ " true = filelib:is_dir(?config(priv_dir,Config)),\n"
+ " ok.\n"],
+ {ok,Fd} = file:open(raw_filename(File,Encoding),[write,{encoding,Encoding}]),
+ io:put_chars(Fd,Suite),
+ ok = file:close(Fd),
+ File.
+
+raw_filename(Name,latin1) -> list_to_binary(Name);
+raw_filename(Name,utf8) -> unicode:characters_to_binary(Name).
+
+rm_dir(Dir) ->
+ case file:list_dir(Dir) of
+ {error,enoent} ->
+ ok;
+ {ok,Files} ->
+ rm_files([filename:join(Dir, F) || F <- Files]),
+ file:del_dir(Dir)
+ end.
+
+rm_files([F | Fs]) ->
+ case file:read_file_info(F) of
+ {ok,#file_info{type=directory}} ->
+ rm_dir(F),
+ rm_files(Fs);
+ {ok,_Regular} ->
+ case file:delete(F) of
+ ok ->
+ rm_files(Fs);
+ {error,Errno} ->
+ exit({del_failed,F,Errno})
+ end
+ end;
+rm_files([]) ->
+ ok.
+
+erts_switch(latin1) -> "+fnl";
+erts_switch(utf8) -> "+fnu".
diff --git a/lib/test_server/test/test_server_SUITE_data/Makefile.src b/lib/test_server/test/test_server_SUITE_data/Makefile.src
index c770627f04..5aeb035572 100644
--- a/lib/test_server/test/test_server_SUITE_data/Makefile.src
+++ b/lib/test_server/test/test_server_SUITE_data/Makefile.src
@@ -7,4 +7,5 @@ all:
erlc test_server_skip_SUITE.erl
erlc test_server_break_SUITE.erl
erlc test_server_cover_SUITE.erl
- erlc +debug_info test_server_cover_SUITE_data/cover_helper.erl \ No newline at end of file
+ erlc +debug_info test_server_cover_SUITE_data/cover_helper.erl
+ erlc test_server_unicode_SUITE.erl
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl
new file mode 100644
index 0000000000..662adedd4c
--- /dev/null
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl
@@ -0,0 +1,82 @@
+%% -*- coding: utf-8 -*-
+%%
+%% %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(test_server_unicode_SUITE).
+
+-export([all/1, init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+-export([':#"|@\\ difficult_case_name_äöå'/1,
+ print_and_log_unicode/1,
+ print_and_log_latin1/1]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+all(suite) ->
+ [':#"|@\\ difficult_case_name_äöå',
+ print_and_log_unicode,
+ print_and_log_latin1].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_Case,Config) ->
+ init_timetrap(500,Config).
+
+init_timetrap(T,Config) ->
+ Dog = ?t:timetrap(T),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Case,Config) ->
+ cancel_timetrap(Config).
+
+cancel_timetrap(Config) ->
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+
+':#"|@\\ difficult_case_name_äöå'(Config) when is_list(Config) ->
+ ok.
+
+print_and_log_unicode(Config) when is_list(Config) ->
+ String = "שלום-שלום+של 日本語",
+ test_server:comment(String),
+ test_server:capture_start(),
+ io:format("String with ts: ~ts",[String]),
+ test_server:capture_stop(),
+ "String with ts: "++String = lists:flatten(test_server:capture_get()),
+ ok.
+
+print_and_log_latin1(Config) when is_list(Config) ->
+ String = "æøå",
+ test_server:comment(String),
+ test_server:capture_start(),
+ io:format("String with s: ~s",[String]),
+ io:format("String with ts: ~ts",[String]),
+ test_server:capture_stop(),
+ ["String with s: "++String,
+ "String with ts: "++String] =
+ [lists:flatten(L) || L<- test_server:capture_get()],
+ ok.
diff --git a/lib/test_server/test/test_server_test_lib.erl b/lib/test_server/test/test_server_test_lib.erl
index d466aa0110..cd6804f7ad 100644
--- a/lib/test_server/test/test_server_test_lib.erl
+++ b/lib/test_server/test/test_server_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,6 +20,9 @@
-export([parse_suite/1]).
-export([init/2, pre_init_per_testcase/3, post_end_per_testcase/4]).
+%% for test_server_SUITE when node can not be started as slave
+-export([prepare_tester_node/2]).
+
-include("test_server_test_lib.hrl").
%% The CTH hooks all tests
@@ -49,38 +52,41 @@ start_slave(Config,_Level) ->
ct:log("Node ~p started~n", [Node]),
IsCover = test_server:is_cover(),
if IsCover ->
- cover:start(Node);
- true->
- ok
+ cover:start(Node);
+ true->
+ ok
end,
- DataDir = proplists:get_value(data_dir, Config),
- %% We would normally use priv_dir for temporary data,
- %% but the pathnames gets too long on Windows.
- %% Until the run-time system can support long pathnames,
- %% use the data dir.
- WorkDir = DataDir,
-
- %% WorkDir as well as directory of Test Server suites
- %% have to be in code path on Test Server node.
- [_ | Parts] = lists:reverse(filename:split(DataDir)),
- TSDir = filename:join(lists:reverse(Parts)),
- AddPathDirs = case proplists:get_value(path_dirs, Config) of
- undefined -> [];
- Ds -> Ds
- end,
- PathDirs = [WorkDir,TSDir | AddPathDirs],
- [true = rpc:call(Node, code, add_patha, [D]) || D <- PathDirs],
- io:format("Dirs added to code path (on ~w):~n",
- [Node]),
- [io:format("~s~n", [D]) || D <- PathDirs],
-
- true = rpc:call(Node, os, putenv,
- ["TEST_SERVER_FRAMEWORK", "undefined"]),
-
- ok = rpc:call(Node, file, set_cwd, [WorkDir]),
- [{node,Node}, {work_dir,WorkDir} | Config]
+ prepare_tester_node(Node,Config)
end.
+prepare_tester_node(Node,Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ %% We would normally use priv_dir for temporary data,
+ %% but the pathnames gets too long on Windows.
+ %% Until the run-time system can support long pathnames,
+ %% use the data dir.
+ WorkDir = DataDir,
+
+ %% WorkDir as well as directory of Test Server suites
+ %% have to be in code path on Test Server node.
+ [_ | Parts] = lists:reverse(filename:split(DataDir)),
+ TSDir = filename:join(lists:reverse(Parts)),
+ AddPathDirs = case proplists:get_value(path_dirs, Config) of
+ undefined -> [];
+ Ds -> Ds
+ end,
+ PathDirs = [WorkDir,TSDir | AddPathDirs],
+ [true = rpc:call(Node, code, add_patha, [D]) || D <- PathDirs],
+ io:format("Dirs added to code path (on ~w):~n",
+ [Node]),
+ [io:format("~s~n", [D]) || D <- PathDirs],
+
+ true = rpc:call(Node, os, putenv,
+ ["TEST_SERVER_FRAMEWORK", "undefined"]),
+
+ ok = rpc:call(Node, file, set_cwd, [WorkDir]),
+ [{node,Node}, {work_dir,WorkDir} | Config].
+
post_end_per_testcase(_TC, Config, Return, State) ->
Node = proplists:get_value(node, Config),
Cover = test_server:is_cover(),
diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml
index 9706ae6746..891a81639a 100644
--- a/lib/tools/doc/src/xref.xml
+++ b/lib/tools/doc/src/xref.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2011</year>
+ <year>2000</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 2967acf310..d6d4457920 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -7,7 +7,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
@@ -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 bdd0cdce25..e606b97a48 100644
--- a/lib/tools/src/Makefile
+++ b/lib/tools/src/Makefile
@@ -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
@@ -75,7 +75,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS += -Werror
# ----------------------------------------------------
# Targets
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..f13a297ecf 100644
--- a/lib/tools/src/lcnt.erl
+++ b/lib/tools/src/lcnt.erl
@@ -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
@@ -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..c8ef0a04a5 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.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
@@ -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..1c72ef8db5 100644
--- a/lib/tools/src/tags.erl
+++ b/lib/tools/src/tags.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. 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
@@ -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..abc184c84d 100644
--- a/lib/tools/src/xref.erl
+++ b/lib/tools/src/xref.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
@@ -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..30c5f3d12d 100644
--- a/lib/tools/src/xref_base.erl
+++ b/lib/tools/src/xref_base.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
@@ -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..f0fed502a5 100644
--- a/lib/tools/src/xref_compiler.erl
+++ b/lib/tools/src/xref_compiler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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
@@ -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..d3601c6ea0 100644
--- a/lib/tools/src/xref_reader.erl
+++ b/lib/tools/src/xref_reader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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,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..7b72165e6f 100644
--- a/lib/tools/src/xref_utils.erl
+++ b/lib/tools/src/xref_utils.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-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,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/cprof_SUITE.erl b/lib/tools/test/cprof_SUITE.erl
index 93caee0c8f..fa4068dade 100644
--- a/lib/tools/test/cprof_SUITE.erl
+++ b/lib/tools/test/cprof_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -230,10 +230,10 @@ on_load_test(Config) ->
%%
?line N4 = cprof:restart(),
?line {ok,Module} = c:c(File, [{outdir,Priv}]),
- ?line L = Module:seq(1, M, fun (I) -> succ(I) end),
- ?line Lr = Module:seq_r(1, M, fun (I) -> succ(I) end),
- ?line L = seq(1, M, fun (I) -> succ(I) end),
- ?line Lr = seq_r(1, M, fun (I) -> succ(I) end),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
?line N2 = cprof:pause(),
?line {Module,0,[]} = cprof:analyse(Module),
?line M_1 = M - 1,
@@ -265,10 +265,10 @@ modules_test(Config) ->
?line M2__1 = M2 + 1,
?line erlang:yield(),
?line N = cprof:start(),
- ?line L = Module:seq(1, M, fun (I) -> succ(I) end),
- ?line Lr = Module:seq_r(1, M, fun (I) -> succ(I) end),
- ?line L = seq(1, M, fun (I) -> succ(I) end),
- ?line Lr = seq_r(1, M, fun (I) -> succ(I) end),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
?line N = cprof:pause(),
?line Lr = lists:reverse(L),
?line M_1 = M - 1,
diff --git a/lib/tools/test/emacs_SUITE.erl b/lib/tools/test/emacs_SUITE.erl
new file mode 100644
index 0000000000..657a3002a3
--- /dev/null
+++ b/lib/tools/test/emacs_SUITE.erl
@@ -0,0 +1,76 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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/tv/src/tv_main.hrl b/lib/tv/src/tv_main.hrl
index 28329ca83c..c9db1d9484 100644
--- a/lib/tv/src/tv_main.hrl
+++ b/lib/tv/src/tv_main.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. 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
@@ -131,7 +131,6 @@
ir_WstringDef,
lmcounter,
locks,
- mnemosyne_tmp,
pg2_table,
queue,
snmp_agent_table,
diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4
index 918e30a886..25f40944e7 100644
--- a/lib/wx/aclocal.m4
+++ b/lib/wx/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
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/wx/api_gen/wx_extra/wxListCtrl.c_src b/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
index 54d6fafd01..8fa31e512e 100644
--- a/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011. 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
@@ -27,7 +27,7 @@ class EwxListCtrl : public wxListCtrl {
int onGetItemText;
int onGetItemAttr;
int onGetItemColumnImage;
- ErlDrvPort port;
+ ErlDrvTermData port;
private:
virtual wxString OnGetItemText(long item, long col) const;
diff --git a/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src b/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
new file mode 100644
index 0000000000..50dca4e2bb
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxTreeCtrl.c_src
@@ -0,0 +1,28 @@
+%%
+%% %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%
+%%
+
+
+<<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_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 293c97507e..f00fc0c720 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.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
@@ -1210,7 +1210,7 @@ encode_events(Evs) ->
" WxeApp * app = (WxeApp *) wxTheApp;~n"
" return app->getRef(ptr,memenv);~n"
"}~n~n"),
- w("bool sendevent(wxEvent *event, ErlDrvPort port)~n{~n"
+ w("bool sendevent(wxEvent *event, ErlDrvTermData port)~n{~n"
" int send_res ;~n"
" char * evClass = NULL;~n"
" wxMBConvUTF32 UTFconverter;~n"
@@ -1239,7 +1239,7 @@ encode_events(Evs) ->
w(" rt.addTupleCount(3);~n"),
w(" pre_callback();~n"),
w(" send_res = rt.send();~n"),
- w(" if(send_res) handle_event_callback(port, cb->listener);~n"),
+ w(" if(send_res) handle_event_callback(WXE_DRV_PORT_HANDLE, cb->listener);~n"),
w(" app->clearPtr((void *) event);~n"),
w(" } else {~n"),
w(" send_res = rt.send();~n"),
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/egl_impl.cpp b/lib/wx/c_src/egl_impl.cpp
index 1379f07523..a55a145934 100644
--- a/lib/wx/c_src/egl_impl.cpp
+++ b/lib/wx/c_src/egl_impl.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2011. 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
@@ -169,33 +169,34 @@ void gl_error() {
* ******************************************************************************/
static GLUtesselator* tess;
-static GLdouble* tess_coords;
-static GLdouble* tess_alloc_vertex;
-static int* tess_vertices;
-void CALLBACK
-egl_ogla_vertex(GLdouble* coords)
-{
- /* fprintf(stderr, "%d\r\n", (int) (coords - tess_coords) / 3); */
+typedef struct {
+ GLdouble * tess_coords;
+ int alloc_n;
+ int alloc_max;
- *tess_vertices++ = (int) (coords - tess_coords) / 3;
-}
+ int * tess_index_list;
+ int index_n;
+ int index_max;
-void CALLBACK
-egl_ogla_edge_flag(GLboolean flag)
-{
-}
+ int error;
+} egl_tess_data;
+
+#define NEED_MORE_ALLOC 1
+#define NEED_MORE_INDEX 2
+
+static egl_tess_data egl_tess;
void CALLBACK
-egl_ogla_error(GLenum errorCode)
+egl_ogla_vertex(GLdouble* coords)
{
- const GLubyte *err;
- err = gluErrorString(errorCode);
- // wxString msg;
- // msg.Printf(wxT("Tesselation error: %d: "), (int)errorCode);
- // msg += wxString::FromAscii((char *) err);
- // send_msg("error", &msg);
- fprintf(stderr, "Tesselation error: %d: %s\r\n", (int) errorCode, err);
+ /* fprintf(stderr, "%d\r\n", (int) (coords - tess_coords) / 3); */
+ if(egl_tess.index_n < egl_tess.index_max) {
+ egl_tess.tess_index_list[egl_tess.index_n] = (int) (coords - egl_tess.tess_coords) / 3;
+ egl_tess.index_n++;
+ }
+ else
+ egl_tess.error = NEED_MORE_INDEX;
}
void CALLBACK
@@ -204,26 +205,43 @@ egl_ogla_combine(GLdouble coords[3],
GLfloat w[4],
void **dataOut)
{
- GLdouble* vertex = tess_alloc_vertex;
-
- tess_alloc_vertex += 3;
+ GLdouble* vertex = &egl_tess.tess_coords[egl_tess.alloc_n];
+ if(egl_tess.alloc_n < egl_tess.alloc_max) {
+ egl_tess.alloc_n += 3;
+ vertex[0] = coords[0];
+ vertex[1] = coords[1];
+ vertex[2] = coords[2];
+ *dataOut = vertex;
#if 0
- fprintf(stderr, "combine: ");
- int i;
- for (i = 0; i < 4; i++) {
- if (w[i] > 0.0) {
- fprintf(stderr, "%d(%g) ", (int) vertex_data[i], w[i]);
+ fprintf(stderr, "combine: ");
+ int i;
+ for (i = 0; i < 4; i++) {
+ if (w[i] > 0.0) {
+ fprintf(stderr, "%d(%g) ", (int) vertex_data[i], w[i]);
+ }
}
- }
- fprintf(stderr, "\r\n");
- fprintf(stderr, "%g %g %g\r\n", vertex[0], vertex[1], vertex[2]);
+ fprintf(stderr, "\r\n");
+ fprintf(stderr, "%g %g %g\r\n", vertex[0], vertex[1], vertex[2]);
#endif
- vertex[0] = coords[0];
- vertex[1] = coords[1];
- vertex[2] = coords[2];
- *dataOut = vertex;
+ } else {
+ egl_tess.error = NEED_MORE_ALLOC;
+ *dataOut = NULL;
+ }
+}
+
+void CALLBACK
+egl_ogla_edge_flag(GLboolean flag)
+{
+}
+
+void CALLBACK
+egl_ogla_error(GLenum errorCode)
+{
+ // const GLubyte *err;
+ // err = gluErrorString(errorCode);
+ // fprintf(stderr, "Tesselation error: %d: %s\r\n", (int) errorCode, err);
}
void init_tess()
@@ -246,49 +264,46 @@ int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller)
{
ErlDrvBinary* bin;
int i;
- GLdouble* new_vertices;
- int *vertices;
int num_vertices;
GLdouble *n;
- int n_pos, AP;
-
+ int AP;
+ int a_max = 2;
+ int i_max = 6;
num_vertices = * (int *) buff; buff += 8; /* Align */
n = (double *) buff; buff += 8*3;
- bin = driver_alloc_binary(num_vertices*6*sizeof(GLdouble));
- new_vertices = tess_coords = (double *) bin->orig_bytes;
- memcpy(tess_coords,buff,num_vertices*3*sizeof(GLdouble));
- tess_alloc_vertex = tess_coords + num_vertices*3;
+ egl_tess.alloc_max = a_max*num_vertices*3;
+ bin = driver_alloc_binary(egl_tess.alloc_max*sizeof(GLdouble));
+ egl_tess.error = 0;
+ egl_tess.tess_coords = (double *) bin->orig_bytes;
+ memcpy(egl_tess.tess_coords,buff,num_vertices*3*sizeof(GLdouble));
+ egl_tess.index_max = i_max*3*num_vertices;
+ egl_tess.tess_index_list = (int *) driver_alloc(sizeof(int) * egl_tess.index_max);
-#if 0
- fprintf(stderr, "n=%d\r\n", num_vertices);
-#endif
- vertices = (int *) driver_alloc(sizeof(int) * 16*num_vertices);
-
- tess_vertices = vertices;
+ egl_tess.tess_coords = (double *) bin->orig_bytes;
+ egl_tess.index_n = 0;
+ egl_tess.alloc_n = num_vertices*3;
gluTessNormal(tess, n[0], n[1], n[2]);
gluTessBeginPolygon(tess, 0);
gluTessBeginContour(tess);
for (i = 0; i < num_vertices; i++) {
- gluTessVertex(tess, tess_coords+3*i, tess_coords+3*i);
+ gluTessVertex(tess, egl_tess.tess_coords+3*i, egl_tess.tess_coords+3*i);
}
gluTessEndContour(tess);
gluTessEndPolygon(tess);
- n_pos = (tess_vertices - vertices);
-
AP = 0; ErlDrvTermData *rt;
- rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+n_pos*2));
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+egl_tess.index_n*2));
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
- for(i=0; i < n_pos; i++) {
- rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) vertices[i];
+ for(i=0; i < egl_tess.index_n; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) egl_tess.tess_index_list[i];
};
- rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = n_pos+1;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = egl_tess.index_n+1;
rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin;
- rt[AP++] = (tess_alloc_vertex-new_vertices)*sizeof(GLdouble); rt[AP++] = 0;
+ rt[AP++] = egl_tess.alloc_n*sizeof(GLdouble); rt[AP++] = 0;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin}
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple
@@ -300,7 +315,7 @@ int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller)
/* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */
/* num_vertices*6*sizeof(GLdouble)); */
driver_free_binary(bin);
- driver_free(vertices);
+ driver_free(egl_tess.tess_index_list);
driver_free(rt);
return 0;
}
diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h
index 5fdce27d4b..8dcaf1c1ac 100644
--- a/lib/wx/c_src/gen/wxe_derived_dest.h
+++ b/lib/wx/c_src/gen/wxe_derived_dest.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
@@ -391,7 +391,7 @@ class EwxListCtrl : public wxListCtrl {
int onGetItemText;
int onGetItemAttr;
int onGetItemColumnImage;
- ErlDrvPort port;
+ ErlDrvTermData port;
private:
virtual wxString OnGetItemText(long item, long col) const;
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index 7a3233a410..c9cdee3160 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.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
@@ -328,7 +328,7 @@ int getRef(void* ptr, wxeMemEnv* memenv)
return app->getRef(ptr,memenv);
}
-bool sendevent(wxEvent *event, ErlDrvPort port)
+bool sendevent(wxEvent *event, ErlDrvTermData port)
{
int send_res ;
char * evClass = NULL;
@@ -815,7 +815,7 @@ case 226: {// wxTaskBarIconEvent
rt.addTupleCount(3);
pre_callback();
send_res = rt.send();
- if(send_res) handle_event_callback(port, cb->listener);
+ if(send_res) handle_event_callback(WXE_DRV_PORT_HANDLE, cb->listener);
app->clearPtr((void *) event);
} else {
send_res = rt.send();
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/c_src/wxePrintout.cpp b/lib/wx/c_src/wxePrintout.cpp
index 90959df379..fc8782ba95 100644
--- a/lib/wx/c_src/wxePrintout.cpp
+++ b/lib/wx/c_src/wxePrintout.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2011. 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
@@ -38,7 +38,7 @@
rt.addAtom("_wx_invoke_cb_"); \
rt.addTupleCount(3); \
rt.send(); \
- handle_event_callback(port, memenv->owner); \
+ handle_event_callback(WXE_DRV_PORT_HANDLE, memenv->owner); \
}
#define INVOKE_CALLBACK(port, callback, class_str) \
@@ -230,7 +230,7 @@ EwxListCtrl::~EwxListCtrl() {
}
// tools
-void clear_cb(ErlDrvPort port, int callback)
+void clear_cb(ErlDrvTermData port, int callback)
{
if(callback > 0) {
wxeMemEnv * memenv = ((WxeApp *) wxTheApp)->getMemEnv(port);
diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c
index d1ed252ec0..4d3aa577bf 100644
--- a/lib/wx/c_src/wxe_driver.c
+++ b/lib/wx/c_src/wxe_driver.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2011. 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
@@ -100,7 +100,8 @@ int wxe_driver_load()
return -1;
}
-ErlDrvPort WXE_DRV_PORT = 0;
+ErlDrvPort WXE_DRV_PORT_HANDLE = 0;
+ErlDrvTermData WXE_DRV_PORT = 0;
static ErlDrvData
wxe_driver_start(ErlDrvPort port, char *buff)
@@ -114,17 +115,20 @@ wxe_driver_start(ErlDrvPort port, char *buff)
fprintf(stderr, " Couldn't alloc mem\r\n");
return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */
} else {
+ ErlDrvTermData term_port = driver_mk_port(port);
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
data->driver_data = NULL;
data->bin = NULL;
- data->port = port;
+ data->port_handle = port;
+ data->port = term_port;
data->pdl = driver_pdl_create(port);
- if(WXE_DRV_PORT == 0) {
+ if(WXE_DRV_PORT_HANDLE == 0) {
for(; *buff != 32; buff++);
buff++;
erl_wx_privdir = strdup(buff);
- WXE_DRV_PORT = port;
+ WXE_DRV_PORT_HANDLE = port;
+ WXE_DRV_PORT = term_port;
wxe_master = data;
if(!(start_native_gui(data) == 1))
return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */
@@ -139,7 +143,7 @@ static void
wxe_driver_stop(ErlDrvData handle)
{
wxe_data *sd = ((wxe_data *)handle);
- if(sd->port != WXE_DRV_PORT) {
+ if(sd->port_handle != WXE_DRV_PORT_HANDLE) {
// fprintf(stderr, "%s:%d: STOP \r\n", __FILE__,__LINE__);
meta_command(DELETE_PORT,sd);
free(handle);
@@ -194,7 +198,7 @@ void wxe_process_died(ErlDrvData handle, ErlDrvMonitor *monitor)
push_command(WXE_CB_RETURN,NULL,0,sd);
/* ErlDrvTermData pid; */
-/* pid = driver_get_monitored_process(sd->port, monitor); */
+/* pid = driver_get_monitored_process(sd->port_handle, monitor); */
/* fprintf(stderr, "Process died %d \r\n", (int) pid); */
}
@@ -210,7 +214,7 @@ standard_outputv(ErlDrvData drv_data, ErlIOVec* ev)
binref = driver_alloc(sizeof(WXEBinRef));
binref->base = ev->iov[1].iov_base;
binref->size = ev->iov[1].iov_len;
- binref->from = driver_caller(sd->port);
+ binref->from = driver_caller(sd->port_handle);
bin = ev->binv[1];
driver_binary_inc_refc(bin); /* Otherwise it could get deallocated */
binref->bin = bin;
@@ -220,7 +224,7 @@ standard_outputv(ErlDrvData drv_data, ErlIOVec* ev)
binref = driver_alloc(sizeof(WXEBinRef));
binref->base = NULL;
binref->size = 0;
- binref->from = driver_caller(sd->port);
+ binref->from = driver_caller(sd->port_handle);
binref->bin = NULL;
binref->next = sd->bin;
sd->bin = binref;
diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h
index 5c5b8614ed..c765c866c2 100644
--- a/lib/wx/c_src/wxe_driver.h
+++ b/lib/wx/c_src/wxe_driver.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. 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
@@ -43,7 +43,8 @@ typedef struct wxe_bin_ref {
typedef struct wxe_data_def {
void * driver_data;
WXEBinRef * bin; /* Argument binaries */
- ErlDrvPort port;
+ ErlDrvPort port_handle;
+ ErlDrvTermData port;
int is_cbport;
ErlDrvPDL pdl;
} wxe_data;
@@ -67,8 +68,9 @@ void meta_command(int what, wxe_data *sd);
void * wxe_ps_init();
-extern ErlDrvPort WXE_DRV_PORT;
-extern int wxe_debug;
+extern ErlDrvPort WXE_DRV_PORT_HANDLE;
+extern ErlDrvTermData WXE_DRV_PORT;
+extern int wxe_debug;
extern char * erl_wx_privdir;
diff --git a/lib/wx/c_src/wxe_events.h b/lib/wx/c_src/wxe_events.h
index 43ea656a8d..6bbb0dfa13 100644
--- a/lib/wx/c_src/wxe_events.h
+++ b/lib/wx/c_src/wxe_events.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2009. 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
@@ -54,7 +54,7 @@ public:
class wxeEvtListener : public wxEvtHandler
{
public:
- wxeEvtListener(ErlDrvPort Thisport) : port(Thisport)
+ wxeEvtListener(ErlDrvTermData Thisport) : port(Thisport)
{}
// {fprintf(stderr, "Creating %x\r\n", (unsigned int) this); fflush(stderr);}
void forward(wxEvent& event);
@@ -62,7 +62,7 @@ public:
((WxeApp *)wxTheApp)->clearPtr(this);
// fprintf(stderr, "Deleteing %x\r\n", (unsigned int) this); fflush(stderr);
};
- ErlDrvPort port;
+ ErlDrvTermData port;
};
#endif
diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp
index e947a1bc6e..34904397d3 100644
--- a/lib/wx/c_src/wxe_gl.cpp
+++ b/lib/wx/c_src/wxe_gl.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. 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
@@ -141,7 +141,7 @@ void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){
ERL_DRV_INT, op,
ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"),
ERL_DRV_TUPLE,3};
- driver_send_term(WXE_DRV_PORT,caller,rt,8);
+ erl_drv_send_term(WXE_DRV_PORT,caller,rt,8);
return ;
}
};
@@ -155,6 +155,6 @@ void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){
else
bs[i] = NULL;
}
- wxe_gl_dispatch(op, bp, WXE_DRV_PORT, caller, bs, bs_sz);
+ wxe_gl_dispatch(op, bp, WXE_DRV_PORT_HANDLE, caller, bs, bs_sz);
}
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 527fabc315..adfee8da73 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.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
@@ -117,7 +117,7 @@ int start_native_gui(wxe_data *sd)
wxe_batch_locker_m = erl_drv_mutex_create((char *)"wxe_batch_locker_m");
wxe_batch_locker_c = erl_drv_cond_create((char *)"wxe_batch_locker_c");
- init_caller = driver_connected(sd->port);
+ init_caller = driver_connected(sd->port_handle);
#ifdef __DARWIN__
res = erl_drv_steal_main_thread((char *)"wxwidgets",
@@ -169,7 +169,7 @@ void unload_native_gui()
void push_command(int op,char * buf,int len, wxe_data *sd)
{
- // fprintf(stderr, "Op %d %d\r\n", op, (int) driver_caller(sd->port)),fflush(stderr);
+ // fprintf(stderr, "Op %d %d\r\n", op, (int) driver_caller(sd->port_handle)),fflush(stderr);
wxeCommand *Cmd = new wxeCommand(op, buf, len, sd);
erl_drv_mutex_lock(wxe_batch_locker_m);
wxe_batch->Append(Cmd);
@@ -536,18 +536,18 @@ void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) {
memenv->ref2ptr[i] = global_me->ref2ptr[i];
}
memenv->next = global_me->next;
- refmap[(ErlDrvTermData) Ecmd.port] = memenv;
+ refmap[Ecmd.port] = memenv;
memenv->owner = Ecmd.caller;
ErlDrvTermData rt[] = {ERL_DRV_ATOM, driver_mk_atom((char *)"wx_port_initiated")};
- driver_send_term(WXE_DRV_PORT,Ecmd.caller,rt,2);
+ erl_drv_send_term(WXE_DRV_PORT,Ecmd.caller,rt,2);
}
void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) {
// Clear incoming cmd queue first
// dispatch_cmds();
wxWindow *parent = NULL;
- wxeMemEnv * memenv = refmap[(ErlDrvTermData) Ecmd.port];
+ wxeMemEnv * memenv = refmap[Ecmd.port];
if(wxe_debug) {
wxString msg;
@@ -656,8 +656,8 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) {
refmap.erase((ErlDrvTermData) Ecmd.port);
}
-wxeMemEnv * WxeApp::getMemEnv(ErlDrvPort port) {
- return refmap[(ErlDrvTermData) port];
+wxeMemEnv * WxeApp::getMemEnv(ErlDrvTermData port) {
+ return refmap[port];
}
int WxeApp::newPtr(void * ptr, int type, wxeMemEnv *memenv) {
@@ -837,7 +837,7 @@ wxeCommand::wxeCommand(int fc,char * cbuf,int buflen, wxe_data *sd)
{
WXEBinRef *temp, *start, *prev;
int n = 0;
- caller = driver_caller(sd->port);
+ caller = driver_caller(sd->port_handle);
port = sd->port;
op = fc;
len = buflen;
@@ -940,7 +940,7 @@ int wxCALLBACK wxEListCtrlCompare(long item1, long item2, long callbackInfoPtr)
rt.addAtom("_wx_invoke_cb_");
rt.addTupleCount(3);
rt.send();
- handle_event_callback(cb->port, memenv->owner);
+ handle_event_callback(WXE_DRV_PORT_HANDLE, memenv->owner);
if(((WxeApp *) wxTheApp)->cb_buff) {
int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff;
diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h
index ee31068d5d..a3c57e2598 100644
--- a/lib/wx/c_src/wxe_impl.h
+++ b/lib/wx/c_src/wxe_impl.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2011. 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
@@ -34,7 +34,7 @@ class wxeMetaCommand : public wxEvent
public:
wxeMetaCommand(wxe_data *sd, int EvId)
: wxEvent(EvId, wxeEVT_META_COMMAND)
- { caller = driver_caller(sd->port); port = sd->port; pdl = sd->pdl; } ;
+ { caller = driver_caller(sd->port_handle); port = sd->port; pdl = sd->pdl; } ;
wxeMetaCommand(const wxeMetaCommand& event)
: wxEvent(event)
{ caller = event.caller; port = event.port; pdl = event.pdl; };
@@ -42,7 +42,7 @@ class wxeMetaCommand : public wxEvent
virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); }
ErlDrvTermData caller;
- ErlDrvPort port;
+ ErlDrvTermData port;
ErlDrvPDL pdl;
};
@@ -51,9 +51,9 @@ class wxeCommand : public wxObject
public:
wxeCommand(int fc,char * cbuf,int buflen, wxe_data *);
virtual ~wxeCommand();
-
+
ErlDrvTermData caller;
- ErlDrvPort port;
+ ErlDrvTermData port;
WXEBinRef * bin[3];
char * buffer;
int len;
@@ -161,7 +161,7 @@ public:
// MemEnv handling
void newMemEnv(wxeMetaCommand& event);
void destroyMemEnv(wxeMetaCommand& event);
- wxeMemEnv * getMemEnv(ErlDrvPort port);
+ wxeMemEnv * getMemEnv(ErlDrvTermData port);
int newPtr(void * ptr, int type, wxeMemEnv *memenv);
int getRef(void * ptr, wxeMemEnv *memenv);
@@ -193,7 +193,7 @@ class wxETreeItemData : public wxTreeItemData
char * bin;
};
-bool sendevent(wxEvent * event, ErlDrvPort port);
+bool sendevent(wxEvent * event, ErlDrvTermData port);
void pre_callback();
void handle_event_callback(ErlDrvPort port, ErlDrvTermData process);
@@ -208,10 +208,10 @@ extern wxeGLC glc;
class wxEPrintout : public wxPrintout
{
public:
- wxEPrintout(wxString Title, int onPrintP, int onPrepareP,
+ wxEPrintout(wxString Title, int onPrintP, int onPrepareP,
int onBeginP, int onEndP,
int onBeginD, int onEndD,
- int hasP, int getPageI, ErlDrvPort Port) :
+ int hasP, int getPageI, ErlDrvTermData Port) :
wxPrintout(Title),
onPrintPage(onPrintP), onPreparePrinting(onPrepareP),
onBeginPrinting(onBeginP), onEndPrinting(onEndP),
@@ -241,15 +241,15 @@ class wxEPrintout : public wxPrintout
int hasPage;
int getPageInfo;
- ErlDrvPort port;
+ ErlDrvTermData port;
};
-void clear_cb(ErlDrvPort port, int callback);
+void clear_cb(ErlDrvTermData port, int callback);
// Implementation of wxListCtrlCompare
struct callbackInfo {
- ErlDrvPort port;
+ ErlDrvTermData port;
int callbackID;
};
diff --git a/lib/wx/c_src/wxe_ps_init.c b/lib/wx/c_src/wxe_ps_init.c
index 025ea90f8b..541d188098 100644
--- a/lib/wx/c_src/wxe_ps_init.c
+++ b/lib/wx/c_src/wxe_ps_init.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2011. 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
diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp
index 0f3eb40efc..d50a74ac9d 100644
--- a/lib/wx/c_src/wxe_return.cpp
+++ b/lib/wx/c_src/wxe_return.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
@@ -26,9 +26,9 @@ WX_DEFINE_OBJARRAY(wxErlDrvTermDataArray);
#define INLINE
-wxeReturn::wxeReturn (ErlDrvPort _port,
- ErlDrvTermData _caller,
- bool _isResult) {
+wxeReturn::wxeReturn (ErlDrvTermData _port,
+ ErlDrvTermData _caller,
+ bool _isResult) {
port = _port;
caller = _caller;
@@ -61,7 +61,7 @@ int wxeReturn::send() {
rtData[i] = rt[i];
}
- int res = driver_send_term(port, caller, rtData, rtLength);
+ int res = erl_drv_send_term(port, caller, rtData, rtLength);
driver_free(rtData);
#ifdef DEBUG
diff --git a/lib/wx/c_src/wxe_return.h b/lib/wx/c_src/wxe_return.h
index b6bfa85e63..80946e2dc6 100644
--- a/lib/wx/c_src/wxe_return.h
+++ b/lib/wx/c_src/wxe_return.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
@@ -48,9 +48,9 @@ WX_DECLARE_OBJARRAY(ErlDrvTermData, wxErlDrvTermDataArray);
class wxeReturn {
public:
- wxeReturn (ErlDrvPort _port,
- ErlDrvTermData _caller,
- bool _isResult=false);
+ wxeReturn (ErlDrvTermData _port,
+ ErlDrvTermData _caller,
+ bool _isResult=false);
~wxeReturn();
@@ -130,7 +130,7 @@ private:
// WxeApp* wxe_app;
ErlDrvTermData caller;
- ErlDrvPort port;
+ ErlDrvTermData port;
// wxeMemEnv *memEnv;
wxErlDrvTermDataArray rt;
wxArrayDouble temp_float;
diff --git a/lib/wx/configure.in b/lib/wx/configure.in
index c45d2285af..6a0d649ccd 100755
--- a/lib/wx/configure.in
+++ b/lib/wx/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 2008-2012. All Rights Reserved.
+dnl Copyright Ericsson AB 2008-2013. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
@@ -99,7 +99,7 @@ PTHR_CFLAGS="-D_THREAD_SAFE -D_REENTRANT"
OBJC_CC=$CC
OBJC_CFLAGS=""
-
+CXXFLAGS=""
dnl NOTE: CPPFLAGS will be included in CFLAGS at the end
case $host_os in
darwin*)
@@ -111,12 +111,13 @@ case $host_os in
AC_MSG_RESULT([yes])
C_ONLY_FLAGS="-ObjC"
else
- dnl We are probebly trying to build with a non-Apple gcc,
+ dnl We are probably trying to build with a non-Apple gcc,
dnl which is good as long as we do not try to build Cocoa
dnl code. We need an Apple compiler for just that (Objective C)
AC_MSG_RESULT([no])
AC_MSG_CHECKING([for a Cocoa compliant Objective C compiler])
SEARCHFOR=""
+ SEARCHFORXX=""
save_IFS=$IFS
IFS=:
set $PATH
@@ -124,19 +125,29 @@ case $host_os in
while test X"$1" != X""; do
dnl Add all possible paths to a real apple gcc
SEARCHFOR="$1/gcc-apple-4.2 $SEARCHFOR"
+ SEARCHFORXX="$1/g++-apple-4.2 $SEARCHFORXX"
shift
done
dnl Add LLVM compilers, they will work in this case
SEARCHFOR="/usr/bin/clang /usr/bin/gcc $SEARCHFOR"
+ SEARCHFORXX="/usr/bin/clang /usr/bin/g++ $SEARCHFORXX"
APPLE_CC=""
+ APPLE_CXX=""
dnl SEARCHFOR is reversed, so we want to find the last existing
dnl executable in the list
+ IFS=" "
+ set $SEARCHFORXX
for x in $SEARCHFOR; do
if test -x $x; then
APPLE_CC=$x
fi
+ if test -x "$1"; then
+ APPLE_CXX="$1"
+ fi
+ shift
done
- if test X$APPLE_CC = X; then
+ IFS=$save_IFS
+ if test X$APPLE_CC = X -o X$APPLE_CXX = X; then
AC_MSG_RESULT([no])
dnl Complete failure, we cannot build Cocoa code
if test X"$WX_BUILDING_INSIDE_ERLSRC" != X"true" ; then
@@ -150,7 +161,12 @@ case $host_os in
else
dnl We think we found an Apple compiler and will add
dnl Apple specific options
- AC_MSG_RESULT($APPLE_CC)
+ AC_MSG_RESULT([$APPLE_CC ($APPLE_CXX)])
+ dnl We should use this compiler for all of wx - hack...
+ CC=$APPLE_CC
+ CXX=$APPLE_CXX
+ dnl Both clang and gcc accept these flags...
+ #CXXFLAGS="-x c++ $CXXFLAGS"
OBJC_CC=$APPLE_CC
OBJC_CFLAGS="-ObjC"
fi
@@ -267,10 +283,10 @@ fi
AC_SUBST(GL_LIBS)
-CXXFLAGS="$CFLAGS $CPPFLAGS"
+CXXFLAGS="$CXXFLAGS $CFLAGS $CPPFLAGS"
CFLAGS="$CFLAGS $CPPFLAGS $C_ONLY_FLAGS"
-DEBUG_CXXFLAGS="$DEBUG_CFLAGS $CPPFLAGS"
+DEBUG_CXXFLAGS="$CXXFLAGS $DEBUG_CFLAGS $CPPFLAGS"
DEBUG_CFLAGS="$DEBUG_CFLAGS $CPPFLAGS $C_ONLY_FLAGS"
AC_SUBST(DEBUG_CFLAGS)
AC_SUBST(DEBUG_CXXFLAGS)
diff --git a/lib/wx/examples/demo/demo_html_tagger.erl b/lib/wx/examples/demo/demo_html_tagger.erl
index 243e5d659f..7bb6736fdc 100644
--- a/lib/wx/examples/demo/demo_html_tagger.erl
+++ b/lib/wx/examples/demo/demo_html_tagger.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -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/examples/demo/ex_button.erl b/lib/wx/examples/demo/ex_button.erl
index 41bf34e572..0f3296d0c0 100644
--- a/lib/wx/examples/demo/ex_button.erl
+++ b/lib/wx/examples/demo/ex_button.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_canvas.erl b/lib/wx/examples/demo/ex_canvas.erl
index 1f1d260276..8e517ba852 100644
--- a/lib/wx/examples/demo/ex_canvas.erl
+++ b/lib/wx/examples/demo/ex_canvas.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_choices.erl b/lib/wx/examples/demo/ex_choices.erl
index b4418293c1..c8b27f8580 100644
--- a/lib/wx/examples/demo/ex_choices.erl
+++ b/lib/wx/examples/demo/ex_choices.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_cursor.erl b/lib/wx/examples/demo/ex_cursor.erl
index 2f1eaaf7c7..f8a7cdd01b 100644
--- a/lib/wx/examples/demo/ex_cursor.erl
+++ b/lib/wx/examples/demo/ex_cursor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_dialogs.erl b/lib/wx/examples/demo/ex_dialogs.erl
index 5c47b51271..2b9febfb64 100644
--- a/lib/wx/examples/demo/ex_dialogs.erl
+++ b/lib/wx/examples/demo/ex_dialogs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_frame_utils.erl b/lib/wx/examples/demo/ex_frame_utils.erl
index 4a59bb3a68..c2273f80e0 100644
--- a/lib/wx/examples/demo/ex_frame_utils.erl
+++ b/lib/wx/examples/demo/ex_frame_utils.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_gauge.erl b/lib/wx/examples/demo/ex_gauge.erl
index c53dfb807b..5ec524fc37 100644
--- a/lib/wx/examples/demo/ex_gauge.erl
+++ b/lib/wx/examples/demo/ex_gauge.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_grid.erl b/lib/wx/examples/demo/ex_grid.erl
index e284836d5b..691eede3c4 100644
--- a/lib/wx/examples/demo/ex_grid.erl
+++ b/lib/wx/examples/demo/ex_grid.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_htmlWindow.erl b/lib/wx/examples/demo/ex_htmlWindow.erl
index af3d4c71f5..f505dfcfe1 100644
--- a/lib/wx/examples/demo/ex_htmlWindow.erl
+++ b/lib/wx/examples/demo/ex_htmlWindow.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_listCtrl.erl b/lib/wx/examples/demo/ex_listCtrl.erl
index 2c62ac9d5f..a59b30b15c 100644
--- a/lib/wx/examples/demo/ex_listCtrl.erl
+++ b/lib/wx/examples/demo/ex_listCtrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_notebook.erl b/lib/wx/examples/demo/ex_notebook.erl
index 5edcc65082..69b1e02f6b 100644
--- a/lib/wx/examples/demo/ex_notebook.erl
+++ b/lib/wx/examples/demo/ex_notebook.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_pickers.erl b/lib/wx/examples/demo/ex_pickers.erl
index 54f8c7a8e5..b12d1b3877 100644
--- a/lib/wx/examples/demo/ex_pickers.erl
+++ b/lib/wx/examples/demo/ex_pickers.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_popupMenu.erl b/lib/wx/examples/demo/ex_popupMenu.erl
index f48b00963d..c0d82444b6 100644
--- a/lib/wx/examples/demo/ex_popupMenu.erl
+++ b/lib/wx/examples/demo/ex_popupMenu.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_radioBox.erl b/lib/wx/examples/demo/ex_radioBox.erl
index 17a11d1054..f615b81997 100644
--- a/lib/wx/examples/demo/ex_radioBox.erl
+++ b/lib/wx/examples/demo/ex_radioBox.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_sashWindow.erl b/lib/wx/examples/demo/ex_sashWindow.erl
index 9eb3b9b27e..8057d9b2c3 100644
--- a/lib/wx/examples/demo/ex_sashWindow.erl
+++ b/lib/wx/examples/demo/ex_sashWindow.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_sizers.erl b/lib/wx/examples/demo/ex_sizers.erl
index ecd539cd62..5875198d38 100644
--- a/lib/wx/examples/demo/ex_sizers.erl
+++ b/lib/wx/examples/demo/ex_sizers.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_slider.erl b/lib/wx/examples/demo/ex_slider.erl
index 4979e8b4f4..001e04a0f8 100644
--- a/lib/wx/examples/demo/ex_slider.erl
+++ b/lib/wx/examples/demo/ex_slider.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_splitterWindow.erl b/lib/wx/examples/demo/ex_splitterWindow.erl
index ac2fbe0113..06357d7d08 100644
--- a/lib/wx/examples/demo/ex_splitterWindow.erl
+++ b/lib/wx/examples/demo/ex_splitterWindow.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_static.erl b/lib/wx/examples/demo/ex_static.erl
index 8cf477b55a..1be033eac5 100644
--- a/lib/wx/examples/demo/ex_static.erl
+++ b/lib/wx/examples/demo/ex_static.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/examples/demo/ex_treeCtrl.erl b/lib/wx/examples/demo/ex_treeCtrl.erl
index 7698ab1f00..d2ce0cf95e 100644
--- a/lib/wx/examples/demo/ex_treeCtrl.erl
+++ b/lib/wx/examples/demo/ex_treeCtrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/src/gen/wxNcPaintEvent.erl b/lib/wx/src/gen/wxNcPaintEvent.erl
deleted file mode 100644
index 4dd292a0be..0000000000
--- a/lib/wx/src/gen/wxNcPaintEvent.erl
+++ /dev/null
@@ -1,64 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% 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
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%% This file is generated DO NOT EDIT
-
-%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxncpaintevent.html">wxNcPaintEvent</a>.
-%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt>
-%% <dd><em>nc_paint</em></dd></dl>
-%% See also the message variant {@link wxEvtHandler:wxNcPaint(). #wxNcPaint{}} event record type.
-%%
-%% <p>This class is derived (and can use functions) from:
-%% <br />{@link wxEvent}
-%% </p>
-%% @type wxNcPaintEvent(). An object reference, The representation is internal
-%% and can be changed without notice. It can't be used for comparsion
-%% stored on disc or distributed for use on other nodes.
-
--module(wxNcPaintEvent).
--include("wxe.hrl").
--export([]).
-
-%% inherited exports
--export([getId/1,getSkipped/1,getTimestamp/1,isCommandEvent/1,parent_class/1,
- resumePropagation/2,shouldPropagate/1,skip/1,skip/2,stopPropagation/1]).
-
--export_type([wxNcPaintEvent/0]).
-%% @hidden
-parent_class(wxEvent) -> true;
-parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-
--type wxNcPaintEvent() :: wx:wx_object().
- %% From wxEvent
-%% @hidden
-stopPropagation(This) -> wxEvent:stopPropagation(This).
-%% @hidden
-skip(This, Options) -> wxEvent:skip(This, Options).
-%% @hidden
-skip(This) -> wxEvent:skip(This).
-%% @hidden
-shouldPropagate(This) -> wxEvent:shouldPropagate(This).
-%% @hidden
-resumePropagation(This,PropagationLevel) -> wxEvent:resumePropagation(This,PropagationLevel).
-%% @hidden
-isCommandEvent(This) -> wxEvent:isCommandEvent(This).
-%% @hidden
-getTimestamp(This) -> wxEvent:getTimestamp(This).
-%% @hidden
-getSkipped(This) -> wxEvent:getSkipped(This).
-%% @hidden
-getId(This) -> wxEvent:getId(This).
diff --git a/lib/wx/src/gen/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/src/wxe_server.erl b/lib/wx/src/wxe_server.erl
index 689fe16a70..a8604c76b9 100644
--- a/lib/wx/src/wxe_server.erl
+++ b/lib/wx/src/wxe_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. 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
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/make/emd2exml.in b/make/emd2exml.in
index b677ef8ed4..5bfe89894e 100644
--- a/make/emd2exml.in
+++ b/make/emd2exml.in
@@ -5,7 +5,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. 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
diff --git a/make/fakefop b/make/fakefop
index bbe81ef3b1..b64428bbd1 100755
--- a/make/fakefop
+++ b/make/fakefop
@@ -1,10 +1,9 @@
#!/bin/sh
#
-# Copyright Tuncer Ayaz 2010. All Rights Reserved.
-#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. All Rights Reserved.
+# Copyright Tuncer Ayaz 2010-2013. 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
@@ -22,92 +21,85 @@
# Author: Tuncer Ayaz
#
-if [ $# -lt 4 ]
+if [ $# -lt 6 ]
then
- echo "Usage: fakefop -fo IGNORED -pdf OUTFILE"
+ echo "Usage: fakefop -c IGNORED -fo IGNORED -pdf OUTFILE"
exit 1
fi
-OUTFILE=$4
-NAME=`basename $4 .pdf`
+OUTFILE=$6
+
+echo -n -e '%PDF-1.4\n%\0342\0343\0317\0323\n\n' > $OUTFILE
-echo Write $OUTFILE
-cat > $OUTFILE <<EndOfFile
-%PDF-1.4
+cat >> $OUTFILE <<EndOfFile
1 0 obj
- << /Type /Catalog
- /Outlines 2 0 R
- /Pages 3 0 R
- >>
+<<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
endobj
2 0 obj
- << /Type /Outlines
- /Count 0
- >>
+<<
+ /Type /Pages
+ /Kids [ 3 0 R ]
+ /Count 1
+>>
endobj
3 0 obj
- << /Type /Pages
- /Kids [4 0 R]
- /Count 1
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [ 0 0 612 492 ]
+ /Contents 5 0 R
+ /Resources <<
+ /Font <<
+ /F1 4 0 R
+ >>
>>
+>>
endobj
4 0 obj
- << /Type /Page
- /Parent 3 0 R
- /MediaBox [0 0 612 492]
- /Contents 5 0 R
- /Resources << /ProcSet 6 0 R
- /Font << /F1 7 0 R >>
- >>
- >>
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F1
+ /BaseFont /Helvetica
+ /Encoding /StandardEncoding
+>>
endobj
5 0 obj
- << /Length 73 >>
+<<
+ /Length 74
+>>
stream
- BT
- /F1 24 Tf
- 10 400 Td
- ($NAME) Tj
- ET
- BT
- /F1 24 Tf
- 10 350 Td
- (\(placeholder PDF generated without FOP\)) Tj
- ET
+BT
+/F1 24 Tf
+10 400 Td
+(\(placeholder PDF generated with fakefop\)) Tj
+ET
endstream
endobj
-6 0 obj
- [/PDF /Text]
-endobj
-7 0 obj
- << /Type /Font
- /Subtype /Type1
- /Name /F1
- /BaseFont /Helvetica
- /Encoding /MacRomanEncoding
- >>
-endobj
xref
-0 8
-0000000000 65535 f
-0000000009 00000 n
-0000000074 00000 n
-0000000120 00000 n
-0000000179 00000 n
-0000000364 00000 n
-0000000466 00000 n
-0000000496 00000 n
+0 6
+0000000000 65536 f
+0000000016 00000 n
+0000000070 00000 n
+0000000136 00000 n
+0000000291 00000 n
+0000000410 00000 n
trailer
- << /Size 8
- /Root 1 0 R
- >>
+<<
+ /Size 6
+ /Root 1 0 R
+>>
+
startxref
-625
+536
%%EOF
EndOfFile
diff --git a/make/otp.mk.in b/make/otp.mk.in
index 0e58a27016..91e2d8a95e 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -4,7 +4,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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
@@ -255,6 +255,7 @@ DEFAULT_GIF_FILES = $(HTMLDIR)/min_head.gif
#
XSLTPROC = @XSLTPROC@
FOP = @FOP@
+XMLLINT = @XMLLINT@
DOCGEN=$(ERL_TOP)/lib/erl_docgen
FOP_CONFIG = $(DOCGEN)/priv/fop.xconf
diff --git a/make/otp_ded.mk.in b/make/otp_ded.mk.in
index e2232acbb1..0c9a8a087f 100644
--- a/make/otp_ded.mk.in
+++ b/make/otp_ded.mk.in
@@ -2,7 +2,7 @@
# ----------------------------------------------------
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+# Copyright Ericsson AB 2009-2013. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk
index 0be0a2de56..998e25a436 100644
--- a/make/otp_release_targets.mk
+++ b/make/otp_release_targets.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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
@@ -106,6 +106,9 @@ $(HTMLDIR)/$(APPLICATION).eix: $(XML_FILES) $(SPECS_FILES)
docs: $(HTMLDIR)/$(APPLICATION).eix
+xmllint: $(XML_FILES)
+ $(XMLLINT) --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities $(XML_FILES)
+
# ----------------------------------------------------
# Local documentation target for testing
# ----------------------------------------------------
diff --git a/make/output.mk.in b/make/output.mk.in
index 2f1a1d3a79..938f878ebe 100644
--- a/make/output.mk.in
+++ b/make/output.mk.in
@@ -4,7 +4,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. 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,19 +22,35 @@
# Author: Anthony Ramine
# ----------------------------------------------------
+# These variables are used to produce less output when running make with V=0 or
+# with the --enable-silent-rules flag.
+#
+# For each compiler kind of file generated by a command during the building of
+# Erlang/OTP, a variable named <command>_verbose should be defined and used as
+# a command prefix. The generic gen_verbose variable is offered for
+# miscellaneous operations like sed, cp or magical Perl incantations.
+#
+# A second variable V_<COMMAND> is also provided for major compilation tools
+# like CC, ERLC or JAVAC.
+
+# DEFAULT_VERBOSITY is set by the --enable-silent-rules configure flag.
ifeq ($(V),)
V = @DEFAULT_VERBOSITY@
endif
+# v_p should be used with `test` to dynamically print things.
ifeq ($(V),0)
v_p = 0
else
v_p = 1
endif
+# V_at is the @ prefix when silent rules are enabled.
V_at_0 = @
V_at = $(V_at_$(V))
+# V_colon makes the prefixed command into a no-op if silent rules are enabled,
+# useful to annihilate an `echo` command.
V_colon_0 = @: ""
V_colon = $(V_colon_$(V))
@@ -49,6 +65,10 @@ cc_verbose_0 = @echo " CC "$@;
cc_verbose = $(cc_verbose_$(V))
V_CC = $(cc_verbose)$(CC)
+cpp_verbose_0 = @echo " CPP "$@;
+cpp_verbose = $(cpp_verbose_$(V))
+
+# For the diameter compiler.
dia_verbose_0 = @echo " DIA "$@;
dia_verbose = $(dia_verbose_$(V))
@@ -87,6 +107,11 @@ V_LEX = $(lex_verbose)$(LEX)
m4_verbose_0 = @echo " M4 "$@;
m4_verbose = $(m4_verbose_$(V))
+# V_MAKE isn't defined and shouldn't be to avoid breaking parallel building and
+# the following warning:
+#
+# warning: jobserver unavailable: using -j1. Add `+' to parent make rule.
+#
make_verbose_0 = @echo " MAKE "$@;
make_verbose = $(make_verbose_$(V))
@@ -105,6 +130,8 @@ V_RC = $(rc_verbose)$(RC)
snmp_verbose_0 = @echo " SNMP "$@;
snmp_verbose = $(snmp_verbose_$(V))
+# vsn_verbose should be used instead of gen_verbose when sed or another tool
+# is used to insert a version number into a file.
vsn_verbose_0 = @echo " VSN "$@;
vsn_verbose = $(vsn_verbose_$(V))
diff --git a/system/README b/system/README
index b1e18ef55c..61277306f1 100644
--- a/system/README
+++ b/system/README
@@ -1,7 +1,7 @@
-Erlang/OTP December 8, 2011
+Erlang/OTP Januari 25, 2013
-Release of Erlang 5.9/OTP R15B
+Release of Erlang 5.10/OTP R16
1. GENERAL
diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml
index ac35a37bc4..3bbaf7a0ad 100644
--- a/system/doc/efficiency_guide/advanced.xml
+++ b/system/doc/efficiency_guide/advanced.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2011</year>
+ <year>2001</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/drivers.xml b/system/doc/efficiency_guide/drivers.xml
index b10595ea4d..66311a3738 100644
--- a/system/doc/efficiency_guide/drivers.xml
+++ b/system/doc/efficiency_guide/drivers.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year><year>2011</year>
+ <year>2009</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/part.xml b/system/doc/embedded/part.xml
index d96a94a1a0..6dd0b73965 100644
--- a/system/doc/embedded/part.xml
+++ b/system/doc/embedded/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/xmlfiles.mk b/system/doc/embedded/xmlfiles.mk
index 0001a55b9a..d11f5a1004 100644
--- a/system/doc/embedded/xmlfiles.mk
+++ b/system/doc/embedded/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2013. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml
index 648beb0afd..2cffd30283 100644
--- a/system/doc/installation_guide/part.xml
+++ b/system/doc/installation_guide/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk
index 8ea2b296aa..3995c607af 100644
--- a/system/doc/installation_guide/xmlfiles.mk
+++ b/system/doc/installation_guide/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+# Copyright Ericsson AB 2009-2013. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/system/doc/reference_manual/ports.xml b/system/doc/reference_manual/ports.xml
index c4e4ef1d35..58e2baac17 100644
--- a/system/doc/reference_manual/ports.xml
+++ b/system/doc/reference_manual/ports.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
index c3620f83f6..9207d536d5 100644
--- a/system/doc/reference_manual/typespec.xml
+++ b/system/doc/reference_manual/typespec.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2011</year>
+ <year>2003</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -196,7 +196,7 @@ TList :: Type
<cell><c>nonempty_string()</c></cell><cell><c>[char(),...]</c></cell>
</row>
<row>
- <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(char() | binary() | iolist(), binary() | [])</c></cell>
+ <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(byte() | binary() | iolist(), binary() | [])</c></cell>
</row>
<row>
<cell><c>module()</c></cell><cell><c>atom()</c></cell>